2.3 Module Lattice-based signatures

2.3.1 Module Lattice-based signature keys

The Crypto API supports Module Lattice-based digital signatures (ML-DSA), as defined in FIPS Publication 204: Module-Lattice-Based Digital Signature Standard [FIPS204].

PSA_KEY_TYPE_ML_DSA_KEY_PAIR (macro)

ML-DSA key pair: both the private and public key.

Added in version 1.3.

#define PSA_KEY_TYPE_ML_DSA_KEY_PAIR ((psa_key_type_t)0x7002)

The key attribute size of an ML-DSA key is a measure of the security strength of the ML-DSA parameter set in [FIPS204]:

  • ML-DSA-44 : key_bits = 128

  • ML-DSA-65 : key_bits = 192

  • ML-DSA-87 : key_bits = 256

See also §4 in [FIPS204].

Compatible algorithms

Key format

Warning

The key format may change in a final version of this API. The standardization of exchange formats for ML-DSA public and private keys is in progress, but final documents have not been published. See Internet X.509 Public Key Infrastructure: Algorithm Identifiers for ML-DSA [LAMPS-MLDSA].

The current proposed format is based on the expected outcome of that process.

An ML-DSA key pair is the \((pk,sk)\) pair of public key and secret key, which are generated from a secret 32-byte seed, \(\xi\). See [FIPS204] §5.1.

In calls to psa_import_key() and psa_export_key(), the key-pair data format is the 32-byte seed \(\xi\).

Rationale

The IETF working group responsible for defining the format of the ML-DSA keys in SubjectPublicKeyInfo and OneAsymmetricKey structures is discussing the formats at present (September 2024), with the current consensus to using just the seed value as the private key, for the following reasons:

  • ML-DSA key pairs are several kB in size, but can be recomputed efficiently from the initial 32-byte seed.

  • There is no need to validate an imported ML-DSA private key — every 32-byte seed values is valid.

  • The public key cannot be derived from the secret key, so a key pair must store both the secret key and the public key. The size of the key pair depends on the ML-DSA parameter set as follows:

    Parameter set

    Key-pair size in bytes

    ML-DSA-44

    3872

    ML-DSA-65

    5984

    ML-DSA-87

    7488

  • It is better for the standard to choose a single format to improve interoperability.

See PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY for the data format used when exporting the public key with psa_export_public_key().

Implementation note

An implementation can optionally compute and store the \((pk,sk)\) values, to accelerate operations that use the key. It is recommended that an implementation retains the seed \(\xi\) with the key pair, in order to export the key, or copy the key to a different location.

Key derivation

A call to psa_key_derivation_output_key() will draw 32 bytes of output and use these as the 32-byte ML-DSA key-pair seed, \(\xi\). The key pair \((pk, sk)\) is generated from the seed as defined by ML-DSA.KeyGen_internal() in [FIPS204] §6.1.

Implementation note

It is implementation defined whether the seed \(\xi\) is expanded to \((pk, sk)\) at the point of derivation, or only just before the key is used.

PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY (macro)

ML-DSA public key.

Added in version 1.3.

#define PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY ((psa_key_type_t)0x4002)

The key attribute size of an ML-DSA public key is the same as the corresponding private key. See PSA_KEY_TYPE_ML_DSA_KEY_PAIR.

Compatible algorithms

Key format

Warning

The key format may change in a final version of this API. The standardization of exchange formats for ML-DSA public and private keys is in progress, but final documents have not been published. See Internet X.509 Public Key Infrastructure: Algorithm Identifiers for ML-DSA [LAMPS-MLDSA].

The current proposed format is based on the expected outcome of that process.

An ML-DSA public key is the \(pk\) output of ML-DSA.KeyGen(), defined in [FIPS204] §5.1.

In calls to psa_import_key(), psa_export_key(), and psa_export_public_key(), the public-key data format is \(pk\).

The size of the public key depends on the ML-DSA parameter set as follows:

Parameter set

Public-key size in bytes

ML-DSA-44

1312

ML-DSA-65

1952

ML-DSA-87

2592

PSA_KEY_TYPE_IS_ML_DSA (macro)

Whether a key type is an ML-DSA key, either a key pair or a public key.

Added in version 1.3.

#define PSA_KEY_TYPE_IS_ML_DSA(type) /* specification-defined value */

Parameters

type

A key type: a value of type psa_key_type_t.

2.3.2 Module Lattice-based signature algorithms

These algorithms extend those defined in PSA Certified Crypto API [PSA-CRYPT] §10.7 Asymmetric signature, for use with the signature functions.

The ML-DSA signature and verification scheme is defined in FIPS Publication 204: Module-Lattice-Based Digital Signature Standard [FIPS204]. ML-DSA has three parameter sets which provide differing security strengths.

ML-DSA keys are large: 1.2–2.5kB for the public key, and triple that for the key pair. ML-DSA signatures are much larger than those for RSA and Elliptic curve schemes, between 2.4kB and 4.6kB, depending on the selected parameter set.

See [FIPS204] §4 for details on the parameter sets, and the key and generated signature sizes.

The generation of an ML-DSA key depends on the full parameter specification. The encoding of each parameter set into the key attributes is described in Module Lattice-based signature keys.

[FIPS204] defines pure and pre-hashed variants of the signature scheme, which can either be hedged (randomized) or deterministic. Four algorithms are defined to support these variants: PSA_ALG_ML_DSA, PSA_ALG_DETERMINISTIC_ML_DSA, PSA_ALG_HASH_ML_DSA(), and PSA_ALG_DETERMINISTIC_HASH_ML_DSA().

Hedged and deterministic signatures

Hedging incorporates fresh randomness in the signature computation, resulting in distinct signatures on every signing operation when given identical inputs. Deterministic signatures do not require additional random data, and result in an identical signature for the same inputs.

Signature verification does not distinguish between a hedged and a deterministic signature. Either hedged or deterministic algorithms can be used when verifying a signature.

When computing a signature, the key’s permitted-algorithm policy must match the requested algorithm, treating hedged and deterministic versions as distinct. When verifying a signature, the hedged and deterministic versions of each algorithm are considered equivalent when checking the key’s permitted-algorithm policy.

Note

The hedged version provides message secrecy and some protection against side-channels. [FIPS204] recommends that users should use the hedged version if either of these issues are a concern. The deterministic variant should only be used if the implementation does not include any source of randomness.

Implementation note

[FIPS204] recommends that implementations use an approved random number generator to provide the random value in the hedged version. However, it notes that use of the hedged variant with a weak RNG is generally preferable to the deterministic variant.

Rationale

The use of fresh randomness, or not, when computing a signature seems like an implementation decision based on the capability of the system, and its vulnerability to specific threats, following the recommendations in [FIPS204].

However, the Crypto API gives distinct algorithm identifiers for the hedged and deterministic variants, to enable an application use case to require a specific variant.

Pure and pre-hashed algorithms

The pre-hashed signature computation HashML-DSA generates distinct signatures to a pure signature ML-DSA, with the same key and message hashing algorithm.

An ML-DSA signature can only be verified with an ML-DSA algorithm. A HashML-DSA signature can only be verified with a HashML-DSA algorithm.

Contexts

Contexts are not supported in the current version of this specification because there is no suitable signature interface that can take the context as a parameter. A empty context string is used when computing or verifying ML-DSA signatures.

A future version of this specification may add suitable functions and extend this algorithm to support contexts.

PSA_ALG_ML_DSA (macro)

Module lattice-based digital signature algorithm without pre-hashing (ML-DSA).

Added in version 1.3.

#define PSA_ALG_ML_DSA ((psa_algorithm_t) 0x06004400)

This algorithm can only be used with the psa_sign_message() and psa_verify_message() functions.

This is the pure ML-DSA digital signature algorithm, defined by FIPS Publication 204: Module-Lattice-Based Digital Signature Standard [FIPS204], using hedging. ML-DSA requires an ML-DSA key, which determines the ML-DSA parameter set for the operation.

This algorithm is randomized: each invocation returns a different, equally valid signature. See the notes on hedged signatures.

When PSA_ALG_ML_DSA is used as a permitted algorithm in a key policy, this permits:

Note

To sign or verify the pre-computed hash of a message using ML-DSA, the HashML-DSA algorithms (PSA_ALG_HASH_ML_DSA() and PSA_ALG_DETERMINISTIC_HASH_ML_DSA()) can also be used with psa_sign_hash() and psa_verify_hash().

The signature produced by HashML-DSA is distinct from that produced by ML-DSA.

Compatible key types

PSA_ALG_DETERMINISTIC_ML_DSA (macro)

Deterministic module lattice-based digital signature algorithm without pre-hashing (ML-DSA).

Added in version 1.3.

#define PSA_ALG_DETERMINISTIC_ML_DSA ((psa_algorithm_t) 0x06004500)

This algorithm can only be used with the psa_sign_message() and psa_verify_message() functions.

This is the pure ML-DSA digital signature algorithm, defined by FIPS Publication 204: Module-Lattice-Based Digital Signature Standard [FIPS204], without hedging. ML-DSA requires an ML-DSA key, which determines the ML-DSA parameter set for the operation.

This algorithm is deterministic: each invocation with the same inputs returns an identical signature.

Warning

It is recommended to use the hedged PSA_ALG_ML_DSA algorithm instead, when supported by the implementation. See the notes on deterministic signatures.

When PSA_ALG_DETERMINISTIC_ML_DSA is used as a permitted algorithm in a key policy, this permits:

Note

To sign or verify the pre-computed hash of a message using ML-DSA, the HashML-DSA algorithms (PSA_ALG_HASH_ML_DSA() and PSA_ALG_DETERMINISTIC_HASH_ML_DSA()) can also be used with psa_sign_hash() and psa_verify_hash().

The signature produced by HashML-DSA is distinct from that produced by ML-DSA.

Compatible key types

PSA_ALG_HASH_ML_DSA (macro)

Module lattice-based digital signature algorithm with pre-hashing (HashML-DSA).

Added in version 1.3.

#define PSA_ALG_HASH_ML_DSA(hash_alg) /* specification-defined value */

Parameters

hash_alg

A hash algorithm: a value of type psa_algorithm_t such that PSA_ALG_IS_HASH(hash_alg) is true. This includes PSA_ALG_ANY_HASH when specifying the algorithm in a key policy.

Returns

The corresponding HashML-DSA signature algorithm, using hash_alg to pre-hash the message.

Unspecified if hash_alg is not a supported hash algorithm.

Description

This algorithm can be used with both the message and hash signature functions.

This is the pre-hashed ML-DSA digital signature algorithm, defined by FIPS Publication 204: Module-Lattice-Based Digital Signature Standard [FIPS204], using hedging. ML-DSA requires an ML-DSA key, which determines the ML-DSA parameter set for the operation.

Note

For the pre-hashing, [FIPS204] §5.4 recommends the use of an approved hash function with an equivalent, or better, security strength than the chosen ML-DSA parameter set.

This algorithm is randomized: each invocation returns a different, equally valid signature. See the notes on hedged signatures.

When PSA_ALG_HASH_ML_DSA() is used as a permitted algorithm in a key policy, this permits:

Note

The signature produced by HashML-DSA is distinct from that produced by ML-DSA.

Usage

This is a hash-and-sign algorithm. To calculate a signature, use one of the following approaches:

  • Call psa_sign_message() with the message.

  • Calculate the hash of the message with psa_hash_compute(), or with a multi-part hash operation, using the hash_alg hash algorithm. Note that hash_alg can be extracted from the signature algorithm using PSA_ALG_GET_HASH(sig_alg). Then sign the calculated hash with psa_sign_hash().

Verifying a signature is similar, using psa_verify_message() or psa_verify_hash() instead of the signature function.

Compatible key types

PSA_ALG_DETERMINISTIC_HASH_ML_DSA (macro)

Deterministic module lattice-based digital signature algorithm with pre-hashing (HashML-DSA).

Added in version 1.3.

#define PSA_ALG_DETERMINISTIC_HASH_ML_DSA(hash_alg) \
    /* specification-defined value */

Parameters

hash_alg

A hash algorithm: a value of type psa_algorithm_t such that PSA_ALG_IS_HASH(hash_alg) is true. This includes PSA_ALG_ANY_HASH when specifying the algorithm in a key policy.

Returns

The corresponding deterministic HashML-DSA signature algorithm, using hash_alg to pre-hash the message.

Unspecified if hash_alg is not a supported hash algorithm.

Description

This algorithm can be used with both the message and hash signature functions.

This is the pre-hashed ML-DSA digital signature algorithm, defined by FIPS Publication 204: Module-Lattice-Based Digital Signature Standard [FIPS204], without hedging. ML-DSA requires an ML-DSA key, which determines the ML-DSA parameter set for the operation.

Note

For the pre-hashing, [FIPS204] §5.4 recommends the use of an approved hash function with an equivalent, or better, security strength than the chosen ML-DSA parameter set.

This algorithm is deterministic: each invocation with the same inputs returns an identical signature.

Warning

It is recommended to use the hedged PSA_ALG_HASH_ML_DSA() algorithm instead, when supported by the implementation. See the notes on deterministic signatures.

When PSA_ALG_DETERMINISTIC_HASH_ML_DSA() is used as a permitted algorithm in a key policy, this permits:

Note

The signature produced by HashML-DSA is distinct from that produced by ML-DSA.

Usage

See PSA_ALG_HASH_ML_DSA() for example usage.

Compatible key types

PSA_ALG_IS_ML_DSA (macro)

Whether the specified algorithm is ML-DSA, without pre-hashing.

Added in version 1.3.

#define PSA_ALG_IS_ML_DSA(alg) /* specification-defined value */

Parameters

alg

An algorithm identifier: a value of type psa_algorithm_t.

Returns

1 if alg is a pure ML-DSA algorithm, 0 otherwise.

This macro can return either 0 or 1 if alg is not a supported algorithm identifier.

Description

Note

Use PSA_ALG_IS_HASH_ML_DSA() to determine if an algorithm identifier is a HashML-DSA algorithm.

PSA_ALG_IS_HASH_ML_DSA (macro)

Whether the specified algorithm is HashML-DSA.

Added in version 1.3.

#define PSA_ALG_IS_HASH_ML_DSA(alg) /* specification-defined value */

Parameters

alg

An algorithm identifier: a value of type psa_algorithm_t.

Returns

1 if alg is a HashML-DSA algorithm, 0 otherwise.

This macro can return either 0 or 1 if alg is not a supported algorithm identifier.

Description

Note

Use PSA_ALG_IS_ML_DSA() to determine if an algorithm identifier is a pre-hashed ML-DSA algorithm.

PSA_ALG_IS_DETERMINISTIC_HASH_ML_DSA (macro)

Whether the specified algorithm is deterministic HashML-DSA.

Added in version 1.3.

#define PSA_ALG_IS_DETERMINISTIC_HASH_ML_DSA(alg) \
    /* specification-defined value */

Parameters

alg

An algorithm identifier: a value of type psa_algorithm_t.

Returns

1 if alg is a deterministic HashML-DSA algorithm, 0 otherwise.

This macro can return either 0 or 1 if alg is not a supported algorithm identifier.

Description

See also PSA_ALG_IS_HASH_ML_DSA() and PSA_ALG_IS_HEDGED_HASH_ML_DSA().

PSA_ALG_IS_HEDGED_HASH_ML_DSA (macro)

Whether the specified algorithm is hedged HashML-DSA.

Added in version 1.3.

#define PSA_ALG_IS_HEDGED_HASH_ML_DSA(alg) /* specification-defined value */

Parameters

alg

An algorithm identifier: a value of type psa_algorithm_t.

Returns

1 if alg is a hedged HashML-DSA algorithm, 0 otherwise.

This macro can return either 0 or 1 if alg is not a supported algorithm identifier.

Description

See also PSA_ALG_IS_HASH_ML_DSA() and PSA_ALG_IS_DETERMINISTIC_HASH_ML_DSA().