Skip to content

Commit

Permalink
Merge pull request #358 from pq-code-package/cbmc_poly_frommsg
Browse files Browse the repository at this point in the history
Proofs of poly_frommsg
  • Loading branch information
hanno-becker authored Nov 7, 2024
2 parents 67058df + ec079fd commit 9350cd9
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 18 deletions.
54 changes: 54 additions & 0 deletions cbmc/proofs/poly_frommsg/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# SPDX-License-Identifier: Apache-2.0

include ../Makefile_params.common

HARNESS_ENTRY = harness
HARNESS_FILE = poly_frommsg_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 = poly_frommsg

DEFINES +=
INCLUDES +=

REMOVE_FUNCTION_BODY +=
UNWINDSET +=

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

CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_frommsg
USE_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)cmov_int16
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)poly_frommsg

# 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 = 8

# 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/poly_frommsg/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.
30 changes: 30 additions & 0 deletions cbmc/proofs/poly_frommsg/poly_frommsg_harness.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0

/*
* Insert copyright notice
*/

/**
* @file poly_frommsg_harness.c
* @brief Implements the proof harness for poly_frommsg function.
*/

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

/**
* @brief Starting point for formal analysis
*
*/
void harness(void) {
poly *a;
uint8_t *msg;

/* Contracts for this function are in poly.h */
poly_frommsg(a, msg);
}
29 changes: 13 additions & 16 deletions mlkem/poly.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,28 +274,25 @@ void poly_frombytes(poly *r, const uint8_t a[MLKEM_POLYBYTES]) {
}
#endif /* MLKEM_USE_NATIVE_POLY_FROMBYTES */

/*************************************************
* Name: poly_frommsg
*
* Description: Convert 32-byte message to polynomial
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t *msg: pointer to input message
**************************************************/
void poly_frommsg(poly *r, const uint8_t msg[MLKEM_INDCPA_MSGBYTES]) {
unsigned int i, j;

#if (MLKEM_INDCPA_MSGBYTES != MLKEM_N / 8)
#error "MLKEM_INDCPA_MSGBYTES must be equal to MLKEM_N/8 bytes!"
#endif

for (i = 0; i < MLKEM_N / 8; i++) {
for (j = 0; j < 8; j++) {
r->coeffs[8 * i + j] = 0;
cmov_int16(r->coeffs + 8 * i + j, ((MLKEM_Q + 1) / 2), (msg[i] >> j) & 1);
for (int i = 0; i < MLKEM_N / 8; i++) // clang-format off
ASSIGNS(i, OBJECT_WHOLE(r))
INVARIANT(i >= 0 && i <= MLKEM_N / 8)
INVARIANT(ARRAY_IN_BOUNDS(int, k, 0, (8 * i - 1), r->coeffs, 0, (MLKEM_Q - 1)))
{ // clang-format on
for (int j = 0; j < 8; j++) // clang-format off
ASSIGNS(j, OBJECT_WHOLE(r))
INVARIANT(i >= 0 && i < MLKEM_N / 8 && j >= 0 && j <= 8)
INVARIANT(ARRAY_IN_BOUNDS(int, k, 0, (8 * i + j - 1), r->coeffs, 0, (MLKEM_Q - 1)))
{ // clang-format on
r->coeffs[8 * i + j] = 0;
cmov_int16(&r->coeffs[8 * i + j], HALF_Q, (msg[i] >> j) & 1);
}
}
}

POLY_BOUND_MSG(r, MLKEM_Q, "poly_frommsg output");
}

Expand Down
17 changes: 16 additions & 1 deletion mlkem/poly.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,23 @@ ASSIGNS(OBJECT_UPTO(r, sizeof(poly)))
ENSURES(ARRAY_IN_BOUNDS(int, k, 0, (MLKEM_N - 1), r->coeffs, 0, 4095));
// clang-format on


#define poly_frommsg MLKEM_NAMESPACE(poly_frommsg)
void poly_frommsg(poly *r, const uint8_t msg[MLKEM_INDCPA_MSGBYTES]);
/*************************************************
* Name: poly_frommsg
*
* Description: Convert 32-byte message to polynomial
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t *msg: pointer to input message
**************************************************/
void poly_frommsg(poly *r, const uint8_t msg[MLKEM_INDCPA_MSGBYTES])
// clang-format off
REQUIRES(IS_FRESH(msg, MLKEM_INDCPA_MSGBYTES))
REQUIRES(IS_FRESH(r, sizeof(poly)))
ASSIGNS(OBJECT_WHOLE(r))
ENSURES(ARRAY_IN_BOUNDS(int, k, 0, (MLKEM_N - 1), r->coeffs, 0, (MLKEM_Q - 1)));
// clang-format on


#define poly_tomsg MLKEM_NAMESPACE(poly_tomsg)
Expand Down
3 changes: 2 additions & 1 deletion mlkem/verify.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ void cmov_int16(int16_t *r, const int16_t v, const uint16_t b)
// clang-format off
REQUIRES(b == 0 || b == 1)
REQUIRES(IS_FRESH(r, sizeof(int16_t)))
ASSIGNS(OBJECT_WHOLE(r))
ASSIGNS(OBJECT_UPTO(r, sizeof(int16_t)))
ENSURES(*r == (b ? v : OLD(*r)));
// clang-format on

#endif

0 comments on commit 9350cd9

Please sign in to comment.