@@ -486,7 +486,7 @@ __contract__(
486486 return_value == MLD_ERR_OUT_OF_MEMORY )
487487)
488488{
489- unsigned int n ;
489+ unsigned int n , i ;
490490 uint32_t z_invalid , w0_invalid , h_invalid ;
491491 int ret ;
492492 /* TODO: Remove the following workaround for
@@ -495,34 +495,45 @@ __contract__(
495495 {
496496 mld_polyvecl y ;
497497 mld_polyveck h ;
498- }
499- yh_u ;
498+ } yh_u ;
500499 mld_polyvecl * y ;
501500 mld_polyveck * h ;
502501
502+ /* TODO: Remove the following workaround for
503+ * https://github.com/diffblue/cbmc/issues/8813 */
504+ typedef MLK_UNION_OR_STRUCT
505+ {
506+ mld_polyveck w1 ;
507+ mld_polyvecl tmp ;
508+ } w1tmp_u ;
509+ mld_polyveck * w1 ;
510+ mld_polyvecl * tmp ;
511+
503512 MLD_ALLOC (challenge_bytes , uint8_t , MLDSA_CTILDEBYTES );
504513 MLD_ALLOC (yh , yh_u , 1 );
505- MLD_ALLOC (z , mld_polyvecl , 1 );
506- MLD_ALLOC (w1 , mld_polyveck , 1 );
514+ MLD_ALLOC (z , mld_poly , 1 );
515+ MLD_ALLOC (w1tmp , w1tmp_u , 1 );
507516 MLD_ALLOC (w0 , mld_polyveck , 1 );
508517 MLD_ALLOC (cp , mld_poly , 1 );
509518
510- if (challenge_bytes == NULL || yh == NULL || z == NULL || w1 == NULL ||
519+ if (challenge_bytes == NULL || yh == NULL || z == NULL || w1tmp == NULL ||
511520 w0 == NULL || cp == NULL )
512521 {
513522 ret = MLD_ERR_OUT_OF_MEMORY ;
514523 goto cleanup ;
515524 }
516525 y = & yh -> y ;
517526 h = & yh -> h ;
527+ w1 = & w1tmp -> w1 ;
528+ tmp = & w1tmp -> tmp ;
518529
519530 /* Sample intermediate vector y */
520531 mld_polyvecl_uniform_gamma1 (y , rhoprime , nonce );
521532
522533 /* Matrix-vector multiplication */
523- * z = * y ;
524- mld_polyvecl_ntt (z );
525- mld_polyvec_matrix_pointwise_montgomery (w0 , mat , z );
534+ * tmp = * y ;
535+ mld_polyvecl_ntt (tmp );
536+ mld_polyvec_matrix_pointwise_montgomery (w0 , mat , tmp );
526537 mld_polyveck_reduce (w0 );
527538 mld_polyveck_invntt_tomont (w0 );
528539
@@ -541,31 +552,36 @@ __contract__(
541552 mld_poly_challenge (cp , challenge_bytes );
542553 mld_poly_ntt (cp );
543554
555+ ret = 0 ;
544556 /* Compute z, reject if it reveals secret */
545- mld_polyvecl_pointwise_poly_montgomery (z , cp , s1 );
546- mld_polyvecl_invntt_tomont (z );
547- mld_polyvecl_add (z , y );
548- mld_polyvecl_reduce (z );
549-
550- z_invalid = mld_polyvecl_chknorm (z , MLDSA_GAMMA1 - MLDSA_BETA );
551- /* Constant time: It is fine (and prohibitively expensive to avoid)
552- * leaking the result of the norm check. In case of rejection it
553- * would even be okay to leak which coefficient led to rejection
554- * as the candidate signature will be discarded anyway.
555- * See Section 5.5 of @[Round3_Spec]. */
556- MLD_CT_TESTING_DECLASSIFY (& z_invalid , sizeof (uint32_t ));
557- if (z_invalid )
558- {
559- ret = MLD_ERR_FAIL ; /* reject */
560- goto cleanup ;
557+ for (i = 0 ; i < MLDSA_L ; i ++ )
558+ __loop__ (
559+ invariant (i <= MLDSA_L ))
560+ {
561+ mld_poly_pointwise_montgomery (z , cp , & s1 -> vec [i ]);
562+ mld_poly_invntt_tomont (z );
563+ mld_poly_add (z , & y -> vec [i ]);
564+ mld_poly_reduce (z );
565+
566+ z_invalid = mld_poly_chknorm (z , MLDSA_GAMMA1 - MLDSA_BETA );
567+ /* Constant time: It is fine (and prohibitively expensive to avoid)
568+ * leaking the result of the norm check. In case of rejection it
569+ * would even be okay to leak which coefficient led to rejection
570+ * as the candidate signature will be discarded anyway.
571+ * See Section 5.5 of @[Round3_Spec]. */
572+ MLD_CT_TESTING_DECLASSIFY (& z_invalid , sizeof (uint32_t ));
573+ if (z_invalid )
574+ {
575+ ret = MLD_ERR_FAIL ; /* reject */
576+ goto cleanup ;
577+ }
578+ /* If z is valid, then its coefficients are bounded by */
579+ /* MLDSA_GAMMA1 - MLDSA_BETA. This will be needed below */
580+ /* to prove the pre-condition of pack_sig_z() */
581+ mld_assert_abs_bound (z , MLDSA_N , (MLDSA_GAMMA1 - MLDSA_BETA ));
582+ mld_pack_sig_z (sig , z , i );
561583 }
562584
563- /* If z is valid, then its coefficients are bounded by */
564- /* MLDSA_GAMMA1 - MLDSA_BETA. This will be needed below */
565- /* to prove the pre-condition of pack_sig() */
566- mld_assert_abs_bound_2d (z -> vec , MLDSA_L , MLDSA_N ,
567- (MLDSA_GAMMA1 - MLDSA_BETA ));
568-
569585 /* Check that subtracting cs2 does not change high bits of w and low bits
570586 * do not reveal secret information */
571587 mld_polyveck_pointwise_poly_montgomery (h , cp , s2 );
@@ -619,17 +635,16 @@ __contract__(
619635 /* Constant time: At this point it is clear that the signature is valid - it
620636 * can, hence, be considered public. */
621637 MLD_CT_TESTING_DECLASSIFY (h , sizeof (* h ));
622- MLD_CT_TESTING_DECLASSIFY (z , sizeof (* z ));
623- mld_pack_sig (sig , challenge_bytes , z , h , n );
638+ mld_pack_sig (sig , challenge_bytes , h , n );
624639
625640 ret = 0 ; /* success */
626641
627642cleanup :
628643 /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
629644 MLD_FREE (cp , mld_poly , 1 );
630645 MLD_FREE (w0 , mld_polyveck , 1 );
631- MLD_FREE (w1 , mld_polyveck , 1 );
632- MLD_FREE (z , mld_polyvecl , 1 );
646+ MLD_FREE (w1tmp , w1tmp_u , 1 );
647+ MLD_FREE (z , mld_poly , 1 );
633648 MLD_FREE (yh , yh_u , 1 );
634649 MLD_FREE (challenge_bytes , uint8_t , MLDSA_CTILDEBYTES );
635650
0 commit comments