mirror of
https://github.com/emn178/js-sha3.git
synced 2026-08-13 03:51:54 +08:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3fc9645d4 | ||
|
|
59d5441220 | ||
|
|
a67f74cf2c | ||
|
|
d506b22f67 |
@@ -0,0 +1,77 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Node 24
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 24.x
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Pack npm package
|
||||||
|
run: |
|
||||||
|
mkdir -p package-artifact
|
||||||
|
npm pack --pack-destination package-artifact
|
||||||
|
|
||||||
|
- name: Upload package artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: package-node-24
|
||||||
|
path: package-artifact/*.tgz
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
runtime-test:
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [18.x, 20.x, 22.x, 24.x]
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Node ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Download package artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: package-node-24
|
||||||
|
path: package-artifact
|
||||||
|
|
||||||
|
- name: Extract package artifact
|
||||||
|
run: tar -xzf package-artifact/*.tgz --strip-components=1 -C .
|
||||||
|
|
||||||
|
- name: Run runtime tests
|
||||||
|
if: matrix.node-version != '24.x'
|
||||||
|
run: npm run test:runtime
|
||||||
|
|
||||||
|
- name: Run runtime tests with coverage
|
||||||
|
if: matrix.node-version == '24.x'
|
||||||
|
run: npm run test:coverage
|
||||||
|
|
||||||
|
- name: Upload to coveralls
|
||||||
|
if: matrix.node-version == '24.x'
|
||||||
|
uses: coverallsapp/github-action@v2
|
||||||
|
with:
|
||||||
|
file: ./coverage/lcov.info
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
name: Publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 24.x
|
||||||
|
registry-url: https://registry.npmjs.org
|
||||||
|
package-manager-cache: false
|
||||||
|
|
||||||
|
- run: npm ci
|
||||||
|
|
||||||
|
- name: Verify release version
|
||||||
|
run: |
|
||||||
|
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
||||||
|
test "$GITHUB_REF_NAME" = "v$PACKAGE_VERSION"
|
||||||
|
|
||||||
|
- run: npm run build
|
||||||
|
- run: npm test
|
||||||
|
- run: npm publish
|
||||||
@@ -2,6 +2,5 @@
|
|||||||
/coverage/
|
/coverage/
|
||||||
/.nyc_output/
|
/.nyc_output/
|
||||||
/tests/
|
/tests/
|
||||||
.travis.yml
|
|
||||||
.npmignore
|
.npmignore
|
||||||
bower.json
|
bower.json
|
||||||
|
|||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- "6.11.4"
|
|
||||||
- "8.6.0"
|
|
||||||
before_install:
|
|
||||||
- npm install coveralls
|
|
||||||
after_success: npm run coveralls
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
@@ -1,5 +1,17 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## v0.13.0 / 2026-08-07
|
||||||
|
### Added
|
||||||
|
- ParallelHash128, ParallelHash256, ParallelHashXOF128, and ParallelHashXOF256 (NIST SP 800-185)
|
||||||
|
- GitHub Actions CI across Node.js 18, 20, 22, and 24 against the packed npm artifact
|
||||||
|
- GitHub Actions publish workflow on release with npm trusted publishing
|
||||||
|
- `prepack` script to build distributions before `npm pack` / `npm publish`
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Replace Travis CI with GitHub Actions
|
||||||
|
- Update README badges to GitHub Actions, npm, and jsDelivr
|
||||||
|
- Upgrade mocha and pin vulnerable transitive dependencies via npm overrides
|
||||||
|
|
||||||
## v0.12.0 / 2026-07-18
|
## v0.12.0 / 2026-07-18
|
||||||
### Added
|
### Added
|
||||||
- KMACXOF128 and KMACXOF256 (NIST SP 800-185)
|
- KMACXOF128 and KMACXOF256 (NIST SP 800-185)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# js-sha3
|
# js-sha3
|
||||||
|
[](https://github.com/emn178/js-sha3/actions/workflows/ci.yml)
|
||||||
|
[](https://coveralls.io/r/emn178/js-sha3?branch=master)
|
||||||
|
[](https://www.npmjs.com/package/js-sha3)
|
||||||
|
[](https://www.jsdelivr.com/package/npm/js-sha3)
|
||||||
|
|
||||||
[](https://travis-ci.org/emn178/js-sha3)
|
A simple SHA-3 / Keccak / SHAKE / cSHAKE / KMAC / TupleHash / ParallelHash hash function for JavaScript supports UTF-8 encoding.
|
||||||
[](https://coveralls.io/r/emn178/js-sha3?branch=master)
|
|
||||||
[](https://nodei.co/npm/js-sha3/)
|
|
||||||
|
|
||||||
A simple SHA-3 / Keccak / SHAKE / cSHAKE / KMAC / TupleHash hash function for JavaScript supports UTF-8 encoding.
|
|
||||||
|
|
||||||
## Notice
|
## Notice
|
||||||
* v0.8.0+ will throw an error if try to update hash after finalize.
|
* v0.8.0+ will throw an error if try to update hash after finalize.
|
||||||
@@ -20,8 +20,22 @@ A simple SHA-3 / Keccak / SHAKE / cSHAKE / KMAC / TupleHash hash function for Ja
|
|||||||
[Keccak-384 Online](http://emn178.github.io/online-tools/keccak_384.html)
|
[Keccak-384 Online](http://emn178.github.io/online-tools/keccak_384.html)
|
||||||
[Keccak-256 Online](http://emn178.github.io/online-tools/keccak_256.html)
|
[Keccak-256 Online](http://emn178.github.io/online-tools/keccak_256.html)
|
||||||
[Keccak-224 Online](http://emn178.github.io/online-tools/keccak_224.html)
|
[Keccak-224 Online](http://emn178.github.io/online-tools/keccak_224.html)
|
||||||
[Shake128 Online](http://emn178.github.io/online-tools/shake_128.html)
|
[Shake128 Online](http://emn178.github.io/online-tools/shake128/)
|
||||||
[Shake256 Online](http://emn178.github.io/online-tools/shake_256.html)
|
[Shake256 Online](http://emn178.github.io/online-tools/shake256/)
|
||||||
|
[cShake128 Online](http://emn178.github.io/online-tools/cshake128/)
|
||||||
|
[cShake256 Online](http://emn178.github.io/online-tools/cshake256/)
|
||||||
|
[KMAC128 Online](http://emn178.github.io/online-tools/kmac128/)
|
||||||
|
[KMAC256 Online](http://emn178.github.io/online-tools/kmac256/)
|
||||||
|
[KMACXOF128 Online](http://emn178.github.io/online-tools/kmacxof128/)
|
||||||
|
[KMACXOF256 Online](http://emn178.github.io/online-tools/kmacxof256/)
|
||||||
|
[TupleHash128 Online](http://emn178.github.io/online-tools/tuplehash128/)
|
||||||
|
[TupleHash256 Online](http://emn178.github.io/online-tools/tuplehash256/)
|
||||||
|
[TupleHashXOF128 Online](http://emn178.github.io/online-tools/tuplehashxof128/)
|
||||||
|
[TupleHashXOF256 Online](http://emn178.github.io/online-tools/tuplehashxof256/)
|
||||||
|
[ParallelHash128 Online](http://emn178.github.io/online-tools/parallelhash128/)
|
||||||
|
[ParallelHash256 Online](http://emn178.github.io/online-tools/parallelhash256/)
|
||||||
|
[ParallelHashXOF128 Online](http://emn178.github.io/online-tools/parallelhashxof128/)
|
||||||
|
[ParallelHashXOF256 Online](http://emn178.github.io/online-tools/parallelhashxof256/)
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
[Compress](https://raw.github.com/emn178/js-sha3/master/build/sha3.min.js)
|
[Compress](https://raw.github.com/emn178/js-sha3/master/build/sha3.min.js)
|
||||||
@@ -59,6 +73,10 @@ tuplehash128(['abc', 'd'], 256, 'customization');
|
|||||||
tuplehash256(['abc', 'd'], 512, 'customization');
|
tuplehash256(['abc', 'd'], 512, 'customization');
|
||||||
tuplehashxof128(['abc', 'd'], 256, 'customization');
|
tuplehashxof128(['abc', 'd'], 256, 'customization');
|
||||||
tuplehashxof256(['abc', 'd'], 512, 'customization');
|
tuplehashxof256(['abc', 'd'], 512, 'customization');
|
||||||
|
parallelhash128('Message to hash', 8, 256, 'customization');
|
||||||
|
parallelhash256('Message to hash', 8, 512, 'customization');
|
||||||
|
parallelhashxof128('Message to hash', 8, 256, 'customization');
|
||||||
|
parallelhashxof256('Message to hash', 8, 512, 'customization');
|
||||||
|
|
||||||
// Support ArrayBuffer output
|
// Support ArrayBuffer output
|
||||||
var arrayBuffer = keccak224.arrayBuffer('Message to hash');
|
var arrayBuffer = keccak224.arrayBuffer('Message to hash');
|
||||||
@@ -112,6 +130,13 @@ tupleHash.updateChunk([0x63]);
|
|||||||
tupleHash.beginInput(1);
|
tupleHash.beginInput(1);
|
||||||
tupleHash.updateChunk([0x64]);
|
tupleHash.updateChunk([0x64]);
|
||||||
tupleHash.hex();
|
tupleHash.hex();
|
||||||
|
|
||||||
|
// ParallelHash: hash one large input in fixed-size blocks.
|
||||||
|
parallelhash128('Message to hash', 8, 256, '');
|
||||||
|
parallelhash128.create(8, 256, '')
|
||||||
|
.update('Message ')
|
||||||
|
.update('to hash')
|
||||||
|
.hex();
|
||||||
```
|
```
|
||||||
### Node.js
|
### Node.js
|
||||||
If you use node.js, you should require the module first:
|
If you use node.js, you should require the module first:
|
||||||
@@ -136,7 +161,11 @@ const {
|
|||||||
tuplehash128,
|
tuplehash128,
|
||||||
tuplehash256,
|
tuplehash256,
|
||||||
tuplehashxof128,
|
tuplehashxof128,
|
||||||
tuplehashxof256
|
tuplehashxof256,
|
||||||
|
parallelhash128,
|
||||||
|
parallelhash256,
|
||||||
|
parallelhashxof128,
|
||||||
|
parallelhashxof256
|
||||||
} = require('js-sha3');
|
} = require('js-sha3');
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -163,7 +192,11 @@ import {
|
|||||||
tuplehash128,
|
tuplehash128,
|
||||||
tuplehash256,
|
tuplehash256,
|
||||||
tuplehashxof128,
|
tuplehashxof128,
|
||||||
tuplehashxof256
|
tuplehashxof256,
|
||||||
|
parallelhash128,
|
||||||
|
parallelhash256,
|
||||||
|
parallelhashxof128,
|
||||||
|
parallelhashxof256
|
||||||
} from 'js-sha3';
|
} from 'js-sha3';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "js-sha3",
|
"name": "js-sha3",
|
||||||
"version": "0.12.0",
|
"version": "0.13.0",
|
||||||
"main": ["src/sha3.js"],
|
"main": ["src/sha3.js"],
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"samples",
|
"samples",
|
||||||
|
|||||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
+132
-3
@@ -9,7 +9,7 @@ var sha3$1 = {exports: {}};
|
|||||||
/**
|
/**
|
||||||
* [js-sha3]{@link https://github.com/emn178/js-sha3}
|
* [js-sha3]{@link https://github.com/emn178/js-sha3}
|
||||||
*
|
*
|
||||||
* @version 0.12.0
|
* @version 0.13.0
|
||||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||||
* @copyright Chen, Yi-Cyuan 2015-2026
|
* @copyright Chen, Yi-Cyuan 2015-2026
|
||||||
* @license MIT
|
* @license MIT
|
||||||
@@ -25,6 +25,7 @@ var sha3$1 = {exports: {}};
|
|||||||
var TUPLE_INCOMPLETE_ERROR = 'tuple input is incomplete';
|
var TUPLE_INCOMPLETE_ERROR = 'tuple input is incomplete';
|
||||||
var TUPLE_LENGTH_ERROR = 'tuple input exceeds declared length';
|
var TUPLE_LENGTH_ERROR = 'tuple input exceeds declared length';
|
||||||
var TUPLE_BYTE_LENGTH_ERROR = 'tuple input byte length is invalid';
|
var TUPLE_BYTE_LENGTH_ERROR = 'tuple input byte length is invalid';
|
||||||
|
var BLOCK_SIZE_ERROR = 'block size is invalid';
|
||||||
var WINDOW = typeof window === 'object';
|
var WINDOW = typeof window === 'object';
|
||||||
var root = WINDOW ? window : {};
|
var root = WINDOW ? window : {};
|
||||||
if (root.JS_SHA3_NO_WINDOW) {
|
if (root.JS_SHA3_NO_WINDOW) {
|
||||||
@@ -131,6 +132,12 @@ var sha3$1 = {exports: {}};
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var createParallelHashOutputMethod = function (bits, padding, xof, outputType) {
|
||||||
|
return function (message, blockSize, outputBits, s) {
|
||||||
|
return methods[(xof ? 'parallelhashxof' : 'parallelhash') + bits].update(message, blockSize, outputBits, s)[outputType]();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
var createOutputMethods = function (method, createMethod, bits, padding) {
|
var createOutputMethods = function (method, createMethod, bits, padding) {
|
||||||
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
||||||
var type = OUTPUT_TYPES[i];
|
var type = OUTPUT_TYPES[i];
|
||||||
@@ -212,6 +219,26 @@ var sha3$1 = {exports: {}};
|
|||||||
}, bits, padding);
|
}, bits, padding);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var createParallelHashMethod = function (bits, padding, xof) {
|
||||||
|
var w = CSHAKE_BYTEPAD[bits];
|
||||||
|
var method = createParallelHashOutputMethod(bits, padding, xof, 'hex');
|
||||||
|
method.create = function (blockSize, outputBits, s) {
|
||||||
|
if (typeof blockSize !== 'number' || !isFinite(blockSize) || blockSize < 1 ||
|
||||||
|
Math.floor(blockSize) !== blockSize || blockSize > 0x0fffffff) {
|
||||||
|
throw new Error(BLOCK_SIZE_ERROR);
|
||||||
|
}
|
||||||
|
var hash = new ParallelHash(bits, padding, outputBits, xof, blockSize).bytepad(['ParallelHash', s], w);
|
||||||
|
hash.encode(blockSize, false);
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
method.update = function (message, blockSize, outputBits, s) {
|
||||||
|
return method.create(blockSize, outputBits, s).update(message);
|
||||||
|
};
|
||||||
|
return createOutputMethods(method, function (b, p, outputType) {
|
||||||
|
return createParallelHashOutputMethod(b, p, xof, outputType);
|
||||||
|
}, bits, padding);
|
||||||
|
};
|
||||||
|
|
||||||
var algorithms = [
|
var algorithms = [
|
||||||
{ name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod },
|
{ name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod },
|
||||||
{ name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod },
|
{ name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod },
|
||||||
@@ -228,6 +255,12 @@ var sha3$1 = {exports: {}};
|
|||||||
}},
|
}},
|
||||||
{ name: 'tuplehashxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
|
{ name: 'tuplehashxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
|
||||||
return createTupleHashMethod(bits, padding, true);
|
return createTupleHashMethod(bits, padding, true);
|
||||||
|
}},
|
||||||
|
{ name: 'parallelhash', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
|
||||||
|
return createParallelHashMethod(bits, padding, false);
|
||||||
|
}},
|
||||||
|
{ name: 'parallelhashxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
|
||||||
|
return createParallelHashMethod(bits, padding, true);
|
||||||
}}
|
}}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -597,6 +630,93 @@ var sha3$1 = {exports: {}};
|
|||||||
return Kmac.prototype.finalize.call(this);
|
return Kmac.prototype.finalize.call(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function ParallelHash(bits, padding, outputBits, xof, blockSize) {
|
||||||
|
Kmac.call(this, bits, padding, outputBits, xof);
|
||||||
|
this.bits = bits;
|
||||||
|
this.blockSize = blockSize;
|
||||||
|
this.inner = null;
|
||||||
|
this.innerBytes = 0;
|
||||||
|
this.blockNumber = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParallelHash.prototype = new Kmac();
|
||||||
|
|
||||||
|
ParallelHash.prototype._finishInner = function () {
|
||||||
|
Kmac.prototype.update.call(this, this.inner.array());
|
||||||
|
this.inner = null;
|
||||||
|
this.innerBytes = 0;
|
||||||
|
++this.blockNumber;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParallelHash.prototype._updateBytes = function (message) {
|
||||||
|
var length = message.length;
|
||||||
|
if (!length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slice = message.subarray || message.slice;
|
||||||
|
var blockSize = this.blockSize;
|
||||||
|
var index = 0;
|
||||||
|
while (index < length) {
|
||||||
|
if (!this.inner) {
|
||||||
|
this.inner = new Keccak(this.bits, SHAKE_PADDING, this.bits << 1);
|
||||||
|
}
|
||||||
|
var take = blockSize - this.innerBytes;
|
||||||
|
if (length - index < take) {
|
||||||
|
take = length - index;
|
||||||
|
}
|
||||||
|
this.inner.update(slice.call(message, index, index + take));
|
||||||
|
this.innerBytes += take;
|
||||||
|
index += take;
|
||||||
|
if (this.innerBytes === blockSize) {
|
||||||
|
this._finishInner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ParallelHash.prototype.update = function (message) {
|
||||||
|
if (this.finalized) {
|
||||||
|
throw new Error(FINALIZE_ERROR);
|
||||||
|
}
|
||||||
|
var result = formatMessage(message);
|
||||||
|
message = result[0];
|
||||||
|
if (result[1]) {
|
||||||
|
var bytes = [], length = message.length, index = 0, code, i;
|
||||||
|
for (i = 0; i < length; ++i) {
|
||||||
|
code = message.charCodeAt(i);
|
||||||
|
if (code < 0x80) {
|
||||||
|
bytes[index++] = code;
|
||||||
|
} else if (code < 0x800) {
|
||||||
|
bytes[index++] = (0xc0 | (code >>> 6));
|
||||||
|
bytes[index++] = (0x80 | (code & 0x3f));
|
||||||
|
} else if (code < 0xd800 || code >= 0xe000) {
|
||||||
|
bytes[index++] = (0xe0 | (code >>> 12));
|
||||||
|
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||||
|
bytes[index++] = (0x80 | (code & 0x3f));
|
||||||
|
} else {
|
||||||
|
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++i) & 0x3ff));
|
||||||
|
bytes[index++] = (0xf0 | (code >>> 18));
|
||||||
|
bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
|
||||||
|
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||||
|
bytes[index++] = (0x80 | (code & 0x3f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message = bytes;
|
||||||
|
}
|
||||||
|
this._updateBytes(message);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParallelHash.prototype.finalize = function () {
|
||||||
|
if (!this.finalized) {
|
||||||
|
if (this.inner) {
|
||||||
|
this._finishInner();
|
||||||
|
}
|
||||||
|
this.encode(this.blockNumber, true);
|
||||||
|
}
|
||||||
|
return Kmac.prototype.finalize.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
var f = function (s) {
|
var f = function (s) {
|
||||||
var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9,
|
var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9,
|
||||||
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17,
|
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17,
|
||||||
@@ -836,7 +956,16 @@ const {
|
|||||||
tuplehashxof_128,
|
tuplehashxof_128,
|
||||||
tuplehashxof_256,
|
tuplehashxof_256,
|
||||||
tuplehashxof128,
|
tuplehashxof128,
|
||||||
tuplehashxof256
|
tuplehashxof256,
|
||||||
|
|
||||||
|
parallelhash_128,
|
||||||
|
parallelhash_256,
|
||||||
|
parallelhash128,
|
||||||
|
parallelhash256,
|
||||||
|
parallelhashxof_128,
|
||||||
|
parallelhashxof_256,
|
||||||
|
parallelhashxof128,
|
||||||
|
parallelhashxof256
|
||||||
} = sha3;
|
} = sha3;
|
||||||
|
|
||||||
export { cshake128, cshake256, cshake_128, cshake_256, sha3 as default, keccak224, keccak256, keccak384, keccak512, keccak_224, keccak_256, keccak_384, keccak_512, kmac128, kmac256, kmac_128, kmac_256, kmacxof128, kmacxof256, kmacxof_128, kmacxof_256, sha3_224, sha3_256, sha3_384, sha3_512, shake128, shake256, shake_128, shake_256, tuplehash128, tuplehash256, tuplehash_128, tuplehash_256, tuplehashxof128, tuplehashxof256, tuplehashxof_128, tuplehashxof_256 };
|
export { cshake128, cshake256, cshake_128, cshake_256, sha3 as default, keccak224, keccak256, keccak384, keccak512, keccak_224, keccak_256, keccak_384, keccak_512, kmac128, kmac256, kmac_128, kmac_256, kmacxof128, kmacxof256, kmacxof_128, kmacxof_256, parallelhash128, parallelhash256, parallelhash_128, parallelhash_256, parallelhashxof128, parallelhashxof256, parallelhashxof_128, parallelhashxof_256, sha3_224, sha3_256, sha3_384, sha3_512, shake128, shake256, shake_128, shake_256, tuplehash128, tuplehash256, tuplehash_128, tuplehash_256, tuplehashxof128, tuplehashxof256, tuplehashxof_128, tuplehashxof_256 };
|
||||||
|
|||||||
Vendored
+89
@@ -417,3 +417,92 @@ export var tuplehashxof_128: TupleHashMethod;
|
|||||||
export var tuplehashxof_256: TupleHashMethod;
|
export var tuplehashxof_256: TupleHashMethod;
|
||||||
export var tuplehashxof128: TupleHashMethod;
|
export var tuplehashxof128: TupleHashMethod;
|
||||||
export var tuplehashxof256: TupleHashMethod;
|
export var tuplehashxof256: TupleHashMethod;
|
||||||
|
|
||||||
|
interface ParallelHash extends Hasher {
|
||||||
|
/**
|
||||||
|
* Absorb message bytes into ParallelHash blocks.
|
||||||
|
*
|
||||||
|
* @param message The next message chunk.
|
||||||
|
*/
|
||||||
|
update(message: Message): ParallelHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ParallelHashMethod {
|
||||||
|
/**
|
||||||
|
* Hash and return hex string.
|
||||||
|
*
|
||||||
|
* @param message The message you want to hash.
|
||||||
|
* @param blockSize The ParallelHash block size in bytes.
|
||||||
|
* @param outputBits The length of output.
|
||||||
|
* @param customization The customization string.
|
||||||
|
*/
|
||||||
|
(message: Message, blockSize: number, outputBits: number, customization: Message): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash and return hex string.
|
||||||
|
*
|
||||||
|
* @param message The message you want to hash.
|
||||||
|
* @param blockSize The ParallelHash block size in bytes.
|
||||||
|
* @param outputBits The length of output.
|
||||||
|
* @param customization The customization string.
|
||||||
|
*/
|
||||||
|
hex(message: Message, blockSize: number, outputBits: number, customization: Message): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash and return ArrayBuffer.
|
||||||
|
*
|
||||||
|
* @param message The message you want to hash.
|
||||||
|
* @param blockSize The ParallelHash block size in bytes.
|
||||||
|
* @param outputBits The length of output.
|
||||||
|
* @param customization The customization string.
|
||||||
|
*/
|
||||||
|
arrayBuffer(message: Message, blockSize: number, outputBits: number, customization: Message): ArrayBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash and return integer array.
|
||||||
|
*
|
||||||
|
* @param message The message you want to hash.
|
||||||
|
* @param blockSize The ParallelHash block size in bytes.
|
||||||
|
* @param outputBits The length of output.
|
||||||
|
* @param customization The customization string.
|
||||||
|
*/
|
||||||
|
digest(message: Message, blockSize: number, outputBits: number, customization: Message): number[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash and return integer array.
|
||||||
|
*
|
||||||
|
* @param message The message you want to hash.
|
||||||
|
* @param blockSize The ParallelHash block size in bytes.
|
||||||
|
* @param outputBits The length of output.
|
||||||
|
* @param customization The customization string.
|
||||||
|
*/
|
||||||
|
array(message: Message, blockSize: number, outputBits: number, customization: Message): number[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a ParallelHash object.
|
||||||
|
*
|
||||||
|
* @param blockSize The ParallelHash block size in bytes.
|
||||||
|
* @param outputBits The length of output.
|
||||||
|
* @param customization The customization string.
|
||||||
|
*/
|
||||||
|
create(blockSize: number, outputBits: number, customization: Message): ParallelHash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a ParallelHash object and hash message.
|
||||||
|
*
|
||||||
|
* @param message The message you want to hash.
|
||||||
|
* @param blockSize The ParallelHash block size in bytes.
|
||||||
|
* @param outputBits The length of output.
|
||||||
|
* @param customization The customization string.
|
||||||
|
*/
|
||||||
|
update(message: Message, blockSize: number, outputBits: number, customization: Message): ParallelHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
export var parallelhash_128: ParallelHashMethod;
|
||||||
|
export var parallelhash_256: ParallelHashMethod;
|
||||||
|
export var parallelhash128: ParallelHashMethod;
|
||||||
|
export var parallelhash256: ParallelHashMethod;
|
||||||
|
export var parallelhashxof_128: ParallelHashMethod;
|
||||||
|
export var parallelhashxof_256: ParallelHashMethod;
|
||||||
|
export var parallelhashxof128: ParallelHashMethod;
|
||||||
|
export var parallelhashxof256: ParallelHashMethod;
|
||||||
|
|||||||
Generated
+942
-1118
File diff suppressed because it is too large
Load Diff
+14
-6
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "js-sha3",
|
"name": "js-sha3",
|
||||||
"version": "0.12.0",
|
"version": "0.13.0",
|
||||||
"description": "A simple SHA-3 / Keccak / SHAKE / cSHAKE / KMAC / TupleHash hash function for JavaScript supports UTF-8 encoding.",
|
"description": "A simple SHA-3 / Keccak / SHAKE / cSHAKE / KMAC / TupleHash / ParallelHash hash function for JavaScript supports UTF-8 encoding.",
|
||||||
"main": "src/sha3.js",
|
"main": "src/sha3.js",
|
||||||
"module": "build/sha3.mjs",
|
"module": "build/sha3.mjs",
|
||||||
"exports": {
|
"exports": {
|
||||||
@@ -22,17 +22,20 @@
|
|||||||
"@rollup/plugin-commonjs": "^28.0.5",
|
"@rollup/plugin-commonjs": "^28.0.5",
|
||||||
"@rollup/plugin-terser": "^1.0.0",
|
"@rollup/plugin-terser": "^1.0.0",
|
||||||
"expect.js": "~0.3.1",
|
"expect.js": "~0.3.1",
|
||||||
"mocha": "^11.7.6",
|
"mocha": "^11.8.0",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^18.0.0",
|
||||||
"rollup": "^4.43.0",
|
"rollup": "^4.43.0",
|
||||||
"tiny-worker": "^2.3.0",
|
"tiny-worker": "^2.3.0",
|
||||||
"uglify-js": "^3.1.9"
|
"uglify-js": "^3.1.9"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "nyc mocha tests/node-test.js",
|
"test": "npm run build && npm run test:coverage",
|
||||||
|
"test:runtime": "mocha tests/node-test.js",
|
||||||
|
"test:coverage": "nyc --reporter=text --reporter=html --reporter=lcov mocha tests/node-test.js",
|
||||||
"report": "nyc --reporter=html --reporter=text mocha tests/node-test.js",
|
"report": "nyc --reporter=html --reporter=text mocha tests/node-test.js",
|
||||||
"coveralls": "nyc report --reporter=text-lcov | coveralls",
|
"coveralls": "nyc report --reporter=text-lcov | coveralls",
|
||||||
"build": "rollup -c && uglifyjs src/sha3.js -c -m --comments --output build/sha3.min.js"
|
"build": "rollup -c && uglifyjs src/sha3.js -c -m --comments --output build/sha3.min.js",
|
||||||
|
"prepack": "npm run build"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -45,6 +48,7 @@
|
|||||||
"cshake",
|
"cshake",
|
||||||
"kmac",
|
"kmac",
|
||||||
"tuplehash",
|
"tuplehash",
|
||||||
|
"parallelhash",
|
||||||
"hash",
|
"hash",
|
||||||
"encryption",
|
"encryption",
|
||||||
"cryptography",
|
"cryptography",
|
||||||
@@ -60,5 +64,9 @@
|
|||||||
"exclude": [
|
"exclude": [
|
||||||
"tests"
|
"tests"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"diff": "^8.0.3",
|
||||||
|
"serialize-javascript": "^7.0.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+121
-1
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* [js-sha3]{@link https://github.com/emn178/js-sha3}
|
* [js-sha3]{@link https://github.com/emn178/js-sha3}
|
||||||
*
|
*
|
||||||
* @version 0.12.0
|
* @version 0.13.0
|
||||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||||
* @copyright Chen, Yi-Cyuan 2015-2026
|
* @copyright Chen, Yi-Cyuan 2015-2026
|
||||||
* @license MIT
|
* @license MIT
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
var TUPLE_INCOMPLETE_ERROR = 'tuple input is incomplete';
|
var TUPLE_INCOMPLETE_ERROR = 'tuple input is incomplete';
|
||||||
var TUPLE_LENGTH_ERROR = 'tuple input exceeds declared length';
|
var TUPLE_LENGTH_ERROR = 'tuple input exceeds declared length';
|
||||||
var TUPLE_BYTE_LENGTH_ERROR = 'tuple input byte length is invalid';
|
var TUPLE_BYTE_LENGTH_ERROR = 'tuple input byte length is invalid';
|
||||||
|
var BLOCK_SIZE_ERROR = 'block size is invalid';
|
||||||
var WINDOW = typeof window === 'object';
|
var WINDOW = typeof window === 'object';
|
||||||
var root = WINDOW ? window : {};
|
var root = WINDOW ? window : {};
|
||||||
if (root.JS_SHA3_NO_WINDOW) {
|
if (root.JS_SHA3_NO_WINDOW) {
|
||||||
@@ -123,6 +124,12 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var createParallelHashOutputMethod = function (bits, padding, xof, outputType) {
|
||||||
|
return function (message, blockSize, outputBits, s) {
|
||||||
|
return methods[(xof ? 'parallelhashxof' : 'parallelhash') + bits].update(message, blockSize, outputBits, s)[outputType]();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
var createOutputMethods = function (method, createMethod, bits, padding) {
|
var createOutputMethods = function (method, createMethod, bits, padding) {
|
||||||
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
||||||
var type = OUTPUT_TYPES[i];
|
var type = OUTPUT_TYPES[i];
|
||||||
@@ -204,6 +211,26 @@
|
|||||||
}, bits, padding);
|
}, bits, padding);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var createParallelHashMethod = function (bits, padding, xof) {
|
||||||
|
var w = CSHAKE_BYTEPAD[bits];
|
||||||
|
var method = createParallelHashOutputMethod(bits, padding, xof, 'hex');
|
||||||
|
method.create = function (blockSize, outputBits, s) {
|
||||||
|
if (typeof blockSize !== 'number' || !isFinite(blockSize) || blockSize < 1 ||
|
||||||
|
Math.floor(blockSize) !== blockSize || blockSize > 0x0fffffff) {
|
||||||
|
throw new Error(BLOCK_SIZE_ERROR);
|
||||||
|
}
|
||||||
|
var hash = new ParallelHash(bits, padding, outputBits, xof, blockSize).bytepad(['ParallelHash', s], w);
|
||||||
|
hash.encode(blockSize, false);
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
method.update = function (message, blockSize, outputBits, s) {
|
||||||
|
return method.create(blockSize, outputBits, s).update(message);
|
||||||
|
};
|
||||||
|
return createOutputMethods(method, function (b, p, outputType) {
|
||||||
|
return createParallelHashOutputMethod(b, p, xof, outputType);
|
||||||
|
}, bits, padding);
|
||||||
|
};
|
||||||
|
|
||||||
var algorithms = [
|
var algorithms = [
|
||||||
{ name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod },
|
{ name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod },
|
||||||
{ name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod },
|
{ name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod },
|
||||||
@@ -220,6 +247,12 @@
|
|||||||
}},
|
}},
|
||||||
{ name: 'tuplehashxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
|
{ name: 'tuplehashxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
|
||||||
return createTupleHashMethod(bits, padding, true);
|
return createTupleHashMethod(bits, padding, true);
|
||||||
|
}},
|
||||||
|
{ name: 'parallelhash', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
|
||||||
|
return createParallelHashMethod(bits, padding, false);
|
||||||
|
}},
|
||||||
|
{ name: 'parallelhashxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
|
||||||
|
return createParallelHashMethod(bits, padding, true);
|
||||||
}}
|
}}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -589,6 +622,93 @@
|
|||||||
return Kmac.prototype.finalize.call(this);
|
return Kmac.prototype.finalize.call(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function ParallelHash(bits, padding, outputBits, xof, blockSize) {
|
||||||
|
Kmac.call(this, bits, padding, outputBits, xof);
|
||||||
|
this.bits = bits;
|
||||||
|
this.blockSize = blockSize;
|
||||||
|
this.inner = null;
|
||||||
|
this.innerBytes = 0;
|
||||||
|
this.blockNumber = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParallelHash.prototype = new Kmac();
|
||||||
|
|
||||||
|
ParallelHash.prototype._finishInner = function () {
|
||||||
|
Kmac.prototype.update.call(this, this.inner.array());
|
||||||
|
this.inner = null;
|
||||||
|
this.innerBytes = 0;
|
||||||
|
++this.blockNumber;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParallelHash.prototype._updateBytes = function (message) {
|
||||||
|
var length = message.length;
|
||||||
|
if (!length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slice = message.subarray || message.slice;
|
||||||
|
var blockSize = this.blockSize;
|
||||||
|
var index = 0;
|
||||||
|
while (index < length) {
|
||||||
|
if (!this.inner) {
|
||||||
|
this.inner = new Keccak(this.bits, SHAKE_PADDING, this.bits << 1);
|
||||||
|
}
|
||||||
|
var take = blockSize - this.innerBytes;
|
||||||
|
if (length - index < take) {
|
||||||
|
take = length - index;
|
||||||
|
}
|
||||||
|
this.inner.update(slice.call(message, index, index + take));
|
||||||
|
this.innerBytes += take;
|
||||||
|
index += take;
|
||||||
|
if (this.innerBytes === blockSize) {
|
||||||
|
this._finishInner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ParallelHash.prototype.update = function (message) {
|
||||||
|
if (this.finalized) {
|
||||||
|
throw new Error(FINALIZE_ERROR);
|
||||||
|
}
|
||||||
|
var result = formatMessage(message);
|
||||||
|
message = result[0];
|
||||||
|
if (result[1]) {
|
||||||
|
var bytes = [], length = message.length, index = 0, code, i;
|
||||||
|
for (i = 0; i < length; ++i) {
|
||||||
|
code = message.charCodeAt(i);
|
||||||
|
if (code < 0x80) {
|
||||||
|
bytes[index++] = code;
|
||||||
|
} else if (code < 0x800) {
|
||||||
|
bytes[index++] = (0xc0 | (code >>> 6));
|
||||||
|
bytes[index++] = (0x80 | (code & 0x3f));
|
||||||
|
} else if (code < 0xd800 || code >= 0xe000) {
|
||||||
|
bytes[index++] = (0xe0 | (code >>> 12));
|
||||||
|
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||||
|
bytes[index++] = (0x80 | (code & 0x3f));
|
||||||
|
} else {
|
||||||
|
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++i) & 0x3ff));
|
||||||
|
bytes[index++] = (0xf0 | (code >>> 18));
|
||||||
|
bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
|
||||||
|
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||||
|
bytes[index++] = (0x80 | (code & 0x3f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message = bytes;
|
||||||
|
}
|
||||||
|
this._updateBytes(message);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParallelHash.prototype.finalize = function () {
|
||||||
|
if (!this.finalized) {
|
||||||
|
if (this.inner) {
|
||||||
|
this._finishInner();
|
||||||
|
}
|
||||||
|
this.encode(this.blockNumber, true);
|
||||||
|
}
|
||||||
|
return Kmac.prototype.finalize.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
var f = function (s) {
|
var f = function (s) {
|
||||||
var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9,
|
var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9,
|
||||||
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17,
|
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17,
|
||||||
|
|||||||
+10
-1
@@ -41,7 +41,16 @@ export const {
|
|||||||
tuplehashxof_128,
|
tuplehashxof_128,
|
||||||
tuplehashxof_256,
|
tuplehashxof_256,
|
||||||
tuplehashxof128,
|
tuplehashxof128,
|
||||||
tuplehashxof256
|
tuplehashxof256,
|
||||||
|
|
||||||
|
parallelhash_128,
|
||||||
|
parallelhash_256,
|
||||||
|
parallelhash128,
|
||||||
|
parallelhash256,
|
||||||
|
parallelhashxof_128,
|
||||||
|
parallelhashxof_256,
|
||||||
|
parallelhashxof128,
|
||||||
|
parallelhashxof256
|
||||||
} = sha3;
|
} = sha3;
|
||||||
|
|
||||||
export default sha3;
|
export default sha3;
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ function unset() {
|
|||||||
tuplehash256 = null;
|
tuplehash256 = null;
|
||||||
tuplehashxof128 = null;
|
tuplehashxof128 = null;
|
||||||
tuplehashxof256 = null;
|
tuplehashxof256 = null;
|
||||||
|
parallelhash128 = null;
|
||||||
|
parallelhash256 = null;
|
||||||
|
parallelhashxof128 = null;
|
||||||
|
parallelhashxof256 = null;
|
||||||
BUFFER = undefined;
|
BUFFER = undefined;
|
||||||
JS_SHA3_NO_WINDOW = undefined;
|
JS_SHA3_NO_WINDOW = undefined;
|
||||||
JS_SHA3_NO_NODE_JS = undefined;
|
JS_SHA3_NO_NODE_JS = undefined;
|
||||||
@@ -53,6 +57,10 @@ function requireToGlobal() {
|
|||||||
tuplehash256 = sha3.tuplehash256;
|
tuplehash256 = sha3.tuplehash256;
|
||||||
tuplehashxof128 = sha3.tuplehashxof128;
|
tuplehashxof128 = sha3.tuplehashxof128;
|
||||||
tuplehashxof256 = sha3.tuplehashxof256;
|
tuplehashxof256 = sha3.tuplehashxof256;
|
||||||
|
parallelhash128 = sha3.parallelhash128;
|
||||||
|
parallelhash256 = sha3.parallelhash256;
|
||||||
|
parallelhashxof128 = sha3.parallelhashxof128;
|
||||||
|
parallelhashxof256 = sha3.parallelhashxof256;
|
||||||
}
|
}
|
||||||
|
|
||||||
function runCommonJsTest() {
|
function runCommonJsTest() {
|
||||||
@@ -70,6 +78,7 @@ function runWindowTest(extra) {
|
|||||||
require('./test-cshake.js');
|
require('./test-cshake.js');
|
||||||
require('./test-kmac.js');
|
require('./test-kmac.js');
|
||||||
require('./test-tuplehash.js');
|
require('./test-tuplehash.js');
|
||||||
|
require('./test-parallelhash.js');
|
||||||
}
|
}
|
||||||
unset();
|
unset();
|
||||||
}
|
}
|
||||||
@@ -127,6 +136,10 @@ define = function (func) {
|
|||||||
tuplehash256 = sha3.tuplehash256;
|
tuplehash256 = sha3.tuplehash256;
|
||||||
tuplehashxof128 = sha3.tuplehashxof128;
|
tuplehashxof128 = sha3.tuplehashxof128;
|
||||||
tuplehashxof256 = sha3.tuplehashxof256;
|
tuplehashxof256 = sha3.tuplehashxof256;
|
||||||
|
parallelhash128 = sha3.parallelhash128;
|
||||||
|
parallelhash256 = sha3.parallelhash256;
|
||||||
|
parallelhashxof128 = sha3.parallelhashxof128;
|
||||||
|
parallelhashxof256 = sha3.parallelhashxof256;
|
||||||
require('./test.js');
|
require('./test.js');
|
||||||
};
|
};
|
||||||
define.amd = true;
|
define.amd = true;
|
||||||
|
|||||||
@@ -0,0 +1,251 @@
|
|||||||
|
(function (parallelhash256, parallelhash128, parallelhashxof256, parallelhashxof128) {
|
||||||
|
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/ParallelHash_samples.pdf
|
||||||
|
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/ParallelHashXOF_samples.pdf
|
||||||
|
var d1 = [
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||||
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
|
||||||
|
];
|
||||||
|
var d2 = [
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||||
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
|
||||||
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
|
||||||
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b
|
||||||
|
];
|
||||||
|
|
||||||
|
var testCases = [
|
||||||
|
{
|
||||||
|
name: 'parallelhash128',
|
||||||
|
method: parallelhash128,
|
||||||
|
cases: [
|
||||||
|
{
|
||||||
|
message: d1,
|
||||||
|
blockSize: 8,
|
||||||
|
bits: 256,
|
||||||
|
s: '',
|
||||||
|
output: 'ba8dc1d1d979331d3f813603c67f72609ab5e44b94a0b8f9af46514454a2b4f5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: d1,
|
||||||
|
blockSize: 8,
|
||||||
|
bits: 256,
|
||||||
|
s: 'Parallel Data',
|
||||||
|
output: 'fc484dcb3f84dceedc353438151bee58157d6efed0445a81f165e495795b7206'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: d2,
|
||||||
|
blockSize: 12,
|
||||||
|
bits: 256,
|
||||||
|
s: 'Parallel Data',
|
||||||
|
output: 'f7fd5312896c6685c828af7e2adb97e393e7f8d54e3c2ea4b95e5aca3796e8fc'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parallelhash256',
|
||||||
|
method: parallelhash256,
|
||||||
|
cases: [
|
||||||
|
{
|
||||||
|
message: d1,
|
||||||
|
blockSize: 8,
|
||||||
|
bits: 512,
|
||||||
|
s: '',
|
||||||
|
output: 'bc1ef124da34495e948ead207dd9842235da432d2bbc54b4c110e64c451105531b7f2a3e0ce055c02805e7c2de1fb746af97a1dd01f43b824e31b87612410429'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: d1,
|
||||||
|
blockSize: 8,
|
||||||
|
bits: 512,
|
||||||
|
s: 'Parallel Data',
|
||||||
|
output: 'cdf15289b54f6212b4bc270528b49526006dd9b54e2b6add1ef6900dda3963bb33a72491f236969ca8afaea29c682d47a393c065b38e29fae651a2091c833110'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: d2,
|
||||||
|
blockSize: 12,
|
||||||
|
bits: 512,
|
||||||
|
s: 'Parallel Data',
|
||||||
|
output: '69d0fcb764ea055dd09334bc6021cb7e4b61348dff375da262671cdec3effa8d1b4568a6cce16b1cad946ddde27f6ce2b8dee4cd1b24851ebf00eb90d43813e9'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parallelhashxof128',
|
||||||
|
method: parallelhashxof128,
|
||||||
|
cases: [
|
||||||
|
{
|
||||||
|
message: d1,
|
||||||
|
blockSize: 8,
|
||||||
|
bits: 256,
|
||||||
|
s: '',
|
||||||
|
output: 'fe47d661e49ffe5b7d999922c062356750caf552985b8e8ce6667f2727c3c8d3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: d1,
|
||||||
|
blockSize: 8,
|
||||||
|
bits: 256,
|
||||||
|
s: 'Parallel Data',
|
||||||
|
output: 'ea2a793140820f7a128b8eb70a9439f93257c6e6e79b4a540d291d6dae7098d7'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: d2,
|
||||||
|
blockSize: 12,
|
||||||
|
bits: 256,
|
||||||
|
s: 'Parallel Data',
|
||||||
|
output: '0127ad9772ab904691987fcc4a24888f341fa0db2145e872d4efd255376602f0'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'parallelhashxof256',
|
||||||
|
method: parallelhashxof256,
|
||||||
|
cases: [
|
||||||
|
{
|
||||||
|
message: d1,
|
||||||
|
blockSize: 8,
|
||||||
|
bits: 512,
|
||||||
|
s: '',
|
||||||
|
output: 'c10a052722614684144d28474850b410757e3cba87651ba167a5cbddff7f466675fbf84bcae7378ac444be681d729499afca667fb879348bfdda427863c82f1c'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: d1,
|
||||||
|
blockSize: 8,
|
||||||
|
bits: 512,
|
||||||
|
s: 'Parallel Data',
|
||||||
|
output: '538e105f1a22f44ed2f5cc1674fbd40be803d9c99bf5f8d90a2c8193f3fe6ea768e5c1a20987e2c9c65febed03887a51d35624ed12377594b5585541dc377efc'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: d2,
|
||||||
|
blockSize: 12,
|
||||||
|
bits: 512,
|
||||||
|
s: 'Parallel Data',
|
||||||
|
output: '6b3e790b330c889a204c2fbc728d809f19367328d852f4002dc829f73afd6bcefb7fe5b607b13a801c0be5c1170bdb794e339458fdb0e62a6af3d42558970249'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
testCases.forEach(function (testCase) {
|
||||||
|
describe('#' + testCase.name, function () {
|
||||||
|
testCase.cases.forEach(function (c) {
|
||||||
|
it('should match NIST sample vector', function () {
|
||||||
|
expect(testCase.method(c.message, c.blockSize, c.bits, c.s)).to.be(c.output);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#parallelhash API', function () {
|
||||||
|
it('should match instance update and method update with one-shot', function () {
|
||||||
|
var expected = parallelhash128(d1, 8, 256, 'cache');
|
||||||
|
var incremental = parallelhash128.create(8, 256, 'cache').update(d1.slice(0, 10)).update(d1.slice(10)).hex();
|
||||||
|
var methodUpdate = parallelhash128.update(d1.slice(0, 5), 8, 256, 'cache').update(d1.slice(5)).hex();
|
||||||
|
expect(incremental).to.be(expected);
|
||||||
|
expect(methodUpdate).to.be(expected);
|
||||||
|
expect(parallelhash128.update(d1, 8, 256, 'cache').hex()).to.be(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should stream binary messages in irregular chunks', function () {
|
||||||
|
var expected = parallelhash128(d2, 12, 256, '');
|
||||||
|
var hash = parallelhash128.create(12, 256, '');
|
||||||
|
hash.update(d2.slice(0, 1));
|
||||||
|
hash.update(d2.slice(1, 17));
|
||||||
|
hash.update(d2.slice(17, 50));
|
||||||
|
hash.update(d2.slice(50));
|
||||||
|
expect(hash.hex()).to.be(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should stream ArrayBuffer and Uint8Array views', function () {
|
||||||
|
var expected = parallelhash128(d1, 8, 256, '');
|
||||||
|
var buffer = new Uint8Array(d1).buffer;
|
||||||
|
var view = new Uint8Array(new Uint8Array(d1).buffer, 0, d1.length);
|
||||||
|
expect(parallelhash128.create(8, 256, '').update(buffer).hex()).to.be(expected);
|
||||||
|
expect(parallelhash128.create(8, 256, '').update(view).hex()).to.be(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should hash empty message with n = 0', function () {
|
||||||
|
var empty = parallelhash128([], 8, 256, '');
|
||||||
|
var emptyString = parallelhash128('', 8, 256, '');
|
||||||
|
expect(empty).to.be(emptyString);
|
||||||
|
expect(empty).to.not.be(parallelhash128([0x00], 8, 256, ''));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle UTF-8 strings across block boundaries', function () {
|
||||||
|
var message = 'åbc'; // 2 + 1 + 1 = 4 UTF-8 bytes
|
||||||
|
var expected = parallelhash128(message, 3, 256, '');
|
||||||
|
var hash = parallelhash128.create(3, 256, '');
|
||||||
|
hash.update('å').update('bc');
|
||||||
|
expect(hash.hex()).to.be(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should encode 3-byte and 4-byte UTF-8 characters', function () {
|
||||||
|
var message = '中\uE000\uD83D\uDE00'; // 3 + 3 + 4 = 10 UTF-8 bytes
|
||||||
|
var expected = parallelhash128(message, 4, 256, '');
|
||||||
|
var hash = parallelhash128.create(4, 256, '');
|
||||||
|
hash.update('中').update('\uE000').update('\uD83D\uDE00');
|
||||||
|
expect(hash.hex()).to.be(expected);
|
||||||
|
expect(hash.array().length).to.be(32);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep absorbing when update is shorter than remaining block space', function () {
|
||||||
|
var expected = parallelhash128(d1, 8, 256, '');
|
||||||
|
var hash = parallelhash128.create(8, 256, '');
|
||||||
|
hash.update(d1.slice(0, 3)); // partial inner block, need 5 more
|
||||||
|
hash.update(d1.slice(3, 5)); // still short, continue same inner SHAKE
|
||||||
|
hash.update(d1.slice(5)); // finish remaining blocks
|
||||||
|
expect(hash.hex()).to.be(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be affected by mutating input after update', function () {
|
||||||
|
var expected = parallelhash128(d1, 8, 256, '');
|
||||||
|
var chunk = new Uint8Array(d1.slice(0, 3));
|
||||||
|
var rest = new Uint8Array(d1.slice(3));
|
||||||
|
var hash = parallelhash128.create(8, 256, '');
|
||||||
|
hash.update(chunk);
|
||||||
|
chunk[0] = 0xff;
|
||||||
|
chunk[1] = 0xff;
|
||||||
|
chunk[2] = 0xff;
|
||||||
|
hash.update(rest);
|
||||||
|
expect(hash.hex()).to.be(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow repeated output representations', function () {
|
||||||
|
var hash = parallelhash128.create(8, 256, '').update(d1);
|
||||||
|
var hex = hash.hex();
|
||||||
|
var array = hash.array();
|
||||||
|
var digest = hash.digest();
|
||||||
|
var buffer = hash.arrayBuffer();
|
||||||
|
expect(hash.hex()).to.be(hex);
|
||||||
|
expect(array).to.eql(digest);
|
||||||
|
expect(Array.prototype.slice.call(new Uint8Array(buffer))).to.eql(array);
|
||||||
|
expect(function () { hash.update(d1); }).to.throwError(/finalize already called/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should require customization like KMAC', function () {
|
||||||
|
expect(function () { parallelhash128(d1, 8, 256); }).to.throwError(/input is invalid type/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reject invalid block sizes', function () {
|
||||||
|
expect(function () { parallelhash128.create(0, 256, ''); }).to.throwError(/block size is invalid/);
|
||||||
|
expect(function () { parallelhash128.create(-1, 256, ''); }).to.throwError(/block size is invalid/);
|
||||||
|
expect(function () { parallelhash128.create(1.5, 256, ''); }).to.throwError(/block size is invalid/);
|
||||||
|
expect(function () { parallelhash128.create(NaN, 256, ''); }).to.throwError(/block size is invalid/);
|
||||||
|
expect(function () { parallelhash128.create(0x20000000, 256, ''); }).to.throwError(/block size is invalid/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should export identical aliases', function () {
|
||||||
|
var sha3 = require('../src/sha3.js');
|
||||||
|
expect(sha3.parallelhash128).to.be(sha3.parallelhash_128);
|
||||||
|
expect(sha3.parallelhash256).to.be(sha3.parallelhash_256);
|
||||||
|
expect(sha3.parallelhashxof128).to.be(sha3.parallelhashxof_128);
|
||||||
|
expect(sha3.parallelhashxof256).to.be(sha3.parallelhashxof_256);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reject update after finalize', function () {
|
||||||
|
var hash = parallelhash128.create(8, 256, '').update([0x00]);
|
||||||
|
hash.hex();
|
||||||
|
expect(function () { hash.update([0x01]); }).to.throwError(/finalize already called/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(parallelhash256, parallelhash128, parallelhashxof256, parallelhashxof128);
|
||||||
Reference in New Issue
Block a user