2015-12-13 14:51:43 +01:00
|
|
|
// Copyright (c) 2014-2015 The Bitcoin Core developers
|
2014-12-13 05:09:33 +01:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2014-05-31 22:01:42 +02:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2016-06-01 18:22:20 +02:00
|
|
|
#include "crypto/aes.h"
|
2017-04-24 14:02:12 +02:00
|
|
|
#include "crypto/chacha20.h"
|
2019-07-11 21:36:46 +02:00
|
|
|
#include "crypto/chacha_poly_aead.h"
|
2019-03-27 11:46:07 +01:00
|
|
|
#include "crypto/poly1305.h"
|
2014-05-31 22:01:42 +02:00
|
|
|
#include "crypto/ripemd160.h"
|
|
|
|
#include "crypto/sha1.h"
|
2014-10-26 09:23:23 +01:00
|
|
|
#include "crypto/sha256.h"
|
|
|
|
#include "crypto/sha512.h"
|
2014-10-26 09:38:13 +01:00
|
|
|
#include "crypto/hmac_sha256.h"
|
2014-10-26 09:23:23 +01:00
|
|
|
#include "crypto/hmac_sha512.h"
|
2017-04-24 14:02:12 +02:00
|
|
|
#include "random.h"
|
Split up util.cpp/h
Split up util.cpp/h into:
- string utilities (hex, base32, base64): no internal dependencies, no dependency on boost (apart from foreach)
- money utilities (parsesmoney, formatmoney)
- time utilities (gettime*, sleep, format date):
- and the rest (logging, argument parsing, config file parsing)
The latter is basically the environment and OS handling,
and is stripped of all utility functions, so we may want to
rename it to something else than util.cpp/h for clarity (Matt suggested
osinterface).
Breaks dependency of sha256.cpp on all the things pulled in by util.
2014-08-21 16:11:09 +02:00
|
|
|
#include "utilstrencodings.h"
|
2016-03-03 20:20:32 +01:00
|
|
|
#include "test/test_dash.h"
|
2014-05-31 22:01:42 +02:00
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <boost/test/unit_test.hpp>
|
2016-06-01 18:22:20 +02:00
|
|
|
#include <openssl/aes.h>
|
2017-05-29 13:51:40 +02:00
|
|
|
#include <openssl/evp.h>
|
|
|
|
|
2015-03-12 09:34:42 +01:00
|
|
|
BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup)
|
2014-05-31 22:01:42 +02:00
|
|
|
|
|
|
|
template<typename Hasher, typename In, typename Out>
|
|
|
|
void TestVector(const Hasher &h, const In &in, const Out &out) {
|
|
|
|
Out hash;
|
2014-06-12 13:34:29 +02:00
|
|
|
BOOST_CHECK(out.size() == h.OUTPUT_SIZE);
|
2014-05-31 22:01:42 +02:00
|
|
|
hash.resize(out.size());
|
|
|
|
{
|
|
|
|
// Test that writing the whole input string at once works.
|
|
|
|
Hasher(h).Write((unsigned char*)&in[0], in.size()).Finalize(&hash[0]);
|
|
|
|
BOOST_CHECK(hash == out);
|
|
|
|
}
|
|
|
|
for (int i=0; i<32; i++) {
|
|
|
|
// Test that writing the string broken up in random pieces works.
|
|
|
|
Hasher hasher(h);
|
|
|
|
size_t pos = 0;
|
|
|
|
while (pos < in.size()) {
|
2017-06-07 23:59:41 +02:00
|
|
|
size_t len = InsecureRandRange((in.size() - pos + 1) / 2 + 1);
|
2014-05-31 22:01:42 +02:00
|
|
|
hasher.Write((unsigned char*)&in[pos], len);
|
|
|
|
pos += len;
|
2014-09-23 17:17:43 +02:00
|
|
|
if (pos > 0 && pos + 2 * out.size() > in.size() && pos < in.size()) {
|
2014-05-31 22:01:42 +02:00
|
|
|
// Test that writing the rest at once to a copy of a hasher works.
|
|
|
|
Hasher(hasher).Write((unsigned char*)&in[pos], in.size() - pos).Finalize(&hash[0]);
|
|
|
|
BOOST_CHECK(hash == out);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
hasher.Finalize(&hash[0]);
|
|
|
|
BOOST_CHECK(hash == out);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestSHA1(const std::string &in, const std::string &hexout) { TestVector(CSHA1(), in, ParseHex(hexout));}
|
|
|
|
void TestSHA256(const std::string &in, const std::string &hexout) { TestVector(CSHA256(), in, ParseHex(hexout));}
|
|
|
|
void TestSHA512(const std::string &in, const std::string &hexout) { TestVector(CSHA512(), in, ParseHex(hexout));}
|
|
|
|
void TestRIPEMD160(const std::string &in, const std::string &hexout) { TestVector(CRIPEMD160(), in, ParseHex(hexout));}
|
|
|
|
|
2014-10-26 09:38:13 +01:00
|
|
|
void TestHMACSHA256(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
|
|
|
TestVector(CHMAC_SHA256(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout));
|
|
|
|
}
|
|
|
|
|
2014-05-31 22:01:42 +02:00
|
|
|
void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
|
|
|
TestVector(CHMAC_SHA512(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout));
|
|
|
|
}
|
|
|
|
|
2016-06-01 18:22:20 +02:00
|
|
|
void TestAES128(const std::string &hexkey, const std::string &hexin, const std::string &hexout)
|
|
|
|
{
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
|
|
|
std::vector<unsigned char> in = ParseHex(hexin);
|
|
|
|
std::vector<unsigned char> correctout = ParseHex(hexout);
|
|
|
|
std::vector<unsigned char> buf, buf2;
|
|
|
|
|
|
|
|
assert(key.size() == 16);
|
|
|
|
assert(in.size() == 16);
|
|
|
|
assert(correctout.size() == 16);
|
|
|
|
AES128Encrypt enc(&key[0]);
|
|
|
|
buf.resize(correctout.size());
|
|
|
|
buf2.resize(correctout.size());
|
|
|
|
enc.Encrypt(&buf[0], &in[0]);
|
|
|
|
BOOST_CHECK_EQUAL(HexStr(buf), HexStr(correctout));
|
|
|
|
AES128Decrypt dec(&key[0]);
|
|
|
|
dec.Decrypt(&buf2[0], &buf[0]);
|
|
|
|
BOOST_CHECK_EQUAL(HexStr(buf2), HexStr(in));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestAES256(const std::string &hexkey, const std::string &hexin, const std::string &hexout)
|
|
|
|
{
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
|
|
|
std::vector<unsigned char> in = ParseHex(hexin);
|
|
|
|
std::vector<unsigned char> correctout = ParseHex(hexout);
|
|
|
|
std::vector<unsigned char> buf;
|
|
|
|
|
|
|
|
assert(key.size() == 32);
|
|
|
|
assert(in.size() == 16);
|
|
|
|
assert(correctout.size() == 16);
|
|
|
|
AES256Encrypt enc(&key[0]);
|
|
|
|
buf.resize(correctout.size());
|
|
|
|
enc.Encrypt(&buf[0], &in[0]);
|
|
|
|
BOOST_CHECK(buf == correctout);
|
|
|
|
AES256Decrypt dec(&key[0]);
|
|
|
|
dec.Decrypt(&buf[0], &buf[0]);
|
|
|
|
BOOST_CHECK(buf == in);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestAES128CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout)
|
|
|
|
{
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
|
|
|
std::vector<unsigned char> iv = ParseHex(hexiv);
|
|
|
|
std::vector<unsigned char> in = ParseHex(hexin);
|
|
|
|
std::vector<unsigned char> correctout = ParseHex(hexout);
|
|
|
|
std::vector<unsigned char> realout(in.size() + AES_BLOCKSIZE);
|
|
|
|
|
|
|
|
// Encrypt the plaintext and verify that it equals the cipher
|
|
|
|
AES128CBCEncrypt enc(&key[0], &iv[0], pad);
|
|
|
|
int size = enc.Encrypt(&in[0], in.size(), &realout[0]);
|
|
|
|
realout.resize(size);
|
|
|
|
BOOST_CHECK(realout.size() == correctout.size());
|
|
|
|
BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout);
|
|
|
|
|
|
|
|
// Decrypt the cipher and verify that it equals the plaintext
|
|
|
|
std::vector<unsigned char> decrypted(correctout.size());
|
|
|
|
AES128CBCDecrypt dec(&key[0], &iv[0], pad);
|
|
|
|
size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]);
|
|
|
|
decrypted.resize(size);
|
|
|
|
BOOST_CHECK(decrypted.size() == in.size());
|
|
|
|
BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin);
|
|
|
|
|
|
|
|
// Encrypt and re-decrypt substrings of the plaintext and verify that they equal each-other
|
|
|
|
for(std::vector<unsigned char>::iterator i(in.begin()); i != in.end(); ++i)
|
|
|
|
{
|
|
|
|
std::vector<unsigned char> sub(i, in.end());
|
|
|
|
std::vector<unsigned char> subout(sub.size() + AES_BLOCKSIZE);
|
2016-09-27 13:25:42 +02:00
|
|
|
int _size = enc.Encrypt(&sub[0], sub.size(), &subout[0]);
|
|
|
|
if (_size != 0)
|
2016-06-01 18:22:20 +02:00
|
|
|
{
|
2016-09-27 13:25:42 +02:00
|
|
|
subout.resize(_size);
|
2016-06-01 18:22:20 +02:00
|
|
|
std::vector<unsigned char> subdecrypted(subout.size());
|
2016-09-27 13:25:42 +02:00
|
|
|
_size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]);
|
|
|
|
subdecrypted.resize(_size);
|
2016-06-01 18:22:20 +02:00
|
|
|
BOOST_CHECK(decrypted.size() == in.size());
|
|
|
|
BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout)
|
|
|
|
{
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
|
|
|
std::vector<unsigned char> iv = ParseHex(hexiv);
|
|
|
|
std::vector<unsigned char> in = ParseHex(hexin);
|
|
|
|
std::vector<unsigned char> correctout = ParseHex(hexout);
|
|
|
|
std::vector<unsigned char> realout(in.size() + AES_BLOCKSIZE);
|
|
|
|
|
|
|
|
// Encrypt the plaintext and verify that it equals the cipher
|
|
|
|
AES256CBCEncrypt enc(&key[0], &iv[0], pad);
|
|
|
|
int size = enc.Encrypt(&in[0], in.size(), &realout[0]);
|
|
|
|
realout.resize(size);
|
|
|
|
BOOST_CHECK(realout.size() == correctout.size());
|
|
|
|
BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout);
|
|
|
|
|
|
|
|
// Decrypt the cipher and verify that it equals the plaintext
|
|
|
|
std::vector<unsigned char> decrypted(correctout.size());
|
|
|
|
AES256CBCDecrypt dec(&key[0], &iv[0], pad);
|
|
|
|
size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]);
|
|
|
|
decrypted.resize(size);
|
|
|
|
BOOST_CHECK(decrypted.size() == in.size());
|
|
|
|
BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin);
|
|
|
|
|
|
|
|
// Encrypt and re-decrypt substrings of the plaintext and verify that they equal each-other
|
|
|
|
for(std::vector<unsigned char>::iterator i(in.begin()); i != in.end(); ++i)
|
|
|
|
{
|
|
|
|
std::vector<unsigned char> sub(i, in.end());
|
|
|
|
std::vector<unsigned char> subout(sub.size() + AES_BLOCKSIZE);
|
2016-09-27 13:25:42 +02:00
|
|
|
int _size = enc.Encrypt(&sub[0], sub.size(), &subout[0]);
|
|
|
|
if (_size != 0)
|
2016-06-01 18:22:20 +02:00
|
|
|
{
|
2016-09-27 13:25:42 +02:00
|
|
|
subout.resize(_size);
|
2016-06-01 18:22:20 +02:00
|
|
|
std::vector<unsigned char> subdecrypted(subout.size());
|
2016-09-27 13:25:42 +02:00
|
|
|
_size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]);
|
|
|
|
subdecrypted.resize(_size);
|
2016-06-01 18:22:20 +02:00
|
|
|
BOOST_CHECK(decrypted.size() == in.size());
|
|
|
|
BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 09:26:02 +02:00
|
|
|
void TestChaCha20(const std::string &hex_message, const std::string &hexkey, uint64_t nonce, uint64_t seek, const std::string& hexout)
|
2017-04-24 14:02:12 +02:00
|
|
|
{
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
2019-05-10 09:26:02 +02:00
|
|
|
std::vector<unsigned char> m = ParseHex(hex_message);
|
2017-04-24 14:02:12 +02:00
|
|
|
ChaCha20 rng(key.data(), key.size());
|
|
|
|
rng.SetIV(nonce);
|
|
|
|
rng.Seek(seek);
|
|
|
|
std::vector<unsigned char> out = ParseHex(hexout);
|
|
|
|
std::vector<unsigned char> outres;
|
|
|
|
outres.resize(out.size());
|
2019-05-10 09:26:02 +02:00
|
|
|
assert(hex_message.empty() || m.size() == out.size());
|
|
|
|
|
|
|
|
// perform the ChaCha20 round(s), if message is provided it will output the encrypted ciphertext otherwise the keystream
|
|
|
|
if (!hex_message.empty()) {
|
|
|
|
rng.Crypt(m.data(), outres.data(), outres.size());
|
|
|
|
} else {
|
|
|
|
rng.Keystream(outres.data(), outres.size());
|
|
|
|
}
|
2017-04-24 14:02:12 +02:00
|
|
|
BOOST_CHECK(out == outres);
|
2019-05-10 09:26:02 +02:00
|
|
|
if (!hex_message.empty()) {
|
|
|
|
// Manually XOR with the keystream and compare the output
|
|
|
|
rng.SetIV(nonce);
|
|
|
|
rng.Seek(seek);
|
|
|
|
std::vector<unsigned char> only_keystream(outres.size());
|
|
|
|
rng.Keystream(only_keystream.data(), only_keystream.size());
|
|
|
|
for (size_t i = 0; i != m.size(); i++) {
|
|
|
|
outres[i] = m[i] ^ only_keystream[i];
|
|
|
|
}
|
|
|
|
BOOST_CHECK(out == outres);
|
|
|
|
}
|
2017-04-24 14:02:12 +02:00
|
|
|
}
|
|
|
|
|
2019-03-27 11:46:07 +01:00
|
|
|
static void TestPoly1305(const std::string &hexmessage, const std::string &hexkey, const std::string& hextag)
|
|
|
|
{
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
|
|
|
std::vector<unsigned char> m = ParseHex(hexmessage);
|
|
|
|
std::vector<unsigned char> tag = ParseHex(hextag);
|
|
|
|
std::vector<unsigned char> tagres;
|
|
|
|
tagres.resize(POLY1305_TAGLEN);
|
|
|
|
poly1305_auth(tagres.data(), m.data(), m.size(), key.data());
|
|
|
|
BOOST_CHECK(tag == tagres);
|
|
|
|
}
|
|
|
|
|
2014-05-31 22:01:42 +02:00
|
|
|
std::string LongTestString(void) {
|
|
|
|
std::string ret;
|
|
|
|
for (int i=0; i<200000; i++) {
|
|
|
|
ret += (unsigned char)(i);
|
|
|
|
ret += (unsigned char)(i >> 4);
|
|
|
|
ret += (unsigned char)(i >> 8);
|
|
|
|
ret += (unsigned char)(i >> 12);
|
|
|
|
ret += (unsigned char)(i >> 16);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string test1 = LongTestString();
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(ripemd160_testvectors) {
|
|
|
|
TestRIPEMD160("", "9c1185a5c5e9fc54612808977ee8f548b2258d31");
|
|
|
|
TestRIPEMD160("abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
|
|
|
|
TestRIPEMD160("message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36");
|
|
|
|
TestRIPEMD160("secure hash algorithm", "20397528223b6a5f4cbc2808aba0464e645544f9");
|
|
|
|
TestRIPEMD160("RIPEMD160 is considered to be safe", "a7d78608c7af8a8e728778e81576870734122b66");
|
|
|
|
TestRIPEMD160("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
|
|
|
"12a053384a9c0c88e405a06c27dcf49ada62eb2b");
|
|
|
|
TestRIPEMD160("For this sample, this 63-byte string will be used as input data",
|
|
|
|
"de90dbfee14b63fb5abf27c2ad4a82aaa5f27a11");
|
|
|
|
TestRIPEMD160("This is exactly 64 bytes long, not counting the terminating byte",
|
|
|
|
"eda31d51d3a623b81e19eb02e24ff65d27d67b37");
|
|
|
|
TestRIPEMD160(std::string(1000000, 'a'), "52783243c1697bdbe16d37f97f68f08325dc1528");
|
|
|
|
TestRIPEMD160(test1, "464243587bd146ea835cdf57bdae582f25ec45f1");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(sha1_testvectors) {
|
|
|
|
TestSHA1("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
|
|
|
|
TestSHA1("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
|
|
|
|
TestSHA1("message digest", "c12252ceda8be8994d5fa0290a47231c1d16aae3");
|
|
|
|
TestSHA1("secure hash algorithm", "d4d6d2f0ebe317513bbd8d967d89bac5819c2f60");
|
|
|
|
TestSHA1("SHA1 is considered to be safe", "f2b6650569ad3a8720348dd6ea6c497dee3a842a");
|
|
|
|
TestSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
|
|
|
"84983e441c3bd26ebaae4aa1f95129e5e54670f1");
|
|
|
|
TestSHA1("For this sample, this 63-byte string will be used as input data",
|
|
|
|
"4f0ea5cd0585a23d028abdc1a6684e5a8094dc49");
|
|
|
|
TestSHA1("This is exactly 64 bytes long, not counting the terminating byte",
|
|
|
|
"fb679f23e7d1ce053313e66e127ab1b444397057");
|
|
|
|
TestSHA1(std::string(1000000, 'a'), "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
|
|
|
|
TestSHA1(test1, "b7755760681cbfd971451668f32af5774f4656b5");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(sha256_testvectors) {
|
|
|
|
TestSHA256("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
|
|
|
TestSHA256("abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
|
|
|
|
TestSHA256("message digest",
|
|
|
|
"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650");
|
|
|
|
TestSHA256("secure hash algorithm",
|
|
|
|
"f30ceb2bb2829e79e4ca9753d35a8ecc00262d164cc077080295381cbd643f0d");
|
|
|
|
TestSHA256("SHA256 is considered to be safe",
|
|
|
|
"6819d915c73f4d1e77e4e1b52d1fa0f9cf9beaead3939f15874bd988e2a23630");
|
|
|
|
TestSHA256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
|
|
|
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
|
|
|
|
TestSHA256("For this sample, this 63-byte string will be used as input data",
|
|
|
|
"f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342");
|
|
|
|
TestSHA256("This is exactly 64 bytes long, not counting the terminating byte",
|
|
|
|
"ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8");
|
|
|
|
TestSHA256("As Bitcoin relies on 80 byte header hashes, we want to have an example for that.",
|
|
|
|
"7406e8de7d6e4fffc573daef05aefb8806e7790f55eab5576f31349743cca743");
|
|
|
|
TestSHA256(std::string(1000000, 'a'),
|
|
|
|
"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
|
|
|
|
TestSHA256(test1, "a316d55510b49662420f49d145d42fb83f31ef8dc016aa4e32df049991a91e26");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(sha512_testvectors) {
|
|
|
|
TestSHA512("",
|
|
|
|
"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
|
|
|
|
"47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
|
|
|
|
TestSHA512("abc",
|
|
|
|
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
|
|
|
|
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
|
|
|
|
TestSHA512("message digest",
|
|
|
|
"107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f33"
|
|
|
|
"09e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c");
|
|
|
|
TestSHA512("secure hash algorithm",
|
|
|
|
"7746d91f3de30c68cec0dd693120a7e8b04d8073cb699bdce1a3f64127bca7a3"
|
|
|
|
"d5db502e814bb63c063a7a5043b2df87c61133395f4ad1edca7fcf4b30c3236e");
|
|
|
|
TestSHA512("SHA512 is considered to be safe",
|
|
|
|
"099e6468d889e1c79092a89ae925a9499b5408e01b66cb5b0a3bd0dfa51a9964"
|
|
|
|
"6b4a3901caab1318189f74cd8cf2e941829012f2449df52067d3dd5b978456c2");
|
|
|
|
TestSHA512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
|
|
|
"204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335"
|
|
|
|
"96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445");
|
|
|
|
TestSHA512("For this sample, this 63-byte string will be used as input data",
|
|
|
|
"b3de4afbc516d2478fe9b518d063bda6c8dd65fc38402dd81d1eb7364e72fb6e"
|
|
|
|
"6663cf6d2771c8f5a6da09601712fb3d2a36c6ffea3e28b0818b05b0a8660766");
|
|
|
|
TestSHA512("This is exactly 64 bytes long, not counting the terminating byte",
|
|
|
|
"70aefeaa0e7ac4f8fe17532d7185a289bee3b428d950c14fa8b713ca09814a38"
|
|
|
|
"7d245870e007a80ad97c369d193e41701aa07f3221d15f0e65a1ff970cedf030");
|
|
|
|
TestSHA512("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"
|
|
|
|
"ijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
|
|
|
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
|
|
|
|
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909");
|
|
|
|
TestSHA512(std::string(1000000, 'a'),
|
|
|
|
"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
|
|
|
|
"de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b");
|
|
|
|
TestSHA512(test1,
|
|
|
|
"40cac46c147e6131c5193dd5f34e9d8bb4951395f27b08c558c65ff4ba2de594"
|
|
|
|
"37de8c3ef5459d76a52cedc02dc499a3c9ed9dedbfb3281afd9653b8a112fafc");
|
|
|
|
}
|
|
|
|
|
2014-10-26 09:38:13 +01:00
|
|
|
BOOST_AUTO_TEST_CASE(hmac_sha256_testvectors) {
|
|
|
|
// test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
|
|
|
|
TestHMACSHA256("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
|
|
|
|
"4869205468657265",
|
|
|
|
"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7");
|
|
|
|
TestHMACSHA256("4a656665",
|
|
|
|
"7768617420646f2079612077616e7420666f72206e6f7468696e673f",
|
|
|
|
"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843");
|
|
|
|
TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
|
|
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
|
|
|
|
"dddddddddddddddddddddddddddddddddddd",
|
|
|
|
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe");
|
|
|
|
TestHMACSHA256("0102030405060708090a0b0c0d0e0f10111213141516171819",
|
|
|
|
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
|
|
|
|
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
|
|
|
|
"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b");
|
|
|
|
TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaa",
|
|
|
|
"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a"
|
|
|
|
"65204b6579202d2048617368204b6579204669727374",
|
|
|
|
"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54");
|
|
|
|
TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaa",
|
|
|
|
"5468697320697320612074657374207573696e672061206c6172676572207468"
|
|
|
|
"616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074"
|
|
|
|
"68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565"
|
|
|
|
"647320746f20626520686173686564206265666f7265206265696e6720757365"
|
|
|
|
"642062792074686520484d414320616c676f726974686d2e",
|
|
|
|
"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2");
|
|
|
|
}
|
|
|
|
|
2014-05-31 22:01:42 +02:00
|
|
|
BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) {
|
|
|
|
// test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
|
|
|
|
TestHMACSHA512("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
|
|
|
|
"4869205468657265",
|
|
|
|
"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cde"
|
|
|
|
"daa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854");
|
|
|
|
TestHMACSHA512("4a656665",
|
|
|
|
"7768617420646f2079612077616e7420666f72206e6f7468696e673f",
|
|
|
|
"164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554"
|
|
|
|
"9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737");
|
|
|
|
TestHMACSHA512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
|
|
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
|
|
|
|
"dddddddddddddddddddddddddddddddddddd",
|
|
|
|
"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
|
|
|
|
"bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb");
|
|
|
|
TestHMACSHA512("0102030405060708090a0b0c0d0e0f10111213141516171819",
|
|
|
|
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
|
|
|
|
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
|
|
|
|
"b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3db"
|
|
|
|
"a91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd");
|
|
|
|
TestHMACSHA512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaa",
|
|
|
|
"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a"
|
|
|
|
"65204b6579202d2048617368204b6579204669727374",
|
|
|
|
"80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f352"
|
|
|
|
"6b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598");
|
|
|
|
TestHMACSHA512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
"aaaaaa",
|
|
|
|
"5468697320697320612074657374207573696e672061206c6172676572207468"
|
|
|
|
"616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074"
|
|
|
|
"68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565"
|
|
|
|
"647320746f20626520686173686564206265666f7265206265696e6720757365"
|
|
|
|
"642062792074686520484d414320616c676f726974686d2e",
|
|
|
|
"e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944"
|
|
|
|
"b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58");
|
|
|
|
}
|
|
|
|
|
2016-06-01 18:22:20 +02:00
|
|
|
BOOST_AUTO_TEST_CASE(aes_testvectors) {
|
|
|
|
// AES test vectors from FIPS 197.
|
|
|
|
TestAES128("000102030405060708090a0b0c0d0e0f", "00112233445566778899aabbccddeeff", "69c4e0d86a7b0430d8cdb78070b4c55a");
|
|
|
|
TestAES256("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089");
|
|
|
|
|
|
|
|
// AES-ECB test vectors from NIST sp800-38a.
|
|
|
|
TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97");
|
|
|
|
TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf");
|
|
|
|
TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "30c81c46a35ce411e5fbc1191a0a52ef", "43b1cd7f598ece23881b00e3ed030688");
|
|
|
|
TestAES128("2b7e151628aed2a6abf7158809cf4f3c", "f69f2445df4f9b17ad2b417be66c3710", "7b0c785e27e8ad3f8223207104725dd4");
|
|
|
|
TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8");
|
|
|
|
TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870");
|
|
|
|
TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d");
|
|
|
|
TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(aes_cbc_testvectors) {
|
|
|
|
|
|
|
|
// NIST AES CBC 128-bit encryption test-vectors
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090A0B0C0D0E0F", false, \
|
|
|
|
"6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d");
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D", false, \
|
|
|
|
"ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b2");
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "5086cb9b507219ee95db113a917678b2", false, \
|
|
|
|
"30c81c46a35ce411e5fbc1191a0a52ef", "73bed6b8e3c1743b7116e69e22229516");
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "73bed6b8e3c1743b7116e69e22229516", false, \
|
|
|
|
"f69f2445df4f9b17ad2b417be66c3710", "3ff1caa1681fac09120eca307586e1a7");
|
|
|
|
|
|
|
|
// The same vectors with padding enabled
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090A0B0C0D0E0F", true, \
|
|
|
|
"6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d8964e0b149c10b7b682e6e39aaeb731c");
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D", true, \
|
|
|
|
"ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b255e21d7100b988ffec32feeafaf23538");
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "5086cb9b507219ee95db113a917678b2", true, \
|
|
|
|
"30c81c46a35ce411e5fbc1191a0a52ef", "73bed6b8e3c1743b7116e69e22229516f6eccda327bf8e5ec43718b0039adceb");
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "73bed6b8e3c1743b7116e69e22229516", true, \
|
|
|
|
"f69f2445df4f9b17ad2b417be66c3710", "3ff1caa1681fac09120eca307586e1a78cb82807230e1321d3fae00d18cc2012");
|
|
|
|
|
|
|
|
// NIST AES CBC 256-bit encryption test-vectors
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
"000102030405060708090A0B0C0D0E0F", false, "6bc1bee22e409f96e93d7e117393172a", \
|
|
|
|
"f58c4c04d6e5f1ba779eabfb5f7bfbd6");
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
"F58C4C04D6E5F1BA779EABFB5F7BFBD6", false, "ae2d8a571e03ac9c9eb76fac45af8e51", \
|
|
|
|
"9cfc4e967edb808d679f777bc6702c7d");
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
"9CFC4E967EDB808D679F777BC6702C7D", false, "30c81c46a35ce411e5fbc1191a0a52ef",
|
|
|
|
"39f23369a9d9bacfa530e26304231461");
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
"39F23369A9D9BACFA530E26304231461", false, "f69f2445df4f9b17ad2b417be66c3710", \
|
|
|
|
"b2eb05e2c39be9fcda6c19078c6a9d1b");
|
|
|
|
|
|
|
|
// The same vectors with padding enabled
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
"000102030405060708090A0B0C0D0E0F", true, "6bc1bee22e409f96e93d7e117393172a", \
|
|
|
|
"f58c4c04d6e5f1ba779eabfb5f7bfbd6485a5c81519cf378fa36d42b8547edc0");
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
"F58C4C04D6E5F1BA779EABFB5F7BFBD6", true, "ae2d8a571e03ac9c9eb76fac45af8e51", \
|
|
|
|
"9cfc4e967edb808d679f777bc6702c7d3a3aa5e0213db1a9901f9036cf5102d2");
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
"9CFC4E967EDB808D679F777BC6702C7D", true, "30c81c46a35ce411e5fbc1191a0a52ef",
|
|
|
|
"39f23369a9d9bacfa530e263042314612f8da707643c90a6f732b3de1d3f5cee");
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
"39F23369A9D9BACFA530E26304231461", true, "f69f2445df4f9b17ad2b417be66c3710", \
|
|
|
|
"b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644");
|
|
|
|
}
|
|
|
|
|
2017-05-29 13:51:40 +02:00
|
|
|
BOOST_AUTO_TEST_CASE(pbkdf2_hmac_sha512_test) {
|
|
|
|
// test vectors from
|
|
|
|
// https://github.com/trezor/trezor-crypto/blob/87c920a7e747f7ed40b6ae841327868ab914435b/tests.c#L1936-L1957
|
|
|
|
// https://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors
|
|
|
|
uint8_t k[64], s[40];
|
|
|
|
|
|
|
|
strcpy((char *)s, "salt");
|
|
|
|
PKCS5_PBKDF2_HMAC("password", 8, s, 4, 1, EVP_sha512(), 64, k);
|
|
|
|
BOOST_CHECK(HexStr(k, k + 64) == "867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce");
|
|
|
|
|
|
|
|
strcpy((char *)s, "salt");
|
|
|
|
PKCS5_PBKDF2_HMAC("password", 8, s, 4, 2, EVP_sha512(), 64, k);
|
|
|
|
BOOST_CHECK(HexStr(k, k + 64) == "e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e");
|
|
|
|
|
|
|
|
strcpy((char *)s, "salt");
|
|
|
|
PKCS5_PBKDF2_HMAC("password", 8, s, 4, 4096, EVP_sha512(), 64, k);
|
|
|
|
BOOST_CHECK(HexStr(k, k + 64) == "d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5");
|
|
|
|
|
|
|
|
strcpy((char *)s, "saltSALTsaltSALTsaltSALTsaltSALTsalt");
|
|
|
|
PKCS5_PBKDF2_HMAC("passwordPASSWORDpassword", 3*8, s, 9*4, 4096, EVP_sha512(), 64, k);
|
|
|
|
BOOST_CHECK(HexStr(k, k + 64) == "8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8");
|
|
|
|
}
|
|
|
|
|
2017-04-24 14:02:12 +02:00
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(chacha20_testvector)
|
|
|
|
{
|
|
|
|
// Test vector from RFC 7539
|
2019-05-10 09:26:02 +02:00
|
|
|
|
|
|
|
// test encryption
|
|
|
|
TestChaCha20("4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756"
|
|
|
|
"c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e"
|
|
|
|
"20776f756c642062652069742e",
|
|
|
|
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", 0x4a000000UL, 1,
|
|
|
|
"6e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afccfd9fae0bf91b65c5524733ab8f593dabcd62b3571639d"
|
|
|
|
"624e65152ab8f530c359f0861d807ca0dbf500d6a6156a38e088a22b65e52bc514d16ccf806818ce91ab77937365af90bbf74"
|
|
|
|
"a35be6b40b8eedf2785e42874d"
|
|
|
|
);
|
|
|
|
|
|
|
|
// test keystream output
|
|
|
|
TestChaCha20("", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", 0x4a000000UL, 1,
|
2017-04-24 14:02:12 +02:00
|
|
|
"224f51f3401bd9e12fde276fb8631ded8c131f823d2c06e27e4fcaec9ef3cf788a3b0aa372600a92b57974cded2b9334794cb"
|
|
|
|
"a40c63e34cdea212c4cf07d41b769a6749f3f630f4122cafe28ec4dc47e26d4346d70b98c73f3e9c53ac40c5945398b6eda1a"
|
|
|
|
"832c89c167eacd901d7e2bf363");
|
|
|
|
|
|
|
|
// Test vectors from https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7
|
2019-05-10 09:26:02 +02:00
|
|
|
TestChaCha20("", "0000000000000000000000000000000000000000000000000000000000000000", 0, 0,
|
2017-04-24 14:02:12 +02:00
|
|
|
"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b"
|
|
|
|
"8f41518a11cc387b669b2ee6586");
|
2019-05-10 09:26:02 +02:00
|
|
|
TestChaCha20("", "0000000000000000000000000000000000000000000000000000000000000001", 0, 0,
|
2017-04-24 14:02:12 +02:00
|
|
|
"4540f05a9f1fb296d7736e7b208e3c96eb4fe1834688d2604f450952ed432d41bbe2a0b6ea7566d2a5d1e7e20d42af2c53d79"
|
|
|
|
"2b1c43fea817e9ad275ae546963");
|
2019-05-10 09:26:02 +02:00
|
|
|
TestChaCha20("", "0000000000000000000000000000000000000000000000000000000000000000", 0x0100000000000000ULL, 0,
|
2017-04-24 14:02:12 +02:00
|
|
|
"de9cba7bf3d69ef5e786dc63973f653a0b49e015adbff7134fcb7df137821031e85a050278a7084527214f73efc7fa5b52770"
|
|
|
|
"62eb7a0433e445f41e3");
|
2019-05-10 09:26:02 +02:00
|
|
|
TestChaCha20("", "0000000000000000000000000000000000000000000000000000000000000000", 1, 0,
|
2017-04-24 14:02:12 +02:00
|
|
|
"ef3fdfd6c61578fbf5cf35bd3dd33b8009631634d21e42ac33960bd138e50d32111e4caf237ee53ca8ad6426194a88545ddc4"
|
|
|
|
"97a0b466e7d6bbdb0041b2f586b");
|
2019-05-10 09:26:02 +02:00
|
|
|
TestChaCha20("", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", 0x0706050403020100ULL, 0,
|
2017-04-24 14:02:12 +02:00
|
|
|
"f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3b"
|
|
|
|
"e59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc1"
|
|
|
|
"18be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5"
|
|
|
|
"a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5"
|
|
|
|
"360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78"
|
|
|
|
"fab78c9");
|
|
|
|
}
|
|
|
|
|
2019-03-27 11:46:07 +01:00
|
|
|
BOOST_AUTO_TEST_CASE(poly1305_testvector)
|
|
|
|
{
|
|
|
|
// RFC 7539, section 2.5.2.
|
|
|
|
TestPoly1305("43727970746f6772617068696320466f72756d2052657365617263682047726f7570",
|
|
|
|
"85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b",
|
|
|
|
"a8061dc1305136c6c22b8baf0c0127a9");
|
|
|
|
|
|
|
|
// RFC 7539, section A.3.
|
|
|
|
TestPoly1305("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
|
|
"000000000000000000000000000",
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
"00000000000000000000000000000000");
|
|
|
|
|
|
|
|
TestPoly1305("416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e747269627"
|
|
|
|
"5746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465"
|
|
|
|
"726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686"
|
|
|
|
"520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e2022494554"
|
|
|
|
"4620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c20737461746"
|
|
|
|
"56d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c65"
|
|
|
|
"6374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207"
|
|
|
|
"768696368206172652061646472657373656420746f",
|
|
|
|
"0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e",
|
|
|
|
"36e5f6b5c5e06070f0efca96227a863e");
|
|
|
|
|
|
|
|
TestPoly1305("416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e747269627"
|
|
|
|
"5746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465"
|
|
|
|
"726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686"
|
|
|
|
"520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e2022494554"
|
|
|
|
"4620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c20737461746"
|
|
|
|
"56d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c65"
|
|
|
|
"6374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207"
|
|
|
|
"768696368206172652061646472657373656420746f",
|
|
|
|
"36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000",
|
|
|
|
"f3477e7cd95417af89a6b8794c310cf0");
|
|
|
|
|
|
|
|
TestPoly1305("2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e6420676"
|
|
|
|
"96d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e"
|
|
|
|
"6420746865206d6f6d65207261746873206f757467726162652e",
|
|
|
|
"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
|
|
|
|
"4541669a7eaaee61e708dc7cbcc5eb62");
|
|
|
|
|
|
|
|
TestPoly1305("ffffffffffffffffffffffffffffffff",
|
|
|
|
"0200000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
"03000000000000000000000000000000");
|
|
|
|
|
|
|
|
TestPoly1305("02000000000000000000000000000000",
|
|
|
|
"02000000000000000000000000000000ffffffffffffffffffffffffffffffff",
|
|
|
|
"03000000000000000000000000000000");
|
|
|
|
|
|
|
|
TestPoly1305("fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff11000000000000000000000000000000",
|
|
|
|
"0100000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
"05000000000000000000000000000000");
|
|
|
|
|
|
|
|
TestPoly1305("fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe01010101010101010101010101010101",
|
|
|
|
"0100000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
"00000000000000000000000000000000");
|
|
|
|
|
|
|
|
TestPoly1305("fdffffffffffffffffffffffffffffff",
|
|
|
|
"0200000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
"faffffffffffffffffffffffffffffff");
|
|
|
|
|
|
|
|
TestPoly1305("e33594d7505e43b900000000000000003394d7505e4379cd01000000000000000000000000000000000000000000000001000000000000000000000000000000",
|
|
|
|
"0100000000000000040000000000000000000000000000000000000000000000",
|
|
|
|
"14000000000000005500000000000000");
|
|
|
|
|
|
|
|
TestPoly1305("e33594d7505e43b900000000000000003394d7505e4379cd010000000000000000000000000000000000000000000000",
|
|
|
|
"0100000000000000040000000000000000000000000000000000000000000000",
|
|
|
|
"13000000000000000000000000000000");
|
|
|
|
}
|
|
|
|
|
2019-07-11 21:36:46 +02:00
|
|
|
static void TestChaCha20Poly1305AEAD(bool must_succeed, unsigned int expected_aad_length, const std::string& hex_m, const std::string& hex_k1, const std::string& hex_k2, const std::string& hex_aad_keystream, const std::string& hex_encrypted_message, const std::string& hex_encrypted_message_seq_999)
|
|
|
|
{
|
|
|
|
// we need two sequence numbers, one for the payload cipher instance...
|
|
|
|
uint32_t seqnr_payload = 0;
|
|
|
|
// ... and one for the AAD (length) cipher instance
|
|
|
|
uint32_t seqnr_aad = 0;
|
|
|
|
// we need to keep track of the position in the AAD cipher instance
|
|
|
|
// keystream since we use the same 64byte output 21 times
|
|
|
|
// (21 times 3 bytes length < 64)
|
|
|
|
int aad_pos = 0;
|
|
|
|
|
|
|
|
std::vector<unsigned char> aead_K_1 = ParseHex(hex_k1);
|
|
|
|
std::vector<unsigned char> aead_K_2 = ParseHex(hex_k2);
|
|
|
|
std::vector<unsigned char> plaintext_buf = ParseHex(hex_m);
|
|
|
|
std::vector<unsigned char> expected_aad_keystream = ParseHex(hex_aad_keystream);
|
|
|
|
std::vector<unsigned char> expected_ciphertext_and_mac = ParseHex(hex_encrypted_message);
|
|
|
|
std::vector<unsigned char> expected_ciphertext_and_mac_sequence999 = ParseHex(hex_encrypted_message_seq_999);
|
|
|
|
|
|
|
|
std::vector<unsigned char> ciphertext_buf(plaintext_buf.size() + POLY1305_TAGLEN, 0);
|
|
|
|
std::vector<unsigned char> plaintext_buf_new(plaintext_buf.size(), 0);
|
|
|
|
std::vector<unsigned char> cmp_ctx_buffer(64);
|
|
|
|
uint32_t out_len = 0;
|
|
|
|
|
|
|
|
// create the AEAD instance
|
|
|
|
ChaCha20Poly1305AEAD aead(aead_K_1.data(), aead_K_1.size(), aead_K_2.data(), aead_K_2.size());
|
|
|
|
|
|
|
|
// create a chacha20 instance to compare against
|
|
|
|
ChaCha20 cmp_ctx(aead_K_2.data(), 32);
|
|
|
|
|
|
|
|
// encipher
|
|
|
|
bool res = aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, ciphertext_buf.data(), ciphertext_buf.size(), plaintext_buf.data(), plaintext_buf.size(), true);
|
|
|
|
// make sure the operation succeeded if expected to succeed
|
|
|
|
BOOST_CHECK_EQUAL(res, must_succeed);
|
|
|
|
if (!res) return;
|
|
|
|
|
|
|
|
// verify ciphertext & mac against the test vector
|
|
|
|
BOOST_CHECK_EQUAL(expected_ciphertext_and_mac.size(), ciphertext_buf.size());
|
|
|
|
BOOST_CHECK(memcmp(ciphertext_buf.data(), expected_ciphertext_and_mac.data(), ciphertext_buf.size()) == 0);
|
|
|
|
|
|
|
|
// manually construct the AAD keystream
|
|
|
|
cmp_ctx.SetIV(seqnr_aad);
|
|
|
|
cmp_ctx.Seek(0);
|
|
|
|
cmp_ctx.Keystream(cmp_ctx_buffer.data(), 64);
|
|
|
|
BOOST_CHECK(memcmp(expected_aad_keystream.data(), cmp_ctx_buffer.data(), expected_aad_keystream.size()) == 0);
|
|
|
|
// crypt the 3 length bytes and compare the length
|
|
|
|
uint32_t len_cmp = 0;
|
|
|
|
len_cmp = (ciphertext_buf[0] ^ cmp_ctx_buffer[aad_pos + 0]) |
|
|
|
|
(ciphertext_buf[1] ^ cmp_ctx_buffer[aad_pos + 1]) << 8 |
|
|
|
|
(ciphertext_buf[2] ^ cmp_ctx_buffer[aad_pos + 2]) << 16;
|
|
|
|
BOOST_CHECK_EQUAL(len_cmp, expected_aad_length);
|
|
|
|
|
|
|
|
// encrypt / decrypt 1000 packets
|
|
|
|
for (size_t i = 0; i < 1000; ++i) {
|
|
|
|
res = aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, ciphertext_buf.data(), ciphertext_buf.size(), plaintext_buf.data(), plaintext_buf.size(), true);
|
|
|
|
BOOST_CHECK(res);
|
|
|
|
BOOST_CHECK(aead.GetLength(&out_len, seqnr_aad, aad_pos, ciphertext_buf.data()));
|
|
|
|
BOOST_CHECK_EQUAL(out_len, expected_aad_length);
|
|
|
|
res = aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, plaintext_buf_new.data(), plaintext_buf_new.size(), ciphertext_buf.data(), ciphertext_buf.size(), false);
|
|
|
|
BOOST_CHECK(res);
|
|
|
|
|
|
|
|
// make sure we repetitive get the same plaintext
|
|
|
|
BOOST_CHECK(memcmp(plaintext_buf.data(), plaintext_buf_new.data(), plaintext_buf.size()) == 0);
|
|
|
|
|
|
|
|
// compare sequence number 999 against the test vector
|
|
|
|
if (seqnr_payload == 999) {
|
|
|
|
BOOST_CHECK(memcmp(ciphertext_buf.data(), expected_ciphertext_and_mac_sequence999.data(), expected_ciphertext_and_mac_sequence999.size()) == 0);
|
|
|
|
}
|
|
|
|
// set nonce and block counter, output the keystream
|
|
|
|
cmp_ctx.SetIV(seqnr_aad);
|
|
|
|
cmp_ctx.Seek(0);
|
|
|
|
cmp_ctx.Keystream(cmp_ctx_buffer.data(), 64);
|
|
|
|
|
|
|
|
// crypt the 3 length bytes and compare the length
|
|
|
|
len_cmp = 0;
|
|
|
|
len_cmp = (ciphertext_buf[0] ^ cmp_ctx_buffer[aad_pos + 0]) |
|
|
|
|
(ciphertext_buf[1] ^ cmp_ctx_buffer[aad_pos + 1]) << 8 |
|
|
|
|
(ciphertext_buf[2] ^ cmp_ctx_buffer[aad_pos + 2]) << 16;
|
|
|
|
BOOST_CHECK_EQUAL(len_cmp, expected_aad_length);
|
|
|
|
|
|
|
|
// increment the sequence number(s)
|
|
|
|
// always increment the payload sequence number
|
|
|
|
// increment the AAD keystream position by its size (3)
|
|
|
|
// increment the AAD sequence number if we would hit the 64 byte limit
|
|
|
|
seqnr_payload++;
|
|
|
|
aad_pos += CHACHA20_POLY1305_AEAD_AAD_LEN;
|
|
|
|
if (aad_pos + CHACHA20_POLY1305_AEAD_AAD_LEN > CHACHA20_ROUND_OUTPUT) {
|
|
|
|
aad_pos = 0;
|
|
|
|
seqnr_aad++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(chacha20_poly1305_aead_testvector)
|
|
|
|
{
|
|
|
|
/* test chacha20poly1305@bitcoin AEAD */
|
|
|
|
|
|
|
|
// must fail with no message
|
|
|
|
TestChaCha20Poly1305AEAD(false, 0,
|
|
|
|
"",
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000", "", "", "");
|
|
|
|
|
|
|
|
TestChaCha20Poly1305AEAD(true, 0,
|
|
|
|
/* m */ "0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
/* k1 (payload) */ "0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
/* k2 (AAD) */ "0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
/* AAD keystream */ "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586",
|
|
|
|
/* encrypted message & MAC */ "76b8e09f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32d2fc11829c1b6c1df1f551cd6131ff08",
|
|
|
|
/* encrypted message & MAC at sequence 999 */ "b0a03d5bd2855d60699e7d3a3133fa47be740fe4e4c1f967555e2d9271f31c3aaa7aa16ec62c5e24f040c08bb20c3598");
|
|
|
|
TestChaCha20Poly1305AEAD(true, 1,
|
|
|
|
"0100000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586",
|
|
|
|
"77b8e09f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32baf0c85b6dff8602b06cf52a6aefc62e",
|
|
|
|
"b1a03d5bd2855d60699e7d3a3133fa47be740fe4e4c1f967555e2d9271f31c3a8bd94d54b5ecabbc41ffbb0c90924080");
|
|
|
|
TestChaCha20Poly1305AEAD(true, 255,
|
|
|
|
"ff0000f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9",
|
|
|
|
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
|
|
|
"ff0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
|
|
|
"c640c1711e3ee904ac35c57ab9791c8a1c408603a90b77a83b54f6c844cb4b06d94e7fc6c800e165acd66147e80ec45a567f6ce66d05ec0cae679dceeb890017",
|
|
|
|
"3940c1e92da4582ff6f92a776aeb14d014d384eeb30f660dacf70a14a23fd31e91212701334e2ce1acf5199dc84f4d61ddbe6571bca5af874b4c9226c26e650995d157644e1848b96ed6c2102d5489a050e71d29a5a66ece11de5fb5c9558d54da28fe45b0bc4db4e5b88030bfc4a352b4b7068eccf656bae7ad6a35615315fc7c49d4200388d5eca67c2e822e069336c69b40db67e0f3c81209c50f3216a4b89fb3ae1b984b7851a2ec6f68ab12b101ab120e1ea7313bb93b5a0f71185c7fea017ddb92769861c29dba4fbc432280d5dff21b36d1c4c790128b22699950bb18bf74c448cdfe547d8ed4f657d8005fdc0cd7a050c2d46050a44c4376355858981fbe8b184288276e7a93eabc899c4a",
|
|
|
|
"f039c6689eaeef0456685200feaab9d54bbd9acde4410a3b6f4321296f4a8ca2604b49727d8892c57e005d799b2a38e85e809f20146e08eec75169691c8d4f54a0d51a1e1c7b381e0474eb02f994be9415ef3ffcbd2343f0601e1f3b172a1d494f838824e4df570f8e3b0c04e27966e36c82abd352d07054ef7bd36b84c63f9369afe7ed79b94f953873006b920c3fa251a771de1b63da927058ade119aa898b8c97e42a606b2f6df1e2d957c22f7593c1e2002f4252f4c9ae4bf773499e5cfcfe14dfc1ede26508953f88553bf4a76a802f6a0068d59295b01503fd9a600067624203e880fdf53933b96e1f4d9eb3f4e363dd8165a278ff667a41ee42b9892b077cefff92b93441f7be74cf10e6cd");
|
|
|
|
}
|
|
|
|
|
2017-04-24 14:02:12 +02:00
|
|
|
BOOST_AUTO_TEST_CASE(countbits_tests)
|
|
|
|
{
|
|
|
|
FastRandomContext ctx;
|
|
|
|
for (int i = 0; i <= 64; ++i) {
|
|
|
|
if (i == 0) {
|
|
|
|
// Check handling of zero.
|
|
|
|
BOOST_CHECK_EQUAL(CountBits(0), 0);
|
|
|
|
} else if (i < 10) {
|
|
|
|
for (uint64_t j = 1 << (i - 1); (j >> i) == 0; ++j) {
|
|
|
|
// Exhaustively test up to 10 bits
|
|
|
|
BOOST_CHECK_EQUAL(CountBits(j), i);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (int k = 0; k < 1000; k++) {
|
|
|
|
// Randomly test 1000 samples of each length above 10 bits.
|
|
|
|
uint64_t j = ((uint64_t)1) << (i - 1) | ctx.randbits(i - 1);
|
|
|
|
BOOST_CHECK_EQUAL(CountBits(j), i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-31 22:01:42 +02:00
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|