diff --git a/html/js/nacl-fast-cn.js b/html/js/nacl-fast-cn.js new file mode 100644 index 0000000..536b667 --- /dev/null +++ b/html/js/nacl-fast-cn.js @@ -0,0 +1,571 @@ +(function(nacl) { +'use strict'; + +// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. +// Public domain. +// +// Implementation derived from TweetNaCl version 20140427. +// See for details: http://tweetnacl.cr.yp.to/ + +// modified 2017 for some CN functions by luigi1111 + +var gf = function(init) { + var i, r = new Float64Array(16); + if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; + return r; +}; + +// Pluggable, initialized in high-level API below. +var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; + +var _0 = new Uint8Array(16); +var _9 = new Uint8Array(32); _9[0] = 9; + +var gf0 = gf(), + gf1 = gf([1]), + _121665 = gf([0xdb41, 1]), + D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), + D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), + X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), + Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), + I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); + +function vn(x, xi, y, yi, n) { + var i,d = 0; + for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; + return (1 & ((d - 1) >>> 8)) - 1; +} + +function crypto_verify_16(x, xi, y, yi) { + return vn(x,xi,y,yi,16); +} + +function crypto_verify_32(x, xi, y, yi) { + return vn(x,xi,y,yi,32); +} + +function set25519(r, a) { + var i; + for (i = 0; i < 16; i++) r[i] = a[i]|0; +} + +function car25519(o) { + var i, v, c = 1; + for (i = 0; i < 16; i++) { + v = o[i] + c + 65535; + c = Math.floor(v / 65536); + o[i] = v - c * 65536; + } + o[0] += c-1 + 37 * (c-1); +} + +function sel25519(p, q, b) { + var t, c = ~(b-1); + for (var i = 0; i < 16; i++) { + t = c & (p[i] ^ q[i]); + p[i] ^= t; + q[i] ^= t; + } +} + +function pack25519(o, n) { + var i, j, b; + var m = gf(), t = gf(); + for (i = 0; i < 16; i++) t[i] = n[i]; + car25519(t); + car25519(t); + car25519(t); + for (j = 0; j < 2; j++) { + m[0] = t[0] - 0xffed; + for (i = 1; i < 15; i++) { + m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); + m[i-1] &= 0xffff; + } + m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); + b = (m[15]>>16) & 1; + m[14] &= 0xffff; + sel25519(t, m, 1-b); + } + for (i = 0; i < 16; i++) { + o[2*i] = t[i] & 0xff; + o[2*i+1] = t[i]>>8; + } +} + +function neq25519(a, b) { + var c = new Uint8Array(32), d = new Uint8Array(32); + pack25519(c, a); + pack25519(d, b); + return crypto_verify_32(c, 0, d, 0); +} + +function par25519(a) { + var d = new Uint8Array(32); + pack25519(d, a); + return d[0] & 1; +} + +function unpack25519(o, n) { + var i; + for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); + o[15] &= 0x7fff; +} + +function A(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; +} + +function Z(o, a, b) { + for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; +} + +function M(o, a, b) { + var v, c, + t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, + t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, + t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, + t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, + b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], + b6 = b[6], b7 = b[7], b8 = b[8], b9 = b[9], b10 = b[10], + b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15]; + + v = a[0]; + t0 += v * b0; t1 += v * b1; t2 += v * b2; t3 += v * b3; + t4 += v * b4; t5 += v * b5; t6 += v * b6; t7 += v * b7; + t8 += v * b8; t9 += v * b9; t10 += v * b10; t11 += v * b11; + t12 += v * b12; t13 += v * b13; t14 += v * b14; t15 += v * b15; + v = a[1]; + t1 += v * b0; t2 += v * b1; t3 += v * b2; t4 += v * b3; + t5 += v * b4; t6 += v * b5; t7 += v * b6; t8 += v * b7; + t9 += v * b8; t10 += v * b9; t11 += v * b10; t12 += v * b11; + t13 += v * b12; t14 += v * b13; t15 += v * b14; t16 += v * b15; + v = a[2]; + t2 += v * b0; t3 += v * b1; t4 += v * b2; t5 += v * b3; + t6 += v * b4; t7 += v * b5; t8 += v * b6; t9 += v * b7; + t10 += v * b8; t11 += v * b9; t12 += v * b10; t13 += v * b11; + t14 += v * b12; t15 += v * b13; t16 += v * b14; t17 += v * b15; + v = a[3]; + t3 += v * b0; t4 += v * b1; t5 += v * b2; t6 += v * b3; + t7 += v * b4; t8 += v * b5; t9 += v * b6; t10 += v * b7; + t11 += v * b8; t12 += v * b9; t13 += v * b10; t14 += v * b11; + t15 += v * b12; t16 += v * b13; t17 += v * b14; t18 += v * b15; + v = a[4]; + t4 += v * b0; t5 += v * b1; t6 += v * b2; t7 += v * b3; + t8 += v * b4; t9 += v * b5; t10 += v * b6; t11 += v * b7; + t12 += v * b8; t13 += v * b9; t14 += v * b10; t15 += v * b11; + t16 += v * b12; t17 += v * b13; t18 += v * b14; t19 += v * b15; + v = a[5]; + t5 += v * b0; t6 += v * b1; t7 += v * b2; t8 += v * b3; + t9 += v * b4; t10 += v * b5; t11 += v * b6; t12 += v * b7; + t13 += v * b8; t14 += v * b9; t15 += v * b10; t16 += v * b11; + t17 += v * b12; t18 += v * b13; t19 += v * b14; t20 += v * b15; + v = a[6]; + t6 += v * b0; t7 += v * b1; t8 += v * b2; t9 += v * b3; + t10 += v * b4; t11 += v * b5; t12 += v * b6; t13 += v * b7; + t14 += v * b8; t15 += v * b9; t16 += v * b10; t17 += v * b11; + t18 += v * b12; t19 += v * b13; t20 += v * b14; t21 += v * b15; + v = a[7]; + t7 += v * b0; t8 += v * b1; t9 += v * b2; t10 += v * b3; + t11 += v * b4; t12 += v * b5; t13 += v * b6; t14 += v * b7; + t15 += v * b8; t16 += v * b9; t17 += v * b10; t18 += v * b11; + t19 += v * b12; t20 += v * b13; t21 += v * b14; t22 += v * b15; + v = a[8]; + t8 += v * b0; t9 += v * b1; t10 += v * b2; t11 += v * b3; + t12 += v * b4; t13 += v * b5; t14 += v * b6; t15 += v * b7; + t16 += v * b8; t17 += v * b9; t18 += v * b10; t19 += v * b11; + t20 += v * b12; t21 += v * b13; t22 += v * b14; t23 += v * b15; + v = a[9]; + t9 += v * b0; t10 += v * b1; t11 += v * b2; t12 += v * b3; + t13 += v * b4; t14 += v * b5; t15 += v * b6; t16 += v * b7; + t17 += v * b8; t18 += v * b9; t19 += v * b10; t20 += v * b11; + t21 += v * b12; t22 += v * b13; t23 += v * b14; t24 += v * b15; + v = a[10]; + t10 += v * b0; t11 += v * b1; t12 += v * b2; t13 += v * b3; + t14 += v * b4; t15 += v * b5; t16 += v * b6; t17 += v * b7; + t18 += v * b8; t19 += v * b9; t20 += v * b10; t21 += v * b11; + t22 += v * b12; t23 += v * b13; t24 += v * b14; t25 += v * b15; + v = a[11]; + t11 += v * b0; t12 += v * b1; t13 += v * b2; t14 += v * b3; + t15 += v * b4; t16 += v * b5; t17 += v * b6; t18 += v * b7; + t19 += v * b8; t20 += v * b9; t21 += v * b10; t22 += v * b11; + t23 += v * b12; t24 += v * b13; t25 += v * b14; t26 += v * b15; + v = a[12]; + t12 += v * b0; t13 += v * b1; t14 += v * b2; t15 += v * b3; + t16 += v * b4; t17 += v * b5; t18 += v * b6; t19 += v * b7; + t20 += v * b8; t21 += v * b9; t22 += v * b10; t23 += v * b11; + t24 += v * b12; t25 += v * b13; t26 += v * b14; t27 += v * b15; + v = a[13]; + t13 += v * b0; t14 += v * b1; t15 += v * b2; t16 += v * b3; + t17 += v * b4; t18 += v * b5; t19 += v * b6; t20 += v * b7; + t21 += v * b8; t22 += v * b9; t23 += v * b10; t24 += v * b11; + t25 += v * b12; t26 += v * b13; t27 += v * b14; t28 += v * b15; + v = a[14]; + t14 += v * b0; t15 += v * b1; t16 += v * b2; t17 += v * b3; + t18 += v * b4; t19 += v * b5; t20 += v * b6; t21 += v * b7; + t22 += v * b8; t23 += v * b9; t24 += v * b10; t25 += v * b11; + t26 += v * b12; t27 += v * b13; t28 += v * b14; t29 += v * b15; + v = a[15]; + t15 += v * b0; t16 += v * b1; t17 += v * b2; t18 += v * b3; + t19 += v * b4; t20 += v * b5; t21 += v * b6; t22 += v * b7; + t23 += v * b8; t24 += v * b9; t25 += v * b10; t26 += v * b11; + t27 += v * b12; t28 += v * b13; t29 += v * b14; t30 += v * b15; + + t0 += 38 * t16; t1 += 38 * t17; t2 += 38 * t18; t3 += 38 * t19; + t4 += 38 * t20; t5 += 38 * t21; t6 += 38 * t22; t7 += 38 * t23; + t8 += 38 * t24; t9 += 38 * t25; t10 += 38 * t26; t11 += 38 * t27; + t12 += 38 * t28; t13 += 38 * t29; t14 += 38 * t30; // t15 left as is + + // first car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + // second car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c-1 + 37 * (c-1); + + o[ 0] = t0; + o[ 1] = t1; + o[ 2] = t2; + o[ 3] = t3; + o[ 4] = t4; + o[ 5] = t5; + o[ 6] = t6; + o[ 7] = t7; + o[ 8] = t8; + o[ 9] = t9; + o[10] = t10; + o[11] = t11; + o[12] = t12; + o[13] = t13; + o[14] = t14; + o[15] = t15; +} + +function S(o, a) { + M(o, a, a); +} + +function inv25519(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 253; a >= 0; a--) { + S(c, c); + if(a !== 2 && a !== 4) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function pow2523(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 250; a >= 0; a--) { + S(c, c); + if(a !== 1) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function add(p, q) { + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(), + g = gf(), h = gf(), t = gf(); + + Z(a, p[1], p[0]); + Z(t, q[1], q[0]); + M(a, a, t); + A(b, p[0], p[1]); + A(t, q[0], q[1]); + M(b, b, t); + M(c, p[3], q[3]); + M(c, c, D2); + M(d, p[2], q[2]); + A(d, d, d); + Z(e, b, a); + Z(f, d, c); + A(g, d, c); + A(h, b, a); + + M(p[0], e, f); + M(p[1], h, g); + M(p[2], g, f); + M(p[3], e, h); +} + +function cswap(p, q, b) { + var i; + for (i = 0; i < 4; i++) { + sel25519(p[i], q[i], b); + } +} + +function pack(r, p) { + var tx = gf(), ty = gf(), zi = gf(); + inv25519(zi, p[2]); + M(tx, p[0], zi); + M(ty, p[1], zi); + pack25519(r, ty); + r[31] ^= par25519(tx) << 7; +} + +function scalarmult(p, q, s) { + var b, i; + set25519(p[0], gf0); + set25519(p[1], gf1); + set25519(p[2], gf1); + set25519(p[3], gf0); + for (i = 255; i >= 0; --i) { + b = (s[(i/8)|0] >> (i&7)) & 1; + cswap(p, q, b); + add(q, p); + add(p, p); + cswap(p, q, b); + } +} + +function scalarbase(p, s) { + var q = [gf(), gf(), gf(), gf()]; + set25519(q[0], X); + set25519(q[1], Y); + set25519(q[2], gf1); + M(q[3], X, Y); + scalarmult(p, q, s); +} + +//new functions for CN - scalar operations are handled externally +// this only handles curve operations, except for Hp() + +//why do we negate points when unpacking them??? +function ge_neg(pub) { + pub[31] ^= 0x80; +} + +//res = s*G +function ge_scalarmult_base(s) { + var p = [gf(), gf(), gf(), gf()]; + scalarbase(p, s); + var pk = new Uint8Array(32); + pack(pk, p); + return pk; +} + +//res = s*P +function ge_scalarmult(P, s) { + var p = [gf(), gf(), gf(), gf()], + upk = [gf(), gf(), gf(), gf()], + res = new Uint8Array(32); + ge_neg(P); + if (unpackneg(upk, P) !== 0) throw "non-0 error on point decode"; + scalarmult(p, upk, s); + pack(res, p); + return res; +} + +//res = c*P + r*G +function ge_double_scalarmult_base_vartime(c, P, r) { + var uP = [gf(), gf(), gf(), gf()], + cP = [gf(), gf(), gf(), gf()], + rG = [gf(), gf(), gf(), gf()], + res = new Uint8Array(32); + ge_neg(P); + if (unpackneg(uP, P) !== 0) throw "non-0 error on point decode"; + scalarmult(cP, uP, c); + scalarbase(rG, r); + add(rG, cP); + pack(res, rG); + return res; +} + +//name changed to reflect not using precomp; res = r*Pb + c*I +function ge_double_scalarmult_postcomp_vartime(r, Pb, c, I) { + var uPb = [gf(), gf(), gf(), gf()], + uI = [gf(), gf(), gf(), gf()], + cI = [gf(), gf(), gf(), gf()], + rPb = [gf(), gf(), gf(), gf()], + res = new Uint8Array(32); + ge_neg(Pb); + if (unpackneg(uPb, Pb) !== 0) throw "non-0 error on point decode"; + scalarmult(rPb, uPb, r); + ge_neg(I); + if (unpackneg(uI, I) !== 0) throw "non-0 error on point decode"; + scalarmult(cI, uI, c); + add(rPb, cI); + pack(res, rPb); + return res; +} + +//res = P + Q +function ge_add(P, Q) { + var uP = [gf(), gf(), gf(), gf()], + uQ = [gf(), gf(), gf(), gf()], + res = new Uint8Array(32); + ge_neg(P); + ge_neg(Q); + if (unpackneg(uP, P) !== 0) throw "non-0 error on point decode"; + if (unpackneg(uQ, Q) !== 0) throw "non-0 error on point decode"; + add(uP, uQ); + pack(res, uP); + return res; +} + +var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); + +function modL(r, x) { + var carry, i, j, k; + for (i = 63; i >= 32; --i) { + carry = 0; + for (j = i - 32, k = i - 12; j < k; ++j) { + x[j] += carry - 16 * x[i] * L[j - (i - 32)]; + carry = (x[j] + 128) >> 8; + x[j] -= carry * 256; + } + x[j] += carry; + x[i] = 0; + } + carry = 0; + for (j = 0; j < 32; j++) { + x[j] += carry - (x[31] >> 4) * L[j]; + carry = x[j] >> 8; + x[j] &= 255; + } + for (j = 0; j < 32; j++) x[j] -= carry * L[j]; + for (i = 0; i < 32; i++) { + x[i+1] += x[i] >> 8; + r[i] = x[i] & 255; + } +} + +function reduce(r) { + var x = new Float64Array(64), i; + for (i = 0; i < 64; i++) x[i] = r[i]; + for (i = 0; i < 64; i++) r[i] = 0; + modL(r, x); +} + +function unpackneg(r, p) { + var t = gf(), chk = gf(), num = gf(), + den = gf(), den2 = gf(), den4 = gf(), + den6 = gf(); + + set25519(r[2], gf1); + unpack25519(r[1], p); + S(num, r[1]); + M(den, num, D); + Z(num, num, r[2]); + A(den, r[2], den); + + S(den2, den); + S(den4, den2); + M(den6, den4, den2); + M(t, den6, num); + M(t, t, den); + + pow2523(t, t); + M(t, t, num); + M(t, t, den); + M(t, t, den); + M(r[0], t, den); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) M(r[0], r[0], I); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) return -1; + + if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); + + M(r[3], r[0], r[1]); + return 0; +} + +nacl.ll = { + + ge_scalarmult_base: ge_scalarmult_base, + ge_scalarmult: ge_scalarmult, + ge_double_scalarmult_base_vartime: ge_double_scalarmult_base_vartime, + ge_add: ge_add, + ge_double_scalarmult_postcomp_vartime: ge_double_scalarmult_postcomp_vartime + +}; + + +/* High-level API */ + +function cleanup(arr) { + for (var i = 0; i < arr.length; i++) arr[i] = 0; +} + +nacl.randomBytes = function(n) { + var b = new Uint8Array(n); + randombytes(b, n); + return b; +}; + +nacl.setPRNG = function(fn) { + randombytes = fn; +}; + +(function() { + // Initialize PRNG if environment provides CSPRNG. + // If not, methods calling randombytes will throw. + var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null; + if (crypto && crypto.getRandomValues) { + // Browsers. + var QUOTA = 65536; + nacl.setPRNG(function(x, n) { + var i, v = new Uint8Array(n); + for (i = 0; i < n; i += QUOTA) { + crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA))); + } + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } else if (typeof require !== 'undefined') { + // Node.js. + crypto = require('crypto'); + if (crypto && crypto.randomBytes) { + nacl.setPRNG(function(x, n) { + var i, v = crypto.randomBytes(n); + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } + } +})(); + +})(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {})); diff --git a/html/js/sha3.js b/html/js/sha3.js new file mode 100644 index 0000000..dcf3d53 --- /dev/null +++ b/html/js/sha3.js @@ -0,0 +1,473 @@ +/* + * js-sha3 v0.5.1 + * https://github.com/emn178/js-sha3 + * + * Copyright 2015, emn178@gmail.com + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ +;(function(root, undefined) { + 'use strict'; + + var NODE_JS = typeof(module) != 'undefined'; + if(NODE_JS) { + root = global; + if(root.JS_SHA3_TEST) { + root.navigator = { userAgent: 'Chrome'}; + } + } + var HEX_CHARS = '0123456789abcdef'.split(''); + var SHAKE_PADDING = [31, 7936, 2031616, 520093696]; + var KECCAK_PADDING = [1, 256, 65536, 16777216]; + var PADDING = [6, 1536, 393216, 100663296]; + var SHIFT = [0, 8, 16, 24]; + var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, + 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, + 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, + 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, + 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; + var BITS = [224, 256, 384, 512]; + var SHAKE_BITS = [128, 256]; + var OUTPUT_TYPES = ['hex', 'buffer', 'array']; + + var createOutputMethod = function(bits, padding, outputType) { + return function(message) { + return new Keccak(bits, padding, bits).update(message)[outputType](); + } + }; + + var createShakeOutputMethod = function(bits, padding, outputType) { + return function(message, outputBits) { + return new Keccak(bits, padding, outputBits).update(message)[outputType](); + } + }; + + var createMethod = function(bits, padding) { + var method = createOutputMethod(bits, padding, 'hex'); + method.create = function() { + return new Keccak(bits, padding, bits); + }; + method.update = function(message) { + return method.create().update(message); + }; + for(var i = 0;i < OUTPUT_TYPES.length;++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(bits, padding, type); + } + return method; + }; + + var createShakeMethod = function(bits, padding) { + var method = createShakeOutputMethod(bits, padding, 'hex'); + method.create = function(outputBits) { + return new Keccak(bits, padding, outputBits); + }; + method.update = function(message, outputBits) { + return method.create(outputBits).update(message); + }; + for(var i = 0;i < OUTPUT_TYPES.length;++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createShakeOutputMethod(bits, padding, type); + } + return method; + }; + + var algorithms = [ + {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod}, + {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod}, + {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod} + ]; + + var methods = {}; + + for(var i = 0;i < algorithms.length;++i) { + var algorithm = algorithms[i]; + var bits = algorithm.bits; + var createMethod = algorithm.createMethod; + for(var j = 0;j < bits.length;++j) { + var method = algorithm.createMethod(bits[j], algorithm.padding); + methods[algorithm.name +'_' + bits[j]] = method; + } + } + + function Keccak(bits, padding, outputBits) { + this.blocks = []; + this.s = []; + this.padding = padding; + this.outputBits = outputBits; + this.reset = true; + this.block = 0; + this.start = 0; + this.blockCount = (1600 - (bits << 1)) >> 5; + this.byteCount = this.blockCount << 2; + this.outputBlocks = outputBits >> 5; + this.extraBytes = (outputBits & 31) >> 3; + + for(var i = 0;i < 50;++i) { + this.s[i] = 0; + } + }; + + Keccak.prototype.update = function(message) { + var notString = typeof(message) != 'string'; + if(notString && message.constructor == root.ArrayBuffer) { + message = new Uint8Array(message); + } + var length = message.length, blocks = this.blocks, byteCount = this.byteCount, + blockCount = this.blockCount, index = 0, s = this.s, i, code; + + while(index < length) { + if(this.reset) { + this.reset = false; + blocks[0] = this.block; + for(i = 1;i < blockCount + 1;++i) { + blocks[i] = 0; + } + } + if(notString) { + for (i = this.start;index < length && i < byteCount; ++index) { + blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start;index < length && i < byteCount; ++index) { + code = message.charCodeAt(index); + if (code < 0x80) { + blocks[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 0x800) { + blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else if (code < 0xd800 || code >= 0xe000) { + blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); + blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } + } + } + this.lastByteIndex = i; + if(i >= byteCount) { + this.start = i - byteCount; + this.block = blocks[blockCount]; + for(i = 0;i < blockCount;++i) { + s[i] ^= blocks[i]; + } + f(s); + this.reset = true; + } else { + this.start = i; + } + } + return this; + }; + + Keccak.prototype.finalize = function() { + var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; + blocks[i >> 2] |= this.padding[i & 3]; + if(this.lastByteIndex == this.byteCount) { + blocks[0] = blocks[blockCount]; + for(i = 1;i < blockCount + 1;++i) { + blocks[i] = 0; + } + } + blocks[blockCount - 1] |= 0x80000000; + for(i = 0;i < blockCount;++i) { + s[i] ^= blocks[i]; + } + f(s); + }; + + Keccak.prototype.toString = Keccak.prototype.hex = function() { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var hex = '', block; + while(j < outputBlocks) { + for(i = 0;i < blockCount && j < outputBlocks;++i, ++j) { + block = s[i]; + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + + HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + + HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + + HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; + } + if(j % blockCount == 0) { + f(s); + } + } + if(extraBytes) { + block = s[i]; + if(extraBytes > 0) { + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; + } + if(extraBytes > 1) { + hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; + } + if(extraBytes > 2) { + hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F]; + } + } + return hex; + }; + + Keccak.prototype.buffer = function() { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var bytes = this.outputBits >> 3; + var buffer; + if(extraBytes) { + buffer = new ArrayBuffer((outputBlocks + 1) << 2); + } else { + buffer = new ArrayBuffer(bytes); + } + var array = new Uint32Array(buffer); + while(j < outputBlocks) { + for(i = 0;i < blockCount && j < outputBlocks;++i, ++j) { + array[j] = s[i]; + } + if(j % blockCount == 0) { + f(s); + } + } + if(extraBytes) { + array[i] = s[i]; + buffer = buffer.slice(0, bytes); + } + return buffer; + }; + + Keccak.prototype.digest = Keccak.prototype.array = function() { + this.finalize(); + + var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, + extraBytes = this.extraBytes, i = 0, j = 0; + var array = [], offset, block; + while(j < outputBlocks) { + for(i = 0;i < blockCount && j < outputBlocks;++i, ++j) { + offset = j << 2; + block = s[i]; + array[offset] = block & 0xFF; + array[offset + 1] = (block >> 8) & 0xFF; + array[offset + 2] = (block >> 16) & 0xFF; + array[offset + 3] = (block >> 24) & 0xFF; + } + if(j % blockCount == 0) { + f(s); + } + } + if(extraBytes) { + offset = j << 2; + block = s[i]; + if(extraBytes > 0) { + array[offset] = block & 0xFF; + } + if(extraBytes > 1) { + array[offset + 1] = (block >> 8) & 0xFF; + } + if(extraBytes > 2) { + array[offset + 2] = (block >> 16) & 0xFF; + } + } + return array; + }; + + var f = function(s) { + var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, + b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, + b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, + b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; + for(n = 0; n < 48; n += 2) { + c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; + c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; + c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; + c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; + c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; + c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; + c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; + c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; + c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; + c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; + + h = c8 ^ ((c2 << 1) | (c3 >>> 31)); + l = c9 ^ ((c3 << 1) | (c2 >>> 31)); + s[0] ^= h; + s[1] ^= l; + s[10] ^= h; + s[11] ^= l; + s[20] ^= h; + s[21] ^= l; + s[30] ^= h; + s[31] ^= l; + s[40] ^= h; + s[41] ^= l; + h = c0 ^ ((c4 << 1) | (c5 >>> 31)); + l = c1 ^ ((c5 << 1) | (c4 >>> 31)); + s[2] ^= h; + s[3] ^= l; + s[12] ^= h; + s[13] ^= l; + s[22] ^= h; + s[23] ^= l; + s[32] ^= h; + s[33] ^= l; + s[42] ^= h; + s[43] ^= l; + h = c2 ^ ((c6 << 1) | (c7 >>> 31)); + l = c3 ^ ((c7 << 1) | (c6 >>> 31)); + s[4] ^= h; + s[5] ^= l; + s[14] ^= h; + s[15] ^= l; + s[24] ^= h; + s[25] ^= l; + s[34] ^= h; + s[35] ^= l; + s[44] ^= h; + s[45] ^= l; + h = c4 ^ ((c8 << 1) | (c9 >>> 31)); + l = c5 ^ ((c9 << 1) | (c8 >>> 31)); + s[6] ^= h; + s[7] ^= l; + s[16] ^= h; + s[17] ^= l; + s[26] ^= h; + s[27] ^= l; + s[36] ^= h; + s[37] ^= l; + s[46] ^= h; + s[47] ^= l; + h = c6 ^ ((c0 << 1) | (c1 >>> 31)); + l = c7 ^ ((c1 << 1) | (c0 >>> 31)); + s[8] ^= h; + s[9] ^= l; + s[18] ^= h; + s[19] ^= l; + s[28] ^= h; + s[29] ^= l; + s[38] ^= h; + s[39] ^= l; + s[48] ^= h; + s[49] ^= l; + + b0 = s[0]; + b1 = s[1]; + b32 = (s[11] << 4) | (s[10] >>> 28); + b33 = (s[10] << 4) | (s[11] >>> 28); + b14 = (s[20] << 3) | (s[21] >>> 29); + b15 = (s[21] << 3) | (s[20] >>> 29); + b46 = (s[31] << 9) | (s[30] >>> 23); + b47 = (s[30] << 9) | (s[31] >>> 23); + b28 = (s[40] << 18) | (s[41] >>> 14); + b29 = (s[41] << 18) | (s[40] >>> 14); + b20 = (s[2] << 1) | (s[3] >>> 31); + b21 = (s[3] << 1) | (s[2] >>> 31); + b2 = (s[13] << 12) | (s[12] >>> 20); + b3 = (s[12] << 12) | (s[13] >>> 20); + b34 = (s[22] << 10) | (s[23] >>> 22); + b35 = (s[23] << 10) | (s[22] >>> 22); + b16 = (s[33] << 13) | (s[32] >>> 19); + b17 = (s[32] << 13) | (s[33] >>> 19); + b48 = (s[42] << 2) | (s[43] >>> 30); + b49 = (s[43] << 2) | (s[42] >>> 30); + b40 = (s[5] << 30) | (s[4] >>> 2); + b41 = (s[4] << 30) | (s[5] >>> 2); + b22 = (s[14] << 6) | (s[15] >>> 26); + b23 = (s[15] << 6) | (s[14] >>> 26); + b4 = (s[25] << 11) | (s[24] >>> 21); + b5 = (s[24] << 11) | (s[25] >>> 21); + b36 = (s[34] << 15) | (s[35] >>> 17); + b37 = (s[35] << 15) | (s[34] >>> 17); + b18 = (s[45] << 29) | (s[44] >>> 3); + b19 = (s[44] << 29) | (s[45] >>> 3); + b10 = (s[6] << 28) | (s[7] >>> 4); + b11 = (s[7] << 28) | (s[6] >>> 4); + b42 = (s[17] << 23) | (s[16] >>> 9); + b43 = (s[16] << 23) | (s[17] >>> 9); + b24 = (s[26] << 25) | (s[27] >>> 7); + b25 = (s[27] << 25) | (s[26] >>> 7); + b6 = (s[36] << 21) | (s[37] >>> 11); + b7 = (s[37] << 21) | (s[36] >>> 11); + b38 = (s[47] << 24) | (s[46] >>> 8); + b39 = (s[46] << 24) | (s[47] >>> 8); + b30 = (s[8] << 27) | (s[9] >>> 5); + b31 = (s[9] << 27) | (s[8] >>> 5); + b12 = (s[18] << 20) | (s[19] >>> 12); + b13 = (s[19] << 20) | (s[18] >>> 12); + b44 = (s[29] << 7) | (s[28] >>> 25); + b45 = (s[28] << 7) | (s[29] >>> 25); + b26 = (s[38] << 8) | (s[39] >>> 24); + b27 = (s[39] << 8) | (s[38] >>> 24); + b8 = (s[48] << 14) | (s[49] >>> 18); + b9 = (s[49] << 14) | (s[48] >>> 18); + + s[0] = b0 ^ (~b2 & b4); + s[1] = b1 ^ (~b3 & b5); + s[10] = b10 ^ (~b12 & b14); + s[11] = b11 ^ (~b13 & b15); + s[20] = b20 ^ (~b22 & b24); + s[21] = b21 ^ (~b23 & b25); + s[30] = b30 ^ (~b32 & b34); + s[31] = b31 ^ (~b33 & b35); + s[40] = b40 ^ (~b42 & b44); + s[41] = b41 ^ (~b43 & b45); + s[2] = b2 ^ (~b4 & b6); + s[3] = b3 ^ (~b5 & b7); + s[12] = b12 ^ (~b14 & b16); + s[13] = b13 ^ (~b15 & b17); + s[22] = b22 ^ (~b24 & b26); + s[23] = b23 ^ (~b25 & b27); + s[32] = b32 ^ (~b34 & b36); + s[33] = b33 ^ (~b35 & b37); + s[42] = b42 ^ (~b44 & b46); + s[43] = b43 ^ (~b45 & b47); + s[4] = b4 ^ (~b6 & b8); + s[5] = b5 ^ (~b7 & b9); + s[14] = b14 ^ (~b16 & b18); + s[15] = b15 ^ (~b17 & b19); + s[24] = b24 ^ (~b26 & b28); + s[25] = b25 ^ (~b27 & b29); + s[34] = b34 ^ (~b36 & b38); + s[35] = b35 ^ (~b37 & b39); + s[44] = b44 ^ (~b46 & b48); + s[45] = b45 ^ (~b47 & b49); + s[6] = b6 ^ (~b8 & b0); + s[7] = b7 ^ (~b9 & b1); + s[16] = b16 ^ (~b18 & b10); + s[17] = b17 ^ (~b19 & b11); + s[26] = b26 ^ (~b28 & b20); + s[27] = b27 ^ (~b29 & b21); + s[36] = b36 ^ (~b38 & b30); + s[37] = b37 ^ (~b39 & b31); + s[46] = b46 ^ (~b48 & b40); + s[47] = b47 ^ (~b49 & b41); + s[8] = b8 ^ (~b0 & b2); + s[9] = b9 ^ (~b1 & b3); + s[18] = b18 ^ (~b10 & b12); + s[19] = b19 ^ (~b11 & b13); + s[28] = b28 ^ (~b20 & b22); + s[29] = b29 ^ (~b21 & b23); + s[38] = b38 ^ (~b30 & b32); + s[39] = b39 ^ (~b31 & b33); + s[48] = b48 ^ (~b40 & b42); + s[49] = b49 ^ (~b41 & b43); + + s[0] ^= RC[n]; + s[1] ^= RC[n + 1]; + } + } + + if(!root.JS_SHA3_TEST && NODE_JS) { + module.exports = methods; + } else if(root) { + for(var key in methods) { + root[key] = methods[key]; + } + } +}(this));