├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── open_an_issue.md ├── config.yml └── workflows │ └── main.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── benchmarks └── hash.js ├── package.json ├── src ├── blake.js ├── crypto.js ├── index.js ├── sha.browser.js ├── sha.js ├── types.ts └── utils.js ├── test ├── fixtures │ └── encodes.js └── index.spec.js └── tsconfig.json /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Getting Help on IPFS 4 | url: https://ipfs.io/help 5 | about: All information about how and where to get help on IPFS. 6 | - name: IPFS Official Forum 7 | url: https://discuss.ipfs.io 8 | about: Please post general questions, support requests, and discussions here. 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/open_an_issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Open an issue 3 | about: Only for actionable issues relevant to this repository. 4 | title: '' 5 | labels: need/triage 6 | assignees: '' 7 | 8 | --- 9 | 20 | -------------------------------------------------------------------------------- /.github/config.yml: -------------------------------------------------------------------------------- 1 | # Configuration for welcome - https://github.com/behaviorbot/welcome 2 | 3 | # Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome 4 | # Comment to be posted to on first time issues 5 | newIssueWelcomeComment: > 6 | Thank you for submitting your first issue to this repository! A maintainer 7 | will be here shortly to triage and review. 8 | 9 | In the meantime, please double-check that you have provided all the 10 | necessary information to make this process easy! Any information that can 11 | help save additional round trips is useful! We currently aim to give 12 | initial feedback within **two business days**. If this does not happen, feel 13 | free to leave a comment. 14 | 15 | Please keep an eye on how this issue will be labeled, as labels give an 16 | overview of priorities, assignments and additional actions requested by the 17 | maintainers: 18 | 19 | - "Priority" labels will show how urgent this is for the team. 20 | - "Status" labels will show if this is ready to be worked on, blocked, or in progress. 21 | - "Need" labels will indicate if additional input or analysis is required. 22 | 23 | Finally, remember to use https://discuss.ipfs.io if you just need general 24 | support. 25 | 26 | # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome 27 | # Comment to be posted to on PRs from first time contributors in your repository 28 | newPRWelcomeComment: > 29 | Thank you for submitting this PR! 30 | 31 | A maintainer will be here shortly to review it. 32 | 33 | We are super grateful, but we are also overloaded! Help us by making sure 34 | that: 35 | 36 | * The context for this PR is clear, with relevant discussion, decisions 37 | and stakeholders linked/mentioned. 38 | 39 | * Your contribution itself is clear (code comments, self-review for the 40 | rest) and in its best form. Follow the [code contribution 41 | guidelines](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md#code-contribution-guidelines) 42 | if they apply. 43 | 44 | Getting other community members to do a review would be great help too on 45 | complex PRs (you can ask in the chats/forums). If you are unsure about 46 | something, just leave us a comment. 47 | 48 | Next steps: 49 | 50 | * A maintainer will triage and assign priority to this PR, commenting on 51 | any missing things and potentially assigning a reviewer for high 52 | priority items. 53 | 54 | * The PR gets reviews, discussed and approvals as needed. 55 | 56 | * The PR is merged by maintainers when it has been approved and comments addressed. 57 | 58 | We currently aim to provide initial feedback/triaging within **two business 59 | days**. Please keep an eye on any labelling actions, as these will indicate 60 | priorities and status of your contribution. 61 | 62 | We are very grateful for your contribution! 63 | 64 | 65 | # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge 66 | # Comment to be posted to on pull requests merged by a first time user 67 | # Currently disabled 68 | #firstPRMergeComment: "" 69 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | 10 | jobs: 11 | check: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - uses: actions/setup-node@v2 16 | with: 17 | node-version: 14 18 | - run: npm install 19 | - run: npx aegir lint 20 | - run: npx aegir ts -p check 21 | # or 22 | # - uses: gozala/typescript-error-reporter-action@v1.0.8 23 | - run: npx aegir build 24 | - run: npx aegir dep-check 25 | - uses: ipfs/aegir/actions/bundle-size@master 26 | with: 27 | github_token: ${{ secrets.GITHUB_TOKEN }} 28 | test-node: 29 | needs: check 30 | runs-on: ${{ matrix.os }} 31 | strategy: 32 | matrix: 33 | os: [windows-latest, ubuntu-latest, macos-latest] 34 | node: [12, 14] 35 | fail-fast: true 36 | steps: 37 | - uses: actions/checkout@v2 38 | - uses: actions/setup-node@v1 39 | with: 40 | node-version: ${{ matrix.node }} 41 | - run: npm install 42 | - run: npx aegir test -t node --bail --cov 43 | - uses: codecov/codecov-action@v1 44 | test-chrome: 45 | needs: check 46 | runs-on: ubuntu-latest 47 | steps: 48 | - uses: actions/checkout@v2 49 | - uses: microsoft/playwright-github-action@v1 50 | - run: npm install 51 | - run: npx aegir test -t browser -t webworker --bail --cov 52 | - uses: codecov/codecov-action@v1 53 | test-firefox: 54 | needs: check 55 | runs-on: ubuntu-latest 56 | steps: 57 | - uses: actions/checkout@v2 58 | - uses: microsoft/playwright-github-action@v1 59 | - run: npm install 60 | - run: npx aegir test -t browser -t webworker --bail -- --browser firefox 61 | test-webkit: 62 | needs: check 63 | runs-on: ubuntu-latest 64 | steps: 65 | - uses: actions/checkout@v2 66 | - uses: microsoft/playwright-github-action@v1 67 | - run: npm install 68 | - run: npx aegir test -t browser -t webworker --bail -- --browser webkit 69 | test-electron-main: 70 | needs: check 71 | runs-on: ubuntu-latest 72 | steps: 73 | - uses: actions/checkout@v2 74 | - run: npm install 75 | - run: npx xvfb-maybe aegir test -t electron-main --bail 76 | test-electron-renderer: 77 | needs: check 78 | runs-on: ubuntu-latest 79 | steps: 80 | - uses: actions/checkout@v2 81 | - run: npm install 82 | - run: npx xvfb-maybe aegir test -t electron-renderer --bail -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | yarn.lock 3 | # Logs 4 | logs 5 | *.log 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # node-waf configuration 22 | .lock-wscript 23 | 24 | # Compiled binary addons (http://nodejs.org/api/addons.html) 25 | build/Release 26 | 27 | # Dependency directory 28 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 29 | node_modules 30 | 31 | dist 32 | docs 33 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [2.1.4](https://github.com/multiformats/js-multihashing-async/compare/v2.1.3...v2.1.4) (2021-08-24) 2 | 3 | 4 | 5 | ## [2.1.3](https://github.com/multiformats/js-multihashing-async/compare/v2.1.2...v2.1.3) (2021-08-11) 6 | 7 | 8 | 9 | ## [2.1.2](https://github.com/multiformats/js-multihashing-async/compare/v2.1.1...v2.1.2) (2021-03-03) 10 | 11 | 12 | ### Bug Fixes 13 | 14 | * revert to node 12 ([39d843d](https://github.com/multiformats/js-multihashing-async/commit/39d843d85e9bbfd083be5f2c3ebce1f84b202dbd)) 15 | 16 | 17 | 18 | ## [2.1.1](https://github.com/multiformats/js-multihashing-async/compare/v2.1.0...v2.1.1) (2021-03-02) 19 | 20 | 21 | ### Bug Fixes 22 | 23 | * update to aegir v31 and others deps ([#99](https://github.com/multiformats/js-multihashing-async/issues/99)) ([fa88cbc](https://github.com/multiformats/js-multihashing-async/commit/fa88cbcedc6c3713f32e89ab04c5f7c429c48c52)) 24 | 25 | 26 | 27 | # [2.1.0](https://github.com/multiformats/js-multihashing-async/compare/v2.0.1...v2.1.0) (2021-02-02) 28 | 29 | 30 | ### Features 31 | 32 | * add types to the library ([#92](https://github.com/multiformats/js-multihashing-async/issues/92)) ([4b16057](https://github.com/multiformats/js-multihashing-async/commit/4b1605755df620d0a5193ad0d682206e000ccb06)) 33 | 34 | 35 | 36 | 37 | ## [2.0.1](https://github.com/multiformats/js-multihashing-async/compare/v2.0.0...v2.0.1) (2020-08-05) 38 | 39 | 40 | 41 | 42 | # [2.0.0](https://github.com/multiformats/js-multihashing-async/compare/v1.0.0...v2.0.0) (2020-08-03) 43 | 44 | 45 | ### Bug Fixes 46 | 47 | * replace node buffers with uint8arrays ([#78](https://github.com/multiformats/js-multihashing-async/issues/78)) ([eb612f3](https://github.com/multiformats/js-multihashing-async/commit/eb612f3)) 48 | 49 | 50 | 51 | 52 | # [1.0.0](https://github.com/multiformats/js-multihashing-async/compare/v0.8.2...v1.0.0) (2020-06-23) 53 | 54 | 55 | 56 | 57 | ## [0.8.2](https://github.com/multiformats/js-multihashing-async/compare/v0.8.1...v0.8.2) (2020-06-23) 58 | 59 | 60 | 61 | 62 | ## [0.8.1](https://github.com/multiformats/js-multihashing-async/compare/v0.8.0...v0.8.1) (2020-03-14) 63 | 64 | 65 | ### Bug Fixes 66 | 67 | * expose sha ([#66](https://github.com/multiformats/js-multihashing-async/issues/66)) ([dbe2a4a](https://github.com/multiformats/js-multihashing-async/commit/dbe2a4a)) 68 | 69 | 70 | 71 | 72 | # [0.8.0](https://github.com/multiformats/js-multihashing-async/compare/v0.7.0...v0.8.0) (2019-09-12) 73 | 74 | 75 | ### Bug Fixes 76 | 77 | * add identity hashing ([#53](https://github.com/multiformats/js-multihashing-async/issues/53)) ([3d4958e](https://github.com/multiformats/js-multihashing-async/commit/3d4958e)) 78 | * update deps and fix err-code usage ([fca09d6](https://github.com/multiformats/js-multihashing-async/commit/fca09d6)) 79 | 80 | 81 | 82 | 83 | # [0.7.0](https://github.com/multiformats/js-multihashing-async/compare/v0.6.0...v0.7.0) (2019-04-16) 84 | 85 | 86 | ### Features 87 | 88 | * change api to async/await ([#37](https://github.com/multiformats/js-multihashing-async/issues/37)) ([01f1da6](https://github.com/multiformats/js-multihashing-async/commit/01f1da6)) 89 | 90 | 91 | ### BREAKING CHANGES 92 | 93 | * callbacks are not supported!! 94 | 95 | 96 | 97 | 98 | # [0.6.0](https://github.com/multiformats/js-multihashing-async/compare/v0.5.2...v0.6.0) (2019-04-12) 99 | 100 | 101 | ### Features 102 | 103 | * validation. fixes [#43](https://github.com/multiformats/js-multihashing-async/issues/43) ([#44](https://github.com/multiformats/js-multihashing-async/issues/44)) ([fc01b26](https://github.com/multiformats/js-multihashing-async/commit/fc01b26)) 104 | 105 | 106 | 107 | 108 | ## [0.5.2](https://github.com/multiformats/js-multihashing-async/compare/v0.5.1...v0.5.2) (2019-01-09) 109 | 110 | 111 | ### Bug Fixes 112 | 113 | * use Buffer.from instead of the deprecated new Buffer ([#36](https://github.com/multiformats/js-multihashing-async/issues/36)) ([7f9c6d1](https://github.com/multiformats/js-multihashing-async/commit/7f9c6d1)) 114 | * use process.nextTick instead of setImmediate ([#35](https://github.com/multiformats/js-multihashing-async/issues/35)) ([343a6c0](https://github.com/multiformats/js-multihashing-async/commit/343a6c0)) 115 | 116 | 117 | 118 | 119 | ## [0.5.1](https://github.com/multiformats/js-multihashing-async/compare/v0.5.0...v0.5.1) (2018-05-30) 120 | 121 | 122 | ### Bug Fixes 123 | 124 | * improve Error on missing webcrypto ([b9c52b9](https://github.com/multiformats/js-multihashing-async/commit/b9c52b9)) 125 | 126 | 127 | 128 | 129 | # [0.5.0](https://github.com/multiformats/js-multihashing-async/compare/v0.4.9...v0.5.0) (2018-05-07) 130 | 131 | 132 | 133 | 134 | ## [0.4.9](https://github.com/multiformats/js-multihashing-async/compare/v0.4.8...v0.4.9) (2018-05-07) 135 | 136 | 137 | ### Bug Fixes 138 | 139 | * shake digest size ([5444fba](https://github.com/multiformats/js-multihashing-async/commit/5444fba)) 140 | 141 | 142 | 143 | 144 | ## [0.4.8](https://github.com/multiformats/js-multihashing-async/compare/v0.4.7...v0.4.8) (2018-02-27) 145 | 146 | 147 | ### Features 148 | 149 | * add double SHA2-256 hashing ([cb3779d](https://github.com/multiformats/js-multihashing-async/commit/cb3779d)), closes [#25](https://github.com/multiformats/js-multihashing-async/issues/25) 150 | 151 | 152 | 153 | 154 | ## [0.4.7](https://github.com/multiformats/js-multihashing-async/compare/v0.4.6...v0.4.7) (2017-10-20) 155 | 156 | 157 | 158 | 159 | ## [0.4.6](https://github.com/multiformats/js-multihashing-async/compare/v0.4.5...v0.4.6) (2017-07-21) 160 | 161 | 162 | 163 | 164 | ## [0.4.5](https://github.com/multiformats/js-multihashing-async/compare/v0.4.4...v0.4.5) (2017-03-23) 165 | 166 | 167 | 168 | 169 | ## [0.4.4](https://github.com/multiformats/js-multihashing-async/compare/v0.4.3...v0.4.4) (2017-03-16) 170 | 171 | 172 | ### Bug Fixes 173 | 174 | * **deps:** update to fixed version of nodeify (1.0.1) ([154001d](https://github.com/multiformats/js-multihashing-async/commit/154001d)) 175 | 176 | 177 | 178 | 179 | ## [0.4.3](https://github.com/multiformats/js-multihashing-async/compare/v0.4.2...v0.4.3) (2017-02-24) 180 | 181 | 182 | ### Features 183 | 184 | * add blake support ([303a94c](https://github.com/multiformats/js-multihashing-async/commit/303a94c)) 185 | 186 | 187 | 188 | 189 | ## [0.4.2](https://github.com/multiformats/js-multihashing-async/compare/v0.4.1...v0.4.2) (2017-02-09) 190 | 191 | 192 | 193 | 194 | ## [0.4.1](https://github.com/multiformats/js-multihashing-async/compare/v0.4.0...v0.4.1) (2017-02-08) 195 | 196 | 197 | ### Features 198 | 199 | * change window to self for webworker support ([d89e039](https://github.com/multiformats/js-multihashing-async/commit/d89e039)) 200 | 201 | 202 | 203 | 204 | # [0.4.0](https://github.com/multiformats/js-multihashing-async/compare/v0.3.0...v0.4.0) (2017-01-27) 205 | 206 | 207 | ### Features 208 | 209 | * add support for murmur3 ([a1ed649](https://github.com/multiformats/js-multihashing-async/commit/a1ed649)) 210 | * add support for webworkers ([2f30f71](https://github.com/multiformats/js-multihashing-async/commit/2f30f71)) 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Protocol Labs Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ⛔️ DEPRECATED: This module has been superseded by the [multiformats](https://github.com/multiformats/js-multiformats) module 2 | 3 | # js-multihashing-async 4 | 5 | [![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) 6 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats) 7 | [![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs) 8 | [![codecov](https://img.shields.io/codecov/c/github/multiformats/js-multihashing-async.svg?style=flat-square)](https://codecov.io/gh/multiformats/js-multihashing-async) 9 | [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/multiformats/js-multihashing-async/ci?label=ci&style=flat-square)](https://github.com/multiformats/js-multihashing-async/actions?query=branch%3Amaster+workflow%3Aci+) 10 | 11 | > Use all the functions in [multihash](https://github.com/multiformats/multihash). 12 | 13 | ## Lead Maintainer 14 | 15 | [Hugo Dias](https://github.com/hugomrdias) 16 | 17 | ### Notice 18 | > This module is moving to async/await starting from 0.7.0. 19 | > The last minor version to support callbacks is 0.6.0, any backports will merged to the branch `callbacks` and released under `>0.6.0 <0.7.0`. 20 | 21 | #### Wait, why, how is this different from Node `crypto`? 22 | 23 | This module just makes working with multihashes a bit nicer. 24 | [js-multihash](//github.com/multiformats/js-multihash) is only for 25 | encoding/decoding multihashes, and does not depend on other libs. 26 | This module will depend on various implementations for each hash. 27 | It currently uses `crypto` and [`sha3`](https://github.com/phusion/node-sha3) in Node.js. 28 | In the browser [`webcrypto`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) 29 | and [`browserify-sha3`](https://github.com/wanderer/browserify-sha3) are used. 30 | 31 | ## Table of Contents 32 | 33 | - [Install](#install) 34 | - [In Node.js through npm](#in-nodejs-through-npm) 35 | - [Use in a browser with browserify, webpack or any other bundler](#use-in-a-browser-with-browserify-webpack-or-any-other-bundler) 36 | - [Use in a browser Using a script tag](#use-in-a-browser-using-a-script-tag) 37 | - [Usage](#usage) 38 | - [Examples](#examples) 39 | - [Multihash output](#multihash-output) 40 | - [API](#api) 41 | - [Contribute](#contribute) 42 | - [License](#license) 43 | 44 | ## Install 45 | 46 | ### In Node.js through npm 47 | 48 | ```bash 49 | $ npm install --save multihashing-async 50 | ``` 51 | 52 | ```js 53 | const multihashing = require('multihashing-async') 54 | ``` 55 | 56 | ### Use in a browser with browserify, webpack or any other bundler 57 | 58 | The code published to npm that gets loaded on require is in fact a ES5 transpiled 59 | version with the right shims added. This means that you can require it and use with 60 | your favourite bundler without having to adjust asset management process. 61 | 62 | ```js 63 | const multihashing = require('multihashing-async') 64 | ``` 65 | 66 | ### Use in a browser Using a script tag 67 | 68 | Loading this module through a script tag will make the `multihashing` obj 69 | available in the global namespace. 70 | 71 | ```html 72 | 73 | 74 | 75 | ``` 76 | 77 | ## Usage 78 | 79 | ```js 80 | const multihashing = require('multihashing-async') 81 | const bytes = new TextEncoder().encode('beep boop') 82 | 83 | const mh = await multihashing(bytes, 'sha1') 84 | 85 | // Use `.digest(...)` if you want only the hash digest (drops the prefix indicating the hash type). 86 | const digest = await multihashing.digest(bytes, 'sha1') 87 | 88 | // Use `.createHash(...)` for the raw hash functions 89 | const hash = multihashing.createHash('sha1') 90 | const digest = await hash(bytes) 91 | ``` 92 | 93 | ## Examples 94 | 95 | ### Multihash output 96 | 97 | ```js 98 | const multihashing = require('multihashing-async') 99 | const bytes = new TextEncoder().encode('beep boop') 100 | 101 | const mh = await multihashing(bytes, 'sha1') 102 | console.log(mh) 103 | // => 104 | 105 | const mh = await multihashing(bytes, 'sha2-256') 106 | console.log(mh) 107 | // => 108 | 109 | const mh = await multihashing(bytes, 'sha2-512') 110 | console.log(mh) 111 | // => 112 | ``` 113 | 114 | ## API 115 | 116 | https://multiformats.github.io/js-multihashing-async/ 117 | 118 | 119 | ## Contribute 120 | 121 | Contributions welcome. Please check out [the issues](https://github.com/multiformats/js-multihashing-async/issues). 122 | 123 | Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). 124 | 125 | Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. 126 | 127 | ## License 128 | 129 | [MIT](LICENSE) © Protocol Labs Inc. 130 | -------------------------------------------------------------------------------- /benchmarks/hash.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Benchmark = require('benchmark') 4 | const multihashing = require('../src') 5 | 6 | const suite = new Benchmark.Suite('multihashing-async') 7 | 8 | let list = [] 9 | 10 | const algs = [ 11 | 'sha1', 12 | 'sha2-256', 13 | 'sha2-512', 14 | 'sha3-512', 15 | 'sha3-384', 16 | 'sha3-256', 17 | 'sha3-224', 18 | 'shake-128', 19 | 'shake-256', 20 | 'keccak-224', 21 | 'keccak-256', 22 | 'keccak-384', 23 | 'keccak-512', 24 | 'murmur3-32', 25 | 'murmur3-128', 26 | 'dbl-sha2-256', 27 | 'blake2b-256', 28 | 'blake2b-512', 29 | 'blake2s-256' 30 | ] 31 | 32 | algs.forEach((alg) => { 33 | suite.add(alg, async function (d) { 34 | const buf = new Uint8Array(10 * 1024) 35 | buf.fill(Math.ceil(Math.random() * 100)) 36 | const res = await multihashing(buf, alg) 37 | list.push(res) 38 | d.resolve() 39 | }, { 40 | defer: true 41 | }) 42 | }) 43 | suite 44 | .on('cycle', (event) => { 45 | // eslint-disable-next-line 46 | console.log(String(event.target)) 47 | list = [] 48 | }) 49 | // run async 50 | .run({ 51 | async: true 52 | }) 53 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "multihashing-async", 3 | "version": "2.1.4", 4 | "description": "multiple hash functions", 5 | "keywords": [ 6 | "multihash", 7 | "hash", 8 | "hashing", 9 | "async" 10 | ], 11 | "homepage": "https://github.com/multiformats/js-multihashing-async", 12 | "bugs": "https://github.com/multiformats/js-multihashing-async/issues", 13 | "license": "MIT", 14 | "leadMaintainer": "Hugo Dias ", 15 | "files": [ 16 | "src", 17 | "dist" 18 | ], 19 | "main": "src/index.js", 20 | "browser": { 21 | "./src/sha.js": "./src/sha.browser.js" 22 | }, 23 | "types": "dist/src/index.d.ts", 24 | "repository": "github:multiformats/js-multihashing-async", 25 | "scripts": { 26 | "test": "aegir test", 27 | "test:browser": "aegir test -t browser", 28 | "test:node": "aegir test -t node", 29 | "lint": "aegir lint", 30 | "check": "aegir ts -p check", 31 | "prepare": "aegir build --no-bundle", 32 | "docs": "aegir docs", 33 | "release": "aegir release", 34 | "release-minor": "aegir release --type minor", 35 | "release-major": "aegir release --type major", 36 | "build": "aegir build", 37 | "bench": "node benchmarks/hash.js" 38 | }, 39 | "dependencies": { 40 | "blakejs": "^1.1.0", 41 | "err-code": "^3.0.0", 42 | "js-sha3": "^0.8.0", 43 | "multihashes": "^4.0.1", 44 | "murmurhash3js-revisited": "^3.0.0", 45 | "uint8arrays": "^3.0.0" 46 | }, 47 | "devDependencies": { 48 | "@types/sinon": "^9.0.10", 49 | "aegir": "^31.0.1", 50 | "benchmark": "^2.1.4", 51 | "sinon": "^9.0.2", 52 | "util": "^0.12.3" 53 | }, 54 | "eslintConfig": { 55 | "extends": "ipfs" 56 | }, 57 | "aegir": { 58 | "build": { 59 | "bundlesizeMax": "20kB" 60 | } 61 | }, 62 | "engines": { 63 | "node": ">=12.0.0", 64 | "npm": ">=6.0.0" 65 | }, 66 | "contributors": [ 67 | "David Dias ", 68 | "Hugo Dias ", 69 | "Friedel Ziegelmayer ", 70 | "achingbrain ", 71 | "Juan Batiz-Benet ", 72 | "Richard Littauer ", 73 | "Harlan T Wood ", 74 | "Pedro Teixeira ", 75 | "Irakli Gozalishvili ", 76 | "Victor Bjelkholm ", 77 | "Volker Mische ", 78 | "André Cruz ", 79 | "Arve Knudsen ", 80 | "Dmitriy Ryajov ", 81 | "Jacob Heun ", 82 | "Marcin Rataj ", 83 | "Matteo Collina ", 84 | "Mikeal Rogers ", 85 | "Mitar ", 86 | "Richard Schneider ", 87 | "Vasco Santos " 88 | ] 89 | } 90 | -------------------------------------------------------------------------------- /src/blake.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | // @ts-ignore - no types available 4 | const blake = require('blakejs') 5 | 6 | const minB = 0xb201 7 | const minS = 0xb241 8 | 9 | const blake2b = { 10 | init: blake.blake2bInit, 11 | update: blake.blake2bUpdate, 12 | digest: blake.blake2bFinal 13 | } 14 | 15 | const blake2s = { 16 | init: blake.blake2sInit, 17 | update: blake.blake2sUpdate, 18 | digest: blake.blake2sFinal 19 | } 20 | 21 | // Note that although this function doesn't do any asynchronous work, we mark 22 | // the function as async because it must return a Promise to match the API 23 | // for other functions that do perform asynchronous work (see sha.browser.js) 24 | // eslint-disable-next-line 25 | 26 | /** 27 | * @param {number} size 28 | * @param {any} hf 29 | * @returns {import('./types').Digest} 30 | */ 31 | const makeB2Hash = (size, hf) => async (data) => { 32 | const ctx = hf.init(size, null) 33 | hf.update(ctx, data) 34 | return hf.digest(ctx) 35 | } 36 | 37 | /** 38 | * @param {Record} table 39 | */ 40 | module.exports = (table) => { 41 | for (let i = 0; i < 64; i++) { 42 | table[minB + i] = makeB2Hash(i + 1, blake2b) 43 | } 44 | for (let i = 0; i < 32; i++) { 45 | table[minS + i] = makeB2Hash(i + 1, blake2s) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/crypto.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const sha3 = require('js-sha3') 4 | // @ts-ignore - no types available 5 | const mur = require('murmurhash3js-revisited') 6 | const { factory: sha } = require('./sha') 7 | const { fromNumberTo32BitBuf } = require('./utils') 8 | const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') 9 | 10 | // Note that although this function doesn't do any asynchronous work, we mark 11 | // the function as async because it must return a Promise to match the API 12 | // for other functions that do perform asynchronous work (see sha.browser.js) 13 | // eslint-disable-next-line 14 | /** 15 | * @param {string} algorithm 16 | * @returns {import('./types').Digest} 17 | */ 18 | const hash = (algorithm) => async (data) => { 19 | switch (algorithm) { 20 | case 'sha3-224': 21 | return new Uint8Array(sha3.sha3_224.arrayBuffer(data)) 22 | case 'sha3-256': 23 | return new Uint8Array(sha3.sha3_256.arrayBuffer(data)) 24 | case 'sha3-384': 25 | return new Uint8Array(sha3.sha3_384.arrayBuffer(data)) 26 | case 'sha3-512': 27 | return new Uint8Array(sha3.sha3_512.arrayBuffer(data)) 28 | case 'shake-128': 29 | return new Uint8Array(sha3.shake128.create(128).update(data).arrayBuffer()) 30 | case 'shake-256': 31 | return new Uint8Array(sha3.shake256.create(256).update(data).arrayBuffer()) 32 | case 'keccak-224': 33 | return new Uint8Array(sha3.keccak224.arrayBuffer(data)) 34 | case 'keccak-256': 35 | return new Uint8Array(sha3.keccak256.arrayBuffer(data)) 36 | case 'keccak-384': 37 | return new Uint8Array(sha3.keccak384.arrayBuffer(data)) 38 | case 'keccak-512': 39 | return new Uint8Array(sha3.keccak512.arrayBuffer(data)) 40 | case 'murmur3-128': 41 | return uint8ArrayFromString(mur.x64.hash128(data), 'base16') 42 | case 'murmur3-32': 43 | return fromNumberTo32BitBuf(mur.x86.hash32(data)) 44 | 45 | default: 46 | throw new TypeError(`${algorithm} is not a supported algorithm`) 47 | } 48 | } 49 | 50 | /** @type {import('./types').Digest} */ 51 | const identity = data => data 52 | 53 | module.exports = { 54 | identity, 55 | sha1: sha('sha1'), 56 | sha2256: sha('sha2-256'), 57 | sha2512: sha('sha2-512'), 58 | dblSha2256: sha('dbl-sha2-256'), 59 | sha3224: hash('sha3-224'), 60 | sha3256: hash('sha3-256'), 61 | sha3384: hash('sha3-384'), 62 | sha3512: hash('sha3-512'), 63 | shake128: hash('shake-128'), 64 | shake256: hash('shake-256'), 65 | keccak224: hash('keccak-224'), 66 | keccak256: hash('keccak-256'), 67 | keccak384: hash('keccak-384'), 68 | keccak512: hash('keccak-512'), 69 | murmur3128: hash('murmur3-128'), 70 | murmur332: hash('murmur3-32'), 71 | addBlake: require('./blake') 72 | } 73 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const errcode = require('err-code') 4 | const multihash = require('multihashes') 5 | const crypto = require('./crypto') 6 | const { equals } = require('uint8arrays/equals') 7 | 8 | /** 9 | * @typedef {import("./types").Digest} Digest 10 | * @typedef {import("multihashes").HashName} HashName 11 | */ 12 | 13 | /** 14 | * Hash the given `bytes` using the algorithm specified by `alg`. 15 | * 16 | * @param {Uint8Array} bytes - The value to hash. 17 | * @param {HashName} alg - The algorithm to use eg 'sha1' 18 | * @param {number} [length] - Optionally trim the result to this length. 19 | * @returns {Promise} 20 | */ 21 | async function Multihashing (bytes, alg, length) { 22 | const digest = await Multihashing.digest(bytes, alg, length) 23 | return multihash.encode(digest, alg, length) 24 | } 25 | 26 | /** 27 | * Expose multihash itself, to avoid silly double requires. 28 | */ 29 | Multihashing.multihash = multihash 30 | 31 | /** 32 | * @param {Uint8Array} bytes - The value to hash. 33 | * @param {HashName} alg - The algorithm to use eg 'sha1' 34 | * @param {number} [length] - Optionally trim the result to this length. 35 | * @returns {Promise} 36 | */ 37 | Multihashing.digest = async (bytes, alg, length) => { 38 | const hash = Multihashing.createHash(alg) 39 | const digest = await hash(bytes) 40 | return length ? digest.slice(0, length) : digest 41 | } 42 | 43 | /** 44 | * Creates a function that hashes with the given algorithm 45 | * 46 | * @param {HashName} alg - The algorithm to use eg 'sha1' 47 | * @returns {Digest} - The hash function corresponding to `alg` 48 | */ 49 | Multihashing.createHash = function (alg) { 50 | if (!alg) { 51 | const e = errcode(new Error('hash algorithm must be specified'), 'ERR_HASH_ALGORITHM_NOT_SPECIFIED') 52 | throw e 53 | } 54 | 55 | const code = multihash.coerceCode(alg) 56 | if (!Multihashing.functions[code]) { 57 | throw errcode(new Error(`multihash function '${alg}' not yet supported`), 'ERR_HASH_ALGORITHM_NOT_SUPPORTED') 58 | } 59 | 60 | return Multihashing.functions[code] 61 | } 62 | 63 | /** 64 | * Mapping of multihash codes to their hashing functions. 65 | * 66 | * @type {Record} 67 | */ 68 | // @ts-ignore - most of those functions aren't typed 69 | Multihashing.functions = { 70 | // identity 71 | 0x00: crypto.identity, 72 | // sha1 73 | 0x11: crypto.sha1, 74 | // sha2-256 75 | 0x12: crypto.sha2256, 76 | // sha2-512 77 | 0x13: crypto.sha2512, 78 | // sha3-512 79 | 0x14: crypto.sha3512, 80 | // sha3-384 81 | 0x15: crypto.sha3384, 82 | // sha3-256 83 | 0x16: crypto.sha3256, 84 | // sha3-224 85 | 0x17: crypto.sha3224, 86 | // shake-128 87 | 0x18: crypto.shake128, 88 | // shake-256 89 | 0x19: crypto.shake256, 90 | // keccak-224 91 | 0x1A: crypto.keccak224, 92 | // keccak-256 93 | 0x1B: crypto.keccak256, 94 | // keccak-384 95 | 0x1C: crypto.keccak384, 96 | // keccak-512 97 | 0x1D: crypto.keccak512, 98 | // murmur3-128 99 | 0x22: crypto.murmur3128, 100 | // murmur3-32 101 | 0x23: crypto.murmur332, 102 | // dbl-sha2-256 103 | 0x56: crypto.dblSha2256 104 | } 105 | 106 | // add blake functions 107 | crypto.addBlake(Multihashing.functions) 108 | 109 | /** 110 | * @param {Uint8Array} bytes 111 | * @param {Uint8Array} hash 112 | * @returns {Promise} 113 | */ 114 | Multihashing.validate = async (bytes, hash) => { 115 | const newHash = await Multihashing(bytes, multihash.decode(hash).name) 116 | 117 | return equals(hash, newHash) 118 | } 119 | 120 | module.exports = Multihashing 121 | -------------------------------------------------------------------------------- /src/sha.browser.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable require-await */ 2 | 'use strict' 3 | 4 | const multihash = require('multihashes') 5 | /** 6 | * @typedef {import('multihashes').HashName} HashName 7 | * @typedef {import('./types').Digest} Digest 8 | */ 9 | 10 | /** 11 | * @type {Crypto} 12 | */ 13 | const crypto = 14 | self.crypto || 15 | /** @type {typeof window.crypto} */ 16 | // @ts-ignore - unknown property 17 | (self.msCrypto) 18 | 19 | /** 20 | * 21 | * @param {Uint8Array} data 22 | * @param {HashName} alg 23 | * @returns {Promise} 24 | */ 25 | const digest = async (data, alg) => { 26 | if (typeof self === 'undefined' || !crypto) { 27 | throw new Error( 28 | 'Please use a browser with webcrypto support and ensure the code has been delivered securely via HTTPS/TLS and run within a Secure Context' 29 | ) 30 | } 31 | switch (alg) { 32 | case 'sha1': 33 | return new Uint8Array(await crypto.subtle.digest({ name: 'SHA-1' }, data)) 34 | case 'sha2-256': 35 | return new Uint8Array(await crypto.subtle.digest({ name: 'SHA-256' }, data)) 36 | case 'sha2-512': 37 | return new Uint8Array(await crypto.subtle.digest({ name: 'SHA-512' }, data)) 38 | case 'dbl-sha2-256': { 39 | const d = await crypto.subtle.digest({ name: 'SHA-256' }, data) 40 | return new Uint8Array(await crypto.subtle.digest({ name: 'SHA-256' }, d)) 41 | } 42 | default: 43 | throw new Error(`${alg} is not a supported algorithm`) 44 | } 45 | } 46 | 47 | module.exports = { 48 | /** 49 | * @param {HashName} alg 50 | * @returns {Digest} 51 | */ 52 | factory: (alg) => async (data) => { 53 | return digest(data, alg) 54 | }, 55 | digest, 56 | /** 57 | * @param {Uint8Array} buf 58 | * @param {HashName} alg 59 | * @param {number} [length] 60 | */ 61 | multihashing: async (buf, alg, length) => { 62 | const h = await digest(buf, alg) 63 | return multihash.encode(h, alg, length) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/sha.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable require-await */ 2 | 'use strict' 3 | const crypto = require('crypto') 4 | const multihash = require('multihashes') 5 | 6 | /** 7 | * @typedef {import('multihashes').HashName} HashName 8 | * @typedef {import('./types').Digest} Digest 9 | */ 10 | 11 | // Note that although this function doesn't do any asynchronous work, we mark 12 | // the function as async because it must return a Promise to match the API 13 | // for other functions that do perform asynchronous work (see sha.browser.js) 14 | // eslint-disable-next-line 15 | 16 | /** 17 | * @param {Uint8Array} data 18 | * @param {HashName} alg 19 | * @returns {Promise} 20 | */ 21 | const digest = async (data, alg) => { 22 | switch (alg) { 23 | case 'sha1': 24 | return crypto.createHash('sha1').update(data).digest() 25 | case 'sha2-256': 26 | return crypto.createHash('sha256').update(data).digest() 27 | case 'sha2-512': 28 | return crypto.createHash('sha512').update(data).digest() 29 | case 'dbl-sha2-256': { 30 | const first = crypto.createHash('sha256').update(data).digest() 31 | return crypto.createHash('sha256').update(first).digest() 32 | } 33 | default: 34 | throw new Error(`${alg} is not a supported algorithm`) 35 | } 36 | } 37 | 38 | module.exports = { 39 | /** 40 | * @param {HashName} alg 41 | * @returns {Digest} 42 | */ 43 | factory: (alg) => async (data) => { 44 | return digest(data, alg) 45 | }, 46 | digest, 47 | /** 48 | * @param {Uint8Array} buf 49 | * @param {HashName} alg 50 | * @param {number} [length] 51 | */ 52 | multihashing: async (buf, alg, length) => { 53 | const h = await digest(buf, alg) 54 | return multihash.encode(h, alg, length) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export interface Digest { 2 | (data: Uint8Array): Promise | Uint8Array 3 | } 4 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * @param {number} number 5 | * @returns {Uint8Array} 6 | */ 7 | const fromNumberTo32BitBuf = (number) => { 8 | const bytes = new Uint8Array(4) 9 | 10 | for (let i = 0; i < 4; i++) { 11 | bytes[i] = number & 0xff 12 | number = number >> 8 13 | } 14 | 15 | return bytes 16 | } 17 | 18 | module.exports = { 19 | fromNumberTo32BitBuf 20 | } 21 | -------------------------------------------------------------------------------- /test/fixtures/encodes.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * @type {Array<[string, import('multihashes').HashName, string]>} 5 | */ 6 | module.exports = [[ 7 | 'beep boop', 8 | 'identity', 9 | '00096265657020626f6f70' 10 | ], [ 11 | 'beep boop', 12 | 'sha1', 13 | '11147c8357577f51d4f0a8d393aa1aaafb28863d9421' 14 | ], [ 15 | 'beep boop', 16 | 'sha2-256', 17 | '122090ea688e275d580567325032492b597bc77221c62493e76330b85ddda191ef7c' 18 | ], [ 19 | 'beep boop', 20 | 'sha2-512', 21 | '134014f301f31be243f34c5668937883771fa381002f1aaa5f31b3f78e500b66ff2f4f8ea5e3c9f5a61bd073e2452c480484b02e030fb239315a2577f7ae156af177' 22 | ], [ 23 | 'beep boop', 24 | 'sha3-512', 25 | '1440fae2c9eb19906057f8bf507f0e73ee02bb669d58c3069e7718b89ca4d314cf4fd6f1679019cc46d185c7af34f6c05a307b070e74e9ed5b9c64f86aacc2b90d10' 26 | ], [ 27 | 'beep boop', 28 | 'sha3-384', 29 | '153075a9cff1bcfbe8a7025aa225dd558fb002769d4bf3b67d2aaf180459172208bea989804aefccf060b583e629e5f41e8d' 30 | ], [ 31 | 'beep boop', 32 | 'sha3-256', 33 | '1620828705da60284b39de02e3599d1f39e6c1df001f5dbf63c9ec2d2c91a95a427f' 34 | ], [ 35 | 'beep boop', 36 | 'sha3-224', 37 | '171c0da73a89549018df311c0a63250e008f7be357f93ba4e582aaea32b8' 38 | ], [ 39 | 'beep boop', 40 | 'shake-128', 41 | '18105fe422311f770743c2e0d86bcca09211' 42 | ], [ 43 | 'beep boop', 44 | 'shake-256', 45 | '192059feb5565e4f924baef74708649fed376d63948a862322ed763ecf093b63b38b' 46 | ], [ 47 | 'beep boop', 48 | 'keccak-224', 49 | '1a1c2bd72cde2f75e523512999eb7639f17b699efe29bec342f5a0270896' 50 | ], [ 51 | 'beep boop', 52 | 'keccak-256', 53 | '1b20ee6f6b4ce5d754c01203cb3b99294b88615df5999e20d6fe509204fa254a0f97' 54 | ], [ 55 | 'beep boop', 56 | 'keccak-384', 57 | '1c300e2fcca40e861fc425a2503a65f4a4befab7be7f193e57654ca3713e85262b035e54d5ade93f9632b810ab88b04f7d84' 58 | ], [ 59 | 'beep boop', 60 | 'keccak-512', 61 | '1d40e161c54798f78eba3404ac5e7e12d27555b7b810e7fd0db3f25ffa0c785c438331b0fbb6156215f69edf403c642e5280f4521da9bd767296ec81f05100852e78' 62 | ], [ 63 | 'beep boop', 64 | 'murmur3-128', 65 | '2210acfe9c5bbf88f075c0c4df0464430ead' 66 | ], [ 67 | 'beep boop', 68 | 'murmur3-32', 69 | '2304243ddb9e' 70 | ], [ 71 | 'beep boop', 72 | 'blake2b-512', 73 | 'c0e402400eac6255ba822373a0948122b8d295008419a8ab27842ee0d70eca39855621463c03ec75ac3610aacfdff89fa989d8d61fc00450148f289eb5b12ad1a954f659' 74 | ], [ 75 | 'beep boop', 76 | 'blake2b-160', 77 | '94e40214fe303247293e54e0a7ea48f9408ca68b36b08442' 78 | ], [ 79 | 'beep boop', 80 | 'blake2s-256', 81 | 'e0e402204542eaca484e4311def8af74b546edd7fceb49eeb3cdcfd8a4a72ed0dc81d4c0' 82 | ], [ 83 | 'beep boop', 84 | 'dbl-sha2-256', 85 | '56209cd9115d76945c2455b1450295b05f4edeba2e7286bc24c23e266b48faf578c0' 86 | ]] 87 | -------------------------------------------------------------------------------- /test/index.spec.js: -------------------------------------------------------------------------------- 1 | /* eslint-env mocha */ 2 | 'use strict' 3 | 4 | const { expect } = require('aegir/utils/chai') 5 | const sinon = require('sinon') 6 | const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') 7 | const { toString: uint8ArrayToString } = require('uint8arrays/to-string') 8 | 9 | const multihashing = require('../src') 10 | const fixtures = require('./fixtures/encodes') 11 | /** 12 | * @typedef {import('multihashes').HashName} HashName 13 | */ 14 | 15 | describe('multihashing', () => { 16 | for (const fixture of fixtures) { 17 | const raw = fixture[0] 18 | const func = fixture[1] 19 | const encoded = fixture[2] 20 | 21 | it(`encodes in ${func}`, async function () { 22 | const digest = await multihashing(uint8ArrayFromString(raw), func) 23 | expect(digest).to.be.an.instanceOf(Uint8Array) 24 | expect(uint8ArrayToString(digest, 'base16')).to.eql(encoded) 25 | }) 26 | } 27 | 28 | it('cuts the length', async () => { 29 | const buf = uint8ArrayFromString('beep boop') 30 | 31 | const digest = await multihashing(buf, 'sha2-256', 10) 32 | expect(digest) 33 | .to.eql(uint8ArrayFromString('120a90ea688e275d58056732', 'base16')) 34 | }) 35 | 36 | it('digest only, without length', async () => { 37 | const buf = uint8ArrayFromString('beep boop') 38 | const digest = await multihashing.digest(buf, 'sha2-256') 39 | expect(digest).to.be.an.instanceOf(Uint8Array) 40 | expect( 41 | digest 42 | ).to.eql( 43 | uint8ArrayFromString('90ea688e275d580567325032492b597bc77221c62493e76330b85ddda191ef7c', 'base16') 44 | ) 45 | }) 46 | }) 47 | 48 | describe('validate', () => { 49 | it('true on pass', async () => { 50 | const hash = await multihashing(uint8ArrayFromString('test'), 'sha2-256') 51 | const validation = await multihashing.validate(uint8ArrayFromString('test'), hash) 52 | 53 | return expect(validation).to.eql(true) 54 | }) 55 | 56 | it('false on fail', async () => { 57 | const hash = await multihashing(uint8ArrayFromString('test'), 'sha2-256') 58 | const validation = await multihashing.validate(uint8ArrayFromString('test-fail'), hash) 59 | return expect(validation).to.eql(false) 60 | }) 61 | }) 62 | 63 | describe('error handling', () => { 64 | const methods = { 65 | multihashing: multihashing, 66 | digest: multihashing.digest, 67 | /** 68 | * @param {Uint8Array} buff 69 | * @param {HashName} alg 70 | */ 71 | createHash: (buff, alg) => multihashing.createHash(alg) 72 | } 73 | 74 | for (const [name, fn] of Object.entries(methods)) { 75 | describe(name, () => { 76 | it('throws an error when there is no hashing algorithm specified', async () => { 77 | const buf = uint8ArrayFromString('beep boop') 78 | 79 | try { 80 | // @ts-expect-error - alg argument is expected 81 | await fn(buf) 82 | } catch (err) { 83 | expect(err).to.exist() 84 | expect(err.code).to.eql('ERR_HASH_ALGORITHM_NOT_SPECIFIED') 85 | return 86 | } 87 | expect.fail('Did not throw') 88 | }) 89 | 90 | it('throws an error when the hashing algorithm is not supported', async () => { 91 | const buf = uint8ArrayFromString('beep boop') 92 | 93 | // @ts-ignore - sinon is inferring that snake-oil isn't a valid alg 94 | const stub = sinon.stub(require('multihashes'), 'coerceCode').returns('snake-oil') 95 | try { 96 | // @ts-expect-error - non valid algorithm 97 | await fn(buf, 'snake-oil') 98 | } catch (err) { 99 | expect(err).to.exist() 100 | expect(err.code).to.eql('ERR_HASH_ALGORITHM_NOT_SUPPORTED') 101 | return 102 | } finally { 103 | stub.restore() 104 | } 105 | expect.fail('Did not throw') 106 | }) 107 | }) 108 | } 109 | }) 110 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/aegir/src/config/tsconfig.aegir.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": [ 7 | "test", 8 | "src" 9 | ] 10 | } 11 | --------------------------------------------------------------------------------