12#include <botan/internal/mce_internal.h>
14#include <botan/internal/code_based_util.h>
20void matrix_arr_mul(std::vector<uint32_t> matrix,
23 const uint8_t input_vec[],
24 uint32_t output_vec[],
25 size_t output_vec_len) {
26 for(
size_t j = 0; j < numo_rows; j++) {
27 if((input_vec[j / 8] >> (j % 8)) & 1) {
28 for(
size_t i = 0; i < output_vec_len; i++) {
29 output_vec[i] ^= matrix[j * (words_per_row) + i];
38secure_vector<gf2m> goppa_decode(
const polyn_gf2m& syndrom_polyn,
40 const std::vector<polyn_gf2m>& sqrtmod,
41 const std::vector<gf2m>& Linv) {
42 const size_t code_length = Linv.size();
44 uint32_t t = g.get_degree();
46 std::shared_ptr<GF2m_Field> sp_field = g.get_sp_field();
49 polyn_gf2m& h = h_aux.first;
50 polyn_gf2m& aux = h_aux.second;
51 a = sp_field->gf_inv(aux.get_coef(0));
52 gf2m log_a = sp_field->gf_log(a);
53 for(
int i = 0; i <= h.get_degree(); ++i) {
54 h.set_coef(i, sp_field->gf_mul_zrz(log_a, h.get_coef(i)));
60 polyn_gf2m S(t - 1, g.get_sp_field());
62 for(uint32_t i = 0; i < t; i++) {
63 a = sp_field->gf_sqrt(h.get_coef(i));
66 for(uint32_t j = 0; j < t; j++) {
67 S.add_to_coef(j, sp_field->gf_mul(a, sqrtmod[i / 2].get_coef(j)));
70 S.add_to_coef(i / 2, a);
77 polyn_gf2m& u = v_u.second;
78 polyn_gf2m& v = v_u.first;
81 polyn_gf2m
sigma(t, g.get_sp_field());
83 const int u_deg = u.get_degree();
85 for(
int i = 0; i <= u_deg; ++i) {
86 sigma.set_coef(2 * i, sp_field->gf_square(u.get_coef(i)));
89 const int v_deg = v.get_degree();
91 for(
int i = 0; i <= v_deg; ++i) {
92 sigma.set_coef(2 * i + 1, sp_field->gf_square(v.get_coef(i)));
96 size_t d = res.size();
98 secure_vector<gf2m> result(d);
99 for(uint32_t i = 0; i < d; ++i) {
100 gf2m current = res[i];
105 if(tmp >= code_length)
107 result[i] =
static_cast<gf2m>(i);
109 result[i] = Linv[tmp];
120 mceliece_decrypt(plaintext_out, error_mask_out, ciphertext.data(), ciphertext.size(), key);
125 const uint8_t ciphertext[],
126 size_t ciphertext_len,
133 for(
auto&& pos : error_pos) {
134 if(pos > code_length) {
137 result[pos / 8] |= (1 << (pos % 8));
148 const uint8_t* ciphertext,
149 size_t ciphertext_len,
155 const unsigned unused_pt_bits = dimension % 8;
156 const uint8_t unused_pt_bits_mask = (1 << unused_pt_bits) - 1;
173 syndrome_vec.size());
176 const size_t syndrome_byte_vec_size = syndrome_byte_vec.size();
177 for(
size_t i = 0; i < syndrome_byte_vec_size; i++) {
178 syndrome_byte_vec[i] =
static_cast<uint8_t
>(syndrome_vec[i / 4] >> (8 * (i % 4)));
187 const size_t nb_err = error_pos.size();
190 copy_mem(cleartext.data(), ciphertext, cleartext_len);
192 for(
size_t i = 0; i < nb_err; i++) {
193 gf2m current = error_pos[i];
195 if(current >= cleartext_len * 8) {
199 cleartext[current / 8] ^= (1 << (current % 8));
203 cleartext[cleartext_len - 1] &= unused_pt_bits_mask;
#define BOTAN_ASSERT(expr, assertion_made)
const std::vector< polyn_gf2m > & get_sqrtmod() const
size_t get_codimension() const
size_t get_dimension() const
const polyn_gf2m & get_goppa_polyn() const
const std::vector< gf2m > & get_Linv() const
const std::vector< uint32_t > & get_H_coeffs() const
size_t get_message_word_bit_length() const
size_t get_code_length() const
std::shared_ptr< GF2m_Field > get_sp_field() const
static std::pair< polyn_gf2m, polyn_gf2m > eea_with_coefficients(const polyn_gf2m &p, const polyn_gf2m &g, int break_deg)
void mceliece_decrypt(secure_vector< uint8_t > &plaintext_out, secure_vector< uint8_t > &error_mask_out, const secure_vector< uint8_t > &ciphertext, const McEliece_PrivateKey &key)
constexpr void copy_mem(T *out, const T *in, size_t n)
gf2m gray_to_lex(gf2m gray)
size_t bit_size_to_32bit_size(size_t bit_size)
secure_vector< gf2m > find_roots_gf2m_decomp(const polyn_gf2m &polyn, size_t code_length)
size_t bit_size_to_byte_size(size_t bit_size)
std::vector< T, secure_allocator< T > > secure_vector