Skip to content

Commit cbff485

Browse files
willieyzmkannwischer
authored andcommitted
CBMC: Add proofs on top of native functions (poly_decompose_native)
- This commit adds CBMC proofs for following the native function: `mld_poly_decompose_32_native`, `mld_poly_decompose_88_native`. called `poly_decompose_native`. - This following changes are include: - Apply the same harness file and construct function contract reference from `poly_decompose`. - Use the following function contracts: - mld_poly_decompose_c - mld_poly_decompose_32_native - mld_poly_decompose_88_native - Add `MLD_USE_NATIVE_POLY_DECOMPOSE_32`, `MLD_USE_NATIVE_POLY_DECOMPOSE_88` in dummy_backend.h Signed-off-by: willieyz <willie.zhao@chelpis.com>
1 parent 5d26e11 commit cbff485

File tree

5 files changed

+103
-4
lines changed

5 files changed

+103
-4
lines changed

mldsa/src/native/api.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,20 @@ __contract__(
258258
* - const int32_t *a: input polynomial
259259
**************************************************/
260260
static MLD_INLINE int mld_poly_decompose_32_native(int32_t *a1, int32_t *a0,
261-
const int32_t *a);
261+
const int32_t *a)
262+
__contract__(
263+
requires(memory_no_alias(a1, sizeof(int32_t) * MLDSA_N))
264+
requires(memory_no_alias(a0, sizeof(int32_t) * MLDSA_N))
265+
requires(memory_no_alias(a, sizeof(int32_t) * MLDSA_N))
266+
requires(array_bound(a, 0, MLDSA_N, 0, MLDSA_Q))
267+
assigns(memory_slice(a1, sizeof(int32_t) * MLDSA_N))
268+
assigns(memory_slice(a0, sizeof(int32_t) * MLDSA_N))
269+
ensures(return_value == MLD_NATIVE_FUNC_FALLBACK || return_value == MLD_NATIVE_FUNC_SUCCESS)
270+
ensures((return_value == MLD_NATIVE_FUNC_SUCCESS) ==> array_bound(a1, 0, MLDSA_N, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
271+
ensures((return_value == MLD_NATIVE_FUNC_SUCCESS) ==> array_abs_bound(a0, 0, MLDSA_N, MLDSA_GAMMA2+1))
272+
ensures((return_value == MLD_NATIVE_FUNC_FALLBACK) ==> array_bound(a, 0, MLDSA_N, 0, MLDSA_Q))
273+
ensures((return_value == MLD_NATIVE_FUNC_FALLBACK) ==> array_unchanged(a, MLDSA_N))
274+
);
262275
#endif /* MLD_USE_NATIVE_POLY_DECOMPOSE_32 */
263276

264277
#if defined(MLD_USE_NATIVE_POLY_DECOMPOSE_88)
@@ -279,7 +292,20 @@ static MLD_INLINE int mld_poly_decompose_32_native(int32_t *a1, int32_t *a0,
279292
* - const int32_t *a: input polynomial
280293
**************************************************/
281294
static MLD_INLINE int mld_poly_decompose_88_native(int32_t *a1, int32_t *a0,
282-
const int32_t *a);
295+
const int32_t *a)
296+
__contract__(
297+
requires(memory_no_alias(a1, sizeof(int32_t) * MLDSA_N))
298+
requires(memory_no_alias(a0, sizeof(int32_t) * MLDSA_N))
299+
requires(memory_no_alias(a, sizeof(int32_t) * MLDSA_N))
300+
requires(array_bound(a, 0, MLDSA_N, 0, MLDSA_Q))
301+
assigns(memory_slice(a1, sizeof(int32_t) * MLDSA_N))
302+
assigns(memory_slice(a0, sizeof(int32_t) * MLDSA_N))
303+
ensures(return_value == MLD_NATIVE_FUNC_FALLBACK || return_value == MLD_NATIVE_FUNC_SUCCESS)
304+
ensures((return_value == MLD_NATIVE_FUNC_SUCCESS) ==> array_bound(a1, 0, MLDSA_N, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
305+
ensures((return_value == MLD_NATIVE_FUNC_SUCCESS) ==> array_abs_bound(a0, 0, MLDSA_N, MLDSA_GAMMA2+1))
306+
ensures((return_value == MLD_NATIVE_FUNC_FALLBACK) ==> array_bound(a, 0, MLDSA_N, 0, MLDSA_Q))
307+
ensures((return_value == MLD_NATIVE_FUNC_FALLBACK) ==> array_unchanged(a, MLDSA_N))
308+
);
283309
#endif /* MLD_USE_NATIVE_POLY_DECOMPOSE_88 */
284310

285311
#if defined(MLD_USE_NATIVE_POLY_CADDQ)

mldsa/src/poly_kl.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ void mld_poly_decompose(mld_poly *a1, mld_poly *a0, const mld_poly *a)
7575
#if defined(MLD_USE_NATIVE_POLY_DECOMPOSE_88) && MLD_CONFIG_PARAMETER_SET == 44
7676
int ret;
7777
mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
78-
/* TODO: proof */
7978
ret = mld_poly_decompose_88_native(a1->coeffs, a0->coeffs, a->coeffs);
8079
if (ret == MLD_NATIVE_FUNC_SUCCESS)
8180
{
@@ -88,7 +87,6 @@ void mld_poly_decompose(mld_poly *a1, mld_poly *a0, const mld_poly *a)
8887
(MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
8988
int ret;
9089
mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
91-
/* TODO: proof */
9290
ret = mld_poly_decompose_32_native(a1->coeffs, a0->coeffs, a->coeffs);
9391
if (ret == MLD_NATIVE_FUNC_SUCCESS)
9492
{

proofs/cbmc/dummy_backend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#define MLD_USE_NATIVE_REJ_UNIFORM
1313
#define MLD_USE_NATIVE_REJ_UNIFORM_ETA2
1414
#define MLD_USE_NATIVE_REJ_UNIFORM_ETA4
15+
#define MLD_USE_NATIVE_POLY_DECOMPOSE_32
16+
#define MLD_USE_NATIVE_POLY_DECOMPOSE_88
1517

1618
#include "../../mldsa/src/native/api.h"
1719

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

0 commit comments

Comments
 (0)