8 #include <botan/elgamal.h>
9 #include <botan/internal/pk_ops_impl.h>
10 #include <botan/keypair.h>
11 #include <botan/reducer.h>
12 #include <botan/blinding.h>
13 #include <botan/workfactor.h>
73 size_t max_raw_input_bits()
const override {
return m_mod_p.get_modulus().bits() - 1; }
75 ElGamal_Encryption_Operation(
const ElGamal_PublicKey& key,
const std::string& eme);
77 secure_vector<uint8_t> raw_encrypt(
const uint8_t msg[],
size_t msg_len,
78 RandomNumberGenerator& rng)
override;
85 ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(
const ElGamal_PublicKey& key,
86 const std::string& eme) :
87 PK_Ops::Encryption_with_EME(eme)
89 const BigInt& p = key.group_p();
96 secure_vector<uint8_t>
97 ElGamal_Encryption_Operation::raw_encrypt(
const uint8_t msg[],
size_t msg_len,
98 RandomNumberGenerator& rng)
100 const BigInt& p =
m_mod_p.get_modulus();
102 BigInt m(msg, msg_len);
105 throw Invalid_Argument(
"ElGamal encryption: Input is too large");
112 secure_vector<uint8_t> output(2*p.bytes());
113 a.binary_encode(&output[p.bytes() - a.bytes()]);
114 b.binary_encode(&output[output.size() / 2 + (p.bytes() - b.bytes())]);
121 class ElGamal_Decryption_Operation :
public PK_Ops::Decryption_with_EME
125 size_t max_raw_input_bits()
const override
126 {
return m_mod_p.get_modulus().bits() - 1; }
128 ElGamal_Decryption_Operation(
const ElGamal_PrivateKey& key,
129 const std::string& eme,
130 RandomNumberGenerator& rng);
132 secure_vector<uint8_t> raw_decrypt(
const uint8_t msg[],
size_t msg_len)
override;
139 ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(
const ElGamal_PrivateKey& key,
140 const std::string& eme,
141 RandomNumberGenerator& rng) :
142 PK_Ops::Decryption_with_EME(eme),
143 m_powermod_x_p(Fixed_Exponent_Power_Mod(key.get_x(), key.group_p())),
144 m_mod_p(Modular_Reducer(key.group_p())),
147 [](const BigInt& k) {
return k; },
152 secure_vector<uint8_t>
153 ElGamal_Decryption_Operation::raw_decrypt(
const uint8_t msg[],
size_t msg_len)
155 const BigInt& p =
m_mod_p.get_modulus();
157 const size_t p_bytes = p.bytes();
159 if(msg_len != 2 * p_bytes)
160 throw Invalid_Argument(
"ElGamal decryption: Invalid message");
162 BigInt a(msg, p_bytes);
163 BigInt b(msg + p_bytes, p_bytes);
166 throw Invalid_Argument(
"ElGamal decryption: Invalid message");
172 return BigInt::encode_1363(
m_blinder.unblind(r), p_bytes);
177 std::unique_ptr<PK_Ops::Encryption>
179 const std::string& params,
180 const std::string& provider)
const
182 if(provider ==
"base" || provider.empty())
183 return std::unique_ptr<PK_Ops::Encryption>(
new ElGamal_Encryption_Operation(*
this, params));
187 std::unique_ptr<PK_Ops::Decryption>
189 const std::string& params,
190 const std::string& provider)
const
192 if(provider ==
"base" || provider.empty())
193 return std::unique_ptr<PK_Ops::Decryption>(
new ElGamal_Decryption_Operation(*
this, params, rng));
size_t dl_exponent_size(size_t bits)
bool encryption_consistency_check(RandomNumberGenerator &rng, const Private_Key &private_key, const Public_Key &public_key, const std::string &padding)
ElGamal_PrivateKey(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
void randomize(RandomNumberGenerator &rng, size_t bitsize, bool set_high_bit=true)
bool check_key(RandomNumberGenerator &rng, bool) const override
Fixed_Base_Power_Mod m_powermod_y_p
const BigInt & group_p() const
std::vector< T, secure_allocator< T >> secure_vector
ElGamal_PublicKey()=default
Fixed_Exponent_Power_Mod m_powermod_x_p
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
bool check_key(RandomNumberGenerator &rng, bool) const override
const BigInt & group_g() const
Fixed_Base_Power_Mod m_powermod_g_p