Leancrypto 1.6.0
Post-Quantum Cryptographic Library
Loading...
Searching...
No Matches
ML-DSA / CRYSTALS-Dilithium Signature Mechanism

Functions

int lc_dilithium_ctx_alloc (struct lc_dilithium_ctx **ctx)
 Allocate stack memory for the Dilithium stream context and additional parameter relevant for the signature operation.
int lc_dilithium_ctx_alloc_ahat (struct lc_dilithium_ctx **ctx)
 Allocates Dilithium context on heap with support to keep the internal representation of the key.
void lc_dilithium_ctx_zero_free (struct lc_dilithium_ctx *ctx)
 Zeroizes and frees Dilithium context on heap.
void lc_dilithium_ctx_zero (struct lc_dilithium_ctx *ctx)
 Zeroizes Dilithium context either on heap or on stack.
void lc_dilithium_ctx_internal (struct lc_dilithium_ctx *ctx)
 Mark the Dilithium context to execute ML-DSA.Sign_internal / ML-DSA.Verify_internal.
void lc_dilithium_ctx_hash (struct lc_dilithium_ctx *ctx, const struct lc_hash *hash)
 Set the hash type that was used for pre-hashing the message. The message digest is used with the HashML-DSA. The message digest is to be provided via the message pointer in the sign/verify APIs.
void lc_dilithium_ctx_userctx (struct lc_dilithium_ctx *ctx, const uint8_t *userctx, size_t userctxlen)
 Specify the optional user context string to be applied with the Dilithium signature operation.
void lc_dilithium_ctx_external_mu (struct lc_dilithium_ctx *ctx, const uint8_t *external_mu, size_t external_mu_len)
 Specify the optional external mu value.
void lc_dilithium_ctx_drop_ahat (struct lc_dilithium_ctx *ctx)
 Invalidate the expanded key that potentially is stored in the context.
enum lc_dilithium_type lc_dilithium_sk_type (const struct lc_dilithium_sk *sk)
 Obtain Dilithium type from secret key.
enum lc_dilithium_type lc_dilithium_pk_type (const struct lc_dilithium_pk *pk)
 Obtain Dilithium type from public key.
enum lc_dilithium_type lc_dilithium_sig_type (const struct lc_dilithium_sig *sig)
 Obtain Dilithium type from signature.
LC_PURE unsigned int lc_dilithium_sk_size (enum lc_dilithium_type dilithium_type)
 Return the size of the Dilithium secret key.
LC_PURE unsigned int lc_dilithium_pk_size (enum lc_dilithium_type dilithium_type)
 Return the size of the Dilithium public key.
LC_PURE unsigned int lc_dilithium_sig_size (enum lc_dilithium_type dilithium_type)
 Return the size of the Dilithium signature.
int lc_dilithium_sk_load (struct lc_dilithium_sk *sk, const uint8_t *src_key, size_t src_key_len)
 Load a Dilithium secret key provided with a buffer into the leancrypto data structure.
int lc_dilithium_pk_load (struct lc_dilithium_pk *pk, const uint8_t *src_key, size_t src_key_len)
 Load a Dilithium public key provided with a buffer into the leancrypto data structure.
int lc_dilithium_sig_load (struct lc_dilithium_sig *sig, const uint8_t *src_sig, size_t src_sig_len)
 Load a Dilithium signature provided with a buffer into the leancrypto data structure.
int lc_dilithium_sk_ptr (uint8_t **dilithium_key, size_t *dilithium_key_len, struct lc_dilithium_sk *sk)
 Obtain the reference to the Dilithium key and its length.
int lc_dilithium_pk_ptr (uint8_t **dilithium_key, size_t *dilithium_key_len, struct lc_dilithium_pk *pk)
 Obtain the reference to the Dilithium key and its length.
int lc_dilithium_sig_ptr (uint8_t **dilithium_sig, size_t *dilithium_sig_len, struct lc_dilithium_sig *sig)
 Obtain the reference to the Dilithium signature and its length.
int lc_dilithium_keypair (struct lc_dilithium_pk *pk, struct lc_dilithium_sk *sk, struct lc_rng_ctx *rng_ctx, enum lc_dilithium_type dilithium_type)
 Generates Dilithium public and private key.
int lc_dilithium_keypair_from_seed (struct lc_dilithium_pk *pk, struct lc_dilithium_sk *sk, const uint8_t *seed, size_t seedlen, enum lc_dilithium_type dilithium_type)
 Generates Dilithium public and private key from a given seed.
int lc_dilithium_sign (struct lc_dilithium_sig *sig, const uint8_t *m, size_t mlen, const struct lc_dilithium_sk *sk, struct lc_rng_ctx *rng_ctx)
 Computes signature in one shot.
int lc_dilithium_sign_ctx (struct lc_dilithium_sig *sig, struct lc_dilithium_ctx *ctx, const uint8_t *m, size_t mlen, const struct lc_dilithium_sk *sk, struct lc_rng_ctx *rng_ctx)
 Computes signature woth user context in one shot.
int lc_dilithium_sign_init (struct lc_dilithium_ctx *ctx, const struct lc_dilithium_sk *sk)
 Initializes a signature operation.
int lc_dilithium_sign_update (struct lc_dilithium_ctx *ctx, const uint8_t *m, size_t mlen)
 Add more data to an already initialized signature state.
int lc_dilithium_sign_final (struct lc_dilithium_sig *sig, struct lc_dilithium_ctx *ctx, const struct lc_dilithium_sk *sk, struct lc_rng_ctx *rng_ctx)
 Computes signature.
int lc_dilithium_verify (const struct lc_dilithium_sig *sig, const uint8_t *m, size_t mlen, const struct lc_dilithium_pk *pk)
 Verifies signature in one shot.
int lc_dilithium_verify_ctx (const struct lc_dilithium_sig *sig, struct lc_dilithium_ctx *ctx, const uint8_t *m, size_t mlen, const struct lc_dilithium_pk *pk)
 Verifies signature with Dilithium context in one shot.
int lc_dilithium_verify_init (struct lc_dilithium_ctx *ctx, const struct lc_dilithium_pk *pk)
 Initializes a signature verification operation.
int lc_dilithium_verify_update (struct lc_dilithium_ctx *ctx, const uint8_t *m, size_t mlen)
 Add more data to an already initialized signature state.
int lc_dilithium_verify_final (const struct lc_dilithium_sig *sig, struct lc_dilithium_ctx *ctx, const struct lc_dilithium_pk *pk)
 Verifies signature.

Detailed Description

Note
Although the API uses the term "dilithium", the implementation complies with FIPS 204. Thus the terms Dilithium and ML-DSA are used interchangeably.

Dilithium API concept

The Dilithium API is accessible via the following header files with the mentioned purpose.

To support the stream mode of the Dilithium signature operation, a context structure is required. This context structure can be allocated either on the stack or heap with LC_DILITHIUM_CTX_ON_STACK or lc_dilithium_ctx_alloc. The context should be zeroized and freed (only for heap) with lc_dilithium_ctx_zero or lc_dilithium_ctx_zero_free.

Function Documentation

◆ lc_dilithium_ctx_alloc()

int lc_dilithium_ctx_alloc ( struct lc_dilithium_ctx ** ctx)

Allocate stack memory for the Dilithium stream context and additional parameter relevant for the signature operation.

In addition, the memory buffer returned by this allocation contains the space for an expanded representation of the public key which is required in both, signature generation and verification. When using this memory, the first signature operation expands the key and any subsequent operation using this context will re-use the expanded key which improves performance of the signature operation significantly.

As the same expanded structure is used for signature generation and verification and the structure can be expanded by either operation, it is perfectly legal to use one context for both operations as the expanded key can (a) be generated from either the public or the secret key and (b) it applies to both operations and (c) is identical irrespective it was generated from the public or secret key.

The provided context size is sufficiently large to support all ML-DSA key sizes this library version offers support for.

Note
: ML-DSA AVX2 signature operation uses a completely different algorithm which does not use a pre-pcomputed expanded key. Thus, if you know you have AVX2 support, you may not need this larger buffer and you can use LC_DILITHIUM_CTX_ON_STACK instead.
: The expanded representation only uses public key data. Even when deriving the expanded representation from a secret key, this data is only obtained from a part that is considered public. Thus, this memory does not require special protections. See FIPS 204 section 3.6.3 on the properties and handling requirements of the  matrix. Further, see the FIPS 204 ML-DSA.Sign_internal and ML-DSA.Verify_internal algorithm specification on how this  matrix is generated and that the input to the generation is public data.
Warning
: One instance of the expanded key representation can only ever apply to one given key (pair). If you want to reuse the context with multiple keys, you MUST invalidate the potentially present expanded key representation. Such invalidation is invoked with the method lc_dilithium_ctx_drop_ahat. Only after this invalidation you can use the context with a different key.

param [in] name Name of the stack variable

Allocates Dilithium context on heap

Parameters
[out]ctxDilithium context pointer
Returns
0 (success) or < 0 on error

◆ lc_dilithium_ctx_alloc_ahat()

int lc_dilithium_ctx_alloc_ahat ( struct lc_dilithium_ctx ** ctx)

Allocates Dilithium context on heap with support to keep the internal representation of the key.

Note
See LC_DILITHIUM_CTX_ON_STACK_AHAT for details.
Parameters
[out]ctxDilithium context pointer
Returns
0 (success) or < 0 on error

◆ lc_dilithium_ctx_drop_ahat()

void lc_dilithium_ctx_drop_ahat ( struct lc_dilithium_ctx * ctx)

Invalidate the expanded key that potentially is stored in the context.

This call can be executed on a context irrespective it was allocated with space for the expanded representation or not. Thus, the caller does not need to track whether the context supports the expanded key.

Parameters
[in]ctxDilithium context

◆ lc_dilithium_ctx_external_mu()

void lc_dilithium_ctx_external_mu ( struct lc_dilithium_ctx * ctx,
const uint8_t * external_mu,
size_t external_mu_len )

Specify the optional external mu value.

Note
If the external mu is specified, the signature generation / verification APIs do not require a message. In this case, the message buffer can be set to NULL.
If both a message and an external mu are provided, the external mu takes precedence.
Parameters
[in]ctxDilithium context
[in]external_muUser context string
[in]external_mu_lenSize of the user context string

◆ lc_dilithium_ctx_hash()

void lc_dilithium_ctx_hash ( struct lc_dilithium_ctx * ctx,
const struct lc_hash * hash )

Set the hash type that was used for pre-hashing the message. The message digest is used with the HashML-DSA. The message digest is to be provided via the message pointer in the sign/verify APIs.

Parameters
[in]ctxDilithium context
[in]hashHash context referencing the used hash for pre-hashing the message

◆ lc_dilithium_ctx_internal()

void lc_dilithium_ctx_internal ( struct lc_dilithium_ctx * ctx)

Mark the Dilithium context to execute ML-DSA.Sign_internal / ML-DSA.Verify_internal.

Parameters
[in]ctxDilithium context

◆ lc_dilithium_ctx_userctx()

void lc_dilithium_ctx_userctx ( struct lc_dilithium_ctx * ctx,
const uint8_t * userctx,
size_t userctxlen )

Specify the optional user context string to be applied with the Dilithium signature operation.

Parameters
[in]ctxDilithium context
[in]userctxUser context string
[in]userctxlenSize of the user context string

◆ lc_dilithium_ctx_zero()

void lc_dilithium_ctx_zero ( struct lc_dilithium_ctx * ctx)

Zeroizes Dilithium context either on heap or on stack.

Parameters
[out]ctxDilithium context pointer

◆ lc_dilithium_ctx_zero_free()

void lc_dilithium_ctx_zero_free ( struct lc_dilithium_ctx * ctx)

Zeroizes and frees Dilithium context on heap.

Parameters
[out]ctxDilithium context pointer

◆ lc_dilithium_keypair()

int lc_dilithium_keypair ( struct lc_dilithium_pk * pk,
struct lc_dilithium_sk * sk,
struct lc_rng_ctx * rng_ctx,
enum lc_dilithium_type dilithium_type )

Generates Dilithium public and private key.

Parameters
[out]pkpointer to allocated output public key
[out]skpointer to allocated output private key
[in]rng_ctxpointer to seeded random number generator context
[in]dilithium_typetype of the Dilithium key to generate
Returns
0 (success) or < 0 on error

◆ lc_dilithium_keypair_from_seed()

int lc_dilithium_keypair_from_seed ( struct lc_dilithium_pk * pk,
struct lc_dilithium_sk * sk,
const uint8_t * seed,
size_t seedlen,
enum lc_dilithium_type dilithium_type )

Generates Dilithium public and private key from a given seed.

The idea of the function is the allowance of FIPS 204 to maintain the seed used to generate a key pair in lieu of maintaining a private key or the key pair (which used much more memory). The seed must be treated equally sensitive as a private key.

The seed is generated by simply obtaining 32 bytes from a properly seeded DRNG, i.e. the same way as a symmetric key would be generated.

Parameters
[out]pkpointer to allocated output public key
[out]skpointer to allocated output private key
[in]seedbuffer with the seed data which must be exactly 32 bytes in size
[in]seedlenlength of the seed buffer
[in]dilithium_typetype of the Dilithium key to generate
Returns
0 (success) or < 0 on error

◆ lc_dilithium_pk_load()

int lc_dilithium_pk_load ( struct lc_dilithium_pk * pk,
const uint8_t * src_key,
size_t src_key_len )

Load a Dilithium public key provided with a buffer into the leancrypto data structure.

Parameters
[out]pkSecret key to be filled (the caller must have it allocated)
[in]src_keyBuffer that holds the key to be imported
[in]src_key_lenBuffer length that holds the key to be imported
Returns
0 on success or < 0 on error

◆ lc_dilithium_pk_ptr()

int lc_dilithium_pk_ptr ( uint8_t ** dilithium_key,
size_t * dilithium_key_len,
struct lc_dilithium_pk * pk )

Obtain the reference to the Dilithium key and its length.

Note
Only pointer references into the leancrypto data structure are returned which implies that any modification will modify the leancrypto key, too.
Parameters
[out]dilithium_keyDilithium key pointer
[out]dilithium_key_lenLength of the key buffer
[in]pkDilithium publi key from which the references are obtained
Returns
0 on success, != 0 on error

◆ lc_dilithium_pk_size()

LC_PURE unsigned int lc_dilithium_pk_size ( enum lc_dilithium_type dilithium_type)

Return the size of the Dilithium public key.

Parameters
[in]dilithium_typeDilithium type for which the size is requested
Returns
requested size

◆ lc_dilithium_pk_type()

enum lc_dilithium_type lc_dilithium_pk_type ( const struct lc_dilithium_pk * pk)

Obtain Dilithium type from public key.

Parameters
[in]pkPublic key from which the type is to be obtained
Returns
key type

◆ lc_dilithium_sig_load()

int lc_dilithium_sig_load ( struct lc_dilithium_sig * sig,
const uint8_t * src_sig,
size_t src_sig_len )

Load a Dilithium signature provided with a buffer into the leancrypto data structure.

Parameters
[out]sigSecret key to be filled (the caller must have it allocated)
[in]src_sigBuffer that holds the signature to be imported
[in]src_sig_lenBuffer length that holds the signature to be imported
Returns
0 on success or < 0 on error

◆ lc_dilithium_sig_ptr()

int lc_dilithium_sig_ptr ( uint8_t ** dilithium_sig,
size_t * dilithium_sig_len,
struct lc_dilithium_sig * sig )

Obtain the reference to the Dilithium signature and its length.

Note
Only pointer references into the leancrypto data structure are returned which implies that any modification will modify the leancrypto signature, too.
Parameters
[out]dilithium_sigDilithium signature pointer
[out]dilithium_sig_lenLength of the signature buffer
[in]sigDilithium signature from which the references are obtained
Returns
0 on success, != 0 on error

◆ lc_dilithium_sig_size()

LC_PURE unsigned int lc_dilithium_sig_size ( enum lc_dilithium_type dilithium_type)

Return the size of the Dilithium signature.

Parameters
[in]dilithium_typeDilithium type for which the size is requested
Returns
requested size

◆ lc_dilithium_sig_type()

enum lc_dilithium_type lc_dilithium_sig_type ( const struct lc_dilithium_sig * sig)

Obtain Dilithium type from signature.

Parameters
[in]sigSignature from which the type is to be obtained
Returns
key type

◆ lc_dilithium_sign()

int lc_dilithium_sign ( struct lc_dilithium_sig * sig,
const uint8_t * m,
size_t mlen,
const struct lc_dilithium_sk * sk,
struct lc_rng_ctx * rng_ctx )

Computes signature in one shot.

Parameters
[out]sigpointer to output signature
[in]mpointer to message to be signed
[in]mlenlength of message
[in]skpointer to bit-packed secret key
[in]rng_ctxpointer to seeded random number generator context - when pointer is non-NULL, perform a randomized signing. Otherwise use deterministic signing.
Returns
0 (success) or < 0 on error

◆ lc_dilithium_sign_ctx()

int lc_dilithium_sign_ctx ( struct lc_dilithium_sig * sig,
struct lc_dilithium_ctx * ctx,
const uint8_t * m,
size_t mlen,
const struct lc_dilithium_sk * sk,
struct lc_rng_ctx * rng_ctx )

Computes signature woth user context in one shot.

This API allows the caller to provide an arbitrary context buffer which is hashed together with the message to form the message digest to be signed.

Using the ctx structure, the caller can select 3 different types of ML-DSA:

  • ctx->dilithium_prehash_type set to a hash type, HashML-DSA is assumed which implies that the message m must be exactly digest size (FIPS 204 section 5.4)
  • ctx->ml_dsa_internal set to 1, the ML-DSA.Sign_internal and .Verify_internal are executed (FIPS 204 chapter 6)
  • both aforementioned parameter set to NULL / 0, ML-DSA.Sign and ML-DSA.Verify are executed (FIPS 204 sections 5.2 and 5.3)
Parameters
[out]sigpointer to output signature
[in]ctxreference to the allocated Dilithium context handle
[in]mpointer to message to be signed
[in]mlenlength of message
[in]skpointer to bit-packed secret key
[in]rng_ctxpointer to seeded random number generator context - when pointer is non-NULL, perform a randomized signing. Otherwise use deterministic signing.
Returns
0 (success) or < 0 on error

◆ lc_dilithium_sign_final()

int lc_dilithium_sign_final ( struct lc_dilithium_sig * sig,
struct lc_dilithium_ctx * ctx,
const struct lc_dilithium_sk * sk,
struct lc_rng_ctx * rng_ctx )

Computes signature.

Parameters
[out]sigpointer to output signature
[in]ctxpointer to Dilithium context that was initialized with lc_dilithium_sign_init and filled with lc_dilithium_sign_update
[in]skpointer to bit-packed secret key
[in]rng_ctxpointer to seeded random number generator context - when pointer is non-NULL, perform a randomized signing. Otherwise use deterministic signing.
Returns
0 (success) or < 0 on error

◆ lc_dilithium_sign_init()

int lc_dilithium_sign_init ( struct lc_dilithium_ctx * ctx,
const struct lc_dilithium_sk * sk )

Initializes a signature operation.

This call is intended to support messages that are located in non-contiguous places and even becomes available at different times. This call is to be used together with the lc_dilithium_sign_update and lc_dilithium_sign_final.

Parameters
[in,out]ctxpointer Dilithium context
[in]skpointer to bit-packed secret key
Returns
0 (success) or < 0 on error; -EOPNOTSUPP is returned if a different hash than lc_shake256 is used.

◆ lc_dilithium_sign_update()

int lc_dilithium_sign_update ( struct lc_dilithium_ctx * ctx,
const uint8_t * m,
size_t mlen )

Add more data to an already initialized signature state.

This call is intended to support messages that are located in non-contiguous places and even becomes available at different times. This call is to be used together with the lc_dilithium_sign_init and lc_dilithium_sign_final.

Parameters
[in]ctxpointer to Dilithium context that was initialized with lc_dilithium_sign_init
[in]mpointer to message to be signed
[in]mlenlength of message
Returns
0 (success) or < 0 on error

◆ lc_dilithium_sk_load()

int lc_dilithium_sk_load ( struct lc_dilithium_sk * sk,
const uint8_t * src_key,
size_t src_key_len )

Load a Dilithium secret key provided with a buffer into the leancrypto data structure.

Parameters
[out]skSecret key to be filled (the caller must have it allocated)
[in]src_keyBuffer that holds the key to be imported
[in]src_key_lenBuffer length that holds the key to be imported
Returns
0 on success or < 0 on error

◆ lc_dilithium_sk_ptr()

int lc_dilithium_sk_ptr ( uint8_t ** dilithium_key,
size_t * dilithium_key_len,
struct lc_dilithium_sk * sk )

Obtain the reference to the Dilithium key and its length.

Note
Only pointer references into the leancrypto data structure are returned which implies that any modification will modify the leancrypto key, too.
Parameters
[out]dilithium_keyDilithium key pointer
[out]dilithium_key_lenLength of the key buffer
[in]skDilithium secret key from which the references are obtained
Returns
0 on success, != 0 on error

◆ lc_dilithium_sk_size()

LC_PURE unsigned int lc_dilithium_sk_size ( enum lc_dilithium_type dilithium_type)

Return the size of the Dilithium secret key.

Parameters
[in]dilithium_typeDilithium type for which the size is requested
Returns
requested size

◆ lc_dilithium_sk_type()

enum lc_dilithium_type lc_dilithium_sk_type ( const struct lc_dilithium_sk * sk)

Obtain Dilithium type from secret key.

Parameters
[in]skSecret key from which the type is to be obtained
Returns
key type

◆ lc_dilithium_verify()

int lc_dilithium_verify ( const struct lc_dilithium_sig * sig,
const uint8_t * m,
size_t mlen,
const struct lc_dilithium_pk * pk )

Verifies signature in one shot.

Parameters
[in]sigpointer to input signature
[in]mpointer to message
[in]mlenlength of message
[in]pkpointer to bit-packed public key
Returns
0 if signature could be verified correctly and -EBADMSG when signature cannot be verified, < 0 on other errors

◆ lc_dilithium_verify_ctx()

int lc_dilithium_verify_ctx ( const struct lc_dilithium_sig * sig,
struct lc_dilithium_ctx * ctx,
const uint8_t * m,
size_t mlen,
const struct lc_dilithium_pk * pk )

Verifies signature with Dilithium context in one shot.

This API allows the caller to provide an arbitrary context buffer which is hashed together with the message to form the message digest to be signed.

Parameters
[in]sigpointer to input signature
[in]ctxreference to the allocated Dilithium context handle
[in]mpointer to message
[in]mlenlength of message
[in]pkpointer to bit-packed public key
Returns
0 if signature could be verified correctly and -EBADMSG when signature cannot be verified, < 0 on other errors

◆ lc_dilithium_verify_final()

int lc_dilithium_verify_final ( const struct lc_dilithium_sig * sig,
struct lc_dilithium_ctx * ctx,
const struct lc_dilithium_pk * pk )

Verifies signature.

Parameters
[in]sigpointer to output signature
[in]ctxpointer to Dilithium context that was initialized with lc_dilithium_sign_init and filled with lc_dilithium_sign_update
[in]pkpointer to bit-packed public key
Returns
0 if signature could be verified correctly and -EBADMSG when signature cannot be verified, < 0 on other errors

◆ lc_dilithium_verify_init()

int lc_dilithium_verify_init ( struct lc_dilithium_ctx * ctx,
const struct lc_dilithium_pk * pk )

Initializes a signature verification operation.

This call is intended to support messages that are located in non-contiguous places and even becomes available at different times. This call is to be used together with the lc_dilithium_verify_update and lc_dilithium_verify_final.

Parameters
[in,out]ctxpointer to an allocated Dilithium context
[in]pkpointer to bit-packed public key
Returns
0 (success) or < 0 on error; -EOPNOTSUPP is returned if a different hash than lc_shake256 is used.

◆ lc_dilithium_verify_update()

int lc_dilithium_verify_update ( struct lc_dilithium_ctx * ctx,
const uint8_t * m,
size_t mlen )

Add more data to an already initialized signature state.

This call is intended to support messages that are located in non-contiguous places and even becomes available at different times. This call is to be used together with the lc_dilithium_verify_init and lc_dilithium_verify_final.

Parameters
[in]ctxpointer to Dilithium context that was initialized with lc_dilithium_sign_init
[in]mpointer to message to be signed
[in]mlenlength of message
Returns
0 (success) or < 0 on error