From 957da99ec9014948ac687f5400c92795f940ca9c Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 23 Oct 2014 16:38:50 +0200 Subject: [PATCH] commit before narrowing down import-public key issue w/cryptopp --- libdevcrypto/CryptoPP.cpp | 36 +++++++++---------- libdevcrypto/CryptoPP.h | 39 ++++---------------- libdevcrypto/EC.cpp | 75 +++++++++++++++++++-------------------- libdevcrypto/EC.h | 37 +++++++++++-------- test/crypto.cpp | 64 +++++++++++++++++++++++---------- 5 files changed, 128 insertions(+), 123 deletions(-) diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp index 611036e72..5c9c2f4b6 100644 --- a/libdevcrypto/CryptoPP.cpp +++ b/libdevcrypto/CryptoPP.cpp @@ -28,15 +28,6 @@ using namespace dev::crypto; using namespace pp; using namespace CryptoPP; -void pp::PublicFromDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC const& _k, Public& _p) { - bytes prefixedKey(65); - _k.GetGroupParameters().GetCurve().EncodePoint(prefixedKey.data(), _k.GetPublicElement(), false); - memcpy(_p.data(), &prefixedKey[1], 64); -} - -void pp::SecretFromDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC const& _k, Secret& _s) { - _k.GetPrivateExponent().Encode(_s.data(), 32); -} ECP::Point pp::PointFromPublic(Public const& _p) { @@ -56,18 +47,23 @@ Integer pp::ExponentFromSecret(Secret const& _s) return std::move(Integer(_s.data(), 32)); } +void pp::PublicFromExponent(Integer const& _e, Public& _p) { + CryptoPP::DL_PrivateKey_EC k; + k.AccessGroupParameters().Initialize(ASN1::secp256r1()); + k.SetPrivateExponent(_e); + CryptoPP::DL_PublicKey_EC p; + p.AccessGroupParameters().Initialize(ASN1::secp256r1()); + k.MakePublicKey(p); + pp::PublicFromDL_PublicKey_EC(p, _p); +} - - -pp::ECKeyPair::ECKeyPair(): -m_decryptor(pp::PRNG(), pp::secp256k1()) -{ +void pp::PublicFromDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC const& _k, Public& _p) { + bytes prefixedKey(65); + _k.GetGroupParameters().GetCurve().EncodePoint(prefixedKey.data(), _k.GetPublicElement(), false); + memcpy(_p.data(), &prefixedKey[1], 64); } -Secret pp::ECKeyPair::secret() -{ - Secret s; - SecretFromDL_PrivateKey_EC(m_decryptor.AccessKey(), s); - return std::move(s); -} \ No newline at end of file +void pp::SecretFromDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC const& _k, Secret& _s) { + _k.GetPrivateExponent().Encode(_s.data(), 32); +} diff --git a/libdevcrypto/CryptoPP.h b/libdevcrypto/CryptoPP.h index cd41bdf14..40be68aaa 100644 --- a/libdevcrypto/CryptoPP.h +++ b/libdevcrypto/CryptoPP.h @@ -40,43 +40,18 @@ inline CryptoPP::AutoSeededRandomPool& PRNG() { static CryptoPP::AutoSeededRando /// EC curve used by CryptoPP inline CryptoPP::OID const& secp256k1() { static CryptoPP::OID curve = CryptoPP::ASN1::secp256k1(); return curve; } - -void PublicFromDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC const& _k, Public& _p); - -void SecretFromDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC const& _k, Secret& _s); - -/// Helper for CryptoPP key +/// CryptoPP::ECP::Point PointFromPublic(Public const& _p); - -/// Helper for CryptoPP key -CryptoPP::Integer ExponentFromSecret(Secret const& _s); - -void ECIESEncrypt(CryptoPP::ECP::Point const& _point, byte*); -void ECIESDecrypt(CryptoPP::Integer const& _exponent, byte*); - -/** - * @brief CryptoPP-specific EC keypair - */ -class ECKeyPair -{ -public: - /// Export address - Address const& address() const { return m_address; } - - /// Export Public key - Public const& publicKey() const { return m_public; } - - Secret secret(); +/// +CryptoPP::Integer ExponentFromSecret(Secret const& _s); - CryptoPP::ECIES::Decryptor m_decryptor; +void PublicFromExponent(CryptoPP::Integer const& _k, Public& _s); -protected: - ECKeyPair(); +void PublicFromDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC const& _k, Public& _p); - Address m_address; - Public m_public; -}; +void SecretFromDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC const& _k, Secret& _s); + } } } diff --git a/libdevcrypto/EC.cpp b/libdevcrypto/EC.cpp index f532cb74e..04e9c681c 100644 --- a/libdevcrypto/EC.cpp +++ b/libdevcrypto/EC.cpp @@ -48,58 +48,55 @@ void dev::crypto::encrypt(Public const& _key, bytes& _plain) e.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1()); e.AccessKey().SetPublicElement(pp::PointFromPublic(_key)); size_t plen = _plain.size(); - _plain.resize(e.CiphertextLength(plen)); - e.Encrypt(pp::PRNG(), _plain.data(), plen, _plain.data()); + std::string c; + c.resize(e.CiphertextLength(plen)); + e.Encrypt(pp::PRNG(), _plain.data(), plen, (byte*)c.data()); + _plain.resize(c.size()); + memcpy(_plain.data(), c.data(), c.size()); } void dev::crypto::decrypt(Secret const& _k, bytes& _c) { - CryptoPP::ECIES::Decryptor m_decryptor; - m_decryptor.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1()); - m_decryptor.AccessKey().SetPrivateExponent(pp::ExponentFromSecret(_k)); - size_t plen = _c.size(); - DecodingResult r = m_decryptor.Decrypt(pp::PRNG(), _c.data(), plen, _c.data()); + CryptoPP::ECIES::Decryptor d; + d.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1()); + d.AccessKey().SetPrivateExponent(pp::ExponentFromSecret(_k)); + size_t clen = _c.size(); + std::string p; + p.resize(d.MaxPlaintextLength(_c.size())); + DecodingResult r = d.Decrypt(pp::PRNG(), _c.data(), clen, (byte*)p.data()); + assert(r.messageLength); _c.resize(r.messageLength); + memcpy(_c.data(), p.data(), _c.size()); } - - - - - -/// Old stuff :) - -ECKeyPair ECKeyPair::create() +SecretKeyRef::SecretKeyRef() { - ECKeyPair k; - - // export public key and set address - ECIES::Encryptor e(k.m_decryptor.GetKey()); - pp::PublicFromDL_PublicKey_EC(e.GetKey(), k.m_public); - k.m_address = dev::right160(dev::sha3(k.m_public.ref())); - - return k; + secp256k1_start(); + static std::mt19937_64 s_eng(time(0)); + std::uniform_int_distribution d(0, 255); + + for (int i = 0; i < 100; ++i) + { + for (unsigned i = 0; i < 32; ++i) + m_secret[i] = (byte)d(s_eng); + + KeyPair ret(m_secret); + if (ret.address()) + break; + } + /// todo: throw exception if key doesn't happen (or run forever?) + /// todo: ^ also in KeyPair::create() } -void ECKeyPair::encrypt(bytes& _text) +Public SecretKeyRef::pub() const { - ECIES::Encryptor e(m_decryptor); - std::string c; - StringSource ss(_text.data(), _text.size(), true, new PK_EncryptorFilter(pp::PRNG(), e, new StringSink(c))); - bzero(_text.data(), _text.size() * sizeof(byte)); - _text = std::move(asBytes(c)); + Public p; + pp::PublicFromExponent(pp::ExponentFromSecret(m_secret), p); + return p; } -void ECKeyPair::decrypt(bytes& _c) +Address SecretKeyRef::address() const { - DecodingResult r = m_decryptor.Decrypt(pp::PRNG(), _c.data(), _c.size(), _c.data()); - _c.resize(r.messageLength); - -// std::string p; -// StringSource ss(_c.data(), _c.size(), true, new PK_DecryptorFilter(pp::PRNG(), m_decryptor, new StringSink(p))); -// return std::move(asBytes(p)); + return dev::right160(dev::sha3(bytesConstRef(pub().data(), 64))); } - - - diff --git a/libdevcrypto/EC.h b/libdevcrypto/EC.h index 771ac95f4..1cae5c4f6 100644 --- a/libdevcrypto/EC.h +++ b/libdevcrypto/EC.h @@ -53,31 +53,40 @@ void encrypt(Public const& _k, bytes& _text); void decrypt(Secret const& _k, bytes& _text); +class SecretKeyRef +{ +public: + /// Creates random secret + SecretKeyRef(); + + /// Creates from secret (move). + SecretKeyRef(Secret _s): m_secret(_s) {} + + /// Retrieve the secret key. + Secret sec() const { return m_secret; } + + /// Retrieve the public key. + Public pub() const; + + /// Retrieve the associated address of the public key. + Address address() const; + +private: + Secret m_secret; +}; /** * @brief EC KeyPair - * @todo remove secret access - * @todo Integrate and/or replace KeyPair, move to common.h + * @deprecated */ -class ECKeyPair: public pp::ECKeyPair +class ECKeyPair { friend class ECDHETKeyExchange; - friend class ECIESEncryptor; - friend class ECIESDecryptor; public: static ECKeyPair create(); - /// Sign message. - Signature sign(h256 _messageHash); - - /// Decrypt ciphertext (in place). - void decrypt(bytes& _cipher); - - /// Encrypt using public key (in place). - void encrypt(bytes& _text); - private: ECKeyPair() {}; diff --git a/test/crypto.cpp b/test/crypto.cpp index 55ee1e176..ccfa1003a 100644 --- a/test/crypto.cpp +++ b/test/crypto.cpp @@ -62,52 +62,80 @@ BOOST_AUTO_TEST_CASE(cryptopp_vs_secp256k1) Public p; pp::PublicFromDL_PublicKey_EC(e.GetKey(), p); - - /// wow, this worked. the first time. + assert(dev::toAddress(s) == right160(dev::sha3(p.ref()))); } } -BOOST_AUTO_TEST_CASE(cryptopp_private_secret_import) +BOOST_AUTO_TEST_CASE(cryptopp_is_bad) { - ECKeyPair k = ECKeyPair::create(); - Integer e = k.m_decryptor.AccessKey().GetPrivateExponent(); - assert(pp::ExponentFromSecret(k.secret()) == e); + SecretKeyRef k; + Secret s = k.sec(); + + /// Convert secret to exponent used by pp + Integer e = pp::ExponentFromSecret(k.sec()); + + ECIES::Decryptor d; +// k.AccessGroupParameters().Initialize(ASN1::secp256r1()); +// k.SetPrivateExponent(_e); + + pp::SecretFromDL_PrivateKey_EC(d.GetKey(), s); + } BOOST_AUTO_TEST_CASE(cryptopp_public_export_import) { ECIES::Decryptor d(pp::PRNG(), pp::secp256k1()); ECIES::Encryptor e(d.GetKey()); - + + Secret s; + pp::SecretFromDL_PrivateKey_EC(d.GetKey(), s); Public p; pp::PublicFromDL_PublicKey_EC(e.GetKey(), p); - + Address addr = right160(dev::sha3(p.ref())); + assert(toAddress(s) == addr); + + KeyPair l(s); + assert(l.address() == addr); + DL_PublicKey_EC pub; pub.Initialize(pp::secp256k1(), pp::PointFromPublic(p)); assert(pub.GetPublicElement() == e.GetKey().GetPublicElement()); + + + //// + SecretKeyRef k; + Public p2; + pp::PublicFromExponent(pp::ExponentFromSecret(k.sec()), p2); + assert(k.pub() == p2); + + // Fix me: + Address a = k.address(); + Address a2 = toAddress(k.sec()); + assert(a2 == a); } BOOST_AUTO_TEST_CASE(ecies_eckeypair) { - ECKeyPair k = ECKeyPair::create(); + KeyPair l = KeyPair::create(); + SecretKeyRef k(l.sec()); + string message("Now is the time for all good persons to come to the aide of humanity."); string original = message; bytes b = asBytes(message); - k.encrypt(b); + encrypt(k.pub(), b); assert(b != asBytes(original)); - Secret s = k.secret(); - decrypt(s, b); + decrypt(k.sec(), b); assert(b == asBytes(original)); - // Fix Me! -// encrypt(k.publicKey(), b); - k.encrypt(b); - assert(b != asBytes(original)); - k.decrypt(b); - assert(b == asBytes(original)); +// // Fix Me! +//// encrypt(k.publicKey(), b); +// k.encrypt(b); +// assert(b != asBytes(original)); +// k.decrypt(b); +// assert(b == asBytes(original)); } BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac)