Add regression tests and test vectors for Sapling merkle tree

This commit is contained in:
Sean Bowe
2018-04-17 22:59:41 -06:00
parent 2b002a7e60
commit 2f23a656fb
8 changed files with 443 additions and 5 deletions

View File

@@ -7,6 +7,13 @@
#include "test/data/merkle_path.json.h"
#include "test/data/merkle_commitments.json.h"
#include "test/data/merkle_roots_sapling.json.h"
#include "test/data/merkle_roots_empty_sapling.json.h"
#include "test/data/merkle_serialization_sapling.json.h"
#include "test/data/merkle_witness_serialization_sapling.json.h"
#include "test/data/merkle_path_sapling.json.h"
#include "test/data/merkle_commitments_sapling.json.h"
#include <iostream>
#include <stdexcept>
@@ -51,7 +58,8 @@ void test_tree(
UniValue root_tests,
UniValue ser_tests,
UniValue witness_ser_tests,
UniValue path_tests
UniValue path_tests,
bool libsnark_test
)
{
size_t witness_ser_i = 0;
@@ -106,10 +114,9 @@ void test_tree(
ASSERT_THROW(wit.element(), std::runtime_error);
} else {
auto path = wit.path();
expect_test_vector(path_tests[path_i++], path);
{
expect_test_vector(path_tests[path_i++], path);
if (libsnark_test) {
typedef Fr<default_r1cs_ppzksnark_pp> FieldT;
protoboard<FieldT> pb;
@@ -188,7 +195,31 @@ TEST(merkletree, vectors) {
UniValue path_tests = read_json(MAKE_STRING(json_tests::merkle_path));
UniValue commitment_tests = read_json(MAKE_STRING(json_tests::merkle_commitments));
test_tree<ZCTestingIncrementalMerkleTree, ZCTestingIncrementalWitness>(commitment_tests, root_tests, ser_tests, witness_ser_tests, path_tests);
test_tree<ZCTestingIncrementalMerkleTree, ZCTestingIncrementalWitness>(
commitment_tests,
root_tests,
ser_tests,
witness_ser_tests,
path_tests,
true
);
}
TEST(merkletree, sapling_vectors) {
UniValue root_tests = read_json(MAKE_STRING(json_tests::merkle_roots_sapling));
UniValue ser_tests = read_json(MAKE_STRING(json_tests::merkle_serialization_sapling));
UniValue witness_ser_tests = read_json(MAKE_STRING(json_tests::merkle_witness_serialization_sapling));
UniValue path_tests = read_json(MAKE_STRING(json_tests::merkle_path_sapling));
UniValue commitment_tests = read_json(MAKE_STRING(json_tests::merkle_commitments_sapling));
test_tree<ZCSaplingTestingIncrementalMerkleTree, ZCSaplingTestingIncrementalWitness>(
commitment_tests,
root_tests,
ser_tests,
witness_ser_tests,
path_tests,
false
);
}
TEST(merkletree, emptyroots) {
@@ -204,6 +235,19 @@ TEST(merkletree, emptyroots) {
ASSERT_TRUE(INCREMENTAL_MERKLE_TREE_DEPTH <= 64);
}
TEST(merkletree, emptyroots_sapling) {
UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty_sapling));
libzcash::EmptyMerkleRoots<62, libzcash::PedersenHash> emptyroots;
for (size_t depth = 0; depth <= 62; depth++) {
expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth));
}
// Double check that we're testing (at least) all the empty roots we'll use.
ASSERT_TRUE(INCREMENTAL_MERKLE_TREE_DEPTH <= 62);
}
TEST(merkletree, emptyroot) {
// This literal is the depth-20 empty tree root with the bytes reversed to
// account for the fact that uint256S() loads a big-endian representation of
@@ -213,6 +257,15 @@ TEST(merkletree, emptyroot) {
ASSERT_TRUE(ZCIncrementalMerkleTree::empty_root() == expected);
}
TEST(merkletree, emptyroot_sapling) {
// This literal is the depth-20 empty tree root with the bytes reversed to
// account for the fact that uint256S() loads a big-endian representation of
// an integer which converted to little-endian internally.
uint256 expected = uint256S("56f5903dbfe4e7356e55f13b2e6e3180a8f7056c7d8814511f797487b398ee42");
ASSERT_TRUE(ZCSaplingIncrementalMerkleTree::empty_root() == expected);
}
TEST(merkletree, deserializeInvalid) {
// attempt to deserialize a small tree from a serialized large tree
// (exceeds depth well-formedness check)