From 062e7a3dc98af064792967cfac44f61b0e7b0d8a Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 28 Sep 2008 20:41:59 +0000 Subject: Modularize the public key algorithms, though currently a great deal of the underlying implementation goop remains in the core library instead of being shunted off, due to various dependencies it has (most of which it shouldn't). --- src/dh.cpp | 117 -------------------------------- src/dsa.cpp | 131 ------------------------------------ src/elgamal.cpp | 121 ---------------------------------- src/nr.cpp | 131 ------------------------------------ src/pk/dh/dh.cpp | 117 ++++++++++++++++++++++++++++++++ src/pk/dh/dh.h | 57 ++++++++++++++++ src/pk/dsa/dsa.cpp | 131 ++++++++++++++++++++++++++++++++++++ src/pk/dsa/dsa.h | 60 +++++++++++++++++ src/pk/elgamal/elgamal.cpp | 121 ++++++++++++++++++++++++++++++++++ src/pk/elgamal/elgamal.h | 57 ++++++++++++++++ src/pk/nr/nr.cpp | 131 ++++++++++++++++++++++++++++++++++++ src/pk/nr/nr.h | 61 +++++++++++++++++ src/pk/rsa/rsa.cpp | 161 +++++++++++++++++++++++++++++++++++++++++++++ src/pk/rsa/rsa.h | 63 ++++++++++++++++++ src/pk/rw/rw.cpp | 145 ++++++++++++++++++++++++++++++++++++++++ src/pk/rw/rw.h | 54 +++++++++++++++ src/pk_algs.cpp | 86 +++++++++++++++++++----- src/rsa.cpp | 161 --------------------------------------------- src/rw.cpp | 145 ---------------------------------------- 19 files changed, 1228 insertions(+), 822 deletions(-) delete mode 100644 src/dh.cpp delete mode 100644 src/dsa.cpp delete mode 100644 src/elgamal.cpp delete mode 100644 src/nr.cpp create mode 100644 src/pk/dh/dh.cpp create mode 100644 src/pk/dh/dh.h create mode 100644 src/pk/dsa/dsa.cpp create mode 100644 src/pk/dsa/dsa.h create mode 100644 src/pk/elgamal/elgamal.cpp create mode 100644 src/pk/elgamal/elgamal.h create mode 100644 src/pk/nr/nr.cpp create mode 100644 src/pk/nr/nr.h create mode 100644 src/pk/rsa/rsa.cpp create mode 100644 src/pk/rsa/rsa.h create mode 100644 src/pk/rw/rw.cpp create mode 100644 src/pk/rw/rw.h delete mode 100644 src/rsa.cpp delete mode 100644 src/rw.cpp (limited to 'src') diff --git a/src/dh.cpp b/src/dh.cpp deleted file mode 100644 index 8d2059936..000000000 --- a/src/dh.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************* -* Diffie-Hellman Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -#include -#include - -namespace Botan { - -/************************************************* -* DH_PublicKey Constructor * -*************************************************/ -DH_PublicKey::DH_PublicKey(const DL_Group& grp, const BigInt& y1) - { - group = grp; - y = y1; - X509_load_hook(); - } - -/************************************************* -* Algorithm Specific X.509 Initialization Code * -*************************************************/ -void DH_PublicKey::X509_load_hook() - { - } - -/************************************************* -* Return the maximum input size in bits * -*************************************************/ -u32bit DH_PublicKey::max_input_bits() const - { - return group_p().bits(); - } - -/************************************************* -* Return the public value for key agreement * -*************************************************/ -MemoryVector DH_PublicKey::public_value() const - { - return BigInt::encode_1363(y, group_p().bytes()); - } - -/************************************************* -* Create a DH private key * -*************************************************/ -DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& grp, - const BigInt& x_arg) - { - group = grp; - x = x_arg; - - if(x == 0) - { - const BigInt& p = group_p(); - x.randomize(rng, 2 * dl_work_factor(p.bits())); - PKCS8_load_hook(rng, true); - } - else - PKCS8_load_hook(rng, false); - } - -/************************************************* -* Algorithm Specific PKCS #8 Initialization Code * -*************************************************/ -void DH_PrivateKey::PKCS8_load_hook(RandomNumberGenerator& rng, - bool generated) - { - if(y == 0) - y = power_mod(group_g(), x, group_p()); - core = DH_Core(rng, group, x); - - if(generated) - gen_check(rng); - else - load_check(rng); - } - -/************************************************* -* Return the public value for key agreement * -*************************************************/ -MemoryVector DH_PrivateKey::public_value() const - { - return DH_PublicKey::public_value(); - } - -/************************************************* -* Derive a key * -*************************************************/ -SecureVector DH_PrivateKey::derive_key(const byte w[], - u32bit w_len) const - { - return derive_key(BigInt::decode(w, w_len)); - } - -/************************************************* -* Derive a key * -*************************************************/ -SecureVector DH_PrivateKey::derive_key(const DH_PublicKey& key) const - { - return derive_key(key.get_y()); - } - -/************************************************* -* Derive a key * -*************************************************/ -SecureVector DH_PrivateKey::derive_key(const BigInt& w) const - { - const BigInt& p = group_p(); - if(w <= 1 || w >= p-1) - throw Invalid_Argument(algo_name() + "::derive_key: Invalid key input"); - return BigInt::encode_1363(core.agree(w), p.bytes()); - } - -} diff --git a/src/dsa.cpp b/src/dsa.cpp deleted file mode 100644 index a7eb8e789..000000000 --- a/src/dsa.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/************************************************* -* DSA Source File * -* (C) 1999-2008 Jack Lloyd * -*************************************************/ - -#include -#include -#include - -namespace Botan { - -/************************************************* -* DSA_PublicKey Constructor * -*************************************************/ -DSA_PublicKey::DSA_PublicKey(const DL_Group& grp, const BigInt& y1) - { - group = grp; - y = y1; - X509_load_hook(); - } - -/************************************************* -* Algorithm Specific X.509 Initialization Code * -*************************************************/ -void DSA_PublicKey::X509_load_hook() - { - core = DSA_Core(group, y); - } - -/************************************************* -* DSA Verification Function * -*************************************************/ -bool DSA_PublicKey::verify(const byte msg[], u32bit msg_len, - const byte sig[], u32bit sig_len) const - { - return core.verify(msg, msg_len, sig, sig_len); - } - -/************************************************* -* Return the maximum input size in bits * -*************************************************/ -u32bit DSA_PublicKey::max_input_bits() const - { - return group_q().bits(); - } - -/************************************************* -* Return the size of each portion of the sig * -*************************************************/ -u32bit DSA_PublicKey::message_part_size() const - { - return group_q().bytes(); - } - -/************************************************* -* Create a DSA private key * -*************************************************/ -DSA_PrivateKey::DSA_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& grp, - const BigInt& x_arg) - { - group = grp; - x = x_arg; - - if(x == 0) - { - x = random_integer(rng, 2, group_q() - 1); - PKCS8_load_hook(rng, true); - } - else - PKCS8_load_hook(rng, false); - } - -/************************************************* -* Algorithm Specific PKCS #8 Initialization Code * -*************************************************/ -void DSA_PrivateKey::PKCS8_load_hook(RandomNumberGenerator& rng, - bool generated) - { - y = power_mod(group_g(), x, group_p()); - core = DSA_Core(group, y, x); - - if(generated) - gen_check(rng); - else - load_check(rng); - } - -/************************************************* -* DSA Signature Operation * -*************************************************/ -SecureVector DSA_PrivateKey::sign(const byte in[], u32bit length, - RandomNumberGenerator& rng) const - { - const BigInt& q = group_q(); - - BigInt k; - do - k.randomize(rng, q.bits()); - while(k >= q); - - return core.sign(in, length, k); - } - -/************************************************* -* Check Private DSA Parameters * -*************************************************/ -bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const - { - if(!DL_Scheme_PrivateKey::check_key(rng, strong) || x >= group_q()) - return false; - - if(!strong) - return true; - - try - { - KeyPair::check_key(rng, - get_pk_signer(*this, "EMSA1(SHA-1)"), - get_pk_verifier(*this, "EMSA1(SHA-1)") - ); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; - } - -} diff --git a/src/elgamal.cpp b/src/elgamal.cpp deleted file mode 100644 index ea0d581b0..000000000 --- a/src/elgamal.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/************************************************* -* ElGamal Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -#include -#include -#include - -namespace Botan { - -/************************************************* -* ElGamal_PublicKey Constructor * -*************************************************/ -ElGamal_PublicKey::ElGamal_PublicKey(const DL_Group& grp, const BigInt& y1) - { - group = grp; - y = y1; - X509_load_hook(); - } - -/************************************************* -* Algorithm Specific X.509 Initialization Code * -*************************************************/ -void ElGamal_PublicKey::X509_load_hook() - { - core = ELG_Core(group, y); - } - -/************************************************* -* ElGamal Encryption Function * -*************************************************/ -SecureVector -ElGamal_PublicKey::encrypt(const byte in[], u32bit length, - RandomNumberGenerator& rng) const - { - BigInt k(rng, 2 * dl_work_factor(group_p().bits())); - return core.encrypt(in, length, k); - } - -/************************************************* -* Return the maximum input size in bits * -*************************************************/ -u32bit ElGamal_PublicKey::max_input_bits() const - { - return (group_p().bits() - 1); - } - -/************************************************* -* 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())); - PKCS8_load_hook(rng, true); - } - else - PKCS8_load_hook(rng, false); - } - -/************************************************* -* Algorithm Specific PKCS #8 Initialization Code * -*************************************************/ -void ElGamal_PrivateKey::PKCS8_load_hook(RandomNumberGenerator& rng, - bool generated) - { - if(y == 0) - y = power_mod(group_g(), x, group_p()); - core = ELG_Core(rng, group, y, x); - - if(generated) - gen_check(rng); - else - load_check(rng); - } - -/************************************************* -* ElGamal Decryption Function * -*************************************************/ -SecureVector ElGamal_PrivateKey::decrypt(const byte in[], - u32bit length) const - { - return core.decrypt(in, length); - } - -/************************************************* -* 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; - - try - { - KeyPair::check_key(rng, - get_pk_encryptor(*this, "EME1(SHA-1)"), - get_pk_decryptor(*this, "EME1(SHA-1)") - ); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; - } - -} diff --git a/src/nr.cpp b/src/nr.cpp deleted file mode 100644 index 02919d52e..000000000 --- a/src/nr.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/************************************************* -* Nyberg-Rueppel Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -#include -#include - -namespace Botan { - -/************************************************* -* NR_PublicKey Constructor * -*************************************************/ -NR_PublicKey::NR_PublicKey(const DL_Group& grp, const BigInt& y1) - { - group = grp; - y = y1; - X509_load_hook(); - } - -/************************************************* -* Algorithm Specific X.509 Initialization Code * -*************************************************/ -void NR_PublicKey::X509_load_hook() - { - core = NR_Core(group, y); - } - -/************************************************* -* Nyberg-Rueppel Verification Function * -*************************************************/ -SecureVector NR_PublicKey::verify(const byte sig[], u32bit sig_len) const - { - return core.verify(sig, sig_len); - } - -/************************************************* -* Return the maximum input size in bits * -*************************************************/ -u32bit NR_PublicKey::max_input_bits() const - { - return (group_q().bits() - 1); - } - -/************************************************* -* Return the size of each portion of the sig * -*************************************************/ -u32bit NR_PublicKey::message_part_size() const - { - return group_q().bytes(); - } - -/************************************************* -* Create a NR private key * -*************************************************/ -NR_PrivateKey::NR_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& grp, - const BigInt& x_arg) - { - group = grp; - x = x_arg; - - if(x == 0) - { - x = random_integer(rng, 2, group_q() - 1); - PKCS8_load_hook(rng, true); - } - else - PKCS8_load_hook(rng, false); - } - -/************************************************* -* Algorithm Specific PKCS #8 Initialization Code * -*************************************************/ -void NR_PrivateKey::PKCS8_load_hook(RandomNumberGenerator& rng, - bool generated) - { - if(y == 0) - y = power_mod(group_g(), x, group_p()); - core = NR_Core(group, y, x); - - if(generated) - gen_check(rng); - else - load_check(rng); - } - -/************************************************* -* Nyberg-Rueppel Signature Operation * -*************************************************/ -SecureVector NR_PrivateKey::sign(const byte in[], u32bit length, - RandomNumberGenerator& rng) const - { - const BigInt& q = group_q(); - - BigInt k; - do - k.randomize(rng, q.bits()); - while(k >= q); - - return core.sign(in, length, k); - } - -/************************************************* -* Check Private Nyberg-Rueppel Parameters * -*************************************************/ -bool NR_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const - { - if(!DL_Scheme_PrivateKey::check_key(rng, strong) || x >= group_q()) - return false; - - if(!strong) - return true; - - try - { - KeyPair::check_key(rng, - get_pk_signer(*this, "EMSA1(SHA-1)"), - get_pk_verifier(*this, "EMSA1(SHA-1)") - ); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; - } - -} diff --git a/src/pk/dh/dh.cpp b/src/pk/dh/dh.cpp new file mode 100644 index 000000000..8d2059936 --- /dev/null +++ b/src/pk/dh/dh.cpp @@ -0,0 +1,117 @@ +/************************************************* +* Diffie-Hellman Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +#include +#include + +namespace Botan { + +/************************************************* +* DH_PublicKey Constructor * +*************************************************/ +DH_PublicKey::DH_PublicKey(const DL_Group& grp, const BigInt& y1) + { + group = grp; + y = y1; + X509_load_hook(); + } + +/************************************************* +* Algorithm Specific X.509 Initialization Code * +*************************************************/ +void DH_PublicKey::X509_load_hook() + { + } + +/************************************************* +* Return the maximum input size in bits * +*************************************************/ +u32bit DH_PublicKey::max_input_bits() const + { + return group_p().bits(); + } + +/************************************************* +* Return the public value for key agreement * +*************************************************/ +MemoryVector DH_PublicKey::public_value() const + { + return BigInt::encode_1363(y, group_p().bytes()); + } + +/************************************************* +* Create a DH private key * +*************************************************/ +DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, + const DL_Group& grp, + const BigInt& x_arg) + { + group = grp; + x = x_arg; + + if(x == 0) + { + const BigInt& p = group_p(); + x.randomize(rng, 2 * dl_work_factor(p.bits())); + PKCS8_load_hook(rng, true); + } + else + PKCS8_load_hook(rng, false); + } + +/************************************************* +* Algorithm Specific PKCS #8 Initialization Code * +*************************************************/ +void DH_PrivateKey::PKCS8_load_hook(RandomNumberGenerator& rng, + bool generated) + { + if(y == 0) + y = power_mod(group_g(), x, group_p()); + core = DH_Core(rng, group, x); + + if(generated) + gen_check(rng); + else + load_check(rng); + } + +/************************************************* +* Return the public value for key agreement * +*************************************************/ +MemoryVector DH_PrivateKey::public_value() const + { + return DH_PublicKey::public_value(); + } + +/************************************************* +* Derive a key * +*************************************************/ +SecureVector DH_PrivateKey::derive_key(const byte w[], + u32bit w_len) const + { + return derive_key(BigInt::decode(w, w_len)); + } + +/************************************************* +* Derive a key * +*************************************************/ +SecureVector DH_PrivateKey::derive_key(const DH_PublicKey& key) const + { + return derive_key(key.get_y()); + } + +/************************************************* +* Derive a key * +*************************************************/ +SecureVector DH_PrivateKey::derive_key(const BigInt& w) const + { + const BigInt& p = group_p(); + if(w <= 1 || w >= p-1) + throw Invalid_Argument(algo_name() + "::derive_key: Invalid key input"); + return BigInt::encode_1363(core.agree(w), p.bytes()); + } + +} diff --git a/src/pk/dh/dh.h b/src/pk/dh/dh.h new file mode 100644 index 000000000..17a3fcae1 --- /dev/null +++ b/src/pk/dh/dh.h @@ -0,0 +1,57 @@ +/************************************************* +* Diffie-Hellman Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_DIFFIE_HELLMAN_H__ +#define BOTAN_DIFFIE_HELLMAN_H__ + +#include +#include + +namespace Botan { + +/************************************************* +* Diffie-Hellman Public Key * +*************************************************/ +class BOTAN_DLL DH_PublicKey : public virtual DL_Scheme_PublicKey + { + public: + std::string algo_name() const { return "DH"; } + + MemoryVector public_value() const; + u32bit max_input_bits() const; + + DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; } + + DH_PublicKey() {} + DH_PublicKey(const DL_Group&, const BigInt&); + private: + void X509_load_hook(); + }; + +/************************************************* +* Diffie-Hellman Private Key * +*************************************************/ +class BOTAN_DLL DH_PrivateKey : public DH_PublicKey, + public PK_Key_Agreement_Key, + public virtual DL_Scheme_PrivateKey + { + public: + SecureVector derive_key(const byte[], u32bit) const; + SecureVector derive_key(const DH_PublicKey&) const; + SecureVector derive_key(const BigInt&) const; + + MemoryVector public_value() const; + + DH_PrivateKey() {} + DH_PrivateKey(RandomNumberGenerator&, const DL_Group&, + const BigInt& = 0); + private: + void PKCS8_load_hook(RandomNumberGenerator&, bool = false); + DH_Core core; + }; + +} + +#endif diff --git a/src/pk/dsa/dsa.cpp b/src/pk/dsa/dsa.cpp new file mode 100644 index 000000000..a7eb8e789 --- /dev/null +++ b/src/pk/dsa/dsa.cpp @@ -0,0 +1,131 @@ +/************************************************* +* DSA Source File * +* (C) 1999-2008 Jack Lloyd * +*************************************************/ + +#include +#include +#include + +namespace Botan { + +/************************************************* +* DSA_PublicKey Constructor * +*************************************************/ +DSA_PublicKey::DSA_PublicKey(const DL_Group& grp, const BigInt& y1) + { + group = grp; + y = y1; + X509_load_hook(); + } + +/************************************************* +* Algorithm Specific X.509 Initialization Code * +*************************************************/ +void DSA_PublicKey::X509_load_hook() + { + core = DSA_Core(group, y); + } + +/************************************************* +* DSA Verification Function * +*************************************************/ +bool DSA_PublicKey::verify(const byte msg[], u32bit msg_len, + const byte sig[], u32bit sig_len) const + { + return core.verify(msg, msg_len, sig, sig_len); + } + +/************************************************* +* Return the maximum input size in bits * +*************************************************/ +u32bit DSA_PublicKey::max_input_bits() const + { + return group_q().bits(); + } + +/************************************************* +* Return the size of each portion of the sig * +*************************************************/ +u32bit DSA_PublicKey::message_part_size() const + { + return group_q().bytes(); + } + +/************************************************* +* Create a DSA private key * +*************************************************/ +DSA_PrivateKey::DSA_PrivateKey(RandomNumberGenerator& rng, + const DL_Group& grp, + const BigInt& x_arg) + { + group = grp; + x = x_arg; + + if(x == 0) + { + x = random_integer(rng, 2, group_q() - 1); + PKCS8_load_hook(rng, true); + } + else + PKCS8_load_hook(rng, false); + } + +/************************************************* +* Algorithm Specific PKCS #8 Initialization Code * +*************************************************/ +void DSA_PrivateKey::PKCS8_load_hook(RandomNumberGenerator& rng, + bool generated) + { + y = power_mod(group_g(), x, group_p()); + core = DSA_Core(group, y, x); + + if(generated) + gen_check(rng); + else + load_check(rng); + } + +/************************************************* +* DSA Signature Operation * +*************************************************/ +SecureVector DSA_PrivateKey::sign(const byte in[], u32bit length, + RandomNumberGenerator& rng) const + { + const BigInt& q = group_q(); + + BigInt k; + do + k.randomize(rng, q.bits()); + while(k >= q); + + return core.sign(in, length, k); + } + +/************************************************* +* Check Private DSA Parameters * +*************************************************/ +bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const + { + if(!DL_Scheme_PrivateKey::check_key(rng, strong) || x >= group_q()) + return false; + + if(!strong) + return true; + + try + { + KeyPair::check_key(rng, + get_pk_signer(*this, "EMSA1(SHA-1)"), + get_pk_verifier(*this, "EMSA1(SHA-1)") + ); + } + catch(Self_Test_Failure) + { + return false; + } + + return true; + } + +} diff --git a/src/pk/dsa/dsa.h b/src/pk/dsa/dsa.h new file mode 100644 index 000000000..59776147b --- /dev/null +++ b/src/pk/dsa/dsa.h @@ -0,0 +1,60 @@ +/************************************************* +* DSA Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_DSA_H__ +#define BOTAN_DSA_H__ + +#include +#include + +namespace Botan { + +/************************************************* +* DSA Public Key * +*************************************************/ +class BOTAN_DLL DSA_PublicKey : public PK_Verifying_wo_MR_Key, + public virtual DL_Scheme_PublicKey + { + public: + std::string algo_name() const { return "DSA"; } + + DL_Group::Format group_format() const { return DL_Group::ANSI_X9_57; } + u32bit message_parts() const { return 2; } + u32bit message_part_size() const; + + bool verify(const byte[], u32bit, const byte[], u32bit) const; + u32bit max_input_bits() const; + + DSA_PublicKey() {} + DSA_PublicKey(const DL_Group&, const BigInt&); + protected: + DSA_Core core; + private: + void X509_load_hook(); + }; + +/************************************************* +* DSA Private Key * +*************************************************/ +class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey, + public PK_Signing_Key, + public virtual DL_Scheme_PrivateKey + { + public: + SecureVector sign(const byte[], u32bit, + RandomNumberGenerator& rng) const; + + bool check_key(RandomNumberGenerator& rng, bool) const; + + DSA_PrivateKey() {} + DSA_PrivateKey(RandomNumberGenerator&, const DL_Group&, + const BigInt& = 0); + private: + void PKCS8_load_hook(RandomNumberGenerator& rng, bool = false); + }; + +} + +#endif diff --git a/src/pk/elgamal/elgamal.cpp b/src/pk/elgamal/elgamal.cpp new file mode 100644 index 000000000..ea0d581b0 --- /dev/null +++ b/src/pk/elgamal/elgamal.cpp @@ -0,0 +1,121 @@ +/************************************************* +* ElGamal Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +#include +#include +#include + +namespace Botan { + +/************************************************* +* ElGamal_PublicKey Constructor * +*************************************************/ +ElGamal_PublicKey::ElGamal_PublicKey(const DL_Group& grp, const BigInt& y1) + { + group = grp; + y = y1; + X509_load_hook(); + } + +/************************************************* +* Algorithm Specific X.509 Initialization Code * +*************************************************/ +void ElGamal_PublicKey::X509_load_hook() + { + core = ELG_Core(group, y); + } + +/************************************************* +* ElGamal Encryption Function * +*************************************************/ +SecureVector +ElGamal_PublicKey::encrypt(const byte in[], u32bit length, + RandomNumberGenerator& rng) const + { + BigInt k(rng, 2 * dl_work_factor(group_p().bits())); + return core.encrypt(in, length, k); + } + +/************************************************* +* Return the maximum input size in bits * +*************************************************/ +u32bit ElGamal_PublicKey::max_input_bits() const + { + return (group_p().bits() - 1); + } + +/************************************************* +* 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())); + PKCS8_load_hook(rng, true); + } + else + PKCS8_load_hook(rng, false); + } + +/************************************************* +* Algorithm Specific PKCS #8 Initialization Code * +*************************************************/ +void ElGamal_PrivateKey::PKCS8_load_hook(RandomNumberGenerator& rng, + bool generated) + { + if(y == 0) + y = power_mod(group_g(), x, group_p()); + core = ELG_Core(rng, group, y, x); + + if(generated) + gen_check(rng); + else + load_check(rng); + } + +/************************************************* +* ElGamal Decryption Function * +*************************************************/ +SecureVector ElGamal_PrivateKey::decrypt(const byte in[], + u32bit length) const + { + return core.decrypt(in, length); + } + +/************************************************* +* 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; + + try + { + KeyPair::check_key(rng, + get_pk_encryptor(*this, "EME1(SHA-1)"), + get_pk_decryptor(*this, "EME1(SHA-1)") + ); + } + catch(Self_Test_Failure) + { + return false; + } + + return true; + } + +} diff --git a/src/pk/elgamal/elgamal.h b/src/pk/elgamal/elgamal.h new file mode 100644 index 000000000..feeeb3953 --- /dev/null +++ b/src/pk/elgamal/elgamal.h @@ -0,0 +1,57 @@ +/************************************************* +* ElGamal Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_ELGAMAL_H__ +#define BOTAN_ELGAMAL_H__ + +#include +#include + +namespace Botan { + +/************************************************* +* ElGamal Public Key * +*************************************************/ +class BOTAN_DLL ElGamal_PublicKey : public PK_Encrypting_Key, + 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; } + + SecureVector encrypt(const byte[], u32bit, + RandomNumberGenerator& rng) const; + u32bit max_input_bits() const; + + ElGamal_PublicKey() {} + ElGamal_PublicKey(const DL_Group&, const BigInt&); + protected: + ELG_Core core; + private: + void X509_load_hook(); + }; + +/************************************************* +* ElGamal Private Key * +*************************************************/ +class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey, + public PK_Decrypting_Key, + public virtual DL_Scheme_PrivateKey + { + public: + SecureVector decrypt(const byte[], u32bit) const; + + bool check_key(RandomNumberGenerator& rng, bool) const; + + ElGamal_PrivateKey() {} + ElGamal_PrivateKey(RandomNumberGenerator&, const DL_Group&, + const BigInt& = 0); + private: + void PKCS8_load_hook(RandomNumberGenerator&, bool = false); + }; + +} + +#endif diff --git a/src/pk/nr/nr.cpp b/src/pk/nr/nr.cpp new file mode 100644 index 000000000..02919d52e --- /dev/null +++ b/src/pk/nr/nr.cpp @@ -0,0 +1,131 @@ +/************************************************* +* Nyberg-Rueppel Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +#include +#include + +namespace Botan { + +/************************************************* +* NR_PublicKey Constructor * +*************************************************/ +NR_PublicKey::NR_PublicKey(const DL_Group& grp, const BigInt& y1) + { + group = grp; + y = y1; + X509_load_hook(); + } + +/************************************************* +* Algorithm Specific X.509 Initialization Code * +*************************************************/ +void NR_PublicKey::X509_load_hook() + { + core = NR_Core(group, y); + } + +/************************************************* +* Nyberg-Rueppel Verification Function * +*************************************************/ +SecureVector NR_PublicKey::verify(const byte sig[], u32bit sig_len) const + { + return core.verify(sig, sig_len); + } + +/************************************************* +* Return the maximum input size in bits * +*************************************************/ +u32bit NR_PublicKey::max_input_bits() const + { + return (group_q().bits() - 1); + } + +/************************************************* +* Return the size of each portion of the sig * +*************************************************/ +u32bit NR_PublicKey::message_part_size() const + { + return group_q().bytes(); + } + +/************************************************* +* Create a NR private key * +*************************************************/ +NR_PrivateKey::NR_PrivateKey(RandomNumberGenerator& rng, + const DL_Group& grp, + const BigInt& x_arg) + { + group = grp; + x = x_arg; + + if(x == 0) + { + x = random_integer(rng, 2, group_q() - 1); + PKCS8_load_hook(rng, true); + } + else + PKCS8_load_hook(rng, false); + } + +/************************************************* +* Algorithm Specific PKCS #8 Initialization Code * +*************************************************/ +void NR_PrivateKey::PKCS8_load_hook(RandomNumberGenerator& rng, + bool generated) + { + if(y == 0) + y = power_mod(group_g(), x, group_p()); + core = NR_Core(group, y, x); + + if(generated) + gen_check(rng); + else + load_check(rng); + } + +/************************************************* +* Nyberg-Rueppel Signature Operation * +*************************************************/ +SecureVector NR_PrivateKey::sign(const byte in[], u32bit length, + RandomNumberGenerator& rng) const + { + const BigInt& q = group_q(); + + BigInt k; + do + k.randomize(rng, q.bits()); + while(k >= q); + + return core.sign(in, length, k); + } + +/************************************************* +* Check Private Nyberg-Rueppel Parameters * +*************************************************/ +bool NR_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const + { + if(!DL_Scheme_PrivateKey::check_key(rng, strong) || x >= group_q()) + return false; + + if(!strong) + return true; + + try + { + KeyPair::check_key(rng, + get_pk_signer(*this, "EMSA1(SHA-1)"), + get_pk_verifier(*this, "EMSA1(SHA-1)") + ); + } + catch(Self_Test_Failure) + { + return false; + } + + return true; + } + +} diff --git a/src/pk/nr/nr.h b/src/pk/nr/nr.h new file mode 100644 index 000000000..0b68340d6 --- /dev/null +++ b/src/pk/nr/nr.h @@ -0,0 +1,61 @@ +/************************************************* +* Nyberg-Rueppel Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_NYBERG_RUEPPEL_H__ +#define BOTAN_NYBERG_RUEPPEL_H__ + +#include +#include + +namespace Botan { + +/************************************************* +* Nyberg-Rueppel Public Key * +*************************************************/ +class BOTAN_DLL NR_PublicKey : public PK_Verifying_with_MR_Key, + public virtual DL_Scheme_PublicKey + { + public: + std::string algo_name() const { return "NR"; } + + SecureVector verify(const byte[], u32bit) const; + u32bit max_input_bits() const; + + DL_Group::Format group_format() const { return DL_Group::ANSI_X9_57; } + u32bit message_parts() const { return 2; } + u32bit message_part_size() const; + + NR_PublicKey() {} + NR_PublicKey(const DL_Group&, const BigInt&); + protected: + NR_Core core; + private: + void X509_load_hook(); + }; + +/************************************************* +* Nyberg-Rueppel Private Key * +*************************************************/ +class BOTAN_DLL NR_PrivateKey : public NR_PublicKey, + public PK_Signing_Key, + public virtual DL_Scheme_PrivateKey + { + public: + SecureVector sign(const byte[], u32bit, + RandomNumberGenerator& rng) const; + + bool check_key(RandomNumberGenerator& rng, bool) const; + + NR_PrivateKey() {} + + NR_PrivateKey(RandomNumberGenerator&, const DL_Group&, + const BigInt& = 0); + private: + void PKCS8_load_hook(RandomNumberGenerator&, bool = false); + }; + +} + +#endif diff --git a/src/pk/rsa/rsa.cpp b/src/pk/rsa/rsa.cpp new file mode 100644 index 000000000..8faec9972 --- /dev/null +++ b/src/pk/rsa/rsa.cpp @@ -0,0 +1,161 @@ +/************************************************* +* RSA Source File * +* (C) 1999-2008 Jack Lloyd * +*************************************************/ + +#include +#include +#include +#include + +namespace Botan { + +/************************************************* +* RSA_PublicKey Constructor * +*************************************************/ +RSA_PublicKey::RSA_PublicKey(const BigInt& mod, const BigInt& exp) + { + n = mod; + e = exp; + X509_load_hook(); + } + +/************************************************* +* RSA Public Operation * +*************************************************/ +BigInt RSA_PublicKey::public_op(const BigInt& i) const + { + if(i >= n) + throw Invalid_Argument(algo_name() + "::public_op: input is too large"); + return core.public_op(i); + } + +/************************************************* +* RSA Encryption Function * +*************************************************/ +SecureVector RSA_PublicKey::encrypt(const byte in[], u32bit len, + RandomNumberGenerator&) const + { + BigInt i(in, len); + return BigInt::encode_1363(public_op(i), n.bytes()); + } + +/************************************************* +* RSA Verification Function * +*************************************************/ +SecureVector RSA_PublicKey::verify(const byte in[], u32bit len) const + { + BigInt i(in, len); + return BigInt::encode(public_op(i)); + } + +/************************************************* +* Create a RSA private key * +*************************************************/ +RSA_PrivateKey::RSA_PrivateKey(RandomNumberGenerator& rng, + u32bit bits, u32bit exp) + { + if(bits < 512) + throw Invalid_Argument(algo_name() + ": Can't make a key that is only " + + to_string(bits) + " bits long"); + if(exp < 3 || exp % 2 == 0) + throw Invalid_Argument(algo_name() + ": Invalid encryption exponent"); + + e = exp; + p = random_prime(rng, (bits + 1) / 2, e); + q = random_prime(rng, bits - p.bits(), e); + d = inverse_mod(e, lcm(p - 1, q - 1)); + + PKCS8_load_hook(rng, true); + + if(n.bits() != bits) + throw Self_Test_Failure(algo_name() + " private key generation failed"); + } + +/************************************************* +* RSA_PrivateKey Constructor * +*************************************************/ +RSA_PrivateKey::RSA_PrivateKey(RandomNumberGenerator& rng, + const BigInt& prime1, const BigInt& prime2, + const BigInt& exp, const BigInt& d_exp, + const BigInt& mod) + { + p = prime1; + q = prime2; + e = exp; + d = d_exp; + n = mod; + + if(d == 0) + d = inverse_mod(e, lcm(p - 1, q - 1)); + + PKCS8_load_hook(rng); + } + +/************************************************* +* RSA Private Operation * +*************************************************/ +BigInt RSA_PrivateKey::private_op(const byte in[], u32bit length) const + { + BigInt i(in, length); + if(i >= n) + throw Invalid_Argument(algo_name() + "::private_op: input is too large"); + + BigInt r = core.private_op(i); + if(i != public_op(r)) + throw Self_Test_Failure(algo_name() + " private operation check failed"); + return r; + } + +/************************************************* +* RSA Decryption Operation * +*************************************************/ +SecureVector RSA_PrivateKey::decrypt(const byte in[], u32bit len) const + { + return BigInt::encode(private_op(in, len)); + } + +/************************************************* +* RSA Signature Operation * +*************************************************/ +SecureVector RSA_PrivateKey::sign(const byte in[], u32bit len, + RandomNumberGenerator&) const + { + return BigInt::encode_1363(private_op(in, len), n.bytes()); + } + +/************************************************* +* Check Private RSA Parameters * +*************************************************/ +bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const + { + if(!IF_Scheme_PrivateKey::check_key(rng, strong)) + return false; + + if(!strong) + return true; + + if((e * d) % lcm(p - 1, q - 1) != 1) + return false; + + try + { + KeyPair::check_key(rng, + get_pk_encryptor(*this, "EME1(SHA-1)"), + get_pk_decryptor(*this, "EME1(SHA-1)") + ); + + KeyPair::check_key(rng, + get_pk_signer(*this, "EMSA4(SHA-1)"), + get_pk_verifier(*this, "EMSA4(SHA-1)") + ); + } + catch(Self_Test_Failure) + { + return false; + } + + return true; + } + +} diff --git a/src/pk/rsa/rsa.h b/src/pk/rsa/rsa.h new file mode 100644 index 000000000..445902a6f --- /dev/null +++ b/src/pk/rsa/rsa.h @@ -0,0 +1,63 @@ +/************************************************* +* RSA Header File * +* (C) 1999-2008 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_RSA_H__ +#define BOTAN_RSA_H__ + +#include + +namespace Botan { + +/************************************************* +* RSA Public Key * +*************************************************/ +class BOTAN_DLL RSA_PublicKey : public PK_Encrypting_Key, + public PK_Verifying_with_MR_Key, + public virtual IF_Scheme_PublicKey + { + public: + std::string algo_name() const { return "RSA"; } + + SecureVector encrypt(const byte[], u32bit, + RandomNumberGenerator& rng) const; + + SecureVector verify(const byte[], u32bit) const; + + RSA_PublicKey() {} + RSA_PublicKey(const BigInt&, const BigInt&); + protected: + BigInt public_op(const BigInt&) const; + }; + +/************************************************* +* RSA Private Key * +*************************************************/ +class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey, + public PK_Decrypting_Key, + public PK_Signing_Key, + public IF_Scheme_PrivateKey + { + public: + SecureVector sign(const byte[], u32bit, + RandomNumberGenerator&) const; + + SecureVector decrypt(const byte[], u32bit) const; + + bool check_key(RandomNumberGenerator& rng, bool) const; + + RSA_PrivateKey() {} + + RSA_PrivateKey(RandomNumberGenerator&, + const BigInt& p, const BigInt& q, const BigInt& e, + const BigInt& d = 0, const BigInt& n = 0); + + RSA_PrivateKey(RandomNumberGenerator&, u32bit bits, u32bit = 65537); + private: + BigInt private_op(const byte[], u32bit) const; + }; + +} + +#endif diff --git a/src/pk/rw/rw.cpp b/src/pk/rw/rw.cpp new file mode 100644 index 000000000..39cbcdd6e --- /dev/null +++ b/src/pk/rw/rw.cpp @@ -0,0 +1,145 @@ +/************************************************* +* Rabin-Williams Source File * +* (C) 1999-2008 Jack Lloyd * +*************************************************/ + +#include +#include +#include +#include +#include + +namespace Botan { + +/************************************************* +* RW_PublicKey Constructor * +*************************************************/ +RW_PublicKey::RW_PublicKey(const BigInt& mod, const BigInt& exp) + { + n = mod; + e = exp; + X509_load_hook(); + } + +/************************************************* +* Rabin-Williams Public Operation * +*************************************************/ +BigInt RW_PublicKey::public_op(const BigInt& i) const + { + if((i > (n >> 1)) || i.is_negative()) + throw Invalid_Argument(algo_name() + "::public_op: i > n / 2 || i < 0"); + + BigInt r = core.public_op(i); + if(r % 16 == 12) return r; + if(r % 8 == 6) return 2*r; + + r = n - r; + if(r % 16 == 12) return r; + if(r % 8 == 6) return 2*r; + + throw Invalid_Argument(algo_name() + "::public_op: Invalid input"); + } + +/************************************************* +* Rabin-Williams Verification Function * +*************************************************/ +SecureVector RW_PublicKey::verify(const byte in[], u32bit len) const + { + BigInt i(in, len); + return BigInt::encode(public_op(i)); + } + +/************************************************* +* Create a Rabin-Williams private key * +*************************************************/ +RW_PrivateKey::RW_PrivateKey(RandomNumberGenerator& rng, + u32bit bits, u32bit exp) + { + if(bits < 512) + throw Invalid_Argument(algo_name() + ": Can't make a key that is only " + + to_string(bits) + " bits long"); + if(exp < 2 || exp % 2 == 1) + throw Invalid_Argument(algo_name() + ": Invalid encryption exponent"); + + e = exp; + p = random_prime(rng, (bits + 1) / 2, e / 2, 3, 4); + q = random_prime(rng, bits - p.bits(), e / 2, ((p % 8 == 3) ? 7 : 3), 8); + d = inverse_mod(e, lcm(p - 1, q - 1) >> 1); + + PKCS8_load_hook(rng, true); + + if(n.bits() != bits) + throw Self_Test_Failure(algo_name() + " private key generation failed"); + } + +/************************************************* +* RW_PrivateKey Constructor * +*************************************************/ +RW_PrivateKey::RW_PrivateKey(RandomNumberGenerator& rng, + const BigInt& prime1, const BigInt& prime2, + const BigInt& exp, const BigInt& d_exp, + const BigInt& mod) + { + p = prime1; + q = prime2; + e = exp; + d = d_exp; + n = mod; + + if(d == 0) + d = inverse_mod(e, lcm(p - 1, q - 1) >> 1); + + PKCS8_load_hook(rng); + } + +/************************************************* +* Rabin-Williams Signature Operation * +*************************************************/ +SecureVector RW_PrivateKey::sign(const byte in[], u32bit len, + RandomNumberGenerator&) const + { + BigInt i(in, len); + if(i >= n || i % 16 != 12) + throw Invalid_Argument(algo_name() + "::sign: Invalid input"); + + BigInt r; + if(jacobi(i, n) == 1) r = core.private_op(i); + else r = core.private_op(i >> 1); + + r = std::min(r, n - r); + if(i != public_op(r)) + throw Self_Test_Failure(algo_name() + " private operation check failed"); + + return BigInt::encode_1363(r, n.bytes()); + } + +/************************************************* +* Check Private Rabin-Williams Parameters * +*************************************************/ +bool RW_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const + { + if(!IF_Scheme_PrivateKey::check_key(rng, strong)) + return false; + + if(!strong) + return true; + + if((e * d) % (lcm(p - 1, q - 1) / 2) != 1) + return false; + + try + { + KeyPair::check_key(rng, + get_pk_signer(*this, "EMSA2(SHA-1)"), + get_pk_verifier(*this, "EMSA2(SHA-1)") + ); + } + catch(Self_Test_Failure) + { + return false; + } + + return true; + } + +} diff --git a/src/pk/rw/rw.h b/src/pk/rw/rw.h new file mode 100644 index 000000000..d9f95eaa9 --- /dev/null +++ b/src/pk/rw/rw.h @@ -0,0 +1,54 @@ +/************************************************* +* Rabin-Williams Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_RW_H__ +#define BOTAN_RW_H__ + +#include + +namespace Botan { + +/************************************************* +* Rabin-Williams Public Key * +*************************************************/ +class BOTAN_DLL RW_PublicKey : public PK_Verifying_with_MR_Key, + public virtual IF_Scheme_PublicKey + { + public: + std::string algo_name() const { return "RW"; } + + SecureVector verify(const byte[], u32bit) const; + + RW_PublicKey() {} + RW_PublicKey(const BigInt&, const BigInt&); + protected: + BigInt public_op(const BigInt&) const; + }; + +/************************************************* +* Rabin-Williams Private Key * +*************************************************/ +class BOTAN_DLL RW_PrivateKey : public RW_PublicKey, + public PK_Signing_Key, + public IF_Scheme_PrivateKey + { + public: + SecureVector sign(const byte[], u32bit, + RandomNumberGenerator& rng) const; + + bool check_key(RandomNumberGenerator& rng, bool) const; + + RW_PrivateKey() {} + + RW_PrivateKey(RandomNumberGenerator&, + const BigInt&, const BigInt&, const BigInt&, + const BigInt& = 0, const BigInt& = 0); + + RW_PrivateKey(RandomNumberGenerator& rng, u32bit bits, u32bit = 2); + }; + +} + +#endif diff --git a/src/pk_algs.cpp b/src/pk_algs.cpp index 6a76b11c3..d400d5b74 100644 --- a/src/pk_algs.cpp +++ b/src/pk_algs.cpp @@ -4,12 +4,30 @@ *************************************************/ #include + +#ifdef BOTAN_HAS_RSA #include +#endif + +#ifdef BOTAN_HAS_DSA #include +#endif + +#ifdef BOTAN_HAS_DH #include +#endif + +#ifdef BOTAN_HAS_NR #include +#endif + +#ifdef BOTAN_HAS_RW #include +#endif + +#ifdef BOTAN_HAS_ELGAMAL #include +#endif namespace Botan { @@ -18,14 +36,32 @@ namespace Botan { *************************************************/ Public_Key* get_public_key(const std::string& alg_name) { - if(alg_name == "RSA") return new RSA_PublicKey; - else if(alg_name == "DSA") return new DSA_PublicKey; - else if(alg_name == "DH") return new DH_PublicKey; - else if(alg_name == "NR") return new NR_PublicKey; - else if(alg_name == "RW") return new RW_PublicKey; - else if(alg_name == "ELG") return new ElGamal_PublicKey; - else - return 0; +#if defined(BOTAN_HAS_RSA) + if(alg_name == "RSA") return new RSA_PublicKey; +#endif + +#if defined(BOTAN_HAS_DSA) + if(alg_name == "DSA") return new DSA_PublicKey; +#endif + +#if defined(BOTAN_HAS_DH) + if(alg_name == "DH") return new DH_PublicKey; +#endif + +#if defined(BOTAN_HAS_NR) + if(alg_name == "NR") return new NR_PublicKey; +#endif + +#if defined(BOTAN_HAS_RW) + if(alg_name == "RW") return new RW_PublicKey; +#endif + +#if defined(BOTAN_HAS_ELG) + if(alg_name == "ELG") return new ElGamal_PublicKey; +#endif + + + return 0; } /************************************************* @@ -33,14 +69,32 @@ Public_Key* get_public_key(const std::string& alg_name) *************************************************/ Private_Key* get_private_key(const std::string& alg_name) { - if(alg_name == "RSA") return new RSA_PrivateKey; - else if(alg_name == "DSA") return new DSA_PrivateKey; - else if(alg_name == "DH") return new DH_PrivateKey; - else if(alg_name == "NR") return new NR_PrivateKey; - else if(alg_name == "RW") return new RW_PrivateKey; - else if(alg_name == "ELG") return new ElGamal_PrivateKey; - else - return 0; +#if defined(BOTAN_HAS_RSA) + if(alg_name == "RSA") return new RSA_PrivateKey; +#endif + +#if defined(BOTAN_HAS_DSA) + if(alg_name == "DSA") return new DSA_PrivateKey; +#endif + +#if defined(BOTAN_HAS_DH) + if(alg_name == "DH") return new DH_PrivateKey; +#endif + +#if defined(BOTAN_HAS_NR) + if(alg_name == "NR") return new NR_PrivateKey; +#endif + +#if defined(BOTAN_HAS_RW) + if(alg_name == "RW") return new RW_PrivateKey; +#endif + +#if defined(BOTAN_HAS_ELG) + if(alg_name == "ELG") return new ElGamal_PrivateKey; +#endif + + + return 0; } } diff --git a/src/rsa.cpp b/src/rsa.cpp deleted file mode 100644 index 8faec9972..000000000 --- a/src/rsa.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/************************************************* -* RSA Source File * -* (C) 1999-2008 Jack Lloyd * -*************************************************/ - -#include -#include -#include -#include - -namespace Botan { - -/************************************************* -* RSA_PublicKey Constructor * -*************************************************/ -RSA_PublicKey::RSA_PublicKey(const BigInt& mod, const BigInt& exp) - { - n = mod; - e = exp; - X509_load_hook(); - } - -/************************************************* -* RSA Public Operation * -*************************************************/ -BigInt RSA_PublicKey::public_op(const BigInt& i) const - { - if(i >= n) - throw Invalid_Argument(algo_name() + "::public_op: input is too large"); - return core.public_op(i); - } - -/************************************************* -* RSA Encryption Function * -*************************************************/ -SecureVector RSA_PublicKey::encrypt(const byte in[], u32bit len, - RandomNumberGenerator&) const - { - BigInt i(in, len); - return BigInt::encode_1363(public_op(i), n.bytes()); - } - -/************************************************* -* RSA Verification Function * -*************************************************/ -SecureVector RSA_PublicKey::verify(const byte in[], u32bit len) const - { - BigInt i(in, len); - return BigInt::encode(public_op(i)); - } - -/************************************************* -* Create a RSA private key * -*************************************************/ -RSA_PrivateKey::RSA_PrivateKey(RandomNumberGenerator& rng, - u32bit bits, u32bit exp) - { - if(bits < 512) - throw Invalid_Argument(algo_name() + ": Can't make a key that is only " + - to_string(bits) + " bits long"); - if(exp < 3 || exp % 2 == 0) - throw Invalid_Argument(algo_name() + ": Invalid encryption exponent"); - - e = exp; - p = random_prime(rng, (bits + 1) / 2, e); - q = random_prime(rng, bits - p.bits(), e); - d = inverse_mod(e, lcm(p - 1, q - 1)); - - PKCS8_load_hook(rng, true); - - if(n.bits() != bits) - throw Self_Test_Failure(algo_name() + " private key generation failed"); - } - -/************************************************* -* RSA_PrivateKey Constructor * -*************************************************/ -RSA_PrivateKey::RSA_PrivateKey(RandomNumberGenerator& rng, - const BigInt& prime1, const BigInt& prime2, - const BigInt& exp, const BigInt& d_exp, - const BigInt& mod) - { - p = prime1; - q = prime2; - e = exp; - d = d_exp; - n = mod; - - if(d == 0) - d = inverse_mod(e, lcm(p - 1, q - 1)); - - PKCS8_load_hook(rng); - } - -/************************************************* -* RSA Private Operation * -*************************************************/ -BigInt RSA_PrivateKey::private_op(const byte in[], u32bit length) const - { - BigInt i(in, length); - if(i >= n) - throw Invalid_Argument(algo_name() + "::private_op: input is too large"); - - BigInt r = core.private_op(i); - if(i != public_op(r)) - throw Self_Test_Failure(algo_name() + " private operation check failed"); - return r; - } - -/************************************************* -* RSA Decryption Operation * -*************************************************/ -SecureVector RSA_PrivateKey::decrypt(const byte in[], u32bit len) const - { - return BigInt::encode(private_op(in, len)); - } - -/************************************************* -* RSA Signature Operation * -*************************************************/ -SecureVector RSA_PrivateKey::sign(const byte in[], u32bit len, - RandomNumberGenerator&) const - { - return BigInt::encode_1363(private_op(in, len), n.bytes()); - } - -/************************************************* -* Check Private RSA Parameters * -*************************************************/ -bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const - { - if(!IF_Scheme_PrivateKey::check_key(rng, strong)) - return false; - - if(!strong) - return true; - - if((e * d) % lcm(p - 1, q - 1) != 1) - return false; - - try - { - KeyPair::check_key(rng, - get_pk_encryptor(*this, "EME1(SHA-1)"), - get_pk_decryptor(*this, "EME1(SHA-1)") - ); - - KeyPair::check_key(rng, - get_pk_signer(*this, "EMSA4(SHA-1)"), - get_pk_verifier(*this, "EMSA4(SHA-1)") - ); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; - } - -} diff --git a/src/rw.cpp b/src/rw.cpp deleted file mode 100644 index 39cbcdd6e..000000000 --- a/src/rw.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/************************************************* -* Rabin-Williams Source File * -* (C) 1999-2008 Jack Lloyd * -*************************************************/ - -#include -#include -#include -#include -#include - -namespace Botan { - -/************************************************* -* RW_PublicKey Constructor * -*************************************************/ -RW_PublicKey::RW_PublicKey(const BigInt& mod, const BigInt& exp) - { - n = mod; - e = exp; - X509_load_hook(); - } - -/************************************************* -* Rabin-Williams Public Operation * -*************************************************/ -BigInt RW_PublicKey::public_op(const BigInt& i) const - { - if((i > (n >> 1)) || i.is_negative()) - throw Invalid_Argument(algo_name() + "::public_op: i > n / 2 || i < 0"); - - BigInt r = core.public_op(i); - if(r % 16 == 12) return r; - if(r % 8 == 6) return 2*r; - - r = n - r; - if(r % 16 == 12) return r; - if(r % 8 == 6) return 2*r; - - throw Invalid_Argument(algo_name() + "::public_op: Invalid input"); - } - -/************************************************* -* Rabin-Williams Verification Function * -*************************************************/ -SecureVector RW_PublicKey::verify(const byte in[], u32bit len) const - { - BigInt i(in, len); - return BigInt::encode(public_op(i)); - } - -/************************************************* -* Create a Rabin-Williams private key * -*************************************************/ -RW_PrivateKey::RW_PrivateKey(RandomNumberGenerator& rng, - u32bit bits, u32bit exp) - { - if(bits < 512) - throw Invalid_Argument(algo_name() + ": Can't make a key that is only " + - to_string(bits) + " bits long"); - if(exp < 2 || exp % 2 == 1) - throw Invalid_Argument(algo_name() + ": Invalid encryption exponent"); - - e = exp; - p = random_prime(rng, (bits + 1) / 2, e / 2, 3, 4); - q = random_prime(rng, bits - p.bits(), e / 2, ((p % 8 == 3) ? 7 : 3), 8); - d = inverse_mod(e, lcm(p - 1, q - 1) >> 1); - - PKCS8_load_hook(rng, true); - - if(n.bits() != bits) - throw Self_Test_Failure(algo_name() + " private key generation failed"); - } - -/************************************************* -* RW_PrivateKey Constructor * -*************************************************/ -RW_PrivateKey::RW_PrivateKey(RandomNumberGenerator& rng, - const BigInt& prime1, const BigInt& prime2, - const BigInt& exp, const BigInt& d_exp, - const BigInt& mod) - { - p = prime1; - q = prime2; - e = exp; - d = d_exp; - n = mod; - - if(d == 0) - d = inverse_mod(e, lcm(p - 1, q - 1) >> 1); - - PKCS8_load_hook(rng); - } - -/************************************************* -* Rabin-Williams Signature Operation * -*************************************************/ -SecureVector RW_PrivateKey::sign(const byte in[], u32bit len, - RandomNumberGenerator&) const - { - BigInt i(in, len); - if(i >= n || i % 16 != 12) - throw Invalid_Argument(algo_name() + "::sign: Invalid input"); - - BigInt r; - if(jacobi(i, n) == 1) r = core.private_op(i); - else r = core.private_op(i >> 1); - - r = std::min(r, n - r); - if(i != public_op(r)) - throw Self_Test_Failure(algo_name() + " private operation check failed"); - - return BigInt::encode_1363(r, n.bytes()); - } - -/************************************************* -* Check Private Rabin-Williams Parameters * -*************************************************/ -bool RW_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const - { - if(!IF_Scheme_PrivateKey::check_key(rng, strong)) - return false; - - if(!strong) - return true; - - if((e * d) % (lcm(p - 1, q - 1) / 2) != 1) - return false; - - try - { - KeyPair::check_key(rng, - get_pk_signer(*this, "EMSA2(SHA-1)"), - get_pk_verifier(*this, "EMSA2(SHA-1)") - ); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; - } - -} -- cgit v1.2.3