This repository has been archived on 2026-08-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ciciec2026/sdk/software/examples/mlkem_test/mlkem_native/src/kem.h

305 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/* References
* ==========
*
* - [FIPS203]
* FIPS 203 Module-Lattice-Based Key-Encapsulation Mechanism Standard
* National Institute of Standards and Technology
* https://csrc.nist.gov/pubs/fips/203/final
*
* - [REF]
* CRYSTALS-Kyber C reference implementation
* Bos, Ducas, Kiltz, Lepoint, Lyubashevsky, Schanck, Schwabe, Seiler, Stehlé
* https://github.com/pq-crystals/kyber/tree/main/ref
*/
#ifndef MLK_KEM_H
#define MLK_KEM_H
#include "cbmc.h"
#include "common.h"
#include "sys.h"
#if defined(MLK_CHECK_APIS)
/* Include to ensure consistency between internal kem.h
* and external mlkem_native.h. */
#include "mlkem_native.h"
#if MLKEM_INDCCA_SECRETKEYBYTES != \
MLKEM_SECRETKEYBYTES(MLK_CONFIG_PARAMETER_SET)
#error Mismatch for SECRETKEYBYTES between kem.h and mlkem_native.h
#endif
#if MLKEM_INDCCA_PUBLICKEYBYTES != \
MLKEM_PUBLICKEYBYTES(MLK_CONFIG_PARAMETER_SET)
#error Mismatch for PUBLICKEYBYTES between kem.h and mlkem_native.h
#endif
#if MLKEM_INDCCA_CIPHERTEXTBYTES != \
MLKEM_CIPHERTEXTBYTES(MLK_CONFIG_PARAMETER_SET)
#error Mismatch for CIPHERTEXTBYTES between kem.h and mlkem_native.h
#endif
#endif /* MLK_CHECK_APIS */
#define mlk_kem_keypair_derand \
MLK_NAMESPACE_K(keypair_derand) MLK_CONTEXT_PARAMETERS_3
#define mlk_kem_keypair MLK_NAMESPACE_K(keypair) MLK_CONTEXT_PARAMETERS_2
#define mlk_kem_enc_derand MLK_NAMESPACE_K(enc_derand) MLK_CONTEXT_PARAMETERS_4
#define mlk_kem_enc MLK_NAMESPACE_K(enc) MLK_CONTEXT_PARAMETERS_3
#define mlk_kem_dec MLK_NAMESPACE_K(dec) MLK_CONTEXT_PARAMETERS_3
#define mlk_kem_check_pk MLK_NAMESPACE_K(check_pk) MLK_CONTEXT_PARAMETERS_1
#define mlk_kem_check_sk MLK_NAMESPACE_K(check_sk) MLK_CONTEXT_PARAMETERS_1
/**
* Implements modulus check mandated by FIPS 203, i.e., ensures that
* coefficients are in [0,q-1].
*
* @spec{Implements @[FIPS203, Section 7.2, 'modulus check'].}
*
* @reference{Not implemented in the reference implementation @[REF].}
*
* @param[in] pk Input public key (an already allocated array of
* MLKEM_INDCCA_PUBLICKEYBYTES bytes).
* @param context Application context. Only present when
* MLK_CONFIG_CONTEXT_PARAMETER is defined; type set by
* MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
*
* @retval 0 Success.
* @retval MLK_ERR_FAIL Modulus check failed.
* @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
* MLK_CUSTOM_ALLOC returned NULL.
*/
MLK_EXTERNAL_API
MLK_MUST_CHECK_RETURN_VALUE
int mlk_kem_check_pk(const uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES],
MLK_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
return_value == MLK_ERR_OUT_OF_MEMORY)
);
/**
* Implements public key hash check mandated by FIPS 203, i.e., ensures that
* sk[768𝑘+32 ∶ 768𝑘+64] = H(pk) = H(sk[384𝑘 : 768𝑘+32]).
*
* @spec{Implements @[FIPS203, Section 7.3, 'hash check'].}
*
* @reference{Not implemented in the reference implementation @[REF].}
*
* @param[in] sk Input private key (an already allocated array of
* MLKEM_INDCCA_SECRETKEYBYTES bytes).
* @param context Application context. Only present when
* MLK_CONFIG_CONTEXT_PARAMETER is defined; type set by
* MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
*
* @retval 0 Success.
* @retval MLK_ERR_FAIL Public key hash check failed.
* @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
* MLK_CUSTOM_ALLOC returned NULL.
*/
MLK_EXTERNAL_API
MLK_MUST_CHECK_RETURN_VALUE
int mlk_kem_check_sk(const uint8_t sk[MLKEM_INDCCA_SECRETKEYBYTES],
MLK_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(sk, MLKEM_INDCCA_SECRETKEYBYTES))
ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
return_value == MLK_ERR_OUT_OF_MEMORY)
);
/**
* Generate a public/private keypair for the ML-KEM key encapsulation mechanism.
*
* @spec{Implements @[FIPS203, Algorithm 16, ML-KEM.KeyGen_Internal].}
*
* @param[out] pk Output public key (an already allocated array of
* MLKEM_INDCCA_PUBLICKEYBYTES bytes).
* @param[out] sk Output private key (an already allocated array of
* MLKEM_INDCCA_SECRETKEYBYTES bytes).
* @param[in] coins Input randomness (an already allocated array filled
* with 2*MLKEM_SYMBYTES random bytes).
* @param context Application context. Only present when
* MLK_CONFIG_CONTEXT_PARAMETER is defined; type set by
* MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
*
* @retval 0 Success.
* @retval MLK_ERR_FAIL MLK_CONFIG_KEYGEN_PCT enabled and PCT failed.
* @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
* MLK_CUSTOM_ALLOC returned NULL.
*/
MLK_EXTERNAL_API
MLK_MUST_CHECK_RETURN_VALUE
int mlk_kem_keypair_derand(uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES],
uint8_t sk[MLKEM_INDCCA_SECRETKEYBYTES],
const uint8_t coins[2 * MLKEM_SYMBYTES],
MLK_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
requires(memory_no_alias(sk, MLKEM_INDCCA_SECRETKEYBYTES))
requires(memory_no_alias(coins, 2 * MLKEM_SYMBYTES))
assigns(memory_slice(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
assigns(memory_slice(sk, MLKEM_INDCCA_SECRETKEYBYTES))
ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
return_value == MLK_ERR_OUT_OF_MEMORY ||
return_value == MLK_ERR_RNG_FAIL)
);
/**
* Generate a public/private keypair for the ML-KEM key encapsulation mechanism.
*
* @spec{Implements @[FIPS203, Algorithm 19, ML-KEM.KeyGen].}
*
* @param[out] pk Output public key (an already allocated array of
* MLKEM_INDCCA_PUBLICKEYBYTES bytes).
* @param[out] sk Output private key (an already allocated array of
* MLKEM_INDCCA_SECRETKEYBYTES bytes).
* @param context Application context. Only present when
* MLK_CONFIG_CONTEXT_PARAMETER is defined; type set by
* MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
*
* @retval 0 Success.
* @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
* MLK_CUSTOM_ALLOC returned NULL.
* @retval MLK_ERR_RNG_FAIL Random number generation failed.
* @retval MLK_ERR_FAIL MLK_CONFIG_KEYGEN_PCT enabled and PCT failed.
*/
MLK_EXTERNAL_API
MLK_MUST_CHECK_RETURN_VALUE
int mlk_kem_keypair(uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES],
uint8_t sk[MLKEM_INDCCA_SECRETKEYBYTES],
MLK_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
requires(memory_no_alias(sk, MLKEM_INDCCA_SECRETKEYBYTES))
assigns(memory_slice(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
assigns(memory_slice(sk, MLKEM_INDCCA_SECRETKEYBYTES))
ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
return_value == MLK_ERR_OUT_OF_MEMORY ||
return_value == MLK_ERR_RNG_FAIL)
);
/**
* Generate ciphertext and shared secret for a given public key.
*
* @spec{Implements @[FIPS203, Algorithm 17, ML-KEM.Encaps_Internal].}
*
* @param[out] ct Output ciphertext (an already allocated array of
* MLKEM_INDCCA_CIPHERTEXTBYTES bytes).
* @param[out] ss Output shared secret (an already allocated array of
* MLKEM_SSBYTES bytes).
* @param[in] pk Input public key (an already allocated array of
* MLKEM_INDCCA_PUBLICKEYBYTES bytes).
* @param[in] coins Input randomness (an already allocated array filled
* with MLKEM_SYMBYTES random bytes).
* @param context Application context. Only present when
* MLK_CONFIG_CONTEXT_PARAMETER is defined; type set by
* MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
*
* @retval 0 Success.
* @retval MLK_ERR_FAIL The 'modulus check' @[FIPS203, Section 7.2]
* for the public key failed.
* @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
* MLK_CUSTOM_ALLOC returned NULL.
*/
MLK_EXTERNAL_API
MLK_MUST_CHECK_RETURN_VALUE
int mlk_kem_enc_derand(uint8_t ct[MLKEM_INDCCA_CIPHERTEXTBYTES],
uint8_t ss[MLKEM_SSBYTES],
const uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES],
const uint8_t coins[MLKEM_SYMBYTES],
MLK_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
requires(memory_no_alias(ss, MLKEM_SSBYTES))
requires(memory_no_alias(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
requires(memory_no_alias(coins, MLKEM_SYMBYTES))
assigns(memory_slice(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
assigns(memory_slice(ss, MLKEM_SSBYTES))
ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
return_value == MLK_ERR_OUT_OF_MEMORY)
);
/**
* Generate ciphertext and shared secret for a given public key.
*
* @spec{Implements @[FIPS203, Algorithm 20, ML-KEM.Encaps].}
*
* @param[out] ct Output ciphertext (an already allocated array of
* MLKEM_INDCCA_CIPHERTEXTBYTES bytes).
* @param[out] ss Output shared secret (an already allocated array of
* MLKEM_SSBYTES bytes).
* @param[in] pk Input public key (an already allocated array of
* MLKEM_INDCCA_PUBLICKEYBYTES bytes).
* @param context Application context. Only present when
* MLK_CONFIG_CONTEXT_PARAMETER is defined; type set by
* MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
*
* @retval 0 Success.
* @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
* MLK_CUSTOM_ALLOC returned NULL.
* @retval MLK_ERR_RNG_FAIL Random number generation failed.
* @retval MLK_ERR_FAIL The 'modulus check' @[FIPS203, Section 7.2]
* for the public key failed.
*/
MLK_EXTERNAL_API
MLK_MUST_CHECK_RETURN_VALUE
int mlk_kem_enc(uint8_t ct[MLKEM_INDCCA_CIPHERTEXTBYTES],
uint8_t ss[MLKEM_SSBYTES],
const uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES],
MLK_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
requires(memory_no_alias(ss, MLKEM_SSBYTES))
requires(memory_no_alias(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
assigns(memory_slice(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
assigns(memory_slice(ss, MLKEM_SSBYTES))
ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
return_value == MLK_ERR_OUT_OF_MEMORY ||
return_value == MLK_ERR_RNG_FAIL)
);
/**
* Generate shared secret for a given ciphertext and private key.
*
* @spec{Implements @[FIPS203, Algorithm 21, ML-KEM.Decaps].}
*
* @param[out] ss Output shared secret (an already allocated array of
* MLKEM_SSBYTES bytes).
* @param[in] ct Input ciphertext (an already allocated array of
* MLKEM_INDCCA_CIPHERTEXTBYTES bytes).
* @param[in] sk Input private key (an already allocated array of
* MLKEM_INDCCA_SECRETKEYBYTES bytes).
* @param context Application context. Only present when
* MLK_CONFIG_CONTEXT_PARAMETER is defined; type set by
* MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
*
* @retval 0 Success.
* @retval MLK_ERR_FAIL The 'hash check' @[FIPS203, Section 7.3]
* for the secret key failed.
* @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
* MLK_CUSTOM_ALLOC returned NULL.
*/
MLK_EXTERNAL_API
MLK_MUST_CHECK_RETURN_VALUE
int mlk_kem_dec(uint8_t ss[MLKEM_SSBYTES],
const uint8_t ct[MLKEM_INDCCA_CIPHERTEXTBYTES],
const uint8_t sk[MLKEM_INDCCA_SECRETKEYBYTES],
MLK_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(ss, MLKEM_SSBYTES))
requires(memory_no_alias(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
requires(memory_no_alias(sk, MLKEM_INDCCA_SECRETKEYBYTES))
assigns(memory_slice(ss, MLKEM_SSBYTES))
ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
return_value == MLK_ERR_OUT_OF_MEMORY)
);
#endif /* !MLK_KEM_H */