Skip to main content

Module dsa

Module dsa 

Source
Expand description

Core ML-DSA key generation, signing, and verification algorithms. Core ML-DSA algorithms (FIPS 204, Algorithms 1-8).

Contains the key generation, signing, and verification routines at both the public API level (Algorithms 1-3) and the internal/deterministic level (Algorithms 6-8).

All internal polynomial vector operations use fixed-size stack arrays ([[i32; N]; MAX_K] / [[i32; N]; MAX_L]) to avoid heap allocations.

§Side-channel countermeasures (sca-protected feature)

When the sca-protected Cargo feature is enabled (on by default), sign_internal runs an additional layer of defences on the secret-key material:

CountermeasureModuleThreat addressed
Constant-time arithalways-onCache- / branch-based timing attacks
Zeroizationalways-onCold-boot dumps, use-after-free
Hedged signingalways-onFault-induced nonce reuse (rnd ≠ 0)
Shuffled NTTsuper::shuffle (sca)SPA, trace-alignment for DPA
First-order maskingsuper::masked (sca)First-order DPA, template attacks
Mask refresh / hopsuper::masked (sca)Inter-iteration share correlation

The masking + shuffling layer is deliberately confined to sign_internal, because that is where the secret key (s1, s2, t0) is consumed in polynomial multiplications with values an attacker can influence:

  ŝ1, ŝ2, t̂0  ←  NTT(s1), NTT(s2), NTT(t0)               // SPA + DPA target
  loop:
      ĉ ← NTT(SampleInBall(c̃))
      cs1[i]  ← ĉ · ŝ1[i]                                 // ×L  — DPA target
      cs2[i]  ← ĉ · ŝ2[i]                                 // ×K  — DPA target
      ct0[i]  ← ĉ · t̂0[i]                                 // ×K  — DPA target

The challenge polynomial ĉ is public (the verifier recomputes it), so every secret×public multiplication only needs first-order masking: (s₀ + s₁) · ĉ = s₀·ĉ + s₁·ĉ. There is no secret×secret operation in Sign that would require second-order shares.

Mask randomness is drawn from a SHAKE256-based deterministic ScaRng seeded with (K ‖ rnd ‖ tr ‖ M'), so that:

  • sign_internal keeps a deterministic signature (no &mut dyn CryptoRng parameter), and the NIST ACVP fixed-rnd = 0 test vectors still match bit-for-bit;
  • different rnd values produce independent share streams (hedged signing entropy is preserved through the SCA layer).

The standard build (without sca-protected) still benefits from the always-on countermeasures listed above; only the masking + shuffling defences are conditionally compiled out.

Functions§

keygen
Generate an ML-DSA key pair.
keygen_internal
Deterministic key generation from a 32-byte seed.
sign
Sign a message with an optional context string (hedged mode).
sign_internal
Sign a pre-formatted message (deterministic or hedged).
verify
Verify a signature on a message with an optional context string.
verify_internal
Verify a signature against a pre-formatted message.