|
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 |
|