mirror of
https://github.com/emn178/js-sha3.git
synced 2026-08-12 19:41:36 +08:00
add shake algorithm
This commit is contained in:
+54
-110
@@ -17,8 +17,8 @@
|
||||
root.navigator = { userAgent: 'Chrome'};
|
||||
}
|
||||
}
|
||||
var CHROME = (root.JS_SHA3_TEST || !NODE_JS) && navigator.userAgent.indexOf('Chrome') != -1;
|
||||
var HEX_CHARS = '0123456789abcdef'.split('');
|
||||
var SHAKE_PADDING = [31, 7936, 2031616, 520093696];
|
||||
var KECCAK_PADDING = [1, 256, 65536, 16777216];
|
||||
var PADDING = [6, 1536, 393216, 100663296];
|
||||
var SHIFT = [0, 8, 16, 24];
|
||||
@@ -28,23 +28,34 @@
|
||||
2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648,
|
||||
2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648];
|
||||
var BITS = [224, 256, 384, 512];
|
||||
var ALGORITHMS = [
|
||||
{name: 'keccak', padding: KECCAK_PADDING},
|
||||
{name: 'sha3', padding: PADDING}
|
||||
];
|
||||
var OUTPUT_TYPES = ['hex', 'buffer'];
|
||||
|
||||
var blocks = [], s = [], methods = {};
|
||||
var SHAKE_BITS = [128, 256];
|
||||
var OUTPUT_TYPES = ['hex', 'buffer', 'shake'];
|
||||
|
||||
var createMethod = function(bits, padding, outputType) {
|
||||
return function(message) {
|
||||
return keccak(message, bits, padding, outputType);
|
||||
return keccak(message, bits, padding, bits, outputType);
|
||||
}
|
||||
};
|
||||
|
||||
for(var i = 0;i < ALGORITHMS.length;++i) {
|
||||
var algorithm = ALGORITHMS[i];
|
||||
for(var j = 0;j < BITS.length;++j) {
|
||||
var createShakeMethod = function(bits, padding, outputType) {
|
||||
return function(message, outputBits) {
|
||||
return keccak(message, bits, padding, outputBits, outputType);
|
||||
}
|
||||
};
|
||||
|
||||
var algorithms = [
|
||||
{name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod},
|
||||
{name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod},
|
||||
{name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod}
|
||||
];
|
||||
|
||||
var blocks = [], s = [], methods = {};
|
||||
|
||||
for(var i = 0;i < algorithms.length;++i) {
|
||||
var algorithm = algorithms[i];
|
||||
var bits = algorithm.bits;
|
||||
var createMethod = algorithm.createMethod;
|
||||
for(var j = 0;j < bits.length;++j) {
|
||||
(function(algorithm, bits) {
|
||||
var method = createMethod(bits, algorithm.padding, 'hex');
|
||||
methods[algorithm.name +'_' + bits] = method;
|
||||
@@ -52,11 +63,11 @@
|
||||
var type = OUTPUT_TYPES[k];
|
||||
method[type] = createMethod(bits, algorithm.padding, type);
|
||||
}
|
||||
})(algorithm, BITS[j]);
|
||||
})(algorithm, bits[j]);
|
||||
}
|
||||
}
|
||||
|
||||
var keccak = function(message, bits, padding, outputType) {
|
||||
var keccak = function(message, bits, padding, outputBits, outputType) {
|
||||
var notString = typeof(message) != 'string';
|
||||
if(notString && message.constructor == root.ArrayBuffer) {
|
||||
message = new Uint8Array(message);
|
||||
@@ -300,111 +311,44 @@
|
||||
}
|
||||
} while(!end);
|
||||
|
||||
var outputBlocks = parseInt(outputBits / 32);
|
||||
var extraBytes = parseInt((outputBits % 32) / 8);
|
||||
if(outputType == 'buffer') {
|
||||
var length = bits / 32;
|
||||
var buffer = new ArrayBuffer(bits / 8);
|
||||
var bytes = outputBits / 8;
|
||||
var buffer;
|
||||
if(extraBytes) {
|
||||
buffer = new ArrayBuffer((outputBlocks + 1) * 4);
|
||||
} else {
|
||||
buffer = new ArrayBuffer(bytes);
|
||||
}
|
||||
var array = new Uint32Array(buffer);
|
||||
for(var i = 0;i < length;++i) {
|
||||
for(i = 0;i < outputBlocks;++i) {
|
||||
array[i] = s[i];
|
||||
}
|
||||
if(extraBytes) {
|
||||
array[i] = s[i];
|
||||
buffer = buffer.slice(0, bytes);
|
||||
}
|
||||
return buffer;
|
||||
} else {
|
||||
var hex = '';
|
||||
if(CHROME) {
|
||||
b0 = s[0];
|
||||
b1 = s[1];
|
||||
b2 = s[2];
|
||||
b3 = s[3];
|
||||
b4 = s[4];
|
||||
b5 = s[5];
|
||||
b6 = s[6];
|
||||
b7 = s[7];
|
||||
b8 = s[8];
|
||||
b9 = s[9];
|
||||
b10 = s[10];
|
||||
b11 = s[11];
|
||||
b12 = s[12];
|
||||
b13 = s[13];
|
||||
b14 = s[14];
|
||||
b15 = s[15];
|
||||
hex += HEX_CHARS[(b0 >> 4) & 0x0F] + HEX_CHARS[b0 & 0x0F] +
|
||||
HEX_CHARS[(b0 >> 12) & 0x0F] + HEX_CHARS[(b0 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b0 >> 20) & 0x0F] + HEX_CHARS[(b0 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b0 >> 28) & 0x0F] + HEX_CHARS[(b0 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b1 >> 4) & 0x0F] + HEX_CHARS[b1 & 0x0F] +
|
||||
HEX_CHARS[(b1 >> 12) & 0x0F] + HEX_CHARS[(b1 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b1 >> 20) & 0x0F] + HEX_CHARS[(b1 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b1 >> 28) & 0x0F] + HEX_CHARS[(b1 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b2 >> 4) & 0x0F] + HEX_CHARS[b2 & 0x0F] +
|
||||
HEX_CHARS[(b2 >> 12) & 0x0F] + HEX_CHARS[(b2 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b2 >> 20) & 0x0F] + HEX_CHARS[(b2 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b2 >> 28) & 0x0F] + HEX_CHARS[(b2 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b3 >> 4) & 0x0F] + HEX_CHARS[b3 & 0x0F] +
|
||||
HEX_CHARS[(b3 >> 12) & 0x0F] + HEX_CHARS[(b3 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b3 >> 20) & 0x0F] + HEX_CHARS[(b3 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b3 >> 28) & 0x0F] + HEX_CHARS[(b3 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b4 >> 4) & 0x0F] + HEX_CHARS[b4 & 0x0F] +
|
||||
HEX_CHARS[(b4 >> 12) & 0x0F] + HEX_CHARS[(b4 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b4 >> 20) & 0x0F] + HEX_CHARS[(b4 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b4 >> 28) & 0x0F] + HEX_CHARS[(b4 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b5 >> 4) & 0x0F] + HEX_CHARS[b5 & 0x0F] +
|
||||
HEX_CHARS[(b5 >> 12) & 0x0F] + HEX_CHARS[(b5 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b5 >> 20) & 0x0F] + HEX_CHARS[(b5 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b5 >> 28) & 0x0F] + HEX_CHARS[(b5 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b6 >> 4) & 0x0F] + HEX_CHARS[b6 & 0x0F] +
|
||||
HEX_CHARS[(b6 >> 12) & 0x0F] + HEX_CHARS[(b6 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b6 >> 20) & 0x0F] + HEX_CHARS[(b6 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b6 >> 28) & 0x0F] + HEX_CHARS[(b6 >> 24) & 0x0F];
|
||||
|
||||
if(bits >= 256) {
|
||||
hex += HEX_CHARS[(b7 >> 4) & 0x0F] + HEX_CHARS[b7 & 0x0F] +
|
||||
HEX_CHARS[(b7 >> 12) & 0x0F] + HEX_CHARS[(b7 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b7 >> 20) & 0x0F] + HEX_CHARS[(b7 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b7 >> 28) & 0x0F] + HEX_CHARS[(b7 >> 24) & 0x0F];
|
||||
for(i = 0;i < outputBlocks;++i) {
|
||||
h = s[i];
|
||||
hex += HEX_CHARS[(h >> 4) & 0x0F] + HEX_CHARS[h & 0x0F] +
|
||||
HEX_CHARS[(h >> 12) & 0x0F] + HEX_CHARS[(h >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h >> 20) & 0x0F] + HEX_CHARS[(h >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h >> 28) & 0x0F] + HEX_CHARS[(h >> 24) & 0x0F];
|
||||
}
|
||||
if(extraBytes) {
|
||||
h = s[i];
|
||||
if(extraBytes > 0) {
|
||||
hex += HEX_CHARS[(h >> 4) & 0x0F] + HEX_CHARS[h & 0x0F];
|
||||
}
|
||||
if(bits >= 384) {
|
||||
hex += HEX_CHARS[(b8 >> 4) & 0x0F] + HEX_CHARS[b8 & 0x0F] +
|
||||
HEX_CHARS[(b8 >> 12) & 0x0F] + HEX_CHARS[(b8 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b8 >> 20) & 0x0F] + HEX_CHARS[(b8 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b8 >> 28) & 0x0F] + HEX_CHARS[(b8 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b9 >> 4) & 0x0F] + HEX_CHARS[b9 & 0x0F] +
|
||||
HEX_CHARS[(b9 >> 12) & 0x0F] + HEX_CHARS[(b9 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b9 >> 20) & 0x0F] + HEX_CHARS[(b9 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b9 >> 28) & 0x0F] + HEX_CHARS[(b9 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b10 >> 4) & 0x0F] + HEX_CHARS[b10 & 0x0F] +
|
||||
HEX_CHARS[(b10 >> 12) & 0x0F] + HEX_CHARS[(b10 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b10 >> 20) & 0x0F] + HEX_CHARS[(b10 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b10 >> 28) & 0x0F] + HEX_CHARS[(b10 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b11 >> 4) & 0x0F] + HEX_CHARS[b11 & 0x0F] +
|
||||
HEX_CHARS[(b11 >> 12) & 0x0F] + HEX_CHARS[(b11 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b11 >> 20) & 0x0F] + HEX_CHARS[(b11 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b11 >> 28) & 0x0F] + HEX_CHARS[(b11 >> 24) & 0x0F];
|
||||
if(extraBytes > 1) {
|
||||
hex += HEX_CHARS[(h >> 12) & 0x0F] + HEX_CHARS[(h >> 8) & 0x0F];
|
||||
}
|
||||
if(bits == 512) {
|
||||
hex += HEX_CHARS[(b12 >> 4) & 0x0F] + HEX_CHARS[b12 & 0x0F] +
|
||||
HEX_CHARS[(b12 >> 12) & 0x0F] + HEX_CHARS[(b12 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b12 >> 20) & 0x0F] + HEX_CHARS[(b12 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b12 >> 28) & 0x0F] + HEX_CHARS[(b12 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b13 >> 4) & 0x0F] + HEX_CHARS[b13 & 0x0F] +
|
||||
HEX_CHARS[(b13 >> 12) & 0x0F] + HEX_CHARS[(b13 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b13 >> 20) & 0x0F] + HEX_CHARS[(b13 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b13 >> 28) & 0x0F] + HEX_CHARS[(b13 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b14 >> 4) & 0x0F] + HEX_CHARS[b14 & 0x0F] +
|
||||
HEX_CHARS[(b14 >> 12) & 0x0F] + HEX_CHARS[(b14 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b14 >> 20) & 0x0F] + HEX_CHARS[(b14 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b14 >> 28) & 0x0F] + HEX_CHARS[(b14 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(b15 >> 4) & 0x0F] + HEX_CHARS[b15 & 0x0F] +
|
||||
HEX_CHARS[(b15 >> 12) & 0x0F] + HEX_CHARS[(b15 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(b15 >> 20) & 0x0F] + HEX_CHARS[(b15 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(b15 >> 28) & 0x0F] + HEX_CHARS[(b15 >> 24) & 0x0F];
|
||||
}
|
||||
} else {
|
||||
for(i = 0, n = bits / 32;i < n;++i) {
|
||||
h = s[i];
|
||||
hex += HEX_CHARS[(h >> 4) & 0x0F] + HEX_CHARS[h & 0x0F] +
|
||||
HEX_CHARS[(h >> 12) & 0x0F] + HEX_CHARS[(h >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h >> 20) & 0x0F] + HEX_CHARS[(h >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h >> 28) & 0x0F] + HEX_CHARS[(h >> 24) & 0x0F];
|
||||
if(extraBytes > 2) {
|
||||
hex += HEX_CHARS[(h >> 20) & 0x0F] + HEX_CHARS[(h >> 16) & 0x0F];
|
||||
}
|
||||
}
|
||||
return hex;
|
||||
|
||||
Reference in New Issue
Block a user