Skip to content

Commit

Permalink
CBMC: Prove indcpa_enc
Browse files Browse the repository at this point in the history
This plugs together the various CBMC contracts to prove the full
indcpa_enc.

To make this work we have to slightly change the contract of
poly_getnoise_eta1122_4x to allow argument 1+2 and
argument 3+4 to come from the same polyvec.
That function is only used in indcpa_enc.

Signed-off-by: Matthias J. Kannwischer <[email protected]>
  • Loading branch information
mkannwischer authored and hanno-becker committed Nov 12, 2024
1 parent d7fd84f commit 5e319ea
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 5 deletions.
79 changes: 79 additions & 0 deletions cbmc/proofs/indcpa_enc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# SPDX-License-Identifier: Apache-2.0

include ../Makefile_params.common

HARNESS_ENTRY = harness
HARNESS_FILE = indcpa_enc_harness

# This should be a unique identifier for this proof, and will appear on the
# Litani dashboard. It can be human-readable and contain spaces if you wish.
PROOF_UID = indcpa_enc

DEFINES +=
INCLUDES +=

REMOVE_FUNCTION_BODY +=
UNWINDSET +=

PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROJECT_SOURCES += $(SRCDIR)/mlkem/indcpa.c

CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)indcpa_enc

USED_FUNCTIONS = poly_frommsg
USED_FUNCTIONS += gen_matrix
ifeq ($(MLKEM_K),2)
USED_FUNCTIONS += poly_getnoise_eta1122_4x
USED_FUNCTIONS += poly_getnoise_eta2
else ifeq ($(MLKEM_K),3)
USED_FUNCTIONS += poly_getnoise_eta1_4x
else ifeq ($(MLKEM_K),4)
USED_FUNCTIONS += poly_getnoise_eta1_4x
USED_FUNCTIONS += poly_getnoise_eta2
endif

USED_FUNCTIONS += polyvec_ntt
USED_FUNCTIONS += polyvec_mulcache_compute
USED_FUNCTIONS += polyvec_basemul_acc_montgomery_cached
USED_FUNCTIONS += polyvec_invntt_tomont
USED_FUNCTIONS += poly_invntt_tomont
USED_FUNCTIONS += polyvec_add
USED_FUNCTIONS += poly_add
USED_FUNCTIONS += polyvec_reduce
USED_FUNCTIONS += poly_reduce
USED_FUNCTIONS += polyvec_compress
USED_FUNCTIONS += poly_compress

USE_FUNCTION_CONTRACTS=unpack_pk matvec_mul $(addprefix $(MLKEM_NAMESPACE),$(USED_FUNCTIONS))
APPLY_LOOP_CONTRACTS=on
USE_DYNAMIC_FRAMES=1

# Disable any setting of EXTERNAL_SAT_SOLVER, and choose SMT backend instead
EXTERNAL_SAT_SOLVER=
CBMCFLAGS=--smt2

FUNCTION_NAME = $(MLKEM_NAMESPACE)indcpa_enc

# If this proof is found to consume huge amounts of RAM, you can set the
# EXPENSIVE variable. With new enough versions of the proof tools, this will
# restrict the number of EXPENSIVE CBMC jobs running at once. See the
# documentation in Makefile.common under the "Job Pools" heading for details.
# EXPENSIVE = true

# This function is large enough to need...
CBMC_OBJECT_BITS = 10

# If you require access to a file-local ("static") function or object to conduct
# your proof, set the following (and do not include the original source file
# ("mlkem/poly.c") in PROJECT_SOURCES).
# REWRITTEN_SOURCES = $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i
# include ../Makefile.common
# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_SOURCE = $(SRCDIR)/mlkem/poly.c
# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_FUNCTIONS = foo bar
# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_OBJECTS = baz
# Care is required with variables on the left-hand side: REWRITTEN_SOURCES must
# be set before including Makefile.common, but any use of variables on the
# left-hand side requires those variables to be defined. Hence, _SOURCE,
# _FUNCTIONS, _OBJECTS is set after including Makefile.common.

include ../Makefile.common
3 changes: 3 additions & 0 deletions cbmc/proofs/indcpa_enc/cbmc-proof.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: Apache-2.0

# This file marks this directory as containing a CBMC proof.
28 changes: 28 additions & 0 deletions cbmc/proofs/indcpa_enc/indcpa_enc_harness.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0

/*
* Insert copyright notice
*/

/**
* @file indcpa_keypair_derand_harness.c
* @brief Implements the proof harness for indcpa_keypair_derand function.
*/

/*
* Insert project header files that
* - include the declaration of the function
* - include the types needed to declare function arguments
*/
#include <indcpa.h>
#include <poly.h>

/**
* @brief Starting point for formal analysis
*
*/
void harness(void) {
uint8_t *a, *b, *c, *d;
indcpa_enc(a, b, c, d);
}
8 changes: 7 additions & 1 deletion mlkem/indcpa.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ void indcpa_keypair_derand(
void indcpa_enc(uint8_t c[MLKEM_INDCPA_BYTES],
const uint8_t m[MLKEM_INDCPA_MSGBYTES],
const uint8_t pk[MLKEM_INDCPA_PUBLICKEYBYTES],
const uint8_t coins[MLKEM_SYMBYTES]);
const uint8_t coins[MLKEM_SYMBYTES]) // clang-format off
REQUIRES(IS_FRESH(c, MLKEM_INDCPA_BYTES))
REQUIRES(IS_FRESH(m, MLKEM_INDCPA_MSGBYTES))
REQUIRES(IS_FRESH(pk, MLKEM_INDCPA_PUBLICKEYBYTES))
REQUIRES(IS_FRESH(coins, MLKEM_SYMBYTES))
ASSIGNS(OBJECT_WHOLE(c));
// clang-format on

#define indcpa_dec MLKEM_NAMESPACE(indcpa_dec)
void indcpa_dec(uint8_t m[MLKEM_INDCPA_MSGBYTES],
Expand Down
7 changes: 3 additions & 4 deletions mlkem/poly.h
Original file line number Diff line number Diff line change
Expand Up @@ -517,10 +517,9 @@ void poly_getnoise_eta1122_4x(poly *r0, poly *r1, poly *r2, poly *r3,
const uint8_t seed[MLKEM_SYMBYTES],
uint8_t nonce0, uint8_t nonce1, uint8_t nonce2,
uint8_t nonce3) // clang-format off
REQUIRES(IS_FRESH(r0, sizeof(poly)))
REQUIRES(IS_FRESH(r1, sizeof(poly)))
REQUIRES(IS_FRESH(r2, sizeof(poly)))
REQUIRES(IS_FRESH(r3, sizeof(poly)))
REQUIRES( /* r0, r1 consecutive, r2, r3 consecutive */
(IS_FRESH(r0, 2 * sizeof(poly)) && IS_FRESH(r2, 2 * sizeof(poly)) &&
r1 == r0 + 1 && r3 == r2 + 1 && !SAME_OBJECT(r0, r2)))
REQUIRES(IS_FRESH(seed, MLKEM_SYMBYTES))
ASSIGNS(OBJECT_WHOLE(r0), OBJECT_WHOLE(r1), OBJECT_WHOLE(r2), OBJECT_WHOLE(r3))
ENSURES( \
Expand Down

0 comments on commit 5e319ea

Please sign in to comment.