aboutsummaryrefslogtreecommitdiffstats
path: root/src/pubkey/ecdsa
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-10-07 22:52:55 +0000
committerlloyd <[email protected]>2008-10-07 22:52:55 +0000
commit5b14ea1c31ffcc03b895d75fdbe601493712b3d5 (patch)
tree723f786f8ca6813ca7f2081e46240526caa3471b /src/pubkey/ecdsa
parentbd88a534dd0a1ae830ec1e8093c40a0b94d65868 (diff)
Split ECDSA and ECKAEG implementatations apart
Diffstat (limited to 'src/pubkey/ecdsa')
-rw-r--r--src/pubkey/ecdsa/ec.cpp554
-rw-r--r--src/pubkey/ecdsa/ec.h380
-rw-r--r--src/pubkey/ecdsa/ec_key.cpp141
-rw-r--r--src/pubkey/ecdsa/ecc_key.cpp160
-rw-r--r--src/pubkey/ecdsa/ecdsa.cpp322
-rw-r--r--src/pubkey/ecdsa/ecdsa.h178
-rw-r--r--src/pubkey/ecdsa/ecdsa_sig.cpp72
-rw-r--r--src/pubkey/ecdsa/ecdsa_sig.h99
-rw-r--r--src/pubkey/ecdsa/eckaeg.cpp135
-rw-r--r--src/pubkey/ecdsa/eckaeg.h121
-rw-r--r--src/pubkey/ecdsa/info.txt8
11 files changed, 1124 insertions, 1046 deletions
diff --git a/src/pubkey/ecdsa/ec.cpp b/src/pubkey/ecdsa/ec.cpp
deleted file mode 100644
index 1ab871e25..000000000
--- a/src/pubkey/ecdsa/ec.cpp
+++ /dev/null
@@ -1,554 +0,0 @@
-/*************************************************
-* ECC Key implemenation *
-* (C) 2007 Manuel Hartl / FlexSecure GmbH *
-* *
-* Falko Strenzke *
-*************************************************/
-
-#include <botan/ec.h>
-#include <botan/ecdsa.h>
-#include <botan/numthry.h>
-#include <botan/util.h>
-#include <botan/der_enc.h>
-#include <botan/ber_dec.h>
-#include <botan/secmem.h>
-#include <botan/point_gfp.h>
-
-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");
- }
- }
-EC_Domain_Params const EC_PublicKey::get_domain_parameters() const
- {
- if(!mp_dom_pars.get())
- {
- throw Invalid_State("EC_PublicKey::get_domain_parameters(): ec domain parameters are not yet set");
- }
- return *mp_dom_pars;
- }
-bool EC_PublicKey::domain_parameters_set()
- {
- if (mp_dom_pars.get())
- {
- return true;
- }
- return false;
- }
-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();
- }
- catch ( Illegal_Point exc )
- {
- throw Decoding_Error ( "decoded public point was found not to lie on curve" );
- }
- }
-
-
-X509_Encoder* EC_PublicKey::x509_encoder() const
- {
- class EC_Key_Encoder : public X509_Encoder
- {
- public:
- AlgorithmIdentifier alg_id() const
- {
- key->affirm_init();
- SecureVector<byte> params = encode_der_ec_dompar ( * ( key->mp_dom_pars ), key->m_param_enc );
- return AlgorithmIdentifier ( key->get_oid(),
- params );
- }
-
- MemoryVector<byte> key_bits() const
- {
- key->affirm_init();
- return EC2OSP ( * ( key->mp_public_point ), PointGFp::COMPRESSED );
-
- }
-
- EC_Key_Encoder ( const EC_PublicKey* k ) : key ( k )
- {}
- private:
- const EC_PublicKey* key;
- };
-
- return new EC_Key_Encoder(this);
- }
-
-X509_Decoder* EC_PublicKey::x509_decoder()
- {
- class EC_Key_Decoder : public X509_Decoder
- {
- public:
- void alg_id ( const AlgorithmIdentifier& alg_id )
- {
- key->mp_dom_pars.reset ( new EC_Domain_Params ( decode_ber_ec_dompar ( alg_id.parameters ) ) );
- }
-
- void key_bits ( const MemoryRegion<byte>& bits )
- {
- key->mp_public_point.reset ( new PointGFp ( OS2ECP ( bits, key->mp_dom_pars->get_curve() ) ) );
- key->X509_load_hook();
- }
-
- EC_Key_Decoder ( EC_PublicKey* k ) : key ( k )
- {}
- private:
- EC_PublicKey* key;
- };
-
- return new EC_Key_Decoder(this);
- }
-
-void EC_PublicKey::set_parameter_encoding ( EC_dompar_enc type )
- {
- if ( ( type != ENC_EXPLICIT ) && ( type != ENC_IMPLICITCA ) && ( type != ENC_OID ) )
- {
- throw Invalid_Argument ( "invalid encoding type for EC-key object specified" );
- }
- affirm_init();
- if ( ( mp_dom_pars->get_oid() == "" ) && ( type == ENC_OID ) )
- {
- throw Invalid_Argument ( "invalid encoding type ENC_OID specified for EC-key object whose corresponding domain parameters are without oid" );
- }
- m_param_enc = type;
- }
-
-/********************************
-* EC_PrivateKey *
-********************************/
-void EC_PrivateKey::affirm_init() const // virtual
- {
- EC_PublicKey::affirm_init();
- if (m_private_value == 0)
- {
- throw Invalid_State("cannot use EC_PrivateKey when private key is uninitialized");
- }
- }
-
-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));
- 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);
- }
-
-/**
-* EC_PrivateKey generator
-**/
-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");
- }
- BigInt tmp_private_value(0);
- tmp_private_value = BigInt::random_integer(rng, 1, mp_dom_pars->get_order() );
- mp_public_point = std::auto_ptr<PointGFp>( new PointGFp (mp_dom_pars->get_base_point()));
- mp_public_point->mult_this_secure(tmp_private_value, mp_dom_pars->get_order(), mp_dom_pars->get_order()-1);
-
- //assert(mp_public_point.get() != 0);
- tmp_private_value.swap(m_private_value);
- }
-
-/**
-* Return the PKCS #8 public key encoder
-**/
-PKCS8_Encoder* EC_PrivateKey::pkcs8_encoder() const
- {
- class EC_Key_Encoder : public PKCS8_Encoder
- {
- public:
- AlgorithmIdentifier alg_id() const
- {
- key->affirm_init();
- SecureVector<byte> params = encode_der_ec_dompar ( * ( key->mp_dom_pars ), ENC_EXPLICIT );
- return AlgorithmIdentifier ( key->get_oid(),
- params );
- }
-
- 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 )
- .end_cons()
- .get_contents();
- }
-
- EC_Key_Encoder ( const EC_PrivateKey* k ) : key ( k )
- {}
- private:
- const EC_PrivateKey* key;
- };
-
- return new EC_Key_Encoder(this);
- }
-
-/**
-* Return the PKCS #8 public key decoder
-*/
-PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&)
- {
- class EC_Key_Decoder : public PKCS8_Decoder
- {
- public:
- void alg_id ( const AlgorithmIdentifier& alg_id )
- {
- key->mp_dom_pars.reset ( new EC_Domain_Params ( decode_ber_ec_dompar ( alg_id.parameters ) ) );
- }
-
- void key_bits ( const MemoryRegion<byte>& bits )
- {
- u32bit version;
- SecureVector<byte> octstr_secret;
- BER_Decoder ( bits )
- .start_cons ( SEQUENCE )
- .decode ( version )
- .decode ( octstr_secret, OCTET_STRING )
- .verify_end()
- .end_cons();
- key->m_private_value = BigInt::decode ( octstr_secret, octstr_secret.size() );
- if ( version != 1 )
- throw Decoding_Error ( "Wrong PKCS #1 key format version for EC key" );
- key->PKCS8_load_hook();
- }
-
- EC_Key_Decoder ( EC_PrivateKey* k ) : key ( k )
- {}
- private:
- EC_PrivateKey* key;
- };
-
- return new EC_Key_Decoder(this);
- }
-
-
-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();
-
- }
-
-
-
-
-/*************************************************
-* ECDSA_PublicKey *
-*************************************************/
-void ECDSA_PublicKey::affirm_init() const // virtual
- {
- EC_PublicKey::affirm_init();
- }
-
-void ECDSA_PublicKey::set_domain_parameters(EC_Domain_Params const& dom_pars)
- {
- if (mp_dom_pars.get())
- {
- // they are already set, we must ensure that they are equal to the arg
- if (dom_pars != *mp_dom_pars.get())
- {
- throw Invalid_Argument("EC_PublicKey::set_domain_parameters(): domain parameters are already set, and they are different from the argument");
- }
- else
- {
- // they are equal, so nothing to do
- return;
- }
- }
- // set them ...
- if (m_enc_public_point.size() == 0)
- {
- throw Invalid_State("EC_PublicKey::set_domain_parameters(): encoded public point isn´t set");
- }
-
- // now try to decode the public key ...
- PointGFp tmp_pp(OS2ECP(m_enc_public_point, dom_pars.get_curve()));
- try
- {
- tmp_pp.check_invariants();
- }
- catch(Illegal_Point e)
- {
- throw Invalid_State("EC_PublicKey::set_domain_parameters(): point does not lie on provided curve");
- }
- std::auto_ptr<EC_Domain_Params> p_tmp_pars(new EC_Domain_Params(dom_pars));
- ECDSA_Core tmp_ecdsa_core( *p_tmp_pars, BigInt ( 0 ), tmp_pp );
- mp_public_point.reset(new PointGFp(tmp_pp));
- m_ecdsa_core = tmp_ecdsa_core;
- mp_dom_pars = p_tmp_pars;
- }
-
-void ECDSA_PublicKey::set_all_values ( ECDSA_PublicKey const& other )
- {
- m_param_enc = other.m_param_enc;
- m_ecdsa_core = other.m_ecdsa_core;
- m_enc_public_point = other.m_enc_public_point;
- 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 ) ) );
- }
- }
-ECDSA_PublicKey::ECDSA_PublicKey ( ECDSA_PublicKey const& other )
- : Public_Key(),
- EC_PublicKey(),
- PK_Verifying_wo_MR_Key()
- {
- set_all_values ( other );
- }
-ECDSA_PublicKey const& ECDSA_PublicKey::operator= ( ECDSA_PublicKey const& rhs )
- {
- set_all_values ( rhs );
- return *this;
- }
-bool ECDSA_PublicKey::verify ( const byte message[], u32bit mess_len, const byte signature [], u32bit sig_len ) const
- {
- affirm_init();
- ECDSA_Signature sig;
- std::auto_ptr<ECDSA_Signature_Decoder> dec(sig.x509_decoder());
- SecureVector<byte> sv_sig;
- sv_sig.set ( signature, sig_len );
- dec->signature_bits ( sv_sig );
- SecureVector<byte> sv_plain_sig = sig.get_concatenation();
- return m_ecdsa_core.verify ( sv_plain_sig, sv_plain_sig.size(), message, mess_len );
- }
-ECDSA_PublicKey::ECDSA_PublicKey ( EC_Domain_Params const& dom_par, PointGFp const& public_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 = ENC_EXPLICIT;
- m_ecdsa_core = ECDSA_Core ( *mp_dom_pars, BigInt ( 0 ), *mp_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();
- }
-
-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 ( ECDSA_PrivateKey const& other )
- {
- m_private_value = other.m_private_value;
- m_param_enc = other.m_param_enc;
- m_ecdsa_core = other.m_ecdsa_core;
- m_enc_public_point = other.m_enc_public_point;
- 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 ) ) );
- }
- }
-
-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);
- }
-ECDSA_PrivateKey const& ECDSA_PrivateKey::operator= (ECDSA_PrivateKey const& rhs)
- {
- set_all_values(rhs);
- return *this;
- }
-
-SecureVector<byte> ECDSA_PrivateKey::sign ( const byte message [], u32bit mess_len, RandomNumberGenerator&) const
- {
- affirm_init();
- SecureVector<byte> sv_sig = m_ecdsa_core.sign ( message, mess_len );
- //code which der encodes the signature returned
- ECDSA_Signature sig = decode_concatenation( sv_sig );
- std::auto_ptr<ECDSA_Signature_Encoder> enc(sig.x509_encoder());
- return enc->signature_bits();
-
- }
-
-
-
-/*********************************
-* 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;
- m_enc_public_point = other.m_enc_public_point;
- 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 );
- }
-ECKAEG_PublicKey::ECKAEG_PublicKey ( EC_Domain_Params const& dom_par, PointGFp const& public_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 );
- }
-
-
-/*********************************
-* ECKAEG_PrivateKey *
-*********************************/
-void ECKAEG_PrivateKey::affirm_init() const // virtual
- {
- EC_PrivateKey::affirm_init();
- }
-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;
- m_enc_public_point = other.m_enc_public_point;
- 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_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)
- {
- set_all_values(rhs);
- return *this;
- }
-
-/**
-* Derive a key
-*/
-SecureVector<byte> ECKAEG_PrivateKey::derive_key(const Public_Key& key) const
- {
- affirm_init();
-
- const EC_PublicKey * p_ec_pk = dynamic_cast<const EC_PublicKey*>(&key);
- if(!p_ec_pk)
- {
- throw Invalid_Argument("ECKAEG_PrivateKey::derive_key(): argument must be an EC_PublicKey");
- }
- p_ec_pk->affirm_init();
- return m_eckaeg_core.agree ( p_ec_pk->get_public_point() );
- }
-
-}
diff --git a/src/pubkey/ecdsa/ec.h b/src/pubkey/ecdsa/ec.h
deleted file mode 100644
index 7a0b3cbba..000000000
--- a/src/pubkey/ecdsa/ec.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/*************************************************
-* ECDSA Header File *
-* (C) 2007 Falko Strenzke, FlexSecure GmbH *
-* Manuel hartl, FlexSecure GmbH *
-*************************************************/
-
-#ifndef BOTAN_EC_H__
-#define BOTAN_EC_H__
-
-#include <botan/if_algo.h>
-#include <botan/bigint.h>
-#include <botan/curve_gfp.h>
-#include <botan/pk_keys.h>
-#include <botan/ec_dompar.h>
-#include <botan/ecc_core.h>
-
-namespace Botan {
-
-/**
-* This class represents abstract EC Public Keys.
-* When encoding a key via an encoder that can be accessed via
-* the corresponding member functions, the key will decide upon its
-* internally stored encoding information whether to encode itself with
-* or without domain parameters, or using the domain parameter oid.
-* Furthermore, a public key
-* without domain parameters can be decoded. In that case, it cannot be used
-* for verification until its domain parameters are set by calling the
-* corresponding member function.
-*/
-class 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
- */
- inline Botan::PointGFp get_public_point() const
- {
- if (!mp_public_point.get())
- {
- throw Invalid_State("EC_PublicKey::get_public_point(): public point not set because ec domain parameters are not yet set");
- }
- return *mp_public_point;
- }
- /**
- * Get the domain parameters of this key.
- * @throw Invalid_State is thrown if the
- * domain parameters of this point are not set
- * @result the domain parameters of this key
- */
- EC_Domain_Params const get_domain_parameters() const;
- /**
- * Set the domain parameter encoding to be used when encoding this key.
- * @param enc the encoding to use
- */
- void set_parameter_encoding(EC_dompar_enc enc);
-
- /**
- * 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(ENC_EXPLICIT)
- {
- //assert(mp_dom_pars.get() == 0);
- //assert(mp_public_point.get() == 0);
- }
-
- /**
- * Get an x509_encoder that can be used to encode this key.
- * @result an x509_encoder for this key
- */
- X509_Encoder* x509_encoder() const;
-
- /**
- * Get an x509_decoder that can be used to decode a stored key into
- * this key.
- * @result an x509_decoder for this 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;
-
- virtual ~EC_PublicKey() {}
- protected:
- virtual void X509_load_hook();
-
- SecureVector<byte> m_enc_public_point; // stores the public point
-
- std::auto_ptr<EC_Domain_Params> mp_dom_pars;
- std::auto_ptr<Botan::PointGFp> mp_public_point;
- EC_dompar_enc m_param_enc;
- };
-
-/**
-* This abstract class represents general EC Private Keys
-*/
-class EC_PrivateKey : public virtual EC_PublicKey, public virtual Private_Key
- {
- public:
-
- /**
- * Get an PKCS#8 encoder that can be used to encoded this key.
- * @result an PKCS#8 encoder for this key
- */
- PKCS8_Encoder* pkcs8_encoder() const;
- /**
- * Get an PKCS#8 decoder that can be used to decoded a stored key into
- * this key.
- * @result an PKCS#8 decoder for this key
- */
- PKCS8_Decoder* pkcs8_decoder(RandomNumberGenerator&);
- /**
- * Get the private key value of this key object.
- * @result the private key value of this key object
- */
- inline BigInt const get_value() const
- {
- return m_private_value;
- }
- /**
- * 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;
- };
-
-/**
-* This class represents ECDSA Public Keys.
-*/
-class ECDSA_PublicKey : public virtual EC_PublicKey, public PK_Verifying_wo_MR_Key
- {
- public:
-
- /**
- * Get this keys algorithm name.
- * @result this keys algorithm name ("ECDSA")
- */
- std::string algo_name() const
- {
- return "ECDSA";
- }
-
- /**
- * 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;
-
- /**
- * Verify a message with this key.
- * @param message the byte array containing the message
- * @param mess_len the number of bytes in the message byte array
- * @param signature the byte array containing the signature
- * @param sig_len the number of bytes in the signature byte array
- */
- bool verify(const byte message[], u32bit mess_len,
- const byte signature [], u32bit sig_len) const;
-
- /**
- * Default constructor. Use this one if you want to later fill this object with data
- * from an encoded key.
- */
- ECDSA_PublicKey() {}
-
- /**
- * Construct a public key from a given public point.
- * @param dom_par the domain parameters associated with this key
- * @param public_point the public point defining this key
- */
- ECDSA_PublicKey(EC_Domain_Params const& dom_par, Botan::PointGFp const& public_point); // sets core
-
-
- ECDSA_PublicKey const& operator= (ECDSA_PublicKey const& rhs);
-
- ECDSA_PublicKey(ECDSA_PublicKey const& other);
-
- /**
- * Set the domain parameters of this key. This function has to be
- * used when a key encoded without domain parameters was decoded into
- * this key. Otherwise it will not be able to verify a signature.
- * @param dom_pars the domain_parameters associated with this key
- * @throw Invalid_Argument if the point was found not to be satisfying the
- * curve equation of the provided domain parameters
- * or if this key already has domain parameters set
- * and these are differing from those given as the parameter
- */
- void set_domain_parameters(EC_Domain_Params const& dom_pars);
-
- /**
- * 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;
-
- protected:
- void X509_load_hook();
- virtual void set_all_values(ECDSA_PublicKey const& other);
-
- ECDSA_Core m_ecdsa_core;
- };
-/**
-* This class represents ECDSA Public Keys.
-*/
-class ECDSA_PrivateKey : public ECDSA_PublicKey, public EC_PrivateKey, 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.
- */
- ECDSA_PrivateKey()
- {}
- /**
- * Generate a new private key
- * @param the domain parameters to used for this key
- */
- ECDSA_PrivateKey(RandomNumberGenerator& rng,
- const EC_Domain_Params& domain);
-
- ECDSA_PrivateKey(ECDSA_PrivateKey const& other);
- ECDSA_PrivateKey const& operator= (ECDSA_PrivateKey const& 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;
- protected:
- virtual void set_all_values ( ECDSA_PrivateKey const& other );
- private:
- void PKCS8_load_hook(bool = false);
- };
-
-/**
-* This class represents ECKAEG Public Keys.
-*/
-class ECKAEG_PublicKey : public virtual EC_PublicKey
- {
- public:
- /**
- * Default constructor. Use this one if you want to later fill this object with data
- * from an encoded key.
- */
- ECKAEG_PublicKey()
- {};
- /**
- * Construct a public key from a given public point.
- * @param dom_par the domain parameters associated with this key
- * @param public_point the public point defining this key
- */
- ECKAEG_PublicKey(EC_Domain_Params const& dom_par, Botan::PointGFp const& 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;
- protected:
- void X509_load_hook();
- virtual void set_all_values ( ECKAEG_PublicKey const& other );
-
- ECKAEG_Core m_eckaeg_core;
- };
-
-/**
-* This class represents ECKAEG Private Keys.
-*/
-class ECKAEG_PrivateKey : public ECKAEG_PublicKey, public EC_PrivateKey, public PK_Key_Agreement_Key
- {
- public:
- /**
- * Generate a new private key
- * @param the domain parameters to used for this key
- */
- ECKAEG_PrivateKey(RandomNumberGenerator& rng,
- EC_Domain_Params const& 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);
- }
- /**
- * 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);
-
- void PKCS8_load_hook(bool = false);
-
- /**
- * Derive a shared key with the other partys public key.
- * @param pub_key the other partys public key
- */
- SecureVector<byte> derive_key(const Public_Key& pub_key) 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;
-
- protected:
- virtual void set_all_values ( ECKAEG_PrivateKey const& other );
- };
-
-}
-
-#endif
diff --git a/src/pubkey/ecdsa/ec_key.cpp b/src/pubkey/ecdsa/ec_key.cpp
new file mode 100644
index 000000000..8d0b83f44
--- /dev/null
+++ b/src/pubkey/ecdsa/ec_key.cpp
@@ -0,0 +1,141 @@
+/*************************************************
+* ECC Key implemenation *
+* (C) 2007 Manuel Hartl / FlexSecure GmbH *
+* *
+* Falko Strenzke *
+*************************************************/
+
+#include <botan/ec_key.h>
+#include <botan/x509_key.h>
+#include <botan/numthry.h>
+#include <botan/util.h>
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
+#include <botan/secmem.h>
+#include <botan/point_gfp.h>
+
+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");
+ }
+ }
+EC_Domain_Params const EC_PublicKey::get_domain_parameters() const
+ {
+ if(!mp_dom_pars.get())
+ {
+ throw Invalid_State("EC_PublicKey::get_domain_parameters(): ec domain parameters are not yet set");
+ }
+ return *mp_dom_pars;
+ }
+bool EC_PublicKey::domain_parameters_set()
+ {
+ if (mp_dom_pars.get())
+ {
+ return true;
+ }
+ return false;
+ }
+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();
+ }
+ catch ( Illegal_Point exc )
+ {
+ throw Decoding_Error ( "decoded public point was found not to lie on curve" );
+ }
+ }
+
+
+X509_Encoder* EC_PublicKey::x509_encoder() const
+ {
+ class EC_Key_Encoder : public X509_Encoder
+ {
+ public:
+ AlgorithmIdentifier alg_id() const
+ {
+ key->affirm_init();
+ SecureVector<byte> params = encode_der_ec_dompar ( * ( key->mp_dom_pars ), key->m_param_enc );
+ return AlgorithmIdentifier ( key->get_oid(),
+ params );
+ }
+
+ MemoryVector<byte> key_bits() const
+ {
+ key->affirm_init();
+ return EC2OSP ( * ( key->mp_public_point ), PointGFp::COMPRESSED );
+
+ }
+
+ EC_Key_Encoder ( const EC_PublicKey* k ) : key ( k )
+ {}
+ private:
+ const EC_PublicKey* key;
+ };
+
+ return new EC_Key_Encoder(this);
+ }
+
+X509_Decoder* EC_PublicKey::x509_decoder()
+ {
+ class EC_Key_Decoder : public X509_Decoder
+ {
+ public:
+ void alg_id ( const AlgorithmIdentifier& alg_id )
+ {
+ key->mp_dom_pars.reset ( new EC_Domain_Params ( decode_ber_ec_dompar ( alg_id.parameters ) ) );
+ }
+
+ void key_bits ( const MemoryRegion<byte>& bits )
+ {
+ key->mp_public_point.reset ( new PointGFp ( OS2ECP ( bits, key->mp_dom_pars->get_curve() ) ) );
+ key->X509_load_hook();
+ }
+
+ EC_Key_Decoder ( EC_PublicKey* k ) : key ( k )
+ {}
+ private:
+ EC_PublicKey* key;
+ };
+
+ return new EC_Key_Decoder(this);
+ }
+
+void EC_PublicKey::set_parameter_encoding ( EC_dompar_enc type )
+ {
+ if ( ( type != ENC_EXPLICIT ) && ( type != ENC_IMPLICITCA ) && ( type != ENC_OID ) )
+ {
+ throw Invalid_Argument ( "invalid encoding type for EC-key object specified" );
+ }
+ affirm_init();
+ if ( ( mp_dom_pars->get_oid() == "" ) && ( type == ENC_OID ) )
+ {
+ throw Invalid_Argument ( "invalid encoding type ENC_OID specified for EC-key object whose corresponding domain parameters are without oid" );
+ }
+ m_param_enc = type;
+ }
+
+/********************************
+* EC_PrivateKey *
+********************************/
+void EC_PrivateKey::affirm_init() const // virtual
+ {
+ EC_PublicKey::affirm_init();
+ if (m_private_value == 0)
+ {
+ throw Invalid_State("cannot use EC_PrivateKey when private key is uninitialized");
+ }
+ }
+
+}
diff --git a/src/pubkey/ecdsa/ecc_key.cpp b/src/pubkey/ecdsa/ecc_key.cpp
new file mode 100644
index 000000000..1beba96c5
--- /dev/null
+++ b/src/pubkey/ecdsa/ecc_key.cpp
@@ -0,0 +1,160 @@
+/*************************************************
+* ECDSA Header File *
+* (C) 2007 Falko Strenzke, FlexSecure GmbH *
+* Manuel hartl, FlexSecure GmbH *
+* (C) 2008 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_ECC_KEY_H__
+#define BOTAN_ECC_KEY_H__
+
+#include <botan/bigint.h>
+#include <botan/curve_gfp.h>
+#include <botan/pk_keys.h>
+#include <botan/ec_dompar.h>
+#include <botan/ecc_core.h>
+#include <botan/x509_key.h>
+#include <botan/pkcs8.h>
+
+namespace Botan {
+
+/**
+* This class represents abstract EC Public Keys. When encoding a key
+* via an encoder that can be accessed via the corresponding member
+* functions, the key will decide upon its internally stored encoding
+* information whether to encode itself with or without domain
+* parameters, or using the domain parameter oid. Furthermore, a public
+* key without domain parameters can be decoded. In that case, it
+* cannot be used for verification until its domain parameters are set
+* by calling the corresponding member function.
+*/
+class 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
+ */
+ inline Botan::PointGFp get_public_point() const
+ {
+ if (!mp_public_point.get())
+ {
+ throw Invalid_State("EC_PublicKey::get_public_point(): public point not set because ec domain parameters are not yet set");
+ }
+ return *mp_public_point;
+ }
+
+ /**
+ * Get the domain parameters of this key.
+ * @throw Invalid_State is thrown if the
+ * domain parameters of this point are not set
+ * @result the domain parameters of this key
+ */
+ EC_Domain_Params const get_domain_parameters() const;
+
+ /**
+ * Set the domain parameter encoding to be used when encoding this key.
+ * @param enc the encoding to use
+ */
+ void set_parameter_encoding(EC_dompar_enc enc);
+
+ /**
+ * 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(ENC_EXPLICIT)
+ {
+ //assert(mp_dom_pars.get() == 0);
+ //assert(mp_public_point.get() == 0);
+ }
+
+ /**
+ * Get an x509_encoder that can be used to encode this key.
+ * @result an x509_encoder for this key
+ */
+ X509_Encoder* x509_encoder() const;
+
+ /**
+ * Get an x509_decoder that can be used to decode a stored key into
+ * this key.
+ * @result an x509_decoder for this 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;
+
+ virtual ~EC_PublicKey() {}
+ protected:
+ virtual void X509_load_hook();
+
+ SecureVector<byte> m_enc_public_point; // stores the public point
+
+ std::auto_ptr<EC_Domain_Params> mp_dom_pars;
+ std::auto_ptr<Botan::PointGFp> mp_public_point;
+ EC_dompar_enc m_param_enc;
+ };
+
+/**
+* This abstract class represents general EC Private Keys
+*/
+class EC_PrivateKey : public virtual EC_PublicKey, public virtual Private_Key
+ {
+ public:
+
+ /**
+ * Get an PKCS#8 encoder that can be used to encoded this key.
+ * @result an PKCS#8 encoder for this key
+ */
+ PKCS8_Encoder* pkcs8_encoder() const;
+ /**
+ * Get an PKCS#8 decoder that can be used to decoded a stored key into
+ * this key.
+ * @result an PKCS#8 decoder for this key
+ */
+ PKCS8_Decoder* pkcs8_decoder(RandomNumberGenerator&);
+ /**
+ * Get the private key value of this key object.
+ * @result the private key value of this key object
+ */
+ inline BigInt const get_value() const
+ {
+ return m_private_value;
+ }
+ /**
+ * 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;
+ };
+
+}
+
+#endif
diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp
index 04dc1e529..ae098cdc0 100644
--- a/src/pubkey/ecdsa/ecdsa.cpp
+++ b/src/pubkey/ecdsa/ecdsa.cpp
@@ -1,72 +1,312 @@
-#include <botan/bigint.h>
+/*************************************************
+* ECDSA implemenation *
+* (C) 2007 Manuel Hartl, FlexSecure GmbH *
+* 2007 Falko Strenzke, FlexSecure GmbH *
+* 2008 Jack Lloyd *
+*************************************************/
+
#include <botan/ecdsa.h>
-#include <memory>
+#include <botan/ecdsa_sig.h>
+#include <botan/numthry.h>
+#include <botan/util.h>
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
+#include <botan/secmem.h>
+#include <botan/point_gfp.h>
namespace Botan {
-ECDSA_Signature::ECDSA_Signature(const BigInt& r, const BigInt& s)
- : m_r(r),
- m_s(s)
- {}
+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));
+ generate_private_key(rng);
+
+ try
+ {
+ mp_public_point->check_invariants();
+ }
+ catch(Illegal_Point& e)
+ {
+ throw Invalid_State("ECDSA key generation failed");
+ }
-ECDSA_Signature::ECDSA_Signature(ECDSA_Signature const& other)
- : m_r(other.m_r),
- m_s(other.m_s)
- {}
+ m_ecdsa_core = ECDSA_Core(*mp_dom_pars, m_private_value, *mp_public_point);
+ }
-ECDSA_Signature const& ECDSA_Signature::operator=(ECDSA_Signature const& other)
+/**
+* EC_PrivateKey generator
+**/
+void EC_PrivateKey::generate_private_key(RandomNumberGenerator& rng)
{
- m_r = other.m_r;
- m_s = other.m_s;
- return *this;
+ if (mp_dom_pars.get() == 0)
+ {
+ throw Invalid_State("cannot generate private key when domain parameters are not set");
+ }
+ BigInt tmp_private_value(0);
+ tmp_private_value = BigInt::random_integer(rng, 1, mp_dom_pars->get_order() );
+ mp_public_point = std::auto_ptr<PointGFp>( new PointGFp (mp_dom_pars->get_base_point()));
+ mp_public_point->mult_this_secure(tmp_private_value, mp_dom_pars->get_order(), mp_dom_pars->get_order()-1);
+
+ //assert(mp_public_point.get() != 0);
+ tmp_private_value.swap(m_private_value);
+ }
+
+/**
+* Return the PKCS #8 public key encoder
+**/
+PKCS8_Encoder* EC_PrivateKey::pkcs8_encoder() const
+ {
+ class EC_Key_Encoder : public PKCS8_Encoder
+ {
+ public:
+ AlgorithmIdentifier alg_id() const
+ {
+ key->affirm_init();
+ SecureVector<byte> params = encode_der_ec_dompar ( * ( key->mp_dom_pars ), ENC_EXPLICIT );
+ return AlgorithmIdentifier ( key->get_oid(),
+ params );
+ }
+
+ 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 )
+ .end_cons()
+ .get_contents();
+ }
+
+ EC_Key_Encoder ( const EC_PrivateKey* k ) : key ( k )
+ {}
+ private:
+ const EC_PrivateKey* key;
+ };
+
+ return new EC_Key_Encoder(this);
}
-bool operator== ( ECDSA_Signature const& lhs, ECDSA_Signature const& rhs )
+/**
+* Return the PKCS #8 public key decoder
+*/
+PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&)
{
- return (lhs.get_r() == rhs.get_r() && lhs.get_s() == rhs.get_s());
+ class EC_Key_Decoder : public PKCS8_Decoder
+ {
+ public:
+ void alg_id ( const AlgorithmIdentifier& alg_id )
+ {
+ key->mp_dom_pars.reset ( new EC_Domain_Params ( decode_ber_ec_dompar ( alg_id.parameters ) ) );
+ }
+
+ void key_bits ( const MemoryRegion<byte>& bits )
+ {
+ u32bit version;
+ SecureVector<byte> octstr_secret;
+ BER_Decoder ( bits )
+ .start_cons ( SEQUENCE )
+ .decode ( version )
+ .decode ( octstr_secret, OCTET_STRING )
+ .verify_end()
+ .end_cons();
+ key->m_private_value = BigInt::decode ( octstr_secret, octstr_secret.size() );
+ if ( version != 1 )
+ throw Decoding_Error ( "Wrong PKCS #1 key format version for EC key" );
+ key->PKCS8_load_hook();
+ }
+
+ EC_Key_Decoder ( EC_PrivateKey* k ) : key ( k )
+ {}
+ private:
+ EC_PrivateKey* key;
+ };
+
+ return new EC_Key_Decoder(this);
}
-ECDSA_Signature_Decoder* ECDSA_Signature::x509_decoder()
+
+void EC_PrivateKey::PKCS8_load_hook ( bool )
{
- return new ECDSA_Signature_Decoder(this);
+ // 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();
+
}
-ECDSA_Signature_Encoder* ECDSA_Signature::x509_encoder() const
+
+
+
+/*************************************************
+* ECDSA_PublicKey *
+*************************************************/
+void ECDSA_PublicKey::affirm_init() const // virtual
{
- return new ECDSA_Signature_Encoder(this);
+ EC_PublicKey::affirm_init();
}
-SecureVector<byte> const ECDSA_Signature::get_concatenation() const
+
+void ECDSA_PublicKey::set_domain_parameters(EC_Domain_Params const& dom_pars)
{
- u32bit enc_len = m_r > m_s ? m_r.bytes() : m_s.bytes(); // use the larger
- SecureVector<byte> sv_r = BigInt::encode_1363 ( m_r, enc_len );
- SecureVector<byte> sv_s = BigInt::encode_1363 ( m_s, enc_len );
- SecureVector<byte> result(sv_r);
- result.append(sv_s);
- return result;
+ if (mp_dom_pars.get())
+ {
+ // they are already set, we must ensure that they are equal to the arg
+ if (dom_pars != *mp_dom_pars.get())
+ {
+ throw Invalid_Argument("EC_PublicKey::set_domain_parameters(): domain parameters are already set, and they are different from the argument");
+ }
+ else
+ {
+ // they are equal, so nothing to do
+ return;
+ }
+ }
+ // set them ...
+ if (m_enc_public_point.size() == 0)
+ {
+ throw Invalid_State("EC_PublicKey::set_domain_parameters(): encoded public point isn´t set");
+ }
+
+ // now try to decode the public key ...
+ PointGFp tmp_pp(OS2ECP(m_enc_public_point, dom_pars.get_curve()));
+ try
+ {
+ tmp_pp.check_invariants();
+ }
+ catch(Illegal_Point e)
+ {
+ throw Invalid_State("EC_PublicKey::set_domain_parameters(): point does not lie on provided curve");
+ }
+ std::auto_ptr<EC_Domain_Params> p_tmp_pars(new EC_Domain_Params(dom_pars));
+ ECDSA_Core tmp_ecdsa_core( *p_tmp_pars, BigInt ( 0 ), tmp_pp );
+ mp_public_point.reset(new PointGFp(tmp_pp));
+ m_ecdsa_core = tmp_ecdsa_core;
+ mp_dom_pars = p_tmp_pars;
}
-ECDSA_Signature const decode_seq(MemoryRegion<byte> const& seq)
+void ECDSA_PublicKey::set_all_values ( ECDSA_PublicKey const& other )
+ {
+ m_param_enc = other.m_param_enc;
+ m_ecdsa_core = other.m_ecdsa_core;
+ m_enc_public_point = other.m_enc_public_point;
+ 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 ) ) );
+ }
+ }
+ECDSA_PublicKey::ECDSA_PublicKey ( ECDSA_PublicKey const& other )
+ : Public_Key(),
+ EC_PublicKey(),
+ PK_Verifying_wo_MR_Key()
+ {
+ set_all_values ( other );
+ }
+ECDSA_PublicKey const& ECDSA_PublicKey::operator= ( ECDSA_PublicKey const& rhs )
+ {
+ set_all_values ( rhs );
+ return *this;
+ }
+bool ECDSA_PublicKey::verify ( const byte message[], u32bit mess_len, const byte signature [], u32bit sig_len ) const
{
+ affirm_init();
ECDSA_Signature sig;
std::auto_ptr<ECDSA_Signature_Decoder> dec(sig.x509_decoder());
- dec->signature_bits(seq);
- return sig;
+ SecureVector<byte> sv_sig;
+ sv_sig.set ( signature, sig_len );
+ dec->signature_bits ( sv_sig );
+ SecureVector<byte> sv_plain_sig = sig.get_concatenation();
+ return m_ecdsa_core.verify ( sv_plain_sig, sv_plain_sig.size(), message, mess_len );
+ }
+ECDSA_PublicKey::ECDSA_PublicKey ( EC_Domain_Params const& dom_par, PointGFp const& public_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 = ENC_EXPLICIT;
+ m_ecdsa_core = ECDSA_Core ( *mp_dom_pars, BigInt ( 0 ), *mp_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_Signature const decode_concatenation(MemoryRegion<byte> const& concatenation)
+
+/*************************
+* ECDSA_PrivateKey *
+*************************/
+
+void ECDSA_PrivateKey::affirm_init() const // virtual
+ {
+ EC_PrivateKey::affirm_init();
+ }
+
+void ECDSA_PrivateKey::PKCS8_load_hook ( bool generated )
{
- if(concatenation.size() % 2 != 0)
+ 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 ( ECDSA_PrivateKey const& other )
+ {
+ m_private_value = other.m_private_value;
+ m_param_enc = other.m_param_enc;
+ m_ecdsa_core = other.m_ecdsa_core;
+ m_enc_public_point = other.m_enc_public_point;
+ if ( other.mp_dom_pars.get() )
+ {
+ mp_dom_pars.reset ( new EC_Domain_Params ( * ( other.mp_dom_pars ) ) );
+ }
+ if ( other.mp_public_point.get() )
{
- throw Invalid_Argument("Erroneous length of signature");
+ mp_public_point.reset ( new PointGFp ( * ( other.mp_public_point ) ) );
}
- u32bit rs_len = concatenation.size()/2;
- SecureVector<byte> sv_r;
- SecureVector<byte> sv_s;
- sv_r.set(concatenation.begin(), rs_len);
- sv_s.set(&concatenation[rs_len], rs_len);
- BigInt r = BigInt::decode ( sv_r, sv_r.size());
- BigInt s = BigInt::decode (sv_s, sv_s.size());
- return ECDSA_Signature(r, s);
+ }
+
+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);
+ }
+ECDSA_PrivateKey const& ECDSA_PrivateKey::operator= (ECDSA_PrivateKey const& rhs)
+ {
+ set_all_values(rhs);
+ return *this;
+ }
+
+SecureVector<byte> ECDSA_PrivateKey::sign ( const byte message [], u32bit mess_len, RandomNumberGenerator&) const
+ {
+ affirm_init();
+ SecureVector<byte> sv_sig = m_ecdsa_core.sign ( message, mess_len );
+ //code which der encodes the signature returned
+ ECDSA_Signature sig = decode_concatenation( sv_sig );
+ std::auto_ptr<ECDSA_Signature_Encoder> enc(sig.x509_encoder());
+ return enc->signature_bits();
}
}
diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h
index 2f8392a3f..68d69b24a 100644
--- a/src/pubkey/ecdsa/ecdsa.h
+++ b/src/pubkey/ecdsa/ecdsa.h
@@ -1,100 +1,140 @@
/*************************************************
* ECDSA Header File *
* (C) 2007 Falko Strenzke, FlexSecure GmbH *
-* Defines classes ECDSA_Signature and *
-* ECDSA_Signature_De/Encoder, *
+* Manuel hartl, FlexSecure GmbH *
+* (C) 2008 Jack Lloyd *
*************************************************/
-#ifndef BOTAN_ECDSA_H__
-#define BOTAN_ECDSA_H__
+#ifndef BOTAN_ECDSA_KEY_H__
+#define BOTAN_ECDSA_KEY_H__
-#include <botan/bigint.h>
-#include <botan/der_enc.h>
-#include <botan/ber_dec.h>
+#include <botan/ecc_key.h>
namespace Botan {
-class ECDSA_Signature_Decoder;
-class ECDSA_Signature_Encoder;
-
-class ECDSA_Signature
+/**
+* This class represents ECDSA Public Keys.
+*/
+class ECDSA_PublicKey : public virtual EC_PublicKey,
+ public PK_Verifying_wo_MR_Key
{
- friend class ECDSA_Signature_Decoder;
- friend class ECDSA_Signature_Encoder;
public:
- ECDSA_Signature(const BigInt& r, const BigInt& s);
- ECDSA_Signature()
- {}
- ;
- ECDSA_Signature(ECDSA_Signature const& other);
- ECDSA_Signature const& operator=(ECDSA_Signature const& other);
- BigInt const get_r() const
- {
- return m_r;
- }
- BigInt const get_s() const
+ /**
+ * Get this keys algorithm name.
+ * @result this keys algorithm name ("ECDSA")
+ */
+ std::string algo_name() const
{
- return m_s;
+ return "ECDSA";
}
+
/**
- * return the r||s
+ * 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
*/
- SecureVector<byte> const get_concatenation() const;
+ u32bit max_input_bits() const;
+ /**
+ * Verify a message with this key.
+ * @param message the byte array containing the message
+ * @param mess_len the number of bytes in the message byte array
+ * @param signature the byte array containing the signature
+ * @param sig_len the number of bytes in the signature byte array
+ */
+ bool verify(const byte message[], u32bit mess_len,
+ const byte signature [], u32bit sig_len) const;
- ECDSA_Signature_Encoder* x509_encoder() const;
- ECDSA_Signature_Decoder* x509_decoder();
- private:
- BigInt m_r;
- BigInt m_s;
- };
+ /**
+ * Default constructor. Use this one if you want to later fill this object with data
+ * from an encoded key.
+ */
+ ECDSA_PublicKey() {}
-bool operator== ( ECDSA_Signature const& lhs, ECDSA_Signature const& rhs );
-inline bool operator!= ( ECDSA_Signature const& lhs, ECDSA_Signature const& rhs )
- {
- return !operator== ( lhs, rhs );
- }
+ /**
+ * Construct a public key from a given public point.
+ * @param dom_par the domain parameters associated with this key
+ * @param public_point the public point defining this key
+ */
+ ECDSA_PublicKey(EC_Domain_Params const& dom_par, Botan::PointGFp const& public_point); // sets core
-class ECDSA_Signature_Decoder
- {
- public:
- void signature_bits(const MemoryRegion<byte>& bits)
- {
- BER_Decoder(bits)
- .start_cons(SEQUENCE)
- .decode(m_signature->m_r)
- .decode(m_signature->m_s)
- .verify_end()
- .end_cons();
- }
- ECDSA_Signature_Decoder(ECDSA_Signature* signature) : m_signature(signature)
- {}
- private:
- ECDSA_Signature* m_signature;
+
+ ECDSA_PublicKey const& operator= (ECDSA_PublicKey const& rhs);
+
+ ECDSA_PublicKey(ECDSA_PublicKey const& other);
+
+ /**
+ * Set the domain parameters of this key. This function has to be
+ * used when a key encoded without domain parameters was decoded into
+ * this key. Otherwise it will not be able to verify a signature.
+ * @param dom_pars the domain_parameters associated with this key
+ * @throw Invalid_Argument if the point was found not to be satisfying the
+ * curve equation of the provided domain parameters
+ * or if this key already has domain parameters set
+ * and these are differing from those given as the parameter
+ */
+ void set_domain_parameters(EC_Domain_Params const& dom_pars);
+
+ /**
+ * 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;
+
+ protected:
+ void X509_load_hook();
+ virtual void set_all_values(ECDSA_PublicKey const& other);
+
+ ECDSA_Core m_ecdsa_core;
};
-class ECDSA_Signature_Encoder
+/**
+* This class represents ECDSA Private Keys
+*/
+class ECDSA_PrivateKey : public ECDSA_PublicKey,
+ public EC_PrivateKey,
+ public PK_Signing_Key
{
public:
- MemoryVector<byte> signature_bits() const
- {
- return DER_Encoder()
- .start_cons(SEQUENCE)
- .encode(m_signature->m_r)
- .encode(m_signature->m_s)
- .end_cons()
- .get_contents();
- }
- ECDSA_Signature_Encoder(const ECDSA_Signature* signature) : m_signature(signature)
+ //ctors
+ /**
+ * Default constructor. Use this one if you want to later fill this object with data
+ * from an encoded key.
+ */
+ ECDSA_PrivateKey()
{}
+ /**
+ * Generate a new private key
+ * @param the domain parameters to used for this key
+ */
+ ECDSA_PrivateKey(RandomNumberGenerator& rng,
+ const EC_Domain_Params& domain);
+
+ ECDSA_PrivateKey(ECDSA_PrivateKey const& other);
+ ECDSA_PrivateKey const& operator= (ECDSA_PrivateKey const& 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;
+ protected:
+ virtual void set_all_values ( ECDSA_PrivateKey const& other );
private:
- const ECDSA_Signature* m_signature;
+ void PKCS8_load_hook(bool = false);
};
-ECDSA_Signature const decode_seq(MemoryRegion<byte> const& seq);
-ECDSA_Signature const decode_concatenation(MemoryRegion<byte> const& concatenation);
-
}
#endif
diff --git a/src/pubkey/ecdsa/ecdsa_sig.cpp b/src/pubkey/ecdsa/ecdsa_sig.cpp
new file mode 100644
index 000000000..abe1c631b
--- /dev/null
+++ b/src/pubkey/ecdsa/ecdsa_sig.cpp
@@ -0,0 +1,72 @@
+
+#include <botan/ecdsa_sig.h>
+#include <memory>
+
+namespace Botan {
+
+ECDSA_Signature::ECDSA_Signature(const BigInt& r, const BigInt& s)
+ : m_r(r),
+ m_s(s)
+ {}
+
+ECDSA_Signature::ECDSA_Signature(ECDSA_Signature const& other)
+ : m_r(other.m_r),
+ m_s(other.m_s)
+ {}
+
+ECDSA_Signature const& ECDSA_Signature::operator=(ECDSA_Signature const& other)
+ {
+ m_r = other.m_r;
+ m_s = other.m_s;
+ return *this;
+ }
+
+bool operator== ( ECDSA_Signature const& lhs, ECDSA_Signature const& rhs )
+ {
+ return (lhs.get_r() == rhs.get_r() && lhs.get_s() == rhs.get_s());
+ }
+
+ECDSA_Signature_Decoder* ECDSA_Signature::x509_decoder()
+ {
+ return new ECDSA_Signature_Decoder(this);
+ }
+
+ECDSA_Signature_Encoder* ECDSA_Signature::x509_encoder() const
+ {
+ return new ECDSA_Signature_Encoder(this);
+ }
+SecureVector<byte> const ECDSA_Signature::get_concatenation() const
+ {
+ u32bit enc_len = m_r > m_s ? m_r.bytes() : m_s.bytes(); // use the larger
+ SecureVector<byte> sv_r = BigInt::encode_1363 ( m_r, enc_len );
+ SecureVector<byte> sv_s = BigInt::encode_1363 ( m_s, enc_len );
+ SecureVector<byte> result(sv_r);
+ result.append(sv_s);
+ return result;
+ }
+
+ECDSA_Signature const decode_seq(MemoryRegion<byte> const& seq)
+ {
+ ECDSA_Signature sig;
+ std::auto_ptr<ECDSA_Signature_Decoder> dec(sig.x509_decoder());
+ dec->signature_bits(seq);
+ return sig;
+ }
+
+ECDSA_Signature const decode_concatenation(MemoryRegion<byte> const& concatenation)
+ {
+ if(concatenation.size() % 2 != 0)
+ {
+ throw Invalid_Argument("Erroneous length of signature");
+ }
+ u32bit rs_len = concatenation.size()/2;
+ SecureVector<byte> sv_r;
+ SecureVector<byte> sv_s;
+ sv_r.set(concatenation.begin(), rs_len);
+ sv_s.set(&concatenation[rs_len], rs_len);
+ BigInt r = BigInt::decode ( sv_r, sv_r.size());
+ BigInt s = BigInt::decode (sv_s, sv_s.size());
+ return ECDSA_Signature(r, s);
+ }
+
+}
diff --git a/src/pubkey/ecdsa/ecdsa_sig.h b/src/pubkey/ecdsa/ecdsa_sig.h
new file mode 100644
index 000000000..c92a24a7f
--- /dev/null
+++ b/src/pubkey/ecdsa/ecdsa_sig.h
@@ -0,0 +1,99 @@
+/*************************************************
+* ECDSA Header File *
+* (C) 2007 Falko Strenzke, FlexSecure GmbH *
+* (C) 2008 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_ECDSA_SIGNATURE_H__
+#define BOTAN_ECDSA_SIGNATURE_H__
+
+#include <botan/bigint.h>
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
+
+namespace Botan {
+
+class ECDSA_Signature_Decoder;
+class ECDSA_Signature_Encoder;
+
+class ECDSA_Signature
+ {
+ friend class ECDSA_Signature_Decoder;
+ friend class ECDSA_Signature_Encoder;
+ public:
+ ECDSA_Signature(const BigInt& r, const BigInt& s);
+ ECDSA_Signature()
+ {}
+ ;
+ ECDSA_Signature(ECDSA_Signature const& other);
+ ECDSA_Signature const& operator=(ECDSA_Signature const& other);
+
+ BigInt const get_r() const
+ {
+ return m_r;
+ }
+ BigInt const get_s() const
+ {
+ return m_s;
+ }
+ /**
+ * return the r||s
+ */
+ SecureVector<byte> const get_concatenation() const;
+
+
+ ECDSA_Signature_Encoder* x509_encoder() const;
+ ECDSA_Signature_Decoder* x509_decoder();
+ private:
+ BigInt m_r;
+ BigInt m_s;
+ };
+
+bool operator== ( ECDSA_Signature const& lhs, ECDSA_Signature const& rhs );
+inline bool operator!= ( ECDSA_Signature const& lhs, ECDSA_Signature const& rhs )
+ {
+ return !operator== ( lhs, rhs );
+ }
+
+class ECDSA_Signature_Decoder
+ {
+ public:
+ void signature_bits(const MemoryRegion<byte>& bits)
+ {
+ BER_Decoder(bits)
+ .start_cons(SEQUENCE)
+ .decode(m_signature->m_r)
+ .decode(m_signature->m_s)
+ .verify_end()
+ .end_cons();
+ }
+ ECDSA_Signature_Decoder(ECDSA_Signature* signature) : m_signature(signature)
+ {}
+ private:
+ ECDSA_Signature* m_signature;
+ };
+
+class ECDSA_Signature_Encoder
+ {
+ public:
+ MemoryVector<byte> signature_bits() const
+ {
+ return DER_Encoder()
+ .start_cons(SEQUENCE)
+ .encode(m_signature->m_r)
+ .encode(m_signature->m_s)
+ .end_cons()
+ .get_contents();
+ }
+ ECDSA_Signature_Encoder(const ECDSA_Signature* signature) : m_signature(signature)
+ {}
+ private:
+ const ECDSA_Signature* m_signature;
+ };
+
+ECDSA_Signature const decode_seq(MemoryRegion<byte> const& seq);
+ECDSA_Signature const decode_concatenation(MemoryRegion<byte> const& concatenation);
+
+}
+
+#endif
diff --git a/src/pubkey/ecdsa/eckaeg.cpp b/src/pubkey/ecdsa/eckaeg.cpp
new file mode 100644
index 000000000..dcd30499a
--- /dev/null
+++ b/src/pubkey/ecdsa/eckaeg.cpp
@@ -0,0 +1,135 @@
+/*************************************************
+* ECKAEG implemenation *
+* (C) 2007 Manuel Hartl, FlexSecure GmbH *
+* 2007 Falko Strenzke, FlexSecure GmbH *
+* 2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/eckaeg.h>
+#include <botan/numthry.h>
+#include <botan/util.h>
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
+#include <botan/secmem.h>
+#include <botan/point_gfp.h>
+
+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;
+ m_enc_public_point = other.m_enc_public_point;
+ 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 );
+ }
+ECKAEG_PublicKey::ECKAEG_PublicKey ( EC_Domain_Params const& dom_par, PointGFp const& public_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 );
+ }
+
+
+/*********************************
+* ECKAEG_PrivateKey *
+*********************************/
+void ECKAEG_PrivateKey::affirm_init() const // virtual
+ {
+ EC_PrivateKey::affirm_init();
+ }
+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;
+ m_enc_public_point = other.m_enc_public_point;
+ 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_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)
+ {
+ set_all_values(rhs);
+ return *this;
+ }
+
+/**
+* Derive a key
+*/
+SecureVector<byte> ECKAEG_PrivateKey::derive_key(const Public_Key& key) const
+ {
+ affirm_init();
+
+ const EC_PublicKey * p_ec_pk = dynamic_cast<const EC_PublicKey*>(&key);
+ if(!p_ec_pk)
+ {
+ throw Invalid_Argument("ECKAEG_PrivateKey::derive_key(): argument must be an EC_PublicKey");
+ }
+ p_ec_pk->affirm_init();
+ return m_eckaeg_core.agree ( p_ec_pk->get_public_point() );
+ }
+
+}
diff --git a/src/pubkey/ecdsa/eckaeg.h b/src/pubkey/ecdsa/eckaeg.h
new file mode 100644
index 000000000..7ab286424
--- /dev/null
+++ b/src/pubkey/ecdsa/eckaeg.h
@@ -0,0 +1,121 @@
+/*************************************************
+* ECKAEG Header File *
+* (C) 2007 Falko Strenzke, FlexSecure GmbH *
+* Manuel hartl, FlexSecure GmbH *
+* (C) 2008 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_ECKAEG_KEY_H__
+#define BOTAN_ECKAEG_KEY_H__
+
+#include <botan/ecc_key.h>
+
+namespace Botan {
+
+/**
+* This class represents ECKAEG Public Keys.
+*/
+class ECKAEG_PublicKey : public virtual EC_PublicKey
+ {
+ public:
+ /**
+ * Default constructor. Use this one if you want to later fill this object with data
+ * from an encoded key.
+ */
+ ECKAEG_PublicKey()
+ {};
+ /**
+ * Construct a public key from a given public point.
+ * @param dom_par the domain parameters associated with this key
+ * @param public_point the public point defining this key
+ */
+ ECKAEG_PublicKey(EC_Domain_Params const& dom_par, Botan::PointGFp const& 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;
+ protected:
+ void X509_load_hook();
+ virtual void set_all_values ( ECKAEG_PublicKey const& other );
+
+ ECKAEG_Core m_eckaeg_core;
+ };
+
+/**
+* This class represents ECKAEG Private Keys.
+*/
+class ECKAEG_PrivateKey : public ECKAEG_PublicKey, public EC_PrivateKey, public PK_Key_Agreement_Key
+ {
+ public:
+ /**
+ * Generate a new private key
+ * @param the domain parameters to used for this key
+ */
+ ECKAEG_PrivateKey(RandomNumberGenerator& rng,
+ EC_Domain_Params const& 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);
+ }
+ /**
+ * 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);
+
+ void PKCS8_load_hook(bool = false);
+
+ /**
+ * Derive a shared key with the other partys public key.
+ * @param pub_key the other partys public key
+ */
+ SecureVector<byte> derive_key(const Public_Key& pub_key) 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;
+
+ protected:
+ virtual void set_all_values ( ECKAEG_PrivateKey const& other );
+ };
+
+}
+
+#endif
diff --git a/src/pubkey/ecdsa/info.txt b/src/pubkey/ecdsa/info.txt
index 6c3aec8c6..f6f3400f8 100644
--- a/src/pubkey/ecdsa/info.txt
+++ b/src/pubkey/ecdsa/info.txt
@@ -14,11 +14,15 @@ pubkey
</requires>
<add>
-ec.cpp
-ec.h
+ec_key.cpp
+ec_key.h
ecc_core.cpp
ecc_core.h
ecc_op.h
ecdsa.cpp
ecdsa.h
+ecdsa_sig.cpp
+ecdsa_sig.h
+eckaeg.cpp
+eckaeg.h
</add>