diff options
Diffstat (limited to 'src/pubkey/ecdsa')
-rw-r--r-- | src/pubkey/ecdsa/ecdsa.cpp | 75 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa.h | 9 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa_core.cpp | 58 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa_core.h | 46 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa_op.cpp | 74 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa_op.h | 64 |
6 files changed, 45 insertions, 281 deletions
diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp index 7afbf96af..f5ded5aa6 100644 --- a/src/pubkey/ecdsa/ecdsa.cpp +++ b/src/pubkey/ecdsa/ecdsa.cpp @@ -9,17 +9,21 @@ #include <botan/ecdsa.h> -#include <assert.h> - namespace Botan { +ECDSA_PublicKey::ECDSA_PublicKey(const EC_Domain_Params& dom_par, + const PointGFp& pub_point) + { + domain_encoding = EC_DOMPAR_ENC_EXPLICIT; + domain_params = dom_par; + public_key = pub_point; + } + ECDSA_PrivateKey::ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Domain_Params& dom_pars) { domain_params = dom_pars; generate_private_key(rng); - - ecdsa_core = ECDSA_Core(domain(), private_value(), public_point()); } ECDSA_PrivateKey::ECDSA_PrivateKey(const EC_Domain_Params& dom_pars, @@ -38,36 +42,34 @@ ECDSA_PrivateKey::ECDSA_PrivateKey(const EC_Domain_Params& dom_pars, { throw Invalid_State("ECDSA key generation failed"); } - - 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 { - return ecdsa_core.verify(msg, msg_len, sig, sig_len); - } + const BigInt& n = domain().get_order(); -ECDSA_PublicKey::ECDSA_PublicKey(const EC_Domain_Params& dom_par, - const PointGFp& pub_point) - { - domain_encoding = EC_DOMPAR_ENC_EXPLICIT; - domain_params = dom_par; - public_key = pub_point; + if(n == 0) + throw Invalid_State("ECDSA_PublicKey::verify: Not initialized"); - ecdsa_core = ECDSA_Core(domain(), 0, public_point()); - } + if(sig_len != n.bytes()*2) + return false; -void ECDSA_PublicKey::X509_load_hook() - { - EC_PublicKey::X509_load_hook(); - ecdsa_core = ECDSA_Core(domain(), 0, public_point()); - } + BigInt e(msg, msg_len); -void ECDSA_PrivateKey::PKCS8_load_hook(bool generated) - { - EC_PrivateKey::PKCS8_load_hook(generated); - ecdsa_core = ECDSA_Core(domain(), private_value(), public_point()); + BigInt r(sig, sig_len / 2); + BigInt s(sig + sig_len / 2, sig_len / 2); + + if(r < 0 || r >= n || s < 0 || s >= n) + return false; + + BigInt w = inverse_mod(s, n); + + PointGFp R = w * (e * domain().get_base_point() + r*public_point()); + if(R.is_zero()) + return false; + + return (R.get_affine_x() % n == r); } SecureVector<byte> ECDSA_PrivateKey::sign(const byte msg[], @@ -76,17 +78,30 @@ SecureVector<byte> ECDSA_PrivateKey::sign(const byte msg[], { const BigInt& n = domain().get_order(); - if(n == 0) - throw Invalid_State("ECDSA_PrivateKey: Not initialized"); - - assert(n.bits() >= 1); + if(n == 0 || private_value() == 0) + throw Invalid_State("ECDSA_PrivateKey::sign: Not initialized"); BigInt k; do k.randomize(rng, n.bits()-1); while(k >= n); - return ecdsa_core.sign(msg, msg_len, k); + BigInt e(msg, msg_len); + + PointGFp k_times_P = domain().get_base_point() * k; + BigInt r = k_times_P.get_affine_x() % n; + + if(r == 0) + throw Internal_Error("Default_ECDSA_Op::sign: r was zero"); + + BigInt k_inv = inverse_mod(k, n); + + BigInt s = (((r * private_value()) + e) * k_inv) % n; + + SecureVector<byte> output(2*n.bytes()); + r.binary_encode(output + (output.size() / 2 - r.bytes())); + s.binary_encode(output + (output.size() - s.bytes())); + return output; } } diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h index bc767d8ad..447bc3758 100644 --- a/src/pubkey/ecdsa/ecdsa.h +++ b/src/pubkey/ecdsa/ecdsa.h @@ -11,7 +11,6 @@ #define BOTAN_ECDSA_KEY_H__ #include <botan/ecc_key.h> -#include <botan/ecdsa_core.h> namespace Botan { @@ -64,11 +63,6 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey, */ ECDSA_PublicKey(const EC_Domain_Params& dom_par, const PointGFp& public_point); // sets core - - protected: - void X509_load_hook(); - - ECDSA_Core ecdsa_core; }; /** @@ -108,9 +102,6 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, SecureVector<byte> sign(const byte message[], u32bit mess_len, RandomNumberGenerator& rng) const; - - private: - void PKCS8_load_hook(bool = false); }; } diff --git a/src/pubkey/ecdsa/ecdsa_core.cpp b/src/pubkey/ecdsa/ecdsa_core.cpp deleted file mode 100644 index d661963f2..000000000 --- a/src/pubkey/ecdsa/ecdsa_core.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -* ECDSA Core -* (C) 1999-2010 Jack Lloyd -* (C) 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/ecdsa_core.h> -#include <botan/internal/pk_engine.h> - -namespace Botan { - -/* -* ECDSA Operation -*/ -bool ECDSA_Core::verify(const byte signature[], u32bit sig_len, - const byte message[], u32bit mess_len) const - { - if(op == 0) - throw Invalid_State("ECDSA_Core: uninitialized"); - - return op->verify(signature, sig_len, message, mess_len); - } - -SecureVector<byte> ECDSA_Core::sign(const byte message[], - u32bit mess_len, - const BigInt& k) const - { - if(op == 0) - throw Invalid_State("ECDSA_Core: uninitialized"); - - return op->sign(message, mess_len, k); - } - -ECDSA_Core& ECDSA_Core::operator=(const ECDSA_Core& core) - { - delete op; - if(core.op) - op = core.op->clone(); - return (*this); - } - -ECDSA_Core::ECDSA_Core(const ECDSA_Core& core) - { - op = 0; - if(core.op) - op = core.op->clone(); - } - -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/ecdsa/ecdsa_core.h b/src/pubkey/ecdsa/ecdsa_core.h deleted file mode 100644 index c6583a86f..000000000 --- a/src/pubkey/ecdsa/ecdsa_core.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* ECDSA Core -* (C) 1999-2007 Jack Lloyd -* (C) 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ECDSA_CORE_H__ -#define BOTAN_ECDSA_CORE_H__ - -#include <botan/ecdsa_op.h> -#include <botan/ec_dompar.h> - -namespace Botan { - -/* -* ECDSA Core -*/ -class BOTAN_DLL ECDSA_Core - { - public: - bool verify(const byte signature[], u32bit sig_len, - const byte message[], u32bit mess_len) const; - - SecureVector<byte> sign(const byte message[], u32bit mess_len, - const BigInt& k) const; - - ECDSA_Core& operator=(const ECDSA_Core&); - - ECDSA_Core() { op = 0; } - - ECDSA_Core(const ECDSA_Core&); - - ECDSA_Core(const EC_Domain_Params& dom_pars, - const BigInt& priv_key, - const PointGFp& pub_key); - - ~ECDSA_Core() { delete op; } - private: - ECDSA_Operation* op; - }; - -} - -#endif diff --git a/src/pubkey/ecdsa/ecdsa_op.cpp b/src/pubkey/ecdsa/ecdsa_op.cpp deleted file mode 100644 index dd92ac5c0..000000000 --- a/src/pubkey/ecdsa/ecdsa_op.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* -* ECDSA Operation -* (C) 2007 FlexSecure GmbH -* 2008-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/ecdsa_op.h> -#include <botan/numthry.h> - -namespace Botan { - -Default_ECDSA_Op::Default_ECDSA_Op(const EC_Domain_Params& domain, - const BigInt& priv, - const PointGFp& pub) : - dom_pars(domain), mod_n(dom_pars.get_order()), - pub_key(pub), priv_key(priv) - { - } - -bool Default_ECDSA_Op::verify(const byte msg[], u32bit msg_len, - const byte sig[], u32bit sig_len) const - { - const BigInt& n = dom_pars.get_order(); - - if(sig_len != n.bytes()*2) - return false; - - BigInt e(msg, msg_len); - - BigInt r(sig, sig_len / 2); - BigInt s(sig + sig_len / 2, sig_len / 2); - - if(r < 0 || r >= n || s < 0 || s >= n) - return false; - - BigInt w = inverse_mod(s, n); - - PointGFp R = w * (e * dom_pars.get_base_point() + r*pub_key); - if(R.is_zero()) - return false; - - return (mod_n.reduce(R.get_affine_x()) == r); - } - -SecureVector<byte> Default_ECDSA_Op::sign(const byte msg[], u32bit msg_len, - const BigInt& k) const - { - if(priv_key == 0) - throw Internal_Error("Default_ECDSA_Op::sign(): no private key"); - - const BigInt& n = dom_pars.get_order(); - - BigInt e(msg, msg_len); - - PointGFp k_times_P = dom_pars.get_base_point() * k; - BigInt r = mod_n.reduce(k_times_P.get_affine_x()); - - if(r == 0) - throw Internal_Error("Default_ECDSA_Op::sign: r was zero"); - - BigInt k_inv = inverse_mod(k, n); - - BigInt s = mod_n.reduce(mod_n.multiply(r, priv_key) + e); - s = mod_n.multiply(s, k_inv); - - SecureVector<byte> output(2*n.bytes()); - r.binary_encode(output + (output.size() / 2 - r.bytes())); - s.binary_encode(output + (output.size() - s.bytes())); - return output; - } - -} diff --git a/src/pubkey/ecdsa/ecdsa_op.h b/src/pubkey/ecdsa/ecdsa_op.h deleted file mode 100644 index 3a492ccf4..000000000 --- a/src/pubkey/ecdsa/ecdsa_op.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* ECDSA Operations -* (C) 1999-2008 Jack Lloyd -* (C) 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ECDSA_OPERATIONS_H__ -#define BOTAN_ECDSA_OPERATIONS_H__ - -#include <botan/ec_dompar.h> -#include <botan/reducer.h> - -namespace Botan { - -/* -* ECDSA Operation -*/ -class BOTAN_DLL ECDSA_Operation - { - public: - virtual bool verify(const byte msg[], u32bit msg_len, - const byte sig[], u32bit sig_len) const = 0; - - virtual SecureVector<byte> sign(const byte msg[], u32bit msg_len, - const BigInt& k) const = 0; - - virtual ECDSA_Operation* clone() const = 0; - - virtual ~ECDSA_Operation() {} - }; - -/* -* Default ECDSA operation -*/ -class BOTAN_DLL Default_ECDSA_Op : public ECDSA_Operation - { - public: - bool verify(const byte sig[], u32bit sig_len, - const byte msg[], u32bit msg_len) const; - - SecureVector<byte> sign(const byte msg[], u32bit msg_len, - const BigInt& k) const; - - ECDSA_Operation* clone() const - { - return new Default_ECDSA_Op(*this); - } - - Default_ECDSA_Op(const EC_Domain_Params& dom_pars, - const BigInt& priv_key, - const PointGFp& pub_key); - private: - EC_Domain_Params dom_pars; - Modular_Reducer mod_n; - - PointGFp pub_key; - BigInt priv_key; - }; - -} - -#endif |