@@ -326,9 +326,26 @@ static int lc_dilithium_sign_avx2_internal(struct lc_dilithium_sig *sig,
326326 mu = rnd + LC_DILITHIUM_RNDBYTES ;
327327 rhoprime = mu + LC_DILITHIUM_CRHBYTES ;
328328
329- /* Compute CRH(tr, msg) */
330- lc_hash_set_digestsize (hash_ctx , LC_DILITHIUM_CRHBYTES );
331- lc_hash_final (hash_ctx , mu );
329+ /*
330+ * If the external mu is provided, use this verbatim, otherwise
331+ * calculate the mu value.
332+ */
333+ if (ctx -> external_mu ) {
334+ if (ctx -> external_mu_len != LC_DILITHIUM_CRHBYTES )
335+ return - EINVAL ;
336+ memcpy (mu , ctx -> external_mu , LC_DILITHIUM_CRHBYTES );
337+ } else {
338+ /*
339+ * Set the digestsize - for SHA512 this is a noop, for SHAKE256,
340+ * it sets the value. The BUILD_BUG_ON is to check that the
341+ * SHA-512 output size is identical to the expected length.
342+ */
343+ BUILD_BUG_ON (LC_DILITHIUM_CRHBYTES != LC_SHA3_512_SIZE_DIGEST );
344+
345+ /* Compute CRH(tr, msg) */
346+ lc_hash_set_digestsize (hash_ctx , LC_DILITHIUM_CRHBYTES );
347+ lc_hash_final (hash_ctx , mu );
348+ }
332349
333350 if (rng_ctx ) {
334351 CKINT (lc_rng_generate (rng_ctx , NULL , 0 , rnd ,
@@ -515,25 +532,31 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_ctx_avx2,
515532 uint8_t tr [LC_DILITHIUM_TRBYTES ];
516533 int ret = 0 ;
517534 static int tested = 0 ;
518- struct lc_hash_ctx * hash_ctx ;
519535
520536 /* rng_ctx is allowed to be NULL as handled below */
521- if (!sig || !m || !sk || !ctx )
537+ if (!sig || !sk || !ctx )
538+ return - EINVAL ;
539+ /* Either the message or the external mu must be provided */
540+ if (!m && !ctx -> external_mu )
522541 return - EINVAL ;
523542
524543 dilithium_siggen_tester (& tested , "Dilithium Siggen AVX2" ,
525544 lc_dilithium_sign_ctx_avx2 );
526545
527546 unpack_sk_tr_avx2 (tr , sk );
528547
529- /* Compute mu = CRH(tr, msg) */
530- hash_ctx = & ctx -> dilithium_hash_ctx ;
531- lc_hash_init (hash_ctx );
532- lc_hash_update (hash_ctx , tr , LC_DILITHIUM_TRBYTES );
533- CKINT (signature_domain_separation (
534- & ctx -> dilithium_hash_ctx , ctx -> ml_dsa_internal ,
535- ctx -> dilithium_prehash_type , ctx -> userctx , ctx -> userctxlen , m ,
536- mlen , LC_DILITHIUM_NIST_CATEGORY , !!ctx -> composite_ml_dsa ));
548+ if (m ) {
549+ /* Compute mu = CRH(tr, msg) */
550+ struct lc_hash_ctx * hash_ctx = & ctx -> dilithium_hash_ctx ;
551+
552+ lc_hash_init (hash_ctx );
553+ lc_hash_update (hash_ctx , tr , LC_DILITHIUM_TRBYTES );
554+ CKINT (signature_domain_separation (
555+ & ctx -> dilithium_hash_ctx , ctx -> ml_dsa_internal ,
556+ ctx -> dilithium_prehash_type , ctx -> userctx ,
557+ ctx -> userctxlen , m , mlen , LC_DILITHIUM_NIST_CATEGORY ,
558+ !!ctx -> composite_ml_dsa ));
559+ }
537560
538561 ret = lc_dilithium_sign_avx2_internal (sig , ctx , sk , rng_ctx );
539562
@@ -653,9 +676,6 @@ static int lc_dilithium_verify_avx2_internal(const struct lc_dilithium_sig *sig,
653676
654677 row = ws -> rowbuf ;
655678
656- lc_hash_set_digestsize (hash_ctx , LC_DILITHIUM_CRHBYTES );
657- lc_hash_final (hash_ctx , ws -> mu );
658-
659679 /* Expand challenge */
660680 poly_challenge_avx (& ws -> c , sig -> sig );
661681 poly_ntt_avx (& ws -> c );
@@ -720,9 +740,23 @@ static int lc_dilithium_verify_avx2_internal(const struct lc_dilithium_sig *sig,
720740 }
721741 }
722742
723- /* Call random oracle and verify challenge */
724- lc_hash_init (hash_ctx );
725- lc_hash_update (hash_ctx , ws -> mu , LC_DILITHIUM_CRHBYTES );
743+ if (ctx -> external_mu ) {
744+ if (ctx -> external_mu_len != LC_DILITHIUM_CRHBYTES )
745+ return - EINVAL ;
746+
747+ /* Call random oracle and verify challenge */
748+ lc_hash_init (hash_ctx );
749+ lc_hash_update (hash_ctx , ctx -> external_mu ,
750+ LC_DILITHIUM_CRHBYTES );
751+ } else {
752+ lc_hash_set_digestsize (hash_ctx , LC_DILITHIUM_CRHBYTES );
753+ lc_hash_final (hash_ctx , ws -> mu );
754+
755+ /* Call random oracle and verify challenge */
756+ lc_hash_init (hash_ctx );
757+ lc_hash_update (hash_ctx , ws -> mu , LC_DILITHIUM_CRHBYTES );
758+ }
759+
726760 lc_hash_update (hash_ctx , ws -> buf .coeffs ,
727761 LC_DILITHIUM_K * LC_DILITHIUM_POLYW1_PACKEDBYTES );
728762 lc_hash_set_digestsize (hash_ctx , LC_DILITHIUM_CTILDE_BYTES );
@@ -747,9 +781,11 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_ctx_avx2,
747781 uint8_t tr [LC_DILITHIUM_TRBYTES ];
748782 int ret = 0 ;
749783 static int tested = 0 ;
750- struct lc_hash_ctx * hash_ctx ;
751784
752- if (!sig || !m || !pk || !ctx )
785+ if (!sig || !pk || !ctx )
786+ return - EINVAL ;
787+ /* Either the message or the external mu must be provided */
788+ if (!m && !ctx -> external_mu )
753789 return - EINVAL ;
754790
755791 dilithium_sigver_tester (& tested , "Dilithium Sigver AVX2" ,
@@ -759,13 +795,16 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_ctx_avx2,
759795 lc_xof (lc_shake256 , pk -> pk , LC_DILITHIUM_PUBLICKEYBYTES , tr ,
760796 LC_DILITHIUM_TRBYTES );
761797
762- hash_ctx = & ctx -> dilithium_hash_ctx ;
763- lc_hash_init (hash_ctx );
764- lc_hash_update (hash_ctx , tr , LC_DILITHIUM_TRBYTES );
765- CKINT (signature_domain_separation (
766- & ctx -> dilithium_hash_ctx , ctx -> ml_dsa_internal ,
767- ctx -> dilithium_prehash_type , ctx -> userctx , ctx -> userctxlen , m ,
768- mlen , LC_DILITHIUM_NIST_CATEGORY , !!ctx -> composite_ml_dsa ));
798+ if (m ) {
799+ struct lc_hash_ctx * hash_ctx = & ctx -> dilithium_hash_ctx ;
800+ lc_hash_init (hash_ctx );
801+ lc_hash_update (hash_ctx , tr , LC_DILITHIUM_TRBYTES );
802+ CKINT (signature_domain_separation (
803+ & ctx -> dilithium_hash_ctx , ctx -> ml_dsa_internal ,
804+ ctx -> dilithium_prehash_type , ctx -> userctx ,
805+ ctx -> userctxlen , m , mlen , LC_DILITHIUM_NIST_CATEGORY ,
806+ !!ctx -> composite_ml_dsa ));
807+ }
769808
770809 ret = lc_dilithium_verify_avx2_internal (sig , pk , ctx );
771810
0 commit comments