/src/botan/src/lib/pubkey/dh/dh.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Diffie-Hellman |
3 | | * (C) 1999-2007,2016,2019 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/pk_ops_impl.h> |
10 | | #include <botan/internal/monty_exp.h> |
11 | | #include <botan/blinding.h> |
12 | | |
13 | | namespace Botan { |
14 | | |
15 | | /* |
16 | | * DH_PublicKey Constructor |
17 | | */ |
18 | | DH_PublicKey::DH_PublicKey(const DL_Group& grp, const BigInt& y1) |
19 | 82 | { |
20 | 82 | m_group = grp; |
21 | 82 | m_y = y1; |
22 | 82 | } Unexecuted instantiation: Botan::DH_PublicKey::DH_PublicKey(Botan::DL_Group const&, Botan::BigInt const&) Botan::DH_PublicKey::DH_PublicKey(Botan::DL_Group const&, Botan::BigInt const&) Line | Count | Source | 19 | 82 | { | 20 | 82 | m_group = grp; | 21 | 82 | m_y = y1; | 22 | 82 | } |
|
23 | | |
24 | | /* |
25 | | * Return the public value for key agreement |
26 | | */ |
27 | | std::vector<uint8_t> DH_PublicKey::public_value() const |
28 | 5.93k | { |
29 | 5.93k | return unlock(BigInt::encode_1363(m_y, group_p().bytes())); |
30 | 5.93k | } |
31 | | |
32 | | /* |
33 | | * Create a DH private key |
34 | | */ |
35 | | DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, |
36 | | const DL_Group& grp, |
37 | | const BigInt& x_arg) |
38 | 5.93k | { |
39 | 5.93k | m_group = grp; |
40 | 5.93k | |
41 | 5.93k | if(x_arg == 0) |
42 | 5.93k | { |
43 | 5.93k | const size_t exp_bits = grp.exponent_bits(); |
44 | 5.93k | m_x.randomize(rng, exp_bits); |
45 | 5.93k | m_y = m_group.power_g_p(m_x, exp_bits); |
46 | 5.93k | } |
47 | 0 | else |
48 | 0 | { |
49 | 0 | m_x = x_arg; |
50 | 0 |
|
51 | 0 | if(m_y == 0) |
52 | 0 | m_y = m_group.power_g_p(m_x, grp.p_bits()); |
53 | 0 | } |
54 | 5.93k | } Unexecuted instantiation: Botan::DH_PrivateKey::DH_PrivateKey(Botan::RandomNumberGenerator&, Botan::DL_Group const&, Botan::BigInt const&) Botan::DH_PrivateKey::DH_PrivateKey(Botan::RandomNumberGenerator&, Botan::DL_Group const&, Botan::BigInt const&) Line | Count | Source | 38 | 5.93k | { | 39 | 5.93k | m_group = grp; | 40 | 5.93k | | 41 | 5.93k | if(x_arg == 0) | 42 | 5.93k | { | 43 | 5.93k | const size_t exp_bits = grp.exponent_bits(); | 44 | 5.93k | m_x.randomize(rng, exp_bits); | 45 | 5.93k | m_y = m_group.power_g_p(m_x, exp_bits); | 46 | 5.93k | } | 47 | 0 | else | 48 | 0 | { | 49 | 0 | m_x = x_arg; | 50 | 0 |
| 51 | 0 | if(m_y == 0) | 52 | 0 | m_y = m_group.power_g_p(m_x, grp.p_bits()); | 53 | 0 | } | 54 | 5.93k | } |
|
55 | | |
56 | | /* |
57 | | * Load a DH private key |
58 | | */ |
59 | | DH_PrivateKey::DH_PrivateKey(const AlgorithmIdentifier& alg_id, |
60 | | const secure_vector<uint8_t>& key_bits) : |
61 | | DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42) |
62 | 44 | { |
63 | 44 | if(m_y.is_zero()) |
64 | 27 | { |
65 | 27 | m_y = m_group.power_g_p(m_x, m_group.p_bits()); |
66 | 27 | } |
67 | 44 | } Unexecuted instantiation: Botan::DH_PrivateKey::DH_PrivateKey(Botan::AlgorithmIdentifier const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&) Botan::DH_PrivateKey::DH_PrivateKey(Botan::AlgorithmIdentifier const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&) Line | Count | Source | 62 | 44 | { | 63 | 44 | if(m_y.is_zero()) | 64 | 27 | { | 65 | 27 | m_y = m_group.power_g_p(m_x, m_group.p_bits()); | 66 | 27 | } | 67 | 44 | } |
|
68 | | |
69 | | /* |
70 | | * Return the public value for key agreement |
71 | | */ |
72 | | std::vector<uint8_t> DH_PrivateKey::public_value() const |
73 | 5.93k | { |
74 | 5.93k | return DH_PublicKey::public_value(); |
75 | 5.93k | } |
76 | | |
77 | | namespace { |
78 | | |
79 | | /** |
80 | | * DH operation |
81 | | */ |
82 | | class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF |
83 | | { |
84 | | public: |
85 | | |
86 | | DH_KA_Operation(const DH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) : |
87 | | PK_Ops::Key_Agreement_with_KDF(kdf), |
88 | | m_p(key.group_p()), |
89 | | m_x(key.get_x()), |
90 | | m_x_bits(m_x.bits()), |
91 | | m_monty_p(key.get_group().monty_params_p()), |
92 | | m_blinder(m_p, |
93 | | rng, |
94 | 2.58k | [](const BigInt& k) { return k; }, |
95 | 2.58k | [this](const BigInt& k) { return powermod_x_p(inverse_mod(k, m_p)); }) |
96 | 2.58k | {} |
97 | | |
98 | 0 | size_t agreed_value_size() const override { return m_p.bytes(); } |
99 | | |
100 | | secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override; |
101 | | private: |
102 | | BigInt powermod_x_p(const BigInt& v) const |
103 | 5.13k | { |
104 | 5.13k | const size_t powm_window = 4; |
105 | 5.13k | auto powm_v_p = monty_precompute(m_monty_p, v, powm_window); |
106 | 5.13k | return monty_execute(*powm_v_p, m_x, m_x_bits); |
107 | 5.13k | } |
108 | | |
109 | | const BigInt& m_p; |
110 | | const BigInt& m_x; |
111 | | const size_t m_x_bits; |
112 | | std::shared_ptr<const Montgomery_Params> m_monty_p; |
113 | | Blinder m_blinder; |
114 | | }; |
115 | | |
116 | | secure_vector<uint8_t> DH_KA_Operation::raw_agree(const uint8_t w[], size_t w_len) |
117 | 2.58k | { |
118 | 2.58k | BigInt v = BigInt::decode(w, w_len); |
119 | 2.58k | |
120 | 2.58k | if(v <= 1 || v >= m_p - 1) |
121 | 30 | throw Invalid_Argument("DH agreement - invalid key provided"); |
122 | 2.55k | |
123 | 2.55k | v = m_blinder.blind(v); |
124 | 2.55k | v = powermod_x_p(v); |
125 | 2.55k | v = m_blinder.unblind(v); |
126 | 2.55k | |
127 | 2.55k | return BigInt::encode_1363(v, m_p.bytes()); |
128 | 2.55k | } |
129 | | |
130 | | } |
131 | | |
132 | | std::unique_ptr<PK_Ops::Key_Agreement> |
133 | | DH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng, |
134 | | const std::string& params, |
135 | | const std::string& provider) const |
136 | 2.58k | { |
137 | 2.58k | if(provider == "base" || provider.empty()) |
138 | 2.58k | return std::unique_ptr<PK_Ops::Key_Agreement>(new DH_KA_Operation(*this, params, rng)); |
139 | 0 | throw Provider_Not_Found(algo_name(), provider); |
140 | 0 | } |
141 | | |
142 | | } |