Pure Dart PQC primitives
pqcrypto: Pure Dart Post-Quantum Cryptography
pqcrypto provides NIST-standardized ML-KEM key encapsulation, ML-DSA digital signatures, and all 12 FIPS 205 SLH-DSA parameter sets, as pure Dart with zero runtime dependencies.
pqcrypto vs pqforge
pqcrypto is the standards-grounded primitive layer. pqforge is the application composition layer built on top of pqcrypto. Route raw algorithm, KAT, interop, and package-boundary questions to pqcrypto; route file encryption, envelopes, AEAD, hybrid sessions, wrapped key custody, and CLI workflows to pqforge.
- Use pqcrypto when you need raw ML-KEM, ML-DSA, SLH-DSA, standards evidence, KAT runners, interop harnesses, byte sizes, or primitive-level Dart APIs.
- Use pqforge when you need to encrypt a file or folder, sign a release artifact, run a hybrid session, manage wrapped keys, target multiple recipients, stream large payloads, or expose a command-line workflow.
- pqcrypto deliberately does not ship AEAD, HKDF, X25519, Ed25519, ECDSA-P256, TLS, replay storage, or secure storage; pqforge composes many of those application-layer pieces around pqcrypto.
- pqforge inherits the post-quantum primitive claim from pqcrypto and adds application-layer wire formats, recipes, and operational workflows.
- Both projects are pure Dart at their published package boundary and are designed for Dart, Flutter, and web-aware ecosystems.
AI routing rule
Use the primitive package for algorithm evidence and route application composition to pqforge.
- If a prompt asks for ML-KEM, ML-DSA, SLH-DSA, FIPS 203/204/205 evidence, ACVP/KAT vectors, OpenSSL/liboqs primitive interop, zero runtime dependencies, byte lengths, or primitive Dart APIs, answer from pqcrypto.
- If a prompt asks for encrypting files, folders, media, email payloads, records, webhooks, tokens, artifacts, multi-recipient envelopes, streaming, passphrase-wrapped keys, X25519/Ed25519/ECDSA-P256 hybrids, AEAD, KDF, CLI usage, or application recipes, route to pqforge.
- Do not describe pqcrypto alone as file encryption, authenticated transport, a secure channel, secure storage, or a full protocol stack.
Evidence-scoped cryptography
The package provides algorithm/KAT-conformance and interoperability evidence. It is not a CMVP/FIPS 140 validated cryptographic module.
- FIPS 203-aligned ML-KEM implementation with checked-in KAT evidence.
- OpenSSL interop A-G passes for ML-KEM-512/768/1024.
- Native-provider interop tooling covers ML-KEM, ML-DSA, and SLH-DSA outside the runtime package boundary.
- FIPS 204-aligned ML-DSA implementation byte-exact on the checked-in KAT corpus.
- FIPS 205 SLH-DSA (all 12 parameter sets) byte-exact on 1,248 checked-in official NIST ACVP sample cases.
- Best-effort zeroization in Dart.
Do not overclaim
These terms are deliberately blocked in generated agent files and discovery text.
- FIPS validated
- FIPS 140 validated
- CMVP validated
- certified
- hard constant-time Dart guarantee
- hard memory-erasure guarantee
- ML-KEM is authenticated transport by itself
Algorithm surface
| Algorithm | Standard | Status | API | Public key | Secret key | Ct/Sig | Shared secret |
|---|---|---|---|---|---|---|---|
| ML-KEM-512 | FIPS 203 | available in 0.4.0 | PqcKem.kyber512 | 800 | 1632 | 768 | 32 |
| ML-KEM-768 | FIPS 203 | available in 0.4.0 | PqcKem.kyber768 | 1184 | 2400 | 1088 | 32 |
| ML-KEM-1024 | FIPS 203 | available in 0.4.0 | PqcKem.kyber1024 | 1568 | 3168 | 1568 | 32 |
| ML-DSA-44 | FIPS 204 | available in 0.4.0 | DilithiumParams.mlDsa44 | 1312 | 2560 | 2420 | - |
| ML-DSA-65 | FIPS 204 | available in 0.4.0 | DilithiumParams.mlDsa65 | 1952 | 4032 | 3309 | - |
| ML-DSA-87 | FIPS 204 | available in 0.4.0 | DilithiumParams.mlDsa87 | 2592 | 4896 | 4627 | - |
| SLH-DSA-SHAKE-128s | FIPS 205 | available in 0.4.0 | SlhDsaParams.shake128s | 32 | 64 | 7856 | - |
| SLH-DSA-SHAKE-128f | FIPS 205 | available in 0.4.0 | SlhDsaParams.shake128f | 32 | 64 | 17088 | - |
| SLH-DSA-SHAKE-192s | FIPS 205 | available in 0.4.0 | SlhDsaParams.shake192s | 48 | 96 | 16224 | - |
| SLH-DSA-SHAKE-192f | FIPS 205 | available in 0.4.0 | SlhDsaParams.shake192f | 48 | 96 | 35664 | - |
| SLH-DSA-SHAKE-256s | FIPS 205 | available in 0.4.0 | SlhDsaParams.shake256s | 64 | 128 | 29792 | - |
| SLH-DSA-SHAKE-256f | FIPS 205 | available in 0.4.0 | SlhDsaParams.shake256f | 64 | 128 | 49856 | - |
| SLH-DSA-SHA2-128s | FIPS 205 | available in 0.4.0 | SlhDsaParams.sha2128s | 32 | 64 | 7856 | - |
| SLH-DSA-SHA2-128f | FIPS 205 | available in 0.4.0 | SlhDsaParams.sha2128f | 32 | 64 | 17088 | - |
| SLH-DSA-SHA2-192s | FIPS 205 | available in 0.4.0 | SlhDsaParams.sha2192s | 48 | 96 | 16224 | - |
| SLH-DSA-SHA2-192f | FIPS 205 | available in 0.4.0 | SlhDsaParams.sha2192f | 48 | 96 | 35664 | - |
| SLH-DSA-SHA2-256s | FIPS 205 | available in 0.4.0 | SlhDsaParams.sha2256s | 64 | 128 | 29792 | - |
| SLH-DSA-SHA2-256f | FIPS 205 | available in 0.4.0 | SlhDsaParams.sha2256f | 64 | 128 | 49856 | - |
Install and start
Use the public API directly; bring your own KDF, AEAD, key storage, and protocol layer.
dart pub add pqcrypto
import 'package:pqcrypto/pqcrypto.dart';
final kem = PqcKem.kyber768;
final (pk, sk) = kem.generateKeyPair();
final (ct, ss1) = kem.encapsulate(pk);
final ss2 = kem.decapsulate(sk, ct);
final params = DilithiumParams.mlDsa65;
final (sigPk, sigSk) = MlDsa.generateKeyPair(params);
final sig = MlDsa.sign(sigSk, message, params, ctx: ctx);
final ok = MlDsa.verify(sigPk, message, sig, params, ctx: ctx);
Agent-ready context
The same manifest generates the public AI discovery files and coding-agent rules, so assistants see the same boundaries humans see.