diff --git a/libdevcrypto/EC.cpp b/libdevcrypto/EC.cpp
new file mode 100644
index 000000000..519c59305
--- /dev/null
+++ b/libdevcrypto/EC.cpp
@@ -0,0 +1,49 @@
+/*
+ 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
+ *
+ * Ethereum-specific data structures & algorithms.
+ */
+
+#pragma warning(push)
+#pragma warning(disable:4100 4244)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#include
+#pragma warning(pop)
+#pragma GCC diagnostic pop
+#include "EC.H"
+
+using namespace std;
+using namespace dev::crypto;
+using namespace CryptoPP;
+
+ECKeyPair ECKeyPair::create()
+{
+ ECKeyPair k;
+ ECIES::Decryptor d(PRNG(), secp256k1());
+ k.m_sec = d.GetKey();
+ ECIES::Encryptor e(d);
+ k.m_pub = e.GetKey();
+ return k;
+}
\ No newline at end of file
diff --git a/libdevcrypto/EC.h b/libdevcrypto/EC.h
new file mode 100644
index 000000000..2ef9fd1d7
--- /dev/null
+++ b/libdevcrypto/EC.h
@@ -0,0 +1,78 @@
+/*
+ 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
+ *
+ * Ethereum-specific data structures & algorithms.
+ */
+
+#pragma once
+
+#pragma warning(push)
+#pragma warning(disable:4100 4244)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wunused-function"
+#include
+#include
+#include
+#include
+#include
+#pragma warning(pop)
+#pragma GCC diagnostic pop
+#include "Common.h"
+
+namespace dev
+{
+namespace crypto
+{
+
+inline CryptoPP::AutoSeededRandomPool& PRNG()
+{
+ static CryptoPP::AutoSeededRandomPool prng;
+ return prng;
+}
+
+inline CryptoPP::OID secp256k1()
+{
+ return CryptoPP::ASN1::secp256k1();
+}
+
+class ECKeyPair
+{
+public:
+ static ECKeyPair create();
+ CryptoPP::DL_PublicKey_EC pub() { return m_pub; } // deprecate
+ CryptoPP::DL_PrivateKey_EC sec() { return m_sec; } // deprecate
+
+private:
+ ECKeyPair() {}
+ CryptoPP::DL_PublicKey_EC m_pub;
+ CryptoPP::DL_PrivateKey_EC m_sec;
+};
+
+//class ECDHE;
+//bytes ECSign(KeyPair, bytesConstRef);
+//bool ECVerify(Public, bytesConstRef);
+
+}
+}
diff --git a/libdevcrypto/ECIES.cpp b/libdevcrypto/ECIES.cpp
new file mode 100644
index 000000000..d52dd35fd
--- /dev/null
+++ b/libdevcrypto/ECIES.cpp
@@ -0,0 +1,58 @@
+/*
+ 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 ECIES.cpp
+ * @author Alex Leverington
+ * @date 2014
+ *
+ * Ethereum-specific data structures & algorithms.
+ */
+
+#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(secp256k1());
+ m_encryptor.AccessKey().SetPublicElement(_k->pub().GetPublicElement());
+}
+
+void ECIESEncryptor::encrypt(bytes& _message)
+{
+ std::string c;
+ StringSource ss(_message.data(), _message.size(), true, new PK_EncryptorFilter(PRNG(), m_encryptor, new StringSink(c)));
+ bzero(_message.data(), _message.size() * sizeof(byte));
+ _message = std::move(bytesRef(c).toBytes());
+}
+
+ECIESDecryptor::ECIESDecryptor(ECKeyPair* _k)
+{
+ m_decryptor.AccessKey().AccessGroupParameters().Initialize(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(PRNG(), m_decryptor, new StringSink(p)));
+ return std::move(bytesRef(p).toBytes());
+}
+
diff --git a/libdevcrypto/ECIES.h b/libdevcrypto/ECIES.h
new file mode 100644
index 000000000..a8331f5a8
--- /dev/null
+++ b/libdevcrypto/ECIES.h
@@ -0,0 +1,79 @@
+/*
+ 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 ECIES.h
+ * @author Alex Leverington
+ * @date 2014
+ *
+ * Ethereum-specific data structures & algorithms.
+ */
+
+#pragma once
+
+#pragma warning(push)
+#pragma warning(disable:4100 4244)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#include
+#include
+#include
+#include
+#pragma warning(pop)
+#pragma GCC diagnostic pop
+#include
+#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::Encryptor m_encryptor;
+};
+
+/**
+ * @brief ECIES Decryption
+ */
+class ECIESDecryptor
+{
+public:
+ ECIESDecryptor(ECKeyPair* _k);
+
+ /// Decrypt cipher to plain.
+ bytes decrypt(bytesConstRef& _c);
+
+private:
+ CryptoPP::ECIES::Decryptor m_decryptor;
+};
+
+}
+}
\ No newline at end of file
diff --git a/libdevcrypto/SHA3MAC.cpp b/libdevcrypto/SHA3MAC.cpp
new file mode 100644
index 000000000..d50f07e73
--- /dev/null
+++ b/libdevcrypto/SHA3MAC.cpp
@@ -0,0 +1,48 @@
+/*
+ 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
+ */
+
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma warning(push)
+#pragma warning(disable:4100 4244)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#include
+#pragma warning(pop)
+#pragma GCC diagnostic pop
+#include "SHA3MAC.h"
+
+using namespace dev;
+using namespace dev::crypto;
+using namespace CryptoPP;
+
+void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output)
+{
+ CryptoPP::SHA3_256 ctx;
+ 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
new file mode 100644
index 000000000..4a49f95f1
--- /dev/null
+++ b/libdevcrypto/SHA3MAC.h
@@ -0,0 +1,38 @@
+/*
+ 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
+ *
+ * Ethereum-specific data structures & algorithms.
+ */
+
+#pragma once
+
+#include
+#include
+
+namespace dev
+{
+namespace crypto
+{
+
+void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output);
+
+}
+}
+
diff --git a/test/TestHelperCrypto.h b/test/TestHelperCrypto.h
index 57e4e4201..24104f118 100644
--- a/test/TestHelperCrypto.h
+++ b/test/TestHelperCrypto.h
@@ -21,8 +21,6 @@
#pragma once
-//#include
-
#pragma warning(push)
#pragma warning(disable:4100 4244)
#pragma GCC diagnostic push
diff --git a/test/crypto.cpp b/test/crypto.cpp
index 1c5b9a308..428fcb270 100644
--- a/test/crypto.cpp
+++ b/test/crypto.cpp
@@ -27,27 +27,38 @@
#include
#include
#include
+#include
+#include
#include "TestHelperCrypto.h"
using namespace std;
using namespace dev;
+using namespace dev::crypto;
+using namespace CryptoPP;
-namespace dev
-{
-namespace crypto
+BOOST_AUTO_TEST_SUITE(devcrypto)
+
+BOOST_AUTO_TEST_CASE(ecies)
{
+ ECKeyPair k = ECKeyPair::create();
+
+ string message("Now is the time for all good men to come to the aide of humanity.");
+ bytes b = bytesConstRef(message).toBytes();
+ ECIESEncryptor(&k).encrypt(b);
-inline CryptoPP::AutoSeededRandomPool& PRNG() {
- static CryptoPP::AutoSeededRandomPool prng;
- return prng;
-}
+ bytesConstRef br(&b);
+ bytes plain = ECIESDecryptor(&k).decrypt(br);
+ assert(plain == bytesConstRef(message).toBytes());
}
-}
-
-using namespace CryptoPP;
-BOOST_AUTO_TEST_SUITE(crypto)
+BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac)
+{
+ // New connections require new ECDH keypairs
+ // Every new connection requires a new EC keypair
+ // Every new trust requires a new EC keypair
+ // All connections should share seed for PRF (or PRNG) for nonces
+}
BOOST_AUTO_TEST_CASE(cryptopp_ecies_message)
{
@@ -55,9 +66,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecies_message)
string const message("Now is the time for all good men to come to the aide of humanity.");
- AutoSeededRandomPool prng;
-
- ECIES::Decryptor localDecryptor(prng, ASN1::secp256r1());
+ ECIES::Decryptor localDecryptor(crypto::PRNG(), crypto::secp256k1());
SavePrivateKey(localDecryptor.GetPrivateKey());
ECIES::Encryptor localEncryptor(localDecryptor);
@@ -65,31 +74,31 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecies_message)
ECIES::Decryptor futureDecryptor;
LoadPrivateKey(futureDecryptor.AccessPrivateKey());
- futureDecryptor.GetPrivateKey().ThrowIfInvalid(prng, 3);
+ futureDecryptor.GetPrivateKey().ThrowIfInvalid(crypto::PRNG(), 3);
ECIES::Encryptor futureEncryptor;
LoadPublicKey(futureEncryptor.AccessPublicKey());
- futureEncryptor.GetPublicKey().ThrowIfInvalid(prng, 3);
+ futureEncryptor.GetPublicKey().ThrowIfInvalid(crypto::PRNG(), 3);
// encrypt/decrypt with local
string cipherLocal;
- StringSource ss1 (message, true, new PK_EncryptorFilter(prng, localEncryptor, new StringSink(cipherLocal) ) );
+ StringSource ss1 (message, true, new PK_EncryptorFilter(crypto::PRNG(), localEncryptor, new StringSink(cipherLocal) ) );
string plainLocal;
- StringSource ss2 (cipherLocal, true, new PK_DecryptorFilter(prng, localDecryptor, new StringSink(plainLocal) ) );
+ StringSource ss2 (cipherLocal, true, new PK_DecryptorFilter(crypto::PRNG(), localDecryptor, new StringSink(plainLocal) ) );
// encrypt/decrypt with future
string cipherFuture;
- StringSource ss3 (message, true, new PK_EncryptorFilter(prng, futureEncryptor, new StringSink(cipherFuture) ) );
+ StringSource ss3 (message, true, new PK_EncryptorFilter(crypto::PRNG(), futureEncryptor, new StringSink(cipherFuture) ) );
string plainFuture;
- StringSource ss4 (cipherFuture, true, new PK_DecryptorFilter(prng, futureDecryptor, new StringSink(plainFuture) ) );
+ StringSource ss4 (cipherFuture, true, new PK_DecryptorFilter(crypto::PRNG(), futureDecryptor, new StringSink(plainFuture) ) );
// decrypt local w/future
string plainFutureFromLocal;
- StringSource ss5 (cipherLocal, true, new PK_DecryptorFilter(prng, futureDecryptor, new StringSink(plainFutureFromLocal) ) );
+ StringSource ss5 (cipherLocal, true, new PK_DecryptorFilter(crypto::PRNG(), futureDecryptor, new StringSink(plainFutureFromLocal) ) );
// decrypt future w/local
string plainLocalFromFuture;
- StringSource ss6 (cipherFuture, true, new PK_DecryptorFilter(prng, localDecryptor, new StringSink(plainLocalFromFuture) ) );
+ StringSource ss6 (cipherFuture, true, new PK_DecryptorFilter(crypto::PRNG(), localDecryptor, new StringSink(plainLocalFromFuture) ) );
assert(plainLocal == message);
@@ -173,60 +182,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_aes128_cbc)
cbcDecryption.ProcessData((byte*)&cipher[0], (byte*)&string192[0], cipher.size());
assert(string192 == plainOriginal);
}
-
-BOOST_AUTO_TEST_CASE(cryptopp_ecdh_aes128_cbc_noauth)
-{
- // ECDH gives 256-bit shared while aes uses 128-bits
- // Use first 128-bits of shared secret as symmetric key
- // IV is 0
- // New connections require new ECDH keypairs
-}
-
-BOOST_AUTO_TEST_CASE(cryptopp_eth_fbba)
-{
- // Initial Authentication:
- //
- // New/Known Peer:
- // pubkeyL = knownR? ? myKnown : myECDH
- // pubkeyR = knownR? ? theirKnown : theirECDH
- //
- // Initial message = hmac(k=sha3(shared-secret[128..255]), address(pubkeyL)) || ECIES encrypt(pubkeyR, pubkeyL)
- //
- // Key Exchange (this could occur after handshake messages):
- // If peers do not know each other they will need to exchange public keys.
- //
- // Drop ECDH (this could occur after handshake messages):
- // After authentication and/or key exchange, both sides generate shared key
- // from their 'known' keys and use this to encrypt all future messages.
- //
- // v2: If one side doesn't trust the other then a single-use key maybe sent.
- // This will need to be tracked for future connections; when non-trusting peer
- // wants to trust the other, it can request that it's old, 'new', public key be
- // accepted. And, if the peer *really* doesn't trust the other side, it can request
- // that a new, 'new', public key be accepted.
- //
- // Handshake (all or nothing, padded):
- // All Peers (except blacklisted):
- //
- //
- // New Peer:
- //
- //
- // Known Untrusted Peer:
- //
- //
- // Known Trusted Peer:
- //
- //
- // Blacklisted Peeer:
- // Already dropped by now.
- //
- //
- // MAC:
- // ...
-}
-
BOOST_AUTO_TEST_CASE(eth_keypairs)
{
cnote << "Testing Crypto...";