4 // Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
7 // Implementation derived from TweetNaCl version 20140427.
8 // See for details: http://tweetnacl.cr.yp.to/
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];
17 // Pluggable, initialized in high-level API below.
18 var randombytes = function(/* x, n */) { throw new Error('no PRNG'); };
20 var _0 = new Uint8Array(16);
21 var _9 = new Uint8Array(32); _9[0] = 9;
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]);
32 function L32(x, c) { return (x << c) | (x >>> (32 - c)); }
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);
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];
47 function st32(x, j, u) {
49 for (i = 0; i < 4; i++) { x[j+i] = u & 255; u >>>= 8; }
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;
57 x[i+4] = (u.lo >> 24) & 0xff;
58 x[i+5] = (u.lo >> 16) & 0xff;
59 x[i+6] = (u.lo >> 8) & 0xff;
63 function vn(x, xi, y, yi, n) {
65 for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i];
66 return (1 & ((d - 1) >>> 8)) - 1;
69 function crypto_verify_16(x, xi, y, yi) {
70 return vn(x,xi,y,yi,16);
73 function crypto_verify_32(x, xi, y, yi) {
74 return vn(x,xi,y,yi,32);
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);
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);
89 for (i = 0; i < 16; i++) y[i] = x[i];
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];
100 for (m = 0; m < 16; m++) x[m] = w[m];
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;
109 for (i = 0; i < 4; i++) {
110 st32(out,4*i,x[5*i]);
111 st32(out,16+4*i,x[6+i]);
114 for (i = 0; i < 16; i++) st32(out, 4 * i, (x[i] + y[i]) | 0);
118 function crypto_core_salsa20(out,inp,k,c) {
119 core(out,inp,k,c,false);
123 function crypto_core_hsalsa20(out,inp,k,c) {
124 core(out,inp,k,c,true);
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"
131 function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) {
132 var z = new Uint8Array(16), x = new Uint8Array(64);
135 for (i = 0; i < 16; i++) z[i] = 0;
136 for (i = 0; i < 8; i++) z[i] = n[i];
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];
141 for (i = 8; i < 16; i++) {
142 u = u + (z[i] & 0xff) | 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];
157 function crypto_stream_salsa20(c,cpos,d,n,k) {
158 return crypto_stream_salsa20_xor(c,cpos,null,0,d,n,k);
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);
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);
173 function add1305(h, c) {
175 for (j = 0; j < 17; j++) {
176 u = (u + ((h[j] + c[j]) | 0)) | 0;
182 var minusp = new Uint32Array([
183 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
186 function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
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];
202 for (j = 0; j < 17; j++) c[j] = 0;
203 for (j = 0; (j < 16) && (j < n); ++j) c[j] = m[mpos+j];
207 for (i = 0; i < 17; i++) {
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;
211 for (i = 0; i < 17; i++) h[i] = x[i];
213 for (j = 0; j < 16; j++) {
218 u = (u + h[16]) | 0; h[16] = u & 3;
219 u = (5 * (u >>> 2)) | 0;
220 for (j = 0; j < 16; j++) {
225 u = (u + h[16]) | 0; h[16] = u;
228 for (j = 0; j < 17; j++) g[j] = h[j];
230 s = (-(h[16] >>> 7) | 0);
231 for (j = 0; j < 17; j++) h[j] ^= s & (g[j] ^ h[j]);
233 for (j = 0; j < 16; j++) c[j] = k[j + 16];
236 for (j = 0; j < 16; j++) out[outpos+j] = h[j];
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);
246 function crypto_secretbox(c,m,d,n,k) {
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;
255 function crypto_secretbox_open(m,c,d,n,k) {
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;
266 function set25519(r, a) {
268 for (i = 0; i < 16; i++) r[i] = a[i]|0;
271 function car25519(o) {
274 for (i = 0; i < 16; i++) {
276 c = Math.floor(o[i] / 65536);
277 o[(i+1)*(i<15?1:0)] += c - 1 + 37 * (c-1) * (i===15?1:0);
282 function sel25519(p, q, b) {
284 for (var i = 0; i < 16; i++) {
285 t = c & (p[i] ^ q[i]);
291 function pack25519(o, n) {
293 var m = gf(), t = gf();
294 for (i = 0; i < 16; i++) t[i] = n[i];
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);
304 m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
309 for (i = 0; i < 16; i++) {
310 o[2*i] = t[i] & 0xff;
315 function neq25519(a, b) {
316 var c = new Uint8Array(32), d = new Uint8Array(32);
319 return crypto_verify_32(c, 0, d, 0);
322 function par25519(a) {
323 var d = new Uint8Array(32);
328 function unpack25519(o, n) {
330 for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
334 function A(o, a, b) {
336 for (i = 0; i < 16; i++) o[i] = (a[i] + b[i])|0;
339 function Z(o, a, b) {
341 for (i = 0; i < 16; i++) o[i] = (a[i] - b[i])|0;
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];
352 for (i = 0; i < 15; i++) {
353 t[i] += 38 * t[i+16];
355 for (i = 0; i < 16; i++) o[i] = t[i];
364 function inv25519(o, i) {
367 for (a = 0; a < 16; a++) c[a] = i[a];
368 for (a = 253; a >= 0; a--) {
370 if(a !== 2 && a !== 4) M(c, c, i);
372 for (a = 0; a < 16; a++) o[a] = c[a];
375 function pow2523(o, i) {
378 for (a = 0; a < 16; a++) c[a] = i[a];
379 for (a = 250; a >= 0; a--) {
381 if(a !== 1) M(c, c, i);
383 for (a = 0; a < 16; a++) o[a] = c[a];
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;
395 for (i = 0; i < 16; i++) {
400 for (i=254; i>=0; --i) {
401 r=(z[i>>>3]>>>(i&7))&1;
425 for (i = 0; i < 16; i++) {
431 var x32 = x.subarray(32);
432 var x16 = x.subarray(16);
439 function crypto_scalarmult_base(q, n) {
440 return crypto_scalarmult(q, n, _9);
443 function crypto_box_keypair(y, x) {
445 return crypto_scalarmult_base(y, x);
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);
454 var crypto_box_afternm = crypto_secretbox;
455 var crypto_box_open_afternm = crypto_secretbox_open;
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);
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);
470 var a = 0, b = 0, c = 0, d = 0, m16 = 65535, l, h, i;
471 for (i = 0; i < arguments.length; i++) {
474 a += (l & m16); b += (l >>> 16);
475 c += (h & m16); d += (h >>> 16);
482 return new u64((c & m16) | (d << 16), (a & m16) | (b << 16));
485 function shr64(x, c) {
486 return new u64((x.hi >>> c), (x.lo >>> c) | (x.hi << (32 - c)));
491 for (i = 0; i < arguments.length; i++) {
492 l ^= arguments[i].lo;
493 h ^= arguments[i].hi;
495 return new u64(h, l);
499 var h, l, c1 = 32 - c;
501 h = (x.hi >>> c) | (x.lo << c1);
502 l = (x.lo >>> c) | (x.hi << c1);
504 h = (x.lo >>> c) | (x.hi << c1);
505 l = (x.hi >>> c) | (x.lo << c1);
507 return new u64(h, l);
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);
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);
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)); }
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)
570 function crypto_hashblocks(x, m, n) {
571 var z = [], b = [], a = [], w = [], t, i, j;
573 for (i = 0; i < 8; i++) z[i] = a[i] = dl64(x, 8*i);
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];
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]));
591 for (i = 0; i < 8; i++) {
592 a[i] = add64(a[i], z[i]);
600 for (i = 0; i < 8; i++) ts64(x, 8*i, z[i]);
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
615 function crypto_hash(out, m, n) {
616 var h = new Uint8Array(64), x = new Uint8Array(256);
619 for (i = 0; i < 64; i++) h[i] = iv[i];
621 crypto_hashblocks(h, m, n);
624 for (i = 0; i < 256; i++) x[i] = 0;
625 for (i = 0; i < n; i++) x[i] = m[b-n+i];
628 n = 256-128*(n<112?1:0);
630 ts64(x, n-8, new u64((b / 0x20000000) | 0, b << 3));
631 crypto_hashblocks(h, x, n);
633 for (i = 0; i < 64; i++) out[i] = h[i];
639 var a = gf(), b = gf(), c = gf(),
640 d = gf(), e = gf(), f = gf(),
641 g = gf(), h = gf(), t = gf();
664 function cswap(p, q, b) {
666 for (i = 0; i < 4; i++) {
667 sel25519(p[i], q[i], b);
671 function pack(r, p) {
672 var tx = gf(), ty = gf(), zi = gf();
677 r[31] ^= par25519(tx) << 7;
680 function scalarmult(p, q, s) {
686 for (i = 255; i >= 0; --i) {
687 b = (s[(i/8)|0] >> (i&7)) & 1;
695 function scalarbase(p, s) {
696 var q = [gf(), gf(), gf(), gf()];
704 function crypto_sign_keypair(pk, sk, seeded) {
705 var d = new Uint8Array(64);
706 var p = [gf(), gf(), gf(), gf()];
709 if (!seeded) randombytes(sk, 32);
710 crypto_hash(d, sk, 32);
718 for (i = 0; i < 32; i++) sk[i+32] = pk[i];
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]);
724 function modL(r, x) {
726 for (i = 63; i >= 32; --i) {
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;
737 for (j = 0; j < 32; j++) {
738 x[j] += carry - (x[31] >> 4) * L[j];
742 for (j = 0; j < 32; j++) x[j] -= carry * L[j];
743 for (i = 0; i < 32; i++) {
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;
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()];
762 crypto_hash(d, sk, 32);
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];
771 crypto_hash(r, sm.subarray(32), n+32);
776 for (i = 32; i < 64; i++) sm[i] = sk[i];
777 crypto_hash(h, sm, n + 64);
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];
788 modL(sm.subarray(32), x);
792 function unpackneg(r, p) {
793 var t = gf(), chk = gf(), num = gf(),
794 den = gf(), den2 = gf(), den4 = gf(),
798 unpack25519(r[1], p);
818 if (neq25519(chk, num)) M(r[0], r[0], I);
822 if (neq25519(chk, num)) return -1;
824 if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);
830 function crypto_sign_open(m, sm, n, pk) {
832 var t = new Uint8Array(32), h = new Uint8Array(64);
833 var p = [gf(), gf(), gf(), gf()],
834 q = [gf(), gf(), gf(), gf()];
837 if (n < 64) return -1;
839 if (unpackneg(q, pk)) return -1;
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);
847 scalarbase(q, sm.subarray(32));
852 if (crypto_verify_32(sm, 0, t, 0)) {
853 for (i = 0; i < n; i++) m[i] = 0;
857 for (i = 0; i < n; i++) m[i] = sm[i + 64];
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;
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,
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
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');
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');
935 function checkArrayTypes() {
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');
943 function cleanup(arr) {
944 for (var i = 0; i < arr.length; i++) arr[i] = 0;
949 nacl.util.decodeUTF8 = function(s) {
950 var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length);
951 for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
955 nacl.util.encodeUTF8 = function(arr) {
957 for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i]));
958 return decodeURIComponent(escape(s.join('')));
961 nacl.util.encodeBase64 = function(arr) {
962 if (typeof btoa === 'undefined') {
963 return (new Buffer(arr)).toString('base64');
965 var i, s = [], len = arr.length;
966 for (i = 0; i < len; i++) s.push(String.fromCharCode(arr[i]));
967 return btoa(s.join(''));
971 nacl.util.decodeBase64 = function(s) {
972 if (typeof atob === 'undefined') {
973 return new Uint8Array(Array.prototype.slice.call(new Buffer(s, 'base64'), 0));
975 var i, d = atob(s), b = new Uint8Array(d.length);
976 for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
981 nacl.randomBytes = function(n) {
982 var b = new Uint8Array(n);
987 nacl.secretbox = function(msg, nonce, key) {
988 checkArrayTypes(msg, nonce, key);
989 checkLengths(key, nonce);
990 var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
991 var c = new Uint8Array(m.length);
992 for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i];
993 crypto_secretbox(c, m, m.length, nonce, key);
994 return c.subarray(crypto_secretbox_BOXZEROBYTES);
997 nacl.secretbox.open = function(box, nonce, key) {
998 checkArrayTypes(box, nonce, key);
999 checkLengths(key, nonce);
1000 var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
1001 var m = new Uint8Array(c.length);
1002 for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i];
1003 if (c.length < 32) return false;
1004 if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false;
1005 return m.subarray(crypto_secretbox_ZEROBYTES);
1008 nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES;
1009 nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;
1010 nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;
1012 nacl.scalarMult = function(n, p) {
1013 checkArrayTypes(n, p);
1014 if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
1015 if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');
1016 var q = new Uint8Array(crypto_scalarmult_BYTES);
1017 crypto_scalarmult(q, n, p);
1021 nacl.scalarMult.base = function(n) {
1023 if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
1024 var q = new Uint8Array(crypto_scalarmult_BYTES);
1025 crypto_scalarmult_base(q, n);
1029 nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;
1030 nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES;
1032 nacl.box = function(msg, nonce, publicKey, secretKey) {
1033 var k = nacl.box.before(publicKey, secretKey);
1034 return nacl.secretbox(msg, nonce, k);
1037 nacl.box.before = function(publicKey, secretKey) {
1038 checkArrayTypes(publicKey, secretKey);
1039 checkBoxLengths(publicKey, secretKey);
1040 var k = new Uint8Array(crypto_box_BEFORENMBYTES);
1041 crypto_box_beforenm(k, publicKey, secretKey);
1045 nacl.box.after = nacl.secretbox;
1047 nacl.box.open = function(msg, nonce, publicKey, secretKey) {
1048 var k = nacl.box.before(publicKey, secretKey);
1049 return nacl.secretbox.open(msg, nonce, k);
1052 nacl.box.open.after = nacl.secretbox.open;
1054 nacl.box.keyPair = function() {
1055 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
1056 var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
1057 crypto_box_keypair(pk, sk);
1058 return {publicKey: pk, secretKey: sk};
1061 nacl.box.keyPair.fromSecretKey = function(secretKey) {
1062 checkArrayTypes(secretKey);
1063 if (secretKey.length !== crypto_box_SECRETKEYBYTES)
1064 throw new Error('bad secret key size');
1065 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
1066 crypto_scalarmult_base(pk, secretKey);
1067 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
1070 nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES;
1071 nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES;
1072 nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES;
1073 nacl.box.nonceLength = crypto_box_NONCEBYTES;
1074 nacl.box.overheadLength = nacl.secretbox.overheadLength;
1076 nacl.sign = function(msg, secretKey) {
1077 checkArrayTypes(msg, secretKey);
1078 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
1079 throw new Error('bad secret key size');
1080 var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length);
1081 crypto_sign(signedMsg, msg, msg.length, secretKey);
1085 nacl.sign.open = function(signedMsg, publicKey) {
1086 if (arguments.length !== 2)
1087 throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?');
1088 checkArrayTypes(signedMsg, publicKey);
1089 if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
1090 throw new Error('bad public key size');
1091 var tmp = new Uint8Array(signedMsg.length);
1092 var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
1093 if (mlen < 0) return null;
1094 var m = new Uint8Array(mlen);
1095 for (var i = 0; i < m.length; i++) m[i] = tmp[i];
1099 nacl.sign.detached = function(msg, secretKey) {
1100 var signedMsg = nacl.sign(msg, secretKey);
1101 var sig = new Uint8Array(crypto_sign_BYTES);
1102 for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
1106 nacl.sign.detached.verify = function(msg, sig, publicKey) {
1107 checkArrayTypes(msg, sig, publicKey);
1108 if (sig.length !== crypto_sign_BYTES)
1109 throw new Error('bad signature size');
1110 if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
1111 throw new Error('bad public key size');
1112 var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
1113 var m = new Uint8Array(crypto_sign_BYTES + msg.length);
1115 for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
1116 for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];
1117 return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0);
1120 nacl.sign.keyPair = function() {
1121 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
1122 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
1123 crypto_sign_keypair(pk, sk);
1124 return {publicKey: pk, secretKey: sk};
1127 nacl.sign.keyPair.fromSecretKey = function(secretKey) {
1128 checkArrayTypes(secretKey);
1129 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
1130 throw new Error('bad secret key size');
1131 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
1132 for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i];
1133 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
1136 nacl.sign.keyPair.fromSeed = function(seed) {
1137 checkArrayTypes(seed);
1138 if (seed.length !== crypto_sign_SEEDBYTES)
1139 throw new Error('bad seed size');
1140 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
1141 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
1142 for (var i = 0; i < 32; i++) sk[i] = seed[i];
1143 crypto_sign_keypair(pk, sk, true);
1144 return {publicKey: pk, secretKey: sk};
1147 nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES;
1148 nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES;
1149 nacl.sign.seedLength = crypto_sign_SEEDBYTES;
1150 nacl.sign.signatureLength = crypto_sign_BYTES;
1152 nacl.hash = function(msg) {
1153 checkArrayTypes(msg);
1154 var h = new Uint8Array(crypto_hash_BYTES);
1155 crypto_hash(h, msg, msg.length);
1159 nacl.hash.hashLength = crypto_hash_BYTES;
1161 nacl.verify = function(x, y) {
1162 checkArrayTypes(x, y);
1163 // Zero length arguments are considered not equal.
1164 if (x.length === 0 || y.length === 0) return false;
1165 if (x.length !== y.length) return false;
1166 return (vn(x, 0, y, 0, x.length) === 0) ? true : false;
1169 nacl.setPRNG = function(fn) {
1174 // Initialize PRNG if environment provides CSPRNG.
1175 // If not, methods calling randombytes will throw.
1177 if (typeof window !== 'undefined') {
1179 if (window.crypto && window.crypto.getRandomValues) {
1180 crypto = window.crypto; // Standard
1181 } else if (window.msCrypto && window.msCrypto.getRandomValues) {
1182 crypto = window.msCrypto; // Internet Explorer 11+
1185 nacl.setPRNG(function(x, n) {
1186 var i, v = new Uint8Array(n);
1187 crypto.getRandomValues(v);
1188 for (i = 0; i < n; i++) x[i] = v[i];
1192 } else if (typeof require !== 'undefined') {
1194 crypto = require('crypto');
1196 nacl.setPRNG(function(x, n) {
1197 var i, v = crypto.randomBytes(n);
1198 for (i = 0; i < n; i++) x[i] = v[i];
1205 })(typeof module !== 'undefined' && module.exports ? module.exports : (window.nacl = window.nacl || {}));