Botan 3.9.0
Crypto and TLS for C&
dh.cpp
Go to the documentation of this file.
1/*
2* Diffie-Hellman
3* (C) 1999-2007,2016,2019,2023 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/dh.h>
9
10#include <botan/internal/blinding.h>
11#include <botan/internal/dl_scheme.h>
12#include <botan/internal/pk_ops_impl.h>
13
14namespace Botan {
15
16DH_PublicKey::DH_PublicKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits) {
17 m_public_key = std::make_shared<DL_PublicKey>(alg_id, key_bits, DL_Group_Format::ANSI_X9_42);
18}
19
21 m_public_key = std::make_shared<DL_PublicKey>(group, y);
22}
23
25 return m_public_key->estimated_strength();
26}
27
29 return m_public_key->p_bits();
30}
31
32const BigInt& DH_PublicKey::get_int_field(std::string_view field) const {
33 return m_public_key->get_int_field(algo_name(), field);
34}
35
37 return m_public_key->group();
38}
39
43
44std::vector<uint8_t> DH_PublicKey::raw_public_key_bits() const {
45 return m_public_key->public_key_as_bytes();
46}
47
48std::vector<uint8_t> DH_PublicKey::public_key_bits() const {
49 return m_public_key->DER_encode();
50}
51
52bool DH_PublicKey::check_key(RandomNumberGenerator& rng, bool strong) const {
53 return m_public_key->check_key(rng, strong);
54}
55
56std::unique_ptr<Private_Key> DH_PublicKey::generate_another(RandomNumberGenerator& rng) const {
57 return std::make_unique<DH_PrivateKey>(rng, group());
58}
59
61 m_private_key = std::make_shared<DL_PrivateKey>(group, rng);
62 m_public_key = m_private_key->public_key();
63}
64
66 m_private_key = std::make_shared<DL_PrivateKey>(group, x);
67 m_public_key = m_private_key->public_key();
68}
69
70DH_PrivateKey::DH_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits) {
71 m_private_key = std::make_shared<DL_PrivateKey>(alg_id, key_bits, DL_Group_Format::ANSI_X9_42);
72 m_public_key = m_private_key->public_key();
73}
74
75std::unique_ptr<Public_Key> DH_PrivateKey::public_key() const {
76 return std::unique_ptr<DH_PublicKey>(new DH_PublicKey(m_public_key));
77}
78
79std::vector<uint8_t> DH_PrivateKey::public_value() const {
80 return raw_public_key_bits();
81}
82
84 return m_private_key->DER_encode();
85}
86
88 return m_private_key->raw_private_key_bits();
89}
90
91const BigInt& DH_PrivateKey::get_int_field(std::string_view field) const {
92 return m_private_key->get_int_field(algo_name(), field);
93}
94
95namespace {
96
97/**
98* DH operation
99*/
100class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF {
101 public:
102 DH_KA_Operation(const std::shared_ptr<const DL_PrivateKey>& key,
103 std::string_view kdf,
105 PK_Ops::Key_Agreement_with_KDF(kdf),
106 m_key(key),
107 m_key_bits(m_key->private_key().bits()),
108 m_blinder(
109 m_key->group()._reducer_mod_p(),
110 rng,
111 [](const BigInt& k) { return k; },
112 [this](const BigInt& k) { return powermod_x_p(group().inverse_mod_p(k)); }) {}
113
114 size_t agreed_value_size() const override { return group().p_bytes(); }
115
116 secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override;
117
118 private:
119 const DL_Group& group() const { return m_key->group(); }
120
121 BigInt powermod_x_p(const BigInt& v) const { return group().power_b_p(v, m_key->private_key(), m_key_bits); }
122
123 std::shared_ptr<const DL_PrivateKey> m_key;
124 const size_t m_key_bits;
125 Blinder m_blinder;
126};
127
128secure_vector<uint8_t> DH_KA_Operation::raw_agree(const uint8_t w[], size_t w_len) {
129 BigInt v = BigInt::from_bytes(std::span{w, w_len});
130
131 if(v <= 1 || v >= group().get_p()) {
132 throw Invalid_Argument("DH agreement - invalid key provided");
133 }
134
135 v = m_blinder.blind(v);
136 v = powermod_x_p(v);
137 v = m_blinder.unblind(v);
138
139 return v.serialize<secure_vector<uint8_t>>(group().p_bytes());
140}
141
142} // namespace
143
144std::unique_ptr<PK_Ops::Key_Agreement> DH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng,
145 std::string_view params,
146 std::string_view provider) const {
147 if(provider == "base" || provider.empty()) {
148 return std::make_unique<DH_KA_Operation>(this->m_private_key, params, rng);
149 }
150 throw Provider_Not_Found(algo_name(), provider);
151}
152
153} // namespace Botan
virtual OID object_identifier() const
Definition pk_keys.cpp:22
T serialize(size_t len) const
Definition bigint.h:711
BigInt blind(const BigInt &x) const
Definition blinding.cpp:31
BigInt unblind(const BigInt &x) const
Definition blinding.cpp:47
std::vector< uint8_t > public_value() const override
Definition dh.cpp:79
secure_vector< uint8_t > raw_private_key_bits() const override
Definition dh.cpp:87
const BigInt & get_int_field(std::string_view field) const override
Definition dh.cpp:91
secure_vector< uint8_t > private_key_bits() const override
Definition dh.cpp:83
std::unique_ptr< Public_Key > public_key() const override
Definition dh.cpp:75
std::unique_ptr< PK_Ops::Key_Agreement > create_key_agreement_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
Definition dh.cpp:144
size_t key_length() const override
Definition dh.cpp:28
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition dh.cpp:52
DH_PublicKey(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
Definition dh.cpp:16
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const final
Definition dh.cpp:56
std::vector< uint8_t > public_key_bits() const override
Definition dh.cpp:48
friend class DH_PrivateKey
Definition dh.h:66
AlgorithmIdentifier algorithm_identifier() const override
Definition dh.cpp:40
const BigInt & get_int_field(std::string_view field) const override
Definition dh.cpp:32
std::string algo_name() const override
Definition dh.h:55
const DL_Group & group() const
Definition dh.cpp:36
size_t estimated_strength() const override
Definition dh.cpp:24
std::vector< uint8_t > raw_public_key_bits() const override
Definition dh.cpp:44
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:69