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;
947 // TODO: Completely remove this in v0.15.
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');
955 nacl.randomBytes = function(n) {
956 var b = new Uint8Array(n);
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);
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);
982 nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES;
983 nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;
984 nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;
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);
995 nacl.scalarMult.base = function(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);
1003 nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;
1004 nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES;
1006 nacl.box = function(msg, nonce, publicKey, secretKey) {
1007 var k = nacl.box.before(publicKey, secretKey);
1008 return nacl.secretbox(msg, nonce, k);
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);
1019 nacl.box.after = nacl.secretbox;
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);
1026 nacl.box.open.after = nacl.secretbox.open;
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};
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)};
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;
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);
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];
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];
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);
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);
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};
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)};
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};
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;
1126 nacl.hash = function(msg) {
1127 checkArrayTypes(msg);
1128 var h = new Uint8Array(crypto_hash_BYTES);
1129 crypto_hash(h, msg, msg.length);
1133 nacl.hash.hashLength = crypto_hash_BYTES;
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;
1143 nacl.setPRNG = function(fn) {
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) {
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)));
1159 for (i = 0; i < n; i++) x[i] = v[i];
1162 } else if (typeof require !== 'undefined') {
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];
1175 })(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {}));