{"id":13600636,"url":"https://github.com/paulmillr/noble-post-quantum","last_synced_at":"2025-05-16T10:07:47.388Z","repository":{"id":228188115,"uuid":"764428596","full_name":"paulmillr/noble-post-quantum","owner":"paulmillr","description":"Auditable \u0026 minimal JS implementation of public-key post-quantum cryptography","archived":false,"fork":false,"pushed_at":"2025-05-14T09:24:17.000Z","size":15706,"stargazers_count":178,"open_issues_count":6,"forks_count":15,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-05-14T10:41:57.801Z","etag":null,"topics":["dilithium","falcon","fips-203","fips-204","fips-205","fips-206","fips203","fips204","fips205","fips206","kyber","ml-dsa","ml-kem","post-quantum-cryptography","slh-dsa","sphincs","sphincs-plus","winternitz"],"latest_commit_sha":null,"homepage":"https://paulmillr.com/noble","language":"TypeScript","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":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"paulmillr"}},"created_at":"2024-02-28T03:51:14.000Z","updated_at":"2025-05-14T09:24:21.000Z","dependencies_parsed_at":"2024-05-18T22:22:08.084Z","dependency_job_id":"f66514b2-dcfd-4250-852b-fc0034809afa","html_url":"https://github.com/paulmillr/noble-post-quantum","commit_stats":{"total_commits":35,"total_committers":2,"mean_commits":17.5,"dds":0.02857142857142858,"last_synced_commit":"e73b080b467c7dd1889b749b9d7ec52a4ffcff65"},"previous_names":["paulmillr/noble-post-quantum"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-post-quantum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-post-quantum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-post-quantum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulmillr%2Fnoble-post-quantum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paulmillr","download_url":"https://codeload.github.com/paulmillr/noble-post-quantum/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254154955,"owners_count":22023727,"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":["dilithium","falcon","fips-203","fips-204","fips-205","fips-206","fips203","fips204","fips205","fips206","kyber","ml-dsa","ml-kem","post-quantum-cryptography","slh-dsa","sphincs","sphincs-plus","winternitz"],"created_at":"2024-08-01T18:00:45.487Z","updated_at":"2025-05-16T10:07:42.379Z","avatar_url":"https://github.com/paulmillr.png","language":"TypeScript","funding_links":["https://github.com/sponsors/paulmillr"],"categories":["PQC software","Frameworks and Libs"],"sub_categories":["PQC libraries and language-specific software","JavaScript"],"readme":"# noble-post-quantum\n\nAuditable \u0026 minimal JS implementation of post-quantum public-key cryptography.\n\n- 🔒 Auditable\n- 🔻 Tree-shakeable: unused code is excluded from your builds\n- 🔍 Reliable: tests ensure correctness\n- 🦾 ML-KEM \u0026 CRYSTALS-Kyber: lattice-based kem from FIPS-203\n- 🔋 ML-DSA \u0026 CRYSTALS-Dilithium: lattice-based signatures from FIPS-204\n- 🐈 SLH-DSA \u0026 SPHINCS+: hash-based Winternitz signatures from FIPS-205\n- 🪶 37KB (15KB gzipped) for everything with bundled hashes\n\nTake a glance at [GitHub Discussions](https://github.com/paulmillr/noble-post-quantum/discussions) for questions and support.\n\n\u003e [!IMPORTANT]\n\u003e NIST published [IR 8547](https://nvlpubs.nist.gov/nistpubs/ir/2024/NIST.IR.8547.ipd.pdf),\n\u003e prohibiting classical cryptography (RSA, DSA, ECDSA, ECDH) after 2035.\n\u003e Australian ASD does same thing [after 2030](https://www.cyber.gov.au/resources-business-and-government/essential-cyber-security/ism/cyber-security-guidelines/guidelines-cryptography).\n\u003e Take it into an account while designing a new cryptographic system.\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/post-quantum`\n\n\u003e `deno add jsr:@noble/post-quantum`\n\n\u003e `deno doc jsr:@noble/post-quantum` # command-line documentation\n\nWe support all major platforms and runtimes.\nFor React Native, you may need a\n[polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values).\nA standalone file\n[noble-post-quantum.js](https://github.com/paulmillr/noble-post-quantum/releases) is also available.\n\n```js\n// import * from '@noble/post-quantum'; // Error: use sub-imports instead\nimport { ml_kem512, ml_kem768, ml_kem1024 } from '@noble/post-quantum/ml-kem';\nimport { ml_dsa44, ml_dsa65, ml_dsa87 } from '@noble/post-quantum/ml-dsa';\nimport {\n  slh_dsa_sha2_128f,\n  slh_dsa_sha2_128s,\n  slh_dsa_sha2_192f,\n  slh_dsa_sha2_192s,\n  slh_dsa_sha2_256f,\n  slh_dsa_sha2_256s,\n  slh_dsa_shake_128f,\n  slh_dsa_shake_128s,\n  slh_dsa_shake_192f,\n  slh_dsa_shake_192s,\n  slh_dsa_shake_256f,\n  slh_dsa_shake_256s,\n} from '@noble/post-quantum/slh-dsa';\n```\n\n- [ML-KEM / Kyber](#ml-kem--kyber-shared-secrets)\n- [ML-DSA / Dilithium](#ml-dsa--dilithium-signatures)\n- [SLH-DSA / SPHINCS+](#slh-dsa--sphincs-signatures)\n- [What should I use?](#what-should-i-use)\n- [Security](#security)\n- [Speed](#speed)\n- [Contributing \u0026 testing](#contributing--testing)\n- [License](#license)\n\n### ML-KEM / Kyber shared secrets\n\n```ts\nimport { ml_kem512, ml_kem768, ml_kem1024 } from '@noble/post-quantum/ml-kem';\nimport { randomBytes } from '@noble/post-quantum/utils';\n\n// 1. [Alice] generates secret \u0026 public keys, then sends publicKey to Bob\nconst seed = randomBytes(64); // seed is optional\nconst aliceKeys = ml_kem768.keygen(seed);\n\n// 2. [Bob] generates shared secret for Alice publicKey\n// bobShared never leaves [Bob] system and is unknown to other parties\nconst { cipherText, sharedSecret: bobShared } = ml_kem768.encapsulate(aliceKeys.publicKey);\n\n// 3. [Alice] gets and decrypts cipherText from Bob\nconst aliceShared = ml_kem768.decapsulate(cipherText, aliceKeys.secretKey);\n\n// Now, both Alice and Bob have same sharedSecret key\n// without exchanging in plainText: aliceShared == bobShared\n\n// Warning: Can be MITM-ed\nconst carolKeys = kyber1024.keygen();\nconst carolShared = kyber1024.decapsulate(cipherText, carolKeys.secretKey); // No error!\nnotDeepStrictEqual(aliceShared, carolShared); // Different key!\n```\n\nLattice-based key encapsulation mechanism, defined in [FIPS-203](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf).\n\nSee [website](https://www.pq-crystals.org/kyber/resources.shtml) and [repo](https://github.com/pq-crystals/kyber).\nThere are some concerns with regards to security: see\n[djb blog](https://blog.cr.yp.to/20231003-countcorrectly.html) and\n[mailing list](https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/W2VOzy0wz_E).\nOld, incompatible version (Kyber) is not provided. Open an issue if you need it.\n\n\u003e [!WARNING]\n\u003e Unlike ECDH, KEM doesn't verify whether it was \"Bob\" who've sent the ciphertext.\n\u003e Instead of throwing an error when the ciphertext is encrypted by a different pubkey,\n\u003e `decapsulate` will simply return a different shared secret.\n\u003e ML-KEM is also probabilistic and relies on quality of CSPRNG.\n\n### ML-DSA / Dilithium signatures\n\n```ts\nimport { ml_dsa44, ml_dsa65, ml_dsa87 } from '@noble/post-quantum/ml-dsa';\nimport { utf8ToBytes, randomBytes } from '@noble/post-quantum/utils';\nconst seed = randomBytes(32); // seed is optional\nconst keys = ml_dsa65.keygen(seed);\nconst msg = utf8ToBytes('hello noble');\nconst sig = ml_dsa65.sign(keys.secretKey, msg);\nconst isValid = ml_dsa65.verify(keys.publicKey, msg, sig);\n```\n\nLattice-based digital signature algorithm, defined in [FIPS-204](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf). See\n[website](https://www.pq-crystals.org/dilithium/index.shtml) and\n[repo](https://github.com/pq-crystals/dilithium).\nThe internals are similar to ML-KEM, but keys and params are different.\n\n### SLH-DSA / SPHINCS+ signatures\n\n```ts\nimport {\n  slh_dsa_sha2_128f,\n  slh_dsa_sha2_128s,\n  slh_dsa_sha2_192f,\n  slh_dsa_sha2_192s,\n  slh_dsa_sha2_256f,\n  slh_dsa_sha2_256s,\n  slh_dsa_shake_128f,\n  slh_dsa_shake_128s,\n  slh_dsa_shake_192f,\n  slh_dsa_shake_192s,\n  slh_dsa_shake_256f,\n  slh_dsa_shake_256s,\n} from '@noble/post-quantum/slh-dsa';\nimport { utf8ToBytes } from '@noble/post-quantum/utils';\n\nconst keys2 = sph.keygen();\nconst msg2 = utf8ToBytes('hello noble');\nconst sig2 = sph.sign(keys2.secretKey, msg2);\nconst isValid2 = sph.verify(keys2.publicKey, msg2, sig2);\n```\n\nHash-based digital signature algorithm, defined in [FIPS-205](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.205.pdf).\nSee [website](https://sphincs.org) and [repo](https://github.com/sphincs/sphincsplus). We implement spec v3.1 with FIPS adjustments.\n\nThere are many different kinds,\nbut basically `sha2` / `shake` indicate internal hash, `128` / `192` / `256` indicate security level, and `s` /`f` indicate trade-off (Small / Fast).\nSLH-DSA is slow: see [benchmarks](#speed) for key size \u0026 speed.\n\n### What should I use?\n\n|         | Speed  | Key size    | Sig size    | Created in | Popularized in | Post-quantum? |\n| ------- | ------ | ----------- | ----------- | ---------- | -------------- | ------------- |\n| RSA     | Normal | 256B - 2KB  | 256B - 2KB  | 1970s      | 1990s          | No            |\n| ECC     | Normal | 32 - 256B   | 48 - 128B   | 1980s      | 2010s          | No            |\n| ML-KEM  | Fast   | 1.6 - 31KB  | 1KB         | 1990s      | 2020s          | Yes           |\n| ML-DSA  | Normal | 1.3 - 2.5KB | 2.5 - 4.5KB | 1990s      | 2020s          | Yes           |\n| SLH-DSA | Slow   | 32 - 128B   | 17 - 50KB   | 1970s      | 2020s          | Yes           |\n| FN-DSA  | Slow   | 0.9 - 1.8KB | 0.6 - 1.2KB | 1990s      | 2020s          | Yes           |\n\nWe suggest to use ECC + ML-KEM for key agreement, ECC + SLH-DSA for signatures.\n\nML-KEM and ML-DSA are lattice-based. SLH-DSA is hash-based, which means it is built on top of older, more conservative primitives. NIST guidance for security levels:\n\n- Category 3 (~AES-192): ML-KEM-768, ML-DSA-65, SLH-DSA-[SHA2/shake]-192[s/f]\n- Category 5 (~AES-256): ML-KEM-1024, ML-DSA-87, SLH-DSA-[SHA2/shake]-256[s/f]\n\nNIST recommends to use cat-3+, while australian [ASD only allows cat-5 after 2030](https://www.cyber.gov.au/resources-business-and-government/essential-cyber-security/ism/cyber-security-guidelines/guidelines-cryptography).\n\nFor [hashes](https://github.com/paulmillr/noble-hashes), use SHA512 or SHA3-512 (not SHA256); and for [ciphers](https://github.com/paulmillr/noble-ciphers) ensure AES-256 or ChaCha.\n\n## Security\n\nThe library has not been independently audited yet.\n\nIf you see anything unusual: investigate and report.\n\n### Constant-timeness\n\nThere is no protection against side-channel attacks.\nWe actively research how to provide this property for post-quantum algorithms in JS.\nKeep in mind that even hardware versions ML-KEM [are vulnerable](https://eprint.iacr.org/2023/1084).\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-post-quantum.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 is 1 dependency; and a few dev dependencies:\n\n- [noble-hashes](https://github.com/paulmillr/noble-hashes) provides cryptographic hashing functionality\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## Speed\n\nNoble is the fastest JS implementation of post-quantum algorithms.\nWASM libraries can be faster.\nFor SLH-DSA, SHAKE slows everything down 8x, and -s versions do another 20-50x slowdown.\n\nBenchmarks on Apple M4:\n\n| OPs/sec           | Keygen | Signing | Verification | Shared secret |\n| ----------------- | ------ | ------- | ------------ | ------------- |\n| ECC x/ed25519     | 14216  | 6849    | 1400         | 1981          |\n| ML-KEM-768        | 3778   |         |              | 3750          |\n| ML-DSA65          | 580    | 272     | 546          |               |\n| SLH-DSA-SHA2-192f | 245    | 8       | 169          |               |\n\n```\n# ML-KEM768\nkeygen x 3,778 ops/sec @ 264μs/op\nencapsulate x 3,220 ops/sec @ 310μs/op\ndecapsulate x 4,029 ops/sec @ 248μs/op\n# ML-DSA65\nkeygen x 580 ops/sec @ 1ms/op\nsign x 272 ops/sec @ 3ms/op\nverify x 546 ops/sec @ 1ms/op\n# SLH-DSA SHA2 192f\nkeygen x 245 ops/sec @ 4ms/op\nsign x 8 ops/sec @ 114ms/op\nverify x 169 ops/sec @ 5ms/op\n```\n\nSLH-DSA (\\_shake is 8x slower):\n\n|           | sig size | keygen | sign   | verify |\n| --------- | -------- | ------ | ------ | ------ |\n| sha2_128f | 18088    | 4ms    | 90ms   | 6ms    |\n| sha2_128s | 7856     | 260ms  | 2000ms | 2ms    |\n| sha2_192f | 35664    | 6ms    | 160ms  | 9ms    |\n| sha2_192s | 16224    | 380ms  | 3800ms | 3ms    |\n| sha2_256f | 49856    | 15ms   | 340ms  | 9ms    |\n| sha2_256s | 29792    | 250ms  | 3400ms | 4ms    |\n\n## Contributing \u0026 testing\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\nCheck out [github.com/paulmillr/guidelines](https://github.com/paulmillr/guidelines)\nfor general coding practices and rules.\n\nSee [paulmillr.com/noble](https://paulmillr.com/noble/)\nfor useful resources, articles, documentation and demos\nrelated to the library.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2024 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-post-quantum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulmillr%2Fnoble-post-quantum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulmillr%2Fnoble-post-quantum/lists"}