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 #ifndef BOTAN_MCELIECE_KEY_H_
13 #define BOTAN_MCELIECE_KEY_H_
14 
15 #include <botan/pk_keys.h>
16 #include <botan/polyn_gf2m.h>
17 
18 namespace Botan {
19 
20 typedef uint16_t gf2m;
21 
22 class polyn_gf2m;
23 
24 class BOTAN_PUBLIC_API(2,0) McEliece_PublicKey : public virtual Public_Key
25    {
26    public:
27       explicit McEliece_PublicKey(const std::vector<uint8_t>& key_bits);
28 
McEliece_PublicKey(const std::vector<uint8_t> & pub_matrix,size_t t,size_t the_code_length)29       McEliece_PublicKey(const std::vector<uint8_t>& pub_matrix, size_t t, size_t the_code_length) :
30          m_public_matrix(pub_matrix),
31          m_t(t),
32          m_code_length(the_code_length){}
33 
34       McEliece_PublicKey(const McEliece_PublicKey& other) = default;
35       McEliece_PublicKey& operator=(const McEliece_PublicKey& other) = default;
36       virtual ~McEliece_PublicKey()= default;
37 
38       secure_vector<uint8_t> random_plaintext_element(RandomNumberGenerator& rng) const;
39 
algo_name()40       std::string algo_name() const override { return "McEliece"; }
41 
42       AlgorithmIdentifier algorithm_identifier() const override;
43 
44       size_t key_length() const override;
45       size_t estimated_strength() const override;
46 
47       std::vector<uint8_t> public_key_bits() const override;
48 
check_key(RandomNumberGenerator &,bool)49       bool check_key(RandomNumberGenerator&, bool) const override
50          { return true; }
51 
get_t()52       size_t get_t() const { return m_t; }
get_code_length()53       size_t get_code_length() const { return m_code_length; }
54       size_t get_message_word_bit_length() const;
get_public_matrix()55       const std::vector<uint8_t>& get_public_matrix() const { return m_public_matrix; }
56 
57       bool operator==(const McEliece_PublicKey& other) const;
58       bool operator!=(const McEliece_PublicKey& other) const { return !(*this == other); }
59 
60       std::unique_ptr<PK_Ops::KEM_Encryption>
61          create_kem_encryption_op(RandomNumberGenerator& rng,
62                                   const std::string& params,
63                                   const std::string& provider) const override;
64 
65    protected:
McEliece_PublicKey()66       McEliece_PublicKey() : m_t(0), m_code_length(0) {}
67 
68       std::vector<uint8_t> m_public_matrix;
69       size_t m_t;
70       size_t m_code_length;
71    };
72 
73 class BOTAN_PUBLIC_API(2,0) McEliece_PrivateKey final : public virtual McEliece_PublicKey,
74                                       public virtual Private_Key
75    {
76    public:
77 
78       /**
79       Generate a McEliece key pair
80 
81       Suggested parameters for a given security level (SL)
82 
83       SL=80 n=1632 t=33 - 59 KB pubkey 140 KB privkey
84       SL=107 n=2480 t=45 - 128 KB pubkey 300 KB privkey
85       SL=128 n=2960 t=57 - 195 KB pubkey 459 KB privkey
86       SL=147 n=3408 t=67 - 265 KB pubkey 622 KB privkey
87       SL=191 n=4624 t=95 - 516 KB pubkey 1234 KB privkey
88       SL=256 n=6624 t=115 - 942 KB pubkey 2184 KB privkey
89       */
90       McEliece_PrivateKey(RandomNumberGenerator& rng, size_t code_length, size_t t);
91 
92       explicit McEliece_PrivateKey(const secure_vector<uint8_t>& key_bits);
93 
94       McEliece_PrivateKey(polyn_gf2m const& goppa_polyn,
95                           std::vector<uint32_t> const& parity_check_matrix_coeffs,
96                           std::vector<polyn_gf2m> const& square_root_matrix,
97                           std::vector<gf2m> const& inverse_support,
98                           std::vector<uint8_t> const& public_matrix );
99 
100       ~McEliece_PrivateKey();
101 
102       bool check_key(RandomNumberGenerator& rng, bool strong) const override;
103 
104       polyn_gf2m const& get_goppa_polyn() const;
get_H_coeffs()105       std::vector<uint32_t> const& get_H_coeffs() const { return m_coeffs; }
get_Linv()106       std::vector<gf2m> const& get_Linv() const { return m_Linv; }
get_sqrtmod()107       std::vector<polyn_gf2m> const& get_sqrtmod() const { return m_sqrtmod; }
108 
get_dimension()109       inline size_t get_dimension() const { return m_dimension; }
110 
get_codimension()111       inline size_t get_codimension() const { return m_codimension; }
112 
113       secure_vector<uint8_t> private_key_bits() const override;
114 
115       bool operator==(const McEliece_PrivateKey & other) const;
116 
117       bool operator!=(const McEliece_PrivateKey& other) const { return !(*this == other); }
118 
119       std::unique_ptr<PK_Ops::KEM_Decryption>
120          create_kem_decryption_op(RandomNumberGenerator& rng,
121                                   const std::string& params,
122                                   const std::string& provider) const override;
123    private:
124       std::vector<polyn_gf2m> m_g; // single element
125       std::vector<polyn_gf2m> m_sqrtmod;
126       std::vector<gf2m> m_Linv;
127       std::vector<uint32_t> m_coeffs;
128 
129       size_t m_codimension;
130       size_t m_dimension;
131    };
132 
133 /**
134 * Estimate work factor for McEliece
135 * @return estimated security level for these key parameters
136 */
137 BOTAN_PUBLIC_API(2,0) size_t mceliece_work_factor(size_t code_size, size_t t);
138 
139 }
140 
141 #endif
142