summaryrefslogtreecommitdiffstats
path: root/botan/src/pubkey/eckaeg/eckaeg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'botan/src/pubkey/eckaeg/eckaeg.cpp')
-rw-r--r--botan/src/pubkey/eckaeg/eckaeg.cpp152
1 files changed, 152 insertions, 0 deletions
diff --git a/botan/src/pubkey/eckaeg/eckaeg.cpp b/botan/src/pubkey/eckaeg/eckaeg.cpp
new file mode 100644
index 0000000..b8ff75d
--- /dev/null
+++ b/botan/src/pubkey/eckaeg/eckaeg.cpp
@@ -0,0 +1,152 @@
+/*
+* ECKAEG implemenation
+* (C) 2007 Manuel Hartl, FlexSecure GmbH
+* 2007 Falko Strenzke, FlexSecure GmbH
+* 2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#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;
+ }
+
+MemoryVector<byte> ECKAEG_PrivateKey::public_value() const
+ {
+ return EC2OSP(public_point(), PointGFp::UNCOMPRESSED);
+ }
+
+/**
+* Derive a key
+*/
+SecureVector<byte> ECKAEG_PrivateKey::derive_key(const byte key[],
+ u32bit key_len) const
+ {
+ MemoryVector<byte> key_x(key, key_len); // FIXME: nasty/slow
+ PointGFp point = OS2ECP(key_x, public_point().get_curve());
+
+ return m_eckaeg_core.agree(point);
+ }
+
+/**
+* Derive a 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());
+ }
+
+}