From fab63ce0a086f0e261a3c0abda69bb19a6e4eb1c Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 13 Nov 2014 02:00:19 +0100 Subject: [PATCH] refactor and thread-safe cryptopp. for now, remove secp256klib calls. ecdh and tests. move sha3mac into sha3. --- libdevcrypto/AES.cpp | 17 +++- libdevcrypto/AES.h | 5 +- libdevcrypto/All.h | 7 +- libdevcrypto/Common.cpp | 103 +++++++++++-------- libdevcrypto/Common.h | 11 +- libdevcrypto/CryptoPP.cpp | 192 ++++++++++++++++++++++++++++++++--- libdevcrypto/CryptoPP.h | 90 ++++++++++++----- libdevcrypto/EC.cpp | 208 -------------------------------------- libdevcrypto/EC.h | 62 ------------ libdevcrypto/ECDHE.cpp | 31 ++++-- libdevcrypto/ECDHE.h | 4 +- libdevcrypto/SHA3.cpp | 10 ++ libdevcrypto/SHA3.h | 3 + libdevcrypto/SHA3MAC.cpp | 40 -------- libdevcrypto/SHA3MAC.h | 38 ------- libethcore/CommonEth.cpp | 27 ----- libethereum/State.cpp | 4 - test/crypto.cpp | 143 +++++++++----------------- 18 files changed, 414 insertions(+), 581 deletions(-) delete mode 100644 libdevcrypto/EC.cpp delete mode 100644 libdevcrypto/EC.h delete mode 100644 libdevcrypto/SHA3MAC.cpp delete mode 100644 libdevcrypto/SHA3MAC.h diff --git a/libdevcrypto/AES.cpp b/libdevcrypto/AES.cpp index fc0cf15c4..1807bad19 100644 --- a/libdevcrypto/AES.cpp +++ b/libdevcrypto/AES.cpp @@ -23,14 +23,21 @@ #include "AES.h" using namespace std; +using namespace dev; +using namespace dev::crypto; using namespace dev::crypto::aes; -using namespace dev::crypto::pp; using namespace CryptoPP; +struct aes::Aes128Ctr +{ + Aes128Ctr(h128 _k) { mode.SetKeyWithIV(_k.data(), sizeof(h128), Nonce::get().data()); } + CryptoPP::CTR_Mode::Encryption mode; +}; + Stream::Stream(StreamType _t, h128 _ckey): m_cSecret(_ckey) { - (void)_t; // encrypt and decrypt are same operation w/ctr mode + (void)_t; // encrypt and decrypt are same operation w/ctr cryptor = new Aes128Ctr(_ckey); } @@ -39,13 +46,13 @@ Stream::~Stream() delete cryptor; } -void Stream::update(bytesRef io_bytes) +void Stream::update(bytesRef) { } -size_t Stream::streamOut(bytes& o_bytes) +size_t Stream::streamOut(bytes&) { - + return 0; } diff --git a/libdevcrypto/AES.h b/libdevcrypto/AES.h index 753dcd14b..2bb852653 100644 --- a/libdevcrypto/AES.h +++ b/libdevcrypto/AES.h @@ -29,10 +29,10 @@ namespace dev { namespace crypto { -namespace pp { struct Aes128Ctr; } namespace aes { +struct Aes128Ctr; enum StreamType { Encrypt, Decrypt }; /** @@ -54,8 +54,9 @@ private: h128 m_cSecret; bytes m_text; - pp::Aes128Ctr* cryptor; + Aes128Ctr* cryptor; }; + /** * @brief Encrypted stream with inband SHA3 mac at specific interval. diff --git a/libdevcrypto/All.h b/libdevcrypto/All.h index 8018db4fb..9070725e9 100644 --- a/libdevcrypto/All.h +++ b/libdevcrypto/All.h @@ -1,11 +1,8 @@ #pragma once #include "Common.h" -#include "EC.h" +#include "AES.h" +#include "ECDHE.h" #include "FileSystem.h" -#include "MemoryDB.h" -#include "OverlayDB.h" #include "SHA3.h" -#include "SHA3MAC.h" -#include "TrieCommon.h" #include "TrieDB.h" diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index d82098655..2a105ff25 100644 --- a/libdevcrypto/Common.cpp +++ b/libdevcrypto/Common.cpp @@ -22,70 +22,46 @@ #include #include -#include "EC.h" #include "SHA3.h" #include "FileSystem.h" +#include "CryptoPP.h" #include "Common.h" using namespace std; using namespace dev; -using namespace crypto; +using namespace dev::crypto; -//#define ETH_ADDRESS_DEBUG 1 +static Secp256k1 s_secp256k1; -Address dev::toAddress(Secret _secret) +Public dev::toPublic(Secret _secret) { - return KeyPair(_secret).address(); + Public p; + s_secp256k1.toPublic(_secret, p); + return std::move(p); } -KeyPair KeyPair::create() +Address dev::toAddress(Public _public) { - static mt19937_64 s_eng(time(0)); - uniform_int_distribution d(0, 255); - - for (int i = 0; i < 100; ++i) - { - h256 sec; - for (unsigned i = 0; i < 32; ++i) - sec[i] = (byte)d(s_eng); - - KeyPair ret(sec); - if (ret.address()) - return ret; - } - return KeyPair(); -} - -KeyPair::KeyPair(h256 _sec): - m_secret(_sec) -{ - toPublic(m_secret, m_public); - if (verifySecret(m_secret, m_public)) - m_address = right160(dev::sha3(m_public.ref())); - -#if ETH_ADDRESS_DEBUG - cout << "---- ADDRESS -------------------------------" << endl; - cout << "SEC: " << m_secret << endl; - cout << "PUB: " << m_public << endl; - cout << "ADR: " << m_address << endl; -#endif + return s_secp256k1.toAddress(_public); } -KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password) +Address dev::toAddress(Secret _secret) { - return KeyPair(sha3(aesDecrypt(_seed, _password))); + Public p; + s_secp256k1.toPublic(_secret, p); + return s_secp256k1.toAddress(p); } void dev::encrypt(Public _k, bytesConstRef _plain, bytes& o_cipher) { bytes io = _plain.toBytes(); - crypto::encrypt(_k, io); + s_secp256k1.encrypt(_k, io); o_cipher = std::move(io); } bool dev::decrypt(Secret _k, bytesConstRef _cipher, bytes& o_plaintext) { bytes io = _cipher.toBytes(); - crypto::decrypt(_k, io); + s_secp256k1.decrypt(_k, io); if (io.empty()) return false; o_plaintext = std::move(io); @@ -94,17 +70,60 @@ bool dev::decrypt(Secret _k, bytesConstRef _cipher, bytes& o_plaintext) Public dev::recover(Signature _sig, h256 _message) { - return crypto::recover(_sig, _message.ref()); + return s_secp256k1.recover(_sig, _message.ref()); } Signature dev::sign(Secret _k, h256 _hash) { - return crypto::sign(_k, _hash); + return s_secp256k1.sign(_k, _hash); } bool dev::verify(Public _p, Signature _s, h256 _hash) { - return crypto::verify(_p, _s, bytesConstRef(_hash.data(), 32), true); + return s_secp256k1.verify(_p, _s, bytesConstRef(_hash.data(), 32), true); +} + +KeyPair KeyPair::create() +{ + static mt19937_64 s_eng(time(0)); + uniform_int_distribution d(0, 255); + + for (int i = 0; i < 100; ++i) + { + h256 sec; + for (unsigned i = 0; i < 32; ++i) + sec[i] = (byte)d(s_eng); + + KeyPair ret(sec); + if (ret.address()) + return ret; + } + return KeyPair(); +} + +KeyPair::KeyPair(h256 _sec): + m_secret(_sec) +{ + if (s_secp256k1.verifySecret(m_secret, m_public)) + m_address = s_secp256k1.toAddress(m_public); +} + +KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password) +{ + return KeyPair(sha3(aesDecrypt(_seed, _password))); +} + +h256 crypto::kdf(Secret const& _priv, h256 const& _hash) +{ + // H(H(r||k)^h) + h256 s; + sha3mac(Nonce::get().ref(), _priv.ref(), s.ref()); + s ^= _hash; + sha3(s.ref(), s.ref()); + + if (!s || !_hash || !_priv) + BOOST_THROW_EXCEPTION(InvalidState()); + return std::move(s); } h256 Nonce::get(bool _commit) diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h index e95eefa40..cd0996826 100644 --- a/libdevcrypto/Common.h +++ b/libdevcrypto/Common.h @@ -30,7 +30,7 @@ namespace dev { - + /// A secret key: 32 bytes. /// @NOTE This is not endian-specific; it's just a bunch of bytes. using Secret = h256; @@ -59,6 +59,12 @@ using AddressSet = std::set; using Secrets = h256s; /// Convert a secret key into the public key equivalent. +Public toPublic(Secret _secret); + +/// Convert a public key to address. +Address toAddress(Public _public); + +/// Convert a secret key into address of public key equivalent. /// @returns 0 if it's not a valid secret key. Address toAddress(Secret _secret); @@ -119,6 +125,9 @@ namespace crypto { struct InvalidState: public dev::Exception {}; +/// Key derivation +h256 kdf(Secret const& _priv, h256 const& _hash); + /** * @brief Generator for nonce material */ diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp index 0694699ae..1edddefa1 100644 --- a/libdevcrypto/CryptoPP.cpp +++ b/libdevcrypto/CryptoPP.cpp @@ -21,35 +21,203 @@ #include "CryptoPP.h" +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."); -/// Integer and Point Conversion: +void Secp256k1::encrypt(Public const& _k, bytes& io_cipher) +{ + ECIES::Encryptor e; + initializeDLScheme(_k, e); -void pp::exportPublicKey(CryptoPP::DL_PublicKey_EC const& _k, Public& _p) + size_t plen = io_cipher.size(); + bytes ciphertext; + ciphertext.resize(e.CiphertextLength(plen)); + + { + lock_guard l(x_rng); + e.Encrypt(m_rng, io_cipher.data(), plen, ciphertext.data()); + } + + memset(io_cipher.data(), 0, io_cipher.size()); + io_cipher = std::move(ciphertext); +} + +void Secp256k1::decrypt(Secret const& _k, bytes& io_text) { - bytes prefixedKey(_k.GetGroupParameters().GetEncodedElementSize(true)); + CryptoPP::ECIES::Decryptor d; + initializeDLScheme(_k, d); + + size_t clen = io_text.size(); + bytes plain; + plain.resize(d.MaxPlaintextLength(io_text.size())); - secp256k1Params.GetCurve().EncodePoint(prefixedKey.data(), _k.GetPublicElement(), false); + DecodingResult r; + { + lock_guard l(x_rng); + r = d.Decrypt(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); +} - assert(Public::size + 1 == _k.GetGroupParameters().GetEncodedElementSize(true)); - memcpy(_p.data(), &prefixedKey[1], Public::size); +Signature Secp256k1::sign(Secret const& _k, bytesConstRef _message) +{ + return sign(_k, sha3(_message)); } -void pp::exponentToPublic(Integer const& _e, Public& _p) +Signature Secp256k1::sign(Secret const& _key, h256 const& _hash) { - CryptoPP::DL_PublicKey_EC pk; - pk.Initialize(secp256k1Params, secp256k1Params.ExponentiateBase(_e)); - pp::exportPublicKey(pk, _p); + Signature sig; + + Integer k(kdf(_key, _hash).data(), 32); + if (k == 0) + BOOST_THROW_EXCEPTION(InvalidState()); + k = 1 + (k % (m_qs - 1)); + + ECP::Point rp; + Integer r; + { + lock_guard l(x_params); + rp = m_params.ExponentiateBase(k); + r = m_params.ConvertElementToInteger(rp); + } + sig[64] = 0; +// sig[64] = (r >= m_q) ? 2 : 0; + + Integer kInv = k.InverseMod(m_q); + Integer z(_hash.asBytes().data(), 32); + Integer s = (kInv * (Integer(_key.asBytes().data(), 32)*r + z)) % m_q; + if (r == 0 || s == 0) + BOOST_THROW_EXCEPTION(InvalidState()); + +// if (s > m_qs) +// { +// s = m_q - s; +// if (sig[64]) +// sig[64] ^= 1; +// } + + sig[64] |= rp.y.IsOdd() ? 1 : 0; + r.Encode(sig.data(), 32); + s.Encode(sig.data() + 32, 32); + return sig; } -void pp::ecdhAgree(Secret const& _s, Public const& _r, h256& o_s) +bool Secp256k1::verify(Signature const& _signature, bytesConstRef _message) { - ECDH::Domain d(secp256k1Curve); + return !!recover(_signature, _message); +} + +bool Secp256k1::verify(Public const& _p, Signature const& _sig, bytesConstRef _message, bool _hashed) +{ + // todo: verify w/o recovery (if faster) + return _p == _hashed ? recover(_sig, _message) : recover(_sig, sha3(_message).ref()); +} + +Public Secp256k1::recover(Signature _signature, bytesConstRef _message) +{ + Public recovered; + + Integer r(_signature.data(), 32); + Integer s(_signature.data()+32, 32); + // cryptopp encodes sign of y as 0x02/0x03 instead of 0/1 or 27/28 + byte encodedpoint[33]; + encodedpoint[0] = _signature[64]|2; + memcpy(&encodedpoint[1], _signature.data(), 32); + + ECP::Element x; + { + lock_guard l(x_curve); + m_curve.DecodePoint(x, encodedpoint, 33); + if (!m_curve.VerifyPoint(x)) + return recovered; + } + +// if (_signature[64] & 2) +// { +// r += m_q; +// lock_guard l(x_params); +// if (r >= m_params.GetMaxExponent()) +// return recovered; +// } + + Integer z(_message.data(), 32); + Integer rn = r.InverseMod(m_q); + Integer u1 = m_q - (rn.Times(z)).Modulo(m_q); + Integer u2 = (rn.Times(s)).Modulo(m_q); + + ECP::Point p; + byte recoveredbytes[65]; + { + lock_guard l(x_curve); + // todo: make generator member + p = m_curve.CascadeMultiply(u2, x, u1, m_params.GetSubgroupGenerator()); + m_curve.EncodePoint(recoveredbytes, p, false); + } + memcpy(recovered.data(), &recoveredbytes[1], 64); + return recovered; +} + +bool Secp256k1::verifySecret(Secret const& _s, Public& _p) +{ + DL_PrivateKey_EC k; + k.Initialize(m_params, secretToExponent(_s)); + if (!k.Validate(m_rng, 3)) + return false; + + DL_PublicKey_EC pub; + k.MakePublicKey(pub); + if (!k.Validate(m_rng, 3)) + return false; + + exportPublicKey(pub, _p); + return true; +} + +void Secp256k1::agree(Secret const& _s, Public const& _r, h256& o_s) +{ + ECDH::Domain d(m_oid); assert(d.AgreedValueLength() == sizeof(o_s)); byte remote[65] = {0x04}; memcpy(&remote[1], _r.data(), 64); assert(d.Agree(o_s.data(), _s.data(), remote)); } + +void Secp256k1::exportPublicKey(CryptoPP::DL_PublicKey_EC const& _k, Public& _p) +{ + bytes prefixedKey(_k.GetGroupParameters().GetEncodedElementSize(true)); + + { + lock_guard l(x_params); + m_params.GetCurve().EncodePoint(prefixedKey.data(), _k.GetPublicElement(), false); + assert(Public::size + 1 == _k.GetGroupParameters().GetEncodedElementSize(true)); + } + + memcpy(_p.data(), &prefixedKey[1], Public::size); +} + +void Secp256k1::exponentToPublic(Integer const& _e, Public& _p) +{ + CryptoPP::DL_PublicKey_EC pk; + + { + lock_guard l(x_params); + pk.Initialize(m_params, m_params.ExponentiateBase(_e)); + } + + exportPublicKey(pk, _p); +} + diff --git a/libdevcrypto/CryptoPP.h b/libdevcrypto/CryptoPP.h index 1ae4bee74..b8c1272d9 100644 --- a/libdevcrypto/CryptoPP.h +++ b/libdevcrypto/CryptoPP.h @@ -23,6 +23,7 @@ #pragma once +#include // need to leave this one disabled for link-time. blame cryptopp. #pragma GCC diagnostic ignored "-Wunused-function" #pragma warning(push) @@ -48,50 +49,85 @@ #include #pragma warning(pop) #pragma GCC diagnostic pop +#include "SHA3.h" #include "Common.h" namespace dev { namespace crypto { -namespace pp -{ - + using namespace CryptoPP; + +inline ECP::Point publicToPoint(Public const& _p) { Integer x(_p.data(), 32); Integer y(_p.data() + 32, 32); return std::move(ECP::Point(x,y)); } + +inline Integer secretToExponent(Secret const& _s) { return std::move(Integer(_s.data(), Secret::size)); } -/// CryptoPP random number pool -static CryptoPP::AutoSeededRandomPool PRNG; +/** + * CryptoPP secp256k1 algorithms. + */ +class Secp256k1 +{ +public: + Secp256k1(): m_oid(ASN1::secp256k1()), m_params(m_oid), m_curve(m_params.GetCurve()), m_q(m_params.GetGroupOrder()), m_qs(m_params.GetSubgroupOrder()) {} -/// CryptoPP EC Cruve -static const CryptoPP::OID secp256k1Curve = CryptoPP::ASN1::secp256k1(); + Address toAddress(Public const& _p) { return right160(sha3(_p.ref())); } -static const CryptoPP::DL_GroupParameters_EC secp256k1Params(secp256k1Curve); + void toPublic(Secret const& _s, Public& o_public) { exponentToPublic(Integer(_s.data(), sizeof(_s)), o_public); } -static ECP::Point publicToPoint(Public const& _p) { Integer x(_p.data(), 32); Integer y(_p.data() + 32, 32); return std::move(ECP::Point(x,y)); } + /// Encrypts text (replace input). + void encrypt(Public const& _k, bytes& io_cipher); -static Integer secretToExponent(Secret const& _s) { return std::move(Integer(_s.data(), Secret::size)); } - -void exportPublicKey(CryptoPP::DL_PublicKey_EC const& _k, Public& _p); - -static void exportPrivateKey(CryptoPP::DL_PrivateKey_EC const& _k, Secret& _s) { _k.GetPrivateExponent().Encode(_s.data(), Secret::size); } + /// Decrypts text (replace input). + void decrypt(Secret const& _k, bytes& io_text); -void exponentToPublic(Integer const& _e, Public& _p); - -void ecdhAgree(Secret const& _s, Public const& _r, h256& o_s); - -template -void initializeDLScheme(Secret const& _s, T& io_operator) { io_operator.AccessKey().Initialize(pp::secp256k1Params, secretToExponent(_s)); } + /// @returns siganture of message. + Signature sign(Secret const& _k, bytesConstRef _message); -template -void initializeDLScheme(Public const& _p, T& io_operator) { io_operator.AccessKey().Initialize(pp::secp256k1Params, publicToPoint(_p)); } + /// @returns compact siganture of message hash. + Signature sign(Secret const& _k, h256 const& _hash); -struct Aes128Ctr -{ - Aes128Ctr(h128 _k) { mode.SetKeyWithIV(_k.data(), sizeof(h128), Nonce::get().data()); } - CTR_Mode::Encryption mode; + /// Verify compact signature (public key is extracted from message). + bool verify(Signature const& _signature, bytesConstRef _message); + + /// Verify signature. + bool verify(Public const& _p, Signature const& _sig, bytesConstRef _message, bool _hashed = false); + + /// Recovers public key from compact signature. Uses libsecp256k1. + Public recover(Signature _signature, bytesConstRef _message); + + /// Verify secret key is valid. + bool verifySecret(Secret const& _s, Public& o_p); + + void agree(Secret const& _s, Public const& _r, h256& o_s); + +protected: + void exportPrivateKey(DL_PrivateKey_EC const& _k, Secret& _s) { _k.GetPrivateExponent().Encode(_s.data(), Secret::size); } + + void exportPublicKey(DL_PublicKey_EC const& _k, Public& _p); + + void exponentToPublic(Integer const& _e, Public& _p); + + template void initializeDLScheme(Secret const& _s, T& io_operator) { std::lock_guard l(x_params); io_operator.AccessKey().Initialize(m_params, secretToExponent(_s)); } + + template void initializeDLScheme(Public const& _p, T& io_operator) { std::lock_guard l(x_params); io_operator.AccessKey().Initialize(m_params, publicToPoint(_p)); } + +private: + OID m_oid; + + std::mutex x_rng; + AutoSeededRandomPool m_rng; + + std::mutex x_params; + DL_GroupParameters_EC m_params; + + std::mutex x_curve; + DL_GroupParameters_EC::EllipticCurve m_curve; + + Integer m_q; + Integer m_qs; }; } } -} diff --git a/libdevcrypto/EC.cpp b/libdevcrypto/EC.cpp deleted file mode 100644 index a509a5b41..000000000 --- a/libdevcrypto/EC.cpp +++ /dev/null @@ -1,208 +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 EC.cpp - * @author Alex Leverington - * @date 2014 - * - * ECDSA, ECIES - */ - -#include -#include "CryptoPP.h" -#include "SHA3.h" -#include "SHA3MAC.h" -#include "EC.h" - -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."); - -using namespace std; -using namespace dev; -using namespace dev::crypto; -using namespace CryptoPP; -using namespace pp; - -void crypto::toPublic(Secret const& _s, Public& o_public) -{ - exponentToPublic(Integer(_s.data(), sizeof(_s)), o_public); -} - -h256 crypto::kdf(Secret const& _priv, h256 const& _hash) -{ - // H(H(r||k)^h) - h256 s; - sha3mac(Nonce::get().ref(), _priv.ref(), s.ref()); - s ^= _hash; - sha3(s.ref(), s.ref()); - - if (!s || !_hash || !_priv) - BOOST_THROW_EXCEPTION(InvalidState()); - return std::move(s); -} - -void crypto::encrypt(Public const& _k, bytes& io_cipher) -{ - ECIES::Encryptor e; - initializeDLScheme(_k, e); - size_t plen = io_cipher.size(); - bytes c; - c.resize(e.CiphertextLength(plen)); - // todo: use StringSource with io_cipher as input and output. - e.Encrypt(PRNG, io_cipher.data(), plen, c.data()); - memset(io_cipher.data(), 0, io_cipher.size()); - io_cipher = std::move(c); -} - -void crypto::decrypt(Secret const& _k, bytes& io_text) -{ - CryptoPP::ECIES::Decryptor d; - initializeDLScheme(_k, d); - size_t clen = io_text.size(); - bytes p; - p.resize(d.MaxPlaintextLength(io_text.size())); - // todo: use StringSource with io_text as input and output. - DecodingResult r = d.Decrypt(PRNG, io_text.data(), clen, p.data()); - if (!r.isValidCoding) - { - io_text.clear(); - return; - } - io_text.resize(r.messageLength); - io_text = std::move(p); -} - -Signature crypto::sign(Secret const& _k, bytesConstRef _message) -{ - return crypto::sign(_k, sha3(_message)); -} - -Signature crypto::sign(Secret const& _key, h256 const& _hash) -{ - ECDSA::Signer signer; - initializeDLScheme(_key, signer); - - Integer const& q = secp256k1Params.GetGroupOrder(); - Integer const& qs = secp256k1Params.GetSubgroupOrder(); - Integer e(_hash.asBytes().data(), 32); - - Integer k(kdf(_key, _hash).data(), 32); - if (k == 0) - BOOST_THROW_EXCEPTION(InvalidState()); - k = 1 + (k % (qs - 1)); - - ECP::Point rp = secp256k1Params.ExponentiateBase(k); - Integer r = secp256k1Params.ConvertElementToInteger(rp); - int recid = ((r >= q) ? 2 : 0) | (rp.y.IsOdd() ? 1 : 0); - - Integer kInv = k.InverseMod(q); - Integer s = (kInv * (Integer(_key.asBytes().data(), 32)*r + e)) % q; - assert(!!r && !!s); - - if (s > qs) - { - s = q - s; - if (recid) - recid ^= 1; - } - - Signature sig; - r.Encode(sig.data(), 32); - s.Encode(sig.data() + 32, 32); - sig[64] = recid; - return sig; -} - -bool crypto::verify(Signature const& _signature, bytesConstRef _message) -{ - return crypto::verify(crypto::recover(_signature, _message), _signature, _message); -} - -bool crypto::verify(Public const& _p, Signature const& _sig, bytesConstRef _message, bool _hashed) -{ - static size_t derMaxEncodingLength = 72; - if (_hashed) - { - assert(_message.size() == 32); - byte encpub[65] = {0x04}; - memcpy(&encpub[1], _p.data(), 64); - byte dersig[derMaxEncodingLength]; - size_t cssz = DSAConvertSignatureFormat(dersig, derMaxEncodingLength, DSA_DER, _sig.data(), 64, DSA_P1363); - assert(cssz <= derMaxEncodingLength); - return (1 == secp256k1_ecdsa_verify(_message.data(), _message.size(), dersig, cssz, encpub, 65)); - } - - ECDSA::Verifier verifier; - initializeDLScheme(_p, verifier); - return verifier.VerifyMessage(_message.data(), _message.size(), _sig.data(), sizeof(Signature) - 1); -} - -Public crypto::recover(Signature _signature, bytesConstRef _message) -{ - Integer heInt(_message.data(), 32); - - // a different curve would require additional check for v (aka, recid) - Integer r(_signature.data(), 32); - Integer s(_signature.data()+32, 32); - unsigned recid = _signature[64]; - - byte encodedpoint[33]; - encodedpoint[0] = recid|2; - memcpy(&encodedpoint[1], _signature.data(), 32); - - ECP::Element x; - secp256k1Params.GetCurve().DecodePoint(x, encodedpoint, 33); - - if (!secp256k1Params.GetCurve().VerifyPoint(x)) - BOOST_THROW_EXCEPTION(InvalidState()); - - Integer rn = r.InverseMod(secp256k1Params.GetGroupOrder()); - Integer u1 = secp256k1Params.GetGroupOrder() - (rn.Times(heInt)).Modulo(secp256k1Params.GetGroupOrder()); - Integer u2 = (rn.Times(s)).Modulo(secp256k1Params.GetGroupOrder()); - - ECP::Point p = secp256k1Params.GetCurve().CascadeMultiply(u2, x, u1, secp256k1Params.GetSubgroupGenerator()); - byte recoveredbytes[65]; - secp256k1Params.GetCurve().EncodePoint(recoveredbytes, p, false); - Public recovered; - memcpy(recovered.data(), &recoveredbytes[1], 64); - return recovered; -} - -bool crypto::verifySecret(Secret const& _s, Public const& _p) -{ - secp256k1_start(); - int ok = secp256k1_ecdsa_seckey_verify(_s.data()); - if (!ok) - return false; - - int pubkeylen = 65; - byte pubkey[pubkeylen]; - ok = secp256k1_ecdsa_pubkey_create(pubkey, &pubkeylen, _s.data(), 0); - if (!ok || pubkeylen != 65) - return false; - - ok = secp256k1_ecdsa_pubkey_verify(pubkey, 65); - if (!ok) - return false; - - for (int i = 0; i < 32; i++) - if (pubkey[i+1]!=_p[i]) - return false; - - return true; -} - diff --git a/libdevcrypto/EC.h b/libdevcrypto/EC.h deleted file mode 100644 index 2a4155edf..000000000 --- a/libdevcrypto/EC.h +++ /dev/null @@ -1,62 +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 EC.h - * @author Alex Leverington - * @date 2014 - * - * ECDSA, ECIES - */ - -#pragma once - -#include "Common.h" - -namespace dev -{ -namespace crypto -{ - -void toPublic(Secret const& _s, Public& o_public); -h256 kdf(Secret const& _priv, h256 const& _hash); - -/// Encrypts text (in place). -void encrypt(Public const& _k, bytes& io_cipher); - -/// Decrypts text (in place). -void decrypt(Secret const& _k, bytes& io_text); - -/// Returns siganture of message. -Signature sign(Secret const& _k, bytesConstRef _message); - -/// Returns compact siganture of message hash. -Signature sign(Secret const& _k, h256 const& _hash); - -/// Verify compact signature (public key is extracted from message). -bool verify(Signature const& _signature, bytesConstRef _message); - -/// Verify signature. -bool verify(Public const& _p, Signature const& _sig, bytesConstRef _message, bool _hashed = false); - -/// Recovers public key from compact signature. Uses libsecp256k1. -Public recover(Signature _signature, bytesConstRef _message); - -bool verifySecret(Secret const& _s, Public const& _p); - -} - -} - diff --git a/libdevcrypto/ECDHE.cpp b/libdevcrypto/ECDHE.cpp index 6b3979874..d6874fa33 100644 --- a/libdevcrypto/ECDHE.cpp +++ b/libdevcrypto/ECDHE.cpp @@ -20,14 +20,14 @@ */ #include "SHA3.h" -#include "SHA3MAC.h" #include "CryptoPP.h" #include "ECDHE.h" using namespace std; using namespace dev; using namespace dev::crypto; -using namespace dev::crypto::pp; + +static Secp256k1 s_secp256k1; void ECDHE::agree(Public const& _remote, Secret& o_sharedSecret) { @@ -36,12 +36,12 @@ void ECDHE::agree(Public const& _remote, Secret& o_sharedSecret) BOOST_THROW_EXCEPTION(InvalidState()); m_remoteEphemeral = _remote; - ecdhAgree(m_ephemeral.sec(), m_remoteEphemeral, o_sharedSecret); + s_secp256k1.agree(m_ephemeral.sec(), m_remoteEphemeral, o_sharedSecret); } void ECDHEKeyExchange::agree(Public const& _remoteEphemeral) { - ecdhAgree(m_ephemeral.sec(), _remoteEphemeral, m_ephemeralSecret); + s_secp256k1.agree(m_ephemeral.sec(), _remoteEphemeral, m_ephemeralSecret); } void ECDHEKeyExchange::exchange(bytes& o_exchange) @@ -50,16 +50,29 @@ void ECDHEKeyExchange::exchange(bytes& o_exchange) // didn't agree on public remote BOOST_THROW_EXCEPTION(InvalidState()); + // The key exchange payload is in two parts and is encrypted + // using ephemeral keypair. + // + // The first part is the 'prefix' which is a zero-knowledge proof + // allowing the remote to resume or emplace a previous session. + // If a session previously exists: + // prefix is sha3(token) // todo: ephemeral entropy from both sides + // If a session doesn't exist: + // prefix is sha3mac(m_ephemeralSecret, + // + // The second part is encrypted using the public key which relates to the prefix. + Public encpk = m_known.first|m_remoteEphemeral; bytes exchange(encpk.asBytes()); // This is the public key which we would like the remote to use, - // which maybe different than previously-known public key. - // Here we would pick an appropriate alias or generate a new one, + // which maybe different than the previously-known public key. + // + // Here we should pick an appropriate alias or generate a new one, // but for now, we use static alias passed to constructor. // Public p; - pp::exponentToPublic(pp::secretToExponent(m_alias.m_secret), p); + s_secp256k1.toPublic(m_alias.m_secret, p); exchange.resize(exchange.size() + sizeof(p)); memcpy(exchange.data() - sizeof(p), p.data(), sizeof(p)); @@ -70,7 +83,7 @@ void ECDHEKeyExchange::exchange(bytes& o_exchange) h256 auth; sha3mac(m_alias.m_secret.ref(), m_ephemeralSecret.ref(), auth.ref()); - Signature sig = crypto::sign(m_alias.m_secret, auth); + Signature sig = s_secp256k1.sign(m_alias.m_secret, auth); exchange.resize(exchange.size() + sizeof(sig)); memcpy(exchange.data() - sizeof(sig), sig.data(), sizeof(sig)); @@ -78,7 +91,7 @@ void ECDHEKeyExchange::exchange(bytes& o_exchange) h256 prefix(sha3((h256)(m_known.second|m_remoteEphemeral))); aes.update(prefix.ref()); - encrypt(encpk, exchange); + s_secp256k1.encrypt(encpk, exchange); aes.update(&exchange); aes.streamOut(o_exchange); diff --git a/libdevcrypto/ECDHE.h b/libdevcrypto/ECDHE.h index 88e5ba764..86c333cf9 100644 --- a/libdevcrypto/ECDHE.h +++ b/libdevcrypto/ECDHE.h @@ -24,7 +24,6 @@ #pragma once #include "AES.h" -#include "EC.h" namespace dev { @@ -33,6 +32,9 @@ namespace crypto typedef std::pair AliasSession; +/** + * @brief An addressable EC key pair. + */ class Alias { friend class ECDHEKeyExchange; // todo: remove diff --git a/libdevcrypto/SHA3.cpp b/libdevcrypto/SHA3.cpp index 4a0cd469e..1fc9be950 100644 --- a/libdevcrypto/SHA3.cpp +++ b/libdevcrypto/SHA3.cpp @@ -86,6 +86,16 @@ h256 sha3(bytesConstRef _input) sha3(_input, bytesRef(&ret[0], 32)); return ret; } + +void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) +{ + CryptoPP::SHA3_256 ctx; + assert(_secret.size() > 0); + ctx.Update((byte*)_secret.data(), _secret.size()); + ctx.Update((byte*)_plain.data(), _plain.size()); + assert(_output.size() >= 32); + ctx.Final(_output.data()); +} bytes aesDecrypt(bytesConstRef _ivCipher, std::string const& _password, unsigned _rounds, bytesConstRef _salt) { diff --git a/libdevcrypto/SHA3.h b/libdevcrypto/SHA3.h index 7aa4db246..f27e378ba 100644 --- a/libdevcrypto/SHA3.h +++ b/libdevcrypto/SHA3.h @@ -55,6 +55,9 @@ inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef((bytes*)&_inpu /// Calculate SHA3-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash. inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); } + +/// Calculate SHA3-256 MAC +void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output); /// Calculate SHA3-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash. template inline h256 sha3(FixedHash const& _input) { return sha3(_input.ref()); } diff --git a/libdevcrypto/SHA3MAC.cpp b/libdevcrypto/SHA3MAC.cpp deleted file mode 100644 index 9498ef87b..000000000 --- a/libdevcrypto/SHA3MAC.cpp +++ /dev/null @@ -1,40 +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 SHA3MAC.cpp - * @author Alex Leverington - * @date 2014 - * - * SHA3 MAC - */ - -#include "CryptoPP.h" -#include "SHA3MAC.h" - -using namespace dev; -using namespace dev::crypto; -using namespace CryptoPP; - -void crypto::sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) -{ - CryptoPP::SHA3_256 ctx; - assert(_secret.size() > 0); - ctx.Update((byte*)_secret.data(), _secret.size()); - ctx.Update((byte*)_plain.data(), _plain.size()); - assert(_output.size() >= 32); - ctx.Final(_output.data()); -} - diff --git a/libdevcrypto/SHA3MAC.h b/libdevcrypto/SHA3MAC.h deleted file mode 100644 index 4b2d06eac..000000000 --- a/libdevcrypto/SHA3MAC.h +++ /dev/null @@ -1,38 +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 SHA3MAC.h - * @author Alex Leverington - * @date 2014 - * - * SHA3 MAC - */ - -#pragma once - -#include -#include - -namespace dev -{ -namespace crypto -{ - -void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output); - -} -} - diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index 8e21884ee..3918ff6c7 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -28,7 +28,6 @@ using namespace std; using namespace dev; using namespace dev::eth; -//#define ETH_ADDRESS_DEBUG 1 namespace dev { namespace eth @@ -84,30 +83,4 @@ std::string formatBalance(u256 _b) return ret.str(); } -Address toAddress(Secret _private) -{ - secp256k1_start(); - - byte pubkey[65]; - int pubkeylen = 65; - int ok = secp256k1_ecdsa_seckey_verify(_private.data()); - if (!ok) - return Address(); - ok = secp256k1_ecdsa_pubkey_create(pubkey, &pubkeylen, _private.data(), 0); - assert(pubkeylen == 65); - if (!ok) - return Address(); - ok = secp256k1_ecdsa_pubkey_verify(pubkey, 65); - if (!ok) - return Address(); - auto ret = right160(dev::sha3(bytesConstRef(&(pubkey[1]), 64))); -#if ETH_ADDRESS_DEBUG - cout << "---- ADDRESS -------------------------------" << endl; - cout << "SEC: " << _private << endl; - cout << "PUB: " << toHex(bytesConstRef(&(pubkey[1]), 64)) << endl; - cout << "ADR: " << ret << endl; -#endif - return ret; -} - }} diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 35e00f588..8add9e954 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -113,8 +113,6 @@ State::State(Address _coinbaseAddress, OverlayDB const& _db): m_ourAddress(_coinbaseAddress), m_blockReward(c_blockReward) { - secp256k1_start(); - // Initialise to the state entailed by the genesis block; this guarantees the trie is built correctly. m_state.init(); @@ -138,8 +136,6 @@ State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h): m_state(&m_db), m_blockReward(c_blockReward) { - secp256k1_start(); - // TODO THINK: is this necessary? m_state.init(); diff --git a/test/crypto.cpp b/test/crypto.cpp index 4e752fd1a..2a206bdd7 100644 --- a/test/crypto.cpp +++ b/test/crypto.cpp @@ -27,8 +27,7 @@ #include #include #include -#include -#include +#include #include #include @@ -39,6 +38,21 @@ using namespace CryptoPP; BOOST_AUTO_TEST_SUITE(devcrypto) +static Secp256k1 s_secp256k1; +static CryptoPP::AutoSeededRandomPool s_rng; +static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1()); +static CryptoPP::DL_GroupParameters_EC s_params(s_curveOID); +static CryptoPP::DL_GroupParameters_EC::EllipticCurve s_curve(s_params.GetCurve()); + +BOOST_AUTO_TEST_CASE(verify_secert) +{ + h256 empty; + KeyPair kNot(empty); + BOOST_REQUIRE(!kNot.address()); + KeyPair k(sha3(empty)); + BOOST_REQUIRE(k.address()); +} + BOOST_AUTO_TEST_CASE(common_encrypt_decrypt) { string message("Now is the time for all good persons to come to the aid of humanity."); @@ -57,103 +71,50 @@ BOOST_AUTO_TEST_CASE(common_encrypt_decrypt) BOOST_REQUIRE(plain == asBytes(message)); } -BOOST_AUTO_TEST_CASE(cryptopp_vs_secp256k1) -{ - ECIES::Decryptor d(pp::PRNG, pp::secp256k1Curve); - ECIES::Encryptor e(d.GetKey()); - - Secret s; - pp::exportPrivateKey(d.GetKey(), s); - - Public p; - pp::exportPublicKey(e.GetKey(), p); - - BOOST_REQUIRE(dev::toAddress(s) == right160(dev::sha3(p.ref()))); - - Secret previous = s; - for (auto i = 0; i < 2; i++) - { - ECIES::Decryptor d(pp::PRNG, pp::secp256k1Curve); - ECIES::Encryptor e(d.GetKey()); - - Secret s; - pp::exportPrivateKey(d.GetKey(), s); - BOOST_REQUIRE(s != previous); - - Public p; - pp::exportPublicKey(e.GetKey(), p); - - h160 secp256k1Addr = dev::toAddress(s); - h160 cryptoppAddr = right160(dev::sha3(p.ref())); - if (secp256k1Addr != cryptoppAddr) - { - BOOST_REQUIRE(secp256k1Addr == cryptoppAddr); - break; - } - } -} - BOOST_AUTO_TEST_CASE(cryptopp_cryptopp_secp256k1libport) { - // cryptopp implementation of secp256k1lib sign_compact w/recid parameter and recovery of public key from signature - + secp256k1_start(); + // base secret Secret secret(sha3("privacy")); // we get ec params from signer - const CryptoPP::DL_GroupParameters_EC params = pp::secp256k1Params; ECDSA::Signer signer; // e := sha3(msg) bytes e(fromHex("0x01")); e.resize(32); - int tests = 2; // Oct 29: successful @ 1500 + int tests = 2; while (sha3(&e, &e), secret = sha3(secret.asBytes()), tests--) { KeyPair key(secret); Public pkey = key.pub(); - pp::initializeDLScheme(secret, signer); + signer.AccessKey().Initialize(s_params, secretToExponent(secret)); h256 he(sha3(e)); Integer heInt(he.asBytes().data(), 32); h256 k(crypto::kdf(secret, he)); Integer kInt(k.asBytes().data(), 32); - kInt %= params.GetSubgroupOrder()-1; + kInt %= s_params.GetSubgroupOrder()-1; - ECP::Point rp = params.ExponentiateBase(kInt); - Integer const& q = params.GetGroupOrder(); - Integer r = params.ConvertElementToInteger(rp); - int recid = ((r >= q) ? 2 : 0) | (rp.y.IsOdd() ? 1 : 0); + ECP::Point rp = s_params.ExponentiateBase(kInt); + Integer const& q = s_params.GetGroupOrder(); + Integer r = s_params.ConvertElementToInteger(rp); Integer kInv = kInt.InverseMod(q); Integer s = (kInv * (Integer(secret.asBytes().data(), 32)*r + heInt)) % q; BOOST_REQUIRE(!!r && !!s); - -/* - // For future reference: - // According to maths, this codepath can't be reached, however, it's in secp256k1. - // Commenting this out diverges from codebase implementation. - // To be removed after upstream PR and proof are evaulated. - - if (s > params.GetSubgroupOrder()) - { - // note: this rarely happens - s = params.GetGroupOrder() - s; - if (recid) - recid ^= 1; - } - */ Signature sig; + sig[64] = rp.y.IsOdd() ? 1 : 0; r.Encode(sig.data(), 32); s.Encode(sig.data() + 32, 32); - sig[64] = recid; Public p = dev::recover(sig, he); BOOST_REQUIRE(p == pkey); // verify w/cryptopp - BOOST_REQUIRE(crypto::verify(pkey, sig, bytesConstRef(&e))); + BOOST_REQUIRE(s_secp256k1.verify(pkey, sig, bytesConstRef(&e))); // verify with secp256k1lib byte encpub[65] = {0x04}; @@ -167,17 +128,19 @@ BOOST_AUTO_TEST_CASE(cryptopp_cryptopp_secp256k1libport) BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) { + secp256k1_start(); + // cryptopp integer encoding Integer nHex("f2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2H"); Integer nB(fromHex("f2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2").data(), 32); BOOST_REQUIRE(nHex == nB); bytes sbytes(fromHex("0xFFFF")); - Secret secret(sha3(sbytes)); // 5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2 + Secret secret(sha3(sbytes)); KeyPair key(secret); bytes m(fromHex("0xFF")); - int tests = 3; + int tests = 2; while (m[0]++, tests--) { h256 hm(sha3(m)); @@ -187,42 +150,42 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) // raw sign w/cryptopp (doesn't pass through cryptopp hash filter) ECDSA::Signer signer; - pp::initializeDLScheme(key.sec(), signer); + signer.AccessKey().Initialize(s_params, secretToExponent(key.sec())); Integer r, s; signer.RawSign(kInt, hInt, r, s); // verify cryptopp raw-signature w/cryptopp ECDSA::Verifier verifier; - pp::initializeDLScheme(key.pub(), verifier); + verifier.AccessKey().Initialize(s_params, publicToPoint(key.pub())); Signature sigppraw; r.Encode(sigppraw.data(), 32); s.Encode(sigppraw.data() + 32, 32); BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), sigppraw.data(), 64)); - BOOST_REQUIRE(crypto::verify(key.pub(), sigppraw, bytesConstRef(&m))); +// BOOST_REQUIRE(crypto::verify(key.pub(), sigppraw, bytesConstRef(&m))); BOOST_REQUIRE(dev::verify(key.pub(), sigppraw, hm)); // sign with cryptopp, verify, recover w/sec256lib Signature seclibsig(dev::sign(key.sec(), hm)); BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), seclibsig.data(), 64)); - BOOST_REQUIRE(crypto::verify(key.pub(), seclibsig, bytesConstRef(&m))); +// BOOST_REQUIRE(crypto::verify(key.pub(), seclibsig, bytesConstRef(&m))); BOOST_REQUIRE(dev::verify(key.pub(), seclibsig, hm)); BOOST_REQUIRE(dev::recover(seclibsig, hm) == key.pub()); // sign with cryptopp (w/hash filter?), verify with cryptopp bytes sigppb(signer.MaxSignatureLength()); - size_t ssz = signer.SignMessage(pp::PRNG, m.data(), m.size(), sigppb.data()); + size_t ssz = signer.SignMessage(s_rng, m.data(), m.size(), sigppb.data()); Signature sigpp; memcpy(sigpp.data(), sigppb.data(), 64); BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), sigppb.data(), ssz)); - BOOST_REQUIRE(crypto::verify(key.pub(), sigpp, bytesConstRef(&m))); +// BOOST_REQUIRE(crypto::verify(key.pub(), sigpp, bytesConstRef(&m))); BOOST_REQUIRE(dev::verify(key.pub(), sigpp, hm)); // sign with cryptopp and stringsource hash filter string sigstr; - StringSource ssrc(asString(m), true, new SignerFilter(pp::PRNG, signer, new StringSink(sigstr))); + StringSource ssrc(asString(m), true, new SignerFilter(s_rng, signer, new StringSink(sigstr))); FixedHash retsig((byte const*)sigstr.data(), Signature::ConstructFromPointer); BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), retsig.data(), 64)); - BOOST_REQUIRE(crypto::verify(key.pub(), retsig, bytesConstRef(&m))); +// BOOST_REQUIRE(crypto::verify(key.pub(), retsig, bytesConstRef(&m))); BOOST_REQUIRE(dev::verify(key.pub(), retsig, hm)); /// verification w/sec256lib @@ -248,22 +211,6 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) } } -BOOST_AUTO_TEST_CASE(cryptopp_public_export_import) -{ - ECIES::Decryptor d(pp::PRNG, pp::secp256k1Curve); - ECIES::Encryptor e(d.GetKey()); - - Secret s; - pp::exportPrivateKey(d.GetKey(), s); - Public p; - pp::exportPublicKey(e.GetKey(), p); - Address addr = right160(dev::sha3(p.ref())); - BOOST_REQUIRE(toAddress(s) == addr); - - KeyPair l(s); - BOOST_REQUIRE(l.address() == addr); -} - BOOST_AUTO_TEST_CASE(ecies_eckeypair) { KeyPair k = KeyPair::create(); @@ -272,10 +219,10 @@ BOOST_AUTO_TEST_CASE(ecies_eckeypair) string original = message; bytes b = asBytes(message); - encrypt(k.pub(), b); + s_secp256k1.encrypt(k.pub(), b); BOOST_REQUIRE(b != asBytes(original)); - decrypt(k.sec(), b); + s_secp256k1.decrypt(k.sec(), b); BOOST_REQUIRE(b == asBytes(original)); } @@ -283,15 +230,15 @@ BOOST_AUTO_TEST_CASE(ecdh) { cnote << "Testing ecdh..."; - ECDH::Domain dhLocal(pp::secp256k1Curve); + ECDH::Domain dhLocal(s_curveOID); SecByteBlock privLocal(dhLocal.PrivateKeyLength()); SecByteBlock pubLocal(dhLocal.PublicKeyLength()); - dhLocal.GenerateKeyPair(pp::PRNG, privLocal, pubLocal); + dhLocal.GenerateKeyPair(s_rng, privLocal, pubLocal); - ECDH::Domain dhRemote(pp::secp256k1Curve); + ECDH::Domain dhRemote(s_curveOID); SecByteBlock privRemote(dhRemote.PrivateKeyLength()); SecByteBlock pubRemote(dhRemote.PublicKeyLength()); - dhRemote.GenerateKeyPair(pp::PRNG, privRemote, pubRemote); + dhRemote.GenerateKeyPair(s_rng, privRemote, pubRemote); assert(dhLocal.AgreedValueLength() == dhRemote.AgreedValueLength()); @@ -323,7 +270,7 @@ BOOST_AUTO_TEST_CASE(ecdh) byte pubb[65] = {0x04}; memcpy(&pubb[1], b.pub().data(), 64); - ECDH::Domain dhA(pp::secp256k1Curve); + ECDH::Domain dhA(s_curveOID); Secret shared; BOOST_REQUIRE(dhA.Agree(shared.data(), a.sec().data(), pubb)); BOOST_REQUIRE(shared);