PQC on RISC-V: Hardware-Accelerated Post-Quantum Crypto
Kyber768 (ML-KEM) and Dilithium3 (ML-DSA) accelerated as a custom RISC-V instruction extension, with side-channel-aware microarchitecture.
Phase 4d shipped · source on GitHubWhat this is
A systems-engineering project to design a hardware-accelerated post-quantum cryptography subsystem on a RISC-V soft core. The target primitives are NIST FIPS 203 (ML-KEM, Kyber768) for key encapsulation and NIST FIPS 204 (ML-DSA, Dilithium3) for digital signatures. Design platform is a mid-range Xilinx FPGA (Kria KV260 class).
This page documents the architecture, trade studies, threat model, and verification plan. The implementation is the next phase; the current artifact is the systems-engineering package that scopes it.
System requirements
| ID | Requirement | Source |
|---|---|---|
SR-01 | Implement ML-KEM-768 (Kyber768) key encapsulation per FIPS 203 | NIST FIPS 203 (Aug 2024) |
SR-02 | Implement ML-DSA-65 (Dilithium3) signature scheme per FIPS 204 | NIST FIPS 204 (Aug 2024) |
SR-03 | Constant-time execution for all secret-dependent operations | CNSA 2.0; NIST SP 800-90B |
SR-04 | Hardware-accelerated keygen / encaps / decaps in < 10× soft-core baseline | Project goal |
SR-05 | Acceptable LUT / DSP / BRAM footprint on Kria KV260 (Zynq UltraScale+) | Platform constraint |
SR-06 | Side-channel hygiene: TVLA test suite, target T < 4.5 | ISO/IEC 17825 |
SR-07 | Open-source under permissive license; reproducible from commit + toolchain hash | Project goal |
Architecture
RISC-V soft core (CV32E40P or VexRiscv) with a custom co-processor reachable via the RoCC-style coprocessor interface. Crypto primitives expose a small ISA extension (kem.keygen, kem.encaps, kem.decaps, dsa.sign, dsa.verify). NTT and Keccak are accelerated; Montgomery / Barrett reductions are inlined.
Interfaces
- Core ↔ co-processor: RoCC-style (rd, rs1, rs2, funct7). 1-cycle dispatch, multi-cycle execute, response on completion.
- Co-processor ↔ key buffer: dual-port BRAM, write-protected from core unless explicit unlock.
- TRNG ↔ sampler: 256-bit entropy pool refresh on demand; health-test FSM gates output.
- Host ↔ system: AXI-Lite control / status; AXI-Stream for bulk plaintext / ciphertext.
Trade studies
1. Acceleration partition
| Option | Speedup vs SW | FPGA cost | Side-channel surface | Effort | Verdict |
|---|---|---|---|---|---|
| SW-only on rv32imc | 1× | ~0 | Low (well-studied) | Low | Baseline |
| NTT-only co-processor | ~6–8× | Modest | Modest | Medium | — |
| NTT + Keccak co-proc | ~15–25× | Medium | Bounded | Medium | Selected |
| Full primitive in HW | ~30–50× | High | Larger attack surface | High | Deferred (V2) |
Rationale: the NTT + Keccak split captures > 80% of the cycle budget for Kyber/Dilithium per literature (e.g., Banerjee et al, IEEE TCAD 2019) while keeping the high-level scheme in software where review and patching is cheap.
2. RISC-V core selection
| Core | License | RoCC-style coproc | Constant-time DIV | Verdict |
|---|---|---|---|---|
| CV32E40P (OpenHW) | Solderpad | Native | Yes | Selected |
| VexRiscv | MIT | Plugin model | Configurable | Alternate |
| Ibex (lowRISC) | Apache-2 | No (would need custom) | Yes | Rejected |
| Rocket | BSD | RoCC native | Yes | Considered (too large for Kria) |
3. TRNG topology
| Option | NIST SP 800-90B compliance path | FPGA cost | Verdict |
|---|---|---|---|
| Ring oscillator + von-Neumann debias | Achievable with health tests | Low | Selected (V1) |
| Free-running ring + LFSR whitening | Harder (bias modeling) | Low | — |
| External TRNG IC (e.g., Infineon SLE) | Vendor-attested | BOM cost | V2 option |
Threat model & security analysis
Explicit threat model is the artifact that separates "I implemented a crypto primitive" from "I engineered a system that defends against the attacks the primitive actually faces." This is the section a security-cleared hiring panel reads first.
| Threat | Capability assumed | Mitigation in this design | Residual risk |
|---|---|---|---|
| Timing analysis | Remote attacker, statistical timing | Constant-time control FSM; no data-dependent branches in secret-handling paths | Verified by TVLA timing variant |
| Simple Power Analysis (SPA) | Local, single trace | Constant-time + Hamming-weight balanced state encoding | Low |
| Differential Power Analysis (DPA) | Local, many traces | First-order masking on NTT butterflies (Boolean masking for Kyber); shuffled rejection sampling | Higher-order DPA not addressed in V1 |
| EM side-channel (TEMPEST) | Near-field probe | Same masking; shield recommended at integration | Out of scope for V1; documented for integrator |
| Fault injection (voltage / clock glitch) | Physical access | Redundant computation on signing path; sanity checks on NTT output | Laser fault not addressed |
| Trojan-horse / supply chain | Compromised bitstream | Reproducible build (toolchain hash pinned); deterministic synthesis flow | Open |
Standards alignment
- NIST FIPS 203 (ML-KEM) — primitive correctness
- NIST FIPS 204 (ML-DSA) — primitive correctness
- NIST SP 800-90B — entropy source assessment for the TRNG
- ISO/IEC 17825 — non-invasive side-channel attack testing (TVLA)
- CNSA 2.0 — operational guidance from NSA on PQC migration
Performance & resource budget
Targets, not yet measurements. Will be back-annotated as the implementation lands.
Verification & validation plan
- Primitive correctness — run NIST KAT (Known Answer Tests) for ML-KEM-768 and ML-DSA-65; bit-exact match required.
- Constant-time check — static analysis with
dudecton each secret-handling routine before tape-out to FPGA. - Functional verification — cocotb / UVM testbench at the co-processor boundary; 10⁵ random vector tests per opcode.
- Side-channel evaluation — TVLA on power traces captured with ChipWhisperer Husky / CW313 target board. Fixed-vs-random t-test on raw and aligned traces.
- System-level integration test — TLS 1.3 handshake using the accelerator as the KEM backend (via OpenSSL provider shim). End-to-end timing on a real connection.
- Regression CI — every commit runs KAT + cocotb in GitHub Actions; weekly synthesis check against utilization budget.
Roadmap
- Phase 1 (current): Architecture, trade studies, threat model — this document.
- Phase 2: Bare-metal SW reference of Kyber768 on CV32E40P, profiling to confirm hot spots.
- Phase 3: NTT and Keccak co-processor RTL; cocotb verification.
- Phase 4: Integration on Kria KV260; KAT validation on real silicon.
- Phase 5: Side-channel evaluation with ChipWhisperer; iterate on masking until TVLA target met.
- Phase 6: Add ML-DSA-65 (Dilithium3); OpenSSL provider shim for end-to-end TLS demo.
Source & documentation
Repository · github.com/alovladi007/pqc-riscv-system
Phase 4d is in: full Python ML-KEM-768 reference plus Keccak sponge layer (131 pytest passes), working SystemVerilog NTT engine, forward + inverse (Cooley-Tukey + Gentleman-Sande butterflies + final n-1 scaling; 8 cocotb tests including a forward-then-inverse round-trip), q_alu and butterfly testbenches (4 + 3 cocotb passes), Keccak-f[1600] 24-round controller (3 cocotb tests, matches the canonical f24(0) = 0xF1258F7940E1DDE7), SHA3-256 sponge in RTL (6 cocotb tests), SHAKE-128 with arbitrary output length (5 cocotb tests), Kyber matrix-A rejection sampler (3 cocotb tests — coef-by-coef vs Python ref, every accepted coefficient < q = 3329), SHAKE-256, and Kyber η=2 noise sampler (CBD-2, 3 cocotb tests — coef-by-coef vs Python ref + every coefficient in {0, ±1, ±2} mod q), and CI running pytest + verilator lint + 35 cocotb tests on every push. The architecture and trade studies on this page are the systems-engineering artifact that scoped that work.