/* @(#)SHA1.java 1.11 2004-04-26 * This file was freely contributed to the LimeWire project and is covered * by its existing GPL licence, but it may be used individually as a public * domain implementation of a published algorithm (see below for references). * It was also freely contributed to the Bitzi public domain sources. * @author Philippe Verdy */ /* Sun may wish to change the following package name, if integrating this * class in the Sun JCE Security Provider for Java 1.5 (code-named Tiger). * * You can include it in your own Security Provider by inserting * this property in your Provider derived class: * put("MessageDigest.SHA-1", "com.limegroup.gnutella.security.SHA1"); */ package com.limegroup.gnutella.security; import java.security.DigestException; import java.security.MessageDigest; //--+---+1--+---+--2+---+---+3--+---+--4+---+---+5--+---+--6+---+---+7--+---+-- //34567890123456789012345678901234567890123456789012345678901234567890123456789 /** * <p>The FIPS PUB 180-2 standard specifies four secure hash algorithms (SHA-1, * SHA-256, SHA-384 and SHA-512) for computing a condensed representation of * electronic data (message). When a message of any length < 2^^64 bits (for * SHA-1 and SHA-256) or < 2^^128 bits (for SHA-384 and SHA-512) is input to * an algorithm, the result is an output called a message digest. The message * digests range in length from 160 to 512 bits, depending on the algorithm. * Secure hash algorithms are typically used with other cryptographic * algorithms, such as digital signature algorithms and keyed-hash message * authentication codes, or in the generation of random numbers (bits).</p> * * <p>The four hash algorithms specified in this "SHS" standard are called * secure because, for a given algorithm, it is computationally infeasible * 1) to find a message that corresponds to a given message digest, or 2) * to find two different messages that produce the same message digest. Any * change to a message will, with a very high probability, result in a * different message digest. This will result in a verification failure when * the secure hash algorithm is used with a digital signature algorithm or a * keyed-hash message authentication algorithm.</p> * * <p>A "SHS change notice" adds a SHA-224 algorithm for interoperability, * which, like SHA-1 and SHA-256, operates on 512-bit blocks and 32-bit words, * but truncates the final digest and uses distinct initialization values.</p> * * <p><b>References:</b></p> * <ol> * <li> NIST FIPS PUB 180-2, "Secure Hash Signature Standard (SHS) with * change notice", National Institute of Standards and Technology (NIST), * 2002 August 1, and U.S. Department of Commerce, August 26.<br> * <a href="http://csrc.ncsl.nist.gov/CryptoToolkit/Hash.html"> * http://csrc.ncsl.nist.gov/CryptoToolkit/Hash.html</a> * <li> NIST FIPS PUB 180-1, "Secure Hash Standard", * U.S. Department of Commerce, May 1993.<br> * <a href="http://www.itl.nist.gov/div897/pubs/fip180-1.htm"> * http://www.itl.nist.gov/div897/pubs/fip180-1.htm</a></li> * <li> Bruce Schneier, "Section 18.7 Secure Hash Algorithm (SHA)", * <cite>Applied Cryptography, 2nd edition</cite>, <br> * John Wiley & Sons, 1996</li> * </ol> */ public final class SHA1 extends MessageDigest implements Cloneable { /** * This implementation returns a fixed-size digest. */ private static final int HASH_LENGTH = 20; // bytes == 160 bits /** * Private context for incomplete blocks and padding bytes. * INVARIANT: padding must be in 0..63. * When the padding reaches 64, a new block is computed, and * the 56 last bytes are kept in the padding history. */ private byte[] pad; private int padding; /** * Private contextual byte count, sent in the next block, * after the ending padding block. */ private long bytes; /** * Private context that contains the current digest key. */ private int hA, hB, hC, hD, hE; /** * Creates a SHA1 object with default initial state. */ public SHA1() { super("SHA-1"); pad = new byte[64]; init(); } /** * Clones this object. */ public Object clone() throws CloneNotSupportedException { SHA1 that = (SHA1)super.clone(); that.pad = (byte[])this.pad.clone(); return that; } /** * Returns the digest length in bytes. * * Can be used to allocate your own output buffer when * computing multiple digests. * * Overrides the protected abstract method of * <code>java.security.MessageDigestSpi</code>. * @return the digest length in bytes. */ public int engineGetDigestLength() { return HASH_LENGTH; } /** * Reset athen initialize the digest context. * * Overrides the protected abstract method of * <code>java.security.MessageDigestSpi</code>. */ protected void engineReset() { int i = 60; do { pad[i ] = (byte)0x00; pad[i + 1] = (byte)0x00; pad[i + 2] = (byte)0x00; pad[i + 3] = (byte)0x00; } while ((i -= 4) >= 0); padding = 0; bytes = 0; init(); } /** * Initialize the digest context. */ protected void init() { hA = 0x67452301; hB = 0xefcdab89; hC = 0x98badcfe; hD = 0x10325476; hE = 0xc3d2e1f0; } /** * Updates the digest using the specified byte. * Requires internal buffering, and may be slow. * * Overrides the protected abstract method of * java.security.MessageDigestSpi. * @param input the byte to use for the update. */ public void engineUpdate(byte input) { bytes++; if (padding < 63) { pad[padding++] = input; return; } pad[63] = input; computeBlock(pad, 0); padding = 0; } /** * Updates the digest using the specified array of bytes, * starting at the specified offset. * * Input length can be any size. May require internal buffering, * if input blocks are not multiple of 64 bytes. * * Overrides the protected abstract method of * java.security.MessageDigestSpi. * @param input the array of bytes to use for the update. * @param offset the offset to start from in the array of bytes. * @param length the number of bytes to use, starting at offset. */ public void engineUpdate(byte[] input, int offset, int len) { if (offset >= 0 && len >= 0 && offset + len <= input.length) { bytes += len; /* Terminate the previous block. */ int padlen = 64 - padding; if (padding > 0 && len >= padlen) { System.arraycopy(input, offset, pad, padding, padlen); computeBlock(pad, 0); padding = 0; offset += padlen; len -= padlen; } /* Loop on large sets of complete blocks. */ while (len >= 512) { computeBlock(input, offset); computeBlock(input, offset + 64); computeBlock(input, offset + 128); computeBlock(input, offset + 192); computeBlock(input, offset + 256); computeBlock(input, offset + 320); computeBlock(input, offset + 384); computeBlock(input, offset + 448); offset += 512; len -= 512; } /* Loop on remaining complete blocks. */ while (len >= 64) { computeBlock(input, offset); offset += 64; len -= 64; } /* remaining bytes kept for next block. */ if (len > 0) { System.arraycopy(input, offset, pad, padding, len); padding += len; } return; } throw new ArrayIndexOutOfBoundsException(offset); } /** * Completes the hash computation by performing final operations * such as padding. Computes the final hash and returns the final * value as a byte[20] array. Once engineDigest has been called, * the engine will be automatically reset as specified in the * JavaSecurity MessageDigest specification. * * For faster operations with multiple digests, allocate your own * array and use engineDigest(byte[], int offset, int len). * * Overrides the protected abstract method of * java.security.MessageDigestSpi. * @return the length of the digest stored in the output buffer. */ public byte[] engineDigest() { try { final byte hashvalue[] = new byte[HASH_LENGTH]; engineDigest(hashvalue, 0, HASH_LENGTH); return hashvalue; } catch (DigestException e) { return null; } } /** * Completes the hash computation by performing final operations * such as padding. Once engineDigest has been called, the engine * will be automatically reset (see engineReset). * * Overrides the protected abstract method of * java.security.MessageDigestSpi. * @param hashvalue the output buffer in which to store the digest. * @param offset offset to start from in the output buffer * @param len number of bytes within buf allotted for the digest. * Both this default implementation and the SUN provider * do not return partial digests. The presence of this * parameter is solely for consistency in our API's. * If the value of this parameter is less than the * actual digest length, the method will throw a * DigestException. This parameter is ignored if its * value is greater than or equal to the actual digest * length. * @return the length of the digest stored in the output buffer. */ public int engineDigest(byte[] hashvalue, int offset, final int len) throws DigestException { if (len >= HASH_LENGTH) { if (hashvalue.length - offset >= HASH_LENGTH) { /* Flush the trailing bytes, adding padding bytes into last * blocks. */ int i; /* Add padding null bytes but replace the last 8 padding bytes * by the little-endian 64-bit digested message bit-length. */ pad[i = padding] = (byte)0x80; /* required 1st padding byte */ /* Check if 8 bytes available in pad to store the total * message size */ switch (i) { /* INVARIANT: i must be in [0..63] */ case 52: pad[53] = (byte)0x00; /* no break; falls thru */ case 53: pad[54] = (byte)0x00; /* no break; falls thru */ case 54: pad[55] = (byte)0x00; /* no break; falls thru */ case 55: break; case 56: pad[57] = (byte)0x00; /* no break; falls thru */ case 57: pad[58] = (byte)0x00; /* no break; falls thru */ case 58: pad[59] = (byte)0x00; /* no break; falls thru */ case 59: pad[60] = (byte)0x00; /* no break; falls thru */ case 60: pad[61] = (byte)0x00; /* no break; falls thru */ case 61: pad[62] = (byte)0x00; /* no break; falls thru */ case 62: pad[63] = (byte)0x00; /* no break; falls thru */ case 63: computeBlock(pad, 0); /* Clear the 56 first bytes of pad[]. */ i = 52; do { pad[i ] = (byte)0x00; pad[i + 1] = (byte)0x00; pad[i + 2] = (byte)0x00; pad[i + 3] = (byte)0x00; } while ((i -= 4) >= 0); break; default: /* Clear the rest of 56 first bytes of pad[]. */ switch (i & 3) { case 3: i++; break; case 2: pad[(i += 2) - 1] = (byte)0x00; break; case 1: pad[(i += 3) - 2] = (byte)0x00; pad[ i - 1] = (byte)0x00; break; case 0: pad[(i += 4) - 3] = (byte)0x00; pad[ i - 2] = (byte)0x00; pad[ i - 1] = (byte)0x00; } do { pad[i ] = (byte)0x00; pad[i + 1] = (byte)0x00; pad[i + 2] = (byte)0x00; pad[i + 3] = (byte)0x00; } while ((i += 4) < 56); } /* Convert the message size from bytes to big-endian bits. */ pad[56] = (byte)((i = (int)(bytes >>> 29)) >> 24); pad[57] = (byte)(i >>> 16); pad[58] = (byte)(i >>> 8); pad[59] = (byte)i; pad[60] = (byte)((i = (int)bytes << 3) >> 24); pad[61] = (byte)(i >>> 16); pad[62] = (byte)(i >>> 8); pad[63] = (byte)i; computeBlock(pad, 0); /* Return the computed digest in big-endian byte order. */ hashvalue[offset ] = (byte)((i = hA) >>> 24); hashvalue[offset + 1] = (byte)(i >>> 16); hashvalue[offset + 2] = (byte)(i >>> 8); hashvalue[offset + 3] = (byte)i; hashvalue[offset + 4] = (byte)((i = hB) >>> 24); hashvalue[offset += 5] = (byte)(i >>> 16); hashvalue[offset + 1] = (byte)(i >>> 8); hashvalue[offset + 2] = (byte)i; hashvalue[offset + 3] = (byte)((i = hC) >>> 24); hashvalue[offset + 4] = (byte)(i >>> 16); hashvalue[offset += 5] = (byte)(i >>> 8); hashvalue[offset + 1] = (byte)i; hashvalue[offset + 2] = (byte)((i = hD) >>> 24); hashvalue[offset + 3] = (byte)(i >>> 16); hashvalue[offset + 4] = (byte)(i >>> 8); hashvalue[offset += 5] = (byte)i; hashvalue[offset + 1] = (byte)((i = hE) >>> 24); hashvalue[offset + 2] = (byte)(i >>> 16); hashvalue[offset + 3] = (byte)(i >>> 8); hashvalue[offset + 4] = (byte)i; engineReset(); /* clear the evidence */ return HASH_LENGTH; } throw new DigestException( "insufficient space in output buffer to store the digest"); } throw new DigestException("partial digests not returned"); } /** * Updates the digest using the specified array of bytes, * starting at the specified offset, but an implied length * of exactly 64 bytes. * * Requires no internal buffering, but assumes a fixed input size, * in which the required padding bytes may have been added. * * @param input the array of bytes to use for the update. * @param offset the offset to start from in the array of bytes. */ private void computeBlock(final byte[] input, int offset) { /* Local temporary work variables for intermediate digests. */ int a, b, c, d, e; /* Cache the input block into the local working set of 32-bit * values, in big-endian byte order. Be careful when * widening bytes or integers due to sign extension! */ int i00, i01, i02, i03, i04, i05, i06, i07, i08, i09, i10, i11, i12, i13, i14, i15; /* Use hash schedule function Ch (rounds 0..19): * Ch(x,y,z) = (x & y) ^ (~x & z) = (x & (y ^ z)) ^ z, * and K00 = .... = K19 = 0x5a827999. */ /* First pass, on big endian input (rounds 0..15). */ e = hE + (((a = hA) << 5) | (a >>> 27)) + 0x5a827999 // K00 + (((b = hB) & ((c = hC) ^ (d = hD))) ^ d) // Ch(b,c,d) + (i00 = input[offset ] << 24 | (input[offset + 1] & 0xff) << 16 | (input[offset + 2] & 0xff) << 8 | (input[offset + 3] & 0xff)); // W00 d += ((e << 5) | (e >>> 27)) + 0x5a827999 // K01 + ((a & ((b = (b << 30) | (b >>> 2)) ^ c)) ^ c) // Ch(a,b,c) + (i01 = input[offset + 4] << 24 | (input[offset += 5] & 0xff) << 16 | (input[offset + 1] & 0xff) << 8 | (input[offset + 2] & 0xff)); // W01 c += ((d << 5) | (d >>> 27)) + 0x5a827999 // K02 + ((e & ((a = (a << 30) | (a >>> 2)) ^ b)) ^ b) // Ch(e,a,b) + (i02 = input[offset + 3] << 24 | (input[offset + 4] & 0xff) << 16 | (input[offset += 5] & 0xff) << 8 | (input[offset + 1] & 0xff)); // W02 b += ((c << 5) | (c >>> 27)) + 0x5a827999 // K03 + ((d & ((e = (e << 30) | (e >>> 2)) ^ a)) ^ a) // Ch(d,e,a) + (i03 = input[offset + 2] << 24 | (input[offset + 3] & 0xff) << 16 | (input[offset + 4] & 0xff) << 8 | (input[offset += 5] & 0xff)); // W03 a += ((b << 5) | (b >>> 27)) + 0x5a827999 // K04 + ((c & ((d = (d << 30) | (d >>> 2)) ^ e)) ^ e) // Ch(c,d,e) + (i04 = input[offset + 1] << 24 | (input[offset + 2] & 0xff) << 16 | (input[offset + 3] & 0xff) << 8 | (input[offset + 4] & 0xff)); // W04 e += ((a << 5) | (a >>> 27)) + 0x5a827999 // K05 + ((b & ((c = (c << 30) | (c >>> 2)) ^ d)) ^ d) // Ch(b,c,d) + (i05 = input[offset += 5] << 24 | (input[offset + 1] & 0xff) << 16 | (input[offset + 2] & 0xff) << 8 | (input[offset + 3] & 0xff)); // W05 d += ((e << 5) | (e >>> 27)) + 0x5a827999 // K06 + ((a & ((b = (b << 30) | (b >>> 2)) ^ c)) ^ c) // Ch(a,b,c) + (i06 = input[offset + 4] << 24 | (input[offset += 5] & 0xff) << 16 | (input[offset + 1] & 0xff) << 8 | (input[offset + 2] & 0xff)); // W06 c += ((d << 5) | (d >>> 27)) + 0x5a827999 // K07 + ((e & ((a = (a << 30) | (a >>> 2)) ^ b)) ^ b) // Ch(e,a,b) + (i07 = input[offset + 3] << 24 | (input[offset + 4] & 0xff) << 16 | (input[offset += 5] & 0xff) << 8 | (input[offset + 1] & 0xff)); // W07 b += ((c << 5) | (c >>> 27)) + 0x5a827999 // K08 + ((d & ((e = (e << 30) | (e >>> 2)) ^ a)) ^ a) // Ch(d,e,a) + (i08 = input[offset + 2] << 24 | (input[offset + 3] & 0xff) << 16 | (input[offset + 4] & 0xff) << 8 | (input[offset += 5] & 0xff)); // W08 a += ((b << 5) | (b >>> 27)) + 0x5a827999 // K09 + ((c & ((d = (d << 30) | (d >>> 2)) ^ e)) ^ e) // Ch(c,d,e) + (i09 = input[offset + 1] << 24 | (input[offset + 2] & 0xff) << 16 | (input[offset + 3] & 0xff) << 8 | (input[offset + 4] & 0xff)); // W09 e += ((a << 5) | (a >>> 27)) + 0x5a827999 // K10 + ((b & ((c = (c << 30) | (c >>> 2)) ^ d)) ^ d) // Ch(b,c,d) + (i10 = input[offset += 5] << 24 | (input[offset + 1] & 0xff) << 16 | (input[offset + 2] & 0xff) << 8 | (input[offset + 3] & 0xff)); // W10 d += ((e << 5) | (e >>> 27)) + 0x5a827999 // K11 + ((a & ((b = (b << 30) | (b >>> 2)) ^ c)) ^ c) // Ch(a,b,c) + (i11 = input[offset + 4] << 24 | (input[offset += 5] & 0xff) << 16 | (input[offset + 1] & 0xff) << 8 | (input[offset + 2] & 0xff)); // W11 c += ((d << 5) | (d >>> 27)) + 0x5a827999 // K12 + ((e & ((a = (a << 30) | (a >>> 2)) ^ b)) ^ b) // Ch(e,a,b) + (i12 = input[offset + 3] << 24 | (input[offset + 4] & 0xff) << 16 | (input[offset += 5] & 0xff) << 8 | (input[offset + 1] & 0xff)); // W12 b += ((c << 5) | (c >>> 27)) + 0x5a827999 // K13 + ((d & ((e = (e << 30) | (e >>> 2)) ^ a)) ^ a) // Ch(d,e,a) + (i13 = input[offset + 2] << 24 | (input[offset + 3] & 0xff) << 16 | (input[offset + 4] & 0xff) << 8 | (input[offset += 5] & 0xff)); // W13 a += ((b << 5) | (b >>> 27)) + 0x5a827999 // K14 + ((c & ((d = (d << 30) | (d >>> 2)) ^ e)) ^ e) // Ch(c,d,e) + (i14 = input[offset + 1] << 24 | (input[offset + 2] & 0xff) << 16 | (input[offset + 3] & 0xff) << 8 | (input[offset + 4] & 0xff)); // W14 e += ((a << 5) | (a >>> 27)) + 0x5a827999 // K15 + ((b & ((c = (c << 30) | (c >>> 2)) ^ d)) ^ d) // Ch(b,c,d) + (i15 = input[offset += 5] << 24 | (input[offset + 1] & 0xff) << 16 | (input[offset + 2] & 0xff) << 8 | (input[offset + 3] & 0xff)); // W15 /* Second pass, on scheduled input (rounds 16..31). */ d += ((e << 5) | (e >>> 27)) + 0x5a827999 // K16 + ((a & ((b = (b << 30) | (b >>> 2)) ^ c)) ^ c) // Ch(a,b,c) + (i00 = ((i00 ^= i02 ^ i08 ^ i13) << 1) | (i00 >>> 31)); // W16 c += ((d << 5) | (d >>> 27)) + 0x5a827999 // K17 + ((e & ((a = (a << 30) | (a >>> 2)) ^ b)) ^ b) // Ch(e,a,b) + (i01 = ((i01 ^= i03 ^ i09 ^ i14) << 1) | (i01 >>> 31)); // W17 b += ((c << 5) | (c >>> 27)) + 0x5a827999 // K18 + ((d & ((e = (e << 30) | (e >>> 2)) ^ a)) ^ a) // Ch(d,e,a) + (i02 = ((i02 ^= i04 ^ i10 ^ i15) << 1) | (i02 >>> 31)); // W18 a += ((b << 5) | (b >>> 27)) + 0x5a827999 // K19 + ((c & ((d = (d << 30) | (d >>> 2)) ^ e)) ^ e) // Ch(c,d,e) + (i03 = ((i03 ^= i05 ^ i11 ^ i00) << 1) | (i03 >>> 31)); // W19 /* Use hash schedule function Parity (rounds 20..39): * Parity(x,y,z) = x ^ y ^ z, * and K20 = .... = K39 = 0x6ed9eba1. */ e += ((a << 5) | (a >>> 27)) + 0x6ed9eba1 // K20 + (b ^ (c = (c << 30) | (c >>> 2)) ^ d) // Parity(b,c,d) + (i04 = ((i04 ^= i06 ^ i12 ^ i01) << 1) | (i04 >>> 31)); // W20 d += ((e << 5) | (e >>> 27)) + 0x6ed9eba1 // K21 + (a ^ (b = (b << 30) | (b >>> 2)) ^ c) // Parity(a,b,c) + (i05 = ((i05 ^= i07 ^ i13 ^ i02) << 1) | (i05 >>> 31)); // W21 c += ((d << 5) | (d >>> 27)) + 0x6ed9eba1 // K22 + (e ^ (a = (a << 30) | (a >>> 2)) ^ b) // Parity(e,a,b) + (i06 = ((i06 ^= i08 ^ i14 ^ i03) << 1) | (i06 >>> 31)); // W22 b += ((c << 5) | (c >>> 27)) + 0x6ed9eba1 // K23 + (d ^ (e = (e << 30) | (e >>> 2)) ^ a) // Parity(d,e,a) + (i07 = ((i07 ^= i09 ^ i15 ^ i04) << 1) | (i07 >>> 31)); // W23 a += ((b << 5) | (b >>> 27)) + 0x6ed9eba1 // K24 + (c ^ (d = (d << 30) | (d >>> 2)) ^ e) // Parity(c,d,e) + (i08 = ((i08 ^= i10 ^ i00 ^ i05) << 1) | (i08 >>> 31)); // W24 e += ((a << 5) | (a >>> 27)) + 0x6ed9eba1 // K25 + (b ^ (c = (c << 30) | (c >>> 2)) ^ d) // Parity(b,c,d) + (i09 = ((i09 ^= i11 ^ i01 ^ i06) << 1) | (i09 >>> 31)); // W25 d += ((e << 5) | (e >>> 27)) + 0x6ed9eba1 // K26 + (a ^ (b = (b << 30) | (b >>> 2)) ^ c) // Parity(a,b,c) + (i10 = ((i10 ^= i12 ^ i02 ^ i07) << 1) | (i10 >>> 31)); // W26 c += ((d << 5) | (d >>> 27)) + 0x6ed9eba1 // K27 + (e ^ (a = (a << 30) | (a >>> 2)) ^ b) // Parity(e,a,b) + (i11 = ((i11 ^= i13 ^ i03 ^ i08) << 1) | (i11 >>> 31)); // W27 b += ((c << 5) | (c >>> 27)) + 0x6ed9eba1 // K28 + (d ^ (e = (e << 30) | (e >>> 2)) ^ a) // Parity(d,e,a) + (i12 = ((i12 ^= i14 ^ i04 ^ i09) << 1) | (i12 >>> 31)); // W28 a += ((b << 5) | (b >>> 27)) + 0x6ed9eba1 // K29 + (c ^ (d = (d << 30) | (d >>> 2)) ^ e) // Parity(c,d,e) + (i13 = ((i13 ^= i15 ^ i05 ^ i10) << 1) | (i13 >>> 31)); // W29 e += ((a << 5) | (a >>> 27)) + 0x6ed9eba1 // K30 + (b ^ (c = (c << 30) | (c >>> 2)) ^ d) // Parity(b,c,d) + (i14 = ((i14 ^= i00 ^ i06 ^ i11) << 1) | (i14 >>> 31)); // W30 d += ((e << 5) | (e >>> 27)) + 0x6ed9eba1 // K31 + (a ^ (b = (b << 30) | (b >>> 2)) ^ c) // Parity(a,b,c) + (i15 = ((i15 ^= i01 ^ i07 ^ i12) << 1) | (i15 >>> 31)); // W31 /* Third pass, on scheduled input (rounds 32..47). */ c += ((d << 5) | (d >>> 27)) + 0x6ed9eba1 // K32 + (e ^ (a = (a << 30) | (a >>> 2)) ^ b) // Parity(e,a,b) + (i00 = ((i00 ^= i02 ^ i08 ^ i13) << 1) | (i00 >>> 31)); // W32 b += ((c << 5) | (c >>> 27)) + 0x6ed9eba1 // K33 + (d ^ (e = (e << 30) | (e >>> 2)) ^ a) // Parity(d,e,a) + (i01 = ((i01 ^= i03 ^ i09 ^ i14) << 1) | (i01 >>> 31)); // W33 a += ((b << 5) | (b >>> 27)) + 0x6ed9eba1 // K34 + (c ^ (d = (d << 30) | (d >>> 2)) ^ e) // Parity(c,d,e) + (i02 = ((i02 ^= i04 ^ i10 ^ i15) << 1) | (i02 >>> 31)); // W34 e += ((a << 5) | (a >>> 27)) + 0x6ed9eba1 // K35 + (b ^ (c = (c << 30) | (c >>> 2)) ^ d) // Parity(b,c,d) + (i03 = ((i03 ^= i05 ^ i11 ^ i00) << 1) | (i03 >>> 31)); // W35 d += ((e << 5) | (e >>> 27)) + 0x6ed9eba1 // K36 + (a ^ (b = (b << 30) | (b >>> 2)) ^ c) // Parity(a,b,c) + (i04 = ((i04 ^= i06 ^ i12 ^ i01) << 1) | (i04 >>> 31)); // W36 c += ((d << 5) | (d >>> 27)) + 0x6ed9eba1 // K37 + (e ^ (a = (a << 30) | (a >>> 2)) ^ b) // Parity(e,a,b) + (i05 = ((i05 ^= i07 ^ i13 ^ i02) << 1) | (i05 >>> 31)); // W37 b += ((c << 5) | (c >>> 27)) + 0x6ed9eba1 // K38 + (d ^ (e = (e << 30) | (e >>> 2)) ^ a) // Parity(d,e,a) + (i06 = ((i06 ^= i08 ^ i14 ^ i03) << 1) | (i06 >>> 31)); // W38 a += ((b << 5) | (b >>> 27)) + 0x6ed9eba1 // K39 + (c ^ (d = (d << 30) | (d >>> 2)) ^ e) // Parity(c,d,e) + (i07 = ((i07 ^= i09 ^ i15 ^ i04) << 1) | (i07 >>> 31)); // W39 /* Use hash schedule function Maj (rounds 40..59): * Maj(x,y,z) = (x&y) ^ (x&z) ^ (y&z) = (x & y) | ((x | y) & z), * and K40 = .... = K59 = 0x8f1bbcdc. */ e += ((a << 5) | (a >>> 27)) + 0x8f1bbcdc // K40 + ((b & (c = (c << 30) | (c >>> 2))) | ((b | c) & d)) // Maj(b,c,d) + (i08 = ((i08 ^= i10 ^ i00 ^ i05) << 1) | (i08 >>> 31)); // W40 d += ((e << 5) | (e >>> 27)) + 0x8f1bbcdc // K41 + ((a & (b = (b << 30) | (b >>> 2))) | ((a | b) & c)) // Maj(a,b,c) + (i09 = ((i09 ^= i11 ^ i01 ^ i06) << 1) | (i09 >>> 31)); // W41 c += ((d << 5) | (d >>> 27)) + 0x8f1bbcdc // K42 + ((e & (a = (a << 30) | (a >>> 2))) | ((e | a) & b)) // Maj(e,a,b) + (i10 = ((i10 ^= i12 ^ i02 ^ i07) << 1) | (i10 >>> 31)); // W42 b += ((c << 5) | (c >>> 27)) + 0x8f1bbcdc // K43 + ((d & (e = (e << 30) | (e >>> 2))) | ((d | e) & a)) // Maj(d,e,a) + (i11 = ((i11 ^= i13 ^ i03 ^ i08) << 1) | (i11 >>> 31)); // W43 a += ((b << 5) | (b >>> 27)) + 0x8f1bbcdc // K44 + ((c & (d = (d << 30) | (d >>> 2))) | ((c | d) & e)) // Maj(c,d,e) + (i12 = ((i12 ^= i14 ^ i04 ^ i09) << 1) | (i12 >>> 31)); // W44 e += ((a << 5) | (a >>> 27)) + 0x8f1bbcdc // K45 + ((b & (c = (c << 30) | (c >>> 2))) | ((b | c) & d)) // Maj(b,c,d) + (i13 = ((i13 ^= i15 ^ i05 ^ i10) << 1) | (i13 >>> 31)); // W45 d += ((e << 5) | (e >>> 27)) + 0x8f1bbcdc // K46 + ((a & (b = (b << 30) | (b >>> 2))) | ((a | b) & c)) // Maj(a,b,c) + (i14 = ((i14 ^= i00 ^ i06 ^ i11) << 1) | (i14 >>> 31)); // W46 c += ((d << 5) | (d >>> 27)) + 0x8f1bbcdc // K47 + ((e & (a = (a << 30) | (a >>> 2))) | ((e | a) & b)) // Maj(e,a,b) + (i15 = ((i15 ^= i01 ^ i07 ^ i12) << 1) | (i15 >>> 31)); // W47 /* Fourth pass, on scheduled input (rounds 48..63). */ b += ((c << 5) | (c >>> 27)) + 0x8f1bbcdc // K48 + ((d & (e = (e << 30) | (e >>> 2))) | ((d | e) & a)) // Maj(d,e,a) + (i00 = ((i00 ^= i02 ^ i08 ^ i13) << 1) | (i00 >>> 31)); // W48 a += ((b << 5) | (b >>> 27)) + 0x8f1bbcdc // K49 + ((c & (d = (d << 30) | (d >>> 2))) | ((c | d) & e)) // Maj(c,d,e) + (i01 = ((i01 ^= i03 ^ i09 ^ i14) << 1) | (i01 >>> 31)); // W49 e += ((a << 5) | (a >>> 27)) + 0x8f1bbcdc // K50 + ((b & (c = (c << 30) | (c >>> 2))) | ((b | c) & d)) // Maj(b,c,d) + (i02 = ((i02 ^= i04 ^ i10 ^ i15) << 1) | (i02 >>> 31)); // W50 d += ((e << 5) | (e >>> 27)) + 0x8f1bbcdc // K51 + ((a & (b = (b << 30) | (b >>> 2))) | ((a | b) & c)) // Maj(a,b,c) + (i03 = ((i03 ^= i05 ^ i11 ^ i00) << 1) | (i03 >>> 31)); // W51 c += ((d << 5) | (d >>> 27)) + 0x8f1bbcdc // K52 + ((e & (a = (a << 30) | (a >>> 2))) | ((e | a) & b)) // Maj(e,a,b) + (i04 = ((i04 ^= i06 ^ i12 ^ i01) << 1) | (i04 >>> 31)); // W52 b += ((c << 5) | (c >>> 27)) + 0x8f1bbcdc // K53 + ((d & (e = (e << 30) | (e >>> 2))) | ((d | e) & a)) // Maj(d,e,a) + (i05 = ((i05 ^= i07 ^ i13 ^ i02) << 1) | (i05 >>> 31)); // W53 a += ((b << 5) | (b >>> 27)) + 0x8f1bbcdc // K54 + ((c & (d = (d << 30) | (d >>> 2))) | ((c | d) & e)) // Maj(c,d,e) + (i06 = ((i06 ^= i08 ^ i14 ^ i03) << 1) | (i06 >>> 31)); // W54 e += ((a << 5) | (a >>> 27)) + 0x8f1bbcdc // K55 + ((b & (c = (c << 30) | (c >>> 2))) | ((b | c) & d)) // Maj(b,c,d) + (i07 = ((i07 ^= i09 ^ i15 ^ i04) << 1) | (i07 >>> 31)); // W55 d += ((e << 5) | (e >>> 27)) + 0x8f1bbcdc // K56 + ((a & (b = (b << 30) | (b >>> 2))) | ((a | b) & c)) // Maj(a,b,c) + (i08 = ((i08 ^= i10 ^ i00 ^ i05) << 1) | (i08 >>> 31)); // W56 c += ((d << 5) | (d >>> 27)) + 0x8f1bbcdc // K57 + ((e & (a = (a << 30) | (a >>> 2))) | ((e | a) & b)) // Maj(e,a,b) + (i09 = ((i09 ^= i11 ^ i01 ^ i06) << 1) | (i09 >>> 31)); // W57 b += ((c << 5) | (c >>> 27)) + 0x8f1bbcdc // K58 + ((d & (e = (e << 30) | (e >>> 2))) | ((d | e) & a)) // Maj(d,e,a) + (i10 = ((i10 ^= i12 ^ i02 ^ i07) << 1) | (i10 >>> 31)); // W58 a += ((b << 5) | (b >>> 27)) + 0x8f1bbcdc // K59 + ((c & (d = (d << 30) | (d >>> 2))) | ((c | d) & e)) // Maj(c,d,e) + (i11 = ((i11 ^= i13 ^ i03 ^ i08) << 1) | (i11 >>> 31)); // W59 /* Use hash schedule function Parity (rounds 60..79): * Parity(x,y,z) = x ^ y ^ z, * and K60 = .... = K79 = 0xca62c1d6. */ e += ((a << 5) | (a >>> 27)) + 0xca62c1d6 // K60 + (b ^ (c = (c << 30) | (c >>> 2)) ^ d) // Parity(b,c,d) + (i12 = ((i12 ^= i14 ^ i04 ^ i09) << 1) | (i12 >>> 31)); // W60 d += ((e << 5) | (e >>> 27)) + 0xca62c1d6 // K61 + (a ^ (b = (b << 30) | (b >>> 2)) ^ c) // Parity(a,b,c) + (i13 = ((i13 ^= i15 ^ i05 ^ i10) << 1) | (i13 >>> 31)); // W61 c += ((d << 5) | (d >>> 27)) + 0xca62c1d6 // K62 + (e ^ (a = (a << 30) | (a >>> 2)) ^ b) // Parity(e,a,b) + (i14 = ((i14 ^= i00 ^ i06 ^ i11) << 1) | (i14 >>> 31)); // W62 b += ((c << 5) | (c >>> 27)) + 0xca62c1d6 // K63 + (d ^ (e = (e << 30) | (e >>> 2)) ^ a) // Parity(d,e,a) + (i15 = ((i15 ^= i01 ^ i07 ^ i12) << 1) | (i15 >>> 31)); // W63 /* Fifth pass, on scheduled input (rounds 64..79). */ a += ((b << 5) | (b >>> 27)) + 0xca62c1d6 // K64 + (c ^ (d = (d << 30) | (d >>> 2)) ^ e) // Parity(c,d,e) + (i00 = ((i00 ^= i02 ^ i08 ^ i13) << 1) | (i00 >>> 31)); // W64 e += ((a << 5) | (a >>> 27)) + 0xca62c1d6 // K65 + (b ^ (c = (c << 30) | (c >>> 2)) ^ d) // Parity(b,c,d) + (i01 = ((i01 ^= i03 ^ i09 ^ i14) << 1) | (i01 >>> 31)); // W65 d += ((e << 5) | (e >>> 27)) + 0xca62c1d6 // K66 + (a ^ (b = (b << 30) | (b >>> 2)) ^ c) // Parity(a,b,c) + (i02 = ((i02 ^= i04 ^ i10 ^ i15) << 1) | (i02 >>> 31)); // W66 c += ((d << 5) | (d >>> 27)) + 0xca62c1d6 // K67 + (e ^ (a = (a << 30) | (a >>> 2)) ^ b) // Parity(e,a,b) + (i03 = ((i03 ^= i05 ^ i11 ^ i00) << 1) | (i03 >>> 31)); // W67 b += ((c << 5) | (c >>> 27)) + 0xca62c1d6 // K68 + (d ^ (e = (e << 30) | (e >>> 2)) ^ a) // Parity(d,e,a) + (i04 = ((i04 ^= i06 ^ i12 ^ i01) << 1) | (i04 >>> 31)); // W68 a += ((b << 5) | (b >>> 27)) + 0xca62c1d6 // K69 + (c ^ (d = (d << 30) | (d >>> 2)) ^ e) // Parity(c,d,e) + (i05 = ((i05 ^= i07 ^ i13 ^ i02) << 1) | (i05 >>> 31)); // W69 e += ((a << 5) | (a >>> 27)) + 0xca62c1d6 // K70 + (b ^ (c = (c << 30) | (c >>> 2)) ^ d) // Parity(b,c,d) + (i06 = ((i06 ^= i08 ^ i14 ^ i03) << 1) | (i06 >>> 31)); // W70 d += ((e << 5) | (e >>> 27)) + 0xca62c1d6 // K71 + (a ^ (b = (b << 30) | (b >>> 2)) ^ c) // Parity(a,b,c) + (i07 = ((i07 ^= i09 ^ i15 ^ i04) << 1) | (i07 >>> 31)); // W71 c += ((d << 5) | (d >>> 27)) + 0xca62c1d6 // K72 + (e ^ (a = (a << 30) | (a >>> 2)) ^ b) // Parity(e,a,b) + (i08 = ((i08 ^= i10 ^ i00 ^ i05) << 1) | (i08 >>> 31)); // W72 b += ((c << 5) | (c >>> 27)) + 0xca62c1d6 // K73 + (d ^ (e = (e << 30) | (e >>> 2)) ^ a) // Parity(d,e,a) + (i09 = ((i09 ^= i11 ^ i01 ^ i06) << 1) | (i09 >>> 31)); // W73 a += ((b << 5) | (b >>> 27)) + 0xca62c1d6 // K74 + (c ^ (d = (d << 30) | (d >>> 2)) ^ e) // Parity(c,d,e) + (i10 = ((i10 ^= i12 ^ i02 ^ i07) << 1) | (i10 >>> 31)); // W74 e += ((a << 5) | (a >>> 27)) + 0xca62c1d6 // K75 + (b ^ (c = (c << 30) | (c >>> 2)) ^ d) // Parity(b,c,d) + (i11 = ((i11 ^= i13 ^ i03 ^ i08) << 1) | (i11 >>> 31)); // W75 d += ((e << 5) | (e >>> 27)) + 0xca62c1d6 // K76 + (a ^ (b = (b << 30) | (b >>> 2)) ^ c) // Parity(a,b,c) + (i12 = ((i12 ^= i14 ^ i04 ^ i09) << 1) | (i12 >>> 31)); // W76 c += ((d << 5) | (d >>> 27)) + 0xca62c1d6 // K77 + (e ^ (a = (a << 30) | (a >>> 2)) ^ b) // Parity(e,a,b) + (i13 = ((i13 ^= i15 ^ i05 ^ i10) << 1) | (i13 >>> 31)); // W77 /* Terminate the last two rounds of fifth pass, * feeding the final digest on the fly. */ hB += b += ((c << 5) | (c >>> 27)) + 0xca62c1d6 // K78 + (d ^ (e = (e << 30) | (e >>> 2)) ^ a) // Parity(d,e,a) + (i14 = ((i14 ^= i00 ^ i06 ^ i11) << 1) | (i14 >>> 31)); // W78 hA += a += ((b << 5) | (b >>> 27)) + 0xca62c1d6 // K79 + (c ^ (d = (d << 30) | (d >>> 2)) ^ e) // Parity(c,d,e) + (i15 = ((i15 ^= i01 ^ i07 ^ i12) << 1) | (i15 >>> 31)); // W79 hE += e; hD += d; hC += /* c= */ (c << 30) | (c >>> 2); } }