From 6fd841dc614a77b7a672681606d236e45e308219 Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 28 Sep 2008 22:02:06 +0000 Subject: Add dl_algo and dl_group modules --- include/dl_algo.h | 61 -------- include/dl_group.h | 74 ---------- src/dl_algo.cpp | 165 ---------------------- src/dl_group.cpp | 327 ------------------------------------------- src/pk/dh/modinfo.txt | 5 + src/pk/dl_algo/dl_algo.cpp | 165 ++++++++++++++++++++++ src/pk/dl_algo/dl_algo.h | 61 ++++++++ src/pk/dl_group/dl_group.cpp | 327 +++++++++++++++++++++++++++++++++++++++++++ src/pk/dl_group/dl_group.h | 74 ++++++++++ src/pk/dsa/modinfo.txt | 5 + src/pk/nr/modinfo.txt | 5 + src/pk/rsa/modinfo.txt | 1 + src/pk/rw/modinfo.txt | 1 + 13 files changed, 644 insertions(+), 627 deletions(-) delete mode 100644 include/dl_algo.h delete mode 100644 include/dl_group.h delete mode 100644 src/dl_algo.cpp delete mode 100644 src/dl_group.cpp create mode 100644 src/pk/dl_algo/dl_algo.cpp create mode 100644 src/pk/dl_algo/dl_algo.h create mode 100644 src/pk/dl_group/dl_group.cpp create mode 100644 src/pk/dl_group/dl_group.h diff --git a/include/dl_algo.h b/include/dl_algo.h deleted file mode 100644 index a8d8d1d51..000000000 --- a/include/dl_algo.h +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************* -* DL Scheme Header File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#ifndef BOTAN_DL_ALGO_H__ -#define BOTAN_DL_ALGO_H__ - -#include -#include -#include -#include - -namespace Botan { - -/************************************************* -* DL Public Key * -*************************************************/ -class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - const DL_Group& get_domain() const { return group; } - const BigInt& get_y() const { return y; } - const BigInt& group_p() const { return group.get_p(); } - const BigInt& group_q() const { return group.get_q(); } - const BigInt& group_g() const { return group.get_g(); } - virtual DL_Group::Format group_format() const = 0; - - X509_Encoder* x509_encoder() const; - X509_Decoder* x509_decoder(); - protected: - BigInt y; - DL_Group group; - private: - virtual void X509_load_hook() {} - }; - -/************************************************* -* DL Private Key * -*************************************************/ -class BOTAN_DLL DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey, - public virtual Private_Key - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - const BigInt& get_x() const { return x; } - - PKCS8_Encoder* pkcs8_encoder() const; - PKCS8_Decoder* pkcs8_decoder(RandomNumberGenerator&); - protected: - BigInt x; - private: - virtual void PKCS8_load_hook(RandomNumberGenerator&, bool = false) {} - }; - -} - -#endif diff --git a/include/dl_group.h b/include/dl_group.h deleted file mode 100644 index 5d4f46e2d..000000000 --- a/include/dl_group.h +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************* -* Discrete Logarithm Group Header File * -* (C) 1999-2008 Jack Lloyd * -*************************************************/ - -#ifndef BOTAN_DL_PARAM_H__ -#define BOTAN_DL_PARAM_H__ - -#include -#include - -namespace Botan { - -/************************************************* -* Discrete Logarithm Group * -*************************************************/ -class BOTAN_DLL DL_Group - { - public: - static SecureVector - generate_dsa_primes(RandomNumberGenerator& rng, - BigInt& p, BigInt& q, - u32bit pbits, u32bit qbits); - - static bool generate_dsa_primes(RandomNumberGenerator& rng, - BigInt& p_out, BigInt& q_out, - u32bit p_bits, u32bit q_bits, - const MemoryRegion& seed); - - const BigInt& get_p() const; - const BigInt& get_q() const; - const BigInt& get_g() const; - - enum Format { - ANSI_X9_42, - ANSI_X9_57, - PKCS_3, - - DSA_PARAMETERS = ANSI_X9_57, - DH_PARAMETERS = ANSI_X9_42, - X942_DH_PARAMETERS = ANSI_X9_42, - PKCS3_DH_PARAMETERS = PKCS_3 - }; - - enum PrimeType { Strong, Prime_Subgroup, DSA_Kosherizer }; - - bool verify_group(RandomNumberGenerator& rng, bool) const; - - std::string PEM_encode(Format) const; - SecureVector DER_encode(Format) const; - void BER_decode(DataSource&, Format); - void PEM_decode(DataSource&); - - DL_Group(); - DL_Group(const std::string&); - - DL_Group(RandomNumberGenerator& rng, PrimeType, u32bit, u32bit = 0); - DL_Group(RandomNumberGenerator& rng, const MemoryRegion&, - u32bit = 1024, u32bit = 0); - - DL_Group(const BigInt& p, const BigInt& g); - DL_Group(const BigInt& p, const BigInt& g, const BigInt& q); - private: - static BigInt make_dsa_generator(const BigInt&, const BigInt&); - - void init_check() const; - void initialize(const BigInt&, const BigInt&, const BigInt&); - bool initialized; - BigInt p, q, g; - }; - -} - -#endif diff --git a/src/dl_algo.cpp b/src/dl_algo.cpp deleted file mode 100644 index 2b59a334e..000000000 --- a/src/dl_algo.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/************************************************* -* DL Scheme Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include -#include -#include -#include - -namespace Botan { - -/************************************************* -* Return the X.509 public key encoder * -*************************************************/ -X509_Encoder* DL_Scheme_PublicKey::x509_encoder() const - { - class DL_Scheme_Encoder : public X509_Encoder - { - public: - AlgorithmIdentifier alg_id() const - { - MemoryVector group = - key->group.DER_encode(key->group_format()); - - return AlgorithmIdentifier(key->get_oid(), group); - } - - MemoryVector key_bits() const - { - return DER_Encoder().encode(key->y).get_contents(); - } - - DL_Scheme_Encoder(const DL_Scheme_PublicKey* k) : key(k) {} - private: - const DL_Scheme_PublicKey* key; - }; - - return new DL_Scheme_Encoder(this); - } - -/************************************************* -* Return the X.509 public key decoder * -*************************************************/ -X509_Decoder* DL_Scheme_PublicKey::x509_decoder() - { - class DL_Scheme_Decoder : public X509_Decoder - { - public: - void alg_id(const AlgorithmIdentifier& alg_id) - { - DataSource_Memory source(alg_id.parameters); - key->group.BER_decode(source, key->group_format()); - } - - void key_bits(const MemoryRegion& bits) - { - BER_Decoder(bits).decode(key->y); - key->X509_load_hook(); - } - - DL_Scheme_Decoder(DL_Scheme_PublicKey* k) : key(k) {} - private: - DL_Scheme_PublicKey* key; - }; - - return new DL_Scheme_Decoder(this); - } - -/************************************************* -* Return the PKCS #8 private key encoder * -*************************************************/ -PKCS8_Encoder* DL_Scheme_PrivateKey::pkcs8_encoder() const - { - class DL_Scheme_Encoder : public PKCS8_Encoder - { - public: - AlgorithmIdentifier alg_id() const - { - MemoryVector group = - key->group.DER_encode(key->group_format()); - - return AlgorithmIdentifier(key->get_oid(), group); - } - - MemoryVector key_bits() const - { - return DER_Encoder().encode(key->x).get_contents(); - } - - DL_Scheme_Encoder(const DL_Scheme_PrivateKey* k) : key(k) {} - private: - const DL_Scheme_PrivateKey* key; - }; - - return new DL_Scheme_Encoder(this); - } - -/************************************************* -* Return the PKCS #8 private key decoder * -*************************************************/ -PKCS8_Decoder* DL_Scheme_PrivateKey::pkcs8_decoder(RandomNumberGenerator& rng) - { - class DL_Scheme_Decoder : public PKCS8_Decoder - { - public: - void alg_id(const AlgorithmIdentifier& alg_id) - { - DataSource_Memory source(alg_id.parameters); - key->group.BER_decode(source, key->group_format()); - } - - void key_bits(const MemoryRegion& bits) - { - BER_Decoder(bits).decode(key->x); - key->PKCS8_load_hook(rng); - } - - DL_Scheme_Decoder(DL_Scheme_PrivateKey* k, RandomNumberGenerator& r) : - key(k), rng(r) {} - private: - DL_Scheme_PrivateKey* key; - RandomNumberGenerator& rng; - }; - - return new DL_Scheme_Decoder(this, rng); - } - -/************************************************* -* Check Public DL Parameters * -*************************************************/ -bool DL_Scheme_PublicKey::check_key(RandomNumberGenerator& rng, - bool strong) const - { - if(y < 2 || y >= group_p()) - return false; - if(!group.verify_group(rng, strong)) - return false; - return true; - } - -/************************************************* -* Check DL Scheme Private Parameters * -*************************************************/ -bool DL_Scheme_PrivateKey::check_key(RandomNumberGenerator& rng, - bool strong) const - { - const BigInt& p = group_p(); - const BigInt& g = group_g(); - - if(y < 2 || y >= p || x < 2 || x >= p) - return false; - if(!group.verify_group(rng, strong)) - return false; - - if(!strong) - return true; - - if(y != power_mod(g, x, p)) - return false; - - return true; - } - -} diff --git a/src/dl_group.cpp b/src/dl_group.cpp deleted file mode 100644 index b37bc238c..000000000 --- a/src/dl_group.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/************************************************* -* Discrete Logarithm Parameters Source File * -* (C) 1999-2008 Jack Lloyd * -*************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -/************************************************* -* DL_Group Constructor * -*************************************************/ -DL_Group::DL_Group() - { - initialized = false; - } - -/************************************************* -* DL_Group Constructor * -*************************************************/ -DL_Group::DL_Group(const std::string& type) - { - std::string grp_contents = global_state().get("dl", type); - - if(grp_contents == "") - throw Invalid_Argument("DL_Group: Unknown group " + type); - - DataSource_Memory pem(grp_contents); - PEM_decode(pem); - } - -/************************************************* -* DL_Group Constructor * -*************************************************/ -DL_Group::DL_Group(RandomNumberGenerator& rng, - PrimeType type, u32bit pbits, u32bit qbits) - { - if(pbits < 512) - throw Invalid_Argument("DL_Group: prime size " + to_string(pbits) + - " is too small"); - - if(type == Strong) - { - p = random_safe_prime(rng, pbits); - q = (p - 1) / 2; - g = 2; - } - else if(type == Prime_Subgroup || type == DSA_Kosherizer) - { - if(type == Prime_Subgroup) - { - if(!qbits) - qbits = 2 * dl_work_factor(pbits); - - q = random_prime(rng, qbits); - BigInt X; - while(p.bits() != pbits || !is_prime(p, rng)) - { - X.randomize(rng, pbits); - p = X - (X % (2*q) - 1); - } - } - else - { - qbits = qbits ? qbits : ((pbits == 1024) ? 160 : 256); - generate_dsa_primes(rng, p, q, pbits, qbits); - } - - g = make_dsa_generator(p, q); - } - - initialized = true; - } - -/************************************************* -* DL_Group Constructor * -*************************************************/ -DL_Group::DL_Group(RandomNumberGenerator& rng, - const MemoryRegion& seed, u32bit pbits, u32bit qbits) - { - if(!generate_dsa_primes(rng, p, q, pbits, qbits, seed)) - throw Invalid_Argument("DL_Group: The seed given does not " - "generate a DSA group"); - - g = make_dsa_generator(p, q); - - initialized = true; - } - -/************************************************* -* DL_Group Constructor * -*************************************************/ -DL_Group::DL_Group(const BigInt& p1, const BigInt& g1) - { - initialize(p1, 0, g1); - } - -/************************************************* -* DL_Group Constructor * -*************************************************/ -DL_Group::DL_Group(const BigInt& p1, const BigInt& q1, const BigInt& g1) - { - initialize(p1, q1, g1); - } - -/************************************************* -* DL_Group Initializer * -*************************************************/ -void DL_Group::initialize(const BigInt& p1, const BigInt& q1, const BigInt& g1) - { - if(p1 < 3) - throw Invalid_Argument("DL_Group: Prime invalid"); - if(g1 < 2 || g1 >= p1) - throw Invalid_Argument("DL_Group: Generator invalid"); - if(q1 < 0 || q1 >= p1) - throw Invalid_Argument("DL_Group: Subgroup invalid"); - - p = p1; - g = g1; - q = q1; - - initialized = true; - } - -/************************************************* -* Verify that the group has been set * -*************************************************/ -void DL_Group::init_check() const - { - if(!initialized) - throw Invalid_State("DLP group cannot be used uninitialized"); - } - -/************************************************* -* Verify the parameters * -*************************************************/ -bool DL_Group::verify_group(RandomNumberGenerator& rng, - bool strong) const - { - init_check(); - - if(g < 2 || p < 3 || q < 0) - return false; - if((q != 0) && ((p - 1) % q != 0)) - return false; - - if(!strong) - return true; - - if(!check_prime(p, rng)) - return false; - if((q > 0) && !check_prime(q, rng)) - return false; - return true; - } - -/************************************************* -* Return the prime * -*************************************************/ -const BigInt& DL_Group::get_p() const - { - init_check(); - return p; - } - -/************************************************* -* Return the generator * -*************************************************/ -const BigInt& DL_Group::get_g() const - { - init_check(); - return g; - } - -/************************************************* -* Return the subgroup * -*************************************************/ -const BigInt& DL_Group::get_q() const - { - init_check(); - if(q == 0) - throw Format_Error("DLP group has no q prime specified"); - return q; - } - -/************************************************* -* DER encode the parameters * -*************************************************/ -SecureVector DL_Group::DER_encode(Format format) const - { - init_check(); - - if((q == 0) && (format != PKCS_3)) - throw Encoding_Error("The ANSI DL parameter formats require a subgroup"); - - if(format == ANSI_X9_57) - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(p) - .encode(q) - .encode(g) - .end_cons() - .get_contents(); - } - else if(format == ANSI_X9_42) - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(p) - .encode(g) - .encode(q) - .end_cons() - .get_contents(); - } - else if(format == PKCS_3) - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(p) - .encode(g) - .end_cons() - .get_contents(); - } - - throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format)); - } - -/************************************************* -* PEM encode the parameters * -*************************************************/ -std::string DL_Group::PEM_encode(Format format) const - { - SecureVector encoding = DER_encode(format); - if(format == PKCS_3) - return PEM_Code::encode(encoding, "DH PARAMETERS"); - else if(format == ANSI_X9_57) - return PEM_Code::encode(encoding, "DSA PARAMETERS"); - else if(format == ANSI_X9_42) - return PEM_Code::encode(encoding, "X942 DH PARAMETERS"); - else - throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format)); - } - -/************************************************* -* Decode BER encoded parameters * -*************************************************/ -void DL_Group::BER_decode(DataSource& source, Format format) - { - BigInt new_p, new_q, new_g; - - BER_Decoder decoder(source); - BER_Decoder ber = decoder.start_cons(SEQUENCE); - - if(format == ANSI_X9_57) - { - ber.decode(new_p) - .decode(new_q) - .decode(new_g) - .verify_end(); - } - else if(format == ANSI_X9_42) - { - ber.decode(new_p) - .decode(new_g) - .decode(new_q) - .discard_remaining(); - } - else if(format == PKCS_3) - { - ber.decode(new_p) - .decode(new_g) - .discard_remaining(); - } - else - throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format)); - - initialize(new_p, new_q, new_g); - } - -/************************************************* -* Decode PEM encoded parameters * -*************************************************/ -void DL_Group::PEM_decode(DataSource& source) - { - std::string label; - DataSource_Memory ber(PEM_Code::decode(source, label)); - - if(label == "DH PARAMETERS") - BER_decode(ber, PKCS_3); - else if(label == "DSA PARAMETERS") - BER_decode(ber, ANSI_X9_57); - else if(label == "X942 DH PARAMETERS") - BER_decode(ber, ANSI_X9_42); - else - throw Decoding_Error("DL_Group: Invalid PEM label " + label); - } - -/************************************************* -* Create a random DSA-style generator * -*************************************************/ -BigInt DL_Group::make_dsa_generator(const BigInt& p, const BigInt& q) - { - BigInt g, e = (p - 1) / q; - - for(u32bit j = 0; j != PRIME_TABLE_SIZE; ++j) - { - g = power_mod(PRIMES[j], e, p); - if(g != 1) - break; - } - - if(g == 1) - throw Exception("DL_Group: Couldn't create a suitable generator"); - - return g; - } - -} diff --git a/src/pk/dh/modinfo.txt b/src/pk/dh/modinfo.txt index e3bbe3f32..eed21833d 100644 --- a/src/pk/dh/modinfo.txt +++ b/src/pk/dh/modinfo.txt @@ -8,3 +8,8 @@ load_on auto dh.cpp dh.h + + +asn1 +dl_algo + diff --git a/src/pk/dl_algo/dl_algo.cpp b/src/pk/dl_algo/dl_algo.cpp new file mode 100644 index 000000000..2b59a334e --- /dev/null +++ b/src/pk/dl_algo/dl_algo.cpp @@ -0,0 +1,165 @@ +/************************************************* +* DL Scheme Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +#include +#include +#include + +namespace Botan { + +/************************************************* +* Return the X.509 public key encoder * +*************************************************/ +X509_Encoder* DL_Scheme_PublicKey::x509_encoder() const + { + class DL_Scheme_Encoder : public X509_Encoder + { + public: + AlgorithmIdentifier alg_id() const + { + MemoryVector group = + key->group.DER_encode(key->group_format()); + + return AlgorithmIdentifier(key->get_oid(), group); + } + + MemoryVector key_bits() const + { + return DER_Encoder().encode(key->y).get_contents(); + } + + DL_Scheme_Encoder(const DL_Scheme_PublicKey* k) : key(k) {} + private: + const DL_Scheme_PublicKey* key; + }; + + return new DL_Scheme_Encoder(this); + } + +/************************************************* +* Return the X.509 public key decoder * +*************************************************/ +X509_Decoder* DL_Scheme_PublicKey::x509_decoder() + { + class DL_Scheme_Decoder : public X509_Decoder + { + public: + void alg_id(const AlgorithmIdentifier& alg_id) + { + DataSource_Memory source(alg_id.parameters); + key->group.BER_decode(source, key->group_format()); + } + + void key_bits(const MemoryRegion& bits) + { + BER_Decoder(bits).decode(key->y); + key->X509_load_hook(); + } + + DL_Scheme_Decoder(DL_Scheme_PublicKey* k) : key(k) {} + private: + DL_Scheme_PublicKey* key; + }; + + return new DL_Scheme_Decoder(this); + } + +/************************************************* +* Return the PKCS #8 private key encoder * +*************************************************/ +PKCS8_Encoder* DL_Scheme_PrivateKey::pkcs8_encoder() const + { + class DL_Scheme_Encoder : public PKCS8_Encoder + { + public: + AlgorithmIdentifier alg_id() const + { + MemoryVector group = + key->group.DER_encode(key->group_format()); + + return AlgorithmIdentifier(key->get_oid(), group); + } + + MemoryVector key_bits() const + { + return DER_Encoder().encode(key->x).get_contents(); + } + + DL_Scheme_Encoder(const DL_Scheme_PrivateKey* k) : key(k) {} + private: + const DL_Scheme_PrivateKey* key; + }; + + return new DL_Scheme_Encoder(this); + } + +/************************************************* +* Return the PKCS #8 private key decoder * +*************************************************/ +PKCS8_Decoder* DL_Scheme_PrivateKey::pkcs8_decoder(RandomNumberGenerator& rng) + { + class DL_Scheme_Decoder : public PKCS8_Decoder + { + public: + void alg_id(const AlgorithmIdentifier& alg_id) + { + DataSource_Memory source(alg_id.parameters); + key->group.BER_decode(source, key->group_format()); + } + + void key_bits(const MemoryRegion& bits) + { + BER_Decoder(bits).decode(key->x); + key->PKCS8_load_hook(rng); + } + + DL_Scheme_Decoder(DL_Scheme_PrivateKey* k, RandomNumberGenerator& r) : + key(k), rng(r) {} + private: + DL_Scheme_PrivateKey* key; + RandomNumberGenerator& rng; + }; + + return new DL_Scheme_Decoder(this, rng); + } + +/************************************************* +* Check Public DL Parameters * +*************************************************/ +bool DL_Scheme_PublicKey::check_key(RandomNumberGenerator& rng, + bool strong) const + { + if(y < 2 || y >= group_p()) + return false; + if(!group.verify_group(rng, strong)) + return false; + return true; + } + +/************************************************* +* Check DL Scheme Private Parameters * +*************************************************/ +bool DL_Scheme_PrivateKey::check_key(RandomNumberGenerator& rng, + bool strong) const + { + const BigInt& p = group_p(); + const BigInt& g = group_g(); + + if(y < 2 || y >= p || x < 2 || x >= p) + return false; + if(!group.verify_group(rng, strong)) + return false; + + if(!strong) + return true; + + if(y != power_mod(g, x, p)) + return false; + + return true; + } + +} diff --git a/src/pk/dl_algo/dl_algo.h b/src/pk/dl_algo/dl_algo.h new file mode 100644 index 000000000..a8d8d1d51 --- /dev/null +++ b/src/pk/dl_algo/dl_algo.h @@ -0,0 +1,61 @@ +/************************************************* +* DL Scheme Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_DL_ALGO_H__ +#define BOTAN_DL_ALGO_H__ + +#include +#include +#include +#include + +namespace Botan { + +/************************************************* +* DL Public Key * +*************************************************/ +class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key + { + public: + bool check_key(RandomNumberGenerator& rng, bool) const; + + const DL_Group& get_domain() const { return group; } + const BigInt& get_y() const { return y; } + const BigInt& group_p() const { return group.get_p(); } + const BigInt& group_q() const { return group.get_q(); } + const BigInt& group_g() const { return group.get_g(); } + virtual DL_Group::Format group_format() const = 0; + + X509_Encoder* x509_encoder() const; + X509_Decoder* x509_decoder(); + protected: + BigInt y; + DL_Group group; + private: + virtual void X509_load_hook() {} + }; + +/************************************************* +* DL Private Key * +*************************************************/ +class BOTAN_DLL DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey, + public virtual Private_Key + { + public: + bool check_key(RandomNumberGenerator& rng, bool) const; + + const BigInt& get_x() const { return x; } + + PKCS8_Encoder* pkcs8_encoder() const; + PKCS8_Decoder* pkcs8_decoder(RandomNumberGenerator&); + protected: + BigInt x; + private: + virtual void PKCS8_load_hook(RandomNumberGenerator&, bool = false) {} + }; + +} + +#endif diff --git a/src/pk/dl_group/dl_group.cpp b/src/pk/dl_group/dl_group.cpp new file mode 100644 index 000000000..b37bc238c --- /dev/null +++ b/src/pk/dl_group/dl_group.cpp @@ -0,0 +1,327 @@ +/************************************************* +* Discrete Logarithm Parameters Source File * +* (C) 1999-2008 Jack Lloyd * +*************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/************************************************* +* DL_Group Constructor * +*************************************************/ +DL_Group::DL_Group() + { + initialized = false; + } + +/************************************************* +* DL_Group Constructor * +*************************************************/ +DL_Group::DL_Group(const std::string& type) + { + std::string grp_contents = global_state().get("dl", type); + + if(grp_contents == "") + throw Invalid_Argument("DL_Group: Unknown group " + type); + + DataSource_Memory pem(grp_contents); + PEM_decode(pem); + } + +/************************************************* +* DL_Group Constructor * +*************************************************/ +DL_Group::DL_Group(RandomNumberGenerator& rng, + PrimeType type, u32bit pbits, u32bit qbits) + { + if(pbits < 512) + throw Invalid_Argument("DL_Group: prime size " + to_string(pbits) + + " is too small"); + + if(type == Strong) + { + p = random_safe_prime(rng, pbits); + q = (p - 1) / 2; + g = 2; + } + else if(type == Prime_Subgroup || type == DSA_Kosherizer) + { + if(type == Prime_Subgroup) + { + if(!qbits) + qbits = 2 * dl_work_factor(pbits); + + q = random_prime(rng, qbits); + BigInt X; + while(p.bits() != pbits || !is_prime(p, rng)) + { + X.randomize(rng, pbits); + p = X - (X % (2*q) - 1); + } + } + else + { + qbits = qbits ? qbits : ((pbits == 1024) ? 160 : 256); + generate_dsa_primes(rng, p, q, pbits, qbits); + } + + g = make_dsa_generator(p, q); + } + + initialized = true; + } + +/************************************************* +* DL_Group Constructor * +*************************************************/ +DL_Group::DL_Group(RandomNumberGenerator& rng, + const MemoryRegion& seed, u32bit pbits, u32bit qbits) + { + if(!generate_dsa_primes(rng, p, q, pbits, qbits, seed)) + throw Invalid_Argument("DL_Group: The seed given does not " + "generate a DSA group"); + + g = make_dsa_generator(p, q); + + initialized = true; + } + +/************************************************* +* DL_Group Constructor * +*************************************************/ +DL_Group::DL_Group(const BigInt& p1, const BigInt& g1) + { + initialize(p1, 0, g1); + } + +/************************************************* +* DL_Group Constructor * +*************************************************/ +DL_Group::DL_Group(const BigInt& p1, const BigInt& q1, const BigInt& g1) + { + initialize(p1, q1, g1); + } + +/************************************************* +* DL_Group Initializer * +*************************************************/ +void DL_Group::initialize(const BigInt& p1, const BigInt& q1, const BigInt& g1) + { + if(p1 < 3) + throw Invalid_Argument("DL_Group: Prime invalid"); + if(g1 < 2 || g1 >= p1) + throw Invalid_Argument("DL_Group: Generator invalid"); + if(q1 < 0 || q1 >= p1) + throw Invalid_Argument("DL_Group: Subgroup invalid"); + + p = p1; + g = g1; + q = q1; + + initialized = true; + } + +/************************************************* +* Verify that the group has been set * +*************************************************/ +void DL_Group::init_check() const + { + if(!initialized) + throw Invalid_State("DLP group cannot be used uninitialized"); + } + +/************************************************* +* Verify the parameters * +*************************************************/ +bool DL_Group::verify_group(RandomNumberGenerator& rng, + bool strong) const + { + init_check(); + + if(g < 2 || p < 3 || q < 0) + return false; + if((q != 0) && ((p - 1) % q != 0)) + return false; + + if(!strong) + return true; + + if(!check_prime(p, rng)) + return false; + if((q > 0) && !check_prime(q, rng)) + return false; + return true; + } + +/************************************************* +* Return the prime * +*************************************************/ +const BigInt& DL_Group::get_p() const + { + init_check(); + return p; + } + +/************************************************* +* Return the generator * +*************************************************/ +const BigInt& DL_Group::get_g() const + { + init_check(); + return g; + } + +/************************************************* +* Return the subgroup * +*************************************************/ +const BigInt& DL_Group::get_q() const + { + init_check(); + if(q == 0) + throw Format_Error("DLP group has no q prime specified"); + return q; + } + +/************************************************* +* DER encode the parameters * +*************************************************/ +SecureVector DL_Group::DER_encode(Format format) const + { + init_check(); + + if((q == 0) && (format != PKCS_3)) + throw Encoding_Error("The ANSI DL parameter formats require a subgroup"); + + if(format == ANSI_X9_57) + { + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(p) + .encode(q) + .encode(g) + .end_cons() + .get_contents(); + } + else if(format == ANSI_X9_42) + { + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(p) + .encode(g) + .encode(q) + .end_cons() + .get_contents(); + } + else if(format == PKCS_3) + { + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(p) + .encode(g) + .end_cons() + .get_contents(); + } + + throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format)); + } + +/************************************************* +* PEM encode the parameters * +*************************************************/ +std::string DL_Group::PEM_encode(Format format) const + { + SecureVector encoding = DER_encode(format); + if(format == PKCS_3) + return PEM_Code::encode(encoding, "DH PARAMETERS"); + else if(format == ANSI_X9_57) + return PEM_Code::encode(encoding, "DSA PARAMETERS"); + else if(format == ANSI_X9_42) + return PEM_Code::encode(encoding, "X942 DH PARAMETERS"); + else + throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format)); + } + +/************************************************* +* Decode BER encoded parameters * +*************************************************/ +void DL_Group::BER_decode(DataSource& source, Format format) + { + BigInt new_p, new_q, new_g; + + BER_Decoder decoder(source); + BER_Decoder ber = decoder.start_cons(SEQUENCE); + + if(format == ANSI_X9_57) + { + ber.decode(new_p) + .decode(new_q) + .decode(new_g) + .verify_end(); + } + else if(format == ANSI_X9_42) + { + ber.decode(new_p) + .decode(new_g) + .decode(new_q) + .discard_remaining(); + } + else if(format == PKCS_3) + { + ber.decode(new_p) + .decode(new_g) + .discard_remaining(); + } + else + throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format)); + + initialize(new_p, new_q, new_g); + } + +/************************************************* +* Decode PEM encoded parameters * +*************************************************/ +void DL_Group::PEM_decode(DataSource& source) + { + std::string label; + DataSource_Memory ber(PEM_Code::decode(source, label)); + + if(label == "DH PARAMETERS") + BER_decode(ber, PKCS_3); + else if(label == "DSA PARAMETERS") + BER_decode(ber, ANSI_X9_57); + else if(label == "X942 DH PARAMETERS") + BER_decode(ber, ANSI_X9_42); + else + throw Decoding_Error("DL_Group: Invalid PEM label " + label); + } + +/************************************************* +* Create a random DSA-style generator * +*************************************************/ +BigInt DL_Group::make_dsa_generator(const BigInt& p, const BigInt& q) + { + BigInt g, e = (p - 1) / q; + + for(u32bit j = 0; j != PRIME_TABLE_SIZE; ++j) + { + g = power_mod(PRIMES[j], e, p); + if(g != 1) + break; + } + + if(g == 1) + throw Exception("DL_Group: Couldn't create a suitable generator"); + + return g; + } + +} diff --git a/src/pk/dl_group/dl_group.h b/src/pk/dl_group/dl_group.h new file mode 100644 index 000000000..5d4f46e2d --- /dev/null +++ b/src/pk/dl_group/dl_group.h @@ -0,0 +1,74 @@ +/************************************************* +* Discrete Logarithm Group Header File * +* (C) 1999-2008 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_DL_PARAM_H__ +#define BOTAN_DL_PARAM_H__ + +#include +#include + +namespace Botan { + +/************************************************* +* Discrete Logarithm Group * +*************************************************/ +class BOTAN_DLL DL_Group + { + public: + static SecureVector + generate_dsa_primes(RandomNumberGenerator& rng, + BigInt& p, BigInt& q, + u32bit pbits, u32bit qbits); + + static bool generate_dsa_primes(RandomNumberGenerator& rng, + BigInt& p_out, BigInt& q_out, + u32bit p_bits, u32bit q_bits, + const MemoryRegion& seed); + + const BigInt& get_p() const; + const BigInt& get_q() const; + const BigInt& get_g() const; + + enum Format { + ANSI_X9_42, + ANSI_X9_57, + PKCS_3, + + DSA_PARAMETERS = ANSI_X9_57, + DH_PARAMETERS = ANSI_X9_42, + X942_DH_PARAMETERS = ANSI_X9_42, + PKCS3_DH_PARAMETERS = PKCS_3 + }; + + enum PrimeType { Strong, Prime_Subgroup, DSA_Kosherizer }; + + bool verify_group(RandomNumberGenerator& rng, bool) const; + + std::string PEM_encode(Format) const; + SecureVector DER_encode(Format) const; + void BER_decode(DataSource&, Format); + void PEM_decode(DataSource&); + + DL_Group(); + DL_Group(const std::string&); + + DL_Group(RandomNumberGenerator& rng, PrimeType, u32bit, u32bit = 0); + DL_Group(RandomNumberGenerator& rng, const MemoryRegion&, + u32bit = 1024, u32bit = 0); + + DL_Group(const BigInt& p, const BigInt& g); + DL_Group(const BigInt& p, const BigInt& g, const BigInt& q); + private: + static BigInt make_dsa_generator(const BigInt&, const BigInt&); + + void init_check() const; + void initialize(const BigInt&, const BigInt&, const BigInt&); + bool initialized; + BigInt p, q, g; + }; + +} + +#endif diff --git a/src/pk/dsa/modinfo.txt b/src/pk/dsa/modinfo.txt index 77bb48396..503d9f23a 100644 --- a/src/pk/dsa/modinfo.txt +++ b/src/pk/dsa/modinfo.txt @@ -8,3 +8,8 @@ load_on auto dsa.cpp dsa.h + + +asn1 +dl_algo + diff --git a/src/pk/nr/modinfo.txt b/src/pk/nr/modinfo.txt index 4cb1b1bf5..c54631f16 100644 --- a/src/pk/nr/modinfo.txt +++ b/src/pk/nr/modinfo.txt @@ -8,3 +8,8 @@ load_on auto nr.cpp nr.h + + +asn1 +dl_algo + diff --git a/src/pk/rsa/modinfo.txt b/src/pk/rsa/modinfo.txt index 8125d7efb..041c01ca9 100644 --- a/src/pk/rsa/modinfo.txt +++ b/src/pk/rsa/modinfo.txt @@ -10,5 +10,6 @@ rsa.h +asn1 if_algo diff --git a/src/pk/rw/modinfo.txt b/src/pk/rw/modinfo.txt index dee83c95d..f9989b3b8 100644 --- a/src/pk/rw/modinfo.txt +++ b/src/pk/rw/modinfo.txt @@ -10,5 +10,6 @@ rw.h +asn1 if_algo -- cgit v1.2.3