Browse Source

import/export cryptopp keys. begin to separate operations and public/secret.

cl-refactor
subtly 10 years ago
parent
commit
7ef84cf8fc
  1. 37
      libdevcrypto/CryptoPP.cpp
  2. 17
      libdevcrypto/CryptoPP.h
  3. 37
      libdevcrypto/EC.cpp
  4. 14
      libdevcrypto/EC.h
  5. 59
      libdevcrypto/ECIES.cpp
  6. 67
      libdevcrypto/ECIES.h
  7. 49
      test/crypto.cpp

37
libdevcrypto/CryptoPP.cpp

@ -23,18 +23,45 @@
#include "CryptoPP.h"
using namespace dev;
using namespace dev::crypto;
using namespace pp;
using namespace CryptoPP;
dev::Public pp::exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k) {
Public p;
void pp::exportDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& _p) {
ECP::Point q(_k.GetPublicElement());
q.x.Encode(&p.data()[0], 32);
q.y.Encode(&p.data()[32], 32);
return p;
q.x.Encode(_p.data(), 32);
q.y.Encode(&_p.data()[32], 32);
}
void pp::exportDL_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)
{
Integer x(&_p.data()[0], 32);
Integer y(&_p.data()[32], 32);
return std::move(ECP::Point(x,y));
}
Integer pp::ExponentFromSecret(Secret const& _s)
{
return std::move(Integer(_s.data(), 32));
}
pp::ECKeyPair::ECKeyPair():
m_decryptor(pp::PRNG(), pp::secp256k1())
{
}
Secret pp::ECKeyPair::secret()
{
Secret s;
exportDL_PrivateKey_EC(m_decryptor.AccessKey(), s);
return std::move(s);
}

17
libdevcrypto/CryptoPP.h

@ -40,7 +40,16 @@ 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; }
Public exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k);
void exportDL_PublicKey_EC(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& _p);
void exportDL_PrivateKey_EC(CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> const& _k, Secret& _s);
CryptoPP::ECP::Point PointFromPublic(Public const& _p);
CryptoPP::Integer ExponentFromSecret(Secret const& _s);
void ECIESEncrypt(CryptoPP::ECP::Point const& _point);
void ECIESDecrypt(CryptoPP::Integer const& _exponent);
/**
* @brief CryptoPP-specific EC keypair
@ -54,11 +63,13 @@ public:
/// Export Public key
Public const& publicKey() const { return m_public; }
protected:
ECKeyPair();
Secret secret();
CryptoPP::ECIES<CryptoPP::ECP>::Decryptor m_decryptor;
protected:
ECKeyPair();
Address m_address;
Public m_public;
};

37
libdevcrypto/EC.cpp

@ -42,29 +42,46 @@ using namespace dev;
using namespace dev::crypto;
using namespace CryptoPP;
void dev::crypto::encrypt(bytes& _plain, Public const& _key)
void dev::crypto::encrypt(Public const& _key, bytes& _plain)
{
Integer x(&_key.data()[0], 32);
Integer y(&_key.data()[32], 32);
DL_PublicKey_EC<ECP> p;
p.Initialize(pp::secp256k1(), ECP::Point(x,y));
// DL_PublicKey_EC<ECP> p;
// p.Initialize(pp::secp256k1(), ECP::Point(x,y));
ECIES<ECP>::Encryptor e(p);
// todo: determine size and use _plain as input and output.
std::string c;
StringSource ss(_plain.data(), _plain.size(), true, new PK_EncryptorFilter(pp::PRNG(), e, new StringSink(c)));
bzero(_plain.data(), _plain.size() * sizeof(byte));
_plain = std::move(asBytes(c));
ECIES<ECP>::Encryptor e;
e.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1());
e.AccessKey().SetPublicElement(ECP::Point(x,y));
size_t plen = _plain.size();
_plain.resize(e.CiphertextLength(plen));
e.Encrypt(pp::PRNG(), _plain.data(), plen, _plain.data());
}
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());
_c.resize(r.messageLength);
}
/// Old stuff :)
ECKeyPair ECKeyPair::create()
{
ECKeyPair k;
// export public key and set address
ECIES<ECP>::Encryptor e(k.m_decryptor.GetKey());
k.m_public = pp::exportPublicKey(e.GetKey());
pp::exportDL_PublicKey_EC(e.GetKey(), k.m_public);
k.m_address = dev::right160(dev::sha3(k.m_public.ref()));
return k;

14
libdevcrypto/EC.h

@ -43,11 +43,17 @@ typedef std::pair<Nonce,Public> PublicTrust;
/// Recover public key from signature.
//Public recover(Signature const& _sig, h256 _messageHash);
/// Replaces text with ciphertext.
void encrypt(bytes& _text, Public const& _key);
/// Encrypts text (in place).
void encrypt(Public const& _k, bytes& _text);
/// @returns ciphertext.
//bytes encrypt(bytesConstRef _text, Public const& _key);
/// Encrypt _text into _cipher.
//void encrypt(Public const& _k, bytesConstRef& _text, bytesRef& _cipher);
/// Decrypts text (in place).
void decrypt(Secret const& _k, bytes& _text);
/**
* @brief EC KeyPair

59
libdevcrypto/ECIES.cpp

@ -1,59 +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 <http://www.gnu.org/licenses/>.
*/
/** @file ECIES.cpp
* @author Alex Leverington <nessence@gmail.com>
* @date 2014
*
* ECIES Encrypt/Decrypt
*/
#include "EC.h"
#include "ECIES.h"
using namespace std;
using namespace dev;
using namespace dev::crypto;
using namespace CryptoPP;
//ECIESEncryptor::ECIESEncryptor(ECKeyPair* _k)
//{
// m_encryptor.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1());
// m_encryptor.AccessKey().SetPublicElement(_k->pub().GetPublicElement());
//}
//
//void ECIESEncryptor::encrypt(bytes& _message)
//{
// // todo: determine size and use _message as input and output.
// std::string c;
// StringSource ss(_message.data(), _message.size(), true, new PK_EncryptorFilter(pp::PRNG(), m_encryptor, new StringSink(c)));
// bzero(_message.data(), _message.size() * sizeof(byte));
// _message = std::move(asBytes(c));
//}
//
//ECIESDecryptor::ECIESDecryptor(ECKeyPair* _k)
//{
// m_decryptor.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1());
// m_decryptor.AccessKey().SetPrivateExponent(_k->sec().GetPrivateExponent());
//}
//
//bytes ECIESDecryptor::decrypt(bytesConstRef& _c)
//{
// 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));
//}

67
libdevcrypto/ECIES.h

@ -1,67 +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 <http://www.gnu.org/licenses/>.
*/
/** @file ECIES.h
* @author Alex Leverington <nessence@gmail.com>
* @date 2014
*
* ECIES Encrypt/Decrypt
*/
#pragma once
#include <libdevcore/Exceptions.h>
#include "CryptoHeaders.h"
#include "Common.h"
namespace dev
{
namespace crypto
{
/**
* @brief ECIES Encryption
*/
class ECIESEncryptor
{
public:
ECIESEncryptor(ECKeyPair* _k);
/// Encrypt _message. (object will be resized and replaced with cipher)
void encrypt(bytes& _message);
private:
CryptoPP::ECIES<CryptoPP::ECP>::Encryptor m_encryptor;
};
/**
* @brief ECIES Decryption
*/
class ECIESDecryptor
{
public:
ECIESDecryptor(ECKeyPair* _k);
/// Decrypt cipher to plain.
bytes decrypt(bytesConstRef& _c);
private:
CryptoPP::ECIES<CryptoPP::ECP>::Decryptor m_decryptor;
};
}
}

49
test/crypto.cpp

@ -28,7 +28,6 @@
#include <libethereum/Transaction.h>
#include <boost/test/unit_test.hpp>
#include <libdevcrypto/EC.h>
//#include <libdevcrypto/ECIES.h>
#include "TestHelperCrypto.h"
using namespace std;
@ -38,22 +37,32 @@ using namespace CryptoPP;
BOOST_AUTO_TEST_SUITE(devcrypto)
BOOST_AUTO_TEST_CASE(cryptopp_private_secret_import)
{
ECKeyPair k = ECKeyPair::create();
Integer e = k.m_decryptor.AccessKey().GetPrivateExponent();
assert(pp::ExponentFromSecret(k.secret()) == e);
}
BOOST_AUTO_TEST_CASE(cryptopp_public_export_import)
{
ECIES<ECP>::Decryptor d(pp::PRNG(), pp::secp256k1());
ECIES<ECP>::Encryptor e(d.GetKey());
Public p = pp::exportPublicKey(e.GetKey());
Public p;
pp::exportDL_PublicKey_EC(e.GetKey(), p);
Integer x(&p[0], 32);
Integer y(&p[32], 32);
DL_PublicKey_EC<ECP> pub;
pub.Initialize(pp::secp256k1(), ECP::Point(x,y));
assert(pub == e.GetKey());
DL_PublicKey_EC<ECP> pub2;
pub.Initialize(pp::secp256k1(), ECP::Point(x,y));
}
BOOST_AUTO_TEST_CASE(eckeypair_encrypt)
BOOST_AUTO_TEST_CASE(ecies_eckeypair)
{
ECKeyPair k = ECKeyPair::create();
string message("Now is the time for all good persons to come to the aide of humanity.");
@ -62,32 +71,16 @@ BOOST_AUTO_TEST_CASE(eckeypair_encrypt)
bytes b = asBytes(message);
k.encrypt(b);
assert(b != asBytes(original));
bytes p = k.decrypt(&b);
assert(p == asBytes(original));
encrypt(p, k.publicKey());
assert(p != asBytes(original));
// todo: test decrypt w/Secret
}
Secret s = k.secret();
decrypt(s, b);
assert(b == asBytes(original));
BOOST_AUTO_TEST_CASE(ecies)
{
// ECKeyPair k = ECKeyPair::create();
//
// string message("Now is the time for all good persons to come to the aide of humanity.");
// bytes b = bytesRef(message).toBytes();
// ECIESEncryptor(&k).encrypt(b);
//
// bytesConstRef br(&b);
// bytes plain = ECIESDecryptor(&k).decrypt(br);
//
// // ideally, decryptor will go a step further, accept a bytesRef and zero input.
// assert(plain != b);
//
// // plaintext is same as output
// assert(plain == bytesConstRef(message).toBytes());
// Fix Me!
// encrypt(k.publicKey(), b);
// assert(b != asBytes(original));
// bytes plain = k.decrypt(&b);
// assert(plain == asBytes(original));
}
BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac)

Loading…
Cancel
Save