Botan  1.10.9
elgamal.cpp
Go to the documentation of this file.
1 /*
2 * ElGamal
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/elgamal.h>
9 #include <botan/numthry.h>
10 #include <botan/libstate.h>
11 #include <botan/keypair.h>
12 #include <botan/internal/workfactor.h>
13 
14 namespace Botan {
15 
16 /*
17 * ElGamal_PublicKey Constructor
18 */
20  {
21  group = grp;
22  y = y1;
23  }
24 
25 /*
26 * ElGamal_PrivateKey Constructor
27 */
29  const DL_Group& grp,
30  const BigInt& x_arg)
31  {
32  group = grp;
33  x = x_arg;
34 
35  if(x == 0)
36  x.randomize(rng, 2 * dl_work_factor(group_p().bits()));
37 
38  y = power_mod(group_g(), x, group_p());
39 
40  if(x_arg == 0)
41  gen_check(rng);
42  else
43  load_check(rng);
44  }
45 
47  const MemoryRegion<byte>& key_bits,
49  DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42)
50  {
51  y = power_mod(group_g(), x, group_p());
52  load_check(rng);
53  }
54 
55 /*
56 * Check Private ElGamal Parameters
57 */
59  bool strong) const
60  {
61  if(!DL_Scheme_PrivateKey::check_key(rng, strong))
62  return false;
63 
64  if(!strong)
65  return true;
66 
67  return KeyPair::encryption_consistency_check(rng, *this, "EME1(SHA-1)");
68  }
69 
71  {
72  const BigInt& p = key.group_p();
73 
74  powermod_g_p = Fixed_Base_Power_Mod(key.group_g(), p);
75  powermod_y_p = Fixed_Base_Power_Mod(key.get_y(), p);
76  mod_p = Modular_Reducer(p);
77  }
78 
80 ElGamal_Encryption_Operation::encrypt(const byte msg[], size_t msg_len,
82  {
83  const BigInt& p = mod_p.get_modulus();
84 
85  BigInt m(msg, msg_len);
86 
87  if(m >= p)
88  throw Invalid_Argument("ElGamal encryption: Input is too large");
89 
90  BigInt k(rng, 2 * dl_work_factor(p.bits()));
91 
92  BigInt a = powermod_g_p(k);
93  BigInt b = mod_p.multiply(m, powermod_y_p(k));
94 
95  SecureVector<byte> output(2*p.bytes());
96  a.binary_encode(&output[p.bytes() - a.bytes()]);
97  b.binary_encode(&output[output.size() / 2 + (p.bytes() - b.bytes())]);
98  return output;
99  }
100 
102  {
103  const BigInt& p = key.group_p();
104 
105  powermod_x_p = Fixed_Exponent_Power_Mod(key.get_x(), p);
106  mod_p = Modular_Reducer(p);
107 
108  BigInt k(global_state().global_rng(), p.bits() - 1);
109  blinder = Blinder(k, powermod_x_p(k), p);
110  }
111 
113 ElGamal_Decryption_Operation::decrypt(const byte msg[], size_t msg_len)
114  {
115  const BigInt& p = mod_p.get_modulus();
116 
117  const size_t p_bytes = p.bytes();
118 
119  if(msg_len != 2 * p_bytes)
120  throw Invalid_Argument("ElGamal decryption: Invalid message");
121 
122  BigInt a(msg, p_bytes);
123  BigInt b(msg + p_bytes, p_bytes);
124 
125  if(a >= p || b >= p)
126  throw Invalid_Argument("ElGamal decryption: Invalid message");
127 
128  a = blinder.blind(a);
129 
130  BigInt r = mod_p.multiply(b, inverse_mod(powermod_x_p(a), p));
131 
132  return BigInt::encode(blinder.unblind(r));
133  }
134 
135 }
void load_check(RandomNumberGenerator &rng) const
Definition: pk_keys.cpp:40
void binary_encode(byte buf[]) const
Definition: bigint.cpp:340
SecureVector< byte > encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator &rng)
Definition: elgamal.cpp:80
const BigInt & get_x() const
Definition: dl_algo.h:95
const BigInt & group_p() const
Definition: dl_algo.h:44
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:64
ElGamal_Decryption_Operation(const ElGamal_PrivateKey &key)
Definition: elgamal.cpp:101
unsigned char byte
Definition: types.h:22
bool check_key(RandomNumberGenerator &rng, bool) const
Definition: elgamal.cpp:58
bool check_key(RandomNumberGenerator &rng, bool) const
Definition: dl_algo.cpp:67
const BigInt & get_y() const
Definition: dl_algo.h:38
size_t bits() const
Definition: bigint.cpp:253
RandomNumberGenerator * rng
Definition: global_rng.cpp:165
void randomize(RandomNumberGenerator &rng, size_t bitsize=0)
Definition: big_rand.cpp:29
ElGamal_PrivateKey(const AlgorithmIdentifier &alg_id, const MemoryRegion< byte > &key_bits, RandomNumberGenerator &rng)
Definition: elgamal.cpp:46
Library_State & global_state()
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition: reducer.h:31
bool encryption_consistency_check(RandomNumberGenerator &rng, const Private_Key &key, const std::string &padding)
Definition: keypair.cpp:18
BigInt unblind(const BigInt &x) const
Definition: blinding.cpp:42
ElGamal_Encryption_Operation(const ElGamal_PublicKey &key)
Definition: elgamal.cpp:70
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: numthry.cpp:202
BigInt blind(const BigInt &x) const
Definition: blinding.cpp:29
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition: numthry.cpp:251
BigInt r
Definition: numthry.cpp:26
const BigInt & group_g() const
Definition: dl_algo.h:56
size_t dl_work_factor(size_t bits)
Definition: workfactor.cpp:14
void gen_check(RandomNumberGenerator &rng) const
Definition: pk_keys.cpp:49
const BigInt & get_modulus() const
Definition: reducer.h:21
SecureVector< byte > decrypt(const byte msg[], size_t msg_len)
Definition: elgamal.cpp:113
size_t bytes() const
Definition: bigint.cpp:245