Botan 3.0.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#include <botan/internal/dl_scheme.h>
10#include <botan/internal/pk_ops_impl.h>
11#include <botan/internal/blinding.h>
12
13namespace Botan {
14
15DH_PublicKey::DH_PublicKey(const AlgorithmIdentifier& alg_id,
16 std::span<const uint8_t> key_bits)
17 {
18 m_public_key = std::make_shared<DL_PublicKey>(alg_id, key_bits, DL_Group_Format::ANSI_X9_42);
19 }
20
21DH_PublicKey::DH_PublicKey(const DL_Group& group, const BigInt& y)
22 {
23 m_public_key = std::make_shared<DL_PublicKey>(group, y);
24 }
25
26std::vector<uint8_t> DH_PublicKey::public_value() const
27 {
28 return m_public_key->public_key_as_bytes();
29 }
30
32 {
33 return m_public_key->estimated_strength();
34 }
35
37 {
38 return m_public_key->p_bits();
39 }
40
41const BigInt& DH_PublicKey::get_int_field(std::string_view field) const
42 {
43 return m_public_key->get_int_field(algo_name(), field);
44 }
45
47 {
50 m_public_key->group().DER_encode(DL_Group_Format::ANSI_X9_42));
51 }
52
53std::vector<uint8_t> DH_PublicKey::public_key_bits() const
54 {
55 return m_public_key->DER_encode();
56 }
57
59 {
60 return m_public_key->check_key(rng, strong);
61 }
62
64 const DL_Group& group)
65 {
66 m_private_key = std::make_shared<DL_PrivateKey>(group, rng);
67 m_public_key = m_private_key->public_key();
68 }
69
71 const BigInt& x)
72 {
73 m_private_key = std::make_shared<DL_PrivateKey>(group, x);
74 m_public_key = m_private_key->public_key();
75 }
76
78 std::span<const uint8_t> key_bits)
79 {
80 m_private_key = std::make_shared<DL_PrivateKey>(alg_id, key_bits, DL_Group_Format::ANSI_X9_42);
81 m_public_key = m_private_key->public_key();
82 }
83
84std::unique_ptr<Public_Key> DH_PrivateKey::public_key() const
85 {
86 return std::unique_ptr<DH_PublicKey>(new DH_PublicKey(m_public_key));
87 }
88
89std::vector<uint8_t> DH_PrivateKey::public_value() const
90 {
92 }
93
95 {
96 return m_private_key->DER_encode();
97 }
98
100 {
101 return m_private_key->raw_private_key_bits();
102 }
103
104const BigInt& DH_PrivateKey::get_int_field(std::string_view field) const
105 {
106 return m_private_key->get_int_field(algo_name(), field);
107 }
108
109namespace {
110
111/**
112* DH operation
113*/
114class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
115 {
116 public:
117
118 DH_KA_Operation(const std::shared_ptr<const DL_PrivateKey>& key,
119 std::string_view kdf,
121 PK_Ops::Key_Agreement_with_KDF(kdf),
122 m_key(key),
123 m_key_bits(m_key->private_key().bits()),
124 m_blinder(m_key->group().get_p(),
125 rng,
126 [](const BigInt& k) { return k; },
127 [this](const BigInt& k)
128 {
129 const BigInt inv_k = inverse_mod(k, group().get_p());
130 return powermod_x_p(inv_k);
131 })
132 {}
133
134 size_t agreed_value_size() const override { return group().p_bytes(); }
135
136 secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override;
137 private:
138 const DL_Group& group() const
139 {
140 return m_key->group();
141 }
142
143 BigInt powermod_x_p(const BigInt& v) const
144 {
145 return group().power_b_p(v, m_key->private_key(), m_key_bits);
146 }
147
148 std::shared_ptr<const DL_PrivateKey> m_key;
149 std::shared_ptr<const Montgomery_Params> m_monty_p;
150 const size_t m_key_bits;
151 Blinder m_blinder;
152 };
153
154secure_vector<uint8_t> DH_KA_Operation::raw_agree(const uint8_t w[], size_t w_len)
155 {
156 BigInt v = BigInt::decode(w, w_len);
157
158 if(v <= 1 || v >= group().get_p())
159 throw Invalid_Argument("DH agreement - invalid key provided");
160
161 v = m_blinder.blind(v);
162 v = powermod_x_p(v);
163 v = m_blinder.unblind(v);
164
165 return BigInt::encode_1363(v, group().p_bytes());
166 }
167
168}
169
170std::unique_ptr<PK_Ops::Key_Agreement>
172 std::string_view params,
173 std::string_view provider) const
174 {
175 if(provider == "base" || provider.empty())
176 return std::make_unique<DH_KA_Operation>(this->m_private_key, params, rng);
177 throw Provider_Not_Found(algo_name(), provider);
178 }
179
180}
static SIMD_4x64 y
virtual OID object_identifier() const
Definition: pk_keys.cpp:22
static BigInt decode(const uint8_t buf[], size_t length)
Definition: bigint.h:805
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:107
BigInt blind(const BigInt &x) const
Definition: blinding.cpp:35
BigInt unblind(const BigInt &x) const
Definition: blinding.cpp:58
std::vector< uint8_t > public_value() const override
Definition: dh.cpp:89
secure_vector< uint8_t > raw_private_key_bits() const override
Definition: dh.cpp:99
const BigInt & get_int_field(std::string_view field) const override
Definition: dh.cpp:104
secure_vector< uint8_t > private_key_bits() const override
Definition: dh.cpp:94
std::unique_ptr< Public_Key > public_key() const override
Definition: dh.cpp:84
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:171
size_t key_length() const override
Definition: dh.cpp:36
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition: dh.cpp:58
std::vector< uint8_t > public_value() const
Definition: dh.cpp:26
std::vector< uint8_t > public_key_bits() const override
Definition: dh.cpp:53
friend class DH_PrivateKey
Definition: dh.h:61
AlgorithmIdentifier algorithm_identifier() const override
Definition: dh.cpp:46
const BigInt & get_int_field(std::string_view field) const override
Definition: dh.cpp:41
std::string algo_name() const override
Definition: dh.h:52
size_t estimated_strength() const override
Definition: dh.cpp:31
int(* final)(unsigned char *, CTX *)
Definition: alg_id.cpp:12
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: mod_inv.cpp:177
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64