@pqc-sdk/core
v0.11.4
Published
Post-quantum cryptography SDK for JS/TS: X-Wing hybrid KEM by default, plus ML-KEM-768 and ML-DSA-65 (FIPS 203/204)
Maintainers
Readme
@pqc-sdk/core
Post-quantum cryptography for JS/TS with safe defaults and zero configuration. X-Wing (X25519 + ML-KEM-768) + AES-256-GCM for hybrid encryption by default, with pure ML-KEM-512/768/1024 (FIPS 203) available by opt-in; ML-DSA-44/65/87 (FIPS 204) for signatures. Tested against the official NIST ACVP known-answer vectors. Not FIPS 140-3 / CMVP validated — conformance is a published self-assessment.
npm install @pqc-sdk/coreimport { pqc } from '@pqc-sdk/core';
const pair = await pqc.keys.generate();
const ciphertext = await pqc.encrypt('secret', pair.publicKey);
const plaintext = await pqc.decrypt(ciphertext, pair.secretKey);
const signer = await pqc.keys.generate({ algorithm: 'ml-dsa-65' });
const signature = await pqc.sign('document', signer.secretKey);
const valid = await pqc.verify('document', signature, signer.publicKey);
console.log(new TextDecoder().decode(plaintext), valid); // "secret" trueCompatibility
| Runtime | Support | Notes |
| ------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Node 20+ | ✅ | ESM and CJS |
| Cloudflare Workers | ✅ | No nodejs_compat; 43 KiB gzip total worker upload, measured 2026-09-03 |
| Deno 2+ | ✅ | npm:@pqc-sdk/core |
| Bun | ⏳ not yet run | Expected to work (it targets Node compatibility), but no roundtrip has been executed there, so it is not claimed |
| React Native | ✅ | Requires react-native-get-random-values. Streaming additionally needs a Symbol.asyncIterator alias; the Web Streams adapters do not work on Hermes — use encryptStream/decryptStream |
| Browsers | ⏳ not yet run | Expected to work on any ES2022 target with WebCrypto, but no browser roundtrip has been executed, so it is not claimed |
No WASM or native addons: pure TypeScript on top of @noble/post-quantum.
Benchmarks
GitHub Actions ubuntu-latest (x86_64, Node 20), vitest bench means, July 2026:
| Operation | Time | Throughput | | ----------------- | ---------- | ---------- | | keygen ML-KEM-768 | 0.9 ms/op | 1175 ops/s | | encrypt (1 KiB) | 1.0 ms/op | 973 ops/s | | decrypt (1 KiB) | 1.3 ms/op | 743 ops/s | | encrypt (100 KiB) | 3.5 ms/op | 285 ops/s | | decrypt (100 KiB) | 3.7 ms/op | 269 ops/s | | keygen ML-DSA-65 | 2.9 ms/op | 345 ops/s | | sign (1 KiB) | 16.5 ms/op | 60 ops/s | | verify (1 KiB) | 3.2 ms/op | 310 ops/s |
CI re-runs these on every PR and fails on regressions above 2.5x the
committed baseline (bench/baseline.json in the repo — see
bench/README.md for how the baseline is refreshed).
Documentation
Full documentation at jeloercc.github.io/pqc-sdk.
Security
- We never implement primitives from scratch: ML-KEM/ML-DSA are
@noble/post-quantum0.7.1 vendored into this package with documented FIPS 203/204 corrections, and AES-GCM is@noble/ciphersas published. The risk that is ours to carry is those corrections plus the layer around the primitives — envelope format, key serialization, nonce derivation, fail-closed parsing — and How this is verified lists the suite covering each: NIST ACVP vectors, golden serialization vectors, parser fuzzing,fast-checkproperty tests and the streaming mutation matrix. - Partial memory zeroization only: the vendored ML-KEM/ML-DSA code wipes its internal intermediates, but the shared secret, decrypted plaintext and secret-key bytes you hold are not wiped — JavaScript offers no reliable primitive for it. Details in SECURITY.md.
@noble/post-quantumhas no independent audit yet (self-audit 04/2026). As with all JS, there are no strict constant-time guarantees. The reviews indocs/are internal and AI-assisted — not an independent third-party audit.- Security reports: see SECURITY.md — please do not open public issues.
Supply chain
- Releases are published only from GitHub Actions, by the
release.ymlworkflow injeloercc/pqc-sdk. - Starting with
0.11.2, that workflow publishes through npm trusted publishing (OIDC): each run gets a short-lived credential, and no long-lived npm token is used. Earlier versions were published by the same workflow with an npm token. - Every published version carries an npm provenance attestation that links it to the source commit and the workflow run that built it.
- To check the packages in your project, run
npm audit signatures.
