Browse Source

commit before narrowing down import-public key issue w/cryptopp

cl-refactor
subtly 10 years ago
parent
commit
957da99ec9
  1. 36
      libdevcrypto/CryptoPP.cpp
  2. 39
      libdevcrypto/CryptoPP.h
  3. 75
      libdevcrypto/EC.cpp
  4. 37
      libdevcrypto/EC.h
  5. 64
      test/crypto.cpp

36
libdevcrypto/CryptoPP.cpp

@ -28,15 +28,6 @@ using namespace dev::crypto;
using namespace pp;
using namespace CryptoPP;
void pp::PublicFromDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& _p) {
bytes prefixedKey(65);
_k.GetGroupParameters().GetCurve().EncodePoint(prefixedKey.data(), _k.GetPublicElement(), false);
memcpy(_p.data(), &prefixedKey[1], 64);
}
void pp::SecretFromDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> const& _k, Secret& _s) {
_k.GetPrivateExponent().Encode(_s.data(), 32);
}
ECP::Point pp::PointFromPublic(Public const& _p)
{
@ -56,18 +47,23 @@ Integer pp::ExponentFromSecret(Secret const& _s)
return std::move(Integer(_s.data(), 32));
}
void pp::PublicFromExponent(Integer const& _e, Public& _p) {
CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> k;
k.AccessGroupParameters().Initialize(ASN1::secp256r1());
k.SetPrivateExponent(_e);
CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> p;
p.AccessGroupParameters().Initialize(ASN1::secp256r1());
k.MakePublicKey(p);
pp::PublicFromDL_PublicKey_EC(p, _p);
}
pp::ECKeyPair::ECKeyPair():
m_decryptor(pp::PRNG(), pp::secp256k1())
{
void pp::PublicFromDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& _p) {
bytes prefixedKey(65);
_k.GetGroupParameters().GetCurve().EncodePoint(prefixedKey.data(), _k.GetPublicElement(), false);
memcpy(_p.data(), &prefixedKey[1], 64);
}
Secret pp::ECKeyPair::secret()
{
Secret s;
SecretFromDL_PrivateKey_EC(m_decryptor.AccessKey(), s);
return std::move(s);
}
void pp::SecretFromDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> const& _k, Secret& _s) {
_k.GetPrivateExponent().Encode(_s.data(), 32);
}

39
libdevcrypto/CryptoPP.h

@ -40,43 +40,18 @@ inline CryptoPP::AutoSeededRandomPool& PRNG() { static CryptoPP::AutoSeededRando
/// EC curve used by CryptoPP
inline CryptoPP::OID const& secp256k1() { static CryptoPP::OID curve = CryptoPP::ASN1::secp256k1(); return curve; }
void PublicFromDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& _p);
void SecretFromDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> const& _k, Secret& _s);
/// Helper for CryptoPP key
///
CryptoPP::ECP::Point PointFromPublic(Public const& _p);
/// Helper for CryptoPP key
CryptoPP::Integer ExponentFromSecret(Secret const& _s);
void ECIESEncrypt(CryptoPP::ECP::Point const& _point, byte*);
void ECIESDecrypt(CryptoPP::Integer const& _exponent, byte*);
/**
* @brief CryptoPP-specific EC keypair
*/
class ECKeyPair
{
public:
/// Export address
Address const& address() const { return m_address; }
/// Export Public key
Public const& publicKey() const { return m_public; }
Secret secret();
///
CryptoPP::Integer ExponentFromSecret(Secret const& _s);
CryptoPP::ECIES<CryptoPP::ECP>::Decryptor m_decryptor;
void PublicFromExponent(CryptoPP::Integer const& _k, Public& _s);
protected:
ECKeyPair();
void PublicFromDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& _p);
Address m_address;
Public m_public;
};
void SecretFromDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> const& _k, Secret& _s);
}
}
}

75
libdevcrypto/EC.cpp

@ -48,58 +48,55 @@ void dev::crypto::encrypt(Public const& _key, bytes& _plain)
e.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1());
e.AccessKey().SetPublicElement(pp::PointFromPublic(_key));
size_t plen = _plain.size();
_plain.resize(e.CiphertextLength(plen));
e.Encrypt(pp::PRNG(), _plain.data(), plen, _plain.data());
std::string c;
c.resize(e.CiphertextLength(plen));
e.Encrypt(pp::PRNG(), _plain.data(), plen, (byte*)c.data());
_plain.resize(c.size());
memcpy(_plain.data(), c.data(), c.size());
}
void dev::crypto::decrypt(Secret const& _k, bytes& _c)
{
CryptoPP::ECIES<CryptoPP::ECP>::Decryptor m_decryptor;
m_decryptor.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1());
m_decryptor.AccessKey().SetPrivateExponent(pp::ExponentFromSecret(_k));
size_t plen = _c.size();
DecodingResult r = m_decryptor.Decrypt(pp::PRNG(), _c.data(), plen, _c.data());
CryptoPP::ECIES<CryptoPP::ECP>::Decryptor d;
d.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1());
d.AccessKey().SetPrivateExponent(pp::ExponentFromSecret(_k));
size_t clen = _c.size();
std::string p;
p.resize(d.MaxPlaintextLength(_c.size()));
DecodingResult r = d.Decrypt(pp::PRNG(), _c.data(), clen, (byte*)p.data());
assert(r.messageLength);
_c.resize(r.messageLength);
memcpy(_c.data(), p.data(), _c.size());
}
/// Old stuff :)
ECKeyPair ECKeyPair::create()
SecretKeyRef::SecretKeyRef()
{
ECKeyPair k;
// export public key and set address
ECIES<ECP>::Encryptor e(k.m_decryptor.GetKey());
pp::PublicFromDL_PublicKey_EC(e.GetKey(), k.m_public);
k.m_address = dev::right160(dev::sha3(k.m_public.ref()));
return k;
secp256k1_start();
static std::mt19937_64 s_eng(time(0));
std::uniform_int_distribution<uint16_t> d(0, 255);
for (int i = 0; i < 100; ++i)
{
for (unsigned i = 0; i < 32; ++i)
m_secret[i] = (byte)d(s_eng);
KeyPair ret(m_secret);
if (ret.address())
break;
}
/// todo: throw exception if key doesn't happen (or run forever?)
/// todo: ^ also in KeyPair::create()
}
void ECKeyPair::encrypt(bytes& _text)
Public SecretKeyRef::pub() const
{
ECIES<ECP>::Encryptor e(m_decryptor);
std::string c;
StringSource ss(_text.data(), _text.size(), true, new PK_EncryptorFilter(pp::PRNG(), e, new StringSink(c)));
bzero(_text.data(), _text.size() * sizeof(byte));
_text = std::move(asBytes(c));
Public p;
pp::PublicFromExponent(pp::ExponentFromSecret(m_secret), p);
return p;
}
void ECKeyPair::decrypt(bytes& _c)
Address SecretKeyRef::address() const
{
DecodingResult r = m_decryptor.Decrypt(pp::PRNG(), _c.data(), _c.size(), _c.data());
_c.resize(r.messageLength);
// std::string p;
// StringSource ss(_c.data(), _c.size(), true, new PK_DecryptorFilter(pp::PRNG(), m_decryptor, new StringSink(p)));
// return std::move(asBytes(p));
return dev::right160(dev::sha3(bytesConstRef(pub().data(), 64)));
}

37
libdevcrypto/EC.h

@ -53,31 +53,40 @@ void encrypt(Public const& _k, bytes& _text);
void decrypt(Secret const& _k, bytes& _text);
class SecretKeyRef
{
public:
/// Creates random secret
SecretKeyRef();
/// Creates from secret (move).
SecretKeyRef(Secret _s): m_secret(_s) {}
/// Retrieve the secret key.
Secret sec() const { return m_secret; }
/// Retrieve the public key.
Public pub() const;
/// Retrieve the associated address of the public key.
Address address() const;
private:
Secret m_secret;
};
/**
* @brief EC KeyPair
* @todo remove secret access
* @todo Integrate and/or replace KeyPair, move to common.h
* @deprecated
*/
class ECKeyPair: public pp::ECKeyPair
class ECKeyPair
{
friend class ECDHETKeyExchange;
friend class ECIESEncryptor;
friend class ECIESDecryptor;
public:
static ECKeyPair create();
/// Sign message.
Signature sign(h256 _messageHash);
/// Decrypt ciphertext (in place).
void decrypt(bytes& _cipher);
/// Encrypt using public key (in place).
void encrypt(bytes& _text);
private:
ECKeyPair() {};

64
test/crypto.cpp

@ -62,52 +62,80 @@ BOOST_AUTO_TEST_CASE(cryptopp_vs_secp256k1)
Public p;
pp::PublicFromDL_PublicKey_EC(e.GetKey(), p);
/// wow, this worked. the first time.
assert(dev::toAddress(s) == right160(dev::sha3(p.ref())));
}
}
BOOST_AUTO_TEST_CASE(cryptopp_private_secret_import)
BOOST_AUTO_TEST_CASE(cryptopp_is_bad)
{
ECKeyPair k = ECKeyPair::create();
Integer e = k.m_decryptor.AccessKey().GetPrivateExponent();
assert(pp::ExponentFromSecret(k.secret()) == e);
SecretKeyRef k;
Secret s = k.sec();
/// Convert secret to exponent used by pp
Integer e = pp::ExponentFromSecret(k.sec());
ECIES<ECP>::Decryptor d;
// k.AccessGroupParameters().Initialize(ASN1::secp256r1());
// k.SetPrivateExponent(_e);
pp::SecretFromDL_PrivateKey_EC(d.GetKey(), s);
}
BOOST_AUTO_TEST_CASE(cryptopp_public_export_import)
{
ECIES<ECP>::Decryptor d(pp::PRNG(), pp::secp256k1());
ECIES<ECP>::Encryptor e(d.GetKey());
Secret s;
pp::SecretFromDL_PrivateKey_EC(d.GetKey(), s);
Public p;
pp::PublicFromDL_PublicKey_EC(e.GetKey(), p);
Address addr = right160(dev::sha3(p.ref()));
assert(toAddress(s) == addr);
KeyPair l(s);
assert(l.address() == addr);
DL_PublicKey_EC<ECP> pub;
pub.Initialize(pp::secp256k1(), pp::PointFromPublic(p));
assert(pub.GetPublicElement() == e.GetKey().GetPublicElement());
////
SecretKeyRef k;
Public p2;
pp::PublicFromExponent(pp::ExponentFromSecret(k.sec()), p2);
assert(k.pub() == p2);
// Fix me:
Address a = k.address();
Address a2 = toAddress(k.sec());
assert(a2 == a);
}
BOOST_AUTO_TEST_CASE(ecies_eckeypair)
{
ECKeyPair k = ECKeyPair::create();
KeyPair l = KeyPair::create();
SecretKeyRef k(l.sec());
string message("Now is the time for all good persons to come to the aide of humanity.");
string original = message;
bytes b = asBytes(message);
k.encrypt(b);
encrypt(k.pub(), b);
assert(b != asBytes(original));
Secret s = k.secret();
decrypt(s, b);
decrypt(k.sec(), b);
assert(b == asBytes(original));
// Fix Me!
// encrypt(k.publicKey(), b);
k.encrypt(b);
assert(b != asBytes(original));
k.decrypt(b);
assert(b == asBytes(original));
// // Fix Me!
//// encrypt(k.publicKey(), b);
// k.encrypt(b);
// assert(b != asBytes(original));
// k.decrypt(b);
// assert(b == asBytes(original));
}
BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac)

Loading…
Cancel
Save