aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/ecc_key
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pubkey/ecc_key')
-rw-r--r--src/lib/pubkey/ecc_key/ecc_key.cpp148
-rw-r--r--src/lib/pubkey/ecc_key/ecc_key.h121
-rw-r--r--src/lib/pubkey/ecc_key/info.txt10
3 files changed, 279 insertions, 0 deletions
diff --git a/src/lib/pubkey/ecc_key/ecc_key.cpp b/src/lib/pubkey/ecc_key/ecc_key.cpp
new file mode 100644
index 000000000..c9d4d62fe
--- /dev/null
+++ b/src/lib/pubkey/ecc_key/ecc_key.cpp
@@ -0,0 +1,148 @@
+/*
+* ECC Key implemenation
+* (C) 2007 Manuel Hartl, FlexSecure GmbH
+* Falko Strenzke, FlexSecure GmbH
+* 2008-2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/ecc_key.h>
+#include <botan/x509_key.h>
+#include <botan/numthry.h>
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
+#include <botan/secmem.h>
+#include <botan/point_gfp.h>
+
+namespace Botan {
+
+size_t EC_PublicKey::estimated_strength() const
+ {
+ return domain().get_curve().get_p().bits() / 2;
+ }
+
+EC_PublicKey::EC_PublicKey(const EC_Group& dom_par,
+ const PointGFp& pub_point) :
+ domain_params(dom_par), public_key(pub_point),
+ domain_encoding(EC_DOMPAR_ENC_EXPLICIT)
+ {
+ if(domain().get_curve() != public_point().get_curve())
+ throw Invalid_Argument("EC_PublicKey: curve mismatch in constructor");
+ }
+
+EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id,
+ const secure_vector<byte>& key_bits)
+ {
+ domain_params = EC_Group(alg_id.parameters);
+ domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
+
+ public_key = OS2ECP(key_bits, domain().get_curve());
+ }
+
+bool EC_PublicKey::check_key(RandomNumberGenerator&,
+ bool) const
+ {
+ return public_point().on_the_curve();
+ }
+
+AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const
+ {
+ return AlgorithmIdentifier(get_oid(), DER_domain());
+ }
+
+std::vector<byte> EC_PublicKey::x509_subject_public_key() const
+ {
+ return unlock(EC2OSP(public_point(), PointGFp::COMPRESSED));
+ }
+
+void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form)
+ {
+ if(form != EC_DOMPAR_ENC_EXPLICIT &&
+ form != EC_DOMPAR_ENC_IMPLICITCA &&
+ form != EC_DOMPAR_ENC_OID)
+ throw Invalid_Argument("Invalid encoding form for EC-key object specified");
+
+ 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");
+
+ domain_encoding = form;
+ }
+
+const BigInt& EC_PrivateKey::private_value() const
+ {
+ if(private_key == 0)
+ throw Invalid_State("EC_PrivateKey::private_value - uninitialized");
+
+ return private_key;
+ }
+
+/**
+* EC_PrivateKey constructor
+*/
+EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng,
+ const EC_Group& ec_group,
+ const BigInt& x)
+ {
+ domain_params = ec_group;
+ domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
+
+ if(x == 0)
+ private_key = BigInt::random_integer(rng, 1, domain().get_order());
+ else
+ private_key = x;
+
+ public_key = domain().get_base_point() * private_key;
+
+ BOTAN_ASSERT(public_key.on_the_curve(),
+ "Generated public key point was on the curve");
+ }
+
+secure_vector<byte> EC_PrivateKey::pkcs8_private_key() const
+ {
+ return DER_Encoder()
+ .start_cons(SEQUENCE)
+ .encode(static_cast<size_t>(1))
+ .encode(BigInt::encode_1363(private_key, private_key.bytes()),
+ OCTET_STRING)
+ .end_cons()
+ .get_contents();
+ }
+
+EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id,
+ const secure_vector<byte>& key_bits)
+ {
+ domain_params = EC_Group(alg_id.parameters);
+ domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
+
+ OID key_parameters;
+ secure_vector<byte> public_key_bits;
+
+ BER_Decoder(key_bits)
+ .start_cons(SEQUENCE)
+ .decode_and_check<size_t>(1, "Unknown version code for ECC key")
+ .decode_octet_string_bigint(private_key)
+ .decode_optional(key_parameters, ASN1_Tag(0), PRIVATE)
+ .decode_optional_string(public_key_bits, BIT_STRING, 1, PRIVATE)
+ .end_cons();
+
+ if(!key_parameters.empty() && key_parameters != alg_id.oid)
+ throw Decoding_Error("EC_PrivateKey - inner and outer OIDs did not match");
+
+ if(public_key_bits.empty())
+ {
+ public_key = domain().get_base_point() * private_key;
+
+ BOTAN_ASSERT(public_key.on_the_curve(),
+ "Public point derived from loaded key was on the curve");
+ }
+ else
+ {
+ public_key = OS2ECP(public_key_bits, domain().get_curve());
+ // OS2ECP verifies that the point is on the curve
+ }
+ }
+
+}
diff --git a/src/lib/pubkey/ecc_key/ecc_key.h b/src/lib/pubkey/ecc_key/ecc_key.h
new file mode 100644
index 000000000..de980608a
--- /dev/null
+++ b/src/lib/pubkey/ecc_key/ecc_key.h
@@ -0,0 +1,121 @@
+/*
+* ECDSA
+* (C) 2007 Falko Strenzke, FlexSecure GmbH
+* Manuel Hartl, FlexSecure GmbH
+* (C) 2008-2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_ECC_PUBLIC_KEY_BASE_H__
+#define BOTAN_ECC_PUBLIC_KEY_BASE_H__
+
+#include <botan/ec_group.h>
+#include <botan/pk_keys.h>
+#include <botan/x509_key.h>
+#include <botan/pkcs8.h>
+
+namespace Botan {
+
+/**
+* This class represents abstract ECC 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 BOTAN_DLL EC_PublicKey : public virtual Public_Key
+ {
+ public:
+ EC_PublicKey(const EC_Group& dom_par,
+ const PointGFp& pub_point);
+
+ EC_PublicKey(const AlgorithmIdentifier& alg_id,
+ const secure_vector<byte>& key_bits);
+
+ /**
+ * 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 { return public_key; }
+
+ AlgorithmIdentifier algorithm_identifier() const;
+
+ std::vector<byte> x509_subject_public_key() const;
+
+ bool check_key(RandomNumberGenerator& rng,
+ bool strong) const;
+
+ /**
+ * 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
+ */
+ const EC_Group& domain() const { return domain_params; }
+
+ /**
+ * Set the domain parameter encoding to be used when encoding this key.
+ * @param enc the encoding to use
+ */
+ void set_parameter_encoding(EC_Group_Encoding enc);
+
+ /**
+ * Return the DER encoding of this keys domain in whatever format
+ * is preset for this particular key
+ */
+ std::vector<byte> DER_domain() const
+ { return domain().DER_encode(domain_format()); }
+
+ /**
+ * Get the domain parameter encoding to be used when encoding this key.
+ * @result the encoding to use
+ */
+ EC_Group_Encoding domain_format() const
+ { return domain_encoding; }
+
+ size_t estimated_strength() const override;
+
+ protected:
+ EC_PublicKey() : domain_encoding(EC_DOMPAR_ENC_EXPLICIT) {}
+
+ EC_Group domain_params;
+ PointGFp public_key;
+ EC_Group_Encoding domain_encoding;
+ };
+
+/**
+* This abstract class represents ECC private keys
+*/
+class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey,
+ public virtual Private_Key
+ {
+ public:
+ EC_PrivateKey(RandomNumberGenerator& rng,
+ const EC_Group& domain,
+ const BigInt& private_key);
+
+ EC_PrivateKey(const AlgorithmIdentifier& alg_id,
+ const secure_vector<byte>& key_bits);
+
+ secure_vector<byte> pkcs8_private_key() const;
+
+ /**
+ * Get the private key value of this key object.
+ * @result the private key value of this key object
+ */
+ const BigInt& private_value() const;
+ protected:
+ EC_PrivateKey() {}
+
+ BigInt private_key;
+ };
+
+}
+
+#endif
diff --git a/src/lib/pubkey/ecc_key/info.txt b/src/lib/pubkey/ecc_key/info.txt
new file mode 100644
index 000000000..6d6d5f0e9
--- /dev/null
+++ b/src/lib/pubkey/ecc_key/info.txt
@@ -0,0 +1,10 @@
+define ECC_PUBLIC_KEY_CRYPTO 20131128
+
+<requires>
+alloc
+asn1
+bigint
+ec_gfp
+ec_group
+numbertheory
+</requires>