salty-crypto 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/x25519.ts ADDED
@@ -0,0 +1,596 @@
1
+ /// SPDX-License-Identifier: MIT
2
+ /// SPDX-FileCopyrightText: Copyright © 2023 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
3
+
4
+ // TypeScript port of the X25519 code from nacl-fast.js from tweetnacl.
5
+ //
6
+ // The comment in that file reads as follows:
7
+ //
8
+ // // Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
9
+ // // Public domain.
10
+ // //
11
+ // // Implementation derived from TweetNaCl version 20140427.
12
+ // // See for details: http://tweetnacl.cr.yp.to/
13
+
14
+ export const crypto_scalarmult_BYTES = 32;
15
+ export const crypto_scalarmult_SCALARBYTES = 32;
16
+
17
+ function gf(): Float64Array {
18
+ return new Float64Array(16);
19
+ }
20
+
21
+ const _9 = new Uint8Array(32);
22
+ _9[0] = 9;
23
+
24
+ const _121665 = gf();
25
+ _121665[0] = 0xdb41;
26
+ _121665[1] = 1;
27
+
28
+ function car25519(o: Float64Array) {
29
+ let c = 1;
30
+ for (let i = 0; i < 16; i++) {
31
+ const v = o[i] + c + 65535;
32
+ c = Math.floor(v / 65536);
33
+ o[i] = v - c * 65536;
34
+ }
35
+ o[0] += c-1 + 37 * (c-1);
36
+ }
37
+
38
+ function sel25519(p: Float64Array, q: Float64Array, b: number) {
39
+ const c = ~(b-1);
40
+ for (let i = 0; i < 16; i++) {
41
+ const t = c & (p[i] ^ q[i]);
42
+ p[i] ^= t;
43
+ q[i] ^= t;
44
+ }
45
+ }
46
+
47
+ function pack25519(o: Uint8Array, n: Float64Array) {
48
+ const m = gf();
49
+ const t = gf();
50
+ for (let i = 0; i < 16; i++) t[i] = n[i];
51
+ car25519(t);
52
+ car25519(t);
53
+ car25519(t);
54
+ for (let j = 0; j < 2; j++) {
55
+ m[0] = t[0] - 0xffed;
56
+ for (let i = 1; i < 15; i++) {
57
+ m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
58
+ m[i-1] &= 0xffff;
59
+ }
60
+ m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
61
+ const b = (m[15]>>16) & 1;
62
+ m[14] &= 0xffff;
63
+ sel25519(t, m, 1-b);
64
+ }
65
+ for (let i = 0; i < 16; i++) {
66
+ o[2*i] = t[i] & 0xff;
67
+ o[2*i+1] = t[i]>>8;
68
+ }
69
+ }
70
+
71
+ function unpack25519(o: Float64Array, n: Uint8Array) {
72
+ for (let i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
73
+ o[15] &= 0x7fff;
74
+ }
75
+
76
+ function A(o: Float64Array, a: Float64Array, b: Float64Array) {
77
+ for (let i = 0; i < 16; i++) o[i] = a[i] + b[i];
78
+ }
79
+
80
+ function Z(o: Float64Array, a: Float64Array, b: Float64Array) {
81
+ for (let i = 0; i < 16; i++) o[i] = a[i] - b[i];
82
+ }
83
+
84
+ function M(o: Float64Array, a: Float64Array, b: Float64Array) {
85
+ let t0 = 0;
86
+ let t1 = 0;
87
+ let t2 = 0;
88
+ let t3 = 0;
89
+ let t4 = 0;
90
+ let t5 = 0;
91
+ let t6 = 0;
92
+ let t7 = 0;
93
+ let t8 = 0;
94
+ let t9 = 0;
95
+ let t10 = 0;
96
+ let t11 = 0;
97
+ let t12 = 0;
98
+ let t13 = 0;
99
+ let t14 = 0;
100
+ let t15 = 0;
101
+ let t16 = 0;
102
+ let t17 = 0;
103
+ let t18 = 0;
104
+ let t19 = 0;
105
+ let t20 = 0;
106
+ let t21 = 0;
107
+ let t22 = 0;
108
+ let t23 = 0;
109
+ let t24 = 0;
110
+ let t25 = 0;
111
+ let t26 = 0;
112
+ let t27 = 0;
113
+ let t28 = 0;
114
+ let t29 = 0;
115
+ let t30 = 0;
116
+
117
+ const b0 = b[0];
118
+ const b1 = b[1];
119
+ const b2 = b[2];
120
+ const b3 = b[3];
121
+ const b4 = b[4];
122
+ const b5 = b[5];
123
+ const b6 = b[6];
124
+ const b7 = b[7];
125
+ const b8 = b[8];
126
+ const b9 = b[9];
127
+ const b10 = b[10];
128
+ const b11 = b[11];
129
+ const b12 = b[12];
130
+ const b13 = b[13];
131
+ const b14 = b[14];
132
+ const b15 = b[15];
133
+
134
+ let v = a[0];
135
+ t0 += v * b0;
136
+ t1 += v * b1;
137
+ t2 += v * b2;
138
+ t3 += v * b3;
139
+ t4 += v * b4;
140
+ t5 += v * b5;
141
+ t6 += v * b6;
142
+ t7 += v * b7;
143
+ t8 += v * b8;
144
+ t9 += v * b9;
145
+ t10 += v * b10;
146
+ t11 += v * b11;
147
+ t12 += v * b12;
148
+ t13 += v * b13;
149
+ t14 += v * b14;
150
+ t15 += v * b15;
151
+
152
+ v = a[1];
153
+ t1 += v * b0;
154
+ t2 += v * b1;
155
+ t3 += v * b2;
156
+ t4 += v * b3;
157
+ t5 += v * b4;
158
+ t6 += v * b5;
159
+ t7 += v * b6;
160
+ t8 += v * b7;
161
+ t9 += v * b8;
162
+ t10 += v * b9;
163
+ t11 += v * b10;
164
+ t12 += v * b11;
165
+ t13 += v * b12;
166
+ t14 += v * b13;
167
+ t15 += v * b14;
168
+ t16 += v * b15;
169
+
170
+ v = a[2];
171
+ t2 += v * b0;
172
+ t3 += v * b1;
173
+ t4 += v * b2;
174
+ t5 += v * b3;
175
+ t6 += v * b4;
176
+ t7 += v * b5;
177
+ t8 += v * b6;
178
+ t9 += v * b7;
179
+ t10 += v * b8;
180
+ t11 += v * b9;
181
+ t12 += v * b10;
182
+ t13 += v * b11;
183
+ t14 += v * b12;
184
+ t15 += v * b13;
185
+ t16 += v * b14;
186
+ t17 += v * b15;
187
+
188
+ v = a[3];
189
+ t3 += v * b0;
190
+ t4 += v * b1;
191
+ t5 += v * b2;
192
+ t6 += v * b3;
193
+ t7 += v * b4;
194
+ t8 += v * b5;
195
+ t9 += v * b6;
196
+ t10 += v * b7;
197
+ t11 += v * b8;
198
+ t12 += v * b9;
199
+ t13 += v * b10;
200
+ t14 += v * b11;
201
+ t15 += v * b12;
202
+ t16 += v * b13;
203
+ t17 += v * b14;
204
+ t18 += v * b15;
205
+
206
+ v = a[4];
207
+ t4 += v * b0;
208
+ t5 += v * b1;
209
+ t6 += v * b2;
210
+ t7 += v * b3;
211
+ t8 += v * b4;
212
+ t9 += v * b5;
213
+ t10 += v * b6;
214
+ t11 += v * b7;
215
+ t12 += v * b8;
216
+ t13 += v * b9;
217
+ t14 += v * b10;
218
+ t15 += v * b11;
219
+ t16 += v * b12;
220
+ t17 += v * b13;
221
+ t18 += v * b14;
222
+ t19 += v * b15;
223
+
224
+ v = a[5];
225
+ t5 += v * b0;
226
+ t6 += v * b1;
227
+ t7 += v * b2;
228
+ t8 += v * b3;
229
+ t9 += v * b4;
230
+ t10 += v * b5;
231
+ t11 += v * b6;
232
+ t12 += v * b7;
233
+ t13 += v * b8;
234
+ t14 += v * b9;
235
+ t15 += v * b10;
236
+ t16 += v * b11;
237
+ t17 += v * b12;
238
+ t18 += v * b13;
239
+ t19 += v * b14;
240
+ t20 += v * b15;
241
+
242
+ v = a[6];
243
+ t6 += v * b0;
244
+ t7 += v * b1;
245
+ t8 += v * b2;
246
+ t9 += v * b3;
247
+ t10 += v * b4;
248
+ t11 += v * b5;
249
+ t12 += v * b6;
250
+ t13 += v * b7;
251
+ t14 += v * b8;
252
+ t15 += v * b9;
253
+ t16 += v * b10;
254
+ t17 += v * b11;
255
+ t18 += v * b12;
256
+ t19 += v * b13;
257
+ t20 += v * b14;
258
+ t21 += v * b15;
259
+
260
+ v = a[7];
261
+ t7 += v * b0;
262
+ t8 += v * b1;
263
+ t9 += v * b2;
264
+ t10 += v * b3;
265
+ t11 += v * b4;
266
+ t12 += v * b5;
267
+ t13 += v * b6;
268
+ t14 += v * b7;
269
+ t15 += v * b8;
270
+ t16 += v * b9;
271
+ t17 += v * b10;
272
+ t18 += v * b11;
273
+ t19 += v * b12;
274
+ t20 += v * b13;
275
+ t21 += v * b14;
276
+ t22 += v * b15;
277
+
278
+ v = a[8];
279
+ t8 += v * b0;
280
+ t9 += v * b1;
281
+ t10 += v * b2;
282
+ t11 += v * b3;
283
+ t12 += v * b4;
284
+ t13 += v * b5;
285
+ t14 += v * b6;
286
+ t15 += v * b7;
287
+ t16 += v * b8;
288
+ t17 += v * b9;
289
+ t18 += v * b10;
290
+ t19 += v * b11;
291
+ t20 += v * b12;
292
+ t21 += v * b13;
293
+ t22 += v * b14;
294
+ t23 += v * b15;
295
+
296
+ v = a[9];
297
+ t9 += v * b0;
298
+ t10 += v * b1;
299
+ t11 += v * b2;
300
+ t12 += v * b3;
301
+ t13 += v * b4;
302
+ t14 += v * b5;
303
+ t15 += v * b6;
304
+ t16 += v * b7;
305
+ t17 += v * b8;
306
+ t18 += v * b9;
307
+ t19 += v * b10;
308
+ t20 += v * b11;
309
+ t21 += v * b12;
310
+ t22 += v * b13;
311
+ t23 += v * b14;
312
+ t24 += v * b15;
313
+
314
+ v = a[10];
315
+ t10 += v * b0;
316
+ t11 += v * b1;
317
+ t12 += v * b2;
318
+ t13 += v * b3;
319
+ t14 += v * b4;
320
+ t15 += v * b5;
321
+ t16 += v * b6;
322
+ t17 += v * b7;
323
+ t18 += v * b8;
324
+ t19 += v * b9;
325
+ t20 += v * b10;
326
+ t21 += v * b11;
327
+ t22 += v * b12;
328
+ t23 += v * b13;
329
+ t24 += v * b14;
330
+ t25 += v * b15;
331
+
332
+ v = a[11];
333
+ t11 += v * b0;
334
+ t12 += v * b1;
335
+ t13 += v * b2;
336
+ t14 += v * b3;
337
+ t15 += v * b4;
338
+ t16 += v * b5;
339
+ t17 += v * b6;
340
+ t18 += v * b7;
341
+ t19 += v * b8;
342
+ t20 += v * b9;
343
+ t21 += v * b10;
344
+ t22 += v * b11;
345
+ t23 += v * b12;
346
+ t24 += v * b13;
347
+ t25 += v * b14;
348
+ t26 += v * b15;
349
+
350
+ v = a[12];
351
+ t12 += v * b0;
352
+ t13 += v * b1;
353
+ t14 += v * b2;
354
+ t15 += v * b3;
355
+ t16 += v * b4;
356
+ t17 += v * b5;
357
+ t18 += v * b6;
358
+ t19 += v * b7;
359
+ t20 += v * b8;
360
+ t21 += v * b9;
361
+ t22 += v * b10;
362
+ t23 += v * b11;
363
+ t24 += v * b12;
364
+ t25 += v * b13;
365
+ t26 += v * b14;
366
+ t27 += v * b15;
367
+
368
+ v = a[13];
369
+ t13 += v * b0;
370
+ t14 += v * b1;
371
+ t15 += v * b2;
372
+ t16 += v * b3;
373
+ t17 += v * b4;
374
+ t18 += v * b5;
375
+ t19 += v * b6;
376
+ t20 += v * b7;
377
+ t21 += v * b8;
378
+ t22 += v * b9;
379
+ t23 += v * b10;
380
+ t24 += v * b11;
381
+ t25 += v * b12;
382
+ t26 += v * b13;
383
+ t27 += v * b14;
384
+ t28 += v * b15;
385
+
386
+ v = a[14];
387
+ t14 += v * b0;
388
+ t15 += v * b1;
389
+ t16 += v * b2;
390
+ t17 += v * b3;
391
+ t18 += v * b4;
392
+ t19 += v * b5;
393
+ t20 += v * b6;
394
+ t21 += v * b7;
395
+ t22 += v * b8;
396
+ t23 += v * b9;
397
+ t24 += v * b10;
398
+ t25 += v * b11;
399
+ t26 += v * b12;
400
+ t27 += v * b13;
401
+ t28 += v * b14;
402
+ t29 += v * b15;
403
+
404
+ v = a[15];
405
+ t15 += v * b0;
406
+ t16 += v * b1;
407
+ t17 += v * b2;
408
+ t18 += v * b3;
409
+ t19 += v * b4;
410
+ t20 += v * b5;
411
+ t21 += v * b6;
412
+ t22 += v * b7;
413
+ t23 += v * b8;
414
+ t24 += v * b9;
415
+ t25 += v * b10;
416
+ t26 += v * b11;
417
+ t27 += v * b12;
418
+ t28 += v * b13;
419
+ t29 += v * b14;
420
+ t30 += v * b15;
421
+
422
+ t0 += 38 * t16;
423
+ t1 += 38 * t17;
424
+ t2 += 38 * t18;
425
+ t3 += 38 * t19;
426
+ t4 += 38 * t20;
427
+ t5 += 38 * t21;
428
+ t6 += 38 * t22;
429
+ t7 += 38 * t23;
430
+ t8 += 38 * t24;
431
+ t9 += 38 * t25;
432
+ t10 += 38 * t26;
433
+ t11 += 38 * t27;
434
+ t12 += 38 * t28;
435
+ t13 += 38 * t29;
436
+ t14 += 38 * t30;
437
+ // t15 left as is
438
+
439
+ // first car
440
+ let c = 1;
441
+ v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
442
+ v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
443
+ v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
444
+ v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
445
+ v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
446
+ v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
447
+ v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
448
+ v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
449
+ v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
450
+ v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
451
+ v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
452
+ v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
453
+ v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
454
+ v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
455
+ v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
456
+ v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
457
+ t0 += c-1 + 37 * (c-1);
458
+
459
+ // second car
460
+ c = 1;
461
+ v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
462
+ v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
463
+ v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
464
+ v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
465
+ v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
466
+ v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
467
+ v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
468
+ v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
469
+ v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
470
+ v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
471
+ v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
472
+ v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
473
+ v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
474
+ v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
475
+ v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
476
+ v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
477
+ t0 += c-1 + 37 * (c-1);
478
+
479
+ o[ 0] = t0;
480
+ o[ 1] = t1;
481
+ o[ 2] = t2;
482
+ o[ 3] = t3;
483
+ o[ 4] = t4;
484
+ o[ 5] = t5;
485
+ o[ 6] = t6;
486
+ o[ 7] = t7;
487
+ o[ 8] = t8;
488
+ o[ 9] = t9;
489
+ o[10] = t10;
490
+ o[11] = t11;
491
+ o[12] = t12;
492
+ o[13] = t13;
493
+ o[14] = t14;
494
+ o[15] = t15;
495
+ }
496
+
497
+ function S(o: Float64Array, a: Float64Array) {
498
+ M(o, a, a);
499
+ }
500
+
501
+ function inv25519(o: Float64Array, i: Float64Array) {
502
+ const c = gf();
503
+ for (let a = 0; a < 16; a++) c[a] = i[a];
504
+ for (let a = 253; a >= 0; a--) {
505
+ S(c, c);
506
+ if (a !== 2 && a !== 4) M(c, c, i);
507
+ }
508
+ for (let a = 0; a < 16; a++) o[a] = c[a];
509
+ }
510
+
511
+ export function crypto_scalarmult(q: Uint8Array, n: Uint8Array, p: Uint8Array) {
512
+ const z = new Uint8Array(32);
513
+ const x = new Float64Array(80);
514
+
515
+ const a = gf();
516
+ const b = gf();
517
+ const c = gf();
518
+ const d = gf();
519
+ const e = gf();
520
+ const f = gf();
521
+
522
+ for (let i = 0; i < 31; i++) z[i] = n[i];
523
+ z[31]=(n[31]&127)|64;
524
+ z[0]&=248;
525
+
526
+ unpack25519(x,p);
527
+
528
+ for (let i = 0; i < 16; i++) {
529
+ b[i]=x[i];
530
+ d[i]=a[i]=c[i]=0;
531
+ }
532
+ a[0]=d[0]=1;
533
+
534
+ for (let i=254; i>=0; --i) {
535
+ const r=(z[i>>>3]>>>(i&7))&1;
536
+ sel25519(a,b,r);
537
+ sel25519(c,d,r);
538
+ A(e,a,c);
539
+ Z(a,a,c);
540
+ A(c,b,d);
541
+ Z(b,b,d);
542
+ S(d,e);
543
+ S(f,a);
544
+ M(a,c,a);
545
+ M(c,b,e);
546
+ A(e,a,c);
547
+ Z(a,a,c);
548
+ S(b,a);
549
+ Z(c,d,f);
550
+ M(a,c,_121665);
551
+ A(a,a,d);
552
+ M(c,c,a);
553
+ M(a,d,f);
554
+ M(d,b,x);
555
+ S(b,e);
556
+ sel25519(a,b,r);
557
+ sel25519(c,d,r);
558
+ }
559
+
560
+ for (let i = 0; i < 16; i++) {
561
+ x[i+16]=a[i];
562
+ x[i+32]=c[i];
563
+ x[i+48]=b[i];
564
+ x[i+64]=d[i];
565
+ }
566
+
567
+ const x32 = x.subarray(32);
568
+ const x16 = x.subarray(16);
569
+ inv25519(x32,x32);
570
+ M(x16,x16,x32);
571
+ pack25519(q,x16);
572
+ }
573
+
574
+ export function crypto_scalarmult_base(q: Uint8Array, n: Uint8Array) {
575
+ crypto_scalarmult(q, n, _9);
576
+ }
577
+
578
+ /* High-level API */
579
+
580
+ export function scalarMult(n: Uint8Array, p: Uint8Array): Uint8Array {
581
+ if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
582
+ if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');
583
+ const q = new Uint8Array(crypto_scalarmult_BYTES);
584
+ crypto_scalarmult(q, n, p);
585
+ return q;
586
+ }
587
+
588
+ export function scalarMultBase(n: Uint8Array): Uint8Array {
589
+ if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
590
+ const q = new Uint8Array(crypto_scalarmult_BYTES);
591
+ crypto_scalarmult_base(q, n);
592
+ return q;
593
+ }
594
+
595
+ scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;
596
+ scalarMult.groupElementLength = crypto_scalarmult_BYTES;
@@ -0,0 +1,73 @@
1
+ export { expect } from 'expect';
2
+ import { JestAssertionError } from 'expect';
3
+ import { glob } from 'glob';
4
+ import path from 'path';
5
+
6
+ export class Stats {
7
+ total = 0;
8
+ passed = 0;
9
+ failed = 0;
10
+ errors = 0;
11
+
12
+ merge(s: Stats) {
13
+ this.total += s.total;
14
+ this.passed += s.passed;
15
+ this.failed += s.failed;
16
+ this.errors += s.errors;
17
+ }
18
+ }
19
+
20
+ export let testDepth = 0;
21
+ export let testStats = new Stats();
22
+
23
+ function indent(msg: string) {
24
+ let str = '';
25
+ for (let i = 0; i < testDepth; i++) str = str + ' ';
26
+ console.log(str + msg);
27
+ }
28
+
29
+ export async function describe(what: string, f: () => (Promise<void> | void)) {
30
+ indent('- ' + what);
31
+ testDepth++;
32
+ await f();
33
+ testDepth--;
34
+ }
35
+
36
+ export async function it(what: string, f: () => (Promise<void> | void)) {
37
+ try {
38
+ testStats.total++;
39
+ await f();
40
+ testStats.passed++;
41
+ indent('✓ ' + what);
42
+ } catch (exn) {
43
+ if (exn instanceof JestAssertionError) {
44
+ testStats.failed++;
45
+ indent('\x1b[33m✗ ' + what + '\x1b[0m')
46
+ console.error(`${'\x1b[31m'}${exn.message}${'\x1b[0m'}`);
47
+ } else {
48
+ testStats.errors++;
49
+ throw exn;
50
+ }
51
+ }
52
+ }
53
+
54
+ export async function runTests(patterns: string[]): Promise<void> {
55
+ for (const pattern of patterns) {
56
+ const files = glob.sync(pattern, { nodir: true });
57
+ for (const mod of files) {
58
+ await describe(mod, async () => {
59
+ await import(path.resolve(process.cwd(), mod));
60
+ });
61
+ }
62
+ }
63
+ }
64
+
65
+ if (Object.is(require.main, module)) {
66
+ console.time('tests');
67
+ let patterns = process.argv.slice(2);
68
+ if (patterns.length === 0) patterns = ['./lib/**/*.test.js'];
69
+ runTests(patterns).then(() => {
70
+ console.timeEnd('tests');
71
+ console.log(testStats);
72
+ });
73
+ }
@@ -0,0 +1,49 @@
1
+ import { AEAD_CHACHA20_POLY1305_TAGBYTES, aead_encrypt_detached, aead_decrypt_detached } from '../../src/aead';
2
+ import { it, expect } from '../harness';
3
+
4
+ it('section 2.8.2 from rfc 8439', () => {
5
+ const sunscreen_str = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
6
+ const sunscreen = new TextEncoder().encode(sunscreen_str);
7
+
8
+ const associated_data = new Uint8Array([
9
+ 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
10
+ 0xc4, 0xc5, 0xc6, 0xc7,
11
+ ]);
12
+
13
+ const key = new DataView(new Uint8Array([
14
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
15
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
16
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
17
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
18
+ ]).buffer);
19
+
20
+ const nonce = new DataView(new Uint8Array([
21
+ 0x07, 0x00, 0x00, 0x00,
22
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
23
+ ]).buffer);
24
+
25
+ const tag = new Uint8Array(AEAD_CHACHA20_POLY1305_TAGBYTES);
26
+ aead_encrypt_detached(sunscreen, sunscreen, sunscreen.byteLength, tag, key, nonce, associated_data);
27
+ expect(sunscreen).toEqual(new Uint8Array([
28
+ 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
29
+ 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
30
+ 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
31
+ 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
32
+ 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
33
+ 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
34
+ 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
35
+ 0x61, 0x16,
36
+ ]));
37
+ expect(tag).toEqual(new Uint8Array([
38
+ 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
39
+ 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91,
40
+ ]));
41
+
42
+ const sunscreen2 = Uint8Array.from(sunscreen);
43
+ expect(aead_decrypt_detached(sunscreen2, sunscreen2, sunscreen2.byteLength, tag, key, nonce, associated_data)).toBe(true);
44
+ expect(new TextDecoder().decode(sunscreen2)).toBe(sunscreen_str);
45
+
46
+ tag[0]++;
47
+ expect(aead_decrypt_detached(sunscreen, sunscreen, sunscreen.byteLength, tag, key, nonce, associated_data)).toBe(false);
48
+ expect(sunscreen).toEqual(new Uint8Array(sunscreen_str.length));
49
+ });