|
RIPEMD160MessageDigestImpl |
|
1 /* $RCSfile: RIPEMD160MessageDigestImpl.java,v $
2 * $Revision: 1.2 $
3 * $Date: 2002/02/17 08:27:00 $
4 * $Author: uwe $
5 * $State: Exp $
6 *
7 * Created on July 4, 2001, 1:01 PM
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.security.DigestException;
35
36 /**
37 * This class contains the RIPEMD-160 algorithm. It is a helper class for
38 * ServiceProvider engines. You can not instance these class only at
39 * package scope and you can not inherit from these final class.
40 * These class is directly used by ServiceProviders from these package,
41 * such as RIPEMD160Engine.
42 *
43 * <p>The sum of all bytes, added with {@link #update(byte)
44 * update(byte)} and {@link #update(byte[], int, int)
45 * update(byte[], int, int)} are processed by the RIPEMD-160
46 * message digest algorithm with {@link #digest() digest()} or
47 * {@link #digest(byte[] , int, int) digest(byte[], int, int)}.
48 *
49 * <pre>
50 *
51 * How does it work:
52 * =================
53 *
54 * RIPEMD-160 works only with whole 512 bit Blocks.
55 *
56 * 512 bits == 64 Bytes == 16 Words
57 * -------------------------------------------------
58 * |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
59 * -------------------------------------------------
60 * / \
61 * / \
62 * / \
63 * / \
64 * / \
65 * -------------
66 * |32 bit Word| <-- 32 bit Word = 4 Byte
67 * -------------
68 * |00|01|02|03| <-- 4 Bytes = 4 x 8 bit = 32 bit
69 * -------------
70 *
71 * </pre>
72 *
73 * @author <a href=mailto:uwe@cscc.de>Uwe Günther</a>
74 * @version $Revision: 1.2 $
75 */
76 final class RIPEMD160MessageDigestImpl implements Cloneable {
77
78 /** The length of the message digest in byte. */
79 private static final int DIGEST_LENGTH = 20; // 20 byte or 160 bit
80
81 /** Counts the bytes of the whole message that will be digested. */
82 private RIPEMD160ByteCounter byteCounter;
83
84 /** Internal <CODE>byteBuffer</CODE>. */
85 private RIPEMD160ByteBuffer byteBuffer;
86
87 /**
88 * Internal wordBuffer that holds a 512 bit message block
89 * 512 bit are the block size for the RIPEMD160 algorithm
90 * that will be compressed if the compress functions runs at ones.
91 */
92 private RIPEMD160WordBuffer wordBuffer;
93
94 /**
95 * Internal messageDigest repesentation object for the
96 * five MD words == 160 bit or 20 Byte.
97 */
98 private RIPEMD160MessageDigestBuffer messageDigest;
99
100 /** Creates new RIPEMD160MessageDigestImpl. */
101 public RIPEMD160MessageDigestImpl() {
102 this.byteCounter =new RIPEMD160ByteCounter();
103 this.byteBuffer =new RIPEMD160ByteBuffer();
104 this.wordBuffer =new RIPEMD160WordBuffer();
105 this.messageDigest =new RIPEMD160MessageDigestBuffer();
106 }
107
108 /**
109 * Creates and returns a deep copy of this object.
110 * @return a clone of this instance.
111 * @see java.lang.Cloneable
112 * @exception CloneNotSupportedException if the object's class does not
113 * support the <code>Cloneable</code> interface. Subclasses
114 * that override the <code>clone</code> method can also
115 * throw this exception to indicate that an instance cannot
116 * be cloned.
117 */
118 public Object clone() throws CloneNotSupportedException {
119 RIPEMD160MessageDigestImpl result =
120 (RIPEMD160MessageDigestImpl) super.clone();
121 result.byteCounter = (RIPEMD160ByteCounter) this.byteCounter.clone();
122 result.byteBuffer = (RIPEMD160ByteBuffer) this.byteBuffer.clone();
123 result.wordBuffer = (RIPEMD160WordBuffer) this.wordBuffer.clone();
124 result.messageDigest =
125 (RIPEMD160MessageDigestBuffer) this.messageDigest.clone();
126 return result;
127 }
128
129 /**
130 * Compares two RIPEMD160MessageDigestImpl object. If the private members
131 * of obj are equal with the private members of this object the method
132 * will return true, otherwise false.
133 *
134 * @return return true if the objects are deeply equal.
135 * @param obj RIPEMD160MessageDigestImpl object to compare.
136 */
137 public boolean equals(Object obj){
138 //Only for performance.
139 if (this == obj) {
140 return true;
141 }
142
143 //If obj == null then instanceof returns false, see JLS 15.20.2
144 if (!(obj instanceof RIPEMD160MessageDigestImpl)) {
145 return false;
146 }
147
148 RIPEMD160MessageDigestImpl other = (RIPEMD160MessageDigestImpl) obj;
149 return this.byteCounter.equals(other.byteCounter) &&
150 this.byteBuffer.equals(other.byteBuffer) &&
151 this.wordBuffer.equals(other.wordBuffer) &&
152 this.messageDigest.equals(other.messageDigest) ;
153 }
154
155 /**
156 * Returns a hash code value for the object. This method is
157 * supported for the benefit of hashtables such as those provided by
158 * <code>java.util.Hashtable</code>.
159 *
160 * @return a hash code value for this object.
161 * @see #equals(java.lang.Object)
162 * @see java.util.Hashtable
163 */
164 public int hashCode() {
165 int result = 17;
166 result = 37*result + this.byteCounter.hashCode();
167 result = 37*result + this.byteBuffer.hashCode();
168 result = 37*result + this.wordBuffer.hashCode();
169 result = 37*result + this.messageDigest.hashCode();
170 return result;
171 }
172
173 /**
174 * Returns a string representation of the object.
175 * @return a string representation of the object.
176 */
177 public String toString()
178 {
179 String returnValue ="";
180 returnValue += "<MessageDigestBuffer: " + this.messageDigest + ">";
181 returnValue += "<WordBuffer: " + this.wordBuffer + ">";
182 returnValue += "<ByteCounter: " + this.byteCounter + ">";
183 returnValue += "<ByteBuffer: " + this.byteBuffer + ">";
184 return returnValue;
185 }
186
187 /**
188 * If the whole message added to the message digest object, you should
189 * invoke these method. Returns the 160 bit RIPEMD-160 digest as a byte
190 * array (20 Byte or 160 bit).
191 *
192 * @return the message digest in 20 byte long byte array.
193 * This byte array homes the 160 bit digest in binary form.
194 */
195 public byte[] digest() {
196
197 /* Save the length of the message in bit in long finalBitLength
198 * finalBitLength = ByteCounter * 2^3
199 *
200 * or
201 *
202 * finalBitLength = byteCounter * 8
203 *
204 * After these point any values of this.byteCounter are obsolete!!!
205 */
206 byteCounter.setFinalBitLength();
207
208 /* Message Padding:
209 * 1. We insert an 1 bit at the Message End.
210 * We do this in Byte Form, 0b10000000 == 0x80 == 128
211 *
212 */
213 update((byte)0x80);
214
215 /* Message Padding:
216 * 2. While to byteBuffer is not empty, we will fill it with 0x00 Bytes
217 * until it is full. And if it is full the byteBuffer is flushed to
218 * empty if it was full from the update method and isNotEmpty() is
219 * false and the loop finishs.
220 *
221 */
222 while(this.byteBuffer.isNotEmpty()) {
223 update((byte)0x00);
224 }
225
226
227 /* Check if there are two or more than two words free in the wordBuffer
228 * to do final Padding. If not we process the word Buffer and do the
229 * final Padding in the next 512 bit Block.
230 */
231 if (this.wordBuffer.areLessThanTwoWordsFree()) {
232 processWordBuffer();
233 }
234
235
236 /* Do final Padding at the 512 bit message block (wordBuffer)
237 *
238 *
239 */
240 this.wordBuffer.doFinalPadding(byteCounter.getFinalBitLength());
241
242 /* This is the final call of the RIPEMD-160 Algo (compress funktion),
243 * because the message is padded an the finalBitLength is inserted
244 *in the last two words of the wordBuffer
245 *
246 */
247 processWordBuffer();
248
249 return messageDigest.toByteBuffer();
250 }
251
252 /**
253 * If the whole message added to the message digest object, you should
254 * invoke these method. Returns the 160 bit RIPEMD-160 digest at a byte
255 * array (20 Byte or 160 bit ).
256 *
257 * @param buf the message digest in 20 byte long byte array.
258 * This byte array contains the 160 bit digest in binary form.
259 * @param offset begin of buffer
260 * @param len end of buffer
261 * @throws DigestException if the difference between len-offset less than
262 * 20 bytes a DigestException will be thrown.
263 * @return the length of the digest stored in the output buffer
264 */
265 public int digest(byte[] buf, int offset, int len)
266 throws DigestException {
267
268 /* The following two conditions are checked through the
269 * java.security.MessageDigest API, so we do not
270 * check they here:
271 *
272 * (buf.length < DIGEST_LENGTH)
273 * (offset + len > buf.length)
274 *
275 * Should be the Sun API changed you should add these two conditions
276 * to the if with the || operator.
277 */
278 if (len < RIPEMD160MessageDigestImpl.DIGEST_LENGTH) {
279 throw new DigestException("Buffer to less. It should be " +
280 RIPEMD160MessageDigestImpl.DIGEST_LENGTH + "." );
281 }
282
283 System.arraycopy(digest(), 0, buf, offset,
284 RIPEMD160MessageDigestImpl.DIGEST_LENGTH);
285
286 return RIPEMD160MessageDigestImpl.DIGEST_LENGTH;
287 }
288
289 /**
290 * Returns the length of the message digest in byte. In case of RIPEMD-160
291 * it will be 20.
292 * @return digest length (20)
293 */
294 public int getDigestLength() {
295 return RIPEMD160MessageDigestImpl.DIGEST_LENGTH;
296 }
297
298 /**
299 * Resets the RIPEMD160MessageDigestImpl object, for further use. So if you
300 * have calculated your digest, you should invoke reset() to reset this
301 * digest object to calculate a new digest from a new message.
302 */
303 public void reset() {
304 this.byteCounter.reset();
305 this.byteBuffer.reset();
306 this.wordBuffer.reset();
307 this.messageDigest.init(); // set the initial values h0, h1, h2, h3, h4
308 }
309
310 /**
311 * Updates the internal message buffer (byteBuffer and wordBuffer) with
312 * value.
313 *
314 * @param value message byte.
315 */
316 public void update(byte value) {
317
318 this.byteBuffer.set(value);
319
320 //this.byteCounter++;
321 this.byteCounter.inc();
322
323 if (this.byteBuffer.isFull()) {
324 processByteBuffer(); // and reset it [this.byteBuffer.reset();]
325 }
326 }
327
328 /**
329 * Updates the internal message buffer with <CODE>byte[] value</CODE>,
330 * starting at offset, ending at len.
331 * @param values message byte array.
332 * @param offset begin of message byte array.
333 * @param len end of message byte array.
334 */
335 public void update(byte[] values, int offset, int len) {
336
337 for (int i = offset; i < offset+len; i++) {
338 update(values[i]);
339 }
340 }
341
342 /**
343 * In this method the internal byteBuffer is moved with little endian
344 * byte order to next free word in the internal wordBuffer[16]. If move
345 * finished <CODE>byteBuffer.reset()</CODE> is called to reset byteBuffer.
346 */
347 private void processByteBuffer() {
348
349 this.wordBuffer.set(this.byteBuffer.toWord());
350
351 /* Oure wordBuffer is full, now we should process the compress
352 * RIPEMD-160 compress-Algo located in processWordBuffer.
353 *
354 * There will the wordBuffer be flushed with 0s (Zeros) and the
355 * compressed result will be put in the 5 messageDigest 32-bit Words!
356 */
357 if (this.wordBuffer.isFull()) {
358 processWordBuffer();
359 }
360
361 /** Reset the byteBuffer after processing
362 */
363 this.byteBuffer.reset();
364 }
365
366 /**
367 * Functions F,G,H,I,J are the five non linear functions at bit level:
368 * exor, mux, -, mux, -
369 *
370 * used in left round 1 (0 <= j <= 15); right round 5 (64 <= j <= 79)
371 * @param inX algorithm.
372 * @param inY algorithm.
373 * @param inZ algorithm.
374 * @return algorithm.
375 */
376 private static int operationF(int inX, int inY, int inZ) {
377 return inX ^ inY ^ inZ;
378 }
379
380 /**
381 * Nonlinear functions at bit level: exor, mux, -, mux, -
382 * used in left round 2 (16 <= j <= 31); right round 4 (48 <= j <= 63).
383 *
384 * @param inX algorithm.
385 * @param inY algorithm.
386 * @param inZ algorithm.
387 * @return algorithm.
388 */
389 private static int operationG(int inX, int inY, int inZ) {
390 return (inX & inY) | (~inX & inZ);
391 }
392
393 /**
394 * Non linear functions at bit level: exor, mux, -, mux, -
395 * used in left round 3 (32 <= j <= 47); right round 3 (32 <= j <= 47).
396 *
397 * @param inX algorithm.
398 * @param inY algorithm.
399 * @param inZ algorithm.
400 * @return algorithm.
401 */
402 private static int operationH(int inX, int inY, int inZ) {
403 return (inX | ~inY) ^ inZ;
404 }
405
406 /**
407 * Non linear functions at bit level: exor, mux, -, mux, -
408 * used in left round 4 (48 <= j <= 63); right round 2 (16 <= j <= 31).
409 *
410 * @param inX algorithm.
411 * @param inY algorithm.
412 * @param inZ algorithm.
413 * @return algorithm.
414 */
415 private static int operationI(int inX, int inY, int inZ) {
416 return (inX & inZ) | (inY & ~inZ);
417 }
418
419 /**
420 * Non linear functions at bit level: exor, mux, -, mux, -
421 * used in left round 5 (64 <= j <= 79); right round 2 (0 <= j <= 15).
422 * @param inX algorithm.
423 * @param inY algorithm.
424 * @param inZ algorithm.
425 * @return algorithm.
426 */
427 private static int operationJ(int inX, int inY, int inZ) {
428 return inX ^ (inY | ~inZ);
429 }
430
431 /**
432 * rotateOverLeft() rotate left Funktion (cyclic rotate left).
433 *
434 * <pre>
435 * We rotate the bits in a left order:
436 *
437 * 1. We shift the bits in the original x n positions to the left side
438 * with: x << n
439 * 2. We shift the bits in the original x 32-n positions to te right side.
440 * These are the bits, that we shift out in Step 1. We do that
441 * with: x >>> n
442 * The >>> right shift operator fills the free positions at the left
443 * side with 0 (Zero). E.g. x >>> 5 shift the bits at 5 positions to the
444 * right side and fills the 5 leftmost positions with 0 (Zero):
445 *
446 * 0b10101010101010101010101010101010 >>> 5 ==
447 * --------------------------->>>>> // >>>>> means cating these
448 * // five bits!
449 * 0b00000101010101010101010101010101
450 * ^^^^^---------------------------- // ^^^^^^ means filling these
451 * // five free positions with 0
452 * // (Zero)!
453 *
454 * The operator >>> is necessary since we don't have unsigned numeric
455 * types in Java.
456 *
457 * If we would do that with the >> shift operator the fill bit is
458 * dependend from the sign bit (the left most bit). E.g x >> 5 shift the
459 * bits at 5 positions to the right side and fills the 5 leftmost
460 * positions with 0 (Zero):
461 *
462 * 0b01010101010101010101010101010101 >> 5 ==
463 * --------------------------->>>>> // >>>>> means cating these
464 * //five bits!
465 * 0b000000101010101010101010101010101
466 * ^^^^^---------------------------- // ^^^^^^ means filling these
467 * // five free positions with 0
468 * // (Zero)! Because the leftmost
469 * // bit (sign-bit) is not set
470 * // (is set to 0)
471 *
472 * 0b10101010101010101010101010101010 >> 5 ==
473 * --------------------------->>>>> // >>>>> means cating these
474 * // five bits!
475 * 0b11111101010101010101010101010101
476 * ^^^^^---------------------------- // ^^^^^^ means filling these
477 * // five free Positions with 1
478 * // (One)! Because the leftmost bit
479 * // (sign-bit) is set (is set to 1)
480 *
481 * 3. Now we link the value from step one the value from step two together
482 * with a logical OR (|). These means our int is now organized as a ring
483 * buffer. The n leftmost bits that we lost in step one are shiftet in
484 * the right side with step two and three. E.g. (x << 5) | (x >>> (32-5))
485 *
486 * a. 0b11110000111100001111000011110000 << 5 ==
487 * 0b00011110000111100001111000000000
488 *
489 * b. 0b11110000111100001111000011110000 >>> 27 ==
490 * 0b00000000000000000000000000011110
491 * ----------------------------------
492 * a | b == 0b00011110000111100001111000011110
493 * </pre>
494 * @param in 32 bit word who will be cyclic left shifted.
495 * @param shift shift value.
496 * @return the shifted 32 bit word.
497 */
498 private static int rotateOverLeft(int in, int shift){
499 return (in << shift) | (in >>> (32-shift));
500 }
501
502 /**
503 * This is the compress method for a 512 bit block
504 * 512 bit == 16 32-bit-words or 60 bytes.
505 *
506 * This is the really RIPEMD-160 algorithm. We process the wordBuffer[16]
507 * and put the result in the MDbuf[5] (five 32 bit words) for further use
508 * through this method.
509 *
510 * There are always five rounds for the left side and five round for the
511 * right side of the RIPEMD-160 Algo. Each round contains 16 steps, wich
512 * are computed through the non linear methodes at bit level operationF(),
513 * operationG(), operationH(), operationI() and operationJ(). The five
514 * rounds on each side are independent of the rounds
515 * of the other side until after round five at each side. There will the
516 * results computed and putted in the MDbuf[5] word registers.
517 */
518 private void processWordBuffer() {
519
520 int aa = this.messageDigest.getAt(0);
521 int bb = this.messageDigest.getAt(1);
522 int cc = this.messageDigest.getAt(2);
523 int dd = this.messageDigest.getAt(3);
524 int ee = this.messageDigest.getAt(4);
525
526 int aaa = this.messageDigest.getAt(0);
527 int bbb = this.messageDigest.getAt(1);
528 int ccc = this.messageDigest.getAt(2);
529 int ddd = this.messageDigest.getAt(3);
530 int eee = this.messageDigest.getAt(4);
531
532
533 /*
534 * Left Side Processing
535 * Round 1, Steps 0-15
536 *
537 */
538 aa = rotateOverLeft(aa + operationF(bb,cc,dd) + this.wordBuffer.getAt( 0), 11) + ee;
539 cc = rotateOverLeft(cc, 10);
540
541 ee = rotateOverLeft(ee + operationF(aa,bb,cc) + this.wordBuffer.getAt( 1), 14) + dd;
542 bb = rotateOverLeft(bb, 10);
543
544 dd = rotateOverLeft(dd + operationF(ee,aa,bb) + this.wordBuffer.getAt( 2), 15) + cc;
545 aa = rotateOverLeft(aa, 10);
546
547 cc = rotateOverLeft(cc + operationF(dd,ee,aa) + this.wordBuffer.getAt( 3), 12) + bb;
548 ee = rotateOverLeft(ee, 10);
549
550 bb = rotateOverLeft(bb + operationF(cc,dd,ee) + this.wordBuffer.getAt( 4), 5) + aa;
551 dd = rotateOverLeft(dd, 10);
552
553 aa = rotateOverLeft(aa + operationF(bb,cc,dd) + this.wordBuffer.getAt( 5), 8) + ee;
554 cc = rotateOverLeft(cc, 10);
555
556 ee = rotateOverLeft(ee + operationF(aa,bb,cc) + this.wordBuffer.getAt( 6), 7) + dd;
557 bb = rotateOverLeft(bb, 10);
558
559 dd = rotateOverLeft(dd + operationF(ee,aa,bb) + this.wordBuffer.getAt( 7), 9) + cc;
560 aa = rotateOverLeft(aa, 10);
561
562 cc = rotateOverLeft(cc + operationF(dd,ee,aa) + this.wordBuffer.getAt( 8), 11) + bb;
563 ee = rotateOverLeft(ee, 10);
564
565 bb = rotateOverLeft(bb + operationF(cc,dd,ee) + this.wordBuffer.getAt( 9), 13) + aa;
566 dd = rotateOverLeft(dd, 10);
567
568 aa = rotateOverLeft(aa + operationF(bb,cc,dd) + this.wordBuffer.getAt(10), 14) + ee;
569 cc = rotateOverLeft(cc, 10);
570
571 ee = rotateOverLeft(ee + operationF(aa,bb,cc) + this.wordBuffer.getAt(11), 15) + dd;
572 bb = rotateOverLeft(bb, 10);
573
574 dd = rotateOverLeft(dd + operationF(ee,aa,bb) + this.wordBuffer.getAt(12), 6) + cc;
575 aa = rotateOverLeft(aa, 10);
576
577 cc = rotateOverLeft(cc + operationF(dd,ee,aa) + this.wordBuffer.getAt(13), 7) + bb;
578 ee = rotateOverLeft(ee, 10);
579
580 bb = rotateOverLeft(bb + operationF(cc,dd,ee) + this.wordBuffer.getAt(14), 9) + aa;
581 dd = rotateOverLeft(dd, 10);
582
583 aa = rotateOverLeft(aa + operationF(bb,cc,dd) + this.wordBuffer.getAt(15), 8) + ee;
584 cc = rotateOverLeft(cc, 10);
585
586
587 /*
588 * Left Side Processing
589 * Round 2, Steps 16-31
590 *
591 */
592 ee = rotateOverLeft(ee + operationG(aa,bb,cc) + this.wordBuffer.getAt( 7) + 0x5a827999, 7) + dd;
593 bb = rotateOverLeft(bb, 10);
594
595 dd = rotateOverLeft(dd + operationG(ee,aa,bb) + this.wordBuffer.getAt( 4) + 0x5a827999, 6) + cc;
596 aa = rotateOverLeft(aa, 10);
597
598 cc = rotateOverLeft(cc + operationG(dd,ee,aa) + this.wordBuffer.getAt(13) + 0x5a827999, 8) + bb;
599 ee = rotateOverLeft(ee, 10);
600
601 bb = rotateOverLeft(bb + operationG(cc,dd,ee) + this.wordBuffer.getAt( 1) + 0x5a827999, 13) + aa;
602 dd = rotateOverLeft(dd, 10);
603
604 aa = rotateOverLeft(aa + operationG(bb,cc,dd) + this.wordBuffer.getAt(10) + 0x5a827999, 11) + ee;
605 cc = rotateOverLeft(cc, 10);
606
607 ee = rotateOverLeft(ee + operationG(aa,bb,cc) + this.wordBuffer.getAt( 6) + 0x5a827999, 9) + dd;
608 bb = rotateOverLeft(bb, 10);
609
610 dd = rotateOverLeft(dd + operationG(ee,aa,bb) + this.wordBuffer.getAt(15) + 0x5a827999, 7) + cc;
611 aa = rotateOverLeft(aa, 10);
612
613 cc = rotateOverLeft(cc + operationG(dd,ee,aa) + this.wordBuffer.getAt( 3) + 0x5a827999, 15) + bb;
614 ee = rotateOverLeft(ee, 10);
615
616 bb = rotateOverLeft(bb + operationG(cc,dd,ee) + this.wordBuffer.getAt(12) + 0x5a827999, 7) + aa;
617 dd = rotateOverLeft(dd, 10);
618
619 aa = rotateOverLeft(aa + operationG(bb,cc,dd) + this.wordBuffer.getAt( 0) + 0x5a827999, 12) + ee;
620 cc = rotateOverLeft(cc, 10);
621
622 ee = rotateOverLeft(ee + operationG(aa,bb,cc) + this.wordBuffer.getAt( 9) + 0x5a827999, 15) + dd;
623 bb = rotateOverLeft(bb, 10);
624
625 dd = rotateOverLeft(dd + operationG(ee,aa,bb) + this.wordBuffer.getAt( 5) + 0x5a827999, 9) + cc;
626 aa = rotateOverLeft(aa, 10);
627
628 cc = rotateOverLeft(cc + operationG(dd,ee,aa) + this.wordBuffer.getAt( 2) + 0x5a827999, 11) + bb;
629 ee = rotateOverLeft(ee, 10);
630
631 bb = rotateOverLeft(bb + operationG(cc,dd,ee) + this.wordBuffer.getAt(14) + 0x5a827999, 7) + aa;
632 dd = rotateOverLeft(dd, 10);
633
634 aa = rotateOverLeft(aa + operationG(bb,cc,dd) + this.wordBuffer.getAt(11) + 0x5a827999, 13) + ee;
635 cc = rotateOverLeft(cc, 10);
636
637 ee = rotateOverLeft(ee + operationG(aa,bb,cc) + this.wordBuffer.getAt( 8) + 0x5a827999, 12) + dd;
638 bb = rotateOverLeft(bb, 10);
639
640
641 /*
642 * Left Side Processing
643 * Round 3, Steps 32-37
644 *
645 */
646 dd = rotateOverLeft(dd + operationH(ee,aa,bb) + this.wordBuffer.getAt( 3) + 0x6ed9eba1, 11) + cc;
647 aa = rotateOverLeft(aa, 10);
648
649 cc = rotateOverLeft(cc + operationH(dd,ee,aa) + this.wordBuffer.getAt(10) + 0x6ed9eba1, 13) + bb;
650 ee = rotateOverLeft(ee, 10);
651
652 bb = rotateOverLeft(bb + operationH(cc,dd,ee) + this.wordBuffer.getAt(14) + 0x6ed9eba1, 6) + aa;
653 dd = rotateOverLeft(dd, 10);
654
655 aa = rotateOverLeft(aa + operationH(bb,cc,dd) + this.wordBuffer.getAt( 4) + 0x6ed9eba1, 7) + ee;
656 cc = rotateOverLeft(cc, 10);
657
658 ee = rotateOverLeft(ee + operationH(aa,bb,cc) + this.wordBuffer.getAt( 9) + 0x6ed9eba1, 14) + dd;
659 bb = rotateOverLeft(bb, 10);
660
661 dd = rotateOverLeft(dd + operationH(ee,aa,bb) + this.wordBuffer.getAt(15) + 0x6ed9eba1, 9) + cc;
662 aa = rotateOverLeft(aa, 10);
663
664 cc = rotateOverLeft(cc + operationH(dd,ee,aa) + this.wordBuffer.getAt( 8) + 0x6ed9eba1, 13) + bb;
665 ee = rotateOverLeft(ee, 10);
666
667 bb = rotateOverLeft(bb + operationH(cc,dd,ee) + this.wordBuffer.getAt( 1) + 0x6ed9eba1, 15) + aa;
668 dd = rotateOverLeft(dd, 10);
669
670 aa = rotateOverLeft(aa + operationH(bb,cc,dd) + this.wordBuffer.getAt( 2) + 0x6ed9eba1, 14) + ee;
671 cc = rotateOverLeft(cc, 10);
672
673 ee = rotateOverLeft(ee + operationH(aa,bb,cc) + this.wordBuffer.getAt( 7) + 0x6ed9eba1, 8) + dd;
674 bb = rotateOverLeft(bb, 10);
675
676 dd = rotateOverLeft(dd + operationH(ee,aa,bb) + this.wordBuffer.getAt( 0) + 0x6ed9eba1, 13) + cc;
677 aa = rotateOverLeft(aa, 10);
678
679 cc = rotateOverLeft(cc + operationH(dd,ee,aa) + this.wordBuffer.getAt( 6) + 0x6ed9eba1, 6) + bb;
680 ee = rotateOverLeft(ee, 10);
681
682 bb = rotateOverLeft(bb + operationH(cc,dd,ee) + this.wordBuffer.getAt(13) + 0x6ed9eba1, 5) + aa;
683 dd = rotateOverLeft(dd, 10);
684
685 aa = rotateOverLeft(aa + operationH(bb,cc,dd) + this.wordBuffer.getAt(11) + 0x6ed9eba1, 12) + ee;
686 cc = rotateOverLeft(cc, 10);
687
688 ee = rotateOverLeft(ee + operationH(aa,bb,cc) + this.wordBuffer.getAt( 5) + 0x6ed9eba1, 7) + dd;
689 bb = rotateOverLeft(bb, 10);
690
691 dd = rotateOverLeft(dd + operationH(ee,aa,bb) + this.wordBuffer.getAt(12) + 0x6ed9eba1, 5) + cc;
692 aa = rotateOverLeft(aa, 10);
693
694
695 /*
696 * Left Side Processing
697 * Rounds 4, Step 48-67
698 *
699 */
700 cc = rotateOverLeft(cc + operationI(dd,ee,aa) + this.wordBuffer.getAt( 1) + 0x8f1bbcdc, 11) + bb;
701 ee = rotateOverLeft(ee, 10);
702
703 bb = rotateOverLeft(bb + operationI(cc,dd,ee) + this.wordBuffer.getAt( 9) + 0x8f1bbcdc, 12) + aa;
704 dd = rotateOverLeft(dd, 10);
705
706 aa = rotateOverLeft(aa + operationI(bb,cc,dd) + this.wordBuffer.getAt(11) + 0x8f1bbcdc, 14) + ee;
707 cc = rotateOverLeft(cc, 10);
708
709 ee = rotateOverLeft(ee + operationI(aa,bb,cc) + this.wordBuffer.getAt(10) + 0x8f1bbcdc, 15) + dd;
710 bb = rotateOverLeft(bb, 10);
711
712 dd = rotateOverLeft(dd + operationI(ee,aa,bb) + this.wordBuffer.getAt( 0) + 0x8f1bbcdc, 14) + cc;
713 aa = rotateOverLeft(aa, 10);
714
715 cc = rotateOverLeft(cc + operationI(dd,ee,aa) + this.wordBuffer.getAt( 8) + 0x8f1bbcdc, 15) + bb;
716 ee = rotateOverLeft(ee, 10);
717
718 bb = rotateOverLeft(bb + operationI(cc,dd,ee) + this.wordBuffer.getAt(12) + 0x8f1bbcdc, 9) + aa;
719 dd = rotateOverLeft(dd, 10);
720
721 aa = rotateOverLeft(aa + operationI(bb,cc,dd) + this.wordBuffer.getAt( 4) + 0x8f1bbcdc, 8) + ee;
722 cc = rotateOverLeft(cc, 10);
723
724 ee = rotateOverLeft(ee + operationI(aa,bb,cc) + this.wordBuffer.getAt(13) + 0x8f1bbcdc, 9) + dd;
725 bb = rotateOverLeft(bb, 10);
726
727 dd = rotateOverLeft(dd + operationI(ee,aa,bb) + this.wordBuffer.getAt( 3) + 0x8f1bbcdc, 14) + cc;
728 aa = rotateOverLeft(aa, 10);
729
730 cc = rotateOverLeft(cc + operationI(dd,ee,aa) + this.wordBuffer.getAt( 7) + 0x8f1bbcdc, 5) + bb;
731 ee = rotateOverLeft(ee, 10);
732
733 bb = rotateOverLeft(bb + operationI(cc,dd,ee) + this.wordBuffer.getAt(15) + 0x8f1bbcdc, 6) + aa;
734 dd = rotateOverLeft(dd, 10);
735
736 aa = rotateOverLeft(aa + operationI(bb,cc,dd) + this.wordBuffer.getAt(14) + 0x8f1bbcdc, 8) + ee;
737 cc = rotateOverLeft(cc, 10);
738
739 ee = rotateOverLeft(ee + operationI(aa,bb,cc) + this.wordBuffer.getAt( 5) + 0x8f1bbcdc, 6) + dd;
740 bb = rotateOverLeft(bb, 10);
741
742 dd = rotateOverLeft(dd + operationI(ee,aa,bb) + this.wordBuffer.getAt( 6) + 0x8f1bbcdc, 5) + cc;
743 aa = rotateOverLeft(aa, 10);
744
745 cc = rotateOverLeft(cc + operationI(dd,ee,aa) + this.wordBuffer.getAt( 2) + 0x8f1bbcdc, 12) + bb;
746 ee = rotateOverLeft(ee, 10);
747
748
749 /*
750 * Left Side Processing
751 * Rounds 5, Step 64-79
752 *
753 */
754 bb = rotateOverLeft(bb + operationJ(cc,dd,ee) + this.wordBuffer.getAt( 4) + 0xa953fd4e, 9) + aa;
755 dd = rotateOverLeft(dd, 10);
756
757 aa = rotateOverLeft(aa + operationJ(bb,cc,dd) + this.wordBuffer.getAt( 0) + 0xa953fd4e, 15) + ee;
758 cc = rotateOverLeft(cc, 10);
759
760 ee = rotateOverLeft(ee + operationJ(aa,bb,cc) + this.wordBuffer.getAt( 5) + 0xa953fd4e, 5) + dd;
761 bb = rotateOverLeft(bb, 10);
762
763 dd = rotateOverLeft(dd + operationJ(ee,aa,bb) + this.wordBuffer.getAt( 9) + 0xa953fd4e, 11) + cc;
764 aa = rotateOverLeft(aa, 10);
765
766 cc = rotateOverLeft(cc + operationJ(dd,ee,aa) + this.wordBuffer.getAt( 7) + 0xa953fd4e, 6) + bb;
767 ee = rotateOverLeft(ee, 10);
768
769 bb = rotateOverLeft(bb + operationJ(cc,dd,ee) + this.wordBuffer.getAt(12) + 0xa953fd4e, 8) + aa;
770 dd = rotateOverLeft(dd, 10);
771
772 aa = rotateOverLeft(aa + operationJ(bb,cc,dd) + this.wordBuffer.getAt( 2) + 0xa953fd4e, 13) + ee;
773 cc = rotateOverLeft(cc, 10);
774
775 ee = rotateOverLeft(ee + operationJ(aa,bb,cc) + this.wordBuffer.getAt(10) + 0xa953fd4e, 12) + dd;
776 bb = rotateOverLeft(bb, 10);
777
778 dd = rotateOverLeft(dd + operationJ(ee,aa,bb) + this.wordBuffer.getAt(14) + 0xa953fd4e, 5) + cc;
779 aa = rotateOverLeft(aa, 10);
780
781 cc = rotateOverLeft(cc + operationJ(dd,ee,aa) + this.wordBuffer.getAt( 1) + 0xa953fd4e, 12) + bb;
782 ee = rotateOverLeft(ee, 10);
783
784 bb = rotateOverLeft(bb + operationJ(cc,dd,ee) + this.wordBuffer.getAt( 3) + 0xa953fd4e, 13) + aa;
785 dd = rotateOverLeft(dd, 10);
786
787 aa = rotateOverLeft(aa + operationJ(bb,cc,dd) + this.wordBuffer.getAt( 8) + 0xa953fd4e, 14) + ee;
788 cc = rotateOverLeft(cc, 10);
789
790 ee = rotateOverLeft(ee + operationJ(aa,bb,cc) + this.wordBuffer.getAt(11) + 0xa953fd4e, 11) + dd;
791 bb = rotateOverLeft(bb, 10);
792
793 dd = rotateOverLeft(dd + operationJ(ee,aa,bb) + this.wordBuffer.getAt( 6) + 0xa953fd4e, 8) + cc;
794 aa = rotateOverLeft(aa, 10);
795
796 cc = rotateOverLeft(cc + operationJ(dd,ee,aa) + this.wordBuffer.getAt(15) + 0xa953fd4e, 5) + bb;
797 ee = rotateOverLeft(ee, 10);
798
799 bb = rotateOverLeft(bb + operationJ(cc,dd,ee) + this.wordBuffer.getAt(13) + 0xa953fd4e, 6) + aa;
800 dd = rotateOverLeft(dd, 10);
801
802
803
804 /*
805 * Right Side Processing
806 * Round 1, Steps 0-15
807 *
808 */
809 aaa = rotateOverLeft(aaa + operationJ(bbb,ccc,ddd) + this.wordBuffer.getAt( 5) + 0x50a28be6, 8) + eee;
810 ccc = rotateOverLeft(ccc, 10);
811
812 eee = rotateOverLeft(eee + operationJ(aaa,bbb,ccc) + this.wordBuffer.getAt(14) + 0x50a28be6, 9) + ddd;
813 bbb = rotateOverLeft(bbb, 10);
814
815 ddd = rotateOverLeft(ddd + operationJ(eee,aaa,bbb) + this.wordBuffer.getAt( 7) + 0x50a28be6, 9) + ccc;
816 aaa = rotateOverLeft(aaa, 10);
817
818 ccc = rotateOverLeft(ccc + operationJ(ddd,eee,aaa) + this.wordBuffer.getAt( 0) + 0x50a28be6, 11) + bbb;
819 eee = rotateOverLeft(eee, 10);
820
821 bbb = rotateOverLeft(bbb + operationJ(ccc,ddd,eee) + this.wordBuffer.getAt( 9) + 0x50a28be6, 13) + aaa;
822 ddd = rotateOverLeft(ddd, 10);
823
824 aaa = rotateOverLeft(aaa + operationJ(bbb,ccc,ddd) + this.wordBuffer.getAt( 2) + 0x50a28be6, 15) + eee;
825 ccc = rotateOverLeft(ccc, 10);
826
827 eee = rotateOverLeft(eee + operationJ(aaa,bbb,ccc) + this.wordBuffer.getAt(11) + 0x50a28be6, 15) + ddd;
828 bbb = rotateOverLeft(bbb, 10);
829
830 ddd = rotateOverLeft(ddd + operationJ(eee,aaa,bbb) + this.wordBuffer.getAt( 4) + 0x50a28be6, 5) + ccc;
831 aaa = rotateOverLeft(aaa, 10);
832
833 ccc = rotateOverLeft(ccc + operationJ(ddd,eee,aaa) + this.wordBuffer.getAt(13) + 0x50a28be6, 7) + bbb;
834 eee = rotateOverLeft(eee, 10);
835
836 bbb = rotateOverLeft(bbb + operationJ(ccc,ddd,eee) + this.wordBuffer.getAt( 6) + 0x50a28be6, 7) + aaa;
837 ddd = rotateOverLeft(ddd, 10);
838
839 aaa = rotateOverLeft(aaa + operationJ(bbb,ccc,ddd) + this.wordBuffer.getAt(15) + 0x50a28be6, 8) + eee;
840 ccc = rotateOverLeft(ccc, 10);
841
842 eee = rotateOverLeft(eee + operationJ(aaa,bbb,ccc) + this.wordBuffer.getAt( 8) + 0x50a28be6, 11) + ddd;
843 bbb = rotateOverLeft(bbb, 10);
844
845 ddd = rotateOverLeft(ddd + operationJ(eee,aaa,bbb) + this.wordBuffer.getAt( 1) + 0x50a28be6, 14) + ccc;
846 aaa = rotateOverLeft(aaa, 10);
847
848 ccc = rotateOverLeft(ccc + operationJ(ddd,eee,aaa) + this.wordBuffer.getAt(10) + 0x50a28be6, 14) + bbb;
849 eee = rotateOverLeft(eee, 10);
850
851 bbb = rotateOverLeft(bbb + operationJ(ccc,ddd,eee) + this.wordBuffer.getAt( 3) + 0x50a28be6, 12) + aaa;
852 ddd = rotateOverLeft(ddd, 10);
853
854 aaa = rotateOverLeft(aaa + operationJ(bbb,ccc,ddd) + this.wordBuffer.getAt(12) + 0x50a28be6, 6) + eee;
855 ccc = rotateOverLeft(ccc, 10);
856
857
858 /*
859 * Left Side Processing
860 * Round 2, Steps 16-31
861 *
862 */
863 eee = rotateOverLeft(eee + operationI(aaa,bbb,ccc) + this.wordBuffer.getAt( 6) + 0x5c4dd124, 9) + ddd;
864 bbb = rotateOverLeft(bbb, 10);
865
866 ddd = rotateOverLeft(ddd + operationI(eee,aaa,bbb) + this.wordBuffer.getAt(11) + 0x5c4dd124, 13) + ccc;
867 aaa = rotateOverLeft(aaa, 10);
868
869 ccc = rotateOverLeft(ccc + operationI(ddd,eee,aaa) + this.wordBuffer.getAt( 3) + 0x5c4dd124, 15) + bbb;
870 eee = rotateOverLeft(eee, 10);
871
872 bbb = rotateOverLeft(bbb + operationI(ccc,ddd,eee) + this.wordBuffer.getAt( 7) + 0x5c4dd124, 7) + aaa;
873 ddd = rotateOverLeft(ddd, 10);
874
875 aaa = rotateOverLeft(aaa + operationI(bbb,ccc,ddd) + this.wordBuffer.getAt( 0) + 0x5c4dd124, 12) + eee;
876 ccc = rotateOverLeft(ccc, 10);
877
878 eee = rotateOverLeft(eee + operationI(aaa,bbb,ccc) + this.wordBuffer.getAt(13) + 0x5c4dd124, 8) + ddd;
879 bbb = rotateOverLeft(bbb, 10);
880
881 ddd = rotateOverLeft(ddd + operationI(eee,aaa,bbb) + this.wordBuffer.getAt( 5) + 0x5c4dd124, 9) + ccc;
882 aaa = rotateOverLeft(aaa, 10);
883
884 ccc = rotateOverLeft(ccc + operationI(ddd,eee,aaa) + this.wordBuffer.getAt(10) + 0x5c4dd124, 11) + bbb;
885 eee = rotateOverLeft(eee, 10);
886
887 bbb = rotateOverLeft(bbb + operationI(ccc,ddd,eee) + this.wordBuffer.getAt(14) + 0x5c4dd124, 7) + aaa;
888 ddd = rotateOverLeft(ddd, 10);
889
890 aaa = rotateOverLeft(aaa + operationI(bbb,ccc,ddd) + this.wordBuffer.getAt(15) + 0x5c4dd124, 7) + eee;
891 ccc = rotateOverLeft(ccc, 10);
892
893 eee = rotateOverLeft(eee + operationI(aaa,bbb,ccc) + this.wordBuffer.getAt( 8) + 0x5c4dd124, 12) + ddd;
894 bbb = rotateOverLeft(bbb, 10);
895
896 ddd = rotateOverLeft(ddd + operationI(eee,aaa,bbb) + this.wordBuffer.getAt(12) + 0x5c4dd124, 7) + ccc;
897 aaa = rotateOverLeft(aaa, 10);
898
899 ccc = rotateOverLeft(ccc + operationI(ddd,eee,aaa) + this.wordBuffer.getAt( 4) + 0x5c4dd124, 6) + bbb;
900 eee = rotateOverLeft(eee, 10);
901
902 bbb = rotateOverLeft(bbb + operationI(ccc,ddd,eee) + this.wordBuffer.getAt( 9) + 0x5c4dd124, 15) + aaa;
903 ddd = rotateOverLeft(ddd, 10);
904
905 aaa = rotateOverLeft(aaa + operationI(bbb,ccc,ddd) + this.wordBuffer.getAt( 1) + 0x5c4dd124, 13) + eee;
906 ccc = rotateOverLeft(ccc, 10);
907
908 eee = rotateOverLeft(eee + operationI(aaa,bbb,ccc) + this.wordBuffer.getAt( 2) + 0x5c4dd124, 11) + ddd;
909 bbb = rotateOverLeft(bbb, 10);
910
911
912 /*
913 * Left Side Processing
914 * Round 3, Steps 32-47
915 *
916 */
917 ddd = rotateOverLeft(ddd + operationH(eee,aaa,bbb) + this.wordBuffer.getAt(15) + 0x6d703ef3, 9) + ccc;
918 aaa = rotateOverLeft(aaa, 10);
919
920 ccc = rotateOverLeft(ccc + operationH(ddd,eee,aaa) + this.wordBuffer.getAt( 5) + 0x6d703ef3, 7) + bbb;
921 eee = rotateOverLeft(eee, 10);
922
923 bbb = rotateOverLeft(bbb + operationH(ccc,ddd,eee) + this.wordBuffer.getAt( 1) + 0x6d703ef3, 15) + aaa;
924 ddd = rotateOverLeft(ddd, 10);
925
926 aaa = rotateOverLeft(aaa + operationH(bbb,ccc,ddd) + this.wordBuffer.getAt( 3) + 0x6d703ef3, 11) + eee;
927 ccc = rotateOverLeft(ccc, 10);
928
929 eee = rotateOverLeft(eee + operationH(aaa,bbb,ccc) + this.wordBuffer.getAt( 7) + 0x6d703ef3, 8) + ddd;
930 bbb = rotateOverLeft(bbb, 10);
931
932 ddd = rotateOverLeft(ddd + operationH(eee,aaa,bbb) + this.wordBuffer.getAt(14) + 0x6d703ef3, 6) + ccc;
933 aaa = rotateOverLeft(aaa, 10);
934
935 ccc = rotateOverLeft(ccc + operationH(ddd,eee,aaa) + this.wordBuffer.getAt( 6) + 0x6d703ef3, 6) + bbb;
936 eee = rotateOverLeft(eee, 10);
937
938 bbb = rotateOverLeft(bbb + operationH(ccc,ddd,eee) + this.wordBuffer.getAt( 9) + 0x6d703ef3, 14) + aaa;
939 ddd = rotateOverLeft(ddd, 10);
940
941 aaa = rotateOverLeft(aaa + operationH(bbb,ccc,ddd) + this.wordBuffer.getAt(11) + 0x6d703ef3, 12) + eee;
942 ccc = rotateOverLeft(ccc, 10);
943
944 eee = rotateOverLeft(eee + operationH(aaa,bbb,ccc) + this.wordBuffer.getAt( 8) + 0x6d703ef3, 13) + ddd;
945 bbb = rotateOverLeft(bbb, 10);
946
947 ddd = rotateOverLeft(ddd + operationH(eee,aaa,bbb) + this.wordBuffer.getAt(12) + 0x6d703ef3, 5) + ccc;
948 aaa = rotateOverLeft(aaa, 10);
949
950 ccc = rotateOverLeft(ccc + operationH(ddd,eee,aaa) + this.wordBuffer.getAt( 2) + 0x6d703ef3, 14) + bbb;
951 eee = rotateOverLeft(eee, 10);
952
953 bbb = rotateOverLeft(bbb + operationH(ccc,ddd,eee) + this.wordBuffer.getAt(10) + 0x6d703ef3, 13) + aaa;
954 ddd = rotateOverLeft(ddd, 10);
955
956 aaa = rotateOverLeft(aaa + operationH(bbb,ccc,ddd) + this.wordBuffer.getAt( 0) + 0x6d703ef3, 13) + eee;
957 ccc = rotateOverLeft(ccc, 10);
958
959 eee = rotateOverLeft(eee + operationH(aaa,bbb,ccc) + this.wordBuffer.getAt( 4) + 0x6d703ef3, 7) + ddd;
960 bbb = rotateOverLeft(bbb, 10);
961
962 ddd = rotateOverLeft(ddd + operationH(eee,aaa,bbb) + this.wordBuffer.getAt(13) + 0x6d703ef3, 5) + ccc;
963 aaa = rotateOverLeft(aaa, 10);
964
965
966 /*
967 * Left Side Processing
968 * Round 4, Steps 48-63
969 *
970 */
971 ccc = rotateOverLeft(ccc + operationG(ddd,eee,aaa) + this.wordBuffer.getAt( 8) + 0x7a6d76e9, 15) + bbb;
972 eee = rotateOverLeft(eee, 10);
973
974 bbb = rotateOverLeft(bbb + operationG(ccc,ddd,eee) + this.wordBuffer.getAt( 6) + 0x7a6d76e9, 5) + aaa;
975 ddd = rotateOverLeft(ddd, 10);
976
977 aaa = rotateOverLeft(aaa + operationG(bbb,ccc,ddd) + this.wordBuffer.getAt( 4) + 0x7a6d76e9, 8) + eee;
978 ccc = rotateOverLeft(ccc, 10);
979
980 eee = rotateOverLeft(eee + operationG(aaa,bbb,ccc) + this.wordBuffer.getAt( 1) + 0x7a6d76e9, 11) + ddd;
981 bbb = rotateOverLeft(bbb, 10);
982
983 ddd = rotateOverLeft(ddd + operationG(eee,aaa,bbb) + this.wordBuffer.getAt( 3) + 0x7a6d76e9, 14) + ccc;
984 aaa = rotateOverLeft(aaa, 10);
985
986 ccc = rotateOverLeft(ccc + operationG(ddd,eee,aaa) + this.wordBuffer.getAt(11) + 0x7a6d76e9, 14) + bbb;
987 eee = rotateOverLeft(eee, 10);
988
989 bbb = rotateOverLeft(bbb + operationG(ccc,ddd,eee) + this.wordBuffer.getAt(15) + 0x7a6d76e9, 6) + aaa;
990 ddd = rotateOverLeft(ddd, 10);
991
992 aaa = rotateOverLeft(aaa + operationG(bbb,ccc,ddd) + this.wordBuffer.getAt( 0) + 0x7a6d76e9, 14) + eee;
993 ccc = rotateOverLeft(ccc, 10);
994
995 eee = rotateOverLeft(eee + operationG(aaa,bbb,ccc) + this.wordBuffer.getAt( 5) + 0x7a6d76e9, 6) + ddd;
996 bbb = rotateOverLeft(bbb, 10);
997
998 ddd = rotateOverLeft(ddd + operationG(eee,aaa,bbb) + this.wordBuffer.getAt(12) + 0x7a6d76e9, 9) + ccc;
999 aaa = rotateOverLeft(aaa, 10);
1000
1001 ccc = rotateOverLeft(ccc + operationG(ddd,eee,aaa) + this.wordBuffer.getAt( 2) + 0x7a6d76e9, 12) + bbb;
1002 eee = rotateOverLeft(eee, 10);
1003
1004 bbb = rotateOverLeft(bbb + operationG(ccc,ddd,eee) + this.wordBuffer.getAt(13) + 0x7a6d76e9, 9) + aaa;
1005 ddd = rotateOverLeft(ddd, 10);
1006
1007 aaa = rotateOverLeft(aaa + operationG(bbb,ccc,ddd) + this.wordBuffer.getAt( 9) + 0x7a6d76e9, 12) + eee;
1008 ccc = rotateOverLeft(ccc, 10);
1009
1010 eee = rotateOverLeft(eee + operationG(aaa,bbb,ccc) + this.wordBuffer.getAt( 7) + 0x7a6d76e9, 5) + ddd;
1011 bbb = rotateOverLeft(bbb, 10);
1012
1013 ddd = rotateOverLeft(ddd + operationG(eee,aaa,bbb) + this.wordBuffer.getAt(10) + 0x7a6d76e9, 15) + ccc;
1014 aaa = rotateOverLeft(aaa, 10);
1015
1016 ccc = rotateOverLeft(ccc + operationG(ddd,eee,aaa) + this.wordBuffer.getAt(14) + 0x7a6d76e9, 8) + bbb;
1017 eee = rotateOverLeft(eee, 10);
1018
1019
1020 /*
1021 * Left Side Processing
1022 * Round 5, Steps 64-79
1023 *
1024 */
1025 bbb = rotateOverLeft(bbb + operationF(ccc,ddd,eee) + this.wordBuffer.getAt(12), 8) + aaa;
1026 ddd = rotateOverLeft(ddd, 10);
1027
1028 aaa = rotateOverLeft(aaa + operationF(bbb,ccc,ddd) + this.wordBuffer.getAt(15), 5) + eee;
1029 ccc = rotateOverLeft(ccc, 10);
1030
1031 eee = rotateOverLeft(eee + operationF(aaa,bbb,ccc) + this.wordBuffer.getAt(10), 12) + ddd;
1032 bbb = rotateOverLeft(bbb, 10);
1033
1034 ddd = rotateOverLeft(ddd + operationF(eee,aaa,bbb) + this.wordBuffer.getAt( 4), 9) + ccc;
1035 aaa = rotateOverLeft(aaa, 10);
1036
1037 ccc = rotateOverLeft(ccc + operationF(ddd,eee,aaa) + this.wordBuffer.getAt( 1), 12) + bbb;
1038 eee = rotateOverLeft(eee, 10);
1039
1040 bbb = rotateOverLeft(bbb + operationF(ccc,ddd,eee) + this.wordBuffer.getAt( 5), 5) + aaa;
1041 ddd = rotateOverLeft(ddd, 10);
1042
1043 aaa = rotateOverLeft(aaa + operationF(bbb,ccc,ddd) + this.wordBuffer.getAt( 8), 14) + eee;
1044 ccc = rotateOverLeft(ccc, 10);
1045
1046 eee = rotateOverLeft(eee + operationF(aaa,bbb,ccc) + this.wordBuffer.getAt( 7), 6) + ddd;
1047 bbb = rotateOverLeft(bbb, 10);
1048
1049 ddd = rotateOverLeft(ddd + operationF(eee,aaa,bbb) + this.wordBuffer.getAt( 6), 8) + ccc;
1050 aaa = rotateOverLeft(aaa, 10);
1051
1052 ccc = rotateOverLeft(ccc + operationF(ddd,eee,aaa) + this.wordBuffer.getAt( 2), 13) + bbb;
1053 eee = rotateOverLeft(eee, 10);
1054
1055 bbb = rotateOverLeft(bbb + operationF(ccc,ddd,eee) + this.wordBuffer.getAt(13), 6) + aaa;
1056 ddd = rotateOverLeft(ddd, 10);
1057
1058 aaa = rotateOverLeft(aaa + operationF(bbb,ccc,ddd) + this.wordBuffer.getAt(14), 5) + eee;
1059 ccc = rotateOverLeft(ccc, 10);
1060
1061 eee = rotateOverLeft(eee + operationF(aaa,bbb,ccc) + this.wordBuffer.getAt( 0), 15) + ddd;
1062 bbb = rotateOverLeft(bbb, 10);
1063
1064 ddd = rotateOverLeft(ddd + operationF(eee,aaa,bbb) + this.wordBuffer.getAt( 3), 13) + ccc;
1065 aaa = rotateOverLeft(aaa, 10);
1066
1067 ccc = rotateOverLeft(ccc + operationF(ddd,eee,aaa) + this.wordBuffer.getAt( 9), 11) + bbb;
1068 eee = rotateOverLeft(eee, 10);
1069
1070 bbb = rotateOverLeft(bbb + operationF(ccc,ddd,eee) + this.wordBuffer.getAt(11), 11) + aaa;
1071 ddd = rotateOverLeft(ddd, 10);
1072
1073
1074 /* Put the result from the left and right side of the RIPMD-160 Algo
1075 * together.
1076 *
1077 * The compressed results from the wordBuffer, now are added to
1078 * results or IVs in the messageDigest 32 bit register. It can happend
1079 * that the five internal 32 bit registers (int) overflow, but this is
1080 * part of the Algo and is no problem.
1081 */
1082 ddd += cc + this.messageDigest.getAt(1); // final result for MDbuf[0]
1083 this.messageDigest.setAt(1, this.messageDigest.getAt(2) + dd + eee);
1084 this.messageDigest.setAt(2, this.messageDigest.getAt(3) + ee + aaa);
1085 this.messageDigest.setAt(3, this.messageDigest.getAt(4) + aa + bbb);
1086 this.messageDigest.setAt(4, this.messageDigest.getAt(0) + bb + ccc);
1087 this.messageDigest.setAt(0, ddd);
1088
1089
1090 /*
1091 * At these point we reset the this.wordBuffer
1092 */
1093 this.wordBuffer.reset();
1094 }
1095}
1096
|
RIPEMD160MessageDigestImpl |
|