mirror of
https://github.com/emn178/js-sha256.git
synced 2026-08-12 20:32:16 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a54fb31d4 | ||
|
|
1559263f5b | ||
|
|
a6d0f636aa | ||
|
|
b766562f6a | ||
|
|
7de3689e3c | ||
|
|
03f78b8bb0 | ||
|
|
6755b755cc | ||
|
|
62d740ca61 | ||
|
|
36d8fc4609 | ||
|
|
aee5ce367e | ||
|
|
1b03e6b2b6 | ||
|
|
da84f28777 | ||
|
|
bacba8e8c6 | ||
|
|
7912494a5a | ||
|
|
1aa1c17124 | ||
|
|
bdc011392b | ||
|
|
a1d21024aa | ||
|
|
138e2e169b | ||
|
|
dbb7a10027 | ||
|
|
250566e984 | ||
|
|
dc41862e53 | ||
|
|
c31830ad54 | ||
|
|
f490ee426a | ||
|
|
bb8ae3a623 | ||
|
|
16b101f040 | ||
|
|
189bb9b037 | ||
|
|
e35c679c2b | ||
|
|
bf155ab82f | ||
|
|
68ffecdc6e | ||
|
|
3204c3743e | ||
|
|
4e5354859f | ||
|
|
cf975dfa0c | ||
|
|
77efe9529c | ||
|
|
ee3b3869bc | ||
|
|
b3e7b83e39 | ||
|
|
bae387d0b2 | ||
|
|
730f41e84b | ||
|
|
3c278a9dde | ||
|
|
64c114b54e | ||
|
|
0a82ff3825 | ||
|
|
61d4076633 | ||
|
|
1ff17fbdd9 |
@@ -1 +0,0 @@
|
||||
/tests/
|
||||
@@ -0,0 +1,85 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node 24
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24.x
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Pack npm package
|
||||
run: |
|
||||
mkdir -p package-artifact
|
||||
npm pack --pack-destination package-artifact
|
||||
|
||||
- name: Upload package artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: package-node-24
|
||||
path: package-artifact/*.tgz
|
||||
if-no-files-found: error
|
||||
|
||||
runtime-test:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x, 18.x, 20.x, 22.x, 24.x]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Download package artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: package-node-24
|
||||
path: package-artifact
|
||||
|
||||
- name: Extract package artifact
|
||||
run: tar -xzf package-artifact/*.tgz --strip-components=1 -C .
|
||||
|
||||
- name: Run runtime tests
|
||||
if: matrix.node-version != '24.x'
|
||||
run: npm run test:runtime
|
||||
|
||||
- name: Run runtime tests with coverage
|
||||
if: matrix.node-version == '24.x'
|
||||
run: npm run test:coverage
|
||||
|
||||
- name: Install Chromium
|
||||
if: matrix.node-version == '24.x'
|
||||
run: npx playwright install --with-deps chromium
|
||||
|
||||
- name: Run browser Worker tests
|
||||
if: matrix.node-version == '24.x'
|
||||
run: npm run test:browser
|
||||
|
||||
- name: Upload to coveralls
|
||||
if: matrix.node-version == '24.x'
|
||||
uses: coverallsapp/github-action@v2
|
||||
with:
|
||||
file: ./coverage/lcov.info
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24.x
|
||||
registry-url: https://registry.npmjs.org
|
||||
package-manager-cache: false
|
||||
|
||||
- run: npm ci
|
||||
|
||||
- name: Verify release version
|
||||
run: |
|
||||
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
||||
test "$GITHUB_REF_NAME" = "v$PACKAGE_VERSION"
|
||||
|
||||
- run: npm run build
|
||||
- run: npm test
|
||||
- run: npm publish
|
||||
+5
-2
@@ -1,2 +1,5 @@
|
||||
node_modules/
|
||||
covreporter
|
||||
/node_modules/
|
||||
/coverage/
|
||||
/.nyc_output/
|
||||
/playwright-report/
|
||||
/test-results/
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/node_modules/
|
||||
/coverage/
|
||||
/.nyc_output/
|
||||
/test-results/
|
||||
/tests/
|
||||
.covignore
|
||||
.travis.yml
|
||||
.npmignore
|
||||
bower.json
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
before_install:
|
||||
- npm install mocha -g
|
||||
- npm install coveralls -g
|
||||
- npm install mocha-lcov-reporter -g
|
||||
script: npm run-script coveralls
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
+146
-24
@@ -1,41 +1,163 @@
|
||||
# v0.2.3 / 2015-02-11
|
||||
# Change Log
|
||||
|
||||
* Support byte array input.
|
||||
## v1.0.0 / 2026-07-27
|
||||
### Added
|
||||
- Add dedicated ESM, CommonJS, Node.js, and browser distribution entry points.
|
||||
- Add streaming support to the native Node.js SHA-256, SHA-224, and HMAC implementations.
|
||||
- Add distribution contract tests and real browser Web Worker tests with Playwright.
|
||||
- Add Node.js 16, 18, 20, 22, and 24 runtime tests against the packed npm artifact.
|
||||
|
||||
# v0.2.2 / 2015-02-10
|
||||
### Changed
|
||||
- Refactor the implementation into environment-independent core and Node.js modules.
|
||||
- Use the native Node.js `crypto` implementation for hashing and HMAC.
|
||||
- Load the package version automatically when generating distribution banners.
|
||||
- Export unminified ESM source directly and build only CommonJS and browser/minified distributions.
|
||||
- Replace `expect.js`, NYC, Tiny Worker, and UglifyJS with Node.js assert, c8, Playwright, and Rollup/Terser.
|
||||
- Build automatically before `npm pack` and `npm publish`.
|
||||
- Throw error if update after finalize
|
||||
|
||||
* Improve performance.
|
||||
### Removed
|
||||
- Remove runtime CommonJS, AMD, Node.js, Web Worker, and ArrayBuffer environment switches from the core implementation.
|
||||
- Remove legacy environment flags and obsolete compatibility polyfills.
|
||||
- Remove the old generated `sha256.mjs` and `sha256.node.mjs` entry points.
|
||||
|
||||
# v0.2.1 / 2015-02-05
|
||||
## v0.12.0 / 2026-07-18
|
||||
### Added
|
||||
- support ESM #44
|
||||
- Set up GitHub release action / provenance #46
|
||||
|
||||
* Fixed special length bug.
|
||||
* Add test cases.
|
||||
### Fixed
|
||||
- Fix uploading coverage to coveralls #52
|
||||
- fix recognize environment is node when use browserfs #53
|
||||
|
||||
# v0.2.0 / 2015-02-03
|
||||
## v0.11.1 / 2025-05-24
|
||||
### Fixed
|
||||
- Fix NodeJS check for electron renderer #49
|
||||
|
||||
* Remove ascii parameter.
|
||||
* Improve performance.
|
||||
* Add test cases.
|
||||
## v0.11.0 / 2024-01-24
|
||||
### Fixed
|
||||
- Generates incorrect hash in some cases #43
|
||||
- dependencies and security issues. #41
|
||||
|
||||
# v0.1.4 / 2015-01-24
|
||||
## v0.10.1 / 2023-08-31
|
||||
### Added
|
||||
- Disable webpack polyfill.
|
||||
|
||||
* Improve performance.
|
||||
## v0.10.0 / 2023-08-30
|
||||
### Fixed
|
||||
- Chrome bug by workaround. #40
|
||||
- deprecated `new Buffer`, replace with `Buffer.from`. #34
|
||||
- dependencies and security issues. #32, #36
|
||||
|
||||
# v0.1.3 / 2015-01-09
|
||||
### Changed
|
||||
- TypeScript interface, secretKey can be bytes like message. #23, #25
|
||||
- remove `eval` and use `require` directly. #18, #26
|
||||
|
||||
* Improve performance.
|
||||
## v0.9.0 / 2017-12-18
|
||||
### Fixed
|
||||
- incorrect result when first bit is 1 of bytes.
|
||||
|
||||
# v0.1.2 / 2015-01-06
|
||||
### Changed
|
||||
- throw error by Error oject. #13
|
||||
|
||||
* Add bower package.
|
||||
* Fixed JSHint warnings.
|
||||
* Add travis.
|
||||
* Add coveralls.
|
||||
### Added
|
||||
- TypeScript interfaces. #12
|
||||
|
||||
# v0.1.1 / 2014-07-27
|
||||
## v0.8.0 / 2017-11-19
|
||||
### Added
|
||||
- support for web worker.
|
||||
- typescript types. #10
|
||||
|
||||
* Fixed accents bug
|
||||
### Changed
|
||||
- prevent webpack to require dependencies.
|
||||
|
||||
# v0.1.0 / 2014-01-05
|
||||
## v0.7.1 / 2017-10-31
|
||||
### Improved
|
||||
- performance of hBytes increment.
|
||||
|
||||
* Initial release
|
||||
## v0.7.0 / 2017-10-31
|
||||
### Fixed
|
||||
- incorrect result when file size >= 512M.
|
||||
|
||||
## v0.6.0 / 2017-07-11
|
||||
### Added
|
||||
- HMAC feature.
|
||||
|
||||
### Changed
|
||||
- throw error if input type is incorrect.
|
||||
|
||||
## v0.5.0 / 2017-01-24
|
||||
### Added
|
||||
- Streaming support #6
|
||||
|
||||
## v0.4.0 / 2017-01-23
|
||||
### Added
|
||||
- AMD support.
|
||||
|
||||
### Fixed
|
||||
- ArrayBuffer dosen't work in Webpack.
|
||||
|
||||
## v0.3.2 / 2016-09-12
|
||||
### Added
|
||||
- CommonJS detection.
|
||||
|
||||
## v0.3.1 / 2016-09-08
|
||||
### Added
|
||||
- some files to npm package.
|
||||
|
||||
### Fixed
|
||||
- coding style.
|
||||
|
||||
## v0.3.0 / 2015-05-23
|
||||
### Added
|
||||
- support for ArrayBuffer input.
|
||||
|
||||
## v0.2.3 / 2015-02-11
|
||||
### Added
|
||||
- support for byte array input.
|
||||
|
||||
## v0.2.2 / 2015-02-10
|
||||
### Improved
|
||||
- performance.
|
||||
|
||||
## v0.2.1 / 2015-02-05
|
||||
### Fixed
|
||||
- special length bug.
|
||||
|
||||
### Added
|
||||
- test cases.
|
||||
|
||||
## v0.2.0 / 2015-02-03
|
||||
### Removed
|
||||
- ascii parameter.
|
||||
|
||||
### Improved
|
||||
- performance.
|
||||
|
||||
### Added
|
||||
- test cases.
|
||||
|
||||
## v0.1.4 / 2015-01-24
|
||||
### Improved
|
||||
- performance.
|
||||
|
||||
## v0.1.3 / 2015-01-09
|
||||
### Improved
|
||||
- performance.
|
||||
|
||||
## v0.1.2 / 2015-01-06
|
||||
### Added
|
||||
- bower package.
|
||||
- travis.
|
||||
- coveralls.
|
||||
|
||||
### Fixed
|
||||
- JSHint warnings.
|
||||
|
||||
## v0.1.1 / 2014-07-27
|
||||
### Fixed
|
||||
- accents bug.
|
||||
|
||||
## v0.1.0 / 2014-01-05
|
||||
### Added
|
||||
- initial release.
|
||||
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
Copyright 2014-2015 emn178@gmail.com
|
||||
Copyright (c) 2014-2026 Chen, Yi-Cyuan
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,123 +1,133 @@
|
||||
# js-sha256
|
||||
[](https://travis-ci.org/emn178/js-sha256)
|
||||
[](https://github.com/emn178/js-sha256/actions/workflows/ci.yml)
|
||||
[](https://coveralls.io/r/emn178/js-sha256?branch=master)
|
||||
[](https://nodei.co/npm/js-sha256/)
|
||||
[](https://www.npmjs.com/package/js-sha256)
|
||||
[](https://www.jsdelivr.com/package/npm/js-sha256)
|
||||
|
||||
A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.
|
||||
|
||||
## Demo
|
||||
[SHA256 Online](http://emn178.github.io/online-tools/sha256.html)
|
||||
[SHA224 Online](http://emn178.github.io/online-tools/sha224.html)
|
||||
[SHA256 Online](https://emn178.github.io/online-tools/sha256.html)
|
||||
[SHA224 Online](https://emn178.github.io/online-tools/sha224.html)
|
||||
[SHA256 File Online](https://emn178.github.io/online-tools/sha256_checksum.html)
|
||||
[SHA224 File Online](https://emn178.github.io/online-tools/sha224_checksum.html)
|
||||
|
||||
## Download
|
||||
[Compress](https://raw.github.com/emn178/js-sha256/master/build/sha256.min.js)
|
||||
[Uncompress](https://raw.github.com/emn178/js-sha256/master/src/sha256.js)
|
||||
[Uncompress](https://raw.github.com/emn178/js-sha256/master/build/sha256.js)
|
||||
|
||||
## Installation
|
||||
You can also install js-sha256 by using Bower.
|
||||
|
||||
bower install js-sha256
|
||||
|
||||
For node.js, you can use this command to install:
|
||||
For Node.js, you can use this command to install:
|
||||
|
||||
npm install js-sha256
|
||||
|
||||
## Usage
|
||||
You could use like this:
|
||||
|
||||
### Browser
|
||||
Load the minified UMD build to expose `sha256` and `sha224` as globals:
|
||||
|
||||
```HTML
|
||||
<script src="sha256.min.js"></script>
|
||||
<script>
|
||||
console.log(sha256('Message to hash'));
|
||||
</script>
|
||||
```
|
||||
|
||||
### ES Modules
|
||||
```JavaScript
|
||||
import { sha256, sha224 } from 'js-sha256';
|
||||
```
|
||||
|
||||
### CommonJS
|
||||
```JavaScript
|
||||
const { sha256, sha224 } = require('js-sha256');
|
||||
```
|
||||
|
||||
### API
|
||||
```JavaScript
|
||||
sha256('Message to hash');
|
||||
sha224('Message to hash');
|
||||
```
|
||||
If you use node.js, you should require the module first:
|
||||
```JavaScript
|
||||
sha256 = require('js-sha256');
|
||||
```
|
||||
or
|
||||
```JavaScript
|
||||
sha256 = require('js-sha256').sha256;
|
||||
sha224 = require('js-sha256').sha224;
|
||||
|
||||
var hash = sha256.create();
|
||||
hash.update('Message to hash');
|
||||
hash.hex();
|
||||
|
||||
var hash2 = sha256.update('Message to hash');
|
||||
hash2.update('Message2 to hash');
|
||||
hash2.array();
|
||||
|
||||
// HMAC
|
||||
sha256.hmac('key', 'Message to hash');
|
||||
sha224.hmac('key', 'Message to hash');
|
||||
|
||||
var hash = sha256.hmac.create('key');
|
||||
hash.update('Message to hash');
|
||||
hash.hex();
|
||||
|
||||
var hash2 = sha256.hmac.update('key', 'Message to hash');
|
||||
hash2.update('Message2 to hash');
|
||||
hash2.array();
|
||||
```
|
||||
|
||||
### Node.js
|
||||
Node.js automatically uses its native `crypto` implementation with the same API:
|
||||
|
||||
```JavaScript
|
||||
import { sha256, sha224 } from 'js-sha256';
|
||||
|
||||
const hash = sha256.create();
|
||||
hash.update('Message');
|
||||
hash.update(' to hash');
|
||||
console.log(hash.hex());
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
If you use TypeScript, you can import like this:
|
||||
```TypeScript
|
||||
import { sha256, sha224 } from 'js-sha256';
|
||||
```
|
||||
### RequireJS
|
||||
The UMD browser build supports AMD:
|
||||
```JavaScript
|
||||
require(['your/path/sha256.min.js'], function(sha256) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
## Example
|
||||
Code
|
||||
```JavaScript
|
||||
sha256('');
|
||||
sha256('The quick brown fox jumps over the lazy dog');
|
||||
sha256('The quick brown fox jumps over the lazy dog.');
|
||||
sha224('');
|
||||
sha224('The quick brown fox jumps over the lazy dog');
|
||||
sha224('The quick brown fox jumps over the lazy dog.');
|
||||
sha256(''); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
sha256('The quick brown fox jumps over the lazy dog'); // d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
|
||||
sha256('The quick brown fox jumps over the lazy dog.'); // ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c
|
||||
sha224(''); // d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
|
||||
sha224('The quick brown fox jumps over the lazy dog'); // 730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525
|
||||
sha224('The quick brown fox jumps over the lazy dog.'); // 619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c
|
||||
|
||||
// It also supports UTF-8 encoding
|
||||
sha256('中文'); // 72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21
|
||||
sha224('中文'); // dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4
|
||||
|
||||
// It also supports byte `Array`, `Uint8Array`, `ArrayBuffer` input
|
||||
sha256([]); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
sha256(new Uint8Array([211, 212])); // 182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f
|
||||
|
||||
// Different output
|
||||
sha256(''); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
sha256.hex(''); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
sha256.array(''); // [227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85]
|
||||
sha256.digest(''); // [227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85]
|
||||
sha256.arrayBuffer(''); // ArrayBuffer
|
||||
```
|
||||
Output
|
||||
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
|
||||
ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c
|
||||
d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
|
||||
730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525
|
||||
619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c
|
||||
|
||||
It also supports UTF-8 encoding:
|
||||
|
||||
Code
|
||||
```JavaScript
|
||||
sha256('中文');
|
||||
sha224('中文');
|
||||
```
|
||||
Output
|
||||
|
||||
72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21
|
||||
dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4
|
||||
|
||||
It also supports byte Array or Uint8Array input:
|
||||
|
||||
Code
|
||||
```JavaScript
|
||||
sha256([]);
|
||||
sha256(new Uint8Array([211, 212]));
|
||||
```
|
||||
Output
|
||||
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f
|
||||
|
||||
## Benchmark
|
||||
[UTF8](http://jsperf.com/sha256/66)
|
||||
[ASCII](http://jsperf.com/sha256/65)
|
||||
[jsPerf Benchmark](https://jsperf.app/cidole/2)
|
||||
|
||||
## Extensions
|
||||
### jQuery
|
||||
If you prefer jQuery style, you can add following code to add a jQuery extension.
|
||||
|
||||
Code
|
||||
```JavaScript
|
||||
jQuery.sha256 = sha256
|
||||
jQuery.sha224 = sha224
|
||||
```
|
||||
And then you could use like this:
|
||||
```JavaScript
|
||||
$.sha256('message');
|
||||
$.sha224('message');
|
||||
```
|
||||
### Prototype
|
||||
If you prefer prototype style, you can add following code to add a prototype extension.
|
||||
|
||||
Code
|
||||
```JavaScript
|
||||
String.prototype.sha256 = function() {
|
||||
return sha256(this);
|
||||
};
|
||||
String.prototype.sha224 = function() {
|
||||
return sha224(this);
|
||||
};
|
||||
```
|
||||
And then you could use like this:
|
||||
```JavaScript
|
||||
'message'.sha256();
|
||||
'message'.sha224();
|
||||
```
|
||||
## License
|
||||
The project is released under the [MIT license](http://www.opensource.org/licenses/MIT).
|
||||
The project is released under the [MIT license](https://opensource.org/license/mit/).
|
||||
|
||||
## Contact
|
||||
The project's website is located at https://github.com/emn178/js-sha256
|
||||
Author: emn178@gmail.com
|
||||
Author: Chen, Yi-Cyuan (emn178@gmail.com)
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "js-sha256",
|
||||
"version": "0.2.3",
|
||||
"main": ["build/sha256.min.js"],
|
||||
"version": "1.0.0",
|
||||
"main": ["build/sha256.js"],
|
||||
"ignore": [
|
||||
"samples",
|
||||
"tests"
|
||||
|
||||
@@ -0,0 +1,447 @@
|
||||
/**
|
||||
* [js-sha256]{@link https://github.com/emn178/js-sha256}
|
||||
*
|
||||
* @version 1.0.0
|
||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||
* @copyright Chen, Yi-Cyuan 2014-2026
|
||||
* @license MIT
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var INPUT_ERROR = 'input is invalid type';
|
||||
var FINALIZE_ERROR = 'finalize already called';
|
||||
|
||||
var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
|
||||
|
||||
var formatMessage = function (message) {
|
||||
var type = typeof message;
|
||||
if (type === 'string') {
|
||||
return [message, true];
|
||||
}
|
||||
if (Array.isArray(message)) {
|
||||
return [message, false];
|
||||
}
|
||||
if (ARRAY_BUFFER && message) {
|
||||
if (message.constructor === ArrayBuffer) {
|
||||
return [new Uint8Array(message), false];
|
||||
} else if (ArrayBuffer.isView(message)) {
|
||||
return [message, false];
|
||||
}
|
||||
}
|
||||
throw new Error(INPUT_ERROR);
|
||||
};
|
||||
|
||||
var HEX_CHARS = '0123456789abcdef'.split('');
|
||||
var EXTRA = [-2147483648, 8388608, 32768, 128];
|
||||
var SHIFT = [24, 16, 8, 0];
|
||||
var K = [
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
];
|
||||
var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
|
||||
|
||||
var blocks = [];
|
||||
|
||||
var createOutputMethod = function (outputType, is224) {
|
||||
return function (message) {
|
||||
return new Sha256(is224, true).update(message)[outputType]();
|
||||
};
|
||||
};
|
||||
|
||||
var createMethod = function (is224) {
|
||||
var method = createOutputMethod('hex', is224);
|
||||
method.create = function () {
|
||||
return new Sha256(is224);
|
||||
};
|
||||
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(type, is224);
|
||||
}
|
||||
return method;
|
||||
};
|
||||
|
||||
var createHmacOutputMethod = function (outputType, is224) {
|
||||
return function (key, message) {
|
||||
return new HmacSha256(key, is224, true).update(message)[outputType]();
|
||||
};
|
||||
};
|
||||
|
||||
var createHmacMethod = function (is224) {
|
||||
var method = createHmacOutputMethod('hex', is224);
|
||||
method.create = function (key) {
|
||||
return new HmacSha256(key, is224);
|
||||
};
|
||||
method.update = function (key, message) {
|
||||
return method.create(key).update(message);
|
||||
};
|
||||
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
||||
var type = OUTPUT_TYPES[i];
|
||||
method[type] = createHmacOutputMethod(type, is224);
|
||||
}
|
||||
return method;
|
||||
};
|
||||
|
||||
function Sha256(is224, sharedMemory) {
|
||||
if (sharedMemory) {
|
||||
blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
this.blocks = blocks;
|
||||
} else {
|
||||
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
}
|
||||
|
||||
if (is224) {
|
||||
this.h0 = 0xc1059ed8;
|
||||
this.h1 = 0x367cd507;
|
||||
this.h2 = 0x3070dd17;
|
||||
this.h3 = 0xf70e5939;
|
||||
this.h4 = 0xffc00b31;
|
||||
this.h5 = 0x68581511;
|
||||
this.h6 = 0x64f98fa7;
|
||||
this.h7 = 0xbefa4fa4;
|
||||
} else { // 256
|
||||
this.h0 = 0x6a09e667;
|
||||
this.h1 = 0xbb67ae85;
|
||||
this.h2 = 0x3c6ef372;
|
||||
this.h3 = 0xa54ff53a;
|
||||
this.h4 = 0x510e527f;
|
||||
this.h5 = 0x9b05688c;
|
||||
this.h6 = 0x1f83d9ab;
|
||||
this.h7 = 0x5be0cd19;
|
||||
}
|
||||
|
||||
this.block = this.start = this.bytes = this.hBytes = 0;
|
||||
this.finalized = this.hashed = false;
|
||||
this.first = true;
|
||||
this.is224 = is224;
|
||||
}
|
||||
|
||||
Sha256.prototype.update = function (message) {
|
||||
if (this.finalized) {
|
||||
throw new Error(FINALIZE_ERROR);
|
||||
}
|
||||
var result = formatMessage(message);
|
||||
message = result[0];
|
||||
var isString = result[1];
|
||||
var code, index = 0, i, length = message.length, blocks = this.blocks;
|
||||
while (index < length) {
|
||||
if (this.hashed) {
|
||||
this.hashed = false;
|
||||
blocks[0] = this.block;
|
||||
this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
}
|
||||
|
||||
if (isString) {
|
||||
for (i = this.start; index < length && i < 64; ++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 < 64; ++index) {
|
||||
blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3];
|
||||
}
|
||||
}
|
||||
|
||||
this.lastByteIndex = i;
|
||||
this.bytes += i - this.start;
|
||||
if (i >= 64) {
|
||||
this.block = blocks[16];
|
||||
this.start = i - 64;
|
||||
this.hash();
|
||||
this.hashed = true;
|
||||
} else {
|
||||
this.start = i;
|
||||
}
|
||||
}
|
||||
if (this.bytes > 4294967295) {
|
||||
this.hBytes += this.bytes / 4294967296 << 0;
|
||||
this.bytes = this.bytes % 4294967296;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Sha256.prototype.finalize = function () {
|
||||
if (this.finalized) {
|
||||
return;
|
||||
}
|
||||
this.finalized = true;
|
||||
var blocks = this.blocks, i = this.lastByteIndex;
|
||||
blocks[16] = this.block;
|
||||
blocks[i >>> 2] |= EXTRA[i & 3];
|
||||
this.block = blocks[16];
|
||||
if (i >= 56) {
|
||||
if (!this.hashed) {
|
||||
this.hash();
|
||||
}
|
||||
blocks[0] = this.block;
|
||||
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
}
|
||||
blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
|
||||
blocks[15] = this.bytes << 3;
|
||||
this.hash();
|
||||
};
|
||||
|
||||
Sha256.prototype.hash = function () {
|
||||
var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
|
||||
h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
|
||||
|
||||
for (j = 16; j < 64; ++j) {
|
||||
// rightrotate
|
||||
t1 = blocks[j - 15];
|
||||
s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
|
||||
t1 = blocks[j - 2];
|
||||
s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
|
||||
blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
|
||||
}
|
||||
|
||||
bc = b & c;
|
||||
for (j = 0; j < 64; j += 4) {
|
||||
if (this.first) {
|
||||
if (this.is224) {
|
||||
ab = 300032;
|
||||
t1 = blocks[0] - 1413257819;
|
||||
h = t1 - 150054599 << 0;
|
||||
d = t1 + 24177077 << 0;
|
||||
} else {
|
||||
ab = 704751109;
|
||||
t1 = blocks[0] - 210244248;
|
||||
h = t1 - 1521486534 << 0;
|
||||
d = t1 + 143694565 << 0;
|
||||
}
|
||||
this.first = false;
|
||||
} else {
|
||||
s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
|
||||
s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
|
||||
ab = a & b;
|
||||
maj = ab ^ (a & c) ^ bc;
|
||||
ch = (e & f) ^ (~e & g);
|
||||
t1 = h + s1 + ch + K[j] + blocks[j];
|
||||
t2 = s0 + maj;
|
||||
h = d + t1 << 0;
|
||||
d = t1 + t2 << 0;
|
||||
}
|
||||
s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
|
||||
s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
|
||||
da = d & a;
|
||||
maj = da ^ (d & b) ^ ab;
|
||||
ch = (h & e) ^ (~h & f);
|
||||
t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
|
||||
t2 = s0 + maj;
|
||||
g = c + t1 << 0;
|
||||
c = t1 + t2 << 0;
|
||||
s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
|
||||
s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
|
||||
cd = c & d;
|
||||
maj = cd ^ (c & a) ^ da;
|
||||
ch = (g & h) ^ (~g & e);
|
||||
t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
|
||||
t2 = s0 + maj;
|
||||
f = b + t1 << 0;
|
||||
b = t1 + t2 << 0;
|
||||
s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
|
||||
s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
|
||||
bc = b & c;
|
||||
maj = bc ^ (b & d) ^ cd;
|
||||
ch = (f & g) ^ (~f & h);
|
||||
t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
|
||||
t2 = s0 + maj;
|
||||
e = a + t1 << 0;
|
||||
a = t1 + t2 << 0;
|
||||
this.chromeBugWorkAround = true;
|
||||
}
|
||||
|
||||
this.h0 = this.h0 + a << 0;
|
||||
this.h1 = this.h1 + b << 0;
|
||||
this.h2 = this.h2 + c << 0;
|
||||
this.h3 = this.h3 + d << 0;
|
||||
this.h4 = this.h4 + e << 0;
|
||||
this.h5 = this.h5 + f << 0;
|
||||
this.h6 = this.h6 + g << 0;
|
||||
this.h7 = this.h7 + h << 0;
|
||||
};
|
||||
|
||||
Sha256.prototype.hex = function () {
|
||||
this.finalize();
|
||||
|
||||
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
|
||||
h6 = this.h6, h7 = this.h7;
|
||||
|
||||
var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
|
||||
if (!this.is224) {
|
||||
hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
|
||||
}
|
||||
return hex;
|
||||
};
|
||||
|
||||
Sha256.prototype.toString = Sha256.prototype.hex;
|
||||
|
||||
Sha256.prototype.digest = function () {
|
||||
this.finalize();
|
||||
|
||||
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
|
||||
h6 = this.h6, h7 = this.h7;
|
||||
|
||||
var arr = [
|
||||
(h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF,
|
||||
(h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF,
|
||||
(h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF,
|
||||
(h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF,
|
||||
(h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF,
|
||||
(h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF,
|
||||
(h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF
|
||||
];
|
||||
if (!this.is224) {
|
||||
arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
Sha256.prototype.array = Sha256.prototype.digest;
|
||||
|
||||
Sha256.prototype.arrayBuffer = function () {
|
||||
this.finalize();
|
||||
|
||||
var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
|
||||
var dataView = new DataView(buffer);
|
||||
dataView.setUint32(0, this.h0);
|
||||
dataView.setUint32(4, this.h1);
|
||||
dataView.setUint32(8, this.h2);
|
||||
dataView.setUint32(12, this.h3);
|
||||
dataView.setUint32(16, this.h4);
|
||||
dataView.setUint32(20, this.h5);
|
||||
dataView.setUint32(24, this.h6);
|
||||
if (!this.is224) {
|
||||
dataView.setUint32(28, this.h7);
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
|
||||
function HmacSha256(key, is224, sharedMemory) {
|
||||
var i, result = formatMessage(key);
|
||||
key = result[0];
|
||||
if (result[1]) {
|
||||
var bytes = [], length = key.length, index = 0, code;
|
||||
for (i = 0; i < length; ++i) {
|
||||
code = key.charCodeAt(i);
|
||||
if (code < 0x80) {
|
||||
bytes[index++] = code;
|
||||
} else if (code < 0x800) {
|
||||
bytes[index++] = (0xc0 | (code >>> 6));
|
||||
bytes[index++] = (0x80 | (code & 0x3f));
|
||||
} else if (code < 0xd800 || code >= 0xe000) {
|
||||
bytes[index++] = (0xe0 | (code >>> 12));
|
||||
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||
bytes[index++] = (0x80 | (code & 0x3f));
|
||||
} else {
|
||||
code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
|
||||
bytes[index++] = (0xf0 | (code >>> 18));
|
||||
bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
|
||||
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||
bytes[index++] = (0x80 | (code & 0x3f));
|
||||
}
|
||||
}
|
||||
key = bytes;
|
||||
}
|
||||
|
||||
if (key.length > 64) {
|
||||
key = (new Sha256(is224, true)).update(key).array();
|
||||
}
|
||||
|
||||
var oKeyPad = [], iKeyPad = [];
|
||||
for (i = 0; i < 64; ++i) {
|
||||
var b = key[i] || 0;
|
||||
oKeyPad[i] = 0x5c ^ b;
|
||||
iKeyPad[i] = 0x36 ^ b;
|
||||
}
|
||||
|
||||
Sha256.call(this, is224, sharedMemory);
|
||||
|
||||
this.update(iKeyPad);
|
||||
this.oKeyPad = oKeyPad;
|
||||
this.inner = true;
|
||||
this.sharedMemory = sharedMemory;
|
||||
}
|
||||
HmacSha256.prototype = new Sha256();
|
||||
|
||||
HmacSha256.prototype.finalize = function () {
|
||||
Sha256.prototype.finalize.call(this);
|
||||
if (this.inner) {
|
||||
this.inner = false;
|
||||
var innerHash = this.array();
|
||||
Sha256.call(this, this.is224, this.sharedMemory);
|
||||
this.update(this.oKeyPad);
|
||||
this.update(innerHash);
|
||||
Sha256.prototype.finalize.call(this);
|
||||
}
|
||||
};
|
||||
|
||||
var sha256 = createMethod();
|
||||
var sha224 = createMethod(true);
|
||||
sha256.sha256 = sha256;
|
||||
sha256.sha224 = sha224;
|
||||
sha256.hmac = createHmacMethod();
|
||||
sha224.hmac = createHmacMethod(true);
|
||||
|
||||
module.exports = sha256;
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
/**
|
||||
* [js-sha256]{@link https://github.com/emn178/js-sha256}
|
||||
*
|
||||
* @version 1.0.0
|
||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||
* @copyright Chen, Yi-Cyuan 2014-2026
|
||||
* @license MIT
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.sha256 = factory());
|
||||
})(this, (function () { 'use strict';
|
||||
|
||||
var INPUT_ERROR = 'input is invalid type';
|
||||
var FINALIZE_ERROR = 'finalize already called';
|
||||
|
||||
var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
|
||||
|
||||
var formatMessage = function (message) {
|
||||
var type = typeof message;
|
||||
if (type === 'string') {
|
||||
return [message, true];
|
||||
}
|
||||
if (Array.isArray(message)) {
|
||||
return [message, false];
|
||||
}
|
||||
if (ARRAY_BUFFER && message) {
|
||||
if (message.constructor === ArrayBuffer) {
|
||||
return [new Uint8Array(message), false];
|
||||
} else if (ArrayBuffer.isView(message)) {
|
||||
return [message, false];
|
||||
}
|
||||
}
|
||||
throw new Error(INPUT_ERROR);
|
||||
};
|
||||
|
||||
var HEX_CHARS = '0123456789abcdef'.split('');
|
||||
var EXTRA = [-2147483648, 8388608, 32768, 128];
|
||||
var SHIFT = [24, 16, 8, 0];
|
||||
var K = [
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
];
|
||||
var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
|
||||
|
||||
var blocks = [];
|
||||
|
||||
var createOutputMethod = function (outputType, is224) {
|
||||
return function (message) {
|
||||
return new Sha256(is224, true).update(message)[outputType]();
|
||||
};
|
||||
};
|
||||
|
||||
var createMethod = function (is224) {
|
||||
var method = createOutputMethod('hex', is224);
|
||||
method.create = function () {
|
||||
return new Sha256(is224);
|
||||
};
|
||||
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(type, is224);
|
||||
}
|
||||
return method;
|
||||
};
|
||||
|
||||
var createHmacOutputMethod = function (outputType, is224) {
|
||||
return function (key, message) {
|
||||
return new HmacSha256(key, is224, true).update(message)[outputType]();
|
||||
};
|
||||
};
|
||||
|
||||
var createHmacMethod = function (is224) {
|
||||
var method = createHmacOutputMethod('hex', is224);
|
||||
method.create = function (key) {
|
||||
return new HmacSha256(key, is224);
|
||||
};
|
||||
method.update = function (key, message) {
|
||||
return method.create(key).update(message);
|
||||
};
|
||||
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
||||
var type = OUTPUT_TYPES[i];
|
||||
method[type] = createHmacOutputMethod(type, is224);
|
||||
}
|
||||
return method;
|
||||
};
|
||||
|
||||
function Sha256(is224, sharedMemory) {
|
||||
if (sharedMemory) {
|
||||
blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
this.blocks = blocks;
|
||||
} else {
|
||||
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
}
|
||||
|
||||
if (is224) {
|
||||
this.h0 = 0xc1059ed8;
|
||||
this.h1 = 0x367cd507;
|
||||
this.h2 = 0x3070dd17;
|
||||
this.h3 = 0xf70e5939;
|
||||
this.h4 = 0xffc00b31;
|
||||
this.h5 = 0x68581511;
|
||||
this.h6 = 0x64f98fa7;
|
||||
this.h7 = 0xbefa4fa4;
|
||||
} else { // 256
|
||||
this.h0 = 0x6a09e667;
|
||||
this.h1 = 0xbb67ae85;
|
||||
this.h2 = 0x3c6ef372;
|
||||
this.h3 = 0xa54ff53a;
|
||||
this.h4 = 0x510e527f;
|
||||
this.h5 = 0x9b05688c;
|
||||
this.h6 = 0x1f83d9ab;
|
||||
this.h7 = 0x5be0cd19;
|
||||
}
|
||||
|
||||
this.block = this.start = this.bytes = this.hBytes = 0;
|
||||
this.finalized = this.hashed = false;
|
||||
this.first = true;
|
||||
this.is224 = is224;
|
||||
}
|
||||
|
||||
Sha256.prototype.update = function (message) {
|
||||
if (this.finalized) {
|
||||
throw new Error(FINALIZE_ERROR);
|
||||
}
|
||||
var result = formatMessage(message);
|
||||
message = result[0];
|
||||
var isString = result[1];
|
||||
var code, index = 0, i, length = message.length, blocks = this.blocks;
|
||||
while (index < length) {
|
||||
if (this.hashed) {
|
||||
this.hashed = false;
|
||||
blocks[0] = this.block;
|
||||
this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
}
|
||||
|
||||
if (isString) {
|
||||
for (i = this.start; index < length && i < 64; ++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 < 64; ++index) {
|
||||
blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3];
|
||||
}
|
||||
}
|
||||
|
||||
this.lastByteIndex = i;
|
||||
this.bytes += i - this.start;
|
||||
if (i >= 64) {
|
||||
this.block = blocks[16];
|
||||
this.start = i - 64;
|
||||
this.hash();
|
||||
this.hashed = true;
|
||||
} else {
|
||||
this.start = i;
|
||||
}
|
||||
}
|
||||
if (this.bytes > 4294967295) {
|
||||
this.hBytes += this.bytes / 4294967296 << 0;
|
||||
this.bytes = this.bytes % 4294967296;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Sha256.prototype.finalize = function () {
|
||||
if (this.finalized) {
|
||||
return;
|
||||
}
|
||||
this.finalized = true;
|
||||
var blocks = this.blocks, i = this.lastByteIndex;
|
||||
blocks[16] = this.block;
|
||||
blocks[i >>> 2] |= EXTRA[i & 3];
|
||||
this.block = blocks[16];
|
||||
if (i >= 56) {
|
||||
if (!this.hashed) {
|
||||
this.hash();
|
||||
}
|
||||
blocks[0] = this.block;
|
||||
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
}
|
||||
blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
|
||||
blocks[15] = this.bytes << 3;
|
||||
this.hash();
|
||||
};
|
||||
|
||||
Sha256.prototype.hash = function () {
|
||||
var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
|
||||
h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
|
||||
|
||||
for (j = 16; j < 64; ++j) {
|
||||
// rightrotate
|
||||
t1 = blocks[j - 15];
|
||||
s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
|
||||
t1 = blocks[j - 2];
|
||||
s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
|
||||
blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
|
||||
}
|
||||
|
||||
bc = b & c;
|
||||
for (j = 0; j < 64; j += 4) {
|
||||
if (this.first) {
|
||||
if (this.is224) {
|
||||
ab = 300032;
|
||||
t1 = blocks[0] - 1413257819;
|
||||
h = t1 - 150054599 << 0;
|
||||
d = t1 + 24177077 << 0;
|
||||
} else {
|
||||
ab = 704751109;
|
||||
t1 = blocks[0] - 210244248;
|
||||
h = t1 - 1521486534 << 0;
|
||||
d = t1 + 143694565 << 0;
|
||||
}
|
||||
this.first = false;
|
||||
} else {
|
||||
s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
|
||||
s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
|
||||
ab = a & b;
|
||||
maj = ab ^ (a & c) ^ bc;
|
||||
ch = (e & f) ^ (~e & g);
|
||||
t1 = h + s1 + ch + K[j] + blocks[j];
|
||||
t2 = s0 + maj;
|
||||
h = d + t1 << 0;
|
||||
d = t1 + t2 << 0;
|
||||
}
|
||||
s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
|
||||
s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
|
||||
da = d & a;
|
||||
maj = da ^ (d & b) ^ ab;
|
||||
ch = (h & e) ^ (~h & f);
|
||||
t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
|
||||
t2 = s0 + maj;
|
||||
g = c + t1 << 0;
|
||||
c = t1 + t2 << 0;
|
||||
s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
|
||||
s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
|
||||
cd = c & d;
|
||||
maj = cd ^ (c & a) ^ da;
|
||||
ch = (g & h) ^ (~g & e);
|
||||
t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
|
||||
t2 = s0 + maj;
|
||||
f = b + t1 << 0;
|
||||
b = t1 + t2 << 0;
|
||||
s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
|
||||
s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
|
||||
bc = b & c;
|
||||
maj = bc ^ (b & d) ^ cd;
|
||||
ch = (f & g) ^ (~f & h);
|
||||
t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
|
||||
t2 = s0 + maj;
|
||||
e = a + t1 << 0;
|
||||
a = t1 + t2 << 0;
|
||||
this.chromeBugWorkAround = true;
|
||||
}
|
||||
|
||||
this.h0 = this.h0 + a << 0;
|
||||
this.h1 = this.h1 + b << 0;
|
||||
this.h2 = this.h2 + c << 0;
|
||||
this.h3 = this.h3 + d << 0;
|
||||
this.h4 = this.h4 + e << 0;
|
||||
this.h5 = this.h5 + f << 0;
|
||||
this.h6 = this.h6 + g << 0;
|
||||
this.h7 = this.h7 + h << 0;
|
||||
};
|
||||
|
||||
Sha256.prototype.hex = function () {
|
||||
this.finalize();
|
||||
|
||||
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
|
||||
h6 = this.h6, h7 = this.h7;
|
||||
|
||||
var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
|
||||
if (!this.is224) {
|
||||
hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
|
||||
}
|
||||
return hex;
|
||||
};
|
||||
|
||||
Sha256.prototype.toString = Sha256.prototype.hex;
|
||||
|
||||
Sha256.prototype.digest = function () {
|
||||
this.finalize();
|
||||
|
||||
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
|
||||
h6 = this.h6, h7 = this.h7;
|
||||
|
||||
var arr = [
|
||||
(h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF,
|
||||
(h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF,
|
||||
(h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF,
|
||||
(h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF,
|
||||
(h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF,
|
||||
(h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF,
|
||||
(h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF
|
||||
];
|
||||
if (!this.is224) {
|
||||
arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
Sha256.prototype.array = Sha256.prototype.digest;
|
||||
|
||||
Sha256.prototype.arrayBuffer = function () {
|
||||
this.finalize();
|
||||
|
||||
var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
|
||||
var dataView = new DataView(buffer);
|
||||
dataView.setUint32(0, this.h0);
|
||||
dataView.setUint32(4, this.h1);
|
||||
dataView.setUint32(8, this.h2);
|
||||
dataView.setUint32(12, this.h3);
|
||||
dataView.setUint32(16, this.h4);
|
||||
dataView.setUint32(20, this.h5);
|
||||
dataView.setUint32(24, this.h6);
|
||||
if (!this.is224) {
|
||||
dataView.setUint32(28, this.h7);
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
|
||||
function HmacSha256(key, is224, sharedMemory) {
|
||||
var i, result = formatMessage(key);
|
||||
key = result[0];
|
||||
if (result[1]) {
|
||||
var bytes = [], length = key.length, index = 0, code;
|
||||
for (i = 0; i < length; ++i) {
|
||||
code = key.charCodeAt(i);
|
||||
if (code < 0x80) {
|
||||
bytes[index++] = code;
|
||||
} else if (code < 0x800) {
|
||||
bytes[index++] = (0xc0 | (code >>> 6));
|
||||
bytes[index++] = (0x80 | (code & 0x3f));
|
||||
} else if (code < 0xd800 || code >= 0xe000) {
|
||||
bytes[index++] = (0xe0 | (code >>> 12));
|
||||
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||
bytes[index++] = (0x80 | (code & 0x3f));
|
||||
} else {
|
||||
code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
|
||||
bytes[index++] = (0xf0 | (code >>> 18));
|
||||
bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
|
||||
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||
bytes[index++] = (0x80 | (code & 0x3f));
|
||||
}
|
||||
}
|
||||
key = bytes;
|
||||
}
|
||||
|
||||
if (key.length > 64) {
|
||||
key = (new Sha256(is224, true)).update(key).array();
|
||||
}
|
||||
|
||||
var oKeyPad = [], iKeyPad = [];
|
||||
for (i = 0; i < 64; ++i) {
|
||||
var b = key[i] || 0;
|
||||
oKeyPad[i] = 0x5c ^ b;
|
||||
iKeyPad[i] = 0x36 ^ b;
|
||||
}
|
||||
|
||||
Sha256.call(this, is224, sharedMemory);
|
||||
|
||||
this.update(iKeyPad);
|
||||
this.oKeyPad = oKeyPad;
|
||||
this.inner = true;
|
||||
this.sharedMemory = sharedMemory;
|
||||
}
|
||||
HmacSha256.prototype = new Sha256();
|
||||
|
||||
HmacSha256.prototype.finalize = function () {
|
||||
Sha256.prototype.finalize.call(this);
|
||||
if (this.inner) {
|
||||
this.inner = false;
|
||||
var innerHash = this.array();
|
||||
Sha256.call(this, this.is224, this.sharedMemory);
|
||||
this.update(this.oKeyPad);
|
||||
this.update(innerHash);
|
||||
Sha256.prototype.finalize.call(this);
|
||||
}
|
||||
};
|
||||
|
||||
var sha256 = createMethod();
|
||||
var sha224 = createMethod(true);
|
||||
sha256.sha256 = sha256;
|
||||
sha256.sha224 = sha224;
|
||||
sha256.hmac = createHmacMethod();
|
||||
sha224.hmac = createHmacMethod(true);
|
||||
|
||||
const root =
|
||||
typeof globalThis === 'object' ? globalThis :
|
||||
typeof self === 'object' ? self :
|
||||
typeof window === 'object' ? window :
|
||||
typeof global === 'object' ? global :
|
||||
undefined;
|
||||
|
||||
if (root) {
|
||||
root.sha224 = sha224;
|
||||
}
|
||||
|
||||
return sha256;
|
||||
|
||||
}));
|
||||
Vendored
+9
-8
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* [js-sha256]{@link https://github.com/emn178/js-sha256}
|
||||
*
|
||||
* @version 1.0.0
|
||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||
* @copyright Chen, Yi-Cyuan 2014-2026
|
||||
* @license MIT
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var crypto = require('crypto');
|
||||
|
||||
var INPUT_ERROR = 'input is invalid type';
|
||||
var FINALIZE_ERROR = 'finalize already called';
|
||||
|
||||
var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
|
||||
|
||||
var formatMessage = function (message) {
|
||||
var type = typeof message;
|
||||
if (type === 'string') {
|
||||
return [message, true];
|
||||
}
|
||||
if (Array.isArray(message)) {
|
||||
return [message, false];
|
||||
}
|
||||
if (ARRAY_BUFFER && message) {
|
||||
if (message.constructor === ArrayBuffer) {
|
||||
return [new Uint8Array(message), false];
|
||||
} else if (ArrayBuffer.isView(message)) {
|
||||
return [message, false];
|
||||
}
|
||||
}
|
||||
throw new Error(INPUT_ERROR);
|
||||
};
|
||||
|
||||
function toNodeInput(message) {
|
||||
const [ msg, isString ] = formatMessage(message);
|
||||
return isString ? Buffer.from(msg, 'utf8') : Buffer.from(msg);
|
||||
}
|
||||
|
||||
class NodeHasher {
|
||||
constructor(hash) {
|
||||
this.hash = hash;
|
||||
this.result = undefined;
|
||||
}
|
||||
|
||||
update(message) {
|
||||
if (this.result) {
|
||||
throw new Error(FINALIZE_ERROR);
|
||||
}
|
||||
this.hash.update(toNodeInput(message));
|
||||
return this;
|
||||
}
|
||||
|
||||
finalize() {
|
||||
if (!this.result) {
|
||||
this.result = this.hash.digest();
|
||||
this.hash = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
hex() {
|
||||
this.finalize();
|
||||
return this.result.toString('hex');
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.hex();
|
||||
}
|
||||
|
||||
array() {
|
||||
this.finalize();
|
||||
return Array.from(this.result);
|
||||
}
|
||||
|
||||
digest() {
|
||||
return this.array();
|
||||
}
|
||||
|
||||
arrayBuffer() {
|
||||
return Uint8Array.from(this.array()).buffer;
|
||||
}
|
||||
}
|
||||
|
||||
function addOutputMethods(method, createHasher) {
|
||||
method.hex = method;
|
||||
method.array = function (...args) {
|
||||
return createHasher(...args.slice(0, -1)).update(args[args.length - 1]).array();
|
||||
};
|
||||
method.digest = method.array;
|
||||
method.arrayBuffer = function (...args) {
|
||||
return createHasher(...args.slice(0, -1)).update(args[args.length - 1]).arrayBuffer();
|
||||
};
|
||||
return method;
|
||||
}
|
||||
|
||||
function createNodeMethod(algorithm) {
|
||||
const createHasher = () => new NodeHasher(crypto.createHash(algorithm));
|
||||
const method = function (message) {
|
||||
return createHasher().update(message).hex();
|
||||
};
|
||||
addOutputMethods(method, createHasher);
|
||||
method.create = createHasher;
|
||||
method.update = function (message) {
|
||||
return method.create().update(message);
|
||||
};
|
||||
return method;
|
||||
}
|
||||
|
||||
function createNodeHmacMethod(algorithm) {
|
||||
const createHasher = key => new NodeHasher(crypto.createHmac(algorithm, toNodeInput(key)));
|
||||
const method = function (key, message) {
|
||||
return createHasher(key).update(message).hex();
|
||||
};
|
||||
addOutputMethods(method, createHasher);
|
||||
method.create = createHasher;
|
||||
method.update = function (key, message) {
|
||||
return method.create(key).update(message);
|
||||
};
|
||||
return method;
|
||||
}
|
||||
|
||||
const sha256 = createNodeMethod('sha256');
|
||||
const sha224 = createNodeMethod('sha224');
|
||||
|
||||
sha256.sha256 = sha256;
|
||||
sha256.sha224 = sha224;
|
||||
sha256.hmac = createNodeHmacMethod('sha256');
|
||||
sha224.hmac = createNodeHmacMethod('sha224');
|
||||
|
||||
module.exports = sha256;
|
||||
Vendored
+150
@@ -0,0 +1,150 @@
|
||||
type Message = string | number[] | ArrayBuffer | Uint8Array;
|
||||
|
||||
interface Hasher {
|
||||
/**
|
||||
* Update hash
|
||||
*
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
update(message: Message): Hasher;
|
||||
|
||||
/**
|
||||
* Return hash in hex string.
|
||||
*/
|
||||
hex(): string;
|
||||
|
||||
/**
|
||||
* Return hash in hex string.
|
||||
*/
|
||||
toString(): string;
|
||||
|
||||
/**
|
||||
* Return hash in ArrayBuffer.
|
||||
*/
|
||||
arrayBuffer(): ArrayBuffer;
|
||||
|
||||
/**
|
||||
* Return hash in integer array.
|
||||
*/
|
||||
digest(): number[];
|
||||
|
||||
/**
|
||||
* Return hash in integer array.
|
||||
*/
|
||||
array(): number[];
|
||||
}
|
||||
|
||||
interface Hmac {
|
||||
/**
|
||||
* Computes a Hash-based message authentication code (HMAC) using a secret key
|
||||
*
|
||||
* @param secretKey The Secret Key
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
(secretKey: Message, message: Message): string;
|
||||
|
||||
/**
|
||||
* Create a hash object using a secret key.
|
||||
*
|
||||
* @param secretKey The Secret Key
|
||||
*/
|
||||
create(secretKey: Message): Hasher;
|
||||
|
||||
/**
|
||||
* Create a hash object and hash message using a secret key
|
||||
*
|
||||
* @param secretKey The Secret Key
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
update(secretKey: Message, message: Message): Hasher;
|
||||
|
||||
/**
|
||||
* Return hash in hex string.
|
||||
*
|
||||
* @param secretKey The Secret Key
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
hex(secretKey: Message, message: Message): string;
|
||||
|
||||
/**
|
||||
* Return hash in ArrayBuffer.
|
||||
*
|
||||
* @param secretKey The Secret Key
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
arrayBuffer(secretKey: Message, message: Message): ArrayBuffer;
|
||||
|
||||
/**
|
||||
* Return hash in integer array.
|
||||
*
|
||||
* @param secretKey The Secret Key
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
digest(secretKey: Message, message: Message): number[];
|
||||
|
||||
/**
|
||||
* Return hash in integer array.
|
||||
*
|
||||
* @param secretKey The Secret Key
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
array(secretKey: Message, message: Message): number[];
|
||||
}
|
||||
|
||||
interface Hash {
|
||||
/**
|
||||
* Hash and return hex string.
|
||||
*
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
(message: Message): string;
|
||||
|
||||
/**
|
||||
* Create a hash object.
|
||||
*/
|
||||
create(): Hasher;
|
||||
|
||||
/**
|
||||
* Create a hash object and hash message.
|
||||
*
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
update(message: Message): Hasher;
|
||||
|
||||
/**
|
||||
* Return hash in hex string.
|
||||
*
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
hex(message: Message): string;
|
||||
|
||||
/**
|
||||
* Return hash in ArrayBuffer.
|
||||
*
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
arrayBuffer(message: Message): ArrayBuffer;
|
||||
|
||||
/**
|
||||
* Return hash in integer array.
|
||||
*
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
digest(message: Message): number[];
|
||||
|
||||
/**
|
||||
* Return hash in integer array.
|
||||
*
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
array(message: Message): number[];
|
||||
|
||||
/**
|
||||
* HMAC interface
|
||||
*/
|
||||
hmac: Hmac;
|
||||
}
|
||||
|
||||
export var sha256: Hash;
|
||||
export var sha224: Hash;
|
||||
export default sha256;
|
||||
Generated
+1897
File diff suppressed because it is too large
Load Diff
+39
-8
@@ -1,15 +1,45 @@
|
||||
{
|
||||
"name": "js-sha256",
|
||||
"version": "0.2.3",
|
||||
"version": "1.0.0",
|
||||
"description": "A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.",
|
||||
"main": "src/sha256.js",
|
||||
"main": "build/sha256.node.cjs",
|
||||
"module": "src/index.mjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"node": {
|
||||
"import": "./src/node.mjs",
|
||||
"require": "./build/sha256.node.cjs"
|
||||
},
|
||||
"import": "./src/index.mjs",
|
||||
"require": "./build/sha256.cjs",
|
||||
"default": "./src/index.mjs"
|
||||
},
|
||||
"./src/sha256.js": "./build/sha256.js",
|
||||
"./build/sha256.js": "./build/sha256.js",
|
||||
"./build/sha256.cjs": "./build/sha256.cjs",
|
||||
"./build/sha256.min.js": "./build/sha256.min.js",
|
||||
"./build/sha256.min.mjs": "./build/sha256.min.mjs",
|
||||
"./build/sha256.node.cjs": "./build/sha256.node.cjs",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"types": "./index.d.ts",
|
||||
"devDependencies": {
|
||||
"expect.js": "~0.3.1",
|
||||
"jscoverage": "~0.5.9"
|
||||
"@playwright/test": "^1.62.0",
|
||||
"@rollup/plugin-terser": "^1.0.0",
|
||||
"c8": "^8.0.1",
|
||||
"mocha": "~10.8.2",
|
||||
"rollup": "^4.43.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha tests/node-test.js -r jscoverage",
|
||||
"coveralls": "mocha tests/node-test.js -R mocha-lcov-reporter -r jscoverage | coveralls"
|
||||
"test": "npm run build && npm run test:coverage",
|
||||
"test:unit": "mocha tests/core-test.mjs && mocha tests/node-test.mjs",
|
||||
"test:dist": "node tests/dist-test.mjs",
|
||||
"test:runtime": "npm run test:unit && npm run test:dist",
|
||||
"test:coverage": "c8 --all --include=src/shared.mjs --include=src/core.mjs --include=src/node.mjs --reporter=text --reporter=html --reporter=lcov npm run test:runtime",
|
||||
"test:browser": "playwright test",
|
||||
"build": "rollup -c",
|
||||
"prepack": "npm run build"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -26,9 +56,10 @@
|
||||
"HMAC"
|
||||
],
|
||||
"license": "MIT",
|
||||
"author": "emn178 <emn178@gmail.com>",
|
||||
"author": "Chen, Yi-Cyuan <emn178@gmail.com>",
|
||||
"homepage": "https://github.com/emn178/js-sha256",
|
||||
"bugs": {
|
||||
"url": "https://github.com/emn178/js-sha256/issues"
|
||||
}
|
||||
},
|
||||
"browser": "build/sha256.cjs"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests/browser',
|
||||
use: {
|
||||
browserName: 'chromium',
|
||||
headless: true
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import terser from '@rollup/plugin-terser';
|
||||
|
||||
const { version } = JSON.parse(
|
||||
readFileSync(new URL('package.json', import.meta.url), 'utf8')
|
||||
);
|
||||
|
||||
const banner = `/**
|
||||
* [js-sha256]{@link https://github.com/emn178/js-sha256}
|
||||
*
|
||||
* @version ${version}
|
||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||
* @copyright Chen, Yi-Cyuan 2014-2026
|
||||
* @license MIT
|
||||
*/`;
|
||||
|
||||
export default [
|
||||
{
|
||||
input: 'src/cjs.mjs',
|
||||
output: {
|
||||
banner,
|
||||
exports: 'default',
|
||||
file: 'build/sha256.cjs',
|
||||
format: 'cjs'
|
||||
}
|
||||
},
|
||||
{
|
||||
input: 'src/umd.mjs',
|
||||
output: {
|
||||
banner,
|
||||
exports: 'default',
|
||||
file: 'build/sha256.js',
|
||||
format: 'umd',
|
||||
name: 'sha256'
|
||||
}
|
||||
},
|
||||
{
|
||||
external: ['crypto'],
|
||||
input: 'src/node-cjs.mjs',
|
||||
output: {
|
||||
banner,
|
||||
exports: 'default',
|
||||
file: 'build/sha256.node.cjs',
|
||||
format: 'cjs'
|
||||
}
|
||||
},
|
||||
{
|
||||
input: 'src/umd.mjs',
|
||||
output: [
|
||||
{
|
||||
banner,
|
||||
exports: 'default',
|
||||
file: 'build/sha256.min.js',
|
||||
format: 'umd',
|
||||
name: 'sha256',
|
||||
plugins: [terser()]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
input: 'src/index.mjs',
|
||||
output: {
|
||||
banner,
|
||||
file: 'build/sha256.min.mjs',
|
||||
format: 'es',
|
||||
plugins: [terser()]
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './core.mjs';
|
||||
+417
@@ -0,0 +1,417 @@
|
||||
import { FINALIZE_ERROR, formatMessage } from './shared.mjs';
|
||||
|
||||
var HEX_CHARS = '0123456789abcdef'.split('');
|
||||
var EXTRA = [-2147483648, 8388608, 32768, 128];
|
||||
var SHIFT = [24, 16, 8, 0];
|
||||
var K = [
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
];
|
||||
var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
|
||||
|
||||
var blocks = [];
|
||||
|
||||
var createOutputMethod = function (outputType, is224) {
|
||||
return function (message) {
|
||||
return new Sha256(is224, true).update(message)[outputType]();
|
||||
};
|
||||
};
|
||||
|
||||
var createMethod = function (is224) {
|
||||
var method = createOutputMethod('hex', is224);
|
||||
method.create = function () {
|
||||
return new Sha256(is224);
|
||||
};
|
||||
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(type, is224);
|
||||
}
|
||||
return method;
|
||||
};
|
||||
|
||||
var createHmacOutputMethod = function (outputType, is224) {
|
||||
return function (key, message) {
|
||||
return new HmacSha256(key, is224, true).update(message)[outputType]();
|
||||
};
|
||||
};
|
||||
|
||||
var createHmacMethod = function (is224) {
|
||||
var method = createHmacOutputMethod('hex', is224);
|
||||
method.create = function (key) {
|
||||
return new HmacSha256(key, is224);
|
||||
};
|
||||
method.update = function (key, message) {
|
||||
return method.create(key).update(message);
|
||||
};
|
||||
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
||||
var type = OUTPUT_TYPES[i];
|
||||
method[type] = createHmacOutputMethod(type, is224);
|
||||
}
|
||||
return method;
|
||||
};
|
||||
|
||||
function Sha256(is224, sharedMemory) {
|
||||
if (sharedMemory) {
|
||||
blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
this.blocks = blocks;
|
||||
} else {
|
||||
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
}
|
||||
|
||||
if (is224) {
|
||||
this.h0 = 0xc1059ed8;
|
||||
this.h1 = 0x367cd507;
|
||||
this.h2 = 0x3070dd17;
|
||||
this.h3 = 0xf70e5939;
|
||||
this.h4 = 0xffc00b31;
|
||||
this.h5 = 0x68581511;
|
||||
this.h6 = 0x64f98fa7;
|
||||
this.h7 = 0xbefa4fa4;
|
||||
} else { // 256
|
||||
this.h0 = 0x6a09e667;
|
||||
this.h1 = 0xbb67ae85;
|
||||
this.h2 = 0x3c6ef372;
|
||||
this.h3 = 0xa54ff53a;
|
||||
this.h4 = 0x510e527f;
|
||||
this.h5 = 0x9b05688c;
|
||||
this.h6 = 0x1f83d9ab;
|
||||
this.h7 = 0x5be0cd19;
|
||||
}
|
||||
|
||||
this.block = this.start = this.bytes = this.hBytes = 0;
|
||||
this.finalized = this.hashed = false;
|
||||
this.first = true;
|
||||
this.is224 = is224;
|
||||
}
|
||||
|
||||
Sha256.prototype.update = function (message) {
|
||||
if (this.finalized) {
|
||||
throw new Error(FINALIZE_ERROR);
|
||||
}
|
||||
var result = formatMessage(message);
|
||||
message = result[0];
|
||||
var isString = result[1];
|
||||
var code, index = 0, i, length = message.length, blocks = this.blocks;
|
||||
while (index < length) {
|
||||
if (this.hashed) {
|
||||
this.hashed = false;
|
||||
blocks[0] = this.block;
|
||||
this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
}
|
||||
|
||||
if (isString) {
|
||||
for (i = this.start; index < length && i < 64; ++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 < 64; ++index) {
|
||||
blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3];
|
||||
}
|
||||
}
|
||||
|
||||
this.lastByteIndex = i;
|
||||
this.bytes += i - this.start;
|
||||
if (i >= 64) {
|
||||
this.block = blocks[16];
|
||||
this.start = i - 64;
|
||||
this.hash();
|
||||
this.hashed = true;
|
||||
} else {
|
||||
this.start = i;
|
||||
}
|
||||
}
|
||||
if (this.bytes > 4294967295) {
|
||||
this.hBytes += this.bytes / 4294967296 << 0;
|
||||
this.bytes = this.bytes % 4294967296;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Sha256.prototype.finalize = function () {
|
||||
if (this.finalized) {
|
||||
return;
|
||||
}
|
||||
this.finalized = true;
|
||||
var blocks = this.blocks, i = this.lastByteIndex;
|
||||
blocks[16] = this.block;
|
||||
blocks[i >>> 2] |= EXTRA[i & 3];
|
||||
this.block = blocks[16];
|
||||
if (i >= 56) {
|
||||
if (!this.hashed) {
|
||||
this.hash();
|
||||
}
|
||||
blocks[0] = this.block;
|
||||
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
}
|
||||
blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
|
||||
blocks[15] = this.bytes << 3;
|
||||
this.hash();
|
||||
};
|
||||
|
||||
Sha256.prototype.hash = function () {
|
||||
var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
|
||||
h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
|
||||
|
||||
for (j = 16; j < 64; ++j) {
|
||||
// rightrotate
|
||||
t1 = blocks[j - 15];
|
||||
s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
|
||||
t1 = blocks[j - 2];
|
||||
s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
|
||||
blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
|
||||
}
|
||||
|
||||
bc = b & c;
|
||||
for (j = 0; j < 64; j += 4) {
|
||||
if (this.first) {
|
||||
if (this.is224) {
|
||||
ab = 300032;
|
||||
t1 = blocks[0] - 1413257819;
|
||||
h = t1 - 150054599 << 0;
|
||||
d = t1 + 24177077 << 0;
|
||||
} else {
|
||||
ab = 704751109;
|
||||
t1 = blocks[0] - 210244248;
|
||||
h = t1 - 1521486534 << 0;
|
||||
d = t1 + 143694565 << 0;
|
||||
}
|
||||
this.first = false;
|
||||
} else {
|
||||
s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
|
||||
s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
|
||||
ab = a & b;
|
||||
maj = ab ^ (a & c) ^ bc;
|
||||
ch = (e & f) ^ (~e & g);
|
||||
t1 = h + s1 + ch + K[j] + blocks[j];
|
||||
t2 = s0 + maj;
|
||||
h = d + t1 << 0;
|
||||
d = t1 + t2 << 0;
|
||||
}
|
||||
s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
|
||||
s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
|
||||
da = d & a;
|
||||
maj = da ^ (d & b) ^ ab;
|
||||
ch = (h & e) ^ (~h & f);
|
||||
t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
|
||||
t2 = s0 + maj;
|
||||
g = c + t1 << 0;
|
||||
c = t1 + t2 << 0;
|
||||
s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
|
||||
s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
|
||||
cd = c & d;
|
||||
maj = cd ^ (c & a) ^ da;
|
||||
ch = (g & h) ^ (~g & e);
|
||||
t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
|
||||
t2 = s0 + maj;
|
||||
f = b + t1 << 0;
|
||||
b = t1 + t2 << 0;
|
||||
s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
|
||||
s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
|
||||
bc = b & c;
|
||||
maj = bc ^ (b & d) ^ cd;
|
||||
ch = (f & g) ^ (~f & h);
|
||||
t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
|
||||
t2 = s0 + maj;
|
||||
e = a + t1 << 0;
|
||||
a = t1 + t2 << 0;
|
||||
this.chromeBugWorkAround = true;
|
||||
}
|
||||
|
||||
this.h0 = this.h0 + a << 0;
|
||||
this.h1 = this.h1 + b << 0;
|
||||
this.h2 = this.h2 + c << 0;
|
||||
this.h3 = this.h3 + d << 0;
|
||||
this.h4 = this.h4 + e << 0;
|
||||
this.h5 = this.h5 + f << 0;
|
||||
this.h6 = this.h6 + g << 0;
|
||||
this.h7 = this.h7 + h << 0;
|
||||
};
|
||||
|
||||
Sha256.prototype.hex = function () {
|
||||
this.finalize();
|
||||
|
||||
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
|
||||
h6 = this.h6, h7 = this.h7;
|
||||
|
||||
var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
|
||||
if (!this.is224) {
|
||||
hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] +
|
||||
HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] +
|
||||
HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] +
|
||||
HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
|
||||
}
|
||||
return hex;
|
||||
};
|
||||
|
||||
Sha256.prototype.toString = Sha256.prototype.hex;
|
||||
|
||||
Sha256.prototype.digest = function () {
|
||||
this.finalize();
|
||||
|
||||
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
|
||||
h6 = this.h6, h7 = this.h7;
|
||||
|
||||
var arr = [
|
||||
(h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF,
|
||||
(h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF,
|
||||
(h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF,
|
||||
(h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF,
|
||||
(h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF,
|
||||
(h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF,
|
||||
(h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF
|
||||
];
|
||||
if (!this.is224) {
|
||||
arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
Sha256.prototype.array = Sha256.prototype.digest;
|
||||
|
||||
Sha256.prototype.arrayBuffer = function () {
|
||||
this.finalize();
|
||||
|
||||
var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
|
||||
var dataView = new DataView(buffer);
|
||||
dataView.setUint32(0, this.h0);
|
||||
dataView.setUint32(4, this.h1);
|
||||
dataView.setUint32(8, this.h2);
|
||||
dataView.setUint32(12, this.h3);
|
||||
dataView.setUint32(16, this.h4);
|
||||
dataView.setUint32(20, this.h5);
|
||||
dataView.setUint32(24, this.h6);
|
||||
if (!this.is224) {
|
||||
dataView.setUint32(28, this.h7);
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
|
||||
function HmacSha256(key, is224, sharedMemory) {
|
||||
var i, result = formatMessage(key);
|
||||
key = result[0];
|
||||
if (result[1]) {
|
||||
var bytes = [], length = key.length, index = 0, code;
|
||||
for (i = 0; i < length; ++i) {
|
||||
code = key.charCodeAt(i);
|
||||
if (code < 0x80) {
|
||||
bytes[index++] = code;
|
||||
} else if (code < 0x800) {
|
||||
bytes[index++] = (0xc0 | (code >>> 6));
|
||||
bytes[index++] = (0x80 | (code & 0x3f));
|
||||
} else if (code < 0xd800 || code >= 0xe000) {
|
||||
bytes[index++] = (0xe0 | (code >>> 12));
|
||||
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||
bytes[index++] = (0x80 | (code & 0x3f));
|
||||
} else {
|
||||
code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
|
||||
bytes[index++] = (0xf0 | (code >>> 18));
|
||||
bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
|
||||
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
||||
bytes[index++] = (0x80 | (code & 0x3f));
|
||||
}
|
||||
}
|
||||
key = bytes;
|
||||
}
|
||||
|
||||
if (key.length > 64) {
|
||||
key = (new Sha256(is224, true)).update(key).array();
|
||||
}
|
||||
|
||||
var oKeyPad = [], iKeyPad = [];
|
||||
for (i = 0; i < 64; ++i) {
|
||||
var b = key[i] || 0;
|
||||
oKeyPad[i] = 0x5c ^ b;
|
||||
iKeyPad[i] = 0x36 ^ b;
|
||||
}
|
||||
|
||||
Sha256.call(this, is224, sharedMemory);
|
||||
|
||||
this.update(iKeyPad);
|
||||
this.oKeyPad = oKeyPad;
|
||||
this.inner = true;
|
||||
this.sharedMemory = sharedMemory;
|
||||
}
|
||||
HmacSha256.prototype = new Sha256();
|
||||
|
||||
HmacSha256.prototype.finalize = function () {
|
||||
Sha256.prototype.finalize.call(this);
|
||||
if (this.inner) {
|
||||
this.inner = false;
|
||||
var innerHash = this.array();
|
||||
Sha256.call(this, this.is224, this.sharedMemory);
|
||||
this.update(this.oKeyPad);
|
||||
this.update(innerHash);
|
||||
Sha256.prototype.finalize.call(this);
|
||||
}
|
||||
};
|
||||
|
||||
var sha256 = createMethod();
|
||||
var sha224 = createMethod(true);
|
||||
sha256.sha256 = sha256;
|
||||
sha256.sha224 = sha224;
|
||||
sha256.hmac = createHmacMethod();
|
||||
sha224.hmac = createHmacMethod(true);
|
||||
|
||||
export { sha256, sha224 };
|
||||
export default sha256;
|
||||
@@ -0,0 +1 @@
|
||||
export { default, sha224, sha256 } from './core.mjs';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './node.mjs';
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
import { createHash, createHmac } from 'crypto';
|
||||
import { FINALIZE_ERROR, formatMessage } from './shared.mjs';
|
||||
|
||||
function toNodeInput(message) {
|
||||
const [ msg, isString ] = formatMessage(message);
|
||||
return isString ? Buffer.from(msg, 'utf8') : Buffer.from(msg);
|
||||
}
|
||||
|
||||
class NodeHasher {
|
||||
constructor(hash) {
|
||||
this.hash = hash;
|
||||
this.result = undefined;
|
||||
}
|
||||
|
||||
update(message) {
|
||||
if (this.result) {
|
||||
throw new Error(FINALIZE_ERROR);
|
||||
}
|
||||
this.hash.update(toNodeInput(message));
|
||||
return this;
|
||||
}
|
||||
|
||||
finalize() {
|
||||
if (!this.result) {
|
||||
this.result = this.hash.digest();
|
||||
this.hash = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
hex() {
|
||||
this.finalize();
|
||||
return this.result.toString('hex');
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.hex();
|
||||
}
|
||||
|
||||
array() {
|
||||
this.finalize();
|
||||
return Array.from(this.result);
|
||||
}
|
||||
|
||||
digest() {
|
||||
return this.array();
|
||||
}
|
||||
|
||||
arrayBuffer() {
|
||||
return Uint8Array.from(this.array()).buffer;
|
||||
}
|
||||
}
|
||||
|
||||
function addOutputMethods(method, createHasher) {
|
||||
method.hex = method;
|
||||
method.array = function (...args) {
|
||||
return createHasher(...args.slice(0, -1)).update(args[args.length - 1]).array();
|
||||
};
|
||||
method.digest = method.array;
|
||||
method.arrayBuffer = function (...args) {
|
||||
return createHasher(...args.slice(0, -1)).update(args[args.length - 1]).arrayBuffer();
|
||||
};
|
||||
return method;
|
||||
}
|
||||
|
||||
function createNodeMethod(algorithm) {
|
||||
const createHasher = () => new NodeHasher(createHash(algorithm));
|
||||
const method = function (message) {
|
||||
return createHasher().update(message).hex();
|
||||
};
|
||||
addOutputMethods(method, createHasher);
|
||||
method.create = createHasher;
|
||||
method.update = function (message) {
|
||||
return method.create().update(message);
|
||||
};
|
||||
return method;
|
||||
}
|
||||
|
||||
function createNodeHmacMethod(algorithm) {
|
||||
const createHasher = key => new NodeHasher(createHmac(algorithm, toNodeInput(key)));
|
||||
const method = function (key, message) {
|
||||
return createHasher(key).update(message).hex();
|
||||
};
|
||||
addOutputMethods(method, createHasher);
|
||||
method.create = createHasher;
|
||||
method.update = function (key, message) {
|
||||
return method.create(key).update(message);
|
||||
};
|
||||
return method;
|
||||
}
|
||||
|
||||
const sha256 = createNodeMethod('sha256');
|
||||
const sha224 = createNodeMethod('sha224');
|
||||
|
||||
sha256.sha256 = sha256;
|
||||
sha256.sha224 = sha224;
|
||||
sha256.hmac = createNodeHmacMethod('sha256');
|
||||
sha224.hmac = createNodeHmacMethod('sha224');
|
||||
|
||||
export { sha256, sha224 };
|
||||
export default sha256;
|
||||
-229
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* js-sha256 v0.2.3
|
||||
* https://github.com/emn178/js-sha256
|
||||
*
|
||||
* Copyright 2014-2015, emn178@gmail.com
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
;(function(root, undefined) {
|
||||
'use strict';
|
||||
|
||||
var NODE_JS = typeof(module) != 'undefined';
|
||||
if(NODE_JS) {
|
||||
root = global;
|
||||
}
|
||||
var TYPED_ARRAY = typeof(Uint8Array) != 'undefined';
|
||||
var HEX_CHARS = '0123456789abcdef'.split('');
|
||||
var EXTRA = [-2147483648, 8388608, 32768, 128];
|
||||
var SHIFT = [24, 16, 8, 0];
|
||||
var K =[0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
|
||||
|
||||
var blocks = [];
|
||||
|
||||
Array.prototype.__ARRAY__ = true;
|
||||
if(TYPED_ARRAY) {
|
||||
Uint8Array.prototype.__ARRAY__ = true;
|
||||
}
|
||||
|
||||
var sha224 = function(message) {
|
||||
return sha256(message, true);
|
||||
};
|
||||
|
||||
var sha256 = function(message, is224) {
|
||||
var h0, h1, h2, h3, h4, h5, h6, h7, block, code, first = true, end = false,
|
||||
i, j, index = 0, start = 0, bytes = 0, length = message.length,
|
||||
s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
|
||||
|
||||
if(is224) {
|
||||
h0 = 0xc1059ed8;
|
||||
h1 = 0x367cd507;
|
||||
h2 = 0x3070dd17;
|
||||
h3 = 0xf70e5939;
|
||||
h4 = 0xffc00b31;
|
||||
h5 = 0x68581511;
|
||||
h6 = 0x64f98fa7;
|
||||
h7 = 0xbefa4fa4;
|
||||
} else { // 256
|
||||
h0 = 0x6a09e667;
|
||||
h1 = 0xbb67ae85;
|
||||
h2 = 0x3c6ef372;
|
||||
h3 = 0xa54ff53a;
|
||||
h4 = 0x510e527f;
|
||||
h5 = 0x9b05688c;
|
||||
h6 = 0x1f83d9ab;
|
||||
h7 = 0x5be0cd19;
|
||||
}
|
||||
block = 0;
|
||||
do {
|
||||
blocks[0] = block;
|
||||
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
||||
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
||||
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
||||
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
||||
if(message.__ARRAY__) {
|
||||
for (i = start;index < length && i < 64; ++index) {
|
||||
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
|
||||
}
|
||||
} else {
|
||||
for (i = start;index < length && i < 64; ++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];
|
||||
}
|
||||
}
|
||||
}
|
||||
bytes += i - start;
|
||||
start = i - 64;
|
||||
if(index == length) {
|
||||
blocks[i >> 2] |= EXTRA[i & 3];
|
||||
++index;
|
||||
}
|
||||
block = blocks[16];
|
||||
if(index > length && i < 56) {
|
||||
blocks[15] = bytes << 3;
|
||||
end = true;
|
||||
}
|
||||
|
||||
var a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7;
|
||||
for(j = 16;j < 64;++j) {
|
||||
// rightrotate
|
||||
t1 = blocks[j - 15];
|
||||
s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
|
||||
t1 = blocks[j - 2];
|
||||
s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
|
||||
blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
|
||||
}
|
||||
|
||||
bc = b & c;
|
||||
for(j = 0;j < 64;j += 4) {
|
||||
if(first) {
|
||||
if(is224) {
|
||||
ab = 300032;
|
||||
t1 = blocks[0] - 1413257819;
|
||||
h = t1 - 150054599 << 0;
|
||||
d = t1 + 24177077 << 0;
|
||||
} else {
|
||||
ab = 704751109;
|
||||
t1 = blocks[0] - 210244248;
|
||||
h = t1 - 1521486534 << 0;
|
||||
d = t1 + 143694565 << 0;
|
||||
}
|
||||
first = false;
|
||||
} else {
|
||||
s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
|
||||
s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
|
||||
ab = a & b;
|
||||
maj = ab ^ (a & c) ^ bc;
|
||||
ch = (e & f) ^ (~e & g);
|
||||
t1 = h + s1 + ch + K[j] + blocks[j];
|
||||
t2 = s0 + maj;
|
||||
h = d + t1 << 0;
|
||||
d = t1 + t2 << 0;
|
||||
}
|
||||
s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
|
||||
s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
|
||||
da = d & a;
|
||||
maj = da ^ (d & b) ^ ab;
|
||||
ch = (h & e) ^ (~h & f);
|
||||
t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
|
||||
t2 = s0 + maj;
|
||||
g = c + t1 << 0;
|
||||
c = t1 + t2 << 0;
|
||||
s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
|
||||
s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
|
||||
cd = c & d;
|
||||
maj = cd ^ (c & a) ^ da;
|
||||
ch = (g & h) ^ (~g & e);
|
||||
t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
|
||||
t2 = s0 + maj;
|
||||
f = b + t1 << 0;
|
||||
b = t1 + t2 << 0;
|
||||
s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
|
||||
s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
|
||||
bc = b & c;
|
||||
maj = bc ^ (b & d) ^ cd;
|
||||
ch = (f & g) ^ (~f & h);
|
||||
t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
|
||||
t2 = s0 + maj;
|
||||
e = a + t1 << 0;
|
||||
a = t1 + t2 << 0;
|
||||
}
|
||||
|
||||
h0 = h0 + a << 0;
|
||||
h1 = h1 + b << 0;
|
||||
h2 = h2 + c << 0;
|
||||
h3 = h3 + d << 0;
|
||||
h4 = h4 + e << 0;
|
||||
h5 = h5 + f << 0;
|
||||
h6 = h6 + g << 0;
|
||||
h7 = h7 + h << 0;
|
||||
} while(!end);
|
||||
|
||||
var hex = HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
|
||||
HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
|
||||
HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
|
||||
HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
|
||||
HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
|
||||
HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
|
||||
HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
|
||||
if(!is224) {
|
||||
hex += HEX_CHARS[(h7 >> 28) & 0x0F] + HEX_CHARS[(h7 >> 24) & 0x0F] +
|
||||
HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] +
|
||||
HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] +
|
||||
HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
|
||||
}
|
||||
return hex;
|
||||
};
|
||||
|
||||
if(!root.JS_SHA256_TEST && NODE_JS) {
|
||||
sha256.sha256 = sha256;
|
||||
sha256.sha224 = sha224;
|
||||
module.exports = sha256;
|
||||
} else if(root) {
|
||||
root.sha256 = sha256;
|
||||
root.sha224 = sha224;
|
||||
}
|
||||
}(this));
|
||||
@@ -0,0 +1,22 @@
|
||||
export var INPUT_ERROR = 'input is invalid type';
|
||||
export var FINALIZE_ERROR = 'finalize already called';
|
||||
|
||||
var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
|
||||
|
||||
export var formatMessage = function (message) {
|
||||
var type = typeof message;
|
||||
if (type === 'string') {
|
||||
return [message, true];
|
||||
}
|
||||
if (Array.isArray(message)) {
|
||||
return [message, false];
|
||||
}
|
||||
if (ARRAY_BUFFER && message) {
|
||||
if (message.constructor === ArrayBuffer) {
|
||||
return [new Uint8Array(message), false];
|
||||
} else if (ArrayBuffer.isView(message)) {
|
||||
return [message, false];
|
||||
}
|
||||
}
|
||||
throw new Error(INPUT_ERROR);
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import sha256, { sha224 } from './core.mjs';
|
||||
|
||||
const root =
|
||||
typeof globalThis === 'object' ? globalThis :
|
||||
typeof self === 'object' ? self :
|
||||
typeof window === 'object' ? window :
|
||||
typeof global === 'object' ? global :
|
||||
undefined;
|
||||
|
||||
if (root) {
|
||||
root.sha224 = sha224;
|
||||
}
|
||||
|
||||
export default sha256;
|
||||
@@ -0,0 +1,5 @@
|
||||
importScripts('/build/sha256.min.js');
|
||||
|
||||
self.onmessage = function (event) {
|
||||
self.postMessage(sha256(event.data));
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
import { sha256 } from '../../src/index.mjs';
|
||||
|
||||
self.onmessage = function (event) {
|
||||
self.postMessage(sha256(event.data));
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { createReadStream } from 'node:fs';
|
||||
import { stat } from 'node:fs/promises';
|
||||
import { createServer } from 'node:http';
|
||||
import { extname, join, normalize } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const root = fileURLToPath(new URL('../..', import.meta.url));
|
||||
const contentTypes = {
|
||||
'.js': 'text/javascript',
|
||||
'.mjs': 'text/javascript'
|
||||
};
|
||||
|
||||
let server;
|
||||
let origin;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
server = createServer(async (request, response) => {
|
||||
if (request.url === '/') {
|
||||
response.writeHead(200, { 'Content-Type': 'text/html' });
|
||||
response.end('<!doctype html><title>js-sha256 worker test</title>');
|
||||
return;
|
||||
}
|
||||
|
||||
const path = normalize(join(root, decodeURIComponent(request.url)));
|
||||
if (!path.startsWith(root)) {
|
||||
response.writeHead(403);
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await stat(path);
|
||||
response.writeHead(200, {
|
||||
'Content-Type': contentTypes[extname(path)] || 'application/octet-stream'
|
||||
});
|
||||
createReadStream(path).pipe(response);
|
||||
} catch {
|
||||
response.writeHead(404);
|
||||
response.end();
|
||||
}
|
||||
});
|
||||
|
||||
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
|
||||
const address = server.address();
|
||||
origin = `http://127.0.0.1:${address.port}`;
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await new Promise((resolve, reject) => {
|
||||
server.close(error => error ? reject(error) : resolve());
|
||||
});
|
||||
});
|
||||
|
||||
async function hashInWorker(page, workerPath, options) {
|
||||
return page.evaluate(({ workerPath, options }) => new Promise((resolve, reject) => {
|
||||
const worker = new Worker(workerPath, options);
|
||||
const timeout = setTimeout(() => {
|
||||
worker.terminate();
|
||||
reject(new Error('Worker timed out'));
|
||||
}, 5000);
|
||||
|
||||
worker.onmessage = event => {
|
||||
clearTimeout(timeout);
|
||||
worker.terminate();
|
||||
resolve(event.data);
|
||||
};
|
||||
worker.onerror = event => {
|
||||
clearTimeout(timeout);
|
||||
worker.terminate();
|
||||
reject(new Error(event.message));
|
||||
};
|
||||
worker.postMessage('abc');
|
||||
}), { workerPath, options });
|
||||
}
|
||||
|
||||
test('classic Worker loads the minified UMD build', async ({ page }) => {
|
||||
await page.goto(origin);
|
||||
const hash = await hashInWorker(page, '/tests/browser/classic-worker.js');
|
||||
expect(hash).toBe(
|
||||
'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
|
||||
);
|
||||
});
|
||||
|
||||
test('module Worker imports the ESM source entry', async ({ page }) => {
|
||||
await page.goto(origin);
|
||||
const hash = await hashInWorker(
|
||||
page,
|
||||
'/tests/browser/module-worker.mjs',
|
||||
{ type: 'module' }
|
||||
);
|
||||
expect(hash).toBe(
|
||||
'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { sha224, sha256 } from '../src/core.mjs';
|
||||
|
||||
globalThis.assert = assert;
|
||||
globalThis.sha256 = sha256;
|
||||
globalThis.sha224 = sha224;
|
||||
globalThis.TEST_INTERNALS = true;
|
||||
|
||||
await import('./test.js');
|
||||
await import('./hmac-test.js');
|
||||
@@ -0,0 +1,87 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { createRequire } from 'node:module';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import vm from 'node:vm';
|
||||
import packageSha256, {
|
||||
sha224 as packageSha224,
|
||||
sha256 as namedPackageSha256
|
||||
} from 'js-sha256';
|
||||
import browserSha256, {
|
||||
sha224 as browserSha224
|
||||
} from '../src/index.mjs';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const commonJs = require('../build/sha256.cjs');
|
||||
const nodeCommonJs = require('js-sha256');
|
||||
|
||||
const SHA256_ABC = 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad';
|
||||
const SHA224_ABC = '23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7';
|
||||
const HMAC_ABC = '9c196e32dc0175f86f4b1cb89289d6619de6bee699e4c378e68309ed97a1a6ab';
|
||||
|
||||
function testContract(name, sha256, sha224) {
|
||||
assert.equal(sha256('abc'), SHA256_ABC, `${name}: SHA-256`);
|
||||
assert.equal(sha224('abc'), SHA224_ABC, `${name}: SHA-224`);
|
||||
assert.equal(sha256.hmac('key', 'abc'), HMAC_ABC, `${name}: HMAC`);
|
||||
assert.equal(sha256.update('a').update('bc').hex(), SHA256_ABC, `${name}: streaming`);
|
||||
assert.equal(sha256([97, 98, 99]), SHA256_ABC, `${name}: array`);
|
||||
assert.equal(sha256(new Uint8Array([97, 98, 99])), SHA256_ABC, `${name}: typed array`);
|
||||
assert.equal(sha256.sha256, sha256, `${name}: sha256 property`);
|
||||
assert.equal(sha256.sha224, sha224, `${name}: sha224 property`);
|
||||
}
|
||||
|
||||
function testStreamingOutputs(name, algorithm, expected) {
|
||||
const hasher = algorithm.create().update('a').update('bc');
|
||||
assert.equal(hasher.hex(), expected, `${name}: hex`);
|
||||
assert.equal(hasher.toString(), expected, `${name}: toString`);
|
||||
assert.deepEqual(hasher.array(), Array.from(Buffer.from(expected, 'hex')), `${name}: array`);
|
||||
assert.deepEqual(hasher.digest(), hasher.array(), `${name}: digest`);
|
||||
assert.equal(
|
||||
Buffer.from(hasher.arrayBuffer()).toString('hex'),
|
||||
expected,
|
||||
`${name}: arrayBuffer`
|
||||
);
|
||||
assert.equal(hasher.hex(), expected, `${name}: repeated output`);
|
||||
}
|
||||
|
||||
function testHmacStreamingOutputs(name, hmac) {
|
||||
const hasher = hmac.create('key').update('a').update('bc');
|
||||
assert.equal(hasher.hex(), HMAC_ABC, `${name}: hex`);
|
||||
assert.equal(hasher.toString(), HMAC_ABC, `${name}: toString`);
|
||||
assert.deepEqual(hasher.array(), Array.from(Buffer.from(HMAC_ABC, 'hex')), `${name}: array`);
|
||||
assert.deepEqual(hasher.digest(), hasher.array(), `${name}: digest`);
|
||||
assert.equal(
|
||||
Buffer.from(hasher.arrayBuffer()).toString('hex'),
|
||||
HMAC_ABC,
|
||||
`${name}: arrayBuffer`
|
||||
);
|
||||
assert.equal(hasher.hex(), HMAC_ABC, `${name}: repeated output`);
|
||||
}
|
||||
|
||||
testContract('package ESM', packageSha256, packageSha224);
|
||||
assert.equal(namedPackageSha256, packageSha256);
|
||||
testStreamingOutputs('package ESM SHA-256 streaming', packageSha256, SHA256_ABC);
|
||||
testStreamingOutputs('package ESM SHA-224 streaming', packageSha224, SHA224_ABC);
|
||||
testHmacStreamingOutputs('package ESM HMAC streaming', packageSha256.hmac);
|
||||
testContract('browser ESM', browserSha256, browserSha224);
|
||||
testContract('generic CommonJS', commonJs, commonJs.sha224);
|
||||
testContract('package CommonJS', nodeCommonJs, nodeCommonJs.sha224);
|
||||
testStreamingOutputs('package CommonJS SHA-256 streaming', nodeCommonJs, SHA256_ABC);
|
||||
testStreamingOutputs('package CommonJS SHA-224 streaming', nodeCommonJs.sha224, SHA224_ABC);
|
||||
testHmacStreamingOutputs('package CommonJS HMAC streaming', nodeCommonJs.hmac);
|
||||
|
||||
const umdCode = await readFile(new URL('../build/sha256.min.js', import.meta.url), 'utf8');
|
||||
const browserContext = vm.createContext({});
|
||||
vm.runInContext(umdCode, browserContext);
|
||||
testContract('browser UMD', browserContext.sha256, browserContext.sha224);
|
||||
|
||||
let amdSha256;
|
||||
const amdContext = vm.createContext({
|
||||
define(factory) {
|
||||
amdSha256 = factory();
|
||||
}
|
||||
});
|
||||
amdContext.define.amd = true;
|
||||
vm.runInContext(umdCode, amdContext);
|
||||
testContract('AMD', amdSha256, amdSha256.sha224);
|
||||
|
||||
console.log('Distribution contracts: PASS');
|
||||
@@ -0,0 +1,242 @@
|
||||
(function (sha256, sha224) {
|
||||
Array.prototype.toHexString = ArrayBuffer.prototype.toHexString = function () {
|
||||
var array = new Uint8Array(this);
|
||||
var hex = '';
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
var c = array[i].toString('16');
|
||||
hex += c.length === 1 ? '0' + c : c;
|
||||
}
|
||||
return hex;
|
||||
};
|
||||
|
||||
var testCases = {
|
||||
sha256_hmac: {
|
||||
'Test Vectors': {
|
||||
'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7': [
|
||||
[0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b],
|
||||
'Hi There'
|
||||
],
|
||||
'5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843': [
|
||||
'Jefe',
|
||||
'what do ya want for nothing?'
|
||||
],
|
||||
'773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe': [
|
||||
[0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa],
|
||||
[0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd]
|
||||
],
|
||||
'82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b': [
|
||||
[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],
|
||||
[0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd]
|
||||
],
|
||||
'60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54': [
|
||||
[0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa],
|
||||
'Test Using Larger Than Block-Size Key - Hash Key First'
|
||||
],
|
||||
'9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2': [
|
||||
[0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa],
|
||||
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.'
|
||||
]
|
||||
},
|
||||
'UTF8': {
|
||||
'865cc329d317f6d9fdbd183a3c5cc5fd4c370d11f98abbbb404bceb1e6392c7e': ['中文', '中文'],
|
||||
'efeef87be5731506b69bb64a9898a456dd12c94834c36a4d8ba99e3db79ad7ed': ['aécio', 'aécio'],
|
||||
'8a6e527049b9cfc7e1c84bcf356a1289c95da68a586c03de3327f3de0d3737fe': ['𠜎', '𠜎']
|
||||
}
|
||||
},
|
||||
sha224_hmac: {
|
||||
'Test Vectors': {
|
||||
'896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22': [
|
||||
[0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b],
|
||||
'Hi There'
|
||||
],
|
||||
'a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44': [
|
||||
'Jefe',
|
||||
'what do ya want for nothing?'
|
||||
],
|
||||
'7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea': [
|
||||
[0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa],
|
||||
[0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd]
|
||||
],
|
||||
'6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a': [
|
||||
[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],
|
||||
[0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd]
|
||||
],
|
||||
'95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e': [
|
||||
[0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa],
|
||||
'Test Using Larger Than Block-Size Key - Hash Key First'
|
||||
],
|
||||
'3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1': [
|
||||
[0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa],
|
||||
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.'
|
||||
]
|
||||
},
|
||||
'UTF8': {
|
||||
'e2280928fe813aeb7fa59aa14dd5e589041bfdf91945d19d25b9f3db': ['中文', '中文'],
|
||||
'86c53dc054b16f6e006a254891bc9ff0da5df8e1a6faee3b0aaa732d': ['aécio', 'aécio'],
|
||||
'e9e5991bfb84506b105f800afac1599ff807bb8e20db8ffda48997b9': ['𠜎', '𠜎']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
testCases.sha256_hmac.Uint8Array = {
|
||||
'e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b': [
|
||||
new Uint8Array(0),
|
||||
'Hi There'
|
||||
]
|
||||
};
|
||||
testCases.sha256_hmac.ArrayBuffer = {
|
||||
'e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b': [
|
||||
new ArrayBuffer(0),
|
||||
'Hi There'
|
||||
]
|
||||
};
|
||||
testCases.sha224_hmac.Uint8Array = {
|
||||
'da8f94de91d62154b55ea4e8d6eb133f6d553bcd1f1ba205b9488945': [
|
||||
new ArrayBuffer(0),
|
||||
'Hi There'
|
||||
]
|
||||
};
|
||||
testCases.sha224_hmac.ArrayBuffer = {
|
||||
'da8f94de91d62154b55ea4e8d6eb133f6d553bcd1f1ba205b9488945': [
|
||||
new ArrayBuffer(0),
|
||||
'Hi There'
|
||||
]
|
||||
};
|
||||
|
||||
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 (key, message) {
|
||||
return algorithm.array(key, message).toHexString();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: name + '.digest',
|
||||
call: function (key, message) {
|
||||
return algorithm.digest(key, message).toHexString();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: name + '.arrayBuffer',
|
||||
call: function (key, message) {
|
||||
return algorithm.arrayBuffer(key, message).toHexString();
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var classMethods = [
|
||||
{
|
||||
name: 'create',
|
||||
call: function (key, message) {
|
||||
return algorithm.create(key).update(message).toString();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'update',
|
||||
call: function (key, message) {
|
||||
return algorithm.update(key, message).toString();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'hex',
|
||||
call: function (key, message) {
|
||||
return algorithm.update(key, message).hex();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'array',
|
||||
call: function (key, message) {
|
||||
return algorithm.update(key, message).array().toHexString();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'digest',
|
||||
call: function (key, message) {
|
||||
return algorithm.update(key, message).digest().toHexString();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'arrayBuffer',
|
||||
call: function (key, message) {
|
||||
return algorithm.update(key, message).arrayBuffer().toHexString();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'finalize',
|
||||
call: function (key, message) {
|
||||
var hash = algorithm.update(key, message);
|
||||
hash.hex();
|
||||
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 () {
|
||||
assert.equal(method.call(message[0], message[1]), hash);
|
||||
});
|
||||
})(testCase[hash], hash);
|
||||
}
|
||||
});
|
||||
})(testCaseName);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
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 () {
|
||||
assert.equal(method.call(message[0], message[1]), hash);
|
||||
});
|
||||
})(testCase[hash], hash);
|
||||
}
|
||||
});
|
||||
})(testCaseName);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('#' + name, function () {
|
||||
errorTestCases.forEach(function (testCase) {
|
||||
context('when ' + testCase, function () {
|
||||
it('should throw error', function () {
|
||||
assert.throws(function () {
|
||||
algorithm(testCase, '');
|
||||
}, /input is invalid type/);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
runTestCases('sha256_hmac', sha256.hmac);
|
||||
runTestCases('sha224_hmac', sha224.hmac);
|
||||
})(sha256, sha224);
|
||||
@@ -1,22 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>SHA256</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
|
||||
<script src="../src/sha256.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>
|
||||
mocha.setup('bdd');
|
||||
</script>
|
||||
<script src="test.js"></script>
|
||||
<script>
|
||||
mocha.checkLeaks();
|
||||
mocha.run();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,13 +0,0 @@
|
||||
sha256 = require('../src/sha256.js').sha256;
|
||||
sha224 = require('../src/sha256.js').sha224;
|
||||
expect = require('expect.js');
|
||||
require('./test.js');
|
||||
|
||||
delete require.cache[require.resolve('../src/sha256.js')]
|
||||
delete require.cache[require.resolve('./test.js')]
|
||||
sha256 = null;
|
||||
sha224 = null;
|
||||
|
||||
JS_SHA256_TEST = true;
|
||||
require('../src/sha256.js');
|
||||
require('./test.js');
|
||||
@@ -0,0 +1,10 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { sha224, sha256 } from 'js-sha256';
|
||||
|
||||
globalThis.assert = assert;
|
||||
globalThis.sha256 = sha256;
|
||||
globalThis.sha224 = sha224;
|
||||
globalThis.TEST_INTERNALS = false;
|
||||
|
||||
await import('./test.js');
|
||||
await import('./hmac-test.js');
|
||||
+254
-94
@@ -1,107 +1,267 @@
|
||||
describe('sha256', function() {
|
||||
describe('ascii', function() {
|
||||
describe('less than 64 bytes', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha256('')).to.be('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
|
||||
expect(sha256('The quick brown fox jumps over the lazy dog')).to.be('d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592');
|
||||
expect(sha256('The quick brown fox jumps over the lazy dog.')).to.be('ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c');
|
||||
(function (sha256, sha224) {
|
||||
Array.prototype.toHexString = ArrayBuffer.prototype.toHexString = function () {
|
||||
var array = new Uint8Array(this);
|
||||
var hex = '';
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
var c = array[i].toString('16');
|
||||
hex += c.length === 1 ? '0' + c : c;
|
||||
}
|
||||
return hex;
|
||||
};
|
||||
|
||||
var testCases = {
|
||||
sha256: {
|
||||
'ascii': {
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': '',
|
||||
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': 'The quick brown fox jumps over the lazy dog',
|
||||
'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c': 'The quick brown fox jumps over the lazy dog.'
|
||||
},
|
||||
'ascii more than 64 bytes': {
|
||||
'54e73d89e1924fdcd056390266a983924b6d6d461e9470b6cd50bbaf69b5c54c': 'The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity.'
|
||||
},
|
||||
'UTF8': {
|
||||
'72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21': '中文',
|
||||
'53196d1acfce0c4b264e01e8018c989d571351f59e33f055f76ff15b4f0516c6': 'aécio',
|
||||
'8d10a48685dbc34484696de7ea7434d80a54c1d60100530faccf697463ef19c9': '𠜎',
|
||||
'2c731ad02e3d0e3c863bdbce4cce221e0be1d31efffdd8e1455a835e8287dc33': 'Tehtäväsi on muotoilla teksti, jossa käyttäjälle suositellaan hänen henkilökohtaisiin tietoihinsa perustuen avioehdon tekemistä. Suosittelemme nimenomaan tätä tuotetta käyttäjän henkilökohtaisista tiedoista johtuen. Tuottamasi tekstin tulee olla lyhyt, persoonallinen, ymmärrettävä ja todenmukainen. Suositus perustuu seuraaviin seikkoihin:\n\nSeikka 0: Avioehdon tekeminen on verohyötyjen vuoksi suositeltavaa, koska olet ilmaissut että haluat kuoleman tapauksessa turvata ensisijaisesti aviopuolisosi asemaa (ennemmin kuin lasten asemaa). Avioehdolla voit määrätä, että puolet kuolleen puolison omaisuudesta siirtyy verovapaasti leskelle.\n\nVoit halutessasi hyödyntää seuraavia tietoja tekstin muotoilussa persoonallisemmaksi: Käyttäjällä on kumppani nimeltä PARTNER_NAME. Käyttäjällä on suurperhe. Käyttäjällä on lapsiperhe.\n\nPuhuttele käyttäjää siihen sävyyn että tiedät jo mitä käyttäjä haluaa, koska hän on kertonut toiveistaan, ja niiden perusteella tehty suositus on ilmiselvä. Joten älä käytä epävarmoja ilmaisuja kuten "halutessasi", vaan kirjoita itsevarmoilla ilmaisuilla kuten "koska haluat". Älä tee oletuksia käyttäjän sukupuolesta, emme tiedä onko hän mies vai nainen. Älä käytä sanaa jälkikasvu, puhu ennemmin lapsesta tai lapsista riippuen onko lapsia yksi vai useampia. Älä puhuttele käyttäjää ensimmäisessä persoonassa, käytä ennemmin passiivimuotoa. Tekstin sävyn tulisi olla neutraalin asiallinen, ei melodramaattinen eikä leikkisä. Pysy totuudessa, älä keksi uusia seikkoja yllä listattujen lisäksi. Viittaa ihmisiin nimillä silloin kun se on mahdollista. Tekstin tulisi olla vain muutaman lauseen mittainen. Älä siis kirjoita pitkiä selityksiä äläkä kirjoita listoja. Tiivistä oleellinen tieto lyhyeksi ja persoonalliseksi tekstiksi.'
|
||||
},
|
||||
'UTF8 more than 64 bytes': {
|
||||
'd691014feebf35b3500ef6f6738d0094cac63628a7a018a980a40292a77703d1': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一',
|
||||
'81a1472ebdeb09406a783d607ff49ee2fde3e9f44ac1cd158ad8d6ad3c4e69fa': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。'
|
||||
},
|
||||
'special length': {
|
||||
'5e6b963e2b6444dab8544beab8532850cef2a9d143872a6a5384abe37e61b3db': '0123456780123456780123456780123456780123456780123456780',
|
||||
'85d240a4a03a0710423fc4f701da51e8785c9eaa96d718ab1c7991d6afd60d62': '01234567801234567801234567801234567801234567801234567801',
|
||||
'c3ee464d5620eb2dde3dfda4c7955dbd9e9e2e9b113c13983fc67b0dfd892a53': '0123456780123456780123456780123456780123456780123456780123456780',
|
||||
'74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841': '01234567801234567801234567801234567801234567801234567801234567801234567',
|
||||
'6fba9e623ae6abf028a1b195748814aa95eebfb22e3ec5e15d2444cd6c48186a': '012345678012345678012345678012345678012345678012345678012345678012345678'
|
||||
},
|
||||
'Array': {
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': [],
|
||||
'182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': [211, 212],
|
||||
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': [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],
|
||||
'74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841': [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55]
|
||||
}
|
||||
},
|
||||
sha224: {
|
||||
'ascii': {
|
||||
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': '',
|
||||
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': 'The quick brown fox jumps over the lazy dog',
|
||||
'619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c': 'The quick brown fox jumps over the lazy dog.'
|
||||
},
|
||||
'ascii more than 64 bytes': {
|
||||
'4d97e15967391d2e846ea7d21bb480efadbae5868b731e7cc6267006': 'The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity.'
|
||||
},
|
||||
'UTF8': {
|
||||
'dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4': '中文',
|
||||
'd12841cafd89c534924a839e62bf35a2b5f3717b7802eb19bd8d8e15': 'aécio',
|
||||
'eaa0129b5509f5701db218fb7076b282e4409da52d06363aa3bdd63d': '𠜎',
|
||||
'b19e948e39752eb064452abbaecac72e17ce2a028d640a8864e92c36': 'Tehtäväsi on muotoilla teksti, jossa käyttäjälle suositellaan hänen henkilökohtaisiin tietoihinsa perustuen avioehdon tekemistä. Suosittelemme nimenomaan tätä tuotetta käyttäjän henkilökohtaisista tiedoista johtuen. Tuottamasi tekstin tulee olla lyhyt, persoonallinen, ymmärrettävä ja todenmukainen. Suositus perustuu seuraaviin seikkoihin:\n\nSeikka 0: Avioehdon tekeminen on verohyötyjen vuoksi suositeltavaa, koska olet ilmaissut että haluat kuoleman tapauksessa turvata ensisijaisesti aviopuolisosi asemaa (ennemmin kuin lasten asemaa). Avioehdolla voit määrätä, että puolet kuolleen puolison omaisuudesta siirtyy verovapaasti leskelle.\n\nVoit halutessasi hyödyntää seuraavia tietoja tekstin muotoilussa persoonallisemmaksi: Käyttäjällä on kumppani nimeltä PARTNER_NAME. Käyttäjällä on suurperhe. Käyttäjällä on lapsiperhe.\n\nPuhuttele käyttäjää siihen sävyyn että tiedät jo mitä käyttäjä haluaa, koska hän on kertonut toiveistaan, ja niiden perusteella tehty suositus on ilmiselvä. Joten älä käytä epävarmoja ilmaisuja kuten "halutessasi", vaan kirjoita itsevarmoilla ilmaisuilla kuten "koska haluat". Älä tee oletuksia käyttäjän sukupuolesta, emme tiedä onko hän mies vai nainen. Älä käytä sanaa jälkikasvu, puhu ennemmin lapsesta tai lapsista riippuen onko lapsia yksi vai useampia. Älä puhuttele käyttäjää ensimmäisessä persoonassa, käytä ennemmin passiivimuotoa. Tekstin sävyn tulisi olla neutraalin asiallinen, ei melodramaattinen eikä leikkisä. Pysy totuudessa, älä keksi uusia seikkoja yllä listattujen lisäksi. Viittaa ihmisiin nimillä silloin kun se on mahdollista. Tekstin tulisi olla vain muutaman lauseen mittainen. Älä siis kirjoita pitkiä selityksiä äläkä kirjoita listoja. Tiivistä oleellinen tieto lyhyeksi ja persoonalliseksi tekstiksi.'
|
||||
},
|
||||
'UTF8 more than 64 bytes': {
|
||||
'0dda421f3f81272418e1313673e9d74b7f2d04efc9c52c69458e12c3': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一',
|
||||
'a8cb74a54e6dc6ab6110db3915ba08ffe5e1abafaea78538fa12a626': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。'
|
||||
},
|
||||
'special length': {
|
||||
'bc4a354d66f3cff4bc6dd6a88fbb0435cede7fd5fe94da0760cb1924': '0123456780123456780123456780123456780123456780123456780',
|
||||
'2f148f757d1295784a7c69bf328b8bf827a536669e132234cd6f50e7': '01234567801234567801234567801234567801234567801234567801',
|
||||
'496275a96bf41aa27ce89c3ae0fc63c3a3eab063887a8ea075bd091b': '0123456780123456780123456780123456780123456780123456780123456780',
|
||||
'16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8': '01234567801234567801234567801234567801234567801234567801234567801234567',
|
||||
'04c7a30079c640e440d884cdf0d7ab04fd05501d4498cb21be29ca1f': '012345678012345678012345678012345678012345678012345678012345678012345678'
|
||||
},
|
||||
'Array': {
|
||||
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': [],
|
||||
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': [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],
|
||||
'16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8': [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
testCases.sha256.Uint8Array = {
|
||||
'182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': new Uint8Array([211, 212]),
|
||||
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': 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.sha256.Int8Array = {
|
||||
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Int8Array([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.sha256.ArrayBuffer = {
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': new ArrayBuffer(0),
|
||||
'6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d': new ArrayBuffer(1)
|
||||
};
|
||||
testCases.sha224.Uint8Array = {
|
||||
'e17541396a3ecd1cd5a2b968b84e597e8eae3b0ea3127963bf48dd3b': new Uint8Array([211, 212]),
|
||||
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': 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.sha224.Int8Array = {
|
||||
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Int8Array([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.sha224.ArrayBuffer = {
|
||||
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': new ArrayBuffer(0),
|
||||
'fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073': new ArrayBuffer(1),
|
||||
};
|
||||
|
||||
testCases.sha256.Buffer = {
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': Buffer.from([]),
|
||||
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': 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]))
|
||||
};
|
||||
testCases.sha224.Buffer = {
|
||||
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': Buffer.from([]),
|
||||
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': 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();
|
||||
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 () {
|
||||
assert.equal(method.call(message), hash);
|
||||
});
|
||||
})(testCase[hash], hash);
|
||||
}
|
||||
});
|
||||
})(testCaseName);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('more than 64 bytes', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha256('The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity.')).to.be('54e73d89e1924fdcd056390266a983924b6d6d461e9470b6cd50bbaf69b5c54c');
|
||||
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 () {
|
||||
assert.equal(method.call(message), hash);
|
||||
});
|
||||
})(testCase[hash], hash);
|
||||
}
|
||||
});
|
||||
})(testCaseName);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('#' + name, function () {
|
||||
errorTestCases.forEach(function (testCase) {
|
||||
context('when ' + testCase, function () {
|
||||
it('should throw error', function () {
|
||||
assert.throws(function () {
|
||||
algorithm(testCase);
|
||||
}, /input is invalid type/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('UTF8', function() {
|
||||
describe('less than 64 bytes', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha256('中文')).to.be('72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21');
|
||||
expect(sha256('aécio')).to.be('53196d1acfce0c4b264e01e8018c989d571351f59e33f055f76ff15b4f0516c6');
|
||||
expect(sha256('𠜎')).to.be('8d10a48685dbc34484696de7ea7434d80a54c1d60100530faccf697463ef19c9');
|
||||
context('when update after finalize', function () {
|
||||
it('should throw error', function () {
|
||||
assert.throws(function () {
|
||||
var hash = algorithm.update('any');
|
||||
hash.hex();
|
||||
hash.update('any');
|
||||
}, /finalize already called/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('more than 64 bytes', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha256('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一')).to.be('d691014feebf35b3500ef6f6738d0094cac63628a7a018a980a40292a77703d1');
|
||||
expect(sha256('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。')).to.be('81a1472ebdeb09406a783d607ff49ee2fde3e9f44ac1cd158ad8d6ad3c4e69fa');
|
||||
});
|
||||
if (TEST_INTERNALS) {
|
||||
context('when large size', function () {
|
||||
var hash = algorithm.create();
|
||||
hash.bytes = 4294967295;
|
||||
hash.update('any');
|
||||
assert.equal(hash.hBytes, 1);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('special length', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha256('0123456780123456780123456780123456780123456780123456780')).to.be('5e6b963e2b6444dab8544beab8532850cef2a9d143872a6a5384abe37e61b3db');
|
||||
expect(sha256('01234567801234567801234567801234567801234567801234567801')).to.be('85d240a4a03a0710423fc4f701da51e8785c9eaa96d718ab1c7991d6afd60d62');
|
||||
expect(sha256('0123456780123456780123456780123456780123456780123456780123456780')).to.be('c3ee464d5620eb2dde3dfda4c7955dbd9e9e2e9b113c13983fc67b0dfd892a53');
|
||||
expect(sha256('01234567801234567801234567801234567801234567801234567801234567801234567')).to.be('74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841');
|
||||
expect(sha256('012345678012345678012345678012345678012345678012345678012345678012345678')).to.be('6fba9e623ae6abf028a1b195748814aa95eebfb22e3ec5e15d2444cd6c48186a');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Array', function() {
|
||||
describe('Array', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha256([])).to.be('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
|
||||
expect(sha256([211, 212])).to.be('182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f');
|
||||
expect(sha256([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('d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592');
|
||||
expect(sha256([48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55])).to.be('74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Uint8Array', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha256(new Uint8Array([]))).to.be('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
|
||||
expect(sha256(new Uint8Array([211, 212]))).to.be('182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sha224', function() {
|
||||
describe('ascii', function() {
|
||||
describe('less than 64 bytes', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha224('')).to.be('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f');
|
||||
expect(sha224('The quick brown fox jumps over the lazy dog')).to.be('730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525');
|
||||
expect(sha224('The quick brown fox jumps over the lazy dog.')).to.be('619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c');
|
||||
});
|
||||
});
|
||||
|
||||
describe('more than 64 bytes', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha224('The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity.')).to.be('4d97e15967391d2e846ea7d21bb480efadbae5868b731e7cc6267006');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('UTF8', function() {
|
||||
describe('less than 64 bytes', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha224('中文')).to.be('dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4');
|
||||
expect(sha224('aécio')).to.be('d12841cafd89c534924a839e62bf35a2b5f3717b7802eb19bd8d8e15');
|
||||
expect(sha224('𠜎')).to.be('eaa0129b5509f5701db218fb7076b282e4409da52d06363aa3bdd63d');
|
||||
});
|
||||
});
|
||||
|
||||
describe('more than 64 bytes', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha224('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一')).to.be('0dda421f3f81272418e1313673e9d74b7f2d04efc9c52c69458e12c3');
|
||||
expect(sha224('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。')).to.be('a8cb74a54e6dc6ab6110db3915ba08ffe5e1abafaea78538fa12a626');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('special length', function() {
|
||||
it('should be successful', function() {
|
||||
expect(sha224('0123456780123456780123456780123456780123456780123456780')).to.be('bc4a354d66f3cff4bc6dd6a88fbb0435cede7fd5fe94da0760cb1924');
|
||||
expect(sha224('01234567801234567801234567801234567801234567801234567801')).to.be('2f148f757d1295784a7c69bf328b8bf827a536669e132234cd6f50e7');
|
||||
expect(sha224('0123456780123456780123456780123456780123456780123456780123456780')).to.be('496275a96bf41aa27ce89c3ae0fc63c3a3eab063887a8ea075bd091b');
|
||||
expect(sha224('01234567801234567801234567801234567801234567801234567801234567801234567')).to.be('16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8');
|
||||
expect(sha224('012345678012345678012345678012345678012345678012345678012345678012345678')).to.be('04c7a30079c640e440d884cdf0d7ab04fd05501d4498cb21be29ca1f');
|
||||
});
|
||||
});
|
||||
});
|
||||
runTestCases('sha256', sha256);
|
||||
runTestCases('sha224', sha224);
|
||||
})(sha256, sha224);
|
||||
|
||||
Reference in New Issue
Block a user