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. 5
      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. 8
      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

5
CMakeLists.txt

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

2
alethzero/DappLoader.cpp

@ -129,7 +129,7 @@ void DappLoader::downloadComplete(QNetworkReply* _reply)
h256 expected = m_uriHashes[requestUrl];
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);
h256 got = sha3(package);
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} scrypt)
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( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

49
libdevcrypto/Common.cpp

@ -29,6 +29,9 @@
#include <libdevcore/Guards.h>
#include <libdevcore/SHA3.h>
#include <libdevcore/FileSystem.h>
#if ETH_HAVE_SECP256K1
#include <secp256k1/secp256k1.h>
#endif
#include "AES.h"
#include "CryptoPP.h"
#include "Exceptions.h"
@ -36,7 +39,17 @@ using namespace std;
using namespace dev;
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
{
@ -53,34 +66,42 @@ Address dev::ZeroAddress = Address();
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;
s_secp256k1.toPublic(_secret, p);
s_secp256k1pp.toPublic(_secret, p);
return p;
#endif
}
Address dev::toAddress(Public const& _public)
{
return s_secp256k1.toAddress(_public);
return right160(sha3(_public.ref()));
}
Address dev::toAddress(Secret const& _secret)
{
Public p;
s_secp256k1.toPublic(_secret, p);
return s_secp256k1.toAddress(p);
s_secp256k1pp.toPublic(_secret, p);
return toAddress(p);
}
void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
{
bytes io = _plain.toBytes();
s_secp256k1.encrypt(_k, io);
s_secp256k1pp.encrypt(_k, io);
o_cipher = std::move(io);
}
bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
{
bytes io = _cipher.toBytes();
s_secp256k1.decrypt(_k, io);
s_secp256k1pp.decrypt(_k, io);
if (io.empty())
return false;
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)
{
bytes io = _plain.toBytes();
s_secp256k1.encryptECIES(_k, io);
s_secp256k1pp.encryptECIES(_k, io);
o_cipher = std::move(io);
}
bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
{
bytes io = _cipher.toBytes();
if (!s_secp256k1.decryptECIES(_k, io))
if (!s_secp256k1pp.decryptECIES(_k, io))
return false;
o_plaintext = std::move(io);
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)
{
return s_secp256k1.recover(_sig, _message.ref());
return s_secp256k1pp.recover(_sig, _message.ref());
}
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)
{
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)
@ -232,8 +253,8 @@ KeyPair KeyPair::create()
KeyPair::KeyPair(h256 _sec):
m_secret(_sec)
{
if (s_secp256k1.verifySecret(m_secret, m_public))
m_address = s_secp256k1.toAddress(m_public);
if (s_secp256k1pp.verifySecret(m_secret, m_public))
m_address = toAddress(m_public);
}
KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password)

2
libdevcrypto/Common.h

@ -177,6 +177,8 @@ namespace crypto
{
struct InvalidState: public dev::Exception {};
void secp256k1Init();
/// Key derivation
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::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
@ -64,7 +64,7 @@ bytes Secp256k1::eciesKDF(Secret _z, bytes _s1, unsigned kdByteLen)
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
auto r = KeyPair::create();
@ -98,7 +98,7 @@ void Secp256k1::encryptECIES(Public const& _k, bytes& io_cipher)
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
@ -145,7 +145,7 @@ bool Secp256k1::decryptECIES(Secret const& _k, bytes& io_text)
return true;
}
void Secp256k1::encrypt(Public const& _k, bytes& io_cipher)
void Secp256k1PP::encrypt(Public const& _k, bytes& io_cipher)
{
ECIES<ECP>::Encryptor e;
initializeDLScheme(_k, e);
@ -163,7 +163,7 @@ void Secp256k1::encrypt(Public const& _k, bytes& io_cipher)
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;
initializeDLScheme(_k, d);
@ -194,12 +194,12 @@ void Secp256k1::decrypt(Secret const& _k, bytes& io_text)
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));
}
Signature Secp256k1::sign(Secret const& _key, h256 const& _hash)
Signature Secp256k1PP::sign(Secret const& _key, h256 const& _hash)
{
// assumption made by signing alogrithm
asserts(m_q == m_qs);
@ -240,18 +240,18 @@ Signature Secp256k1::sign(Secret const& _key, h256 const& _hash)
return sig;
}
bool Secp256k1::verify(Signature const& _signature, bytesConstRef _message)
bool Secp256k1PP::verify(Signature const& _signature, bytesConstRef _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)
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;
@ -293,7 +293,7 @@ Public Secp256k1::recover(Signature _signature, bytesConstRef _message)
return recovered;
}
bool Secp256k1::verifySecret(Secret const& _s, Public& _p)
bool Secp256k1PP::verifySecret(Secret const& _s, Public& _p)
{
DL_PrivateKey_EC<ECP> k;
k.Initialize(m_params, secretToExponent(_s));
@ -309,7 +309,7 @@ bool Secp256k1::verifySecret(Secret const& _s, Public& _p)
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
// 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);
}
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));
@ -333,7 +333,7 @@ void Secp256k1::exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const&
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;

8
libdevcrypto/CryptoPP.h

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

2
libdevcrypto/ECDHE.cpp

@ -27,7 +27,7 @@ using namespace std;
using namespace dev;
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)
{

2
mix/FileIo.cpp

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

14
test/libdevcrypto/crypto.cpp

@ -43,7 +43,7 @@ BOOST_GLOBAL_FIXTURE( MoveNonceToTempDir )
BOOST_AUTO_TEST_SUITE(devcrypto)
static Secp256k1 s_secp256k1;
static Secp256k1PP s_secp256k1;
static CryptoPP::AutoSeededRandomPool s_rng;
static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1());
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_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)
{
KeyPair k = KeyPair::create();
@ -156,6 +166,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_cryptopp_secp256k1libport)
BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1)
{
#ifdef CRYPTOPPNOTBROKEN
secp256k1_start();
// cryptopp integer encoding
@ -237,6 +248,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1)
BOOST_CHECK(cssz <= 72);
BOOST_REQUIRE(1 == secp256k1_ecdsa_verify(hm.data(), sizeof(hm), dersig, cssz, encpub, 65));
}
#endif
}
BOOST_AUTO_TEST_CASE(sha3_norestart)

2
test/libp2p/rlpx.cpp

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

Loading…
Cancel
Save