aboutsummaryrefslogtreecommitdiffstats
path: root/src/pubkey/ecdsa
diff options
context:
space:
mode:
Diffstat (limited to 'src/pubkey/ecdsa')
-rw-r--r--src/pubkey/ecdsa/ecdsa.cpp81
-rw-r--r--src/pubkey/ecdsa/ecdsa.h97
2 files changed, 100 insertions, 78 deletions
diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp
index d245543f7..afca6cc73 100644
--- a/src/pubkey/ecdsa/ecdsa.cpp
+++ b/src/pubkey/ecdsa/ecdsa.cpp
@@ -11,64 +11,71 @@
namespace Botan {
-bool ECDSA_PublicKey::verify(const byte msg[], u32bit msg_len,
- const byte sig[], u32bit sig_len) const
+ECDSA_Signature_Operation::ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa) :
+ base_point(ecdsa.domain().get_base_point()),
+ order(ecdsa.domain().get_order()),
+ x(ecdsa.private_value())
{
- const BigInt& n = domain().get_order();
+ }
- if(n == 0)
- throw Invalid_State("ECDSA_PublicKey::verify: Not initialized");
+SecureVector<byte>
+ECDSA_Signature_Operation::sign(const byte msg[], u32bit msg_len,
+ RandomNumberGenerator& rng)
+ {
+ rng.add_entropy(msg, msg_len);
- if(sig_len != n.bytes()*2)
- return false;
+ BigInt k;
+ k.randomize(rng, order.bits());
+
+ while(k >= order)
+ k.randomize(rng, order.bits() - 1);
BigInt e(msg, msg_len);
- BigInt r(sig, sig_len / 2);
- BigInt s(sig + sig_len / 2, sig_len / 2);
+ PointGFp k_times_P = base_point * k;
+ BigInt r = k_times_P.get_affine_x() % order;
- if(r < 0 || r >= n || s < 0 || s >= n)
- return false;
+ if(r == 0)
+ throw Internal_Error("ECDSA_Signature_Operation: r was zero");
- BigInt w = inverse_mod(s, n);
+ BigInt k_inv = inverse_mod(k, order);
- PointGFp R = w * (e * domain().get_base_point() + r*public_point());
- if(R.is_zero())
- return false;
+ BigInt s = (((r * x) + e) * k_inv) % order;
- return (R.get_affine_x() % n == r);
+ SecureVector<byte> output(2*order.bytes());
+ r.binary_encode(output + (output.size() / 2 - r.bytes()));
+ s.binary_encode(output + (output.size() - s.bytes()));
+ return output;
}
-SecureVector<byte> ECDSA_PrivateKey::sign(const byte msg[],
- u32bit msg_len,
- RandomNumberGenerator& rng) const
+ECDSA_Verification_Operation::ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa) :
+ base_point(ecdsa.domain().get_base_point()),
+ public_point(ecdsa.public_point()),
+ order(ecdsa.domain().get_order())
{
- const BigInt& n = domain().get_order();
-
- 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);
+bool ECDSA_Verification_Operation::verify(const byte msg[], u32bit msg_len,
+ const byte sig[], u32bit sig_len)
+ {
+ if(sig_len != order.bytes()*2)
+ return false;
BigInt e(msg, msg_len);
- PointGFp k_times_P = domain().get_base_point() * k;
- BigInt r = k_times_P.get_affine_x() % n;
+ BigInt r(sig, sig_len / 2);
+ BigInt s(sig + sig_len / 2, sig_len / 2);
- if(r == 0)
- throw Internal_Error("Default_ECDSA_Op::sign: r was zero");
+ if(r < 0 || r >= order || s < 0 || s >= order)
+ return false;
- BigInt k_inv = inverse_mod(k, n);
+ BigInt w = inverse_mod(s, order);
- BigInt s = (((r * private_value()) + e) * k_inv) % n;
+ PointGFp R = w * (e * base_point + r * public_point);
+ if(R.is_zero())
+ return false;
- 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;
+ return (R.get_affine_x() % order == r);
}
}
diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h
index e7f29b600..e20a234fc 100644
--- a/src/pubkey/ecdsa/ecdsa.h
+++ b/src/pubkey/ecdsa/ecdsa.h
@@ -11,18 +11,31 @@
#define BOTAN_ECDSA_KEY_H__
#include <botan/ecc_key.h>
+#include <botan/pk_ops.h>
namespace Botan {
/**
* This class represents ECDSA Public Keys.
*/
-class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey,
- public PK_Verifying_wo_MR_Key
+class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey
{
public:
/**
+ * 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(const EC_Domain_Params& dom_par,
+ const PointGFp& public_point) :
+ EC_PublicKey(dom_par, public_point) {}
+
+ ECDSA_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ EC_PublicKey(alg_id, key_bits) {}
+
+ /**
* Get this keys algorithm name.
* @result this keys algorithm name ("ECDSA")
*/
@@ -40,46 +53,21 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey,
u32bit message_part_size() const
{ return domain().get_order().bytes(); }
- /**
- * 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.
- */
+ protected:
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(const EC_Domain_Params& dom_par,
- const PointGFp& public_point) :
- EC_PublicKey(dom_par, public_point) {}
-
};
/**
* This class represents ECDSA Private Keys
*/
class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey,
- public EC_PrivateKey,
- public PK_Signing_Key
+ public EC_PrivateKey
{
public:
- /**
- * Default constructor. Use this one if you want to later fill
- * this object with data from an encoded key.
- */
- ECDSA_PrivateKey() {}
+
+ ECDSA_PrivateKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ EC_PrivateKey(alg_id, key_bits) {}
/**
* Generate a new private key
@@ -96,16 +84,43 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey,
*/
ECDSA_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) :
EC_PrivateKey(domain, x) {}
+ };
- /**
- * 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
- */
+class BOTAN_DLL ECDSA_Signature_Operation : public PK_Ops::Signature
+ {
+ public:
+ ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa);
+
+ SecureVector<byte> sign(const byte msg[], u32bit msg_len,
+ RandomNumberGenerator& rng);
+
+ u32bit message_parts() const { return 2; }
+ u32bit message_part_size() const { return order.bytes(); }
+ u32bit max_input_bits() const { return order.bits(); }
+
+ private:
+ const PointGFp& base_point;
+ const BigInt& order;
+ const BigInt& x;
+ };
+
+class BOTAN_DLL ECDSA_Verification_Operation : public PK_Ops::Verification
+ {
+ public:
+ ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa);
+
+ u32bit message_parts() const { return 2; }
+ u32bit message_part_size() const { return order.bytes(); }
+ u32bit max_input_bits() const { return order.bits(); }
+
+ bool with_recovery() const { return false; }
- SecureVector<byte> sign(const byte message[], u32bit mess_len,
- RandomNumberGenerator& rng) const;
+ bool verify(const byte msg[], u32bit msg_len,
+ const byte sig[], u32bit sig_len);
+ private:
+ const PointGFp& base_point;
+ const PointGFp& public_point;
+ const BigInt& order;
};
}