aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/elgamal
diff options
context:
space:
mode:
authorlloyd <[email protected]>2014-01-10 03:41:59 +0000
committerlloyd <[email protected]>2014-01-10 03:41:59 +0000
commit6894dca64c04936d07048c0e8cbf7e25858548c3 (patch)
tree5d572bfde9fe667dab14e3f04b5285a85d8acd95 /src/lib/pubkey/elgamal
parent9efa3be92442afb3d0b69890a36c7f122df18eda (diff)
Move lib into src
Diffstat (limited to 'src/lib/pubkey/elgamal')
-rw-r--r--src/lib/pubkey/elgamal/elgamal.cpp135
-rw-r--r--src/lib/pubkey/elgamal/elgamal.h96
-rw-r--r--src/lib/pubkey/elgamal/info.txt9
3 files changed, 240 insertions, 0 deletions
diff --git a/src/lib/pubkey/elgamal/elgamal.cpp b/src/lib/pubkey/elgamal/elgamal.cpp
new file mode 100644
index 000000000..c8a9ba9d0
--- /dev/null
+++ b/src/lib/pubkey/elgamal/elgamal.cpp
@@ -0,0 +1,135 @@
+/*
+* ElGamal
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/elgamal.h>
+#include <botan/numthry.h>
+#include <botan/keypair.h>
+#include <botan/workfactor.h>
+
+namespace Botan {
+
+/*
+* ElGamal_PublicKey Constructor
+*/
+ElGamal_PublicKey::ElGamal_PublicKey(const DL_Group& grp, const BigInt& y1)
+ {
+ group = grp;
+ y = y1;
+ }
+
+/*
+* ElGamal_PrivateKey Constructor
+*/
+ElGamal_PrivateKey::ElGamal_PrivateKey(RandomNumberGenerator& rng,
+ const DL_Group& grp,
+ const BigInt& x_arg)
+ {
+ group = grp;
+ x = x_arg;
+
+ if(x == 0)
+ x.randomize(rng, 2 * dl_work_factor(group_p().bits()));
+
+ y = power_mod(group_g(), x, group_p());
+
+ if(x_arg == 0)
+ gen_check(rng);
+ else
+ load_check(rng);
+ }
+
+ElGamal_PrivateKey::ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id,
+ const secure_vector<byte>& key_bits,
+ RandomNumberGenerator& rng) :
+ DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42)
+ {
+ y = power_mod(group_g(), x, group_p());
+ load_check(rng);
+ }
+
+/*
+* Check Private ElGamal Parameters
+*/
+bool ElGamal_PrivateKey::check_key(RandomNumberGenerator& rng,
+ bool strong) const
+ {
+ if(!DL_Scheme_PrivateKey::check_key(rng, strong))
+ return false;
+
+ if(!strong)
+ return true;
+
+ return KeyPair::encryption_consistency_check(rng, *this, "EME1(SHA-1)");
+ }
+
+ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(const ElGamal_PublicKey& key)
+ {
+ const BigInt& p = key.group_p();
+
+ powermod_g_p = Fixed_Base_Power_Mod(key.group_g(), p);
+ powermod_y_p = Fixed_Base_Power_Mod(key.get_y(), p);
+ mod_p = Modular_Reducer(p);
+ }
+
+secure_vector<byte>
+ElGamal_Encryption_Operation::encrypt(const byte msg[], size_t msg_len,
+ RandomNumberGenerator& rng)
+ {
+ const BigInt& p = mod_p.get_modulus();
+
+ BigInt m(msg, msg_len);
+
+ if(m >= p)
+ throw Invalid_Argument("ElGamal encryption: Input is too large");
+
+ BigInt k(rng, 2 * dl_work_factor(p.bits()));
+
+ BigInt a = powermod_g_p(k);
+ BigInt b = mod_p.multiply(m, powermod_y_p(k));
+
+ secure_vector<byte> output(2*p.bytes());
+ a.binary_encode(&output[p.bytes() - a.bytes()]);
+ b.binary_encode(&output[output.size() / 2 + (p.bytes() - b.bytes())]);
+ return output;
+ }
+
+ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key,
+ RandomNumberGenerator& rng)
+ {
+ const BigInt& p = key.group_p();
+
+ powermod_x_p = Fixed_Exponent_Power_Mod(key.get_x(), p);
+ mod_p = Modular_Reducer(p);
+
+ BigInt k(rng, p.bits() - 1);
+ blinder = Blinder(k, powermod_x_p(k), p);
+ }
+
+secure_vector<byte>
+ElGamal_Decryption_Operation::decrypt(const byte msg[], size_t msg_len)
+ {
+ const BigInt& p = mod_p.get_modulus();
+
+ const size_t p_bytes = p.bytes();
+
+ if(msg_len != 2 * p_bytes)
+ throw Invalid_Argument("ElGamal decryption: Invalid message");
+
+ BigInt a(msg, p_bytes);
+ BigInt b(msg + p_bytes, p_bytes);
+
+ if(a >= p || b >= p)
+ throw Invalid_Argument("ElGamal decryption: Invalid message");
+
+ a = blinder.blind(a);
+
+ BigInt r = mod_p.multiply(b, inverse_mod(powermod_x_p(a), p));
+
+ return BigInt::encode_locked(blinder.unblind(r));
+ }
+
+}
diff --git a/src/lib/pubkey/elgamal/elgamal.h b/src/lib/pubkey/elgamal/elgamal.h
new file mode 100644
index 000000000..9566bcca6
--- /dev/null
+++ b/src/lib/pubkey/elgamal/elgamal.h
@@ -0,0 +1,96 @@
+/*
+* ElGamal
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_ELGAMAL_H__
+#define BOTAN_ELGAMAL_H__
+
+#include <botan/dl_algo.h>
+#include <botan/numthry.h>
+#include <botan/reducer.h>
+#include <botan/blinding.h>
+#include <botan/pk_ops.h>
+
+namespace Botan {
+
+/**
+* ElGamal Public Key
+*/
+class BOTAN_DLL ElGamal_PublicKey : public virtual DL_Scheme_PublicKey
+ {
+ public:
+ std::string algo_name() const { return "ElGamal"; }
+ DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; }
+
+ size_t max_input_bits() const { return (group_p().bits() - 1); }
+
+ ElGamal_PublicKey(const AlgorithmIdentifier& alg_id,
+ const secure_vector<byte>& key_bits) :
+ DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_42)
+ {}
+
+ ElGamal_PublicKey(const DL_Group& group, const BigInt& y);
+ protected:
+ ElGamal_PublicKey() {}
+ };
+
+/**
+* ElGamal Private Key
+*/
+class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey,
+ public virtual DL_Scheme_PrivateKey
+ {
+ public:
+ bool check_key(RandomNumberGenerator& rng, bool) const;
+
+ ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id,
+ const secure_vector<byte>& key_bits,
+ RandomNumberGenerator& rng);
+
+ ElGamal_PrivateKey(RandomNumberGenerator& rng,
+ const DL_Group& group,
+ const BigInt& priv_key = 0);
+ };
+
+/**
+* ElGamal encryption operation
+*/
+class BOTAN_DLL ElGamal_Encryption_Operation : public PK_Ops::Encryption
+ {
+ public:
+ size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; }
+
+ ElGamal_Encryption_Operation(const ElGamal_PublicKey& key);
+
+ secure_vector<byte> encrypt(const byte msg[], size_t msg_len,
+ RandomNumberGenerator& rng);
+
+ private:
+ Fixed_Base_Power_Mod powermod_g_p, powermod_y_p;
+ Modular_Reducer mod_p;
+ };
+
+/**
+* ElGamal decryption operation
+*/
+class BOTAN_DLL ElGamal_Decryption_Operation : public PK_Ops::Decryption
+ {
+ public:
+ size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; }
+
+ ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key,
+ RandomNumberGenerator& rng);
+
+ secure_vector<byte> decrypt(const byte msg[], size_t msg_len);
+ private:
+ Fixed_Exponent_Power_Mod powermod_x_p;
+ Modular_Reducer mod_p;
+ Blinder blinder;
+ };
+
+}
+
+#endif
diff --git a/src/lib/pubkey/elgamal/info.txt b/src/lib/pubkey/elgamal/info.txt
new file mode 100644
index 000000000..4fe20e828
--- /dev/null
+++ b/src/lib/pubkey/elgamal/info.txt
@@ -0,0 +1,9 @@
+define ELGAMAL 20131128
+
+<requires>
+dl_algo
+dl_group
+keypair
+libstate
+numbertheory
+</requires>