|
RIPEMD160ByteBuffer |
|
1 /* $RCSfile: RIPEMD160ByteBuffer.java,v $
2 * $Revision: 1.10 $
3 * $Date: 2002/01/17 19:24:55 $
4 * $Author: uwe $
5 * $State: Exp $
6 *
7 * Created on July 14, 2001, 11:46 AM
8 *
9 * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
10 *
11 * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
12 * ServiceProvider is a library, written in JavaTM, that should be
13 * used in HBCI banking applications (clients and may be servers),
14 * to do cryptographic operations.
15 *
16 * The jhbci library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
20 *
21 * The jhbci library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32 package de.cscc.crypto.provider;
33
34 import java.util.Arrays;
35
36 import de.cscc.crypto.util.ByteUtil;
37
38 /**
39 * Internal byte buffer Class.
40 *
41 * @author <a href=mailto:uwe@cscc.de>Uwe Günther</a>
42 * @version $Revision: 1.10 $
43 */
44 class RIPEMD160ByteBuffer implements Cloneable {
45
46 /** Length of the internal buffer. */
47 private static final int BUFFER_LENGTH = 4;
48
49 /** Internal buffer. */
50 private byte[] buffer = new byte[BUFFER_LENGTH];
51
52 /** Counts how full is the internal <CODE>buffer</CODE>. */
53 private int bufferOffset = 0;
54
55 /** Creates new RIPEMD160ByteBuffer. */
56 public RIPEMD160ByteBuffer() {}
57
58 /**
59 * Creates and returns a deep copy of this object.
60 * @return a clone of this instance.
61 * @see java.lang.Cloneable
62 * @exception CloneNotSupportedException if the object's class does not
63 * support the <code>Cloneable</code> interface. Subclasses
64 * that override the <code>clone</code> method can also
65 * throw this exception to indicate that an instance cannot
66 * be cloned.
67 */
68 public Object clone() throws CloneNotSupportedException {
69 RIPEMD160ByteBuffer result = (RIPEMD160ByteBuffer) super.clone();
70 result.buffer = (byte[]) this.buffer.clone();
71 return result;
72 }
73
74 /**
75 * Indicates whether some other object is "equal to" this one.
76 *
77 * @param obj the reference object with which to compare.
78 * @return <code>true</code> if this object is the same as the obj
79 * argument; <code>false</code> otherwise.
80 * @see #hashCode()
81 * @see java.util.Hashtable
82 */
83 public boolean equals(Object obj) {
84 //Only for performance.
85 if (this == obj) {
86 return true;
87 }
88
89 //If obj == null then instanceof returns false, see JLS 15.20.2
90 if (!(obj instanceof RIPEMD160ByteBuffer)) {
91 return false;
92 }
93
94 RIPEMD160ByteBuffer other = (RIPEMD160ByteBuffer)obj;
95 //return (Arrays.equals(this.buffer, temp.buffer) &&
96 // this.bufferOffset == temp.bufferOffset );
97 if (this.bufferOffset != other.bufferOffset) {
98 return false; //not equal
99 }
100 for (int i = 0; i < this.bufferOffset; i++) {
101 if (this.buffer[i] != other.buffer[i]) {
102 return false; //not equal
103 }
104 }
105 return true; //equal
106 }
107
108 /**
109 * Returns a hash code value for the object. This method is
110 * supported for the benefit of hashtables such as those provided by
111 * <code>java.util.Hashtable</code>.
112 *
113 * @return a hash code value for this object.
114 * @see #equals(java.lang.Object)
115 * @see java.util.Hashtable
116 */
117 public int hashCode() {
118 int result = 17;
119 for (int i = 0; i < this.bufferOffset; i++) {
120 result = 37*result + this.buffer[i];
121 }
122 return result;
123 }
124
125 /**
126 * Returns a string representation of the object.
127 *
128 * @return a string representation of the object.
129 */
130 public String toString() {
131 return "[bufferOffset: " + this.bufferOffset +
132 " buffer: " + ByteUtil.toHex(buffer) + "]";
133 }
134
135 /**
136 * Indicates if the buffer is not empty.
137 * @return true if the buffer is not empty.
138 */
139 public boolean isNotEmpty() {
140 return (this.bufferOffset != 0);
141 }
142
143 /**
144 * Indicates if the buffer is full.
145 * @return true if the buffer is full.
146 */
147 public boolean isFull() {
148 return (this.bufferOffset == RIPEMD160ByteBuffer.BUFFER_LENGTH);
149 }
150
151 /** Resets the internal buffer and its offset counter. */
152 public void reset() {
153 Arrays.fill(this.buffer, (byte)0x00);
154 bufferOffset = 0;
155 }
156
157 /**
158 * Fills the internal buffer with bytes. If there are more than 4 bytes
159 * added, you should call {@link #reset() reset()}. Otherwise the
160 * ArrayIndexOutOfBoundsException will be thrown.
161 *
162 * @param in byte that will be added to the internal buffer.
163 * @throws ArrayIndexOutOfBoundsException there are more than 16 words added.
164 */
165 public void set(byte in) throws ArrayIndexOutOfBoundsException {
166
167 // if the Buffer is full, we a ArrayIndexOutOfBoundsException
168 // the user must take of the buffer management with isFull() and
169 // isEmpty()
170 if (isFull()) {
171 throw new ArrayIndexOutOfBoundsException(bufferOffset);
172 }
173
174 this.buffer[this.bufferOffset] = in;
175 this.bufferOffset++;
176 }
177
178 /**
179 * In RIPEMD-160 a "word" is a 32-bit quantity and a "byte" is an
180 * eight-bit quantity. A sequence of bits can be interpreted in a
181 * natural manner as a sequence of bytes, where each consecutive group
182 * of eight bits is interpreted as a byte with the high-order (most
183 * significant) bit of each byte listed first. Similarly, a sequence of
184 * bytes can be interpreted as a sequence of 32-bit words, where each
185 * consecutive group of four bytes is interpreted as a word with the
186 * low-order (least significant) byte given first. This means that the
187 * byteBuffer[4]will be moved to the 32 bit word with little endian
188 * byte order. Here follows a example:
189 *
190 * <pre>
191 *
192 * Buffer fill operation:
193 * ======================
194 * wordBuffer[0] = (byte)0x11;
195 * wordBuffer[1] = (byte)0xaa;
196 * wordBuffer[2] = (byte)0xbb;
197 * wordBuffer[3] = (byte)0xcc;
198 *
199 * wordBuffer memory representation: 0x11aabbcc <- important!
200 * -- --
201 * / \
202 * lowest highest
203 * memory memory
204 * address address
205 * (e.g.0x2000) (e.g.0x2003)
206 *
207 * Now we fill the byte array in 32 bit word (int):
208 * ------------------------------------------------
209 * empty int: 0x00000000
210 * -- --
211 * / \
212 * most least
213 * significant significant
214 * byte byte
215 *
216 * lowest highest
217 * memory memory
218 * address address
219 * (e.g.0x2000) (e.g.0x2003)
220 *
221 * word after fill with the byteBuffer[4] byte array: 0xccbbaa11
222 * ^^^^^^^^^^
223 * important!
224 *
225 * word memory representation is also: 0xccbbaa11 <- important!
226 *
227 * </pre>
228 *
229 * <p>For Java conversion and promotion question, see in the Book
230 * "The Java Language Specification Second Edition" by
231 * James Gosling, Bill Joy, Guy Steel and Gilard Bracha
232 * ISBN: 0-202-31008-2
233 * A serious Java programmer should have this book in his book shelf!!!
234 *
235 *
236 * @return the word that contains the 4bytes in little endian byte order.
237 */
238 public int toWord(){
239
240 return ((this.buffer[0] & 0x000000ff) |
241 ((this.buffer[1] & 0x000000ff) << 8) |
242 ((this.buffer[2] & 0x000000ff) << 16) |
243 ((this.buffer[3] & 0x000000ff) << 24) );
244 }
245 }
246
|
RIPEMD160ByteBuffer |
|