Cryptography
Understanding the lattice-based primitives, mathematical foundations, and implementation details of Po8's post-quantum cryptographic substrate.
From Curves to Lattices
The security of traditional cryptography (RSA, ECC) relies on the hardness of integer factorization and the discrete logarithm problem. Shor's algorithm breaks both in polynomial time on a quantum computer.
| Problem | Classical | Quantum | Status |
|---|---|---|---|
| Integer Factorization (RSA) | Sub-exponential | Polynomial (Shor) | Broken |
| Discrete Log (ECC) | Exponential | Polynomial (Shor) | Broken |
| Learning With Errors | Exponential | Exponential | Secure |
| Shortest Vector Problem | Exponential | Exponential | Secure |
Module-Learning With Errors (MLWE)
Po8 builds on the MLWE problem, which forms the foundation of Kyber and Dilithium.
Where:
- A is a public matrix
- s is the secret vector
- e is a small error vector (noise)
- q = 3329 (chosen for NTT optimization)
Without the error term, solving for s is trivial (Gaussian elimination). The error transforms this into the Closest Vector Problem (CVP) on a lattice—exponentially hard for both classical and quantum computers.
ML-KEM (Kyber)
ML-KEM-768 provides NIST Security Level 3 key encapsulation for establishing encrypted channels.
Parameter Set
| Parameter | ML-KEM-768 | Description |
|---|---|---|
| Module Rank (k) | 3 | Number of polynomial vectors |
| Polynomial Degree (n) | 256 | Coefficients per polynomial |
| Modulus (q) | 3329 | Prime for NTT compatibility |
| Public Key | 1,184 bytes | Compressed representation |
| Ciphertext | 1,088 bytes | Encrypted shared secret |
| Secret Key | 2,400 bytes | Including reject seed |
Key Generation
KeyGen()
- Generate random seed ρ
- Expand ρ via SHAKE-128 to derive matrix A
- Sample secret s and error e from CBD(η)
- Compute t = As + e
- Return (pk = (t, ρ), sk = (s, pk, H(pk), z))
Encapsulation
Encaps(pk)
- Generate random message m
- Derive (K̄, r) = G(m || H(pk))
- Compute ciphertext c = Encrypt(pk, m, r)
- Return (c, K = KDF(K̄ || H(c)))
Fujisaki-Okamoto Transform
ML-KEM uses the FO transform to achieve CCA2 security from CPA-secure PKE.
Implicit Rejection
During decapsulation, the implementation re-encrypts the recovered message and compares to the received ciphertext. On mismatch (indicating attack or failure), it returns a pseudorandom key derived from a secret reject seed—never an error code. This prevents timing and validity oracles.
ML-DSA (Dilithium)
ML-DSA-65 provides NIST Security Level 3 signatures using the Fiat-Shamir with Abort paradigm.
Parameter Set
| Parameter | ML-DSA-65 | Description |
|---|---|---|
| Module Rank (k, l) | (6, 5) | Matrix dimensions |
| Polynomial Degree | 256 | Coefficients per polynomial |
| Modulus (q) | 8380417 | Larger than Kyber for signatures |
| Public Key | 1,952 bytes | Compressed t₁ |
| Signature | 3,309 bytes | (z, h, c̃) |
| Secret Key | 4,032 bytes | (ρ, K, tr, s₁, s₂, t₀) |
Why Not Falcon?
Falcon
Dilithium (ML-DSA)
Rejection Sampling
Naive lattice signatures leak secret key information through the distribution of outputs. ML-DSA uses rejection sampling:
Sign(sk, M)
- Compute μ = CRH(tr || M)
- Sample masking vector y
- Compute w = Ay
- Compute challenge c = H(μ || w₁)
- Compute z = y + cs₁
- If ||z||∞ ≥ γ₁ - β, REJECT and restart
- If ||cs₂||∞ ≥ γ₂, REJECT and restart
- Return σ = (z, h, c̃)
The rejection loop ensures signatures are statistically independent of the secret key, preventing leakage.
Number Theoretic Transform
Polynomial multiplication is the core operation in lattice cryptography. Naive multiplication is O(n²); NTT reduces this to O(n log n).
Why q = 3329?
The modulus is carefully chosen: 3329 ≡ 1 (mod 512). This means 512th roots of unity exist in Z_q, enabling efficient NTT.
Butterfly Operation
The NTT building block:
b' = a - ζ·b
Where ζ is a precomputed twiddle factor (root of unity)
Implementation Requirements
Constant-Time
No branches on secret data. Use bitwise masking instead of conditionals.
Bit Reversal
NTT requires bit-reversed input ordering for in-place computation.
Precomputed Tables
Twiddle factors computed once at startup for maximum performance.
SLH-DSA (SPHINCS+)
SLH-DSA is a stateless hash-based signature scheme serving as Po8's governance fallback.
Security Basis
Unlike lattice schemes, SLH-DSA security depends only on the security of the underlying hash function (SHA-3). No mathematical structure to attack—just hash function preimage resistance.
Trade-offs
| Aspect | ML-DSA-65 | SLH-DSA-128f |
|---|---|---|
| Signature Size | 3,309 bytes | 17,088 bytes |
| Public Key | 1,952 bytes | 32 bytes |
| Sign Time | ~0.3 ms | ~50 ms |
| Verify Time | ~0.1 ms | ~3 ms |
| Security Assumption | MLWE hardness | Hash preimage |
Use Case
SLH-DSA is too slow for transaction signing but perfect for:
- Governance key ceremonies
- Emergency hard fork authorization
- Root of trust for key rotation
- Long-term archival signatures
Belt and Suspenders
Po8 uses hybrid key exchange combining classical and post-quantum algorithms.
Session key derived from both exchanges
Security Guarantees
If PQC Broken
X25519 maintains security against classical attackers
If ECC Broken
ML-KEM maintains security against quantum attackers
If Implementation Bug
Redundancy provides defense-in-depth
Explore the Implementation
See how these primitives are used in the Po8 node architecture.
