Skip to content

Commit 8a9a8fb

Browse files
committed
Add experimental proof for wots_sign using wots_chain function pointer
1 parent 29c1ec1 commit 8a9a8fb

File tree

6 files changed

+105
-0
lines changed

6 files changed

+105
-0
lines changed

cbmc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
/* cassert to avoid confusion with in-built assert */
3333
#define cassert(x) __CPROVER_assert(x, "cbmc assertion failed")
3434
#define assume(...) __CPROVER_assume(__VA_ARGS__)
35+
/* https://diffblue.github.io/cbmc/contracts-function-pointer-predicates.html */
36+
#define obeys_contract(...) __CPROVER_obeys_contract(__VA_ARGS__)
37+
38+
39+
3540

3641
/***************************************************
3742
* Macros for "expression" forms that may appear

proofs/cbmc/wots_sign/Makefile

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Copyright (c) The mlkem-native project authors
2+
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
3+
4+
HARNESS_ENTRY = harness
5+
HARNESS_FILE = wots_sign_harness
6+
7+
# This should be a unique identifier for this proof, and will appear on the
8+
# Litani dashboard. It can be human-readable and contain spaces if you wish.
9+
PROOF_UID = wots_sign
10+
11+
DEFINES +=
12+
INCLUDES +=
13+
14+
REMOVE_FUNCTION_BODY +=
15+
UNWINDSET +=
16+
17+
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
18+
PROJECT_SOURCES += $(SRCDIR)/slh_dsa.c
19+
20+
CHECK_FUNCTION_CONTRACTS=wots_sign
21+
USE_FUNCTION_CONTRACTS=get_len wots_csum adrs_set_chain_address
22+
APPLY_LOOP_CONTRACTS=on
23+
USE_DYNAMIC_FRAMES=1
24+
RESTRICT_FUNCTION_POINTER=wots_sign.function_pointer_call.1/wots_chain_contract
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 = wots_sign
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+
# ("mlkem/src/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)/mlkem/src/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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) The slhdsa-c project authors
2+
// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
3+
4+
#include <stddef.h>
5+
#include <stdint.h>
6+
#include <string.h>
7+
#include "slh_var.h"
8+
9+
size_t wots_sign(slh_var_t *var, uint8_t *sig, const uint8_t *m);
10+
11+
void harness(void)
12+
{
13+
slh_var_t *var;
14+
uint8_t *sig;
15+
uint8_t *m;
16+
wots_sign(var, sig, m);
17+
}

slh_adrs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ static SLH_INLINE void adrs_set_tree_height(slh_var_t *var, uint32_t x)
108108

109109
/* === Set WOTS+ chain address. */
110110
static SLH_INLINE void adrs_set_chain_address(slh_var_t *var, uint32_t x)
111+
/* TODO: complete*/
112+
__contract__()
111113
{
112114
var->adrs->u32[6] = rev8_be32(x);
113115
}

slh_dsa.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ static SLH_INLINE uint32_t gen_len2(const slh_param_t *prm)
4444
}
4545

4646
static SLH_INLINE uint32_t get_len(const slh_param_t *prm)
47+
/* TODO: complete*/
48+
__contract__(
49+
ensures(return_value < SLH_MAX_LEN)
50+
)
4751
{
4852
return get_len1(prm) + gen_len2(prm);
4953
}
@@ -93,6 +97,8 @@ static SLH_INLINE size_t base_2b(uint32_t *v, const uint8_t *x, uint32_t b,
9397

9498
/* (wots_csum is a shared helper function for algorithms 7 and 8) */
9599
static void wots_csum(uint32_t *vm, const uint8_t *m, const slh_param_t *prm)
100+
/* TODO: complete*/
101+
__contract__()
96102
{
97103
uint32_t csum, i, t;
98104
uint32_t len1, len2;
@@ -119,6 +125,14 @@ static void wots_csum(uint32_t *vm, const uint8_t *m, const slh_param_t *prm)
119125
}
120126

121127
static size_t wots_sign(slh_var_t *var, uint8_t *sig, const uint8_t *m)
128+
__contract__(
129+
requires(memory_no_alias(var, sizeof(slh_var_t)))
130+
requires(memory_no_alias(var->prm, sizeof(slh_param_t)))
131+
requires(var->prm->n <= SLH_MAX_N)
132+
requires(obeys_contract(var->prm->wots_chain, wots_chain_contract))
133+
requires(memory_no_alias(sig, var->prm->n * SLH_MAX_LEN))
134+
assigns(object_whole(sig))
135+
)
122136
{
123137
const slh_param_t *prm = var->prm;
124138
uint32_t i, len;
@@ -129,6 +143,11 @@ static size_t wots_sign(slh_var_t *var, uint8_t *sig, const uint8_t *m)
129143
wots_csum(vm, m, prm);
130144

131145
for (i = 0; i < len; i++)
146+
__loop__(
147+
assigns(i, sig)
148+
invariant(i <= len)
149+
invariant(sig == loop_entry(sig) + i * n)
150+
)
132151
{
133152
adrs_set_chain_address(var, i);
134153
prm->wots_chain(var, sig, vm[i]);

slh_var.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,13 @@ struct slh_var_s
5757
/* Core signing function (of a randomized digest) with initialized context. */
5858
size_t slh_do_sign(slh_var_t *var, uint8_t *sig, const uint8_t *digest);
5959

60+
61+
/* TODO: find a better place where to put the contract*/
62+
void wots_chain_contract(slh_var_t *var, uint8_t *tmp, uint32_t s)
63+
__contract__(
64+
requires(memory_no_alias(var, sizeof(slh_var_t)))
65+
);
66+
67+
6068
/* _SLH_VAR_H_ */
6169
#endif

0 commit comments

Comments
 (0)