npm package diff
Package: @noble/hashes
Versions: 1.3.2 - 1.3.3
File: package/README.md
Index: package/README.md
===================================================================
--- package/README.md
+++ package/README.md
@@ -1,83 +1,77 @@
# noble-hashes
-Audited & minimal JS implementation of SHA2, SHA3, RIPEMD, BLAKE2/3, HMAC, HKDF, PBKDF2 & Scrypt.
+Audited & minimal JS implementation of SHA, RIPEMD, BLAKE, HMAC, HKDF, PBKDF, Scrypt & Argon2.
- ð [**Audited**](#security) by an independent security firm
- ðŧ Tree-shaking-friendly: use only what's necessary, other code won't be included
- ð Ultra-fast, hand-optimized for caveats of JS engines
- ð Unique tests ensure correctness: chained tests, sliding window tests, DoS tests, fuzzing
- ð No unrolled loops: makes it easier to verify and reduces source code size up to 5x
- ðĒ Scrypt supports `N: 2**22`, while other implementations are limited to `2**20`
-- ðĶ SHA3 supports Keccak, TupleHash, KangarooTwelve and MarsupilamiFourteen
+- ðĶ SHA3 supports Keccak, cSHAKE, KangarooTwelve, MarsupilamiFourteen and TurboSHAKE
- ðŠķ Just 3.4k lines / 17KB gzipped. SHA256-only is 240 lines / 3KB gzipped
The library's initial development was funded by [Ethereum Foundation](https://ethereum.org/).
### This library belongs to _noble_ crypto
> **noble-crypto** â high-security, easily auditable set of contained cryptographic libraries and tools.
-- No dependencies, protection against supply chain attacks
-- Auditable TypeScript / JS code
-- Supported on all major platforms
-- Releases are signed with PGP keys and built transparently with NPM provenance
-- Check out [homepage](https://paulmillr.com/noble/) & all libraries:
+- Zero or minimal dependencies
+- Highly readable TypeScript / JS code
+- PGP-signed releases and transparent NPM builds
+- All libraries:
[ciphers](https://github.com/paulmillr/noble-ciphers),
[curves](https://github.com/paulmillr/noble-curves),
- [hashes](https://github.com/paulmillr/noble-hashes),
- 4kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) /
- [ed25519](https://github.com/paulmillr/noble-ed25519)
+ [hashes](https://github.com/paulmillr/noble-hashes)
+- [Check out homepage](https://paulmillr.com/noble/)
+ for reading resources, documentation and apps built with noble
## Usage
> npm install @noble/hashes
We support all major platforms and runtimes.
For [Deno](https://deno.land), ensure to use [npm specifier](https://deno.land/[email protected]/node/npm_specifiers).
For React Native, you may need a [polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values).
-If you don't like NPM, a standalone [noble-hashes.js](https://github.com/paulmillr/noble-hashes/releases) is also available.
+A standalone file [noble-hashes.js](https://github.com/paulmillr/noble-hashes/releases) is also available.
```js
// import * from '@noble/hashes'; // Error: use sub-imports, to ensure small app size
import { sha256 } from '@noble/hashes/sha256'; // ECMAScript modules (ESM) and Common.js
// import { sha256 } from 'npm:@noble/[email protected]/sha256'; // Deno
console.log(sha256(new Uint8Array([1, 2, 3]))); // Uint8Array(32) [3, 144, 88, 198, 242...]
// you could also pass strings that will be UTF8-encoded to Uint8Array
console.log(sha256('abc')); // == sha256(new TextEncoder().encode('abc'))
-
-// sha384 is here, because it uses same internals as sha512
-import { sha512, sha512_256, sha384 } from '@noble/hashes/sha512';
-// prettier-ignore
-import {
- sha3_224, sha3_256, sha3_384, sha3_512,
- keccak_224, keccak_256, keccak_384, keccak_512,
- shake128, shake256
-} from '@noble/hashes/sha3';
-// prettier-ignore
-import {
- cshake128, cshake256, kmac128, kmac256,
- k12, m14,
- tuplehash256, parallelhash256, keccakprg
-} from '@noble/hashes/sha3-addons';
-import { ripemd160 } from '@noble/hashes/ripemd160';
-import { blake3 } from '@noble/hashes/blake3';
-import { blake2b } from '@noble/hashes/blake2b';
-import { blake2s } from '@noble/hashes/blake2s';
-import { hmac } from '@noble/hashes/hmac';
-import { hkdf } from '@noble/hashes/hkdf';
-import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2';
-import { scrypt, scryptAsync } from '@noble/hashes/scrypt';
-
-import { sha1 } from '@noble/hashes/sha1'; // legacy
-
-// small utility method that converts bytes to hex
-import { bytesToHex as toHex } from '@noble/hashes/utils';
-console.log(toHex(sha256('abc'))); // ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
```
-## API
+- [Implementations](#implementations)
+ - [sha2: sha256, sha384, sha512, sha512_256](#sha2-sha256-sha384-sha512-sha512_256)
+ - [sha3: FIPS, SHAKE, Keccak](#sha3-fips-shake-keccak)
+ - [sha3-addons: cSHAKE, KMAC, K12, M14, TurboSHAKE](#sha3-addons-cshake-kmac-k12-m14-turboshake)
+ - [ripemd160](#ripemd160)
+ - [blake2b, blake2s, blake3](#blake2b-blake2s-blake3)
+ - [sha1: legacy hash](#sha1-legacy-hash)
+ - [hmac](#hmac)
+ - [hkdf](#hkdf)
+ - [pbkdf2](#pbkdf2)
+ - [scrypt](#scrypt)
+ - [argon2](#argon2)
+ - [utils](#utils)
+ - [All available imports](#all-available-imports)
+- [Security](#security)
+ - [Constant-timeness](#constant-timeness)
+ - [Memory dumping](#memory-dumping)
+ - [Supply chain security](#supply-chain-security)
+ - [Randomness](#randomness)
+- [Speed](#speed)
+- [Contributing & testing](#contributing--testing)
+- [Resources](#resources)
+- [License](#license)
+### Implementations
+
All hash functions:
- can be called directly, with `Uint8Array`.
- return `Uint8Array`
@@ -107,26 +101,10 @@
- second argument to hash function: `blake3('abc', { key: 'd', dkLen: 32 })`
- first argument to class initializer: `blake3.create({ context: 'e', dkLen: 32 })`
-## Modules
+##### sha2: sha256, sha384, sha512, sha512_256
-- [SHA2 (sha256, sha384, sha512, sha512_256)](#sha2-sha256-sha384-sha512-sha512_256)
-- [SHA3 (FIPS, SHAKE, Keccak)](#sha3-fips-shake-keccak)
-- [SHA3 Addons (cSHAKE, KMAC, KangarooTwelve, MarsupilamiFourteen)](#sha3-addons-cshake-kmac-tuplehash-parallelhash-kangarootwelve-marsupilamifourteen)
-- [RIPEMD-160](#ripemd-160)
-- [BLAKE2b, BLAKE2s](#blake2b-blake2s)
-- [BLAKE3](#blake3)
-- [SHA1 (legacy)](#sha1-legacy)
-- [HMAC](#hmac)
-- [HKDF](#hkdf)
-- [PBKDF2](#pbkdf2)
-- [Scrypt](#scrypt)
-- [ESKDF](#eskdf)
-- [utils](#utils)
-
-##### SHA2 (sha256, sha384, sha512, sha512_256)
-
```typescript
import { sha256 } from '@noble/hashes/sha256';
const h1a = sha256('abc');
const h1b = sha256
@@ -162,9 +140,9 @@
See [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
[the paper on SHA512/256](https://eprint.iacr.org/2010/548.pdf).
-##### SHA3 (FIPS, SHAKE, Keccak)
+##### sha3: FIPS, SHAKE, Keccak
```typescript
import {
sha3_224,
@@ -192,9 +170,9 @@
[Website](https://keccak.team/keccak.html).
Check out [the differences between SHA-3 and Keccak](https://crypto.stackexchange.com/questions/15727/what-are-the-key-differences-between-the-draft-sha-3-standard-and-the-keccak-sub)
-##### SHA3 Addons (cSHAKE, KMAC, TupleHash, ParallelHash, KangarooTwelve, MarsupilamiFourteen)
+##### sha3-addons: cSHAKE, KMAC, K12, M14, TurboSHAKE
```typescript
import {
cshake128,
@@ -202,8 +180,10 @@
kmac128,
kmac256,
k12,
m14,
+ turboshake128,
+ turboshake256,
tuplehash128,
tuplehash256,
parallelhash128,
parallelhash256,
@@ -214,8 +194,10 @@
const h7e = kmac128('key', 'message');
const h7f = kmac256('key', 'message');
const h7h = k12('abc');
const h7g = m14('abc');
+const h7t1 = turboshake128('abc');
+const h7t2 = turboshake256('def', { D: 0x05 });
const h7i = tuplehash128(['ab', 'c']); // tuplehash(['ab', 'c']) !== tuplehash(['a', 'bc']) !== tuplehash(['abc'])
// Same as k12/blake3, but without reduced number of rounds. Doesn't speedup anything due lack of SIMD and threading,
// added for compatibility.
const h7j = parallelhash128('abc', { blockLen: 8 });
@@ -227,30 +209,30 @@
```
- Full [NIST SP 800-185](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf):
cSHAKE, KMAC, TupleHash, ParallelHash + XOF variants
-- ðĶ K12 ([KangarooTwelve Paper](https://keccak.team/files/KangarooTwelve.pdf),
- [RFC Draft](https://www.ietf.org/archive/id/draft-irtf-cfrg-kangarootwelve-06.txt))
- and M14 aka MarsupilamiFourteen are basically parallel versions of Keccak with
- reduced number of rounds (same as Blake3 and ParallelHash).
+- [Reduced-round Keccak](https://datatracker.ietf.org/doc/draft-irtf-cfrg-kangarootwelve/):
+ - ðĶ K12 aka KangarooTwelve
+ - M14 aka MarsupilamiFourteen
+ - TurboSHAKE
- [KeccakPRG](https://keccak.team/files/CSF-0.1.pdf): Pseudo-random generator based on Keccak
-##### RIPEMD-160
+##### ripemd160
```typescript
import { ripemd160 } from '@noble/hashes/ripemd160';
// function ripemd160(data: Uint8Array): Uint8Array;
const hash8 = ripemd160('abc');
-const hash9 = ripemd160()
+const hash9 = ripemd160
.create()
.update(Uint8Array.from([1, 2, 3]))
.digest();
```
See [RFC 2286](https://datatracker.ietf.org/doc/html/rfc2286),
[Website](https://homes.esat.kuleuven.be/~bosselae/ripemd160.html)
-##### BLAKE2b, BLAKE2s
+##### blake2b, blake2s, blake3
```typescript
import { blake2b } from '@noble/hashes/blake2b';
import { blake2s } from '@noble/hashes/blake2s';
@@ -260,22 +242,18 @@
const h10c = blake2s
.create(b2params)
.update(Uint8Array.from([1, 2, 3]))
.digest();
-```
-See [RFC 7693](https://datatracker.ietf.org/doc/html/rfc7693), [Website](https://www.blake2.net).
-
-##### BLAKE3
-
-```typescript
import { blake3 } from '@noble/hashes/blake3';
// All params are optional
const h11 = blake3('abc', { dkLen: 256, key: 'def', context: 'fji' });
```
-##### SHA1 (legacy)
+See [RFC 7693](https://datatracker.ietf.org/doc/html/rfc7693), [Website](https://www.blake2.net).
+##### sha1: legacy hash
+
SHA1 was cryptographically broken, however, it was not broken for cases like HMAC.
See [RFC4226 B.2](https://datatracker.ietf.org/doc/html/rfc4226#appendix-B.2).
@@ -285,20 +263,23 @@
import { sha1 } from '@noble/hashes/sha1';
const h12 = sha1('def');
```
-##### HMAC
+##### hmac
```typescript
import { hmac } from '@noble/hashes/hmac';
import { sha256 } from '@noble/hashes/sha256';
const mac1 = hmac(sha256, 'key', 'message');
-const mac2 = hmac.create(sha256, Uint8Array.from([1, 2, 3])).update(Uint8Array.from([4, 5, 6])).digest();
+const mac2 = hmac
+ .create(sha256, Uint8Array.from([1, 2, 3]))
+ .update(Uint8Array.from([4, 5, 6]))
+ .digest();
```
Matches [RFC 2104](https://datatracker.ietf.org/doc/html/rfc2104).
-##### HKDF
+##### hkdf
```typescript
import { hkdf } from '@noble/hashes/hkdf';
import { sha256 } from '@noble/hashes/sha256';
@@ -317,9 +298,9 @@
```
Matches [RFC 5869](https://datatracker.ietf.org/doc/html/rfc5869).
-##### PBKDF2
+##### pbkdf2
```typescript
import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2';
import { sha256 } from '@noble/hashes/sha256';
@@ -332,9 +313,9 @@
```
Matches [RFC 2898](https://datatracker.ietf.org/doc/html/rfc2898).
-##### Scrypt
+##### scrypt
```typescript
import { scrypt, scryptAsync } from '@noble/hashes/scrypt';
const scr1 = scrypt('password', 'salt', { N: 2 ** 16, r: 8, p: 1, dkLen: 32 });
@@ -369,47 +350,17 @@
libs. Many other implementations don't support it. We cannot support `2**23`,
because there is a limitation in JS engines that makes allocating
arrays bigger than 4GB impossible, but we're looking into other possible solutions.
-##### Argon2
+##### argon2
Experimental Argon2 RFC 9106 implementation. It may be removed at any time.
```ts
import { argon2d, argon2i, argon2id } from '@noble/hashes/argon2';
const result = argon2id('password', 'salt', { t: 2, m: 65536, p: 1 });
```
-##### ESKDF
-
-A tiny stretched KDF for various applications like AES key-gen. Takes >= 2 seconds to execute.
-
-Takes following params:
-
-- `username` - username, email, or identifier, min: 8 characters, should have enough entropy
-- `password` - min: 8 characters, should have enough entropy
-
-Produces ESKDF instance that has `deriveChildKey(protocol, accountId[, options])` function.
-
-- `protocol` - 3-15 character protocol name
-- `accountId` - numeric identifier of account
-- `options` - `keyLength: 32` with specified key length (default is 32),
- or `modulus: 2n ** 221n - 17n` with specified modulus. It will fetch modulus + 64 bits of
- data, execute modular division. The result will have negligible bias as per FIPS 186 B.4.1.
- Can be used to generate, for example, elliptic curve keys.
-
-Takes username and password, then takes protocol name and account id.
-
-```typescript
-import { eskdf } from '@noble/hashes/eskdf';
-const kdf = await eskdf('example@university', 'beginning-new-example');
-console.log(kdf.fingerprint);
-const key1 = kdf.deriveChildKey('aes', 0);
-const key2 = kdf.deriveChildKey('aes', 0, { keyLength: 16 });
-const ecc1 = kdf.deriveChildKey('ecc', 0, { modulus: 2n ** 252n - 27742317777372353535851937790883648493n })
-kdf.expire();
-```
-
##### utils
```typescript
import { bytesToHex as toHex, randomBytes } from '@noble/hashes/utils';
@@ -418,51 +369,111 @@
- `bytesToHex` will convert `Uint8Array` to a hex string
- `randomBytes(bytes)` will produce cryptographically secure random `Uint8Array` of length `bytes`
+##### All available imports
+
+```js
+// sha384 is here, because it uses same internals as sha512
+import { sha512, sha512_256, sha384 } from '@noble/hashes/sha512';
+// prettier-ignore
+import {
+ sha3_224, sha3_256, sha3_384, sha3_512,
+ keccak_224, keccak_256, keccak_384, keccak_512,
+ shake128, shake256
+} from '@noble/hashes/sha3';
+// prettier-ignore
+import {
+ cshake128, cshake256,
+ k12, m14,
+ turboshake128, turboshake256,
+ kmac128, kmac256,
+ tuplehash256, parallelhash256, keccakprg
+} from '@noble/hashes/sha3-addons';
+import { ripemd160 } from '@noble/hashes/ripemd160';
+import { blake3 } from '@noble/hashes/blake3';
+import { blake2b } from '@noble/hashes/blake2b';
+import { blake2s } from '@noble/hashes/blake2s';
+import { hmac } from '@noble/hashes/hmac';
+import { hkdf } from '@noble/hashes/hkdf';
+import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2';
+import { scrypt, scryptAsync } from '@noble/hashes/scrypt';
+
+import { sha1 } from '@noble/hashes/sha1'; // legacy
+
+// small utility method that converts bytes to hex
+import { bytesToHex as toHex } from '@noble/hashes/utils';
+console.log(toHex(sha256('abc'))); // ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
+```
+
## Security
-Noble is production-ready.
+The library has been independently audited:
-1. The library has been audited in Jan 2022 by an independent security firm
- cure53: [PDF](https://cure53.de/pentest-report_hashing-libs.pdf).
- No vulnerabilities have been found. The audit has been funded by
- [Ethereum Foundation](https://ethereum.org/en/) with help of [Nomic Labs](https://nomiclabs.io).
- Modules `blake3`, `sha3-addons`, `sha1` and `argon2` have not been audited.
- See [changes since audit](https://github.com/paulmillr/noble-hashes/compare/1.0.0..main).
-2. The library has been fuzzed by [Guido Vranken's cryptofuzz](https://github.com/guidovranken/cryptofuzz).
- You can run the fuzzer by yourself to check it.
-3. [Timing attack](https://en.wikipedia.org/wiki/Timing_attack) considerations:
- _JIT-compiler_ and _Garbage Collector_ make "constant time" extremely hard to
- achieve in a scripting language. Which means _any other JS library can't have constant-timeness_.
- Even statically typed Rust, a language without GC,
- [makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security)
- for some cases. If your goal is absolute security, don't use any JS lib â including
- bindings to native ones. Use low-level libraries & languages. Nonetheless we're
- targetting algorithmic constant time.
-4. Memory dump considerations: the library shares state buffers between hash
- function calls. The buffers are zeroed-out after each call. However, if an attacker
- can read application memory, you are doomed in any case:
- - At some point, input will be a string and strings are immutable in JS:
- there is no way to overwrite them with zeros. For example: deriving
- key from `scrypt(password, salt)` where password and salt are strings
- - Input from a file will stay in file buffers
- - Input / output will be re-used multiple times in application which means
- it could stay in memory
- - `await anything()` will always write all internal variables (including numbers)
- to memory. With async functions / Promises there are no guarantees when the code
- chunk would be executed. Which means attacker can have plenty of time to read data from memory
- - There is no way to guarantee anything about zeroing sensitive data without
- complex tests-suite which will dump process memory and verify that there is
- no sensitive data left. For JS it means testing all browsers (incl. mobile),
- which is complex. And of course it will be useless without using the same
- test-suite in the actual application that consumes the library
+- at version 1.0.0, in Jan 2022, by [cure53](https://cure53.de)
+ - PDFs: [online](https://cure53.de/pentest-report_hashing-libs.pdf), [offline, in-repo](./audit/2022-01-05-cure53-audit-nbl2.pdf)
+ - [Changes since audit](https://github.com/paulmillr/noble-hashes/compare/1.0.0..main).
+ - Scope: everything, besides `blake3`, `sha3-addons`, `sha1` and `argon2`, which have not been audited
+ - The audit has been funded by [Ethereum Foundation](https://ethereum.org/en/) with help of [Nomic Labs](https://nomiclabs.io)
-We consider infrastructure attacks like rogue NPM modules very important; that's
-why it's crucial to minimize the amount of 3rd-party dependencies & native bindings.
-If your app uses 500 dependencies, any dep could get hacked and you'll be downloading
-malware with every `npm install`. Our goal is to minimize this attack vector.
+It is tested against property-based, cross-library and Wycheproof vectors,
+and has fuzzing by [Guido Vranken's cryptofuzz](https://github.com/guidovranken/cryptofuzz).
+If you see anything unusual: investigate and report.
+
+### Constant-timeness
+
+_JIT-compiler_ and _Garbage Collector_ make "constant time" extremely hard to
+achieve [timing attack](https://en.wikipedia.org/wiki/Timing_attack) resistance
+in a scripting language. Which means _any other JS library can't have
+constant-timeness_. Even statically typed Rust, a language without GC,
+[makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security)
+for some cases. If your goal is absolute security, don't use any JS lib â including bindings to native ones.
+Use low-level libraries & languages. Nonetheless we're targetting algorithmic constant time.
+
+### Memory dumping
+
+The library shares state buffers between hash
+function calls. The buffers are zeroed-out after each call. However, if an attacker
+can read application memory, you are doomed in any case:
+
+- At some point, input will be a string and strings are immutable in JS:
+ there is no way to overwrite them with zeros. For example: deriving
+ key from `scrypt(password, salt)` where password and salt are strings
+- Input from a file will stay in file buffers
+- Input / output will be re-used multiple times in application which means it could stay in memory
+- `await anything()` will always write all internal variables (including numbers)
+ to memory. With async functions / Promises there are no guarantees when the code
+ chunk would be executed. Which means attacker can have plenty of time to read data from memory
+- There is no way to guarantee anything about zeroing sensitive data without
+ complex tests-suite which will dump process memory and verify that there is
+ no sensitive data left. For JS it means testing all browsers (incl. mobile),
+ which is complex. And of course it will be useless without using the same
+ test-suite in the actual application that consumes the library
+
+### Supply chain security
+
+* **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures.
+* **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs
+* **Rare releasing** is followed to ensure less re-audit need for end-users
+* **Dependencies** are minimized and locked-down:
+ - If your app has 500 dependencies, any dep could get hacked and you'll be downloading
+ malware with every install. We make sure to use as few dependencies as possible
+ - We prevent automatic dependency updates by locking-down version ranges. Every update is checked with `npm-diff`
+* **Dev Dependencies** are only used if you want to contribute to the repo. They are disabled for end-users:
+ - scure-base, scure-bip32, scure-bip39, micro-bmark and micro-should are developed by the same author and follow identical security practices
+ - prettier (linter), fast-check (property-based testing) and typescript are used for code quality, vector generation and ts compilation. The packages are big, which makes it hard to audit their source code thoroughly and fully
+
+### Randomness
+
+We're deferring to built-in
+[crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)
+which is considered cryptographically secure (CSPRNG).
+
+In the past, browsers had bugs that made it weak: it may happen again.
+Implementing a userspace CSPRNG to get resilient to the weakness
+is even worse: there is no reliable userspace source of quality entropy.
+
## Speed
Benchmarks measured on Apple M1 with macOS 12.
Note that PBKDF2 and Scrypt are tested with extremely high work factor.
@@ -524,8 +535,14 @@
5. `npm run test:dos` will test against DoS; by measuring function complexity. **Takes ~20 minutes**
6. `npm run test:big` will execute hashing on 4GB inputs,
scrypt with 1024 different `N, r, p` combinations, etc. **Takes several hours**. Using 8-32+ core CPU helps.
+## Resources
+
+Check out [paulmillr.com/noble](https://paulmillr.com/noble/)
+for useful resources, articles, documentation and demos
+related to the library.
+
## License
The MIT License (MIT)