mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 12:39:20 +03:00
2898 lines
95 KiB
JavaScript
2898 lines
95 KiB
JavaScript
/*! 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 <vybornov@gmail.com>
|
|
* @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.
|
|
*
|
|
* <p>
|
|
* Heap buffer layout by offset:
|
|
* <pre>
|
|
* 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
|
|
* </pre>
|
|
* Don't touch anything before <code>0x400</code>.
|
|
* </p>
|
|
*
|
|
* @alias AES_asm
|
|
* @class
|
|
* @param {GlobalScope} stdlib - global scope object (e.g. <code>window</code>)
|
|
* @param {Object} foreign - <i>ignored</i>
|
|
* @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 );
|