krypteia-quantica 0.1.0

Pure-Rust post-quantum cryptography: FIPS 203 ML-KEM, FIPS 204 ML-DSA, and FIPS 205 SLH-DSA. First-order arithmetic masking, shuffled NTT, FORS recompute-and-compare redundancy, constant-time rejection sampling. Targets embedded (no_std), STM32 M0/M4/M33, ESP32-C3 RISC-V. Zero runtime dependencies.
Documentation
//! ML-DSA parameter sets (FIPS 204, Table 1).
//!
//! Defines the global constants shared across all parameter sets (the prime
//! modulus `Q`, polynomial degree `N`, etc.) and the [`Params`] trait that
//! encodes the per-security-level constants.

/// The prime modulus q = 2^23 - 2^13 + 1 = 8380417.
///
/// All polynomial arithmetic in ML-DSA is performed modulo this prime.
pub const Q: i32 = 8380417;

/// Polynomial degree (number of coefficients per polynomial).
///
/// ML-DSA operates over the ring `Z_q[X]/(X^256 + 1)`.
pub const N: usize = 256;

/// Primitive 512th root of unity modulo q.
///
/// Used to build the NTT twiddle factor table. zeta = 1753 satisfies
/// zeta^256 = -1 (mod q).
pub const ZETA: i32 = 1753;

/// Maximum value of K across all parameter sets (ML-DSA-87 has K=8).
pub const MAX_K: usize = 8;

/// Maximum value of L across all parameter sets (ML-DSA-87 has L=7).
pub const MAX_L: usize = 7;

/// The `d` parameter (number of dropped bits from t).
///
/// Public key compression drops the low `d = 13` bits of the vector t,
/// splitting it into (t1, t0) via Power2Round.
pub const D: usize = 13;

/// Multiplicative inverse of N modulo q: 256^{-1} mod q.
///
/// Applied as a final scaling factor in the inverse NTT.
pub const N_INV: i32 = 8347681;

/// Parameter trait for ML-DSA security levels.
///
/// Each implementor (e.g., [`MlDsa44`], [`MlDsa65`], [`MlDsa87`]) provides
/// the constants from FIPS 204, Table 1. Derived sizes for public key,
/// secret key, and signature are computed automatically from the base
/// constants.
pub trait Params {
    /// Number of rows in the matrix A (dimension k).
    const K: usize;
    /// Number of columns in the matrix A (dimension l).
    const L: usize;
    /// Secret key coefficient bound: coefficients of s1, s2 lie in [-eta, eta].
    const ETA: usize;
    /// Number of +/-1 entries in the challenge polynomial c.
    const TAU: usize;
    /// Signing bound beta = tau * eta. Candidate signatures with infinity norm >= gamma1 - beta are rejected.
    const BETA: i32;
    /// Masking range: coefficients of the masking vector y are sampled from [-(gamma1-1), gamma1].
    const GAMMA1: i32;
    /// Decomposition parameter: controls the rounding used in HighBits/LowBits.
    const GAMMA2: i32;
    /// Maximum number of non-zero hint entries allowed across all k hint polynomials.
    const OMEGA: usize;
    /// Collision strength in bits; determines the length of the commitment hash c_tilde (lambda/4 bytes).
    const LAMBDA: usize;

    /// Public key length in bytes: 32 (rho) + k * 320 (encoded t1).
    const PK_LEN: usize = 32 + 32 * Self::K * 10; // bitlen(q-1)-d = 23-13 = 10
    /// Secret key length in bytes.
    const SK_LEN: usize = 32 + 32 + 64 + 32 * (Self::L + Self::K) * Self::BITLEN_2ETA + 32 * Self::K * D;
    /// Signature length in bytes.
    const SIG_LEN: usize = Self::LAMBDA / 4 + Self::L * 32 * (1 + Self::BITLEN_GAMMA1_MINUS1) + Self::OMEGA + Self::K;

    /// Helper constant: bit-length of 2*eta, used for encoding secret polynomials.
    const BITLEN_2ETA: usize;
    /// Helper constant: bit-length of gamma1 - 1, used for encoding z in signatures.
    const BITLEN_GAMMA1_MINUS1: usize;
}

/// ML-DSA-44 parameter set (NIST security level 2).
///
/// Provides approximately 128 bits of classical security. Matrix dimensions
/// are k=4, l=4 with eta=2.
pub struct MlDsa44;

impl Params for MlDsa44 {
    const K: usize = 4;
    const L: usize = 4;
    const ETA: usize = 2;
    const TAU: usize = 39;
    const BETA: i32 = 78;
    const GAMMA1: i32 = 1 << 17; // 2^17
    const GAMMA2: i32 = (Q - 1) / 88; // 95232
    const OMEGA: usize = 80;
    const LAMBDA: usize = 128;
    const BITLEN_2ETA: usize = 3; // bitlen(4) = 3
    const BITLEN_GAMMA1_MINUS1: usize = 17; // bitlen(2^17 - 1) = 17
}

/// ML-DSA-65 parameter set (NIST security level 3).
///
/// Provides approximately 192 bits of classical security. Matrix dimensions
/// are k=6, l=5 with eta=4.
pub struct MlDsa65;

impl Params for MlDsa65 {
    const K: usize = 6;
    const L: usize = 5;
    const ETA: usize = 4;
    const TAU: usize = 49;
    const BETA: i32 = 196;
    const GAMMA1: i32 = 1 << 19; // 2^19
    const GAMMA2: i32 = (Q - 1) / 32; // 261888
    const OMEGA: usize = 55;
    const LAMBDA: usize = 192;
    const BITLEN_2ETA: usize = 4; // bitlen(8) = 4
    const BITLEN_GAMMA1_MINUS1: usize = 19; // bitlen(2^19 - 1) = 19
}

/// ML-DSA-87 parameter set (NIST security level 5).
///
/// Provides approximately 256 bits of classical security. Matrix dimensions
/// are k=8, l=7 with eta=2.
pub struct MlDsa87;

impl Params for MlDsa87 {
    const K: usize = 8;
    const L: usize = 7;
    const ETA: usize = 2;
    const TAU: usize = 60;
    const BETA: i32 = 120;
    const GAMMA1: i32 = 1 << 19; // 2^19
    const GAMMA2: i32 = (Q - 1) / 32; // 261888
    const OMEGA: usize = 75;
    const LAMBDA: usize = 256;
    const BITLEN_2ETA: usize = 3; // bitlen(4) = 3
    const BITLEN_GAMMA1_MINUS1: usize = 19; // bitlen(2^19 - 1) = 19
}