Skip to content

Commit b729a2d

Browse files
committed
Add spec and proof for polyvec_matrix_expand
Signed-off-by: manastasova <[email protected]>
1 parent 858772b commit b729a2d

File tree

4 files changed

+102
-5
lines changed

4 files changed

+102
-5
lines changed

mldsa/polyvec.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,38 @@
1111
void polyvec_matrix_expand(polyvecl mat[MLDSA_K],
1212
const uint8_t rho[MLDSA_SEEDBYTES])
1313
{
14-
unsigned int i, j;
14+
/* Reference: This code is re-factored from the reference implementation
15+
* to facilitate proof with CBMC and to improve readability.
16+
*
17+
* The temporary polyvecl and poly variables simplify the CBMC
18+
* memory model by removing nested access patterns. Loop invariant
19+
* checks are performed on the local variable tmp_polyvecl before
20+
* assigning it to the output matrix |mat|. */
21+
22+
unsigned int i;
1523

1624
for (i = 0; i < MLDSA_K; ++i)
25+
__loop__(
26+
assigns(i, memory_slice(mat, MLDSA_K * sizeof(polyvecl)))
27+
invariant(i <= MLDSA_K)
28+
invariant(forall(k1, 0, i, forall(l1, 0, MLDSA_L, array_bound(mat[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
29+
)
1730
{
31+
unsigned int j;
32+
polyvecl tmp_polyvecl;
33+
1834
for (j = 0; j < MLDSA_L; ++j)
35+
__loop__(
36+
assigns(j, memory_slice(&tmp_polyvecl, sizeof(polyvecl)))
37+
invariant(j <= MLDSA_L)
38+
invariant(forall(l1, 0, j, array_bound(tmp_polyvecl.vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q)))
39+
)
1940
{
20-
poly_uniform(&mat[i].vec[j], rho, (i << 8) + j);
41+
poly temp_poly;
42+
poly_uniform(&temp_poly, rho, (i << 8) + j);
43+
tmp_polyvecl.vec[j] = temp_poly;
2144
}
45+
mat[i] = tmp_polyvecl;
2246
}
2347
}
2448

@@ -35,7 +59,7 @@ void polyvec_matrix_pointwise_montgomery(polyveck *t,
3559
}
3660

3761
/**************************************************************/
38-
/************ Vectors of polynomials of length MLDSA_L **************/
62+
/********** Vectors of polynomials of length MLDSA_L **********/
3963
/**************************************************************/
4064

4165
void polyvecl_uniform_eta(polyvecl *v, const uint8_t seed[MLDSA_CRHBYTES],
@@ -190,7 +214,7 @@ int polyvecl_chknorm(const polyvecl *v, int32_t bound)
190214
}
191215

192216
/**************************************************************/
193-
/************ Vectors of polynomials of length MLDSA_K **************/
217+
/********** Vectors of polynomials of length MLDSA_K **********/
194218
/**************************************************************/
195219

196220
void polyveck_uniform_eta(polyveck *v, const uint8_t seed[MLDSA_CRHBYTES],

mldsa/polyvec.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,14 @@ __contract__(
619619
* - const uint8_t rho[]: byte array containing seed rho
620620
**************************************************/
621621
void polyvec_matrix_expand(polyvecl mat[MLDSA_K],
622-
const uint8_t rho[MLDSA_SEEDBYTES]);
622+
const uint8_t rho[MLDSA_SEEDBYTES])
623+
__contract__(
624+
requires(memory_no_alias(mat, MLDSA_K * sizeof(polyvecl)))
625+
requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
626+
assigns(memory_slice(mat, MLDSA_K * sizeof(polyvecl)))
627+
ensures(forall(k1, 0, MLDSA_K, forall(l1, 0, MLDSA_L,
628+
array_bound(mat[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
629+
);
623630

624631
#define polyvec_matrix_pointwise_montgomery \
625632
MLD_NAMESPACE(polyvec_matrix_pointwise_montgomery)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
include ../Makefile_params.common
4+
5+
HARNESS_ENTRY = harness
6+
HARNESS_FILE = polyvec_matrix_expand_harness
7+
8+
# This should be a unique identifier for this proof, and will appear on the
9+
# Litani dashboard. It can be human-readable and contain spaces if you wish.
10+
PROOF_UID = polyvec_matrix_expand
11+
12+
DEFINES +=
13+
INCLUDES +=
14+
15+
REMOVE_FUNCTION_BODY +=
16+
UNWINDSET +=
17+
18+
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
19+
PROJECT_SOURCES += $(SRCDIR)/mldsa/polyvec.c
20+
21+
CHECK_FUNCTION_CONTRACTS=$(MLD_NAMESPACE)polyvec_matrix_expand
22+
USE_FUNCTION_CONTRACTS=$(MLD_NAMESPACE)poly_uniform
23+
APPLY_LOOP_CONTRACTS=on
24+
USE_DYNAMIC_FRAMES=1
25+
26+
# Disable any setting of EXTERNAL_SAT_SOLVER, and choose SMT backend instead
27+
EXTERNAL_SAT_SOLVER=
28+
CBMCFLAGS=--smt2
29+
30+
FUNCTION_NAME = polyvec_matrix_expand
31+
32+
# If this proof is found to consume huge amounts of RAM, you can set the
33+
# EXPENSIVE variable. With new enough versions of the proof tools, this will
34+
# restrict the number of EXPENSIVE CBMC jobs running at once. See the
35+
# documentation in Makefile.common under the "Job Pools" heading for details.
36+
# EXPENSIVE = true
37+
38+
# This function is large enough to need...
39+
CBMC_OBJECT_BITS = 8
40+
41+
# If you require access to a file-local ("static") function or object to conduct
42+
# your proof, set the following (and do not include the original source file
43+
# ("mldsa/poly.c") in PROJECT_SOURCES).
44+
# REWRITTEN_SOURCES = $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i
45+
# include ../Makefile.common
46+
# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_SOURCE = $(SRCDIR)/mldsa/poly.c
47+
# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_FUNCTIONS = foo bar
48+
# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_OBJECTS = baz
49+
# Care is required with variables on the left-hand side: REWRITTEN_SOURCES must
50+
# be set before including Makefile.common, but any use of variables on the
51+
# left-hand side requires those variables to be defined. Hence, _SOURCE,
52+
# _FUNCTIONS, _OBJECTS is set after including Makefile.common.
53+
54+
include ../Makefile.common
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) 2025 The mldsa-native project authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#include "polyvec.h"
5+
6+
void harness(void)
7+
{
8+
polyvecl *mat;
9+
const uint8_t *rho;
10+
11+
polyvec_matrix_expand(mat, rho);
12+
}

0 commit comments

Comments
 (0)