Skip to main content

cryptography/public_key/
ntru_hps509.rs

1//! NTRU-HPS-2048-509 — round-3 NTRU parameter set $(N = 509, q = 2048,
2//! \text{weight} = q/8 - 2 = 254)$.
3//!
4//! Algorithmic core, OWCPA + FO-style KEM, and side-channel inventory
5//! are documented in [`crate::public_key::ntru_pqc_shared`]; this file
6//! is the parameter binding plus the LOGQ-11 Sq packer override.
7//!
8//! Validated against all 100 entries of the round-3 KAT file
9//! `PQCkemKAT_935.rsp` (sampled subset by default; full sweep under
10//! `--ignored`).
11
12
13
14// ---- parameter constants ---------------------------------------------------
15
16const N: usize = 509;
17const LOGQ: usize = 11;
18const Q: u32 = 1 << LOGQ;
19const Q_MASK: u16 = (Q as u16).wrapping_sub(1);
20const WEIGHT: usize = (Q as usize) / 8 - 2; // 254
21
22const PRFKEYBYTES: usize = 32;
23const SHAREDKEYBYTES: usize = 32;
24
25const SAMPLE_IID_BYTES: usize = N - 1; // 508
26const SAMPLE_FT_BYTES: usize = (30 * (N - 1) + 7) / 8; // 1905
27const SAMPLE_FG_BYTES: usize = SAMPLE_IID_BYTES + SAMPLE_FT_BYTES; // 2413
28const SAMPLE_RM_BYTES: usize = SAMPLE_IID_BYTES + SAMPLE_FT_BYTES; // 2413
29
30const PACK_DEG: usize = N - 1; // 508
31const PACK_TRINARY_BYTES: usize = (PACK_DEG + 4) / 5; // 102
32
33const OWCPA_MSGBYTES: usize = 2 * PACK_TRINARY_BYTES; // 204
34const OWCPA_PUBLICKEYBYTES: usize = (LOGQ * PACK_DEG + 7) / 8; // 699
35const OWCPA_SECRETKEYBYTES: usize = 2 * PACK_TRINARY_BYTES + OWCPA_PUBLICKEYBYTES; // 903
36const OWCPA_BYTES: usize = (LOGQ * PACK_DEG + 7) / 8; // 699
37
38/// Public-key length in bytes.
39pub const PUBLIC_KEY_BYTES: usize = OWCPA_PUBLICKEYBYTES; // 699
40/// Private-key length in bytes (includes implicit-rejection PRF key).
41pub const PRIVATE_KEY_BYTES: usize = OWCPA_SECRETKEYBYTES + PRFKEYBYTES; // 935
42/// Ciphertext length in bytes.
43pub const CIPHERTEXT_BYTES: usize = OWCPA_BYTES; // 699
44/// Shared-secret length in bytes.
45pub const SHARED_SECRET_BYTES: usize = SHAREDKEYBYTES; // 32
46
47// ---- variant marker -------------------------------------------------------
48
49struct Hps509Variant;
50
51impl crate::public_key::ntru_pqc_shared::NtruVariant<N, LOGQ> for Hps509Variant {
52    const Q_MASK: u16 = Q_MASK;
53    const WEIGHT: usize = WEIGHT;
54    const SAMPLE_FG_BYTES: usize = SAMPLE_FG_BYTES;
55    const SAMPLE_RM_BYTES: usize = SAMPLE_RM_BYTES;
56    const PACK_TRINARY_BYTES: usize = PACK_TRINARY_BYTES;
57    const OWCPA_PUBLICKEYBYTES: usize = OWCPA_PUBLICKEYBYTES;
58    const OWCPA_SECRETKEYBYTES: usize = OWCPA_SECRETKEYBYTES;
59    const OWCPA_BYTES: usize = OWCPA_BYTES;
60    const OWCPA_MSGBYTES: usize = OWCPA_MSGBYTES;
61
62    // HPS-default `sample_fg` / `sample_rm` / `update_g_after_z3_to_zq` /
63    // `poly_lift` / `check_m` are inherited from the trait — only the
64    // LOGQ-11 Sq packer is set here.
65
66    fn poly_sq_tobytes(r: &mut [u8], a: &[u16; N]) {
67        crate::public_key::ntru_pqc_shared::poly_sq_tobytes_logq11::<N>(r, a);
68    }
69
70    fn poly_sq_frombytes(r: &mut [u16; N], a: &[u8]) {
71        crate::public_key::ntru_pqc_shared::poly_sq_frombytes_logq11::<N>(r, a);
72    }
73}
74
75// ---- public API + standard tests (macro-generated) -------------------------
76
77crate::public_key::ntru_pqc_shared::define_pqc_kem! {
78    namespace = NtruHps509,
79    public_key = NtruHps509PublicKey,
80    private_key = NtruHps509PrivateKey,
81    ciphertext = NtruHps509Ciphertext,
82    shared_secret = NtruHps509SharedSecret,
83    variant = Hps509Variant,
84    kat_path = "../../kat/ntruhps509.rsp",
85}