Coverage Report

Created: 2026-04-08 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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