Skip to content

Commit

Permalink
Merge pull request #380 from pq-code-package/cbmc-invntt
Browse files Browse the repository at this point in the history
CBMC: State (not prove) `poly_invntt_tomont` + Prove `polyvec_ntt` and `polyvec_invntt_tomont`
  • Loading branch information
hanno-becker authored Nov 12, 2024
2 parents 5987d2c + 9d46053 commit d7fd84f
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 17 deletions.
54 changes: 54 additions & 0 deletions cbmc/proofs/polyvec_invntt_tomont/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 = polyvec_invntt_tomont_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 = polyvec_invntt_tomont

DEFINES +=
INCLUDES +=

REMOVE_FUNCTION_BODY +=
UNWINDSET += $(MLKEM_NAMESPACE)polyvec_invntt_tomont.0:4 # Largest value of MLKEM_K

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

CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)polyvec_invntt_tomont
USE_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_invntt_tomont
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 = polyvec_invntt_tomont

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

/*
* Insert copyright notice
*/

/**
* @file polyvec_invntt_tomont_harness.c
* @brief Implements the proof harness for polyvec_invntt_tomont function.
*/
#include "polyvec.h"

/*
* Insert project header files that
* - include the declaration of the function
* - include the types needed to declare function arguments
*/

/**
* @brief Starting point for formal analysis
*
*/
void harness(void) {
polyvec *r;
polyvec_invntt_tomont(r);
}
54 changes: 54 additions & 0 deletions cbmc/proofs/polyvec_ntt/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 = polyvec_ntt_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 = polyvec_ntt

DEFINES +=
INCLUDES +=

REMOVE_FUNCTION_BODY +=
UNWINDSET += $(MLKEM_NAMESPACE)polyvec_ntt.0:4 # Largest value of MLKEM_K

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

CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)polyvec_ntt
USE_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_ntt
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 = polyvec_ntt

# 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/polyvec_ntt/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/polyvec_ntt/polyvec_ntt_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 AND Apache-2.0

/*
* Insert copyright notice
*/

/**
* @file polyvec_ntt_harness.c
* @brief Implements the proof harness for polyvec_ntt function.
*/
#include "ntt.h"
#include "polyvec.h"

/*
* Insert project header files that
* - include the declaration of the function
* - include the types needed to declare function arguments
*/

/**
* @brief Starting point for formal analysis
*
*/
void harness(void) {
polyvec *r;
polyvec_ntt(r);
}
6 changes: 5 additions & 1 deletion mlkem/ntt.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ ENSURES(ARRAY_IN_BOUNDS(0, MLKEM_N - 1, r->coeffs, -(NTT_BOUND - 1), NTT_BOUND -
* Arguments: - uint16_t *a: pointer to in/output polynomial
**************************************************/
#define poly_invntt_tomont MLKEM_NAMESPACE(poly_invntt_tomont)
void poly_invntt_tomont(poly *r);
void poly_invntt_tomont(poly *r) // clang-format off
REQUIRES(IS_FRESH(r, sizeof(poly)))
ASSIGNS(OBJECT_UPTO(r, sizeof(poly)))
ENSURES(ARRAY_IN_BOUNDS(0, MLKEM_N - 1, r->coeffs, -(INVNTT_BOUND - 1), INVNTT_BOUND - 1));
// clang-format on

#define basemul_cached MLKEM_NAMESPACE(basemul_cached)
/************************************************************
Expand Down
15 changes: 0 additions & 15 deletions mlkem/polyvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,28 +202,13 @@ void polyvec_frombytes(polyvec *r, const uint8_t a[MLKEM_POLYVECBYTES]) {
}
}

/*************************************************
* Name: polyvec_ntt
*
* Description: Apply forward NTT to all elements of a vector of polynomials
*
* Arguments: - polyvec *r: pointer to in/output vector of polynomials
**************************************************/
void polyvec_ntt(polyvec *r) {
unsigned int i;
for (i = 0; i < MLKEM_K; i++) {
poly_ntt(&r->vec[i]);
}
}

/*************************************************
* Name: polyvec_invntt_tomont
*
* Description: Apply inverse NTT to all elements of a vector of polynomials
* and multiply by Montgomery factor 2^16
*
* Arguments: - polyvec *r: pointer to in/output vector of polynomials
**************************************************/
void polyvec_invntt_tomont(polyvec *r) {
unsigned int i;
for (i = 0; i < MLKEM_K; i++) {
Expand Down
40 changes: 39 additions & 1 deletion mlkem/polyvec.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,54 @@ ENSURES(FORALL(int, k0, 0, MLKEM_K - 1,
ASSIGNS(OBJECT_WHOLE(r)); // clang-format on

#define polyvec_ntt MLKEM_NAMESPACE(polyvec_ntt)
/*************************************************
* Name: polyvec_ntt
*
* Description: Apply forward NTT to all elements of a vector of polynomials.
*
* The input is assumed to be in normal order and
* coefficient-wise bound by MLKEM_Q in absolute value.
*
* The output polynomial is in bitreversed order, and
* coefficient-wise bound by NTT_BOUND in absolute value.
*
* Arguments: - polyvec *r: pointer to in/output vector of polynomials
*
**************************************************/
void polyvec_ntt(polyvec *r) // clang-format off
REQUIRES(IS_FRESH(r, sizeof(polyvec)))
REQUIRES(FORALL(int, j, 0, MLKEM_K - 1,
ARRAY_IN_BOUNDS(0, MLKEM_N - 1,
r->vec[j].coeffs, -(MLKEM_Q - 1), (MLKEM_Q - 1))))
ASSIGNS(OBJECT_WHOLE(r))
ENSURES(FORALL(int, j, 0, MLKEM_K - 1,
ARRAY_IN_BOUNDS(0, MLKEM_N - 1,
r->vec[j].coeffs, -(NTT_BOUND - 1), (NTT_BOUND - 1))));
// clang-format on

#define polyvec_invntt_tomont MLKEM_NAMESPACE(polyvec_invntt_tomont)
void polyvec_invntt_tomont(polyvec *r);
/*************************************************
* Name: polyvec_invntt_tomont
*
* Description: Apply inverse NTT to all elements of a vector of polynomials
* and multiply by Montgomery factor 2^16
*
* The input is assumed to be in bitreversed order, and can
* have arbitrary coefficients in int16_t.
*
* The output polynomial is in normal order, and
* coefficient-wise bound by INVNTT_BOUND in absolute value.
*
*
* Arguments: - polyvec *r: pointer to in/output vector of polynomials
**************************************************/
void polyvec_invntt_tomont(polyvec *r) // clang-format off
REQUIRES(IS_FRESH(r, sizeof(polyvec)))
ASSIGNS(OBJECT_WHOLE(r))
ENSURES(FORALL(int, j, 0, MLKEM_K - 1,
ARRAY_IN_BOUNDS(0, MLKEM_N - 1,
r->vec[j].coeffs, -(INVNTT_BOUND - 1), (INVNTT_BOUND - 1))));
// clang-format on

#define polyvec_basemul_acc_montgomery \
MLKEM_NAMESPACE(polyvec_basemul_acc_montgomery)
Expand Down

0 comments on commit d7fd84f

Please sign in to comment.