Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

elgamal.cpp
Go to the documentation of this file.
1 /*
2 * ElGamal
3 * (C) 1999-2007,2018,2019 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/elgamal.h>
9 #include <botan/internal/pk_ops_impl.h>
10 #include <botan/internal/monty_exp.h>
11 #include <botan/keypair.h>
12 #include <botan/blinding.h>
13
14 namespace Botan {
15
16 /*
17 * ElGamal_PublicKey Constructor
18 */
19 ElGamal_PublicKey::ElGamal_PublicKey(const DL_Group& group, const BigInt& y) :
20 DL_Scheme_PublicKey(group, y)
21 {
22 }
23
24 /*
25 * ElGamal_PrivateKey Constructor
26 */
27 ElGamal_PrivateKey::ElGamal_PrivateKey(RandomNumberGenerator& rng,
28 const DL_Group& group,
29 const BigInt& x)
30 {
31 m_x = x;
32 m_group = group;
33
34 if(m_x.is_zero())
35 {
36 const size_t exp_bits = m_group.exponent_bits();
37 m_x.randomize(rng, exp_bits);
38 m_y = m_group.power_g_p(m_x, exp_bits);
39 }
40 else
41 {
42 m_y = m_group.power_g_p(m_x, m_group.p_bits());
43 }
44 }
45
46 ElGamal_PrivateKey::ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id,
47 const secure_vector<uint8_t>& key_bits) :
48 DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42)
49 {
50 m_y = m_group.power_g_p(m_x, m_group.p_bits());
51 }
52
53 /*
54 * Check Private ElGamal Parameters
55 */
56 bool ElGamal_PrivateKey::check_key(RandomNumberGenerator& rng,
57 bool strong) const
58 {
59 if(!DL_Scheme_PrivateKey::check_key(rng, strong))
60 return false;
61
62 if(!strong)
63 return true;
64
65 return KeyPair::encryption_consistency_check(rng, *this, "OAEP(SHA-256)");
66 }
67
68 namespace {
69
70 /**
71 * ElGamal encryption operation
72 */
73 class ElGamal_Encryption_Operation final : public PK_Ops::Encryption_with_EME
74 {
75 public:
76
77 size_t ciphertext_length(size_t) const override { return 2*m_group.p_bytes(); }
78
79 size_t max_raw_input_bits() const override { return m_group.p_bits() - 1; }
80
81 ElGamal_Encryption_Operation(const ElGamal_PublicKey& key, const std::string& eme);
82
83 secure_vector<uint8_t> raw_encrypt(const uint8_t msg[], size_t msg_len,
84 RandomNumberGenerator& rng) override;
85
86 private:
87 const DL_Group m_group;
88 std::shared_ptr<const Montgomery_Exponentation_State> m_monty_y_p;
89 };
90
91 ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(const ElGamal_PublicKey& key,
92 const std::string& eme) :
93 PK_Ops::Encryption_with_EME(eme),
94 m_group(key.get_group())
95 {
96 const size_t powm_window = 4;
97 m_monty_y_p = monty_precompute(key.get_group().monty_params_p(),
98 key.get_y(),
99 powm_window);
100 }
101
102 secure_vector<uint8_t>
103 ElGamal_Encryption_Operation::raw_encrypt(const uint8_t msg[], size_t msg_len,
104 RandomNumberGenerator& rng)
105 {
106 BigInt m(msg, msg_len);
107
108 if(m >= m_group.get_p())
109 throw Invalid_Argument("ElGamal encryption: Input is too large");
110
111 const size_t k_bits = m_group.exponent_bits();
112 const BigInt k(rng, k_bits);
113
114 const BigInt a = m_group.power_g_p(k, k_bits);
115 const BigInt b = m_group.multiply_mod_p(m, monty_execute(*m_monty_y_p, k, k_bits));
116
117 return BigInt::encode_fixed_length_int_pair(a, b, m_group.p_bytes());
118 }
119
120 /**
121 * ElGamal decryption operation
122 */
123 class ElGamal_Decryption_Operation final : public PK_Ops::Decryption_with_EME
124 {
125 public:
126
127 ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key,
128 const std::string& eme,
129 RandomNumberGenerator& rng);
130
131 size_t plaintext_length(size_t) const override { return m_group.p_bytes(); }
132
133 secure_vector<uint8_t> raw_decrypt(const uint8_t msg[], size_t msg_len) override;
134 private:
135 BigInt powermod_x_p(const BigInt& v) const
136 {
137 const size_t powm_window = 4;
138 auto powm_v_p = monty_precompute(m_monty_p, v, powm_window);
139 return monty_execute(*powm_v_p, m_x, m_x_bits);
140 }
141
142 const DL_Group m_group;
143 const BigInt& m_x;
144 const size_t m_x_bits;
145 std::shared_ptr<const Montgomery_Params> m_monty_p;
146 Blinder m_blinder;
147 };
148
149 ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key,
150 const std::string& eme,
151 RandomNumberGenerator& rng) :
152 PK_Ops::Decryption_with_EME(eme),
153 m_group(key.get_group()),
154 m_x(key.get_x()),
155 m_x_bits(m_x.bits()),
156 m_monty_p(key.get_group().monty_params_p()),
157 m_blinder(m_group.get_p(),
158 rng,
159 [](const BigInt& k) { return k; },
160 [this](const BigInt& k) { return powermod_x_p(k); })
161 {
162 }
163
164 secure_vector<uint8_t>
165 ElGamal_Decryption_Operation::raw_decrypt(const uint8_t msg[], size_t msg_len)
166 {
167 const size_t p_bytes = m_group.p_bytes();
168
169 if(msg_len != 2 * p_bytes)
170 throw Invalid_Argument("ElGamal decryption: Invalid message");
171
172 BigInt a(msg, p_bytes);
173 const BigInt b(msg + p_bytes, p_bytes);
174
175 if(a >= m_group.get_p() || b >= m_group.get_p())
176 throw Invalid_Argument("ElGamal decryption: Invalid message");
177
178 a = m_blinder.blind(a);
179
180 const BigInt r = m_group.multiply_mod_p(m_group.inverse_mod_p(powermod_x_p(a)), b);
181
182 return BigInt::encode_1363(m_blinder.unblind(r), p_bytes);
183 }
184
185 }
186
187 std::unique_ptr<PK_Ops::Encryption>
188 ElGamal_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/,
189 const std::string& params,
190 const std::string& provider) const
191 {
192 if(provider == "base" || provider.empty())
193 return std::unique_ptr<PK_Ops::Encryption>(new ElGamal_Encryption_Operation(*this, params));
194 throw Provider_Not_Found(algo_name(), provider);
195 }
196
197 std::unique_ptr<PK_Ops::Decryption>
198 ElGamal_PrivateKey::create_decryption_op(RandomNumberGenerator& rng,
199 const std::string& params,
200 const std::string& provider) const
201 {
202 if(provider == "base" || provider.empty())
203 return std::unique_ptr<PK_Ops::Decryption>(new ElGamal_Decryption_Operation(*this, params, rng));
204 throw Provider_Not_Found(algo_name(), provider);
205 }
206
207 }
Botan::DL_Scheme_PrivateKey
Definition: dl_algo.h:103
m_blinder
Blinder m_blinder
Definition: elgamal.cpp:146
Botan::DL_Scheme_PrivateKey::m_x
BigInt m_x
Definition: dl_algo.h:135
Botan::BigInt
Definition: bigint.h:24
Botan::RandomNumberGenerator
Definition: rng.h:24
Botan::ElGamal_PrivateKey::ElGamal_PrivateKey
ElGamal_PrivateKey(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
Definition: elgamal.cpp:46
Botan::BigInt::randomize
void randomize(RandomNumberGenerator &rng, size_t bitsize, bool set_high_bit=true)
Definition: big_rand.cpp:17
m_monty_y_p
std::shared_ptr< const Montgomery_Exponentation_State > m_monty_y_p
Definition: elgamal.cpp:88
Botan::ElGamal_PrivateKey::check_key
bool check_key(RandomNumberGenerator &rng, bool) const override
Definition: elgamal.cpp:56
final
int(* final)(unsigned char *, CTX *)
Definition: commoncrypto_hash.cpp:28
Botan::DL_Scheme_PublicKey
Definition: dl_algo.h:19
Botan::KeyPair::encryption_consistency_check
bool encryption_consistency_check(RandomNumberGenerator &rng, const Private_Key &private_key, const Public_Key &public_key, const std::string &padding)
Definition: keypair.cpp:19
Botan::DL_Group::p_bits
size_t p_bits() const
Definition: dl_group.cpp:436
Botan::DL_Group
Definition: dl_group.h:23
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
m_monty_p
std::shared_ptr< const Montgomery_Params > m_monty_p
Definition: elgamal.cpp:145
Botan::DL_Scheme_PublicKey::m_group
DL_Group m_group
Definition: dl_algo.h:97
Botan::DL_Scheme_PublicKey::m_y
BigInt m_y
Definition: dl_algo.h:92
Botan::monty_precompute
std::shared_ptr< const Montgomery_Exponentation_State > monty_precompute(std::shared_ptr< const Montgomery_Params > params, const BigInt &g, size_t window_bits, bool const_time)
Definition: monty_exp.cpp:157
Botan::DL_Group::exponent_bits
size_t exponent_bits() const
Definition: dl_group.cpp:463
Botan
Definition: alg_id.cpp:13
Botan::ElGamal_PublicKey::ElGamal_PublicKey
ElGamal_PublicKey()=default
Botan::PK_Ops::Encryption_with_EME
Definition: pk_ops_impl.h:20
m_group
const DL_Group m_group
Definition: elgamal.cpp:87
Botan::DL_Group::power_g_p
BigInt power_g_p(const BigInt &x) const
Definition: dl_group.cpp:520
m_x
const BigInt & m_x
Definition: elgamal.cpp:143
Botan::DL_Scheme_PrivateKey::check_key
bool check_key(RandomNumberGenerator &rng, bool) const override
Definition: dl_algo.cpp:78
m_x_bits
const size_t m_x_bits
Definition: elgamal.cpp:144
Botan::AlgorithmIdentifier
Definition: alg_id.h:21
Botan::Provider_Not_Found
Definition: exceptn.h:278
Botan::BigInt::is_zero
bool is_zero() const
Definition: bigint.h:419
Botan::monty_execute
BigInt monty_execute(const Montgomery_Exponentation_State &precomputed_state, const BigInt &k, size_t max_k_bits)
Definition: monty_exp.cpp:165