12 #include <botan/internal/mce_internal.h>
13 #include <botan/internal/code_based_util.h>
19 void matrix_arr_mul(std::vector<uint32_t> matrix,
21 uint32_t words_per_row,
22 const uint8_t* input_vec,
23 uint32_t* output_vec, uint32_t output_vec_len)
25 for(
size_t j = 0; j < numo_rows; j++)
27 if((input_vec[j / 8] >> (j % 8)) & 1)
29 for(
size_t i = 0; i < output_vec_len; i ++)
31 output_vec[i] ^= matrix[ j * (words_per_row) + i];
40 secure_vector<gf2m> goppa_decode(
const polyn_gf2m & syndrom_polyn,
42 const std::vector<polyn_gf2m> & sqrtmod,
43 const std::vector<gf2m> & Linv)
47 uint32_t t = g.get_degree();
49 std::shared_ptr<GF2m_Field> sp_field = g.get_sp_field();
52 polyn_gf2m & h = h__aux.first;
53 polyn_gf2m & aux = h__aux.second;
54 a = sp_field->gf_inv(aux.get_coef(0));
55 gf2m log_a = sp_field->gf_log(a);
56 for(
int i = 0; i <= h.get_degree(); ++i)
58 h.set_coef(i,sp_field->gf_mul_zrz(log_a,h.get_coef(i)));
64 polyn_gf2m S(t - 1, g.get_sp_field());
66 for(uint32_t i=0;i<t;i++)
68 a = sp_field->gf_sqrt(h.get_coef(i));
72 for(uint32_t j=0;j<t;j++)
74 S.add_to_coef( j, sp_field->gf_mul(a, sqrtmod[i/2].get_coef(j)));
79 S.add_to_coef( i/2, a);
87 polyn_gf2m & u = v__u.second;
88 polyn_gf2m & v = v__u.first;
91 polyn_gf2m sigma ( t , g.get_sp_field());
93 const size_t u_deg = u.get_degree();
94 for(
size_t i = 0; i <= u_deg; ++i)
96 sigma.set_coef(2*i, sp_field->gf_square(u.get_coef(i)));
99 const int v_deg = v.get_degree();
101 for(
int i = 0; i <= v_deg; ++i)
103 sigma.set_coef(2*i+1, sp_field->gf_square(v.get_coef(i)));
107 size_t d = res.size();
109 secure_vector<gf2m> result(d);
110 for(uint32_t i = 0; i < d; ++i)
112 gf2m current = res[i];
116 if(tmp >= code_length)
120 result[i] = Linv[tmp];
132 mceliece_decrypt(plaintext_out, error_mask_out, ciphertext.data(), ciphertext.size(), key);
138 const uint8_t ciphertext[],
139 size_t ciphertext_len,
147 for(
auto&& pos : error_pos)
149 if(pos > code_length)
153 result[pos / 8] |= (1 << (pos % 8));
165 const uint8_t *ciphertext, uint32_t ciphertext_len,
173 const unsigned unused_pt_bits = dimension % 8;
174 const uint8_t unused_pt_bits_mask = (1 << unused_pt_bits) - 1;
192 syndrome_vec.data(), syndrome_vec.size());
195 uint32_t syndrome_byte_vec_size = syndrome_byte_vec.size();
196 for(uint32_t i = 0; i < syndrome_byte_vec_size; i++)
198 syndrome_byte_vec[i] = syndrome_vec[i/4] >> (8* (i % 4));
206 uint32_t nb_err = error_pos.size();
209 copy_mem(cleartext.data(), ciphertext, cleartext_len);
211 for(uint32_t i = 0; i < nb_err; i++)
213 gf2m current = error_pos[i];
215 if(current >= cleartext_len * 8)
220 cleartext[current / 8] ^= (1 << (current % 8));
225 cleartext[cleartext_len - 1] &= unused_pt_bits_mask;
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)
uint32_t bit_size_to_32bit_size(uint32_t bit_size)
uint32_t bit_size_to_byte_size(uint32_t bit_size)
polyn_gf2m const & get_goppa_polyn() const
std::vector< uint32_t > const & get_H_coeffs() const
std::vector< gf2m > const & get_Linv() const
uint32_t get_dimension() const
uint32_t get_code_length() const
uint32_t get_message_word_bit_length() const
std::shared_ptr< GF2m_Field > get_sp_field() const
#define BOTAN_ASSERT(expr, assertion_made)
std::vector< T, secure_allocator< T >> secure_vector
gf2m gray_to_lex(gf2m gray)
std::vector< polyn_gf2m > const & get_sqrtmod() const
secure_vector< gf2m > find_roots_gf2m_decomp(const polyn_gf2m &polyn, uint32_t code_length)
void copy_mem(T *out, const T *in, size_t n)
static std::pair< polyn_gf2m, polyn_gf2m > eea_with_coefficients(const polyn_gf2m &p, const polyn_gf2m &g, int break_deg)
uint32_t get_codimension() const