Skip to content

Commit 1fa9c2c

Browse files
committed
sign stack usage: compute z incrementally
40448 -> 34304 Signed-off-by: Matthias J. Kannwischer <[email protected]>
1 parent 7a35665 commit 1fa9c2c

File tree

3 files changed

+65
-40
lines changed

3 files changed

+65
-40
lines changed

mldsa/src/packing.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,26 @@ void mld_unpack_sk(uint8_t rho[MLDSA_SEEDBYTES], uint8_t tr[MLDSA_TRBYTES],
9090
// mld_polyveck_unpack_t0(t0, sk);
9191
}
9292

93+
MLD_INTERNAL_API
94+
void mld_pack_sig_z(uint8_t sig[MLDSA_CRYPTO_BYTES], const mld_poly *z,
95+
unsigned i)
96+
{
97+
sig += MLDSA_CTILDEBYTES;
98+
sig += i * MLDSA_POLYZ_PACKEDBYTES;
99+
mld_polyz_pack(sig, z);
100+
}
101+
93102
MLD_INTERNAL_API
94103
void mld_pack_sig(uint8_t sig[MLDSA_CRYPTO_BYTES],
95-
const uint8_t c[MLDSA_CTILDEBYTES], const mld_polyvecl *z,
96-
const mld_polyveck *h, const unsigned int number_of_hints)
104+
const uint8_t c[MLDSA_CTILDEBYTES], const mld_polyveck *h,
105+
const unsigned int number_of_hints)
97106
{
98107
unsigned int i, j, k;
99108

100109
mld_memcpy(sig, c, MLDSA_CTILDEBYTES);
101110
sig += MLDSA_CTILDEBYTES;
102111

103-
mld_polyvecl_pack_z(sig, z);
112+
// mld_polyvecl_pack_z(sig, z);
104113
sig += MLDSA_L * MLDSA_POLYZ_PACKEDBYTES;
105114

106115
/* Encode hints h */

mldsa/src/packing.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,13 @@ __contract__(
6969
);
7070

7171

72+
#define mld_pack_sig_z MLD_NAMESPACE_KL(pack_sig_z)
73+
MLD_INTERNAL_API
74+
void mld_pack_sig_z(uint8_t sig[MLDSA_CRYPTO_BYTES], const mld_poly *z,
75+
unsigned i);
76+
7277
#define mld_pack_sig MLD_NAMESPACE_KL(pack_sig)
78+
7379
/*************************************************
7480
* Name: mld_pack_sig
7581
*
@@ -89,8 +95,8 @@ __contract__(
8995
**************************************************/
9096
MLD_INTERNAL_API
9197
void mld_pack_sig(uint8_t sig[MLDSA_CRYPTO_BYTES],
92-
const uint8_t c[MLDSA_CTILDEBYTES], const mld_polyvecl *z,
93-
const mld_polyveck *h, const unsigned int number_of_hints)
98+
const uint8_t c[MLDSA_CTILDEBYTES], const mld_polyveck *h,
99+
const unsigned int number_of_hints)
94100
__contract__(
95101
requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
96102
requires(memory_no_alias(c, MLDSA_CTILDEBYTES))

mldsa/src/sign.c

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -444,13 +444,18 @@ __contract__(
444444
)
445445
{
446446
MLD_ALIGN uint8_t challenge_bytes[MLDSA_CTILDEBYTES];
447-
unsigned int n;
447+
unsigned int n, i;
448448
union
449449
{
450-
mld_polyvecl z;
451-
mld_polyvecl s1;
450+
mld_poly z;
451+
mld_poly s1;
452452
} zs1;
453-
mld_polyveck w1, w0;
453+
mld_polyveck w0;
454+
union
455+
{
456+
mld_polyveck w1;
457+
mld_polyvecl tmp;
458+
} w1tmp;
454459

455460
union
456461
{
@@ -468,16 +473,16 @@ __contract__(
468473
mld_polyvecl_uniform_gamma1(&yht0s2.y, rhoprime, nonce);
469474

470475
/* Matrix-vector multiplication */
471-
zs1.z = yht0s2.y;
472-
mld_polyvecl_ntt(&zs1.z);
473-
mld_polyvec_matrix_pointwise_montgomery(&w0, mat, &zs1.z);
476+
w1tmp.tmp = yht0s2.y;
477+
mld_polyvecl_ntt(&w1tmp.tmp);
478+
mld_polyvec_matrix_pointwise_montgomery(&w0, mat, &w1tmp.tmp);
474479
mld_polyveck_reduce(&w0);
475480
mld_polyveck_invntt_tomont(&w0);
476481

477482
/* Decompose w and call the random oracle */
478483
mld_polyveck_caddq(&w0);
479-
mld_polyveck_decompose(&w1, &w0);
480-
mld_polyveck_pack_w1(sig, &w1);
484+
mld_polyveck_decompose(&w1tmp.w1, &w0);
485+
mld_polyveck_pack_w1(sig, &w1tmp.w1);
481486

482487
mld_H(challenge_bytes, MLDSA_CTILDEBYTES, mu, MLDSA_CRHBYTES, sig,
483488
MLDSA_K * MLDSA_POLYW1_PACKEDBYTES, NULL, 0);
@@ -490,31 +495,36 @@ __contract__(
490495
mld_poly_ntt(&cp);
491496

492497
/* Compute z, reject if it reveals secret */
493-
mld_polyvecl_unpack_eta(
494-
&zs1.s1, sk + MLDSA_SEEDBYTES + MLDSA_SEEDBYTES + MLDSA_TRBYTES);
495-
mld_polyvecl_ntt(&zs1.s1);
496-
mld_polyvecl_pointwise_poly_montgomery(&zs1.z, &cp, &zs1.s1);
497-
mld_polyvecl_invntt_tomont(&zs1.z);
498-
mld_polyvecl_add(&zs1.z, &yht0s2.y);
499-
mld_polyvecl_reduce(&zs1.z);
500-
501-
z_invalid = mld_polyvecl_chknorm(&zs1.z, MLDSA_GAMMA1 - MLDSA_BETA);
502-
/* Constant time: It is fine (and prohibitively expensive to avoid)
503-
* leaking the result of the norm check. In case of rejection it
504-
* would even be okay to leak which coefficient led to rejection
505-
* as the candidate signature will be discarded anyway.
506-
* See Section 5.5 of @[Round3_Spec]. */
507-
MLD_CT_TESTING_DECLASSIFY(&z_invalid, sizeof(uint32_t));
508-
if (z_invalid)
498+
for (i = 0; i < MLDSA_L; i++)
509499
{
510-
res = -1; /* reject */
511-
goto cleanup;
512-
}
500+
mld_polyeta_unpack(&zs1.s1, sk + MLDSA_SEEDBYTES + MLDSA_SEEDBYTES +
501+
MLDSA_TRBYTES +
502+
i * MLDSA_POLYETA_PACKEDBYTES);
503+
mld_poly_ntt(&zs1.s1);
504+
mld_poly_pointwise_montgomery(&zs1.z, &cp, &zs1.s1);
505+
mld_poly_invntt_tomont(&zs1.z);
506+
mld_poly_add(&zs1.z, &yht0s2.y.vec[i]);
507+
mld_poly_reduce(&zs1.z);
508+
509+
z_invalid = mld_poly_chknorm(&zs1.z, MLDSA_GAMMA1 - MLDSA_BETA);
510+
/* Constant time: It is fine (and prohibitively expensive to avoid)
511+
* leaking the result of the norm check. In case of rejection it
512+
* would even be okay to leak which coefficient led to rejection
513+
* as the candidate signature will be discarded anyway.
514+
* See Section 5.5 of @[Round3_Spec]. */
515+
MLD_CT_TESTING_DECLASSIFY(&z_invalid, sizeof(uint32_t));
516+
if (z_invalid)
517+
{
518+
res = -1; /* reject */
519+
goto cleanup;
520+
}
513521

514-
/* If z is valid, then its coefficients are bounded by */
515-
/* MLDSA_GAMMA1 - MLDSA_BETA. This will be needed below */
516-
/* to prove the pre-condition of pack_sig() */
517-
mld_assert_abs_bound_2d(z.vec, MLDSA_L, MLDSA_N, (MLDSA_GAMMA1 - MLDSA_BETA));
522+
/* If z is valid, then its coefficients are bounded by */
523+
/* MLDSA_GAMMA1 - MLDSA_BETA. This will be needed below */
524+
/* to prove the pre-condition of pack_sig() */
525+
mld_assert_abs_bound(&zs1.z, MLDSA_N, (MLDSA_GAMMA1 - MLDSA_BETA));
526+
mld_pack_sig_z(sig, &zs1.z, i);
527+
}
518528

519529
/* Check that subtracting cs2 does not change high bits of w and low bits
520530
* do not reveal secret information */
@@ -568,7 +578,7 @@ __contract__(
568578
*/
569579
MLD_CT_TESTING_DECLASSIFY(&w0, sizeof(w0));
570580
MLD_CT_TESTING_DECLASSIFY(&w1, sizeof(w1));
571-
n = mld_polyveck_make_hint(&yht0s2.h, &w0, &w1);
581+
n = mld_polyveck_make_hint(&yht0s2.h, &w0, &w1tmp.w1);
572582
if (n > MLDSA_OMEGA)
573583
{
574584
res = -1; /* reject */
@@ -580,16 +590,16 @@ __contract__(
580590
* can, hence, be considered public. */
581591
MLD_CT_TESTING_DECLASSIFY(&h, sizeof(h));
582592
MLD_CT_TESTING_DECLASSIFY(&zs1.z, sizeof(mld_polyvecl));
583-
mld_pack_sig(sig, challenge_bytes, &zs1.z, &yht0s2.h, n);
593+
mld_pack_sig(sig, challenge_bytes, &yht0s2.h, n);
584594

585595
res = 0; /* success */
586596

587597
cleanup:
588598
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
589599
mld_zeroize(challenge_bytes, MLDSA_CTILDEBYTES);
590600
mld_zeroize(&zs1, sizeof(zs1));
591-
mld_zeroize(&w1, sizeof(w1));
592601
mld_zeroize(&w0, sizeof(w0));
602+
mld_zeroize(&w1tmp, sizeof(w1tmp));
593603
mld_zeroize(&yht0s2, sizeof(yht0s2));
594604
mld_zeroize(&cp, sizeof(cp));
595605

0 commit comments

Comments
 (0)