/src/botan/src/lib/pubkey/classic_mceliece/cmce.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Classic McEliece Key Generation |
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 | | #include <botan/cmce.h> |
10 | | #include <botan/pk_ops.h> |
11 | | #include <botan/rng.h> |
12 | | #include <botan/internal/cmce_decaps.h> |
13 | | #include <botan/internal/cmce_encaps.h> |
14 | | #include <botan/internal/cmce_field_ordering.h> |
15 | | #include <botan/internal/cmce_keys_internal.h> |
16 | | #include <botan/internal/cmce_matrix.h> |
17 | | #include <botan/internal/ct_utils.h> |
18 | | #include <botan/internal/pk_ops_impl.h> |
19 | | |
20 | | #include <algorithm> |
21 | | |
22 | | namespace Botan { |
23 | | |
24 | | Classic_McEliece_PublicKey::Classic_McEliece_PublicKey(const AlgorithmIdentifier& alg_id, |
25 | | std::span<const uint8_t> key_bits) : |
26 | 0 | Classic_McEliece_PublicKey(key_bits, Classic_McEliece_Parameter_Set::from_oid(alg_id.oid())) {} Unexecuted instantiation: Botan::Classic_McEliece_PublicKey::Classic_McEliece_PublicKey(Botan::AlgorithmIdentifier const&, std::__1::span<unsigned char const, 18446744073709551615ul>) Unexecuted instantiation: Botan::Classic_McEliece_PublicKey::Classic_McEliece_PublicKey(Botan::AlgorithmIdentifier const&, std::__1::span<unsigned char const, 18446744073709551615ul>) |
27 | | |
28 | | Classic_McEliece_PublicKey::Classic_McEliece_PublicKey(std::span<const uint8_t> key_bits, |
29 | 0 | Classic_McEliece_Parameter_Set param_set) { |
30 | 0 | auto params = Classic_McEliece_Parameters::create(param_set); |
31 | 0 | BOTAN_ARG_CHECK(key_bits.size() == params.pk_size_bytes(), "Wrong public key length"); |
32 | 0 | m_public = std::make_shared<Classic_McEliece_PublicKeyInternal>( |
33 | 0 | params, Classic_McEliece_Matrix(params, {key_bits.begin(), key_bits.end()})); |
34 | 0 | } Unexecuted instantiation: Botan::Classic_McEliece_PublicKey::Classic_McEliece_PublicKey(std::__1::span<unsigned char const, 18446744073709551615ul>, Botan::Classic_McEliece_Parameter_Set) Unexecuted instantiation: Botan::Classic_McEliece_PublicKey::Classic_McEliece_PublicKey(std::__1::span<unsigned char const, 18446744073709551615ul>, Botan::Classic_McEliece_Parameter_Set) |
35 | | |
36 | 0 | Classic_McEliece_PublicKey::Classic_McEliece_PublicKey(const Classic_McEliece_PublicKey& other) { |
37 | 0 | m_public = std::make_shared<Classic_McEliece_PublicKeyInternal>(*other.m_public); |
38 | 0 | } Unexecuted instantiation: Botan::Classic_McEliece_PublicKey::Classic_McEliece_PublicKey(Botan::Classic_McEliece_PublicKey const&) Unexecuted instantiation: Botan::Classic_McEliece_PublicKey::Classic_McEliece_PublicKey(Botan::Classic_McEliece_PublicKey const&) |
39 | | |
40 | 0 | Classic_McEliece_PublicKey& Classic_McEliece_PublicKey::operator=(const Classic_McEliece_PublicKey& other) { |
41 | 0 | if(this != &other) { |
42 | 0 | m_public = std::make_shared<Classic_McEliece_PublicKeyInternal>(*other.m_public); |
43 | 0 | } |
44 | 0 | return *this; |
45 | 0 | } |
46 | | |
47 | 0 | AlgorithmIdentifier Classic_McEliece_PublicKey::algorithm_identifier() const { |
48 | 0 | return AlgorithmIdentifier(object_identifier(), AlgorithmIdentifier::USE_EMPTY_PARAM); |
49 | 0 | } |
50 | | |
51 | 0 | OID Classic_McEliece_PublicKey::object_identifier() const { |
52 | 0 | return m_public->params().object_identifier(); |
53 | 0 | } |
54 | | |
55 | 0 | size_t Classic_McEliece_PublicKey::key_length() const { |
56 | | // The key length is the dimension k of the goppa code (i.e. the code has 2^k codewords) |
57 | 0 | return m_public->params().pk_no_cols(); |
58 | 0 | } |
59 | | |
60 | 0 | size_t Classic_McEliece_PublicKey::estimated_strength() const { |
61 | 0 | return m_public->params().estimated_strength(); |
62 | 0 | } |
63 | | |
64 | 0 | std::vector<uint8_t> Classic_McEliece_PublicKey::public_key_bits() const { |
65 | 0 | return raw_public_key_bits(); |
66 | 0 | } |
67 | | |
68 | 0 | std::vector<uint8_t> Classic_McEliece_PublicKey::raw_public_key_bits() const { |
69 | 0 | return m_public->matrix().bytes(); |
70 | 0 | } |
71 | | |
72 | 0 | bool Classic_McEliece_PublicKey::check_key(RandomNumberGenerator&, bool) const { |
73 | 0 | return true; |
74 | 0 | } |
75 | | |
76 | 0 | std::unique_ptr<Private_Key> Classic_McEliece_PublicKey::generate_another(RandomNumberGenerator& rng) const { |
77 | 0 | return std::make_unique<Classic_McEliece_PrivateKey>(rng, m_public->params().parameter_set()); |
78 | 0 | } |
79 | | |
80 | | std::unique_ptr<PK_Ops::KEM_Encryption> Classic_McEliece_PublicKey::create_kem_encryption_op( |
81 | 0 | std::string_view params, std::string_view provider) const { |
82 | 0 | if(provider.empty() || provider == "base") { |
83 | 0 | return std::make_unique<Classic_McEliece_Encryptor>(this->m_public, params); |
84 | 0 | } |
85 | 0 | throw Provider_Not_Found(algo_name(), provider); |
86 | 0 | } |
87 | | |
88 | | Classic_McEliece_PrivateKey::Classic_McEliece_PrivateKey(RandomNumberGenerator& rng, |
89 | 0 | Classic_McEliece_Parameter_Set param_set) { |
90 | 0 | auto params = Classic_McEliece_Parameters::create(param_set); |
91 | 0 | const auto seed = rng.random_vec<CmceInitialSeed>(params.seed_len()); |
92 | 0 | CT::poison(seed); |
93 | 0 | std::tie(m_private, m_public) = Classic_McEliece_KeyPair_Internal::generate(params, seed).decompose_to_pair(); |
94 | |
|
95 | 0 | BOTAN_ASSERT_NONNULL(m_private); |
96 | 0 | BOTAN_ASSERT_NONNULL(m_public); |
97 | 0 | CT::unpoison_all(*m_private, *m_public); |
98 | 0 | } Unexecuted instantiation: Botan::Classic_McEliece_PrivateKey::Classic_McEliece_PrivateKey(Botan::RandomNumberGenerator&, Botan::Classic_McEliece_Parameter_Set) Unexecuted instantiation: Botan::Classic_McEliece_PrivateKey::Classic_McEliece_PrivateKey(Botan::RandomNumberGenerator&, Botan::Classic_McEliece_Parameter_Set) |
99 | | |
100 | | Classic_McEliece_PrivateKey::Classic_McEliece_PrivateKey(std::span<const uint8_t> sk, |
101 | 0 | Classic_McEliece_Parameter_Set param_set) { |
102 | 0 | auto scope = CT::scoped_poison(sk); |
103 | 0 | auto params = Classic_McEliece_Parameters::create(param_set); |
104 | 0 | auto sk_internal = Classic_McEliece_PrivateKeyInternal::from_bytes(params, sk); |
105 | 0 | m_private = std::make_shared<Classic_McEliece_PrivateKeyInternal>(std::move(sk_internal)); |
106 | | // This creates and loads the public key, which is very large. Potentially, we could only load |
107 | | // it on demand (since one may use the private key only for decapsulation without needing the public key). |
108 | | // TODO: consider building a load-on-demand mechanism for the public key |
109 | 0 | m_public = Classic_McEliece_PublicKeyInternal::create_from_private_key(*m_private); |
110 | 0 | CT::unpoison_all(*m_public, *m_private); |
111 | 0 | } Unexecuted instantiation: Botan::Classic_McEliece_PrivateKey::Classic_McEliece_PrivateKey(std::__1::span<unsigned char const, 18446744073709551615ul>, Botan::Classic_McEliece_Parameter_Set) Unexecuted instantiation: Botan::Classic_McEliece_PrivateKey::Classic_McEliece_PrivateKey(std::__1::span<unsigned char const, 18446744073709551615ul>, Botan::Classic_McEliece_Parameter_Set) |
112 | | |
113 | | Classic_McEliece_PrivateKey::Classic_McEliece_PrivateKey(const AlgorithmIdentifier& alg_id, |
114 | | std::span<const uint8_t> key_bits) : |
115 | 0 | Classic_McEliece_PrivateKey(key_bits, Classic_McEliece_Parameter_Set::from_oid(alg_id.oid())) {} Unexecuted instantiation: Botan::Classic_McEliece_PrivateKey::Classic_McEliece_PrivateKey(Botan::AlgorithmIdentifier const&, std::__1::span<unsigned char const, 18446744073709551615ul>) Unexecuted instantiation: Botan::Classic_McEliece_PrivateKey::Classic_McEliece_PrivateKey(Botan::AlgorithmIdentifier const&, std::__1::span<unsigned char const, 18446744073709551615ul>) |
116 | | |
117 | 0 | std::unique_ptr<Public_Key> Classic_McEliece_PrivateKey::public_key() const { |
118 | 0 | return std::make_unique<Classic_McEliece_PublicKey>(*this); |
119 | 0 | } |
120 | | |
121 | 0 | secure_vector<uint8_t> Classic_McEliece_PrivateKey::private_key_bits() const { |
122 | 0 | return raw_private_key_bits(); |
123 | 0 | } |
124 | | |
125 | 0 | secure_vector<uint8_t> Classic_McEliece_PrivateKey::raw_private_key_bits() const { |
126 | 0 | return m_private->serialize(); |
127 | 0 | } |
128 | | |
129 | 0 | bool Classic_McEliece_PrivateKey::check_key(RandomNumberGenerator&, bool) const { |
130 | 0 | return m_private->check_key(); |
131 | 0 | } |
132 | | |
133 | | std::unique_ptr<PK_Ops::KEM_Decryption> Classic_McEliece_PrivateKey::create_kem_decryption_op( |
134 | 0 | RandomNumberGenerator& rng, std::string_view params, std::string_view provider) const { |
135 | 0 | BOTAN_UNUSED(rng); |
136 | 0 | if(provider.empty() || provider == "base") { |
137 | 0 | return std::make_unique<Classic_McEliece_Decryptor>(this->m_private, params); |
138 | 0 | } |
139 | 0 | throw Provider_Not_Found(algo_name(), provider); |
140 | 0 | } |
141 | | |
142 | | } // namespace Botan |