/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/internal/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 | 0 | { |
20 | 0 | m_group = grp; |
21 | 0 | m_y = y1; |
22 | 0 | } Unexecuted instantiation: Botan::DH_PublicKey::DH_PublicKey(Botan::DL_Group const&, Botan::BigInt const&) Unexecuted instantiation: Botan::DH_PublicKey::DH_PublicKey(Botan::DL_Group const&, Botan::BigInt const&) |
23 | | |
24 | | /* |
25 | | * Return the public value for key agreement |
26 | | */ |
27 | | std::vector<uint8_t> DH_PublicKey::public_value() const |
28 | 0 | { |
29 | 0 | return unlock(BigInt::encode_1363(m_y, group_p().bytes())); |
30 | 0 | } |
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 | 0 | { |
39 | 0 | m_group = grp; |
40 | |
|
41 | 0 | if(x_arg == 0) |
42 | 0 | { |
43 | 0 | const size_t exp_bits = grp.exponent_bits(); |
44 | 0 | m_x.randomize(rng, exp_bits); |
45 | 0 | m_y = m_group.power_g_p(m_x, exp_bits); |
46 | 0 | } |
47 | 0 | else |
48 | 0 | { |
49 | 0 | m_x = x_arg; |
50 | |
|
51 | 0 | if(m_y == 0) |
52 | 0 | m_y = m_group.power_g_p(m_x, grp.p_bits()); |
53 | 0 | } |
54 | 0 | } Unexecuted instantiation: Botan::DH_PrivateKey::DH_PrivateKey(Botan::RandomNumberGenerator&, Botan::DL_Group const&, Botan::BigInt const&) Unexecuted instantiation: Botan::DH_PrivateKey::DH_PrivateKey(Botan::RandomNumberGenerator&, Botan::DL_Group const&, Botan::BigInt const&) |
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_Format::ANSI_X9_42) |
62 | 59 | { |
63 | 59 | 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 | 59 | } 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 | 59 | { | 63 | 59 | 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 | 59 | } |
|
68 | | |
69 | | std::unique_ptr<Public_Key> DH_PrivateKey::public_key() const |
70 | 0 | { |
71 | 0 | return std::make_unique<DH_PublicKey>(get_group(), get_y()); |
72 | 0 | } |
73 | | |
74 | | /* |
75 | | * Return the public value for key agreement |
76 | | */ |
77 | | std::vector<uint8_t> DH_PrivateKey::public_value() const |
78 | 0 | { |
79 | 0 | return DH_PublicKey::public_value(); |
80 | 0 | } |
81 | | |
82 | | namespace { |
83 | | |
84 | | /** |
85 | | * DH operation |
86 | | */ |
87 | | class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF |
88 | | { |
89 | | public: |
90 | | |
91 | | DH_KA_Operation(const DH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) : |
92 | | PK_Ops::Key_Agreement_with_KDF(kdf), |
93 | | m_p(key.group_p()), |
94 | | m_x(key.get_x()), |
95 | | m_x_bits(m_x.bits()), |
96 | | m_monty_p(key.get_group().monty_params_p()), |
97 | | m_blinder(m_p, |
98 | | rng, |
99 | 0 | [](const BigInt& k) { return k; }, |
100 | 0 | [this](const BigInt& k) { return powermod_x_p(inverse_mod(k, m_p)); }) |
101 | 0 | {} |
102 | | |
103 | 0 | size_t agreed_value_size() const override { return m_p.bytes(); } |
104 | | |
105 | | secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override; |
106 | | private: |
107 | | BigInt powermod_x_p(const BigInt& v) const |
108 | 0 | { |
109 | 0 | const size_t powm_window = 4; |
110 | 0 | auto powm_v_p = monty_precompute(m_monty_p, v, powm_window); |
111 | 0 | return monty_execute(*powm_v_p, m_x, m_x_bits); |
112 | 0 | } |
113 | | |
114 | | const BigInt& m_p; |
115 | | const BigInt& m_x; |
116 | | const size_t m_x_bits; |
117 | | std::shared_ptr<const Montgomery_Params> m_monty_p; |
118 | | Blinder m_blinder; |
119 | | }; |
120 | | |
121 | | secure_vector<uint8_t> DH_KA_Operation::raw_agree(const uint8_t w[], size_t w_len) |
122 | 0 | { |
123 | 0 | BigInt v = BigInt::decode(w, w_len); |
124 | |
|
125 | 0 | if(v <= 1 || v >= m_p - 1) |
126 | 0 | throw Invalid_Argument("DH agreement - invalid key provided"); |
127 | | |
128 | 0 | v = m_blinder.blind(v); |
129 | 0 | v = powermod_x_p(v); |
130 | 0 | v = m_blinder.unblind(v); |
131 | |
|
132 | 0 | return BigInt::encode_1363(v, m_p.bytes()); |
133 | 0 | } |
134 | | |
135 | | } |
136 | | |
137 | | std::unique_ptr<PK_Ops::Key_Agreement> |
138 | | DH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng, |
139 | | const std::string& params, |
140 | | const std::string& provider) const |
141 | 0 | { |
142 | 0 | if(provider == "base" || provider.empty()) |
143 | 0 | return std::make_unique<DH_KA_Operation>(*this, params, rng); |
144 | 0 | throw Provider_Not_Found(algo_name(), provider); |
145 | 0 | } |
146 | | |
147 | | } |