Skip to content

Commit e090aec

Browse files
committed
Lowram: Share buffers with non-overlapping lifetimes in verify
Signed-off-by: Matthias J. Kannwischer <matthias@zerorisc.com>
1 parent 6fd5e9c commit e090aec

File tree

10 files changed

+74
-164
lines changed

10 files changed

+74
-164
lines changed
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright (c) The mldsa-native project authors
22
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
33
diff --git a/sw/device/lib/crypto/include/mldsa.h b/sw/device/lib/crypto/include/mldsa.h
4-
index be11f20..26351ee 100644
4+
index be11f20..0000000 100644
55
--- a/sw/device/lib/crypto/include/mldsa.h
66
+++ b/sw/device/lib/crypto/include/mldsa.h
77
@@ -41,16 +41,16 @@ enum {
@@ -10,20 +10,23 @@ index be11f20..26351ee 100644
1010
// Work buffer sizes in 32-bit words
1111
- kOtcryptoMldsa44WorkBufferKeypairWords = 32992 / sizeof(uint32_t),
1212
- kOtcryptoMldsa44WorkBufferSignWords = 32448 / sizeof(uint32_t),
13+
- kOtcryptoMldsa44WorkBufferVerifyWords = 22464 / sizeof(uint32_t),
1314
+ kOtcryptoMldsa44WorkBufferKeypairWords = 28960 / sizeof(uint32_t),
1415
+ kOtcryptoMldsa44WorkBufferSignWords = 20256 / sizeof(uint32_t),
15-
kOtcryptoMldsa44WorkBufferVerifyWords = 22464 / sizeof(uint32_t),
16+
+ kOtcryptoMldsa44WorkBufferVerifyWords = 13248 / sizeof(uint32_t),
1617

1718
- kOtcryptoMldsa65WorkBufferKeypairWords = 46304 / sizeof(uint32_t),
1819
- kOtcryptoMldsa65WorkBufferSignWords = 44768 / sizeof(uint32_t),
20+
- kOtcryptoMldsa65WorkBufferVerifyWords = 30720 / sizeof(uint32_t),
1921
+ kOtcryptoMldsa65WorkBufferKeypairWords = 40224 / sizeof(uint32_t),
2022
+ kOtcryptoMldsa65WorkBufferSignWords = 26432 / sizeof(uint32_t),
21-
kOtcryptoMldsa65WorkBufferVerifyWords = 30720 / sizeof(uint32_t),
23+
+ kOtcryptoMldsa65WorkBufferVerifyWords = 18400 / sizeof(uint32_t),
2224

2325
- kOtcryptoMldsa87WorkBufferKeypairWords = 62688 / sizeof(uint32_t),
2426
- kOtcryptoMldsa87WorkBufferSignWords = 59104 / sizeof(uint32_t),
27+
- kOtcryptoMldsa87WorkBufferVerifyWords = 41216 / sizeof(uint32_t),
2528
+ kOtcryptoMldsa87WorkBufferKeypairWords = 54560 / sizeof(uint32_t),
2629
+ kOtcryptoMldsa87WorkBufferSignWords = 34624 / sizeof(uint32_t),
27-
kOtcryptoMldsa87WorkBufferVerifyWords = 41216 / sizeof(uint32_t),
30+
+ kOtcryptoMldsa87WorkBufferVerifyWords = 24800 / sizeof(uint32_t),
2831
};
2932

mldsa/mldsa_native.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@
261261
#undef mld_pack_sig_h_poly
262262
#undef mld_pack_sig_z
263263
#undef mld_pack_sk
264+
#undef mld_unpack_hints
264265
#undef mld_unpack_pk
265-
#undef mld_unpack_sig
266266
#undef mld_unpack_sk
267267
/* mldsa/src/params.h */
268268
#undef MLDSA_BETA

mldsa/mldsa_native.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -932,17 +932,17 @@ int MLD_API_NAMESPACE(pk_from_sk)(
932932
#define MLD_TOTAL_ALLOC_44_KEYPAIR_PCT 28960
933933
#define MLD_TOTAL_ALLOC_44_PK_FROM_SK 32992
934934
#define MLD_TOTAL_ALLOC_44_SIGN 20256
935-
#define MLD_TOTAL_ALLOC_44_VERIFY 22464
935+
#define MLD_TOTAL_ALLOC_44_VERIFY 13248
936936
#define MLD_TOTAL_ALLOC_65_KEYPAIR_NO_PCT 40224
937937
#define MLD_TOTAL_ALLOC_65_KEYPAIR_PCT 40224
938938
#define MLD_TOTAL_ALLOC_65_PK_FROM_SK 46304
939939
#define MLD_TOTAL_ALLOC_65_SIGN 26432
940-
#define MLD_TOTAL_ALLOC_65_VERIFY 30720
940+
#define MLD_TOTAL_ALLOC_65_VERIFY 18400
941941
#define MLD_TOTAL_ALLOC_87_KEYPAIR_NO_PCT 54560
942942
#define MLD_TOTAL_ALLOC_87_KEYPAIR_PCT 54560
943943
#define MLD_TOTAL_ALLOC_87_PK_FROM_SK 62688
944944
#define MLD_TOTAL_ALLOC_87_SIGN 34624
945-
#define MLD_TOTAL_ALLOC_87_VERIFY 41216
945+
#define MLD_TOTAL_ALLOC_87_VERIFY 24800
946946
#endif /* !(MLD_API_LEGACY_CONFIG || !MLD_CONFIG_REDUCE_RAM) */
947947
/* check-magic: on */
948948

mldsa/mldsa_native_asm.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@
266266
#undef mld_pack_sig_h_poly
267267
#undef mld_pack_sig_z
268268
#undef mld_pack_sk
269+
#undef mld_unpack_hints
269270
#undef mld_unpack_pk
270-
#undef mld_unpack_sig
271271
#undef mld_unpack_sk
272272
/* mldsa/src/params.h */
273273
#undef MLDSA_BETA

mldsa/src/packing.c

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
* This is to facilitate building multiple instances
1414
* of mldsa-native (e.g. with varying parameter sets)
1515
* within a single compilation unit. */
16-
#define mld_unpack_hints MLD_ADD_PARAM_SET(mld_unpack_hints)
1716
/* End of parameter set namespacing */
1817

1918
MLD_INTERNAL_API
@@ -168,17 +167,9 @@ void mld_pack_sig_z(uint8_t sig[MLDSA_CRYPTO_BYTES], const mld_poly *zi,
168167
*
169168
* Returns 1 in case of malformed hints; otherwise 0.
170169
**************************************************/
171-
static int mld_unpack_hints(
172-
mld_polyveck *h, const uint8_t packed_hints[MLDSA_POLYVECH_PACKEDBYTES])
173-
__contract__(
174-
requires(memory_no_alias(packed_hints, MLDSA_POLYVECH_PACKEDBYTES))
175-
requires(memory_no_alias(h, sizeof(mld_polyveck)))
176-
assigns(memory_slice(h, sizeof(mld_polyveck)))
177-
/* All returned coefficients are either 0 or 1 */
178-
ensures(forall(k1, 0, MLDSA_K,
179-
array_bound(h->vec[k1].coeffs, 0, MLDSA_N, 0, 2)))
180-
ensures(return_value >= 0 && return_value <= 1)
181-
)
170+
MLD_INTERNAL_API
171+
int mld_unpack_hints(mld_polyveck *h,
172+
const uint8_t packed_hints[MLDSA_POLYVECH_PACKEDBYTES])
182173
{
183174
unsigned int i, j;
184175
unsigned int old_hint_count;
@@ -251,19 +242,5 @@ __contract__(
251242
return 0;
252243
}
253244

254-
MLD_INTERNAL_API
255-
int mld_unpack_sig(uint8_t c[MLDSA_CTILDEBYTES], mld_polyvecl *z,
256-
mld_polyveck *h, const uint8_t sig[MLDSA_CRYPTO_BYTES])
257-
{
258-
mld_memcpy(c, sig, MLDSA_CTILDEBYTES);
259-
sig += MLDSA_CTILDEBYTES;
260-
261-
mld_polyvecl_unpack_z(z, sig);
262-
sig += MLDSA_L * MLDSA_POLYZ_PACKEDBYTES;
263-
264-
return mld_unpack_hints(h, sig);
265-
}
266-
267245
/* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
268246
* Don't modify by hand -- this is auto-generated by scripts/autogen. */
269-
#undef mld_unpack_hints

mldsa/src/packing.h

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -204,36 +204,29 @@ __contract__(
204204
array_abs_bound(s2->vec.vec[k2].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
205205
);
206206

207-
#define mld_unpack_sig MLD_NAMESPACE_KL(unpack_sig)
207+
#define mld_unpack_hints MLD_NAMESPACE_KL(unpack_hints)
208208
/*************************************************
209-
* Name: mld_unpack_sig
209+
* Name: mld_unpack_hints
210210
*
211-
* Description: Unpack signature sig = (c, z, h).
211+
* Description: Unpack hint vector h from packed hint bytes in signature.
212212
*
213-
* Arguments: - uint8_t *c: pointer to output challenge hash
214-
* - mld_polyvecl *z: pointer to output vector z
215-
* - mld_polyveck *h: pointer to output hint vector h
216-
* - const uint8_t sig[]: byte array containing
217-
* bit-packed signature
213+
* Arguments: - mld_polyveck *h: pointer to output hint vector
214+
* - const uint8_t *packed_hints: pointer to
215+
* raw hint bytes (MLDSA_POLYVECH_PACKEDBYTES)
218216
*
219-
* Returns 1 in case of malformed signature; otherwise 0.
217+
* Returns 1 in case of malformed hints; otherwise 0.
220218
**************************************************/
221219
MLD_INTERNAL_API
222220
MLD_MUST_CHECK_RETURN_VALUE
223-
int mld_unpack_sig(uint8_t c[MLDSA_CTILDEBYTES], mld_polyvecl *z,
224-
mld_polyveck *h, const uint8_t sig[MLDSA_CRYPTO_BYTES])
221+
int mld_unpack_hints(mld_polyveck *h,
222+
const uint8_t packed_hints[MLDSA_POLYVECH_PACKEDBYTES])
225223
__contract__(
226-
requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
227-
requires(memory_no_alias(c, MLDSA_CTILDEBYTES))
228-
requires(memory_no_alias(z, sizeof(mld_polyvecl)))
224+
requires(memory_no_alias(packed_hints, MLDSA_POLYVECH_PACKEDBYTES))
229225
requires(memory_no_alias(h, sizeof(mld_polyveck)))
230-
assigns(memory_slice(c, MLDSA_CTILDEBYTES))
231-
assigns(memory_slice(z, sizeof(mld_polyvecl)))
232226
assigns(memory_slice(h, sizeof(mld_polyveck)))
233-
ensures(forall(k0, 0, MLDSA_L,
234-
array_bound(z->vec[k0].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)))
235227
ensures(forall(k1, 0, MLDSA_K,
236228
array_bound(h->vec[k1].coeffs, 0, MLDSA_N, 0, 2)))
237229
ensures(return_value >= 0 && return_value <= 1)
238230
);
231+
239232
#endif /* !MLD_PACKING_H */

mldsa/src/sign.c

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,51 +1024,53 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
10241024
* https://github.com/diffblue/cbmc/issues/8813 */
10251025
typedef MLD_UNION_OR_STRUCT
10261026
{
1027+
mld_polyvecl z;
1028+
mld_poly cp;
1029+
}
1030+
zcp_u;
1031+
mld_polyvecl *z;
1032+
mld_poly *cp;
1033+
1034+
/* TODO: Remove the following workaround for
1035+
* https://github.com/diffblue/cbmc/issues/8813 */
1036+
typedef MLD_UNION_OR_STRUCT
1037+
{
1038+
mld_polymat mat;
10271039
mld_polyveck t1;
1028-
mld_polyveck w1;
1040+
mld_polyveck tmp;
1041+
mld_polyveck h;
10291042
}
1030-
t1w1_u;
1031-
mld_polyveck *t1;
1032-
mld_polyveck *w1;
1043+
reuse_u;
10331044

10341045
MLD_ALLOC(buf, uint8_t, (MLDSA_K * MLDSA_POLYW1_PACKEDBYTES), context);
10351046
MLD_ALLOC(rho, uint8_t, MLDSA_SEEDBYTES, context);
10361047
MLD_ALLOC(mu, uint8_t, MLDSA_CRHBYTES, context);
10371048
MLD_ALLOC(c, uint8_t, MLDSA_CTILDEBYTES, context);
10381049
MLD_ALLOC(c2, uint8_t, MLDSA_CTILDEBYTES, context);
1039-
MLD_ALLOC(cp, mld_poly, 1, context);
1040-
MLD_ALLOC(mat, mld_polymat, 1, context);
1041-
MLD_ALLOC(z, mld_polyvecl, 1, context);
1042-
MLD_ALLOC(t1w1, t1w1_u, 1, context);
1043-
MLD_ALLOC(tmp, mld_polyveck, 1, context);
1044-
MLD_ALLOC(h, mld_polyveck, 1, context);
1050+
MLD_ALLOC(zcp, zcp_u, 1, context);
1051+
MLD_ALLOC(w1, mld_polyveck, 1, context);
1052+
MLD_ALLOC(reuse, reuse_u, 1, context);
10451053

10461054
if (buf == NULL || rho == NULL || mu == NULL || c == NULL || c2 == NULL ||
1047-
cp == NULL || mat == NULL || z == NULL || t1w1 == NULL || tmp == NULL ||
1048-
h == NULL)
1055+
zcp == NULL || w1 == NULL || reuse == NULL)
10491056
{
10501057
ret = MLD_ERR_OUT_OF_MEMORY;
10511058
goto cleanup;
10521059
}
1053-
t1 = &t1w1->t1;
1054-
w1 = &t1w1->w1;
1060+
z = &zcp->z;
1061+
cp = &zcp->cp;
10551062

10561063
if (siglen != MLDSA_CRYPTO_BYTES)
10571064
{
10581065
ret = MLD_ERR_FAIL;
10591066
goto cleanup;
10601067
}
10611068

1062-
mld_unpack_pk(rho, t1, pk);
1069+
mld_memcpy(rho, pk, MLDSA_SEEDBYTES);
1070+
1071+
mld_memcpy(c, sig, MLDSA_CTILDEBYTES);
1072+
mld_polyvecl_unpack_z(z, sig + MLDSA_CTILDEBYTES);
10631073

1064-
/* mld_unpack_sig and mld_polyvecl_chknorm signal failure through a
1065-
* single non-zero error code that's not yet aligned with MLD_ERR_XXX.
1066-
* Map it to MLD_ERR_FAIL explicitly. */
1067-
if (mld_unpack_sig(c, z, h, sig))
1068-
{
1069-
ret = MLD_ERR_FAIL;
1070-
goto cleanup;
1071-
}
10721074
if (mld_polyvecl_chknorm(z, MLDSA_GAMMA1 - MLDSA_BETA))
10731075
{
10741076
ret = MLD_ERR_FAIL;
@@ -1093,23 +1095,31 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
10931095
}
10941096

10951097
/* Matrix-vector multiplication; compute Az - c2^dt1 */
1098+
mld_polyvecl_ntt(z);
1099+
mld_polyvec_matrix_expand(&reuse->mat, rho);
1100+
mld_polyvec_matrix_pointwise_montgomery(w1, &reuse->mat, z);
1101+
10961102
mld_poly_challenge(cp, c);
10971103
mld_poly_ntt(cp);
1098-
mld_polyveck_shiftl(t1);
1099-
mld_polyveck_ntt(t1);
1100-
mld_polyveck_pointwise_poly_montgomery(tmp, cp, t1);
1101-
1102-
mld_polyvec_matrix_expand(mat, rho);
1103-
mld_polyvecl_ntt(z);
1104-
mld_polyvec_matrix_pointwise_montgomery(w1, mat, z);
1105-
mld_polyveck_sub(w1, tmp);
1104+
mld_unpack_pk(rho, &reuse->t1, pk);
1105+
mld_polyveck_shiftl(&reuse->t1);
1106+
mld_polyveck_ntt(&reuse->t1);
1107+
mld_polyveck_pointwise_poly_montgomery(&reuse->tmp, cp, &reuse->t1);
1108+
mld_polyveck_sub(w1, &reuse->tmp);
11061109
mld_polyveck_reduce(w1);
11071110
mld_polyveck_invntt_tomont(w1);
11081111

11091112
/* Reconstruct w1 */
11101113
mld_polyveck_caddq(w1);
1111-
mld_polyveck_use_hint(tmp, w1, h);
1112-
mld_polyveck_pack_w1(buf, tmp);
1114+
if (mld_unpack_hints(&reuse->h, sig + MLDSA_CTILDEBYTES +
1115+
MLDSA_L * MLDSA_POLYZ_PACKEDBYTES))
1116+
{
1117+
ret = MLD_ERR_FAIL;
1118+
goto cleanup;
1119+
}
1120+
mld_polyveck_use_hint(&reuse->tmp, w1, &reuse->h);
1121+
mld_polyveck_pack_w1(buf, &reuse->tmp);
1122+
11131123
/* Call random oracle and verify challenge */
11141124
mld_H(c2, MLDSA_CTILDEBYTES, mu, MLDSA_CRHBYTES, buf,
11151125
MLDSA_K * MLDSA_POLYW1_PACKEDBYTES, NULL, 0);
@@ -1123,12 +1133,9 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
11231133

11241134
cleanup:
11251135
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
1126-
MLD_FREE(h, mld_polyveck, 1, context);
1127-
MLD_FREE(tmp, mld_polyveck, 1, context);
1128-
MLD_FREE(t1w1, t1w1_u, 1, context);
1129-
MLD_FREE(z, mld_polyvecl, 1, context);
1130-
MLD_FREE(mat, mld_polymat, 1, context);
1131-
MLD_FREE(cp, mld_poly, 1, context);
1136+
MLD_FREE(reuse, reuse_u, 1, context);
1137+
MLD_FREE(w1, mld_polyveck, 1, context);
1138+
MLD_FREE(zcp, zcp_u, 1, context);
11321139
MLD_FREE(c2, uint8_t, MLDSA_CTILDEBYTES, context);
11331140
MLD_FREE(c, uint8_t, MLDSA_CTILDEBYTES, context);
11341141
MLD_FREE(mu, uint8_t, MLDSA_CRHBYTES, context);

proofs/cbmc/sign_verify_internal/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ PROJECT_SOURCES += $(SRCDIR)/mldsa/src/sign.c
2121

2222
CHECK_FUNCTION_CONTRACTS=mld_verify_internal
2323
USE_FUNCTION_CONTRACTS=mld_unpack_pk
24-
USE_FUNCTION_CONTRACTS+=mld_unpack_sig
24+
USE_FUNCTION_CONTRACTS+=mld_polyvecl_unpack_z
2525
USE_FUNCTION_CONTRACTS+=mld_polyvecl_chknorm
26+
USE_FUNCTION_CONTRACTS+=mld_unpack_hints
2627
USE_FUNCTION_CONTRACTS+=mld_H
2728
USE_FUNCTION_CONTRACTS+=mld_poly_challenge
2829
USE_FUNCTION_CONTRACTS+=mld_polyvec_matrix_expand

proofs/cbmc/unpack_sig/Makefile

Lines changed: 0 additions & 56 deletions
This file was deleted.

proofs/cbmc/unpack_sig/unpack_sig_harness.c

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)