Expand description
§pqrascv-core
A no_std + alloc Rust library for issuing post-quantum attestation quotes on embedded
devices, IoT firmware, cloud orchestrators, and AI agents.
Every quote is signed with ML-DSA-65 (FIPS 204) and carries a SLSA v1 / in-toto provenance predicate — binding the device’s firmware identity to its build pipeline in a single compact CBOR message, on bare-metal Cortex-M4, RISC-V, WASM, or Linux.
§Why PQ-RASCV?
Traditional attestation tells you what is running. It doesn’t tell you how the firmware was built, who signed it off, or whether the build pipeline was compromised. Classical signatures (RSA, ECDSA) also won’t survive a cryptographically-relevant quantum computer.
PQ-RASCV fixes both in one library:
- Post-quantum by default — ML-DSA-65 signatures, no RSA or ECDSA anywhere.
- Supply-chain provenance — SLSA v1 predicate + SBOM hash inside every signed quote.
- One API everywhere — Cortex-M4, RISC-V, WASM, Linux, all using the same code.
§How it works
The verifier sends a random nonce; the prover measures its firmware, attaches provenance, signs everything, and sends back a CBOR quote:
Verifier ───── Challenge { nonce: [u8; 32] } ─────► Prover
◄────── AttestationQuote (CBOR + ML-DSA-65 signature) ───────§Feature flags
| Feature | Default | What it does |
|---|---|---|
std | yes | Enables std::error::Error on the error type |
alloc | yes | Required for building quotes and provenance predicates |
hardware-tpm | no | Reads PCR values from a real TPM 2.0 chip (Linux only) |
dice | no | DICE CDI derivation backend — pure Rust, no OS required |
§Quick start
use pqrascv_core::{
crypto::{generate_ml_dsa_keypair, MlDsaBackend},
measurement::SoftwareRoT,
provenance::SlsaPredicateBuilder,
quote::{generate_quote, QuoteTimestamp},
};
// Keep the signing seed secret — store it in a hardware keystore on real devices.
let (sk, vk) = generate_ml_dsa_keypair().unwrap();
// SoftwareRoT is for testing only. Use TpmRoT or DiceRoT in production.
let rot = SoftwareRoT::new(b"my-firmware", None, 1);
let provenance = SlsaPredicateBuilder::new("https://ci.example.com/pipeline/42")
.add_subject("firmware.bin", &[0xabu8; 32])
.with_slsa_level(2)
.build()
.unwrap();
let nonce = [0x42u8; 32]; // received from the verifier's Challenge
let quote = generate_quote(
&rot,
&MlDsaBackend,
sk.as_bytes(),
&vk,
&nonce,
provenance,
QuoteTimestamp::Rtc(1_700_000_000),
)
.unwrap();
let cbor_bytes = quote.to_cbor().unwrap(); // send this to the verifierSend cbor_bytes to a verifier. See pqrascv-verifier
for the verification side.
§Modules
measurement— theRoTtrait and backends (Software SHA3-256, TPM 2.0, DICE)provenance— builds SLSA v1 predicates and in-toto attestationscrypto— ML-DSA-65 sign and verify, all constant-time viaRustCryptoquote— assembles and serializes anAttestationQuote;generate_quoteis the main entry pointconfig— policy settings: minimum SLSA level, max quote age, firmware hash requirementserror— the singlePqRascvErrortype used throughout the cratebackends— optional hardware backends gated behind feature flags
§Security notes
- Keep the seed secret. Store it in a TPM NV slot, eFuse, or
TrustZonekeystore — not in flash. - Use a fresh nonce every time. Reusing a nonce breaks replay protection.
- Use a post-quantum transport. ML-DSA-65 protects the signature, but classical TLS is still vulnerable to “harvest now, decrypt later” attacks. Pair with a PQ transport when you can.
- See the repository README for the full security considerations.
§Contributing
Issues, PRs, and feedback are welcome at https://github.com/comwanga/pqrascv-core. Areas where contributions are especially valuable:
- New platform backends — SEV-SNP, TDX, OP-TEE, Apple Secure Enclave
- Allocation-free quote assembly — removing the
allocrequirement entirely - Post-quantum transport — Noise_PQX or COSE/CBOR signing integration
- Formal verification — Kani harnesses and fuzzing coverage
Licensed under either MIT or Apache-2.0 at your option.
Re-exports§
pub use config::PolicyConfig;pub use error::PqRascvError;pub use quote::QuoteTimestamp;pub use quote::generate_quote;allocpub use quote::AttestationQuote;allocpub use quote::Challenge;allocpub use nonce::ClockEvidence;allocpub use nonce::InMemoryNonceLedger;allocpub use nonce::NonceHandle;allocpub use nonce::NonceLedger;allocpub use policy::HardwareBackendKind;allocpub use policy::PolicyEngineV2;allocpub use policy::PolicyRule;allocpub use pki::validate_chain;allocpub use pki::CertChain;allocpub use pki::DeviceCertificate;allocpub use pki::TrustAnchor;alloc
Modules§
- backends
- Optional hardware-specific Root-of-Trust backends.
- config
- Policy configuration for the PQ-RASCV attestation engine.
- crypto
- Post-quantum cryptography abstraction layer.
- error
- Error types for pqrascv-core.
- measurement
- Measurement layer — hardware-agnostic Root-of-Trust abstraction.
- nonce
- Replay-resistant nonce management and explicit clock evidence. Fixes audit findings #3 and #6. Replay-resistant nonce management.
- pki
- Device PKI — certificate chain, trust anchor, and revocation. Fixes audit finding #4 (missing PKI). Device PKI — certificate chain, trust anchor, and revocation.
- policy
- Composable policy engine v2. Fixes audit findings #1, #2, #4, #10. Policy engine v2 — typed, composable attestation policy rules.
- provenance
- Provenance layer — in-toto attestations and SLSA v1 predicates.
- provenance_
v2 - External CI-signed provenance bundles (Sigstore). Fixes audit finding #2 (self-asserted SLSA provenance). External provenance bundles — CI-signed, independently verifiable.
- quote
- Quote assembly —
AttestationQuoteand thegenerate_quoteentry point.