Skip to content

Commit f2ed6f4

Browse files
committed
sign stack usage: Re-use y/h buffer
This commit is the second commit working towards bringing down the memory consumption of signature_internal. It combines the y and h buffer as those lifetime does not overlap. Signed-off-by: Matthias J. Kannwischer <[email protected]>
1 parent 86496ce commit f2ed6f4

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

mldsa/src/sign.c

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -446,17 +446,24 @@ __contract__(
446446
{
447447
MLD_ALIGN uint8_t challenge_bytes[MLDSA_CTILDEBYTES];
448448
unsigned int n;
449-
mld_polyvecl y, z;
450-
mld_polyveck w1, w0, h;
449+
mld_polyvecl z;
450+
mld_polyveck w1, w0;
451+
union
452+
{
453+
mld_polyvecl y;
454+
mld_polyveck h;
455+
} yh;
456+
mld_polyvecl *y = &yh.y;
457+
mld_polyveck *h = &yh.h;
451458
mld_poly cp;
452459
uint32_t z_invalid, w0_invalid, h_invalid;
453460
int res;
454461

455462
/* Sample intermediate vector y */
456-
mld_polyvecl_uniform_gamma1(&y, rhoprime, nonce);
463+
mld_polyvecl_uniform_gamma1(y, rhoprime, nonce);
457464

458465
/* Matrix-vector multiplication */
459-
z = y;
466+
z = *y;
460467
mld_polyvecl_ntt(&z);
461468
mld_polyvec_matrix_pointwise_montgomery(&w0, mat, &z);
462469
mld_polyveck_reduce(&w0);
@@ -480,7 +487,7 @@ __contract__(
480487
/* Compute z, reject if it reveals secret */
481488
mld_polyvecl_pointwise_poly_montgomery(&z, &cp, s1);
482489
mld_polyvecl_invntt_tomont(&z);
483-
mld_polyvecl_add(&z, &y);
490+
mld_polyvecl_add(&z, y);
484491
mld_polyvecl_reduce(&z);
485492

486493
z_invalid = mld_polyvecl_chknorm(&z, MLDSA_GAMMA1 - MLDSA_BETA);
@@ -503,9 +510,9 @@ __contract__(
503510

504511
/* Check that subtracting cs2 does not change high bits of w and low bits
505512
* do not reveal secret information */
506-
mld_polyveck_pointwise_poly_montgomery(&h, &cp, s2);
507-
mld_polyveck_invntt_tomont(&h);
508-
mld_polyveck_sub(&w0, &h);
513+
mld_polyveck_pointwise_poly_montgomery(h, &cp, s2);
514+
mld_polyveck_invntt_tomont(h);
515+
mld_polyveck_sub(&w0, h);
509516
mld_polyveck_reduce(&w0);
510517

511518
w0_invalid = mld_polyveck_chknorm(&w0, MLDSA_GAMMA2 - MLDSA_BETA);
@@ -518,20 +525,20 @@ __contract__(
518525
}
519526

520527
/* Compute hints for w1 */
521-
mld_polyveck_pointwise_poly_montgomery(&h, &cp, t0);
522-
mld_polyveck_invntt_tomont(&h);
523-
mld_polyveck_reduce(&h);
528+
mld_polyveck_pointwise_poly_montgomery(h, &cp, t0);
529+
mld_polyveck_invntt_tomont(h);
530+
mld_polyveck_reduce(h);
524531

525-
h_invalid = mld_polyveck_chknorm(&h, MLDSA_GAMMA2);
532+
h_invalid = mld_polyveck_chknorm(h, MLDSA_GAMMA2);
526533
/* Constant time: h_invalid may be leaked - see comment for z_invalid. */
527-
MLD_CT_TESTING_DECLASSIFY(&h_invalid, sizeof(uint32_t));
534+
MLD_CT_TESTING_DECLASSIFY(h_invalid, sizeof(uint32_t));
528535
if (h_invalid)
529536
{
530537
res = -1; /* reject */
531538
goto cleanup;
532539
}
533540

534-
mld_polyveck_add(&w0, &h);
541+
mld_polyveck_add(&w0, h);
535542

536543
/* Constant time: At this point all norm checks have passed and we, hence,
537544
* know that the signature does not leak any secret information.
@@ -543,7 +550,7 @@ __contract__(
543550
*/
544551
MLD_CT_TESTING_DECLASSIFY(&w0, sizeof(w0));
545552
MLD_CT_TESTING_DECLASSIFY(&w1, sizeof(w1));
546-
n = mld_polyveck_make_hint(&h, &w0, &w1);
553+
n = mld_polyveck_make_hint(h, &w0, &w1);
547554
if (n > MLDSA_OMEGA)
548555
{
549556
res = -1; /* reject */
@@ -553,20 +560,19 @@ __contract__(
553560
/* All is well - write signature */
554561
/* Constant time: At this point it is clear that the signature is valid - it
555562
* can, hence, be considered public. */
556-
MLD_CT_TESTING_DECLASSIFY(&h, sizeof(h));
563+
MLD_CT_TESTING_DECLASSIFY(h, sizeof(mld_polyveck));
557564
MLD_CT_TESTING_DECLASSIFY(&z, sizeof(z));
558-
mld_pack_sig(sig, challenge_bytes, &z, &h, n);
565+
mld_pack_sig(sig, challenge_bytes, &z, h, n);
559566

560567
res = 0; /* success */
561568

562569
cleanup:
563570
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
564571
mld_zeroize(challenge_bytes, MLDSA_CTILDEBYTES);
565-
mld_zeroize(&y, sizeof(y));
566572
mld_zeroize(&z, sizeof(z));
567573
mld_zeroize(&w1, sizeof(w1));
568574
mld_zeroize(&w0, sizeof(w0));
569-
mld_zeroize(&h, sizeof(h));
575+
mld_zeroize(&yh, sizeof(yh));
570576
mld_zeroize(&cp, sizeof(cp));
571577

572578
return res;

0 commit comments

Comments
 (0)