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>
77 size_t ciphertext_length(
size_t)
const override {
return 2*m_group.p_bytes(); }
79 size_t max_raw_input_bits()
const override {
return m_group.p_bits() - 1; }
81 ElGamal_Encryption_Operation(
const ElGamal_PublicKey& key,
const std::string& eme);
83 secure_vector<uint8_t> raw_encrypt(
const uint8_t msg[],
size_t msg_len,
84 RandomNumberGenerator& rng)
override;
87 const DL_Group m_group;
88 std::shared_ptr<const Montgomery_Exponentation_State> m_monty_y_p;
91ElGamal_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())
96 const size_t powm_window = 4;
102secure_vector<uint8_t>
103ElGamal_Encryption_Operation::raw_encrypt(
const uint8_t msg[],
size_t msg_len,
104 RandomNumberGenerator& rng)
106 BigInt m(msg, msg_len);
108 if(m >= m_group.
get_p())
109 throw Invalid_Argument(
"ElGamal encryption: Input is too large");
117 const size_t k_bits = m_group.
p_bits() - 1;
118 const BigInt k(rng, k_bits,
false);
120 const BigInt a = m_group.
power_g_p(k, k_bits);
129class ElGamal_Decryption_Operation
final :
public PK_Ops::Decryption_with_EME
133 ElGamal_Decryption_Operation(
const ElGamal_PrivateKey& key,
134 const std::string& eme,
135 RandomNumberGenerator& rng);
137 size_t plaintext_length(
size_t)
const override {
return m_group.p_bytes(); }
139 secure_vector<uint8_t> raw_decrypt(
const uint8_t msg[],
size_t msg_len)
override;
141 BigInt powermod_x_p(
const BigInt& v)
const
143 const size_t powm_window = 4;
148 const DL_Group m_group;
150 const size_t m_x_bits;
151 std::shared_ptr<const Montgomery_Params> m_monty_p;
155ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(
const ElGamal_PrivateKey& key,
156 const std::string& eme,
157 RandomNumberGenerator& rng) :
158 PK_Ops::Decryption_with_EME(eme),
159 m_group(key.get_group()),
161 m_x_bits(m_x.bits()),
162 m_monty_p(key.get_group().monty_params_p()),
163 m_blinder(m_group.get_p(),
165 [](const BigInt& k) {
return k; },
166 [
this](
const BigInt& k) {
return powermod_x_p(k); })
170secure_vector<uint8_t>
171ElGamal_Decryption_Operation::raw_decrypt(
const uint8_t msg[],
size_t msg_len)
173 const size_t p_bytes = m_group.
p_bytes();
175 if(msg_len != 2 * p_bytes)
176 throw Invalid_Argument(
"ElGamal decryption: Invalid message");
178 BigInt a(msg, p_bytes);
179 const BigInt b(msg + p_bytes, p_bytes);
181 if(a >= m_group.
get_p() || b >= m_group.
get_p())
182 throw Invalid_Argument(
"ElGamal decryption: Invalid message");
184 a = m_blinder.
blind(a);
193std::unique_ptr<PK_Ops::Encryption>
195 const std::string& params,
196 const std::string& provider)
const
198 if(provider ==
"base" || provider.empty())
199 return std::unique_ptr<PK_Ops::Encryption>(
new ElGamal_Encryption_Operation(*
this, params));
203std::unique_ptr<PK_Ops::Decryption>
205 const std::string& params,
206 const std::string& provider)
const
208 if(provider ==
"base" || provider.empty())
209 return std::unique_ptr<PK_Ops::Decryption>(
new ElGamal_Decryption_Operation(*
this, params, rng));
void randomize(RandomNumberGenerator &rng, size_t bitsize, bool set_high_bit=true)
static secure_vector< uint8_t > encode_fixed_length_int_pair(const BigInt &n1, const BigInt &n2, size_t bytes)
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
BigInt blind(const BigInt &x) const
BigInt unblind(const BigInt &x) const
BigInt power_g_p(const BigInt &x) const
BigInt multiply_mod_p(const BigInt &x, const BigInt &y) const
const BigInt & get_p() const
BigInt inverse_mod_p(const BigInt &x) const
size_t exponent_bits() const
bool check_key(RandomNumberGenerator &rng, bool) const override
ElGamal_PrivateKey(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
bool check_key(RandomNumberGenerator &rng, bool) const override
std::unique_ptr< PK_Ops::Decryption > create_decryption_op(RandomNumberGenerator &rng, const std::string ¶ms, const std::string &provider) const override
ElGamal_PublicKey()=default
std::unique_ptr< PK_Ops::Encryption > create_encryption_op(RandomNumberGenerator &rng, const std::string ¶ms, const std::string &provider) const override
std::string algo_name() const override
int(* final)(unsigned char *, CTX *)
bool encryption_consistency_check(RandomNumberGenerator &rng, const Private_Key &private_key, const Public_Key &public_key, const std::string &padding)
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)
BigInt monty_execute(const Montgomery_Exponentation_State &precomputed_state, const BigInt &k, size_t max_k_bits)
std::vector< T, secure_allocator< T > > secure_vector