buddy

node MVC discord bot
Log | Files | Refs | README

nacl.js (32657B)


      1 (function(nacl) {
      2 'use strict';
      3 
      4 // Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
      5 // Public domain.
      6 //
      7 // Implementation derived from TweetNaCl version 20140427.
      8 // See for details: http://tweetnacl.cr.yp.to/
      9 
     10 var u64 = function(h, l) { this.hi = h|0 >>> 0; this.lo = l|0 >>> 0; };
     11 var gf = function(init) {
     12   var i, r = new Float64Array(16);
     13   if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
     14   return r;
     15 };
     16 
     17 //  Pluggable, initialized in high-level API below.
     18 var randombytes = function(/* x, n */) { throw new Error('no PRNG'); };
     19 
     20 var _0 = new Uint8Array(16);
     21 var _9 = new Uint8Array(32); _9[0] = 9;
     22 
     23 var gf0 = gf(),
     24     gf1 = gf([1]),
     25     _121665 = gf([0xdb41, 1]),
     26     D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),
     27     D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),
     28     X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),
     29     Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),
     30     I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
     31 
     32 function L32(x, c) { return (x << c) | (x >>> (32 - c)); }
     33 
     34 function ld32(x, i) {
     35   var u = x[i+3] & 0xff;
     36   u = (u<<8)|(x[i+2] & 0xff);
     37   u = (u<<8)|(x[i+1] & 0xff);
     38   return (u<<8)|(x[i+0] & 0xff);
     39 }
     40 
     41 function dl64(x, i) {
     42   var h = (x[i] << 24) | (x[i+1] << 16) | (x[i+2] << 8) | x[i+3];
     43   var l = (x[i+4] << 24) | (x[i+5] << 16) | (x[i+6] << 8) | x[i+7];
     44   return new u64(h, l);
     45 }
     46 
     47 function st32(x, j, u) {
     48   var i;
     49   for (i = 0; i < 4; i++) { x[j+i] = u & 255; u >>>= 8; }
     50 }
     51 
     52 function ts64(x, i, u) {
     53   x[i]   = (u.hi >> 24) & 0xff;
     54   x[i+1] = (u.hi >> 16) & 0xff;
     55   x[i+2] = (u.hi >>  8) & 0xff;
     56   x[i+3] = u.hi & 0xff;
     57   x[i+4] = (u.lo >> 24)  & 0xff;
     58   x[i+5] = (u.lo >> 16)  & 0xff;
     59   x[i+6] = (u.lo >>  8)  & 0xff;
     60   x[i+7] = u.lo & 0xff;
     61 }
     62 
     63 function vn(x, xi, y, yi, n) {
     64   var i,d = 0;
     65   for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i];
     66   return (1 & ((d - 1) >>> 8)) - 1;
     67 }
     68 
     69 function crypto_verify_16(x, xi, y, yi) {
     70   return vn(x,xi,y,yi,16);
     71 }
     72 
     73 function crypto_verify_32(x, xi, y, yi) {
     74   return vn(x,xi,y,yi,32);
     75 }
     76 
     77 function core(out,inp,k,c,h) {
     78   var w = new Uint32Array(16), x = new Uint32Array(16),
     79       y = new Uint32Array(16), t = new Uint32Array(4);
     80   var i, j, m;
     81 
     82   for (i = 0; i < 4; i++) {
     83     x[5*i] = ld32(c, 4*i);
     84     x[1+i] = ld32(k, 4*i);
     85     x[6+i] = ld32(inp, 4*i);
     86     x[11+i] = ld32(k, 16+4*i);
     87   }
     88 
     89   for (i = 0; i < 16; i++) y[i] = x[i];
     90 
     91   for (i = 0; i < 20; i++) {
     92     for (j = 0; j < 4; j++) {
     93       for (m = 0; m < 4; m++) t[m] = x[(5*j+4*m)%16];
     94       t[1] ^= L32((t[0]+t[3])|0, 7);
     95       t[2] ^= L32((t[1]+t[0])|0, 9);
     96       t[3] ^= L32((t[2]+t[1])|0,13);
     97       t[0] ^= L32((t[3]+t[2])|0,18);
     98       for (m = 0; m < 4; m++) w[4*j+(j+m)%4] = t[m];
     99     }
    100     for (m = 0; m < 16; m++) x[m] = w[m];
    101   }
    102 
    103   if (h) {
    104     for (i = 0; i < 16; i++) x[i] = (x[i] + y[i]) | 0;
    105     for (i = 0; i < 4; i++) {
    106       x[5*i] = (x[5*i] - ld32(c, 4*i)) | 0;
    107       x[6+i] = (x[6+i] - ld32(inp, 4*i)) | 0;
    108     }
    109     for (i = 0; i < 4; i++) {
    110       st32(out,4*i,x[5*i]);
    111       st32(out,16+4*i,x[6+i]);
    112     }
    113   } else {
    114     for (i = 0; i < 16; i++) st32(out, 4 * i, (x[i] + y[i]) | 0);
    115   }
    116 }
    117 
    118 function crypto_core_salsa20(out,inp,k,c) {
    119   core(out,inp,k,c,false);
    120   return 0;
    121 }
    122 
    123 function crypto_core_hsalsa20(out,inp,k,c) {
    124   core(out,inp,k,c,true);
    125   return 0;
    126 }
    127 
    128 var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]);
    129             // "expand 32-byte k"
    130 
    131 function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) {
    132   var z = new Uint8Array(16), x = new Uint8Array(64);
    133   var u, i;
    134   if (!b) return 0;
    135   for (i = 0; i < 16; i++) z[i] = 0;
    136   for (i = 0; i < 8; i++) z[i] = n[i];
    137   while (b >= 64) {
    138     crypto_core_salsa20(x,z,k,sigma);
    139     for (i = 0; i < 64; i++) c[cpos+i] = (m?m[mpos+i]:0) ^ x[i];
    140     u = 1;
    141     for (i = 8; i < 16; i++) {
    142       u = u + (z[i] & 0xff) | 0;
    143       z[i] = u & 0xff;
    144       u >>>= 8;
    145     }
    146     b -= 64;
    147     cpos += 64;
    148     if (m) mpos += 64;
    149   }
    150   if (b > 0) {
    151     crypto_core_salsa20(x,z,k,sigma);
    152     for (i = 0; i < b; i++) c[cpos+i] = (m?m[mpos+i]:0) ^ x[i];
    153   }
    154   return 0;
    155 }
    156 
    157 function crypto_stream_salsa20(c,cpos,d,n,k) {
    158   return crypto_stream_salsa20_xor(c,cpos,null,0,d,n,k);
    159 }
    160 
    161 function crypto_stream(c,cpos,d,n,k) {
    162   var s = new Uint8Array(32);
    163   crypto_core_hsalsa20(s,n,k,sigma);
    164   return crypto_stream_salsa20(c,cpos,d,n.subarray(16),s);
    165 }
    166 
    167 function crypto_stream_xor(c,cpos,m,mpos,d,n,k) {
    168   var s = new Uint8Array(32);
    169   crypto_core_hsalsa20(s,n,k,sigma);
    170   return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,n.subarray(16),s);
    171 }
    172 
    173 function add1305(h, c) {
    174   var j, u = 0;
    175   for (j = 0; j < 17; j++) {
    176     u = (u + ((h[j] + c[j]) | 0)) | 0;
    177     h[j] = u & 255;
    178     u >>>= 8;
    179   }
    180 }
    181 
    182 var minusp = new Uint32Array([
    183   5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
    184 ]);
    185 
    186 function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
    187   var s, i, j, u;
    188   var x = new Uint32Array(17), r = new Uint32Array(17),
    189       h = new Uint32Array(17), c = new Uint32Array(17),
    190       g = new Uint32Array(17);
    191   for (j = 0; j < 17; j++) r[j]=h[j]=0;
    192   for (j = 0; j < 16; j++) r[j]=k[j];
    193   r[3]&=15;
    194   r[4]&=252;
    195   r[7]&=15;
    196   r[8]&=252;
    197   r[11]&=15;
    198   r[12]&=252;
    199   r[15]&=15;
    200 
    201   while (n > 0) {
    202     for (j = 0; j < 17; j++) c[j] = 0;
    203     for (j = 0; (j < 16) && (j < n); ++j) c[j] = m[mpos+j];
    204     c[j] = 1;
    205     mpos += j; n -= j;
    206     add1305(h,c);
    207     for (i = 0; i < 17; i++) {
    208       x[i] = 0;
    209       for (j = 0; j < 17; j++) x[i] = (x[i] + (h[j] * ((j <= i) ? r[i - j] : ((320 * r[i + 17 - j])|0))) | 0) | 0;
    210     }
    211     for (i = 0; i < 17; i++) h[i] = x[i];
    212     u = 0;
    213     for (j = 0; j < 16; j++) {
    214       u = (u + h[j]) | 0;
    215       h[j] = u & 255;
    216       u >>>= 8;
    217     }
    218     u = (u + h[16]) | 0; h[16] = u & 3;
    219     u = (5 * (u >>> 2)) | 0;
    220     for (j = 0; j < 16; j++) {
    221       u = (u + h[j]) | 0;
    222       h[j] = u & 255;
    223       u >>>= 8;
    224     }
    225     u = (u + h[16]) | 0; h[16] = u;
    226   }
    227 
    228   for (j = 0; j < 17; j++) g[j] = h[j];
    229   add1305(h,minusp);
    230   s = (-(h[16] >>> 7) | 0);
    231   for (j = 0; j < 17; j++) h[j] ^= s & (g[j] ^ h[j]);
    232 
    233   for (j = 0; j < 16; j++) c[j] = k[j + 16];
    234   c[16] = 0;
    235   add1305(h,c);
    236   for (j = 0; j < 16; j++) out[outpos+j] = h[j];
    237   return 0;
    238 }
    239 
    240 function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {
    241   var x = new Uint8Array(16);
    242   crypto_onetimeauth(x,0,m,mpos,n,k);
    243   return crypto_verify_16(h,hpos,x,0);
    244 }
    245 
    246 function crypto_secretbox(c,m,d,n,k) {
    247   var i;
    248   if (d < 32) return -1;
    249   crypto_stream_xor(c,0,m,0,d,n,k);
    250   crypto_onetimeauth(c, 16, c, 32, d - 32, c);
    251   for (i = 0; i < 16; i++) c[i] = 0;
    252   return 0;
    253 }
    254 
    255 function crypto_secretbox_open(m,c,d,n,k) {
    256   var i;
    257   var x = new Uint8Array(32);
    258   if (d < 32) return -1;
    259   crypto_stream(x,0,32,n,k);
    260   if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1;
    261   crypto_stream_xor(m,0,c,0,d,n,k);
    262   for (i = 0; i < 32; i++) m[i] = 0;
    263   return 0;
    264 }
    265 
    266 function set25519(r, a) {
    267   var i;
    268   for (i = 0; i < 16; i++) r[i] = a[i]|0;
    269 }
    270 
    271 function car25519(o) {
    272   var c;
    273   var i;
    274   for (i = 0; i < 16; i++) {
    275       o[i] += 65536;
    276       c = Math.floor(o[i] / 65536);
    277       o[(i+1)*(i<15?1:0)] += c - 1 + 37 * (c-1) * (i===15?1:0);
    278       o[i] -= (c * 65536);
    279   }
    280 }
    281 
    282 function sel25519(p, q, b) {
    283   var t, c = ~(b-1);
    284   for (var i = 0; i < 16; i++) {
    285     t = c & (p[i] ^ q[i]);
    286     p[i] ^= t;
    287     q[i] ^= t;
    288   }
    289 }
    290 
    291 function pack25519(o, n) {
    292   var i, j, b;
    293   var m = gf(), t = gf();
    294   for (i = 0; i < 16; i++) t[i] = n[i];
    295   car25519(t);
    296   car25519(t);
    297   car25519(t);
    298   for (j = 0; j < 2; j++) {
    299     m[0] = t[0] - 0xffed;
    300     for (i = 1; i < 15; i++) {
    301       m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
    302       m[i-1] &= 0xffff;
    303     }
    304     m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
    305     b = (m[15]>>16) & 1;
    306     m[14] &= 0xffff;
    307     sel25519(t, m, 1-b);
    308   }
    309   for (i = 0; i < 16; i++) {
    310     o[2*i] = t[i] & 0xff;
    311     o[2*i+1] = t[i]>>8;
    312   }
    313 }
    314 
    315 function neq25519(a, b) {
    316   var c = new Uint8Array(32), d = new Uint8Array(32);
    317   pack25519(c, a);
    318   pack25519(d, b);
    319   return crypto_verify_32(c, 0, d, 0);
    320 }
    321 
    322 function par25519(a) {
    323   var d = new Uint8Array(32);
    324   pack25519(d, a);
    325   return d[0] & 1;
    326 }
    327 
    328 function unpack25519(o, n) {
    329   var i;
    330   for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
    331   o[15] &= 0x7fff;
    332 }
    333 
    334 function A(o, a, b) {
    335   var i;
    336   for (i = 0; i < 16; i++) o[i] = (a[i] + b[i])|0;
    337 }
    338 
    339 function Z(o, a, b) {
    340   var i;
    341   for (i = 0; i < 16; i++) o[i] = (a[i] - b[i])|0;
    342 }
    343 
    344 function M(o, a, b) {
    345   var i, j, t = new Float64Array(31);
    346   for (i = 0; i < 31; i++) t[i] = 0;
    347   for (i = 0; i < 16; i++) {
    348     for (j = 0; j < 16; j++) {
    349       t[i+j] += a[i] * b[j];
    350     }
    351   }
    352   for (i = 0; i < 15; i++) {
    353     t[i] += 38 * t[i+16];
    354   }
    355   for (i = 0; i < 16; i++) o[i] = t[i];
    356   car25519(o);
    357   car25519(o);
    358 }
    359 
    360 function S(o, a) {
    361   M(o, a, a);
    362 }
    363 
    364 function inv25519(o, i) {
    365   var c = gf();
    366   var a;
    367   for (a = 0; a < 16; a++) c[a] = i[a];
    368   for (a = 253; a >= 0; a--) {
    369     S(c, c);
    370     if(a !== 2 && a !== 4) M(c, c, i);
    371   }
    372   for (a = 0; a < 16; a++) o[a] = c[a];
    373 }
    374 
    375 function pow2523(o, i) {
    376   var c = gf();
    377   var a;
    378   for (a = 0; a < 16; a++) c[a] = i[a];
    379   for (a = 250; a >= 0; a--) {
    380       S(c, c);
    381       if(a !== 1) M(c, c, i);
    382   }
    383   for (a = 0; a < 16; a++) o[a] = c[a];
    384 }
    385 
    386 function crypto_scalarmult(q, n, p) {
    387   var z = new Uint8Array(32);
    388   var x = new Float64Array(80), r, i;
    389   var a = gf(), b = gf(), c = gf(),
    390       d = gf(), e = gf(), f = gf();
    391   for (i = 0; i < 31; i++) z[i] = n[i];
    392   z[31]=(n[31]&127)|64;
    393   z[0]&=248;
    394   unpack25519(x,p);
    395   for (i = 0; i < 16; i++) {
    396     b[i]=x[i];
    397     d[i]=a[i]=c[i]=0;
    398   }
    399   a[0]=d[0]=1;
    400   for (i=254; i>=0; --i) {
    401     r=(z[i>>>3]>>>(i&7))&1;
    402     sel25519(a,b,r);
    403     sel25519(c,d,r);
    404     A(e,a,c);
    405     Z(a,a,c);
    406     A(c,b,d);
    407     Z(b,b,d);
    408     S(d,e);
    409     S(f,a);
    410     M(a,c,a);
    411     M(c,b,e);
    412     A(e,a,c);
    413     Z(a,a,c);
    414     S(b,a);
    415     Z(c,d,f);
    416     M(a,c,_121665);
    417     A(a,a,d);
    418     M(c,c,a);
    419     M(a,d,f);
    420     M(d,b,x);
    421     S(b,e);
    422     sel25519(a,b,r);
    423     sel25519(c,d,r);
    424   }
    425   for (i = 0; i < 16; i++) {
    426     x[i+16]=a[i];
    427     x[i+32]=c[i];
    428     x[i+48]=b[i];
    429     x[i+64]=d[i];
    430   }
    431   var x32 = x.subarray(32);
    432   var x16 = x.subarray(16);
    433   inv25519(x32,x32);
    434   M(x16,x16,x32);
    435   pack25519(q,x16);
    436   return 0;
    437 }
    438 
    439 function crypto_scalarmult_base(q, n) {
    440   return crypto_scalarmult(q, n, _9);
    441 }
    442 
    443 function crypto_box_keypair(y, x) {
    444   randombytes(x, 32);
    445   return crypto_scalarmult_base(y, x);
    446 }
    447 
    448 function crypto_box_beforenm(k, y, x) {
    449   var s = new Uint8Array(32);
    450   crypto_scalarmult(s, x, y);
    451   return crypto_core_hsalsa20(k, _0, s, sigma);
    452 }
    453 
    454 var crypto_box_afternm = crypto_secretbox;
    455 var crypto_box_open_afternm = crypto_secretbox_open;
    456 
    457 function crypto_box(c, m, d, n, y, x) {
    458   var k = new Uint8Array(32);
    459   crypto_box_beforenm(k, y, x);
    460   return crypto_box_afternm(c, m, d, n, k);
    461 }
    462 
    463 function crypto_box_open(m, c, d, n, y, x) {
    464   var k = new Uint8Array(32);
    465   crypto_box_beforenm(k, y, x);
    466   return crypto_box_open_afternm(m, c, d, n, k);
    467 }
    468 
    469 function add64() {
    470   var a = 0, b = 0, c = 0, d = 0, m16 = 65535, l, h, i;
    471   for (i = 0; i < arguments.length; i++) {
    472     l = arguments[i].lo;
    473     h = arguments[i].hi;
    474     a += (l & m16); b += (l >>> 16);
    475     c += (h & m16); d += (h >>> 16);
    476   }
    477 
    478   b += (a >>> 16);
    479   c += (b >>> 16);
    480   d += (c >>> 16);
    481 
    482   return new u64((c & m16) | (d << 16), (a & m16) | (b << 16));
    483 }
    484 
    485 function shr64(x, c) {
    486   return new u64((x.hi >>> c), (x.lo >>> c) | (x.hi << (32 - c)));
    487 }
    488 
    489 function xor64() {
    490   var l = 0, h = 0, i;
    491   for (i = 0; i < arguments.length; i++) {
    492     l ^= arguments[i].lo;
    493     h ^= arguments[i].hi;
    494   }
    495   return new u64(h, l);
    496 }
    497 
    498 function R(x, c) {
    499   var h, l, c1 = 32 - c;
    500   if (c < 32) {
    501     h = (x.hi >>> c) | (x.lo << c1);
    502     l = (x.lo >>> c) | (x.hi << c1);
    503   } else if (c < 64) {
    504     h = (x.lo >>> c) | (x.hi << c1);
    505     l = (x.hi >>> c) | (x.lo << c1);
    506   }
    507   return new u64(h, l);
    508 }
    509 
    510 function Ch(x, y, z) {
    511   var h = (x.hi & y.hi) ^ (~x.hi & z.hi),
    512       l = (x.lo & y.lo) ^ (~x.lo & z.lo);
    513   return new u64(h, l);
    514 }
    515 
    516 function Maj(x, y, z) {
    517   var h = (x.hi & y.hi) ^ (x.hi & z.hi) ^ (y.hi & z.hi),
    518       l = (x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo);
    519   return new u64(h, l);
    520 }
    521 
    522 function Sigma0(x) { return xor64(R(x,28), R(x,34), R(x,39)); }
    523 function Sigma1(x) { return xor64(R(x,14), R(x,18), R(x,41)); }
    524 function sigma0(x) { return xor64(R(x, 1), R(x, 8), shr64(x,7)); }
    525 function sigma1(x) { return xor64(R(x,19), R(x,61), shr64(x,6)); }
    526 
    527 var K = [
    528   new u64(0x428a2f98, 0xd728ae22), new u64(0x71374491, 0x23ef65cd),
    529   new u64(0xb5c0fbcf, 0xec4d3b2f), new u64(0xe9b5dba5, 0x8189dbbc),
    530   new u64(0x3956c25b, 0xf348b538), new u64(0x59f111f1, 0xb605d019),
    531   new u64(0x923f82a4, 0xaf194f9b), new u64(0xab1c5ed5, 0xda6d8118),
    532   new u64(0xd807aa98, 0xa3030242), new u64(0x12835b01, 0x45706fbe),
    533   new u64(0x243185be, 0x4ee4b28c), new u64(0x550c7dc3, 0xd5ffb4e2),
    534   new u64(0x72be5d74, 0xf27b896f), new u64(0x80deb1fe, 0x3b1696b1),
    535   new u64(0x9bdc06a7, 0x25c71235), new u64(0xc19bf174, 0xcf692694),
    536   new u64(0xe49b69c1, 0x9ef14ad2), new u64(0xefbe4786, 0x384f25e3),
    537   new u64(0x0fc19dc6, 0x8b8cd5b5), new u64(0x240ca1cc, 0x77ac9c65),
    538   new u64(0x2de92c6f, 0x592b0275), new u64(0x4a7484aa, 0x6ea6e483),
    539   new u64(0x5cb0a9dc, 0xbd41fbd4), new u64(0x76f988da, 0x831153b5),
    540   new u64(0x983e5152, 0xee66dfab), new u64(0xa831c66d, 0x2db43210),
    541   new u64(0xb00327c8, 0x98fb213f), new u64(0xbf597fc7, 0xbeef0ee4),
    542   new u64(0xc6e00bf3, 0x3da88fc2), new u64(0xd5a79147, 0x930aa725),
    543   new u64(0x06ca6351, 0xe003826f), new u64(0x14292967, 0x0a0e6e70),
    544   new u64(0x27b70a85, 0x46d22ffc), new u64(0x2e1b2138, 0x5c26c926),
    545   new u64(0x4d2c6dfc, 0x5ac42aed), new u64(0x53380d13, 0x9d95b3df),
    546   new u64(0x650a7354, 0x8baf63de), new u64(0x766a0abb, 0x3c77b2a8),
    547   new u64(0x81c2c92e, 0x47edaee6), new u64(0x92722c85, 0x1482353b),
    548   new u64(0xa2bfe8a1, 0x4cf10364), new u64(0xa81a664b, 0xbc423001),
    549   new u64(0xc24b8b70, 0xd0f89791), new u64(0xc76c51a3, 0x0654be30),
    550   new u64(0xd192e819, 0xd6ef5218), new u64(0xd6990624, 0x5565a910),
    551   new u64(0xf40e3585, 0x5771202a), new u64(0x106aa070, 0x32bbd1b8),
    552   new u64(0x19a4c116, 0xb8d2d0c8), new u64(0x1e376c08, 0x5141ab53),
    553   new u64(0x2748774c, 0xdf8eeb99), new u64(0x34b0bcb5, 0xe19b48a8),
    554   new u64(0x391c0cb3, 0xc5c95a63), new u64(0x4ed8aa4a, 0xe3418acb),
    555   new u64(0x5b9cca4f, 0x7763e373), new u64(0x682e6ff3, 0xd6b2b8a3),
    556   new u64(0x748f82ee, 0x5defb2fc), new u64(0x78a5636f, 0x43172f60),
    557   new u64(0x84c87814, 0xa1f0ab72), new u64(0x8cc70208, 0x1a6439ec),
    558   new u64(0x90befffa, 0x23631e28), new u64(0xa4506ceb, 0xde82bde9),
    559   new u64(0xbef9a3f7, 0xb2c67915), new u64(0xc67178f2, 0xe372532b),
    560   new u64(0xca273ece, 0xea26619c), new u64(0xd186b8c7, 0x21c0c207),
    561   new u64(0xeada7dd6, 0xcde0eb1e), new u64(0xf57d4f7f, 0xee6ed178),
    562   new u64(0x06f067aa, 0x72176fba), new u64(0x0a637dc5, 0xa2c898a6),
    563   new u64(0x113f9804, 0xbef90dae), new u64(0x1b710b35, 0x131c471b),
    564   new u64(0x28db77f5, 0x23047d84), new u64(0x32caab7b, 0x40c72493),
    565   new u64(0x3c9ebe0a, 0x15c9bebc), new u64(0x431d67c4, 0x9c100d4c),
    566   new u64(0x4cc5d4be, 0xcb3e42b6), new u64(0x597f299c, 0xfc657e2a),
    567   new u64(0x5fcb6fab, 0x3ad6faec), new u64(0x6c44198c, 0x4a475817)
    568 ];
    569 
    570 function crypto_hashblocks(x, m, n) {
    571   var z = [], b = [], a = [], w = [], t, i, j;
    572 
    573   for (i = 0; i < 8; i++) z[i] = a[i] = dl64(x, 8*i);
    574 
    575   var pos = 0;
    576   while (n >= 128) {
    577     for (i = 0; i < 16; i++) w[i] = dl64(m, 8*i+pos);
    578     for (i = 0; i < 80; i++) {
    579       for (j = 0; j < 8; j++) b[j] = a[j];
    580       t = add64(a[7], Sigma1(a[4]), Ch(a[4], a[5], a[6]), K[i], w[i%16]);
    581       b[7] = add64(t, Sigma0(a[0]), Maj(a[0], a[1], a[2]));
    582       b[3] = add64(b[3], t);
    583       for (j = 0; j < 8; j++) a[(j+1)%8] = b[j];
    584       if (i%16 === 15) {
    585         for (j = 0; j < 16; j++) {
    586           w[j] = add64(w[j], w[(j+9)%16], sigma0(w[(j+1)%16]), sigma1(w[(j+14)%16]));
    587         }
    588       }
    589     }
    590 
    591     for (i = 0; i < 8; i++) {
    592       a[i] = add64(a[i], z[i]);
    593       z[i] = a[i];
    594     }
    595 
    596     pos += 128;
    597     n -= 128;
    598   }
    599 
    600   for (i = 0; i < 8; i++) ts64(x, 8*i, z[i]);
    601   return n;
    602 }
    603 
    604 var iv = new Uint8Array([
    605   0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
    606   0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
    607   0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
    608   0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
    609   0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
    610   0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
    611   0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
    612   0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
    613 ]);
    614 
    615 function crypto_hash(out, m, n) {
    616   var h = new Uint8Array(64), x = new Uint8Array(256);
    617   var i, b = n;
    618 
    619   for (i = 0; i < 64; i++) h[i] = iv[i];
    620 
    621   crypto_hashblocks(h, m, n);
    622   n %= 128;
    623 
    624   for (i = 0; i < 256; i++) x[i] = 0;
    625   for (i = 0; i < n; i++) x[i] = m[b-n+i];
    626   x[n] = 128;
    627 
    628   n = 256-128*(n<112?1:0);
    629   x[n-9] = 0;
    630   ts64(x, n-8, new u64((b / 0x20000000) | 0, b << 3));
    631   crypto_hashblocks(h, x, n);
    632 
    633   for (i = 0; i < 64; i++) out[i] = h[i];
    634 
    635   return 0;
    636 }
    637 
    638 function add(p, q) {
    639   var a = gf(), b = gf(), c = gf(),
    640       d = gf(), e = gf(), f = gf(),
    641       g = gf(), h = gf(), t = gf();
    642 
    643   Z(a, p[1], p[0]);
    644   Z(t, q[1], q[0]);
    645   M(a, a, t);
    646   A(b, p[0], p[1]);
    647   A(t, q[0], q[1]);
    648   M(b, b, t);
    649   M(c, p[3], q[3]);
    650   M(c, c, D2);
    651   M(d, p[2], q[2]);
    652   A(d, d, d);
    653   Z(e, b, a);
    654   Z(f, d, c);
    655   A(g, d, c);
    656   A(h, b, a);
    657 
    658   M(p[0], e, f);
    659   M(p[1], h, g);
    660   M(p[2], g, f);
    661   M(p[3], e, h);
    662 }
    663 
    664 function cswap(p, q, b) {
    665   var i;
    666   for (i = 0; i < 4; i++) {
    667     sel25519(p[i], q[i], b);
    668   }
    669 }
    670 
    671 function pack(r, p) {
    672   var tx = gf(), ty = gf(), zi = gf();
    673   inv25519(zi, p[2]);
    674   M(tx, p[0], zi);
    675   M(ty, p[1], zi);
    676   pack25519(r, ty);
    677   r[31] ^= par25519(tx) << 7;
    678 }
    679 
    680 function scalarmult(p, q, s) {
    681   var b, i;
    682   set25519(p[0], gf0);
    683   set25519(p[1], gf1);
    684   set25519(p[2], gf1);
    685   set25519(p[3], gf0);
    686   for (i = 255; i >= 0; --i) {
    687     b = (s[(i/8)|0] >> (i&7)) & 1;
    688     cswap(p, q, b);
    689     add(q, p);
    690     add(p, p);
    691     cswap(p, q, b);
    692   }
    693 }
    694 
    695 function scalarbase(p, s) {
    696   var q = [gf(), gf(), gf(), gf()];
    697   set25519(q[0], X);
    698   set25519(q[1], Y);
    699   set25519(q[2], gf1);
    700   M(q[3], X, Y);
    701   scalarmult(p, q, s);
    702 }
    703 
    704 function crypto_sign_keypair(pk, sk, seeded) {
    705   var d = new Uint8Array(64);
    706   var p = [gf(), gf(), gf(), gf()];
    707   var i;
    708 
    709   if (!seeded) randombytes(sk, 32);
    710   crypto_hash(d, sk, 32);
    711   d[0] &= 248;
    712   d[31] &= 127;
    713   d[31] |= 64;
    714 
    715   scalarbase(p, d);
    716   pack(pk, p);
    717 
    718   for (i = 0; i < 32; i++) sk[i+32] = pk[i];
    719   return 0;
    720 }
    721 
    722 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]);
    723 
    724 function modL(r, x) {
    725   var carry, i, j, k;
    726   for (i = 63; i >= 32; --i) {
    727     carry = 0;
    728     for (j = i - 32, k = i - 12; j < k; ++j) {
    729       x[j] += carry - 16 * x[i] * L[j - (i - 32)];
    730       carry = Math.floor((x[j] + 128) / 256);
    731       x[j] -= carry * 256;
    732     }
    733     x[j] += carry;
    734     x[i] = 0;
    735   }
    736   carry = 0;
    737   for (j = 0; j < 32; j++) {
    738     x[j] += carry - (x[31] >> 4) * L[j];
    739     carry = x[j] >> 8;
    740     x[j] &= 255;
    741   }
    742   for (j = 0; j < 32; j++) x[j] -= carry * L[j];
    743   for (i = 0; i < 32; i++) {
    744     x[i+1] += x[i] >> 8;
    745     r[i] = x[i] & 255;
    746   }
    747 }
    748 
    749 function reduce(r) {
    750   var x = new Float64Array(64), i;
    751   for (i = 0; i < 64; i++) x[i] = r[i];
    752   for (i = 0; i < 64; i++) r[i] = 0;
    753   modL(r, x);
    754 }
    755 
    756 // Note: difference from C - smlen returned, not passed as argument.
    757 function crypto_sign(sm, m, n, sk) {
    758   var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);
    759   var i, j, x = new Float64Array(64);
    760   var p = [gf(), gf(), gf(), gf()];
    761 
    762   crypto_hash(d, sk, 32);
    763   d[0] &= 248;
    764   d[31] &= 127;
    765   d[31] |= 64;
    766 
    767   var smlen = n + 64;
    768   for (i = 0; i < n; i++) sm[64 + i] = m[i];
    769   for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
    770 
    771   crypto_hash(r, sm.subarray(32), n+32);
    772   reduce(r);
    773   scalarbase(p, r);
    774   pack(sm, p);
    775 
    776   for (i = 32; i < 64; i++) sm[i] = sk[i];
    777   crypto_hash(h, sm, n + 64);
    778   reduce(h);
    779 
    780   for (i = 0; i < 64; i++) x[i] = 0;
    781   for (i = 0; i < 32; i++) x[i] = r[i];
    782   for (i = 0; i < 32; i++) {
    783     for (j = 0; j < 32; j++) {
    784       x[i+j] += h[i] * d[j];
    785     }
    786   }
    787 
    788   modL(sm.subarray(32), x);
    789   return smlen;
    790 }
    791 
    792 function unpackneg(r, p) {
    793   var t = gf(), chk = gf(), num = gf(),
    794       den = gf(), den2 = gf(), den4 = gf(),
    795       den6 = gf();
    796 
    797   set25519(r[2], gf1);
    798   unpack25519(r[1], p);
    799   S(num, r[1]);
    800   M(den, num, D);
    801   Z(num, num, r[2]);
    802   A(den, r[2], den);
    803 
    804   S(den2, den);
    805   S(den4, den2);
    806   M(den6, den4, den2);
    807   M(t, den6, num);
    808   M(t, t, den);
    809 
    810   pow2523(t, t);
    811   M(t, t, num);
    812   M(t, t, den);
    813   M(t, t, den);
    814   M(r[0], t, den);
    815 
    816   S(chk, r[0]);
    817   M(chk, chk, den);
    818   if (neq25519(chk, num)) M(r[0], r[0], I);
    819 
    820   S(chk, r[0]);
    821   M(chk, chk, den);
    822   if (neq25519(chk, num)) return -1;
    823 
    824   if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);
    825 
    826   M(r[3], r[0], r[1]);
    827   return 0;
    828 }
    829 
    830 function crypto_sign_open(m, sm, n, pk) {
    831   var i;
    832   var t = new Uint8Array(32), h = new Uint8Array(64);
    833   var p = [gf(), gf(), gf(), gf()],
    834       q = [gf(), gf(), gf(), gf()];
    835 
    836   if (n < 64) return -1;
    837 
    838   if (unpackneg(q, pk)) return -1;
    839 
    840   for (i = 0; i < n; i++) m[i] = sm[i];
    841   for (i = 0; i < 32; i++) m[i+32] = pk[i];
    842   crypto_hash(h, m, n);
    843   reduce(h);
    844   scalarmult(p, q, h);
    845 
    846   scalarbase(q, sm.subarray(32));
    847   add(p, q);
    848   pack(t, p);
    849 
    850   n -= 64;
    851   if (crypto_verify_32(sm, 0, t, 0)) {
    852     for (i = 0; i < n; i++) m[i] = 0;
    853     return -1;
    854   }
    855 
    856   for (i = 0; i < n; i++) m[i] = sm[i + 64];
    857   return n;
    858 }
    859 
    860 var crypto_secretbox_KEYBYTES = 32,
    861     crypto_secretbox_NONCEBYTES = 24,
    862     crypto_secretbox_ZEROBYTES = 32,
    863     crypto_secretbox_BOXZEROBYTES = 16,
    864     crypto_scalarmult_BYTES = 32,
    865     crypto_scalarmult_SCALARBYTES = 32,
    866     crypto_box_PUBLICKEYBYTES = 32,
    867     crypto_box_SECRETKEYBYTES = 32,
    868     crypto_box_BEFORENMBYTES = 32,
    869     crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES,
    870     crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES,
    871     crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,
    872     crypto_sign_BYTES = 64,
    873     crypto_sign_PUBLICKEYBYTES = 32,
    874     crypto_sign_SECRETKEYBYTES = 64,
    875     crypto_sign_SEEDBYTES = 32,
    876     crypto_hash_BYTES = 64;
    877 
    878 nacl.lowlevel = {
    879   crypto_core_hsalsa20: crypto_core_hsalsa20,
    880   crypto_stream_xor: crypto_stream_xor,
    881   crypto_stream: crypto_stream,
    882   crypto_stream_salsa20_xor: crypto_stream_salsa20_xor,
    883   crypto_stream_salsa20: crypto_stream_salsa20,
    884   crypto_onetimeauth: crypto_onetimeauth,
    885   crypto_onetimeauth_verify: crypto_onetimeauth_verify,
    886   crypto_verify_16: crypto_verify_16,
    887   crypto_verify_32: crypto_verify_32,
    888   crypto_secretbox: crypto_secretbox,
    889   crypto_secretbox_open: crypto_secretbox_open,
    890   crypto_scalarmult: crypto_scalarmult,
    891   crypto_scalarmult_base: crypto_scalarmult_base,
    892   crypto_box_beforenm: crypto_box_beforenm,
    893   crypto_box_afternm: crypto_box_afternm,
    894   crypto_box: crypto_box,
    895   crypto_box_open: crypto_box_open,
    896   crypto_box_keypair: crypto_box_keypair,
    897   crypto_hash: crypto_hash,
    898   crypto_sign: crypto_sign,
    899   crypto_sign_keypair: crypto_sign_keypair,
    900   crypto_sign_open: crypto_sign_open,
    901 
    902   crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES,
    903   crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES,
    904   crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES,
    905   crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES,
    906   crypto_scalarmult_BYTES: crypto_scalarmult_BYTES,
    907   crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES,
    908   crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES,
    909   crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES,
    910   crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES,
    911   crypto_box_NONCEBYTES: crypto_box_NONCEBYTES,
    912   crypto_box_ZEROBYTES: crypto_box_ZEROBYTES,
    913   crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES,
    914   crypto_sign_BYTES: crypto_sign_BYTES,
    915   crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES,
    916   crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES,
    917   crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES,
    918   crypto_hash_BYTES: crypto_hash_BYTES,
    919 
    920   gf: gf,
    921   D: D,
    922   L: L,
    923   pack25519: pack25519,
    924   unpack25519: unpack25519,
    925   M: M,
    926   A: A,
    927   S: S,
    928   Z: Z,
    929   pow2523: pow2523,
    930   add: add,
    931   set25519: set25519,
    932   modL: modL,
    933   scalarmult: scalarmult,
    934   scalarbase: scalarbase,
    935 };
    936 
    937 /* High-level API */
    938 
    939 function checkLengths(k, n) {
    940   if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size');
    941   if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size');
    942 }
    943 
    944 function checkBoxLengths(pk, sk) {
    945   if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size');
    946   if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size');
    947 }
    948 
    949 function checkArrayTypes() {
    950   for (var i = 0; i < arguments.length; i++) {
    951     if (!(arguments[i] instanceof Uint8Array))
    952       throw new TypeError('unexpected type, use Uint8Array');
    953   }
    954 }
    955 
    956 function cleanup(arr) {
    957   for (var i = 0; i < arr.length; i++) arr[i] = 0;
    958 }
    959 
    960 nacl.randomBytes = function(n) {
    961   var b = new Uint8Array(n);
    962   randombytes(b, n);
    963   return b;
    964 };
    965 
    966 nacl.secretbox = function(msg, nonce, key) {
    967   checkArrayTypes(msg, nonce, key);
    968   checkLengths(key, nonce);
    969   var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
    970   var c = new Uint8Array(m.length);
    971   for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i];
    972   crypto_secretbox(c, m, m.length, nonce, key);
    973   return c.subarray(crypto_secretbox_BOXZEROBYTES);
    974 };
    975 
    976 nacl.secretbox.open = function(box, nonce, key) {
    977   checkArrayTypes(box, nonce, key);
    978   checkLengths(key, nonce);
    979   var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
    980   var m = new Uint8Array(c.length);
    981   for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i];
    982   if (c.length < 32) return null;
    983   if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return null;
    984   return m.subarray(crypto_secretbox_ZEROBYTES);
    985 };
    986 
    987 nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES;
    988 nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;
    989 nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;
    990 
    991 nacl.scalarMult = function(n, p) {
    992   checkArrayTypes(n, p);
    993   if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
    994   if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');
    995   var q = new Uint8Array(crypto_scalarmult_BYTES);
    996   crypto_scalarmult(q, n, p);
    997   return q;
    998 };
    999 
   1000 nacl.scalarMult.base = function(n) {
   1001   checkArrayTypes(n);
   1002   if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
   1003   var q = new Uint8Array(crypto_scalarmult_BYTES);
   1004   crypto_scalarmult_base(q, n);
   1005   return q;
   1006 };
   1007 
   1008 nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;
   1009 nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES;
   1010 
   1011 nacl.box = function(msg, nonce, publicKey, secretKey) {
   1012   var k = nacl.box.before(publicKey, secretKey);
   1013   return nacl.secretbox(msg, nonce, k);
   1014 };
   1015 
   1016 nacl.box.before = function(publicKey, secretKey) {
   1017   checkArrayTypes(publicKey, secretKey);
   1018   checkBoxLengths(publicKey, secretKey);
   1019   var k = new Uint8Array(crypto_box_BEFORENMBYTES);
   1020   crypto_box_beforenm(k, publicKey, secretKey);
   1021   return k;
   1022 };
   1023 
   1024 nacl.box.after = nacl.secretbox;
   1025 
   1026 nacl.box.open = function(msg, nonce, publicKey, secretKey) {
   1027   var k = nacl.box.before(publicKey, secretKey);
   1028   return nacl.secretbox.open(msg, nonce, k);
   1029 };
   1030 
   1031 nacl.box.open.after = nacl.secretbox.open;
   1032 
   1033 nacl.box.keyPair = function() {
   1034   var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
   1035   var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
   1036   crypto_box_keypair(pk, sk);
   1037   return {publicKey: pk, secretKey: sk};
   1038 };
   1039 
   1040 nacl.box.keyPair.fromSecretKey = function(secretKey) {
   1041   checkArrayTypes(secretKey);
   1042   if (secretKey.length !== crypto_box_SECRETKEYBYTES)
   1043     throw new Error('bad secret key size');
   1044   var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
   1045   crypto_scalarmult_base(pk, secretKey);
   1046   return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
   1047 };
   1048 
   1049 nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES;
   1050 nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES;
   1051 nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES;
   1052 nacl.box.nonceLength = crypto_box_NONCEBYTES;
   1053 nacl.box.overheadLength = nacl.secretbox.overheadLength;
   1054 
   1055 nacl.sign = function(msg, secretKey) {
   1056   checkArrayTypes(msg, secretKey);
   1057   if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
   1058     throw new Error('bad secret key size');
   1059   var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length);
   1060   crypto_sign(signedMsg, msg, msg.length, secretKey);
   1061   return signedMsg;
   1062 };
   1063 
   1064 nacl.sign.open = function(signedMsg, publicKey) {
   1065   checkArrayTypes(signedMsg, publicKey);
   1066   if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
   1067     throw new Error('bad public key size');
   1068   var tmp = new Uint8Array(signedMsg.length);
   1069   var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
   1070   if (mlen < 0) return null;
   1071   var m = new Uint8Array(mlen);
   1072   for (var i = 0; i < m.length; i++) m[i] = tmp[i];
   1073   return m;
   1074 };
   1075 
   1076 nacl.sign.detached = function(msg, secretKey) {
   1077   var signedMsg = nacl.sign(msg, secretKey);
   1078   var sig = new Uint8Array(crypto_sign_BYTES);
   1079   for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
   1080   return sig;
   1081 };
   1082 
   1083 nacl.sign.detached.verify = function(msg, sig, publicKey) {
   1084   checkArrayTypes(msg, sig, publicKey);
   1085   if (sig.length !== crypto_sign_BYTES)
   1086     throw new Error('bad signature size');
   1087   if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
   1088     throw new Error('bad public key size');
   1089   var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
   1090   var m = new Uint8Array(crypto_sign_BYTES + msg.length);
   1091   var i;
   1092   for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
   1093   for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];
   1094   return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0);
   1095 };
   1096 
   1097 nacl.sign.keyPair = function() {
   1098   var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
   1099   var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
   1100   crypto_sign_keypair(pk, sk);
   1101   return {publicKey: pk, secretKey: sk};
   1102 };
   1103 
   1104 nacl.sign.keyPair.fromSecretKey = function(secretKey) {
   1105   checkArrayTypes(secretKey);
   1106   if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
   1107     throw new Error('bad secret key size');
   1108   var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
   1109   for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i];
   1110   return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
   1111 };
   1112 
   1113 nacl.sign.keyPair.fromSeed = function(seed) {
   1114   checkArrayTypes(seed);
   1115   if (seed.length !== crypto_sign_SEEDBYTES)
   1116     throw new Error('bad seed size');
   1117   var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
   1118   var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
   1119   for (var i = 0; i < 32; i++) sk[i] = seed[i];
   1120   crypto_sign_keypair(pk, sk, true);
   1121   return {publicKey: pk, secretKey: sk};
   1122 };
   1123 
   1124 nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES;
   1125 nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES;
   1126 nacl.sign.seedLength = crypto_sign_SEEDBYTES;
   1127 nacl.sign.signatureLength = crypto_sign_BYTES;
   1128 
   1129 nacl.hash = function(msg) {
   1130   checkArrayTypes(msg);
   1131   var h = new Uint8Array(crypto_hash_BYTES);
   1132   crypto_hash(h, msg, msg.length);
   1133   return h;
   1134 };
   1135 
   1136 nacl.hash.hashLength = crypto_hash_BYTES;
   1137 
   1138 nacl.verify = function(x, y) {
   1139   checkArrayTypes(x, y);
   1140   // Zero length arguments are considered not equal.
   1141   if (x.length === 0 || y.length === 0) return false;
   1142   if (x.length !== y.length) return false;
   1143   return (vn(x, 0, y, 0, x.length) === 0) ? true : false;
   1144 };
   1145 
   1146 nacl.setPRNG = function(fn) {
   1147   randombytes = fn;
   1148 };
   1149 
   1150 (function() {
   1151   // Initialize PRNG if environment provides CSPRNG.
   1152   // If not, methods calling randombytes will throw.
   1153   var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null;
   1154   if (crypto && crypto.getRandomValues) {
   1155     // Browsers.
   1156     var QUOTA = 65536;
   1157     nacl.setPRNG(function(x, n) {
   1158       var i, v = new Uint8Array(n);
   1159       for (i = 0; i < n; i += QUOTA) {
   1160         crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
   1161       }
   1162       for (i = 0; i < n; i++) x[i] = v[i];
   1163       cleanup(v);
   1164     });
   1165   } else if (typeof require !== 'undefined') {
   1166     // Node.js.
   1167     crypto = require('crypto');
   1168     if (crypto && crypto.randomBytes) {
   1169       nacl.setPRNG(function(x, n) {
   1170         var i, v = crypto.randomBytes(n);
   1171         for (i = 0; i < n; i++) x[i] = v[i];
   1172         cleanup(v);
   1173       });
   1174     }
   1175   }
   1176 })();
   1177 
   1178 })(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {}));