/src/botan/src/lib/pubkey/hybrid_kem/hybrid_kem.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * Abstraction for a combined KEM public and private key. |
3 | | * |
4 | | * (C) 2024 Jack Lloyd |
5 | | * 2024 Fabian Albert, René Meusel - Rohde & Schwarz Cybersecurity |
6 | | * |
7 | | * Botan is released under the Simplified BSD License (see license.txt) |
8 | | */ |
9 | | #include <botan/internal/hybrid_kem.h> |
10 | | |
11 | | #include <botan/pk_algs.h> |
12 | | #include <botan/internal/fmt.h> |
13 | | #include <botan/internal/kex_to_kem_adapter.h> |
14 | | #include <botan/internal/pk_ops_impl.h> |
15 | | #include <botan/internal/stl_util.h> |
16 | | |
17 | | namespace Botan { |
18 | | |
19 | | Hybrid_PublicKey::Hybrid_PublicKey(std::vector<std::unique_ptr<Public_Key>> pks) : |
20 | 0 | m_pks(std::move(pks)), m_key_length(0), m_estimated_strength(0) { |
21 | 0 | BOTAN_ARG_CHECK(m_pks.size() >= 2, "List of public keys must include at least two keys"); |
22 | 0 | for(const auto& pk : m_pks) { |
23 | 0 | BOTAN_ARG_CHECK(pk != nullptr, "List of public keys contains a nullptr"); |
24 | 0 | BOTAN_ARG_CHECK(pk->supports_operation(PublicKeyOperation::KeyEncapsulation), |
25 | 0 | fmt("Public key type '{}' does not support key encapsulation", pk->algo_name()).c_str()); |
26 | 0 | m_key_length = std::max(m_key_length, pk->key_length()); |
27 | 0 | m_estimated_strength = std::max(m_estimated_strength, pk->estimated_strength()); |
28 | 0 | } |
29 | 0 | } |
30 | | |
31 | 0 | bool Hybrid_PublicKey::check_key(RandomNumberGenerator& rng, bool strong) const { |
32 | 0 | return reduce(public_keys(), true, [&](bool ckr, const auto& key) { return ckr && key->check_key(rng, strong); }); |
33 | 0 | } |
34 | | |
35 | 0 | std::vector<uint8_t> Hybrid_PublicKey::raw_public_key_bits() const { |
36 | 0 | return reduce(public_keys(), std::vector<uint8_t>(), [](auto pkb, const auto& key) { |
37 | 0 | return concat(pkb, key->raw_public_key_bits()); |
38 | 0 | }); |
39 | 0 | } |
40 | | |
41 | 0 | bool Hybrid_PublicKey::supports_operation(PublicKeyOperation op) const { |
42 | 0 | return PublicKeyOperation::KeyEncapsulation == op; |
43 | 0 | } |
44 | | |
45 | | std::vector<std::unique_ptr<Private_Key>> Hybrid_PublicKey::generate_other_sks_from_pks( |
46 | 0 | RandomNumberGenerator& rng) const { |
47 | 0 | std::vector<std::unique_ptr<Private_Key>> new_private_keys; |
48 | 0 | new_private_keys.reserve(public_keys().size()); |
49 | 0 | for(const auto& pk : public_keys()) { |
50 | 0 | new_private_keys.push_back(pk->generate_another(rng)); |
51 | 0 | } |
52 | 0 | return new_private_keys; |
53 | 0 | } |
54 | | |
55 | | Hybrid_PrivateKey::Hybrid_PrivateKey(std::vector<std::unique_ptr<Private_Key>> private_keys) : |
56 | 0 | m_sks(std::move(private_keys)) { |
57 | 0 | BOTAN_ARG_CHECK(m_sks.size() >= 2, "List of secret keys must include at least two keys"); |
58 | 0 | for(const auto& sk : m_sks) { |
59 | 0 | BOTAN_ARG_CHECK(sk != nullptr, "List of secret keys contains a nullptr"); |
60 | 0 | BOTAN_ARG_CHECK(sk->supports_operation(PublicKeyOperation::KeyEncapsulation), |
61 | 0 | "Some provided secret key is not compatible with this hybrid wrapper"); |
62 | 0 | } |
63 | 0 | } |
64 | | |
65 | 0 | secure_vector<uint8_t> Hybrid_PrivateKey::private_key_bits() const { |
66 | 0 | throw Not_Implemented("Hybrid private keys cannot be serialized"); |
67 | 0 | } |
68 | | |
69 | 0 | bool Hybrid_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const { |
70 | 0 | return reduce(private_keys(), true, [&](bool ckr, const auto& key) { return ckr && key->check_key(rng, strong); }); |
71 | 0 | } |
72 | | |
73 | | std::vector<std::unique_ptr<Public_Key>> Hybrid_PrivateKey::extract_public_keys( |
74 | 0 | const std::vector<std::unique_ptr<Private_Key>>& private_keys) { |
75 | 0 | std::vector<std::unique_ptr<Public_Key>> public_keys; |
76 | 0 | public_keys.reserve(private_keys.size()); |
77 | 0 | for(const auto& sk : private_keys) { |
78 | 0 | BOTAN_ARG_CHECK(sk != nullptr, "List of private keys contains a nullptr"); |
79 | 0 | public_keys.push_back(sk->public_key()); |
80 | 0 | } |
81 | 0 | return public_keys; |
82 | 0 | } |
83 | | |
84 | | } // namespace Botan |