From b97d9bbd6fbeef239913858ee62d1cb8d1c716c1 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 22 Oct 2014 23:59:00 +0200 Subject: [PATCH] Export and encrypt via dev::Public. more cryptopp abstraction. --- libdevcrypto/CryptoPP.cpp | 40 +++++++++++++++++++++++ libdevcrypto/CryptoPP.h | 68 +++++++++++++++++++++++++++++++++++++++ libdevcrypto/EC.cpp | 44 +++++++++---------------- libdevcrypto/EC.h | 52 ++++++------------------------ test/crypto.cpp | 22 ++++++++++++- 5 files changed, 154 insertions(+), 72 deletions(-) create mode 100644 libdevcrypto/CryptoPP.cpp create mode 100644 libdevcrypto/CryptoPP.h diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp new file mode 100644 index 000000000..fbc6d9074 --- /dev/null +++ b/libdevcrypto/CryptoPP.cpp @@ -0,0 +1,40 @@ +/* + 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 . + */ +/** @file CryptoPP.h + * @author Alex Leverington + * @date 2014 + * + * CryptoPP wrappers + */ + +#include "CryptoPP.h" + +using namespace dev::crypto; +using namespace CryptoPP; + +dev::Public pp::exportPublicKey(CryptoPP::DL_PublicKey_EC 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; +} + +pp::ECKeyPair::ECKeyPair(): +m_decryptor(pp::PRNG(), pp::secp256k1()) +{ +} \ No newline at end of file diff --git a/libdevcrypto/CryptoPP.h b/libdevcrypto/CryptoPP.h new file mode 100644 index 000000000..437a48035 --- /dev/null +++ b/libdevcrypto/CryptoPP.h @@ -0,0 +1,68 @@ +/* + 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 . + */ +/** @file CryptoPP.h + * @author Alex Leverington + * @date 2014 + * + * CryptoPP wrappers + */ + +#pragma once + +#include "Common.h" +#include "CryptoHeaders.h" + +namespace dev +{ +namespace crypto +{ + +namespace pp +// cryptopp wrappers +{ +/// RNG used by CryptoPP +inline CryptoPP::AutoSeededRandomPool& PRNG() { static CryptoPP::AutoSeededRandomPool prng; return prng; } + +/// 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 const& _k); + +/** + * @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; } + +protected: + ECKeyPair(); + + CryptoPP::ECIES::Decryptor m_decryptor; + + Address m_address; + Public m_public; +}; +} +} +} + diff --git a/libdevcrypto/EC.cpp b/libdevcrypto/EC.cpp index 26327f271..9990244dc 100644 --- a/libdevcrypto/EC.cpp +++ b/libdevcrypto/EC.cpp @@ -32,25 +32,30 @@ #include #pragma warning(pop) #pragma GCC diagnostic pop +#include "CryptoPP.h" #include "SHA3.h" #include "EC.h" // CryptoPP and dev conflict so dev and pp namespace are used explicitly using namespace std; +using namespace dev; using namespace dev::crypto; using namespace CryptoPP; -dev::Public pp::exportPublicKey(CryptoPP::DL_PublicKey_EC 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; -} - -pp::ECKeyPair::ECKeyPair(): - m_decryptor(pp::PRNG(), pp::secp256k1()) +void dev::crypto::encrypt(bytes& _plain, Public const& _key) { + Integer x(&_key.data()[0], 32); + Integer y(&_key.data()[32], 32); + + DL_PublicKey_EC p; + p.Initialize(pp::secp256k1(), ECP::Point(x,y)); + + ECIES::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)); } ECKeyPair ECKeyPair::create() @@ -74,25 +79,6 @@ void ECKeyPair::encrypt(bytes& _text) _text = std::move(asBytes(c)); } -void ECKeyPair::encrypt(bytes& _plain, Public _key) -{ - const char* xbytes = (char*)&_key[0]; - Integer x(xbytes); - - const char* ybytes = (char*)&_key[32]; - Integer y(ybytes); - - DL_PublicKey_EC p; - p.Initialize(pp::secp256k1(), ECP::Point(x,y)); - - ECIES::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)); -} - dev::bytes ECKeyPair::decrypt(bytesConstRef _c) { std::string p; diff --git a/libdevcrypto/EC.h b/libdevcrypto/EC.h index 8f7637c48..a1534d351 100644 --- a/libdevcrypto/EC.h +++ b/libdevcrypto/EC.h @@ -23,45 +23,13 @@ #pragma once -#include "CryptoHeaders.h" +#include "CryptoPP.h" #include "Common.h" namespace dev { namespace crypto { - -namespace pp -// cryptopp wrappers -{ -/// RNG used by CryptoPP -inline CryptoPP::AutoSeededRandomPool& PRNG() { static CryptoPP::AutoSeededRandomPool prng; return prng; } - -/// 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 const& _k); - -/** - * @brief CryptoPP-specific EC keypair - */ -class ECKeyPair -{ -public: - /// Create a new, randomly generated keypair. - Address const& address() const { return m_address; } - - Public const& publicKey() const { return m_public; } - -protected: - ECKeyPair(); - - CryptoPP::ECIES::Decryptor m_decryptor; - - Address m_address; - Public m_public; -}; -} /// ECDSA Signature using Signature = FixedHash<65>; @@ -72,6 +40,15 @@ using Nonce = h256; /// Public key with nonce corresponding to trusted key exchange. typedef std::pair PublicTrust; +/// Recover public key from signature. +//Public recover(Signature const& _sig, h256 _messageHash); + +/// Replaces text with ciphertext. +void encrypt(bytes& _text, Public const& _key); + +/// @returns ciphertext. +//bytes encrypt(bytesConstRef _text, Public const& _key); + /** * @brief EC KeyPair * @todo remove secret access @@ -86,15 +63,6 @@ class ECKeyPair: public pp::ECKeyPair public: static ECKeyPair create(); - /// Replaces text with ciphertext. - static void encrypt(bytes& _text, Public _key); - - /// @returns ciphertext. - static bytes encrypt(bytesConstRef _text, Public _key); - - /// Recover public key from signature. - static Public recover(Signature _sig, h256 _messageHash); - /// Sign message. Signature sign(h256 _messageHash); diff --git a/test/crypto.cpp b/test/crypto.cpp index 48c6fc70c..7e3ce81ab 100644 --- a/test/crypto.cpp +++ b/test/crypto.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +//#include #include "TestHelperCrypto.h" using namespace std; @@ -38,6 +38,21 @@ using namespace CryptoPP; BOOST_AUTO_TEST_SUITE(devcrypto) +BOOST_AUTO_TEST_CASE(cryptopp_public_export_import) +{ + ECIES::Decryptor d(pp::PRNG(), pp::secp256k1()); + ECIES::Encryptor e(d.GetKey()); + + Public p = pp::exportPublicKey(e.GetKey()); + Integer x(&p[0], 32); + Integer y(&p[32], 32); + + DL_PublicKey_EC pub; + pub.Initialize(pp::secp256k1(), ECP::Point(x,y)); + + assert(pub == e.GetKey()); +} + BOOST_AUTO_TEST_CASE(eckeypair_encrypt) { ECKeyPair k = ECKeyPair::create(); @@ -50,6 +65,11 @@ BOOST_AUTO_TEST_CASE(eckeypair_encrypt) bytes p = k.decrypt(&b); assert(p == asBytes(original)); + + encrypt(p, k.publicKey()); + assert(p != asBytes(original)); + + // todo: test decrypt w/Secret } BOOST_AUTO_TEST_CASE(ecies)