/*! asmCrypto Lite v1.1.0, (c) 2013 Artem S Vybornov, opensource.org/licenses/MIT */ (function ( exports, global ) { class IllegalStateError extends Error {} class IllegalArgumentError extends Error {} class SecurityError extends Error {} function string_to_bytes ( str, utf8 ) { utf8 = !!utf8; var len = str.length, bytes = new Uint8Array( utf8 ? 4*len : len ); for ( var i = 0, j = 0; i < len; i++ ) { var c = str.charCodeAt(i); if ( utf8 && 0xd800 <= c && c <= 0xdbff ) { if ( ++i >= len ) throw new Error( "Malformed string, low surrogate expected at position " + i ); c = ( (c ^ 0xd800) << 10 ) | 0x10000 | ( str.charCodeAt(i) ^ 0xdc00 ); } else if ( !utf8 && c >>> 8 ) { throw new Error("Wide characters are not allowed."); } if ( !utf8 || c <= 0x7f ) { bytes[j++] = c; } else if ( c <= 0x7ff ) { bytes[j++] = 0xc0 | (c >> 6); bytes[j++] = 0x80 | (c & 0x3f); } else if ( c <= 0xffff ) { bytes[j++] = 0xe0 | (c >> 12); bytes[j++] = 0x80 | (c >> 6 & 0x3f); bytes[j++] = 0x80 | (c & 0x3f); } else { bytes[j++] = 0xf0 | (c >> 18); bytes[j++] = 0x80 | (c >> 12 & 0x3f); bytes[j++] = 0x80 | (c >> 6 & 0x3f); bytes[j++] = 0x80 | (c & 0x3f); } } return bytes.subarray(0, j); } function bytes_to_string ( bytes, utf8 ) { utf8 = !!utf8; var len = bytes.length, chars = new Array(len); for ( var i = 0, j = 0; i < len; i++ ) { var b = bytes[i]; if ( !utf8 || b < 128 ) { chars[j++] = b; } else if ( b >= 192 && b < 224 && i+1 < len ) { chars[j++] = ( (b & 0x1f) << 6 ) | (bytes[++i] & 0x3f); } else if ( b >= 224 && b < 240 && i+2 < len ) { chars[j++] = ( (b & 0xf) << 12 ) | ( (bytes[++i] & 0x3f) << 6 ) | (bytes[++i] & 0x3f); } else if ( b >= 240 && b < 248 && i+3 < len ) { var c = ( (b & 7) << 18 ) | ( (bytes[++i] & 0x3f) << 12 ) | ( (bytes[++i] & 0x3f) << 6 ) | (bytes[++i] & 0x3f); if ( c <= 0xffff ) { chars[j++] = c; } else { c ^= 0x10000; chars[j++] = 0xd800 | (c >> 10); chars[j++] = 0xdc00 | (c & 0x3ff); } } else { throw new Error("Malformed UTF8 character at byte offset " + i); } } var str = '', bs = 16384; for ( var i = 0; i < j; i += bs ) { str += String.fromCharCode.apply( String, chars.slice( i, i+bs <= j ? i+bs : j ) ); } return str; } function bytes_to_hex ( arr ) { var str = ''; for ( var i = 0; i < arr.length; i++ ) { var h = ( arr[i] & 0xff ).toString(16); if ( h.length < 2 ) str += '0'; str += h; } return str; } function bytes_to_base64 ( arr ) { return btoa( bytes_to_string(arr) ); } function is_number ( a ) { return ( typeof a === 'number' ); } function is_string ( a ) { return ( typeof a === 'string' ); } function is_buffer ( a ) { return ( a instanceof ArrayBuffer ); } function is_bytes ( a ) { return ( a instanceof Uint8Array ); } function _heap_init ( constructor, options ) { var heap = options.heap, size = heap ? heap.byteLength : options.heapSize || 65536; if ( size & 0xfff || size <= 0 ) throw new Error("heap size must be a positive integer and a multiple of 4096"); heap = heap || new constructor( new ArrayBuffer(size) ); return heap; } function _heap_write ( heap, hpos, data, dpos, dlen ) { var hlen = heap.length - hpos, wlen = ( hlen < dlen ) ? hlen : dlen; heap.set( data.subarray( dpos, dpos+wlen ), hpos ); return wlen; } /** * Error definitions */ global.IllegalStateError = IllegalStateError; global.IllegalArgumentError = IllegalArgumentError; global.SecurityError = SecurityError; /** * @file {@link http://asmjs.org Asm.js} implementation of the {@link https://en.wikipedia.org/wiki/Advanced_Encryption_Standard Advanced Encryption Standard}. * @author Artem S Vybornov * @license MIT */ var AES_asm = function () { "use strict"; /** * Galois Field stuff init flag */ var ginit_done = false; /** * Galois Field exponentiation and logarithm tables for 3 (the generator) */ var gexp3, glog3; /** * Init Galois Field tables */ function ginit () { gexp3 = [], glog3 = []; var a = 1, c, d; for ( c = 0; c < 255; c++ ) { gexp3[c] = a; // Multiply by three d = a & 0x80, a <<= 1, a &= 255; if ( d === 0x80 ) a ^= 0x1b; a ^= gexp3[c]; // Set the log table value glog3[gexp3[c]] = c; } gexp3[255] = gexp3[0]; glog3[0] = 0; ginit_done = true; } /** * Galois Field multiplication * @param {int} a * @param {int} b * @return {int} */ function gmul ( a, b ) { var c = gexp3[ ( glog3[a] + glog3[b] ) % 255 ]; if ( a === 0 || b === 0 ) c = 0; return c; } /** * Galois Field reciprocal * @param {int} a * @return {int} */ function ginv ( a ) { var i = gexp3[ 255 - glog3[a] ]; if ( a === 0 ) i = 0; return i; } /** * AES stuff init flag */ var aes_init_done = false; /** * Encryption, Decryption, S-Box and KeyTransform tables */ var aes_sbox, aes_sinv, aes_enc, aes_dec; /** * Init AES tables */ function aes_init () { if ( !ginit_done ) ginit(); // Calculates AES S-Box value function _s ( a ) { var c, s, x; s = x = ginv(a); for ( c = 0; c < 4; c++ ) { s = ( (s << 1) | (s >>> 7) ) & 255; x ^= s; } x ^= 99; return x; } // Tables aes_sbox = [], aes_sinv = [], aes_enc = [ [], [], [], [] ], aes_dec = [ [], [], [], [] ]; for ( var i = 0; i < 256; i++ ) { var s = _s(i); // S-Box and its inverse aes_sbox[i] = s; aes_sinv[s] = i; // Ecryption and Decryption tables aes_enc[0][i] = ( gmul( 2, s ) << 24 ) | ( s << 16 ) | ( s << 8 ) | gmul( 3, s ); aes_dec[0][s] = ( gmul( 14, i ) << 24 ) | ( gmul( 9, i ) << 16 ) | ( gmul( 13, i ) << 8 ) | gmul( 11, i ); // Rotate tables for ( var t = 1; t < 4; t++ ) { aes_enc[t][i] = ( aes_enc[t-1][i] >>> 8 ) | ( aes_enc[t-1][i] << 24 ); aes_dec[t][s] = ( aes_dec[t-1][s] >>> 8 ) | ( aes_dec[t-1][s] << 24 ); } } } /** * Asm.js module constructor. * *

* Heap buffer layout by offset: *

     * 0x0000   encryption key schedule
     * 0x0400   decryption key schedule
     * 0x0800   sbox
     * 0x0c00   inv sbox
     * 0x1000   encryption tables
     * 0x2000   decryption tables
     * 0x3000   reserved (future GCM multiplication lookup table)
     * 0x4000   data
     * 
* Don't touch anything before 0x400. *

* * @alias AES_asm * @class * @param {GlobalScope} stdlib - global scope object (e.g. window) * @param {Object} foreign - ignored * @param {ArrayBuffer} buffer - heap buffer to link with */ var wrapper = function ( stdlib, foreign, buffer ) { // Init AES stuff for the first time if ( !aes_init_done ) aes_init(); // Fill up AES tables var heap = new Uint32Array(buffer); heap.set( aes_sbox, 0x0800>>2 ); heap.set( aes_sinv, 0x0c00>>2 ); for ( var i = 0; i < 4; i++ ) { heap.set( aes_enc[i], ( 0x1000 + 0x400 * i )>>2 ); heap.set( aes_dec[i], ( 0x2000 + 0x400 * i )>>2 ); } /** * Calculate AES key schedules. * @instance * @memberof AES_asm * @param {int} ks - key size, 4/6/8 (for 128/192/256-bit key correspondingly) * @param {int} k0..k7 - key vector components */ function set_key ( ks, k0, k1, k2, k3, k4, k5, k6, k7 ) { var ekeys = heap.subarray( 0x000, 60 ), dkeys = heap.subarray( 0x100, 0x100+60 ); // Encryption key schedule ekeys.set( [ k0, k1, k2, k3, k4, k5, k6, k7 ] ); for ( var i = ks, rcon = 1; i < 4*ks+28; i++ ) { var k = ekeys[i-1]; if ( ( i % ks === 0 ) || ( ks === 8 && i % ks === 4 ) ) { k = aes_sbox[k>>>24]<<24 ^ aes_sbox[k>>>16&255]<<16 ^ aes_sbox[k>>>8&255]<<8 ^ aes_sbox[k&255]; } if ( i % ks === 0 ) { k = (k << 8) ^ (k >>> 24) ^ (rcon << 24); rcon = (rcon << 1) ^ ( (rcon & 0x80) ? 0x1b : 0 ); } ekeys[i] = ekeys[i-ks] ^ k; } // Decryption key schedule for ( var j = 0; j < i; j += 4 ) { for ( var jj = 0; jj < 4; jj++ ) { var k = ekeys[i-(4+j)+(4-jj)%4]; if ( j < 4 || j >= i-4 ) { dkeys[j+jj] = k; } else { dkeys[j+jj] = aes_dec[0][aes_sbox[k>>>24]] ^ aes_dec[1][aes_sbox[k>>>16&255]] ^ aes_dec[2][aes_sbox[k>>>8&255]] ^ aes_dec[3][aes_sbox[k&255]]; } } } // Set rounds number asm.set_rounds( ks + 5 ); } var asm = function ( stdlib, foreign, buffer ) { "use asm"; var S0 = 0, S1 = 0, S2 = 0, S3 = 0, I0 = 0, I1 = 0, I2 = 0, I3 = 0, N0 = 0, N1 = 0, N2 = 0, N3 = 0, M0 = 0, M1 = 0, M2 = 0, M3 = 0, H0 = 0, H1 = 0, H2 = 0, H3 = 0, R = 0; var HEAP = new stdlib.Uint32Array(buffer), DATA = new stdlib.Uint8Array(buffer); /** * AES core * @param {int} k - precomputed key schedule offset * @param {int} s - precomputed sbox table offset * @param {int} t - precomputed round table offset * @param {int} r - number of inner rounds to perform * @param {int} x0..x3 - 128-bit input block vector */ function _core ( k, s, t, r, x0, x1, x2, x3 ) { k = k|0; s = s|0; t = t|0; r = r|0; x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; var t1 = 0, t2 = 0, t3 = 0, y0 = 0, y1 = 0, y2 = 0, y3 = 0, i = 0; t1 = t|0x400, t2 = t|0x800, t3 = t|0xc00; // round 0 x0 = x0 ^ HEAP[(k|0)>>2], x1 = x1 ^ HEAP[(k|4)>>2], x2 = x2 ^ HEAP[(k|8)>>2], x3 = x3 ^ HEAP[(k|12)>>2]; // round 1..r for ( i = 16; (i|0) <= (r<<4); i = (i+16)|0 ) { y0 = HEAP[(t|x0>>22&1020)>>2] ^ HEAP[(t1|x1>>14&1020)>>2] ^ HEAP[(t2|x2>>6&1020)>>2] ^ HEAP[(t3|x3<<2&1020)>>2] ^ HEAP[(k|i|0)>>2], y1 = HEAP[(t|x1>>22&1020)>>2] ^ HEAP[(t1|x2>>14&1020)>>2] ^ HEAP[(t2|x3>>6&1020)>>2] ^ HEAP[(t3|x0<<2&1020)>>2] ^ HEAP[(k|i|4)>>2], y2 = HEAP[(t|x2>>22&1020)>>2] ^ HEAP[(t1|x3>>14&1020)>>2] ^ HEAP[(t2|x0>>6&1020)>>2] ^ HEAP[(t3|x1<<2&1020)>>2] ^ HEAP[(k|i|8)>>2], y3 = HEAP[(t|x3>>22&1020)>>2] ^ HEAP[(t1|x0>>14&1020)>>2] ^ HEAP[(t2|x1>>6&1020)>>2] ^ HEAP[(t3|x2<<2&1020)>>2] ^ HEAP[(k|i|12)>>2]; x0 = y0, x1 = y1, x2 = y2, x3 = y3; } // final round S0 = HEAP[(s|x0>>22&1020)>>2]<<24 ^ HEAP[(s|x1>>14&1020)>>2]<<16 ^ HEAP[(s|x2>>6&1020)>>2]<<8 ^ HEAP[(s|x3<<2&1020)>>2] ^ HEAP[(k|i|0)>>2], S1 = HEAP[(s|x1>>22&1020)>>2]<<24 ^ HEAP[(s|x2>>14&1020)>>2]<<16 ^ HEAP[(s|x3>>6&1020)>>2]<<8 ^ HEAP[(s|x0<<2&1020)>>2] ^ HEAP[(k|i|4)>>2], S2 = HEAP[(s|x2>>22&1020)>>2]<<24 ^ HEAP[(s|x3>>14&1020)>>2]<<16 ^ HEAP[(s|x0>>6&1020)>>2]<<8 ^ HEAP[(s|x1<<2&1020)>>2] ^ HEAP[(k|i|8)>>2], S3 = HEAP[(s|x3>>22&1020)>>2]<<24 ^ HEAP[(s|x0>>14&1020)>>2]<<16 ^ HEAP[(s|x1>>6&1020)>>2]<<8 ^ HEAP[(s|x2<<2&1020)>>2] ^ HEAP[(k|i|12)>>2]; } /** * ECB mode encryption * @param {int} x0..x3 - 128-bit input block vector */ function _ecb_enc ( x0, x1, x2, x3 ) { x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; _core( 0x0000, 0x0800, 0x1000, R, x0, x1, x2, x3 ); } /** * ECB mode decryption * @param {int} x0..x3 - 128-bit input block vector */ function _ecb_dec ( x0, x1, x2, x3 ) { x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; var t = 0; _core( 0x0400, 0x0c00, 0x2000, R, x0, x3, x2, x1 ); t = S1, S1 = S3, S3 = t; } /** * CBC mode encryption * @param {int} x0..x3 - 128-bit input block vector */ function _cbc_enc ( x0, x1, x2, x3 ) { x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; _core( 0x0000, 0x0800, 0x1000, R, I0 ^ x0, I1 ^ x1, I2 ^ x2, I3 ^ x3 ); I0 = S0, I1 = S1, I2 = S2, I3 = S3; } /** * CBC mode decryption * @param {int} x0..x3 - 128-bit input block vector */ function _cbc_dec ( x0, x1, x2, x3 ) { x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; var t = 0; _core( 0x0400, 0x0c00, 0x2000, R, x0, x3, x2, x1 ); t = S1, S1 = S3, S3 = t; S0 = S0 ^ I0, S1 = S1 ^ I1, S2 = S2 ^ I2, S3 = S3 ^ I3; I0 = x0, I1 = x1, I2 = x2, I3 = x3; } /** * CFB mode encryption * @param {int} x0..x3 - 128-bit input block vector */ function _cfb_enc ( x0, x1, x2, x3 ) { x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; _core( 0x0000, 0x0800, 0x1000, R, I0, I1, I2, I3 ); I0 = S0 = S0 ^ x0, I1 = S1 = S1 ^ x1, I2 = S2 = S2 ^ x2, I3 = S3 = S3 ^ x3; } /** * CFB mode decryption * @param {int} x0..x3 - 128-bit input block vector */ function _cfb_dec ( x0, x1, x2, x3 ) { x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; _core( 0x0000, 0x0800, 0x1000, R, I0, I1, I2, I3 ); S0 = S0 ^ x0, S1 = S1 ^ x1, S2 = S2 ^ x2, S3 = S3 ^ x3; I0 = x0, I1 = x1, I2 = x2, I3 = x3; } /** * OFB mode encryption / decryption * @param {int} x0..x3 - 128-bit input block vector */ function _ofb ( x0, x1, x2, x3 ) { x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; _core( 0x0000, 0x0800, 0x1000, R, I0, I1, I2, I3 ); I0 = S0, I1 = S1, I2 = S2, I3 = S3; S0 = S0 ^ x0, S1 = S1 ^ x1, S2 = S2 ^ x2, S3 = S3 ^ x3; } /** * CTR mode encryption / decryption * @param {int} x0..x3 - 128-bit input block vector */ function _ctr ( x0, x1, x2, x3 ) { x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; _core( 0x0000, 0x0800, 0x1000, R, N0, N1, N2, N3 ); N3 = ( ~M3 & N3 ) | M3 & ( N3 + 1 ), N2 = ( ~M2 & N2 ) | M2 & ( N2 + ( (N3|0) == 0 ) ), N1 = ( ~M1 & N1 ) | M1 & ( N1 + ( (N2|0) == 0 ) ), N0 = ( ~M0 & N0 ) | M0 & ( N0 + ( (N1|0) == 0 ) ); S0 = S0 ^ x0, S1 = S1 ^ x1, S2 = S2 ^ x2, S3 = S3 ^ x3; } /** * GCM mode MAC calculation * @param {int} x0..x3 - 128-bit input block vector */ function _gcm_mac ( x0, x1, x2, x3 ) { x0 = x0|0; x1 = x1|0; x2 = x2|0; x3 = x3|0; var y0 = 0, y1 = 0, y2 = 0, y3 = 0, z0 = 0, z1 = 0, z2 = 0, z3 = 0, i = 0, c = 0; x0 = x0 ^ I0, x1 = x1 ^ I1, x2 = x2 ^ I2, x3 = x3 ^ I3; y0 = H0|0, y1 = H1|0, y2 = H2|0, y3 = H3|0; for ( ; (i|0) < 128; i = (i + 1)|0 ) { if ( y0 >>> 31 ) { z0 = z0 ^ x0, z1 = z1 ^ x1, z2 = z2 ^ x2, z3 = z3 ^ x3; } y0 = (y0 << 1) | (y1 >>> 31), y1 = (y1 << 1) | (y2 >>> 31), y2 = (y2 << 1) | (y3 >>> 31), y3 = (y3 << 1); c = x3 & 1; x3 = (x3 >>> 1) | (x2 << 31), x2 = (x2 >>> 1) | (x1 << 31), x1 = (x1 >>> 1) | (x0 << 31), x0 = (x0 >>> 1); if ( c ) x0 = x0 ^ 0xe1000000; } I0 = z0, I1 = z1, I2 = z2, I3 = z3; } /** * Set the internal rounds number. * @instance * @memberof AES_asm * @param {int} r - number if inner AES rounds */ function set_rounds ( r ) { r = r|0; R = r; } /** * Populate the internal state of the module. * @instance * @memberof AES_asm * @param {int} s0...s3 - state vector */ function set_state ( s0, s1, s2, s3 ) { s0 = s0|0; s1 = s1|0; s2 = s2|0; s3 = s3|0; S0 = s0, S1 = s1, S2 = s2, S3 = s3; } /** * Populate the internal iv of the module. * @instance * @memberof AES_asm * @param {int} i0...i3 - iv vector */ function set_iv ( i0, i1, i2, i3 ) { i0 = i0|0; i1 = i1|0; i2 = i2|0; i3 = i3|0; I0 = i0, I1 = i1, I2 = i2, I3 = i3; } /** * Set nonce for CTR-family modes. * @instance * @memberof AES_asm * @param {int} n0..n3 - nonce vector */ function set_nonce ( n0, n1, n2, n3 ) { n0 = n0|0; n1 = n1|0; n2 = n2|0; n3 = n3|0; N0 = n0, N1 = n1, N2 = n2, N3 = n3; } /** * Set counter mask for CTR-family modes. * @instance * @memberof AES_asm * @param {int} m0...m3 - counter mask vector */ function set_mask ( m0, m1, m2, m3 ) { m0 = m0|0; m1 = m1|0; m2 = m2|0; m3 = m3|0; M0 = m0, M1 = m1, M2 = m2, M3 = m3; } /** * Set counter for CTR-family modes. * @instance * @memberof AES_asm * @param {int} c0...c3 - counter vector */ function set_counter ( c0, c1, c2, c3 ) { c0 = c0|0; c1 = c1|0; c2 = c2|0; c3 = c3|0; N3 = ( ~M3 & N3 ) | M3 & c3, N2 = ( ~M2 & N2 ) | M2 & c2, N1 = ( ~M1 & N1 ) | M1 & c1, N0 = ( ~M0 & N0 ) | M0 & c0; } /** * Store the internal state vector into the heap. * @instance * @memberof AES_asm * @param {int} pos - offset where to put the data * @return {int} The number of bytes have been written into the heap, always 16. */ function get_state ( pos ) { pos = pos|0; if ( pos & 15 ) return -1; DATA[pos|0] = S0>>>24, DATA[pos|1] = S0>>>16&255, DATA[pos|2] = S0>>>8&255, DATA[pos|3] = S0&255, DATA[pos|4] = S1>>>24, DATA[pos|5] = S1>>>16&255, DATA[pos|6] = S1>>>8&255, DATA[pos|7] = S1&255, DATA[pos|8] = S2>>>24, DATA[pos|9] = S2>>>16&255, DATA[pos|10] = S2>>>8&255, DATA[pos|11] = S2&255, DATA[pos|12] = S3>>>24, DATA[pos|13] = S3>>>16&255, DATA[pos|14] = S3>>>8&255, DATA[pos|15] = S3&255; return 16; } /** * Store the internal iv vector into the heap. * @instance * @memberof AES_asm * @param {int} pos - offset where to put the data * @return {int} The number of bytes have been written into the heap, always 16. */ function get_iv ( pos ) { pos = pos|0; if ( pos & 15 ) return -1; DATA[pos|0] = I0>>>24, DATA[pos|1] = I0>>>16&255, DATA[pos|2] = I0>>>8&255, DATA[pos|3] = I0&255, DATA[pos|4] = I1>>>24, DATA[pos|5] = I1>>>16&255, DATA[pos|6] = I1>>>8&255, DATA[pos|7] = I1&255, DATA[pos|8] = I2>>>24, DATA[pos|9] = I2>>>16&255, DATA[pos|10] = I2>>>8&255, DATA[pos|11] = I2&255, DATA[pos|12] = I3>>>24, DATA[pos|13] = I3>>>16&255, DATA[pos|14] = I3>>>8&255, DATA[pos|15] = I3&255; return 16; } /** * GCM initialization. * @instance * @memberof AES_asm */ function gcm_init ( ) { _ecb_enc( 0, 0, 0, 0 ); H0 = S0, H1 = S1, H2 = S2, H3 = S3; } /** * Perform ciphering operation on the supplied data. * @instance * @memberof AES_asm * @param {int} mode - block cipher mode (see {@link AES_asm} mode constants) * @param {int} pos - offset of the data being processed * @param {int} len - length of the data being processed * @return {int} Actual amount of data have been processed. */ function cipher ( mode, pos, len ) { mode = mode|0; pos = pos|0; len = len|0; var ret = 0; if ( pos & 15 ) return -1; while ( (len|0) >= 16 ) { _cipher_modes[mode&7]( DATA[pos|0]<<24 | DATA[pos|1]<<16 | DATA[pos|2]<<8 | DATA[pos|3], DATA[pos|4]<<24 | DATA[pos|5]<<16 | DATA[pos|6]<<8 | DATA[pos|7], DATA[pos|8]<<24 | DATA[pos|9]<<16 | DATA[pos|10]<<8 | DATA[pos|11], DATA[pos|12]<<24 | DATA[pos|13]<<16 | DATA[pos|14]<<8 | DATA[pos|15] ); DATA[pos|0] = S0>>>24, DATA[pos|1] = S0>>>16&255, DATA[pos|2] = S0>>>8&255, DATA[pos|3] = S0&255, DATA[pos|4] = S1>>>24, DATA[pos|5] = S1>>>16&255, DATA[pos|6] = S1>>>8&255, DATA[pos|7] = S1&255, DATA[pos|8] = S2>>>24, DATA[pos|9] = S2>>>16&255, DATA[pos|10] = S2>>>8&255, DATA[pos|11] = S2&255, DATA[pos|12] = S3>>>24, DATA[pos|13] = S3>>>16&255, DATA[pos|14] = S3>>>8&255, DATA[pos|15] = S3&255; ret = (ret + 16)|0, pos = (pos + 16)|0, len = (len - 16)|0; } return ret|0; } /** * Calculates MAC of the supplied data. * @instance * @memberof AES_asm * @param {int} mode - block cipher mode (see {@link AES_asm} mode constants) * @param {int} pos - offset of the data being processed * @param {int} len - length of the data being processed * @return {int} Actual amount of data have been processed. */ function mac ( mode, pos, len ) { mode = mode|0; pos = pos|0; len = len|0; var ret = 0; if ( pos & 15 ) return -1; while ( (len|0) >= 16 ) { _mac_modes[mode&1]( DATA[pos|0]<<24 | DATA[pos|1]<<16 | DATA[pos|2]<<8 | DATA[pos|3], DATA[pos|4]<<24 | DATA[pos|5]<<16 | DATA[pos|6]<<8 | DATA[pos|7], DATA[pos|8]<<24 | DATA[pos|9]<<16 | DATA[pos|10]<<8 | DATA[pos|11], DATA[pos|12]<<24 | DATA[pos|13]<<16 | DATA[pos|14]<<8 | DATA[pos|15] ); ret = (ret + 16)|0, pos = (pos + 16)|0, len = (len - 16)|0; } return ret|0; } /** * AES cipher modes table (virual methods) */ var _cipher_modes = [ _ecb_enc, _ecb_dec, _cbc_enc, _cbc_dec, _cfb_enc, _cfb_dec, _ofb, _ctr ]; /** * AES MAC modes table (virual methods) */ var _mac_modes = [ _cbc_enc, _gcm_mac ]; /** * Asm.js module exports */ return { set_rounds: set_rounds, set_state: set_state, set_iv: set_iv, set_nonce: set_nonce, set_mask: set_mask, set_counter:set_counter, get_state: get_state, get_iv: get_iv, gcm_init: gcm_init, cipher: cipher, mac: mac }; }( stdlib, foreign, buffer ); asm.set_key = set_key; return asm; }; /** * AES enciphering mode constants * @enum {int} * @const */ wrapper.ENC = { ECB: 0, CBC: 2, CFB: 4, OFB: 6, CTR: 7 }, /** * AES deciphering mode constants * @enum {int} * @const */ wrapper.DEC = { ECB: 1, CBC: 3, CFB: 5, OFB: 6, CTR: 7 }, /** * AES MAC mode constants * @enum {int} * @const */ wrapper.MAC = { CBC: 0, GCM: 1 }; /** * Heap data offset * @type {int} * @const */ wrapper.HEAP_DATA = 0x4000; return wrapper; }(); function AES ( options ) { options = options || {}; this.heap = _heap_init( Uint8Array, options ).subarray( AES_asm.HEAP_DATA ); this.asm = options.asm || AES_asm( global, null, this.heap.buffer ); this.mode = null; this.key = null; this.reset( options ); } function AES_set_key ( key ) { if ( key !== undefined ) { if ( is_buffer(key) || is_bytes(key) ) { key = new Uint8Array(key); } else if ( is_string(key) ) { key = string_to_bytes(key); } else { throw new TypeError("unexpected key type"); } var keylen = key.length; if ( keylen !== 16 && keylen !== 24 && keylen !== 32 ) throw new IllegalArgumentError("illegal key size"); var keyview = new DataView( key.buffer, key.byteOffset, key.byteLength ); this.asm.set_key( keylen >> 2, keyview.getUint32(0), keyview.getUint32(4), keyview.getUint32(8), keyview.getUint32(12), keylen > 16 ? keyview.getUint32(16) : 0, keylen > 16 ? keyview.getUint32(20) : 0, keylen > 24 ? keyview.getUint32(24) : 0, keylen > 24 ? keyview.getUint32(28) : 0 ); this.key = key; } else if ( !this.key ) { throw new Error("key is required"); } } function AES_set_iv ( iv ) { if ( iv !== undefined ) { if ( is_buffer(iv) || is_bytes(iv) ) { iv = new Uint8Array(iv); } else if ( is_string(iv) ) { iv = string_to_bytes(iv); } else { throw new TypeError("unexpected iv type"); } if ( iv.length !== 16 ) throw new IllegalArgumentError("illegal iv size"); var ivview = new DataView( iv.buffer, iv.byteOffset, iv.byteLength ); this.iv = iv; this.asm.set_iv( ivview.getUint32(0), ivview.getUint32(4), ivview.getUint32(8), ivview.getUint32(12) ); } else { this.iv = null; this.asm.set_iv( 0, 0, 0, 0 ); } } function AES_set_padding ( padding ) { if ( padding !== undefined ) { this.padding = !!padding; } else { this.padding = true; } } function AES_reset ( options ) { options = options || {}; this.result = null; this.pos = 0; this.len = 0; AES_set_key.call( this, options.key ); if ( this.hasOwnProperty('iv') ) AES_set_iv.call( this, options.iv ); if ( this.hasOwnProperty('padding') ) AES_set_padding.call( this, options.padding ); return this; } function AES_Encrypt_process ( data ) { if ( is_string(data) ) data = string_to_bytes(data); if ( is_buffer(data) ) data = new Uint8Array(data); if ( !is_bytes(data) ) throw new TypeError("data isn't of expected type"); var asm = this.asm, heap = this.heap, amode = AES_asm.ENC[this.mode], hpos = AES_asm.HEAP_DATA, pos = this.pos, len = this.len, dpos = 0, dlen = data.length || 0, rpos = 0, rlen = (len + dlen) & -16, wlen = 0; var result = new Uint8Array(rlen); while ( dlen > 0 ) { wlen = _heap_write( heap, pos+len, data, dpos, dlen ); len += wlen; dpos += wlen; dlen -= wlen; wlen = asm.cipher( amode, hpos + pos, len ); if ( wlen ) result.set( heap.subarray( pos, pos + wlen ), rpos ); rpos += wlen; if ( wlen < len ) { pos += wlen; len -= wlen; } else { pos = 0; len = 0; } } this.result = result; this.pos = pos; this.len = len; return this; } function AES_Encrypt_finish ( data ) { var presult = null, prlen = 0; if ( data !== undefined ) { presult = AES_Encrypt_process.call( this, data ).result; prlen = presult.length; } var asm = this.asm, heap = this.heap, amode = AES_asm.ENC[this.mode], hpos = AES_asm.HEAP_DATA, pos = this.pos, len = this.len, plen = 16 - len % 16, rlen = len; if ( this.hasOwnProperty('padding') ) { if ( this.padding ) { for ( var p = 0; p < plen; ++p ) heap[ pos + len + p ] = plen; len += plen; rlen = len; } else if ( len % 16 ) { throw new IllegalArgumentError("data length must be a multiple of the block size"); } } else { len += plen; } var result = new Uint8Array( prlen + rlen ); if ( prlen ) result.set( presult ); if ( len ) asm.cipher( amode, hpos + pos, len ); if ( rlen ) result.set( heap.subarray( pos, pos + rlen ), prlen ); this.result = result; this.pos = 0; this.len = 0; return this; } function AES_Decrypt_process ( data ) { if ( is_string(data) ) data = string_to_bytes(data); if ( is_buffer(data) ) data = new Uint8Array(data); if ( !is_bytes(data) ) throw new TypeError("data isn't of expected type"); var asm = this.asm, heap = this.heap, amode = AES_asm.DEC[this.mode], hpos = AES_asm.HEAP_DATA, pos = this.pos, len = this.len, dpos = 0, dlen = data.length || 0, rpos = 0, rlen = (len + dlen) & -16, plen = 0, wlen = 0; if ( this.hasOwnProperty('padding') && this.padding ) { plen = len + dlen - rlen || 16; rlen -= plen; } var result = new Uint8Array(rlen); while ( dlen > 0 ) { wlen = _heap_write( heap, pos+len, data, dpos, dlen ); len += wlen; dpos += wlen; dlen -= wlen; wlen = asm.cipher( amode, hpos + pos, len - ( !dlen ? plen : 0 ) ); if ( wlen ) result.set( heap.subarray( pos, pos + wlen ), rpos ); rpos += wlen; if ( wlen < len ) { pos += wlen; len -= wlen; } else { pos = 0; len = 0; } } this.result = result; this.pos = pos; this.len = len; return this; } function AES_Decrypt_finish ( data ) { var presult = null, prlen = 0; if ( data !== undefined ) { presult = AES_Decrypt_process.call( this, data ).result; prlen = presult.length; } var asm = this.asm, heap = this.heap, amode = AES_asm.DEC[this.mode], hpos = AES_asm.HEAP_DATA, pos = this.pos, len = this.len, rlen = len; if ( len > 0 ) { if ( len % 16 ) { if ( this.hasOwnProperty('padding') ) { throw new IllegalArgumentError("data length must be a multiple of the block size"); } else { len += 16 - len % 16; } } asm.cipher( amode, hpos + pos, len ); if ( this.hasOwnProperty('padding') && this.padding ) { var pad = heap[ pos + rlen - 1 ]; if ( pad < 1 || pad > 16 || pad > rlen ) throw new SecurityError("bad padding"); var pcheck = 0; for ( var i = pad; i > 1; i-- ) pcheck |= pad ^ heap[ pos + rlen - i ]; if ( pcheck ) throw new SecurityError("bad padding"); rlen -= pad; } } var result = new Uint8Array( prlen + rlen ); if ( prlen > 0 ) { result.set( presult ); } if ( rlen > 0 ) { result.set( heap.subarray( pos, pos + rlen ), prlen ); } this.result = result; this.pos = 0; this.len = 0; return this; } /** * Cipher Feedback Mode (CFB) */ function AES_CFB ( options ) { this.iv = null; AES.call( this, options ); this.mode = 'CFB'; } var AES_CFB_prototype = AES_CFB.prototype; AES_CFB_prototype.BLOCK_SIZE = 16; AES_CFB_prototype.reset = AES_reset; AES_CFB_prototype.encrypt = AES_Encrypt_finish; AES_CFB_prototype.decrypt = AES_Decrypt_finish; function AES_CFB_Encrypt ( options ) { AES_CFB.call( this, options ); } var AES_CFB_Encrypt_prototype = AES_CFB_Encrypt.prototype; AES_CFB_Encrypt_prototype.BLOCK_SIZE = 16; AES_CFB_Encrypt_prototype.reset = AES_reset; AES_CFB_Encrypt_prototype.process = AES_Encrypt_process; AES_CFB_Encrypt_prototype.finish = AES_Encrypt_finish; function AES_CFB_Decrypt ( options ) { AES_CFB.call( this, options ); } var AES_CFB_Decrypt_prototype = AES_CFB_Decrypt.prototype; AES_CFB_Decrypt_prototype.BLOCK_SIZE = 16; AES_CFB_Decrypt_prototype.reset = AES_reset; AES_CFB_Decrypt_prototype.process = AES_Decrypt_process; AES_CFB_Decrypt_prototype.finish = AES_Decrypt_finish; /** * Counter Mode (CTR) */ function AES_CTR ( options ) { this.nonce = null, this.counter = 0, this.counterSize = 0; AES.call( this, options ); this.mode = 'CTR'; } function AES_CTR_Crypt ( options ) { AES_CTR.call( this, options ); } function AES_CTR_set_options ( nonce, counter, size ) { if ( size !== undefined ) { if ( size < 8 || size > 48 ) throw new IllegalArgumentError("illegal counter size"); this.counterSize = size; var mask = Math.pow( 2, size ) - 1; this.asm.set_mask( 0, 0, (mask / 0x100000000)|0, mask|0 ); } else { this.counterSize = size = 48; this.asm.set_mask( 0, 0, 0xffff, 0xffffffff ); } if ( nonce !== undefined ) { if ( is_buffer(nonce) || is_bytes(nonce) ) { nonce = new Uint8Array(nonce); } else if ( is_string(nonce) ) { nonce = string_to_bytes(nonce); } else { throw new TypeError("unexpected nonce type"); } var len = nonce.length; if ( !len || len > 16 ) throw new IllegalArgumentError("illegal nonce size"); this.nonce = nonce; var view = new DataView( new ArrayBuffer(16) ); new Uint8Array(view.buffer).set(nonce); this.asm.set_nonce( view.getUint32(0), view.getUint32(4), view.getUint32(8), view.getUint32(12) ); } else { throw new Error("nonce is required"); } if ( counter !== undefined ) { if ( !is_number(counter) ) throw new TypeError("unexpected counter type"); if ( counter < 0 || counter >= Math.pow( 2, size ) ) throw new IllegalArgumentError("illegal counter value"); this.counter = counter; this.asm.set_counter( 0, 0, (counter / 0x100000000)|0, counter|0 ); } else { this.counter = counter = 0; } } function AES_CTR_reset ( options ) { options = options || {}; AES_reset.call( this, options ); AES_CTR_set_options.call( this, options.nonce, options.counter, options.counterSize ); return this; } var AES_CTR_prototype = AES_CTR.prototype; AES_CTR_prototype.BLOCK_SIZE = 16; AES_CTR_prototype.reset = AES_CTR_reset; AES_CTR_prototype.encrypt = AES_Encrypt_finish; AES_CTR_prototype.decrypt = AES_Encrypt_finish; var AES_CTR_Crypt_prototype = AES_CTR_Crypt.prototype; AES_CTR_Crypt_prototype.BLOCK_SIZE = 16; AES_CTR_Crypt_prototype.reset = AES_CTR_reset; AES_CTR_Crypt_prototype.process = AES_Encrypt_process; AES_CTR_Crypt_prototype.finish = AES_Encrypt_finish; /** * Galois/Counter mode */ var _AES_GCM_data_maxLength = 68719476704; // 2^36 - 2^5 function _gcm_mac_process ( data ) { var heap = this.heap, asm = this.asm, dpos = 0, dlen = data.length || 0, wlen = 0; while ( dlen > 0 ) { wlen = _heap_write( heap, 0, data, dpos, dlen ); dpos += wlen; dlen -= wlen; while ( wlen & 15 ) heap[ wlen++ ] = 0; asm.mac( AES_asm.MAC.GCM, AES_asm.HEAP_DATA, wlen ); } } function AES_GCM ( options ) { this.nonce = null; this.adata = null; this.iv = null; this.counter = 1; this.tagSize = 16; AES.call( this, options ); this.mode = 'GCM'; } function AES_GCM_Encrypt ( options ) { AES_GCM.call( this, options ); } function AES_GCM_Decrypt ( options ) { AES_GCM.call( this, options ); } function AES_GCM_reset ( options ) { options = options || {}; AES_reset.call( this, options ); var asm = this.asm, heap = this.heap; asm.gcm_init(); var tagSize = options.tagSize; if ( tagSize !== undefined ) { if ( !is_number(tagSize) ) throw new TypeError("tagSize must be a number"); if ( tagSize < 4 || tagSize > 16 ) throw new IllegalArgumentError("illegal tagSize value"); this.tagSize = tagSize; } else { this.tagSize = 16; } var nonce = options.nonce; if ( nonce !== undefined ) { if ( is_bytes(nonce) || is_buffer(nonce) ) { nonce = new Uint8Array(nonce); } else if ( is_string(nonce) ) { nonce = string_to_bytes(nonce); } else { throw new TypeError("unexpected nonce type"); } this.nonce = nonce; var noncelen = nonce.length || 0, noncebuf = new Uint8Array(16); if ( noncelen !== 12 ) { _gcm_mac_process.call( this, nonce ); heap[0] = heap[1] = heap[2] = heap[3] = heap[4] = heap[5] = heap[6] = heap[7] = heap[8] = heap[9] = heap[10] = 0, heap[11] = noncelen>>>29, heap[12] = noncelen>>>21&255, heap[13] = noncelen>>>13&255, heap[14] = noncelen>>>5&255, heap[15] = noncelen<<3&255; asm.mac( AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16 ); asm.get_iv( AES_asm.HEAP_DATA ); asm.set_iv(); noncebuf.set( heap.subarray( 0, 16 ) ); } else { noncebuf.set(nonce); noncebuf[15] = 1; } var nonceview = new DataView( noncebuf.buffer ); this.gamma0 = nonceview.getUint32(12); asm.set_nonce( nonceview.getUint32(0), nonceview.getUint32(4), nonceview.getUint32(8), 0 ); asm.set_mask( 0, 0, 0, 0xffffffff ); } else { throw new Error("nonce is required"); } var adata = options.adata; if ( adata !== undefined && adata !== null ) { if ( is_bytes(adata) || is_buffer(adata) ) { adata = new Uint8Array(adata); } else if ( is_string(adata) ) { adata = string_to_bytes(adata); } else { throw new TypeError("unexpected adata type"); } if ( adata.length > _AES_GCM_data_maxLength ) throw new IllegalArgumentError("illegal adata length"); if ( adata.length ) { this.adata = adata; _gcm_mac_process.call( this, adata ); } else { this.adata = null; } } else { this.adata = null; } var counter = options.counter; if ( counter !== undefined ) { if ( !is_number(counter) ) throw new TypeError("counter must be a number"); if ( counter < 1 || counter > 0xffffffff ) throw new RangeError("counter must be a positive 32-bit integer"); this.counter = counter; asm.set_counter( 0, 0, 0, this.gamma0+counter|0 ); } else { this.counter = 1; asm.set_counter( 0, 0, 0, this.gamma0+1|0 ); } var iv = options.iv; if ( iv !== undefined ) { if ( !is_number(counter) ) throw new TypeError("counter must be a number"); this.iv = iv; AES_set_iv.call( this, iv ); } return this; } function AES_GCM_Encrypt_process ( data ) { if ( is_string(data) ) data = string_to_bytes(data); if ( is_buffer(data) ) data = new Uint8Array(data); if ( !is_bytes(data) ) throw new TypeError("data isn't of expected type"); var dpos = 0, dlen = data.length || 0, asm = this.asm, heap = this.heap, counter = this.counter, pos = this.pos, len = this.len, rpos = 0, rlen = ( len + dlen ) & -16, wlen = 0; if ( ((counter-1)<<4) + len + dlen > _AES_GCM_data_maxLength ) throw new RangeError("counter overflow"); var result = new Uint8Array(rlen); while ( dlen > 0 ) { wlen = _heap_write( heap, pos+len, data, dpos, dlen ); len += wlen; dpos += wlen; dlen -= wlen; wlen = asm.cipher( AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, len ); wlen = asm.mac( AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen ); if ( wlen ) result.set( heap.subarray( pos, pos + wlen ), rpos ); counter += (wlen>>>4); rpos += wlen; if ( wlen < len ) { pos += wlen; len -= wlen; } else { pos = 0; len = 0; } } this.result = result; this.counter = counter; this.pos = pos; this.len = len; return this; } function AES_GCM_Encrypt_finish () { var asm = this.asm, heap = this.heap, counter = this.counter, tagSize = this.tagSize, adata = this.adata, pos = this.pos, len = this.len; var result = new Uint8Array( len + tagSize ); asm.cipher( AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, (len + 15) & -16 ); if ( len ) result.set( heap.subarray( pos, pos + len ) ); for ( var i = len; i & 15; i++ ) heap[ pos + i ] = 0; asm.mac( AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i ); var alen = ( adata !== null ) ? adata.length : 0, clen = ( (counter-1) << 4) + len; heap[0] = heap[1] = heap[2] = 0, heap[3] = alen>>>29, heap[4] = alen>>>21, heap[5] = alen>>>13&255, heap[6] = alen>>>5&255, heap[7] = alen<<3&255, heap[8] = heap[9] = heap[10] = 0, heap[11] = clen>>>29, heap[12] = clen>>>21&255, heap[13] = clen>>>13&255, heap[14] = clen>>>5&255, heap[15] = clen<<3&255; asm.mac( AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16 ); asm.get_iv( AES_asm.HEAP_DATA ); asm.set_counter( 0, 0, 0, this.gamma0 ); asm.cipher( AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16 ); result.set( heap.subarray( 0, tagSize ), len ); this.result = result; this.counter = 1; this.pos = 0; this.len = 0; return this; } function AES_GCM_encrypt ( data ) { var result1 = AES_GCM_Encrypt_process.call( this, data ).result, result2 = AES_GCM_Encrypt_finish.call(this).result; var result = new Uint8Array( result1.length + result2.length ); if ( result1.length ) result.set( result1 ); if ( result2.length ) result.set( result2, result1.length ); this.result = result; return this; } function AES_GCM_Decrypt_process ( data ) { if ( is_string(data) ) data = string_to_bytes(data); if ( is_buffer(data) ) data = new Uint8Array(data); if ( !is_bytes(data) ) throw new TypeError("data isn't of expected type"); var dpos = 0, dlen = data.length || 0, asm = this.asm, heap = this.heap, counter = this.counter, tagSize = this.tagSize, pos = this.pos, len = this.len, rpos = 0, rlen = len + dlen > tagSize ? ( len + dlen - tagSize ) & -16 : 0, tlen = len + dlen - rlen, wlen = 0; if ( ((counter-1)<<4) + len + dlen > _AES_GCM_data_maxLength ) throw new RangeError("counter overflow"); var result = new Uint8Array(rlen); while ( dlen > tlen ) { wlen = _heap_write( heap, pos+len, data, dpos, dlen-tlen ); len += wlen; dpos += wlen; dlen -= wlen; wlen = asm.mac( AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen ); wlen = asm.cipher( AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, wlen ); if ( wlen ) result.set( heap.subarray( pos, pos+wlen ), rpos ); counter += (wlen>>>4); rpos += wlen; pos = 0; len = 0; } if ( dlen > 0 ) { len += _heap_write( heap, 0, data, dpos, dlen ); } this.result = result; this.counter = counter; this.pos = pos; this.len = len; return this; } function AES_GCM_Decrypt_finish () { var asm = this.asm, heap = this.heap, tagSize = this.tagSize, adata = this.adata, counter = this.counter, pos = this.pos, len = this.len, rlen = len - tagSize, wlen = 0; if ( len < tagSize ) throw new IllegalStateError("authentication tag not found"); var result = new Uint8Array(rlen), atag = new Uint8Array( heap.subarray( pos+rlen, pos+len ) ); for ( var i = rlen; i & 15; i++ ) heap[ pos + i ] = 0; wlen = asm.mac( AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i ); wlen = asm.cipher( AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, i ); if ( rlen ) result.set( heap.subarray( pos, pos+rlen ) ); var alen = ( adata !== null ) ? adata.length : 0, clen = ( (counter-1) << 4) + len - tagSize; heap[0] = heap[1] = heap[2] = 0, heap[3] = alen>>>29, heap[4] = alen>>>21, heap[5] = alen>>>13&255, heap[6] = alen>>>5&255, heap[7] = alen<<3&255, heap[8] = heap[9] = heap[10] = 0, heap[11] = clen>>>29, heap[12] = clen>>>21&255, heap[13] = clen>>>13&255, heap[14] = clen>>>5&255, heap[15] = clen<<3&255; asm.mac( AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16 ); asm.get_iv( AES_asm.HEAP_DATA ); asm.set_counter( 0, 0, 0, this.gamma0 ); asm.cipher( AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16 ); var acheck = 0; for ( var i = 0; i < tagSize; ++i ) acheck |= atag[i] ^ heap[i]; if ( acheck ) throw new SecurityError("data integrity check failed"); this.result = result; this.counter = 1; this.pos = 0; this.len = 0; return this; } function AES_GCM_decrypt ( data ) { var result1 = AES_GCM_Decrypt_process.call( this, data ).result, result2 = AES_GCM_Decrypt_finish.call( this ).result; var result = new Uint8Array( result1.length + result2.length ); if ( result1.length ) result.set( result1 ); if ( result2.length ) result.set( result2, result1.length ); this.result = result; return this; } var AES_GCM_prototype = AES_GCM.prototype; AES_GCM_prototype.BLOCK_SIZE = 16; AES_GCM_prototype.reset = AES_GCM_reset; AES_GCM_prototype.encrypt = AES_GCM_encrypt; AES_GCM_prototype.decrypt = AES_GCM_decrypt; var AES_GCM_Encrypt_prototype = AES_GCM_Encrypt.prototype; AES_GCM_Encrypt_prototype.BLOCK_SIZE = 16; AES_GCM_Encrypt_prototype.reset = AES_GCM_reset; AES_GCM_Encrypt_prototype.process = AES_GCM_Encrypt_process; AES_GCM_Encrypt_prototype.finish = AES_GCM_Encrypt_finish; var AES_GCM_Decrypt_prototype = AES_GCM_Decrypt.prototype; AES_GCM_Decrypt_prototype.BLOCK_SIZE = 16; AES_GCM_Decrypt_prototype.reset = AES_GCM_reset; AES_GCM_Decrypt_prototype.process = AES_GCM_Decrypt_process; AES_GCM_Decrypt_prototype.finish = AES_GCM_Decrypt_finish; // shared asm.js module and heap var _AES_heap_instance = new Uint8Array(0x100000), _AES_asm_instance = AES_asm( global, null, _AES_heap_instance.buffer ); /** * AES-CFB exports */ function AES_CFB_encrypt_bytes ( data, key, iv ) { if ( data === undefined ) throw new SyntaxError("data required"); if ( key === undefined ) throw new SyntaxError("key required"); return new AES_CFB( { heap: _AES_heap_instance, asm: _AES_asm_instance, key: key, iv: iv } ).encrypt(data).result; } function AES_CFB_decrypt_bytes ( data, key, iv ) { if ( data === undefined ) throw new SyntaxError("data required"); if ( key === undefined ) throw new SyntaxError("key required"); return new AES_CFB( { heap: _AES_heap_instance, asm: _AES_asm_instance, key: key, iv: iv } ).decrypt(data).result; } exports.AES_CFB = AES_CFB; exports.AES_CFB.encrypt = AES_CFB_encrypt_bytes; exports.AES_CFB.decrypt = AES_CFB_decrypt_bytes; exports.AES_CFB.Encrypt = AES_CFB_Encrypt; exports.AES_CFB.Decrypt = AES_CFB_Decrypt; /** * AES-GCM exports */ function AES_GCM_encrypt_bytes ( data, key, nonce, adata, tagSize ) { if ( data === undefined ) throw new SyntaxError("data required"); if ( key === undefined ) throw new SyntaxError("key required"); if ( nonce === undefined ) throw new SyntaxError("nonce required"); return new AES_GCM( { heap: _AES_heap_instance, asm: _AES_asm_instance, key: key, nonce: nonce, adata: adata, tagSize: tagSize } ).encrypt(data).result; } function AES_GCM_decrypt_bytes ( data, key, nonce, adata, tagSize ) { if ( data === undefined ) throw new SyntaxError("data required"); if ( key === undefined ) throw new SyntaxError("key required"); if ( nonce === undefined ) throw new SyntaxError("nonce required"); return new AES_GCM( { heap: _AES_heap_instance, asm: _AES_asm_instance, key: key, nonce: nonce, adata: adata, tagSize: tagSize } ).decrypt(data).result; } exports.AES_GCM = AES_GCM; exports.AES_GCM.encrypt = AES_GCM_encrypt_bytes; exports.AES_GCM.decrypt = AES_GCM_decrypt_bytes; exports.AES_GCM.Encrypt = AES_GCM_Encrypt; exports.AES_GCM.Decrypt = AES_GCM_Decrypt; function hash_reset () { this.result = null; this.pos = 0; this.len = 0; this.asm.reset(); return this; } function hash_process ( data ) { if ( this.result !== null ) throw new IllegalStateError("state must be reset before processing new data"); if ( is_string(data) ) data = string_to_bytes(data); if ( is_buffer(data) ) data = new Uint8Array(data); if ( !is_bytes(data) ) throw new TypeError("data isn't of expected type"); var asm = this.asm, heap = this.heap, hpos = this.pos, hlen = this.len, dpos = 0, dlen = data.length, wlen = 0; while ( dlen > 0 ) { wlen = _heap_write( heap, hpos+hlen, data, dpos, dlen ); hlen += wlen; dpos += wlen; dlen -= wlen; wlen = asm.process( hpos, hlen ); hpos += wlen; hlen -= wlen; if ( !hlen ) hpos = 0; } this.pos = hpos; this.len = hlen; return this; } function hash_finish () { if ( this.result !== null ) throw new IllegalStateError("state must be reset before processing new data"); this.asm.finish( this.pos, this.len, 0 ); this.result = new Uint8Array(this.HASH_SIZE); this.result.set( this.heap.subarray( 0, this.HASH_SIZE ) ); this.pos = 0; this.len = 0; return this; } function sha256_asm ( stdlib, foreign, buffer ) { "use asm"; // SHA256 state var H0 = 0, H1 = 0, H2 = 0, H3 = 0, H4 = 0, H5 = 0, H6 = 0, H7 = 0, TOTAL0 = 0, TOTAL1 = 0; // HMAC state var I0 = 0, I1 = 0, I2 = 0, I3 = 0, I4 = 0, I5 = 0, I6 = 0, I7 = 0, O0 = 0, O1 = 0, O2 = 0, O3 = 0, O4 = 0, O5 = 0, O6 = 0, O7 = 0; // I/O buffer var HEAP = new stdlib.Uint8Array(buffer); function _core ( w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15 ) { w0 = w0|0; w1 = w1|0; w2 = w2|0; w3 = w3|0; w4 = w4|0; w5 = w5|0; w6 = w6|0; w7 = w7|0; w8 = w8|0; w9 = w9|0; w10 = w10|0; w11 = w11|0; w12 = w12|0; w13 = w13|0; w14 = w14|0; w15 = w15|0; var a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, t = 0; a = H0; b = H1; c = H2; d = H3; e = H4; f = H5; g = H6; h = H7; // 0 t = ( w0 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x428a2f98 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 1 t = ( w1 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x71374491 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 2 t = ( w2 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xb5c0fbcf )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 3 t = ( w3 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xe9b5dba5 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 4 t = ( w4 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x3956c25b )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 5 t = ( w5 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x59f111f1 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 6 t = ( w6 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x923f82a4 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 7 t = ( w7 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xab1c5ed5 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 8 t = ( w8 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xd807aa98 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 9 t = ( w9 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x12835b01 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 10 t = ( w10 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x243185be )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 11 t = ( w11 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x550c7dc3 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 12 t = ( w12 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x72be5d74 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 13 t = ( w13 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x80deb1fe )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 14 t = ( w14 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x9bdc06a7 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 15 t = ( w15 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xc19bf174 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 16 w0 = t = ( ( w1>>>7 ^ w1>>>18 ^ w1>>>3 ^ w1<<25 ^ w1<<14 ) + ( w14>>>17 ^ w14>>>19 ^ w14>>>10 ^ w14<<15 ^ w14<<13 ) + w0 + w9 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xe49b69c1 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 17 w1 = t = ( ( w2>>>7 ^ w2>>>18 ^ w2>>>3 ^ w2<<25 ^ w2<<14 ) + ( w15>>>17 ^ w15>>>19 ^ w15>>>10 ^ w15<<15 ^ w15<<13 ) + w1 + w10 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xefbe4786 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 18 w2 = t = ( ( w3>>>7 ^ w3>>>18 ^ w3>>>3 ^ w3<<25 ^ w3<<14 ) + ( w0>>>17 ^ w0>>>19 ^ w0>>>10 ^ w0<<15 ^ w0<<13 ) + w2 + w11 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x0fc19dc6 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 19 w3 = t = ( ( w4>>>7 ^ w4>>>18 ^ w4>>>3 ^ w4<<25 ^ w4<<14 ) + ( w1>>>17 ^ w1>>>19 ^ w1>>>10 ^ w1<<15 ^ w1<<13 ) + w3 + w12 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x240ca1cc )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 20 w4 = t = ( ( w5>>>7 ^ w5>>>18 ^ w5>>>3 ^ w5<<25 ^ w5<<14 ) + ( w2>>>17 ^ w2>>>19 ^ w2>>>10 ^ w2<<15 ^ w2<<13 ) + w4 + w13 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x2de92c6f )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 21 w5 = t = ( ( w6>>>7 ^ w6>>>18 ^ w6>>>3 ^ w6<<25 ^ w6<<14 ) + ( w3>>>17 ^ w3>>>19 ^ w3>>>10 ^ w3<<15 ^ w3<<13 ) + w5 + w14 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x4a7484aa )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 22 w6 = t = ( ( w7>>>7 ^ w7>>>18 ^ w7>>>3 ^ w7<<25 ^ w7<<14 ) + ( w4>>>17 ^ w4>>>19 ^ w4>>>10 ^ w4<<15 ^ w4<<13 ) + w6 + w15 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x5cb0a9dc )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 23 w7 = t = ( ( w8>>>7 ^ w8>>>18 ^ w8>>>3 ^ w8<<25 ^ w8<<14 ) + ( w5>>>17 ^ w5>>>19 ^ w5>>>10 ^ w5<<15 ^ w5<<13 ) + w7 + w0 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x76f988da )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 24 w8 = t = ( ( w9>>>7 ^ w9>>>18 ^ w9>>>3 ^ w9<<25 ^ w9<<14 ) + ( w6>>>17 ^ w6>>>19 ^ w6>>>10 ^ w6<<15 ^ w6<<13 ) + w8 + w1 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x983e5152 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 25 w9 = t = ( ( w10>>>7 ^ w10>>>18 ^ w10>>>3 ^ w10<<25 ^ w10<<14 ) + ( w7>>>17 ^ w7>>>19 ^ w7>>>10 ^ w7<<15 ^ w7<<13 ) + w9 + w2 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xa831c66d )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 26 w10 = t = ( ( w11>>>7 ^ w11>>>18 ^ w11>>>3 ^ w11<<25 ^ w11<<14 ) + ( w8>>>17 ^ w8>>>19 ^ w8>>>10 ^ w8<<15 ^ w8<<13 ) + w10 + w3 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xb00327c8 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 27 w11 = t = ( ( w12>>>7 ^ w12>>>18 ^ w12>>>3 ^ w12<<25 ^ w12<<14 ) + ( w9>>>17 ^ w9>>>19 ^ w9>>>10 ^ w9<<15 ^ w9<<13 ) + w11 + w4 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xbf597fc7 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 28 w12 = t = ( ( w13>>>7 ^ w13>>>18 ^ w13>>>3 ^ w13<<25 ^ w13<<14 ) + ( w10>>>17 ^ w10>>>19 ^ w10>>>10 ^ w10<<15 ^ w10<<13 ) + w12 + w5 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xc6e00bf3 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 29 w13 = t = ( ( w14>>>7 ^ w14>>>18 ^ w14>>>3 ^ w14<<25 ^ w14<<14 ) + ( w11>>>17 ^ w11>>>19 ^ w11>>>10 ^ w11<<15 ^ w11<<13 ) + w13 + w6 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xd5a79147 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 30 w14 = t = ( ( w15>>>7 ^ w15>>>18 ^ w15>>>3 ^ w15<<25 ^ w15<<14 ) + ( w12>>>17 ^ w12>>>19 ^ w12>>>10 ^ w12<<15 ^ w12<<13 ) + w14 + w7 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x06ca6351 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 31 w15 = t = ( ( w0>>>7 ^ w0>>>18 ^ w0>>>3 ^ w0<<25 ^ w0<<14 ) + ( w13>>>17 ^ w13>>>19 ^ w13>>>10 ^ w13<<15 ^ w13<<13 ) + w15 + w8 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x14292967 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 32 w0 = t = ( ( w1>>>7 ^ w1>>>18 ^ w1>>>3 ^ w1<<25 ^ w1<<14 ) + ( w14>>>17 ^ w14>>>19 ^ w14>>>10 ^ w14<<15 ^ w14<<13 ) + w0 + w9 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x27b70a85 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 33 w1 = t = ( ( w2>>>7 ^ w2>>>18 ^ w2>>>3 ^ w2<<25 ^ w2<<14 ) + ( w15>>>17 ^ w15>>>19 ^ w15>>>10 ^ w15<<15 ^ w15<<13 ) + w1 + w10 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x2e1b2138 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 34 w2 = t = ( ( w3>>>7 ^ w3>>>18 ^ w3>>>3 ^ w3<<25 ^ w3<<14 ) + ( w0>>>17 ^ w0>>>19 ^ w0>>>10 ^ w0<<15 ^ w0<<13 ) + w2 + w11 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x4d2c6dfc )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 35 w3 = t = ( ( w4>>>7 ^ w4>>>18 ^ w4>>>3 ^ w4<<25 ^ w4<<14 ) + ( w1>>>17 ^ w1>>>19 ^ w1>>>10 ^ w1<<15 ^ w1<<13 ) + w3 + w12 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x53380d13 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 36 w4 = t = ( ( w5>>>7 ^ w5>>>18 ^ w5>>>3 ^ w5<<25 ^ w5<<14 ) + ( w2>>>17 ^ w2>>>19 ^ w2>>>10 ^ w2<<15 ^ w2<<13 ) + w4 + w13 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x650a7354 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 37 w5 = t = ( ( w6>>>7 ^ w6>>>18 ^ w6>>>3 ^ w6<<25 ^ w6<<14 ) + ( w3>>>17 ^ w3>>>19 ^ w3>>>10 ^ w3<<15 ^ w3<<13 ) + w5 + w14 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x766a0abb )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 38 w6 = t = ( ( w7>>>7 ^ w7>>>18 ^ w7>>>3 ^ w7<<25 ^ w7<<14 ) + ( w4>>>17 ^ w4>>>19 ^ w4>>>10 ^ w4<<15 ^ w4<<13 ) + w6 + w15 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x81c2c92e )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 39 w7 = t = ( ( w8>>>7 ^ w8>>>18 ^ w8>>>3 ^ w8<<25 ^ w8<<14 ) + ( w5>>>17 ^ w5>>>19 ^ w5>>>10 ^ w5<<15 ^ w5<<13 ) + w7 + w0 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x92722c85 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 40 w8 = t = ( ( w9>>>7 ^ w9>>>18 ^ w9>>>3 ^ w9<<25 ^ w9<<14 ) + ( w6>>>17 ^ w6>>>19 ^ w6>>>10 ^ w6<<15 ^ w6<<13 ) + w8 + w1 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xa2bfe8a1 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 41 w9 = t = ( ( w10>>>7 ^ w10>>>18 ^ w10>>>3 ^ w10<<25 ^ w10<<14 ) + ( w7>>>17 ^ w7>>>19 ^ w7>>>10 ^ w7<<15 ^ w7<<13 ) + w9 + w2 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xa81a664b )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 42 w10 = t = ( ( w11>>>7 ^ w11>>>18 ^ w11>>>3 ^ w11<<25 ^ w11<<14 ) + ( w8>>>17 ^ w8>>>19 ^ w8>>>10 ^ w8<<15 ^ w8<<13 ) + w10 + w3 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xc24b8b70 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 43 w11 = t = ( ( w12>>>7 ^ w12>>>18 ^ w12>>>3 ^ w12<<25 ^ w12<<14 ) + ( w9>>>17 ^ w9>>>19 ^ w9>>>10 ^ w9<<15 ^ w9<<13 ) + w11 + w4 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xc76c51a3 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 44 w12 = t = ( ( w13>>>7 ^ w13>>>18 ^ w13>>>3 ^ w13<<25 ^ w13<<14 ) + ( w10>>>17 ^ w10>>>19 ^ w10>>>10 ^ w10<<15 ^ w10<<13 ) + w12 + w5 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xd192e819 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 45 w13 = t = ( ( w14>>>7 ^ w14>>>18 ^ w14>>>3 ^ w14<<25 ^ w14<<14 ) + ( w11>>>17 ^ w11>>>19 ^ w11>>>10 ^ w11<<15 ^ w11<<13 ) + w13 + w6 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xd6990624 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 46 w14 = t = ( ( w15>>>7 ^ w15>>>18 ^ w15>>>3 ^ w15<<25 ^ w15<<14 ) + ( w12>>>17 ^ w12>>>19 ^ w12>>>10 ^ w12<<15 ^ w12<<13 ) + w14 + w7 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xf40e3585 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 47 w15 = t = ( ( w0>>>7 ^ w0>>>18 ^ w0>>>3 ^ w0<<25 ^ w0<<14 ) + ( w13>>>17 ^ w13>>>19 ^ w13>>>10 ^ w13<<15 ^ w13<<13 ) + w15 + w8 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x106aa070 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 48 w0 = t = ( ( w1>>>7 ^ w1>>>18 ^ w1>>>3 ^ w1<<25 ^ w1<<14 ) + ( w14>>>17 ^ w14>>>19 ^ w14>>>10 ^ w14<<15 ^ w14<<13 ) + w0 + w9 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x19a4c116 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 49 w1 = t = ( ( w2>>>7 ^ w2>>>18 ^ w2>>>3 ^ w2<<25 ^ w2<<14 ) + ( w15>>>17 ^ w15>>>19 ^ w15>>>10 ^ w15<<15 ^ w15<<13 ) + w1 + w10 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x1e376c08 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 50 w2 = t = ( ( w3>>>7 ^ w3>>>18 ^ w3>>>3 ^ w3<<25 ^ w3<<14 ) + ( w0>>>17 ^ w0>>>19 ^ w0>>>10 ^ w0<<15 ^ w0<<13 ) + w2 + w11 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x2748774c )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 51 w3 = t = ( ( w4>>>7 ^ w4>>>18 ^ w4>>>3 ^ w4<<25 ^ w4<<14 ) + ( w1>>>17 ^ w1>>>19 ^ w1>>>10 ^ w1<<15 ^ w1<<13 ) + w3 + w12 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x34b0bcb5 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 52 w4 = t = ( ( w5>>>7 ^ w5>>>18 ^ w5>>>3 ^ w5<<25 ^ w5<<14 ) + ( w2>>>17 ^ w2>>>19 ^ w2>>>10 ^ w2<<15 ^ w2<<13 ) + w4 + w13 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x391c0cb3 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 53 w5 = t = ( ( w6>>>7 ^ w6>>>18 ^ w6>>>3 ^ w6<<25 ^ w6<<14 ) + ( w3>>>17 ^ w3>>>19 ^ w3>>>10 ^ w3<<15 ^ w3<<13 ) + w5 + w14 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x4ed8aa4a )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 54 w6 = t = ( ( w7>>>7 ^ w7>>>18 ^ w7>>>3 ^ w7<<25 ^ w7<<14 ) + ( w4>>>17 ^ w4>>>19 ^ w4>>>10 ^ w4<<15 ^ w4<<13 ) + w6 + w15 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x5b9cca4f )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 55 w7 = t = ( ( w8>>>7 ^ w8>>>18 ^ w8>>>3 ^ w8<<25 ^ w8<<14 ) + ( w5>>>17 ^ w5>>>19 ^ w5>>>10 ^ w5<<15 ^ w5<<13 ) + w7 + w0 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x682e6ff3 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 56 w8 = t = ( ( w9>>>7 ^ w9>>>18 ^ w9>>>3 ^ w9<<25 ^ w9<<14 ) + ( w6>>>17 ^ w6>>>19 ^ w6>>>10 ^ w6<<15 ^ w6<<13 ) + w8 + w1 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x748f82ee )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 57 w9 = t = ( ( w10>>>7 ^ w10>>>18 ^ w10>>>3 ^ w10<<25 ^ w10<<14 ) + ( w7>>>17 ^ w7>>>19 ^ w7>>>10 ^ w7<<15 ^ w7<<13 ) + w9 + w2 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x78a5636f )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 58 w10 = t = ( ( w11>>>7 ^ w11>>>18 ^ w11>>>3 ^ w11<<25 ^ w11<<14 ) + ( w8>>>17 ^ w8>>>19 ^ w8>>>10 ^ w8<<15 ^ w8<<13 ) + w10 + w3 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x84c87814 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 59 w11 = t = ( ( w12>>>7 ^ w12>>>18 ^ w12>>>3 ^ w12<<25 ^ w12<<14 ) + ( w9>>>17 ^ w9>>>19 ^ w9>>>10 ^ w9<<15 ^ w9<<13 ) + w11 + w4 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x8cc70208 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 60 w12 = t = ( ( w13>>>7 ^ w13>>>18 ^ w13>>>3 ^ w13<<25 ^ w13<<14 ) + ( w10>>>17 ^ w10>>>19 ^ w10>>>10 ^ w10<<15 ^ w10<<13 ) + w12 + w5 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x90befffa )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 61 w13 = t = ( ( w14>>>7 ^ w14>>>18 ^ w14>>>3 ^ w14<<25 ^ w14<<14 ) + ( w11>>>17 ^ w11>>>19 ^ w11>>>10 ^ w11<<15 ^ w11<<13 ) + w13 + w6 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xa4506ceb )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 62 w14 = t = ( ( w15>>>7 ^ w15>>>18 ^ w15>>>3 ^ w15<<25 ^ w15<<14 ) + ( w12>>>17 ^ w12>>>19 ^ w12>>>10 ^ w12<<15 ^ w12<<13 ) + w14 + w7 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xbef9a3f7 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; // 63 w15 = t = ( ( w0>>>7 ^ w0>>>18 ^ w0>>>3 ^ w0<<25 ^ w0<<14 ) + ( w13>>>17 ^ w13>>>19 ^ w13>>>10 ^ w13<<15 ^ w13<<13 ) + w15 + w8 )|0; t = ( t + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xc67178f2 )|0; h = g; g = f; f = e; e = ( d + t )|0; d = c; c = b; b = a; a = ( t + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0; H0 = ( H0 + a )|0; H1 = ( H1 + b )|0; H2 = ( H2 + c )|0; H3 = ( H3 + d )|0; H4 = ( H4 + e )|0; H5 = ( H5 + f )|0; H6 = ( H6 + g )|0; H7 = ( H7 + h )|0; } function _core_heap ( offset ) { offset = offset|0; _core( HEAP[offset|0]<<24 | HEAP[offset|1]<<16 | HEAP[offset|2]<<8 | HEAP[offset|3], HEAP[offset|4]<<24 | HEAP[offset|5]<<16 | HEAP[offset|6]<<8 | HEAP[offset|7], HEAP[offset|8]<<24 | HEAP[offset|9]<<16 | HEAP[offset|10]<<8 | HEAP[offset|11], HEAP[offset|12]<<24 | HEAP[offset|13]<<16 | HEAP[offset|14]<<8 | HEAP[offset|15], HEAP[offset|16]<<24 | HEAP[offset|17]<<16 | HEAP[offset|18]<<8 | HEAP[offset|19], HEAP[offset|20]<<24 | HEAP[offset|21]<<16 | HEAP[offset|22]<<8 | HEAP[offset|23], HEAP[offset|24]<<24 | HEAP[offset|25]<<16 | HEAP[offset|26]<<8 | HEAP[offset|27], HEAP[offset|28]<<24 | HEAP[offset|29]<<16 | HEAP[offset|30]<<8 | HEAP[offset|31], HEAP[offset|32]<<24 | HEAP[offset|33]<<16 | HEAP[offset|34]<<8 | HEAP[offset|35], HEAP[offset|36]<<24 | HEAP[offset|37]<<16 | HEAP[offset|38]<<8 | HEAP[offset|39], HEAP[offset|40]<<24 | HEAP[offset|41]<<16 | HEAP[offset|42]<<8 | HEAP[offset|43], HEAP[offset|44]<<24 | HEAP[offset|45]<<16 | HEAP[offset|46]<<8 | HEAP[offset|47], HEAP[offset|48]<<24 | HEAP[offset|49]<<16 | HEAP[offset|50]<<8 | HEAP[offset|51], HEAP[offset|52]<<24 | HEAP[offset|53]<<16 | HEAP[offset|54]<<8 | HEAP[offset|55], HEAP[offset|56]<<24 | HEAP[offset|57]<<16 | HEAP[offset|58]<<8 | HEAP[offset|59], HEAP[offset|60]<<24 | HEAP[offset|61]<<16 | HEAP[offset|62]<<8 | HEAP[offset|63] ); } // offset — multiple of 32 function _state_to_heap ( output ) { output = output|0; HEAP[output|0] = H0>>>24; HEAP[output|1] = H0>>>16&255; HEAP[output|2] = H0>>>8&255; HEAP[output|3] = H0&255; HEAP[output|4] = H1>>>24; HEAP[output|5] = H1>>>16&255; HEAP[output|6] = H1>>>8&255; HEAP[output|7] = H1&255; HEAP[output|8] = H2>>>24; HEAP[output|9] = H2>>>16&255; HEAP[output|10] = H2>>>8&255; HEAP[output|11] = H2&255; HEAP[output|12] = H3>>>24; HEAP[output|13] = H3>>>16&255; HEAP[output|14] = H3>>>8&255; HEAP[output|15] = H3&255; HEAP[output|16] = H4>>>24; HEAP[output|17] = H4>>>16&255; HEAP[output|18] = H4>>>8&255; HEAP[output|19] = H4&255; HEAP[output|20] = H5>>>24; HEAP[output|21] = H5>>>16&255; HEAP[output|22] = H5>>>8&255; HEAP[output|23] = H5&255; HEAP[output|24] = H6>>>24; HEAP[output|25] = H6>>>16&255; HEAP[output|26] = H6>>>8&255; HEAP[output|27] = H6&255; HEAP[output|28] = H7>>>24; HEAP[output|29] = H7>>>16&255; HEAP[output|30] = H7>>>8&255; HEAP[output|31] = H7&255; } function reset () { H0 = 0x6a09e667; H1 = 0xbb67ae85; H2 = 0x3c6ef372; H3 = 0xa54ff53a; H4 = 0x510e527f; H5 = 0x9b05688c; H6 = 0x1f83d9ab; H7 = 0x5be0cd19; TOTAL0 = TOTAL1 = 0; } function init ( h0, h1, h2, h3, h4, h5, h6, h7, total0, total1 ) { h0 = h0|0; h1 = h1|0; h2 = h2|0; h3 = h3|0; h4 = h4|0; h5 = h5|0; h6 = h6|0; h7 = h7|0; total0 = total0|0; total1 = total1|0; H0 = h0; H1 = h1; H2 = h2; H3 = h3; H4 = h4; H5 = h5; H6 = h6; H7 = h7; TOTAL0 = total0; TOTAL1 = total1; } // offset — multiple of 64 function process ( offset, length ) { offset = offset|0; length = length|0; var hashed = 0; if ( offset & 63 ) return -1; while ( (length|0) >= 64 ) { _core_heap(offset); offset = ( offset + 64 )|0; length = ( length - 64 )|0; hashed = ( hashed + 64 )|0; } TOTAL0 = ( TOTAL0 + hashed )|0; if ( TOTAL0>>>0 < hashed>>>0 ) TOTAL1 = ( TOTAL1 + 1 )|0; return hashed|0; } // offset — multiple of 64 // output — multiple of 32 function finish ( offset, length, output ) { offset = offset|0; length = length|0; output = output|0; var hashed = 0, i = 0; if ( offset & 63 ) return -1; if ( ~output ) if ( output & 31 ) return -1; if ( (length|0) >= 64 ) { hashed = process( offset, length )|0; if ( (hashed|0) == -1 ) return -1; offset = ( offset + hashed )|0; length = ( length - hashed )|0; } hashed = ( hashed + length )|0; TOTAL0 = ( TOTAL0 + length )|0; if ( TOTAL0>>>0 < length>>>0 ) TOTAL1 = ( TOTAL1 + 1 )|0; HEAP[offset|length] = 0x80; if ( (length|0) >= 56 ) { for ( i = (length+1)|0; (i|0) < 64; i = (i+1)|0 ) HEAP[offset|i] = 0x00; _core_heap(offset); length = 0; HEAP[offset|0] = 0; } for ( i = (length+1)|0; (i|0) < 59; i = (i+1)|0 ) HEAP[offset|i] = 0; HEAP[offset|56] = TOTAL1>>>21&255; HEAP[offset|57] = TOTAL1>>>13&255; HEAP[offset|58] = TOTAL1>>>5&255; HEAP[offset|59] = TOTAL1<<3&255 | TOTAL0>>>29; HEAP[offset|60] = TOTAL0>>>21&255; HEAP[offset|61] = TOTAL0>>>13&255; HEAP[offset|62] = TOTAL0>>>5&255; HEAP[offset|63] = TOTAL0<<3&255; _core_heap(offset); if ( ~output ) _state_to_heap(output); return hashed|0; } function hmac_reset () { H0 = I0; H1 = I1; H2 = I2; H3 = I3; H4 = I4; H5 = I5; H6 = I6; H7 = I7; TOTAL0 = 64; TOTAL1 = 0; } function _hmac_opad () { H0 = O0; H1 = O1; H2 = O2; H3 = O3; H4 = O4; H5 = O5; H6 = O6; H7 = O7; TOTAL0 = 64; TOTAL1 = 0; } function hmac_init ( p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15 ) { p0 = p0|0; p1 = p1|0; p2 = p2|0; p3 = p3|0; p4 = p4|0; p5 = p5|0; p6 = p6|0; p7 = p7|0; p8 = p8|0; p9 = p9|0; p10 = p10|0; p11 = p11|0; p12 = p12|0; p13 = p13|0; p14 = p14|0; p15 = p15|0; // opad reset(); _core( p0 ^ 0x5c5c5c5c, p1 ^ 0x5c5c5c5c, p2 ^ 0x5c5c5c5c, p3 ^ 0x5c5c5c5c, p4 ^ 0x5c5c5c5c, p5 ^ 0x5c5c5c5c, p6 ^ 0x5c5c5c5c, p7 ^ 0x5c5c5c5c, p8 ^ 0x5c5c5c5c, p9 ^ 0x5c5c5c5c, p10 ^ 0x5c5c5c5c, p11 ^ 0x5c5c5c5c, p12 ^ 0x5c5c5c5c, p13 ^ 0x5c5c5c5c, p14 ^ 0x5c5c5c5c, p15 ^ 0x5c5c5c5c ); O0 = H0; O1 = H1; O2 = H2; O3 = H3; O4 = H4; O5 = H5; O6 = H6; O7 = H7; // ipad reset(); _core( p0 ^ 0x36363636, p1 ^ 0x36363636, p2 ^ 0x36363636, p3 ^ 0x36363636, p4 ^ 0x36363636, p5 ^ 0x36363636, p6 ^ 0x36363636, p7 ^ 0x36363636, p8 ^ 0x36363636, p9 ^ 0x36363636, p10 ^ 0x36363636, p11 ^ 0x36363636, p12 ^ 0x36363636, p13 ^ 0x36363636, p14 ^ 0x36363636, p15 ^ 0x36363636 ); I0 = H0; I1 = H1; I2 = H2; I3 = H3; I4 = H4; I5 = H5; I6 = H6; I7 = H7; TOTAL0 = 64; TOTAL1 = 0; } // offset — multiple of 64 // output — multiple of 32 function hmac_finish ( offset, length, output ) { offset = offset|0; length = length|0; output = output|0; var t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, hashed = 0; if ( offset & 63 ) return -1; if ( ~output ) if ( output & 31 ) return -1; hashed = finish( offset, length, -1 )|0; t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7; _hmac_opad(); _core( t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768 ); if ( ~output ) _state_to_heap(output); return hashed|0; } // salt is assumed to be already processed // offset — multiple of 64 // output — multiple of 32 function pbkdf2_generate_block ( offset, length, block, count, output ) { offset = offset|0; length = length|0; block = block|0; count = count|0; output = output|0; var h0 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0, h5 = 0, h6 = 0, h7 = 0, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0; if ( offset & 63 ) return -1; if ( ~output ) if ( output & 31 ) return -1; // pad block number into heap // FIXME probable OOB write HEAP[(offset+length)|0] = block>>>24; HEAP[(offset+length+1)|0] = block>>>16&255; HEAP[(offset+length+2)|0] = block>>>8&255; HEAP[(offset+length+3)|0] = block&255; // finish first iteration hmac_finish( offset, (length+4)|0, -1 )|0; h0 = t0 = H0, h1 = t1 = H1, h2 = t2 = H2, h3 = t3 = H3, h4 = t4 = H4, h5 = t5 = H5, h6 = t6 = H6, h7 = t7 = H7; count = (count-1)|0; // perform the rest iterations while ( (count|0) > 0 ) { hmac_reset(); _core( t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768 ); t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7; _hmac_opad(); _core( t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768 ); t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7; h0 = h0 ^ H0; h1 = h1 ^ H1; h2 = h2 ^ H2; h3 = h3 ^ H3; h4 = h4 ^ H4; h5 = h5 ^ H5; h6 = h6 ^ H6; h7 = h7 ^ H7; count = (count-1)|0; } H0 = h0; H1 = h1; H2 = h2; H3 = h3; H4 = h4; H5 = h5; H6 = h6; H7 = h7; if ( ~output ) _state_to_heap(output); return 0; } return { // SHA256 reset: reset, init: init, process: process, finish: finish, // HMAC-SHA256 hmac_reset: hmac_reset, hmac_init: hmac_init, hmac_finish: hmac_finish, // PBKDF2-HMAC-SHA256 pbkdf2_generate_block: pbkdf2_generate_block } } var _sha256_block_size = 64, _sha256_hash_size = 32; function sha256_constructor ( options ) { options = options || {}; this.heap = _heap_init( Uint8Array, options ); this.asm = options.asm || sha256_asm( global, null, this.heap.buffer ); this.BLOCK_SIZE = _sha256_block_size; this.HASH_SIZE = _sha256_hash_size; this.reset(); } sha256_constructor.BLOCK_SIZE = _sha256_block_size; sha256_constructor.HASH_SIZE = _sha256_hash_size; var sha256_prototype = sha256_constructor.prototype; sha256_prototype.reset = hash_reset; sha256_prototype.process = hash_process; sha256_prototype.finish = hash_finish; var sha256_instance = null; function get_sha256_instance () { if ( sha256_instance === null ) sha256_instance = new sha256_constructor( { heapSize: 0x100000 } ); return sha256_instance; } /** * SHA256 exports */ function sha256_bytes ( data ) { if ( data === undefined ) throw new SyntaxError("data required"); return get_sha256_instance().reset().process(data).finish().result; } function sha256_hex ( data ) { var result = sha256_bytes(data); return bytes_to_hex(result); } function sha256_base64 ( data ) { var result = sha256_bytes(data); return bytes_to_base64(result); } sha256_constructor.bytes = sha256_bytes; sha256_constructor.hex = sha256_hex; sha256_constructor.base64 = sha256_base64; exports.SHA256 = sha256_constructor; 'object'==typeof module&&module.exports?module.exports=exports:global.asmCrypto=exports; return exports; })( {}, this );