Browse Source

ecdh, ecdhe, initial aes classes

cl-refactor
subtly 10 years ago
parent
commit
0f86ce7545
  1. 1
      libdevcore/Common.h
  2. 1
      libdevcore/FixedHash.h
  3. 28
      libdevcrypto/AES.cpp
  4. 22
      libdevcrypto/AES.h
  5. 1
      libdevcrypto/All.h
  6. 6
      libdevcrypto/CryptoPP.cpp
  7. 8
      libdevcrypto/CryptoPP.h
  8. 19
      libdevcrypto/ECDHE.cpp
  9. 12
      libdevcrypto/ECDHE.h
  10. 36
      libethcore/CryptoHeaders.h
  11. 51
      test/TestHelperCrypto.h
  12. 143
      test/crypto.cpp

1
libdevcore/Common.h

@ -59,6 +59,7 @@ using bytesConstRef = vector_ref<byte const>;
// Numeric types. // Numeric types.
using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>; using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
using u128 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128, 128, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>; using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
using u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; using u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;

1
libdevcore/FixedHash.h

@ -240,6 +240,7 @@ using h520 = FixedHash<65>;
using h512 = FixedHash<64>; using h512 = FixedHash<64>;
using h256 = FixedHash<32>; using h256 = FixedHash<32>;
using h160 = FixedHash<20>; using h160 = FixedHash<20>;
using h128 = FixedHash<16>;
using h512s = std::vector<h512>; using h512s = std::vector<h512>;
using h256s = std::vector<h256>; using h256s = std::vector<h256>;
using h160s = std::vector<h160>; using h160s = std::vector<h160>;

28
libdevcrypto/AES.cpp

@ -19,5 +19,33 @@
* @date 2014 * @date 2014
*/ */
#include "CryptoPP.h"
#include "AES.h" #include "AES.h"
using namespace std;
using namespace dev::crypto::aes;
using namespace dev::crypto::pp;
using namespace CryptoPP;
Stream::Stream(StreamType _t, h128 _ckey):
m_cSecret(_ckey)
{
(void)_t; // encrypt and decrypt are same operation w/ctr mode
cryptor = new Aes128Ctr(_ckey);
}
Stream::~Stream()
{
delete cryptor;
}
void Stream::update(bytesRef io_bytes)
{
}
size_t Stream::streamOut(bytes& o_bytes)
{
}

22
libdevcrypto/AES.h

@ -29,10 +29,10 @@ namespace dev
{ {
namespace crypto namespace crypto
{ {
namespace pp { struct Aes128Ctr; }
namespace aes namespace aes
{ {
using Secret128 = FixedHash<16>;
enum StreamType { Encrypt, Decrypt }; enum StreamType { Encrypt, Decrypt };
/** /**
@ -41,18 +41,20 @@ enum StreamType { Encrypt, Decrypt };
class Stream class Stream
{ {
public: public:
Stream(StreamType _t, Secret128 _encS, bool _zero = true): m_type(_t), m_zeroInput(_zero), m_encSecret(_encS) {}; // streamtype maybe irrelevant w/ctr
Stream(StreamType _t, h128 _ckey);
~Stream();
virtual void update(bytesRef io_bytes) {}; virtual void update(bytesRef io_bytes);
/// Move ciphertext to _bytes. /// Move ciphertext to _bytes.
virtual size_t streamOut(bytes& o_bytes) {}; virtual size_t streamOut(bytes& o_bytes);
private: private:
StreamType m_type; h128 m_cSecret;
bool m_zeroInput;
Secret128 m_encSecret;
bytes m_text; bytes m_text;
pp::Aes128Ctr* cryptor;
}; };
/** /**
@ -61,16 +63,16 @@ private:
class AuthenticatedStream: public Stream class AuthenticatedStream: public Stream
{ {
public: public:
AuthenticatedStream(StreamType _t, Secret128 _encS, Secret128 _macS, unsigned _interval, bool _zero = true): Stream(_t, _encS, _zero), m_macSecret(_macS) { m_macInterval = _interval; } AuthenticatedStream(StreamType _t, h128 _ckey, h128 _mackey, unsigned _interval): Stream(_t, _ckey), m_macSecret(_mackey) { m_macInterval = _interval; }
AuthenticatedStream(StreamType _t, Secret const& _s, unsigned _interval, bool _zero = true): Stream(_t, Secret128(_s), _zero), m_macSecret(FixedHash<16>(_s[0]+16)) { m_macInterval = _interval; } AuthenticatedStream(StreamType _t, Secret const& _s, unsigned _interval): Stream(_t, h128(_s)), m_macSecret(FixedHash<16>(_s[0]+16)) { m_macInterval = _interval; }
/// Adjust mac interval. Next mac will be xored with value. /// Adjust mac interval. Next mac will be xored with value.
void adjustInterval(unsigned _interval) { m_macInterval = _interval; }; void adjustInterval(unsigned _interval) { m_macInterval = _interval; };
private: private:
std::atomic<unsigned> m_macInterval; std::atomic<unsigned> m_macInterval;
Secret128 m_macSecret; h128 m_macSecret;
}; };
} }

1
libdevcrypto/All.h

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Common.h" #include "Common.h"
#include "CryptoPP.h"
#include "EC.h" #include "EC.h"
#include "FileSystem.h" #include "FileSystem.h"
#include "MemoryDB.h" #include "MemoryDB.h"

6
libdevcrypto/CryptoPP.cpp

@ -45,9 +45,11 @@ void pp::exponentToPublic(Integer const& _e, Public& _p)
pp::exportPublicKey(pk, _p); pp::exportPublicKey(pk, _p);
} }
void pp::ecdhAgree(Secret _s, Public _r, h256& o_s) void pp::ecdhAgree(Secret const& _s, Public const& _r, h256& o_s)
{ {
ECDH<ECP>::Domain d(secp256k1Curve); ECDH<ECP>::Domain d(secp256k1Curve);
assert(d.AgreedValueLength() == sizeof(o_s)); assert(d.AgreedValueLength() == sizeof(o_s));
d.Agree(o_s.data(), _s.data(), _r.data()); byte remote[65] = {0x04};
memcpy(&remote[1], _r.data(), 64);
assert(d.Agree(o_s.data(), _s.data(), remote));
} }

8
libdevcrypto/CryptoPP.h

@ -77,13 +77,19 @@ static void exportPrivateKey(CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> const& _k
void exponentToPublic(Integer const& _e, Public& _p); void exponentToPublic(Integer const& _e, Public& _p);
void ecdhAgree(Secret _s, Public _r, h256& o_s); void ecdhAgree(Secret const& _s, Public const& _r, h256& o_s);
template <class T> template <class T>
void initializeDLScheme(Secret const& _s, T& io_operator) { io_operator.AccessKey().Initialize(pp::secp256k1Params, secretToExponent(_s)); } void initializeDLScheme(Secret const& _s, T& io_operator) { io_operator.AccessKey().Initialize(pp::secp256k1Params, secretToExponent(_s)); }
template <class T> template <class T>
void initializeDLScheme(Public const& _p, T& io_operator) { io_operator.AccessKey().Initialize(pp::secp256k1Params, publicToPoint(_p)); } void initializeDLScheme(Public const& _p, T& io_operator) { io_operator.AccessKey().Initialize(pp::secp256k1Params, publicToPoint(_p)); }
struct Aes128Ctr
{
Aes128Ctr(h128 _k) { mode.SetKeyWithIV(_k.data(), sizeof(h128), Nonce::get().data()); }
CTR_Mode<AES>::Encryption mode;
};
} }
} }

19
libdevcrypto/ECDHE.cpp

@ -29,15 +29,24 @@ using namespace dev;
using namespace dev::crypto; using namespace dev::crypto;
using namespace dev::crypto::pp; using namespace dev::crypto::pp;
void ECDHE::agree(Public _remote) void ECDHE::agree(Public const& _remote, Secret& o_sharedSecret)
{ {
if (m_remoteEphemeral)
// agreement can only occur once
BOOST_THROW_EXCEPTION(InvalidState());
m_remoteEphemeral = _remote; m_remoteEphemeral = _remote;
ecdhAgree(m_ephemeral.sec(), m_remoteEphemeral, m_sharedSecret); ecdhAgree(m_ephemeral.sec(), m_remoteEphemeral, o_sharedSecret);
}
void ECDHEKeyExchange::agree(Public const& _remoteEphemeral)
{
ecdhAgree(m_ephemeral.sec(), _remoteEphemeral, m_ephemeralSecret);
} }
void ECDHEKeyExchange::exchange(bytes& o_exchange) void ECDHEKeyExchange::exchange(bytes& o_exchange)
{ {
if (!m_sharedSecret) if (!m_ephemeralSecret)
// didn't agree on public remote // didn't agree on public remote
BOOST_THROW_EXCEPTION(InvalidState()); BOOST_THROW_EXCEPTION(InvalidState());
@ -60,12 +69,12 @@ void ECDHEKeyExchange::exchange(bytes& o_exchange)
memcpy(exchange.data() - v.size(), v.data(), v.size()); memcpy(exchange.data() - v.size(), v.data(), v.size());
h256 auth; h256 auth;
sha3mac(m_alias.m_secret.ref(), m_sharedSecret.ref(), auth.ref()); sha3mac(m_alias.m_secret.ref(), m_ephemeralSecret.ref(), auth.ref());
Signature sig = crypto::sign(m_alias.m_secret, auth); Signature sig = crypto::sign(m_alias.m_secret, auth);
exchange.resize(exchange.size() + sizeof(sig)); exchange.resize(exchange.size() + sizeof(sig));
memcpy(exchange.data() - sizeof(sig), sig.data(), sizeof(sig)); memcpy(exchange.data() - sizeof(sig), sig.data(), sizeof(sig));
aes::AuthenticatedStream aes(aes::Encrypt, m_sharedSecret, 0); aes::AuthenticatedStream aes(aes::Encrypt, m_ephemeralSecret, 0);
h256 prefix(sha3((h256)(m_known.second|m_remoteEphemeral))); h256 prefix(sha3((h256)(m_known.second|m_remoteEphemeral)));
aes.update(prefix.ref()); aes.update(prefix.ref());

12
libdevcrypto/ECDHE.h

@ -48,6 +48,7 @@ private:
/** /**
* @brief Derive DH shared secret from EC keypairs. * @brief Derive DH shared secret from EC keypairs.
* As ephemeral keys are single-use, agreement is limited to a single occurence.
*/ */
class ECDHE class ECDHE
{ {
@ -58,13 +59,12 @@ public:
/// Public key sent to remote. /// Public key sent to remote.
Public pubkey() { return m_ephemeral.pub(); } Public pubkey() { return m_ephemeral.pub(); }
/// Provide public key for dh agreement to generated shared secret. /// Input public key for dh agreement, output generated shared secret.
void agree(Public _remoteEphemeral); void agree(Public const& _remoteEphemeral, Secret& o_sharedSecret);
protected: protected:
KeyPair m_ephemeral; ///< Ephemeral keypair; generated. KeyPair m_ephemeral; ///< Ephemeral keypair; generated.
Public m_remoteEphemeral; ///< Public key of remote; parameter. Public m_remoteEphemeral; ///< Public key of remote; parameter.
Secret m_sharedSecret; ///< Derived secret; derived by agree.
}; };
/** /**
@ -73,7 +73,7 @@ protected:
* *
* Usage: Agree -> Exchange -> Authenticate * Usage: Agree -> Exchange -> Authenticate
*/ */
class ECDHEKeyExchange: public ECDHE class ECDHEKeyExchange: private ECDHE
{ {
public: public:
/// Exchange with unknown remote (pass public key for ingress exchange) /// Exchange with unknown remote (pass public key for ingress exchange)
@ -82,6 +82,9 @@ public:
/// Exchange with known remote /// Exchange with known remote
ECDHEKeyExchange(Alias& _k, AliasSession _known): m_alias(_k), m_known(_known) {}; ECDHEKeyExchange(Alias& _k, AliasSession _known): m_alias(_k), m_known(_known) {};
/// Provide public key for dh agreement to generate shared secret.
void agree(Public const& _remoteEphemeral);
/// @returns encrypted payload of key exchange /// @returns encrypted payload of key exchange
void exchange(bytes& o_exchange); void exchange(bytes& o_exchange);
@ -89,6 +92,7 @@ public:
bool authenticate(bytes _exchangeIn); bool authenticate(bytes _exchangeIn);
private: private:
Secret m_ephemeralSecret;
Alias m_alias; Alias m_alias;
AliasSession m_known; AliasSession m_known;
Secret m_sharedAliasSecret; Secret m_sharedAliasSecret;

36
libethcore/CryptoHeaders.h

@ -1,36 +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 CryptoHeaders.h
* @author Tim Hughes <tim@twistedfury.com>
* @date 2014
*/
#pragma once
// need to leave this one disabled
#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"
#include <sha.h>
#include <sha3.h>
#include <ripemd.h>
#include <secp256k1/secp256k1.h>
#pragma warning(pop)
#pragma GCC diagnostic pop

51
test/TestHelperCrypto.h

@ -1,51 +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 TestHelperCrypto.h
* @author Alex Leverington <nessence@gmail.com>
* @date 2014
*/
#pragma once
#include <libdevcrypto/CryptoPP.h>
using namespace std;
using namespace CryptoPP;
void SavePrivateKey(const PrivateKey& key, const string& file = "ecies.private.key")
{
FileSink sink(file.c_str());
key.Save(sink);
}
void SavePublicKey(const PublicKey& key, const string& file = "ecies.public.key")
{
FileSink sink(file.c_str());
key.Save(sink);
}
void LoadPrivateKey(PrivateKey& key, const string& file = "ecies.private.key")
{
FileSource source(file.c_str(), true);
key.Load(source);
}
void LoadPublicKey(PublicKey& key, const string& file = "ecies.public.key")
{
FileSource source(file.c_str(), true);
key.Load(source);
}

143
test/crypto.cpp

@ -27,9 +27,10 @@
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libethereum/Transaction.h> #include <libethereum/Transaction.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <libdevcrypto/EC.h>
#include <libdevcrypto/SHA3MAC.h> #include <libdevcrypto/SHA3MAC.h>
#include "TestHelperCrypto.h" #include <libdevcrypto/EC.h>
#include <libdevcrypto/ECDHE.h>
#include <libdevcrypto/CryptoPP.h>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -40,7 +41,7 @@ BOOST_AUTO_TEST_SUITE(devcrypto)
BOOST_AUTO_TEST_CASE(common_encrypt_decrypt) BOOST_AUTO_TEST_CASE(common_encrypt_decrypt)
{ {
string message("Now is the time for all good persons to come to the aide of humanity."); string message("Now is the time for all good persons to come to the aid of humanity.");
bytes m = asBytes(message); bytes m = asBytes(message);
bytesConstRef bcr(&m); bytesConstRef bcr(&m);
@ -267,7 +268,7 @@ BOOST_AUTO_TEST_CASE(ecies_eckeypair)
{ {
KeyPair k = KeyPair::create(); KeyPair k = KeyPair::create();
string message("Now is the time for all good persons to come to the aide of humanity."); string message("Now is the time for all good persons to come to the aid of humanity.");
string original = message; string original = message;
bytes b = asBytes(message); bytes b = asBytes(message);
@ -278,61 +279,87 @@ BOOST_AUTO_TEST_CASE(ecies_eckeypair)
BOOST_REQUIRE(b == asBytes(original)); BOOST_REQUIRE(b == asBytes(original));
} }
BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac) BOOST_AUTO_TEST_CASE(ecdh)
{ {
// New connections require new ECDH keypairs cnote << "Testing ecdh...";
// Every new connection requires a new EC keypair
// Every new trust requires a new EC keypair ECDH<ECP>::Domain dhLocal(pp::secp256k1Curve);
// All connections should share seed for PRF (or PRNG) for nonces SecByteBlock privLocal(dhLocal.PrivateKeyLength());
SecByteBlock pubLocal(dhLocal.PublicKeyLength());
dhLocal.GenerateKeyPair(pp::PRNG, privLocal, pubLocal);
ECDH<ECP>::Domain dhRemote(pp::secp256k1Curve);
SecByteBlock privRemote(dhRemote.PrivateKeyLength());
SecByteBlock pubRemote(dhRemote.PublicKeyLength());
dhRemote.GenerateKeyPair(pp::PRNG, privRemote, pubRemote);
assert(dhLocal.AgreedValueLength() == dhRemote.AgreedValueLength());
// local: send public to remote; remote: send public to local
// Local
SecByteBlock sharedLocal(dhLocal.AgreedValueLength());
assert(dhLocal.Agree(sharedLocal, privLocal, pubRemote));
// Remote
SecByteBlock sharedRemote(dhRemote.AgreedValueLength());
assert(dhRemote.Agree(sharedRemote, privRemote, pubLocal));
// Test
Integer ssLocal, ssRemote;
ssLocal.Decode(sharedLocal.BytePtr(), sharedLocal.SizeInBytes());
ssRemote.Decode(sharedRemote.BytePtr(), sharedRemote.SizeInBytes());
assert(ssLocal != 0);
assert(ssLocal == ssRemote);
// Now use our keys
KeyPair a = KeyPair::create();
byte puba[65] = {0x04};
memcpy(&puba[1], a.pub().data(), 64);
KeyPair b = KeyPair::create();
byte pubb[65] = {0x04};
memcpy(&pubb[1], b.pub().data(), 64);
ECDH<ECP>::Domain dhA(pp::secp256k1Curve);
Secret shared;
BOOST_REQUIRE(dhA.Agree(shared.data(), a.sec().data(), pubb));
BOOST_REQUIRE(shared);
} }
BOOST_AUTO_TEST_CASE(cryptopp_ecies_message) BOOST_AUTO_TEST_CASE(ecdhe)
{ {
cnote << "Testing cryptopp_ecies_message..."; cnote << "Testing ecdhe...";
string const message("Now is the time for all good persons to come to the aide of humanity.");
ECIES<ECP>::Decryptor localDecryptor(pp::PRNG, pp::secp256k1Curve);
SavePrivateKey(localDecryptor.GetPrivateKey());
ECIES<ECP>::Encryptor localEncryptor(localDecryptor); ECDHE a, b;
SavePublicKey(localEncryptor.GetPublicKey()); BOOST_CHECK_NE(a.pubkey(), b.pubkey());
ECIES<ECP>::Decryptor futureDecryptor;
LoadPrivateKey(futureDecryptor.AccessPrivateKey());
futureDecryptor.GetPrivateKey().ThrowIfInvalid(pp::PRNG, 3);
ECIES<ECP>::Encryptor futureEncryptor; ECDHE local;
LoadPublicKey(futureEncryptor.AccessPublicKey()); ECDHE remote;
futureEncryptor.GetPublicKey().ThrowIfInvalid(pp::PRNG, 3);
// encrypt/decrypt with local
string cipherLocal;
StringSource ss1 (message, true, new PK_EncryptorFilter(pp::PRNG, localEncryptor, new StringSink(cipherLocal) ) );
string plainLocal;
StringSource ss2 (cipherLocal, true, new PK_DecryptorFilter(pp::PRNG, localDecryptor, new StringSink(plainLocal) ) );
// encrypt/decrypt with future
string cipherFuture;
StringSource ss3 (message, true, new PK_EncryptorFilter(pp::PRNG, futureEncryptor, new StringSink(cipherFuture) ) );
string plainFuture;
StringSource ss4 (cipherFuture, true, new PK_DecryptorFilter(pp::PRNG, futureDecryptor, new StringSink(plainFuture) ) );
// decrypt local w/future // local tx pubkey -> remote
string plainFutureFromLocal; Secret sremote;
StringSource ss5 (cipherLocal, true, new PK_DecryptorFilter(pp::PRNG, futureDecryptor, new StringSink(plainFutureFromLocal) ) ); remote.agree(local.pubkey(), sremote);
// decrypt future w/local // remote tx pbukey -> local
string plainLocalFromFuture; Secret slocal;
StringSource ss6 (cipherFuture, true, new PK_DecryptorFilter(pp::PRNG, localDecryptor, new StringSink(plainLocalFromFuture) ) ); local.agree(remote.pubkey(), slocal);
BOOST_REQUIRE(sremote);
BOOST_REQUIRE(slocal);
BOOST_REQUIRE_EQUAL(sremote, slocal);
}
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_REQUIRE(plainLocal == message);
BOOST_REQUIRE(plainFuture == plainLocal);
BOOST_REQUIRE(plainFutureFromLocal == plainLocal);
BOOST_REQUIRE(plainLocalFromFuture == plainLocal);
} }
BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr) BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr)
@ -346,21 +373,29 @@ BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr)
rng.GenerateBlock(key, key.size()); rng.GenerateBlock(key, key.size());
// cryptopp uses IV as nonce/counter which is same as using nonce w/0 ctr // cryptopp uses IV as nonce/counter which is same as using nonce w/0 ctr
byte ctr[AES::BLOCKSIZE]; FixedHash<AES::BLOCKSIZE> ctr;
rng.GenerateBlock(ctr, sizeof(ctr)); rng.GenerateBlock(ctr.data(), sizeof(ctr));
// used for decrypt
FixedHash<AES::BLOCKSIZE> ctrcopy(ctr);
string text = "Now is the time for all good persons to come to the aide of humanity."; string text = "Now is the time for all good persons to come to the aid of humanity.";
// c++11 ftw
unsigned char const* in = (unsigned char*)&text[0]; unsigned char const* in = (unsigned char*)&text[0];
unsigned char* out = (unsigned char*)&text[0]; unsigned char* out = (unsigned char*)&text[0];
string original = text; string original = text;
string doublespeak = text + text;
string cipherCopy; string cipherCopy;
try try
{ {
CTR_Mode<AES>::Encryption e; CTR_Mode<AES>::Encryption e;
e.SetKeyWithIV(key, key.size(), ctr); e.SetKeyWithIV(key, key.size(), ctr.data());
// 68 % 255 should be difference of counter
e.ProcessData(out, in, text.size()); e.ProcessData(out, in, text.size());
(u128)ctr += (u128)(text.size() % 16);
BOOST_REQUIRE(text != original); BOOST_REQUIRE(text != original);
cipherCopy = text; cipherCopy = text;
} }
@ -372,7 +407,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr)
try try
{ {
CTR_Mode< AES >::Decryption d; CTR_Mode< AES >::Decryption d;
d.SetKeyWithIV(key, key.size(), ctr); d.SetKeyWithIV(key, key.size(), ctrcopy.data());
d.ProcessData(out, in, text.size()); d.ProcessData(out, in, text.size());
BOOST_REQUIRE(text == original); BOOST_REQUIRE(text == original);
} }
@ -390,7 +425,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr)
out = (unsigned char*)&cipherCopy[0]; out = (unsigned char*)&cipherCopy[0];
CTR_Mode<AES>::Encryption e; CTR_Mode<AES>::Encryption e;
e.SetKeyWithIV(key, key.size(), ctr); e.SetKeyWithIV(key, key.size(), ctrcopy.data());
e.ProcessData(out, in, text.size()); e.ProcessData(out, in, text.size());
// yep, ctr mode. // yep, ctr mode.

Loading…
Cancel
Save