/* @(#)SHA256.java	1.12 2004-08-08
 * 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-256", "org.rodage.pub.java.security.SHA256");
 */
//package org.rodage.pub.java.security;
import java.security.*;
//--+---+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 &amp; Sons, 1996</li>
 * </ol>
 */
public final class SHA256 extends MessageDigestSpi implements Cloneable {
    /**
     * Private contextual byte count, stored at end of the last block,
     * after the final padded block.
     */
    private long bytes;

    /**
     * Private context for incomplete blocks and padding bytes.<br/>
     * INVARIANT: padded must be in 0..63.<br/>
     * When the padding reaches 64 bytes, a new block is computed, and
     * the 56 last bytes are kept in the padding history.
     */
    private int padded;
    private byte[] pad;

    /**
     * Private context that contains the current digest key.
     */
    private int hA, hB, hC, hD, hE, hF, hG, hH;

    /**
     * Internal intermediate store for the scheduled input block.
     * Set before each of the 4 passes of 16 rounds each.<br/>
     * Needed because computeBlock() cannot be fully inlined and must be
     * splitted, due to the total bytecode size that would prohibit JIT
     * compilation at run-time and would give too slow performance if the
     * bytecode was interpreted (this problem affects both the client and
     * server VMs).
     */
    private int m00, m01, m02, m03, m04, m05, m06, m07,
                m08, m09, m10, m11, m12, m13, m14, m15;

    /**
     * Internal intermediate store for the transformed digest.
     * Set between 2 passes of 16 rounds each.<br/>
     * Needed because computeBlock() cannot be fully inlined and must be
     * splitted, due to the total bytecode size that would prohibit JIT
     * compilation at run-time and would give too slow performance if the
     * bytecode was interpreted (this problem affects both the client and
     * server VMs).
     */
    private int tA, tB, tC, tD, tE, tF, tG, tH;

    /**
     * Creates a SHA256 object with default initial state.
     */
    public SHA256() {
        pad = new byte[64];
        init();
    }

    /**
     * Clones this object.
     */
    public Object clone() throws CloneNotSupportedException  {
        SHA256 that = (SHA256)super.clone();
        that.pad = (byte[])this.pad.clone();
        return that;
    }

    /**
     * Reset then initialize the digest context.<br/>
     *
     * Overrides the protected abstract method of
     * <code>java.security.MessageDigestSpi</code>.
     * @modifies  this
     */
    public void engineReset() {
        int i = 60;
        do {
           pad[i    ] =
           pad[i + 1] =
           pad[i + 2] =
           pad[i + 3] = (byte)0x00;
        } while ((i -= 4) >= 0);
        bytes =
        padded =
        m00 = m01 = m02 = m03 = m04 = m05 = m06 = m07 =
        m08 = m09 = m10 = m11 = m12 = m13 = m14 = m15 =
        tA = tB = tC = tD = tE = tF = tG = tH = 0;
        init();
    }

    /**
     * Initialize the digest context.
     * @modifies  this
     */
    protected void init() {
        hA = 0x6a09e667;
        hB = 0xbb67ae85;
        hC = 0x3c6ef372;
        hD = 0xa54ff53a;
        hE = 0x510e527f;
        hF = 0x9b05688c;
        hG = 0x1f83d9ab;
        hH = 0x5be0cd19;
    }

    /**
     * Updates the digest using the specified byte.
     * Requires internal buffering, and may be slow.<br/>
     *
     * Overrides the protected abstract method of
     * <code>java.security.MessageDigestSpi</code>.
     * @param input  the byte to use for the update.
     * @modifies  this
     */
    public void engineUpdate(byte input) {
        bytes++;
        if (padded < 63) {
            pad[padded++] = input;
            return;
        }
        pad[63] = input;
        computeBlock(pad, padded = 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.<br/>
     *
     * Overrides the protected abstract method of
     * <code>java.security.MessageDigestSpi</code>.
     * @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.
     * @modifies  this
     */
    public void engineUpdate(byte[] input, int offset, int length) {
        if (offset >= 0 && length >= 0 && offset + length <= input.length) {
            bytes += length;
            /* Terminate the previous block. */
            if (padded > 0 && padded + length >= 64) {
                final int remaining;
                System.arraycopy(input, offset, pad, padded,
                    remaining = 64 - padded);
                computeBlock(pad, padded = 0);
                offset += remaining;
                length -= remaining;
            }
            /* Loop on large sets of complete blocks. */
            while (length >= 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;
                length -= 512;
            }
            /* Loop on remaining complete blocks. */
            while (length >= 64) {
                computeBlock(input, offset);
                offset += 64;
                length -= 64;
            }
            /* remaining bytes kept for next block. */
            if (length > 0) {
                System.arraycopy(input, offset, pad, padded, length);
                padded += length;
            }
            return;
        }
        throw new ArrayIndexOutOfBoundsException(offset);
    }

    /**
     * Completes the hash computation by performing final operations
     * such as padded. Computes the final hash and returns the final
     * value as a byte[32] array. Once engineDigest has been called,
     * the engine will be automatically reset as specified in the
     * JavaSecurity MessageDigest specification.<br/>
     *
     * For faster operations with multiple digests, allocate your own
     * array and use engineDigest(byte[], int offset, int len).<br/>
     *
     * Overrides the protected abstract method of
     * <code>java.security.MessageDigestSpi</code>.
     * @return the length of the digest stored in the output buffer.
     * @modifies  this
     */
    public byte[] engineDigest() {
        try {
            final byte hashvalue[] = new byte[32]; /* digest length in bytes */
            engineDigest(hashvalue, 0, 32); /* digest length in bytes */
            return hashvalue;
        } catch (DigestException e) {
            return null;
        }
    }

    /**
     * Returns the digest length in bytes. Can be used to allocate your own
     * output buffer when computing multiple digests.<br/>
     *
     * Overrides the protected abstract method of
     * <code>java.security.MessageDigestSpi</code>.
     * @return the digest length in bytes.
     */
    public int engineGetDigestLength() {
        return 32; /* digest length in bytes */
    }

    /**
     * Completes the hash computation by performing final operations
     * such as padded. Once engineDigest has been called, the engine
     * will be automatically reset (see engineReset).<br/>
     *
     * Overrides the protected abstract method of
     * <code>java.security.MessageDigestSpi</code>.
     * @param hashvalue  the output buffer in which to store the digest.
     * @param offset  offset to start from in the output buffer
     * @param length  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.
     * @modifies  this
     */
    public int engineDigest(byte[] hashvalue, int offset, final int length)
            throws DigestException {
        if (length >= 32) { /* digest length in bytes */
            if (hashvalue.length - offset >= 32) { /* digest length in bytes */
                /* Flush the trailing bytes, adding padded bytes into last
                 * blocks. */
                int i;
                /* Add padded null bytes but replace the last 8 padded bytes
                 * by the little-endian 64-bit digested message bit-length. */
                pad[i = padded] = (byte)0x80; /* required 1st padded 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    ] =
                        pad[i + 1] =
                        pad[i + 2] =
                        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] =
                            pad[ i       - 1] = (byte)0x00;
                            break;
                    case 0: pad[(i += 4) - 3] =
                            pad[ i       - 2] =
                            pad[ i       - 1] = (byte)0x00;
                    }
                    do {
                        pad[i    ] =
                        pad[i + 1] =
                        pad[i + 2] =
                        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;
                hashvalue[offset += 5] = (byte)((i = hF) >>> 24);
                hashvalue[offset +  1] = (byte)(i >>> 16);
                hashvalue[offset +  2] = (byte)(i >>> 8);
                hashvalue[offset +  3] = (byte)i;
                hashvalue[offset +  4] = (byte)((i = hG) >>> 24);
                hashvalue[offset += 5] = (byte)(i >>> 16);
                hashvalue[offset +  1] = (byte)(i >>> 8);
                hashvalue[offset +  2] = (byte)i;
                hashvalue[offset +  3] = (byte)((i = hH) >>> 24);
                hashvalue[offset +  4] = (byte)(i >>> 16);
                hashvalue[offset += 5] = (byte)(i >>> 8);
                hashvalue[offset +  1] = (byte)i;
                engineReset(); /* clear the evidence */
                return 32; /* digest length in bytes */
            }
            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.<br/>
     * Requires no internal buffering, but assumes a fixed input size,
     * in which the required padded 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.
     * @modifies  this
     */
    private final void computeBlock(final byte[] input, int offset) {
        /* Read input in big-endian order. */
        m00 =  input[offset     ] << 24
            | (input[offset +  1] & 0xff) << 16
            | (input[offset +  2] & 0xff) << 8
            | (input[offset +  3] & 0xff); /* W00 */
        m01 =  input[offset +  4] << 24
            | (input[offset += 5] & 0xff) << 16
            | (input[offset +  1] & 0xff) << 8
            | (input[offset +  2] & 0xff); /* W01 */
        m02 =  input[offset +  3] << 24
            | (input[offset +  4] & 0xff) << 16
            | (input[offset += 5] & 0xff) << 8
            | (input[offset +  1] & 0xff); /* W02 */
        m03 =  input[offset +  2] << 24
            | (input[offset +  3] & 0xff) << 16
            | (input[offset +  4] & 0xff) << 8
            | (input[offset += 5] & 0xff); /* W03 */
        m04 =  input[offset +  1] << 24
            | (input[offset +  2] & 0xff) << 16
            | (input[offset +  3] & 0xff) << 8
            | (input[offset +  4] & 0xff); /* W04 */
        m05 =  input[offset += 5] << 24
            | (input[offset +  1] & 0xff) << 16
            | (input[offset +  2] & 0xff) << 8
            | (input[offset +  3] & 0xff); /* W05 */
        m06 =  input[offset +  4] << 24
            | (input[offset += 5] & 0xff) << 16
            | (input[offset +  1] & 0xff) << 8
            | (input[offset +  2] & 0xff); /* W06 */
        m07 =  input[offset +  3] << 24
            | (input[offset +  4] & 0xff) << 16
            | (input[offset += 5] & 0xff) << 8
            | (input[offset +  1] & 0xff); /* W07 */
        m08 =  input[offset +  2] << 24
            | (input[offset +  3] & 0xff) << 16
            | (input[offset +  4] & 0xff) << 8
            | (input[offset += 5] & 0xff); /* W08 */
        m09 =  input[offset +  1] << 24
            | (input[offset +  2] & 0xff) << 16
            | (input[offset +  3] & 0xff) << 8
            | (input[offset +  4] & 0xff); /* W09 */
        m10 =  input[offset += 5] << 24
            | (input[offset +  1] & 0xff) << 16
            | (input[offset +  2] & 0xff) << 8
            | (input[offset +  3] & 0xff); /* W10 */
        m11 =  input[offset +  4] << 24
            | (input[offset += 5] & 0xff) << 16
            | (input[offset +  1] & 0xff) << 8
            | (input[offset +  2] & 0xff); /* W11 */
        m12 =  input[offset +  3] << 24
            | (input[offset +  4] & 0xff) << 16
            | (input[offset += 5] & 0xff) << 8
            | (input[offset +  1] & 0xff); /* W12 */
        m13 =  input[offset +  2] << 24
            | (input[offset +  3] & 0xff) << 16
            | (input[offset +  4] & 0xff) << 8
            | (input[offset += 5] & 0xff); /* W13 */
        m14 =  input[offset +  1] << 24
            | (input[offset +  2] & 0xff) << 16
            | (input[offset +  3] & 0xff) << 8
            | (input[offset +  4] & 0xff); /* W14 */
        m15 =  input[offset += 5] << 24
            | (input[offset +  1] & 0xff) << 16
            | (input[offset +  2] & 0xff) << 8
            | (input[offset +  3] & 0xff); /* W15 */
        /* Due to code size, a complete inlining is not possible as it
         * prohibits JIT of compiling the bytecode at run-time for the fastest
         * performance. So we need some extra local stores in this instance to
         * store the scheduled input, and the intermediate sub-digest between
         * each pass.
         */
        pass1(); /* rounds 0..15 */
        pass2(); /* rounds 16..31 */
        pass3(); /* rounds 32..47 */
        pass4(); /* rounds 48..63 */
    }

    /*
     * Rotation function operates on 32-bit words:
     *  ROTR(x, n) = (x >> n) | (x << (32 - n))
     *             = (x >> n) ^ (x << (32 - n));
     * Key schedule functions:
     *  Sigma0(x) = ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)
     *            = (x >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
     *              (x << 10) ^ (x << 19) ^ (x << 30);
     *  Sigma1(x) = ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)
     *            = (x >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
     *              (x << 7) ^ (x << 21) ^ (x << 26);
     *  Ch(x, y, z) = (x & y) ^ (~x & z)
     *              = (x & (y ^ z)) ^ z;
     *  Maj(x, y, z) = (x & y) ^ (x & z) ^ (y & z)
     *               = (x & y) | ((x | y) & z);
     * The 64 constant 32-bit words K00..K63 are the first 32 bits of the
     * fractional part of the cube root of the first 64 prime numbers; in hex:
     *  428a2f98 71374491 b5c0fbcf e9b5dba5 3956c25b 59f111f1 923f82a4 ab1c5ed5
     *  d807aa98 12835b01 243185be 550c7dc3 72be5d74 80deb1fe 9bdc06a7 c19bf174
     *  e49b69c1 efbe4786 0fc19dc6 240ca1cc 2de92c6f 4a7484aa 5cb0a9dc 76f988da
     *  983e5152 a831c66d b00327c8 bf597fc7 c6e00bf3 d5a79147 06ca6351 14292967
     *  27b70a85 2e1b2138 4d2c6dfc 53380d13 650a7354 766a0abb 81c2c92e 92722c85
     *  a2bfe8a1 a81a664b c24b8b70 c76c51a3 d192e819 d6990624 f40e3585 106aa070
     *  19a4c116 1e376c08 2748774c 34b0bcb5 391c0cb3 4ed8aa4a 5b9cca4f 682e6ff3
     *  748f82ee 78a5636f 84c87814 8cc70208 90befffa a4506ceb bef9a3f7 c67178f2.
     * Input schedule functions (used in rounds 16..63):
     *  sigma0(x) = ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)
     *            = (x >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
     *              (x << 14) ^ (x << 25);
     *  sigma1(x) = ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)
     *            = (x >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
     *              (x << 13) ^ (x << 15);
     */

    /**
     * First pass, on big-endian input (rounds 0..15).
     *
     * @modifies  this
     */
    private final void pass1() {
        /* Local temporary work variables for intermediate digests. */
        int x; /* temporary: only 3 first variables have optimized bytecode. */
        int a, b, /* local variables with optimized bytecodes. */
            c, d, e, f, g, h; /* local variables with longer bytecodes. */
        /* 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;

        /* Reload the current digest on the fly in the first round. */
        d = hD
          +(x = hH + (((x = e = hE) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(e) */
                   + ((x & ((f = hF) ^ (g = hG))) ^ g) /* Ch(e, f, g) */
                   + 0x428a2f98 /* K00 */
                   + m00 /* W00 */
           );
        h = x + (((a = hA) >>> 2) ^ (a >>> 13) ^ (a >>> 22) ^
                 (a << 10) ^ (a << 19) ^ (a << 30)) /* Sigma0(a) */
              + ((a & (b = hB)) | ((a | b) & (c = hC))) /* Maj(a, b, c) */;

        /* Normal rounds. */
        c += x = g + (((x = d) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(d) */
                   + ((x & (e ^ f)) ^ f) /* Ch(d, e, f) */
                   + 0x71374491 /* K01 */
                   + m01 /* W01 */;
        g = x + (((x = h) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(h) */
              + ((x & a) | ((x | a) & b)) /* Maj(h, a, b) */;

        b += x = f + (((x = c) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(c) */
                   + ((x & (d ^ e)) ^ e) /* Ch(c, d, e) */
                   + 0xb5c0fbcf /* K02 */
                   + m02 /* W02 */;
        f = x + (((x = g) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(g) */
              + ((x & h) | ((x | h) & a)) /* Maj(g, h, a) */;

        a += x = e + ((b >>> 6) ^ (b >>> 11) ^ (b >>> 25) ^
                      (b << 7) ^ (b << 21) ^ (b << 26)) /* Sigma1(b) */
                   + ((b & (c ^ d)) ^ d) /* Ch(b, c, d) */
                   + 0xe9b5dba5 /* K03 */
                   + m03 /* W03 */;
        e = x + (((x = f) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(f) */
              + ((x & g) | ((x | g) & h)) /* Maj(f, g, h) */;

        h += x = d + ((a >>> 6) ^ (a >>> 11) ^ (a >>> 25) ^
                      (a << 7) ^ (a << 21) ^ (a << 26)) /* Sigma1(a) */
                   + ((a & (b ^ c)) ^ c) /* Ch(a, b, c) */
                   + 0x3956c25b /* K04 */
                   + m04 /* W04 */;
        d = x + (((x = e) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(e) */
              + ((x & f) | ((x | f) & g)) /* Maj(e, f, g) */;

        g += x = c + (((x = h) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(h) */
                   + ((x & (a ^ b)) ^ b) /* Ch(h, a, b) */
                   + 0x59f111f1 /* K05 */
                   + m05 /* W05 */;
        c = x + (((x = d) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(d) */
              + ((x & e) | ((x | e) & f)) /* Maj(d, e, f) */;

        f +=     b +=(((x = g) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(g) */
                   + ((x & (h ^ a)) ^ a) /* Ch(g, h, a) */
                   + 0x923f82a4 /* K06 */
                   + m06 /* W06 */;
        b     +=(((x = c) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(c) */
              + ((x & d) | ((x | d) & e)) /* Maj(c, d, e) */;

        e +=     a +=(((x = f) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(f) */
                   + ((x & (g ^ h)) ^ h) /* Ch(f, g, h) */
                   + 0xab1c5ed5 /* K07 */
                   + m07 /* W07 */;
        a     +=((b >>> 2) ^ (b >>> 13) ^ (b >>> 22) ^
                 (b << 10) ^ (b << 19) ^ (b << 30)) /* Sigma0(b) */
              + ((b & c) | ((b | c) & d)) /* Maj(b, c, d) */;

        d += x = h + (((x = e) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(e) */
                   + ((x & (f ^ g)) ^ g) /* Ch(e, f, g) */
                   + 0xd807aa98 /* K08 */
                   + m08 /* W08 */;
        h = x + ((a >>> 2) ^ (a >>> 13) ^ (a >>> 22) ^
                 (a << 10) ^ (a << 19) ^ (a << 30)) /* Sigma0(a) */
              + ((a & b) | ((a | b) & c)) /* Maj(a, b, c) */;

        c += x = g + (((x = d) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(d) */
                   + ((x & (e ^ f)) ^ f) /* Ch(d, e, f) */
                   + 0x12835b01 /* K09 */
                   + m09 /* W09 */;
        g = x + (((x = h) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(h) */
              + ((x & a) | ((x | a) & b)) /* Maj(h, a, b) */;

        b += x = f + (((x = c) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(c) */
                   + ((x & (d ^ e)) ^ e) /* Ch(c, d, e) */
                   + 0x243185be /* K10 */
                   + m10 /* W10 */;
        f = x + (((x = g) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(g) */
              + ((x & h) | ((x | h) & a)) /* Maj(g, h, a) */;

        a += x = e + ((b >>> 6) ^ (b >>> 11) ^ (b >>> 25) ^
                      (b << 7) ^ (b << 21) ^ (b << 26)) /* Sigma1(b) */
                   + ((b & (c ^ d)) ^ d) /* Ch(b, c, d) */
                   + 0x550c7dc3 /* K11 */
                   + m11 /* W11 */;
        e = x + (((x = f) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(f) */
              + ((x & g) | ((x | g) & h)) /* Maj(f, g, h) */;

        /* Preserve the current sub-digest on the fly in the last 4 rounds. */
        tH =
        h += x = d + ((a >>> 6) ^ (a >>> 11) ^ (a >>> 25) ^
                      (a << 7) ^ (a << 21) ^ (a << 26)) /* Sigma1(a) */
                   + ((a & (b ^ c)) ^ c) /* Ch(a, b, c) */
                   + 0x72be5d74 /* K12 */
                   + m12 /* W12 */;
        tD =
        d = x + (((x = e) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(e) */
              + ((x & f) | ((x | f) & g)) /* Maj(e, f, g) */;

        tG =
        g += x = c + (((x = h) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(h) */
                   + ((x & (a ^ b)) ^ b) /* Ch(h, a, b) */
                   + 0x80deb1fe /* K13 */
                   + m13 /* W13 */;
        tC =
        c = x + (((x = d) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(d) */
              + ((x & e) | ((x | e) & f)) /* Maj(d, e, f) */;

        tF =
        f +=     b +=(((x = g) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(g) */
                   + ((x & (h ^ a)) ^ a) /* Ch(g, h, a) */
                   + 0x9bdc06a7 /* K14 */
                   + m14 /* W14 */;
        tB =
        b     +=(((x = c) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(c) */
              + ((x & d) | ((x | d) & e)) /* Maj(c, d, e) */;

        tE =
        e +(     a +=(((x = f) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(f) */
                   + ((x & (g ^ h)) ^ h) /* Ch(f, g, h) */
                   + 0xc19bf174 /* K15 */
                   + m15 /* W15 */
           );
        tA =
        a     + ((b >>> 2) ^ (b >>> 13) ^ (b >>> 22) ^
                 (b << 10) ^ (b << 19) ^ (b << 30)) /* Sigma0(b) */
              + ((b & c) | ((b | c) & d)) /* Maj(b, c, d) */;
    }
    
    /**
     * Second pass, on scheduled input (rounds 16..31).
     *
     * @modifies  this
     */
    private final void pass2() {
        /* Local temporary work variables for intermediate digests. */
        int x; /* temporary: only 3 first variables have optimized bytecode. */
        int a, b, /* local variables with optimized bytecodes. */
            c, d, e, f, g, h; /* local variables with longer bytecodes. */
        /* Cache the scheduled input block. */
        int i00, i01, i02, i03, i04, i05, i06, i07,
            i08, i09, i10, i11, i12, i13, i14, i15;

        /* Reload the current sub-digest on the fly in the first round. */
        d = tD
          +(x = tH + (((x = e = tE) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(e) */
                   + ((x & ((f = tF) ^ (g = tG))) ^ g) /* Ch(e, f, g) */
                   + 0xe49b69c1 /* K16 */
                   + (m00 = i00 = m00 + (i09 = m09) /* W09 */
                        + (((x = i14 = m14) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W14) */
                        + (((x = i01 = m01) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W01) */
                     ) /* W16 */
           );
        h = x + (((a = tA) >>> 2) ^ (a >>> 13) ^ (a >>> 22) ^
                 (a << 10) ^ (a << 19) ^ (a << 30)) /* Sigma0(a) */
              + ((a & (b = tB)) | ((a | b) & (c = tC))) /* Maj(a, b, c) */;

        /* Normal rounds. */
        c += x = g + (((x = d) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(d) */
                   + ((x & (e ^ f)) ^ f) /* Ch(d, e, f) */
                   + 0xefbe4786 /* K17 */
                   + (m01 = i01 += (i10 = m10) /* W10 */
                        + (((x = i15 = m15) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x <<  13) ^ (x << 15)) /* sigma1(W15) */
                        + (((x = i02 = m02) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W02) */
                     ) /* W17 */;
        g = x + (((x = h) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(h) */
              + ((x & a) | ((x | a) & b)) /* Maj(h, a, b) */;

        b += x = f + (((x = c) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(c) */
                   + ((x & (d ^ e)) ^ e) /* Ch(c, d, e) */
                   + 0x0fc19dc6 /* K18 */
                   + (m02 = i02 += (i11 = m11) /* W11 */
                        + (((x = i00) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W16) */
                        + (((x = i03 = m03) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W03) */
                     ) /* W18 */;
        f = x + (((x = g) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(g) */
              + ((x & h) | ((x | h) & a)) /* Maj(g, h, a) */;

        a += x = e + ((b >>> 6) ^ (b >>> 11) ^ (b >>> 25) ^
                      (b << 7) ^ (b << 21) ^ (b << 26)) /* Sigma1(b) */
                   + ((b & (c ^ d)) ^ d) /* Ch(b, c, d) */
                   + 0x240ca1cc /* K19 */
                   + (m03 = i03 += (i12 = m12) /* W12 */
                        + (((x = i01) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (i01 << 15)) /* sigma1(W17) */
                        + (((x = i04 = m04) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W04) */
                     ) /* W19 */;
        e = x + (((x = f) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(f) */
              + ((x & g) | ((x | g) & h)) /* Maj(f, g, h) */;

        h += x = d + ((a >>> 6) ^ (a >>> 11) ^ (a >>> 25) ^
                      (a << 7) ^ (a << 21) ^ (a << 26)) /* Sigma1(a) */
                   + ((a & (b ^ c)) ^ c) /* Ch(a, b, c) */
                   + 0x2de92c6f /* K20 */
                   + (m04 = i04 += (i13 = m13) /* W13 */
                        + (((x = i02) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W18) */
                        + (((x = i05 = m05) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W05) */
                     ) /* W20 */;
        d = x + (((x = e) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(e) */
              + ((x & f) | ((x | f) & g)) /* Maj(e, f, g) */;

        g += x = c + (((x = h) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(h) */
                   + ((x & (a ^ b)) ^ b) /* Ch(h, a, b) */
                   + 0x4a7484aa /* K21 */
                   + (m05 = i05 += i14 /* W14 */
                        + (((x = i03) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W19) */
                        + (((x = i06 = m06) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W06) */
                     ) /* W21 */;
        c = x + (((x = d) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(d) */
              + ((x & e) | ((x | e) & f)) /* Maj(d, e, f) */;

        f +=     b +=(((x = g) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(g) */
                   + ((x & (h ^ a)) ^ a) /* Ch(g, h, a) */
                   + 0x5cb0a9dc /* K22 */
                   + (m06 = i06 += i15 /* W15 */
                        + (((x = i04) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W20) */
                        + (((x = i07 = m07) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W07) */
                     ) /* W22 */;
        b     +=(((x = c) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(c) */
              + ((x & d) | ((x | d) & e)) /* Maj(c, d, e) */;

        e +=     a +=(((x = f) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(f) */
                   + ((x & (g ^ h)) ^ h) /* Ch(f, g, h) */
                   + 0x76f988da /* K23 */
                   + (m07 = i07 += i00 /* W16 */
                        + (((x = i05) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W21) */
                        + (((x = i08 = m08) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W08) */
                     ) /* W23 */;
        a     +=((b >>> 2) ^ (b >>> 13) ^ (b >>> 22) ^
                 (b << 10) ^ (b << 19) ^ (b << 30)) /* Sigma0(b) */
              + ((b & c) | ((b | c) & d)) /* Maj(b, c, d) */;

        d += x = h + (((x = e) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(e) */
                   + ((x & (f ^ g)) ^ g) /* Ch(e, f, g) */
                   + 0x983e5152 /* K24 */
                   + (m08 = i08 += i01 /* W17 */
                        + (((x = i06) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W22) */
                        + (((x = i09) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W09) */
                     ) /* W24 */;
        h = x + ((a >>> 2) ^ (a >>> 13) ^ (a >>> 22) ^
                 (a << 10) ^ (a << 19) ^ (a << 30)) /* Sigma0(a) */
              + ((a & b) | ((a | b) & c)) /* Maj(a, b, c) */;

        c += x = g + (((x = d) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(d) */
                   + ((x & (e ^ f)) ^ f) /* Ch(d, e, f) */
                   + 0xa831c66d /* K25 */
                   + (m09 = i09 += i02 /* W18 */
                        + (((x = i07) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W23) */
                        + (((x = i10) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W10) */
                     ) /* W25 */;
        g = x + (((x = h) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(h) */
              + ((x & a) | ((x | a) & b)) /* Maj(h, a, b) */;

        b += x = f + (((x = c) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(c) */
                   + ((x & (d ^ e)) ^ e) /* Ch(c, d, e) */
                   + 0xb00327c8 /* K26 */
                   + (m10 = i10 += i03 /* W19 */
                        + (((x = i08) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W24) */
                        + (((x = i11) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W11) */
                     ) /* W26 */;
        f = x + (((x = g) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(g) */
              + ((x & h) | ((x | h) & a)) /* Maj(g, h, a) */;

        a += x = e + ((b >>> 6) ^ (b >>> 11) ^ (b >>> 25) ^
                      (b << 7) ^ (b << 21) ^ (b << 26)) /* Sigma1(b) */
                   + ((b & (c ^ d)) ^ d) /* Ch(b, c, d) */
                   + 0xbf597fc7 /* K27 */
                   + (m11 = i11 += i04 /* W20 */
                        + (((x = i09) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W25) */
                        + (((x = i12) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W12) */
                     ) /* W27 */;
        e = x + (((x = f) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(f) */
              + ((x & g) | ((x | g) & h)) /* Maj(f, g, h) */;

        /* Preserve the current sub-digest on the fly in the last 4 rounds. */
        tH =
        h += x = d + ((a >>> 6) ^ (a >>> 11) ^ (a >>> 25) ^
                      (a << 7) ^ (a << 21) ^ (a << 26)) /* Sigma1(a) */
                   + ((a & (b ^ c)) ^ c) /* Ch(a, b, c) */
                   + 0xc6e00bf3 /* K28 */
                   + (m12 = i12 += i05 /* W21 */
                        + (((x = i10) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W26) */
                        + (((x = i13) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W13) */
                     ) /* W28 */;
        tD =
        d = x + (((x = e) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(e) */
              + ((x & f) | ((x | f) & g)) /* Maj(e, f, g) */;

        tG =
        g += x = c + (((x = h) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(h) */
                   + ((x & (a ^ b)) ^ b) /* Ch(h, a, b) */
                   + 0xd5a79147 /* K29 */
                   + (m13 = i13 += i06 /* W22 */
                        + (((x = i11) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W27) */
                        + (((x = i14) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W14) */
                     ) /* W29 */;
        tC =                
        c = x + (((x = d) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(d) */
              + ((x & e) | ((x | e) & f)) /* Maj(d, e, f) */;

        tF =
        f +=     b +=(((x = g) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(g) */
                   + ((x & (h ^ a)) ^ a) /* Ch(g, h, a) */
                   + 0x06ca6351 /* K30 */
                   + (m14 = i14 += i07 /* W23 */
                        + (((x = i12) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W28) */
                        + (((x = i15) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W15) */
                     ) /* W30 */;
        tB =
        b     +=(((x = c) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(c) */
              + ((x & d) | ((x | d) & e)) /* Maj(c, d, e) */;

        tE =
        e +(     a +=(((x = f) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(f) */
                   + ((x & (g ^ h)) ^ h) /* Ch(f, g, h) */
                   + 0x14292967 /* K31 */
                   + (m15 = i15 += i08 /* W24 */
                        + (((x = i13) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W29) */
                        + (((x = i00) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W16) */
                     ) /* W31 */
           );
        tA =
        a     + ((b >>> 2) ^ (b >>> 13) ^ (b >>> 22) ^
                 (b << 10) ^ (b << 19) ^ (b << 30)) /* Sigma0(b) */
              + ((b & c) | ((b | c) & d)) /* Maj(b, c, d) */;
    }

    /**
     * Third pass, on scheduled input (rounds 32..47).
     *
     * @modifies  this
     */
    private final void pass3() {
        /* Local temporary work variables for intermediate digests. */
        int x; /* temporary: only 3 first variables have optimized bytecode. */
        int a, b, /* local variables with optimized bytecodes. */
            c, d, e, f, g, h; /* local variables with longer bytecodes. */
        /* Cache the scheduled input block. */
        int i00, i01, i02, i03, i04, i05, i06, i07,
            i08, i09, i10, i11, i12, i13, i14, i15;

        /* Reload the current sub-digest on the fly in the first round. */
        d = tD
          +(x = tH + (((x = e = tE) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(e) */
                   + ((x & ((f = tF) ^ (g = tG))) ^ g) /* Ch(e, f, g) */
                   + 0x27b70a85 /* K32 */
                   + (m00 = i00 = m00 + (i09 = m09) /* W25 */
                        + (((x = i14 = m14) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W30) */
                        + (((x = i01 = m01) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W17) */
                     ) /* W32 */
           );
        h = x + (((a = tA) >>> 2) ^ (a >>> 13) ^ (a >>> 22) ^
                 (a << 10) ^ (a << 19) ^ (a << 30)) /* Sigma0(a) */
              + ((a & (b = tB)) | ((a | b) & (c = tC))) /* Maj(a, b, c) */;

        /* Normal rounds. */
        c += x = g + (((x = d) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(d) */
                   + ((x & (e ^ f)) ^ f) /* Ch(d, e, f) */
                   + 0x2e1b2138 /* K33 */
                   + (m01 = i01 += (i10 = m10) /* W26 */
                        + (((x = i15 = m15) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W31) */
                        + (((x = i02 = m02) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W18) */
                     ) /* W33 */;
        g = x + (((x = h) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(h) */
              + ((x & a) | ((x | a) & b)) /* Maj(h, a, b) */;

        b += x = f + (((x = c) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(c) */
                   + ((x & (d ^ e)) ^ e) /* Ch(c, d, e) */
                   + 0x4d2c6dfc /* K34 */
                   + (m02 = i02 += (i11 = m11) /* W27 */
                        + (((x = i00) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W32) */
                        + (((x = i03 = m03) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W19) */
                     ) /* W34 */;
        f = x + (((x = g) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(g) */
              + ((x & h) | ((x | h) & a)) /* Maj(g, h, a) */;

        a += x = e + ((b >>> 6) ^ (b >>> 11) ^ (b >>> 25) ^
                      (b << 7) ^ (b << 21) ^ (b << 26)) /* Sigma1(b) */
                   + ((b & (c ^ d)) ^ d) /* Ch(b, c, d) */
                   + 0x53380d13 /* K35 */
                   + (m03 = i03 += (i12 = m12) /* W28 */
                        + (((x = i01) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W33) */
                        + (((x = i04 = m04) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W20) */
                     ) /* W35 */;
        e = x + (((x = f) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(f) */
              + ((x & g) | ((x | g) & h)) /* Maj(f, g, h) */;

        h += x = d + ((a >>> 6) ^ (a >>> 11) ^ (a >>> 25) ^
                      (a << 7) ^ (a << 21) ^ (a << 26)) /* Sigma1(a) */
                   + ((a & (b ^ c)) ^ c) /* Ch(a, b, c) */
                   + 0x650a7354 /* K36 */
                   + (m04 = i04 += (i13 = m13) /* W29 */
                        + (((x = i02) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W34) */
                        + (((x = i05 = m05) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W21) */
                     ) /* W36 */;
        d = x + (((x = e) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(e) */
              + ((x & f) | ((x | f) & g)) /* Maj(e, f, g) */;

        g += x = c + (((x = h) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(h) */
                   + ((x & (a ^ b)) ^ b) /* Ch(h, a, b) */
                   + 0x766a0abb /* K37 */
                   + (m05 = i05 += i14 /* W30 */
                        + (((x = i03) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W35) */
                        + (((x = i06 = m06) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W22) */
                     ) /* W37 */;
        c = x + (((x = d) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(d) */
              + ((x & e) | ((x | e) & f)) /* Maj(d, e, f) */;

        f +=     b +=(((x = g) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(g) */
                   + ((x & (h ^ a)) ^ a) /* Ch(g, h, a) */
                   + 0x81c2c92e /* K38 */
                   + (m06 = i06 += i15 /* W31 */
                        + (((x = i04) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W36) */
                        + (((x = i07 = m07) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W23) */
                     ) /* W38 */;
        b     +=(((x = c) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(c) */
              + ((x & d) | ((x | d) & e)) /* Maj(c, d, e) */;

        e +=     a +=(((x = f) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(f) */
                   + ((x & (g ^ h)) ^ h) /* Ch(f, g, h) */
                   + 0x92722c85 /* K39 */
                   + (m07 = i07 += i00 /* W32 */
                        + (((x = i05) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W37) */
                        + (((x = i08 = m08) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W24) */
                     ) /* W39 */;
        a     +=((b >>> 2) ^ (b >>> 13) ^ (b >>> 22) ^
                 (b << 10) ^ (b << 19) ^ (b << 30)) /* Sigma0(b) */
              + ((b & c) | ((b | c) & d)) /* Maj(b, c, d) */;

        d += x = h + (((x = e) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(e) */
                   + ((x & (f ^ g)) ^ g) /* Ch(e, f, g) */
                   + 0xa2bfe8a1 /* K40 */
                   + (m08 = i08 += i01 /* W33 */
                        + (((x = i06) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W38) */
                        + (((x = i09) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W25) */
                     ) /* W40 */;
        h = x + ((a >>> 2) ^ (a >>> 13) ^ (a >>> 22) ^
                 (a << 10) ^ (a << 19) ^ (a << 30)) /* Sigma0(a) */
              + ((a & b) | ((a | b) & c)) /* Maj(a, b, c) */;

        c += x = g + (((x = d) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(d) */
                   + ((x & (e ^ f)) ^ f) /* Ch(d, e, f) */
                   + 0xa81a664b /* K41 */
                   + (m09 = i09 += i02 /* W34 */
                        + (((x = i07) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W39) */
                        + (((x = i10) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W26) */
                     ) /* W41 */;
        g = x + (((x = h) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(h) */
              + ((x & a) | ((x | a) & b)) /* Maj(h, a, b) */;

        b += x = f + (((x = c) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(c) */
                   + ((x & (d ^ e)) ^ e) /* Ch(c, d, e) */
                   + 0xc24b8b70 /* K42 */
                   + (m10 = i10 += i03 /* W35 */
                        + (((x = i08) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W40) */
                        + (((x = i11) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W27) */
                     ) /* W42 */;
        f = x + (((x = g) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(g) */
              + ((x & h) | ((x | h) & a)) /* Maj(g, h, a) */;

        a += x = e + ((b >>> 6) ^ (b >>> 11) ^ (b >>> 25) ^
                      (b << 7) ^ (b << 21) ^ (b << 26)) /* Sigma1(b) */
                   + ((b & (c ^ d)) ^ d) /* Ch(b, c, d) */
                   + 0xc76c51a3 /* K43 */
                   + (m11 = i11 += i04 /* W36 */
                        + (((x = i09) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W41) */
                        + (((x = i12) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W28) */
                     ) /* W43 */;
        e = x + (((x = f) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(f) */
              + ((x & g) | ((x | g) & h)) /* Maj(f, g, h) */;

        /* Preserve the current sub-digest on the fly in the last 4 rounds. */
        tH =
        h += x = d + ((a >>> 6) ^ (a >>> 11) ^ (a >>> 25) ^
                      (a << 7) ^ (a << 21) ^ (a << 26)) /* Sigma1(a) */
                   + ((a & (b ^ c)) ^ c) /* Ch(a, b, c) */
                   + 0xd192e819 /* K44 */
                   + (m12 = i12 += i05 /* W37 */
                        + (((x = i10) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W42) */
                        + (((x = i13) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W29) */
                     ) /* W44 */;
        tD =
        d = x + (((x = e) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(e) */
              + ((x & f) | ((x | f) & g)) /* Maj(e, f, g) */;

        tG =
        g += x = c + (((x = h) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(h) */
                   + ((x & (a ^ b)) ^ b) /* Ch(h, a, b) */
                   + 0xd6990624 /* K45 */
                   + (m13 = i13 += i06 /* W38 */
                        + (((x = i11) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W43) */
                        + (((x = i14) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W30) */
                     ) /* W45 */;
        tC =
        c = x + (((x = d) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(d) */
              + ((x & e) | ((x | e) & f)) /* Maj(d, e, f) */;

        tF =
        f +=     b +=(((x = g) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(g) */
                   + ((x & (h ^ a)) ^ a) /* Ch(g, h, a) */
                   + 0xf40e3585 /* K46 */
                   + (m14 = i14 += i07 /* W39 */
                        + (((x = i12) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W44) */
                        + (((x = i15) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W31) */
                     ) /* W46 */;
        tB =
        b     +=(((x = c) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(c) */
              + ((x & d) | ((x | d) & e)) /* Maj(c, d, e) */;

        tE =
        e +(     a +=(((x = f) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(f) */
                   + ((x & (g ^ h)) ^ h) /* Ch(f, g, h) */
                   + 0x106aa070 /* K47 */
                   + (m15 = i15 += i08 /* W40 */
                        + (((x = i13) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W45) */
                        + (((x = i00) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W32) */
                     ) /* W47 */
           );
        tA =
        a     + ((b >>> 2) ^ (b >>> 13) ^ (b >>> 22) ^
                 (b << 10) ^ (b << 19) ^ (b << 30)) /* Sigma0(b) */
              + ((b & c) | ((b | c) & d)) /* Maj(b, c, d) */;
    }

    /**
     * Last pass, on scheduled input (rounds 48..63).
     *
     * @modifies  this
     */
    private final void pass4() {
        /* Local temporary work variables for intermediate digests. */
        int x; /* temporary: only 3 first variables have optimized bytecode. */
        int a, b, /* local variables with optimized bytecodes. */
            c, d, e, f, g, h; /* local variables with longer bytecodes. */
        /* Cache the scheduled input block. */
        int i00, i01, i02, i03, i04, i05, i06, i07,
            i08, i09, i10, i11, i12, i13, i14, i15;

        /* Reload the current sub-digest on the fly in the first round. */
        d = tD
          +(x = tH + (((x = e = tE) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(e) */
                   + ((x & ((f = tF) ^ (g = tG))) ^ g) /* Ch(e, f, g) */
                   + 0x19a4c116 /* K48 */
                   + (i00 = m00 + (i09 = m09) /* W41 */
                        + (((x = i14 = m14) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W46) */
                        + (((x = i01 = m01) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W33) */
                     ) /* W48 */
          );
        h = x + (((a = tA) >>> 2) ^ (a >>> 13) ^ (a >>> 22) ^
                 (a << 10) ^ (a << 19) ^ (a << 30)) /* Sigma0(a) */
              + ((a & (b = tB)) | ((a | b) & (c = tC))) /* Maj(a, b, c) */;

        /* Normal rounds. */
        c += x = g + (((x = d) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(d) */
                   + ((x & (e ^ f)) ^ f) /* Ch(d, e, f) */
                   + 0x1e376c08 /* K49 */
                   + (i01 += (i10 = m10) /* W42 */
                        + (((x = i15 = m15) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W47) */
                        + (((x = i02 = m02) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W34) */
                     ) /* W49 */;
        g = x + (((x = h) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(h) */
              + ((x & a) | ((x | a) & b)) /* Maj(h, a, b) */;

        b += x = f + (((x = c) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(c) */
                   + ((x & (d ^ e)) ^ e) /* Ch(c, d, e) */
                   + 0x2748774c /* K50 */
                   + (i02 += (i11 = m11) /* W43 */
                        + (((x = i00) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W48) */
                        + (((x = i03 = m03) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W35) */
                     ) /* W50 */;
        f = x + (((x = g) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(g) */
              + ((x & h) | ((x | h) & a)) /* Maj(g, h, a) */;

        a += x = e + ((b >>> 6) ^ (b >>> 11) ^ (b >>> 25) ^
                      (b << 7) ^ (b << 21) ^ (b << 26)) /* Sigma1(b) */
                   + ((b & (c ^ d)) ^ d) /* Ch(b, c, d) */
                   + 0x34b0bcb5 /* K51 */
                   + (i03 += (i12 = m12) /* W44 */
                        + (((x = i01) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W49) */
                        + (((x = i04 = m04) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W36) */
                     ) /* W51 */;
        e = x + (((x = f) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(f) */
              + ((x & g) | ((x | g) & h)) /* Maj(f, g, h) */;

        h += x = d + ((a >>> 6) ^ (a >>> 11) ^ (a >>> 25) ^
                      (a << 7) ^ (a << 21) ^ (a << 26)) /* Sigma1(a) */
                   + ((a & (b ^ c)) ^ c) /* Ch(a, b, c) */
                   + 0x391c0cb3 /* K52 */
                   + (i04 += (i13 = m13) /* W45 */
                        + (((x = i02) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W50) */
                        + (((x = i05 = m05) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W37) */
                     ) /* W52 */;
        d = x + (((x = e) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(e) */
              + ((x & f) | ((x | f) & g)) /* Maj(e, f, g) */;

        g += x = c + (((x = h) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(h) */
                   + ((x & (a ^ b)) ^ b) /* Ch(h, a, b) */
                   + 0x4ed8aa4a /* K53 */
                   + (i05 += i14 /* W46 */
                        + (((x = i03) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W51) */
                        + (((x = i06 = m06) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W38) */
                     ) /* W53 */;
        c = x + (((x = d) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(d) */
              + ((x & e) | ((x | e) & f)) /* Maj(d, e, f) */;

        f +=     b +=(((x = g) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(g) */
                   + ((x & (h ^ a)) ^ a) /* Ch(g, h, a) */
                   + 0x5b9cca4f /* K54 */
                   + (i06 += i15 /* W47 */
                        + (((x = i04) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W52) */
                        + (((x = i07 = m07) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W39) */
                     ) /* W54 */;
        b     +=(((x = c) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(c) */
              + ((x & d) | ((x | d) & e)) /* Maj(c, d, e) */;

        e +=     a +=(((x = f) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(f) */
                   + ((x & (g ^ h)) ^ h) /* Ch(f, g, h) */
                   + 0x682e6ff3 /* K55 */
                   + (i07 += i00 /* W48 */
                        + (((x = i05) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W53) */
                        + (((x = i08 = m08) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W40) */
                     ) /* W55 */;
        a     +=((b >>> 2) ^ (b >>> 13) ^ (b >>> 22) ^
                 (b << 10) ^ (b << 19) ^ (b << 30)) /* Sigma0(b) */
              + ((b & c) | ((b | c) & d)) /* Maj(b, c, d) */;

        d += x = h + (((x = e) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(e) */
                   + ((x & (f ^ g)) ^ g) /* Ch(e, f, g) */
                   + 0x748f82ee /* K56 */
                   + (i08 += i01 /* W49 */
                        + (((x = i06) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W54) */
                        + (((x = i09) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W41) */
                     ) /* W56 */;
        h = x + ((a >>> 2) ^ (a >>> 13) ^ (a >>> 22) ^
                 (a << 10) ^ (a << 19) ^ (a << 30)) /* Sigma0(a) */
              + ((a & b) | ((a | b) & c)) /* Maj(a, b, c) */;

        c += x = g + (((x = d) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(d) */
                   + ((x & (e ^ f)) ^ f) /* Ch(d, e, f) */
                   + 0x78a5636f /* K57 */
                   + (i09 += i02 /* W50 */
                        + (((x = i07) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W55) */
                        + (((x = i10) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W42) */
                     ) /* W57 */;
        g = x + (((x = h) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(h) */
              + ((x & a) | ((x | a) & b)) /* Maj(h, a, b) */;

        b += x = f + (((x = c) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(c) */
                   + ((x & (d ^ e)) ^ e) /* Ch(c, d, e) */
                   + 0x84c87814 /* K58 */
                   + (i10 += i03 /* W5 */
                        + (((x = i08) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W56) */
                        + (((x = i11) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W43) */
                     ) /* W58 */;
        f = x + (((x = g) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(g) */
              + ((x & h) | ((x | h) & a)) /* Maj(g, h, a) */;

        a += x = e + ((b >>> 6) ^ (b >>> 11) ^ (b >>> 25) ^
                      (b << 7) ^ (b << 21) ^ (b << 26)) /* Sigma1(b) */
                   + ((b & (c ^ d)) ^ d) /* Ch(b, c, d) */
                   + 0x8cc70208 /* K59 */
                   + (i11 += i04 /* W52 */
                        + (((x = i09) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W57) */
                        + (((x = i12) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W44) */
                     ) /* W59 */;
        e = x + (((x = f) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(f) */
              + ((x & g) | ((x | g) & h)) /* Maj(f, g, h) */;

        /* Update the final digest on the fly in the last 4 rounds. */
        hH +=
        h += x = d + ((a >>> 6) ^ (a >>> 11) ^ (a >>> 25) ^
                      (a << 7) ^ (a << 21) ^ (a << 26)) /* Sigma1(a) */
                   + ((a & (b ^ c)) ^ c) /* Ch(a, b, c) */
                   + 0x90befffa /* K60 */
                   + (i12 += i05 /* W53 */
                        +  (((x = i10) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                            (x << 13) ^ (x << 15)) /* sigma1(W58) */
                        +  (((x = i13) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                            (x << 14) ^ (x << 25)) /* sigma0(W45) */
                     ) /* W60 */;
        hD +=
        d = x + (((x = e) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(e) */
              + ((x & f) | ((x | f) & g)) /* Maj(e, f, g) */;

        hG +=
        g += x = c + (((x = h) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(h) */
                   + ((x & (a ^ b)) ^ b) /* Ch(h, a, b) */
                   + 0xa4506ceb /* K61 */
                   + (i13 += i06 /* W54 */
                        +  (((x = i11) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                            (x << 13) ^ (x << 15)) /* sigma1(W59) */
                        +  (((x = i14) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                            (x << 14) ^ (x << 25)) /* sigma0(W46) */
                     ) /* W61 */;
        hC +=
        c = x + (((x = d) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(d) */
              + ((x & e) | ((x | e) & f)) /* Maj(d, e, f) */;

        hF +=
        f +=     b +=(((x = g) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(g) */
                   + ((x & (h ^ a)) ^ a) /* Ch(g, h, a) */
                   + 0xbef9a3f7 /* K62 */
                   + (i14 += i07 /* W55 */
                        + (((x = i12) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W60) */
                        + (((x = i15) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W47) */
                     ) /* W62 */;
        hB +=
        b     +=(((x = c) >>> 2) ^ (x >>> 13) ^ (x >>> 22) ^
                 (x << 10) ^ (x << 19) ^ (x << 30)) /* Sigma0(c) */
              + ((x & d) | ((x | d) & e)) /* Maj(c, d, e) */;

        hE +=
        e +(     a +=(((x = f) >>> 6) ^ (x >>> 11) ^ (x >>> 25) ^
                      (x << 7) ^ (x << 21) ^ (x << 26)) /* Sigma1(f) */
                   + ((x & (g ^ h)) ^ h) /* Ch(f, g, h) */
                   + 0xc67178f2 /* K63 */
                   + (i15 += i08 /* W56 */
                        + (((x = i13) >>> 10) ^ (x >>> 17) ^ (x >>> 19) ^
                           (x << 13) ^ (x << 15)) /* sigma1(W61) */
                        + (((x = i00) >>> 3) ^ (x >>> 7) ^ (x >>> 18) ^
                           (x << 14) ^ (x << 25)) /* sigma0(W48) */
                     ) /* W63 */
           );
        hA +=
        a     + ((b >>> 2) ^ (b >>> 13) ^ (b >>> 22) ^
                 (b << 10) ^ (b << 19) ^ (b << 30)) /* Sigma0(b) */
              + ((b & c) | ((b | c) & d)) /* Maj(b, c, d) */;
    }
}

