Botan  2.1.0
Crypto and TLS for C++11
mceliece.cpp
Go to the documentation of this file.
1 /*
2  * (C) Copyright Projet SECRET, INRIA, Rocquencourt
3  * (C) Bhaskar Biswas and Nicolas Sendrier
4  *
5  * (C) 2014 cryptosource GmbH
6  * (C) 2014 Falko Strenzke fstrenzke@cryptosource.de
7  *
8  * Botan is released under the Simplified BSD License (see license.txt)
9  *
10  */
11 
12 #include <botan/internal/mce_internal.h>
13 #include <botan/mceliece.h>
14 #include <botan/internal/code_based_util.h>
15 #include <botan/internal/bit_ops.h>
16 #include <set>
17 
18 namespace Botan {
19 
20 namespace {
21 
22 secure_vector<uint8_t> concat_vectors(const secure_vector<uint8_t>& a, const secure_vector<uint8_t>& b,
23  uint32_t dimension, uint32_t codimension)
24  {
25  secure_vector<uint8_t> x(bit_size_to_byte_size(dimension) + bit_size_to_byte_size(codimension));
26 
27  const size_t final_bits = dimension % 8;
28 
29  if(final_bits == 0)
30  {
31  const size_t dim_bytes = bit_size_to_byte_size(dimension);
32  copy_mem(&x[0], a.data(), dim_bytes);
33  copy_mem(&x[dim_bytes], b.data(), bit_size_to_byte_size(codimension));
34  }
35  else
36  {
37  copy_mem(&x[0], a.data(), (dimension / 8));
38  uint32_t l = dimension / 8;
39  x[l] = static_cast<uint8_t>(a[l] & ((1 << final_bits) - 1));
40 
41  for(uint32_t k = 0; k < codimension / 8; ++k)
42  {
43  x[l] ^= static_cast<uint8_t>(b[k] << final_bits);
44  ++l;
45  x[l] = static_cast<uint8_t>(b[k] >> (8 - final_bits));
46  }
47  x[l] ^= static_cast<uint8_t>(b[codimension/8] << final_bits);
48  }
49 
50  return x;
51  }
52 
53 secure_vector<uint8_t> mult_by_pubkey(const secure_vector<uint8_t>& cleartext,
54  std::vector<uint8_t> const& public_matrix,
55  uint32_t code_length, uint32_t t)
56  {
57  const uint32_t ext_deg = ceil_log2(code_length);
58  const uint32_t codimension = ext_deg * t;
59  const uint32_t dimension = code_length - codimension;
60  secure_vector<uint8_t> cR(bit_size_to_32bit_size(codimension) * sizeof(uint32_t));
61 
62  const uint8_t* pt = public_matrix.data();
63 
64  for(size_t i = 0; i < dimension / 8; ++i)
65  {
66  for(size_t j = 0; j < 8; ++j)
67  {
68  if(cleartext[i] & (1 << j))
69  {
70  xor_buf(cR.data(), pt, cR.size());
71  }
72  pt += cR.size();
73  }
74  }
75 
76  for(size_t i = 0; i < dimension % 8 ; ++i)
77  {
78  if(cleartext[dimension/8] & (1 << i))
79  {
80  xor_buf(cR.data(), pt, cR.size());
81  }
82  pt += cR.size();
83  }
84 
85  secure_vector<uint8_t> ciphertext = concat_vectors(cleartext, cR, dimension, codimension);
86  ciphertext.resize((code_length+7)/8);
87  return ciphertext;
88  }
89 
90 secure_vector<uint8_t> create_random_error_vector(unsigned code_length,
91  unsigned error_weight,
92  RandomNumberGenerator& rng)
93  {
94  secure_vector<uint8_t> result((code_length+7)/8);
95 
96  size_t bits_set = 0;
97 
98  while(bits_set < error_weight)
99  {
100  gf2m x = random_code_element(code_length, rng);
101 
102  const size_t byte_pos = x / 8, bit_pos = x % 8;
103 
104  const uint8_t mask = (1 << bit_pos);
105 
106  if(result[byte_pos] & mask)
107  continue; // already set this bit
108 
109  result[byte_pos] |= mask;
110  bits_set++;
111  }
112 
113  return result;
114  }
115 
116 }
117 
119  secure_vector<uint8_t>& error_mask_out,
120  const secure_vector<uint8_t>& plaintext,
121  const McEliece_PublicKey& key,
123  {
124  secure_vector<uint8_t> error_mask = create_random_error_vector(key.get_code_length(), key.get_t(), rng);
125 
126  secure_vector<uint8_t> ciphertext = mult_by_pubkey(plaintext, key.get_public_matrix(),
127  key.get_code_length(), key.get_t());
128 
129  ciphertext ^= error_mask;
130 
131  ciphertext_out.swap(ciphertext);
132  error_mask_out.swap(error_mask);
133  }
134 
135 }
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:115
void mceliece_encrypt(secure_vector< uint8_t > &ciphertext_out, secure_vector< uint8_t > &error_mask_out, const secure_vector< uint8_t > &plaintext, const McEliece_PublicKey &key, RandomNumberGenerator &rng)
Definition: mceliece.cpp:118
uint32_t get_t() const
Definition: mceliece.h:49
uint32_t bit_size_to_32bit_size(uint32_t bit_size)
uint32_t bit_size_to_byte_size(uint32_t bit_size)
uint32_t get_code_length() const
Definition: mceliece.h:50
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
const std::vector< uint8_t > & get_public_matrix() const
Definition: mceliece.h:52
uint16_t gf2m
Definition: gf2m_small_m.h:20
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Definition: alg_id.cpp:13
gf2m random_code_element(unsigned code_length, RandomNumberGenerator &rng)
Definition: polyn_gf2m.cpp:71
size_t ceil_log2(T x)
Definition: bit_ops.h:106
uint32_t code_length