diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp index fbc6d9074..0578d180c 100644 --- a/libdevcrypto/CryptoPP.cpp +++ b/libdevcrypto/CryptoPP.cpp @@ -23,18 +23,45 @@ #include "CryptoPP.h" +using namespace dev; using namespace dev::crypto; +using namespace pp; using namespace CryptoPP; -dev::Public pp::exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k) { - Public p; +void pp::exportDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& _p) { ECP::Point q(_k.GetPublicElement()); - q.x.Encode(&p.data()[0], 32); - q.y.Encode(&p.data()[32], 32); - return p; + q.x.Encode(_p.data(), 32); + q.y.Encode(&_p.data()[32], 32); } +void pp::exportDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> const& _k, Secret& _s) { + _k.GetPrivateExponent().Encode(_s.data(), 32); +} + +ECP::Point pp::PointFromPublic(Public const& _p) +{ + Integer x(&_p.data()[0], 32); + Integer y(&_p.data()[32], 32); + return std::move(ECP::Point(x,y)); +} + +Integer pp::ExponentFromSecret(Secret const& _s) +{ + return std::move(Integer(_s.data(), 32)); +} + + + + + pp::ECKeyPair::ECKeyPair(): m_decryptor(pp::PRNG(), pp::secp256k1()) { +} + +Secret pp::ECKeyPair::secret() +{ + Secret s; + exportDL_PrivateKey_EC(m_decryptor.AccessKey(), s); + return std::move(s); } \ No newline at end of file diff --git a/libdevcrypto/CryptoPP.h b/libdevcrypto/CryptoPP.h index 437a48035..7556a6922 100644 --- a/libdevcrypto/CryptoPP.h +++ b/libdevcrypto/CryptoPP.h @@ -40,7 +40,16 @@ 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; } -Public exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k); +void exportDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& _p); + +void exportDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> const& _k, Secret& _s); + +CryptoPP::ECP::Point PointFromPublic(Public const& _p); +CryptoPP::Integer ExponentFromSecret(Secret const& _s); + +void ECIESEncrypt(CryptoPP::ECP::Point const& _point); + +void ECIESDecrypt(CryptoPP::Integer const& _exponent); /** * @brief CryptoPP-specific EC keypair @@ -54,11 +63,13 @@ public: /// Export Public key Public const& publicKey() const { return m_public; } -protected: - ECKeyPair(); + Secret secret(); CryptoPP::ECIES<CryptoPP::ECP>::Decryptor m_decryptor; +protected: + ECKeyPair(); + Address m_address; Public m_public; }; diff --git a/libdevcrypto/EC.cpp b/libdevcrypto/EC.cpp index 9990244dc..b7e66a9a3 100644 --- a/libdevcrypto/EC.cpp +++ b/libdevcrypto/EC.cpp @@ -42,29 +42,46 @@ using namespace dev; using namespace dev::crypto; using namespace CryptoPP; -void dev::crypto::encrypt(bytes& _plain, Public const& _key) +void dev::crypto::encrypt(Public const& _key, bytes& _plain) { Integer x(&_key.data()[0], 32); Integer y(&_key.data()[32], 32); - DL_PublicKey_EC<ECP> p; - p.Initialize(pp::secp256k1(), ECP::Point(x,y)); +// DL_PublicKey_EC<ECP> p; +// p.Initialize(pp::secp256k1(), ECP::Point(x,y)); - ECIES<ECP>::Encryptor e(p); - // todo: determine size and use _plain as input and output. - std::string c; - StringSource ss(_plain.data(), _plain.size(), true, new PK_EncryptorFilter(pp::PRNG(), e, new StringSink(c))); - bzero(_plain.data(), _plain.size() * sizeof(byte)); - _plain = std::move(asBytes(c)); + ECIES<ECP>::Encryptor e; + e.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1()); + e.AccessKey().SetPublicElement(ECP::Point(x,y)); + size_t plen = _plain.size(); + _plain.resize(e.CiphertextLength(plen)); + e.Encrypt(pp::PRNG(), _plain.data(), plen, _plain.data()); } +void dev::crypto::decrypt(Secret const& _k, bytes& _c) +{ + CryptoPP::ECIES<CryptoPP::ECP>::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()); + _c.resize(r.messageLength); +} + + + + + + +/// Old stuff :) + ECKeyPair ECKeyPair::create() { ECKeyPair k; // export public key and set address ECIES<ECP>::Encryptor e(k.m_decryptor.GetKey()); - k.m_public = pp::exportPublicKey(e.GetKey()); + pp::exportDL_PublicKey_EC(e.GetKey(), k.m_public); k.m_address = dev::right160(dev::sha3(k.m_public.ref())); return k; diff --git a/libdevcrypto/EC.h b/libdevcrypto/EC.h index a1534d351..c21291145 100644 --- a/libdevcrypto/EC.h +++ b/libdevcrypto/EC.h @@ -43,11 +43,17 @@ typedef std::pair<Nonce,Public> PublicTrust; /// Recover public key from signature. //Public recover(Signature const& _sig, h256 _messageHash); -/// Replaces text with ciphertext. -void encrypt(bytes& _text, Public const& _key); +/// Encrypts text (in place). +void encrypt(Public const& _k, bytes& _text); -/// @returns ciphertext. -//bytes encrypt(bytesConstRef _text, Public const& _key); +/// Encrypt _text into _cipher. +//void encrypt(Public const& _k, bytesConstRef& _text, bytesRef& _cipher); + +/// Decrypts text (in place). +void decrypt(Secret const& _k, bytes& _text); + + + /** * @brief EC KeyPair diff --git a/libdevcrypto/ECIES.cpp b/libdevcrypto/ECIES.cpp deleted file mode 100644 index e76be2c2c..000000000 --- a/libdevcrypto/ECIES.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. - */ -/** @file ECIES.cpp - * @author Alex Leverington <nessence@gmail.com> - * @date 2014 - * - * ECIES Encrypt/Decrypt - */ - -#include "EC.h" -#include "ECIES.h" - -using namespace std; -using namespace dev; -using namespace dev::crypto; -using namespace CryptoPP; - -//ECIESEncryptor::ECIESEncryptor(ECKeyPair* _k) -//{ -// m_encryptor.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1()); -// m_encryptor.AccessKey().SetPublicElement(_k->pub().GetPublicElement()); -//} -// -//void ECIESEncryptor::encrypt(bytes& _message) -//{ -// // todo: determine size and use _message as input and output. -// std::string c; -// StringSource ss(_message.data(), _message.size(), true, new PK_EncryptorFilter(pp::PRNG(), m_encryptor, new StringSink(c))); -// bzero(_message.data(), _message.size() * sizeof(byte)); -// _message = std::move(asBytes(c)); -//} -// -//ECIESDecryptor::ECIESDecryptor(ECKeyPair* _k) -//{ -// m_decryptor.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1()); -// m_decryptor.AccessKey().SetPrivateExponent(_k->sec().GetPrivateExponent()); -//} -// -//bytes ECIESDecryptor::decrypt(bytesConstRef& _c) -//{ -// 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)); -//} - diff --git a/libdevcrypto/ECIES.h b/libdevcrypto/ECIES.h deleted file mode 100644 index 376942f4c..000000000 --- a/libdevcrypto/ECIES.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. - */ -/** @file ECIES.h - * @author Alex Leverington <nessence@gmail.com> - * @date 2014 - * - * ECIES Encrypt/Decrypt - */ - -#pragma once - -#include <libdevcore/Exceptions.h> -#include "CryptoHeaders.h" -#include "Common.h" - -namespace dev -{ -namespace crypto -{ - -/** - * @brief ECIES Encryption - */ -class ECIESEncryptor -{ -public: - ECIESEncryptor(ECKeyPair* _k); - - /// Encrypt _message. (object will be resized and replaced with cipher) - void encrypt(bytes& _message); - -private: - CryptoPP::ECIES<CryptoPP::ECP>::Encryptor m_encryptor; -}; - -/** - * @brief ECIES Decryption - */ -class ECIESDecryptor -{ -public: - ECIESDecryptor(ECKeyPair* _k); - - /// Decrypt cipher to plain. - bytes decrypt(bytesConstRef& _c); - -private: - CryptoPP::ECIES<CryptoPP::ECP>::Decryptor m_decryptor; -}; - -} -} - diff --git a/test/crypto.cpp b/test/crypto.cpp index 7e3ce81ab..a9b9904cc 100644 --- a/test/crypto.cpp +++ b/test/crypto.cpp @@ -28,7 +28,6 @@ #include <libethereum/Transaction.h> #include <boost/test/unit_test.hpp> #include <libdevcrypto/EC.h> -//#include <libdevcrypto/ECIES.h> #include "TestHelperCrypto.h" using namespace std; @@ -38,22 +37,32 @@ using namespace CryptoPP; BOOST_AUTO_TEST_SUITE(devcrypto) +BOOST_AUTO_TEST_CASE(cryptopp_private_secret_import) +{ + ECKeyPair k = ECKeyPair::create(); + Integer e = k.m_decryptor.AccessKey().GetPrivateExponent(); + assert(pp::ExponentFromSecret(k.secret()) == e); +} + BOOST_AUTO_TEST_CASE(cryptopp_public_export_import) { ECIES<ECP>::Decryptor d(pp::PRNG(), pp::secp256k1()); ECIES<ECP>::Encryptor e(d.GetKey()); - Public p = pp::exportPublicKey(e.GetKey()); + Public p; + pp::exportDL_PublicKey_EC(e.GetKey(), p); Integer x(&p[0], 32); Integer y(&p[32], 32); DL_PublicKey_EC<ECP> pub; pub.Initialize(pp::secp256k1(), ECP::Point(x,y)); - assert(pub == e.GetKey()); + + DL_PublicKey_EC<ECP> pub2; + pub.Initialize(pp::secp256k1(), ECP::Point(x,y)); } -BOOST_AUTO_TEST_CASE(eckeypair_encrypt) +BOOST_AUTO_TEST_CASE(ecies_eckeypair) { ECKeyPair k = ECKeyPair::create(); string message("Now is the time for all good persons to come to the aide of humanity."); @@ -62,32 +71,16 @@ BOOST_AUTO_TEST_CASE(eckeypair_encrypt) bytes b = asBytes(message); k.encrypt(b); assert(b != asBytes(original)); - - bytes p = k.decrypt(&b); - assert(p == asBytes(original)); - encrypt(p, k.publicKey()); - assert(p != asBytes(original)); - - // todo: test decrypt w/Secret -} + Secret s = k.secret(); + decrypt(s, b); + assert(b == asBytes(original)); -BOOST_AUTO_TEST_CASE(ecies) -{ -// ECKeyPair k = ECKeyPair::create(); -// -// string message("Now is the time for all good persons to come to the aide of humanity."); -// bytes b = bytesRef(message).toBytes(); -// ECIESEncryptor(&k).encrypt(b); -// -// bytesConstRef br(&b); -// bytes plain = ECIESDecryptor(&k).decrypt(br); -// -// // ideally, decryptor will go a step further, accept a bytesRef and zero input. -// assert(plain != b); -// -// // plaintext is same as output -// assert(plain == bytesConstRef(message).toBytes()); + // Fix Me! +// encrypt(k.publicKey(), b); +// assert(b != asBytes(original)); +// bytes plain = k.decrypt(&b); +// assert(plain == asBytes(original)); } BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac)