{"_id":"@ahparsapour/post-quantum-with-pke","name":"@ahparsapour/post-quantum-with-pke","dist-tags":{"latest":"0.5.1"},"versions":{"0.5.1":{"name":"@ahparsapour/post-quantum-with-pke","version":"0.5.1","description":"Auditable & minimal JS implementation of post-quantum cryptography: FIPS 203, 204, 205","dependencies":{"@noble/curves":"~2.0.0","@noble/hashes":"~2.0.0"},"devDependencies":{"@paulmillr/jsbt":"0.4.4","@types/node":"24.2.1","fast-check":"4.2.0","prettier":"3.6.2","typescript":"5.9.2"},"scripts":{"bench":"node test/benchmark.ts","build":"tsc","build:release":"npx --no @paulmillr/jsbt esbuild test/build","build:clean":"rm *.{js,js.map,d.ts,d.ts.map} 2> /dev/null","format":"prettier --write 'src/**/*.{js,ts}' 'test/**/*.{js,ts,mjs}'","test":"node --experimental-strip-types --no-warnings test/index.ts","test:bun":"bun test/index.ts","test:deno":"deno --allow-env --allow-read test/index.ts","test:node20":"cd test; npx tsc; node compiled/test/index.js","test:big":"SLOW_TESTS=1 node test/index.js"},"exports":{".":"./index.js","./_crystals.js":"./_crystals.js","./hybrid.js":"./hybrid.js","./ml-dsa.js":"./ml-dsa.js","./ml-kem.js":"./ml-kem.js","./slh-dsa.js":"./slh-dsa.js","./utils.js":"./utils.js"},"engines":{"node":">= 20.19.0"},"keywords":["ml-kem","ml-dsa","slh-dsa","kyber","dilithium","sphincs","fips203","fips204","fips205","xwing","kitchensink","pqc","post-quantum","public-key","crypto","noble","cryptography"],"repository":{"type":"git","url":"git+https://github.com/ahparsapour/noble-post-quantum-with-pke.git"},"type":"module","main":"index.js","module":"index.js","types":"index.d.ts","sideEffects":false,"author":{"name":"AmirHossein Parsapour"},"license":"MIT","_id":"@ahparsapour/post-quantum-with-pke@0.5.1","gitHead":"d362f4182cb5015ebebc56847c582e28a2f41345","bugs":{"url":"https://github.com/ahparsapour/noble-post-quantum-with-pke/issues"},"homepage":"https://github.com/ahparsapour/noble-post-quantum-with-pke#readme","_nodeVersion":"22.19.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-RyTKHxA7E7YjkJlP3CB2ur4w0GDZNOwGaEC50rE5gEKo4gll3gV7yCQX8682Sy/5nlwyPKcWS+19M+RvnQAkKQ==","shasum":"7fc70998665b3ee9936fd7b853560475610147d8","tarball":"https://registry.npmjs.org/@ahparsapour/post-quantum-with-pke/-/post-quantum-with-pke-0.5.1.tgz","fileCount":38,"unpackedSize":313353,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEItNA3GWIJ0gbItSKmIWyHko/C0iJ3RMIlp7QJ+YDR3AiAP5qiIKFfvNnHNUALPj7fENV/mlGhNHBHDbOP6bxbpUg=="}]},"_npmUser":{"name":"ahparsapour","email":"ah.parsapour@gmail.com"},"directories":{},"maintainers":[{"name":"ahparsapour","email":"ah.parsapour@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/post-quantum-with-pke_0.5.1_1758024925346_0.43998974206124464"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-16T12:15:25.229Z","0.5.1":"2025-09-16T12:15:25.551Z","modified":"2025-09-16T12:15:25.805Z"},"maintainers":[{"name":"ahparsapour","email":"ah.parsapour@gmail.com"}],"description":"Auditable & minimal JS implementation of post-quantum cryptography: FIPS 203, 204, 205","homepage":"https://github.com/ahparsapour/noble-post-quantum-with-pke#readme","keywords":["ml-kem","ml-dsa","slh-dsa","kyber","dilithium","sphincs","fips203","fips204","fips205","xwing","kitchensink","pqc","post-quantum","public-key","crypto","noble","cryptography"],"repository":{"type":"git","url":"git+https://github.com/ahparsapour/noble-post-quantum-with-pke.git"},"author":{"name":"AmirHossein Parsapour"},"bugs":{"url":"https://github.com/ahparsapour/noble-post-quantum-with-pke/issues"},"license":"MIT","readme":"# noble-post-quantum\n\nAuditable & 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 & CRYSTALS-Kyber: lattice-based kem from FIPS-203\n- 🔋 ML-DSA & CRYSTALS-Dilithium: lattice-based signatures from FIPS-204\n- 🐈 SLH-DSA & SPHINCS+: hash-based Winternitz signatures from FIPS-205\n- 🍡 Hybrid algorithms, combining classic & post-quantum\n- 🪶 16KB (gzipped) for everything, including bundled noble-hashes & noble-curves\n\nTake a glance at [GitHub Discussions](https://github.com/paulmillr/noble-post-quantum/discussions) for questions and support.\n\n> [!IMPORTANT]\n> NIST published [IR 8547](https://nvlpubs.nist.gov/nistpubs/ir/2024/NIST.IR.8547.ipd.pdf),\n> prohibiting classical cryptography (RSA, DSA, ECDSA, ECDH) after 2035.\n> 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> Take it into an account while designing a new cryptographic system.\n\n### This library belongs to _noble_ cryptography\n\n> **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  5kb [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> `npm install @noble/post-quantum`\n\n> `deno add jsr:@noble/post-quantum`\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.js';\nimport { ml_dsa44, ml_dsa65, ml_dsa87 } from '@noble/post-quantum/ml-dsa.js';\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.js';\nimport {\n  XWing,\n  KitchenSinkMLKEM768X25519,\n  QSFMLKEM768P256, QSFMLKEM1024P384\n} from '@noble/post-quantum/hybrids.js';\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- [Hybrids: XWing, KitchenSink and others](#hybrids-xwing-kitchensink-and-others)\n- [What should I use?](#what-should-i-use)\n- [Security](#security)\n- [Speed](#speed)\n- [Contributing & 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.js';\nimport { randomBytes } from '@noble/post-quantum/utils.js';\nconst seed = randomBytes(64); // seed is optional\nconst aliceKeys = ml_kem768.keygen(seed);\nconst { cipherText, sharedSecret: bobShared } = ml_kem768.encapsulate(aliceKeys.publicKey);\nconst aliceShared = ml_kem768.decapsulate(cipherText, aliceKeys.secretKey);\n\n// Warning: Can be MITM-ed\nconst malloryKeys = ml_kem768.keygen();\nconst malloryShared = ml_kem768.decapsulate(cipherText, malloryKeys.secretKey); // No error!\nnotDeepStrictEqual(aliceShared, malloryShared); // Different key!\n```\n\nLattice-based key encapsulation mechanism, defined in [FIPS-203](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf).\nCan be used as follows:\n\n1. *Alice* generates secret & public keys, then sends publicKey to *Bob*\n2. *Bob* generates shared secret for Alice publicKey.\n  bobShared never leaves *Bob* system and is unknown to other parties\n3. *Alice* gets and decrypts cipherText from Bob\n  Now, both Alice and Bob have same sharedSecret key\n  without exchanging in plainText: aliceShared == bobShared.\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> [!WARNING]\n> Unlike ECDH, KEM doesn't verify whether it was \"Bob\" who've sent the ciphertext.\n> Instead of throwing an error when the ciphertext is encrypted by a different pubkey,\n> `decapsulate` will simply return a different shared secret.\n> 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.js';\nimport { randomBytes } from '@noble/post-quantum/utils.js';\nconst seed = randomBytes(32); // seed is optional\nconst keys = ml_dsa65.keygen(seed);\nconst msg = new TextEncoder().encode('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.js';\n\nconst keys2 = sph.keygen();\nconst msg2 = new TextEncoder().encode('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 & speed.\n\n### Hybrids: XWing, KitchenSink and others\n\n```js\nimport {\n  XWing,\n  KitchenSinkMLKEM768X25519,\n  QSFMLKEM768P256, QSFMLKEM1024P384\n} from '@noble/post-quantum/hybrids.js';\n```\n\nXWing is x25519+mlkem768, just like kitchensink.\n\nThe following spec drafts are matched:\n\n- [irtf-cfrg-hybrid-kems](https://datatracker.ietf.org/doc/draft-irtf-cfrg-hybrid-kems/)\n- [connolly-cfrg-xwing-kem](https://datatracker.ietf.org/doc/draft-connolly-cfrg-xwing-kem/)\n- [tls-westerbaan-xyber768d00](https://datatracker.ietf.org/doc/draft-tls-westerbaan-xyber768d00/)\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.\n  Check out [attested checksums of single-file builds](https://github.com/paulmillr/noble-post-quantum/attestations)\n  and [provenance logs](https://github.com/paulmillr/noble-post-quantum/actions/workflows/release.yml)\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 (**higher is better**):\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 & testing\n\n- `npm install && npm run build && 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\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","readmeFilename":"README.md","_rev":"1-7b5a712c92f7d3f5e196dcfa538921ed"}