diff --git a/bench/main.cpp b/bench/main.cpp index 6042d9b82e0..0531a4627ad 100644 --- a/bench/main.cpp +++ b/bench/main.cpp @@ -31,7 +31,6 @@ #include #include #include -#include using namespace std; using namespace dev; namespace js = json_spirit; diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index 1c85bc856a6..e11f138074f 100644 --- a/libdevcrypto/Common.cpp +++ b/libdevcrypto/Common.cpp @@ -27,15 +27,13 @@ #include #include #include -#include -#include #include #include #include #include #include "AES.h" -#include "CryptoPP.h" #include "Exceptions.h" + using namespace std; using namespace dev; using namespace dev::crypto; @@ -104,19 +102,12 @@ Address dev::toAddress(Address const& _from, u256 const& _nonce) void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher) { - bytes io = _plain.toBytes(); - Secp256k1PP::get()->encrypt(_k, io); - o_cipher = std::move(io); + encryptECIES(_k, _plain, o_cipher); } bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext) { - bytes io = _cipher.toBytes(); - Secp256k1PP::get()->decrypt(_k, io); - if (io.empty()) - return false; - o_plaintext = std::move(io); - return true; + return decryptECIES(_k, _cipher, o_plaintext); } void dev::encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher) @@ -126,9 +117,40 @@ void dev::encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher) void dev::encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytesConstRef _plain, bytes& o_cipher) { - bytes io = _plain.toBytes(); - Secp256k1PP::get()->encryptECIES(_k, _sharedMacData, io); - o_cipher = std::move(io); + // interop w/go ecies implementation + auto r = KeyPair::create(); + Secret z; + ecdh::agree(r.secret(), _k, z); + auto key = ecies::kdf(z, bytes(), 32); + bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16); + bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16); + secp256k1_sha256_t ctx; + secp256k1_sha256_initialize(&ctx); + secp256k1_sha256_write(&ctx, mKeyMaterial.data(), mKeyMaterial.size()); + bytes mKey(32); + secp256k1_sha256_finalize(&ctx, mKey.data()); + + auto iv = h128::random(); + bytes cipherText = encryptSymNoAuth(SecureFixedHash<16>(eKey), iv, _plain); + if (cipherText.empty()) + return; + + bytes msg(1 + Public::size + h128::size + cipherText.size() + 32); + msg[0] = 0x04; + r.pub().ref().copyTo(bytesRef(&msg).cropped(1, Public::size)); + iv.ref().copyTo(bytesRef(&msg).cropped(1 + Public::size, h128::size)); + bytesRef msgCipherRef = bytesRef(&msg).cropped(1 + Public::size + h128::size, cipherText.size()); + bytesConstRef(&cipherText).copyTo(msgCipherRef); + + // tag message + secp256k1_hmac_sha256_t hmacCtx; + secp256k1_hmac_sha256_initialize(&hmacCtx, mKey.data(), mKey.size()); + bytesConstRef cipherWithIV = bytesRef(&msg).cropped(1 + Public::size, h128::size + cipherText.size()); + secp256k1_hmac_sha256_write(&hmacCtx, cipherWithIV.data(), cipherWithIV.size()); + secp256k1_hmac_sha256_write(&hmacCtx, _sharedMacData.data(), _sharedMacData.size()); + secp256k1_hmac_sha256_finalize(&hmacCtx, msg.data() + 1 + Public::size + cipherWithIV.size()); + + o_cipher = std::move(msg); } bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext) @@ -138,10 +160,50 @@ bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plainte bool dev::decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytesConstRef _cipher, bytes& o_plaintext) { - bytes io = _cipher.toBytes(); - if (!Secp256k1PP::get()->decryptECIES(_k, _sharedMacData, io)) + // interop w/go ecies implementation + + // io_cipher[0] must be 2, 3, or 4, else invalidpublickey + if (_cipher.empty() || _cipher[0] < 2 || _cipher[0] > 4) + // invalid message: publickey return false; - o_plaintext = std::move(io); + + if (_cipher.size() < (1 + Public::size + h128::size + 1 + h256::size)) + // invalid message: length + return false; + + Secret z; + ecdh::agree(_k, *(Public*)(_cipher.data() + 1), z); + auto key = ecies::kdf(z, bytes(), 64); + bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16); + bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16); + bytes mKey(32); + // FIXME: Use crypto::sha256() + secp256k1_sha256_t ctx; + secp256k1_sha256_initialize(&ctx); + secp256k1_sha256_write(&ctx, mKeyMaterial.data(), mKeyMaterial.size()); + secp256k1_sha256_finalize(&ctx, mKey.data()); + + bytes plain; + size_t cipherLen = _cipher.size() - 1 - Public::size - h128::size - h256::size; + bytesConstRef cipherWithIV(_cipher.data() + 1 + Public::size, h128::size + cipherLen); + bytesConstRef cipherIV = cipherWithIV.cropped(0, h128::size); + bytesConstRef cipherNoIV = cipherWithIV.cropped(h128::size, cipherLen); + bytesConstRef msgMac(cipherNoIV.data() + cipherLen, h256::size); + h128 iv(cipherIV.toBytes()); + + // verify tag + + secp256k1_hmac_sha256_t hmacCtx; + secp256k1_hmac_sha256_initialize(&hmacCtx, mKey.data(), mKey.size()); + secp256k1_hmac_sha256_write(&hmacCtx, cipherWithIV.data(), cipherWithIV.size()); + secp256k1_hmac_sha256_write(&hmacCtx, _sharedMacData.data(), _sharedMacData.size()); + h256 mac; + secp256k1_hmac_sha256_finalize(&hmacCtx, mac.data()); + for (unsigned i = 0; i < h256::size; i++) + if (mac[i] != msgMac[i]) + return false; + + o_plaintext = decryptSymNoAuth(SecureFixedHash<16>(eKey), iv, cipherNoIV).makeInsecure(); return true; } @@ -265,18 +327,41 @@ bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash) bytesSec dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen) { + static const size_t bufSize = 32; + bytesSec secBuf(bufSize); + byte* buf = secBuf.writable().data(); + bytesSec ret(_dkLen); - if (PKCS5_PBKDF2_HMAC().DeriveKey( - ret.writable().data(), - _dkLen, - 0, - reinterpret_cast(_pass.data()), - _pass.size(), - _salt.data(), - _salt.size(), - _iterations - ) != _iterations) - BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed.")); + byte* derived = ret.writable().data(); + size_t derivedLen = _dkLen; + for (unsigned int i = 1; derivedLen > 0; ++i) + { + secp256k1_hmac_sha256_t ctx; + secp256k1_hmac_sha256_initialize(&ctx, reinterpret_cast(_pass.data()), _pass.size()); + secp256k1_hmac_sha256_write(&ctx, _salt.data(), _salt.size()); + for (auto j = 0; j < 4; ++j) + { + byte b = byte(i >> ((3-j)*8)); + secp256k1_hmac_sha256_write(&ctx, &b, 1); + } + secp256k1_hmac_sha256_finalize(&ctx, buf); + + size_t const segmentLen = std::min(derivedLen, bufSize); + std::copy(buf, buf + segmentLen, derived); + + for (decltype(_iterations) j = 1; j < _iterations; ++j) + { + secp256k1_hmac_sha256_initialize(&ctx, reinterpret_cast(_pass.data()), _pass.size()); + secp256k1_hmac_sha256_write(&ctx, buf, bufSize); + secp256k1_hmac_sha256_finalize(&ctx, buf); + std::transform(buf, buf + segmentLen, derived, derived, + [](byte a, byte b) { return a ^ b; } + ); + } + + derived += segmentLen; + derivedLen -= segmentLen; + } return ret; } diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp deleted file mode 100644 index 23b3515ab76..00000000000 --- a/libdevcrypto/CryptoPP.cpp +++ /dev/null @@ -1,236 +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 . - */ -/** @file CryptoPP.cpp - * @author Alex Leverington - * @date 2014 - */ - -#include // conflicts with -#include "CryptoPP.h" -#include -#include -#include -#include -#include - -static_assert(CRYPTOPP_VERSION == 570, "Wrong Crypto++ version"); - -using namespace std; -using namespace dev; -using namespace dev::crypto; -using namespace CryptoPP; - -static_assert(dev::Secret::size == 32, "Secret key must be 32 bytes."); -static_assert(dev::Public::size == 64, "Public key must be 64 bytes."); -static_assert(dev::Signature::size == 65, "Signature must be 65 bytes."); - -namespace -{ -class Secp256k1PPCtx -{ -public: - OID m_oid; - - std::mutex x_rng; - AutoSeededRandomPool m_rng; - - std::mutex x_params; - DL_GroupParameters_EC m_params; - - DL_GroupParameters_EC::EllipticCurve m_curve; - - Integer m_q; - Integer m_qs; - - static Secp256k1PPCtx& get() - { - static Secp256k1PPCtx ctx; - return ctx; - } - -private: - Secp256k1PPCtx(): - m_oid(ASN1::secp256k1()), m_params(m_oid), m_curve(m_params.GetCurve()), - m_q(m_params.GetGroupOrder()), m_qs(m_params.GetSubgroupOrder()) - {} -}; - -inline ECP::Point publicToPoint(Public const& _p) { Integer x(_p.data(), 32); Integer y(_p.data() + 32, 32); return ECP::Point(x,y); } - -inline Integer secretToExponent(Secret const& _s) { return Integer(_s.data(), Secret::size); } - -} - -Secp256k1PP* Secp256k1PP::get() -{ - static Secp256k1PP s_this; - return &s_this; -} - -void Secp256k1PP::encryptECIES(Public const& _k, bytes& io_cipher) -{ - encryptECIES(_k, bytesConstRef(), io_cipher); -} - -void Secp256k1PP::encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytes& io_cipher) -{ - // interop w/go ecies implementation - auto r = KeyPair::create(); - Secret z; - ecdh::agree(r.secret(), _k, z); - auto key = ecies::kdf(z, bytes(), 32); - bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16); - bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16); - CryptoPP::SHA256 ctx; - ctx.Update(mKeyMaterial.data(), mKeyMaterial.size()); - bytes mKey(32); - ctx.Final(mKey.data()); - - auto iv = h128::random(); - bytes cipherText = encryptSymNoAuth(SecureFixedHash<16>(eKey), iv, bytesConstRef(&io_cipher)); - if (cipherText.empty()) - return; - - bytes msg(1 + Public::size + h128::size + cipherText.size() + 32); - msg[0] = 0x04; - r.pub().ref().copyTo(bytesRef(&msg).cropped(1, Public::size)); - iv.ref().copyTo(bytesRef(&msg).cropped(1 + Public::size, h128::size)); - bytesRef msgCipherRef = bytesRef(&msg).cropped(1 + Public::size + h128::size, cipherText.size()); - bytesConstRef(&cipherText).copyTo(msgCipherRef); - - // tag message - CryptoPP::HMAC hmacctx(mKey.data(), mKey.size()); - bytesConstRef cipherWithIV = bytesRef(&msg).cropped(1 + Public::size, h128::size + cipherText.size()); - hmacctx.Update(cipherWithIV.data(), cipherWithIV.size()); - hmacctx.Update(_sharedMacData.data(), _sharedMacData.size()); - hmacctx.Final(msg.data() + 1 + Public::size + cipherWithIV.size()); - - io_cipher.resize(msg.size()); - io_cipher.swap(msg); -} - -bool Secp256k1PP::decryptECIES(Secret const& _k, bytes& io_text) -{ - return decryptECIES(_k, bytesConstRef(), io_text); -} - -bool Secp256k1PP::decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytes& io_text) -{ - - // interop w/go ecies implementation - - // io_cipher[0] must be 2, 3, or 4, else invalidpublickey - if (io_text.empty() || io_text[0] < 2 || io_text[0] > 4) - // invalid message: publickey - return false; - - if (io_text.size() < (1 + Public::size + h128::size + 1 + h256::size)) - // invalid message: length - return false; - - Secret z; - if (!ecdh::agree(_k, *(Public*)(io_text.data() + 1), z)) - return false; // Invalid pubkey or seckey. - auto key = ecies::kdf(z, bytes(), 64); - bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16); - bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16); - bytes mKey(32); - CryptoPP::SHA256 ctx; - ctx.Update(mKeyMaterial.data(), mKeyMaterial.size()); - ctx.Final(mKey.data()); - - bytes plain; - size_t cipherLen = io_text.size() - 1 - Public::size - h128::size - h256::size; - bytesConstRef cipherWithIV(io_text.data() + 1 + Public::size, h128::size + cipherLen); - bytesConstRef cipherIV = cipherWithIV.cropped(0, h128::size); - bytesConstRef cipherNoIV = cipherWithIV.cropped(h128::size, cipherLen); - bytesConstRef msgMac(cipherNoIV.data() + cipherLen, h256::size); - h128 iv(cipherIV.toBytes()); - - // verify tag - CryptoPP::HMAC hmacctx(mKey.data(), mKey.size()); - hmacctx.Update(cipherWithIV.data(), cipherWithIV.size()); - hmacctx.Update(_sharedMacData.data(), _sharedMacData.size()); - h256 mac; - hmacctx.Final(mac.data()); - for (unsigned i = 0; i < h256::size; i++) - if (mac[i] != msgMac[i]) - return false; - - plain = decryptSymNoAuth(SecureFixedHash<16>(eKey), iv, cipherNoIV).makeInsecure(); - io_text.resize(plain.size()); - io_text.swap(plain); - - return true; -} - -void Secp256k1PP::encrypt(Public const& _k, bytes& io_cipher) -{ - auto& ctx = Secp256k1PPCtx::get(); - ECIES::Encryptor e; - { - Guard l(ctx.x_params); - e.AccessKey().Initialize(ctx.m_params, publicToPoint(_k)); - } - - size_t plen = io_cipher.size(); - bytes ciphertext; - ciphertext.resize(e.CiphertextLength(plen)); - - { - Guard l(ctx.x_rng); - e.Encrypt(ctx.m_rng, io_cipher.data(), plen, ciphertext.data()); - } - - memset(io_cipher.data(), 0, io_cipher.size()); - io_cipher = std::move(ciphertext); -} - -void Secp256k1PP::decrypt(Secret const& _k, bytes& io_text) -{ - auto& ctx = Secp256k1PPCtx::get(); - CryptoPP::ECIES::Decryptor d; - { - Guard l(ctx.x_params); - d.AccessKey().Initialize(ctx.m_params, secretToExponent(_k)); - } - - if (!io_text.size()) - { - io_text.resize(1); - io_text[0] = 0; - } - - size_t clen = io_text.size(); - bytes plain; - plain.resize(d.MaxPlaintextLength(io_text.size())); - - DecodingResult r; - { - Guard l(ctx.x_rng); - r = d.Decrypt(ctx.m_rng, io_text.data(), clen, plain.data()); - } - - if (!r.isValidCoding) - { - io_text.clear(); - return; - } - - io_text.resize(r.messageLength); - io_text = std::move(plain); -} diff --git a/libdevcrypto/CryptoPP.h b/libdevcrypto/CryptoPP.h deleted file mode 100644 index f5affa7159a..00000000000 --- a/libdevcrypto/CryptoPP.h +++ /dev/null @@ -1,68 +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 . - */ -/** @file CryptoPP.h - * @author Alex Leverington - * @date 2014 - * - * CryptoPP headers and primitive helper methods - */ - -#pragma once - -#include "Common.h" - -namespace dev -{ -namespace crypto -{ -/// Amount of bytes added when encrypting with encryptECIES. -static const unsigned c_eciesOverhead = 113; - -/** - * CryptoPP secp256k1 algorithms. - * @todo Collect ECIES methods into class. - */ -class Secp256k1PP -{ -public: - static Secp256k1PP* get(); - - /// Encrypts text (replace input). (ECIES w/XOR-SHA1) - void encrypt(Public const& _k, bytes& io_cipher); - - /// Decrypts text (replace input). (ECIES w/XOR-SHA1) - void decrypt(Secret const& _k, bytes& io_text); - - /// Encrypts text (replace input). (ECIES w/AES128-CTR-SHA256) - void encryptECIES(Public const& _k, bytes& io_cipher); - - /// Encrypts text (replace input). (ECIES w/AES128-CTR-SHA256) - void encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytes& io_cipher); - - /// Decrypts text (replace input). (ECIES w/AES128-CTR-SHA256) - bool decryptECIES(Secret const& _k, bytes& io_text); - - /// Decrypts text (replace input). (ECIES w/AES128-CTR-SHA256) - bool decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytes& io_text); - -private: - Secp256k1PP() = default; -}; - -} -} - diff --git a/libethashseal/EthashAux.cpp b/libethashseal/EthashAux.cpp index e6ee864089d..996e8c03899 100644 --- a/libethashseal/EthashAux.cpp +++ b/libethashseal/EthashAux.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/libp2p/RLPXFrameCoder.h b/libp2p/RLPXFrameCoder.h index d7fd18aa513..5ab2e1b1c5b 100644 --- a/libp2p/RLPXFrameCoder.h +++ b/libp2p/RLPXFrameCoder.h @@ -24,7 +24,6 @@ #include #include -#include #include "Common.h" namespace dev diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp index b3d3d4f850b..b381553a18e 100644 --- a/libp2p/RLPxHandshake.cpp +++ b/libp2p/RLPxHandshake.cpp @@ -86,6 +86,8 @@ void RLPXHandshake::writeAckEIP8() m_ack.resize(m_ack.size() + padAmount, 0); bytes prefix(2); + /// Amount of bytes added when encrypting with encryptECIES. + static const unsigned c_eciesOverhead = 113; toBigEndian(m_ack.size() + c_eciesOverhead, prefix); encryptECIES(m_remote, bytesConstRef(&prefix), &m_ack, m_ackCipher); m_ackCipher.insert(m_ackCipher.begin(), prefix.begin(), prefix.end()); diff --git a/rlp/main.cpp b/rlp/main.cpp index bc1db7c4ae1..f45ad14b882 100644 --- a/rlp/main.cpp +++ b/rlp/main.cpp @@ -29,7 +29,6 @@ #include #include #include -#include using namespace std; using namespace dev; namespace js = json_spirit; @@ -182,7 +181,7 @@ void putOut(bytes _out, Encoding _encoding, bool _encrypt, bool _quiet) { dev::h256 h = dev::sha3(_out); if (_encrypt) - crypto::Secp256k1PP::get()->encrypt(toPublic(Secret(h)), _out); + dev::encrypt(toPublic(Secret(h)), &_out, _out); if (!_quiet) cerr << "Keccak of RLP: " << h.hex() << endl; diff --git a/test/unittests/libdevcrypto/crypto.cpp b/test/unittests/libdevcrypto/crypto.cpp index 75370af2a03..f07c1ca5210 100644 --- a/test/unittests/libdevcrypto/crypto.cpp +++ b/test/unittests/libdevcrypto/crypto.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include using namespace std; @@ -50,12 +49,7 @@ namespace utf = boost::unit_test; BOOST_AUTO_TEST_SUITE(Crypto) -struct DevcryptoTestFixture: public TestOutputHelper { - DevcryptoTestFixture() : s_secp256k1(Secp256k1PP::get()) {} - - Secp256k1PP* s_secp256k1; -}; -BOOST_FIXTURE_TEST_SUITE(devcrypto, DevcryptoTestFixture) +BOOST_FIXTURE_TEST_SUITE(devcrypto, TestOutputHelper) static CryptoPP::AutoSeededRandomPool& rng() { @@ -158,12 +152,12 @@ BOOST_AUTO_TEST_CASE(SignAndRecoverLoop) } } -BOOST_AUTO_TEST_CASE(cryptopp_patch) +BOOST_AUTO_TEST_CASE(decryptEmpty) { KeyPair k = KeyPair::create(); - bytes io_text; - s_secp256k1->decrypt(k.secret(), io_text); - BOOST_REQUIRE_EQUAL(io_text.size(), 0); + bytes text; + decrypt(k.secret(), {}, text); + BOOST_CHECK_EQUAL(text.size(), 0); } BOOST_AUTO_TEST_CASE(verify_secert) @@ -272,16 +266,16 @@ BOOST_AUTO_TEST_CASE(ecdh_agree_invalid_seckey) BOOST_AUTO_TEST_CASE(ecies_standard) { KeyPair k = KeyPair::create(); - + string message("Now is the time for all good persons to come to the aid of humanity."); string original = message; bytes b = asBytes(message); - - s_secp256k1->encryptECIES(k.pub(), b); + + encryptECIES(k.pub(), &b, b); BOOST_REQUIRE(b != asBytes(original)); BOOST_REQUIRE(b.size() > 0 && b[0] == 0x04); - s_secp256k1->decryptECIES(k.secret(), b); + decryptECIES(k.secret(), &b, b); BOOST_REQUIRE(bytesConstRef(&b).cropped(0, original.size()).toBytes() == asBytes(original)); } @@ -289,23 +283,19 @@ BOOST_AUTO_TEST_CASE(ecies_sharedMacData) { KeyPair k = KeyPair::create(); - string message("Now is the time for all good persons to come to the aid of humanity."); - bytes original = asBytes(message); - bytes b = original; - - string shared("shared MAC data"); - string wrongShared("wrong shared MAC data"); + bytes const msg = asBytes("Now is the time for all good persons to come to the aid of humanity."); + string const shared("shared MAC data"); + string const wrongShared("wrong shared MAC data"); - s_secp256k1->encryptECIES(k.pub(), shared, b); - BOOST_REQUIRE(b != original); - BOOST_REQUIRE(b.size() > 0 && b[0] == 0x04); - - BOOST_REQUIRE(!s_secp256k1->decryptECIES(k.secret(), wrongShared, b)); + bytes b = msg; + encryptECIES(k.pub(), shared, &b, b); + BOOST_REQUIRE(!b.empty()); + BOOST_CHECK_EQUAL(b[0], 0x04); + BOOST_CHECK(b != msg); - s_secp256k1->decryptECIES(k.secret(), shared, b); - - auto decrypted = bytesConstRef(&b).cropped(0, original.size()).toBytes(); - BOOST_CHECK_EQUAL(toHex(decrypted), toHex(original)); + BOOST_CHECK(!decryptECIES(k.secret(), wrongShared, &b, b)); + BOOST_CHECK(decryptECIES(k.secret(), shared, &b, b)); + BOOST_CHECK_EQUAL(toHex(bytesConstRef(&b).cropped(0, msg.size())), toHex(msg)); } BOOST_AUTO_TEST_CASE(ecies_eckeypair) @@ -316,11 +306,11 @@ BOOST_AUTO_TEST_CASE(ecies_eckeypair) string original = message; bytes b = asBytes(message); - s_secp256k1->encrypt(k.pub(), b); - BOOST_REQUIRE(b != asBytes(original)); + encrypt(k.pub(), &b, b); + BOOST_CHECK(b != asBytes(original)); - s_secp256k1->decrypt(k.secret(), b); - BOOST_REQUIRE(b == asBytes(original)); + decrypt(k.secret(), &b, b); + BOOST_CHECK(b == asBytes(original)); } BOOST_AUTO_TEST_CASE(ecdhCryptopp) @@ -440,7 +430,7 @@ BOOST_AUTO_TEST_CASE(handshakeNew) } bytes authcipher; encrypt(nodeB.pub(), &auth, authcipher); - BOOST_REQUIRE_EQUAL(authcipher.size(), 279); + BOOST_REQUIRE_EQUAL(authcipher.size(), 307); // Receipient is Bob (nodeB) auto eB = KeyPair::create(); @@ -465,7 +455,7 @@ BOOST_AUTO_TEST_CASE(handshakeNew) } bytes ackcipher; encrypt(nodeA.pub(), &ack, ackcipher); - BOOST_REQUIRE_EQUAL(ackcipher.size(), 182); + BOOST_REQUIRE_EQUAL(ackcipher.size(), 210); BOOST_REQUIRE(eA.pub()); BOOST_REQUIRE(eB.pub()); @@ -795,6 +785,14 @@ BOOST_AUTO_TEST_CASE(recoverVgt3) } } +BOOST_AUTO_TEST_CASE(pbkdf2Static) +{ + auto salt = asBytes("Red Hot Chili Peppers"); + auto key = pbkdf2("Hello Ethereum!", salt, 999, 15); + auto expected = "4187067867ced7bca83da5cfc21a7a"; + BOOST_CHECK_EQUAL(toHex(key.makeInsecure()), expected); +} + BOOST_AUTO_TEST_CASE(PerfSHA256_32, *utf::disabled() *utf::label("perf")) { if (!test::Options::get().performance) diff --git a/test/unittests/libp2p/rlpx.cpp b/test/unittests/libp2p/rlpx.cpp index a092bb3104a..cb9a074d3ae 100644 --- a/test/unittests/libp2p/rlpx.cpp +++ b/test/unittests/libp2p/rlpx.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -45,13 +44,7 @@ using namespace dev::p2p; using namespace dev::test; using namespace CryptoPP; -struct RLPXTestFixture: public TestOutputHelper { - RLPXTestFixture() : s_secp256k1(Secp256k1PP::get()) {} - ~RLPXTestFixture() {} - - Secp256k1PP* s_secp256k1; -}; -BOOST_FIXTURE_TEST_SUITE(rlpx, RLPXTestFixture) +BOOST_FIXTURE_TEST_SUITE(rlpx, TestOutputHelper) BOOST_AUTO_TEST_CASE(test_secrets_cpp_vectors) { @@ -203,11 +196,11 @@ BOOST_AUTO_TEST_CASE(test_secrets_from_go) bytes authPlainExpected(fromHex("0x884c36f7ae6b406637c1f61b2f57e1d2cab813d24c6559aaf843c3f48962f32f46662c066d39669b7b2e3ba14781477417600e7728399278b1b5d801a519aa570034fdb5419558137e0d44cd13d319afe5629eeccb47fd9dfe55cc6089426e46cc762dd8a0636e07a54b31169eba0c7a20a1ac1ef68596f1f283b5c676bae4064abfcce24799d09f67e392632d3ffdc12e3d6430dcb0ea19c318343ffa7aae74d4cd26fecb93657d1cd9e9eaf4f8be720b56dd1d39f190c4e1c6b7ec66f077bb1100")); bytes ackPlainExpected(fromHex("0x802b052f8b066640bba94a4fc39d63815c377fced6fcb84d27f791c9921ddf3e9bf0108e298f490812847109cbd778fae393e80323fd643209841a3b7f110397f37ec61d84cea03dcc5e8385db93248584e8af4b4d1c832d8c7453c0089687a700")); - - bytes authPlain = authCipher; - BOOST_REQUIRE(s_secp256k1->decryptECIES(recv.secret(), authPlain)); - bytes ackPlain = ackCipher; - BOOST_REQUIRE(s_secp256k1->decryptECIES(init.secret(), ackPlain)); + + bytes authPlain; + BOOST_REQUIRE(decryptECIES(recv.secret(), &authCipher, authPlain)); + bytes ackPlain; + BOOST_REQUIRE(decryptECIES(init.secret(), &ackCipher, ackPlain)); CryptoPP::CTR_Mode::Encryption m_frameEnc; CryptoPP::CTR_Mode::Encryption m_frameDec; @@ -435,9 +428,9 @@ BOOST_AUTO_TEST_CASE(ecies_interop_test_primitives) KeyPair kmK(Secret(fromHex("0x57baf2c62005ddec64c357d96183ebc90bf9100583280e848aa31d683cad73cb"))); bytes kmCipher(fromHex("0x04ff2c874d0a47917c84eea0b2a4141ca95233720b5c70f81a8415bae1dc7b746b61df7558811c1d6054333907333ef9bb0cc2fbf8b34abb9730d14e0140f4553f4b15d705120af46cf653a1dc5b95b312cf8444714f95a4f7a0425b67fc064d18f4d0a528761565ca02d97faffdac23de10")); - bytes kmPlain = kmCipher; + bytes kmPlain; bytes kmExpected(asBytes("a")); - BOOST_REQUIRE(s_secp256k1->decryptECIES(kmK.secret(), kmPlain)); + BOOST_REQUIRE(decryptECIES(kmK.secret(), &kmCipher, kmPlain)); BOOST_REQUIRE(kmExpected == kmPlain); KeyPair kenc(Secret(fromHex("0x472413e97f1fd58d84e28a559479e6b6902d2e8a0cee672ef38a3a35d263886b"))); @@ -445,21 +438,21 @@ BOOST_AUTO_TEST_CASE(ecies_interop_test_primitives) BOOST_REQUIRE(penc == kenc.pub()); bytes cipher1(fromHex("0x046f647e1bd8a5cd1446d31513bac233e18bdc28ec0e59d46de453137a72599533f1e97c98154343420d5f16e171e5107999a7c7f1a6e26f57bcb0d2280655d08fb148d36f1d4b28642d3bb4a136f0e33e3dd2e3cffe4b45a03fb7c5b5ea5e65617250fdc89e1a315563c20504b9d3a72555")); - bytes plainTest1 = cipher1; + bytes plainTest1; bytes expectedPlain1 = asBytes("a"); - BOOST_REQUIRE(s_secp256k1->decryptECIES(kenc.secret(), plainTest1)); + BOOST_REQUIRE(decryptECIES(kenc.secret(), &cipher1, plainTest1)); BOOST_REQUIRE(plainTest1 == expectedPlain1); bytes cipher2(fromHex("0x0443c24d6ccef3ad095140760bb143078b3880557a06392f17c5e368502d79532bc18903d59ced4bbe858e870610ab0d5f8b7963dd5c9c4cf81128d10efd7c7aa80091563c273e996578403694673581829e25a865191bdc9954db14285b56eb0043b6288172e0d003c10f42fe413222e273d1d4340c38a2d8344d7aadcbc846ee")); - bytes plainTest2 = cipher2; + bytes plainTest2; bytes expectedPlain2 = asBytes("aaaaaaaaaaaaaaaa"); - BOOST_REQUIRE(s_secp256k1->decryptECIES(kenc.secret(), plainTest2)); + BOOST_REQUIRE(decryptECIES(kenc.secret(), &cipher2, plainTest2)); BOOST_REQUIRE(plainTest2 == expectedPlain2); bytes cipher3(fromHex("0x04c4e40c86bb5324e017e598c6d48c19362ae527af8ab21b077284a4656c8735e62d73fb3d740acefbec30ca4c024739a1fcdff69ecaf03301eebf156eb5f17cca6f9d7a7e214a1f3f6e34d1ee0ec00ce0ef7d2b242fbfec0f276e17941f9f1bfbe26de10a15a6fac3cda039904ddd1d7e06e7b96b4878f61860e47f0b84c8ceb64f6a900ff23844f4359ae49b44154980a626d3c73226c19e")); - bytes plainTest3 = cipher3; + bytes plainTest3; bytes expectedPlain3 = asBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - BOOST_REQUIRE(s_secp256k1->decryptECIES(kenc.secret(), plainTest3)); + BOOST_REQUIRE(decryptECIES(kenc.secret(), &cipher3, plainTest3)); BOOST_REQUIRE(plainTest3 == expectedPlain3); }