ML-DSA: Add a digest that can calculate external mu.

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/29223)
This commit is contained in:
slontis
2025-11-26 17:42:43 +11:00
committed by Pauli
parent faf48d097b
commit 175cda569d
23 changed files with 878 additions and 54 deletions

View File

@@ -65,32 +65,29 @@ static void signature_init(ML_DSA_SIG *sig,
* @param ctx_len The size of |ctx|. It must be in the range 0..255
* @returns an EVP_MD_CTX if the operation is successful, NULL otherwise.
*/
EVP_MD_CTX *ossl_ml_dsa_mu_init(const ML_DSA_KEY *key, int encode,
EVP_MD_CTX *ossl_ml_dsa_mu_init_int(EVP_MD *shake256_md,
const uint8_t *tr, size_t tr_len, int encode, int prehash,
const uint8_t *ctx, size_t ctx_len)
{
EVP_MD_CTX *md_ctx;
uint8_t itb[2];
if (key == NULL)
return NULL;
md_ctx = EVP_MD_CTX_new();
if (md_ctx == NULL)
return NULL;
/* H(.. */
if (!EVP_DigestInit_ex2(md_ctx, key->shake256_md, NULL))
if (!EVP_DigestInit_ex2(md_ctx, shake256_md, NULL))
goto err;
/* ..pk (= key->tr) */
if (!EVP_DigestUpdate(md_ctx, key->tr, sizeof(key->tr)))
if (!EVP_DigestUpdate(md_ctx, tr, tr_len))
goto err;
/* M' = .. */
if (encode) {
if (ctx_len > ML_DSA_MAX_CONTEXT_STRING_LEN)
goto err;
/* IntegerToBytes(0, 1) .. */
itb[0] = 0;
itb[0] = prehash ? 1 : 0;
/* || IntegerToBytes(|ctx|, 1) || .. */
itb[1] = (uint8_t)ctx_len;
if (!EVP_DigestUpdate(md_ctx, itb, 2))
@@ -108,6 +105,15 @@ err:
return NULL;
}
EVP_MD_CTX *ossl_ml_dsa_mu_init(const ML_DSA_KEY *key, int encode,
const uint8_t *ctx, size_t ctx_len)
{
if (key == NULL)
return NULL;
return ossl_ml_dsa_mu_init_int(key->shake256_md, key->tr, sizeof(key->tr),
encode, 0, ctx, ctx_len);
}
/*
* @brief: updates the internal ML-DSA hash with an additional message chunk.
*
@@ -153,8 +159,7 @@ int ossl_ml_dsa_mu_finalize(EVP_MD_CTX *md_ctx, uint8_t *mu, size_t mu_len)
* @returns 1 on success, 0 on error
*/
static int ml_dsa_sign_internal(const ML_DSA_KEY *priv,
const uint8_t *mu, size_t mu_len,
const uint8_t *rnd, size_t rnd_len,
const uint8_t *mu, size_t mu_len, const uint8_t *rnd, size_t rnd_len,
uint8_t *out_sig)
{
int ret = 0;
@@ -315,8 +320,7 @@ err:
*/
static int ml_dsa_verify_internal(const ML_DSA_KEY *pub,
const uint8_t *mu, size_t mu_len,
const uint8_t *sig_enc,
size_t sig_enc_len)
const uint8_t *sig_enc, size_t sig_enc_len)
{
int ret = 0;
uint8_t *alloc = NULL, *w1_encoded;
@@ -412,8 +416,8 @@ err:
*
* @returns 1 on success, or 0 on error.
*/
int ossl_ml_dsa_sign(const ML_DSA_KEY *priv, int msg_is_mu,
const uint8_t *msg, size_t msg_len,
int ossl_ml_dsa_sign(const ML_DSA_KEY *priv,
int msg_is_mu, const uint8_t *msg, size_t msg_len,
const uint8_t *context, size_t context_len,
const uint8_t *rand, size_t rand_len, int encode,
unsigned char *sig, size_t *sig_len, size_t sig_size)
@@ -462,8 +466,8 @@ err:
* See FIPS 203 Section 5.3 Algorithm 3 ML-DSA.Verify()
* @returns 1 on success, or 0 on error.
*/
int ossl_ml_dsa_verify(const ML_DSA_KEY *pub, int msg_is_mu,
const uint8_t *msg, size_t msg_len,
int ossl_ml_dsa_verify(const ML_DSA_KEY *pub,
int msg_is_mu, const uint8_t *msg, size_t msg_len,
const uint8_t *context, size_t context_len, int encode,
const uint8_t *sig, size_t sig_len)
{