pub struct MLDSA<const PK_LEN: usize, const SK_LEN: usize, const SIG_LEN: usize, PK: MLDSAPublicKeyTrait<k, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>, SK: MLDSAPrivateKeyTrait<k, l, ETA, SK_LEN, PK_LEN> + MLDSAPrivateKeyInternalTrait<k, l, ETA, SK_LEN, PK_LEN>, const TAU: i32, const LAMBDA: i32, const GAMMA1: i32, const GAMMA2: i32, const k: usize, const l: usize, const ETA: usize, const BETA: i32, const OMEGA: i32, const C_TILDE: usize, const POLY_VEC_H_PACKED_LEN: usize, const POLY_W1_PACKED_LEN: usize, const W1_PACKED_LEN: usize, const POLY_ETA_PACKED_LEN: usize, const LAMBDA_over_4: usize, const GAMMA1_MASK_LEN: usize> { /* private fields */ }Expand description
The core internal implementation of the ML-DSA algorithm. This needs to be public for the compiler to be able to find it, but you shouldn’t ever need to use this directly. Please use the named public types.
Implementations§
Source§impl<const PK_LEN: usize, const SK_LEN: usize, const SIG_LEN: usize, PK: MLDSAPublicKeyTrait<k, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>, SK: MLDSAPrivateKeyTrait<k, l, ETA, SK_LEN, PK_LEN> + MLDSAPrivateKeyInternalTrait<k, l, ETA, SK_LEN, PK_LEN>, const TAU: i32, const LAMBDA: i32, const GAMMA1: i32, const GAMMA2: i32, const k: usize, const l: usize, const ETA: usize, const BETA: i32, const OMEGA: i32, const C_TILDE: usize, const POLY_Z_PACKED_LEN: usize, const POLY_W1_PACKED_LEN: usize, const W1_PACKED_LEN: usize, const POLY_ETA_PACKED_LEN: usize, const LAMBDA_over_4: usize, const GAMMA1_MASK_LEN: usize> MLDSA<PK_LEN, SK_LEN, SIG_LEN, PK, SK, TAU, LAMBDA, GAMMA1, GAMMA2, k, l, ETA, BETA, OMEGA, C_TILDE, POLY_Z_PACKED_LEN, POLY_W1_PACKED_LEN, W1_PACKED_LEN, POLY_ETA_PACKED_LEN, LAMBDA_over_4, GAMMA1_MASK_LEN>
impl<const PK_LEN: usize, const SK_LEN: usize, const SIG_LEN: usize, PK: MLDSAPublicKeyTrait<k, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>, SK: MLDSAPrivateKeyTrait<k, l, ETA, SK_LEN, PK_LEN> + MLDSAPrivateKeyInternalTrait<k, l, ETA, SK_LEN, PK_LEN>, const TAU: i32, const LAMBDA: i32, const GAMMA1: i32, const GAMMA2: i32, const k: usize, const l: usize, const ETA: usize, const BETA: i32, const OMEGA: i32, const C_TILDE: usize, const POLY_Z_PACKED_LEN: usize, const POLY_W1_PACKED_LEN: usize, const W1_PACKED_LEN: usize, const POLY_ETA_PACKED_LEN: usize, const LAMBDA_over_4: usize, const GAMMA1_MASK_LEN: usize> MLDSA<PK_LEN, SK_LEN, SIG_LEN, PK, SK, TAU, LAMBDA, GAMMA1, GAMMA2, k, l, ETA, BETA, OMEGA, C_TILDE, POLY_Z_PACKED_LEN, POLY_W1_PACKED_LEN, W1_PACKED_LEN, POLY_ETA_PACKED_LEN, LAMBDA_over_4, GAMMA1_MASK_LEN>
Sourcepub fn keygen_from_os_rng() -> Result<(PK, SK), SignatureError>
pub fn keygen_from_os_rng() -> Result<(PK, SK), SignatureError>
Should still be ok in FIPS mode
Trait Implementations§
Source§impl<const PK_LEN: usize, const SK_LEN: usize, const SIG_LEN: usize, PK: MLDSAPublicKeyTrait<k, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>, SK: MLDSAPrivateKeyTrait<k, l, ETA, SK_LEN, PK_LEN> + MLDSAPrivateKeyInternalTrait<k, l, ETA, SK_LEN, PK_LEN>, const TAU: i32, const LAMBDA: i32, const GAMMA1: i32, const GAMMA2: i32, const k: usize, const l: usize, const ETA: usize, const BETA: i32, const OMEGA: i32, const C_TILDE: usize, const POLY_Z_PACKED_LEN: usize, const POLY_W1_PACKED_LEN: usize, const W1_PACKED_LEN: usize, const POLY_ETA_PACKED_LEN: usize, const LAMBDA_over_4: usize, const GAMMA1_MASK_LEN: usize> MLDSATrait<PK_LEN, SK_LEN, SIG_LEN, PK, SK, k, l, ETA> for MLDSA<PK_LEN, SK_LEN, SIG_LEN, PK, SK, TAU, LAMBDA, GAMMA1, GAMMA2, k, l, ETA, BETA, OMEGA, C_TILDE, POLY_Z_PACKED_LEN, POLY_W1_PACKED_LEN, W1_PACKED_LEN, POLY_ETA_PACKED_LEN, LAMBDA_over_4, GAMMA1_MASK_LEN>
impl<const PK_LEN: usize, const SK_LEN: usize, const SIG_LEN: usize, PK: MLDSAPublicKeyTrait<k, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>, SK: MLDSAPrivateKeyTrait<k, l, ETA, SK_LEN, PK_LEN> + MLDSAPrivateKeyInternalTrait<k, l, ETA, SK_LEN, PK_LEN>, const TAU: i32, const LAMBDA: i32, const GAMMA1: i32, const GAMMA2: i32, const k: usize, const l: usize, const ETA: usize, const BETA: i32, const OMEGA: i32, const C_TILDE: usize, const POLY_Z_PACKED_LEN: usize, const POLY_W1_PACKED_LEN: usize, const W1_PACKED_LEN: usize, const POLY_ETA_PACKED_LEN: usize, const LAMBDA_over_4: usize, const GAMMA1_MASK_LEN: usize> MLDSATrait<PK_LEN, SK_LEN, SIG_LEN, PK, SK, k, l, ETA> for MLDSA<PK_LEN, SK_LEN, SIG_LEN, PK, SK, TAU, LAMBDA, GAMMA1, GAMMA2, k, l, ETA, BETA, OMEGA, C_TILDE, POLY_Z_PACKED_LEN, POLY_W1_PACKED_LEN, W1_PACKED_LEN, POLY_ETA_PACKED_LEN, LAMBDA_over_4, GAMMA1_MASK_LEN>
Source§fn keygen_from_seed(
seed: &KeyMaterialSized<32>,
) -> Result<(PK, SK), SignatureError>
fn keygen_from_seed( seed: &KeyMaterialSized<32>, ) -> Result<(PK, SK), SignatureError>
Imports a secret key from a seed.
Source§fn keygen_from_seed_and_encoded(
seed: &KeyMaterialSized<32>,
encoded_sk: &[u8; SK_LEN],
) -> Result<(PK, SK), SignatureError>
fn keygen_from_seed_and_encoded( seed: &KeyMaterialSized<32>, encoded_sk: &[u8; SK_LEN], ) -> Result<(PK, SK), SignatureError>
Imports a secret key from both a seed and an encoded_sk.
This is a convenience function to expand the key from seed and compare it against
the provided encoded_sk using a constant-time equality check.
If everything checks out, the secret key is returned fully populated with pk and seed.
If the provided key and derived key don’t match, an error is returned.
Source§fn keypair_consistency_check(pk: &PK, sk: &SK) -> Result<(), SignatureError>
fn keypair_consistency_check(pk: &PK, sk: &SK) -> Result<(), SignatureError>
Given a public key and a secret key, check that the public key matches the secret key. This is a sanity check that the public key was generated correctly from the secret key.
At the current time, this is only possible if sk either contains a public key (in which case
the two pk’s are encoded and compared for byte equality), or if sk contains a seed
(in which case a keygen_from_seed is run and then the pk’s compared).
Returns either () or SignatureError::ConsistencyCheckFailed.
Source§fn compute_mu_from_tr(
msg: &[u8],
ctx: Option<&[u8]>,
tr: &[u8; 64],
) -> Result<[u8; 64], SignatureError>
fn compute_mu_from_tr( msg: &[u8], ctx: Option<&[u8]>, tr: &[u8; 64], ) -> Result<[u8; 64], SignatureError>
This provides the first half of the “External Mu” interface to ML-DSA which is described in, and allowed under, NIST’s FAQ that accompanies FIPS 204.
This function, together with MLDSATrait::sign_mu perform a complete ML-DSA signature which is indistinguishable from one produced by the one-shot sign APIs.
The utility of this function is exactly as described on Line 6 of Algorithm 7 of FIPS 204:
message representative that may optionally be computed in a different cryptographic module
The utility is when an extremely large message needs to be signed, where the message exists on one computing system and the private key to sign it is held on another and either the transfer time or bandwidth causes operational concerns (this is common for example with network HSMs or sending large messages to be signed by a smartcard communicating over near-field radio). Another use case is if the contents of the message are sensitive and the signer does not want to transmit the message itself for fear of leaking it via proxy logging and instead would prefer to only transmit a hash of it.
Since “External Mu” mode is well-defined by FIPS 204 and allowed by NIST, the mu value produced here can be used with many hardware crypto modules.
This “External Mu” mode of ML-DSA provides an alternative to the HashML-DSA algorithm in that it allows the message to be externally pre-hashed, however, unlike HashML-DSA, this is merely an optimization between the application holding the to-be-signed message and the cryptographic module holding the private key – in particular, while HashML-DSA requires the verifier to know whether ML-DSA or HashML-DSA was used to sign the message, both “direct” ML-DSA and “External Mu” signatures can be verified with a standard ML-DSA verifier.
This function requires the public key hash tr, which can be computed from the public key
using MLDSAPublicKeyTrait::compute_tr.
For a streaming version of this, see MuBuilder.
Source§fn compute_mu_from_pk(
msg: &[u8],
ctx: Option<&[u8]>,
pk: &PK,
) -> Result<[u8; 64], SignatureError>
fn compute_mu_from_pk( msg: &[u8], ctx: Option<&[u8]>, pk: &PK, ) -> Result<[u8; 64], SignatureError>
Same as MLDSA::compute_mu_from_tr, but extracts tr from the public key.
Source§fn compute_mu_from_sk(
msg: &[u8],
ctx: Option<&[u8]>,
sk: &SK,
) -> Result<[u8; 64], SignatureError>
fn compute_mu_from_sk( msg: &[u8], ctx: Option<&[u8]>, sk: &SK, ) -> Result<[u8; 64], SignatureError>
Same as MLDSA::compute_mu_from_tr, but extracts tr from the private key.
Source§fn sign_mu(sk: &SK, mu: &[u8; 64]) -> Result<[u8; SIG_LEN], SignatureError>
fn sign_mu(sk: &SK, mu: &[u8; 64]) -> Result<[u8; SIG_LEN], SignatureError>
Performs an ML-DSA signature using the provided external message representative mu.
This implements FIPS 204 Algorithm 7 with line 6 removed; a modification that is allowed by both
FIPS 204 itself, as well as subsequent FAQ documents.
This mode uses randomized signing (called “hedged mode” in FIPS 204) using an internal RNG.
Source§fn sign_mu_out(
sk: &SK,
mu: &[u8; 64],
output: &mut [u8; SIG_LEN],
) -> Result<usize, SignatureError>
fn sign_mu_out( sk: &SK, mu: &[u8; 64], output: &mut [u8; SIG_LEN], ) -> Result<usize, SignatureError>
Performs an ML-DSA signature using the provided external message representative mu.
This implements FIPS 204 Algorithm 7 with line 6 removed; a modification that is allowed by both
FIPS 204 itself, as well as subsequent FAQ documents.
This mode uses randomized signing (called “hedged mode” in FIPS 204) using an internal RNG.
Returns the number of bytes written to the output buffer. Can be called with an oversized buffer.
Source§fn sign_mu_deterministic(
sk: &SK,
mu: &[u8; 64],
rnd: [u8; 32],
) -> Result<[u8; SIG_LEN], SignatureError>
fn sign_mu_deterministic( sk: &SK, mu: &[u8; 64], rnd: [u8; 32], ) -> Result<[u8; SIG_LEN], SignatureError>
Algorithm 7 ML-DSA.Sign_internal(𝑠𝑘, 𝑀′, 𝑟𝑛𝑑) (modified to take an externally-computed mu instead of M’)
Performs an ML-DSA signature using the provided external message representative mu.
This implements FIPS 204 Algorithm 7 with line 6 removed; a modification that is allowed by both
FIPS 204 itself, as well as subsequent FAQ documents.
Security note:
This mode exposes deterministic signing (called “hedged mode” and allowed by FIPS 204).
The ML-DSA algorithm is considered safe to use in deterministic mode, but be aware that
the responsibility is on you to ensure that your nonce rnd is unique per signature.
If not, you may lose some privacy properties; for example it becomes easy to tell if a signer
has signed the same message twice or two different messagase, or to tell if the same message
has been signed by the same signer twice or two different signers.
Since rnd should be either a per-signature nonce, or a fixed value, therefore, to help
prevent accidental nonce reuse, this function moves rnd.
Source§fn sign_mu_deterministic_out(
sk: &SK,
mu: &[u8; 64],
rnd: [u8; 32],
output: &mut [u8; SIG_LEN],
) -> Result<usize, SignatureError>
fn sign_mu_deterministic_out( sk: &SK, mu: &[u8; 64], rnd: [u8; 32], output: &mut [u8; SIG_LEN], ) -> Result<usize, SignatureError>
Algorithm 7 ML-DSA.Sign_internal(𝑠𝑘, 𝑀′, 𝑟𝑛𝑑) (modified to take an externally-computed mu instead of M’)
Performs an ML-DSA signature using the provided external message representative mu.
This implements FIPS 204 Algorithm 7 with line 6 removed; a modification that is allowed by both
FIPS 204 itself, as well as subsequent FAQ documents.
This mode exposes deterministic signing (called “hedged mode” in FIPS 204) using an internal RNG.
Since rnd should be either a per-signature nonce, or a fixed value, therefore, to help
prevent accidental nonce reuse, this function moves rnd.
Returns the number of bytes written to the output buffer. Can be called with an oversized buffer.
Source§fn set_signer_rnd(&mut self, rnd: [u8; 32])
fn set_signer_rnd(&mut self, rnd: [u8; 32])
To be used for deterministic signing in conjunction with the MLDSA44::sign_init, MLDSA44::sign_update, and MLDSA44::sign_final flow. Can be set anywhere after MLDSA44::sign_init and before MLDSA44::sign_final
Source§fn sign_init_from_seed(
seed: &KeyMaterialSized<32>,
ctx: Option<&[u8]>,
) -> Result<Self, SignatureError>
fn sign_init_from_seed( seed: &KeyMaterialSized<32>, ctx: Option<&[u8]>, ) -> Result<Self, SignatureError>
Alternative initialization of the streaming signer where you have your private key as a seed and you want to delay its expansion as late as possible for memory-usage reasons.
Source§fn verify_mu_internal(pk: &PK, mu: &[u8; 64], sig: &[u8; SIG_LEN]) -> bool
fn verify_mu_internal(pk: &PK, mu: &[u8; 64], sig: &[u8; SIG_LEN]) -> bool
Algorithm 8 ML-DSA.Verify_internal(𝑝𝑘, 𝑀′, 𝜎) Internal function to verify a signature 𝜎 for a formatted message 𝑀′ . Input: Public key 𝑝𝑘 ∈ 𝔹32+32𝑘(bitlen (𝑞−1)−𝑑) and message 𝑀′ ∈ {0, 1}∗ . Input: Signature 𝜎 ∈ 𝔹𝜆/4+ℓ⋅32⋅(1+bitlen (𝛾1−1))+𝜔+𝑘.
Source§fn sign_mu_deterministic_from_seed(
seed: &KeyMaterialSized<32>,
mu: &[u8; 64],
rnd: [u8; 32],
) -> Result<[u8; SIG_LEN], SignatureError>
fn sign_mu_deterministic_from_seed( seed: &KeyMaterialSized<32>, mu: &[u8; 64], rnd: [u8; 32], ) -> Result<[u8; SIG_LEN], SignatureError>
Source§fn sign_mu_deterministic_from_seed_out(
seed: &KeyMaterialSized<32>,
mu: &[u8; 64],
rnd: [u8; 32],
output: &mut [u8; SIG_LEN],
) -> Result<usize, SignatureError>
fn sign_mu_deterministic_from_seed_out( seed: &KeyMaterialSized<32>, mu: &[u8; 64], rnd: [u8; 32], output: &mut [u8; SIG_LEN], ) -> Result<usize, SignatureError>
Source§impl<const PK_LEN: usize, const SK_LEN: usize, const SIG_LEN: usize, PK: MLDSAPublicKeyTrait<k, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>, SK: MLDSAPrivateKeyTrait<k, l, ETA, SK_LEN, PK_LEN> + MLDSAPrivateKeyInternalTrait<k, l, ETA, SK_LEN, PK_LEN>, const TAU: i32, const LAMBDA: i32, const GAMMA1: i32, const GAMMA2: i32, const k: usize, const l: usize, const ETA: usize, const BETA: i32, const OMEGA: i32, const C_TILDE: usize, const POLY_Z_PACKED_LEN: usize, const POLY_W1_PACKED_LEN: usize, const W1_PACKED_LEN: usize, const POLY_ETA_PACKED_LEN: usize, const LAMBDA_over_4: usize, const GAMMA1_MASK_LEN: usize> Signature<PK, SK> for MLDSA<PK_LEN, SK_LEN, SIG_LEN, PK, SK, TAU, LAMBDA, GAMMA1, GAMMA2, k, l, ETA, BETA, OMEGA, C_TILDE, POLY_Z_PACKED_LEN, POLY_W1_PACKED_LEN, W1_PACKED_LEN, POLY_ETA_PACKED_LEN, LAMBDA_over_4, GAMMA1_MASK_LEN>
impl<const PK_LEN: usize, const SK_LEN: usize, const SIG_LEN: usize, PK: MLDSAPublicKeyTrait<k, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>, SK: MLDSAPrivateKeyTrait<k, l, ETA, SK_LEN, PK_LEN> + MLDSAPrivateKeyInternalTrait<k, l, ETA, SK_LEN, PK_LEN>, const TAU: i32, const LAMBDA: i32, const GAMMA1: i32, const GAMMA2: i32, const k: usize, const l: usize, const ETA: usize, const BETA: i32, const OMEGA: i32, const C_TILDE: usize, const POLY_Z_PACKED_LEN: usize, const POLY_W1_PACKED_LEN: usize, const W1_PACKED_LEN: usize, const POLY_ETA_PACKED_LEN: usize, const LAMBDA_over_4: usize, const GAMMA1_MASK_LEN: usize> Signature<PK, SK> for MLDSA<PK_LEN, SK_LEN, SIG_LEN, PK, SK, TAU, LAMBDA, GAMMA1, GAMMA2, k, l, ETA, BETA, OMEGA, C_TILDE, POLY_Z_PACKED_LEN, POLY_W1_PACKED_LEN, W1_PACKED_LEN, POLY_ETA_PACKED_LEN, LAMBDA_over_4, GAMMA1_MASK_LEN>
Source§fn keygen() -> Result<(PK, SK), SignatureError>
fn keygen() -> Result<(PK, SK), SignatureError>
Source§fn sign(
sk: &SK,
msg: &[u8],
ctx: Option<&[u8]>,
) -> Result<Vec<u8>, SignatureError>
fn sign( sk: &SK, msg: &[u8], ctx: Option<&[u8]>, ) -> Result<Vec<u8>, SignatureError>
msg and ctx accept zero-length byte arrays. Read more