Initial commit
[yaffs-website] / node_modules / tweetnacl / nacl.js
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 = (x[j] + 128) >> 8;
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, mlen;
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   mlen = -1;
837   if (n < 64) return -1;
838
839   if (unpackneg(q, pk)) return -1;
840
841   for (i = 0; i < n; i++) m[i] = sm[i];
842   for (i = 0; i < 32; i++) m[i+32] = pk[i];
843   crypto_hash(h, m, n);
844   reduce(h);
845   scalarmult(p, q, h);
846
847   scalarbase(q, sm.subarray(32));
848   add(p, q);
849   pack(t, p);
850
851   n -= 64;
852   if (crypto_verify_32(sm, 0, t, 0)) {
853     for (i = 0; i < n; i++) m[i] = 0;
854     return -1;
855   }
856
857   for (i = 0; i < n; i++) m[i] = sm[i + 64];
858   mlen = n;
859   return mlen;
860 }
861
862 var crypto_secretbox_KEYBYTES = 32,
863     crypto_secretbox_NONCEBYTES = 24,
864     crypto_secretbox_ZEROBYTES = 32,
865     crypto_secretbox_BOXZEROBYTES = 16,
866     crypto_scalarmult_BYTES = 32,
867     crypto_scalarmult_SCALARBYTES = 32,
868     crypto_box_PUBLICKEYBYTES = 32,
869     crypto_box_SECRETKEYBYTES = 32,
870     crypto_box_BEFORENMBYTES = 32,
871     crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES,
872     crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES,
873     crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,
874     crypto_sign_BYTES = 64,
875     crypto_sign_PUBLICKEYBYTES = 32,
876     crypto_sign_SECRETKEYBYTES = 64,
877     crypto_sign_SEEDBYTES = 32,
878     crypto_hash_BYTES = 64;
879
880 nacl.lowlevel = {
881   crypto_core_hsalsa20: crypto_core_hsalsa20,
882   crypto_stream_xor: crypto_stream_xor,
883   crypto_stream: crypto_stream,
884   crypto_stream_salsa20_xor: crypto_stream_salsa20_xor,
885   crypto_stream_salsa20: crypto_stream_salsa20,
886   crypto_onetimeauth: crypto_onetimeauth,
887   crypto_onetimeauth_verify: crypto_onetimeauth_verify,
888   crypto_verify_16: crypto_verify_16,
889   crypto_verify_32: crypto_verify_32,
890   crypto_secretbox: crypto_secretbox,
891   crypto_secretbox_open: crypto_secretbox_open,
892   crypto_scalarmult: crypto_scalarmult,
893   crypto_scalarmult_base: crypto_scalarmult_base,
894   crypto_box_beforenm: crypto_box_beforenm,
895   crypto_box_afternm: crypto_box_afternm,
896   crypto_box: crypto_box,
897   crypto_box_open: crypto_box_open,
898   crypto_box_keypair: crypto_box_keypair,
899   crypto_hash: crypto_hash,
900   crypto_sign: crypto_sign,
901   crypto_sign_keypair: crypto_sign_keypair,
902   crypto_sign_open: crypto_sign_open,
903
904   crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES,
905   crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES,
906   crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES,
907   crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES,
908   crypto_scalarmult_BYTES: crypto_scalarmult_BYTES,
909   crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES,
910   crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES,
911   crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES,
912   crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES,
913   crypto_box_NONCEBYTES: crypto_box_NONCEBYTES,
914   crypto_box_ZEROBYTES: crypto_box_ZEROBYTES,
915   crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES,
916   crypto_sign_BYTES: crypto_sign_BYTES,
917   crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES,
918   crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES,
919   crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES,
920   crypto_hash_BYTES: crypto_hash_BYTES
921 };
922
923 /* High-level API */
924
925 function checkLengths(k, n) {
926   if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size');
927   if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size');
928 }
929
930 function checkBoxLengths(pk, sk) {
931   if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size');
932   if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size');
933 }
934
935 function checkArrayTypes() {
936   var t, i;
937   for (i = 0; i < arguments.length; i++) {
938      if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]')
939        throw new TypeError('unexpected type ' + t + ', use Uint8Array');
940   }
941 }
942
943 function cleanup(arr) {
944   for (var i = 0; i < arr.length; i++) arr[i] = 0;
945 }
946
947 // TODO: Completely remove this in v0.15.
948 if (!nacl.util) {
949   nacl.util = {};
950   nacl.util.decodeUTF8 = nacl.util.encodeUTF8 = nacl.util.encodeBase64 = nacl.util.decodeBase64 = function() {
951     throw new Error('nacl.util moved into separate package: https://github.com/dchest/tweetnacl-util-js');
952   };
953 }
954
955 nacl.randomBytes = function(n) {
956   var b = new Uint8Array(n);
957   randombytes(b, n);
958   return b;
959 };
960
961 nacl.secretbox = function(msg, nonce, key) {
962   checkArrayTypes(msg, nonce, key);
963   checkLengths(key, nonce);
964   var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
965   var c = new Uint8Array(m.length);
966   for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i];
967   crypto_secretbox(c, m, m.length, nonce, key);
968   return c.subarray(crypto_secretbox_BOXZEROBYTES);
969 };
970
971 nacl.secretbox.open = function(box, nonce, key) {
972   checkArrayTypes(box, nonce, key);
973   checkLengths(key, nonce);
974   var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
975   var m = new Uint8Array(c.length);
976   for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i];
977   if (c.length < 32) return false;
978   if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false;
979   return m.subarray(crypto_secretbox_ZEROBYTES);
980 };
981
982 nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES;
983 nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;
984 nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;
985
986 nacl.scalarMult = function(n, p) {
987   checkArrayTypes(n, p);
988   if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
989   if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');
990   var q = new Uint8Array(crypto_scalarmult_BYTES);
991   crypto_scalarmult(q, n, p);
992   return q;
993 };
994
995 nacl.scalarMult.base = function(n) {
996   checkArrayTypes(n);
997   if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
998   var q = new Uint8Array(crypto_scalarmult_BYTES);
999   crypto_scalarmult_base(q, n);
1000   return q;
1001 };
1002
1003 nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;
1004 nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES;
1005
1006 nacl.box = function(msg, nonce, publicKey, secretKey) {
1007   var k = nacl.box.before(publicKey, secretKey);
1008   return nacl.secretbox(msg, nonce, k);
1009 };
1010
1011 nacl.box.before = function(publicKey, secretKey) {
1012   checkArrayTypes(publicKey, secretKey);
1013   checkBoxLengths(publicKey, secretKey);
1014   var k = new Uint8Array(crypto_box_BEFORENMBYTES);
1015   crypto_box_beforenm(k, publicKey, secretKey);
1016   return k;
1017 };
1018
1019 nacl.box.after = nacl.secretbox;
1020
1021 nacl.box.open = function(msg, nonce, publicKey, secretKey) {
1022   var k = nacl.box.before(publicKey, secretKey);
1023   return nacl.secretbox.open(msg, nonce, k);
1024 };
1025
1026 nacl.box.open.after = nacl.secretbox.open;
1027
1028 nacl.box.keyPair = function() {
1029   var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
1030   var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
1031   crypto_box_keypair(pk, sk);
1032   return {publicKey: pk, secretKey: sk};
1033 };
1034
1035 nacl.box.keyPair.fromSecretKey = function(secretKey) {
1036   checkArrayTypes(secretKey);
1037   if (secretKey.length !== crypto_box_SECRETKEYBYTES)
1038     throw new Error('bad secret key size');
1039   var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
1040   crypto_scalarmult_base(pk, secretKey);
1041   return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
1042 };
1043
1044 nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES;
1045 nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES;
1046 nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES;
1047 nacl.box.nonceLength = crypto_box_NONCEBYTES;
1048 nacl.box.overheadLength = nacl.secretbox.overheadLength;
1049
1050 nacl.sign = function(msg, secretKey) {
1051   checkArrayTypes(msg, secretKey);
1052   if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
1053     throw new Error('bad secret key size');
1054   var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length);
1055   crypto_sign(signedMsg, msg, msg.length, secretKey);
1056   return signedMsg;
1057 };
1058
1059 nacl.sign.open = function(signedMsg, publicKey) {
1060   if (arguments.length !== 2)
1061     throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?');
1062   checkArrayTypes(signedMsg, publicKey);
1063   if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
1064     throw new Error('bad public key size');
1065   var tmp = new Uint8Array(signedMsg.length);
1066   var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
1067   if (mlen < 0) return null;
1068   var m = new Uint8Array(mlen);
1069   for (var i = 0; i < m.length; i++) m[i] = tmp[i];
1070   return m;
1071 };
1072
1073 nacl.sign.detached = function(msg, secretKey) {
1074   var signedMsg = nacl.sign(msg, secretKey);
1075   var sig = new Uint8Array(crypto_sign_BYTES);
1076   for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
1077   return sig;
1078 };
1079
1080 nacl.sign.detached.verify = function(msg, sig, publicKey) {
1081   checkArrayTypes(msg, sig, publicKey);
1082   if (sig.length !== crypto_sign_BYTES)
1083     throw new Error('bad signature size');
1084   if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
1085     throw new Error('bad public key size');
1086   var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
1087   var m = new Uint8Array(crypto_sign_BYTES + msg.length);
1088   var i;
1089   for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
1090   for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];
1091   return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0);
1092 };
1093
1094 nacl.sign.keyPair = function() {
1095   var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
1096   var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
1097   crypto_sign_keypair(pk, sk);
1098   return {publicKey: pk, secretKey: sk};
1099 };
1100
1101 nacl.sign.keyPair.fromSecretKey = function(secretKey) {
1102   checkArrayTypes(secretKey);
1103   if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
1104     throw new Error('bad secret key size');
1105   var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
1106   for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i];
1107   return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
1108 };
1109
1110 nacl.sign.keyPair.fromSeed = function(seed) {
1111   checkArrayTypes(seed);
1112   if (seed.length !== crypto_sign_SEEDBYTES)
1113     throw new Error('bad seed size');
1114   var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
1115   var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
1116   for (var i = 0; i < 32; i++) sk[i] = seed[i];
1117   crypto_sign_keypair(pk, sk, true);
1118   return {publicKey: pk, secretKey: sk};
1119 };
1120
1121 nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES;
1122 nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES;
1123 nacl.sign.seedLength = crypto_sign_SEEDBYTES;
1124 nacl.sign.signatureLength = crypto_sign_BYTES;
1125
1126 nacl.hash = function(msg) {
1127   checkArrayTypes(msg);
1128   var h = new Uint8Array(crypto_hash_BYTES);
1129   crypto_hash(h, msg, msg.length);
1130   return h;
1131 };
1132
1133 nacl.hash.hashLength = crypto_hash_BYTES;
1134
1135 nacl.verify = function(x, y) {
1136   checkArrayTypes(x, y);
1137   // Zero length arguments are considered not equal.
1138   if (x.length === 0 || y.length === 0) return false;
1139   if (x.length !== y.length) return false;
1140   return (vn(x, 0, y, 0, x.length) === 0) ? true : false;
1141 };
1142
1143 nacl.setPRNG = function(fn) {
1144   randombytes = fn;
1145 };
1146
1147 (function() {
1148   // Initialize PRNG if environment provides CSPRNG.
1149   // If not, methods calling randombytes will throw.
1150   var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null;
1151   if (crypto && crypto.getRandomValues) {
1152     // Browsers.
1153     var QUOTA = 65536;
1154     nacl.setPRNG(function(x, n) {
1155       var i, v = new Uint8Array(n);
1156       for (i = 0; i < n; i += QUOTA) {
1157         crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
1158       }
1159       for (i = 0; i < n; i++) x[i] = v[i];
1160       cleanup(v);
1161     });
1162   } else if (typeof require !== 'undefined') {
1163     // Node.js.
1164     crypto = require('crypto');
1165     if (crypto && crypto.randomBytes) {
1166       nacl.setPRNG(function(x, n) {
1167         var i, v = crypto.randomBytes(n);
1168         for (i = 0; i < n; i++) x[i] = v[i];
1169         cleanup(v);
1170       });
1171     }
1172   }
1173 })();
1174
1175 })(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {}));