1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
|
7 |
|
8 | var 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 |
|
39 | poly1305.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 |
|
252 | poly1305.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 |
|
328 | poly1305.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 |
|
360 | module.exports = poly1305
|