| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| (function() { |
| "use strict"; |
|
|
| |
|
|
| function u8(arr) { return arr instanceof Uint8Array ? arr : new Uint8Array(arr); } |
| function view(buf) { |
| return buf instanceof ArrayBuffer ? new Uint8Array(buf) : |
| buf.buffer && buf.buffer instanceof ArrayBuffer ? new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength) : |
| u8(buf); |
| } |
|
|
| |
|
|
| |
| var SHA256_K = new Uint32Array([ |
| 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, |
| 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, |
| 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, |
| 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, |
| 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, |
| 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, |
| 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, |
| 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 |
| ]); |
|
|
| function sha256_block(H, block) { |
| var w = new Uint32Array(64); |
| for (var i = 0; i < 16; i++) { |
| w[i] = (block[i*4]<<24) | (block[i*4+1]<<16) | (block[i*4+2]<<8) | block[i*4+3]; |
| } |
| for (var i = 16; i < 64; i++) { |
| var s0 = ((w[i-15]>>>7)^(w[i-15]>>>18)^(w[i-15]>>>3)) ^ ((w[i-15]<<25)^(w[i-15]<<14)); |
| var s1 = ((w[i-2]>>>17)^(w[i-2]>>>19)^(w[i-2]>>>10)) ^ ((w[i-2]<<15)^(w[i-2]<<13)); |
| w[i] = (w[i-16] + s0 + w[i-7] + s1) | 0; |
| } |
| var a=H[0],b=H[1],c=H[2],d=H[3],e=H[4],f=H[5],g=H[6],h=H[7]; |
| for (var i = 0; i < 64; i++) { |
| var S1 = ((e>>>6)^(e>>>11)^(e>>>25)) ^ ((e<<(32-6))^(e<<(32-11))^(e<<(32-25))); |
| var ch = (e&f)^(~e&g); |
| var t1 = (h + S1 + ch + SHA256_K[i] + w[i]) | 0; |
| var S0 = ((a>>>2)^(a>>>13)^(a>>>22)) ^ ((a<<(32-2))^(a<<(32-13))^(a<<(32-22))); |
| var maj = (a&b)^(a&c)^(b&c); |
| var t2 = (S0 + maj) | 0; |
| h=g; g=f; f=e; e=(d+t1)|0; d=c; c=b; b=a; a=(t1+t2)|0; |
| } |
| H[0]=(H[0]+a)|0; H[1]=(H[1]+b)|0; H[2]=(H[2]+c)|0; H[3]=(H[3]+d)|0; |
| H[4]=(H[4]+e)|0; H[5]=(H[5]+f)|0; H[6]=(H[6]+g)|0; H[7]=(H[7]+h)|0; |
| } |
|
|
| function _sha256(data) { |
| var msg = view(data); |
| var H = new Uint32Array([0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19]); |
| var len = msg.length; |
| var bitLen = len * 8; |
| |
| var padLen; |
| if ((len + 1) % 64 <= 56) { |
| padLen = 56 - (len + 1) % 64; |
| } else { |
| padLen = 64 + 56 - (len + 1) % 64; |
| } |
| var total = len + 1 + padLen + 8; |
| var padded = new Uint8Array(total); |
| padded.set(msg); |
| padded[len] = 0x80; |
| |
| padded[total-8] = (bitLen / 0x100000000) & 0xff; |
| padded[total-7] = ((bitLen / 0x1000000) & 0xff); |
| padded[total-6] = ((bitLen / 0x10000) & 0xff); |
| padded[total-5] = ((bitLen / 0x100) & 0xff); |
| padded[total-4] = (bitLen >>> 24) & 0xff; |
| padded[total-3] = (bitLen >>> 16) & 0xff; |
| padded[total-2] = (bitLen >>> 8) & 0xff; |
| padded[total-1] = bitLen & 0xff; |
| for (var i = 0; i < padded.length; i += 64) { |
| sha256_block(H, padded.subarray(i, i + 64)); |
| } |
| var out = new Uint8Array(32); |
| for (var i = 0; i < 8; i++) { |
| out[i*4] = (H[i] >>> 24) & 0xff; |
| out[i*4+1] = (H[i] >>> 16) & 0xff; |
| out[i*4+2] = (H[i] >>> 8) & 0xff; |
| out[i*4+3] = H[i] & 0xff; |
| } |
| return out; |
| } |
|
|
| |
| function _sha1(data) { |
| var msg = view(data); |
| var h0=0x67452301, h1=0xEFCDAB89, h2=0x98BADCFE, h3=0x10325476, h4=0xC3D2E1F0; |
| var len = msg.length; |
| var bitLen = len * 8; |
| var padLen; |
| if ((len + 1) % 64 <= 56) { |
| padLen = 56 - (len + 1) % 64; |
| } else { |
| padLen = 64 + 56 - (len + 1) % 64; |
| } |
| var total = len + 1 + padLen + 8; |
| var padded = new Uint8Array(total); |
| padded.set(msg); |
| padded[len] = 0x80; |
| padded[total-4] = (bitLen >>> 24) & 0xff; |
| padded[total-3] = (bitLen >>> 16) & 0xff; |
| padded[total-2] = (bitLen >>> 8) & 0xff; |
| padded[total-1] = bitLen & 0xff; |
| for (var off = 0; off < total; off += 64) { |
| var w = new Uint32Array(80); |
| for (var i = 0; i < 16; i++) { |
| w[i] = (padded[off+i*4]<<24) | (padded[off+i*4+1]<<16) | (padded[off+i*4+2]<<8) | padded[off+i*4+3]; |
| } |
| for (var i = 16; i < 80; i++) { |
| w[i] = ((w[i-3]^w[i-8]^w[i-14]^w[i-16]) << 1) | ((w[i-3]^w[i-8]^w[i-14]^w[i-16]) >>> 31); |
| } |
| var a=h0,b=h1,c=h2,d=h3,e=h4; |
| for (var i = 0; i < 80; i++) { |
| var f,k; |
| if (i<20) { f=(b&c)|(~b&d); k=0x5A827999; } |
| else if (i<40) { f=b^c^d; k=0x6ED9EBA1; } |
| else if (i<60) { f=(b&c)|(b&d)|(c&d); k=0x8F1BBCDC; } |
| else { f=b^c^d; k=0xCA62C1D6; } |
| var temp = (((a<<5)|(a>>>27)) + f + e + k + w[i]) | 0; |
| e=d; d=c; c=((b<<30)|(b>>>2)); b=a; a=temp; |
| } |
| h0=(h0+a)|0; h1=(h1+b)|0; h2=(h2+c)|0; h3=(h3+d)|0; h4=(h4+e)|0; |
| } |
| var out = new Uint8Array(20); |
| var H = [h0,h1,h2,h3,h4]; |
| for (var i = 0; i < 5; i++) { |
| out[i*4] = (H[i] >>> 24) & 0xff; |
| out[i*4+1] = (H[i] >>> 16) & 0xff; |
| out[i*4+2] = (H[i] >>> 8) & 0xff; |
| out[i*4+3] = H[i] & 0xff; |
| } |
| return out; |
| } |
|
|
| |
| var SHA512_K = null; |
| function _init_sha512_k() { |
| if (SHA512_K) return; |
| |
| SHA512_K = [ |
| 0x428a2f98d728ae22n,0x7137449123ef65cdn,0xb5c0fbcfec4d3b2fn,0xe9b5dba58189dbbcn, |
| 0x3956c25bf348b538n,0x59f111f1b605d019n,0x923f82a4af194f9bn,0xab1c5ed5da6d8118n, |
| 0xd807aa98a3030242n,0x12835b0145706fben,0x243185be4ee4b28cn,0x550c7dc3d5ffb4e2n, |
| 0x72be5d74f27b896fn,0x80deb1fe3b1696b1n,0x9bdc06a725c71235n,0xc19bf174cf692694n, |
| 0xe49b69c19ef14ad2n,0xefbe4786384f25e3n,0x0fc19dc68b8cd5b5n,0x240ca1cc77ac9c65n, |
| 0x2de92c6f592b0275n,0x4a7484aa6ea6e483n,0x5cb0a9dcbd41fbd4n,0x76f988da831153b5n, |
| 0x983e5152ee66dfabn,0xa831c66d2db43210n,0xb00327c898fb213fn,0xbf597fc7beef0ee4n, |
| 0xc6e00bf33da88fc2n,0xd5a79147930aa725n,0x06ca6351e003826fn,0x142929670a0e6e70n, |
| 0x27b70a8546d22ffcn,0x2e1b21385c26c926n,0x4d2c6dfc5ac42aedn,0x53380d139d95b3dfn, |
| 0x650a73548baf63den,0x766a0abb3c77b2a8n,0x81c2c92e47edaee6n,0x92722c851482353bn, |
| 0xa2bfe8a14cf10364n,0xa81a664bbc423001n,0xc24b8b70d0f89791n,0xc76c51a30654be30n, |
| 0xd192e819d6ef5218n,0xd69906245565a910n,0xf40e35855771202an,0x106aa07032bbd1b8n, |
| 0x19a4c116b8d2d0c8n,0x1e376c085141ab53n,0x2748774cdf8eeb99n,0x34b0bcb5e19b48a8n, |
| 0x391c0cb3c5c95a63n,0x4ed8aa4ae3418acbn,0x5b9cca4f7763e373n,0x682e6ff3d6b2b8a3n, |
| 0x748f82ee5defb2fcn,0x78a5636f43172f60n,0x84c87814a1f0ab72n,0x8cc702081a6439ecn, |
| 0x90befffa23631e28n,0xa4506cebde82bde9n,0xbef9a3f7b2c67915n,0xc67178f2e372532bn, |
| 0xca273eceea26619cn,0xd186b8c721c0c207n,0xeada7dd6cde0eb1en,0xf57d4f7fee6ed178n, |
| 0x06f067aa72176fban,0x0a637dc5a2c898a6n,0x113f9804bef90daen,0x1b710b35131c471bn, |
| 0x28db77f523047d84n,0x32caab7b40c72493n,0x3c9ebe0a15c9bebcn,0x431d67c49c100d4cn, |
| 0x4cc5d4becb3e42b6n,0x597f299cfc657e2an,0x5fcb6fab3ad6faecn,0x6c44198c4a475817n |
| ]; |
| } |
|
|
| function _sha512(data) { |
| _init_sha512_k(); |
| var msg = view(data); |
| var M = 0xFFFFFFFFFFFFFFFFn; |
| var H = [0x6a09e667f3bcc908n,0xbb67ae8584caa73bn,0x3c6ef372fe94f82bn,0xa54ff53a5f1d36f1n, |
| 0x510e527fade682d1n,0x9b05688c2b3e6c1fn,0x1f83d9abfb41bd6bn,0x5be0cd19137e2179n]; |
| var len = msg.length; |
| var bitLen = BigInt(len * 8); |
| var padLen; |
| if ((len + 1) % 128 <= 112) { |
| padLen = 112 - (len + 1) % 128; |
| } else { |
| padLen = 128 + 112 - (len + 1) % 128; |
| } |
| var total = len + 1 + padLen + 16; |
| var padded = new Uint8Array(total); |
| padded.set(msg); |
| padded[len] = 0x80; |
| |
| for (var i = 0; i < 8; i++) padded[total-8+i] = 0; |
| for (var i = 0; i < 8; i++) { |
| padded[total-1-i] = Number((bitLen >> BigInt(i*8)) & 0xFFn); |
| } |
| for (var off = 0; off < total; off += 128) { |
| var w = new Array(80); |
| for (var i = 0; i < 16; i++) { |
| w[i] = 0n; |
| for (var j = 0; j < 8; j++) w[i] = (w[i] << 8n) | BigInt(padded[off+i*8+j]); |
| } |
| for (var i = 16; i < 80; i++) { |
| var s0 = ((w[i-15] >> 1n) ^ (w[i-15] >> 8n) ^ (w[i-15] >> 7n) ^ ((w[i-15] << 63n) & M)); |
| var s1 = ((w[i-2] >> 19n) ^ (w[i-2] >> 61n) ^ (w[i-2] >> 6n) ^ ((w[i-2] << 58n) & M)); |
| w[i] = (w[i-16] + s0 + w[i-7] + s1) & M; |
| } |
| var a=H[0],b=H[1],c=H[2],d=H[3],e=H[4],f=H[5],g=H[6],h=H[7]; |
| for (var i = 0; i < 80; i++) { |
| var S1 = ((e>>14n)^(e>>18n)^(e>>41n)^(((e<<50n)&M)^((e<<46n)&M)^((e<<23n)&M))); |
| var ch = (e&f)^(~e&g)&M; |
| var t1 = (h + S1 + ch + SHA512_K[i] + w[i]) & M; |
| var S0 = ((a>>28n)^(a>>34n)^(a>>39n)^(((a<<36n)&M)^((a<<30n)&M)^((a<<25n)&M))); |
| var maj = (a&b)^(a&c)^(b&c); |
| var t2 = (S0 + maj) & M; |
| h=g; g=f; f=e; e=(d+t1)&M; d=c; c=b; b=a; a=(t1+t2)&M; |
| } |
| H[0]=(H[0]+a)&M; H[1]=(H[1]+b)&M; H[2]=(H[2]+c)&M; H[3]=(H[3]+d)&M; |
| H[4]=(H[4]+e)&M; H[5]=(H[5]+f)&M; H[6]=(H[6]+g)&M; H[7]=(H[7]+h)&M; |
| } |
| var out = new Uint8Array(64); |
| for (var i = 0; i < 8; i++) { |
| for (var j = 0; j < 8; j++) { |
| out[i*8+j] = Number((H[i] >> BigInt((7-j)*8)) & 0xFFn); |
| } |
| } |
| return out; |
| } |
|
|
| |
| function _sha384(data) { |
| var msg = view(data); |
| var M = 0xFFFFFFFFFFFFFFFFn; |
| var H = [0xcbbb9d5dc1059ed8n,0x629a292a367cd507n,0x9159015a3070dd17n,0x152fecd8f70e5939n, |
| 0x67332667ffc00b31n,0x8eb44a8768581511n,0xdb0c2e0d64f98fa7n,0x47b5481dbefa4fa4n]; |
| _init_sha512_k(); |
| var len = msg.length; |
| var bitLen = BigInt(len * 8); |
| var padLen; |
| if ((len + 1) % 128 <= 112) { |
| padLen = 112 - (len + 1) % 128; |
| } else { |
| padLen = 128 + 112 - (len + 1) % 128; |
| } |
| var total = len + 1 + padLen + 16; |
| var padded = new Uint8Array(total); |
| padded.set(msg); |
| padded[len] = 0x80; |
| for (var i = 0; i < 8; i++) padded[total-8+i] = 0; |
| for (var i = 0; i < 8; i++) padded[total-1-i] = Number((bitLen >> BigInt(i*8)) & 0xFFn); |
| for (var off = 0; off < total; off += 128) { |
| var w = new Array(80); |
| for (var i = 0; i < 16; i++) { w[i] = 0n; for (var j = 0; j < 8; j++) w[i] = (w[i] << 8n) | BigInt(padded[off+i*8+j]); } |
| for (var i = 16; i < 80; i++) { |
| var s0 = ((w[i-15]>>1n)^(w[i-15]>>8n)^(w[i-15]>>7n)^((w[i-15]<<63n)&M)); |
| var s1 = ((w[i-2]>>19n)^(w[i-2]>>61n)^(w[i-2]>>6n)^((w[i-2]<<58n)&M)); |
| w[i] = (w[i-16]+s0+w[i-7]+s1)&M; |
| } |
| var a=H[0],b=H[1],c=H[2],d=H[3],e=H[4],f=H[5],g=H[6],h=H[7]; |
| for (var i = 0; i < 80; i++) { |
| var S1 = ((e>>14n)^(e>>18n)^(e>>41n)^(((e<<50n)&M)^((e<<46n)&M)^((e<<23n)&M))); |
| var ch = (e&f)^(~e&g)&M; |
| var t1 = (h+S1+ch+SHA512_K[i]+w[i])&M; |
| var S0 = ((a>>28n)^(a>>34n)^(a>>39n)^(((a<<36n)&M)^((a<<30n)&M)^((a<<25n)&M))); |
| var maj = (a&b)^(a&c)^(b&c); |
| var t2 = (S0+maj)&M; |
| h=g;g=f;f=e;e=(d+t1)&M;d=c;c=b;b=a;a=(t1+t2)&M; |
| } |
| H[0]=(H[0]+a)&M;H[1]=(H[1]+b)&M;H[2]=(H[2]+c)&M;H[3]=(H[3]+d)&M; |
| H[4]=(H[4]+e)&M;H[5]=(H[5]+f)&M;H[6]=(H[6]+g)&M;H[7]=(H[7]+h)&M; |
| } |
| var out = new Uint8Array(48); |
| for (var i = 0; i < 6; i++) { for (var j = 0; j < 8; j++) out[i*8+j] = Number((H[i] >> BigInt((7-j)*8)) & 0xFFn); } |
| return out; |
| } |
|
|
| |
|
|
| function _hmac(hashFn, blockLen, key, data) { |
| key = view(key); |
| data = view(data); |
| if (key.length > blockLen) key = hashFn(key); |
| var kpad = new Uint8Array(blockLen); |
| kpad.set(key); |
| var ipad = new Uint8Array(blockLen); |
| var opad = new Uint8Array(blockLen); |
| for (var i = 0; i < blockLen; i++) { |
| ipad[i] = kpad[i] ^ 0x36; |
| opad[i] = kpad[i] ^ 0x5c; |
| } |
| var innerData = new Uint8Array(blockLen + data.length); |
| innerData.set(ipad); |
| innerData.set(data, blockLen); |
| var innerHash = hashFn(innerData); |
| var outerData = new Uint8Array(blockLen + innerHash.length); |
| outerData.set(opad); |
| outerData.set(innerHash, blockLen); |
| return hashFn(outerData); |
| } |
|
|
| |
|
|
| |
| var SBOX = new Uint8Array([ |
| 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, |
| 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, |
| 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, |
| 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, |
| 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, |
| 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, |
| 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, |
| 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, |
| 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, |
| 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, |
| 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, |
| 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, |
| 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, |
| 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, |
| 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, |
| 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 |
| ]); |
|
|
| var RCON = [0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36]; |
|
|
| function aes_key_expansion(key) { |
| var Nk = key.length / 4; |
| var Nr = Nk + 6; |
| var W = new Uint8Array(4 * (Nr + 1) * 4); |
| W.set(key); |
| for (var i = Nk; i < 4*(Nr+1); i++) { |
| var t = W.slice((i-1)*4, i*4); |
| if (i % Nk === 0) { |
| var tmp = t[0]; t[0]=SBOX[t[1]]^RCON[i/Nk-1]; t[1]=SBOX[t[2]]; t[2]=SBOX[t[3]]; t[3]=SBOX[tmp]; |
| } else if (Nk > 6 && i % Nk === 4) { |
| t[0]=SBOX[t[0]]; t[1]=SBOX[t[1]]; t[2]=SBOX[t[2]]; t[3]=SBOX[t[3]]; |
| } |
| for (var j = 0; j < 4; j++) W[i*4+j] = W[(i-Nk)*4+j] ^ t[j]; |
| } |
| return { W: W, Nr: Nr }; |
| } |
|
|
| function aes_encrypt_block(W, Nr, input) { |
| var s = new Uint8Array(16); |
| s.set(input); |
| |
| for (var i = 0; i < 16; i++) s[i] ^= W[i]; |
| for (var r = 1; r <= Nr; r++) { |
| |
| for (var i = 0; i < 16; i++) s[i] = SBOX[s[i]]; |
| |
| var t = new Uint8Array(16); |
| t[0]=s[0];t[1]=s[5];t[2]=s[10];t[3]=s[15]; |
| t[4]=s[4];t[5]=s[9];t[6]=s[14];t[7]=s[3]; |
| t[8]=s[8];t[9]=s[13];t[10]=s[2];t[11]=s[7]; |
| t[12]=s[12];t[13]=s[1];t[14]=s[6];t[15]=s[11]; |
| s.set(t); |
| |
| |
| |
| |
| if (r < Nr) { |
| for (var c = 0; c < 4; c++) { |
| var a0=s[c*4],a1=s[c*4+1],a2=s[c*4+2],a3=s[c*4+3]; |
| var xt0 = (a0 << 1) ^ ((a0 & 0x80) ? 0x1b : 0); |
| var xt1 = (a1 << 1) ^ ((a1 & 0x80) ? 0x1b : 0); |
| var xt2 = (a2 << 1) ^ ((a2 & 0x80) ? 0x1b : 0); |
| var xt3 = (a3 << 1) ^ ((a3 & 0x80) ? 0x1b : 0); |
| s[c*4] = xt0 ^ xt1 ^ a1 ^ a2 ^ a3; |
| s[c*4+1] = a0 ^ xt1 ^ xt2 ^ a2 ^ a3; |
| s[c*4+2] = a0 ^ a1 ^ xt2 ^ xt3 ^ a3; |
| s[c*4+3] = xt0 ^ a0 ^ a1 ^ a2 ^ xt3; |
| } |
| } |
| |
| var off = r * 16; |
| for (var i = 0; i < 16; i++) s[i] ^= W[off+i]; |
| } |
| return s; |
| } |
|
|
| |
| var INV_SBOX = null; |
| function _init_inv_sbox() { |
| if (INV_SBOX) return; |
| INV_SBOX = new Uint8Array(256); |
| for (var i = 0; i < 256; i++) INV_SBOX[SBOX[i]] = i; |
| } |
|
|
| function aes_decrypt_block(W, Nr, input) { |
| _init_inv_sbox(); |
| var s = new Uint8Array(16); |
| s.set(input); |
| |
| for (var i = 0; i < 16; i++) s[i] ^= W[Nr*16+i]; |
| for (var r = Nr-1; r >= 0; r--) { |
| |
| var t = new Uint8Array(16); |
| t[0]=s[0];t[1]=s[13];t[2]=s[10];t[3]=s[7]; |
| t[4]=s[4];t[5]=s[1];t[6]=s[14];t[7]=s[11]; |
| t[8]=s[8];t[9]=s[5];t[10]=s[2];t[11]=s[15]; |
| t[12]=s[12];t[13]=s[9];t[14]=s[6];t[15]=s[3]; |
| s.set(t); |
| |
| for (var i = 0; i < 16; i++) s[i] = INV_SBOX[s[i]]; |
| |
| for (var i = 0; i < 16; i++) s[i] ^= W[r*16+i]; |
| |
| if (r > 0) { |
| for (var c = 0; c < 4; c++) { |
| var a0=s[c*4],a1=s[c*4+1],a2=s[c*4+2],a3=s[c*4+3]; |
| |
| s[c*4] = _gmul(0x0e,a0)^_gmul(0x0b,a1)^_gmul(0x0d,a2)^_gmul(0x09,a3); |
| s[c*4+1] = _gmul(0x09,a0)^_gmul(0x0e,a1)^_gmul(0x0b,a2)^_gmul(0x0d,a3); |
| s[c*4+2] = _gmul(0x0d,a0)^_gmul(0x09,a1)^_gmul(0x0e,a2)^_gmul(0x0b,a3); |
| s[c*4+3] = _gmul(0x0b,a0)^_gmul(0x0d,a1)^_gmul(0x09,a2)^_gmul(0x0e,a3); |
| } |
| } |
| } |
| return s; |
| } |
|
|
| function _gmul(a, b) { |
| var p = 0; |
| for (var i = 0; i < 8; i++) { |
| if (b & 1) p ^= a; |
| var hi = a & 0x80; |
| a = (a << 1) & 0xff; |
| if (hi) a ^= 0x1b; |
| b >>= 1; |
| } |
| return p; |
| } |
|
|
| |
| function _aes_cbc_encrypt(key, iv, data) { |
| key = view(key); iv = view(iv); data = view(data); |
| var exp = aes_key_expansion(key); |
| |
| var padLen = 16 - (data.length % 16); |
| var padded = new Uint8Array(data.length + padLen); |
| padded.set(data); |
| for (var i = data.length; i < padded.length; i++) padded[i] = padLen; |
| var out = new Uint8Array(padded.length); |
| var prev = iv; |
| for (var i = 0; i < padded.length; i += 16) { |
| var block = new Uint8Array(16); |
| for (var j = 0; j < 16; j++) block[j] = padded[i+j] ^ prev[j]; |
| var enc = aes_encrypt_block(exp.W, exp.Nr, block); |
| out.set(enc, i); |
| prev = enc; |
| } |
| return out; |
| } |
|
|
| |
| function _aes_cbc_decrypt(key, iv, data) { |
| key = view(key); iv = view(iv); data = view(data); |
| var exp = aes_key_expansion(key); |
| if (data.length % 16 !== 0 || data.length === 0) throw new Error('Invalid ciphertext length'); |
| var out = new Uint8Array(data.length); |
| var prev = iv; |
| for (var i = 0; i < data.length; i += 16) { |
| var block = data.subarray(i, i+16); |
| var dec = aes_decrypt_block(exp.W, exp.Nr, block); |
| for (var j = 0; j < 16; j++) out[i+j] = dec[j] ^ prev[j]; |
| prev = block; |
| } |
| |
| var padLen = out[out.length - 1]; |
| if (padLen > 0 && padLen <= 16) { |
| var valid = true; |
| for (var i = out.length - padLen; i < out.length; i++) { |
| if (out[i] !== padLen) { valid = false; break; } |
| } |
| if (valid) out = out.slice(0, out.length - padLen); |
| } |
| return out; |
| } |
|
|
| |
|
|
| function _pbkdf2(hashFn, hashLen, blockLen, password, salt, iterations, dkLen) { |
| password = view(password); salt = view(salt); |
| var nBlocks = Math.ceil(dkLen / hashLen); |
| var dk = new Uint8Array(nBlocks * hashLen); |
| for (var block = 1; block <= nBlocks; block++) { |
| var u = new Uint8Array(salt.length + 4); |
| u.set(salt); |
| u[salt.length] = (block >>> 24) & 0xff; |
| u[salt.length+1] = (block >>> 16) & 0xff; |
| u[salt.length+2] = (block >>> 8) & 0xff; |
| u[salt.length+3] = block & 0xff; |
| u = _hmac(hashFn, blockLen, password, u); |
| var t = new Uint8Array(u); |
| for (var i = 1; i < iterations; i++) { |
| u = _hmac(hashFn, blockLen, password, u); |
| for (var j = 0; j < hashLen; j++) t[j] ^= u[j]; |
| } |
| dk.set(t.subarray(0, hashLen), (block-1)*hashLen); |
| } |
| return dk.slice(0, dkLen); |
| } |
|
|
| |
|
|
| var _subtle = { |
| async digest(algorithm, data) { |
| var name = typeof algorithm === 'string' ? algorithm : algorithm.name; |
| name = name.toUpperCase(); |
| var bytes = view(data); |
| if (name === 'SHA-1') return _sha1(bytes).buffer; |
| if (name === 'SHA-256') return _sha256(bytes).buffer; |
| if (name === 'SHA-384') return _sha384(bytes).buffer; |
| if (name === 'SHA-512') return _sha512(bytes).buffer; |
| throw new Error('Unsupported algorithm: ' + name); |
| }, |
|
|
| async importKey(format, keyData, algorithm, extractable, usages) { |
| if (format !== 'raw') throw new Error('Only raw format supported'); |
| var algoName = typeof algorithm === 'string' ? algorithm : algorithm.name; |
| return { _type: 'key', _algo: algoName, _data: new Uint8Array(keyData), extractable: extractable, usages: usages }; |
| }, |
|
|
| async exportKey(format, key) { |
| if (format !== 'raw') throw new Error('Only raw format supported'); |
| return key._data.buffer; |
| }, |
|
|
| async encrypt(algorithm, key, data) { |
| var algoName = typeof algorithm === 'string' ? algorithm : algorithm.name; |
| if (algoName === 'AES-CBC') { |
| var iv = view(algorithm.iv); |
| return _aes_cbc_encrypt(key._data, iv, data).buffer; |
| } |
| throw new Error('Unsupported encrypt algorithm: ' + algoName); |
| }, |
|
|
| async decrypt(algorithm, key, data) { |
| var algoName = typeof algorithm === 'string' ? algorithm : algorithm.name; |
| if (algoName === 'AES-CBC') { |
| var iv = view(algorithm.iv); |
| return _aes_cbc_decrypt(key._data, iv, data).buffer; |
| } |
| throw new Error('Unsupported decrypt algorithm: ' + algoName); |
| }, |
|
|
| async sign(algorithm, key, data) { |
| var algoName = typeof algorithm === 'string' ? algorithm : algorithm.name; |
| algoName = algoName.toUpperCase(); |
| if (algoName === 'HMAC') { |
| var hash = (algorithm.hash || 'SHA-256'); |
| if (typeof hash === 'object') hash = hash.name; |
| hash = hash.toUpperCase(); |
| if (hash === 'SHA-256') return _hmac(_sha256, 64, key._data, data).buffer; |
| if (hash === 'SHA-512') return _hmac(_sha512, 128, key._data, data).buffer; |
| if (hash === 'SHA-1') return _hmac(_sha1, 64, key._data, data).buffer; |
| throw new Error('Unsupported HMAC hash: ' + hash); |
| } |
| throw new Error('Unsupported sign algorithm: ' + algoName); |
| }, |
|
|
| async verify(algorithm, key, signature, data) { |
| var algoName = typeof algorithm === 'string' ? algorithm : algorithm.name; |
| algoName = algoName.toUpperCase(); |
| if (algoName === 'HMAC') { |
| var hash = (algorithm.hash || 'SHA-256'); |
| if (typeof hash === 'object') hash = hash.name; |
| hash = hash.toUpperCase(); |
| var expected; |
| if (hash === 'SHA-256') expected = _hmac(_sha256, 64, key._data, data); |
| else if (hash === 'SHA-512') expected = _hmac(_sha512, 128, key._data, data); |
| else if (hash === 'SHA-1') expected = _hmac(_sha1, 64, key._data, data); |
| else throw new Error('Unsupported HMAC hash: ' + hash); |
| var sig = view(signature); |
| if (expected.length !== sig.length) return false; |
| var diff = 0; |
| for (var i = 0; i < expected.length; i++) diff |= expected[i] ^ sig[i]; |
| return diff === 0; |
| } |
| throw new Error('Unsupported verify algorithm: ' + algoName); |
| }, |
|
|
| async deriveBits(algorithm, baseKey, length) { |
| var algoName = typeof algorithm === 'string' ? algorithm : algorithm.name; |
| algoName = algoName.toUpperCase(); |
| if (algoName === 'PBKDF2') { |
| var hash = algorithm.hash; |
| if (typeof hash === 'object') hash = hash.name; |
| hash = hash.toUpperCase(); |
| var hashFn, hashLen, blockLen; |
| if (hash === 'SHA-256') { hashFn = _sha256; hashLen = 32; blockLen = 64; } |
| else if (hash === 'SHA-512') { hashFn = _sha512; hashLen = 64; blockLen = 128; } |
| else if (hash === 'SHA-1') { hashFn = _sha1; hashLen = 20; blockLen = 64; } |
| else throw new Error('Unsupported PBKDF2 hash: ' + hash); |
| var dkLen = Math.ceil(length / 8); |
| var dk = _pbkdf2(hashFn, hashLen, blockLen, baseKey._data, view(algorithm.salt), algorithm.iterations, dkLen); |
| return dk.buffer.slice(0, Math.ceil(length / 8)); |
| } |
| throw new Error('Unsupported deriveBits algorithm: ' + algoName); |
| }, |
|
|
| async deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages) { |
| var bits = await _subtle.deriveBits(algorithm, baseKey, derivedKeyAlgorithm.length || 256); |
| return _subtle.importKey('raw', bits, derivedKeyAlgorithm, extractable, keyUsages); |
| } |
| }; |
|
|
| |
| if (typeof globalThis.crypto !== 'undefined') { |
| globalThis.crypto.subtle = _subtle; |
| } else { |
| globalThis.crypto = { subtle: _subtle }; |
| } |
| })(); |
|
|