11#include <botan/internal/cmce_encaps.h>
17CmceCodeWord Classic_McEliece_Encryptor::encode(
const Classic_McEliece_Parameters& params,
19 const Classic_McEliece_Matrix& mat)
const {
20 return mat.mul(params, e);
23std::optional<CmceErrorVector> Classic_McEliece_Encryptor::fixed_weight_vector_gen(
24 const Classic_McEliece_Parameters& params, RandomNumberGenerator& rng)
const {
25 const auto rand = rng.random_vec((params.sigma1() / 8) * params.tau());
27 uint16_t mask_m = (uint32_t(1) << params.m()) - 1;
29 a_values.reserve(params.tau());
30 BufferSlicer rand_slicer(rand);
34 for(
size_t j = 0; j < params.tau(); ++j) {
40 bool d_in_range = d < params.n();
42 if(d_in_range && a_values.size() < params.t()) {
43 a_values.push_back(d);
46 if(a_values.size() < params.t()) {
52 for(
size_t i = 1; i < params.t(); ++i) {
53 for(
size_t j = 0; j < i; ++j) {
54 bool a_i_j_equal = a_values.at(i) == a_values.at(j);
68 for(
size_t j = 0; j < a_values.size(); ++j) {
69 a_value_byte[j] = 1 << (a_values[j] % 8);
72 for(
size_t i = 0; i < params.n() / 8; ++i) {
73 for(
size_t j = 0; j < a_values.size(); ++j) {
77 e_bytes[i] |= mask.if_set_return(a_value_byte[j]);
85 std::span<uint8_t> out_shared_key,
87 BOTAN_ARG_CHECK(out_encapsulated_key.size() == m_key->params().ciphertext_size(),
88 "Incorrect encapsulated key output length");
89 BOTAN_ARG_CHECK(out_shared_key.size() == m_key->params().hash_out_bytes(),
"Incorrect shared key output length");
91 const auto& params = m_key->params();
99 constexpr size_t MAX_ATTEMPTS = 203;
100 for(
size_t attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) {
101 if(
auto maybe_e = fixed_weight_vector_gen(params, rng)) {
102 return maybe_e.value();
105 throw Internal_Error(
"Cannot created fixed weight vector. Is your RNG broken?");
108 auto hash_func = params.hash_func();
111 const auto e_bytes = e.
get().to_bytes();
113 const auto big_c_0 = encode(params, e, m_key->matrix());
117 hash_func->update(0x02);
118 hash_func->update(e_bytes);
119 hash_func->final(big_c_stuf.
next(hash_func->output_length()));
124 hash_func->update(0x01);
125 hash_func->update(e_bytes);
126 hash_func->update(out_encapsulated_key);
127 hash_func->final(out_shared_key);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_ARG_CHECK(expr, msg)
Helper class to ease in-place marshalling of concatenated fixed-length values.
constexpr std::span< uint8_t > next(size_t bytes)
constexpr bool full() const
static constexpr Mask< T > is_equal(T x, T y)
void raw_kem_encrypt(std::span< uint8_t > out_encapsulated_key, std::span< uint8_t > out_shared_key, RandomNumberGenerator &rng) override
constexpr void unpoison_all(Ts &&... ts)
constexpr void unpoison(const T *p, size_t n)
constexpr void poison(const T *p, size_t n)
Strong< secure_bitvector, struct CmceCodeWord_ > CmceCodeWord
Represents C of decapsulation.
bitvector_base< secure_allocator > secure_bitvector
Strong< secure_bitvector, struct CmceErrorVector_ > CmceErrorVector
Represents e of encapsulation.
constexpr auto load_le(ParamTs &&... params)
std::vector< T, secure_allocator< T > > secure_vector
constexpr T ceil_tobytes(T bits)