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