Skip to content

Commit 79b7670

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

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 = 27456 / 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 = 35648 / 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_c_h
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 27456
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 35648
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
@@ -264,8 +264,8 @@
264264
#undef mld_pack_sig_c_h
265265
#undef mld_pack_sig_z
266266
#undef mld_pack_sk
267+
#undef mld_unpack_hints
267268
#undef mld_unpack_pk
268-
#undef mld_unpack_sig
269269
#undef mld_unpack_sk
270270
/* mldsa/src/params.h */
271271
#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
@@ -192,17 +191,9 @@ void mld_pack_sig_z(uint8_t sig[MLDSA_CRYPTO_BYTES], const mld_poly *zi,
192191
*
193192
* Returns 1 in case of malformed hints; otherwise 0.
194193
**************************************************/
195-
static int mld_unpack_hints(
196-
mld_polyveck *h, const uint8_t packed_hints[MLDSA_POLYVECH_PACKEDBYTES])
197-
__contract__(
198-
requires(memory_no_alias(packed_hints, MLDSA_POLYVECH_PACKEDBYTES))
199-
requires(memory_no_alias(h, sizeof(mld_polyveck)))
200-
assigns(memory_slice(h, sizeof(mld_polyveck)))
201-
/* All returned coefficients are either 0 or 1 */
202-
ensures(forall(k1, 0, MLDSA_K,
203-
array_bound(h->vec[k1].coeffs, 0, MLDSA_N, 0, 2)))
204-
ensures(return_value >= 0 && return_value <= 1)
205-
)
194+
MLD_INTERNAL_API
195+
int mld_unpack_hints(mld_polyveck *h,
196+
const uint8_t packed_hints[MLDSA_POLYVECH_PACKEDBYTES])
206197
{
207198
unsigned int i, j;
208199
unsigned int old_hint_count;
@@ -275,19 +266,5 @@ __contract__(
275266
return 0;
276267
}
277268

278-
MLD_INTERNAL_API
279-
int mld_unpack_sig(uint8_t c[MLDSA_CTILDEBYTES], mld_polyvecl *z,
280-
mld_polyveck *h, const uint8_t sig[MLDSA_CRYPTO_BYTES])
281-
{
282-
mld_memcpy(c, sig, MLDSA_CTILDEBYTES);
283-
sig += MLDSA_CTILDEBYTES;
284-
285-
mld_polyvecl_unpack_z(z, sig);
286-
sig += MLDSA_L * MLDSA_POLYZ_PACKEDBYTES;
287-
288-
return mld_unpack_hints(h, sig);
289-
}
290-
291269
/* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
292270
* Don't modify by hand -- this is auto-generated by scripts/autogen. */
293-
#undef mld_unpack_hints

mldsa/src/packing.h

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

196-
#define mld_unpack_sig MLD_NAMESPACE_KL(unpack_sig)
196+
#define mld_unpack_hints MLD_NAMESPACE_KL(unpack_hints)
197197
/*************************************************
198-
* Name: mld_unpack_sig
198+
* Name: mld_unpack_hints
199199
*
200-
* Description: Unpack signature sig = (c, z, h).
200+
* Description: Unpack hint vector h from packed hint bytes in signature.
201201
*
202-
* Arguments: - uint8_t *c: pointer to output challenge hash
203-
* - mld_polyvecl *z: pointer to output vector z
204-
* - mld_polyveck *h: pointer to output hint vector h
205-
* - const uint8_t sig[]: byte array containing
206-
* bit-packed signature
202+
* Arguments: - mld_polyveck *h: pointer to output hint vector
203+
* - const uint8_t *packed_hints: pointer to
204+
* raw hint bytes (MLDSA_POLYVECH_PACKEDBYTES)
207205
*
208-
* Returns 1 in case of malformed signature; otherwise 0.
206+
* Returns 1 in case of malformed hints; otherwise 0.
209207
**************************************************/
210208
MLD_INTERNAL_API
211209
MLD_MUST_CHECK_RETURN_VALUE
212-
int mld_unpack_sig(uint8_t c[MLDSA_CTILDEBYTES], mld_polyvecl *z,
213-
mld_polyveck *h, const uint8_t sig[MLDSA_CRYPTO_BYTES])
210+
int mld_unpack_hints(mld_polyveck *h,
211+
const uint8_t packed_hints[MLDSA_POLYVECH_PACKEDBYTES])
214212
__contract__(
215-
requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
216-
requires(memory_no_alias(c, MLDSA_CTILDEBYTES))
217-
requires(memory_no_alias(z, sizeof(mld_polyvecl)))
213+
requires(memory_no_alias(packed_hints, MLDSA_POLYVECH_PACKEDBYTES))
218214
requires(memory_no_alias(h, sizeof(mld_polyveck)))
219-
assigns(memory_slice(c, MLDSA_CTILDEBYTES))
220-
assigns(memory_slice(z, sizeof(mld_polyvecl)))
221215
assigns(memory_slice(h, sizeof(mld_polyveck)))
222-
ensures(forall(k0, 0, MLDSA_L,
223-
array_bound(z->vec[k0].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)))
224216
ensures(forall(k1, 0, MLDSA_K,
225217
array_bound(h->vec[k1].coeffs, 0, MLDSA_N, 0, 2)))
226218
ensures(return_value >= 0 && return_value <= 1)
227219
);
220+
228221
#endif /* !MLD_PACKING_H */

mldsa/src/sign.c

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,51 +1082,53 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
10821082
* https://github.com/diffblue/cbmc/issues/8813 */
10831083
typedef MLD_UNION_OR_STRUCT
10841084
{
1085+
mld_polyvecl z;
1086+
mld_poly cp;
1087+
}
1088+
zcp_u;
1089+
mld_polyvecl *z;
1090+
mld_poly *cp;
1091+
1092+
/* TODO: Remove the following workaround for
1093+
* https://github.com/diffblue/cbmc/issues/8813 */
1094+
typedef MLD_UNION_OR_STRUCT
1095+
{
1096+
mld_polymat mat;
10851097
mld_polyveck t1;
1086-
mld_polyveck w1;
1098+
mld_polyveck tmp;
1099+
mld_polyveck h;
10871100
}
1088-
t1w1_u;
1089-
mld_polyveck *t1;
1090-
mld_polyveck *w1;
1101+
reuse_u;
10911102

10921103
MLD_ALLOC(buf, uint8_t, (MLDSA_K * MLDSA_POLYW1_PACKEDBYTES), context);
10931104
MLD_ALLOC(rho, uint8_t, MLDSA_SEEDBYTES, context);
10941105
MLD_ALLOC(mu, uint8_t, MLDSA_CRHBYTES, context);
10951106
MLD_ALLOC(c, uint8_t, MLDSA_CTILDEBYTES, context);
10961107
MLD_ALLOC(c2, uint8_t, MLDSA_CTILDEBYTES, context);
1097-
MLD_ALLOC(cp, mld_poly, 1, context);
1098-
MLD_ALLOC(mat, mld_polymat, 1, context);
1099-
MLD_ALLOC(z, mld_polyvecl, 1, context);
1100-
MLD_ALLOC(t1w1, t1w1_u, 1, context);
1101-
MLD_ALLOC(tmp, mld_polyveck, 1, context);
1102-
MLD_ALLOC(h, mld_polyveck, 1, context);
1108+
MLD_ALLOC(zcp, zcp_u, 1, context);
1109+
MLD_ALLOC(w1, mld_polyveck, 1, context);
1110+
MLD_ALLOC(reuse, reuse_u, 1, context);
11031111

11041112
if (buf == NULL || rho == NULL || mu == NULL || c == NULL || c2 == NULL ||
1105-
cp == NULL || mat == NULL || z == NULL || t1w1 == NULL || tmp == NULL ||
1106-
h == NULL)
1113+
zcp == NULL || w1 == NULL || reuse == NULL)
11071114
{
11081115
ret = MLD_ERR_OUT_OF_MEMORY;
11091116
goto cleanup;
11101117
}
1111-
t1 = &t1w1->t1;
1112-
w1 = &t1w1->w1;
1118+
z = &zcp->z;
1119+
cp = &zcp->cp;
11131120

11141121
if (siglen != MLDSA_CRYPTO_BYTES)
11151122
{
11161123
ret = MLD_ERR_FAIL;
11171124
goto cleanup;
11181125
}
11191126

1120-
mld_unpack_pk(rho, t1, pk);
1127+
mld_memcpy(rho, pk, MLDSA_SEEDBYTES);
1128+
1129+
mld_memcpy(c, sig, MLDSA_CTILDEBYTES);
1130+
mld_polyvecl_unpack_z(z, sig + MLDSA_CTILDEBYTES);
11211131

1122-
/* mld_unpack_sig and mld_polyvecl_chknorm signal failure through a
1123-
* single non-zero error code that's not yet aligned with MLD_ERR_XXX.
1124-
* Map it to MLD_ERR_FAIL explicitly. */
1125-
if (mld_unpack_sig(c, z, h, sig))
1126-
{
1127-
ret = MLD_ERR_FAIL;
1128-
goto cleanup;
1129-
}
11301132
if (mld_polyvecl_chknorm(z, MLDSA_GAMMA1 - MLDSA_BETA))
11311133
{
11321134
ret = MLD_ERR_FAIL;
@@ -1151,23 +1153,31 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
11511153
}
11521154

11531155
/* Matrix-vector multiplication; compute Az - c2^dt1 */
1156+
mld_polyvecl_ntt(z);
1157+
mld_polyvec_matrix_expand(&reuse->mat, rho);
1158+
mld_polyvec_matrix_pointwise_montgomery(w1, &reuse->mat, z);
1159+
11541160
mld_poly_challenge(cp, c);
11551161
mld_poly_ntt(cp);
1156-
mld_polyveck_shiftl(t1);
1157-
mld_polyveck_ntt(t1);
1158-
mld_polyveck_pointwise_poly_montgomery(tmp, cp, t1);
1159-
1160-
mld_polyvec_matrix_expand(mat, rho);
1161-
mld_polyvecl_ntt(z);
1162-
mld_polyvec_matrix_pointwise_montgomery(w1, mat, z);
1163-
mld_polyveck_sub(w1, tmp);
1162+
mld_unpack_pk(rho, &reuse->t1, pk);
1163+
mld_polyveck_shiftl(&reuse->t1);
1164+
mld_polyveck_ntt(&reuse->t1);
1165+
mld_polyveck_pointwise_poly_montgomery(&reuse->tmp, cp, &reuse->t1);
1166+
mld_polyveck_sub(w1, &reuse->tmp);
11641167
mld_polyveck_reduce(w1);
11651168
mld_polyveck_invntt_tomont(w1);
11661169

11671170
/* Reconstruct w1 */
11681171
mld_polyveck_caddq(w1);
1169-
mld_polyveck_use_hint(tmp, w1, h);
1170-
mld_polyveck_pack_w1(buf, tmp);
1172+
if (mld_unpack_hints(&reuse->h, sig + MLDSA_CTILDEBYTES +
1173+
MLDSA_L * MLDSA_POLYZ_PACKEDBYTES))
1174+
{
1175+
ret = MLD_ERR_FAIL;
1176+
goto cleanup;
1177+
}
1178+
mld_polyveck_use_hint(&reuse->tmp, w1, &reuse->h);
1179+
mld_polyveck_pack_w1(buf, &reuse->tmp);
1180+
11711181
/* Call random oracle and verify challenge */
11721182
mld_H(c2, MLDSA_CTILDEBYTES, mu, MLDSA_CRHBYTES, buf,
11731183
MLDSA_K * MLDSA_POLYW1_PACKEDBYTES, NULL, 0);
@@ -1181,12 +1191,9 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
11811191

11821192
cleanup:
11831193
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
1184-
MLD_FREE(h, mld_polyveck, 1, context);
1185-
MLD_FREE(tmp, mld_polyveck, 1, context);
1186-
MLD_FREE(t1w1, t1w1_u, 1, context);
1187-
MLD_FREE(z, mld_polyvecl, 1, context);
1188-
MLD_FREE(mat, mld_polymat, 1, context);
1189-
MLD_FREE(cp, mld_poly, 1, context);
1194+
MLD_FREE(reuse, reuse_u, 1, context);
1195+
MLD_FREE(w1, mld_polyveck, 1, context);
1196+
MLD_FREE(zcp, zcp_u, 1, context);
11901197
MLD_FREE(c2, uint8_t, MLDSA_CTILDEBYTES, context);
11911198
MLD_FREE(c, uint8_t, MLDSA_CTILDEBYTES, context);
11921199
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)