diff options
Diffstat (limited to 'src/pubkey')
-rw-r--r-- | src/pubkey/ec_dompar/ec_dompar.h | 2 | ||||
-rw-r--r-- | src/pubkey/ecc_key/ecc_key.cpp | 117 | ||||
-rw-r--r-- | src/pubkey/ecc_key/ecc_key.h | 50 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa.cpp | 146 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa.h | 34 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa_core.cpp | 14 | ||||
-rw-r--r-- | src/pubkey/eckaeg/eckaeg.cpp | 109 | ||||
-rw-r--r-- | src/pubkey/eckaeg/eckaeg.h | 53 | ||||
-rw-r--r-- | src/pubkey/eckaeg/eckaeg_core.cpp | 5 | ||||
-rw-r--r-- | src/pubkey/gost_3410/gost_3410.cpp | 158 | ||||
-rw-r--r-- | src/pubkey/gost_3410/gost_3410.h | 34 |
11 files changed, 136 insertions, 586 deletions
diff --git a/src/pubkey/ec_dompar/ec_dompar.h b/src/pubkey/ec_dompar/ec_dompar.h index 6789976d0..7da2120cc 100644 --- a/src/pubkey/ec_dompar/ec_dompar.h +++ b/src/pubkey/ec_dompar/ec_dompar.h @@ -102,6 +102,8 @@ class BOTAN_DLL EC_Domain_Params */ const BigInt& get_cofactor() const { return cofactor; } + bool initialized() const { return !base_point.is_zero(); } + /** * Return the OID of these domain parameters * @result the OID diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp index c14617cfe..8273256cf 100644 --- a/src/pubkey/ecc_key/ecc_key.cpp +++ b/src/pubkey/ecc_key/ecc_key.cpp @@ -2,7 +2,7 @@ * ECC Key implemenation * (C) 2007 Manuel Hartl, FlexSecure GmbH * Falko Strenzke, FlexSecure GmbH -* 2008 Jack Lloyd +* 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -17,48 +17,15 @@ namespace Botan { -/* -* EC_PublicKey -*/ -void EC_PublicKey::affirm_init() const // virtual - { - if((mp_dom_pars.get() == 0) || (mp_public_point.get() == 0)) - throw Invalid_State("cannot use uninitialized EC_Key"); - } - -const EC_Domain_Params& EC_PublicKey::domain_parameters() const - { - if(!mp_dom_pars.get()) - throw Invalid_State("EC_PublicKey::domain_parameters(): " - "ec domain parameters are not yet set"); - - return *mp_dom_pars; - } - -const PointGFp& EC_PublicKey::public_point() const - { - if(!mp_public_point.get()) - throw Invalid_State("EC_PublicKey::public_point(): public point not set"); - - return *mp_public_point; - } - -bool EC_PublicKey::domain_parameters_set() - { - return mp_dom_pars.get(); - } - void EC_PublicKey::X509_load_hook() { try { - // the base point is checked to be on curve already when decoding it - affirm_init(); - mp_public_point->check_invariants(); + public_point().check_invariants(); } catch(Illegal_Point) { - throw Decoding_Error("decoded public point was found not to lie on curve"); + throw Decoding_Error("Invalid public point; not on curve"); } } @@ -69,16 +36,13 @@ X509_Encoder* EC_PublicKey::x509_encoder() const public: AlgorithmIdentifier alg_id() const { - key->affirm_init(); - return AlgorithmIdentifier(key->get_oid(), - key->domain_parameters().DER_encode(key->m_param_enc)); + key->domain().DER_encode(key->domain_format())); } MemoryVector<byte> key_bits() const { - key->affirm_init(); - return EC2OSP(*(key->mp_public_point), PointGFp::COMPRESSED); + return EC2OSP(key->public_point(), PointGFp::COMPRESSED); } EC_Key_Encoder(const EC_PublicKey* k): key(k) {} @@ -96,15 +60,13 @@ X509_Decoder* EC_PublicKey::x509_decoder() public: void alg_id(const AlgorithmIdentifier& alg_id) { - key->mp_dom_pars.reset(new EC_Domain_Params(alg_id.parameters)); + key->domain_params = EC_Domain_Params(alg_id.parameters); } void key_bits(const MemoryRegion<byte>& bits) { - key->mp_public_point.reset( - new PointGFp( - OS2ECP(bits, key->domain_parameters().get_curve()) - )); + key->public_key = PointGFp( + OS2ECP(bits, key->domain().get_curve())); key->X509_load_hook(); } @@ -124,33 +86,20 @@ void EC_PublicKey::set_parameter_encoding(EC_Domain_Params_Encoding form) form != EC_DOMPAR_ENC_OID) throw Invalid_Argument("Invalid encoding form for EC-key object specified"); - affirm_init(); - - if((form == EC_DOMPAR_ENC_OID) && (mp_dom_pars->get_oid() == "")) + if((form == EC_DOMPAR_ENC_OID) && (domain_params.get_oid() == "")) throw Invalid_Argument("Invalid encoding form OID specified for " "EC-key object whose corresponding domain " "parameters are without oid"); - m_param_enc = form; - } - -/* -* EC_PrivateKey -*/ -void EC_PrivateKey::affirm_init() const // virtual - { - if(m_private_value == 0) - throw Invalid_State("cannot use EC_PrivateKey when private key is uninitialized"); - - EC_PublicKey::affirm_init(); + domain_encoding = form; } const BigInt& EC_PrivateKey::private_value() const { - if(m_private_value == 0) + if(private_key == 0) throw Invalid_State("cannot use EC_PrivateKey when private key is uninitialized"); - return m_private_value; + return private_key; } /** @@ -158,16 +107,20 @@ const BigInt& EC_PrivateKey::private_value() const **/ void EC_PrivateKey::generate_private_key(RandomNumberGenerator& rng) { - if(mp_dom_pars.get() == 0) - { - throw Invalid_State("cannot generate private key when domain parameters are not set"); - } + if(!domain().initialized()) + throw Invalid_State("Cannot generate new EC key, domain unset"); - m_private_value = BigInt::random_integer(rng, 1, mp_dom_pars->get_order()); + private_key = BigInt::random_integer(rng, 1, domain().get_order()); + public_key = domain().get_base_point() * private_key; - mp_public_point = std::auto_ptr<PointGFp>( new PointGFp (mp_dom_pars->get_base_point())); - - *mp_public_point *= m_private_value; + try + { + public_key.check_invariants(); + } + catch(Illegal_Point& e) + { + throw Invalid_State(algo_name() + " key generation failed"); + } } /** @@ -180,22 +133,17 @@ PKCS8_Encoder* EC_PrivateKey::pkcs8_encoder() const public: AlgorithmIdentifier alg_id() const { - key->affirm_init(); - return AlgorithmIdentifier(key->get_oid(), - key->domain_parameters().DER_encode(EC_DOMPAR_ENC_EXPLICIT)); + key->domain().DER_encode(EC_DOMPAR_ENC_EXPLICIT)); } MemoryVector<byte> key_bits() const { - key->affirm_init(); - SecureVector<byte> octstr_secret = - BigInt::encode_1363(key->m_private_value, key->m_private_value.bytes()); - return DER_Encoder() .start_cons(SEQUENCE) .encode(BigInt(1)) - .encode(octstr_secret, OCTET_STRING) + .encode(BigInt::encode_1363(key->private_key, key->private_key.bytes()), + OCTET_STRING) .end_cons() .get_contents(); } @@ -218,7 +166,7 @@ PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&) public: void alg_id(const AlgorithmIdentifier& alg_id) { - key->mp_dom_pars.reset(new EC_Domain_Params(alg_id.parameters)); + key->domain_params = EC_Domain_Params(alg_id.parameters); } void key_bits(const MemoryRegion<byte>& bits) @@ -233,7 +181,7 @@ PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&) .verify_end() .end_cons(); - key->m_private_value = BigInt::decode(octstr_secret, octstr_secret.size()); + key->private_key = BigInt::decode(octstr_secret, octstr_secret.size()); if(version != 1) throw Decoding_Error("Wrong PKCS #1 key format version for EC key"); @@ -251,12 +199,7 @@ PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&) void EC_PrivateKey::PKCS8_load_hook(bool) { - // we cannot use affirm_init() here because mp_public_point might still be null - if(mp_dom_pars.get() == 0) - throw Invalid_State("attempt to set public point for an uninitialized key"); - - mp_public_point.reset(new PointGFp(m_private_value * mp_dom_pars->get_base_point())); - mp_public_point->check_invariants(); + public_key = domain().get_base_point() * private_key; } } diff --git a/src/pubkey/ecc_key/ecc_key.h b/src/pubkey/ecc_key/ecc_key.h index f61e4a2dc..073597bc9 100644 --- a/src/pubkey/ecc_key/ecc_key.h +++ b/src/pubkey/ecc_key/ecc_key.h @@ -2,7 +2,7 @@ * ECDSA * (C) 2007 Falko Strenzke, FlexSecure GmbH * Manuel Hartl, FlexSecure GmbH -* (C) 2008 Jack Lloyd +* (C) 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -33,18 +33,12 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key public: /** - * Tells whether this key knows his own domain parameters. - * @result true if the domain parameters are set, false otherwise - */ - bool domain_parameters_set(); - - /** * Get the public point of this key. * @throw Invalid_State is thrown if the * domain parameters of this point are not set * @result the public point of this key */ - const PointGFp& public_point() const; + const PointGFp& public_point() const { return public_key; } /** * Get the domain parameters of this key. @@ -52,7 +46,7 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key * domain parameters of this point are not set * @result the domain parameters of this key */ - const EC_Domain_Params& domain_parameters() const; + const EC_Domain_Params& domain() const { return domain_params; } /** * Set the domain parameter encoding to be used when encoding this key. @@ -64,18 +58,7 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key * Get the domain parameter encoding to be used when encoding this key. * @result the encoding to use */ - inline int get_parameter_encoding() const - { - return m_param_enc; - } - - //ctors - EC_PublicKey() - : m_param_enc(EC_DOMPAR_ENC_EXPLICIT) - { - //assert(mp_dom_pars.get() == 0); - //assert(mp_public_point.get() == 0); - } + EC_Domain_Params_Encoding domain_format() const { return domain_encoding; } /** * Get an x509_encoder that can be used to encode this key. @@ -90,19 +73,14 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key */ X509_Decoder* x509_decoder(); - /** - * Make sure that the public point and domain parameters of this key are set. - * @throw Invalid_State if either of the two data members is not set - */ - virtual void affirm_init() const; - + EC_PublicKey() : domain_encoding(EC_DOMPAR_ENC_EXPLICIT) {} virtual ~EC_PublicKey() {} protected: virtual void X509_load_hook(); - std::auto_ptr<EC_Domain_Params> mp_dom_pars; - std::auto_ptr<PointGFp> mp_public_point; - EC_Domain_Params_Encoding m_param_enc; + EC_Domain_Params domain_params; + PointGFp public_key; + EC_Domain_Params_Encoding domain_encoding; }; /** @@ -131,19 +109,13 @@ class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey, public virtual Priv */ const BigInt& private_value() const; - /** - * Make sure that the public key parts of this object are set - * (calls EC_PublicKey::affirm_init()) as well as the private key - * value. - * @throw Invalid_State if the above conditions are not satisfied - */ - virtual void affirm_init() const; - virtual ~EC_PrivateKey() {} protected: virtual void PKCS8_load_hook(bool = false); + void generate_private_key(RandomNumberGenerator&); - BigInt m_private_value; + + BigInt private_key; }; } diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp index 462f0cd0c..7afbf96af 100644 --- a/src/pubkey/ecdsa/ecdsa.cpp +++ b/src/pubkey/ecdsa/ecdsa.cpp @@ -2,185 +2,91 @@ * ECDSA implemenation * (C) 2007 Manuel Hartl, FlexSecure GmbH * 2007 Falko Strenzke, FlexSecure GmbH -* 2008 Jack Lloyd +* 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ #include <botan/ecdsa.h> -#include <botan/numthry.h> -#include <botan/der_enc.h> -#include <botan/ber_dec.h> -#include <botan/secmem.h> -#include <botan/point_gfp.h> + +#include <assert.h> namespace Botan { ECDSA_PrivateKey::ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Domain_Params& dom_pars) { - mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_pars)); + domain_params = dom_pars; generate_private_key(rng); - try - { - mp_public_point->check_invariants(); - } - catch(Illegal_Point& e) - { - throw Invalid_State("ECDSA key generation failed"); - } - - m_ecdsa_core = ECDSA_Core(*mp_dom_pars, m_private_value, *mp_public_point); + ecdsa_core = ECDSA_Core(domain(), private_value(), public_point()); } -ECDSA_PrivateKey::ECDSA_PrivateKey(const EC_Domain_Params& domain, +ECDSA_PrivateKey::ECDSA_PrivateKey(const EC_Domain_Params& dom_pars, const BigInt& x) { - mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(domain)); - - m_private_value = x; - mp_public_point = std::auto_ptr<PointGFp>(new PointGFp (mp_dom_pars->get_base_point())); + domain_params = dom_pars; - *mp_public_point *= m_private_value; + private_key = x; + public_key = domain().get_base_point() * x; try { - mp_public_point->check_invariants(); + public_key.check_invariants(); } catch(Illegal_Point& e) { throw Invalid_State("ECDSA key generation failed"); } - m_ecdsa_core = ECDSA_Core(*mp_dom_pars, m_private_value, *mp_public_point); - } - -/* -* ECDSA_PublicKey -*/ -void ECDSA_PublicKey::affirm_init() const // virtual - { - EC_PublicKey::affirm_init(); - } - -void ECDSA_PublicKey::set_all_values(const ECDSA_PublicKey& other) - { - m_param_enc = other.m_param_enc; - m_ecdsa_core = other.m_ecdsa_core; - if(other.mp_dom_pars.get()) - mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); - - if(other.mp_public_point.get()) - mp_public_point.reset(new PointGFp(other.public_point())); - } - -ECDSA_PublicKey::ECDSA_PublicKey(const ECDSA_PublicKey& other) - : Public_Key(), - EC_PublicKey(), - PK_Verifying_wo_MR_Key() - { - set_all_values(other); - } - -const ECDSA_PublicKey& ECDSA_PublicKey::operator=(const ECDSA_PublicKey& rhs) - { - set_all_values(rhs); - return *this; + ecdsa_core = ECDSA_Core(domain(), private_value(), public_point()); } bool ECDSA_PublicKey::verify(const byte msg[], u32bit msg_len, const byte sig[], u32bit sig_len) const { - affirm_init(); - - return m_ecdsa_core.verify(msg, msg_len, sig, sig_len); + return ecdsa_core.verify(msg, msg_len, sig, sig_len); } ECDSA_PublicKey::ECDSA_PublicKey(const EC_Domain_Params& dom_par, - const PointGFp& public_point) + const PointGFp& pub_point) { - mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_par)); - mp_public_point = std::auto_ptr<PointGFp>(new PointGFp(public_point)); - m_param_enc = EC_DOMPAR_ENC_EXPLICIT; - m_ecdsa_core = ECDSA_Core(*mp_dom_pars, BigInt(0), *mp_public_point); + domain_encoding = EC_DOMPAR_ENC_EXPLICIT; + domain_params = dom_par; + public_key = pub_point; + + ecdsa_core = ECDSA_Core(domain(), 0, public_point()); } void ECDSA_PublicKey::X509_load_hook() { EC_PublicKey::X509_load_hook(); - EC_PublicKey::affirm_init(); - m_ecdsa_core = ECDSA_Core ( *mp_dom_pars, BigInt ( 0 ), *mp_public_point ); - } - -u32bit ECDSA_PublicKey::max_input_bits() const - { - if(!mp_dom_pars.get()) - { - throw Invalid_State("ECDSA_PublicKey::max_input_bits(): domain parameters not set"); - } - return mp_dom_pars->get_order().bits(); - } - -/* -* ECDSA_PrivateKey -*/ -void ECDSA_PrivateKey::affirm_init() const // virtual - { - EC_PrivateKey::affirm_init(); + ecdsa_core = ECDSA_Core(domain(), 0, public_point()); } void ECDSA_PrivateKey::PKCS8_load_hook(bool generated) { EC_PrivateKey::PKCS8_load_hook(generated); - EC_PrivateKey::affirm_init(); - m_ecdsa_core = ECDSA_Core(*mp_dom_pars, m_private_value, *mp_public_point); - } - -void ECDSA_PrivateKey::set_all_values(const ECDSA_PrivateKey& other) - { - m_private_value = other.m_private_value; - m_param_enc = other.m_param_enc; - m_ecdsa_core = other.m_ecdsa_core; - - if(other.mp_dom_pars.get()) - mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); - - if(other.mp_public_point.get()) - mp_public_point.reset(new PointGFp(other.public_point())); - } - -ECDSA_PrivateKey::ECDSA_PrivateKey(ECDSA_PrivateKey const& other) - : Public_Key(), - EC_PublicKey(), - Private_Key(), - ECDSA_PublicKey(), - EC_PrivateKey(), - PK_Signing_Key() - { - set_all_values(other); - } - -const ECDSA_PrivateKey& ECDSA_PrivateKey::operator=(const ECDSA_PrivateKey& rhs) - { - set_all_values(rhs); - return *this; + ecdsa_core = ECDSA_Core(domain(), private_value(), public_point()); } SecureVector<byte> ECDSA_PrivateKey::sign(const byte msg[], u32bit msg_len, RandomNumberGenerator& rng) const { - affirm_init(); + const BigInt& n = domain().get_order(); + + if(n == 0) + throw Invalid_State("ECDSA_PrivateKey: Not initialized"); - const BigInt& n = mp_dom_pars->get_order(); + assert(n.bits() >= 1); BigInt k; do k.randomize(rng, n.bits()-1); while(k >= n); - return m_ecdsa_core.sign(msg, msg_len, k); + return ecdsa_core.sign(msg, msg_len, k); } } diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h index f6ac8a0d7..bc767d8ad 100644 --- a/src/pubkey/ecdsa/ecdsa.h +++ b/src/pubkey/ecdsa/ecdsa.h @@ -2,7 +2,7 @@ * ECDSA * (C) 2007 Falko Strenzke, FlexSecure GmbH * Manuel Hartl, FlexSecure GmbH -* (C) 2008 Jack Lloyd +* (C) 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -32,15 +32,14 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey, /** * Get the maximum number of bits allowed to be fed to this key. * This is the bitlength of the order of the base point. - * @result the maximum number of input bits */ - u32bit max_input_bits() const; + u32bit max_input_bits() const { return domain().get_order().bits(); } u32bit message_parts() const { return 2; } u32bit message_part_size() const - { return mp_dom_pars->get_order().bytes(); } + { return domain().get_order().bytes(); } /** * Verify a message with this key. @@ -66,21 +65,10 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey, ECDSA_PublicKey(const EC_Domain_Params& dom_par, const PointGFp& public_point); // sets core - ECDSA_PublicKey const& operator=(const ECDSA_PublicKey& rhs); - - ECDSA_PublicKey(const ECDSA_PublicKey& other); - - /** - * Ensure that the public point and domain parameters of this key are set. - * @throw Invalid_State if either of the two data members is not set - */ - virtual void affirm_init() const; - protected: void X509_load_hook(); - void set_all_values(const ECDSA_PublicKey& other); - ECDSA_Core m_ecdsa_core; + ECDSA_Core ecdsa_core; }; /** @@ -91,8 +79,6 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, public PK_Signing_Key { public: - //ctors - /** * Default constructor. Use this one if you want to later fill * this object with data from an encoded key. @@ -113,9 +99,6 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, */ ECDSA_PrivateKey(const EC_Domain_Params& domain, const BigInt& x); - ECDSA_PrivateKey(const ECDSA_PrivateKey& other); - ECDSA_PrivateKey const& operator=(const ECDSA_PrivateKey& rhs); - /** * Sign a message with this key. * @param message the byte array representing the message to be signed @@ -126,16 +109,7 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, SecureVector<byte> sign(const byte message[], u32bit mess_len, RandomNumberGenerator& rng) const; - /** - * Make sure that the public key parts of this object are set - * (calls EC_PublicKey::affirm_init()) as well as the private key - * value. - * @throw Invalid_State if the above conditions are not satisfied - */ - virtual void affirm_init() const; - private: - void set_all_values(const ECDSA_PrivateKey& other); void PKCS8_load_hook(bool = false); }; diff --git a/src/pubkey/ecdsa/ecdsa_core.cpp b/src/pubkey/ecdsa/ecdsa_core.cpp index 78b527786..d661963f2 100644 --- a/src/pubkey/ecdsa/ecdsa_core.cpp +++ b/src/pubkey/ecdsa/ecdsa_core.cpp @@ -1,6 +1,6 @@ /* * ECDSA Core -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2010 Jack Lloyd * (C) 2007 FlexSecure GmbH * * Distributed under the terms of the Botan license @@ -17,7 +17,9 @@ namespace Botan { bool ECDSA_Core::verify(const byte signature[], u32bit sig_len, const byte message[], u32bit mess_len) const { - //assert(op.get()); + if(op == 0) + throw Invalid_State("ECDSA_Core: uninitialized"); + return op->verify(signature, sig_len, message, mess_len); } @@ -25,7 +27,9 @@ SecureVector<byte> ECDSA_Core::sign(const byte message[], u32bit mess_len, const BigInt& k) const { - //assert(op.get()); + if(op == 0) + throw Invalid_State("ECDSA_Core: uninitialized"); + return op->sign(message, mess_len, k); } @@ -44,7 +48,9 @@ ECDSA_Core::ECDSA_Core(const ECDSA_Core& core) op = core.op->clone(); } -ECDSA_Core::ECDSA_Core(EC_Domain_Params const& dom_pars, const BigInt& priv_key, PointGFp const& pub_key) +ECDSA_Core::ECDSA_Core(const EC_Domain_Params& dom_pars, + const BigInt& priv_key, + const PointGFp& pub_key) { op = Engine_Core::ecdsa_op(dom_pars, priv_key, pub_key); } diff --git a/src/pubkey/eckaeg/eckaeg.cpp b/src/pubkey/eckaeg/eckaeg.cpp index fe47e3c31..639060f33 100644 --- a/src/pubkey/eckaeg/eckaeg.cpp +++ b/src/pubkey/eckaeg/eckaeg.cpp @@ -16,113 +16,41 @@ namespace Botan { -/* -* ECKAEG_PublicKey -*/ - -void ECKAEG_PublicKey::affirm_init() const // virtual - { - EC_PublicKey::affirm_init(); - } - -void ECKAEG_PublicKey::set_all_values(ECKAEG_PublicKey const& other) - { - m_param_enc = other.m_param_enc; - m_eckaeg_core = other.m_eckaeg_core; - - if(other.mp_dom_pars.get()) - { - mp_dom_pars.reset(new EC_Domain_Params(*(other.mp_dom_pars))); - } - if(other.mp_public_point.get()) - { - mp_public_point.reset(new PointGFp(*(other.mp_public_point))); - } - } - -ECKAEG_PublicKey::ECKAEG_PublicKey(ECKAEG_PublicKey const& other) - : Public_Key(), - EC_PublicKey() - { - set_all_values(other); - } - -ECKAEG_PublicKey const& ECKAEG_PublicKey::operator=(ECKAEG_PublicKey const& rhs) - { - set_all_values(rhs); - return *this; - } - void ECKAEG_PublicKey::X509_load_hook() { EC_PublicKey::X509_load_hook(); - EC_PublicKey::affirm_init(); - m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, BigInt(0), *mp_public_point); + m_eckaeg_core = ECKAEG_Core(domain(), 0, public_point()); } -ECKAEG_PublicKey::ECKAEG_PublicKey(EC_Domain_Params const& dom_par, PointGFp const& public_point) +ECKAEG_PublicKey::ECKAEG_PublicKey(const EC_Domain_Params& dom_par, + const PointGFp& pub_point) { - mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_par)); - mp_public_point = std::auto_ptr<PointGFp>(new PointGFp(public_point)); - if(mp_public_point->get_curve() != mp_dom_pars->get_curve()) - { - throw Invalid_Argument("ECKAEG_PublicKey(): curve of arg. point and curve of arg. domain parameters are different"); - } - EC_PublicKey::affirm_init(); - m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, BigInt(0), *mp_public_point); - } + domain_params = dom_par; + public_key = pub_point; -/* -* ECKAEG_PrivateKey -*/ -void ECKAEG_PrivateKey::affirm_init() const // virtual - { - EC_PrivateKey::affirm_init(); + if(domain().get_curve() != pub_point.get_curve()) + throw Invalid_Argument("ECKAEG_PublicKey: curve mismatch in constructor"); + + m_eckaeg_core = ECKAEG_Core(domain(), 0, public_point()); } void ECKAEG_PrivateKey::PKCS8_load_hook(bool generated) { EC_PrivateKey::PKCS8_load_hook(generated); - EC_PrivateKey::affirm_init(); - m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, m_private_value, *mp_public_point); - } - -void ECKAEG_PrivateKey::set_all_values(ECKAEG_PrivateKey const& other) - { - m_private_value = other.m_private_value; - m_param_enc = other.m_param_enc; - m_eckaeg_core = other.m_eckaeg_core; - - if(other.mp_dom_pars.get()) - { - mp_dom_pars.reset(new EC_Domain_Params(*(other.mp_dom_pars))); - } - if(other.mp_public_point.get()) - { - mp_public_point.reset(new PointGFp(*(other.mp_public_point))); - } + m_eckaeg_core = ECKAEG_Core(domain(), private_value(), public_point()); } -ECKAEG_PrivateKey::ECKAEG_PrivateKey(ECKAEG_PrivateKey const& other) - : Public_Key(), - EC_PublicKey(), - Private_Key(), - ECKAEG_PublicKey(), - EC_PrivateKey(), - PK_Key_Agreement_Key() - { - set_all_values(other); - } - -ECKAEG_PrivateKey const& ECKAEG_PrivateKey::operator= (ECKAEG_PrivateKey const& rhs) +MemoryVector<byte> ECKAEG_PrivateKey::public_value() const { - set_all_values(rhs); - return *this; + return EC2OSP(public_point(), PointGFp::UNCOMPRESSED); } -MemoryVector<byte> ECKAEG_PrivateKey::public_value() const +ECKAEG_PrivateKey::ECKAEG_PrivateKey(RandomNumberGenerator& rng, + const EC_Domain_Params& dom_pars) { - return EC2OSP(public_point(), PointGFp::UNCOMPRESSED); + domain_params = dom_pars; + generate_private_key(rng); + m_eckaeg_core = ECKAEG_Core(domain(), private_value(), public_point()); } /** @@ -142,9 +70,6 @@ SecureVector<byte> ECKAEG_PrivateKey::derive_key(const byte key[], */ SecureVector<byte> ECKAEG_PrivateKey::derive_key(const ECKAEG_PublicKey& key) const { - affirm_init(); - key.affirm_init(); - return m_eckaeg_core.agree(key.public_point()); } diff --git a/src/pubkey/eckaeg/eckaeg.h b/src/pubkey/eckaeg/eckaeg.h index 7c4dfdb2d..fbd263e82 100644 --- a/src/pubkey/eckaeg/eckaeg.h +++ b/src/pubkey/eckaeg/eckaeg.h @@ -23,6 +23,12 @@ class BOTAN_DLL ECKAEG_PublicKey : public virtual EC_PublicKey public: /** + * Get this keys algorithm name. + * @result this keys algorithm name + */ + std::string algo_name() const { return "ECKAEG"; } + + /** * Default constructor. Use this one if you want to later fill * this object with data from an encoded key. */ @@ -37,41 +43,17 @@ class BOTAN_DLL ECKAEG_PublicKey : public virtual EC_PublicKey const PointGFp& public_point); /** - * Get this keys algorithm name. - * @result this keys algorithm name - */ - std::string algo_name() const { return "ECKAEG"; } - - /** * Get the maximum number of bits allowed to be fed to this key. * This is the bitlength of the order of the base point. * @result the maximum number of input bits */ - u32bit max_input_bits() const - { - if(!mp_dom_pars.get()) - throw Invalid_State("ECKAEG_PublicKey::max_input_bits(): domain parameters not set"); - - return mp_dom_pars->get_order().bits(); - } - - ECKAEG_PublicKey(ECKAEG_PublicKey const& other); - ECKAEG_PublicKey const& operator= (ECKAEG_PublicKey const& rhs); - - /** - * Make sure that the public point and domain parameters of this - * key are set. - * @throw Invalid_State if either of the two data members is not set - */ - virtual void affirm_init() const; + u32bit max_input_bits() const { return domain().get_order().bits(); } protected: void X509_load_hook(); ECKAEG_Core m_eckaeg_core; - private: - void set_all_values(const ECKAEG_PublicKey& other); }; /** @@ -88,21 +70,13 @@ class BOTAN_DLL ECKAEG_PrivateKey : public ECKAEG_PublicKey, * @param the domain parameters to used for this key */ ECKAEG_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& dom_pars) - { - mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_pars)); - generate_private_key(rng); - mp_public_point->check_invariants(); - m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, m_private_value, *mp_public_point); - } + const EC_Domain_Params& dom_pars); /** * Default constructor. Use this one if you want to later fill this object with data * from an encoded key. */ ECKAEG_PrivateKey() {} - ECKAEG_PrivateKey(ECKAEG_PrivateKey const& other); - ECKAEG_PrivateKey const& operator=(ECKAEG_PrivateKey const& rhs); MemoryVector<byte> public_value() const; @@ -120,17 +94,6 @@ class BOTAN_DLL ECKAEG_PrivateKey : public ECKAEG_PublicKey, * @param other the other partys public key */ SecureVector<byte> derive_key(const ECKAEG_PublicKey& other) const; - - /** - * Make sure that the public key parts of this object are set - * (calls EC_PublicKey::affirm_init()) as well as the private key - * value. - * @throw Invalid_State if the above conditions are not satisfied - */ - virtual void affirm_init() const; - - private: - void set_all_values(const ECKAEG_PrivateKey& other); }; } diff --git a/src/pubkey/eckaeg/eckaeg_core.cpp b/src/pubkey/eckaeg/eckaeg_core.cpp index eaf467933..e22a6dcfe 100644 --- a/src/pubkey/eckaeg/eckaeg_core.cpp +++ b/src/pubkey/eckaeg/eckaeg_core.cpp @@ -1,6 +1,6 @@ /* * ECKAEG Core -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2010 Jack Lloyd * (C) 2007 FlexSecure GmbH * * Distributed under the terms of the Botan license @@ -52,7 +52,8 @@ ECKAEG_Core& ECKAEG_Core::operator=(const ECKAEG_Core& core) */ SecureVector<byte> ECKAEG_Core::agree(const PointGFp& otherKey) const { - //assert(op.get()); + if(op == 0) + throw Invalid_State("ECKAEG_Core: uninitialized"); return op->agree(otherKey); } diff --git a/src/pubkey/gost_3410/gost_3410.cpp b/src/pubkey/gost_3410/gost_3410.cpp index d45f70cfd..1c3faca7a 100644 --- a/src/pubkey/gost_3410/gost_3410.cpp +++ b/src/pubkey/gost_3410/gost_3410.cpp @@ -19,32 +19,21 @@ namespace Botan { GOST_3410_PrivateKey::GOST_3410_PrivateKey(RandomNumberGenerator& rng, const EC_Domain_Params& dom_pars) { - mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_pars)); + domain_params = dom_pars; generate_private_key(rng); - - try - { - mp_public_point->check_invariants(); - } - catch(Illegal_Point& e) - { - throw Invalid_State("GOST_3410 key generation failed"); - } } -GOST_3410_PrivateKey::GOST_3410_PrivateKey(const EC_Domain_Params& domain, +GOST_3410_PrivateKey::GOST_3410_PrivateKey(const EC_Domain_Params& dom_pars, const BigInt& x) { - mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(domain)); + domain_params = dom_pars; - m_private_value = x; - mp_public_point = std::auto_ptr<PointGFp>(new PointGFp (mp_dom_pars->get_base_point())); - - *mp_public_point *= m_private_value; + private_key = x; + public_key = domain().get_base_point() * private_key; try { - mp_public_point->check_invariants(); + public_key.check_invariants(); } catch(Illegal_Point) { @@ -59,19 +48,15 @@ X509_Encoder* GOST_3410_PublicKey::x509_encoder() const public: AlgorithmIdentifier alg_id() const { - key->affirm_init(); - return AlgorithmIdentifier(key->get_oid(), - key->domain_parameters().DER_encode(key->m_param_enc)); + key->domain().DER_encode(key->domain_format())); } MemoryVector<byte> key_bits() const { - key->affirm_init(); - // Trust CryptoPro to come up with something obnoxious - const BigInt x = key->mp_public_point->get_affine_x(); - const BigInt y = key->mp_public_point->get_affine_y(); + const BigInt x = key->public_point().get_affine_x(); + const BigInt y = key->public_point().get_affine_y(); SecureVector<byte> bits(2*std::max(x.bytes(), y.bytes())); @@ -102,7 +87,7 @@ X509_Decoder* GOST_3410_PublicKey::x509_decoder() BER_Decoder ber(alg_id.parameters); ber.start_cons(SEQUENCE).decode(ecc_param_id); - key->mp_dom_pars.reset(new EC_Domain_Params(ecc_param_id)); + key->domain_params = EC_Domain_Params(ecc_param_id); } void key_bits(const MemoryRegion<byte>& bits) @@ -117,11 +102,9 @@ X509_Decoder* GOST_3410_PublicKey::x509_decoder() BigInt y(key_bits, part_size); BigInt x(key_bits + part_size, part_size); - const BigInt p = key->domain_parameters().get_curve().get_p(); + const BigInt p = key->domain().get_curve().get_p(); - key->mp_public_point.reset( - new PointGFp(key->domain_parameters().get_curve(), - x, y)); + key->public_key = PointGFp(key->domain().get_curve(), x, y); key->X509_load_hook(); } @@ -134,51 +117,16 @@ X509_Decoder* GOST_3410_PublicKey::x509_decoder() return new GOST_3410_Key_Decoder(this); } -/* -* GOST_3410_PublicKey -*/ -void GOST_3410_PublicKey::affirm_init() const // virtual - { - EC_PublicKey::affirm_init(); - } - -void GOST_3410_PublicKey::set_all_values(const GOST_3410_PublicKey& other) - { - m_param_enc = other.m_param_enc; - - if(other.mp_dom_pars.get()) - mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); - - if(other.mp_public_point.get()) - mp_public_point.reset(new PointGFp(other.public_point())); - } - -GOST_3410_PublicKey::GOST_3410_PublicKey(const GOST_3410_PublicKey& other) - : Public_Key(), - EC_PublicKey(), - PK_Verifying_wo_MR_Key() - { - set_all_values(other); - } - -const GOST_3410_PublicKey& GOST_3410_PublicKey::operator=(const GOST_3410_PublicKey& rhs) - { - set_all_values(rhs); - return *this; - } - bool GOST_3410_PublicKey::verify(const byte msg[], u32bit msg_len, const byte sig[], u32bit sig_len) const { - affirm_init(); - - const BigInt& n = mp_dom_pars->get_order(); + const BigInt& n = domain().get_order(); if(sig_len != n.bytes()*2) return false; // NOTE: it is not checked whether the public point is set - if(mp_dom_pars->get_curve().get_p() == 0) + if(domain().get_curve().get_p() == 0) throw Internal_Error("domain parameters not set"); BigInt e(msg, msg_len); @@ -198,75 +146,17 @@ bool GOST_3410_PublicKey::verify(const byte msg[], u32bit msg_len, BigInt z1 = (s*v) % n; BigInt z2 = (-r*v) % n; - PointGFp R = (z1 * mp_dom_pars->get_base_point() + z2 * *mp_public_point); + PointGFp R = (z1 * domain().get_base_point() + z2 * public_point()); return (R.get_affine_x() == r); } GOST_3410_PublicKey::GOST_3410_PublicKey(const EC_Domain_Params& dom_par, - const PointGFp& public_point) + const PointGFp& pub_point) { - mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_par)); - mp_public_point = std::auto_ptr<PointGFp>(new PointGFp(public_point)); - m_param_enc = EC_DOMPAR_ENC_EXPLICIT; - } - -void GOST_3410_PublicKey::X509_load_hook() - { - EC_PublicKey::X509_load_hook(); - EC_PublicKey::affirm_init(); - } - -u32bit GOST_3410_PublicKey::max_input_bits() const - { - if(!mp_dom_pars.get()) - { - throw Invalid_State("GOST_3410_PublicKey::max_input_bits(): domain parameters not set"); - } - return mp_dom_pars->get_order().bits(); - } - -/************************* -* GOST_3410_PrivateKey -*************************/ -void GOST_3410_PrivateKey::affirm_init() const // virtual - { - EC_PrivateKey::affirm_init(); - } - -void GOST_3410_PrivateKey::PKCS8_load_hook(bool generated) - { - EC_PrivateKey::PKCS8_load_hook(generated); - EC_PrivateKey::affirm_init(); - } - -void GOST_3410_PrivateKey::set_all_values(const GOST_3410_PrivateKey& other) - { - m_private_value = other.m_private_value; - m_param_enc = other.m_param_enc; - - if(other.mp_dom_pars.get()) - mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); - - if(other.mp_public_point.get()) - mp_public_point.reset(new PointGFp(other.public_point())); - } - -GOST_3410_PrivateKey::GOST_3410_PrivateKey(GOST_3410_PrivateKey const& other) - : Public_Key(), - EC_PublicKey(), - Private_Key(), - GOST_3410_PublicKey(), - EC_PrivateKey(), - PK_Signing_Key() - { - set_all_values(other); - } - -const GOST_3410_PrivateKey& GOST_3410_PrivateKey::operator=(const GOST_3410_PrivateKey& rhs) - { - set_all_values(rhs); - return *this; + domain_params = dom_par; + public_key = pub_point; + domain_encoding = EC_DOMPAR_ENC_EXPLICIT; } SecureVector<byte> @@ -274,16 +164,14 @@ GOST_3410_PrivateKey::sign(const byte msg[], u32bit msg_len, RandomNumberGenerator& rng) const { - affirm_init(); - - const BigInt& n = mp_dom_pars->get_order(); + const BigInt& n = domain().get_order(); BigInt k; do k.randomize(rng, n.bits()-1); while(k >= n); - if(m_private_value == 0) + if(private_value() == 0) throw Internal_Error("GOST_3410::sign(): no private key"); if(n == 0) @@ -295,7 +183,7 @@ GOST_3410_PrivateKey::sign(const byte msg[], if(e == 0) e = 1; - PointGFp k_times_P = mp_dom_pars->get_base_point() * k; + PointGFp k_times_P = domain().get_base_point() * k; k_times_P.check_invariants(); BigInt r = k_times_P.get_affine_x() % n; @@ -303,7 +191,7 @@ GOST_3410_PrivateKey::sign(const byte msg[], if(r == 0) throw Internal_Error("GOST_3410::sign: r was zero"); - BigInt s = (r*m_private_value + k*e) % n; + BigInt s = (r*private_value() + k*e) % n; SecureVector<byte> output(2*n.bytes()); r.binary_encode(output + (output.size() / 2 - r.bytes())); diff --git a/src/pubkey/gost_3410/gost_3410.h b/src/pubkey/gost_3410/gost_3410.h index 2f97c1a04..1d3430753 100644 --- a/src/pubkey/gost_3410/gost_3410.h +++ b/src/pubkey/gost_3410/gost_3410.h @@ -34,12 +34,12 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey, * @result the maximum number of input bits */ - u32bit max_input_bits() const; + u32bit max_input_bits() const { return domain().get_order().bits(); } u32bit message_parts() const { return 2; } u32bit message_part_size() const - { return mp_dom_pars->get_order().bytes(); } + { return domain().get_order().bytes(); } /** * Verify a message with this key. @@ -65,16 +65,6 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey, GOST_3410_PublicKey(const EC_Domain_Params& dom_par, const PointGFp& public_point); // sets core - GOST_3410_PublicKey const& operator=(const GOST_3410_PublicKey& rhs); - - GOST_3410_PublicKey(const GOST_3410_PublicKey& other); - - /** - * Ensure that the public point and domain parameters of this key are set. - * @throw Invalid_State if either of the two data members is not set - */ - virtual void affirm_init() const; - /** * Get an x509_encoder that can be used to encode this key. * @result an x509_encoder for this key @@ -87,10 +77,6 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey, * @result an x509_decoder for this key */ X509_Decoder* x509_decoder(); - - protected: - void X509_load_hook(); - void set_all_values(const GOST_3410_PublicKey& other); }; /** @@ -121,30 +107,14 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, */ GOST_3410_PrivateKey(const EC_Domain_Params& domain, const BigInt& x); - GOST_3410_PrivateKey(const GOST_3410_PrivateKey& other); - GOST_3410_PrivateKey const& operator=(const GOST_3410_PrivateKey& rhs); - /** * Sign a message with this key. * @param message the byte array representing the message to be signed * @param mess_len the length of the message byte array * @result the signature */ - SecureVector<byte> sign(const byte message[], u32bit mess_len, RandomNumberGenerator& rng) const; - - /** - * Make sure that the public key parts of this object are set - * (calls EC_PublicKey::affirm_init()) as well as the private key - * value. - * @throw Invalid_State if the above conditions are not satisfied - */ - virtual void affirm_init() const; - - private: - void set_all_values(const GOST_3410_PrivateKey& other); - void PKCS8_load_hook(bool = false); }; } |