/src/botan/build/include/internal/botan/internal/cmce_parameters.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Classic McEliece Parameters |
3 | | * (C) 2023 Jack Lloyd |
4 | | * 2023,2024 Fabian Albert, Amos Treiber - Rohde & Schwarz Cybersecurity |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | **/ |
8 | | |
9 | | #ifndef BOTAN_CMCE_PARAMS_H_ |
10 | | #define BOTAN_CMCE_PARAMS_H_ |
11 | | |
12 | | #include <botan/asn1_obj.h> |
13 | | #include <botan/cmce_parameter_set.h> |
14 | | #include <botan/hash.h> |
15 | | #include <botan/xof.h> |
16 | | #include <botan/internal/cmce_gf.h> |
17 | | #include <botan/internal/cmce_poly.h> |
18 | | |
19 | | #include <string_view> |
20 | | |
21 | | namespace Botan { |
22 | | |
23 | | struct Classic_McEliece_Big_F_Coefficient; |
24 | | class Classic_McEliece_Polynomial_Ring; |
25 | | |
26 | | /** |
27 | | * Container for all Classic McEliece parameters. |
28 | | */ |
29 | | class BOTAN_TEST_API Classic_McEliece_Parameters final { |
30 | | public: |
31 | | /** |
32 | | * @brief Create Classic McEliece parameters from a parameter set. |
33 | | */ |
34 | | static Classic_McEliece_Parameters create(Classic_McEliece_Parameter_Set set); |
35 | | |
36 | | /** |
37 | | * @brief Create Classic McEliece parameters from a parameter set name. |
38 | | */ |
39 | | static Classic_McEliece_Parameters create(std::string_view name); |
40 | | |
41 | | /** |
42 | | * @brief Create Classic McEliece parameters from an OID. |
43 | | */ |
44 | | static Classic_McEliece_Parameters create(const OID& oid); |
45 | | |
46 | | /** |
47 | | * @brief The parameter set for this Classic McEliece instance. |
48 | | */ |
49 | 0 | Classic_McEliece_Parameter_Set parameter_set() const { return m_set; } |
50 | | |
51 | | /** |
52 | | * @brief The OID for the Classic McEliece instance. |
53 | | */ |
54 | | OID object_identifier() const; |
55 | | |
56 | | /** |
57 | | * @returns true iff the instance is a plaintext confirmation (PC) instance. |
58 | | */ |
59 | 0 | bool is_pc() const { |
60 | 0 | return (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_6688128pc) || |
61 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_6688128pcf) || |
62 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119pc) || |
63 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119pcf) || |
64 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_8192128pc) || |
65 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_8192128pcf); |
66 | 0 | } |
67 | | |
68 | | /** |
69 | | * @returns true iff the instance is a fast (F) instance, i.e. if the semi-systematic |
70 | | * matrix creation is used. |
71 | | ` */ |
72 | 0 | bool is_f() const { |
73 | 0 | return (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_348864f) || |
74 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_460896f) || |
75 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_6688128f) || |
76 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_6688128pcf) || |
77 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119f) || |
78 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119pcf) || |
79 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_8192128f) || |
80 | 0 | (m_set == Classic_McEliece_Parameter_Set::ClassicMcEliece_8192128pcf); |
81 | 0 | } |
82 | | |
83 | | /** |
84 | | * @brief The degree of the Classic McEliece instance's underlying Galois Field, i.e. GF(q) = GF(2^m). |
85 | | */ |
86 | 0 | size_t m() const { return m_m; } |
87 | | |
88 | | /** |
89 | | * @brief The field size of the Classic McEliece instance's underlying Galois Field, i.e. |
90 | | * GF(q) is the underlying field. |
91 | | */ |
92 | 0 | size_t q() const { return (size_t(1) << m_m); } |
93 | | |
94 | | /** |
95 | | * @brief The code length of the Classic McEliece instance. |
96 | | * |
97 | | * E.g. the Classic McEliece matrix H is of size m*t x n, |
98 | | * the encoded error vector is, therefore, of size n. |
99 | | */ |
100 | 0 | size_t n() const { return m_n; } |
101 | | |
102 | | /** |
103 | | * @brief The weight of the error vector e. |
104 | | */ |
105 | 0 | size_t t() const { return m_poly_ring.degree(); } |
106 | | |
107 | | /** |
108 | | * @brief Bit output length of the hash function H. |
109 | | */ |
110 | 0 | static constexpr size_t ell() { return 256; } |
111 | | |
112 | | /** |
113 | | * @brief The number of bits each GF element is encoded with. |
114 | | */ |
115 | 0 | static constexpr size_t sigma1() { return 16; } |
116 | | |
117 | | /** |
118 | | * @brief Constant for field-ordering generation. (see Classic McEliece ISO 8.2) |
119 | | */ |
120 | 0 | static constexpr size_t sigma2() { return 32; } |
121 | | |
122 | | /** |
123 | | * @brief Constant mu for semi-systematic matrix creation. (see Classic McEliece ISO 7.2.3) |
124 | | */ |
125 | 0 | static constexpr size_t mu() { return 32; } |
126 | | |
127 | | /** |
128 | | * @brief Constant nu for semi-systematic matrix creation. (see Classic McEliece ISO 7.2.3) |
129 | | */ |
130 | 0 | static constexpr size_t nu() { return 64; } |
131 | | |
132 | | /** |
133 | | * @brief Constant tau for fixed-weight vector generation. (see Classic McEliece ISO 8.4) |
134 | | */ |
135 | 0 | size_t tau() const { |
136 | | // Section 8.4 of ISO: |
137 | | // The integer tau is defined as t if n=q; as 2t if q/2<=n<q; as 4t if q/4<=n<q/2; etc |
138 | 0 | size_t tau_fact = size_t(1) << (m() - floor_log2(n())); |
139 | 0 | return tau_fact * t(); |
140 | 0 | } |
141 | | |
142 | | /** |
143 | | * @brief The monic irreducible polynomial f(z) of degree m over GF(2). Used for modular |
144 | | * reduction in GF(2^m). |
145 | | */ |
146 | 0 | CmceGfMod poly_f() const { return m_poly_ring.poly_f(); } |
147 | | |
148 | | /** |
149 | | * @brief The estimated bit security strength of the Classic McEliece instance. |
150 | | * |
151 | | * Reference: Classic McEliece NIST Round 4 submission, Guide for security reviewers |
152 | | */ |
153 | | size_t estimated_strength() const; |
154 | | |
155 | | /** |
156 | | * @brief The byte length of the seed delta. See ISO 9.2.12. |
157 | | */ |
158 | 0 | static constexpr size_t seed_len() { return ell() / 8; } |
159 | | |
160 | | /** |
161 | | * @brief The byte length of the column selection c. See ISO 9.2.12. |
162 | | */ |
163 | 0 | static constexpr size_t sk_c_bytes() { return 8; } |
164 | | |
165 | | /** |
166 | | * @brief The length of the byte representation of the minimal polynomial g. See ISO 9.2.12. |
167 | | */ |
168 | 0 | size_t sk_poly_g_bytes() const { return t() * sizeof(uint16_t); } |
169 | | |
170 | | /** |
171 | | * @brief The length of the byte representation of the field ordering's control bits. See ISO 9.2.12. |
172 | | */ |
173 | 0 | size_t sk_alpha_control_bytes() const { return (2 * m() - 1) * (size_t(1) << (m() - 4)); } |
174 | | |
175 | | /** |
176 | | * @brief The byte length of the seed s. s is used for implicit rejection. See ISO 9.2.12. |
177 | | */ |
178 | 0 | size_t sk_s_bytes() const { return n() / 8; } |
179 | | |
180 | | /** |
181 | | * @brief The byte length of the secret key sk. See ISO 9.2.12. |
182 | | */ |
183 | 0 | size_t sk_size_bytes() const { |
184 | | // ISO 9.2.12: sk = (delta, c, g, alpha(control bits), s) |
185 | 0 | return seed_len() + sk_c_bytes() + sk_poly_g_bytes() + sk_alpha_control_bytes() + sk_s_bytes(); |
186 | 0 | } |
187 | | |
188 | | /** |
189 | | * @brief The number of rows in the public key's matrix. |
190 | | */ |
191 | 0 | size_t pk_no_rows() const { return t() * m(); } |
192 | | |
193 | | /** |
194 | | * @brief The number of columns in the public key's matrix. |
195 | | * |
196 | | * Note that this is only the column number of the submatrix T (with H = (I_mt | T)), |
197 | | * which is stored in the public key. The column number of the whole matrix H is n. |
198 | | * This constant is also denoted as k in the spec. |
199 | | */ |
200 | 0 | size_t pk_no_cols() const { return n() - pk_no_rows(); } |
201 | | |
202 | | /** |
203 | | * @brief The number of bytes for each row in the public key's matrix. |
204 | | */ |
205 | 0 | size_t pk_row_size_bytes() const { return (pk_no_cols() + 7) / 8; } |
206 | | |
207 | | /** |
208 | | * @brief The number of bytes for the public key. |
209 | | * |
210 | | * Equal to the byte size of the CMCE matrix. |
211 | | */ |
212 | 0 | size_t pk_size_bytes() const { return pk_no_rows() * pk_row_size_bytes(); } |
213 | | |
214 | | /** |
215 | | * @brief The output byte size of the encoding algorithm. See ISO 7.3 |
216 | | */ |
217 | 0 | size_t encode_out_size() const { return ceil_division<size_t>(m() * t(), 8); } |
218 | | |
219 | | /** |
220 | | * @brief The byte size of the hash output. |
221 | | * |
222 | | * This is also the size of the shared key K that is a hash output. |
223 | | */ |
224 | 0 | static constexpr size_t hash_out_bytes() { return ell() / 8; } |
225 | | |
226 | | /** |
227 | | * @brief The byte size of the ciphertext. |
228 | | */ |
229 | 0 | size_t ciphertext_size() const { |
230 | 0 | if(is_pc()) { |
231 | | // C_0 + C_1 |
232 | 0 | return encode_out_size() + hash_out_bytes(); |
233 | 0 | } else { |
234 | 0 | return encode_out_size(); |
235 | 0 | } |
236 | 0 | } |
237 | | |
238 | | /** |
239 | | * @brief The underlying polynomial ring. |
240 | | */ |
241 | 0 | const Classic_McEliece_Polynomial_Ring& poly_ring() const { return m_poly_ring; } |
242 | | |
243 | | /** |
244 | | * @brief Create a seeded XOF object representing Classic McEliece's PRG. |
245 | | * See Classic McEliece ISO 9.1. |
246 | | * |
247 | | * @param seed The seed used for the XOF. |
248 | | */ |
249 | | std::unique_ptr<XOF> prg(std::span<const uint8_t> seed) const; |
250 | | |
251 | | /** |
252 | | * @brief Create an instance of the hash function Hash(x) used in Classic McEliece's |
253 | | * Decaps and Encaps algorithms. |
254 | | * |
255 | | * @return a new instance of the hash function. |
256 | | */ |
257 | 0 | std::unique_ptr<HashFunction> hash_func() const { return HashFunction::create_or_throw("SHAKE-256(256)"); } |
258 | | |
259 | | /** |
260 | | * @brief Create a GF(q) element using the modulus for the current instance. |
261 | | * |
262 | | * @param elem The GF(q) element value. |
263 | | * @return The GF(q) element. |
264 | | */ |
265 | 0 | Classic_McEliece_GF gf(CmceGfElem elem) const { return Classic_McEliece_GF(elem, poly_f()); } |
266 | | |
267 | | private: |
268 | | Classic_McEliece_Parameters(Classic_McEliece_Parameter_Set param_set, |
269 | | size_t m, |
270 | | size_t n, |
271 | | Classic_McEliece_Polynomial_Ring poly_ring); |
272 | | |
273 | | Classic_McEliece_Parameter_Set m_set; |
274 | | size_t m_m; |
275 | | size_t m_n; |
276 | | Classic_McEliece_Polynomial_Ring m_poly_ring; |
277 | | }; |
278 | | |
279 | | } // namespace Botan |
280 | | |
281 | | #endif |