12#include <botan/internal/mce_internal.h>
14#include <botan/mceliece.h>
15#include <botan/mem_ops.h>
16#include <botan/internal/bit_ops.h>
17#include <botan/internal/code_based_util.h>
29 const size_t final_bits = dimension % 8;
33 copy_mem(&x[0], a.data(), dim_bytes);
36 copy_mem(&x[0], a.data(), (dimension / 8));
37 size_t l = dimension / 8;
38 x[l] =
static_cast<uint8_t
>(a[l] & ((1 << final_bits) - 1));
40 for(
size_t k = 0; k < codimension / 8; ++k) {
41 x[l] ^=
static_cast<uint8_t
>(b[k] << final_bits);
43 x[l] =
static_cast<uint8_t
>(b[k] >> (8 - final_bits));
45 if(
const size_t remaining_codim_bits = codimension % 8) {
46 const uint8_t final_codim_byte = b[codimension / 8];
47 x[l] ^=
static_cast<uint8_t
>(final_codim_byte << final_bits);
48 if(final_bits + remaining_codim_bits > 8) {
50 x[l] =
static_cast<uint8_t
>(final_codim_byte >> (8 - final_bits));
59 const std::vector<uint8_t>& public_matrix,
62 const size_t ext_deg =
ceil_log2(code_length);
63 const size_t codimension = ext_deg * t;
64 const size_t dimension = code_length - codimension;
68 BOTAN_ARG_CHECK(public_matrix.size() == dimension * cR.size(),
"Invalid McEliece public matrix length");
70 const uint8_t* pt = public_matrix.data();
72 for(
size_t i = 0; i < dimension / 8; ++i) {
73 for(
size_t j = 0; j < 8; ++j) {
74 if((cleartext[i] & (1 << j)) != 0) {
75 xor_buf(cR.data(), pt, cR.size());
81 for(
size_t i = 0; i < dimension % 8; ++i) {
82 if((cleartext[dimension / 8] & (1 << i)) != 0) {
83 xor_buf(cR.data(), pt, cR.size());
89 ciphertext.resize((code_length + 7) / 8);
98 while(bits_set < error_weight) {
101 const size_t byte_pos = x / 8;
102 const size_t bit_pos = x % 8;
104 const uint8_t mask = (1 << bit_pos);
106 if((result[byte_pos] & mask) != 0) {
110 result[byte_pos] |= mask;
124 const uint16_t code_length =
static_cast<uint16_t
>(key.
code_length());
130 ciphertext ^= error_mask;
132 ciphertext_out.swap(ciphertext);
133 error_mask_out.swap(error_mask);
#define BOTAN_ARG_CHECK(expr, msg)
size_t code_length() const
const std::vector< uint8_t > & public_matrix() const
gf2m random_code_element(uint16_t code_length, RandomNumberGenerator &rng)
constexpr void copy_mem(T *out, const T *in, size_t n)
constexpr uint8_t ceil_log2(T x)
constexpr void xor_buf(ranges::contiguous_output_range< uint8_t > auto &&out, ranges::contiguous_range< uint8_t > auto &&in)
void mceliece_encrypt(secure_vector< uint8_t > &ciphertext_out, secure_vector< uint8_t > &error_mask_out, const secure_vector< uint8_t > &plaintext, const McEliece_PublicKeyInternal &key, RandomNumberGenerator &rng)
std::vector< T, secure_allocator< T > > secure_vector
size_t bit_size_to_32bit_size(size_t bit_size)
size_t bit_size_to_byte_size(size_t bit_size)