quantica/ml_kem/params.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Cédric Mesnil <cslashm@pm.me>
3
4//! ML-KEM parameter sets as defined in FIPS 203 Section 8, Table 2.
5//!
6//! Constants: n = 256, q = 3329 for all parameter sets.
7
8/// The polynomial ring dimension. All ML-KEM parameter sets use n = 256.
9pub const N: usize = 256;
10
11/// The modulus for the polynomial ring `R_q = Z_q[X]/(X^n + 1)`.
12///
13/// q = 3329 is chosen because it is prime and satisfies q ≡ 1 (mod 2n),
14/// enabling efficient NTT-based polynomial multiplication.
15pub const Q: u16 = 3329;
16
17/// Parameter set trait for ML-KEM security levels.
18///
19/// Implemented by [`MlKem512`], [`MlKem768`], and [`MlKem1024`], each
20/// providing the constants that define key sizes, ciphertext sizes, and
21/// sampling parameters for a specific NIST security category.
22///
23/// The derived constants ([`EK_LEN`](Params::EK_LEN), [`DK_LEN`](Params::DK_LEN),
24/// [`CT_LEN`](Params::CT_LEN), [`SS_LEN`](Params::SS_LEN)) are computed
25/// automatically from the core parameters.
26pub trait Params: 'static {
27 /// Module rank (number of polynomials per vector). Determines security level.
28 const K: usize;
29 /// CBD sampling parameter for secret key and first error vector.
30 const ETA1: usize;
31 /// CBD sampling parameter for second error vectors during encryption.
32 const ETA2: usize;
33 /// Compression bit-width for the `u` component of ciphertexts.
34 const DU: usize;
35 /// Compression bit-width for the `v` component of ciphertexts.
36 const DV: usize;
37
38 // Derived sizes (in bytes)
39 /// Encapsulation key size in bytes: 384*k + 32.
40 const EK_LEN: usize = 384 * Self::K + 32;
41 /// Decapsulation key size in bytes: 768*k + 96.
42 ///
43 /// Layout: `dk_pke || ek_pke || H(ek) || z` where `z` is the implicit
44 /// rejection seed.
45 const DK_LEN: usize = 768 * Self::K + 96;
46 /// Ciphertext size in bytes: 32*(du*k + dv).
47 const CT_LEN: usize = 32 * (Self::DU * Self::K + Self::DV);
48 /// Shared secret size in bytes. Always 32 (256 bits) for all parameter sets.
49 const SS_LEN: usize = 32;
50}
51
52/// ML-KEM-512 parameter set (NIST security category 1).
53///
54/// Provides 128-bit classical security. Smallest key and ciphertext sizes.
55///
56/// | Property | Value |
57/// |----------|-------|
58/// | `EK_LEN` | 800 bytes |
59/// | `DK_LEN` | 1632 bytes |
60/// | `CT_LEN` | 768 bytes |
61pub struct MlKem512;
62impl Params for MlKem512 {
63 const K: usize = 2;
64 const ETA1: usize = 3;
65 const ETA2: usize = 2;
66 const DU: usize = 10;
67 const DV: usize = 4;
68}
69
70/// ML-KEM-768 parameter set (NIST security category 3).
71///
72/// The NIST recommended default. Provides 192-bit classical security and
73/// balances performance with security margin.
74///
75/// | Property | Value |
76/// |----------|-------|
77/// | `EK_LEN` | 1184 bytes |
78/// | `DK_LEN` | 2400 bytes |
79/// | `CT_LEN` | 1088 bytes |
80pub struct MlKem768;
81impl Params for MlKem768 {
82 const K: usize = 3;
83 const ETA1: usize = 2;
84 const ETA2: usize = 2;
85 const DU: usize = 10;
86 const DV: usize = 4;
87}
88
89/// ML-KEM-1024 parameter set (NIST security category 5).
90///
91/// Provides 256-bit classical security. Largest key and ciphertext sizes,
92/// but highest security margin.
93///
94/// | Property | Value |
95/// |----------|-------|
96/// | `EK_LEN` | 1568 bytes |
97/// | `DK_LEN` | 3168 bytes |
98/// | `CT_LEN` | 1568 bytes |
99pub struct MlKem1024;
100impl Params for MlKem1024 {
101 const K: usize = 4;
102 const ETA1: usize = 2;
103 const ETA2: usize = 2;
104 const DU: usize = 11;
105 const DV: usize = 5;
106}