Browse Source

Prep for supporting both cryptopp and secp256k1. Link (old) secp256k1 library to devcrypto. Rename cryptopp Secp256k1 to Secp256k1PP. Update toPublic to use secp256k1 library and add test.

cl-refactor
subtly 10 years ago
parent
commit
59d88742c2
  1. 3
      CMakeLists.txt
  2. 2
      alethzero/DappLoader.cpp
  3. 4
      libdevcrypto/CMakeLists.txt
  4. 49
      libdevcrypto/Common.cpp
  5. 2
      libdevcrypto/Common.h
  6. 30
      libdevcrypto/CryptoPP.cpp
  7. 6
      libdevcrypto/CryptoPP.h
  8. 2
      libdevcrypto/ECDHE.cpp
  9. 2
      mix/FileIo.cpp
  10. 14
      test/libdevcrypto/crypto.cpp
  11. 2
      test/libp2p/rlpx.cpp

3
CMakeLists.txt

@ -397,7 +397,10 @@ if (JSCONSOLE)
add_subdirectory(ethconsole) add_subdirectory(ethconsole)
endif () endif ()
if (NOT WIN32)
add_subdirectory(secp256k1) add_subdirectory(secp256k1)
endif ()
add_subdirectory(libscrypt) add_subdirectory(libscrypt)
add_subdirectory(libdevcrypto) add_subdirectory(libdevcrypto)

2
alethzero/DappLoader.cpp

@ -129,7 +129,7 @@ void DappLoader::downloadComplete(QNetworkReply* _reply)
h256 expected = m_uriHashes[requestUrl]; h256 expected = m_uriHashes[requestUrl];
bytes package(reinterpret_cast<unsigned char const*>(data.constData()), reinterpret_cast<unsigned char const*>(data.constData() + data.size())); bytes package(reinterpret_cast<unsigned char const*>(data.constData()), reinterpret_cast<unsigned char const*>(data.constData() + data.size()));
Secp256k1 dec; Secp256k1PP dec;
dec.decrypt(expected, package); dec.decrypt(expected, package);
h256 got = sha3(package); h256 got = sha3(package);
if (got != expected) if (got != expected)

4
libdevcrypto/CMakeLists.txt

@ -24,6 +24,10 @@ target_link_libraries(${EXECUTABLE} ${DB_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} scrypt) target_link_libraries(${EXECUTABLE} scrypt)
target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} devcore)
if (NOT WIN32)
add_definitions(-DETH_HAVE_SECP256K1)
target_link_libraries(${EXECUTABLE} secp256k1)
endif ()
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

49
libdevcrypto/Common.cpp

@ -29,6 +29,9 @@
#include <libdevcore/Guards.h> #include <libdevcore/Guards.h>
#include <libdevcore/SHA3.h> #include <libdevcore/SHA3.h>
#include <libdevcore/FileSystem.h> #include <libdevcore/FileSystem.h>
#if ETH_HAVE_SECP256K1
#include <secp256k1/secp256k1.h>
#endif
#include "AES.h" #include "AES.h"
#include "CryptoPP.h" #include "CryptoPP.h"
#include "Exceptions.h" #include "Exceptions.h"
@ -36,7 +39,17 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::crypto; using namespace dev::crypto;
static Secp256k1 s_secp256k1; #ifdef ETH_HAVE_SECP256K1
struct Secp256k1Context
{
Secp256k1Context() { secp256k1_start(); }
~Secp256k1Context() { secp256k1_stop(); }
};
static Secp256k1Context s_secp256k1;
void dev::crypto::secp256k1Init() { (void)s_secp256k1; }
#endif
static Secp256k1PP s_secp256k1pp;
bool dev::SignatureStruct::isValid() const noexcept bool dev::SignatureStruct::isValid() const noexcept
{ {
@ -53,34 +66,42 @@ Address dev::ZeroAddress = Address();
Public dev::toPublic(Secret const& _secret) Public dev::toPublic(Secret const& _secret)
{ {
#ifdef ETH_HAVE_SECP256K1
bytes o(65);
int pubkeylen;
if (!secp256k1_ecdsa_pubkey_create(o.data(), &pubkeylen, _secret.data(), false))
return Public();
return FixedHash<64>(o.data()+1, Public::ConstructFromPointer);
#else
Public p; Public p;
s_secp256k1.toPublic(_secret, p); s_secp256k1pp.toPublic(_secret, p);
return p; return p;
#endif
} }
Address dev::toAddress(Public const& _public) Address dev::toAddress(Public const& _public)
{ {
return s_secp256k1.toAddress(_public); return right160(sha3(_public.ref()));
} }
Address dev::toAddress(Secret const& _secret) Address dev::toAddress(Secret const& _secret)
{ {
Public p; Public p;
s_secp256k1.toPublic(_secret, p); s_secp256k1pp.toPublic(_secret, p);
return s_secp256k1.toAddress(p); return toAddress(p);
} }
void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher) void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
{ {
bytes io = _plain.toBytes(); bytes io = _plain.toBytes();
s_secp256k1.encrypt(_k, io); s_secp256k1pp.encrypt(_k, io);
o_cipher = std::move(io); o_cipher = std::move(io);
} }
bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext) bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
{ {
bytes io = _cipher.toBytes(); bytes io = _cipher.toBytes();
s_secp256k1.decrypt(_k, io); s_secp256k1pp.decrypt(_k, io);
if (io.empty()) if (io.empty())
return false; return false;
o_plaintext = std::move(io); o_plaintext = std::move(io);
@ -90,14 +111,14 @@ bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
void dev::encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher) void dev::encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
{ {
bytes io = _plain.toBytes(); bytes io = _plain.toBytes();
s_secp256k1.encryptECIES(_k, io); s_secp256k1pp.encryptECIES(_k, io);
o_cipher = std::move(io); o_cipher = std::move(io);
} }
bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext) bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
{ {
bytes io = _cipher.toBytes(); bytes io = _cipher.toBytes();
if (!s_secp256k1.decryptECIES(_k, io)) if (!s_secp256k1pp.decryptECIES(_k, io))
return false; return false;
o_plaintext = std::move(io); o_plaintext = std::move(io);
return true; return true;
@ -163,17 +184,17 @@ bytes dev::decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _ci
Public dev::recover(Signature const& _sig, h256 const& _message) Public dev::recover(Signature const& _sig, h256 const& _message)
{ {
return s_secp256k1.recover(_sig, _message.ref()); return s_secp256k1pp.recover(_sig, _message.ref());
} }
Signature dev::sign(Secret const& _k, h256 const& _hash) Signature dev::sign(Secret const& _k, h256 const& _hash)
{ {
return s_secp256k1.sign(_k, _hash); return s_secp256k1pp.sign(_k, _hash);
} }
bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash) bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash)
{ {
return s_secp256k1.verify(_p, _s, _hash.ref(), true); return s_secp256k1pp.verify(_p, _s, _hash.ref(), true);
} }
bytes dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen) bytes dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen)
@ -232,8 +253,8 @@ KeyPair KeyPair::create()
KeyPair::KeyPair(h256 _sec): KeyPair::KeyPair(h256 _sec):
m_secret(_sec) m_secret(_sec)
{ {
if (s_secp256k1.verifySecret(m_secret, m_public)) if (s_secp256k1pp.verifySecret(m_secret, m_public))
m_address = s_secp256k1.toAddress(m_public); m_address = toAddress(m_public);
} }
KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password) KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password)

2
libdevcrypto/Common.h

@ -177,6 +177,8 @@ namespace crypto
{ {
struct InvalidState: public dev::Exception {}; struct InvalidState: public dev::Exception {};
void secp256k1Init();
/// Key derivation /// Key derivation
h256 kdf(Secret const& _priv, h256 const& _hash); h256 kdf(Secret const& _priv, h256 const& _hash);

30
libdevcrypto/CryptoPP.cpp

@ -33,7 +33,7 @@ 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::Public::size == 64, "Public key must be 64 bytes.");
static_assert(dev::Signature::size == 65, "Signature must be 65 bytes."); static_assert(dev::Signature::size == 65, "Signature must be 65 bytes.");
bytes Secp256k1::eciesKDF(Secret _z, bytes _s1, unsigned kdByteLen) bytes Secp256k1PP::eciesKDF(Secret _z, bytes _s1, unsigned kdByteLen)
{ {
// interop w/go ecies implementation // interop w/go ecies implementation
@ -64,7 +64,7 @@ bytes Secp256k1::eciesKDF(Secret _z, bytes _s1, unsigned kdByteLen)
return k; return k;
} }
void Secp256k1::encryptECIES(Public const& _k, bytes& io_cipher) void Secp256k1PP::encryptECIES(Public const& _k, bytes& io_cipher)
{ {
// interop w/go ecies implementation // interop w/go ecies implementation
auto r = KeyPair::create(); auto r = KeyPair::create();
@ -98,7 +98,7 @@ void Secp256k1::encryptECIES(Public const& _k, bytes& io_cipher)
io_cipher.swap(msg); io_cipher.swap(msg);
} }
bool Secp256k1::decryptECIES(Secret const& _k, bytes& io_text) bool Secp256k1PP::decryptECIES(Secret const& _k, bytes& io_text)
{ {
// interop w/go ecies implementation // interop w/go ecies implementation
@ -145,7 +145,7 @@ bool Secp256k1::decryptECIES(Secret const& _k, bytes& io_text)
return true; return true;
} }
void Secp256k1::encrypt(Public const& _k, bytes& io_cipher) void Secp256k1PP::encrypt(Public const& _k, bytes& io_cipher)
{ {
ECIES<ECP>::Encryptor e; ECIES<ECP>::Encryptor e;
initializeDLScheme(_k, e); initializeDLScheme(_k, e);
@ -163,7 +163,7 @@ void Secp256k1::encrypt(Public const& _k, bytes& io_cipher)
io_cipher = std::move(ciphertext); io_cipher = std::move(ciphertext);
} }
void Secp256k1::decrypt(Secret const& _k, bytes& io_text) void Secp256k1PP::decrypt(Secret const& _k, bytes& io_text)
{ {
CryptoPP::ECIES<CryptoPP::ECP>::Decryptor d; CryptoPP::ECIES<CryptoPP::ECP>::Decryptor d;
initializeDLScheme(_k, d); initializeDLScheme(_k, d);
@ -194,12 +194,12 @@ void Secp256k1::decrypt(Secret const& _k, bytes& io_text)
io_text = std::move(plain); io_text = std::move(plain);
} }
Signature Secp256k1::sign(Secret const& _k, bytesConstRef _message) Signature Secp256k1PP::sign(Secret const& _k, bytesConstRef _message)
{ {
return sign(_k, sha3(_message)); return sign(_k, sha3(_message));
} }
Signature Secp256k1::sign(Secret const& _key, h256 const& _hash) Signature Secp256k1PP::sign(Secret const& _key, h256 const& _hash)
{ {
// assumption made by signing alogrithm // assumption made by signing alogrithm
asserts(m_q == m_qs); asserts(m_q == m_qs);
@ -240,18 +240,18 @@ Signature Secp256k1::sign(Secret const& _key, h256 const& _hash)
return sig; return sig;
} }
bool Secp256k1::verify(Signature const& _signature, bytesConstRef _message) bool Secp256k1PP::verify(Signature const& _signature, bytesConstRef _message)
{ {
return !!recover(_signature, _message); return !!recover(_signature, _message);
} }
bool Secp256k1::verify(Public const& _p, Signature const& _sig, bytesConstRef _message, bool _hashed) bool Secp256k1PP::verify(Public const& _p, Signature const& _sig, bytesConstRef _message, bool _hashed)
{ {
// todo: verify w/o recovery (if faster) // todo: verify w/o recovery (if faster)
return (bool)_p == _hashed ? (bool)recover(_sig, _message) : (bool)recover(_sig, sha3(_message).ref()); return _p == (_hashed ? recover(_sig, _message) : recover(_sig, sha3(_message).ref()));
} }
Public Secp256k1::recover(Signature _signature, bytesConstRef _message) Public Secp256k1PP::recover(Signature _signature, bytesConstRef _message)
{ {
Public recovered; Public recovered;
@ -293,7 +293,7 @@ Public Secp256k1::recover(Signature _signature, bytesConstRef _message)
return recovered; return recovered;
} }
bool Secp256k1::verifySecret(Secret const& _s, Public& _p) bool Secp256k1PP::verifySecret(Secret const& _s, Public& _p)
{ {
DL_PrivateKey_EC<ECP> k; DL_PrivateKey_EC<ECP> k;
k.Initialize(m_params, secretToExponent(_s)); k.Initialize(m_params, secretToExponent(_s));
@ -309,7 +309,7 @@ bool Secp256k1::verifySecret(Secret const& _s, Public& _p)
return true; return true;
} }
void Secp256k1::agree(Secret const& _s, Public const& _r, h256& o_s) void Secp256k1PP::agree(Secret const& _s, Public const& _r, h256& o_s)
{ {
// TODO: mutex ASN1::secp256k1() singleton // TODO: mutex ASN1::secp256k1() singleton
// Creating Domain is non-const for m_oid and m_oid is not thread-safe // Creating Domain is non-const for m_oid and m_oid is not thread-safe
@ -320,7 +320,7 @@ void Secp256k1::agree(Secret const& _s, Public const& _r, h256& o_s)
d.Agree(o_s.data(), _s.data(), remote); d.Agree(o_s.data(), _s.data(), remote);
} }
void Secp256k1::exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& o_p) void Secp256k1PP::exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& o_p)
{ {
bytes prefixedKey(_k.GetGroupParameters().GetEncodedElementSize(true)); bytes prefixedKey(_k.GetGroupParameters().GetEncodedElementSize(true));
@ -333,7 +333,7 @@ void Secp256k1::exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const&
memcpy(o_p.data(), &prefixedKey[1], Public::size); memcpy(o_p.data(), &prefixedKey[1], Public::size);
} }
void Secp256k1::exponentToPublic(Integer const& _e, Public& o_p) void Secp256k1PP::exponentToPublic(Integer const& _e, Public& o_p)
{ {
CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> pk; CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> pk;

6
libdevcrypto/CryptoPP.h

@ -67,12 +67,10 @@ inline Integer secretToExponent(Secret const& _s) { return std::move(Integer(_s.
* CryptoPP secp256k1 algorithms. * CryptoPP secp256k1 algorithms.
* @todo Collect ECIES methods into class. * @todo Collect ECIES methods into class.
*/ */
class Secp256k1 class Secp256k1PP
{ {
public: 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()) {} Secp256k1PP(): m_oid(ASN1::secp256k1()), m_params(m_oid), m_curve(m_params.GetCurve()), m_q(m_params.GetGroupOrder()), m_qs(m_params.GetSubgroupOrder()) {}
Address toAddress(Public const& _p) { return right160(sha3(_p.ref())); }
void toPublic(Secret const& _s, Public& o_public) { exponentToPublic(Integer(_s.data(), sizeof(_s)), o_public); } void toPublic(Secret const& _s, Public& o_public) { exponentToPublic(Integer(_s.data(), sizeof(_s)), o_public); }

2
libdevcrypto/ECDHE.cpp

@ -27,7 +27,7 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::crypto; using namespace dev::crypto;
static Secp256k1 s_secp256k1; static Secp256k1PP s_secp256k1;
void dev::crypto::ecdh::agree(Secret const& _s, Public const& _r, h256& o_s) void dev::crypto::ecdh::agree(Secret const& _s, Public const& _r, h256& o_s)
{ {

2
mix/FileIo.cpp

@ -180,7 +180,7 @@ QStringList FileIo::makePackage(QString const& _deploymentFolder)
dev::h256 dappHash = dev::sha3(dapp); dev::h256 dappHash = dev::sha3(dapp);
//encrypt //encrypt
KeyPair key(dappHash); KeyPair key(dappHash);
Secp256k1 enc; Secp256k1PP enc;
enc.encrypt(key.pub(), dapp); enc.encrypt(key.pub(), dapp);
QUrl url(_deploymentFolder + "package.dapp"); QUrl url(_deploymentFolder + "package.dapp");

14
test/libdevcrypto/crypto.cpp

@ -43,7 +43,7 @@ BOOST_GLOBAL_FIXTURE( MoveNonceToTempDir )
BOOST_AUTO_TEST_SUITE(devcrypto) BOOST_AUTO_TEST_SUITE(devcrypto)
static Secp256k1 s_secp256k1; static Secp256k1PP s_secp256k1;
static CryptoPP::AutoSeededRandomPool s_rng; static CryptoPP::AutoSeededRandomPool s_rng;
static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1()); static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1());
static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP> s_params(s_curveOID); static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP> s_params(s_curveOID);
@ -64,6 +64,16 @@ BOOST_AUTO_TEST_CASE(emptySHA3Types)
BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3); BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3);
} }
BOOST_AUTO_TEST_CASE(secp256k1lib)
{
secp256k1Init();
KeyPair k = KeyPair::create();
BOOST_REQUIRE(!!k.sec());
BOOST_REQUIRE(!!k.pub());
Public test = toPublic(k.sec());
BOOST_REQUIRE(k.pub() == test);
}
BOOST_AUTO_TEST_CASE(cryptopp_patch) BOOST_AUTO_TEST_CASE(cryptopp_patch)
{ {
KeyPair k = KeyPair::create(); KeyPair k = KeyPair::create();
@ -156,6 +166,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_cryptopp_secp256k1libport)
BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1)
{ {
#ifdef CRYPTOPPNOTBROKEN
secp256k1_start(); secp256k1_start();
// cryptopp integer encoding // cryptopp integer encoding
@ -237,6 +248,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1)
BOOST_CHECK(cssz <= 72); BOOST_CHECK(cssz <= 72);
BOOST_REQUIRE(1 == secp256k1_ecdsa_verify(hm.data(), sizeof(hm), dersig, cssz, encpub, 65)); BOOST_REQUIRE(1 == secp256k1_ecdsa_verify(hm.data(), sizeof(hm), dersig, cssz, encpub, 65));
} }
#endif
} }
BOOST_AUTO_TEST_CASE(sha3_norestart) BOOST_AUTO_TEST_CASE(sha3_norestart)

2
test/libp2p/rlpx.cpp

@ -39,7 +39,7 @@ using namespace CryptoPP;
BOOST_AUTO_TEST_SUITE(rlpx) BOOST_AUTO_TEST_SUITE(rlpx)
static Secp256k1 s_secp256k1; static Secp256k1PP s_secp256k1;
static CryptoPP::AutoSeededRandomPool s_rng; static CryptoPP::AutoSeededRandomPool s_rng;
static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1()); static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1());
static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP> s_params(s_curveOID); static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP> s_params(s_curveOID);

Loading…
Cancel
Save