Skip to content

Commit 86374eb

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

11 files changed

Lines changed: 102 additions & 160 deletions

File tree

.github/workflows/integration-opentitan.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ jobs:
8080
echo "=== Patched extensions.bzl ==="
8181
cat third_party/mldsa_native/extensions.bzl
8282
83+
- name: Apply integration patches
84+
run: |
85+
cd "$EXPO_DIR"
86+
for patch in "$GITHUB_WORKSPACE"/integration/opentitan/*.patch; do
87+
if [ -f "$patch" ]; then
88+
echo "Applying $patch"
89+
git apply "$patch"
90+
fi
91+
done
92+
8393
- name: Build mldsa functest
8494
run: |
8595
cd "$EXPO_DIR"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright (c) The mldsa-native project authors
2+
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
3+
diff --git a/sw/device/lib/crypto/include/mldsa.h b/sw/device/lib/crypto/include/mldsa.h
4+
index be11f20..dccb52c 100644
5+
--- a/sw/device/lib/crypto/include/mldsa.h
6+
+++ b/sw/device/lib/crypto/include/mldsa.h
7+
@@ -43,15 +43,15 @@ enum {
8+
// Work buffer sizes in 32-bit words
9+
kOtcryptoMldsa44WorkBufferKeypairWords = 32992 / sizeof(uint32_t),
10+
kOtcryptoMldsa44WorkBufferSignWords = 32448 / sizeof(uint32_t),
11+
- kOtcryptoMldsa44WorkBufferVerifyWords = 22464 / sizeof(uint32_t),
12+
+ kOtcryptoMldsa44WorkBufferVerifyWords = 13248 / sizeof(uint32_t),
13+
14+
kOtcryptoMldsa65WorkBufferKeypairWords = 46304 / sizeof(uint32_t),
15+
kOtcryptoMldsa65WorkBufferSignWords = 44768 / sizeof(uint32_t),
16+
- kOtcryptoMldsa65WorkBufferVerifyWords = 30720 / sizeof(uint32_t),
17+
+ kOtcryptoMldsa65WorkBufferVerifyWords = 18400 / sizeof(uint32_t),
18+
19+
kOtcryptoMldsa87WorkBufferKeypairWords = 62688 / sizeof(uint32_t),
20+
kOtcryptoMldsa87WorkBufferSignWords = 59104 / sizeof(uint32_t),
21+
- kOtcryptoMldsa87WorkBufferVerifyWords = 41216 / sizeof(uint32_t),
22+
+ kOtcryptoMldsa87WorkBufferVerifyWords = 24800 / sizeof(uint32_t),
23+
};
24+
25+
/**

mldsa/mldsa_native.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@
257257
#undef mld_pack_sig_c_h
258258
#undef mld_pack_sig_z
259259
#undef mld_pack_sk
260+
#undef mld_unpack_hints
260261
#undef mld_unpack_pk
261-
#undef mld_unpack_sig
262262
#undef mld_unpack_sk
263263
/* mldsa/src/params.h */
264264
#undef MLDSA_BETA

mldsa/mldsa_native.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -928,15 +928,15 @@ int MLD_API_NAMESPACE(pk_from_sk)(
928928
#define MLD_TOTAL_ALLOC_44_KEYPAIR_NO_PCT 32992
929929
#define MLD_TOTAL_ALLOC_44_KEYPAIR_PCT 36192
930930
#define MLD_TOTAL_ALLOC_44_SIGN 32448
931-
#define MLD_TOTAL_ALLOC_44_VERIFY 22464
931+
#define MLD_TOTAL_ALLOC_44_VERIFY 13248
932932
#define MLD_TOTAL_ALLOC_65_KEYPAIR_NO_PCT 46304
933933
#define MLD_TOTAL_ALLOC_65_KEYPAIR_PCT 50048
934934
#define MLD_TOTAL_ALLOC_65_SIGN 44768
935-
#define MLD_TOTAL_ALLOC_65_VERIFY 30720
935+
#define MLD_TOTAL_ALLOC_65_VERIFY 18400
936936
#define MLD_TOTAL_ALLOC_87_KEYPAIR_NO_PCT 62688
937937
#define MLD_TOTAL_ALLOC_87_KEYPAIR_PCT 66336
938938
#define MLD_TOTAL_ALLOC_87_SIGN 59104
939-
#define MLD_TOTAL_ALLOC_87_VERIFY 41216
939+
#define MLD_TOTAL_ALLOC_87_VERIFY 24800
940940
#endif /* !(MLD_API_LEGACY_CONFIG || !MLD_CONFIG_REDUCE_RAM) */
941941
/* check-magic: on */
942942

mldsa/mldsa_native_asm.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@
260260
#undef mld_pack_sig_c_h
261261
#undef mld_pack_sig_z
262262
#undef mld_pack_sk
263+
#undef mld_unpack_hints
263264
#undef mld_unpack_pk
264-
#undef mld_unpack_sig
265265
#undef mld_unpack_sk
266266
/* mldsa/src/params.h */
267267
#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
@@ -189,36 +189,29 @@ __contract__(
189189
array_bound(s2->vec[k2].coeffs, 0, MLDSA_N, MLD_POLYETA_UNPACK_LOWER_BOUND, MLDSA_ETA + 1)))
190190
);
191191

192-
#define mld_unpack_sig MLD_NAMESPACE_KL(unpack_sig)
192+
#define mld_unpack_hints MLD_NAMESPACE_KL(unpack_hints)
193193
/*************************************************
194-
* Name: mld_unpack_sig
194+
* Name: mld_unpack_hints
195195
*
196-
* Description: Unpack signature sig = (c, z, h).
196+
* Description: Unpack hint vector h from packed hint bytes in signature.
197197
*
198-
* Arguments: - uint8_t *c: pointer to output challenge hash
199-
* - mld_polyvecl *z: pointer to output vector z
200-
* - mld_polyveck *h: pointer to output hint vector h
201-
* - const uint8_t sig[]: byte array containing
202-
* bit-packed signature
198+
* Arguments: - mld_polyveck *h: pointer to output hint vector
199+
* - const uint8_t *packed_hints: pointer to
200+
* raw hint bytes (MLDSA_POLYVECH_PACKEDBYTES)
203201
*
204-
* Returns 1 in case of malformed signature; otherwise 0.
202+
* Returns 1 in case of malformed hints; otherwise 0.
205203
**************************************************/
206204
MLD_INTERNAL_API
207205
MLD_MUST_CHECK_RETURN_VALUE
208-
int mld_unpack_sig(uint8_t c[MLDSA_CTILDEBYTES], mld_polyvecl *z,
209-
mld_polyveck *h, const uint8_t sig[MLDSA_CRYPTO_BYTES])
206+
int mld_unpack_hints(mld_polyveck *h,
207+
const uint8_t packed_hints[MLDSA_POLYVECH_PACKEDBYTES])
210208
__contract__(
211-
requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
212-
requires(memory_no_alias(c, MLDSA_CTILDEBYTES))
213-
requires(memory_no_alias(z, sizeof(mld_polyvecl)))
209+
requires(memory_no_alias(packed_hints, MLDSA_POLYVECH_PACKEDBYTES))
214210
requires(memory_no_alias(h, sizeof(mld_polyveck)))
215-
assigns(memory_slice(c, MLDSA_CTILDEBYTES))
216-
assigns(memory_slice(z, sizeof(mld_polyvecl)))
217211
assigns(memory_slice(h, sizeof(mld_polyveck)))
218-
ensures(forall(k0, 0, MLDSA_L,
219-
array_bound(z->vec[k0].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)))
220212
ensures(forall(k1, 0, MLDSA_K,
221213
array_bound(h->vec[k1].coeffs, 0, MLDSA_N, 0, 2)))
222214
ensures(return_value >= 0 && return_value <= 1)
223215
);
216+
224217
#endif /* !MLD_PACKING_H */

mldsa/src/sign.c

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -987,51 +987,53 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
987987
* https://github.com/diffblue/cbmc/issues/8813 */
988988
typedef MLD_UNION_OR_STRUCT
989989
{
990+
mld_polyvecl z;
991+
mld_poly cp;
992+
}
993+
zcp_u;
994+
mld_polyvecl *z;
995+
mld_poly *cp;
996+
997+
/* TODO: Remove the following workaround for
998+
* https://github.com/diffblue/cbmc/issues/8813 */
999+
typedef MLD_UNION_OR_STRUCT
1000+
{
1001+
mld_polymat mat;
9901002
mld_polyveck t1;
991-
mld_polyveck w1;
1003+
mld_polyveck tmp;
1004+
mld_polyveck h;
9921005
}
993-
t1w1_u;
994-
mld_polyveck *t1;
995-
mld_polyveck *w1;
1006+
reuse_u;
9961007

9971008
MLD_ALLOC(buf, uint8_t, (MLDSA_K * MLDSA_POLYW1_PACKEDBYTES), context);
9981009
MLD_ALLOC(rho, uint8_t, MLDSA_SEEDBYTES, context);
9991010
MLD_ALLOC(mu, uint8_t, MLDSA_CRHBYTES, context);
10001011
MLD_ALLOC(c, uint8_t, MLDSA_CTILDEBYTES, context);
10011012
MLD_ALLOC(c2, uint8_t, MLDSA_CTILDEBYTES, context);
1002-
MLD_ALLOC(cp, mld_poly, 1, context);
1003-
MLD_ALLOC(mat, mld_polymat, 1, context);
1004-
MLD_ALLOC(z, mld_polyvecl, 1, context);
1005-
MLD_ALLOC(t1w1, t1w1_u, 1, context);
1006-
MLD_ALLOC(tmp, mld_polyveck, 1, context);
1007-
MLD_ALLOC(h, mld_polyveck, 1, context);
1013+
MLD_ALLOC(zcp, zcp_u, 1, context);
1014+
MLD_ALLOC(w1, mld_polyveck, 1, context);
1015+
MLD_ALLOC(reuse, reuse_u, 1, context);
10081016

10091017
if (buf == NULL || rho == NULL || mu == NULL || c == NULL || c2 == NULL ||
1010-
cp == NULL || mat == NULL || z == NULL || t1w1 == NULL || tmp == NULL ||
1011-
h == NULL)
1018+
zcp == NULL || w1 == NULL || reuse == NULL)
10121019
{
10131020
ret = MLD_ERR_OUT_OF_MEMORY;
10141021
goto cleanup;
10151022
}
1016-
t1 = &t1w1->t1;
1017-
w1 = &t1w1->w1;
1023+
z = &zcp->z;
1024+
cp = &zcp->cp;
10181025

10191026
if (siglen != MLDSA_CRYPTO_BYTES)
10201027
{
10211028
ret = MLD_ERR_FAIL;
10221029
goto cleanup;
10231030
}
10241031

1025-
mld_unpack_pk(rho, t1, pk);
1032+
mld_memcpy(rho, pk, MLDSA_SEEDBYTES);
1033+
1034+
mld_memcpy(c, sig, MLDSA_CTILDEBYTES);
1035+
mld_polyvecl_unpack_z(z, sig + MLDSA_CTILDEBYTES);
10261036

1027-
/* mld_unpack_sig and mld_polyvecl_chknorm signal failure through a
1028-
* single non-zero error code that's not yet aligned with MLD_ERR_XXX.
1029-
* Map it to MLD_ERR_FAIL explicitly. */
1030-
if (mld_unpack_sig(c, z, h, sig))
1031-
{
1032-
ret = MLD_ERR_FAIL;
1033-
goto cleanup;
1034-
}
10351037
if (mld_polyvecl_chknorm(z, MLDSA_GAMMA1 - MLDSA_BETA))
10361038
{
10371039
ret = MLD_ERR_FAIL;
@@ -1056,23 +1058,31 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
10561058
}
10571059

10581060
/* Matrix-vector multiplication; compute Az - c2^dt1 */
1061+
mld_polyvecl_ntt(z);
1062+
mld_polyvec_matrix_expand(&reuse->mat, rho);
1063+
mld_polyvec_matrix_pointwise_montgomery(w1, &reuse->mat, z);
1064+
10591065
mld_poly_challenge(cp, c);
10601066
mld_poly_ntt(cp);
1061-
mld_polyveck_shiftl(t1);
1062-
mld_polyveck_ntt(t1);
1063-
mld_polyveck_pointwise_poly_montgomery(tmp, cp, t1);
1064-
1065-
mld_polyvec_matrix_expand(mat, rho);
1066-
mld_polyvecl_ntt(z);
1067-
mld_polyvec_matrix_pointwise_montgomery(w1, mat, z);
1068-
mld_polyveck_sub(w1, tmp);
1067+
mld_unpack_pk(rho, &reuse->t1, pk);
1068+
mld_polyveck_shiftl(&reuse->t1);
1069+
mld_polyveck_ntt(&reuse->t1);
1070+
mld_polyveck_pointwise_poly_montgomery(&reuse->tmp, cp, &reuse->t1);
1071+
mld_polyveck_sub(w1, &reuse->tmp);
10691072
mld_polyveck_reduce(w1);
10701073
mld_polyveck_invntt_tomont(w1);
10711074

10721075
/* Reconstruct w1 */
10731076
mld_polyveck_caddq(w1);
1074-
mld_polyveck_use_hint(tmp, w1, h);
1075-
mld_polyveck_pack_w1(buf, tmp);
1077+
if (mld_unpack_hints(&reuse->h, sig + MLDSA_CTILDEBYTES +
1078+
MLDSA_L * MLDSA_POLYZ_PACKEDBYTES))
1079+
{
1080+
ret = MLD_ERR_FAIL;
1081+
goto cleanup;
1082+
}
1083+
mld_polyveck_use_hint(&reuse->tmp, w1, &reuse->h);
1084+
mld_polyveck_pack_w1(buf, &reuse->tmp);
1085+
10761086
/* Call random oracle and verify challenge */
10771087
mld_H(c2, MLDSA_CTILDEBYTES, mu, MLDSA_CRHBYTES, buf,
10781088
MLDSA_K * MLDSA_POLYW1_PACKEDBYTES, NULL, 0);
@@ -1086,12 +1096,9 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
10861096

10871097
cleanup:
10881098
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
1089-
MLD_FREE(h, mld_polyveck, 1, context);
1090-
MLD_FREE(tmp, mld_polyveck, 1, context);
1091-
MLD_FREE(t1w1, t1w1_u, 1, context);
1092-
MLD_FREE(z, mld_polyvecl, 1, context);
1093-
MLD_FREE(mat, mld_polymat, 1, context);
1094-
MLD_FREE(cp, mld_poly, 1, context);
1099+
MLD_FREE(reuse, reuse_u, 1, context);
1100+
MLD_FREE(w1, mld_polyveck, 1, context);
1101+
MLD_FREE(zcp, zcp_u, 1, context);
10951102
MLD_FREE(c2, uint8_t, MLDSA_CTILDEBYTES, context);
10961103
MLD_FREE(c, uint8_t, MLDSA_CTILDEBYTES, context);
10971104
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.

0 commit comments

Comments
 (0)