UNPKG

9.94 kBJavaScriptView Raw
1/*
2* Port of Andrew Moon's Poly1305-donna-16. Public domain.
3* https://github.com/floodyberry/poly1305-donna
4*/
5
6if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
7
8var poly1305 = function(key) {
9 this.buffer = new Uint8Array(16);
10 this.r = new Uint16Array(10);
11 this.h = new Uint16Array(10);
12 this.pad = new Uint16Array(8);
13 this.leftover = 0;
14 this.fin = 0;
15
16 var t0, t1, t2, t3, t4, t5, t6, t7;
17
18 t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff;
19 t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
20 t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
21 t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
22 t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
23 this.r[5] = ((t4 >>> 1)) & 0x1ffe;
24 t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
25 t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
26 t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
27 this.r[9] = ((t7 >>> 5)) & 0x007f;
28
29 this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8;
30 this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8;
31 this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8;
32 this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8;
33 this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8;
34 this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8;
35 this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8;
36 this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8;
37};
38
39poly1305.prototype.blocks = function(m, mpos, bytes) {
40 var hibit = this.fin ? 0 : (1 << 11);
41 var t0, t1, t2, t3, t4, t5, t6, t7, c;
42 var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;
43
44 var h0 = this.h[0],
45 h1 = this.h[1],
46 h2 = this.h[2],
47 h3 = this.h[3],
48 h4 = this.h[4],
49 h5 = this.h[5],
50 h6 = this.h[6],
51 h7 = this.h[7],
52 h8 = this.h[8],
53 h9 = this.h[9];
54
55 var r0 = this.r[0],
56 r1 = this.r[1],
57 r2 = this.r[2],
58 r3 = this.r[3],
59 r4 = this.r[4],
60 r5 = this.r[5],
61 r6 = this.r[6],
62 r7 = this.r[7],
63 r8 = this.r[8],
64 r9 = this.r[9];
65
66 while (bytes >= 16) {
67 t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff;
68 t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
69 t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff;
70 t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
71 t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff;
72 h5 += ((t4 >>> 1)) & 0x1fff;
73 t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
74 t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff;
75 t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
76 h9 += ((t7 >>> 5)) | hibit;
77
78 c = 0;
79
80 d0 = c;
81 d0 += h0 * r0;
82 d0 += h1 * (5 * r9);
83 d0 += h2 * (5 * r8);
84 d0 += h3 * (5 * r7);
85 d0 += h4 * (5 * r6);
86 c = (d0 >>> 13); d0 &= 0x1fff;
87 d0 += h5 * (5 * r5);
88 d0 += h6 * (5 * r4);
89 d0 += h7 * (5 * r3);
90 d0 += h8 * (5 * r2);
91 d0 += h9 * (5 * r1);
92 c += (d0 >>> 13); d0 &= 0x1fff;
93
94 d1 = c;
95 d1 += h0 * r1;
96 d1 += h1 * r0;
97 d1 += h2 * (5 * r9);
98 d1 += h3 * (5 * r8);
99 d1 += h4 * (5 * r7);
100 c = (d1 >>> 13); d1 &= 0x1fff;
101 d1 += h5 * (5 * r6);
102 d1 += h6 * (5 * r5);
103 d1 += h7 * (5 * r4);
104 d1 += h8 * (5 * r3);
105 d1 += h9 * (5 * r2);
106 c += (d1 >>> 13); d1 &= 0x1fff;
107
108 d2 = c;
109 d2 += h0 * r2;
110 d2 += h1 * r1;
111 d2 += h2 * r0;
112 d2 += h3 * (5 * r9);
113 d2 += h4 * (5 * r8);
114 c = (d2 >>> 13); d2 &= 0x1fff;
115 d2 += h5 * (5 * r7);
116 d2 += h6 * (5 * r6);
117 d2 += h7 * (5 * r5);
118 d2 += h8 * (5 * r4);
119 d2 += h9 * (5 * r3);
120 c += (d2 >>> 13); d2 &= 0x1fff;
121
122 d3 = c;
123 d3 += h0 * r3;
124 d3 += h1 * r2;
125 d3 += h2 * r1;
126 d3 += h3 * r0;
127 d3 += h4 * (5 * r9);
128 c = (d3 >>> 13); d3 &= 0x1fff;
129 d3 += h5 * (5 * r8);
130 d3 += h6 * (5 * r7);
131 d3 += h7 * (5 * r6);
132 d3 += h8 * (5 * r5);
133 d3 += h9 * (5 * r4);
134 c += (d3 >>> 13); d3 &= 0x1fff;
135
136 d4 = c;
137 d4 += h0 * r4;
138 d4 += h1 * r3;
139 d4 += h2 * r2;
140 d4 += h3 * r1;
141 d4 += h4 * r0;
142 c = (d4 >>> 13); d4 &= 0x1fff;
143 d4 += h5 * (5 * r9);
144 d4 += h6 * (5 * r8);
145 d4 += h7 * (5 * r7);
146 d4 += h8 * (5 * r6);
147 d4 += h9 * (5 * r5);
148 c += (d4 >>> 13); d4 &= 0x1fff;
149
150 d5 = c;
151 d5 += h0 * r5;
152 d5 += h1 * r4;
153 d5 += h2 * r3;
154 d5 += h3 * r2;
155 d5 += h4 * r1;
156 c = (d5 >>> 13); d5 &= 0x1fff;
157 d5 += h5 * r0;
158 d5 += h6 * (5 * r9);
159 d5 += h7 * (5 * r8);
160 d5 += h8 * (5 * r7);
161 d5 += h9 * (5 * r6);
162 c += (d5 >>> 13); d5 &= 0x1fff;
163
164 d6 = c;
165 d6 += h0 * r6;
166 d6 += h1 * r5;
167 d6 += h2 * r4;
168 d6 += h3 * r3;
169 d6 += h4 * r2;
170 c = (d6 >>> 13); d6 &= 0x1fff;
171 d6 += h5 * r1;
172 d6 += h6 * r0;
173 d6 += h7 * (5 * r9);
174 d6 += h8 * (5 * r8);
175 d6 += h9 * (5 * r7);
176 c += (d6 >>> 13); d6 &= 0x1fff;
177
178 d7 = c;
179 d7 += h0 * r7;
180 d7 += h1 * r6;
181 d7 += h2 * r5;
182 d7 += h3 * r4;
183 d7 += h4 * r3;
184 c = (d7 >>> 13); d7 &= 0x1fff;
185 d7 += h5 * r2;
186 d7 += h6 * r1;
187 d7 += h7 * r0;
188 d7 += h8 * (5 * r9);
189 d7 += h9 * (5 * r8);
190 c += (d7 >>> 13); d7 &= 0x1fff;
191
192 d8 = c;
193 d8 += h0 * r8;
194 d8 += h1 * r7;
195 d8 += h2 * r6;
196 d8 += h3 * r5;
197 d8 += h4 * r4;
198 c = (d8 >>> 13); d8 &= 0x1fff;
199 d8 += h5 * r3;
200 d8 += h6 * r2;
201 d8 += h7 * r1;
202 d8 += h8 * r0;
203 d8 += h9 * (5 * r9);
204 c += (d8 >>> 13); d8 &= 0x1fff;
205
206 d9 = c;
207 d9 += h0 * r9;
208 d9 += h1 * r8;
209 d9 += h2 * r7;
210 d9 += h3 * r6;
211 d9 += h4 * r5;
212 c = (d9 >>> 13); d9 &= 0x1fff;
213 d9 += h5 * r4;
214 d9 += h6 * r3;
215 d9 += h7 * r2;
216 d9 += h8 * r1;
217 d9 += h9 * r0;
218 c += (d9 >>> 13); d9 &= 0x1fff;
219
220 c = (((c << 2) + c)) | 0;
221 c = (c + d0) | 0;
222 d0 = c & 0x1fff;
223 c = (c >>> 13);
224 d1 += c;
225
226 h0 = d0;
227 h1 = d1;
228 h2 = d2;
229 h3 = d3;
230 h4 = d4;
231 h5 = d5;
232 h6 = d6;
233 h7 = d7;
234 h8 = d8;
235 h9 = d9;
236
237 mpos += 16;
238 bytes -= 16;
239 }
240 this.h[0] = h0;
241 this.h[1] = h1;
242 this.h[2] = h2;
243 this.h[3] = h3;
244 this.h[4] = h4;
245 this.h[5] = h5;
246 this.h[6] = h6;
247 this.h[7] = h7;
248 this.h[8] = h8;
249 this.h[9] = h9;
250};
251
252poly1305.prototype.finish = function(mac, macpos) {
253 var g = new Uint16Array(10);
254 var c, mask, f, i;
255
256 if (this.leftover) {
257 i = this.leftover;
258 this.buffer[i++] = 1;
259 for (; i < 16; i++) this.buffer[i] = 0;
260 this.fin = 1;
261 this.blocks(this.buffer, 0, 16);
262 }
263
264 c = this.h[1] >>> 13;
265 this.h[1] &= 0x1fff;
266 for (i = 2; i < 10; i++) {
267 this.h[i] += c;
268 c = this.h[i] >>> 13;
269 this.h[i] &= 0x1fff;
270 }
271 this.h[0] += (c * 5);
272 c = this.h[0] >>> 13;
273 this.h[0] &= 0x1fff;
274 this.h[1] += c;
275 c = this.h[1] >>> 13;
276 this.h[1] &= 0x1fff;
277 this.h[2] += c;
278
279 g[0] = this.h[0] + 5;
280 c = g[0] >>> 13;
281 g[0] &= 0x1fff;
282 for (i = 1; i < 10; i++) {
283 g[i] = this.h[i] + c;
284 c = g[i] >>> 13;
285 g[i] &= 0x1fff;
286 }
287 g[9] -= (1 << 13);
288
289 mask = (c ^ 1) - 1;
290 for (i = 0; i < 10; i++) g[i] &= mask;
291 mask = ~mask;
292 for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i];
293
294 this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff;
295 this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff;
296 this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff;
297 this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff;
298 this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff;
299 this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff;
300 this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff;
301 this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff;
302
303 f = this.h[0] + this.pad[0];
304 this.h[0] = f & 0xffff;
305 for (i = 1; i < 8; i++) {
306 f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0;
307 this.h[i] = f & 0xffff;
308 }
309
310 mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff;
311 mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff;
312 mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff;
313 mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff;
314 mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff;
315 mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff;
316 mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff;
317 mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff;
318 mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff;
319 mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff;
320 mac[macpos+10] = (this.h[5] >>> 0) & 0xff;
321 mac[macpos+11] = (this.h[5] >>> 8) & 0xff;
322 mac[macpos+12] = (this.h[6] >>> 0) & 0xff;
323 mac[macpos+13] = (this.h[6] >>> 8) & 0xff;
324 mac[macpos+14] = (this.h[7] >>> 0) & 0xff;
325 mac[macpos+15] = (this.h[7] >>> 8) & 0xff;
326};
327
328poly1305.prototype.update = function(m, mpos, bytes) {
329 var i, want;
330
331 if (this.leftover) {
332 want = (16 - this.leftover);
333 if (want > bytes)
334 want = bytes;
335 for (i = 0; i < want; i++)
336 this.buffer[this.leftover + i] = m[mpos+i];
337 bytes -= want;
338 mpos += want;
339 this.leftover += want;
340 if (this.leftover < 16)
341 return;
342 this.blocks(this.buffer, 0, 16);
343 this.leftover = 0;
344 }
345
346 if (bytes >= 16) {
347 want = bytes - (bytes % 16);
348 this.blocks(m, mpos, want);
349 mpos += want;
350 bytes -= want;
351 }
352
353 if (bytes) {
354 for (i = 0; i < bytes; i++)
355 this.buffer[this.leftover + i] = m[mpos+i];
356 this.leftover += bytes;
357 }
358};
359
360module.exports = poly1305