UNPKG

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