From 57f118176f3979f039626c377f162bd8c0774b4f Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Wed, 27 Apr 2016 14:08:55 -0600 Subject: [PATCH] Move NoteEncryption tests to gtest suite. --- src/Makefile.test.include | 5 +- src/gtest/test_noteencryption.cpp | 169 ++++++++++++++++++++++++++- src/test/noteencryption_tests.cpp | 183 ------------------------------ 3 files changed, 169 insertions(+), 188 deletions(-) delete mode 100644 src/test/noteencryption_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 6f932c020..6b09c1309 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -56,7 +56,6 @@ BITCOIN_TESTS =\ test/miner_tests.cpp \ test/mruset_tests.cpp \ test/multisig_tests.cpp \ - test/noteencryption_tests.cpp \ test/netbase_tests.cpp \ test/pmt_tests.cpp \ test/policyestimator_tests.cpp \ @@ -91,12 +90,12 @@ endif test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) test_test_bitcoin_CPPFLAGS = $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ - $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(LIBZEROCASH) $(LIBZEROCASH_LIBS) + $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) if ENABLE_WALLET test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET) endif -test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) +test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBZEROCASH) $(LIBZEROCASH_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) diff --git a/src/gtest/test_noteencryption.cpp b/src/gtest/test_noteencryption.cpp index f3e2ff066..ecd8b2691 100644 --- a/src/gtest/test_noteencryption.cpp +++ b/src/gtest/test_noteencryption.cpp @@ -1,5 +1,170 @@ #include +#include "sodium.h" -TEST(tautologies, nine_eq_nine) { - ASSERT_EQ(9, 9); +#include + +#include "zcash/NoteEncryption.hpp" +#include "zcash/prf.h" + +class TestNoteDecryption : public ZCNoteDecryption { +public: + TestNoteDecryption(uint256 sk_enc) : ZCNoteDecryption(sk_enc) {} + + void change_pk_enc(uint256 to) { + pk_enc = to; + } +}; + +TEST(noteencryption, api) +{ + uint256 sk_enc = ZCNoteEncryption::generate_privkey(uint256S("21035d60bc1983e37950ce4803418a8fb33ea68d5b937ca382ecbae7564d6a77")); + uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc); + + ZCNoteEncryption b = ZCNoteEncryption(uint256()); + + boost::array message; + for (unsigned char i = 0; i < 216; i++) { + // Fill the message with dummy data + message[i] = (unsigned char) i; + } + + for (int i = 0; i < 255; i++) { + auto ciphertext = b.encrypt(pk_enc, message); + + { + ZCNoteDecryption decrypter(sk_enc); + + // Test decryption + auto plaintext = decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i); + ASSERT_TRUE(plaintext == message); + + // Test wrong nonce + ASSERT_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256(), (i == 0) ? 1 : (i - 1)), std::runtime_error); + + // Test wrong ephemeral key + ASSERT_THROW(decrypter.decrypt(ciphertext, ZCNoteEncryption::generate_privkey(uint256()), uint256(), i), std::runtime_error); + + // Test wrong seed + ASSERT_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256S("11035d60bc1983e37950ce4803418a8fb33ea68d5b937ca382ecbae7564d6a77"), i), std::runtime_error); + + // Test corrupted ciphertext + ciphertext[10] ^= 0xff; + ASSERT_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i), std::runtime_error); + ciphertext[10] ^= 0xff; + } + + { + // Test wrong private key + uint256 sk_enc_2 = ZCNoteEncryption::generate_privkey(uint256()); + ZCNoteDecryption decrypter(sk_enc_2); + + ASSERT_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i), std::runtime_error); + } + + { + TestNoteDecryption decrypter(sk_enc); + + // Test decryption + auto plaintext = decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i); + ASSERT_TRUE(plaintext == message); + + // Test wrong public key (test of KDF) + decrypter.change_pk_enc(uint256()); + ASSERT_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i), std::runtime_error); + } + } + + // Nonce space should run out here + ASSERT_THROW(b.encrypt(pk_enc, message), std::logic_error); +} + +uint256 test_prf( + unsigned char distinguisher, + uint256 x, + uint256 y +) { + *x.begin() &= 0x0f; + *x.begin() |= distinguisher; + CSHA256 hasher; + hasher.Write(x.begin(), 32); + hasher.Write(y.begin(), 32); + + uint256 ret; + hasher.FinalizeNoPadding(ret.begin()); + return ret; +} + +TEST(noteencryption, prf_addr) +{ + for (size_t i = 0; i < 100; i++) { + uint256 a_sk = libzcash::random_uint256(); + uint256 rest; + ASSERT_TRUE( + test_prf(0xc0, a_sk, rest) == PRF_addr_a_pk(a_sk) + ); + } + + for (size_t i = 0; i < 100; i++) { + uint256 a_sk = libzcash::random_uint256(); + uint256 rest; + *rest.begin() = 0x01; + ASSERT_TRUE( + test_prf(0xc0, a_sk, rest) == PRF_addr_sk_enc(a_sk) + ); + } +} + +TEST(noteencryption, prf_nf) +{ + for (size_t i = 0; i < 100; i++) { + uint256 a_sk = libzcash::random_uint256(); + uint256 rho = libzcash::random_uint256(); + ASSERT_TRUE( + test_prf(0xe0, a_sk, rho) == PRF_nf(a_sk, rho) + ); + } +} + +TEST(noteencryption, prf_pk) +{ + for (size_t i = 0; i < 100; i++) { + uint256 a_sk = libzcash::random_uint256(); + uint256 h_sig = libzcash::random_uint256(); + ASSERT_TRUE( + test_prf(0x00, a_sk, h_sig) == PRF_pk(a_sk, 0, h_sig) + ); + } + + for (size_t i = 0; i < 100; i++) { + uint256 a_sk = libzcash::random_uint256(); + uint256 h_sig = libzcash::random_uint256(); + ASSERT_TRUE( + test_prf(0x40, a_sk, h_sig) == PRF_pk(a_sk, 1, h_sig) + ); + } + + uint256 dummy; + ASSERT_THROW(PRF_pk(dummy, 2, dummy), std::domain_error); +} + +TEST(noteencryption, prf_rho) +{ + for (size_t i = 0; i < 100; i++) { + uint256 phi = libzcash::random_uint256(); + uint256 h_sig = libzcash::random_uint256(); + ASSERT_TRUE( + test_prf(0x20, phi, h_sig) == PRF_rho(phi, 0, h_sig) + ); + } + + for (size_t i = 0; i < 100; i++) { + uint256 phi = libzcash::random_uint256(); + uint256 h_sig = libzcash::random_uint256(); + ASSERT_TRUE( + test_prf(0x60, phi, h_sig) == PRF_rho(phi, 1, h_sig) + ); + } + + uint256 dummy; + ASSERT_THROW(PRF_rho(dummy, 2, dummy), std::domain_error); } diff --git a/src/test/noteencryption_tests.cpp b/src/test/noteencryption_tests.cpp deleted file mode 100644 index a31c245d1..000000000 --- a/src/test/noteencryption_tests.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "test/test_bitcoin.h" -#include "sodium.h" - -#include - -#include "zcash/NoteEncryption.hpp" -#include "zcash/prf.h" - -#include - -class TestNoteDecryption : public ZCNoteDecryption { -public: - TestNoteDecryption(uint256 sk_enc) : ZCNoteDecryption(sk_enc) {} - - void change_pk_enc(uint256 to) { - pk_enc = to; - } -}; - -BOOST_FIXTURE_TEST_SUITE(noteencryption_tests, BasicTestingSetup) - -BOOST_AUTO_TEST_CASE(noteencryption) -{ - uint256 sk_enc = ZCNoteEncryption::generate_privkey(uint256S("21035d60bc1983e37950ce4803418a8fb33ea68d5b937ca382ecbae7564d6a77")); - uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc); - - ZCNoteEncryption b = ZCNoteEncryption(uint256()); - - boost::array message; - for (unsigned char i = 0; i < 216; i++) { - // Fill the message with dummy data - message[i] = (unsigned char) i; - } - - for (int i = 0; i < 255; i++) { - auto ciphertext = b.encrypt(pk_enc, message); - - { - ZCNoteDecryption decrypter(sk_enc); - - // Test decryption - auto plaintext = decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i); - BOOST_CHECK(plaintext == message); - - // Test wrong nonce - BOOST_CHECK_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256(), (i == 0) ? 1 : (i - 1)), std::runtime_error); - - // Test wrong ephemeral key - BOOST_CHECK_THROW(decrypter.decrypt(ciphertext, ZCNoteEncryption::generate_privkey(uint256()), uint256(), i), std::runtime_error); - - // Test wrong seed - BOOST_CHECK_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256S("11035d60bc1983e37950ce4803418a8fb33ea68d5b937ca382ecbae7564d6a77"), i), std::runtime_error); - - // Test corrupted ciphertext - ciphertext[10] ^= 0xff; - BOOST_CHECK_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i), std::runtime_error); - ciphertext[10] ^= 0xff; - } - - { - // Test wrong private key - uint256 sk_enc_2 = ZCNoteEncryption::generate_privkey(uint256()); - ZCNoteDecryption decrypter(sk_enc_2); - - BOOST_CHECK_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i), std::runtime_error); - } - - { - TestNoteDecryption decrypter(sk_enc); - - // Test decryption - auto plaintext = decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i); - BOOST_CHECK(plaintext == message); - - // Test wrong public key (test of KDF) - decrypter.change_pk_enc(uint256()); - BOOST_CHECK_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i), std::runtime_error); - } - } - - // Nonce space should run out here - BOOST_CHECK_THROW(b.encrypt(pk_enc, message), std::logic_error); -} - -uint256 test_prf( - unsigned char distinguisher, - uint256 x, - uint256 y -) { - *x.begin() &= 0x0f; - *x.begin() |= distinguisher; - CSHA256 hasher; - hasher.Write(x.begin(), 32); - hasher.Write(y.begin(), 32); - - uint256 ret; - hasher.FinalizeNoPadding(ret.begin()); - return ret; -} - -BOOST_AUTO_TEST_CASE(prf_addr) -{ - for (size_t i = 0; i < 100; i++) { - uint256 a_sk = libzcash::random_uint256(); - uint256 rest; - BOOST_CHECK_MESSAGE( - test_prf(0xc0, a_sk, rest) == PRF_addr_a_pk(a_sk), - a_sk.GetHex() - ); - } - - for (size_t i = 0; i < 100; i++) { - uint256 a_sk = libzcash::random_uint256(); - uint256 rest; - *rest.begin() = 0x01; - BOOST_CHECK_MESSAGE( - test_prf(0xc0, a_sk, rest) == PRF_addr_sk_enc(a_sk), - a_sk.GetHex() - ); - } -} - -BOOST_AUTO_TEST_CASE(prf_nf) -{ - for (size_t i = 0; i < 100; i++) { - uint256 a_sk = libzcash::random_uint256(); - uint256 rho = libzcash::random_uint256(); - BOOST_CHECK_MESSAGE( - test_prf(0xe0, a_sk, rho) == PRF_nf(a_sk, rho), - a_sk.GetHex() + " and " + rho.GetHex() - ); - } -} - -BOOST_AUTO_TEST_CASE(prf_pk) -{ - for (size_t i = 0; i < 100; i++) { - uint256 a_sk = libzcash::random_uint256(); - uint256 h_sig = libzcash::random_uint256(); - BOOST_CHECK_MESSAGE( - test_prf(0x00, a_sk, h_sig) == PRF_pk(a_sk, 0, h_sig), - a_sk.GetHex() + " and " + h_sig.GetHex() - ); - } - - for (size_t i = 0; i < 100; i++) { - uint256 a_sk = libzcash::random_uint256(); - uint256 h_sig = libzcash::random_uint256(); - BOOST_CHECK_MESSAGE( - test_prf(0x40, a_sk, h_sig) == PRF_pk(a_sk, 1, h_sig), - a_sk.GetHex() + " and " + h_sig.GetHex() - ); - } - - uint256 dummy; - BOOST_CHECK_THROW(PRF_pk(dummy, 2, dummy), std::domain_error); -} - -BOOST_AUTO_TEST_CASE(prf_rho) -{ - for (size_t i = 0; i < 100; i++) { - uint256 phi = libzcash::random_uint256(); - uint256 h_sig = libzcash::random_uint256(); - BOOST_CHECK_MESSAGE( - test_prf(0x20, phi, h_sig) == PRF_rho(phi, 0, h_sig), - phi.GetHex() + " and " + h_sig.GetHex() - ); - } - - for (size_t i = 0; i < 100; i++) { - uint256 phi = libzcash::random_uint256(); - uint256 h_sig = libzcash::random_uint256(); - BOOST_CHECK_MESSAGE( - test_prf(0x60, phi, h_sig) == PRF_rho(phi, 1, h_sig), - phi.GetHex() + " and " + h_sig.GetHex() - ); - } - - uint256 dummy; - BOOST_CHECK_THROW(PRF_rho(dummy, 2, dummy), std::domain_error); -} - -BOOST_AUTO_TEST_SUITE_END()