Back to Electronics Projects

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 GitHub

What 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

IDRequirementSource
SR-01Implement ML-KEM-768 (Kyber768) key encapsulation per FIPS 203NIST FIPS 203 (Aug 2024)
SR-02Implement ML-DSA-65 (Dilithium3) signature scheme per FIPS 204NIST FIPS 204 (Aug 2024)
SR-03Constant-time execution for all secret-dependent operationsCNSA 2.0; NIST SP 800-90B
SR-04Hardware-accelerated keygen / encaps / decaps in < 10× soft-core baselineProject goal
SR-05Acceptable LUT / DSP / BRAM footprint on Kria KV260 (Zynq UltraScale+)Platform constraint
SR-06Side-channel hygiene: TVLA test suite, target T < 4.5ISO/IEC 17825
SR-07Open-source under permissive license; reproducible from commit + toolchain hashProject 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.

+------------------------------------------------------------------+ | RISC-V Application Core (rv32imc) | | +-----------+ +-----------+ +--------------------------+ | | | Fetch |-->| Decode |-->| Execute / Custom-instr | | | +-----------+ +-----------+ +-------------+------------+ | | | RoCC iface | +------------------------------------------------|------------------+ v +------------------------------------------------------------------+ | PQC Co-Processor (this work) | | | | +----------------+ +----------------+ +----------------+ | | | NTT engine | | Keccak-f[1600]| | Sampler | | | | (radix-2/4) | | (24-round) | | (CBD / rej.) | | | +----------------+ +----------------+ +----------------+ | | | | +----------------+ +----------------+ +----------------+ | | | Mod-q ALU | | Constant-time | | Secure key | | | | (q=3329) | | control FSM | | buffer (BRAM) | | | +----------------+ +----------------+ +----------------+ | | | | +----------------------------------------------------------+ | | | TRNG (ring-osc, von-Neumann debias) | | | +----------------------------------------------------------+ | +------------------------------------------------------------------+

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

OptionSpeedup vs SWFPGA costSide-channel surfaceEffortVerdict
SW-only on rv32imc~0Low (well-studied)LowBaseline
NTT-only co-processor~6–8×ModestModestMedium
NTT + Keccak co-proc~15–25×MediumBoundedMediumSelected
Full primitive in HW~30–50×HighLarger attack surfaceHighDeferred (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

CoreLicenseRoCC-style coprocConstant-time DIVVerdict
CV32E40P (OpenHW)SolderpadNativeYesSelected
VexRiscvMITPlugin modelConfigurableAlternate
Ibex (lowRISC)Apache-2No (would need custom)YesRejected
RocketBSDRoCC nativeYesConsidered (too large for Kria)

3. TRNG topology

OptionNIST SP 800-90B compliance pathFPGA costVerdict
Ring oscillator + von-Neumann debiasAchievable with health testsLowSelected (V1)
Free-running ring + LFSR whiteningHarder (bias modeling)Low
External TRNG IC (e.g., Infineon SLE)Vendor-attestedBOM costV2 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.

ThreatCapability assumedMitigation in this designResidual risk
Timing analysisRemote attacker, statistical timingConstant-time control FSM; no data-dependent branches in secret-handling pathsVerified by TVLA timing variant
Simple Power Analysis (SPA)Local, single traceConstant-time + Hamming-weight balanced state encodingLow
Differential Power Analysis (DPA)Local, many tracesFirst-order masking on NTT butterflies (Boolean masking for Kyber); shuffled rejection samplingHigher-order DPA not addressed in V1
EM side-channel (TEMPEST)Near-field probeSame masking; shield recommended at integrationOut of scope for V1; documented for integrator
Fault injection (voltage / clock glitch)Physical accessRedundant computation on signing path; sanity checks on NTT outputLaser fault not addressed
Trojan-horse / supply chainCompromised bitstreamReproducible build (toolchain hash pinned); deterministic synthesis flowOpen

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.

Kyber768 encaps
≤ 60 µs target
Kyber768 decaps
≤ 70 µs target
Dilithium3 sign
≤ 800 µs target
Dilithium3 verify
≤ 250 µs target
LUT budget
≤ 35 k (Kria KV260)
BRAM budget
≤ 40 × 36 Kb
DSP slices
≤ 32
TVLA target
|T| < 4.5 @ 10⁵ traces

Verification & validation plan

  1. Primitive correctness — run NIST KAT (Known Answer Tests) for ML-KEM-768 and ML-DSA-65; bit-exact match required.
  2. Constant-time check — static analysis with dudect on each secret-handling routine before tape-out to FPGA.
  3. Functional verification — cocotb / UVM testbench at the co-processor boundary; 10⁵ random vector tests per opcode.
  4. Side-channel evaluation — TVLA on power traces captured with ChipWhisperer Husky / CW313 target board. Fixed-vs-random t-test on raw and aligned traces.
  5. 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.
  6. 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.