Botan 3.13.0
Crypto and TLS for C&
mceliece_key.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 * (C) 2015 Jack Lloyd
8 *
9 * Botan is released under the Simplified BSD License (see license.txt)
10 *
11 */
12
13#include <botan/mceliece.h>
14
15#include <botan/ber_dec.h>
16#include <botan/der_enc.h>
17#include <botan/rng.h>
18#include <botan/internal/bit_ops.h>
19#include <botan/internal/buffer_stuffer.h>
20#include <botan/internal/code_based_util.h>
21#include <botan/internal/loadstor.h>
22#include <botan/internal/mce_internal.h>
23#include <botan/internal/pk_ops_impl.h>
24#include <botan/internal/polyn_gf2m.h>
25
26#include <array>
27#include <utility>
28
29namespace Botan {
30
31namespace {
32
33enum class McEliece_Key_Source : uint8_t { Raw, Encoded };
34
35constexpr std::array<std::pair<size_t, size_t>, 6> MCE_SUPPORTED_PARAMS = {
36 {{1632, 33}, {2480, 45}, {2960, 57}, {3408, 67}, {4624, 95}, {6624, 115}}};
37
38bool mceliece_params_are_supported(size_t code_length, size_t t) {
39 for(const auto& [supported_n, supported_t] : MCE_SUPPORTED_PARAMS) {
40 if(code_length == supported_n && t == supported_t) {
41 return true;
42 }
43 }
44 return false;
45}
46
47[[noreturn]] void throw_mceliece_validation_error(McEliece_Key_Source source, const char* msg) {
48 if(source == McEliece_Key_Source::Encoded) {
49 throw Decoding_Error(msg);
50 } else {
51 throw Invalid_Argument(msg);
52 }
53}
54
55McEliece_Params mceliece_validate_params(size_t code_length, size_t t, McEliece_Key_Source source) {
56 if(!mceliece_params_are_supported(code_length, t)) {
57 throw_mceliece_validation_error(source, "Unsupported McEliece parameters");
58 }
59
60 const size_t ext_deg = ceil_log2(code_length);
61 if(ext_deg < 2 || ext_deg > 15) {
62 throw_mceliece_validation_error(source, "McEliece code length out of supported range");
63 }
64
65 const size_t codimension = ext_deg * t;
66 if(codimension >= code_length) {
67 throw_mceliece_validation_error(source, "McEliece parameters are inconsistent");
68 }
69
70 const size_t dimension = code_length - codimension;
71 const size_t words_per_matrix_row = bit_size_to_32bit_size(codimension);
72 const size_t public_matrix_bytes = dimension * words_per_matrix_row * sizeof(uint32_t);
73
74 return McEliece_Params{code_length, t, ext_deg, codimension, dimension, words_per_matrix_row, public_matrix_bytes};
75}
76
77uint32_t padding_mask(size_t bit_count) {
78 const size_t used_bits = bit_count % 32;
79 if(used_bits == 0) {
80 return 0;
81 }
82 return ~((static_cast<uint32_t>(1) << used_bits) - 1);
83}
84
85void validate_public_matrix(const std::vector<uint8_t>& public_matrix,
86 const McEliece_Params& params,
87 McEliece_Key_Source source) {
88 if(public_matrix.size() != params.public_matrix_bytes) {
89 throw_mceliece_validation_error(source, "McEliece public matrix size does not match parameters");
90 }
91
92 const uint32_t unused_bits_mask = padding_mask(params.codimension);
93 if(unused_bits_mask == 0) {
94 return;
95 }
96
97 const size_t row_bytes = params.words_per_matrix_row * sizeof(uint32_t);
98 const size_t final_word_offset = (params.words_per_matrix_row - 1) * sizeof(uint32_t);
99 for(size_t row = 0; row != params.dimension; ++row) {
100 const uint8_t* row_ptr = public_matrix.data() + row * row_bytes;
101 const uint32_t final_word = load_le<uint32_t>(row_ptr + final_word_offset, 0);
102 if((final_word & unused_bits_mask) != 0) {
103 throw_mceliece_validation_error(source, "McEliece public matrix contains non-zero padding bits");
104 }
105 }
106}
107
108void validate_polynomial(const polyn_gf2m& polyn,
109 const McEliece_Params& params,
110 size_t min_coeff_count,
111 size_t max_degree,
112 McEliece_Key_Source source) {
113 const std::shared_ptr<GF2m_Field> field = polyn.get_sp_field();
114 if(!field || field->get_extension_degree() != params.ext_deg) {
115 throw_mceliece_validation_error(source, "McEliece polynomial uses an inconsistent field");
116 }
117
118 if(polyn.get_coeff_count() < min_coeff_count) {
119 throw_mceliece_validation_error(source, "McEliece polynomial has too few coefficients");
120 }
121
122 const int degree = polyn.get_degree();
123 if(degree >= 0 && static_cast<size_t>(degree) > max_degree) {
124 throw_mceliece_validation_error(source, "McEliece polynomial degree is too large");
125 }
126
127 const size_t field_cardinality = static_cast<size_t>(1) << params.ext_deg;
128 for(size_t i = 0; i != polyn.get_coeff_count(); ++i) {
129 if(polyn.get_coef(i) >= field_cardinality) {
130 throw_mceliece_validation_error(source, "McEliece polynomial coefficient is out of range");
131 }
132 }
133}
134
135void validate_support_inverse(const std::vector<gf2m>& inverse_support,
136 const McEliece_Params& params,
137 McEliece_Key_Source source) {
138 if(inverse_support.size() != params.code_length) {
139 throw_mceliece_validation_error(source, "McEliece support size does not match code length");
140 }
141
142 std::vector<uint8_t> seen(params.code_length);
143 for(const gf2m support_elem : inverse_support) {
144 if(support_elem >= params.code_length) {
145 throw_mceliece_validation_error(source, "McEliece support element is out of range");
146 }
147 if(seen[support_elem] != 0) {
148 throw_mceliece_validation_error(source, "McEliece support is not a permutation");
149 }
150 seen[support_elem] = 1;
151 }
152}
153
154void validate_parity_check_matrix(const std::vector<uint32_t>& parity_check_matrix_coeffs,
155 const McEliece_Params& params,
156 McEliece_Key_Source source) {
157 if(parity_check_matrix_coeffs.size() != params.words_per_matrix_row * params.code_length) {
158 throw_mceliece_validation_error(source, "McEliece parity check matrix has wrong length");
159 }
160
161 const uint32_t unused_bits_mask = padding_mask(params.codimension);
162 if(unused_bits_mask == 0) {
163 return;
164 }
165
166 for(size_t row = 0; row != params.code_length; ++row) {
167 const uint32_t final_word =
168 parity_check_matrix_coeffs[row * params.words_per_matrix_row + params.words_per_matrix_row - 1];
169 if((final_word & unused_bits_mask) != 0) {
170 throw_mceliece_validation_error(source, "McEliece parity check matrix contains non-zero padding bits");
171 }
172 }
173}
174
175void validate_private_components(const polyn_gf2m& goppa_polyn,
176 const std::vector<uint32_t>& parity_check_matrix_coeffs,
177 const std::vector<polyn_gf2m>& square_root_matrix,
178 const std::vector<gf2m>& inverse_support,
179 const std::vector<uint8_t>& public_matrix,
180 const McEliece_Params& params,
181 McEliece_Key_Source source) {
182 validate_public_matrix(public_matrix, params, source);
183
184 if(goppa_polyn.get_degree() != static_cast<int>(params.t)) {
185 throw_mceliece_validation_error(source, "degree of decoded Goppa polynomial is incorrect");
186 }
187 validate_polynomial(goppa_polyn, params, params.t + 1, params.t, source);
188 if(goppa_polyn.get_lead_coef() != 1) {
189 throw_mceliece_validation_error(source, "McEliece Goppa polynomial is not monic");
190 }
191
192 if(square_root_matrix.size() != params.t / 2) {
193 throw_mceliece_validation_error(source, "McEliece square root matrix has wrong length");
194 }
195 for(const auto& sqrt_polyn : square_root_matrix) {
196 validate_polynomial(sqrt_polyn, params, params.t, params.t - 1, source);
197 }
198
199 validate_support_inverse(inverse_support, params, source);
200 validate_parity_check_matrix(parity_check_matrix_coeffs, params, source);
201}
202
203} // namespace
204
206 return mceliece_validate_params(code_length, t, McEliece_Key_Source::Raw);
207}
208
210 return mceliece_validate_params(code_length, t, McEliece_Key_Source::Encoded);
211}
212
213McEliece_PrivateKey::McEliece_PrivateKey(const McEliece_PrivateKey&) = default;
214McEliece_PrivateKey::McEliece_PrivateKey(McEliece_PrivateKey&&) noexcept = default;
215McEliece_PrivateKey& McEliece_PrivateKey::operator=(const McEliece_PrivateKey&) = default;
216McEliece_PrivateKey& McEliece_PrivateKey::operator=(McEliece_PrivateKey&&) noexcept = default;
217McEliece_PrivateKey::~McEliece_PrivateKey() = default;
218
220 const std::vector<uint32_t>& parity_check_matrix_coeffs,
221 const std::vector<polyn_gf2m>& square_root_matrix,
222 const std::vector<gf2m>& inverse_support,
223 const std::vector<uint8_t>& public_matrix) {
224 const int goppa_degree = goppa_polyn.get_degree();
225 if(goppa_degree <= 0) {
226 throw Invalid_Argument("invalid McEliece Goppa polynomial degree");
227 }
228
229 const McEliece_Params params = mceliece_validate_keygen_params(inverse_support.size(), goppa_degree);
230 validate_private_components(goppa_polyn,
231 parity_check_matrix_coeffs,
232 square_root_matrix,
233 inverse_support,
234 public_matrix,
235 params,
236 McEliece_Key_Source::Raw);
237
238 m_public = std::make_shared<const McEliece_PublicKeyInternal>(public_matrix, params.t, params.code_length);
239 m_private = std::make_shared<const McEliece_PrivateKeyInternal>(std::vector<polyn_gf2m>{goppa_polyn},
240 square_root_matrix,
241 inverse_support,
242 parity_check_matrix_coeffs,
243 params.codimension,
244 params.dimension);
245}
246
247// NOLINTNEXTLINE(*-member-init)
249 const McEliece_Params params = mceliece_validate_keygen_params(code_length, t);
250 *this = generate_mceliece_key(rng, params.ext_deg, code_length, t);
251}
252
254 const size_t codimension = ceil_log2(m_code_length) * m_t;
255 return m_code_length - codimension;
256}
257
259 const size_t bits = message_word_bit_length();
260
261 secure_vector<uint8_t> plaintext((bits + 7) / 8);
262 rng.randomize(plaintext.data(), plaintext.size());
263
264 // unset unused bits in the last plaintext byte
265 if(const uint32_t used = bits % 8) {
266 const uint8_t mask = (1 << used) - 1;
267 plaintext[plaintext.size() - 1] &= mask;
268 }
269
270 return plaintext;
271}
272
273McEliece_PublicKey::McEliece_PublicKey(const std::vector<uint8_t>& pub_matrix, size_t t, size_t the_code_length) {
274 const McEliece_Params params = mceliece_validate_keygen_params(the_code_length, t);
275 validate_public_matrix(pub_matrix, params, McEliece_Key_Source::Raw);
276 m_public = std::make_shared<const McEliece_PublicKeyInternal>(pub_matrix, t, the_code_length);
277}
278
280 return m_public->t();
281}
282
284 return m_public->code_length();
285}
286
287const std::vector<uint8_t>& McEliece_PublicKey::get_public_matrix() const {
288 return m_public->public_matrix();
289}
290
292 return m_public->message_word_bit_length();
293}
294
296 return m_public->random_plaintext_element(rng);
297}
298
299bool McEliece_PublicKey::check_key(RandomNumberGenerator& /*rng*/, bool /*strong*/) const {
300 try {
301 if(!m_public) {
302 return false;
303 }
304
305 const McEliece_Params params = mceliece_validate_keygen_params(m_public->code_length(), m_public->t());
306 validate_public_matrix(m_public->public_matrix(), params, McEliece_Key_Source::Raw);
307 return true;
308 } catch(...) {
309 return false;
310 }
311}
312
314 return m_private->goppa_polyn();
315}
316
317const std::vector<uint32_t>& McEliece_PrivateKey::get_H_coeffs() const {
318 return m_private->H_coeffs();
319}
320
321const std::vector<gf2m>& McEliece_PrivateKey::get_Linv() const {
322 return m_private->Linv();
323}
324
325const std::vector<polyn_gf2m>& McEliece_PrivateKey::get_sqrtmod() const {
326 return m_private->sqrtmod();
327}
328
330 return m_private->dimension();
331}
332
334 return m_private->codimension();
335}
336
340
341std::vector<uint8_t> McEliece_PublicKey::raw_public_key_bits() const {
342 return m_public->public_matrix();
343}
344
345std::vector<uint8_t> McEliece_PublicKey::public_key_bits() const {
346 std::vector<uint8_t> output;
347 DER_Encoder(output)
351 .encode(get_t())
352 .end_cons()
353 .encode(m_public->public_matrix(), ASN1_Type::OctetString)
354 .end_cons();
355 return output;
356}
357
359 return m_public->code_length();
360}
361
363 return mceliece_work_factor(m_public->code_length(), m_public->t());
364}
365
366McEliece_PublicKey::McEliece_PublicKey(std::span<const uint8_t> key_bits) :
368
369McEliece_PublicKey::McEliece_PublicKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits) {
370 // The McEliece parameters are carried in the key bits; no AlgorithmIdentifier
371 // parameters are defined.
372 if(!alg_id.parameters_are_empty()) {
373 throw Decoding_Error("Unexpected parameters for McEliece public key");
374 }
375
376 BER_Decoder dec(key_bits, BER_Decoder::Limits::DER());
377 size_t n = 0;
378 size_t t = 0;
379 std::vector<uint8_t> public_matrix;
380 dec.start_sequence()
382 .decode(n)
383 .decode(t)
384 .end_cons()
385 .decode(public_matrix, ASN1_Type::OctetString)
386 .end_cons()
387 .verify_end();
388
390 validate_public_matrix(public_matrix, params, McEliece_Key_Source::Encoded);
391
392 m_public = std::make_shared<const McEliece_PublicKeyInternal>(std::move(public_matrix), t, n);
393}
394
396 DER_Encoder enc;
397 enc.start_sequence()
400 .encode(get_t())
401 .end_cons()
402 .encode(m_public->public_matrix(), ASN1_Type::OctetString)
403 .encode(m_private->goppa_polyn().encode(), ASN1_Type::OctetString); // g as octet string
404 enc.start_sequence();
405 for(const auto& x : m_private->sqrtmod()) {
406 enc.encode(x.encode(), ASN1_Type::OctetString);
407 }
408 enc.end_cons();
409 secure_vector<uint8_t> enc_support;
410
411 for(const uint16_t Linv : m_private->Linv()) {
412 enc_support.push_back(get_byte<0>(Linv));
413 enc_support.push_back(get_byte<1>(Linv));
414 }
415 enc.encode(enc_support, ASN1_Type::OctetString);
417 for(const uint32_t coef : m_private->H_coeffs()) {
418 enc_H.push_back(get_byte<0>(coef));
419 enc_H.push_back(get_byte<1>(coef));
420 enc_H.push_back(get_byte<2>(coef));
421 enc_H.push_back(get_byte<3>(coef));
422 }
423 enc.encode(enc_H, ASN1_Type::OctetString);
424 enc.end_cons();
425 return enc.get_contents();
426}
427
428bool McEliece_PrivateKey::check_key(RandomNumberGenerator& rng, bool /*unused*/) const {
429 const secure_vector<uint8_t> plaintext = this->random_plaintext_element(rng);
430
431 secure_vector<uint8_t> ciphertext;
433 mceliece_encrypt(ciphertext, errors, plaintext, *m_public, rng);
434
435 secure_vector<uint8_t> plaintext_out;
436 secure_vector<uint8_t> errors_out;
437 mceliece_decrypt(plaintext_out, errors_out, ciphertext, *m_private);
438
439 if(errors != errors_out || plaintext != plaintext_out) {
440 return false;
441 }
442
443 return true;
444}
445
446McEliece_PrivateKey::McEliece_PrivateKey(std::span<const uint8_t> key_bits) :
448
449McEliece_PrivateKey::McEliece_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits) {
450 // The McEliece parameters are carried in the key bits; no AlgorithmIdentifier
451 // parameters are defined.
452 if(!alg_id.parameters_are_empty()) {
453 throw Decoding_Error("Unexpected parameters for McEliece private key");
454 }
455
456 size_t n = 0;
457 size_t t = 0;
458 std::vector<uint8_t> public_matrix;
460 BER_Decoder dec_base(key_bits, BER_Decoder::Limits::DER());
461 BER_Decoder dec = dec_base.start_sequence();
462 dec.start_sequence().decode(n).decode(t).end_cons();
464
466 validate_public_matrix(public_matrix, params, McEliece_Key_Source::Encoded);
467
468 auto sp_field = std::make_shared<GF2m_Field>(params.ext_deg);
469 std::vector<polyn_gf2m> g = {polyn_gf2m(enc_g, sp_field)};
470 std::vector<polyn_gf2m> sqrtmod;
471 BER_Decoder dec2 = dec.start_sequence();
472 for(uint32_t i = 0; i < t / 2; i++) {
473 secure_vector<uint8_t> sqrt_enc;
474 dec2.decode(sqrt_enc, ASN1_Type::OctetString);
475 while(sqrt_enc.size() < (t * 2)) {
476 // ensure that the length is always t
477 sqrt_enc.push_back(0);
478 sqrt_enc.push_back(0);
479 }
480 if(sqrt_enc.size() != t * 2) {
481 throw Decoding_Error("length of square root polynomial entry is too large");
482 }
483 sqrtmod.push_back(polyn_gf2m(sqrt_enc, sp_field));
484 }
485 secure_vector<uint8_t> enc_support;
486 dec2.end_cons();
487 dec.decode(enc_support, ASN1_Type::OctetString);
488 if(enc_support.size() % 2 != 0) {
489 throw Decoding_Error("encoded support has odd length");
490 }
491 if(enc_support.size() / 2 != n) {
492 throw Decoding_Error("encoded support has length different from code length");
493 }
494 std::vector<gf2m> Linv;
495 for(uint32_t i = 0; i < n * 2; i += 2) {
496 const gf2m el = (enc_support[i] << 8) | enc_support[i + 1];
497 Linv.push_back(el);
498 }
501 if(enc_H.size() % 4 != 0) {
502 throw Decoding_Error("encoded parity check matrix has length which is not a multiple of four");
503 }
504 if(enc_H.size() / 4 != params.words_per_matrix_row * n) {
505 throw Decoding_Error("encoded parity check matrix has wrong length");
506 }
507
508 std::vector<uint32_t> coeffs;
509 for(uint32_t i = 0; i < enc_H.size(); i += 4) {
510 coeffs.push_back(make_uint32(enc_H[i], enc_H[i + 1], enc_H[i + 2], enc_H[i + 3]));
511 }
512
513 validate_private_components(g[0], coeffs, sqrtmod, Linv, public_matrix, params, McEliece_Key_Source::Encoded);
514
515 m_public = std::make_shared<const McEliece_PublicKeyInternal>(std::move(public_matrix), t, n);
516 m_private = std::make_shared<const McEliece_PrivateKeyInternal>(
517 std::move(g), std::move(sqrtmod), std::move(Linv), std::move(coeffs), params.codimension, params.dimension);
518}
519
521 if(*static_cast<const McEliece_PublicKey*>(this) != *static_cast<const McEliece_PublicKey*>(&other)) {
522 return false;
523 }
524 if(m_private->goppa_polyn_vec() != other.m_private->goppa_polyn_vec()) {
525 return false;
526 }
527
528 if(m_private->sqrtmod() != other.m_private->sqrtmod()) {
529 return false;
530 }
531 if(m_private->Linv() != other.m_private->Linv()) {
532 return false;
533 }
534 if(m_private->H_coeffs() != other.m_private->H_coeffs()) {
535 return false;
536 }
537
538 if(m_private->codimension() != other.m_private->codimension() ||
539 m_private->dimension() != other.m_private->dimension()) {
540 return false;
541 }
542
543 return true;
544}
545
546std::unique_ptr<Public_Key> McEliece_PrivateKey::public_key() const {
547 return std::make_unique<McEliece_PublicKey>(get_public_matrix(), get_t(), get_code_length());
548}
549
551 if(m_public->public_matrix() != other.m_public->public_matrix()) {
552 return false;
553 }
554 if(m_public->t() != other.m_public->t()) {
555 return false;
556 }
557 if(m_public->code_length() != other.m_public->code_length()) {
558 return false;
559 }
560 return true;
561}
562
563namespace {
564
565class MCE_KEM_Encryptor final : public PK_Ops::KEM_Encryption_with_KDF {
566 public:
567 MCE_KEM_Encryptor(std::shared_ptr<const McEliece_PublicKeyInternal> key, std::string_view kdf) :
568 KEM_Encryption_with_KDF(kdf), m_key(std::move(key)) {}
569
570 private:
571 size_t raw_kem_shared_key_length() const override {
572 const size_t err_sz = (m_key->code_length() + 7) / 8;
573 const size_t ptext_sz = (m_key->message_word_bit_length() + 7) / 8;
574 return ptext_sz + err_sz;
575 }
576
577 size_t encapsulated_key_length() const override { return (m_key->code_length() + 7) / 8; }
578
579 void raw_kem_encrypt(std::span<uint8_t> out_encapsulated_key,
580 std::span<uint8_t> raw_shared_key,
581 RandomNumberGenerator& rng) override {
582 secure_vector<uint8_t> plaintext = m_key->random_plaintext_element(rng);
583
584 secure_vector<uint8_t> ciphertext;
585 secure_vector<uint8_t> error_mask;
586 mceliece_encrypt(ciphertext, error_mask, plaintext, *m_key, rng);
587
588 // TODO: Perhaps avoid the copies below
589 BOTAN_ASSERT_NOMSG(out_encapsulated_key.size() == ciphertext.size());
590 std::copy(ciphertext.begin(), ciphertext.end(), out_encapsulated_key.begin());
591
592 BOTAN_ASSERT_NOMSG(raw_shared_key.size() == plaintext.size() + error_mask.size());
593 BufferStuffer bs(raw_shared_key);
594 bs.append(plaintext);
595 bs.append(error_mask);
596 }
597
598 std::shared_ptr<const McEliece_PublicKeyInternal> m_key;
599};
600
601class MCE_KEM_Decryptor final : public PK_Ops::KEM_Decryption_with_KDF {
602 public:
603 MCE_KEM_Decryptor(std::shared_ptr<const McEliece_PrivateKeyInternal> key, std::string_view kdf) :
604 KEM_Decryption_with_KDF(kdf), m_key(std::move(key)) {}
605
606 private:
607 size_t raw_kem_shared_key_length() const override {
608 const size_t err_sz = (m_key->code_length() + 7) / 8;
609 const size_t ptext_sz = (m_key->message_word_bit_length() + 7) / 8;
610 return ptext_sz + err_sz;
611 }
612
613 size_t encapsulated_key_length() const override { return (m_key->code_length() + 7) / 8; }
614
615 void raw_kem_decrypt(std::span<uint8_t> out_shared_key, std::span<const uint8_t> encapsulated_key) override {
616 secure_vector<uint8_t> plaintext;
617 secure_vector<uint8_t> error_mask;
618 mceliece_decrypt(plaintext, error_mask, encapsulated_key.data(), encapsulated_key.size(), *m_key);
619
620 // TODO: perhaps avoid the copies below
621 BOTAN_ASSERT_NOMSG(out_shared_key.size() == plaintext.size() + error_mask.size());
622 BufferStuffer bs(out_shared_key);
623 bs.append(plaintext);
624 bs.append(error_mask);
625 }
626
627 std::shared_ptr<const McEliece_PrivateKeyInternal> m_key;
628};
629
630} // namespace
631
632std::unique_ptr<Private_Key> McEliece_PublicKey::generate_another(RandomNumberGenerator& rng) const {
633 return std::make_unique<McEliece_PrivateKey>(rng, get_code_length(), get_t());
634}
635
636std::unique_ptr<PK_Ops::KEM_Encryption> McEliece_PublicKey::create_kem_encryption_op(std::string_view params,
637 std::string_view provider) const {
638 if(provider == "base" || provider.empty()) {
639 return std::make_unique<MCE_KEM_Encryptor>(m_public, params);
640 }
641 throw Provider_Not_Found(algo_name(), provider);
642}
643
644std::unique_ptr<PK_Ops::KEM_Decryption> McEliece_PrivateKey::create_kem_decryption_op(RandomNumberGenerator& /*rng*/,
645 std::string_view params,
646 std::string_view provider) const {
647 if(provider == "base" || provider.empty()) {
648 return std::make_unique<MCE_KEM_Decryptor>(m_private, params);
649 }
650 throw Provider_Not_Found(algo_name(), provider);
651}
652
653} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
bool parameters_are_empty() const
Definition asn1_obj.h:715
virtual OID object_identifier() const
Definition pk_keys.cpp:22
static Limits DER()
Definition ber_dec.h:42
void push_back(const BER_Object &obj)
Definition ber_dec.cpp:600
BER_Decoder & decode(bool &out)
Definition ber_dec.h:358
BER_Decoder & verify_end()
Definition ber_dec.cpp:471
BER_Decoder & end_cons()
Definition ber_dec.cpp:630
BER_Decoder start_sequence()
Definition ber_dec.h:275
secure_vector< uint8_t > get_contents()
Definition der_enc.cpp:161
DER_Encoder & start_sequence()
Definition der_enc.h:86
DER_Encoder & end_cons()
Definition der_enc.cpp:208
DER_Encoder & encode(bool b)
Definition der_enc.cpp:313
secure_vector< uint8_t > private_key_bits() const override
const std::vector< polyn_gf2m > & get_sqrtmod() const
McEliece_PrivateKey(RandomNumberGenerator &rng, size_t code_length, size_t t)
std::unique_ptr< Public_Key > public_key() const override
std::unique_ptr< PK_Ops::KEM_Decryption > create_kem_decryption_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
const polyn_gf2m & get_goppa_polyn() const
const std::vector< gf2m > & get_Linv() const
bool operator==(const McEliece_PrivateKey &other) const
const std::vector< uint32_t > & get_H_coeffs() const
bool check_key(RandomNumberGenerator &rng, bool strong) const override
secure_vector< uint8_t > random_plaintext_element(RandomNumberGenerator &rng) const
secure_vector< uint8_t > random_plaintext_element(RandomNumberGenerator &rng) const
size_t get_message_word_bit_length() const
std::shared_ptr< const McEliece_PublicKeyInternal > m_public
Definition mceliece.h:80
std::vector< uint8_t > raw_public_key_bits() const override
std::unique_ptr< PK_Ops::KEM_Encryption > create_kem_encryption_op(std::string_view params, std::string_view provider) const override
std::string algo_name() const override
Definition mceliece.h:44
std::vector< uint8_t > public_key_bits() const override
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const final
McEliece_PublicKey(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
const std::vector< uint8_t > & get_public_matrix() const
bool check_key(RandomNumberGenerator &rng, bool strong) const override
size_t estimated_strength() const override
bool operator==(const McEliece_PublicKey &other) const
AlgorithmIdentifier algorithm_identifier() const override
size_t key_length() const override
void randomize(std::span< uint8_t > output)
Definition rng.h:86
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79
void mceliece_decrypt(secure_vector< uint8_t > &plaintext_out, secure_vector< uint8_t > &error_mask_out, const secure_vector< uint8_t > &ciphertext, const McEliece_PrivateKeyInternal &key)
constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
Definition loadstor.h:104
constexpr uint8_t ceil_log2(T x)
Definition bit_ops.h:140
McEliece_Params mceliece_validate_key_encoding_params(size_t code_length, size_t t)
McEliece_PrivateKey generate_mceliece_key(RandomNumberGenerator &rng, size_t ext_deg, size_t code_length, size_t t)
size_t mceliece_work_factor(size_t n, size_t t)
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:495
void mceliece_encrypt(secure_vector< uint8_t > &ciphertext_out, secure_vector< uint8_t > &error_mask_out, const secure_vector< uint8_t > &plaintext, const McEliece_PublicKeyInternal &key, RandomNumberGenerator &rng)
Definition mceliece.cpp:119
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
size_t bit_size_to_32bit_size(size_t bit_size)
McEliece_Params mceliece_validate_keygen_params(size_t code_length, size_t t)
uint16_t gf2m