Compare commits

..
29 Commits
Author SHA1 Message Date
Yi-Cyuan Chen d506b22f67 update RERADME 2026-08-06 11:38:20 +08:00
Yi-Cyuan Chen 5f95ceb733 ### Added
- KMACXOF128 and KMACXOF256 (NIST SP 800-185)
2026-07-18 10:14:36 +08:00
Yi-Cyuan Chen 01b1baf1e7 ### Added
- TupleHash128, TupleHash256, TupleHashXOF128, and TupleHashXOF256 (NIST SP 800-185)

### Fixed
- KMAC repeated output reads after finalize
2026-07-18 08:52:44 +08:00
Yi-Cyuan Chen f0ab0aec2c Merge branch 'master' of https://github.com/emn178/js-sha3 2026-07-17 16:32:05 +08:00
Yi-Cyuan Chen 951408a3aa - support ESM #42, #38
- types index.d.ts to package.json #32
2026-07-17 16:28:36 +08:00
00d3aa232f fix types (#32)
Co-authored-by: Valery Smirnov <57757211+XantreGodlike@users.noreply.github.com>
Co-authored-by: emn178 <emn178@gmail.com>
2026-07-17 15:47:58 +08:00
gkgoatandGitHub 83e468af79 support ESM (#42)
* support ESM

* Optimize
2026-07-17 15:44:06 +08:00
emn178andGitHub d1ab318829 Update README.md 2025-05-24 15:41:16 +08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
6efde1cf1b Bump @babel/traverse from 7.21.2 to 7.23.2 (#35)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.21.2 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-16 10:17:14 +08:00
Yi-Cyuan Chen a6f6da7483 ### Fixed
- Fix error in arrayBuffer when there are extra bytes #37
- fixed output if finalized.
2023-12-16 10:15:26 +08:00
iatllandGitHub 707ee7ced1 Fix error in arrayBuffer when there are extra bytes (#37) 2023-12-16 09:42:22 +08:00
Yi-Cyuan Chen 59caf17eca bump version 2023-09-16 21:32:37 +08:00
legobeatandGitHub d6325442bd refactor: simplify formatMessage internal logic (#34)
* fix: don't modify global Array and ArrayBuffer prototypes

* wip: simplify formatMessage

* wip: simplify formatMessage internal logic

* wip: simplify formatMessage internal logic

* wip: simplify formatMessage internal logic

* refactor: simplify formatMessage internal logic

* formatMessage: remove double-negation: now returns istring instead of notString

* refactor: remove double-negation of isString

* refactor: remove double-negation of isString

* add comment on formatMessage return type
2023-09-16 21:23:54 +08:00
Yi-Cyuan Chen f293b5d508 ## v0.9.1 / 2023-08-31
### Fixed
- cSHAKE empty Array bug. #24
2023-08-31 09:23:33 +08:00
Yi-Cyuan Chen dbb0ea401f ## v0.9.0 / 2023-08-30
### Fixed
- cSHAKE bug. #24
- dependencies and security issues.
2023-08-30 23:39:16 +08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5aecbd6968 Bump minimist, mocha and nyc (#28)
Removes [minimist](https://github.com/minimistjs/minimist). It's no longer used after updating ancestor dependencies [minimist](https://github.com/minimistjs/minimist), [mocha](https://github.com/mochajs/mocha) and [nyc](https://github.com/istanbuljs/nyc). These dependencies need to be updated together.


Removes `minimist`

Updates `mocha` from 2.3.4 to 10.2.0
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/2.3.4...v10.2.0)

Updates `nyc` from 11.3.0 to 15.1.0
- [Release notes](https://github.com/istanbuljs/nyc/releases)
- [Changelog](https://github.com/istanbuljs/nyc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/nyc/compare/v11.3.0...v15.1.0)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
- dependency-name: mocha
  dependency-type: direct:development
- dependency-name: nyc
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-27 10:40:15 +08:00
Yi-Cyuan Chen b39d0910cb - Added TypeScript definitions.
- Changed throw error if update after finalize
2018-08-05 15:33:12 +08:00
Micah Zoltuandemn178 1c00d97268 Adds arrayBuffer and buffer definitions. (#16)
This is based entirely on the examples in the readme.  If the examples in the readme are incorrect then this definition is also incorrect.
2018-08-02 19:45:40 +08:00
Yi-Cyuan Chen fb7e6403d9 Added
- AMD support.
- support for web worker. #13

Changed
- throw error if input type is incorrect when cSHAKE and KMAC.
- freeze hash after finalize.
2017-12-01 21:04:32 +08:00
Chen, Yi-Cyuan c43f9d1d18 update package 2017-07-03 09:01:22 +08:00
emn178andGitHub 94a2758bf7 Merge pull request #12 from isaactorresmichel/isaactorresmichel-fixfortypo
Typo on variable kmac_256 type definition.
2017-07-02 07:19:42 +08:00
Isaac Torres MichelandGitHub 540bbee16b Typo on variable kmac_256 type definition.
Typescript definition file has a typo on variable kmac_256 class type. Typ definition was not in PascalCase format. So when the file is used throws an "/js-sha3/index.d.ts (166,22): Cannot find name 'kmacHash'" error.
2017-06-29 08:48:28 -05:00
Chen, Yi-Cyuan e9084afbdf Added
- cSHAKE method.
- KMAC method.
- alias methods without underscore like shake128, keccak512.

Changed
- throw error if input type is incorrect.
2017-06-15 11:07:11 +08:00
Chen, Yi-Cyuan 5d6193d7f2 Fixed ArrayBuffer detection in old browsers. 2016-12-30 10:17:55 +08:00
Chen, Yi-Cyuan 8ae70989ae Fixed ArrayBuffer dosen't work in Webpack. 2016-12-29 09:31:53 +08:00
emn178andGitHub 035642212a Merge pull request #10 from happylynx/arraybuffer-fix
webpack & ArrayBuffer argument fix
2016-12-29 08:48:13 +08:00
happylynx 9f8c2a3fb3 Fix of recognition of ArrayBuffer parameters
If js-sha3 is loaded using 'webpack' loader then the top-most
fuction is not called with global object (`global` in node,
`window` in browsers) and thus `root.ArrayBuffer` is undefined.

This patch introduces usage of `ArrayBuffer` without `root`
prefix similary to how e.g. `Uint8Array` is already used.
2016-12-27 20:18:36 +01:00
happylynx ec2a9948f9 Test of non-empty ArrayBuffer added 2016-12-27 20:02:45 +01:00
Yi-Cyuan f34e33dc99 update README 2016-09-26 10:55:14 +08:00
27 changed files with 6396 additions and 359 deletions
-2
View File
@@ -1,2 +0,0 @@
/tests/
node_modules/
+3 -3
View File
@@ -1,3 +1,3 @@
node_modules/
covreporter
my_test
/node_modules/
/coverage/
/.nyc_output/
+7 -2
View File
@@ -1,2 +1,7 @@
my_test
covreporter
/node_modules/
/coverage/
/.nyc_output/
/tests/
.travis.yml
.npmignore
bower.json
+3 -5
View File
@@ -1,12 +1,10 @@
language: node_js
node_js:
- "0.12.15"
- "4.5"
- "6.5.0"
- "6.11.4"
- "8.6.0"
before_install:
- npm install coveralls
- npm install mocha-lcov-reporter
script: npm run-script coveralls
after_success: npm run coveralls
branches:
only:
- master
+75
View File
@@ -1,9 +1,82 @@
# Change Log
## v0.12.0 / 2026-07-18
### Added
- KMACXOF128 and KMACXOF256 (NIST SP 800-185)
## v0.11.0 / 2026-07-18
### Added
- TupleHash128, TupleHash256, TupleHashXOF128, and TupleHashXOF256 (NIST SP 800-185)
### Fixed
- KMAC repeated output reads after finalize
## v0.10.0 / 2026-07-17
### Added
- support ESM #42, #38
- types index.d.ts to package.json #32
## v0.9.3 / 2023-12-16
### Fixed
- Fix error in arrayBuffer when there are extra bytes #37
- fixed output if finalized.
## v0.9.2 / 2023-09-16
### Fixed
- don't modify global Array and ArrayBuffer prototypes. #33
- refactor: simplify formatMessage internal logic. #34
## v0.9.1 / 2023-08-31
### Fixed
- cSHAKE empty Array bug. #24
## v0.9.0 / 2023-08-30
### Fixed
- cSHAKE bug. #24
- dependencies and security issues.
## v0.8.0 / 2018-08-05
### Added
- TypeScript definitions.
### Changed
- throw error if update after finalize
## v0.7.0 / 2017-12-01
### Added
- AMD support.
- support for web worker. #13
### Changed
- throw error if input type is incorrect when cSHAKE and KMAC.
- freeze hash after finalize.
## v0.6.1 / 2017-07-03
### Fixed
- Typo on variable kmac_256 type definition. #12
## v0.6.0 / 2017-06-15
### Added
- cSHAKE method.
- KMAC method.
- alias methods without underscore like shake128, keccak512.
### Changed
- throw error if input type is incorrect.
## v0.5.7 / 2016-12-30
### Fixed
- ArrayBuffer detection in old browsers.
## v0.5.6 / 2016-12-29
### Fixed
- ArrayBuffer dosen't work in Webpack.
## v0.5.5 / 2016-09-26
### Added
- TypeScript support.
- ArrayBuffer method.
### Deprecated
- Buffer method.
@@ -30,6 +103,7 @@
## v0.4.1 / 2015-09-18
### Added
- Integer array output.
### Fixed
- Shake output incorrect when it's greater than 1088.
@@ -50,6 +124,7 @@
## v0.2.0 / 2015-04-04
### Added
- NIST's May 2014 SHA-3 version.
### Changed
- Rename original methods to keccak.
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright 2015-2016 Chen, Yi-Cyuan
Copyright 2015-2026 Chen, Yi-Cyuan
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
+132 -41
View File
@@ -4,9 +4,10 @@
[![Coverage Status](https://coveralls.io/repos/emn178/js-sha3/badge.svg?branch=master)](https://coveralls.io/r/emn178/js-sha3?branch=master)
[![NPM](https://nodei.co/npm/js-sha3.png?stars&downloads)](https://nodei.co/npm/js-sha3/)
A simple SHA-3 / Keccak / Shake hash function for JavaScript supports UTF-8 encoding.
A simple SHA-3 / Keccak / SHAKE / cSHAKE / KMAC / TupleHash hash function for JavaScript supports UTF-8 encoding.
## Notice
* v0.8.0+ will throw an error if try to update hash after finalize.
* Sha3 methods has been renamed to keccak since v0.2.0. It means that sha3 methods of v0.1.x are equal to keccak methods of v0.2.x and later.
* `buffer` method is deprecated. This maybe confuse with Buffer in node.js. Please use `arrayBuffer` instead.
@@ -19,8 +20,18 @@ A simple SHA-3 / Keccak / Shake hash function for JavaScript supports UTF-8 enco
[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-224 Online](http://emn178.github.io/online-tools/keccak_224.html)
[Shake-128 Online](http://emn178.github.io/online-tools/shake_128.html)
[Shake-256 Online](http://emn178.github.io/online-tools/shake_256.html)
[Shake128 Online](http://emn178.github.io/online-tools/shake128/)
[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/)
## Download
[Compress](https://raw.github.com/emn178/js-sha3/master/build/sha3.min.js)
@@ -42,23 +53,34 @@ sha3_512('Message to hash');
sha3_384('Message to hash');
sha3_256('Message to hash');
sha3_224('Message to hash');
keccak_512('Message to hash');
keccak_384('Message to hash');
keccak_256('Message to hash');
keccak_224('Message to hash');
shake_128('Message to hash', 256);
shake_256('Message to hash', 512);
keccak512('Message to hash');
keccak384('Message to hash');
keccak256('Message to hash');
keccak224('Message to hash');
shake128('Message to hash', 256);
shake256('Message to hash', 512);
cshake128('Message to hash', 256, 'function name', 'customization');
cshake256('Message to hash', 512, 'function name', 'customization');
kmac128('key', 'Message to hash', 256, 'customization');
kmac256('key', 'Message to hash', 512, 'customization');
kmacxof128('key', 'Message to hash', 256, 'customization');
kmacxof256('key', 'Message to hash', 512, 'customization');
tuplehash128(['abc', 'd'], 256, 'customization');
tuplehash256(['abc', 'd'], 512, 'customization');
tuplehashxof128(['abc', 'd'], 256, 'customization');
tuplehashxof256(['abc', 'd'], 512, 'customization');
// Support ArrayBuffer output
var buffer = keccak_224.buffer('Message to hash');
var arrayBuffer = keccak224.arrayBuffer('Message to hash');
// Support Array output
var buffer = keccak_224.array('Message to hash');
var bytes = keccak224.digest('Message to hash');
var bytes = keccak224.array('Message to hash');
// update hash
sha3_512.update('Message ').update('to ').update('hash').hex();
// specify shake output bits at first update
shake_128.update('Message ', 256).update('to ').update('hash').hex();
shake128.update('Message ', 256).update('to ').update('hash').hex();
// or to use create
var hash = sha3_512.create();
@@ -67,23 +89,92 @@ hash.update('...');
hash.hex();
// specify shake output bits when creating
var hash = shake_128.create(256);
var hash = shake128.create(256);
hash.update('...');
hash.update('...');
hash.hex();
// specify cshake output bits, function name and customization when creating
var hash = cshake128.create(256, 'function name', 'customization');
// specify kmac key, output bits and customization when creating
var hash = kmac128.create('key', 256, 'customization');
// TupleHash: a tuple contains zero or more input strings.
// One-shot and method-level update
tuplehash128(['abc', 'd'], 256, '');
tuplehash128.update(['abc', 'd'], 256, '').hex();
// Incremental complete inputs (each update is one tuple input string)
tuplehash128.create(256, '')
.update('abc')
.update('d')
.hex();
// Streaming a large input when its byte length is known in advance.
// beginInput + updateChunk; no endInput() is needed.
// Inputs are absorbed sequentially. TupleHash does not parallelize tuple inputs;
// use ParallelHash for parallel hashing of one large input.
var tupleHash = tuplehash128.create(256, '');
tupleHash.beginInput(3);
tupleHash.updateChunk([0x61, 0x62]);
tupleHash.updateChunk([0x63]);
tupleHash.beginInput(1);
tupleHash.updateChunk([0x64]);
tupleHash.hex();
```
### Node.js
If you use node.js, you should require the module first:
```JavaScript
sha3_512 = require('js-sha3').sha3_512;
sha3_384 = require('js-sha3').sha3_384;
sha3_256 = require('js-sha3').sha3_256;
sha3_224 = require('js-sha3').sha3_224;
keccak_512 = require('js-sha3').keccak_512;
keccak_384 = require('js-sha3').keccak_384;
keccak_256 = require('js-sha3').keccak_256;
keccak_224 = require('js-sha3').keccak_224;
shake_128 = require('js-sha3').shake_128;
shake_256 = require('js-sha3').shake_256;
const {
sha3_512,
sha3_384,
sha3_256,
sha3_224,
keccak512,
keccak384,
keccak256,
keccak224,
shake128,
shake256,
cshake128,
cshake256,
kmac128,
kmac256,
kmacxof128,
kmacxof256,
tuplehash128,
tuplehash256,
tuplehashxof128,
tuplehashxof256
} = require('js-sha3');
```
### TypeScript
If you use TypeScript, you can import like this:
```TypeScript
import {
sha3_512,
sha3_384,
sha3_256,
sha3_224,
keccak512,
keccak384,
keccak256,
keccak224,
shake128,
shake256,
cshake128,
cshake256,
kmac128,
kmac256,
kmacxof128,
kmacxof256,
tuplehash128,
tuplehash256,
tuplehashxof128,
tuplehashxof256
} from 'js-sha3';
```
## Example
@@ -125,46 +216,46 @@ sha3_224('The quick brown fox jumps over the lazy dog');
sha3_224('The quick brown fox jumps over the lazy dog.');
// 2d0708903833afabdd232a20201176e8b58c5be8a6fe74265ac54db0
keccak_512('');
keccak512('');
// 0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e
keccak_512('The quick brown fox jumps over the lazy dog');
keccak512('The quick brown fox jumps over the lazy dog');
// d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609
keccak_512('The quick brown fox jumps over the lazy dog.');
keccak512('The quick brown fox jumps over the lazy dog.');
// ab7192d2b11f51c7dd744e7b3441febf397ca07bf812cceae122ca4ded6387889064f8db9230f173f6d1ab6e24b6e50f065b039f799f5592360a6558eb52d760
keccak_384('');
keccak384('');
// 2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff
keccak_384('The quick brown fox jumps over the lazy dog');
keccak384('The quick brown fox jumps over the lazy dog');
// 283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3
keccak_384('The quick brown fox jumps over the lazy dog.');
keccak384('The quick brown fox jumps over the lazy dog.');
// 9ad8e17325408eddb6edee6147f13856ad819bb7532668b605a24a2d958f88bd5c169e56dc4b2f89ffd325f6006d820b
keccak_256('');
keccak256('');
// c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
keccak_256('The quick brown fox jumps over the lazy dog');
keccak256('The quick brown fox jumps over the lazy dog');
// 4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15
keccak_256('The quick brown fox jumps over the lazy dog.');
keccak256('The quick brown fox jumps over the lazy dog.');
// 578951e24efd62a3d63a86f7cd19aaa53c898fe287d2552133220370240b572d
keccak_224('');
keccak224('');
// f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd
keccak_224('The quick brown fox jumps over the lazy dog');
keccak224('The quick brown fox jumps over the lazy dog');
// 310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe
keccak_224('The quick brown fox jumps over the lazy dog.');
keccak224('The quick brown fox jumps over the lazy dog.');
// c59d4eaeac728671c635ff645014e2afa935bebffdb5fbd207ffdeab
shake_128('', 256);
shake128('', 256);
// 7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26
shake_256('', 512);
shake256('', 512);
// 46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be
```
It also supports UTF-8 encoding:
@@ -183,16 +274,16 @@ sha3_256('中文');
sha3_224('中文');
// 106d169e10b61c2a2a05554d3e631ec94467f8316640f29545d163ee
keccak_512('中文');
keccak512('中文');
// 2f6a1bd50562230229af34b0ccf46b8754b89d23ae2c5bf7840b4acfcef86f87395edc0a00b2bfef53bafebe3b79de2e3e01cbd8169ddbb08bde888dcc893524
keccak_384('中文');
keccak384('中文');
// 743f64bb7544c6ed923be4741b738dde18b7cee384a3a09c4e01acaaac9f19222cdee137702bd3aa05dc198373d87d6c
keccak_256('中文');
keccak256('中文');
// 70a2b6579047f0a977fcb5e9120a4e07067bea9abb6916fbc2d13ffb9a4e4eee
keccak_224('中文');
keccak224('中文');
// f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd
```
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "js-sha3",
"version": "0.5.5",
"version": "0.12.0",
"main": ["src/sha3.js"],
"ignore": [
"samples",
+3 -16
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+842
View File
@@ -0,0 +1,842 @@
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
var sha3$1 = {exports: {}};
/**
* [js-sha3]{@link https://github.com/emn178/js-sha3}
*
* @version 0.12.0
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2015-2026
* @license MIT
*/
(function (module) {
/*jslint bitwise: true */
(function () {
var INPUT_ERROR = 'input is invalid type';
var FINALIZE_ERROR = 'finalize already called';
var TUPLE_ACTIVE_ERROR = 'no active tuple input';
var TUPLE_INCOMPLETE_ERROR = 'tuple input is incomplete';
var TUPLE_LENGTH_ERROR = 'tuple input exceeds declared length';
var TUPLE_BYTE_LENGTH_ERROR = 'tuple input byte length is invalid';
var WINDOW = typeof window === 'object';
var root = WINDOW ? window : {};
if (root.JS_SHA3_NO_WINDOW) {
WINDOW = false;
}
var WEB_WORKER = !WINDOW && typeof self === 'object';
var NODE_JS = !root.JS_SHA3_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
if (NODE_JS) {
root = commonjsGlobal;
} else if (WEB_WORKER) {
root = self;
}
var COMMON_JS = !root.JS_SHA3_NO_COMMON_JS && 'object' === 'object' && module.exports;
var ARRAY_BUFFER = !root.JS_SHA3_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
var HEX_CHARS = '0123456789abcdef'.split('');
var SHAKE_PADDING = [31, 7936, 2031616, 520093696];
var CSHAKE_PADDING = [4, 1024, 262144, 67108864];
var KECCAK_PADDING = [1, 256, 65536, 16777216];
var PADDING = [6, 1536, 393216, 100663296];
var SHIFT = [0, 8, 16, 24];
var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649,
0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0,
2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771,
2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648,
2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648];
var BITS = [224, 256, 384, 512];
var SHAKE_BITS = [128, 256];
var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array', 'digest'];
var CSHAKE_BYTEPAD = {
'128': 168,
'256': 136
};
var isArray = root.JS_SHA3_NO_NODE_JS || !Array.isArray
? function (obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
: Array.isArray;
var isView = (ARRAY_BUFFER && (root.JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView))
? function (obj) {
return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
}
: ArrayBuffer.isView;
// [message: string, isString: bool]
var formatMessage = function (message) {
var type = typeof message;
if (type === 'string') {
return [message, true];
}
if (type !== 'object' || message === null) {
throw new Error(INPUT_ERROR);
}
if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
return [new Uint8Array(message), false];
}
if (!isArray(message) && !isView(message)) {
throw new Error(INPUT_ERROR);
}
return [message, false];
};
var empty = function (message) {
return formatMessage(message)[0].length === 0;
};
var cloneArray = function (array) {
var newArray = [];
for (var i = 0; i < array.length; ++i) {
newArray[i] = array[i];
}
return newArray;
};
var createOutputMethod = function (bits, padding, outputType) {
return function (message) {
return new Keccak(bits, padding, bits).update(message)[outputType]();
};
};
var createShakeOutputMethod = function (bits, padding, outputType) {
return function (message, outputBits) {
return new Keccak(bits, padding, outputBits).update(message)[outputType]();
};
};
var createCshakeOutputMethod = function (bits, padding, outputType) {
return function (message, outputBits, n, s) {
return methods['cshake' + bits].update(message, outputBits, n, s)[outputType]();
};
};
var createKmacOutputMethod = function (bits, padding, xof, outputType) {
return function (key, message, outputBits, s) {
return methods[(xof ? 'kmacxof' : 'kmac') + bits].update(key, message, outputBits, s)[outputType]();
};
};
var createTupleHashOutputMethod = function (bits, padding, xof, outputType) {
return function (inputs, outputBits, s) {
return methods[(xof ? 'tuplehashxof' : 'tuplehash') + bits].update(inputs, outputBits, s)[outputType]();
};
};
var createOutputMethods = function (method, createMethod, bits, padding) {
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createMethod(bits, padding, type);
}
return method;
};
var createMethod = function (bits, padding) {
var method = createOutputMethod(bits, padding, 'hex');
method.create = function () {
return new Keccak(bits, padding, bits);
};
method.update = function (message) {
return method.create().update(message);
};
return createOutputMethods(method, createOutputMethod, bits, padding);
};
var createShakeMethod = function (bits, padding) {
var method = createShakeOutputMethod(bits, padding, 'hex');
method.create = function (outputBits) {
return new Keccak(bits, padding, outputBits);
};
method.update = function (message, outputBits) {
return method.create(outputBits).update(message);
};
return createOutputMethods(method, createShakeOutputMethod, bits, padding);
};
var createCshakeMethod = function (bits, padding) {
var w = CSHAKE_BYTEPAD[bits];
var method = createCshakeOutputMethod(bits, padding, 'hex');
method.create = function (outputBits, n, s) {
if (empty(n) && empty(s)) {
return methods['shake' + bits].create(outputBits);
} else {
return new Keccak(bits, padding, outputBits).bytepad([n, s], w);
}
};
method.update = function (message, outputBits, n, s) {
return method.create(outputBits, n, s).update(message);
};
return createOutputMethods(method, createCshakeOutputMethod, bits, padding);
};
var createKmacMethod = function (bits, padding, xof) {
var w = CSHAKE_BYTEPAD[bits];
var method = createKmacOutputMethod(bits, padding, xof, 'hex');
method.create = function (key, outputBits, s) {
return new Kmac(bits, padding, outputBits, xof).bytepad(['KMAC', s], w).bytepad([key], w);
};
method.update = function (key, message, outputBits, s) {
return method.create(key, outputBits, s).update(message);
};
return createOutputMethods(method, function (b, p, outputType) {
return createKmacOutputMethod(b, p, xof, outputType);
}, bits, padding);
};
var createTupleHashMethod = function (bits, padding, xof) {
var w = CSHAKE_BYTEPAD[bits];
var method = createTupleHashOutputMethod(bits, padding, xof, 'hex');
method.create = function (outputBits, s) {
return new TupleHash(bits, padding, outputBits, xof).bytepad(['TupleHash', s], w);
};
method.update = function (inputs, outputBits, s) {
if (!isArray(inputs)) {
throw new Error(INPUT_ERROR);
}
var hash = method.create(outputBits, s);
for (var i = 0; i < inputs.length; ++i) {
hash.update(inputs[i]);
}
return hash;
};
return createOutputMethods(method, function (b, p, outputType) {
return createTupleHashOutputMethod(b, p, xof, outputType);
}, bits, padding);
};
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 },
{ name: 'cshake', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: createCshakeMethod },
{ name: 'kmac', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
return createKmacMethod(bits, padding, false);
}},
{ name: 'kmacxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
return createKmacMethod(bits, padding, true);
}},
{ name: 'tuplehash', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
return createTupleHashMethod(bits, padding, false);
}},
{ name: 'tuplehashxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
return createTupleHashMethod(bits, padding, true);
}}
];
var methods = {}, methodNames = [];
for (var i = 0; i < algorithms.length; ++i) {
var algorithm = algorithms[i];
var bits = algorithm.bits;
for (var j = 0; j < bits.length; ++j) {
var methodName = algorithm.name + '_' + bits[j];
methodNames.push(methodName);
methods[methodName] = algorithm.createMethod(bits[j], algorithm.padding);
if (algorithm.name !== 'sha3') {
var newMethodName = algorithm.name + bits[j];
methodNames.push(newMethodName);
methods[newMethodName] = methods[methodName];
}
}
}
function Keccak(bits, padding, outputBits) {
this.blocks = [];
this.s = [];
this.padding = padding;
this.outputBits = outputBits;
this.reset = true;
this.finalized = false;
this.block = 0;
this.start = 0;
this.blockCount = (1600 - (bits << 1)) >> 5;
this.byteCount = this.blockCount << 2;
this.outputBlocks = outputBits >> 5;
this.extraBytes = (outputBits & 31) >> 3;
for (var i = 0; i < 50; ++i) {
this.s[i] = 0;
}
}
Keccak.prototype.update = function (message) {
if (this.finalized) {
throw new Error(FINALIZE_ERROR);
}
var result = formatMessage(message);
message = result[0];
var isString = result[1];
var blocks = this.blocks, byteCount = this.byteCount, length = message.length,
blockCount = this.blockCount, index = 0, s = this.s, i, code;
while (index < length) {
if (this.reset) {
this.reset = false;
blocks[0] = this.block;
for (i = 1; i < blockCount + 1; ++i) {
blocks[i] = 0;
}
}
if (isString) {
for (i = this.start; index < length && i < byteCount; ++index) {
code = message.charCodeAt(index);
if (code < 0x80) {
blocks[i >> 2] |= code << SHIFT[i++ & 3];
} else if (code < 0x800) {
blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else if (code < 0xd800 || code >= 0xe000) {
blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
}
}
} else {
for (i = this.start; index < length && i < byteCount; ++index) {
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
}
}
this.lastByteIndex = i;
if (i >= byteCount) {
this.start = i - byteCount;
this.block = blocks[blockCount];
for (i = 0; i < blockCount; ++i) {
s[i] ^= blocks[i];
}
f(s);
this.reset = true;
} else {
this.start = i;
}
}
return this;
};
Keccak.prototype.encode = function (x, right) {
var o = x & 255, n = 1;
var bytes = [o];
x = x >> 8;
o = x & 255;
while (o > 0) {
bytes.unshift(o);
x = x >> 8;
o = x & 255;
++n;
}
if (right) {
bytes.push(n);
} else {
bytes.unshift(n);
}
Keccak.prototype.update.call(this, bytes);
return bytes.length;
};
Keccak.prototype.encodeString = function (str) {
var result = formatMessage(str);
str = result[0];
var isString = result[1];
var bytes = 0, length = str.length;
if (isString) {
for (var i = 0; i < str.length; ++i) {
var code = str.charCodeAt(i);
if (code < 0x80) {
bytes += 1;
} else if (code < 0x800) {
bytes += 2;
} else if (code < 0xd800 || code >= 0xe000) {
bytes += 3;
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff));
bytes += 4;
}
}
} else {
bytes = length;
}
bytes += this.encode(bytes * 8);
Keccak.prototype.update.call(this, str);
return bytes;
};
Keccak.prototype.bytepad = function (strs, w) {
var bytes = this.encode(w);
for (var i = 0; i < strs.length; ++i) {
bytes += this.encodeString(strs[i]);
}
var paddingBytes = (w - bytes % w) % w;
var zeros = [];
zeros.length = paddingBytes;
Keccak.prototype.update.call(this, zeros);
return this;
};
Keccak.prototype.finalize = function () {
if (this.finalized) {
return;
}
this.finalized = true;
var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s;
blocks[i >> 2] |= this.padding[i & 3];
if (this.lastByteIndex === this.byteCount) {
blocks[0] = blocks[blockCount];
for (i = 1; i < blockCount + 1; ++i) {
blocks[i] = 0;
}
}
blocks[blockCount - 1] |= 0x80000000;
for (i = 0; i < blockCount; ++i) {
s[i] ^= blocks[i];
}
f(s);
};
Keccak.prototype.toString = Keccak.prototype.hex = function () {
this.finalize();
var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
extraBytes = this.extraBytes, i = 0, j = 0;
var hex = '', block;
while (j < outputBlocks) {
for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
block = s[i];
hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] +
HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] +
HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] +
HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F];
}
if (j % blockCount === 0) {
s = cloneArray(s);
f(s);
i = 0;
}
}
if (extraBytes) {
block = s[i];
hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F];
if (extraBytes > 1) {
hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F];
}
if (extraBytes > 2) {
hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F];
}
}
return hex;
};
Keccak.prototype.arrayBuffer = function () {
this.finalize();
var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
extraBytes = this.extraBytes, i = 0, j = 0;
var bytes = this.outputBits >> 3;
var buffer;
if (extraBytes) {
buffer = new ArrayBuffer((outputBlocks + 1) << 2);
} else {
buffer = new ArrayBuffer(bytes);
}
var array = new Uint32Array(buffer);
while (j < outputBlocks) {
for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
array[j] = s[i];
}
if (j % blockCount === 0) {
s = cloneArray(s);
f(s);
}
}
if (extraBytes) {
array[j] = s[i];
buffer = buffer.slice(0, bytes);
}
return buffer;
};
Keccak.prototype.buffer = Keccak.prototype.arrayBuffer;
Keccak.prototype.digest = Keccak.prototype.array = function () {
this.finalize();
var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
extraBytes = this.extraBytes, i = 0, j = 0;
var array = [], offset, block;
while (j < outputBlocks) {
for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
offset = j << 2;
block = s[i];
array[offset] = block & 0xFF;
array[offset + 1] = (block >> 8) & 0xFF;
array[offset + 2] = (block >> 16) & 0xFF;
array[offset + 3] = (block >> 24) & 0xFF;
}
if (j % blockCount === 0) {
s = cloneArray(s);
f(s);
}
}
if (extraBytes) {
offset = j << 2;
block = s[i];
array[offset] = block & 0xFF;
if (extraBytes > 1) {
array[offset + 1] = (block >> 8) & 0xFF;
}
if (extraBytes > 2) {
array[offset + 2] = (block >> 16) & 0xFF;
}
}
return array;
};
function Kmac(bits, padding, outputBits, xof) {
Keccak.call(this, bits, padding, outputBits);
this.xof = xof;
}
Kmac.prototype = new Keccak();
Kmac.prototype.finalize = function () {
if (!this.finalized) {
this.encode(this.xof ? 0 : this.outputBits, true);
}
return Keccak.prototype.finalize.call(this);
};
function TupleHash(bits, padding, outputBits, xof) {
Kmac.call(this, bits, padding, outputBits, xof);
this.inputActive = false;
this.inputBytesRemaining = 0;
}
TupleHash.prototype = new Kmac();
TupleHash.prototype.getMessageByteLength = function (message) {
var result = formatMessage(message);
message = result[0];
if (!result[1]) {
return message.length;
}
var bytes = 0;
for (var i = 0; i < message.length; ++i) {
var code = message.charCodeAt(i);
if (code < 0x80) {
bytes += 1;
} else if (code < 0x800) {
bytes += 2;
} else if (code < 0xd800 || code >= 0xe000) {
bytes += 3;
} else {
++i;
bytes += 4;
}
}
return bytes;
};
TupleHash.prototype.beginInput = function (byteLength) {
if (this.inputActive) {
throw new Error(TUPLE_INCOMPLETE_ERROR);
}
if (typeof byteLength !== 'number' || !isFinite(byteLength) || byteLength < 0 ||
Math.floor(byteLength) !== byteLength || byteLength > 0x0fffffff) {
throw new Error(TUPLE_BYTE_LENGTH_ERROR);
}
this.encode(byteLength * 8, false);
if (byteLength !== 0) {
this.inputActive = true;
this.inputBytesRemaining = byteLength;
}
return this;
};
TupleHash.prototype._updateChunk = function (message, byteLength) {
Kmac.prototype.update.call(this, message);
this.inputBytesRemaining -= byteLength;
if (this.inputBytesRemaining === 0) {
this.inputActive = false;
}
return this;
};
TupleHash.prototype.updateChunk = function (message) {
if (!this.inputActive) {
throw new Error(TUPLE_ACTIVE_ERROR);
}
var byteLength = this.getMessageByteLength(message);
if (byteLength > this.inputBytesRemaining) {
throw new Error(TUPLE_LENGTH_ERROR);
}
return this._updateChunk(message, byteLength);
};
TupleHash.prototype.update = function (message) {
var byteLength = this.getMessageByteLength(message);
this.beginInput(byteLength);
return this._updateChunk(message, byteLength);
};
TupleHash.prototype.finalize = function () {
if (this.inputActive) {
throw new Error(TUPLE_INCOMPLETE_ERROR);
}
return Kmac.prototype.finalize.call(this);
};
var f = function (s) {
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,
b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33,
b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49;
for (n = 0; n < 48; n += 2) {
c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40];
c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41];
c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42];
c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43];
c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44];
c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45];
c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46];
c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47];
c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48];
c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49];
h = c8 ^ ((c2 << 1) | (c3 >>> 31));
l = c9 ^ ((c3 << 1) | (c2 >>> 31));
s[0] ^= h;
s[1] ^= l;
s[10] ^= h;
s[11] ^= l;
s[20] ^= h;
s[21] ^= l;
s[30] ^= h;
s[31] ^= l;
s[40] ^= h;
s[41] ^= l;
h = c0 ^ ((c4 << 1) | (c5 >>> 31));
l = c1 ^ ((c5 << 1) | (c4 >>> 31));
s[2] ^= h;
s[3] ^= l;
s[12] ^= h;
s[13] ^= l;
s[22] ^= h;
s[23] ^= l;
s[32] ^= h;
s[33] ^= l;
s[42] ^= h;
s[43] ^= l;
h = c2 ^ ((c6 << 1) | (c7 >>> 31));
l = c3 ^ ((c7 << 1) | (c6 >>> 31));
s[4] ^= h;
s[5] ^= l;
s[14] ^= h;
s[15] ^= l;
s[24] ^= h;
s[25] ^= l;
s[34] ^= h;
s[35] ^= l;
s[44] ^= h;
s[45] ^= l;
h = c4 ^ ((c8 << 1) | (c9 >>> 31));
l = c5 ^ ((c9 << 1) | (c8 >>> 31));
s[6] ^= h;
s[7] ^= l;
s[16] ^= h;
s[17] ^= l;
s[26] ^= h;
s[27] ^= l;
s[36] ^= h;
s[37] ^= l;
s[46] ^= h;
s[47] ^= l;
h = c6 ^ ((c0 << 1) | (c1 >>> 31));
l = c7 ^ ((c1 << 1) | (c0 >>> 31));
s[8] ^= h;
s[9] ^= l;
s[18] ^= h;
s[19] ^= l;
s[28] ^= h;
s[29] ^= l;
s[38] ^= h;
s[39] ^= l;
s[48] ^= h;
s[49] ^= l;
b0 = s[0];
b1 = s[1];
b32 = (s[11] << 4) | (s[10] >>> 28);
b33 = (s[10] << 4) | (s[11] >>> 28);
b14 = (s[20] << 3) | (s[21] >>> 29);
b15 = (s[21] << 3) | (s[20] >>> 29);
b46 = (s[31] << 9) | (s[30] >>> 23);
b47 = (s[30] << 9) | (s[31] >>> 23);
b28 = (s[40] << 18) | (s[41] >>> 14);
b29 = (s[41] << 18) | (s[40] >>> 14);
b20 = (s[2] << 1) | (s[3] >>> 31);
b21 = (s[3] << 1) | (s[2] >>> 31);
b2 = (s[13] << 12) | (s[12] >>> 20);
b3 = (s[12] << 12) | (s[13] >>> 20);
b34 = (s[22] << 10) | (s[23] >>> 22);
b35 = (s[23] << 10) | (s[22] >>> 22);
b16 = (s[33] << 13) | (s[32] >>> 19);
b17 = (s[32] << 13) | (s[33] >>> 19);
b48 = (s[42] << 2) | (s[43] >>> 30);
b49 = (s[43] << 2) | (s[42] >>> 30);
b40 = (s[5] << 30) | (s[4] >>> 2);
b41 = (s[4] << 30) | (s[5] >>> 2);
b22 = (s[14] << 6) | (s[15] >>> 26);
b23 = (s[15] << 6) | (s[14] >>> 26);
b4 = (s[25] << 11) | (s[24] >>> 21);
b5 = (s[24] << 11) | (s[25] >>> 21);
b36 = (s[34] << 15) | (s[35] >>> 17);
b37 = (s[35] << 15) | (s[34] >>> 17);
b18 = (s[45] << 29) | (s[44] >>> 3);
b19 = (s[44] << 29) | (s[45] >>> 3);
b10 = (s[6] << 28) | (s[7] >>> 4);
b11 = (s[7] << 28) | (s[6] >>> 4);
b42 = (s[17] << 23) | (s[16] >>> 9);
b43 = (s[16] << 23) | (s[17] >>> 9);
b24 = (s[26] << 25) | (s[27] >>> 7);
b25 = (s[27] << 25) | (s[26] >>> 7);
b6 = (s[36] << 21) | (s[37] >>> 11);
b7 = (s[37] << 21) | (s[36] >>> 11);
b38 = (s[47] << 24) | (s[46] >>> 8);
b39 = (s[46] << 24) | (s[47] >>> 8);
b30 = (s[8] << 27) | (s[9] >>> 5);
b31 = (s[9] << 27) | (s[8] >>> 5);
b12 = (s[18] << 20) | (s[19] >>> 12);
b13 = (s[19] << 20) | (s[18] >>> 12);
b44 = (s[29] << 7) | (s[28] >>> 25);
b45 = (s[28] << 7) | (s[29] >>> 25);
b26 = (s[38] << 8) | (s[39] >>> 24);
b27 = (s[39] << 8) | (s[38] >>> 24);
b8 = (s[48] << 14) | (s[49] >>> 18);
b9 = (s[49] << 14) | (s[48] >>> 18);
s[0] = b0 ^ (~b2 & b4);
s[1] = b1 ^ (~b3 & b5);
s[10] = b10 ^ (~b12 & b14);
s[11] = b11 ^ (~b13 & b15);
s[20] = b20 ^ (~b22 & b24);
s[21] = b21 ^ (~b23 & b25);
s[30] = b30 ^ (~b32 & b34);
s[31] = b31 ^ (~b33 & b35);
s[40] = b40 ^ (~b42 & b44);
s[41] = b41 ^ (~b43 & b45);
s[2] = b2 ^ (~b4 & b6);
s[3] = b3 ^ (~b5 & b7);
s[12] = b12 ^ (~b14 & b16);
s[13] = b13 ^ (~b15 & b17);
s[22] = b22 ^ (~b24 & b26);
s[23] = b23 ^ (~b25 & b27);
s[32] = b32 ^ (~b34 & b36);
s[33] = b33 ^ (~b35 & b37);
s[42] = b42 ^ (~b44 & b46);
s[43] = b43 ^ (~b45 & b47);
s[4] = b4 ^ (~b6 & b8);
s[5] = b5 ^ (~b7 & b9);
s[14] = b14 ^ (~b16 & b18);
s[15] = b15 ^ (~b17 & b19);
s[24] = b24 ^ (~b26 & b28);
s[25] = b25 ^ (~b27 & b29);
s[34] = b34 ^ (~b36 & b38);
s[35] = b35 ^ (~b37 & b39);
s[44] = b44 ^ (~b46 & b48);
s[45] = b45 ^ (~b47 & b49);
s[6] = b6 ^ (~b8 & b0);
s[7] = b7 ^ (~b9 & b1);
s[16] = b16 ^ (~b18 & b10);
s[17] = b17 ^ (~b19 & b11);
s[26] = b26 ^ (~b28 & b20);
s[27] = b27 ^ (~b29 & b21);
s[36] = b36 ^ (~b38 & b30);
s[37] = b37 ^ (~b39 & b31);
s[46] = b46 ^ (~b48 & b40);
s[47] = b47 ^ (~b49 & b41);
s[8] = b8 ^ (~b0 & b2);
s[9] = b9 ^ (~b1 & b3);
s[18] = b18 ^ (~b10 & b12);
s[19] = b19 ^ (~b11 & b13);
s[28] = b28 ^ (~b20 & b22);
s[29] = b29 ^ (~b21 & b23);
s[38] = b38 ^ (~b30 & b32);
s[39] = b39 ^ (~b31 & b33);
s[48] = b48 ^ (~b40 & b42);
s[49] = b49 ^ (~b41 & b43);
s[0] ^= RC[n];
s[1] ^= RC[n + 1];
}
};
if (COMMON_JS) {
module.exports = methods;
} else {
for (i = 0; i < methodNames.length; ++i) {
root[methodNames[i]] = methods[methodNames[i]];
}
}
})();
} (sha3$1));
var sha3Exports = sha3$1.exports;
var sha3 = /*@__PURE__*/getDefaultExportFromCjs(sha3Exports);
const {
sha3_224,
sha3_256,
sha3_384,
sha3_512,
keccak_224,
keccak_256,
keccak_384,
keccak_512,
keccak224,
keccak256,
keccak384,
keccak512,
shake_128,
shake_256,
shake128,
shake256,
cshake_128,
cshake_256,
cshake128,
cshake256,
kmac_128,
kmac_256,
kmac128,
kmac256,
kmacxof_128,
kmacxof_256,
kmacxof128,
kmacxof256,
tuplehash_128,
tuplehash_256,
tuplehash128,
tuplehash256,
tuplehashxof_128,
tuplehashxof_256,
tuplehashxof128,
tuplehashxof256
} = 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 };
Vendored
+327
View File
@@ -42,6 +42,34 @@ interface Hash {
*/
(message: Message): string;
/**
* Hash and return hex string.
*
* @param message The message you want to hash.
*/
hex(message: Message): string;
/**
* Hash and return ArrayBuffer.
*
* @param message The message you want to hash.
*/
arrayBuffer(message: Message): ArrayBuffer;
/**
* Hash and return integer array.
*
* @param message The message you want to hash.
*/
digest(message: Message): number[];
/**
* Hash and return integer array.
*
* @param message The message you want to hash.
*/
array(message: Message): number[];
/**
* Create a hash object.
*/
@@ -64,10 +92,43 @@ interface ShakeHash {
*/
(message: Message, outputBits: number): string;
/**
* Hash and return hex string.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
*/
hex(message: Message, outputBits: number): string;
/**
* Hash and return ArrayBuffer.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
*/
arrayBuffer(message: Message, outputBits: number): ArrayBuffer;
/**
* Hash and return integer array.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
*/
digest(message: Message, outputBits: number): number[];
/**
* Hash and return integer array.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
*/
array(message: Message, outputBits: number): number[];
/**
* Create a hash object.
*
* @param outputBits The length of output.
* @param outputBits The length of output.
*/
create(outputBits: number): Hasher;
@@ -80,6 +141,246 @@ interface ShakeHash {
update(message: Message, outputBits: number): Hasher;
}
interface CshakeHash {
/**
* Hash and return hex string.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param functionName The function name string.
* @param customization The customization string.
*/
(message: Message, outputBits: number, functionName: Message, customization: Message): string;
/**
* Hash and return hex string.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param functionName The function name string.
* @param customization The customization string.
*/
hex(message: Message, outputBits: number, functionName: Message, customization: Message): string;
/**
* Hash and return ArrayBuffer.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param functionName The function name string.
* @param customization The customization string.
*/
arrayBuffer(message: Message, outputBits: number, functionName: Message, customization: Message): ArrayBuffer;
/**
* Hash and return integer array.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param functionName The function name string.
* @param customization The customization string.
*/
digest(message: Message, outputBits: number, functionName: Message, customization: Message): number[];
/**
* Hash and return integer array.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param functionName The function name string.
* @param customization The customization string.
*/
array(message: Message, outputBits: number, functionName: Message, customization: Message): number[];
/**
* Create a hash object.
*
* @param outputBits The length of output.
* @param outputBits The length of output.
*/
create(outputBits: number): Hasher;
/**
* Create a hash object.
*
* @param outputBits The length of output.
* @param functionName The function name string.
* @param customization The customization string.
*/
create(outputBits: number, functionName: Message, customization: Message): Hasher;
/**
* Create a hash object and hash message.
*
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param functionName The function name string.
* @param customization The customization string.
*/
update(message: Message, outputBits: number, functionName: Message, customization: Message): Hasher;
}
interface KmacHash {
/**
* Hash and return hex string.
*
* @param key The key string.
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param customization The customization string.
*/
(key: Message, message: Message, outputBits: number, customization: Message): string;
/**
* Hash and return hex string.
*
* @param key The key string.
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param customization The customization string.
*/
hex(key: Message, message: Message, outputBits: number, customization: Message): string;
/**
* Hash and return ArrayBuffer.
*
* @param key The key string.
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param customization The customization string.
*/
arrayBuffer(key: Message, message: Message, outputBits: number, customization: Message): ArrayBuffer;
/**
* Hash and return integer array.
*
* @param key The key string.
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param customization The customization string.
*/
digest(key: Message, message: Message, outputBits: number, customization: Message): number[];
/**
* Hash and return integer array.
*
* @param key The key string.
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param customization The customization string.
*/
array(key: Message, message: Message, outputBits: number, customization: Message): number[];
/**
* Create a hash object.
*
* @param key The key string.
* @param outputBits The length of output.
* @param customization The customization string.
*/
create(key: Message, outputBits: number, customization: Message): Hasher;
/**
* Create a hash object and hash message.
*
* @param key The key string.
* @param message The message you want to hash.
* @param outputBits The length of output.
* @param customization The customization string.
*/
update(key: Message, message: Message, outputBits: number, customization: Message): Hasher;
}
type TupleInput = Message[];
interface TupleHash extends Hasher {
/**
* Start a streaming tuple input with a known UTF-8/binary byte length.
*
* @param byteLength The byte length of the input that will follow through updateChunk().
*/
beginInput(byteLength: number): TupleHash;
/**
* Absorb part of the active streaming tuple input.
*
* @param message The next message chunk.
*/
updateChunk(message: Message): TupleHash;
/**
* Append one complete tuple input string.
* Equivalent to beginInput(byteLength) followed by updateChunk(message).
*
* @param message The input string to encode and absorb.
*/
update(message: Message): TupleHash;
}
interface TupleHashMethod {
/**
* Hash a tuple and return hex string.
*
* @param inputs The tuple of input strings.
* @param outputBits The length of output.
* @param customization The customization string.
*/
(inputs: TupleInput, outputBits: number, customization: Message): string;
/**
* Hash a tuple and return hex string.
*
* @param inputs The tuple of input strings.
* @param outputBits The length of output.
* @param customization The customization string.
*/
hex(inputs: TupleInput, outputBits: number, customization: Message): string;
/**
* Hash a tuple and return ArrayBuffer.
*
* @param inputs The tuple of input strings.
* @param outputBits The length of output.
* @param customization The customization string.
*/
arrayBuffer(inputs: TupleInput, outputBits: number, customization: Message): ArrayBuffer;
/**
* Hash a tuple and return integer array.
*
* @param inputs The tuple of input strings.
* @param outputBits The length of output.
* @param customization The customization string.
*/
digest(inputs: TupleInput, outputBits: number, customization: Message): number[];
/**
* Hash a tuple and return integer array.
*
* @param inputs The tuple of input strings.
* @param outputBits The length of output.
* @param customization The customization string.
*/
array(inputs: TupleInput, outputBits: number, customization: Message): number[];
/**
* Create a TupleHash object.
*
* @param outputBits The length of output.
* @param customization The customization string.
*/
create(outputBits: number, customization: Message): TupleHash;
/**
* Create a TupleHash object and absorb the given tuple inputs.
*
* @param inputs The tuple of input strings.
* @param outputBits The length of output.
* @param customization The customization string.
*/
update(inputs: TupleInput, outputBits: number, customization: Message): TupleHash;
}
export var sha3_512: Hash;
export var sha3_384: Hash;
export var sha3_256: Hash;
@@ -88,5 +389,31 @@ export var keccak_512: Hash;
export var keccak_384: Hash;
export var keccak_256: Hash;
export var keccak_224: Hash;
export var keccak512: Hash;
export var keccak384: Hash;
export var keccak256: Hash;
export var keccak224: Hash;
export var shake_128: ShakeHash;
export var shake_256: ShakeHash;
export var shake128: ShakeHash;
export var shake256: ShakeHash;
export var cshake_128: CshakeHash;
export var cshake_256: CshakeHash;
export var cshake128: CshakeHash;
export var cshake256: CshakeHash;
export var kmac_128: KmacHash;
export var kmac_256: KmacHash;
export var kmac128: KmacHash;
export var kmac256: KmacHash;
export var kmacxof_128: KmacHash;
export var kmacxof_256: KmacHash;
export var kmacxof128: KmacHash;
export var kmacxof256: KmacHash;
export var tuplehash_128: TupleHashMethod;
export var tuplehash_256: TupleHashMethod;
export var tuplehash128: TupleHashMethod;
export var tuplehash256: TupleHashMethod;
export var tuplehashxof_128: TupleHashMethod;
export var tuplehashxof_256: TupleHashMethod;
export var tuplehashxof128: TupleHashMethod;
export var tuplehashxof256: TupleHashMethod;
+3505
View File
File diff suppressed because it is too large Load Diff
+36 -7
View File
@@ -1,17 +1,38 @@
{
"name": "js-sha3",
"version": "0.5.5",
"description": "A simple SHA-3 / Keccak / Shake hash function for JavaScript supports UTF-8 encoding.",
"version": "0.12.0",
"description": "A simple SHA-3 / Keccak / SHAKE / cSHAKE / KMAC / TupleHash hash function for JavaScript supports UTF-8 encoding.",
"main": "src/sha3.js",
"typings": "index",
"module": "build/sha3.mjs",
"exports": {
".": {
"types": "./index.d.ts",
"import": "./build/sha3.mjs",
"require": "./src/sha3.js",
"default": "./src/sha3.js"
},
"./src/sha3.js": "./src/sha3.js",
"./build/sha3.min.js": "./build/sha3.min.js",
"./build/sha3.mjs": "./build/sha3.mjs",
"./build/sha3.min.mjs": "./build/sha3.min.mjs",
"./package.json": "./package.json"
},
"types": "./index.d.ts",
"devDependencies": {
"@rollup/plugin-commonjs": "^28.0.5",
"@rollup/plugin-terser": "^1.0.0",
"expect.js": "~0.3.1",
"jscoverage": "~0.5.9",
"mocha": "~2.3.2"
"mocha": "^11.7.6",
"nyc": "^15.1.0",
"rollup": "^4.43.0",
"tiny-worker": "^2.3.0",
"uglify-js": "^3.1.9"
},
"scripts": {
"test": "mocha tests/node-test.js -r jscoverage",
"coveralls": "mocha tests/node-test.js -R mocha-lcov-reporter -r jscoverage | coveralls"
"test": "nyc mocha tests/node-test.js",
"report": "nyc --reporter=html --reporter=text mocha tests/node-test.js",
"coveralls": "nyc report --reporter=text-lcov | coveralls",
"build": "rollup -c && uglifyjs src/sha3.js -c -m --comments --output build/sha3.min.js"
},
"repository": {
"type": "git",
@@ -21,6 +42,9 @@
"sha3",
"keccak",
"shake",
"cshake",
"kmac",
"tuplehash",
"hash",
"encryption",
"cryptography",
@@ -31,5 +55,10 @@
"homepage": "https://github.com/emn178/js-sha3",
"bugs": {
"url": "https://github.com/emn178/js-sha3/issues"
},
"nyc": {
"exclude": [
"tests"
]
}
}
+23
View File
@@ -0,0 +1,23 @@
import commonjs from '@rollup/plugin-commonjs';
import terser from '@rollup/plugin-terser';
export default [
{
input: 'src/sha3.mjs',
output: {
file: 'build/sha3.mjs',
format: 'es'
},
plugins: [commonjs({
strictRequires: false
})]
},
{
input: 'build/sha3.mjs',
output: {
file: 'build/sha3.min.mjs',
format: 'es'
},
plugins: [terser()]
}
];
+361 -43
View File
@@ -1,21 +1,39 @@
/**
* [js-sha3]{@link https://github.com/emn178/js-sha3}
*
* @version 0.5.5
* @version 0.12.0
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2015-2016
* @copyright Chen, Yi-Cyuan 2015-2026
* @license MIT
*/
(function (root) {
/*jslint bitwise: true */
(function () {
'use strict';
var NODE_JS = typeof process == 'object' && process.versions && process.versions.node;
var INPUT_ERROR = 'input is invalid type';
var FINALIZE_ERROR = 'finalize already called';
var TUPLE_ACTIVE_ERROR = 'no active tuple input';
var TUPLE_INCOMPLETE_ERROR = 'tuple input is incomplete';
var TUPLE_LENGTH_ERROR = 'tuple input exceeds declared length';
var TUPLE_BYTE_LENGTH_ERROR = 'tuple input byte length is invalid';
var WINDOW = typeof window === 'object';
var root = WINDOW ? window : {};
if (root.JS_SHA3_NO_WINDOW) {
WINDOW = false;
}
var WEB_WORKER = !WINDOW && typeof self === 'object';
var NODE_JS = !root.JS_SHA3_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
if (NODE_JS) {
root = global;
} else if (WEB_WORKER) {
root = self;
}
var COMMON_JS = !root.JS_SHA3_TEST && typeof module == 'object' && module.exports;
var COMMON_JS = !root.JS_SHA3_NO_COMMON_JS && typeof module === 'object' && module.exports;
var AMD = typeof define === 'function' && define.amd;
var ARRAY_BUFFER = !root.JS_SHA3_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
var HEX_CHARS = '0123456789abcdef'.split('');
var SHAKE_PADDING = [31, 7936, 2031616, 520093696];
var CSHAKE_PADDING = [4, 1024, 262144, 67108864];
var KECCAK_PADDING = [1, 256, 65536, 16777216];
var PADDING = [6, 1536, 393216, 100663296];
var SHIFT = [0, 8, 16, 24];
@@ -26,18 +44,91 @@
2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648];
var BITS = [224, 256, 384, 512];
var SHAKE_BITS = [128, 256];
var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array'];
var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array', 'digest'];
var CSHAKE_BYTEPAD = {
'128': 168,
'256': 136
};
var isArray = root.JS_SHA3_NO_NODE_JS || !Array.isArray
? function (obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
: Array.isArray;
var isView = (ARRAY_BUFFER && (root.JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView))
? function (obj) {
return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
}
: ArrayBuffer.isView;
// [message: string, isString: bool]
var formatMessage = function (message) {
var type = typeof message;
if (type === 'string') {
return [message, true];
}
if (type !== 'object' || message === null) {
throw new Error(INPUT_ERROR);
}
if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
return [new Uint8Array(message), false];
}
if (!isArray(message) && !isView(message)) {
throw new Error(INPUT_ERROR);
}
return [message, false];
}
var empty = function (message) {
return formatMessage(message)[0].length === 0;
};
var cloneArray = function (array) {
var newArray = [];
for (var i = 0; i < array.length; ++i) {
newArray[i] = array[i];
}
return newArray;
}
var createOutputMethod = function (bits, padding, outputType) {
return function (message) {
return new Keccak(bits, padding, bits).update(message)[outputType]();
}
};
};
var createShakeOutputMethod = function (bits, padding, outputType) {
return function (message, outputBits) {
return new Keccak(bits, padding, outputBits).update(message)[outputType]();
};
};
var createCshakeOutputMethod = function (bits, padding, outputType) {
return function (message, outputBits, n, s) {
return methods['cshake' + bits].update(message, outputBits, n, s)[outputType]();
};
};
var createKmacOutputMethod = function (bits, padding, xof, outputType) {
return function (key, message, outputBits, s) {
return methods[(xof ? 'kmacxof' : 'kmac') + bits].update(key, message, outputBits, s)[outputType]();
};
};
var createTupleHashOutputMethod = function (bits, padding, xof, outputType) {
return function (inputs, outputBits, s) {
return methods[(xof ? 'tuplehashxof' : 'tuplehash') + bits].update(inputs, outputBits, s)[outputType]();
};
};
var createOutputMethods = function (method, createMethod, bits, padding) {
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createMethod(bits, padding, type);
}
return method;
};
var createMethod = function (bits, padding) {
@@ -48,11 +139,7 @@
method.update = function (message) {
return method.create().update(message);
};
for (var i = 0;i < OUTPUT_TYPES.length;++i) {
var type = OUTPUT_TYPES[i];
method[type] = createOutputMethod(bits, padding, type);
}
return method;
return createOutputMethods(method, createOutputMethod, bits, padding);
};
var createShakeMethod = function (bits, padding) {
@@ -63,26 +150,93 @@
method.update = function (message, outputBits) {
return method.create(outputBits).update(message);
};
for (var i = 0;i < OUTPUT_TYPES.length;++i) {
var type = OUTPUT_TYPES[i];
method[type] = createShakeOutputMethod(bits, padding, type);
return createOutputMethods(method, createShakeOutputMethod, bits, padding);
};
var createCshakeMethod = function (bits, padding) {
var w = CSHAKE_BYTEPAD[bits];
var method = createCshakeOutputMethod(bits, padding, 'hex');
method.create = function (outputBits, n, s) {
if (empty(n) && empty(s)) {
return methods['shake' + bits].create(outputBits);
} else {
return new Keccak(bits, padding, outputBits).bytepad([n, s], w);
}
return method;
};
method.update = function (message, outputBits, n, s) {
return method.create(outputBits, n, s).update(message);
};
return createOutputMethods(method, createCshakeOutputMethod, bits, padding);
};
var createKmacMethod = function (bits, padding, xof) {
var w = CSHAKE_BYTEPAD[bits];
var method = createKmacOutputMethod(bits, padding, xof, 'hex');
method.create = function (key, outputBits, s) {
return new Kmac(bits, padding, outputBits, xof).bytepad(['KMAC', s], w).bytepad([key], w);
};
method.update = function (key, message, outputBits, s) {
return method.create(key, outputBits, s).update(message);
};
return createOutputMethods(method, function (b, p, outputType) {
return createKmacOutputMethod(b, p, xof, outputType);
}, bits, padding);
};
var createTupleHashMethod = function (bits, padding, xof) {
var w = CSHAKE_BYTEPAD[bits];
var method = createTupleHashOutputMethod(bits, padding, xof, 'hex');
method.create = function (outputBits, s) {
return new TupleHash(bits, padding, outputBits, xof).bytepad(['TupleHash', s], w);
};
method.update = function (inputs, outputBits, s) {
if (!isArray(inputs)) {
throw new Error(INPUT_ERROR);
}
var hash = method.create(outputBits, s);
for (var i = 0; i < inputs.length; ++i) {
hash.update(inputs[i]);
}
return hash;
};
return createOutputMethods(method, function (b, p, outputType) {
return createTupleHashOutputMethod(b, p, xof, outputType);
}, bits, padding);
};
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}
{ name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod },
{ name: 'cshake', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: createCshakeMethod },
{ name: 'kmac', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
return createKmacMethod(bits, padding, false);
}},
{ name: 'kmacxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
return createKmacMethod(bits, padding, true);
}},
{ name: 'tuplehash', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
return createTupleHashMethod(bits, padding, false);
}},
{ name: 'tuplehashxof', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: function (bits, padding) {
return createTupleHashMethod(bits, padding, true);
}}
];
var methods = {};
var methods = {}, methodNames = [];
for (var i = 0; i < algorithms.length; ++i) {
var algorithm = algorithms[i];
var bits = algorithm.bits;
for (var j = 0; j < bits.length; ++j) {
methods[algorithm.name +'_' + bits[j]] = algorithm.createMethod(bits[j], algorithm.padding);
var methodName = algorithm.name + '_' + bits[j];
methodNames.push(methodName);
methods[methodName] = algorithm.createMethod(bits[j], algorithm.padding);
if (algorithm.name !== 'sha3') {
var newMethodName = algorithm.name + bits[j];
methodNames.push(newMethodName);
methods[newMethodName] = methods[methodName];
}
}
}
@@ -92,6 +246,7 @@
this.padding = padding;
this.outputBits = outputBits;
this.reset = true;
this.finalized = false;
this.block = 0;
this.start = 0;
this.blockCount = (1600 - (bits << 1)) >> 5;
@@ -102,14 +257,16 @@
for (var i = 0; i < 50; ++i) {
this.s[i] = 0;
}
};
}
Keccak.prototype.update = function (message) {
var notString = typeof message != 'string';
if (notString && message.constructor == root.ArrayBuffer) {
message = new Uint8Array(message);
if (this.finalized) {
throw new Error(FINALIZE_ERROR);
}
var length = message.length, blocks = this.blocks, byteCount = this.byteCount,
var result = formatMessage(message);
message = result[0];
var isString = result[1];
var blocks = this.blocks, byteCount = this.byteCount, length = message.length,
blockCount = this.blockCount, index = 0, s = this.s, i, code;
while (index < length) {
@@ -120,11 +277,7 @@
blocks[i] = 0;
}
}
if (notString) {
for (i = this.start;index < length && i < byteCount;++index) {
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
}
} else {
if (isString) {
for (i = this.start; index < length && i < byteCount; ++index) {
code = message.charCodeAt(index);
if (code < 0x80) {
@@ -144,6 +297,10 @@
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
}
}
} else {
for (i = this.start; index < length && i < byteCount; ++index) {
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
}
}
this.lastByteIndex = i;
if (i >= byteCount) {
@@ -161,10 +318,73 @@
return this;
};
Keccak.prototype.encode = function (x, right) {
var o = x & 255, n = 1;
var bytes = [o];
x = x >> 8;
o = x & 255;
while (o > 0) {
bytes.unshift(o);
x = x >> 8;
o = x & 255;
++n;
}
if (right) {
bytes.push(n);
} else {
bytes.unshift(n);
}
Keccak.prototype.update.call(this, bytes);
return bytes.length;
};
Keccak.prototype.encodeString = function (str) {
var result = formatMessage(str);
str = result[0];
var isString = result[1];
var bytes = 0, length = str.length;
if (isString) {
for (var i = 0; i < str.length; ++i) {
var code = str.charCodeAt(i);
if (code < 0x80) {
bytes += 1;
} else if (code < 0x800) {
bytes += 2;
} else if (code < 0xd800 || code >= 0xe000) {
bytes += 3;
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff));
bytes += 4;
}
}
} else {
bytes = length;
}
bytes += this.encode(bytes * 8);
Keccak.prototype.update.call(this, str);
return bytes;
};
Keccak.prototype.bytepad = function (strs, w) {
var bytes = this.encode(w);
for (var i = 0; i < strs.length; ++i) {
bytes += this.encodeString(strs[i]);
}
var paddingBytes = (w - bytes % w) % w;
var zeros = [];
zeros.length = paddingBytes;
Keccak.prototype.update.call(this, zeros);
return this;
};
Keccak.prototype.finalize = function () {
if (this.finalized) {
return;
}
this.finalized = true;
var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s;
blocks[i >> 2] |= this.padding[i & 3];
if (this.lastByteIndex == this.byteCount) {
if (this.lastByteIndex === this.byteCount) {
blocks[0] = blocks[blockCount];
for (i = 1; i < blockCount + 1; ++i) {
blocks[i] = 0;
@@ -191,16 +411,15 @@
HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] +
HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F];
}
if (j % blockCount == 0) {
if (j % blockCount === 0) {
s = cloneArray(s);
f(s);
i = 0;
}
}
if (extraBytes) {
block = s[i];
if (extraBytes > 0) {
hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F];
}
if (extraBytes > 1) {
hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F];
}
@@ -228,12 +447,13 @@
for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
array[j] = s[i];
}
if (j % blockCount == 0) {
if (j % blockCount === 0) {
s = cloneArray(s);
f(s);
}
}
if (extraBytes) {
array[i] = s[i];
array[j] = s[i];
buffer = buffer.slice(0, bytes);
}
return buffer;
@@ -256,16 +476,15 @@
array[offset + 2] = (block >> 16) & 0xFF;
array[offset + 3] = (block >> 24) & 0xFF;
}
if (j % blockCount == 0) {
if (j % blockCount === 0) {
s = cloneArray(s);
f(s);
}
}
if (extraBytes) {
offset = j << 2;
block = s[i];
if (extraBytes > 0) {
array[offset] = block & 0xFF;
}
if (extraBytes > 1) {
array[offset + 1] = (block >> 8) & 0xFF;
}
@@ -276,6 +495,100 @@
return array;
};
function Kmac(bits, padding, outputBits, xof) {
Keccak.call(this, bits, padding, outputBits);
this.xof = xof;
}
Kmac.prototype = new Keccak();
Kmac.prototype.finalize = function () {
if (!this.finalized) {
this.encode(this.xof ? 0 : this.outputBits, true);
}
return Keccak.prototype.finalize.call(this);
};
function TupleHash(bits, padding, outputBits, xof) {
Kmac.call(this, bits, padding, outputBits, xof);
this.inputActive = false;
this.inputBytesRemaining = 0;
}
TupleHash.prototype = new Kmac();
TupleHash.prototype.getMessageByteLength = function (message) {
var result = formatMessage(message);
message = result[0];
if (!result[1]) {
return message.length;
}
var bytes = 0;
for (var i = 0; i < message.length; ++i) {
var code = message.charCodeAt(i);
if (code < 0x80) {
bytes += 1;
} else if (code < 0x800) {
bytes += 2;
} else if (code < 0xd800 || code >= 0xe000) {
bytes += 3;
} else {
++i;
bytes += 4;
}
}
return bytes;
};
TupleHash.prototype.beginInput = function (byteLength) {
if (this.inputActive) {
throw new Error(TUPLE_INCOMPLETE_ERROR);
}
if (typeof byteLength !== 'number' || !isFinite(byteLength) || byteLength < 0 ||
Math.floor(byteLength) !== byteLength || byteLength > 0x0fffffff) {
throw new Error(TUPLE_BYTE_LENGTH_ERROR);
}
this.encode(byteLength * 8, false);
if (byteLength !== 0) {
this.inputActive = true;
this.inputBytesRemaining = byteLength;
}
return this;
};
TupleHash.prototype._updateChunk = function (message, byteLength) {
Kmac.prototype.update.call(this, message);
this.inputBytesRemaining -= byteLength;
if (this.inputBytesRemaining === 0) {
this.inputActive = false;
}
return this;
};
TupleHash.prototype.updateChunk = function (message) {
if (!this.inputActive) {
throw new Error(TUPLE_ACTIVE_ERROR);
}
var byteLength = this.getMessageByteLength(message);
if (byteLength > this.inputBytesRemaining) {
throw new Error(TUPLE_LENGTH_ERROR);
}
return this._updateChunk(message, byteLength);
};
TupleHash.prototype.update = function (message) {
var byteLength = this.getMessageByteLength(message);
this.beginInput(byteLength);
return this._updateChunk(message, byteLength);
};
TupleHash.prototype.finalize = function () {
if (this.inputActive) {
throw new Error(TUPLE_INCOMPLETE_ERROR);
}
return Kmac.prototype.finalize.call(this);
};
var f = function (s) {
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,
@@ -459,13 +772,18 @@
s[0] ^= RC[n];
s[1] ^= RC[n + 1];
}
}
};
if (COMMON_JS) {
module.exports = methods;
} else if (root) {
for (var key in methods) {
root[key] = methods[key];
} else {
for (i = 0; i < methodNames.length; ++i) {
root[methodNames[i]] = methods[methodNames[i]];
}
if (AMD) {
define(function () {
return methods;
});
}
}
}(this));
})();
+47
View File
@@ -0,0 +1,47 @@
import sha3 from './sha3.js';
export const {
sha3_224,
sha3_256,
sha3_384,
sha3_512,
keccak_224,
keccak_256,
keccak_384,
keccak_512,
keccak224,
keccak256,
keccak384,
keccak512,
shake_128,
shake_256,
shake128,
shake256,
cshake_128,
cshake_256,
cshake128,
cshake256,
kmac_128,
kmac_256,
kmac128,
kmac256,
kmacxof_128,
kmacxof_256,
kmacxof128,
kmacxof256,
tuplehash_128,
tuplehash_256,
tuplehash128,
tuplehash256,
tuplehashxof_128,
tuplehashxof_256,
tuplehashxof128,
tuplehashxof256
} = sha3;
export default sha3;
+2
View File
@@ -15,6 +15,8 @@
</script>
<script src="test.js"></script>
<script src="test-shake.js"></script>
<script src="test-cshake.js"></script>
<script src="test-kmac.js"></script>
<script>
mocha.checkLeaks();
mocha.run();
+157 -21
View File
@@ -1,33 +1,169 @@
expect = require('expect.js');
var sha3 = require('../src/sha3.js');
keccak_512 = sha3.keccak_512;
keccak_384 = sha3.keccak_384;
keccak_256 = sha3.keccak_256;
keccak_224 = sha3.keccak_224;
sha3_512 = sha3.sha3_512;
sha3_384 = sha3.sha3_384;
sha3_256 = sha3.sha3_256;
sha3_224 = sha3.sha3_224;
shake_128 = sha3.shake_128;
shake_256 = sha3.shake_256;
require('./test.js');
require('./test-shake.js');
Worker = require("tiny-worker");
function unset() {
delete require.cache[require.resolve('../src/sha3.js')];
delete require.cache[require.resolve('./test.js')];
delete require.cache[require.resolve('./test-shake.js')];
sha3_512 = null;
sha3_384 = null;
sha3_256 = null;
sha3_224 = null;
keccak_512 = null;
keccak_384 = null;
keccak_256 = null;
keccak_224 = null;
shake_128 = null;
shake_256 = null;
keccak512 = null;
keccak384 = null;
keccak256 = null;
keccak224 = null;
shake128 = null;
shake256 = null;
kmac128 = null;
kmac256 = null;
kmacxof128 = null;
kmacxof256 = null;
tuplehash128 = null;
tuplehash256 = null;
tuplehashxof128 = null;
tuplehashxof256 = null;
BUFFER = undefined;
JS_SHA3_NO_WINDOW = undefined;
JS_SHA3_NO_NODE_JS = undefined;
JS_SHA3_NO_COMMON_JS = undefined;
JS_SHA3_NO_ARRAY_BUFFER = undefined;
JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW = undefined;
window = undefined;
}
JS_SHA3_TEST = true;
function requireToGlobal() {
var sha3 = require('../src/sha3.js');
keccak512 = sha3.keccak512;
keccak384 = sha3.keccak384;
keccak256 = sha3.keccak256;
keccak224 = sha3.keccak224;
sha3_512 = sha3.sha3_512;
sha3_384 = sha3.sha3_384;
sha3_256 = sha3.sha3_256;
sha3_224 = sha3.sha3_224;
shake128 = sha3.shake128;
shake256 = sha3.shake256;
cshake128 = sha3.cshake128;
cshake256 = sha3.cshake256;
kmac128 = sha3.kmac128;
kmac256 = sha3.kmac256;
kmacxof128 = sha3.kmacxof128;
kmacxof256 = sha3.kmacxof256;
tuplehash128 = sha3.tuplehash128;
tuplehash256 = sha3.tuplehash256;
tuplehashxof128 = sha3.tuplehashxof128;
tuplehashxof256 = sha3.tuplehashxof256;
}
function runCommonJsTest() {
requireToGlobal();
require('./test.js');
unset();
}
function runWindowTest(extra) {
window = global;
require('../src/sha3.js');
require('./test.js');
if (extra) {
require('./test-shake.js');
require('./test-cshake.js');
require('./test-kmac.js');
require('./test-tuplehash.js');
}
unset();
}
// Node.js env
BUFFER = true;
runCommonJsTest();
// Webpack browser env
JS_SHA3_NO_NODE_JS = true;
window = global;
runCommonJsTest();
// browser env
JS_SHA3_NO_NODE_JS = true;
JS_SHA3_NO_COMMON_JS = true;
runWindowTest(true);
// browser env and no array buffer
JS_SHA3_NO_NODE_JS = true;
JS_SHA3_NO_COMMON_JS = true;
JS_SHA3_NO_ARRAY_BUFFER = true;
runWindowTest();
// browser env and no isView
JS_SHA3_NO_NODE_JS = true;
JS_SHA3_NO_COMMON_JS = true;
JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW = true;
runWindowTest();
// browser AMD
JS_SHA3_NO_NODE_JS = true;
JS_SHA3_NO_COMMON_JS = true;
JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW = false;
window = global;
define = function (func) {
sha3 = func();
keccak512 = sha3.keccak512;
keccak384 = sha3.keccak384;
keccak256 = sha3.keccak256;
keccak224 = sha3.keccak224;
sha3_512 = sha3.sha3_512;
sha3_384 = sha3.sha3_384;
sha3_256 = sha3.sha3_256;
sha3_224 = sha3.sha3_224;
shake128 = sha3.shake128;
shake256 = sha3.shake256;
cshake128 = sha3.cshake128;
cshake256 = sha3.cshake256;
kmac128 = sha3.kmac128;
kmac256 = sha3.kmac256;
kmacxof128 = sha3.kmacxof128;
kmacxof256 = sha3.kmacxof256;
tuplehash128 = sha3.tuplehash128;
tuplehash256 = sha3.tuplehash256;
tuplehashxof128 = sha3.tuplehashxof128;
tuplehashxof256 = sha3.tuplehashxof256;
require('./test.js');
};
define.amd = true;
require('../src/sha3.js');
unset();
// webworker
WORKER = 'tests/worker.js';
SOURCE = 'src/sha3.js';
require('./worker-test.js');
delete require.cache[require.resolve('./worker-test.js')];
// cover webworker
JS_SHA3_NO_WINDOW = true;
JS_SHA3_NO_NODE_JS = true;
WORKER = './worker.js';
SOURCE = '../src/sha3.js';
window = global;
self = global;
Worker = function (file) {
require(file);
currentWorker = this;
this.postMessage = function (data) {
onmessage({data: data});
};
}
postMessage = function (data) {
currentWorker.onmessage({data: data});
}
importScripts = function () {};
requireToGlobal();
require('./worker-test.js');
+90
View File
@@ -0,0 +1,90 @@
(function (cshake256, cshake128) {
// http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/cSHAKE_samples.pdf
var testCases = [
{
name: 'cshake128',
method: cshake128,
cases: [
{
input: [0x00, 0x01, 0x02, 0x03],
bits: 256,
n: '',
s: 'Email Signature',
output: 'c1c36925b6409a04f1b504fcbca9d82b4017277cb5ed2b2065fc1d3814d5aaf5'
},
{
input: [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7],
bits: 256,
n: '',
s: 'Email Signature',
output: 'c5221d50e4f822d96a2e8881a961420f294b7b24fe3d2094baed2c6524cc166b'
},
{
input: '',
bits: 256,
n: '',
s: '',
output: '7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26'
},
{
input: [],
bits: 256,
n: [],
s: [],
output: '7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26'
},
{
input: [],
bits: 256,
n: new ArrayBuffer(0),
s: new ArrayBuffer(0),
output: '7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26'
},
{
input: [],
bits: 256,
n: new Uint8Array([]),
s: new Uint8Array([]),
output: '7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26'
}
]
},
{
name: 'cshake256',
method: cshake256,
cases: [
{
input: [0x00, 0x01, 0x02, 0x03],
bits: 512,
n: '',
s: 'Email Signature',
output: 'd008828e2b80ac9d2218ffee1d070c48b8e4c87bff32c9699d5b6896eee0edd164020e2be0560858d9c00c037e34a96937c561a74c412bb4c746469527281c8c'
},
{
input: [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7],
bits: 512,
n: '',
s: 'Email Signature',
output: '07dc27b11e51fbac75bc7b3c1d983e8b4b85fb1defaf218912ac86430273091727f42b17ed1df63e8ec118f04b23633c1dfb1574c8fb55cb45da8e25afb092bb'
},
{
input: '',
bits: 512,
n: '',
s: '',
output: '46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be'
}
]
}
];
testCases.forEach(function (testCase) {
describe('#' + testCase.name, function () {
testCase.cases.forEach(function (c) {
it('should be equal', function () {
expect(testCase.method(c.input, c.bits, c.n, c.s)).to.be(c.output);
});
});
});
});
})(cshake256, cshake128);
+157
View File
@@ -0,0 +1,157 @@
(function (kmac256, kmac128, kmacxof256, kmacxof128) {
// http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/KMAC_samples.pdf
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/KMACXOF_samples.pdf
var key = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F];
var shortInput = [0x00, 0x01, 0x02, 0x03];
var longInput = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7
];
var testCases = [
{
name: 'kmac128',
method: kmac128,
cases: [
{
input: shortInput,
bits: 256,
key: key,
s: '',
output: 'e5780b0d3ea6f7d3a429c5706aa43a00fadbd7d49628839e3187243f456ee14e'
},
{
input: shortInput,
bits: 256,
key: key,
s: 'My Tagged Application',
output: '3b1fba963cd8b0b59e8c1a6d71888b7143651af8ba0a7070c0979e2811324aa5'
},
{
input: longInput,
bits: 256,
key: key,
s: 'My Tagged Application',
output: '1f5b4e6cca02209e0dcb5ca635b89a15e271ecc760071dfd805faa38f9729230'
}
]
},
{
name: 'kmac256',
method: kmac256,
cases: [
{
input: shortInput,
bits: 512,
key: key,
s: 'My Tagged Application',
output: '20c570c31346f703c9ac36c61c03cb64c3970d0cfc787e9b79599d273a68d2f7f69d4cc3de9d104a351689f27cf6f5951f0103f33f4f24871024d9c27773a8dd'
},
{
input: longInput,
bits: 512,
key: key,
s: '',
output: '75358cf39e41494e949707927cee0af20a3ff553904c86b08f21cc414bcfd691589d27cf5e15369cbbff8b9a4c2eb17800855d0235ff635da82533ec6b759b69'
},
{
input: longInput,
bits: 512,
key: key,
s: 'My Tagged Application',
output: 'b58618f71f92e1d56c1b8c55ddd7cd188b97b4ca4d99831eb2699a837da2e4d970fbacfde50033aea585f1a2708510c32d07880801bd182898fe476876fc8965'
},
{
input: [],
bits: 128,
key: [],
s: [8, 79, 237, 8, 185, 120, 175, 77, 125, 25, 106, 116, 70, 168, 107, 88, 0, 158, 99, 107, 97, 29, 177, 98, 17, 182, 90, 154, 173, 255, 41, 197, 8, 79, 237, 8, 185, 120, 175, 77, 125, 25, 106, 116, 70, 168, 107, 88, 0, 158, 99, 107, 97, 29, 177, 98, 17, 182, 90, 154, 173, 255, 41, 197, 8, 79, 237, 8, 185, 120, 175, 77, 125, 25, 106, 116, 70, 168, 107, 88, 0, 158, 99, 107, 97, 29, 177, 98, 17, 182, 90, 154, 173, 255, 41, 197, 8, 79, 237, 8, 185, 120, 175, 77, 125, 25, 106, 116, 70, 168, 107, 88, 0, 158, 99, 107, 97, 29, 177, 98, 17, 182, 90, 154, 173],
output: '031801b0b50ebeef772fbe7a279bc144'
}
]
},
{
name: 'kmacxof128',
method: kmacxof128,
cases: [
{
input: shortInput,
bits: 256,
key: key,
s: '',
output: 'cd83740bbd92ccc8cf032b1481a0f4460e7ca9dd12b08a0c4031178bacd6ec35'
},
{
input: shortInput,
bits: 256,
key: key,
s: 'My Tagged Application',
output: '31a44527b4ed9f5c6101d11de6d26f0620aa5c341def41299657fe9df1a3b16c'
},
{
input: longInput,
bits: 256,
key: key,
s: 'My Tagged Application',
output: '47026c7cd793084aa0283c253ef658490c0db61438b8326fe9bddf281b83ae0f'
}
]
},
{
name: 'kmacxof256',
method: kmacxof256,
cases: [
{
input: shortInput,
bits: 512,
key: key,
s: 'My Tagged Application',
output: '1755133f1534752aad0748f2c706fb5c784512cab835cd15676b16c0c6647fa96faa7af634a0bf8ff6df39374fa00fad9a39e322a7c92065a64eb1fb0801eb2b'
},
{
input: longInput,
bits: 512,
key: key,
s: '',
output: 'ff7b171f1e8a2b24683eed37830ee797538ba8dc563f6da1e667391a75edc02ca633079f81ce12a25f45615ec89972031d18337331d24ceb8f8ca8e6a19fd98b'
},
{
input: longInput,
bits: 512,
key: key,
s: 'My Tagged Application',
output: 'd5be731c954ed7732846bb59dbe3a8e30f83e77a4bff4459f2f1c2b4ecebb8ce67ba01c62e8ab8578d2d499bd1bb276768781190020a306a97de281dcc30305d'
}
]
}
];
testCases.forEach(function (testCase) {
describe('#' + testCase.name, function () {
testCase.cases.forEach(function (c) {
it('should be equal', function () {
expect(testCase.method(c.key, c.input, c.bits, c.s)).to.be(c.output);
});
});
});
});
describe('#kmacxof aliases', function () {
it('should export identical aliases', function () {
var sha3 = require('../src/sha3.js');
expect(sha3.kmacxof128).to.be(sha3.kmacxof_128);
expect(sha3.kmacxof256).to.be(sha3.kmacxof_256);
});
});
})(kmac256, kmac128, kmacxof256, kmacxof128);
+39 -31
View File
@@ -1,69 +1,71 @@
(function (shake_256, shake_128) {
describe('#shake_128', function () {
(function (shake256, shake128) {
describe('#shake128', function () {
context('with 256 output', function () {
it('should be equal', function () {
expect(shake_128('', 256)).to.be('7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26');
expect(shake_128('The quick brown fox jumps over the lazy dog', 256)).to.be('f4202e3c5852f9182a0430fd8144f0a74b95e7417ecae17db0f8cfeed0e3e66e');
expect(shake_128('The quick brown fox jumps over the lazy dof', 256)).to.be('853f4538be0db9621a6cea659a06c1107b1f83f02b13d18297bd39d7411cf10c');
expect(shake128('', 256)).to.be('7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26');
expect(shake128('The quick brown fox jumps over the lazy dog', 256)).to.be('f4202e3c5852f9182a0430fd8144f0a74b95e7417ecae17db0f8cfeed0e3e66e');
expect(shake128('The quick brown fox jumps over the lazy dof', 256)).to.be('853f4538be0db9621a6cea659a06c1107b1f83f02b13d18297bd39d7411cf10c');
});
});
context('with 8 output', function () {
it('should be equal', function () {
expect(shake_128('', 8)).to.be('7f');
expect(shake_128('The quick brown fox jumps over the lazy dog', 8)).to.be('f4');
expect(shake_128('The quick brown fox jumps over the lazy dof', 8)).to.be('85');
expect(shake128('', 8)).to.be('7f');
expect(shake128('The quick brown fox jumps over the lazy dog', 8)).to.be('f4');
expect(shake128('The quick brown fox jumps over the lazy dof', 8)).to.be('85');
});
});
context('with 1368 output', function () {
it('should be equal', function () {
expect(shake_128('AAA', 1368)).to.be('15e0fe495a05b74f9fd3eaa8a898a623488220dcbf9ba2f12d23d278b7cecfa4a5e4b8d0fccb0fdbc9e51cd0b4344a32a83f0ba40a514a7b86a77c854c61b836192849da9214c43c4f8bc09ec7a76af92b2fc56e4952024be65b1a47835e0bc014733b24d0e31197ca648f831caebbfd8a5b237ae6bdc9d6cc803a2c5e57dd9346eecf972bd85450f18a413dc6239982e1eb6e0c6df856385c9597d0320edb40b6fe60a74f07524015ad36');
expect(shake_128('AAA', 1376)).to.be('15e0fe495a05b74f9fd3eaa8a898a623488220dcbf9ba2f12d23d278b7cecfa4a5e4b8d0fccb0fdbc9e51cd0b4344a32a83f0ba40a514a7b86a77c854c61b836192849da9214c43c4f8bc09ec7a76af92b2fc56e4952024be65b1a47835e0bc014733b24d0e31197ca648f831caebbfd8a5b237ae6bdc9d6cc803a2c5e57dd9346eecf972bd85450f18a413dc6239982e1eb6e0c6df856385c9597d0320edb40b6fe60a74f07524015ad36b6');
expect(shake128('AAA', 1368)).to.be('15e0fe495a05b74f9fd3eaa8a898a623488220dcbf9ba2f12d23d278b7cecfa4a5e4b8d0fccb0fdbc9e51cd0b4344a32a83f0ba40a514a7b86a77c854c61b836192849da9214c43c4f8bc09ec7a76af92b2fc56e4952024be65b1a47835e0bc014733b24d0e31197ca648f831caebbfd8a5b237ae6bdc9d6cc803a2c5e57dd9346eecf972bd85450f18a413dc6239982e1eb6e0c6df856385c9597d0320edb40b6fe60a74f07524015ad36');
expect(shake128('AAA', 1376)).to.be('15e0fe495a05b74f9fd3eaa8a898a623488220dcbf9ba2f12d23d278b7cecfa4a5e4b8d0fccb0fdbc9e51cd0b4344a32a83f0ba40a514a7b86a77c854c61b836192849da9214c43c4f8bc09ec7a76af92b2fc56e4952024be65b1a47835e0bc014733b24d0e31197ca648f831caebbfd8a5b237ae6bdc9d6cc803a2c5e57dd9346eecf972bd85450f18a413dc6239982e1eb6e0c6df856385c9597d0320edb40b6fe60a74f07524015ad36b6');
});
});
context('with more output', function () {
it('should be equal', function () {
expect(shake_128('', 16)).to.be('7f9c');
expect(shake_128('', 24)).to.be('7f9c2b');
expect(shake_128.array('', 16)).to.eql([0x7f, 0x9c]);
expect(shake_128.array('', 24)).to.eql([0x7f, 0x9c, 0x2b]);
expect(shake128('', 16)).to.be('7f9c');
expect(shake128('', 24)).to.be('7f9c2b');
expect(shake128.array('', 8)).to.eql([0x7f]);
expect(shake128.array('', 16)).to.eql([0x7f, 0x9c]);
expect(shake128.array('', 24)).to.eql([0x7f, 0x9c, 0x2b]);
});
});
context('with 8 output ArrayBuffer', function () {
it('should be equal', function () {
expect(shake_128.buffer('', 8).toHexString()).to.be('7f');
expect(shake_128.buffer('The quick brown fox jumps over the lazy dog', 8).toHexString()).to.be('f4');
expect(shake_128.buffer('The quick brown fox jumps over the lazy dof', 8).toHexString()).to.be('85');
expect(shake128.arrayBuffer('', 8).toHexString()).to.be('7f');
expect(shake128.arrayBuffer('The quick brown fox jumps over the lazy dog', 8).toHexString()).to.be('f4');
expect(shake128.arrayBuffer('The quick brown fox jumps over the lazy dof', 8).toHexString()).to.be('85');
});
});
context('#update', function () {
it('should be equal', function () {
expect(shake_128.update('', 256).hex()).to.be('7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26');
expect(shake_128.update('The quick brown fox ', 256).update('jumps over the lazy dog').hex()).to.be('f4202e3c5852f9182a0430fd8144f0a74b95e7417ecae17db0f8cfeed0e3e66e');
expect(shake128.update('', 256).hex()).to.be('7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26');
expect(shake128.update('The quick brown fox ', 256).update('jumps over the lazy dog').hex()).to.be('f4202e3c5852f9182a0430fd8144f0a74b95e7417ecae17db0f8cfeed0e3e66e');
});
});
});
describe('#shake_256', function () {
describe('#shake256', function () {
context('with 512 output', function () {
it('should be equal', function () {
expect(shake_256('', 512)).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be');
expect(shake256('', 512)).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be');
});
});
context('with 8 output', function () {
it('should be equal', function () {
expect(shake_256('', 8)).to.be('46');
expect(shake256('', 8)).to.be('46');
});
});
context('with 1112 output', function () {
it('should be equal', function () {
expect(shake_256('AAA', 1112)).to.be('419614c8b247ee5e9f4a540f7aaa5ca5b44b119f47ab7f494c05095ae5a61ab6b62c84b8b27888813ce8a4d4dab3ed7617c6bab643aa01bb1b113e6d48c3e1eeb73e96f96ffaf12e0c36b190404982b856087acfcb467535e17152e5c15a4d62a18a15d8fe434b3a7274362b0d46b627df1e011a1d037e161d5b540df7ebadab351fb730904daa9a4f40fd');
expect(shake_256('AAA', 1120)).to.be('419614c8b247ee5e9f4a540f7aaa5ca5b44b119f47ab7f494c05095ae5a61ab6b62c84b8b27888813ce8a4d4dab3ed7617c6bab643aa01bb1b113e6d48c3e1eeb73e96f96ffaf12e0c36b190404982b856087acfcb467535e17152e5c15a4d62a18a15d8fe434b3a7274362b0d46b627df1e011a1d037e161d5b540df7ebadab351fb730904daa9a4f40fdb5');
expect(shake256('AAA', 1112)).to.be('419614c8b247ee5e9f4a540f7aaa5ca5b44b119f47ab7f494c05095ae5a61ab6b62c84b8b27888813ce8a4d4dab3ed7617c6bab643aa01bb1b113e6d48c3e1eeb73e96f96ffaf12e0c36b190404982b856087acfcb467535e17152e5c15a4d62a18a15d8fe434b3a7274362b0d46b627df1e011a1d037e161d5b540df7ebadab351fb730904daa9a4f40fd');
expect(shake256('AAA', 1120)).to.be('419614c8b247ee5e9f4a540f7aaa5ca5b44b119f47ab7f494c05095ae5a61ab6b62c84b8b27888813ce8a4d4dab3ed7617c6bab643aa01bb1b113e6d48c3e1eeb73e96f96ffaf12e0c36b190404982b856087acfcb467535e17152e5c15a4d62a18a15d8fe434b3a7274362b0d46b627df1e011a1d037e161d5b540df7ebadab351fb730904daa9a4f40fdb5');
});
});
@@ -71,11 +73,11 @@
it('should be equal', function () {
// https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHAKE256.txt
// Len = 0, Msg = 00
expect(shake_256('', 4100)).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a');
expect(shake256('', 4100)).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a');
// Len = 2040
// Msg = 3A3A819C48EFDE2AD914FBF00E18AB6BC4F14513AB27D0C178A188B61431E7F5623CB66B23346775D386B50E982C493ADBBFC54B9A3CD383382336A1A0B2150A15358F336D03AE18F666C7573D55C4FD181C29E6CCFDE63EA35F0ADF5885CFC0A3D84A2B2E4DD24496DB789E663170CEF74798AA1BBCD4574EA0BBA40489D764B2F83AADC66B148B4A0CD95246C127D5871C4F11418690A5DDF01246A0C80A43C70088B6183639DCFDA4125BD113A8F49EE23ED306FAAC576C3FB0C1E256671D817FC2534A52F5B439F72E424DE376F4C565CCA82307DD9EF76DA5B7C4EB7E085172E328807C02D011FFBF33785378D79DC266F6A5BE6BB0E4A92ECEEBAEB1
expect(shake_256([0x3A,0x3A,0x81,0x9C,0x48,0xEF,0xDE,0x2A,0xD9,0x14,0xFB,0xF0,0x0E,0x18,0xAB,0x6B,0xC4,0xF1,0x45,0x13,0xAB,0x27,0xD0,0xC1,0x78,0xA1,0x88,0xB6,0x14,0x31,0xE7,0xF5,0x62,0x3C,0xB6,0x6B,0x23,0x34,0x67,0x75,0xD3,0x86,0xB5,0x0E,0x98,0x2C,0x49,0x3A,0xDB,0xBF,0xC5,0x4B,0x9A,0x3C,0xD3,0x83,0x38,0x23,0x36,0xA1,0xA0,0xB2,0x15,0x0A,0x15,0x35,0x8F,0x33,0x6D,0x03,0xAE,0x18,0xF6,0x66,0xC7,0x57,0x3D,0x55,0xC4,0xFD,0x18,0x1C,0x29,0xE6,0xCC,0xFD,0xE6,0x3E,0xA3,0x5F,0x0A,0xDF,0x58,0x85,0xCF,0xC0,0xA3,0xD8,0x4A,0x2B,0x2E,0x4D,0xD2,0x44,0x96,0xDB,0x78,0x9E,0x66,0x31,0x70,0xCE,0xF7,0x47,0x98,0xAA,0x1B,0xBC,0xD4,0x57,0x4E,0xA0,0xBB,0xA4,0x04,0x89,0xD7,0x64,0xB2,0xF8,0x3A,0xAD,0xC6,0x6B,0x14,0x8B,0x4A,0x0C,0xD9,0x52,0x46,0xC1,0x27,0xD5,0x87,0x1C,0x4F,0x11,0x41,0x86,0x90,0xA5,0xDD,0xF0,0x12,0x46,0xA0,0xC8,0x0A,0x43,0xC7,0x00,0x88,0xB6,0x18,0x36,0x39,0xDC,0xFD,0xA4,0x12,0x5B,0xD1,0x13,0xA8,0xF4,0x9E,0xE2,0x3E,0xD3,0x06,0xFA,0xAC,0x57,0x6C,0x3F,0xB0,0xC1,0xE2,0x56,0x67,0x1D,0x81,0x7F,0xC2,0x53,0x4A,0x52,0xF5,0xB4,0x39,0xF7,0x2E,0x42,0x4D,0xE3,0x76,0xF4,0xC5,0x65,0xCC,0xA8,0x23,0x07,0xDD,0x9E,0xF7,0x6D,0xA5,0xB7,0xC4,0xEB,0x7E,0x08,0x51,0x72,0xE3,0x28,0x80,0x7C,0x02,0xD0,0x11,0xFF,0xBF,0x33,0x78,0x53,0x78,0xD7,0x9D,0xC2,0x66,0xF6,0xA5,0xBE,0x6B,0xB0,0xE4,0xA9,0x2E,0xCE,0xEB,0xAE,0xB1], 4100)).to.be('8a5199b4a7e133e264a86202720655894d48cff344a928cf8347f48379cef347dfc5bcffab99b27b1f89aa2735e23d30088ffa03b9edb02b9635470ab9f1038985d55f9ca774572dd006470ea65145469609f9fa0831bf1ffd842dc24acade27bd9816e3b5bf2876cb112232a0eb4475f1dff9f5c713d9ffd4ccb89ae5607fe35731df06317949eef646e9591cf3be53add6b7dd2b6096e2b3fb06e662ec8b2d77422daad9463cd155204acdbd38e319613f39f99b6dfb35ca9365160066db19835888c2241ff9a731a4acbb5663727aac34a401247fbaa7499e7d5ee5b69d31025e63d04c35c798bca1262d5673a9cf0930b5ad89bd485599dc184528da4790f088ebd170b635d9581632d2ff90db79665ced430089af13c9f21f6d443a818064f17aec9e9c5457001fa8dc6afbadbe3138f388d89d0e6f22f66671255b210754ed63d81dce75ce8f189b534e6d6b3539aa51e837c42df9df59c71e6171cd4902fe1bdc73fb1775b5c754a1ed4ea7f3105fc543ee0418dad256f3f6118ea77114a16c15355b42877a1db2a7df0e155ae1d8670abcec3450f4e2eec9838f895423ef63d261138baaf5d9f104cb5a957aea06c0b9b8c78b0d441796dc0350ddeabb78a33b6f1f9e68ede3d1805c7b7e2cfd54e0fad62f0d8ca67a775dc4546af9096f2edb221db42843d65327861282dc946a0ba01a11863ab2d1dfd16e3973d4');
expect(shake256([0x3A,0x3A,0x81,0x9C,0x48,0xEF,0xDE,0x2A,0xD9,0x14,0xFB,0xF0,0x0E,0x18,0xAB,0x6B,0xC4,0xF1,0x45,0x13,0xAB,0x27,0xD0,0xC1,0x78,0xA1,0x88,0xB6,0x14,0x31,0xE7,0xF5,0x62,0x3C,0xB6,0x6B,0x23,0x34,0x67,0x75,0xD3,0x86,0xB5,0x0E,0x98,0x2C,0x49,0x3A,0xDB,0xBF,0xC5,0x4B,0x9A,0x3C,0xD3,0x83,0x38,0x23,0x36,0xA1,0xA0,0xB2,0x15,0x0A,0x15,0x35,0x8F,0x33,0x6D,0x03,0xAE,0x18,0xF6,0x66,0xC7,0x57,0x3D,0x55,0xC4,0xFD,0x18,0x1C,0x29,0xE6,0xCC,0xFD,0xE6,0x3E,0xA3,0x5F,0x0A,0xDF,0x58,0x85,0xCF,0xC0,0xA3,0xD8,0x4A,0x2B,0x2E,0x4D,0xD2,0x44,0x96,0xDB,0x78,0x9E,0x66,0x31,0x70,0xCE,0xF7,0x47,0x98,0xAA,0x1B,0xBC,0xD4,0x57,0x4E,0xA0,0xBB,0xA4,0x04,0x89,0xD7,0x64,0xB2,0xF8,0x3A,0xAD,0xC6,0x6B,0x14,0x8B,0x4A,0x0C,0xD9,0x52,0x46,0xC1,0x27,0xD5,0x87,0x1C,0x4F,0x11,0x41,0x86,0x90,0xA5,0xDD,0xF0,0x12,0x46,0xA0,0xC8,0x0A,0x43,0xC7,0x00,0x88,0xB6,0x18,0x36,0x39,0xDC,0xFD,0xA4,0x12,0x5B,0xD1,0x13,0xA8,0xF4,0x9E,0xE2,0x3E,0xD3,0x06,0xFA,0xAC,0x57,0x6C,0x3F,0xB0,0xC1,0xE2,0x56,0x67,0x1D,0x81,0x7F,0xC2,0x53,0x4A,0x52,0xF5,0xB4,0x39,0xF7,0x2E,0x42,0x4D,0xE3,0x76,0xF4,0xC5,0x65,0xCC,0xA8,0x23,0x07,0xDD,0x9E,0xF7,0x6D,0xA5,0xB7,0xC4,0xEB,0x7E,0x08,0x51,0x72,0xE3,0x28,0x80,0x7C,0x02,0xD0,0x11,0xFF,0xBF,0x33,0x78,0x53,0x78,0xD7,0x9D,0xC2,0x66,0xF6,0xA5,0xBE,0x6B,0xB0,0xE4,0xA9,0x2E,0xCE,0xEB,0xAE,0xB1], 4100)).to.be('8a5199b4a7e133e264a86202720655894d48cff344a928cf8347f48379cef347dfc5bcffab99b27b1f89aa2735e23d30088ffa03b9edb02b9635470ab9f1038985d55f9ca774572dd006470ea65145469609f9fa0831bf1ffd842dc24acade27bd9816e3b5bf2876cb112232a0eb4475f1dff9f5c713d9ffd4ccb89ae5607fe35731df06317949eef646e9591cf3be53add6b7dd2b6096e2b3fb06e662ec8b2d77422daad9463cd155204acdbd38e319613f39f99b6dfb35ca9365160066db19835888c2241ff9a731a4acbb5663727aac34a401247fbaa7499e7d5ee5b69d31025e63d04c35c798bca1262d5673a9cf0930b5ad89bd485599dc184528da4790f088ebd170b635d9581632d2ff90db79665ced430089af13c9f21f6d443a818064f17aec9e9c5457001fa8dc6afbadbe3138f388d89d0e6f22f66671255b210754ed63d81dce75ce8f189b534e6d6b3539aa51e837c42df9df59c71e6171cd4902fe1bdc73fb1775b5c754a1ed4ea7f3105fc543ee0418dad256f3f6118ea77114a16c15355b42877a1db2a7df0e155ae1d8670abcec3450f4e2eec9838f895423ef63d261138baaf5d9f104cb5a957aea06c0b9b8c78b0d441796dc0350ddeabb78a33b6f1f9e68ede3d1805c7b7e2cfd54e0fad62f0d8ca67a775dc4546af9096f2edb221db42843d65327861282dc946a0ba01a11863ab2d1dfd16e3973d4');
});
});
@@ -83,11 +85,11 @@
it('should be equal', function () {
// https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHAKE256.txt
// Len = 0, Msg = 00
expect(shake_256.buffer('', 4100).toHexString()).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a');
expect(shake256.arrayBuffer('', 4100).toHexString()).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a');
// Len = 2040
// Msg = 3A3A819C48EFDE2AD914FBF00E18AB6BC4F14513AB27D0C178A188B61431E7F5623CB66B23346775D386B50E982C493ADBBFC54B9A3CD383382336A1A0B2150A15358F336D03AE18F666C7573D55C4FD181C29E6CCFDE63EA35F0ADF5885CFC0A3D84A2B2E4DD24496DB789E663170CEF74798AA1BBCD4574EA0BBA40489D764B2F83AADC66B148B4A0CD95246C127D5871C4F11418690A5DDF01246A0C80A43C70088B6183639DCFDA4125BD113A8F49EE23ED306FAAC576C3FB0C1E256671D817FC2534A52F5B439F72E424DE376F4C565CCA82307DD9EF76DA5B7C4EB7E085172E328807C02D011FFBF33785378D79DC266F6A5BE6BB0E4A92ECEEBAEB1
expect(shake_256.buffer([0x3A,0x3A,0x81,0x9C,0x48,0xEF,0xDE,0x2A,0xD9,0x14,0xFB,0xF0,0x0E,0x18,0xAB,0x6B,0xC4,0xF1,0x45,0x13,0xAB,0x27,0xD0,0xC1,0x78,0xA1,0x88,0xB6,0x14,0x31,0xE7,0xF5,0x62,0x3C,0xB6,0x6B,0x23,0x34,0x67,0x75,0xD3,0x86,0xB5,0x0E,0x98,0x2C,0x49,0x3A,0xDB,0xBF,0xC5,0x4B,0x9A,0x3C,0xD3,0x83,0x38,0x23,0x36,0xA1,0xA0,0xB2,0x15,0x0A,0x15,0x35,0x8F,0x33,0x6D,0x03,0xAE,0x18,0xF6,0x66,0xC7,0x57,0x3D,0x55,0xC4,0xFD,0x18,0x1C,0x29,0xE6,0xCC,0xFD,0xE6,0x3E,0xA3,0x5F,0x0A,0xDF,0x58,0x85,0xCF,0xC0,0xA3,0xD8,0x4A,0x2B,0x2E,0x4D,0xD2,0x44,0x96,0xDB,0x78,0x9E,0x66,0x31,0x70,0xCE,0xF7,0x47,0x98,0xAA,0x1B,0xBC,0xD4,0x57,0x4E,0xA0,0xBB,0xA4,0x04,0x89,0xD7,0x64,0xB2,0xF8,0x3A,0xAD,0xC6,0x6B,0x14,0x8B,0x4A,0x0C,0xD9,0x52,0x46,0xC1,0x27,0xD5,0x87,0x1C,0x4F,0x11,0x41,0x86,0x90,0xA5,0xDD,0xF0,0x12,0x46,0xA0,0xC8,0x0A,0x43,0xC7,0x00,0x88,0xB6,0x18,0x36,0x39,0xDC,0xFD,0xA4,0x12,0x5B,0xD1,0x13,0xA8,0xF4,0x9E,0xE2,0x3E,0xD3,0x06,0xFA,0xAC,0x57,0x6C,0x3F,0xB0,0xC1,0xE2,0x56,0x67,0x1D,0x81,0x7F,0xC2,0x53,0x4A,0x52,0xF5,0xB4,0x39,0xF7,0x2E,0x42,0x4D,0xE3,0x76,0xF4,0xC5,0x65,0xCC,0xA8,0x23,0x07,0xDD,0x9E,0xF7,0x6D,0xA5,0xB7,0xC4,0xEB,0x7E,0x08,0x51,0x72,0xE3,0x28,0x80,0x7C,0x02,0xD0,0x11,0xFF,0xBF,0x33,0x78,0x53,0x78,0xD7,0x9D,0xC2,0x66,0xF6,0xA5,0xBE,0x6B,0xB0,0xE4,0xA9,0x2E,0xCE,0xEB,0xAE,0xB1], 4100).toHexString()).to.be('8a5199b4a7e133e264a86202720655894d48cff344a928cf8347f48379cef347dfc5bcffab99b27b1f89aa2735e23d30088ffa03b9edb02b9635470ab9f1038985d55f9ca774572dd006470ea65145469609f9fa0831bf1ffd842dc24acade27bd9816e3b5bf2876cb112232a0eb4475f1dff9f5c713d9ffd4ccb89ae5607fe35731df06317949eef646e9591cf3be53add6b7dd2b6096e2b3fb06e662ec8b2d77422daad9463cd155204acdbd38e319613f39f99b6dfb35ca9365160066db19835888c2241ff9a731a4acbb5663727aac34a401247fbaa7499e7d5ee5b69d31025e63d04c35c798bca1262d5673a9cf0930b5ad89bd485599dc184528da4790f088ebd170b635d9581632d2ff90db79665ced430089af13c9f21f6d443a818064f17aec9e9c5457001fa8dc6afbadbe3138f388d89d0e6f22f66671255b210754ed63d81dce75ce8f189b534e6d6b3539aa51e837c42df9df59c71e6171cd4902fe1bdc73fb1775b5c754a1ed4ea7f3105fc543ee0418dad256f3f6118ea77114a16c15355b42877a1db2a7df0e155ae1d8670abcec3450f4e2eec9838f895423ef63d261138baaf5d9f104cb5a957aea06c0b9b8c78b0d441796dc0350ddeabb78a33b6f1f9e68ede3d1805c7b7e2cfd54e0fad62f0d8ca67a775dc4546af9096f2edb221db42843d65327861282dc946a0ba01a11863ab2d1dfd16e3973d4');
expect(shake256.arrayBuffer([0x3A,0x3A,0x81,0x9C,0x48,0xEF,0xDE,0x2A,0xD9,0x14,0xFB,0xF0,0x0E,0x18,0xAB,0x6B,0xC4,0xF1,0x45,0x13,0xAB,0x27,0xD0,0xC1,0x78,0xA1,0x88,0xB6,0x14,0x31,0xE7,0xF5,0x62,0x3C,0xB6,0x6B,0x23,0x34,0x67,0x75,0xD3,0x86,0xB5,0x0E,0x98,0x2C,0x49,0x3A,0xDB,0xBF,0xC5,0x4B,0x9A,0x3C,0xD3,0x83,0x38,0x23,0x36,0xA1,0xA0,0xB2,0x15,0x0A,0x15,0x35,0x8F,0x33,0x6D,0x03,0xAE,0x18,0xF6,0x66,0xC7,0x57,0x3D,0x55,0xC4,0xFD,0x18,0x1C,0x29,0xE6,0xCC,0xFD,0xE6,0x3E,0xA3,0x5F,0x0A,0xDF,0x58,0x85,0xCF,0xC0,0xA3,0xD8,0x4A,0x2B,0x2E,0x4D,0xD2,0x44,0x96,0xDB,0x78,0x9E,0x66,0x31,0x70,0xCE,0xF7,0x47,0x98,0xAA,0x1B,0xBC,0xD4,0x57,0x4E,0xA0,0xBB,0xA4,0x04,0x89,0xD7,0x64,0xB2,0xF8,0x3A,0xAD,0xC6,0x6B,0x14,0x8B,0x4A,0x0C,0xD9,0x52,0x46,0xC1,0x27,0xD5,0x87,0x1C,0x4F,0x11,0x41,0x86,0x90,0xA5,0xDD,0xF0,0x12,0x46,0xA0,0xC8,0x0A,0x43,0xC7,0x00,0x88,0xB6,0x18,0x36,0x39,0xDC,0xFD,0xA4,0x12,0x5B,0xD1,0x13,0xA8,0xF4,0x9E,0xE2,0x3E,0xD3,0x06,0xFA,0xAC,0x57,0x6C,0x3F,0xB0,0xC1,0xE2,0x56,0x67,0x1D,0x81,0x7F,0xC2,0x53,0x4A,0x52,0xF5,0xB4,0x39,0xF7,0x2E,0x42,0x4D,0xE3,0x76,0xF4,0xC5,0x65,0xCC,0xA8,0x23,0x07,0xDD,0x9E,0xF7,0x6D,0xA5,0xB7,0xC4,0xEB,0x7E,0x08,0x51,0x72,0xE3,0x28,0x80,0x7C,0x02,0xD0,0x11,0xFF,0xBF,0x33,0x78,0x53,0x78,0xD7,0x9D,0xC2,0x66,0xF6,0xA5,0xBE,0x6B,0xB0,0xE4,0xA9,0x2E,0xCE,0xEB,0xAE,0xB1], 4100).toHexString()).to.be('8a5199b4a7e133e264a86202720655894d48cff344a928cf8347f48379cef347dfc5bcffab99b27b1f89aa2735e23d30088ffa03b9edb02b9635470ab9f1038985d55f9ca774572dd006470ea65145469609f9fa0831bf1ffd842dc24acade27bd9816e3b5bf2876cb112232a0eb4475f1dff9f5c713d9ffd4ccb89ae5607fe35731df06317949eef646e9591cf3be53add6b7dd2b6096e2b3fb06e662ec8b2d77422daad9463cd155204acdbd38e319613f39f99b6dfb35ca9365160066db19835888c2241ff9a731a4acbb5663727aac34a401247fbaa7499e7d5ee5b69d31025e63d04c35c798bca1262d5673a9cf0930b5ad89bd485599dc184528da4790f088ebd170b635d9581632d2ff90db79665ced430089af13c9f21f6d443a818064f17aec9e9c5457001fa8dc6afbadbe3138f388d89d0e6f22f66671255b210754ed63d81dce75ce8f189b534e6d6b3539aa51e837c42df9df59c71e6171cd4902fe1bdc73fb1775b5c754a1ed4ea7f3105fc543ee0418dad256f3f6118ea77114a16c15355b42877a1db2a7df0e155ae1d8670abcec3450f4e2eec9838f895423ef63d261138baaf5d9f104cb5a957aea06c0b9b8c78b0d441796dc0350ddeabb78a33b6f1f9e68ede3d1805c7b7e2cfd54e0fad62f0d8ca67a775dc4546af9096f2edb221db42843d65327861282dc946a0ba01a11863ab2d1dfd16e3973d4');
});
});
@@ -95,12 +97,18 @@
it('should be equal', function () {
// https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHAKE256.txt
// Len = 0, Msg = 00
expect(shake_256.array('', 4100).toHexString()).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a');
expect(shake256.array('', 4100).toHexString()).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a');
// Len = 2040
// Msg = 3A3A819C48EFDE2AD914FBF00E18AB6BC4F14513AB27D0C178A188B61431E7F5623CB66B23346775D386B50E982C493ADBBFC54B9A3CD383382336A1A0B2150A15358F336D03AE18F666C7573D55C4FD181C29E6CCFDE63EA35F0ADF5885CFC0A3D84A2B2E4DD24496DB789E663170CEF74798AA1BBCD4574EA0BBA40489D764B2F83AADC66B148B4A0CD95246C127D5871C4F11418690A5DDF01246A0C80A43C70088B6183639DCFDA4125BD113A8F49EE23ED306FAAC576C3FB0C1E256671D817FC2534A52F5B439F72E424DE376F4C565CCA82307DD9EF76DA5B7C4EB7E085172E328807C02D011FFBF33785378D79DC266F6A5BE6BB0E4A92ECEEBAEB1
expect(shake_256.array([0x3A,0x3A,0x81,0x9C,0x48,0xEF,0xDE,0x2A,0xD9,0x14,0xFB,0xF0,0x0E,0x18,0xAB,0x6B,0xC4,0xF1,0x45,0x13,0xAB,0x27,0xD0,0xC1,0x78,0xA1,0x88,0xB6,0x14,0x31,0xE7,0xF5,0x62,0x3C,0xB6,0x6B,0x23,0x34,0x67,0x75,0xD3,0x86,0xB5,0x0E,0x98,0x2C,0x49,0x3A,0xDB,0xBF,0xC5,0x4B,0x9A,0x3C,0xD3,0x83,0x38,0x23,0x36,0xA1,0xA0,0xB2,0x15,0x0A,0x15,0x35,0x8F,0x33,0x6D,0x03,0xAE,0x18,0xF6,0x66,0xC7,0x57,0x3D,0x55,0xC4,0xFD,0x18,0x1C,0x29,0xE6,0xCC,0xFD,0xE6,0x3E,0xA3,0x5F,0x0A,0xDF,0x58,0x85,0xCF,0xC0,0xA3,0xD8,0x4A,0x2B,0x2E,0x4D,0xD2,0x44,0x96,0xDB,0x78,0x9E,0x66,0x31,0x70,0xCE,0xF7,0x47,0x98,0xAA,0x1B,0xBC,0xD4,0x57,0x4E,0xA0,0xBB,0xA4,0x04,0x89,0xD7,0x64,0xB2,0xF8,0x3A,0xAD,0xC6,0x6B,0x14,0x8B,0x4A,0x0C,0xD9,0x52,0x46,0xC1,0x27,0xD5,0x87,0x1C,0x4F,0x11,0x41,0x86,0x90,0xA5,0xDD,0xF0,0x12,0x46,0xA0,0xC8,0x0A,0x43,0xC7,0x00,0x88,0xB6,0x18,0x36,0x39,0xDC,0xFD,0xA4,0x12,0x5B,0xD1,0x13,0xA8,0xF4,0x9E,0xE2,0x3E,0xD3,0x06,0xFA,0xAC,0x57,0x6C,0x3F,0xB0,0xC1,0xE2,0x56,0x67,0x1D,0x81,0x7F,0xC2,0x53,0x4A,0x52,0xF5,0xB4,0x39,0xF7,0x2E,0x42,0x4D,0xE3,0x76,0xF4,0xC5,0x65,0xCC,0xA8,0x23,0x07,0xDD,0x9E,0xF7,0x6D,0xA5,0xB7,0xC4,0xEB,0x7E,0x08,0x51,0x72,0xE3,0x28,0x80,0x7C,0x02,0xD0,0x11,0xFF,0xBF,0x33,0x78,0x53,0x78,0xD7,0x9D,0xC2,0x66,0xF6,0xA5,0xBE,0x6B,0xB0,0xE4,0xA9,0x2E,0xCE,0xEB,0xAE,0xB1], 4100).toHexString()).to.be('8a5199b4a7e133e264a86202720655894d48cff344a928cf8347f48379cef347dfc5bcffab99b27b1f89aa2735e23d30088ffa03b9edb02b9635470ab9f1038985d55f9ca774572dd006470ea65145469609f9fa0831bf1ffd842dc24acade27bd9816e3b5bf2876cb112232a0eb4475f1dff9f5c713d9ffd4ccb89ae5607fe35731df06317949eef646e9591cf3be53add6b7dd2b6096e2b3fb06e662ec8b2d77422daad9463cd155204acdbd38e319613f39f99b6dfb35ca9365160066db19835888c2241ff9a731a4acbb5663727aac34a401247fbaa7499e7d5ee5b69d31025e63d04c35c798bca1262d5673a9cf0930b5ad89bd485599dc184528da4790f088ebd170b635d9581632d2ff90db79665ced430089af13c9f21f6d443a818064f17aec9e9c5457001fa8dc6afbadbe3138f388d89d0e6f22f66671255b210754ed63d81dce75ce8f189b534e6d6b3539aa51e837c42df9df59c71e6171cd4902fe1bdc73fb1775b5c754a1ed4ea7f3105fc543ee0418dad256f3f6118ea77114a16c15355b42877a1db2a7df0e155ae1d8670abcec3450f4e2eec9838f895423ef63d261138baaf5d9f104cb5a957aea06c0b9b8c78b0d441796dc0350ddeabb78a33b6f1f9e68ede3d1805c7b7e2cfd54e0fad62f0d8ca67a775dc4546af9096f2edb221db42843d65327861282dc946a0ba01a11863ab2d1dfd16e3973d4');
expect(shake256.array([0x3A,0x3A,0x81,0x9C,0x48,0xEF,0xDE,0x2A,0xD9,0x14,0xFB,0xF0,0x0E,0x18,0xAB,0x6B,0xC4,0xF1,0x45,0x13,0xAB,0x27,0xD0,0xC1,0x78,0xA1,0x88,0xB6,0x14,0x31,0xE7,0xF5,0x62,0x3C,0xB6,0x6B,0x23,0x34,0x67,0x75,0xD3,0x86,0xB5,0x0E,0x98,0x2C,0x49,0x3A,0xDB,0xBF,0xC5,0x4B,0x9A,0x3C,0xD3,0x83,0x38,0x23,0x36,0xA1,0xA0,0xB2,0x15,0x0A,0x15,0x35,0x8F,0x33,0x6D,0x03,0xAE,0x18,0xF6,0x66,0xC7,0x57,0x3D,0x55,0xC4,0xFD,0x18,0x1C,0x29,0xE6,0xCC,0xFD,0xE6,0x3E,0xA3,0x5F,0x0A,0xDF,0x58,0x85,0xCF,0xC0,0xA3,0xD8,0x4A,0x2B,0x2E,0x4D,0xD2,0x44,0x96,0xDB,0x78,0x9E,0x66,0x31,0x70,0xCE,0xF7,0x47,0x98,0xAA,0x1B,0xBC,0xD4,0x57,0x4E,0xA0,0xBB,0xA4,0x04,0x89,0xD7,0x64,0xB2,0xF8,0x3A,0xAD,0xC6,0x6B,0x14,0x8B,0x4A,0x0C,0xD9,0x52,0x46,0xC1,0x27,0xD5,0x87,0x1C,0x4F,0x11,0x41,0x86,0x90,0xA5,0xDD,0xF0,0x12,0x46,0xA0,0xC8,0x0A,0x43,0xC7,0x00,0x88,0xB6,0x18,0x36,0x39,0xDC,0xFD,0xA4,0x12,0x5B,0xD1,0x13,0xA8,0xF4,0x9E,0xE2,0x3E,0xD3,0x06,0xFA,0xAC,0x57,0x6C,0x3F,0xB0,0xC1,0xE2,0x56,0x67,0x1D,0x81,0x7F,0xC2,0x53,0x4A,0x52,0xF5,0xB4,0x39,0xF7,0x2E,0x42,0x4D,0xE3,0x76,0xF4,0xC5,0x65,0xCC,0xA8,0x23,0x07,0xDD,0x9E,0xF7,0x6D,0xA5,0xB7,0xC4,0xEB,0x7E,0x08,0x51,0x72,0xE3,0x28,0x80,0x7C,0x02,0xD0,0x11,0xFF,0xBF,0x33,0x78,0x53,0x78,0xD7,0x9D,0xC2,0x66,0xF6,0xA5,0xBE,0x6B,0xB0,0xE4,0xA9,0x2E,0xCE,0xEB,0xAE,0xB1], 4100).toHexString()).to.be('8a5199b4a7e133e264a86202720655894d48cff344a928cf8347f48379cef347dfc5bcffab99b27b1f89aa2735e23d30088ffa03b9edb02b9635470ab9f1038985d55f9ca774572dd006470ea65145469609f9fa0831bf1ffd842dc24acade27bd9816e3b5bf2876cb112232a0eb4475f1dff9f5c713d9ffd4ccb89ae5607fe35731df06317949eef646e9591cf3be53add6b7dd2b6096e2b3fb06e662ec8b2d77422daad9463cd155204acdbd38e319613f39f99b6dfb35ca9365160066db19835888c2241ff9a731a4acbb5663727aac34a401247fbaa7499e7d5ee5b69d31025e63d04c35c798bca1262d5673a9cf0930b5ad89bd485599dc184528da4790f088ebd170b635d9581632d2ff90db79665ced430089af13c9f21f6d443a818064f17aec9e9c5457001fa8dc6afbadbe3138f388d89d0e6f22f66671255b210754ed63d81dce75ce8f189b534e6d6b3539aa51e837c42df9df59c71e6171cd4902fe1bdc73fb1775b5c754a1ed4ea7f3105fc543ee0418dad256f3f6118ea77114a16c15355b42877a1db2a7df0e155ae1d8670abcec3450f4e2eec9838f895423ef63d261138baaf5d9f104cb5a957aea06c0b9b8c78b0d441796dc0350ddeabb78a33b6f1f9e68ede3d1805c7b7e2cfd54e0fad62f0d8ca67a775dc4546af9096f2edb221db42843d65327861282dc946a0ba01a11863ab2d1dfd16e3973d4');
});
});
context('with 1128 output arrayBuffer', function () {
it('should be equal', function () {
expect(shake256.arrayBuffer('', 1128).toHexString()).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec46');
});
});
});
})(shake_256, shake_128);
})(shake256, shake128);
+262
View File
@@ -0,0 +1,262 @@
(function (tuplehash256, tuplehash128, tuplehashxof256, tuplehashxof128, kmac128) {
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/TupleHash_samples.pdf
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/TupleHashXOF_samples.pdf
var t1 = [0x00, 0x01, 0x02];
var t2 = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15];
var t3 = [0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28];
var testCases = [
{
name: 'tuplehash128',
method: tuplehash128,
cases: [
{
inputs: [t1, t2],
bits: 256,
s: '',
output: 'c5d8786c1afb9b82111ab34b65b2c0048fa64e6d48e263264ce1707d3ffc8ed1'
},
{
inputs: [t1, t2],
bits: 256,
s: 'My Tuple App',
output: '75cdb20ff4db1154e841d758e24160c54bae86eb8c13e7f5f40eb35588e96dfb'
},
{
inputs: [t1, t2, t3],
bits: 256,
s: 'My Tuple App',
output: 'e60f202c89a2631eda8d4c588ca5fd07f39e5151998deccf973adb3804bb6e84'
}
]
},
{
name: 'tuplehash256',
method: tuplehash256,
cases: [
{
inputs: [t1, t2],
bits: 512,
s: '',
output: 'cfb7058caca5e668f81a12a20a2195ce97a925f1dba3e7449a56f82201ec607311ac2696b1ab5ea2352df1423bde7bd4bb78c9aed1a853c78672f9eb23bbe194'
},
{
inputs: [t1, t2],
bits: 512,
s: 'My Tuple App',
output: '147c2191d5ed7efd98dbd96d7ab5a11692576f5fe2a5065f3e33de6bba9f3aa1c4e9a068a289c61c95aab30aee1e410b0b607de3620e24a4e3bf9852a1d4367e'
},
{
inputs: [t1, t2, t3],
bits: 512,
s: 'My Tuple App',
output: '45000be63f9b6bfd89f54717670f69a9bc763591a4f05c50d68891a744bcc6e7d6d5b5e82c018da999ed35b0bb49c9678e526abd8e85c13ed254021db9e790ce'
}
]
},
{
name: 'tuplehashxof128',
method: tuplehashxof128,
cases: [
{
inputs: [t1, t2],
bits: 256,
s: '',
output: '2f103cd7c32320353495c68de1a8129245c6325f6f2a3d608d92179c96e68488'
},
{
inputs: [t1, t2],
bits: 256,
s: 'My Tuple App',
output: '3fc8ad69453128292859a18b6c67d7ad85f01b32815e22ce839c49ec374e9b9a'
},
{
inputs: [t1, t2, t3],
bits: 256,
s: 'My Tuple App',
output: '900fe16cad098d28e74d632ed852f99daab7f7df4d99e775657885b4bf76d6f8'
}
]
},
{
name: 'tuplehashxof256',
method: tuplehashxof256,
cases: [
{
inputs: [t1, t2],
bits: 512,
s: '',
output: '03ded4610ed6450a1e3f8bc44951d14fbc384ab0efe57b000df6b6df5aae7cd568e77377daf13f37ec75cf5fc598b6841d51dd207c991cd45d210ba60ac52eb9'
},
{
inputs: [t1, t2],
bits: 512,
s: 'My Tuple App',
output: '6483cb3c9952eb20e830af4785851fc597ee3bf93bb7602c0ef6a65d741aeca7e63c3b128981aa05c6d27438c79d2754bb1b7191f125d6620fca12ce658b2442'
},
{
inputs: [t1, t2, t3],
bits: 512,
s: 'My Tuple App',
output: '0c59b11464f2336c34663ed51b2b950bec743610856f36c28d1d088d8a2446284dd09830a6a178dc752376199fae935d86cfdee5913d4922dfd369b66a53c897'
}
]
}
];
testCases.forEach(function (testCase) {
describe('#' + testCase.name, function () {
testCase.cases.forEach(function (c) {
it('should match NIST sample vector', function () {
expect(testCase.method(c.inputs, c.bits, c.s)).to.be(c.output);
});
});
});
});
describe('#tuplehash API', function () {
it('should treat empty tuple and empty inputs as valid', function () {
var emptyTuple = tuplehash128([], 256, '');
var oneEmpty = tuplehash128([''], 256, '');
var twoEmpty = tuplehash128(['', ''], 256, '');
expect(emptyTuple).to.not.be(oneEmpty);
expect(oneEmpty).to.not.be(twoEmpty);
expect(twoEmpty).to.not.be(tuplehash128(['', '', ''], 256, ''));
expect(tuplehash128.create(256, '').update('').update(t1).hex()).to.be(tuplehash128(['', t1], 256, ''));
});
it('should distinguish tuple boundaries', function () {
expect(tuplehash128(['abc', 'd'], 256, '')).to.not.be(tuplehash128(['ab', 'cd'], 256, ''));
});
it('should match instance update and method update with one-shot', function () {
var expected = tuplehash128(['abc', 'd'], 256, 'cache');
var incremental = tuplehash128.create(256, 'cache').update('abc').update('d').hex();
var methodUpdate = tuplehash128.update(['abc'], 256, 'cache').update('d').hex();
expect(incremental).to.be(expected);
expect(methodUpdate).to.be(expected);
expect(tuplehash128.update(['abc', 'd'], 256, 'cache').hex()).to.be(expected);
});
it('should stream binary messages in irregular chunks', function () {
var bytes = [];
for (var i = 0; i < 200; ++i) {
bytes.push(i & 0xff);
}
var expected = tuplehash128([bytes, t1], 256, '');
var hash = tuplehash128.create(256, '');
hash.beginInput(bytes.length);
hash.updateChunk(bytes.slice(0, 1));
hash.updateChunk(bytes.slice(1, 17));
hash.updateChunk(bytes.slice(17, 168));
hash.updateChunk(bytes.slice(168));
hash.beginInput(t1.length);
hash.updateChunk(t1);
expect(hash.hex()).to.be(expected);
});
it('should stream ArrayBuffer and Uint8Array views', function () {
var expected = tuplehash128([t1, t2], 256, '');
var buffer = new Uint8Array(t1).buffer;
var view = new Uint8Array(new Uint8Array(t2).buffer, 0, t2.length);
var hash = tuplehash128.create(256, '');
hash.beginInput(t1.length).updateChunk(buffer);
hash.beginInput(t2.length).updateChunk(view);
expect(hash.hex()).to.be(expected);
});
it('should support zero-length streaming input', function () {
var expected = tuplehash128(['', t1], 256, '');
var hash = tuplehash128.create(256, '');
hash.beginInput(0);
hash.beginInput(t1.length).updateChunk(t1);
expect(hash.hex()).to.be(expected);
});
it('should reject invalid streaming usage', function () {
var hash = tuplehash128.create(256, '');
expect(function () { hash.updateChunk(t1); }).to.throwError(/no active tuple input/);
hash.beginInput(2);
expect(function () { hash.updateChunk([1, 2, 3]); }).to.throwError(/exceeds declared length/);
expect(function () { hash.beginInput(1); }).to.throwError(/incomplete/);
expect(function () { hash.update(t1); }).to.throwError(/incomplete/);
expect(function () { hash.hex(); }).to.throwError(/incomplete/);
hash.updateChunk([1]);
expect(function () { hash.hex(); }).to.throwError(/incomplete/);
});
it('should reject invalid beginInput lengths', function () {
var hash = tuplehash128.create(256, '');
expect(function () { hash.beginInput(-1); }).to.throwError(/byte length is invalid/);
expect(function () { hash.beginInput(1.5); }).to.throwError(/byte length is invalid/);
expect(function () { hash.beginInput(NaN); }).to.throwError(/byte length is invalid/);
expect(function () { hash.beginInput(0x20000000); }).to.throwError(/byte length is invalid/);
});
it('should allow repeated output representations', function () {
var hash = tuplehash128.create(256, '').update(t1).update(t2);
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(t1); }).to.throwError(/finalize already called/);
expect(function () { hash.updateChunk(t1); }).to.throwError(/no active tuple input/);
});
it('should require customization like KMAC', function () {
expect(function () { tuplehash128([t1], 256); }).to.throwError(/input is invalid type/);
});
it('should require inputs to be an array', function () {
expect(function () { tuplehash128('abc', 256, ''); }).to.throwError(/input is invalid type/);
expect(function () { tuplehash128.update(t1, 256, ''); }).to.throwError(/input is invalid type/);
expect(function () { tuplehash128.hex(null, 256, ''); }).to.throwError(/input is invalid type/);
expect(function () { tuplehashxof128(undefined, 256, ''); }).to.throwError(/input is invalid type/);
});
it('should export identical aliases', function () {
var sha3 = require('../src/sha3.js');
expect(sha3.tuplehash128).to.be(sha3.tuplehash_128);
expect(sha3.tuplehash256).to.be(sha3.tuplehash_256);
expect(sha3.tuplehashxof128).to.be(sha3.tuplehashxof_128);
expect(sha3.tuplehashxof256).to.be(sha3.tuplehashxof_256);
});
it('should count UTF-8 string bytes for streaming', function () {
var message = 'åbc'; // 2 + 1 + 1 = 4 UTF-8 bytes
var expected = tuplehash128([message], 256, '');
var hash = tuplehash128.create(256, '');
hash.beginInput(4).updateChunk('å').updateChunk('bc');
expect(hash.hex()).to.be(expected);
expect(message.length).to.be(3);
});
it('should count 3-byte and 4-byte UTF-8 string bytes for streaming', function () {
var message = '中\uE000\uD83D\uDE00'; // 3 + 3 + 4 = 10 UTF-8 bytes
var expected = tuplehash128([message], 256, '');
var hash = tuplehash128.create(256, '');
hash.beginInput(10).updateChunk('中').updateChunk('\uE000').updateChunk('\uD83D\uDE00');
expect(hash.hex()).to.be(expected);
});
it('should reject update and beginInput after finalize', function () {
var hash = tuplehash128.create(256, '').update([0x00]);
hash.hex();
expect(function () { hash.update([0x01]); }).to.throwError(/finalize already called/);
expect(function () { hash.beginInput(1); }).to.throwError(/finalize already called/);
});
});
describe('#kmac repeated output', function () {
it('should allow repeated output reads after finalize fix', function () {
var hash = kmac128.create([0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F], 256, '');
hash.update([0x00, 0x01, 0x02, 0x03]);
var hex = hash.hex();
expect(hash.hex()).to.be(hex);
expect(hash.array().length).to.be(32);
});
});
})(tuplehash256, tuplehash128, tuplehashxof256, tuplehashxof128, kmac128);
+192 -126
View File
@@ -1,4 +1,4 @@
(function (sha3_512, sha3_384, sha3_256, sha3_224, keccak_512, keccak_384, keccak_256, keccak_224) {
(function (sha3_512, sha3_384, sha3_256, sha3_224, keccak512, keccak384, keccak256, keccak224) {
Array.prototype.toHexString = ArrayBuffer.prototype.toHexString = function () {
var array = new Uint8Array(this);
var hex = '';
@@ -9,63 +9,6 @@
return hex;
};
function runTestCases(methods, testCases) {
methods.forEach(function (method) {
describe('#' + method.name, function () {
var methodTestCases = testCases[method.name];
for (var testCaseName in methodTestCases) {
(function (testCaseName) {
var testCase = methodTestCases[testCaseName];
context('when ' + testCaseName, function () {
for (var hash in testCase) {
(function (message, hash) {
it('should be equal', function () {
expect(method.call(message)).to.be(hash);
});
})(testCase[hash], hash);
}
});
})(testCaseName);
}
});
});
}
var methods = [
{
name: 'sha3_512',
call: sha3_512
},
{
name: 'sha3_384',
call: sha3_384
},
{
name: 'sha3_256',
call: sha3_256
},
{
name: 'sha3_224',
call: sha3_224
},
{
name: 'keccak_512',
call: keccak_512
},
{
name: 'keccak_384',
call: keccak_384
},
{
name: 'keccak_256',
call: keccak_256
},
{
name: 'keccak_224',
call: keccak_224
}
];
var testCases = {
sha3_512: {
'ascii': {
@@ -92,13 +35,6 @@
'Array': {
'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': [],
'01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]
},
'Uint8Array': {
'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': new Uint8Array([]),
'01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
},
'ArrayBuffer': {
'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': new ArrayBuffer(0)
}
},
sha3_384: {
@@ -158,7 +94,7 @@
'bd05581e02445c53e05aad2014f6a3819d77a9dff918b8c6bf60bd06': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。'
}
},
keccak_512: {
keccak512: {
'ascii': {
'0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e': '',
'd135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609': 'The quick brown fox jumps over the lazy dog',
@@ -177,7 +113,7 @@
'd04ff5b0e85e9968be2a4d4e133c15c7ccee7497198bb651599a97d11d00bca6048d329ab75aa454566cd532648fa1cb4551985d9d645de9fa43a311a9ee8e4d': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。'
}
},
keccak_384: {
keccak384: {
'ascii': {
'2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff': '',
'283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3': 'The quick brown fox jumps over the lazy dog',
@@ -196,7 +132,7 @@
'66414c090cc3fe9c396d313cbaa100aefd335e851838b29382568b7f57357ada7c54b8fa8c17f859945bba88b2c2e332': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。'
}
},
keccak_256: {
keccak256: {
'ascii': {
'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470': '',
'4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15': 'The quick brown fox jumps over the lazy dog',
@@ -215,7 +151,7 @@
'ffabf9bba2127c4928d360c9905cb4911f0ec21b9c3b89f3b242bccc68389e36': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。'
}
},
keccak_224: {
keccak224: {
'ascii': {
'f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd': '',
'310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe': 'The quick brown fox jumps over the lazy dog',
@@ -236,80 +172,210 @@
}
};
runTestCases(methods, testCases);
describe('sha3_512', function () {
context('#arrayBuffer', function () {
it('should be equal', function () {
expect(sha3_512.arrayBuffer('').toHexString()).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26');
expect(sha3_512.buffer('').toHexString()).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26');
});
});
context('#hex', function () {
it('should be equal', function () {
expect(sha3_512.hex('')).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26');
});
});
context('#update', function () {
it('should be equal', function () {
expect(sha3_512.update('').hex()).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26');
expect(sha3_512.update('The quick brown fox ').update('jumps over the lazy dog').hex()).to.be('01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450');
});
});
context('#create', function () {
it('should be equal', function () {
var bytes = [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103];
var hash = sha3_512.create();
for (var i = 0;i < bytes.length;++i) {
hash.update([bytes[i]]);
if (!(typeof JS_SHA3_NO_ARRAY_BUFFER === 'boolean' && JS_SHA3_NO_ARRAY_BUFFER)) {
testCases.sha3_512.Uint8Array = {
'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': new Uint8Array([]),
'01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
};
testCases.sha3_512.ArrayBuffer = {
'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': new ArrayBuffer(0),
'01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]).buffer
};
}
expect(hash.hex()).to.be('01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450');
});
});
});
describe('#keccak_512', function () {
context('when special length', function () {
if (typeof BUFFER === 'boolean' && BUFFER) {
testCases.sha3_512.Buffer = {
'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': Buffer.from([]),
'01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': Buffer.from(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]))
};
}
var errorTestCases = [null, undefined, { length: 0 }, 0, 1, false, true, NaN, Infinity, function () {}];
function runTestCases(name, algorithm) {
var methods = [
{
name: name,
call: algorithm,
},
{
name: name + '.hex',
call: algorithm.hex
},
{
name: name + '.array',
call: function (message) {
return algorithm.array(message).toHexString();
}
},
{
name: name + '.digest',
call: function (message) {
return algorithm.digest(message).toHexString();
}
},
{
name: name + '.arrayBuffer',
call: function (message) {
return algorithm.arrayBuffer(message).toHexString();
}
}
];
var classMethods = [
{
name: 'create',
call: function (message) {
return algorithm.create().update(message).toString();
}
},
{
name: 'update',
call: function (message) {
return algorithm.update(message).toString();
}
},
{
name: 'hex',
call: function (message) {
return algorithm.update(message).hex();
}
},
{
name: 'array',
call: function (message) {
return algorithm.update(message).array().toHexString();
}
},
{
name: 'digest',
call: function (message) {
return algorithm.update(message).digest().toHexString();
}
},
{
name: 'arrayBuffer',
call: function (message) {
return algorithm.update(message).arrayBuffer().toHexString();
}
},
{
name: 'finalize',
call: function (message) {
var hash = algorithm.update(message);
hash.hex();
hash.finalize();
return hash.hex();
}
}
];
var subTestCases = testCases[name];
describe(name, function () {
methods.forEach(function (method) {
describe('#' + method.name, function () {
for (var testCaseName in subTestCases) {
(function (testCaseName) {
var testCase = subTestCases[testCaseName];
context('when ' + testCaseName, function () {
for (var hash in testCase) {
(function (message, hash) {
it('should be equal', function () {
expect(keccak_512('012345678901234567890123456789012345678901234567890123456789012345678901')).to.be('90b1d032c3bf06dcc78a46fe52054bab1250600224bfc6dfbfb40a7877c55e89bb982799a2edf198568a4166f6736678b45e76b12fac813cfdf0a76714e5eae8');
expect(keccak_512('01234567890123456789012345678901234567890123456789012345678901234567890')).to.be('3173e7abc754a0b2909410d78986428a9183e996864af02f421d273d9fa1b4e4a5b14e2998b20767712f53a01ff8f6ae2c3e71e51e2c0f24257b03e6da09eb77');
expect(method.call(message)).to.be(hash);
});
})(testCase[hash], hash);
}
});
})(testCaseName);
}
});
});
context('when Array', function () {
classMethods.forEach(function (method) {
describe('#' + method.name, function () {
for (var testCaseName in subTestCases) {
(function (testCaseName) {
var testCase = subTestCases[testCaseName];
context('when ' + testCaseName, function () {
for (var hash in testCase) {
(function (message, hash) {
it('should be equal', function () {
expect(keccak_512([])).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e');
expect(keccak_512([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])).to.be('d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609');
expect(method.call(message)).to.be(hash);
});
})(testCase[hash], hash);
}
});
})(testCaseName);
}
});
});
context('when Uint8Array', function () {
it('should be equal', function () {
expect(keccak_512(new Uint8Array([]))).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e');
expect(keccak_512(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]))).to.be('d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609');
describe('#' + name, function () {
errorTestCases.forEach(function (testCase) {
context('when ' + testCase, function () {
it('should throw error', function () {
expect(function () {
algorithm(testCase);
}).to.throwError(/input is invalid type/);
});
});
});
context('when update after finalize', function () {
it('should throw error', function () {
expect(function () {
var hash = algorithm.update('any');
hash.hex();
hash.update('any');
}).to.throwError(/finalize already called/);
});
});
});
});
}
runTestCases('sha3_512', sha3_512);
runTestCases('sha3_384', sha3_384);
runTestCases('sha3_256', sha3_256);
runTestCases('sha3_224', sha3_224);
runTestCases('keccak512', keccak512);
runTestCases('keccak384', keccak384);
runTestCases('keccak256', keccak256);
runTestCases('keccak224', keccak224);
describe('#keccak512', function () {
context('#encodeString', function () {
errorTestCases.forEach(function (testCase) {
context('when ' + testCase, function () {
it('should throw error', function () {
expect(function () {
keccak512.create().encodeString(testCase);
}).to.throwError(/input is invalid type/);
});
});
});
if (!(typeof JS_SHA3_NO_ARRAY_BUFFER === 'boolean' && JS_SHA3_NO_ARRAY_BUFFER)) {
context('when ArrayBuffer', function () {
it('should be equal', function () {
expect(keccak_512(new ArrayBuffer(0))).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e');
it('should throw error', function () {
expect(keccak512.create().encodeString(new ArrayBuffer(0))).to.be(2);
});
});
context('when Uint8Array', function () {
it('should throw error', function () {
expect(keccak512.create().encodeString(new Uint8Array(0))).to.be(2);
});
});
}
context('when output ArrayBuffer', function () {
it('should be equal', function () {
expect(keccak_512.arrayBuffer('').toHexString()).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e');
expect(keccak_512.buffer('').toHexString()).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e');
});
});
context('when output Array', function () {
it('should be equal', function () {
expect(keccak_512.array('').toHexString()).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e');
context('when UTF-8', function () {
it('should throw error', function () {
expect(keccak512.create().encodeString('中文')).to.be(8);
expect(keccak512.create().encodeString('aécio')).to.be(8);
expect(keccak512.create().encodeString('𠜎')).to.be(6);
});
});
});
})(sha3_512, sha3_384, sha3_256, sha3_224, keccak_512, keccak_384, keccak_256, keccak_224);
});
})(sha3_512, sha3_384, sha3_256, sha3_224, keccak512, keccak384, keccak256, keccak224);
+24
View File
@@ -0,0 +1,24 @@
(function (Worker, WORKER, SOURCE) {
var cases = {
'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': '',
'01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': 'The quick brown fox jumps over the lazy dog',
'18f4f4bd419603f95538837003d9d254c26c23765565162247483f65c50303597bc9ce4d289f21d1c2f1f458828e33dc442100331b35e7eb031b5d38ba6460f8': 'The quick brown fox jumps over the lazy dog.'
};
describe('#sha3_512', function () {
Object.keys(cases).forEach(function (hash) {
it('should be equal', function (done) {
var worker = new Worker(WORKER);
worker.onmessage = function(event) {
expect(event.data).to.be(hash);
if (worker.terminate) {
worker.terminate();
}
done();
};
worker.postMessage(SOURCE);
worker.postMessage(cases[hash]);
});
});
});
})(Worker, WORKER, SOURCE);
+26
View File
@@ -0,0 +1,26 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SHA3</title>
<link rel="stylesheet" href="../node_modules/mocha/mocha.css">
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/expect.js/index.js"></script>
<script src="../src/sha3.js"></script>
</head>
<body>
<div id="mocha"></div>
<script>
WORKER = 'worker.js';
SOURCE = '../src/sha3.js';
mocha.setup('bdd');
</script>
<script src="worker-test.js"></script>
<script>
mocha.checkLeaks();
mocha.run();
</script>
<script>
</script>
</body>
</html>
+12
View File
@@ -0,0 +1,12 @@
var imported = false;
onmessage = function(e) {
if (imported) {
postMessage(sha3_512(e.data));
if (typeof exports !== 'undefined') {
imported = false;
}
} else {
imported = true;
importScripts(e.data);
}
}