UNPKG

15.9 kBJavaScriptView Raw
1/**
2 * [js-sha3]{@link https://github.com/emn178/js-sha3}
3 *
4 * @version 0.5.5
5 * @author Chen, Yi-Cyuan [emn178@gmail.com]
6 * @copyright Chen, Yi-Cyuan 2015-2016
7 * @license MIT
8 */
9(function (root) {
10 'use strict';
11
12 var NODE_JS = typeof process == 'object' && process.versions && process.versions.node;
13 if (NODE_JS) {
14 root = global;
15 }
16 var COMMON_JS = !root.JS_SHA3_TEST && typeof module == 'object' && module.exports;
17 var HEX_CHARS = '0123456789abcdef'.split('');
18 var SHAKE_PADDING = [31, 7936, 2031616, 520093696];
19 var KECCAK_PADDING = [1, 256, 65536, 16777216];
20 var PADDING = [6, 1536, 393216, 100663296];
21 var SHIFT = [0, 8, 16, 24];
22 var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649,
23 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0,
24 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771,
25 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648,
26 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648];
27 var BITS = [224, 256, 384, 512];
28 var SHAKE_BITS = [128, 256];
29 var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array'];
30
31 var createOutputMethod = function (bits, padding, outputType) {
32 return function (message) {
33 return new Keccak(bits, padding, bits).update(message)[outputType]();
34 }
35 };
36
37 var createShakeOutputMethod = function (bits, padding, outputType) {
38 return function (message, outputBits) {
39 return new Keccak(bits, padding, outputBits).update(message)[outputType]();
40 }
41 };
42
43 var createMethod = function (bits, padding) {
44 var method = createOutputMethod(bits, padding, 'hex');
45 method.create = function () {
46 return new Keccak(bits, padding, bits);
47 };
48 method.update = function (message) {
49 return method.create().update(message);
50 };
51 for (var i = 0;i < OUTPUT_TYPES.length;++i) {
52 var type = OUTPUT_TYPES[i];
53 method[type] = createOutputMethod(bits, padding, type);
54 }
55 return method;
56 };
57
58 var createShakeMethod = function (bits, padding) {
59 var method = createShakeOutputMethod(bits, padding, 'hex');
60 method.create = function (outputBits) {
61 return new Keccak(bits, padding, outputBits);
62 };
63 method.update = function (message, outputBits) {
64 return method.create(outputBits).update(message);
65 };
66 for (var i = 0;i < OUTPUT_TYPES.length;++i) {
67 var type = OUTPUT_TYPES[i];
68 method[type] = createShakeOutputMethod(bits, padding, type);
69 }
70 return method;
71 };
72
73 var algorithms = [
74 {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod},
75 {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod},
76 {name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod}
77 ];
78
79 var methods = {};
80
81 for (var i = 0;i < algorithms.length;++i) {
82 var algorithm = algorithms[i];
83 var bits = algorithm.bits;
84 for (var j = 0;j < bits.length;++j) {
85 methods[algorithm.name +'_' + bits[j]] = algorithm.createMethod(bits[j], algorithm.padding);
86 }
87 }
88
89 function Keccak(bits, padding, outputBits) {
90 this.blocks = [];
91 this.s = [];
92 this.padding = padding;
93 this.outputBits = outputBits;
94 this.reset = true;
95 this.block = 0;
96 this.start = 0;
97 this.blockCount = (1600 - (bits << 1)) >> 5;
98 this.byteCount = this.blockCount << 2;
99 this.outputBlocks = outputBits >> 5;
100 this.extraBytes = (outputBits & 31) >> 3;
101
102 for (var i = 0;i < 50;++i) {
103 this.s[i] = 0;
104 }
105 };
106
107 Keccak.prototype.update = function (message) {
108 var notString = typeof message != 'string';
109 if (notString && message.constructor == root.ArrayBuffer) {
110 message = new Uint8Array(message);
111 }
112 var length = message.length, blocks = this.blocks, byteCount = this.byteCount,
113 blockCount = this.blockCount, index = 0, s = this.s, i, code;
114
115 while (index < length) {
116 if (this.reset) {
117 this.reset = false;
118 blocks[0] = this.block;
119 for (i = 1;i < blockCount + 1;++i) {
120 blocks[i] = 0;
121 }
122 }
123 if (notString) {
124 for (i = this.start;index < length && i < byteCount;++index) {
125 blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
126 }
127 } else {
128 for (i = this.start;index < length && i < byteCount;++index) {
129 code = message.charCodeAt(index);
130 if (code < 0x80) {
131 blocks[i >> 2] |= code << SHIFT[i++ & 3];
132 } else if (code < 0x800) {
133 blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
134 blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
135 } else if (code < 0xd800 || code >= 0xe000) {
136 blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
137 blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
138 blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
139 } else {
140 code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
141 blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
142 blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
143 blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
144 blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
145 }
146 }
147 }
148 this.lastByteIndex = i;
149 if (i >= byteCount) {
150 this.start = i - byteCount;
151 this.block = blocks[blockCount];
152 for (i = 0;i < blockCount;++i) {
153 s[i] ^= blocks[i];
154 }
155 f(s);
156 this.reset = true;
157 } else {
158 this.start = i;
159 }
160 }
161 return this;
162 };
163
164 Keccak.prototype.finalize = function () {
165 var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s;
166 blocks[i >> 2] |= this.padding[i & 3];
167 if (this.lastByteIndex == this.byteCount) {
168 blocks[0] = blocks[blockCount];
169 for (i = 1;i < blockCount + 1;++i) {
170 blocks[i] = 0;
171 }
172 }
173 blocks[blockCount - 1] |= 0x80000000;
174 for (i = 0;i < blockCount;++i) {
175 s[i] ^= blocks[i];
176 }
177 f(s);
178 };
179
180 Keccak.prototype.toString = Keccak.prototype.hex = function () {
181 this.finalize();
182
183 var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
184 extraBytes = this.extraBytes, i = 0, j = 0;
185 var hex = '', block;
186 while (j < outputBlocks) {
187 for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) {
188 block = s[i];
189 hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] +
190 HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] +
191 HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] +
192 HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F];
193 }
194 if (j % blockCount == 0) {
195 f(s);
196 i = 0;
197 }
198 }
199 if (extraBytes) {
200 block = s[i];
201 if (extraBytes > 0) {
202 hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F];
203 }
204 if (extraBytes > 1) {
205 hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F];
206 }
207 if (extraBytes > 2) {
208 hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F];
209 }
210 }
211 return hex;
212 };
213
214 Keccak.prototype.arrayBuffer = function () {
215 this.finalize();
216
217 var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
218 extraBytes = this.extraBytes, i = 0, j = 0;
219 var bytes = this.outputBits >> 3;
220 var buffer;
221 if (extraBytes) {
222 buffer = new ArrayBuffer((outputBlocks + 1) << 2);
223 } else {
224 buffer = new ArrayBuffer(bytes);
225 }
226 var array = new Uint32Array(buffer);
227 while (j < outputBlocks) {
228 for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) {
229 array[j] = s[i];
230 }
231 if (j % blockCount == 0) {
232 f(s);
233 }
234 }
235 if (extraBytes) {
236 array[i] = s[i];
237 buffer = buffer.slice(0, bytes);
238 }
239 return buffer;
240 };
241
242 Keccak.prototype.buffer = Keccak.prototype.arrayBuffer;
243
244 Keccak.prototype.digest = Keccak.prototype.array = function () {
245 this.finalize();
246
247 var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
248 extraBytes = this.extraBytes, i = 0, j = 0;
249 var array = [], offset, block;
250 while (j < outputBlocks) {
251 for (i = 0;i < blockCount && j < outputBlocks;++i, ++j) {
252 offset = j << 2;
253 block = s[i];
254 array[offset] = block & 0xFF;
255 array[offset + 1] = (block >> 8) & 0xFF;
256 array[offset + 2] = (block >> 16) & 0xFF;
257 array[offset + 3] = (block >> 24) & 0xFF;
258 }
259 if (j % blockCount == 0) {
260 f(s);
261 }
262 }
263 if (extraBytes) {
264 offset = j << 2;
265 block = s[i];
266 if (extraBytes > 0) {
267 array[offset] = block & 0xFF;
268 }
269 if (extraBytes > 1) {
270 array[offset + 1] = (block >> 8) & 0xFF;
271 }
272 if (extraBytes > 2) {
273 array[offset + 2] = (block >> 16) & 0xFF;
274 }
275 }
276 return array;
277 };
278
279 var f = function (s) {
280 var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9,
281 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17,
282 b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33,
283 b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49;
284 for (n = 0;n < 48;n += 2) {
285 c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40];
286 c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41];
287 c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42];
288 c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43];
289 c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44];
290 c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45];
291 c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46];
292 c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47];
293 c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48];
294 c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49];
295
296 h = c8 ^ ((c2 << 1) | (c3 >>> 31));
297 l = c9 ^ ((c3 << 1) | (c2 >>> 31));
298 s[0] ^= h;
299 s[1] ^= l;
300 s[10] ^= h;
301 s[11] ^= l;
302 s[20] ^= h;
303 s[21] ^= l;
304 s[30] ^= h;
305 s[31] ^= l;
306 s[40] ^= h;
307 s[41] ^= l;
308 h = c0 ^ ((c4 << 1) | (c5 >>> 31));
309 l = c1 ^ ((c5 << 1) | (c4 >>> 31));
310 s[2] ^= h;
311 s[3] ^= l;
312 s[12] ^= h;
313 s[13] ^= l;
314 s[22] ^= h;
315 s[23] ^= l;
316 s[32] ^= h;
317 s[33] ^= l;
318 s[42] ^= h;
319 s[43] ^= l;
320 h = c2 ^ ((c6 << 1) | (c7 >>> 31));
321 l = c3 ^ ((c7 << 1) | (c6 >>> 31));
322 s[4] ^= h;
323 s[5] ^= l;
324 s[14] ^= h;
325 s[15] ^= l;
326 s[24] ^= h;
327 s[25] ^= l;
328 s[34] ^= h;
329 s[35] ^= l;
330 s[44] ^= h;
331 s[45] ^= l;
332 h = c4 ^ ((c8 << 1) | (c9 >>> 31));
333 l = c5 ^ ((c9 << 1) | (c8 >>> 31));
334 s[6] ^= h;
335 s[7] ^= l;
336 s[16] ^= h;
337 s[17] ^= l;
338 s[26] ^= h;
339 s[27] ^= l;
340 s[36] ^= h;
341 s[37] ^= l;
342 s[46] ^= h;
343 s[47] ^= l;
344 h = c6 ^ ((c0 << 1) | (c1 >>> 31));
345 l = c7 ^ ((c1 << 1) | (c0 >>> 31));
346 s[8] ^= h;
347 s[9] ^= l;
348 s[18] ^= h;
349 s[19] ^= l;
350 s[28] ^= h;
351 s[29] ^= l;
352 s[38] ^= h;
353 s[39] ^= l;
354 s[48] ^= h;
355 s[49] ^= l;
356
357 b0 = s[0];
358 b1 = s[1];
359 b32 = (s[11] << 4) | (s[10] >>> 28);
360 b33 = (s[10] << 4) | (s[11] >>> 28);
361 b14 = (s[20] << 3) | (s[21] >>> 29);
362 b15 = (s[21] << 3) | (s[20] >>> 29);
363 b46 = (s[31] << 9) | (s[30] >>> 23);
364 b47 = (s[30] << 9) | (s[31] >>> 23);
365 b28 = (s[40] << 18) | (s[41] >>> 14);
366 b29 = (s[41] << 18) | (s[40] >>> 14);
367 b20 = (s[2] << 1) | (s[3] >>> 31);
368 b21 = (s[3] << 1) | (s[2] >>> 31);
369 b2 = (s[13] << 12) | (s[12] >>> 20);
370 b3 = (s[12] << 12) | (s[13] >>> 20);
371 b34 = (s[22] << 10) | (s[23] >>> 22);
372 b35 = (s[23] << 10) | (s[22] >>> 22);
373 b16 = (s[33] << 13) | (s[32] >>> 19);
374 b17 = (s[32] << 13) | (s[33] >>> 19);
375 b48 = (s[42] << 2) | (s[43] >>> 30);
376 b49 = (s[43] << 2) | (s[42] >>> 30);
377 b40 = (s[5] << 30) | (s[4] >>> 2);
378 b41 = (s[4] << 30) | (s[5] >>> 2);
379 b22 = (s[14] << 6) | (s[15] >>> 26);
380 b23 = (s[15] << 6) | (s[14] >>> 26);
381 b4 = (s[25] << 11) | (s[24] >>> 21);
382 b5 = (s[24] << 11) | (s[25] >>> 21);
383 b36 = (s[34] << 15) | (s[35] >>> 17);
384 b37 = (s[35] << 15) | (s[34] >>> 17);
385 b18 = (s[45] << 29) | (s[44] >>> 3);
386 b19 = (s[44] << 29) | (s[45] >>> 3);
387 b10 = (s[6] << 28) | (s[7] >>> 4);
388 b11 = (s[7] << 28) | (s[6] >>> 4);
389 b42 = (s[17] << 23) | (s[16] >>> 9);
390 b43 = (s[16] << 23) | (s[17] >>> 9);
391 b24 = (s[26] << 25) | (s[27] >>> 7);
392 b25 = (s[27] << 25) | (s[26] >>> 7);
393 b6 = (s[36] << 21) | (s[37] >>> 11);
394 b7 = (s[37] << 21) | (s[36] >>> 11);
395 b38 = (s[47] << 24) | (s[46] >>> 8);
396 b39 = (s[46] << 24) | (s[47] >>> 8);
397 b30 = (s[8] << 27) | (s[9] >>> 5);
398 b31 = (s[9] << 27) | (s[8] >>> 5);
399 b12 = (s[18] << 20) | (s[19] >>> 12);
400 b13 = (s[19] << 20) | (s[18] >>> 12);
401 b44 = (s[29] << 7) | (s[28] >>> 25);
402 b45 = (s[28] << 7) | (s[29] >>> 25);
403 b26 = (s[38] << 8) | (s[39] >>> 24);
404 b27 = (s[39] << 8) | (s[38] >>> 24);
405 b8 = (s[48] << 14) | (s[49] >>> 18);
406 b9 = (s[49] << 14) | (s[48] >>> 18);
407
408 s[0] = b0 ^ (~b2 & b4);
409 s[1] = b1 ^ (~b3 & b5);
410 s[10] = b10 ^ (~b12 & b14);
411 s[11] = b11 ^ (~b13 & b15);
412 s[20] = b20 ^ (~b22 & b24);
413 s[21] = b21 ^ (~b23 & b25);
414 s[30] = b30 ^ (~b32 & b34);
415 s[31] = b31 ^ (~b33 & b35);
416 s[40] = b40 ^ (~b42 & b44);
417 s[41] = b41 ^ (~b43 & b45);
418 s[2] = b2 ^ (~b4 & b6);
419 s[3] = b3 ^ (~b5 & b7);
420 s[12] = b12 ^ (~b14 & b16);
421 s[13] = b13 ^ (~b15 & b17);
422 s[22] = b22 ^ (~b24 & b26);
423 s[23] = b23 ^ (~b25 & b27);
424 s[32] = b32 ^ (~b34 & b36);
425 s[33] = b33 ^ (~b35 & b37);
426 s[42] = b42 ^ (~b44 & b46);
427 s[43] = b43 ^ (~b45 & b47);
428 s[4] = b4 ^ (~b6 & b8);
429 s[5] = b5 ^ (~b7 & b9);
430 s[14] = b14 ^ (~b16 & b18);
431 s[15] = b15 ^ (~b17 & b19);
432 s[24] = b24 ^ (~b26 & b28);
433 s[25] = b25 ^ (~b27 & b29);
434 s[34] = b34 ^ (~b36 & b38);
435 s[35] = b35 ^ (~b37 & b39);
436 s[44] = b44 ^ (~b46 & b48);
437 s[45] = b45 ^ (~b47 & b49);
438 s[6] = b6 ^ (~b8 & b0);
439 s[7] = b7 ^ (~b9 & b1);
440 s[16] = b16 ^ (~b18 & b10);
441 s[17] = b17 ^ (~b19 & b11);
442 s[26] = b26 ^ (~b28 & b20);
443 s[27] = b27 ^ (~b29 & b21);
444 s[36] = b36 ^ (~b38 & b30);
445 s[37] = b37 ^ (~b39 & b31);
446 s[46] = b46 ^ (~b48 & b40);
447 s[47] = b47 ^ (~b49 & b41);
448 s[8] = b8 ^ (~b0 & b2);
449 s[9] = b9 ^ (~b1 & b3);
450 s[18] = b18 ^ (~b10 & b12);
451 s[19] = b19 ^ (~b11 & b13);
452 s[28] = b28 ^ (~b20 & b22);
453 s[29] = b29 ^ (~b21 & b23);
454 s[38] = b38 ^ (~b30 & b32);
455 s[39] = b39 ^ (~b31 & b33);
456 s[48] = b48 ^ (~b40 & b42);
457 s[49] = b49 ^ (~b41 & b43);
458
459 s[0] ^= RC[n];
460 s[1] ^= RC[n + 1];
461 }
462 }
463
464 if (COMMON_JS) {
465 module.exports = methods;
466 } else if (root) {
467 for (var key in methods) {
468 root[key] = methods[key];
469 }
470 }
471}(this));