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/README.md +63 -0
- package/dist/salty-crypto.js +1 -0
- package/package.json +39 -0
- package/rollup.config.js +9 -0
- package/src/aead.ts +86 -0
- package/src/blake2.ts +135 -0
- package/src/chacha20.ts +72 -0
- package/src/index.ts +12 -0
- package/src/noise.ts +368 -0
- package/src/patterns.ts +59 -0
- package/src/poly1305.ts +369 -0
- package/src/profiles.ts +65 -0
- package/src/random.ts +36 -0
- package/src/x25519.ts +596 -0
- package/test/harness.ts +73 -0
- package/test/tests/aead.test.ts +49 -0
- package/test/tests/blake2.test.ts +41 -0
- package/test/tests/chacha20.test.ts +81 -0
- package/test/tests/noise.test.ts +144 -0
- package/test/tests/poly1305.test.ts +16 -0
- package/test-vectors/noise-c-basic.txt +19684 -0
- package/test-vectors/snow.txt +10348 -0
- package/tsconfig.json +18 -0
package/src/poly1305.ts
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/// SPDX-License-Identifier: MIT
|
|
2
|
+
/// SPDX-FileCopyrightText: Copyright © 2023 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
|
3
|
+
|
|
4
|
+
// TypeScript port of the "poly1305" class from nacl-fast.js from tweetnacl.
|
|
5
|
+
//
|
|
6
|
+
// The comment attached to the class in that file reads as follows:
|
|
7
|
+
// /*
|
|
8
|
+
// * Port of Andrew Moon's Poly1305-donna-16. Public domain.
|
|
9
|
+
// * https://github.com/floodyberry/poly1305-donna
|
|
10
|
+
// */
|
|
11
|
+
|
|
12
|
+
export class Poly1305 {
|
|
13
|
+
static readonly KEYBYTES = 32;
|
|
14
|
+
static readonly TAGBYTES = 16;
|
|
15
|
+
static readonly BLOCKBYTES = 16;
|
|
16
|
+
|
|
17
|
+
buffer = new Uint8Array(16);
|
|
18
|
+
r = new Uint16Array(10);
|
|
19
|
+
h = new Uint16Array(10);
|
|
20
|
+
pad = new Uint16Array(8);
|
|
21
|
+
leftover = 0;
|
|
22
|
+
fin = 0;
|
|
23
|
+
|
|
24
|
+
static digest(key: Uint8Array, input: Uint8Array): Uint8Array {
|
|
25
|
+
const p = new Poly1305(key);
|
|
26
|
+
p.update(input, 0, input.byteLength);
|
|
27
|
+
const output = new Uint8Array(Poly1305.TAGBYTES);
|
|
28
|
+
p.finish(output, 0);
|
|
29
|
+
return output;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
constructor(public key: Uint8Array) {
|
|
33
|
+
const t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff;
|
|
34
|
+
const t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
|
|
35
|
+
const t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
|
|
36
|
+
const t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
|
|
37
|
+
const t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
|
|
38
|
+
this.r[5] = ((t4 >>> 1)) & 0x1ffe;
|
|
39
|
+
const t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
|
|
40
|
+
const t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
|
|
41
|
+
const t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
|
|
42
|
+
this.r[9] = ((t7 >>> 5)) & 0x007f;
|
|
43
|
+
|
|
44
|
+
this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8;
|
|
45
|
+
this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8;
|
|
46
|
+
this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8;
|
|
47
|
+
this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8;
|
|
48
|
+
this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8;
|
|
49
|
+
this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8;
|
|
50
|
+
this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8;
|
|
51
|
+
this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
blocks(m: Uint8Array, mpos: number, bytes: number) {
|
|
55
|
+
const hibit = this.fin ? 0 : (1 << 11);
|
|
56
|
+
|
|
57
|
+
let h0 = this.h[0];
|
|
58
|
+
let h1 = this.h[1];
|
|
59
|
+
let h2 = this.h[2];
|
|
60
|
+
let h3 = this.h[3];
|
|
61
|
+
let h4 = this.h[4];
|
|
62
|
+
let h5 = this.h[5];
|
|
63
|
+
let h6 = this.h[6];
|
|
64
|
+
let h7 = this.h[7];
|
|
65
|
+
let h8 = this.h[8];
|
|
66
|
+
let h9 = this.h[9];
|
|
67
|
+
|
|
68
|
+
let r0 = this.r[0];
|
|
69
|
+
let r1 = this.r[1];
|
|
70
|
+
let r2 = this.r[2];
|
|
71
|
+
let r3 = this.r[3];
|
|
72
|
+
let r4 = this.r[4];
|
|
73
|
+
let r5 = this.r[5];
|
|
74
|
+
let r6 = this.r[6];
|
|
75
|
+
let r7 = this.r[7];
|
|
76
|
+
let r8 = this.r[8];
|
|
77
|
+
let r9 = this.r[9];
|
|
78
|
+
|
|
79
|
+
while (bytes >= 16) {
|
|
80
|
+
const t0 = m[mpos + 0] & 0xff | (m[mpos + 1] & 0xff) << 8; h0 += (t0) & 0x1fff;
|
|
81
|
+
const t1 = m[mpos + 2] & 0xff | (m[mpos + 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
|
|
82
|
+
const t2 = m[mpos + 4] & 0xff | (m[mpos + 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff;
|
|
83
|
+
const t3 = m[mpos + 6] & 0xff | (m[mpos + 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
|
|
84
|
+
const t4 = m[mpos + 8] & 0xff | (m[mpos + 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff;
|
|
85
|
+
h5 += ((t4 >>> 1)) & 0x1fff;
|
|
86
|
+
const t5 = m[mpos + 10] & 0xff | (m[mpos + 11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
|
|
87
|
+
const t6 = m[mpos + 12] & 0xff | (m[mpos + 13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff;
|
|
88
|
+
const t7 = m[mpos + 14] & 0xff | (m[mpos + 15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
|
|
89
|
+
h9 += ((t7 >>> 5)) | hibit;
|
|
90
|
+
|
|
91
|
+
let c = 0;
|
|
92
|
+
|
|
93
|
+
let d0 = c;
|
|
94
|
+
d0 += h0 * r0;
|
|
95
|
+
d0 += h1 * (5 * r9);
|
|
96
|
+
d0 += h2 * (5 * r8);
|
|
97
|
+
d0 += h3 * (5 * r7);
|
|
98
|
+
d0 += h4 * (5 * r6);
|
|
99
|
+
c = (d0 >>> 13); d0 &= 0x1fff;
|
|
100
|
+
d0 += h5 * (5 * r5);
|
|
101
|
+
d0 += h6 * (5 * r4);
|
|
102
|
+
d0 += h7 * (5 * r3);
|
|
103
|
+
d0 += h8 * (5 * r2);
|
|
104
|
+
d0 += h9 * (5 * r1);
|
|
105
|
+
c += (d0 >>> 13); d0 &= 0x1fff;
|
|
106
|
+
|
|
107
|
+
let d1 = c;
|
|
108
|
+
d1 += h0 * r1;
|
|
109
|
+
d1 += h1 * r0;
|
|
110
|
+
d1 += h2 * (5 * r9);
|
|
111
|
+
d1 += h3 * (5 * r8);
|
|
112
|
+
d1 += h4 * (5 * r7);
|
|
113
|
+
c = (d1 >>> 13); d1 &= 0x1fff;
|
|
114
|
+
d1 += h5 * (5 * r6);
|
|
115
|
+
d1 += h6 * (5 * r5);
|
|
116
|
+
d1 += h7 * (5 * r4);
|
|
117
|
+
d1 += h8 * (5 * r3);
|
|
118
|
+
d1 += h9 * (5 * r2);
|
|
119
|
+
c += (d1 >>> 13); d1 &= 0x1fff;
|
|
120
|
+
|
|
121
|
+
let d2 = c;
|
|
122
|
+
d2 += h0 * r2;
|
|
123
|
+
d2 += h1 * r1;
|
|
124
|
+
d2 += h2 * r0;
|
|
125
|
+
d2 += h3 * (5 * r9);
|
|
126
|
+
d2 += h4 * (5 * r8);
|
|
127
|
+
c = (d2 >>> 13); d2 &= 0x1fff;
|
|
128
|
+
d2 += h5 * (5 * r7);
|
|
129
|
+
d2 += h6 * (5 * r6);
|
|
130
|
+
d2 += h7 * (5 * r5);
|
|
131
|
+
d2 += h8 * (5 * r4);
|
|
132
|
+
d2 += h9 * (5 * r3);
|
|
133
|
+
c += (d2 >>> 13); d2 &= 0x1fff;
|
|
134
|
+
|
|
135
|
+
let d3 = c;
|
|
136
|
+
d3 += h0 * r3;
|
|
137
|
+
d3 += h1 * r2;
|
|
138
|
+
d3 += h2 * r1;
|
|
139
|
+
d3 += h3 * r0;
|
|
140
|
+
d3 += h4 * (5 * r9);
|
|
141
|
+
c = (d3 >>> 13); d3 &= 0x1fff;
|
|
142
|
+
d3 += h5 * (5 * r8);
|
|
143
|
+
d3 += h6 * (5 * r7);
|
|
144
|
+
d3 += h7 * (5 * r6);
|
|
145
|
+
d3 += h8 * (5 * r5);
|
|
146
|
+
d3 += h9 * (5 * r4);
|
|
147
|
+
c += (d3 >>> 13); d3 &= 0x1fff;
|
|
148
|
+
|
|
149
|
+
let d4 = c;
|
|
150
|
+
d4 += h0 * r4;
|
|
151
|
+
d4 += h1 * r3;
|
|
152
|
+
d4 += h2 * r2;
|
|
153
|
+
d4 += h3 * r1;
|
|
154
|
+
d4 += h4 * r0;
|
|
155
|
+
c = (d4 >>> 13); d4 &= 0x1fff;
|
|
156
|
+
d4 += h5 * (5 * r9);
|
|
157
|
+
d4 += h6 * (5 * r8);
|
|
158
|
+
d4 += h7 * (5 * r7);
|
|
159
|
+
d4 += h8 * (5 * r6);
|
|
160
|
+
d4 += h9 * (5 * r5);
|
|
161
|
+
c += (d4 >>> 13); d4 &= 0x1fff;
|
|
162
|
+
|
|
163
|
+
let d5 = c;
|
|
164
|
+
d5 += h0 * r5;
|
|
165
|
+
d5 += h1 * r4;
|
|
166
|
+
d5 += h2 * r3;
|
|
167
|
+
d5 += h3 * r2;
|
|
168
|
+
d5 += h4 * r1;
|
|
169
|
+
c = (d5 >>> 13); d5 &= 0x1fff;
|
|
170
|
+
d5 += h5 * r0;
|
|
171
|
+
d5 += h6 * (5 * r9);
|
|
172
|
+
d5 += h7 * (5 * r8);
|
|
173
|
+
d5 += h8 * (5 * r7);
|
|
174
|
+
d5 += h9 * (5 * r6);
|
|
175
|
+
c += (d5 >>> 13); d5 &= 0x1fff;
|
|
176
|
+
|
|
177
|
+
let d6 = c;
|
|
178
|
+
d6 += h0 * r6;
|
|
179
|
+
d6 += h1 * r5;
|
|
180
|
+
d6 += h2 * r4;
|
|
181
|
+
d6 += h3 * r3;
|
|
182
|
+
d6 += h4 * r2;
|
|
183
|
+
c = (d6 >>> 13); d6 &= 0x1fff;
|
|
184
|
+
d6 += h5 * r1;
|
|
185
|
+
d6 += h6 * r0;
|
|
186
|
+
d6 += h7 * (5 * r9);
|
|
187
|
+
d6 += h8 * (5 * r8);
|
|
188
|
+
d6 += h9 * (5 * r7);
|
|
189
|
+
c += (d6 >>> 13); d6 &= 0x1fff;
|
|
190
|
+
|
|
191
|
+
let d7 = c;
|
|
192
|
+
d7 += h0 * r7;
|
|
193
|
+
d7 += h1 * r6;
|
|
194
|
+
d7 += h2 * r5;
|
|
195
|
+
d7 += h3 * r4;
|
|
196
|
+
d7 += h4 * r3;
|
|
197
|
+
c = (d7 >>> 13); d7 &= 0x1fff;
|
|
198
|
+
d7 += h5 * r2;
|
|
199
|
+
d7 += h6 * r1;
|
|
200
|
+
d7 += h7 * r0;
|
|
201
|
+
d7 += h8 * (5 * r9);
|
|
202
|
+
d7 += h9 * (5 * r8);
|
|
203
|
+
c += (d7 >>> 13); d7 &= 0x1fff;
|
|
204
|
+
|
|
205
|
+
let d8 = c;
|
|
206
|
+
d8 += h0 * r8;
|
|
207
|
+
d8 += h1 * r7;
|
|
208
|
+
d8 += h2 * r6;
|
|
209
|
+
d8 += h3 * r5;
|
|
210
|
+
d8 += h4 * r4;
|
|
211
|
+
c = (d8 >>> 13); d8 &= 0x1fff;
|
|
212
|
+
d8 += h5 * r3;
|
|
213
|
+
d8 += h6 * r2;
|
|
214
|
+
d8 += h7 * r1;
|
|
215
|
+
d8 += h8 * r0;
|
|
216
|
+
d8 += h9 * (5 * r9);
|
|
217
|
+
c += (d8 >>> 13); d8 &= 0x1fff;
|
|
218
|
+
|
|
219
|
+
let d9 = c;
|
|
220
|
+
d9 += h0 * r9;
|
|
221
|
+
d9 += h1 * r8;
|
|
222
|
+
d9 += h2 * r7;
|
|
223
|
+
d9 += h3 * r6;
|
|
224
|
+
d9 += h4 * r5;
|
|
225
|
+
c = (d9 >>> 13); d9 &= 0x1fff;
|
|
226
|
+
d9 += h5 * r4;
|
|
227
|
+
d9 += h6 * r3;
|
|
228
|
+
d9 += h7 * r2;
|
|
229
|
+
d9 += h8 * r1;
|
|
230
|
+
d9 += h9 * r0;
|
|
231
|
+
c += (d9 >>> 13); d9 &= 0x1fff;
|
|
232
|
+
|
|
233
|
+
c = (((c << 2) + c)) | 0;
|
|
234
|
+
c = (c + d0) | 0;
|
|
235
|
+
d0 = c & 0x1fff;
|
|
236
|
+
c = (c >>> 13);
|
|
237
|
+
d1 += c;
|
|
238
|
+
|
|
239
|
+
h0 = d0;
|
|
240
|
+
h1 = d1;
|
|
241
|
+
h2 = d2;
|
|
242
|
+
h3 = d3;
|
|
243
|
+
h4 = d4;
|
|
244
|
+
h5 = d5;
|
|
245
|
+
h6 = d6;
|
|
246
|
+
h7 = d7;
|
|
247
|
+
h8 = d8;
|
|
248
|
+
h9 = d9;
|
|
249
|
+
|
|
250
|
+
mpos += 16;
|
|
251
|
+
bytes -= 16;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
this.h[0] = h0;
|
|
255
|
+
this.h[1] = h1;
|
|
256
|
+
this.h[2] = h2;
|
|
257
|
+
this.h[3] = h3;
|
|
258
|
+
this.h[4] = h4;
|
|
259
|
+
this.h[5] = h5;
|
|
260
|
+
this.h[6] = h6;
|
|
261
|
+
this.h[7] = h7;
|
|
262
|
+
this.h[8] = h8;
|
|
263
|
+
this.h[9] = h9;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
finish(mac: Uint8Array, macpos: number) {
|
|
267
|
+
if (this.leftover) {
|
|
268
|
+
let i = this.leftover;
|
|
269
|
+
this.buffer[i++] = 1;
|
|
270
|
+
for (; i < 16; i++) this.buffer[i] = 0;
|
|
271
|
+
this.fin = 1;
|
|
272
|
+
this.blocks(this.buffer, 0, 16);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
let c = this.h[1] >>> 13;
|
|
276
|
+
this.h[1] &= 0x1fff;
|
|
277
|
+
for (let i = 2; i < 10; i++) {
|
|
278
|
+
this.h[i] += c;
|
|
279
|
+
c = this.h[i] >>> 13;
|
|
280
|
+
this.h[i] &= 0x1fff;
|
|
281
|
+
}
|
|
282
|
+
this.h[0] += (c * 5);
|
|
283
|
+
c = this.h[0] >>> 13;
|
|
284
|
+
this.h[0] &= 0x1fff;
|
|
285
|
+
this.h[1] += c;
|
|
286
|
+
c = this.h[1] >>> 13;
|
|
287
|
+
this.h[1] &= 0x1fff;
|
|
288
|
+
this.h[2] += c;
|
|
289
|
+
|
|
290
|
+
const g = new Uint16Array(10);
|
|
291
|
+
g[0] = this.h[0] + 5;
|
|
292
|
+
c = g[0] >>> 13;
|
|
293
|
+
g[0] &= 0x1fff;
|
|
294
|
+
for (let i = 1; i < 10; i++) {
|
|
295
|
+
g[i] = this.h[i] + c;
|
|
296
|
+
c = g[i] >>> 13;
|
|
297
|
+
g[i] &= 0x1fff;
|
|
298
|
+
}
|
|
299
|
+
g[9] -= (1 << 13);
|
|
300
|
+
|
|
301
|
+
let mask = (c ^ 1) - 1;
|
|
302
|
+
for (let i = 0; i < 10; i++) g[i] &= mask;
|
|
303
|
+
mask = ~mask;
|
|
304
|
+
for (let i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i];
|
|
305
|
+
|
|
306
|
+
this.h[0] = ((this.h[0]) | (this.h[1] << 13)) & 0xffff;
|
|
307
|
+
this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10)) & 0xffff;
|
|
308
|
+
this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7)) & 0xffff;
|
|
309
|
+
this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4)) & 0xffff;
|
|
310
|
+
this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff;
|
|
311
|
+
this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11)) & 0xffff;
|
|
312
|
+
this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8)) & 0xffff;
|
|
313
|
+
this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5)) & 0xffff;
|
|
314
|
+
|
|
315
|
+
let f = this.h[0] + this.pad[0];
|
|
316
|
+
this.h[0] = f & 0xffff;
|
|
317
|
+
for (let i = 1; i < 8; i++) {
|
|
318
|
+
f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0;
|
|
319
|
+
this.h[i] = f & 0xffff;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
mac[macpos + 0] = (this.h[0] >>> 0) & 0xff;
|
|
323
|
+
mac[macpos + 1] = (this.h[0] >>> 8) & 0xff;
|
|
324
|
+
mac[macpos + 2] = (this.h[1] >>> 0) & 0xff;
|
|
325
|
+
mac[macpos + 3] = (this.h[1] >>> 8) & 0xff;
|
|
326
|
+
mac[macpos + 4] = (this.h[2] >>> 0) & 0xff;
|
|
327
|
+
mac[macpos + 5] = (this.h[2] >>> 8) & 0xff;
|
|
328
|
+
mac[macpos + 6] = (this.h[3] >>> 0) & 0xff;
|
|
329
|
+
mac[macpos + 7] = (this.h[3] >>> 8) & 0xff;
|
|
330
|
+
mac[macpos + 8] = (this.h[4] >>> 0) & 0xff;
|
|
331
|
+
mac[macpos + 9] = (this.h[4] >>> 8) & 0xff;
|
|
332
|
+
mac[macpos + 10] = (this.h[5] >>> 0) & 0xff;
|
|
333
|
+
mac[macpos + 11] = (this.h[5] >>> 8) & 0xff;
|
|
334
|
+
mac[macpos + 12] = (this.h[6] >>> 0) & 0xff;
|
|
335
|
+
mac[macpos + 13] = (this.h[6] >>> 8) & 0xff;
|
|
336
|
+
mac[macpos + 14] = (this.h[7] >>> 0) & 0xff;
|
|
337
|
+
mac[macpos + 15] = (this.h[7] >>> 8) & 0xff;
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
update(m: Uint8Array, mpos: number, bytes: number) {
|
|
341
|
+
if (this.leftover) {
|
|
342
|
+
let want = (16 - this.leftover);
|
|
343
|
+
if (want > bytes)
|
|
344
|
+
want = bytes;
|
|
345
|
+
for (let i = 0; i < want; i++)
|
|
346
|
+
this.buffer[this.leftover + i] = m[mpos + i];
|
|
347
|
+
bytes -= want;
|
|
348
|
+
mpos += want;
|
|
349
|
+
this.leftover += want;
|
|
350
|
+
if (this.leftover < 16)
|
|
351
|
+
return;
|
|
352
|
+
this.blocks(this.buffer, 0, 16);
|
|
353
|
+
this.leftover = 0;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (bytes >= 16) {
|
|
357
|
+
const want = bytes - (bytes % 16);
|
|
358
|
+
this.blocks(m, mpos, want);
|
|
359
|
+
mpos += want;
|
|
360
|
+
bytes -= want;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (bytes) {
|
|
364
|
+
for (let i = 0; i < bytes; i++)
|
|
365
|
+
this.buffer[this.leftover + i] = m[mpos + i];
|
|
366
|
+
this.leftover += bytes;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
package/src/profiles.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/// SPDX-License-Identifier: MIT
|
|
2
|
+
/// SPDX-FileCopyrightText: Copyright © 2023 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
|
3
|
+
|
|
4
|
+
import { BLAKE2s } from './blake2';
|
|
5
|
+
import { AEAD_CHACHA20_POLY1305_NONCEBYTES, AEAD_CHACHA20_POLY1305_TAGBYTES, aead_decrypt_detached, aead_encrypt_detached } from './aead';
|
|
6
|
+
import { DHKeyPair, NoiseProtocolAlgorithms, Nonce } from './noise';
|
|
7
|
+
import { randomBytes } from './random';
|
|
8
|
+
import { scalarMult, scalarMultBase } from './x25519';
|
|
9
|
+
|
|
10
|
+
export class Noise_25519_ChaChaPoly_BLAKE2s extends NoiseProtocolAlgorithms {
|
|
11
|
+
constructor () {
|
|
12
|
+
super();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
dhName(): string {
|
|
16
|
+
return '25519';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
generateKeypair(): DHKeyPair {
|
|
20
|
+
const sk = randomBytes(scalarMult.scalarLength);
|
|
21
|
+
const pk = scalarMultBase(sk);
|
|
22
|
+
return { public: pk, secret: sk };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
dh(kp: DHKeyPair, pk: Uint8Array): Uint8Array {
|
|
26
|
+
return scalarMult(kp.secret, pk);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
cipherName(): string {
|
|
30
|
+
return 'ChaChaPoly';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
encrypt(key: DataView, nonce: Nonce, p: Uint8Array, associated_data?: Uint8Array): Uint8Array {
|
|
34
|
+
const c = new Uint8Array(p.byteLength + AEAD_CHACHA20_POLY1305_TAGBYTES);
|
|
35
|
+
aead_encrypt_detached(p, c, p.byteLength, c.subarray(p.byteLength), key, serializeNonce(nonce), associated_data);
|
|
36
|
+
return c;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
decrypt(key: DataView, nonce: Nonce, c: Uint8Array, associated_data?: Uint8Array): Uint8Array {
|
|
40
|
+
const p = new Uint8Array(c.byteLength - AEAD_CHACHA20_POLY1305_TAGBYTES);
|
|
41
|
+
if (!aead_decrypt_detached(p, c, p.byteLength, c.subarray(p.byteLength), key, serializeNonce(nonce), associated_data)) {
|
|
42
|
+
throw new Error("packet decryption failed");
|
|
43
|
+
}
|
|
44
|
+
return p;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
hashName(): string {
|
|
48
|
+
return "BLAKE2s";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
hash(data: Uint8Array): Uint8Array {
|
|
52
|
+
return BLAKE2s.digest(data);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
hashBlocklen(): number {
|
|
56
|
+
return BLAKE2s.BLOCKLEN;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function serializeNonce(n: Nonce): DataView {
|
|
61
|
+
const view = new DataView(new ArrayBuffer(AEAD_CHACHA20_POLY1305_NONCEBYTES));
|
|
62
|
+
view.setUint32(4, n.lo, true);
|
|
63
|
+
view.setUint32(8, n.hi, true);
|
|
64
|
+
return view;
|
|
65
|
+
}
|
package/src/random.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/// SPDX-License-Identifier: MIT
|
|
2
|
+
/// SPDX-FileCopyrightText: Copyright © 2023 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
|
3
|
+
|
|
4
|
+
// TypeScript port of the randomness-generation 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 _randomBytes: (out: Uint8Array, n: number) => void = (() => {
|
|
15
|
+
var crypto: any = typeof self !== 'undefined' ? (self.crypto || (self as any).msCrypto) : null;
|
|
16
|
+
if (crypto && crypto.getRandomValues) {
|
|
17
|
+
const QUOTA = 65536;
|
|
18
|
+
return (x: Uint8Array, n: number) => {
|
|
19
|
+
for (let i = 0; i < n; i += QUOTA) {
|
|
20
|
+
crypto.getRandomValues(x.subarray(i, i + Math.min(n - i, QUOTA)));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
} else if (typeof require !== 'undefined') {
|
|
24
|
+
crypto = require('crypto');
|
|
25
|
+
if (crypto && crypto.randomBytes) {
|
|
26
|
+
return (x: Uint8Array, n: number) => x.set(crypto.randomBytes(n));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
throw new Error("No usable randomness source found");
|
|
30
|
+
})();
|
|
31
|
+
|
|
32
|
+
export function randomBytes(n: number): Uint8Array {
|
|
33
|
+
const bs = new Uint8Array(n);
|
|
34
|
+
_randomBytes(bs, n);
|
|
35
|
+
return bs;
|
|
36
|
+
}
|