{"id":13622518,"url":"https://github.com/paulmillr/noble-hashes","last_synced_at":"2025-05-13T20:22:27.737Z","repository":{"id":39032198,"uuid":"414330605","full_name":"paulmillr/noble-hashes","owner":"paulmillr","description":"Audited \u0026 minimal JS implementation of hash functions, MACs and KDFs.","archived":false,"fork":false,"pushed_at":"2025-04-24T15:13:32.000Z","size":15776,"stargazers_count":663,"open_issues_count":1,"forks_count":51,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-04-28T12:00:06.231Z","etag":null,"topics":["argon2","blake2","blake3","crypto","cryptography","hash","hashing","hkdf","hmac","kangarootwelve","kdf","keccak","pbkdf2","ripemd160","scrypt","sha1","sha256","sha3","sha512"],"latest_commit_sha":null,"homepage":"https://paulmillr.com/noble","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paulmillr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/funding.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":"audit/2022-01-05-cure53-audit-nbl2.pdf","citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"paulmillr"}},"created_at":"2021-10-06T18:39:37.000Z","updated_at":"2025-04-25T22:28:21.000Z","dependencies_parsed_at":"2023-12-23T18:45:21.773Z","dependency_job_id":"f60093e8-79ce-4224-b016-c1ddedc6040e","html_url":"https://github.com/paulmillr/noble-hashes","commit_stats":{"total_commits":257,"total_committers":6,"mean_commits":"42.833333333333336","dds":"0.054474708171206254","last_synced_commit":"5ee1bce1fe4d66c92f00c6a4c7623d6f8deed573"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-hashes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-hashes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-hashes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-hashes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paulmillr","download_url":"https://codeload.github.com/paulmillr/noble-hashes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251311332,"owners_count":21569008,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argon2","blake2","blake3","crypto","cryptography","hash","hashing","hkdf","hmac","kangarootwelve","kdf","keccak","pbkdf2","ripemd160","scrypt","sha1","sha256","sha3","sha512"],"created_at":"2024-08-01T21:01:20.465Z","updated_at":"2025-05-13T20:22:27.730Z","avatar_url":"https://github.com/paulmillr.png","language":"JavaScript","funding_links":["https://github.com/sponsors/paulmillr"],"categories":["JavaScript","TypeScript","Frameworks and Libs"],"sub_categories":["JavaScript"],"readme":"# noble-hashes\n\nAudited \u0026 minimal JS implementation of hash functions, MACs and KDFs.\n\n- 🔒 [**Audited**](#security) by an independent security firm\n- 🔻 Tree-shakeable: unused code is excluded from your builds\n- 🏎 Fast: hand-optimized for caveats of JS engines\n- 🔍 Reliable: chained / sliding window / DoS tests and fuzzing ensure correctness\n- 🔁 No unrolled loops: makes it easier to verify and reduces source code size up to 5x\n- 🦘 Includes SHA, RIPEMD, BLAKE, HMAC, HKDF, PBKDF, Scrypt, Argon2 \u0026 KangarooTwelve\n- 🪶 20KB (gzipped) for everything, 2.4KB for single-hash build\n\nTake a glance at [GitHub Discussions](https://github.com/paulmillr/noble-hashes/discussions) for questions and support.\nThe library's initial development was funded by [Ethereum Foundation](https://ethereum.org/).\n\n### This library belongs to _noble_ cryptography\n\n\u003e **noble cryptography** — high-security, easily auditable set of contained cryptographic libraries and tools.\n\n- Zero or minimal dependencies\n- Highly readable TypeScript / JS code\n- PGP-signed releases and transparent NPM builds\n- All libraries:\n  [ciphers](https://github.com/paulmillr/noble-ciphers),\n  [curves](https://github.com/paulmillr/noble-curves),\n  [hashes](https://github.com/paulmillr/noble-hashes),\n  [post-quantum](https://github.com/paulmillr/noble-post-quantum),\n  4kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) /\n  [ed25519](https://github.com/paulmillr/noble-ed25519)\n- [Check out homepage](https://paulmillr.com/noble/)\n  for reading resources, documentation and apps built with noble\n\n## Usage\n\n\u003e `npm install @noble/hashes`\n\n\u003e `deno add jsr:@noble/hashes`\n\n\u003e `deno doc jsr:@noble/hashes` # command-line documentation\n\nWe support all major platforms and runtimes.\nFor React Native, you may need a [polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values).\nA standalone file [noble-hashes.js](https://github.com/paulmillr/noble-hashes/releases) is also available.\n\n```js\n// import * from '@noble/hashes'; // Error: use sub-imports, to ensure small app size\nimport { sha256 } from '@noble/hashes/sha2.js'; // ESM \u0026 Common.js\nsha256(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // returns Uint8Array\n\n// Available modules\nimport { sha256, sha384, sha512, sha224, sha512_224, sha512_256 } from '@noble/hashes/sha2.js';\nimport {\n  sha3_256, sha3_512,\n  keccak_256, keccak_512,\n  shake128, shake256,\n} from '@noble/hashes/sha3.js';\nimport {\n  cshake256, turboshake256, kmac256, tuplehash256,\n  k12, m14, keccakprg,\n} from '@noble/hashes/sha3-addons.js';\nimport { blake3 } from '@noble/hashes/blake3.js';\nimport { blake2b, blake2s } from '@noble/hashes/blake2.js';\nimport { blake256, blake512 } from '@noble/hashes/blake1.js';\nimport { sha1, md5, ripemd160 } from '@noble/hashes/legacy.js';\nimport { hmac } from '@noble/hashes/hmac.js';\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js';\nimport { scrypt, scryptAsync } from '@noble/hashes/scrypt.js';\nimport { argon2d, argon2i, argon2id } from '@noble/hashes/argon2.js';\nimport * as utils from '@noble/hashes/utils'; // bytesToHex, bytesToUtf8, concatBytes...\n```\n\n- [sha2: sha256, sha384, sha512](#sha2-sha256-sha384-sha512-and-others)\n- [sha3: FIPS, SHAKE, Keccak](#sha3-fips-shake-keccak)\n- [sha3-addons: cSHAKE, KMAC, K12, M14, TurboSHAKE](#sha3-addons-cshake-kmac-k12-m14-turboshake)\n- [blake1, blake2, blake3](#blake1-blake2-blake3)\n- [legacy: sha1, md5, ripemd160](#legacy-sha1-md5-ripemd160)\n- MACs: [hmac](#hmac) | [kmac](#sha3-addons-cshake-kmac-k12-m14-turboshake) | [blake3 key mode](#blake1-blake2-blake3)\n- KDFs: [hkdf](#hkdf) | [pbkdf2](#pbkdf2) | [scrypt](#scrypt) | [argon2](#argon2)\n- [utils](#utils)\n- [Security](#security) | [Speed](#speed) | [Contributing \u0026 testing](#contributing--testing) | [License](#license)\n\n### Implementations\n\nHash functions:\n\n- `sha256()`: receive \u0026 return `Uint8Array`\n- `sha256.create().update(a).update(b).digest()`: support partial updates\n- `blake3.create({ context: 'e', dkLen: 32 })`: can have options\n- support little-endian architecture; also experimentally big-endian\n- can hash up to 4GB per chunk, with any amount of chunks\n\n#### sha2: sha256, sha384, sha512 and others\n\n```typescript\nimport { sha224, sha256, sha384, sha512, sha512_224, sha512_256 } from '@noble/hashes/sha2.js';\nconst res = sha256(Uint8Array.from([0xbc])); // basic\nfor (let hash of [sha256, sha384, sha512, sha224, sha512_224, sha512_256]) {\n  const arr = Uint8Array.from([0x10, 0x20, 0x30]);\n  const a = hash(arr);\n  const b = hash.create().update(arr).digest();\n}\n```\n\nSee [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and\n[the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf).\n\n#### sha3: FIPS, SHAKE, Keccak\n\n```typescript\nimport {\n  sha3_224, sha3_256, sha3_384, sha3_512,\n  keccak_224, keccak_256, keccak_384, keccak_512,\n  shake128, shake256,\n} from '@noble/hashes/sha3.js';\nfor (let hash of [\n  sha3_224, sha3_256, sha3_384, sha3_512,\n  keccak_224, keccak_256, keccak_384, keccak_512,\n]) {\n  const arr = Uint8Array.from([0x10, 0x20, 0x30]);\n  const a = hash(arr);\n  const b = hash.create().update(arr).digest();\n}\nconst shka = shake128(Uint8Array.from([0x10]), { dkLen: 512 });\nconst shkb = shake256(Uint8Array.from([0x30]), { dkLen: 512 });\n```\n\nSee [FIPS-202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf),\n[Website](https://keccak.team/keccak.html).\n\nCheck 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)\n\n#### sha3-addons: cSHAKE, KMAC, K12, M14, TurboSHAKE\n\n```typescript\nimport {\n  cshake128, cshake256, k12, m14,\n  keccakprg, kmac128, kmac256,\n  parallelhash256, tuplehash256,\n  turboshake128, turboshake256,\n} from '@noble/hashes/sha3-addons.js';\nconst data = Uint8Array.from([0x10, 0x20, 0x30]);\nconst ec1 = cshake128(data, { personalization: 'def' });\nconst ec2 = cshake256(data, { personalization: 'def' });\nconst et1 = turboshake128(data);\nconst et2 = turboshake256(data, { D: 0x05 });\n// tuplehash(['ab', 'c']) !== tuplehash(['a', 'bc']) !== tuplehash([data])\nconst et3 = tuplehash256([utf8ToBytes('ab'), utf8ToBytes('c')]);\n// Not parallel in JS (similar to blake3 / k12), added for compat\nconst ep1 = parallelhash256(data, { blockLen: 8 });\nconst kk = Uint8Array.from([0xca]);\nconst ek10 = kmac128(kk, data);\nconst ek11 = kmac256(kk, data);\nconst ek12 = k12(data);\nconst ek13 = m14(data);\n// pseudo-random generator, first argument is capacity. XKCP recommends 254 bits capacity for 128-bit security strength.\n// * with a capacity of 254 bits.\nconst p = keccakprg(254);\np.feed('test');\nconst rand1b = p.fetch(1);\n```\n\n- Full [NIST SP 800-185](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf):\n  cSHAKE, KMAC, TupleHash, ParallelHash + XOF variants\n- [Reduced-round Keccak](https://datatracker.ietf.org/doc/draft-irtf-cfrg-kangarootwelve/):\n  - 🦘 K12 aka KangarooTwelve\n  - M14 aka MarsupilamiFourteen\n  - TurboSHAKE\n- [KeccakPRG](https://keccak.team/files/CSF-0.1.pdf): Pseudo-random generator based on Keccak\n\n#### blake1, blake2, blake3\n\n```typescript\nimport { blake224, blake256, blake384, blake512 } from '@noble/hashes/blake1.js';\nimport { blake2b, blake2s } from '@noble/hashes/blake2.js';\nimport { blake3 } from '@noble/hashes/blake3.js';\n\nfor (let hash of [blake224, blake256, blake384, blake512, blake2b, blake2s, blake3]) {\n  const arr = Uint8Array.from([0x10, 0x20, 0x30]);\n  const a = hash(arr);\n  const b = hash.create().update(arr).digest();\n}\n\n// blake2 advanced usage\nconst ab = Uint8Array.from([0x01]);\nblake2s(ab);\nblake2s(ab, { key: new Uint8Array(32) });\nblake2s(ab, { personalization: 'pers1234' });\nblake2s(ab, { salt: 'salt1234' });\nblake2b(ab);\nblake2b(ab, { key: new Uint8Array(64) });\nblake2b(ab, { personalization: 'pers1234pers1234' });\nblake2b(ab, { salt: 'salt1234salt1234' });\n\n// blake3 advanced usage\nblake3(ab);\nblake3(ab, { dkLen: 256 });\nblake3(ab, { key: new Uint8Array(32) });\nblake3(ab, { context: 'application-name' });\n```\n\n- Blake1 is legacy hash, one of SHA3 proposals. It is rarely used anywhere. See [pdf](https://www.aumasson.jp/blake/blake.pdf).\n- Blake2 is popular fast hash. blake2b focuses on 64-bit platforms while blake2s is for 8-bit to 32-bit ones. See [RFC 7693](https://datatracker.ietf.org/doc/html/rfc7693), [Website](https://www.blake2.net)\n- Blake3 is faster, reduced-round blake2. See [Website \u0026 specs](https://blake3.io)\n\n#### legacy: sha1, md5, ripemd160\n\nSHA1 (RFC 3174), MD5 (RFC 1321) and RIPEMD160 (RFC 2286) legacy, weak hash functions.\nDon't use them in a new protocol. What \"weak\" means:\n\n- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160.\n- No practical pre-image attacks (only theoretical, 2^123.4)\n- HMAC seems kinda ok: https://datatracker.ietf.org/doc/html/rfc6151\n\n```typescript\nimport { md5, ripemd160, sha1 } from '@noble/hashes/legacy.js';\nfor (let hash of [md5, ripemd160, sha1]) {\n  const arr = Uint8Array.from([0x10, 0x20, 0x30]);\n  const a = hash(arr);\n  const b = hash.create().update(arr).digest();\n}\n```\n\n#### hmac\n\n```typescript\nimport { hmac } from '@noble/hashes/hmac.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nconst key = new Uint8Array(32).fill(1);\nconst msg = new Uint8Array(32).fill(2);\nconst mac1 = hmac(sha256, key, msg);\nconst mac2 = hmac.create(sha256, key).update(msg).digest();\n```\n\nMatches [RFC 2104](https://datatracker.ietf.org/doc/html/rfc2104).\n\n#### hkdf\n\n```typescript\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { randomBytes } from '@noble/hashes/utils.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nconst inputKey = randomBytes(32);\nconst salt = randomBytes(32);\nconst info = 'application-key';\nconst hk1 = hkdf(sha256, inputKey, salt, info, 32);\n\n// == same as\nimport { extract, expand } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nconst prk = extract(sha256, inputKey, salt);\nconst hk2 = expand(sha256, prk, info, 32);\n```\n\nMatches [RFC 5869](https://datatracker.ietf.org/doc/html/rfc5869).\n\n#### pbkdf2\n\n```typescript\nimport { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nconst pbkey1 = pbkdf2(sha256, 'password', 'salt', { c: 32, dkLen: 32 });\nconst pbkey2 = await pbkdf2Async(sha256, 'password', 'salt', { c: 32, dkLen: 32 });\nconst pbkey3 = await pbkdf2Async(sha256, Uint8Array.from([1, 2, 3]), Uint8Array.from([4, 5, 6]), {\n  c: 32,\n  dkLen: 32,\n});\n```\n\nMatches [RFC 2898](https://datatracker.ietf.org/doc/html/rfc2898).\n\n#### scrypt\n\n```typescript\nimport { scrypt, scryptAsync } from '@noble/hashes/scrypt.js';\nconst scr1 = scrypt('password', 'salt', { N: 2 ** 16, r: 8, p: 1, dkLen: 32 });\nconst scr2 = await scryptAsync('password', 'salt', { N: 2 ** 16, r: 8, p: 1, dkLen: 32 });\nconst scr3 = await scryptAsync(Uint8Array.from([1, 2, 3]), Uint8Array.from([4, 5, 6]), {\n  N: 2 ** 17,\n  r: 8,\n  p: 1,\n  dkLen: 32,\n  onProgress(percentage) {\n    console.log('progress', percentage);\n  },\n  maxmem: 2 ** 32 + 128 * 8 * 1, // N * r * p * 128 + (128*r*p)\n});\n```\n\nConforms to [RFC 7914](https://datatracker.ietf.org/doc/html/rfc7914),\n[Website](https://www.tarsnap.com/scrypt.html)\n\n- `N, r, p` are work factors. It is common to only adjust N, while keeping `r: 8, p: 1`.\n  See [the blog post](https://blog.filippo.io/the-scrypt-parameters/).\n  JS doesn't support parallelization, making increasing `p` meaningless.\n- `dkLen` is the length of output bytes e.g. `32` or `64`\n- `onProgress` can be used with async version of the function to report progress to a user.\n- `maxmem` prevents DoS and is limited to `1GB + 1KB` (`2**30 + 2**10`), but can be adjusted using formula: `N * r * p * 128 + (128 * r * p)`\n\nTime it takes to derive Scrypt key under different values of N (2\\*\\*N) on Apple M4 (mobile phones can be 1x-4x slower):\n\n| N pow | Time | RAM   |\n| ----- | ---- | ----- |\n| 16    | 0.1s | 64MB  |\n| 17    | 0.2s | 128MB |\n| 18    | 0.4s | 256MB |\n| 19    | 0.8s | 512MB |\n| 20    | 1.5s | 1GB   |\n| 21    | 3.1s | 2GB   |\n| 22    | 6.2s | 4GB   |\n| 23    | 13s  | 8GB   |\n| 24    | 27s  | 16GB  |\n\n\u003e [!NOTE]\n\u003e We support N larger than `2**20` where available, however,\n\u003e not all JS engines support \u003e= 2GB ArrayBuffer-s.\n\u003e When using such N, you'll need to manually adjust `maxmem`, using formula above.\n\u003e Other JS implementations don't support large N-s.\n\n#### argon2\n\n```ts\nimport { argon2d, argon2i, argon2id } from '@noble/hashes/argon2.js';\nconst arg1 = argon2id('password', 'saltsalt', { t: 2, m: 65536, p: 1, maxmem: 2 ** 32 - 1 });\n```\n\nArgon2 [RFC 9106](https://datatracker.ietf.org/doc/html/rfc9106) implementation.\n\n\u003e [!WARNING]\n\u003e Argon2 can't be fast in JS, because there is no fast Uint64Array.\n\u003e It is suggested to use [Scrypt](#scrypt) instead.\n\u003e Being 5x slower than native code means brute-forcing attackers have bigger advantage.\n\n#### utils\n\n```typescript\nimport { bytesToHex as toHex, randomBytes } from '@noble/hashes/utils';\nconsole.log(toHex(randomBytes(32)));\n```\n\n- `bytesToHex` will convert `Uint8Array` to a hex string\n- `randomBytes(bytes)` will produce cryptographically secure random `Uint8Array` of length `bytes`\n\n## Security\n\nThe library has been independently audited:\n\n- at version 1.0.0, in Jan 2022, by [Cure53](https://cure53.de)\n  - PDFs: [website](https://cure53.de/pentest-report_hashing-libs.pdf), [in-repo](./audit/2022-01-05-cure53-audit-nbl2.pdf)\n  - [Changes since audit](https://github.com/paulmillr/noble-hashes/compare/1.0.0..main).\n  - Scope: everything, besides `blake3`, `sha3-addons`, `sha1` and `argon2`, which have not been audited\n  - The audit has been funded by [Ethereum Foundation](https://ethereum.org/en/) with help of [Nomic Labs](https://nomiclabs.io)\n\nIt is tested against property-based, cross-library and Wycheproof vectors,\nand is being fuzzed in [the separate repo](https://github.com/paulmillr/fuzzing).\n\nIf you see anything unusual: investigate and report.\n\n### Constant-timeness\n\nWe're targetting algorithmic constant time. _JIT-compiler_ and _Garbage Collector_ make \"constant time\"\nextremely hard to achieve [timing attack](https://en.wikipedia.org/wiki/Timing_attack) resistance\nin a scripting language. Which means _any other JS library can't have\nconstant-timeness_. Even statically typed Rust, a language without GC,\n[makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security)\nfor some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones.\nUse low-level libraries \u0026 languages.\n\n### Memory dumping\n\nThe library shares state buffers between hash\nfunction calls. The buffers are zeroed-out after each call. However, if an attacker\ncan read application memory, you are doomed in any case:\n\n- At some point, input will be a string and strings are immutable in JS:\n  there is no way to overwrite them with zeros. For example: deriving\n  key from `scrypt(password, salt)` where password and salt are strings\n- Input from a file will stay in file buffers\n- Input / output will be re-used multiple times in application which means it could stay in memory\n- `await anything()` will always write all internal variables (including numbers)\n  to memory. With async functions / Promises there are no guarantees when the code\n  chunk would be executed. Which means attacker can have plenty of time to read data from memory\n- There is no way to guarantee anything about zeroing sensitive data without\n  complex tests-suite which will dump process memory and verify that there is\n  no sensitive data left. For JS it means testing all browsers (incl. mobile),\n  which is complex. And of course it will be useless without using the same\n  test-suite in the actual application that consumes the library\n\n### Supply chain security\n\n- **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures\n- **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs\n  - Use GitHub CLI to verify single-file builds:\n    `gh attestation verify --owner paulmillr noble-hashes.js`\n- **Rare releasing** is followed to ensure less re-audit need for end-users\n- **Dependencies** are minimized and locked-down: any dependency could get hacked and users will be downloading malware with every install.\n  - We make sure to use as few dependencies as possible\n  - Automatic dep updates are prevented by locking-down version ranges; diffs are checked with `npm-diff`\n- **Dev Dependencies** are disabled for end-users; they are only used to develop / build the source code\n\nFor this package, there are 0 dependencies; and a few dev dependencies:\n\n- micro-bmark, micro-should and jsbt are used for benchmarking / testing / build tooling and developed by the same author\n- prettier, fast-check and typescript are used for code quality / test generation / ts compilation. It's hard to audit their source code thoroughly and fully because of their size\n\n### Randomness\n\nWe're deferring to built-in\n[crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)\nwhich is considered cryptographically secure (CSPRNG).\n\nIn the past, browsers had bugs that made it weak: it may happen again.\nImplementing a userspace CSPRNG to get resilient to the weakness\nis even worse: there is no reliable userspace source of quality entropy.\n\n### Quantum computers\n\nCryptographically relevant quantum computer, if built, will allow to\nutilize Grover's algorithm to break hashes in 2^n/2 operations, instead of 2^n.\n\nThis means SHA256 should be replaced with SHA512, SHA3-256 with SHA3-512, SHAKE128 with SHAKE256 etc.\n\nAustralian ASD prohibits SHA256 and similar hashes [after 2030](https://www.cyber.gov.au/resources-business-and-government/essential-cyber-security/ism/cyber-security-guidelines/guidelines-cryptography).\n\n## Speed\n\n```sh\nnpm run bench:install \u0026\u0026 npm run bench\n```\n\nBenchmarks measured on Apple M4.\n\n```\n# 32B\nsha256 x 1,968,503 ops/sec @ 508ns/op\nsha512 x 740,740 ops/sec @ 1μs/op\nsha3_256 x 287,686 ops/sec @ 3μs/op\nsha3_512 x 288,267 ops/sec @ 3μs/op\nk12 x 476,190 ops/sec @ 2μs/op\nm14 x 423,190 ops/sec @ 2μs/op\nblake2b x 464,252 ops/sec @ 2μs/op\nblake2s x 766,871 ops/sec @ 1μs/op\nblake3 x 879,507 ops/sec @ 1μs/op\n\n# 1MB\nsha256 x 331 ops/sec @ 3ms/op\nsha512 x 129 ops/sec @ 7ms/op\nsha3_256 x 38 ops/sec @ 25ms/op\nsha3_512 x 20 ops/sec @ 47ms/op\nk12 x 88 ops/sec @ 11ms/op\nm14 x 62 ops/sec @ 15ms/op\nblake2b x 69 ops/sec @ 14ms/op\nblake2s x 57 ops/sec @ 17ms/op\nblake3 x 72 ops/sec @ 13ms/op\n\n# MAC\nhmac(sha256) x 599,880 ops/sec @ 1μs/op\nhmac(sha512) x 197,122 ops/sec @ 5μs/op\nkmac256 x 87,981 ops/sec @ 11μs/op\nblake3(key) x 796,812 ops/sec @ 1μs/op\n\n# KDF\nhkdf(sha256) x 259,942 ops/sec @ 3μs/op\nblake3(context) x 424,808 ops/sec @ 2μs/op\npbkdf2(sha256, c: 2 ** 18) x 5 ops/sec @ 197ms/op\npbkdf2(sha512, c: 2 ** 18) x 1 ops/sec @ 630ms/op\nscrypt(n: 2 ** 18, r: 8, p: 1) x 2 ops/sec @ 400ms/op\nargon2id(t: 1, m: 256MB) 2881ms\n```\n\nCompare to native node.js implementation that uses C bindings instead of pure-js code:\n\n```\n# native (node) 32B\nsha256 x 2,267,573 ops/sec\nsha512 x 983,284 ops/sec\nsha3_256 x 1,522,070 ops/sec\nblake2b x 1,512,859 ops/sec\nblake2s x 1,821,493 ops/sec\nhmac(sha256) x 1,085,776 ops/sec\nhkdf(sha256) x 312,109 ops/sec\n# native (node) KDF\npbkdf2(sha256, c: 2 ** 18) x 5 ops/sec @ 197ms/op\npbkdf2(sha512, c: 2 ** 18) x 1 ops/sec @ 630ms/op\nscrypt(n: 2 ** 18, r: 8, p: 1) x 2 ops/sec @ 378ms/op\n```\n\nIt is possible to [make this library 3x+ faster](./benchmark/README.md) by\n_doing code generation of full loop unrolls_. We've decided against it. Reasons:\n\n- current perf is good enough, even compared to other libraries - SHA256 only takes 500 nanoseconds\n- the library must be auditable, with minimum amount of code, and zero dependencies\n- most method invocations with the lib are going to be something like hashing 32b to 64kb of data\n- hashing big inputs is 10x faster with low-level languages, which means you should probably pick 'em instead\n\n## Contributing \u0026 testing\n\n`test/misc` directory contains implementations of loop unrolling and md5.\n\n- `npm install \u0026\u0026 npm run build \u0026\u0026 npm test` will build the code and run tests.\n- `npm run lint` / `npm run format` will run linter / fix linter issues.\n- `npm run bench` will run benchmarks, which may need their deps first (`npm run bench:install`)\n- `npm run build:release` will build single file\n- There is **additional** 20-min DoS test `npm run test:dos` and 2-hour \"big\" multicore test `npm run test:big`.\n  See [our approach to testing](./test/README.md)\n\nNTT hashes are outside of scope of the library. They depend on some math which is not available in noble-hashes, it doesn't make sense to add it here. You can view some of them in different repos:\n\n- [Pedersen in micro-zk-proofs](https://github.com/paulmillr/micro-zk-proofs/blob/1ed5ce1253583b2e540eef7f3477fb52bf5344ff/src/pedersen.ts)\n- [Poseidon in noble-curves](https://github.com/paulmillr/noble-curves/blob/3d124dd3ecec8b6634cc0b2ba1c183aded5304f9/src/abstract/poseidon.ts)\n\nPolynomial MACs are also outside of scope of the library. They are rarely used outside of encryption. Check out [Poly1305 \u0026 GHash in noble-ciphers](https://github.com/paulmillr/noble-ciphers).\n\nAdditional resources:\n\n- Check out [guidelines](https://github.com/paulmillr/guidelines) for coding practices\n- See [paulmillr.com/noble](https://paulmillr.com/noble/) for useful resources, articles, documentation and demos\n  related to the library.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2022 Paul Miller [(https://paulmillr.com)](https://paulmillr.com)\n\nSee LICENSE file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulmillr%2Fnoble-hashes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulmillr%2Fnoble-hashes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulmillr%2Fnoble-hashes/lists"}