From 4d965f53eb2a0948f3c4db37a6ef783a1ede9152 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 24 Jan 2020 06:32:13 -0500 Subject: [PATCH] A bunch more libsnark deletions/updates --- build-aux/m4/ax_openmp.m4 | 123 ----- configure.ac | 33 +- depends/packages/libgmp.mk | 44 -- depends/packages/packages.mk | 4 +- qa/hush/full-test-suite.sh | 18 +- src/Makefile.am | 12 +- src/Makefile.zcash.include | 29 - src/gtest/main.cpp | 10 +- src/gtest/test_circuit.cpp | 183 ------- src/gtest/test_joinsplit.cpp | 61 +-- src/gtest/test_merkletree.cpp | 90 +--- src/gtest/test_proofs.cpp | 702 ------------------------- src/primitives/transaction.h | 1 + src/zcash/CreateJoinSplit.cpp | 40 -- src/zcash/GenerateParams.cpp | 26 - src/zcash/IncrementalMerkleTree.cpp | 788 ++++++++++++++++++++++++++++ src/zcash/IncrementalMerkleTree.hpp | 13 +- src/zcash/Proof.cpp | 233 -------- src/zcash/Proof.hpp | 35 -- src/zcash/circuit/commitment.tcc | 100 ---- src/zcash/circuit/gadget.tcc | 349 ------------ src/zcash/circuit/merkle.tcc | 60 --- src/zcash/circuit/note.tcc | 244 --------- src/zcash/circuit/prfs.tcc | 109 ---- src/zcash/circuit/utils.tcc | 75 --- src/zcbenchmarks.cpp | 23 +- src/zcbenchmarks.h | 2 +- zcutil/build-win.sh | 2 +- 28 files changed, 848 insertions(+), 2561 deletions(-) delete mode 100644 build-aux/m4/ax_openmp.m4 delete mode 100644 depends/packages/libgmp.mk delete mode 100644 src/Makefile.zcash.include delete mode 100644 src/gtest/test_circuit.cpp delete mode 100644 src/gtest/test_proofs.cpp delete mode 100644 src/zcash/CreateJoinSplit.cpp delete mode 100644 src/zcash/GenerateParams.cpp delete mode 100644 src/zcash/circuit/commitment.tcc delete mode 100644 src/zcash/circuit/gadget.tcc delete mode 100644 src/zcash/circuit/merkle.tcc delete mode 100644 src/zcash/circuit/note.tcc delete mode 100644 src/zcash/circuit/prfs.tcc delete mode 100644 src/zcash/circuit/utils.tcc diff --git a/build-aux/m4/ax_openmp.m4 b/build-aux/m4/ax_openmp.m4 deleted file mode 100644 index 866e1d664..000000000 --- a/build-aux/m4/ax_openmp.m4 +++ /dev/null @@ -1,123 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_openmp.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_OPENMP([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) -# -# DESCRIPTION -# -# This macro tries to find out how to compile programs that use OpenMP a -# standard API and set of compiler directives for parallel programming -# (see http://www-unix.mcs/) -# -# On success, it sets the OPENMP_CFLAGS/OPENMP_CXXFLAGS/OPENMP_F77FLAGS -# output variable to the flag (e.g. -omp) used both to compile *and* link -# OpenMP programs in the current language. -# -# NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. -# -# If you want to compile everything with OpenMP, you should set: -# -# CFLAGS="$CFLAGS $OPENMP_CFLAGS" -# #OR# CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" -# #OR# FFLAGS="$FFLAGS $OPENMP_FFLAGS" -# -# (depending on the selected language). -# -# The user can override the default choice by setting the corresponding -# environment variable (e.g. OPENMP_CFLAGS). -# -# ACTION-IF-FOUND is a list of shell commands to run if an OpenMP flag is -# found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is -# not found. If ACTION-IF-FOUND is not specified, the default action will -# define HAVE_OPENMP. -# -# LICENSE -# -# Copyright (c) 2008 Steven G. Johnson -# Copyright (c) 2015 John W. Peterson -# Copyright (c) 2016 Nick R. Papior -# -# This program 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. -# -# This program 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 this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 13 - -AC_DEFUN([AX_OPENMP], [ -AC_PREREQ([2.69]) dnl for _AC_LANG_PREFIX - -AC_CACHE_CHECK([for OpenMP flag of _AC_LANG compiler], ax_cv_[]_AC_LANG_ABBREV[]_openmp, [save[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS -ax_cv_[]_AC_LANG_ABBREV[]_openmp=unknown -# Flags to try: -fopenmp (gcc), -mp (SGI & PGI), -# -qopenmp (icc>=15), -openmp (icc), -# -xopenmp (Sun), -omp (Tru64), -# -qsmp=omp (AIX), -# none -ax_openmp_flags="-fopenmp -openmp -qopenmp -mp -xopenmp -omp -qsmp=omp none" -if test "x$OPENMP_[]_AC_LANG_PREFIX[]FLAGS" != x; then - ax_openmp_flags="$OPENMP_[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flags" -fi -for ax_openmp_flag in $ax_openmp_flags; do - case $ax_openmp_flag in - none) []_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[] ;; - *) []_AC_LANG_PREFIX[]FLAGS="$save[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flag" ;; - esac - AC_LINK_IFELSE([AC_LANG_SOURCE([[ -@%:@include - -static void -parallel_fill(int * data, int n) -{ - int i; -@%:@pragma omp parallel for - for (i = 0; i < n; ++i) - data[i] = i; -} - -int -main() -{ - int arr[100000]; - omp_set_num_threads(2); - parallel_fill(arr, 100000); - return 0; -} -]])],[ax_cv_[]_AC_LANG_ABBREV[]_openmp=$ax_openmp_flag; break],[]) -done -[]_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[]FLAGS -]) -if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" = "xunknown"; then - m4_default([$2],:) -else - if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" != "xnone"; then - OPENMP_[]_AC_LANG_PREFIX[]FLAGS=$ax_cv_[]_AC_LANG_ABBREV[]_openmp - fi - m4_default([$1], [AC_DEFINE(HAVE_OPENMP,1,[Define if OpenMP is enabled])]) -fi -])dnl AX_OPENMP diff --git a/configure.ac b/configure.ac index e06bfb402..9b5c0335b 100644 --- a/configure.ac +++ b/configure.ac @@ -700,7 +700,7 @@ if test x$use_pkgconfig = xyes; then ) else # BUG: Fix this: - echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++, libgmp' + echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++' AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) @@ -740,22 +740,6 @@ else fi fi -# These packages don't provide pkgconfig config files across all -# platforms, so we use older autoconf detection mechanisms: -if test x$TARGET_OS = xdarwin; then -AC_CHECK_HEADER([gmp.h],,AC_MSG_ERROR(libgmp headers missing)) -AC_CHECK_LIB([gmp],[[__gmpn_sub_n]],GMP_LIBS=-lgmp, [AC_MSG_ERROR(libgmp missing)]) - -AC_CHECK_HEADER([gmpxx.h],,AC_MSG_ERROR(libgmpxx headers missing)) -AC_CHECK_LIB([gmpxx],[main],GMPXX_LIBS=-lgmpxx, [AC_MSG_ERROR(libgmpxx missing)]) -fi - -#AC_CHECK_HEADER([gmp.h],,AC_MSG_ERROR(libgmp headers missing)) -#AC_CHECK_LIB([gmp],[[__gmpn_sub_n]],GMP_LIBS=-lgmp, [AC_MSG_ERROR(libgmp missing)]) - -#AC_CHECK_HEADER([gmpxx.h],,AC_MSG_ERROR(libgmpxx headers missing)) -#AC_CHECK_LIB([gmpxx],[main],GMPXX_LIBS=-lgmpxx, [AC_MSG_ERROR(libgmpxx missing)]) - RUST_LIBS="-lrustzcash" case $host in *mingw*) @@ -765,23 +749,12 @@ case $host in ;; esac -dnl Check for OpenMP support -AX_OPENMP( - [AC_DEFINE(HAVE_OPENMP, 1, [Define if OpenMP is enabled]) - AM_CONDITIONAL([HAVE_OPENMP], [true]) - CPPFLAGS="$CPPFLAGS -DMULTICORE" - CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS"], - [AC_MSG_WARN([OpenMP not supported, disabling multithreading]) - AC_DEFINE(HAVE_OPENMP, 0, [Define if OpenMP is enabled]) - AM_CONDITIONAL([HAVE_OPENMP], [false])]) - - -# Additional Zcash flags +# Additional Zcash internals flags AX_CHECK_COMPILE_FLAG([-fwrapv],[CXXFLAGS="$CXXFLAGS -fwrapv"]) AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"]) AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]]) -LIBZCASH_LIBS="-lgmp -lgmpxx $BOOST_SYSTEM_LIB -lcrypto -lsodium $RUST_LIBS" +LIBZCASH_LIBS="$BOOST_SYSTEM_LIB -lcrypto -lsodium $RUST_LIBS" AC_MSG_CHECKING([whether to build komodod]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) diff --git a/depends/packages/libgmp.mk b/depends/packages/libgmp.mk deleted file mode 100644 index acd5d4c0e..000000000 --- a/depends/packages/libgmp.mk +++ /dev/null @@ -1,44 +0,0 @@ -package=libgmp - -ifeq ($(host_os),mingw32) -$(package)_download_path=https://github.com/joshuayabut/$(package)/archive -$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz -$(package)_download_file=$($(package)_git_commit).tar.gz -$(package)_sha256_hash=193836c1acc9dc00fe2521205d7bbe1ba13263f6cbef6f02584bf6f8b34b108f -$(package)_git_commit=053c03b1cab347671d936f43ef66b48ab5e380ee -$(package)_dependencies= -$(package)_config_opts=--enable-cxx --disable-shared -else ifeq ($(build_os),darwin) -$(package)_download_path=https://github.com/ca333/$(package)/archive -$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz -$(package)_download_file=$($(package)_git_commit).tar.gz -$(package)_sha256_hash=59b2c2b5d58fdf5943bfde1fa709e9eb53e7e072c9699d28dc1c2cbb3c8cc32c -$(package)_git_commit=aece03c7b6967f91f3efdac8c673f55adff53ab1 -$(package)_dependencies= -$(package)_config_opts=--enable-cxx --disable-shared -else -$(package)_version=6.1.1 -$(package)_download_path=https://github.com/MyHush/libgmp/releases/download/v6.1.1 -$(package)_file_name=gmp-$($(package)_version).tar.bz2 -$(package)_sha256_hash=a8109865f2893f1373b0a8ed5ff7429de8db696fc451b1036bd7bdf95bbeffd6 -$(package)_dependencies= -$(package)_config_opts=--enable-cxx --disable-shared -endif - -define $(package)_config_cmds - $($(package)_autoconf) --host=$(host) --build=$(build) -endef - -ifeq ($(build_os),darwin) -define $(package)_build_cmds - $(MAKE) -endef -else -define $(package)_build_cmds - $(MAKE) CPPFLAGS='-fPIC' -endef -endif - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install ; echo '=== staging find for $(package):' ; find $($(package)_staging_dir) -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 1c1a50668..5aee77182 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,10 +1,10 @@ rust_packages := rust librustzcash ifeq ($(build_os),darwin) - zcash_packages := libsnark libgmp libsodium utfcpp + zcash_packages := libsnark libsodium utfcpp else proton_packages := proton - zcash_packages := libgmp libsodium utfcpp + zcash_packages := libsodium utfcpp endif rust_crates := \ diff --git a/qa/hush/full-test-suite.sh b/qa/hush/full-test-suite.sh index 0a19b32c8..5c048ff9d 100755 --- a/qa/hush/full-test-suite.sh +++ b/qa/hush/full-test-suite.sh @@ -64,21 +64,19 @@ def check_security_hardening(): # PIE, RELRO, Canary, and NX are tested by make check-security. ret &= subprocess.call(['make', '-C', repofile('src'), 'check-security']) == 0 - ret &= test_rpath_runpath('src/zcashd') - ret &= test_rpath_runpath('src/zcash-cli') - ret &= test_rpath_runpath('src/zcash-gtest') - ret &= test_rpath_runpath('src/zcash-tx') + ret &= test_rpath_runpath('src/hushd') + ret &= test_rpath_runpath('src/hush-cli') + ret &= test_rpath_runpath('src/hush-gtest') + ret &= test_rpath_runpath('src/hush-tx') ret &= test_rpath_runpath('src/test/test_bitcoin') - ret &= test_rpath_runpath('src/zcash/GenerateParams') # NOTE: checksec.sh does not reliably determine whether FORTIFY_SOURCE # is enabled for the entire binary. See issue #915. - ret &= test_fortify_source('src/zcashd') - ret &= test_fortify_source('src/zcash-cli') - ret &= test_fortify_source('src/zcash-gtest') - ret &= test_fortify_source('src/zcash-tx') + ret &= test_fortify_source('src/hushd') + ret &= test_fortify_source('src/hush-cli') + ret &= test_fortify_source('src/hush-gtest') + ret &= test_fortify_source('src/hush-tx') ret &= test_fortify_source('src/test/test_bitcoin') - ret &= test_fortify_source('src/zcash/GenerateParams') return ret diff --git a/src/Makefile.am b/src/Makefile.am index 25f48a557..8863b6e98 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -633,15 +633,9 @@ libzcash_a_SOURCES = \ zcash/Note.cpp \ zcash/prf.cpp \ zcash/util.cpp \ - zcash/zip32.cpp \ - zcash/circuit/commitment.tcc \ - zcash/circuit/gadget.tcc \ - zcash/circuit/merkle.tcc \ - zcash/circuit/note.tcc \ - zcash/circuit/prfs.tcc \ - zcash/circuit/utils.tcc - -libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) $(HARDENED_CXXFLAGS) $(HARDENED_LDFLAGS) -pipe $(SAN_LDFLAGS) -O1 -g -Wstack-protector $(SAN_CXXFLAGS) -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES) + zcash/zip32.cpp + +libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) $(HARDENED_CXXFLAGS) $(HARDENED_LDFLAGS) -pipe $(SAN_LDFLAGS) -O1 -g -Wstack-protector $(SAN_CXXFLAGS) -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES) #libzcash_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) #libzcash_a_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) diff --git a/src/Makefile.zcash.include b/src/Makefile.zcash.include deleted file mode 100644 index c77fe121c..000000000 --- a/src/Makefile.zcash.include +++ /dev/null @@ -1,29 +0,0 @@ -noinst_PROGRAMS += \ - zcash/GenerateParams \ - zcash/CreateJoinSplit - -# tool for generating our public parameters -zcash_GenerateParams_SOURCES = zcash/GenerateParams.cpp -zcash_GenerateParams_CPPFLAGS = $(AM_CPPFLAGS) -zcash_GenerateParams_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -zcash_GenerateParams_LDADD = \ - $(BOOST_LIBS) \ - $(LIBZCASH) \ - $(LIBBITCOIN_UTIL) \ - $(LIBBITCOIN_CRYPTO) \ - $(LIBZCASH_LIBS) - -# tool for profiling the creation of joinsplits -zcash_CreateJoinSplit_SOURCES = zcash/CreateJoinSplit.cpp -zcash_CreateJoinSplit_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -zcash_CreateJoinSplit_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -zcash_CreateJoinSplit_LDADD = \ - $(LIBBITCOIN_COMMON) \ - $(LIBZCASH) \ - $(LIBBITCOIN_UTIL) \ - $(LIBBITCOIN_CRYPTO) \ - $(BOOST_LIBS) \ - $(LIBZCASH_LIBS) \ - $(LIBCRYPTOCONDITIONS) \ - $(LIBSECP256K1) - diff --git a/src/gtest/main.cpp b/src/gtest/main.cpp index bdebedeb5..28114834c 100644 --- a/src/gtest/main.cpp +++ b/src/gtest/main.cpp @@ -5,9 +5,6 @@ #include "zcash/JoinSplit.hpp" #include "util.h" -#include -#include - #include "librustzcash.h" struct ECCryptoClosure @@ -23,12 +20,7 @@ int main(int argc, char **argv) { assert(init_and_check_sodium() != -1); ECC_Start(); - libsnark::default_r1cs_ppzksnark_pp::init_public_params(); - libsnark::inhibit_profiling_info = true; - libsnark::inhibit_profiling_counters = true; - boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key"; - boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key"; - params = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string()); + params = ZCJoinSplit::Prepared(); boost::filesystem::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params"; boost::filesystem::path sapling_output = ZC_GetParamsDir() / "sapling-output.params"; diff --git a/src/gtest/test_circuit.cpp b/src/gtest/test_circuit.cpp deleted file mode 100644 index ab2a8ecb6..000000000 --- a/src/gtest/test_circuit.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include -#include "uint256.h" - -#include "zcash/util.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include "zcash/IncrementalMerkleTree.hpp" - -using namespace libsnark; -using namespace libzcash; - -#include "zcash/circuit/utils.tcc" -#include "zcash/circuit/merkle.tcc" - -template -void test_value_equals(uint64_t i) { - protoboard pb; - pb_variable_array num; - num.allocate(pb, 64, ""); - num.fill_with_bits(pb, uint64_to_bool_vector(i)); - pb.add_r1cs_constraint(r1cs_constraint( - packed_addition(num), - FieldT::one(), - FieldT::one() * i - ), ""); - ASSERT_TRUE(pb.is_satisfied()); -} - -TEST(circuit, values) -{ - typedef Fr FieldT; - test_value_equals(0); - test_value_equals(1); - test_value_equals(3); - test_value_equals(5391); - test_value_equals(883128374); - test_value_equals(173419028459); - test_value_equals(2205843009213693953); -} - -TEST(circuit, endianness) -{ - std::vector before = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63 - }; - auto result = swap_endianness_u64(before); - - std::vector after = { - 56, 57, 58, 59, 60, 61, 62, 63, - 48, 49, 50, 51, 52, 53, 54, 55, - 40, 41, 42, 43, 44, 45, 46, 47, - 32, 33, 34, 35, 36, 37, 38, 39, - 24, 25, 26, 27, 28, 29, 30, 31, - 16, 17, 18, 19, 20, 21, 22, 23, - 8, 9, 10, 11, 12, 13, 14, 15, - 0, 1, 2, 3, 4, 5, 6, 7 - }; - - EXPECT_EQ(after, result); - - std::vector bad = {0, 1, 2, 3}; - - ASSERT_THROW(swap_endianness_u64(bad), std::length_error); -} - -template -bool test_merkle_gadget( - bool enforce_a, - bool enforce_b, - bool write_root_first -) -{ - protoboard pb; - digest_variable root(pb, 256, "root"); - pb.set_input_sizes(256); - - digest_variable commitment1(pb, 256, "commitment1"); - digest_variable commitment2(pb, 256, "commitment2"); - - pb_variable commitment1_read; - commitment1_read.allocate(pb); - pb_variable commitment2_read; - commitment2_read.allocate(pb); - - merkle_tree_gadget mgadget1(pb, commitment1, root, commitment1_read); - merkle_tree_gadget mgadget2(pb, commitment2, root, commitment2_read); - - commitment1.generate_r1cs_constraints(); - commitment2.generate_r1cs_constraints(); - root.generate_r1cs_constraints(); - mgadget1.generate_r1cs_constraints(); - mgadget2.generate_r1cs_constraints(); - - SproutMerkleTree tree; - uint256 commitment1_data = uint256S("54d626e08c1c802b305dad30b7e54a82f102390cc92c7d4db112048935236e9c"); - uint256 commitment2_data = uint256S("59d2cde5e65c1414c32ba54f0fe4bdb3d67618125286e6a191317917c812c6d7"); - tree.append(commitment1_data); - auto wit1 = tree.witness(); - tree.append(commitment2_data); - wit1.append(commitment2_data); - auto wit2 = tree.witness(); - auto expected_root = tree.root(); - tree.append(uint256S("3e243c8798678570bb8d42616c23a536af44be15c4eef073490c2a44ae5f32c3")); - auto unexpected_root = tree.root(); - tree.append(uint256S("26d9b20c7f1c3d2528bbcd43cd63344b0afd3b6a0a8ebd37ec51cba34907bec7")); - auto badwit1 = tree.witness(); - tree.append(uint256S("02c2467c9cd15e0d150f74cd636505ed675b0b71b66a719f6f52fdb49a5937bb")); - auto badwit2 = tree.witness(); - - // Perform the test - - pb.val(commitment1_read) = enforce_a ? FieldT::one() : FieldT::zero(); - pb.val(commitment2_read) = enforce_b ? FieldT::one() : FieldT::zero(); - - commitment1.bits.fill_with_bits(pb, uint256_to_bool_vector(commitment1_data)); - commitment2.bits.fill_with_bits(pb, uint256_to_bool_vector(commitment2_data)); - - if (write_root_first) { - root.bits.fill_with_bits(pb, uint256_to_bool_vector(expected_root)); - } - - mgadget1.generate_r1cs_witness(wit1.path()); - mgadget2.generate_r1cs_witness(wit2.path()); - - // Overwrite with our expected root - root.bits.fill_with_bits(pb, uint256_to_bool_vector(expected_root)); - - return pb.is_satisfied(); -} - -TEST(circuit, merkle_tree_gadget_weirdness) -{ - /* - The merkle tree gadget takes a leaf in the merkle tree (the Note commitment), - a merkle tree authentication path, and a root (anchor). It also takes a parameter - called read_success, which is used to determine if the commitment actually needs to - appear in the tree. - - If two input notes use the same root (which our protocol does) then if `read_success` - is disabled on the first note but enabled on the second note (i.e., the first note - has value of zero and second note has nonzero value) then there is an edge case in - the witnessing behavior. The first witness will accidentally constrain the root to - equal null (the default value of the anchor) and the second witness will actually - copy the bits, violating the constraint system. - - Notice that this edge case is not in the constraint system but in the witnessing - behavior. - */ - - typedef Fr FieldT; - - // Test the normal case - ASSERT_TRUE(test_merkle_gadget(true, true, false)); - ASSERT_TRUE(test_merkle_gadget(true, true, true)); - - // Test the case where the first commitment is enforced but the second isn't - // Works because the first read is performed before the second one - ASSERT_TRUE(test_merkle_gadget(true, false, false)); - ASSERT_TRUE(test_merkle_gadget(true, false, true)); - - // Test the case where the first commitment isn't enforced but the second is - // Doesn't work because the first multipacker witnesses the existing root (which - // is null) - ASSERT_TRUE(!test_merkle_gadget(false, true, false)); - - // Test the last again, except this time write the root first. - ASSERT_TRUE(test_merkle_gadget(false, true, true)); -} diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index 4de2fc471..8032fc972 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -22,10 +22,9 @@ using namespace libzcash; extern ZCJoinSplit* params; -typedef std::array SproutProofs; -// Make both the PHGR and Groth proof for a Sprout statement, -// and store the results in JSDescription objects. -SproutProofs makeSproutProofs( +// Make the Groth proof for a Sprout statement, +// and store the result in a JSDescription object. +JSDescription makeSproutProof( ZCJoinSplit& js, const std::array& inputs, const std::array& outputs, @@ -34,25 +33,17 @@ SproutProofs makeSproutProofs( uint64_t vpub_new, const uint256& rt ){ - //Making the PHGR proof - JSDescription phgr(false, js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new); - //Making the Groth proof - JSDescription groth(true, js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new); - - return {phgr, groth}; - + return JSDescription(js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new); } -bool verifySproutProofs( +bool verifySproutProof( ZCJoinSplit& js, - const SproutProofs& jsdescs, + const JSDescription& jsdesc, const uint256& joinSplitPubKey ) { auto verifier = libzcash::ProofVerifier::Strict(); - bool phgrPassed = jsdescs[0].Verify(js, verifier, joinSplitPubKey); - bool grothPassed = jsdescs[1].Verify(js, verifier, joinSplitPubKey); - return phgrPassed && grothPassed; + return jsdesc.Verify(js, verifier, joinSplitPubKey); } @@ -73,7 +64,7 @@ void test_full_api(ZCJoinSplit* js) uint64_t vpub_new = 0; uint256 joinSplitPubKey = random_uint256(); uint256 rt = tree.root(); - SproutProofs jsdescs; + JSDescription jsdesc; { std::array inputs = { @@ -89,7 +80,7 @@ void test_full_api(ZCJoinSplit* js) std::array output_notes; // Perform the proofs - jsdescs = makeSproutProofs( + jsdesc = makeSproutProof( *js, inputs, outputs, @@ -101,13 +92,11 @@ void test_full_api(ZCJoinSplit* js) } // Verify both PHGR and Groth Proof: - ASSERT_TRUE(verifySproutProofs(*js, jsdescs, joinSplitPubKey)); + ASSERT_TRUE(verifySproutProof(*js, jsdesc, joinSplitPubKey)); - // Run tests using both phgr and groth as basis for field values - for (auto jsdesc : jsdescs) { SproutMerkleTree tree; - SproutProofs jsdescs2; + JSDescription jsdesc2; // Recipient should decrypt // Now the recipient should spend the money again auto h_sig = js->h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey); @@ -153,7 +142,7 @@ void test_full_api(ZCJoinSplit* js) // Perform the proofs - jsdescs2 = makeSproutProofs( + jsdesc2 = makeSproutProof( *js, inputs, outputs, @@ -166,8 +155,8 @@ void test_full_api(ZCJoinSplit* js) } - // Verify both PHGR and Groth Proof: - ASSERT_TRUE(verifySproutProofs(*js, jsdescs2, joinSplitPubKey2)); + // Verify Groth Proof: + ASSERT_TRUE(verifySproutProof(*js, jsdesc2, joinSplitPubKey2)); } } @@ -191,28 +180,8 @@ void invokeAPI( std::array output_notes; - // PHGR - SproutProof proof = js->prove( - false, - inputs, - outputs, - output_notes, - ciphertexts, - ephemeralKey, - joinSplitPubKey, - randomSeed, - macs, - nullifiers, - commitments, - vpub_old, - vpub_new, - rt, - false - ); - // Groth - proof = js->prove( - true, + SproutProof proof = js->prove( inputs, outputs, output_notes, diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index 23c39c044..ad3c2ad06 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -1,14 +1,12 @@ #include #include "test/data/merkle_roots.json.h" -#include "test/data/merkle_roots_empty.json.h" #include "test/data/merkle_serialization.json.h" #include "test/data/merkle_witness_serialization.json.h" #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" @@ -26,17 +24,11 @@ #include "zcash/IncrementalMerkleTree.hpp" #include "zcash/util.h" -#include -#include -#include -#include - #include #include "json_test_vectors.h" using namespace std; -using namespace libsnark; template<> void expect_deser_same(const SproutTestingWitness& expected) @@ -58,8 +50,7 @@ void test_tree( UniValue root_tests, UniValue ser_tests, UniValue witness_ser_tests, - UniValue path_tests, - bool libsnark_test + UniValue path_tests ) { size_t witness_ser_i = 0; @@ -115,55 +106,6 @@ void test_tree( } else { auto path = wit.path(); expect_test_vector(path_tests[path_i++], path); - - if (libsnark_test) { - typedef Fr FieldT; - - protoboard pb; - pb_variable_array positions; - digest_variable commitment(pb, 256, "commitment"); - digest_variable root(pb, 256, "root"); - positions.allocate(pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, "pos"); - merkle_authentication_path_variable> authvars(pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, "auth"); - merkle_tree_check_read_gadget> auth( - pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, positions, commitment, root, authvars, ONE, "path" - ); - commitment.generate_r1cs_constraints(); - root.generate_r1cs_constraints(); - authvars.generate_r1cs_constraints(); - auth.generate_r1cs_constraints(); - - std::vector commitment_bv; - { - uint256 witnessed_commitment = wit.element(); - std::vector commitment_v(witnessed_commitment.begin(), witnessed_commitment.end()); - commitment_bv = convertBytesVectorToVector(commitment_v); - } - - size_t path_index = convertVectorToInt(path.index); - - commitment.bits.fill_with_bits(pb, bit_vector(commitment_bv)); - positions.fill_with_bits_of_uint64(pb, path_index); - - authvars.generate_r1cs_witness(path_index, path.authentication_path); - auth.generate_r1cs_witness(); - - std::vector root_bv; - { - uint256 witroot = wit.root(); - std::vector root_v(witroot.begin(), witroot.end()); - root_bv = convertBytesVectorToVector(root_v); - } - - root.bits.fill_with_bits(pb, bit_vector(root_bv)); - - ASSERT_TRUE(pb.is_satisfied()); - - root_bv[0] = !root_bv[0]; - root.bits.fill_with_bits(pb, bit_vector(root_bv)); - - ASSERT_TRUE(!pb.is_satisfied()); - } } // Check witness serialization @@ -200,8 +142,7 @@ TEST(merkletree, vectors) { root_tests, ser_tests, witness_ser_tests, - path_tests, - true + path_tests ); } @@ -217,18 +158,19 @@ TEST(merkletree, SaplingVectors) { root_tests, ser_tests, witness_ser_tests, - path_tests, - false + path_tests ); } TEST(merkletree, emptyroots) { - UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty)); - libzcash::EmptyMerkleRoots<64, libzcash::SHA256Compress> emptyroots; + std::array computed; - for (size_t depth = 0; depth <= 64; depth++) { - expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth)); + computed.at(0) = libzcash::SHA256Compress::uncommitted(); + ASSERT_TRUE(emptyroots.empty_root(0) == computed.at(0)); + for (size_t d = 1; d <= 64; d++) { + computed.at(d) = libzcash::SHA256Compress::combine(computed.at(d-1), computed.at(d-1), d-1); + ASSERT_TRUE(emptyroots.empty_root(d) == computed.at(d)); } // Double check that we're testing (at least) all the empty roots we'll use. @@ -236,12 +178,14 @@ TEST(merkletree, emptyroots) { } TEST(merkletree, EmptyrootsSapling) { - UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty_sapling)); - libzcash::EmptyMerkleRoots<62, libzcash::PedersenHash> emptyroots; + std::array computed; - for (size_t depth = 0; depth <= 62; depth++) { - expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth)); + computed.at(0) = libzcash::PedersenHash::uncommitted(); + ASSERT_TRUE(emptyroots.empty_root(0) == computed.at(0)); + for (size_t d = 1; d <= 62; d++) { + computed.at(d) = libzcash::PedersenHash::combine(computed.at(d-1), computed.at(d-1), d-1); + ASSERT_TRUE(emptyroots.empty_root(d) == computed.at(d)); } // Double check that we're testing (at least) all the empty roots we'll use. @@ -249,7 +193,7 @@ TEST(merkletree, EmptyrootsSapling) { } TEST(merkletree, emptyroot) { - // This literal is the depth-20 empty tree root with the bytes reversed to + // This literal is the depth-29 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("59d2cde5e65c1414c32ba54f0fe4bdb3d67618125286e6a191317917c812c6d7"); @@ -258,7 +202,7 @@ TEST(merkletree, emptyroot) { } TEST(merkletree, EmptyrootSapling) { - // This literal is the depth-20 empty tree root with the bytes reversed to + // This literal is the depth-32 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("3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb"); diff --git a/src/gtest/test_proofs.cpp b/src/gtest/test_proofs.cpp deleted file mode 100644 index 5b5c19395..000000000 --- a/src/gtest/test_proofs.cpp +++ /dev/null @@ -1,702 +0,0 @@ -#include -#include "zcash/Proof.hpp" - -#include - -#include -#include -#include - -using namespace libzcash; - -typedef libsnark::default_r1cs_ppzksnark_pp curve_pp; -typedef libsnark::default_r1cs_ppzksnark_pp::G1_type curve_G1; -typedef libsnark::default_r1cs_ppzksnark_pp::G2_type curve_G2; -typedef libsnark::default_r1cs_ppzksnark_pp::GT_type curve_GT; -typedef libsnark::default_r1cs_ppzksnark_pp::Fp_type curve_Fr; -typedef libsnark::default_r1cs_ppzksnark_pp::Fq_type curve_Fq; -typedef libsnark::default_r1cs_ppzksnark_pp::Fqe_type curve_Fq2; - -#include "streams.h" -#include "version.h" -#include "utilstrencodings.h" - -TEST(proofs, g1_pairing_at_infinity) -{ - for (size_t i = 0; i < 100; i++) { - auto r1 = curve_G1::random_element(); - auto r2 = curve_G2::random_element(); - ASSERT_TRUE( - curve_pp::reduced_pairing(curve_G1::zero(), r2) == - curve_GT::one() - ); - ASSERT_TRUE( - curve_pp::final_exponentiation( - curve_pp::double_miller_loop( - curve_pp::precompute_G1(curve_G1::zero()), - curve_pp::precompute_G2(r2), - curve_pp::precompute_G1(curve_G1::zero()), - curve_pp::precompute_G2(r2) - ) - ) == - curve_GT::one() - ); - ASSERT_TRUE( - curve_pp::final_exponentiation( - curve_pp::double_miller_loop( - curve_pp::precompute_G1(r1), - curve_pp::precompute_G2(r2), - curve_pp::precompute_G1(curve_G1::zero()), - curve_pp::precompute_G2(r2) - ) - ) == - curve_pp::reduced_pairing(r1, r2) - ); - ASSERT_TRUE( - curve_pp::final_exponentiation( - curve_pp::double_miller_loop( - curve_pp::precompute_G1(curve_G1::zero()), - curve_pp::precompute_G2(r2), - curve_pp::precompute_G1(r1), - curve_pp::precompute_G2(r2) - ) - ) == - curve_pp::reduced_pairing(r1, r2) - ); - } -} - -TEST(proofs, g2_subgroup_check) -{ - // all G2 elements are order r - ASSERT_TRUE(libsnark::alt_bn128_modulus_r * curve_G2::random_element() == curve_G2::zero()); - - // but that doesn't mean all elements that satisfy the curve equation are in G2... - curve_G2 p = curve_G2::one(); - - while (1) { - // This will construct an order r(2q-r) point with high probability - p.X = curve_Fq2::random_element(); - try { - p.Y = ((p.X.squared() * p.X) + libsnark::alt_bn128_twist_coeff_b).sqrt(); - break; - } catch(...) {} - } - - ASSERT_TRUE(p.is_well_formed()); // it's on the curve - ASSERT_TRUE(libsnark::alt_bn128_modulus_r * p != curve_G2::zero()); // but not the order r subgroup.. - - { - // libsnark unfortunately doesn't check, and the pairing will complete - auto e = curve_Fr("149"); - auto a = curve_pp::reduced_pairing(curve_G1::one(), p); - auto b = curve_pp::reduced_pairing(e * curve_G1::one(), p); - - // though it will not preserve bilinearity - ASSERT_TRUE((a^e) != b); - } - - { - // so, our decompression API should not allow you to decompress G2 elements of that form! - CompressedG2 badp(p); - try { - auto newp = badp.to_libsnark_g2(); - FAIL() << "Expected std::runtime_error"; - } catch (std::runtime_error const & err) { - EXPECT_EQ(err.what(), std::string("point is not in G2")); - } catch(...) { - FAIL() << "Expected std::runtime_error"; - } - } - - // educational purposes: showing that E'(Fp2) is of order r(2q-r), - // by multiplying our random point in E' by (2q-r) = (q + q - r) to - // get an element in G2 - { - auto p1 = libsnark::alt_bn128_modulus_q * p; - p1 = p1 + p1; - p1 = p1 - (libsnark::alt_bn128_modulus_r * p); - - ASSERT_TRUE(p1.is_well_formed()); - ASSERT_TRUE(libsnark::alt_bn128_modulus_r * p1 == curve_G2::zero()); - - CompressedG2 goodp(p1); - auto newp = goodp.to_libsnark_g2(); - - ASSERT_TRUE(newp == p1); - } -} - -TEST(proofs, sqrt_zero) -{ - ASSERT_TRUE(curve_Fq::zero() == curve_Fq::zero().sqrt()); - ASSERT_TRUE(curve_Fq2::zero() == curve_Fq2::zero().sqrt()); -} - -TEST(proofs, sqrt_fq) -{ - // Poor man's PRNG - curve_Fq acc = curve_Fq("348957923485290374852379485") ^ 1000; - - size_t quadratic_residues = 0; - size_t quadratic_nonresidues = 0; - - for (size_t i = 1; i < 1000; i++) { - try { - acc += curve_Fq("45634563456") ^ i; - - curve_Fq x = acc.sqrt(); - ASSERT_TRUE((x*x) == acc); - quadratic_residues += 1; - } catch (std::runtime_error &e) { - quadratic_nonresidues += 1; - } - } - - // Half of all nonzero elements in Fp are quadratic residues - ASSERT_TRUE(quadratic_residues == 511); - ASSERT_TRUE(quadratic_nonresidues == 488); - - for (size_t i = 0; i < 1000; i++) { - curve_Fq x = curve_Fq::random_element(); - curve_Fq x2 = x * x; - - ASSERT_TRUE((x2.sqrt() == x) || (x2.sqrt() == -x)); - } - - // Test vectors - ASSERT_TRUE( - curve_Fq("5204065062716160319596273903996315000119019512886596366359652578430118331601") - == - curve_Fq("348579348568").sqrt() - ); - ASSERT_THROW(curve_Fq("348579348569").sqrt(), std::runtime_error); -} - -TEST(proofs, sqrt_fq2) -{ - curve_Fq2 acc = curve_Fq2( - curve_Fq("3456293840592348059238409578239048769348760238476029347885092384059238459834") ^ 1000, - curve_Fq("2394578084760439457823945729347502374590283479582739485723945729384759823745") ^ 1000 - ); - - size_t quadratic_residues = 0; - size_t quadratic_nonresidues = 0; - - for (size_t i = 1; i < 1000; i++) { - try { - acc = acc + curve_Fq2( - curve_Fq("5204065062716160319596273903996315000119019512886596366359652578430118331601") ^ i, - curve_Fq("348957923485290374852379485348957923485290374852379485348957923485290374852") ^ i - ); - - curve_Fq2 x = acc.sqrt(); - ASSERT_TRUE((x*x) == acc); - quadratic_residues += 1; - } catch (std::runtime_error &e) { - quadratic_nonresidues += 1; - } - } - - // Half of all nonzero elements in Fp^k are quadratic residues as long - // as p != 2 - ASSERT_TRUE(quadratic_residues == 505); - ASSERT_TRUE(quadratic_nonresidues == 494); - - for (size_t i = 0; i < 1000; i++) { - curve_Fq2 x = curve_Fq2::random_element(); - curve_Fq2 x2 = x * x; - - ASSERT_TRUE((x2.sqrt() == x) || (x2.sqrt() == -x)); - } - - // Test vectors - ASSERT_THROW(curve_Fq2( - curve_Fq("2"), - curve_Fq("1") - ).sqrt(), std::runtime_error); - - ASSERT_THROW(curve_Fq2( - curve_Fq("3345897230485723946872934576923485762803457692345760237495682347502347589473"), - curve_Fq("1234912378405347958234756902345768290345762348957605678245967234857634857676") - ).sqrt(), std::runtime_error); - - curve_Fq2 x = curve_Fq2( - curve_Fq("12844195307879678418043983815760255909500142247603239203345049921980497041944"), - curve_Fq("7476417578426924565731404322659619974551724117137577781074613937423560117731") - ); - - curve_Fq2 nx = -x; - - curve_Fq2 x2 = curve_Fq2( - curve_Fq("3345897230485723946872934576923485762803457692345760237495682347502347589474"), - curve_Fq("1234912378405347958234756902345768290345762348957605678245967234857634857676") - ); - - ASSERT_TRUE(x == x2.sqrt()); - ASSERT_TRUE(nx == -x2.sqrt()); - ASSERT_TRUE(x*x == x2); - ASSERT_TRUE(nx*nx == x2); -} - -TEST(proofs, size_is_expected) -{ - PHGRProof p; - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << p; - - ASSERT_EQ(ss.size(), 296); -} - -TEST(proofs, fq_serializes_properly) -{ - for (size_t i = 0; i < 1000; i++) { - curve_Fq e = curve_Fq::random_element(); - - Fq e2(e); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << e2; - - Fq e3; - ss >> e3; - - curve_Fq e4 = e3.to_libsnark_fq(); - - ASSERT_TRUE(e == e4); - } -} - -TEST(proofs, fq2_serializes_properly) -{ - for (size_t i = 0; i < 1000; i++) { - curve_Fq2 e = curve_Fq2::random_element(); - - Fq2 e2(e); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << e2; - - Fq2 e3; - ss >> e3; - - curve_Fq2 e4 = e3.to_libsnark_fq2(); - - ASSERT_TRUE(e == e4); - } -} - -template -T deserialize_tv(std::string s) -{ - T e; - CDataStream ss(ParseHex(s), SER_NETWORK, PROTOCOL_VERSION); - ss >> e; - - return e; -} - -curve_Fq deserialize_fq(std::string s) -{ - return deserialize_tv(s).to_libsnark_fq(); -} - -curve_Fq2 deserialize_fq2(std::string s) -{ - return deserialize_tv(s).to_libsnark_fq2(); -} - -TEST(proofs, fq_valid) -{ - curve_Fq e = deserialize_fq("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"); - - ASSERT_TRUE(e == curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582")); - ASSERT_TRUE(e != curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208581")); - - curve_Fq e2 = deserialize_fq("30644e72e131a029b75045b68181585d97816a916871ca8d3c208c16d87cfd46"); - - ASSERT_TRUE(e2 == curve_Fq("21888242871839275222221885816603420866962577604863418715751138068690288573766")); -} - -TEST(proofs, fq_invalid) -{ - // Should not be able to deserialize the modulus - ASSERT_THROW( - deserialize_fq("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"), - std::logic_error - ); - - // Should not be able to deserialize the modulus plus one - ASSERT_THROW( - deserialize_fq("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd48"), - std::logic_error - ); - - // Should not be able to deserialize a ridiculously out of bound int - ASSERT_THROW( - deserialize_fq("ff644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), - std::logic_error - ); -} - -TEST(proofs, fq2_valid) -{ - // (q - 1) * q + q - curve_Fq2 e = deserialize_fq2("0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b0"); - ASSERT_TRUE(e.c0 == curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582")); - ASSERT_TRUE(e.c1 == curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582")); - - curve_Fq2 e2 = deserialize_fq2("000000000000000000000000000000000000000000000000010245be1c91e3186bbbe1c430a93fcfc5aada4ab10c3492f70eea97a91c7b29554db55acffa34d2"); - ASSERT_TRUE(e2.c0 == curve_Fq("238769481237490823")); - ASSERT_TRUE(e2.c1 == curve_Fq("384579238459723485")); - - curve_Fq2 e3 = deserialize_fq2("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); - ASSERT_TRUE(e3.c0 == curve_Fq("0")); - ASSERT_TRUE(e3.c1 == curve_Fq("0")); - - curve_Fq2 e4 = deserialize_fq2("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"); - ASSERT_TRUE(e4.c0 == curve_Fq("1")); - ASSERT_TRUE(e4.c1 == curve_Fq("0")); -} - -TEST(proofs, fq2_invalid) -{ - // (q - 1) * q + q is invalid - ASSERT_THROW( - deserialize_fq2("0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b1"), - std::logic_error - ); - - // q * q + (q - 1) is invalid - ASSERT_THROW( - deserialize_fq2("0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d34cced085b43e2f202a05e52ef18233a3d8371be725c8b8e7774e4b8ffda66f7"), - std::logic_error - ); - - // Ridiculously out of bounds - ASSERT_THROW( - deserialize_fq2("0fffc4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b0"), - std::logic_error - ); - ASSERT_THROW( - deserialize_fq2("ffffffff763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b0"), - std::logic_error - ); -} - -TEST(proofs, g1_serializes_properly) -{ - // Cannot serialize zero - { - ASSERT_THROW({CompressedG1 g = CompressedG1(curve_G1::zero());}, std::domain_error); - } - - for (size_t i = 0; i < 1000; i++) { - curve_G1 e = curve_G1::random_element(); - - CompressedG1 e2(e); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << e2; - - CompressedG1 e3; - ss >> e3; - - ASSERT_TRUE(e2 == e3); - - curve_G1 e4 = e3.to_libsnark_g1(); - - ASSERT_TRUE(e == e4); - } -} - -TEST(proofs, g2_serializes_properly) -{ - // Cannot serialize zero - { - ASSERT_THROW({CompressedG2 g = CompressedG2(curve_G2::zero());}, std::domain_error); - } - - for (size_t i = 0; i < 1000; i++) { - curve_G2 e = curve_G2::random_element(); - - CompressedG2 e2(e); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << e2; - - CompressedG2 e3; - ss >> e3; - - ASSERT_TRUE(e2 == e3); - - curve_G2 e4 = e3.to_libsnark_g2(); - - ASSERT_TRUE(e == e4); - } -} - -TEST(proofs, zksnark_serializes_properly) -{ - auto example = libsnark::generate_r1cs_example_with_field_input(250, 4); - example.constraint_system.swap_AB_if_beneficial(); - auto kp = libsnark::r1cs_ppzksnark_generator(example.constraint_system); - auto vkprecomp = libsnark::r1cs_ppzksnark_verifier_process_vk(kp.vk); - - for (size_t i = 0; i < 20; i++) { - auto badproof = PHGRProof::random_invalid(); - auto proof = badproof.to_libsnark_proof>(); - - auto verifierEnabled = ProofVerifier::Strict(); - auto verifierDisabled = ProofVerifier::Disabled(); - // This verifier should catch the bad proof - ASSERT_FALSE(verifierEnabled.check( - kp.vk, - vkprecomp, - example.primary_input, - proof - )); - // This verifier won't! - ASSERT_TRUE(verifierDisabled.check( - kp.vk, - vkprecomp, - example.primary_input, - proof - )); - } - - for (size_t i = 0; i < 20; i++) { - auto proof = libsnark::r1cs_ppzksnark_prover( - kp.pk, - example.primary_input, - example.auxiliary_input, - example.constraint_system - ); - - { - auto verifierEnabled = ProofVerifier::Strict(); - auto verifierDisabled = ProofVerifier::Disabled(); - ASSERT_TRUE(verifierEnabled.check( - kp.vk, - vkprecomp, - example.primary_input, - proof - )); - ASSERT_TRUE(verifierDisabled.check( - kp.vk, - vkprecomp, - example.primary_input, - proof - )); - } - - ASSERT_TRUE(libsnark::r1cs_ppzksnark_verifier_strong_IC( - kp.vk, - example.primary_input, - proof - )); - - PHGRProof compressed_proof_0(proof); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << compressed_proof_0; - - PHGRProof compressed_proof_1; - ss >> compressed_proof_1; - - ASSERT_TRUE(compressed_proof_0 == compressed_proof_1); - - auto newproof = compressed_proof_1.to_libsnark_proof>(); - - ASSERT_TRUE(proof == newproof); - ASSERT_TRUE(libsnark::r1cs_ppzksnark_verifier_strong_IC( - kp.vk, - example.primary_input, - newproof - )); - } -} - -TEST(proofs, g1_deserialization) -{ - CompressedG1 g; - curve_G1 expected; - - // Valid G1 element. - { - CDataStream ss(ParseHex("0230644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - expected.X = curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - expected.Y = curve_Fq("3969792565221544645472939191694882283483352126195956956354061729942568608776"); - expected.Z = curve_Fq::one(); - - ASSERT_TRUE(g.to_libsnark_g1() == expected); - } - - // Its negation. - { - CDataStream ss(ParseHex("0330644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - expected.X = curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - expected.Y = curve_Fq("3969792565221544645472939191694882283483352126195956956354061729942568608776"); - expected.Z = curve_Fq::one(); - - ASSERT_TRUE(g.to_libsnark_g1() == -expected); - } - - // Invalid leading bytes - { - CDataStream ss(ParseHex("ff30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), SER_NETWORK, PROTOCOL_VERSION); - - ASSERT_THROW(ss >> g, std::ios_base::failure); - } - - // Invalid point - { - CDataStream ss(ParseHex("0208c6d2adffacbc8438f09f321874ea66e2fcc29f8dcfec2caefa21ec8c96a77c"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - ASSERT_THROW(g.to_libsnark_g1(), std::runtime_error); - } - - // Point with out of bounds Fq - { - CDataStream ss(ParseHex("02ffc6d2adffacbc8438f09f321874ea66e2fcc29f8dcfec2caefa21ec8c96a77c"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - ASSERT_THROW(g.to_libsnark_g1(), std::logic_error); - } - - // Randomly produce valid G1 representations and fail/succeed to - // turn them into G1 points based on whether they are valid. - for (size_t i = 0; i < 5000; i++) { - curve_Fq e = curve_Fq::random_element(); - CDataStream ss(ParseHex("02"), SER_NETWORK, PROTOCOL_VERSION); - ss << Fq(e); - CompressedG1 g; - ss >> g; - - try { - curve_G1 g_real = g.to_libsnark_g1(); - } catch(...) { - - } - } -} - -TEST(proofs, g2_deserialization) -{ - CompressedG2 g; - curve_G2 expected = curve_G2::random_element(); - - // Valid G2 point - { - CDataStream ss(ParseHex("0a023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - expected.X = curve_Fq2( - curve_Fq("5923585509243758863255447226263146374209884951848029582715967108651637186684"), - curve_Fq("5336385337059958111259504403491065820971993066694750945459110579338490853570") - ); - expected.Y = curve_Fq2( - curve_Fq("10374495865873200088116930399159835104695426846400310764827677226300185211748"), - curve_Fq("5256529835065685814318509161957442385362539991735248614869838648137856366932") - ); - expected.Z = curve_Fq2::one(); - - ASSERT_TRUE(g.to_libsnark_g2() == expected); - } - - // Its negation - { - CDataStream ss(ParseHex("0b023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - expected.X = curve_Fq2( - curve_Fq("5923585509243758863255447226263146374209884951848029582715967108651637186684"), - curve_Fq("5336385337059958111259504403491065820971993066694750945459110579338490853570") - ); - expected.Y = curve_Fq2( - curve_Fq("10374495865873200088116930399159835104695426846400310764827677226300185211748"), - curve_Fq("5256529835065685814318509161957442385362539991735248614869838648137856366932") - ); - expected.Z = curve_Fq2::one(); - - ASSERT_TRUE(g.to_libsnark_g2() == -expected); - } - - // Invalid leading bytes - { - CDataStream ss(ParseHex("ff023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION); - - ASSERT_THROW(ss >> g, std::ios_base::failure); - } - - - // Invalid point - { - CDataStream ss(ParseHex("0b023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984b"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - ASSERT_THROW(g.to_libsnark_g2(), std::runtime_error); - } - - // Point with out of bounds Fq2 - { - CDataStream ss(ParseHex("0a0f3aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - ASSERT_THROW(g.to_libsnark_g2(), std::logic_error); - } - - // Randomly produce valid G2 representations and fail/succeed to - // turn them into G2 points based on whether they are valid. - for (size_t i = 0; i < 5000; i++) { - curve_Fq2 e = curve_Fq2::random_element(); - CDataStream ss(ParseHex("0a"), SER_NETWORK, PROTOCOL_VERSION); - ss << Fq2(e); - CompressedG2 g; - ss >> g; - - try { - curve_G2 g_real = g.to_libsnark_g2(); - } catch(...) { - - } - } -} - -#include "json_test_vectors.h" -#include "test/data/g1_compressed.json.h" - -TEST(proofs, g1_test_vectors) -{ - UniValue v = read_json(std::string(json_tests::g1_compressed, json_tests::g1_compressed + sizeof(json_tests::g1_compressed))); - - curve_G1 e = curve_Fr("34958239045823") * curve_G1::one(); - for (size_t i = 0; i < 10000; i++) { - e = (curve_Fr("34958239045823") ^ i) * e; - auto expected = CompressedG1(e); - - expect_test_vector(v[i], expected); - ASSERT_TRUE(expected.to_libsnark_g1() == e); - } -} - -#include "test/data/g2_compressed.json.h" - -TEST(proofs, g2_test_vectors) -{ - UniValue v = read_json(std::string(json_tests::g2_compressed, json_tests::g2_compressed + sizeof(json_tests::g2_compressed))); - - curve_G2 e = curve_Fr("34958239045823") * curve_G2::one(); - for (size_t i = 0; i < 10000; i++) { - e = (curve_Fr("34958239045823") ^ i) * e; - auto expected = CompressedG2(e); - - expect_test_vector(v[i], expected); - ASSERT_TRUE(expected.to_libsnark_g2() == e); - } -} diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index e83a519b1..2bc7b48c6 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/zcash/CreateJoinSplit.cpp b/src/zcash/CreateJoinSplit.cpp deleted file mode 100644 index 06b76bb9b..000000000 --- a/src/zcash/CreateJoinSplit.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2016 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "../util.h" -#include "primitives/transaction.h" -#include "zcash/JoinSplit.hpp" - -#include "libsnark/common/profiling.hpp" -#include "komodo_defs.h" -char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -uint16_t BITCOIND_RPCPORT = 7771; -uint32_t ASSETCHAINS_CC = 0; - -using namespace libzcash; - -int main(int argc, char **argv) -{ - libsnark::start_profiling(); - - auto p = ZCJoinSplit::Prepared((ZC_GetParamsDir() / "sprout-verifying.key").string(), - (ZC_GetParamsDir() / "sprout-proving.key").string()); - - // construct a proof. - - for (int i = 0; i < 5; i++) { - uint256 anchor = ZCIncrementalMerkleTree().root(); - uint256 pubKeyHash; - - JSDescription jsdesc(*p, - pubKeyHash, - anchor, - {JSInput(), JSInput()}, - {JSOutput(), JSOutput()}, - 0, - 0); - } - - delete p; // not that it matters -} diff --git a/src/zcash/GenerateParams.cpp b/src/zcash/GenerateParams.cpp deleted file mode 100644 index 94f1c73c1..000000000 --- a/src/zcash/GenerateParams.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "zcash/JoinSplit.hpp" - -#include -#include "crypto/common.h" - -int64_t MAX_MONEY = 200000000 * 100000000LL; - -int main(int argc, char **argv) -{ - if (init_and_check_sodium() == -1) { - return 1; - } - - if(argc != 4) { - std::cerr << "Usage: " << argv[0] << " provingKeyFileName verificationKeyFileName r1csFileName" << std::endl; - return 1; - } - - std::string pkFile = argv[1]; - std::string vkFile = argv[2]; - std::string r1csFile = argv[3]; - - ZCJoinSplit::Generate(r1csFile, vkFile, pkFile); - - return 0; -} diff --git a/src/zcash/IncrementalMerkleTree.cpp b/src/zcash/IncrementalMerkleTree.cpp index f8d5fad61..b8b3cd183 100644 --- a/src/zcash/IncrementalMerkleTree.cpp +++ b/src/zcash/IncrementalMerkleTree.cpp @@ -35,6 +35,391 @@ PedersenHash PedersenHash::uncommitted() { return res; } +static const std::array pedersen_empty_roots = { + uint256(std::vector{ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }), + uint256(std::vector{ + 0x81, 0x7d, 0xe3, 0x6a, 0xb2, 0xd5, 0x7f, 0xeb, + 0x07, 0x76, 0x34, 0xbc, 0xa7, 0x78, 0x19, 0xc8, + 0xe0, 0xbd, 0x29, 0x8c, 0x04, 0xf6, 0xfe, 0xd0, + 0xe6, 0xa8, 0x3c, 0xc1, 0x35, 0x6c, 0xa1, 0x55, + }), + uint256(std::vector{ + 0xff, 0xe9, 0xfc, 0x03, 0xf1, 0x8b, 0x17, 0x6c, + 0x99, 0x88, 0x06, 0x43, 0x9f, 0xf0, 0xbb, 0x8a, + 0xd1, 0x93, 0xaf, 0xdb, 0x27, 0xb2, 0xcc, 0xbc, + 0x88, 0x85, 0x69, 0x16, 0xdd, 0x80, 0x4e, 0x34, + }), + uint256(std::vector{ + 0xd8, 0x28, 0x33, 0x86, 0xef, 0x2e, 0xf0, 0x7e, + 0xbd, 0xbb, 0x43, 0x83, 0xc1, 0x2a, 0x73, 0x9a, + 0x95, 0x3a, 0x4d, 0x6e, 0x0d, 0x6f, 0xb1, 0x13, + 0x9a, 0x40, 0x36, 0xd6, 0x93, 0xbf, 0xbb, 0x6c, + }), + uint256(std::vector{ + 0xe1, 0x10, 0xde, 0x65, 0xc9, 0x07, 0xb9, 0xde, + 0xa4, 0xae, 0x0b, 0xd8, 0x3a, 0x4b, 0x0a, 0x51, + 0xbe, 0xa1, 0x75, 0x64, 0x6a, 0x64, 0xc1, 0x2b, + 0x4c, 0x9f, 0x93, 0x1b, 0x2c, 0xb3, 0x1b, 0x49, + }), + uint256(std::vector{ + 0x91, 0x2d, 0x82, 0xb2, 0xc2, 0xbc, 0xa2, 0x31, + 0xf7, 0x1e, 0xfc, 0xf6, 0x17, 0x37, 0xfb, 0xf0, + 0xa0, 0x8b, 0xef, 0xa0, 0x41, 0x62, 0x15, 0xae, + 0xef, 0x53, 0xe8, 0xbb, 0x6d, 0x23, 0x39, 0x0a, + }), + uint256(std::vector{ + 0x8a, 0xc9, 0xcf, 0x9c, 0x39, 0x1e, 0x3f, 0xd4, + 0x28, 0x91, 0xd2, 0x72, 0x38, 0xa8, 0x1a, 0x8a, + 0x5c, 0x1d, 0x3a, 0x72, 0xb1, 0xbc, 0xbe, 0xa8, + 0xcf, 0x44, 0xa5, 0x8c, 0xe7, 0x38, 0x96, 0x13, + }), + uint256(std::vector{ + 0xd6, 0xc6, 0x39, 0xac, 0x24, 0xb4, 0x6b, 0xd1, + 0x93, 0x41, 0xc9, 0x1b, 0x13, 0xfd, 0xca, 0xb3, + 0x15, 0x81, 0xdd, 0xaf, 0x7f, 0x14, 0x11, 0x33, + 0x6a, 0x27, 0x1f, 0x3d, 0x0a, 0xa5, 0x28, 0x13, + }), + uint256(std::vector{ + 0x7b, 0x99, 0xab, 0xdc, 0x37, 0x30, 0x99, 0x1c, + 0xc9, 0x27, 0x47, 0x27, 0xd7, 0xd8, 0x2d, 0x28, + 0xcb, 0x79, 0x4e, 0xdb, 0xc7, 0x03, 0x4b, 0x4f, + 0x00, 0x53, 0xff, 0x7c, 0x4b, 0x68, 0x04, 0x44, + }), + uint256(std::vector{ + 0x43, 0xff, 0x54, 0x57, 0xf1, 0x3b, 0x92, 0x6b, + 0x61, 0xdf, 0x55, 0x2d, 0x4e, 0x40, 0x2e, 0xe6, + 0xdc, 0x14, 0x63, 0xf9, 0x9a, 0x53, 0x5f, 0x9a, + 0x71, 0x34, 0x39, 0x26, 0x4d, 0x5b, 0x61, 0x6b, + }), + uint256(std::vector{ + 0xba, 0x49, 0xb6, 0x59, 0xfb, 0xd0, 0xb7, 0x33, + 0x42, 0x11, 0xea, 0x6a, 0x9d, 0x9d, 0xf1, 0x85, + 0xc7, 0x57, 0xe7, 0x0a, 0xa8, 0x1d, 0xa5, 0x62, + 0xfb, 0x91, 0x2b, 0x84, 0xf4, 0x9b, 0xce, 0x72, + }), + uint256(std::vector{ + 0x47, 0x77, 0xc8, 0x77, 0x6a, 0x3b, 0x1e, 0x69, + 0xb7, 0x3a, 0x62, 0xfa, 0x70, 0x1f, 0xa4, 0xf7, + 0xa6, 0x28, 0x2d, 0x9a, 0xee, 0x2c, 0x7a, 0x6b, + 0x82, 0xe7, 0x93, 0x7d, 0x70, 0x81, 0xc2, 0x3c, + }), + uint256(std::vector{ + 0xec, 0x67, 0x71, 0x14, 0xc2, 0x72, 0x06, 0xf5, + 0xde, 0xbc, 0x1c, 0x1e, 0xd6, 0x6f, 0x95, 0xe2, + 0xb1, 0x88, 0x5d, 0xa5, 0xb7, 0xbe, 0x3d, 0x73, + 0x6b, 0x1d, 0xe9, 0x85, 0x79, 0x47, 0x30, 0x48, + }), + uint256(std::vector{ + 0x1b, 0x77, 0xda, 0xc4, 0xd2, 0x4f, 0xb7, 0x25, + 0x8c, 0x3c, 0x52, 0x87, 0x04, 0xc5, 0x94, 0x30, + 0xb6, 0x30, 0x71, 0x8b, 0xec, 0x48, 0x64, 0x21, + 0x83, 0x70, 0x21, 0xcf, 0x75, 0xda, 0xb6, 0x51, + }), + uint256(std::vector{ + 0xbd, 0x74, 0xb2, 0x5a, 0xac, 0xb9, 0x23, 0x78, + 0xa8, 0x71, 0xbf, 0x27, 0xd2, 0x25, 0xcf, 0xc2, + 0x6b, 0xac, 0xa3, 0x44, 0xa1, 0xea, 0x35, 0xfd, + 0xd9, 0x45, 0x10, 0xf3, 0xd1, 0x57, 0x08, 0x2c, + }), + uint256(std::vector{ + 0xd6, 0xac, 0xde, 0xdf, 0x95, 0xf6, 0x08, 0xe0, + 0x9f, 0xa5, 0x3f, 0xb4, 0x3d, 0xcd, 0x09, 0x90, + 0x47, 0x57, 0x26, 0xc5, 0x13, 0x12, 0x10, 0xc9, + 0xe5, 0xca, 0xea, 0xb9, 0x7f, 0x0e, 0x64, 0x2f, + }), + uint256(std::vector{ + 0x1e, 0xa6, 0x67, 0x5f, 0x95, 0x51, 0xee, 0xb9, + 0xdf, 0xaa, 0xa9, 0x24, 0x7b, 0xc9, 0x85, 0x82, + 0x70, 0xd3, 0xd3, 0xa4, 0xc5, 0xaf, 0xa7, 0x17, + 0x7a, 0x98, 0x4d, 0x5e, 0xd1, 0xbe, 0x24, 0x51, + }), + uint256(std::vector{ + 0x6e, 0xdb, 0x16, 0xd0, 0x19, 0x07, 0xb7, 0x59, + 0x97, 0x7d, 0x76, 0x50, 0xda, 0xd7, 0xe3, 0xec, + 0x04, 0x9a, 0xf1, 0xa3, 0xd8, 0x75, 0x38, 0x0b, + 0x69, 0x7c, 0x86, 0x2c, 0x9e, 0xc5, 0xd5, 0x1c, + }), + uint256(std::vector{ + 0xcd, 0x1c, 0x8d, 0xbf, 0x6e, 0x3a, 0xcc, 0x7a, + 0x80, 0x43, 0x9b, 0xc4, 0x96, 0x2c, 0xf2, 0x5b, + 0x9d, 0xce, 0x7c, 0x89, 0x6f, 0x3a, 0x5b, 0xd7, + 0x08, 0x03, 0xfc, 0x5a, 0x0e, 0x33, 0xcf, 0x00, + }), + uint256(std::vector{ + 0x6a, 0xca, 0x84, 0x48, 0xd8, 0x26, 0x3e, 0x54, + 0x7d, 0x5f, 0xf2, 0x95, 0x0e, 0x2e, 0xd3, 0x83, + 0x9e, 0x99, 0x8d, 0x31, 0xcb, 0xc6, 0xac, 0x9f, + 0xd5, 0x7b, 0xc6, 0x00, 0x2b, 0x15, 0x92, 0x16, + }), + uint256(std::vector{ + 0x8d, 0x5f, 0xa4, 0x3e, 0x5a, 0x10, 0xd1, 0x16, + 0x05, 0xac, 0x74, 0x30, 0xba, 0x1f, 0x5d, 0x81, + 0xfb, 0x1b, 0x68, 0xd2, 0x9a, 0x64, 0x04, 0x05, + 0x76, 0x77, 0x49, 0xe8, 0x41, 0x52, 0x76, 0x73, + }), + uint256(std::vector{ + 0x08, 0xee, 0xab, 0x0c, 0x13, 0xab, 0xd6, 0x06, + 0x9e, 0x63, 0x10, 0x19, 0x7b, 0xf8, 0x0f, 0x9c, + 0x1e, 0xa6, 0xde, 0x78, 0xfd, 0x19, 0xcb, 0xae, + 0x24, 0xd4, 0xa5, 0x20, 0xe6, 0xcf, 0x30, 0x23, + }), + uint256(std::vector{ + 0x07, 0x69, 0x55, 0x7b, 0xc6, 0x82, 0xb1, 0xbf, + 0x30, 0x86, 0x46, 0xfd, 0x0b, 0x22, 0xe6, 0x48, + 0xe8, 0xb9, 0xe9, 0x8f, 0x57, 0xe2, 0x9f, 0x5a, + 0xf4, 0x0f, 0x6e, 0xdb, 0x83, 0x3e, 0x2c, 0x49, + }), + uint256(std::vector{ + 0x4c, 0x69, 0x37, 0xd7, 0x8f, 0x42, 0x68, 0x5f, + 0x84, 0xb4, 0x3a, 0xd3, 0xb7, 0xb0, 0x0f, 0x81, + 0x28, 0x56, 0x62, 0xf8, 0x5c, 0x6a, 0x68, 0xef, + 0x11, 0xd6, 0x2a, 0xd1, 0xa3, 0xee, 0x08, 0x50, + }), + uint256(std::vector{ + 0xfe, 0xe0, 0xe5, 0x28, 0x02, 0xcb, 0x0c, 0x46, + 0xb1, 0xeb, 0x4d, 0x37, 0x6c, 0x62, 0x69, 0x7f, + 0x47, 0x59, 0xf6, 0xc8, 0x91, 0x7f, 0xa3, 0x52, + 0x57, 0x12, 0x02, 0xfd, 0x77, 0x8f, 0xd7, 0x12, + }), + uint256(std::vector{ + 0x16, 0xd6, 0x25, 0x29, 0x68, 0x97, 0x1a, 0x83, + 0xda, 0x85, 0x21, 0xd6, 0x53, 0x82, 0xe6, 0x1f, + 0x01, 0x76, 0x64, 0x6d, 0x77, 0x1c, 0x91, 0x52, + 0x8e, 0x32, 0x76, 0xee, 0x45, 0x38, 0x3e, 0x4a, + }), + uint256(std::vector{ + 0xd2, 0xe1, 0x64, 0x2c, 0x9a, 0x46, 0x22, 0x29, + 0x28, 0x9e, 0x5b, 0x0e, 0x3b, 0x7f, 0x90, 0x08, + 0xe0, 0x30, 0x1c, 0xbb, 0x93, 0x38, 0x5e, 0xe0, + 0xe2, 0x1d, 0xa2, 0x54, 0x50, 0x73, 0xcb, 0x58, + }), + uint256(std::vector{ + 0xa5, 0x12, 0x2c, 0x08, 0xff, 0x9c, 0x16, 0x1d, + 0x9c, 0xa6, 0xfc, 0x46, 0x20, 0x73, 0x39, 0x6c, + 0x7d, 0x7d, 0x38, 0xe8, 0xee, 0x48, 0xcd, 0xb3, + 0xbe, 0xa7, 0xe2, 0x23, 0x01, 0x34, 0xed, 0x6a, + }), + uint256(std::vector{ + 0x28, 0xe7, 0xb8, 0x41, 0xdc, 0xbc, 0x47, 0xcc, + 0xeb, 0x69, 0xd7, 0xcb, 0x8d, 0x94, 0x24, 0x5f, + 0xb7, 0xcb, 0x2b, 0xa3, 0xa7, 0xa6, 0xbc, 0x18, + 0xf1, 0x3f, 0x94, 0x5f, 0x7d, 0xbd, 0x6e, 0x2a, + }), + uint256(std::vector{ + 0xe1, 0xf3, 0x4b, 0x03, 0x4d, 0x4a, 0x3c, 0xd2, + 0x85, 0x57, 0xe2, 0x90, 0x7e, 0xbf, 0x99, 0x0c, + 0x91, 0x8f, 0x64, 0xec, 0xb5, 0x0a, 0x94, 0xf0, + 0x1d, 0x6f, 0xda, 0x5c, 0xa5, 0xc7, 0xef, 0x72, + }), + uint256(std::vector{ + 0x12, 0x93, 0x5f, 0x14, 0xb6, 0x76, 0x50, 0x9b, + 0x81, 0xeb, 0x49, 0xef, 0x25, 0xf3, 0x92, 0x69, + 0xed, 0x72, 0x30, 0x92, 0x38, 0xb4, 0xc1, 0x45, + 0x80, 0x35, 0x44, 0xb6, 0x46, 0xdc, 0xa6, 0x2d, + }), + uint256(std::vector{ + 0xb2, 0xee, 0xd0, 0x31, 0xd4, 0xd6, 0xa4, 0xf0, + 0x2a, 0x09, 0x7f, 0x80, 0xb5, 0x4c, 0xc1, 0x54, + 0x1d, 0x41, 0x63, 0xc6, 0xb6, 0xf5, 0x97, 0x1f, + 0x88, 0xb6, 0xe4, 0x1d, 0x35, 0xc5, 0x38, 0x14, + }), + uint256(std::vector{ + 0xfb, 0xc2, 0xf4, 0x30, 0x0c, 0x01, 0xf0, 0xb7, + 0x82, 0x0d, 0x00, 0xe3, 0x34, 0x7c, 0x8d, 0xa4, + 0xee, 0x61, 0x46, 0x74, 0x37, 0x6c, 0xbc, 0x45, + 0x35, 0x9d, 0xaa, 0x54, 0xf9, 0xb5, 0x49, 0x3e, + }), + uint256(std::vector{ + 0x25, 0x2e, 0x67, 0x98, 0x64, 0x5f, 0x5b, 0xf1, + 0x14, 0xe4, 0xb4, 0xe9, 0x0e, 0x96, 0x18, 0x28, + 0x61, 0x48, 0x98, 0x40, 0xd9, 0xb4, 0xcc, 0xc4, + 0xc1, 0xfb, 0x5a, 0x46, 0x99, 0x7c, 0xee, 0x14, + }), + uint256(std::vector{ + 0x98, 0xb1, 0x90, 0x42, 0xf1, 0xf7, 0xc7, 0xdd, + 0x11, 0xec, 0x25, 0xea, 0x66, 0xb6, 0xff, 0x74, + 0xe0, 0x8c, 0xe1, 0x1d, 0x44, 0x7e, 0xd6, 0xf1, + 0xbf, 0xe8, 0x7e, 0x11, 0x0e, 0x33, 0x1e, 0x11, + }), + uint256(std::vector{ + 0xd4, 0x51, 0x30, 0x47, 0x99, 0x57, 0x2b, 0xa9, + 0xf4, 0x2c, 0x4d, 0xab, 0x6b, 0x07, 0xc7, 0x03, + 0xbd, 0x2c, 0x12, 0x3a, 0xb9, 0xd6, 0x0f, 0x2a, + 0x60, 0xf9, 0x95, 0x58, 0x54, 0x91, 0x0b, 0x6a, + }), + uint256(std::vector{ + 0x3e, 0xcd, 0x5f, 0x27, 0xac, 0xf0, 0x1b, 0xd3, + 0x7a, 0x33, 0xe4, 0x51, 0x78, 0x67, 0xef, 0x76, + 0x47, 0x4c, 0xd8, 0x3f, 0xb3, 0x1c, 0x92, 0x08, + 0xdc, 0xef, 0x2e, 0xed, 0xce, 0xf3, 0x6c, 0x72, + }), + uint256(std::vector{ + 0x26, 0xc3, 0x7d, 0xa6, 0x78, 0x94, 0xa1, 0x3d, + 0xf8, 0xaa, 0x48, 0x78, 0xd2, 0x51, 0x4a, 0x42, + 0x12, 0x57, 0x3b, 0x73, 0xec, 0xca, 0xab, 0x16, + 0xfe, 0x4f, 0xa6, 0x60, 0xe8, 0xfe, 0x27, 0x07, + }), + uint256(std::vector{ + 0xb5, 0x45, 0xef, 0x34, 0x48, 0x5e, 0xed, 0x30, + 0xd4, 0x2b, 0x2c, 0x29, 0x5a, 0x4a, 0x5b, 0x68, + 0x0d, 0xe8, 0xa9, 0xd5, 0xe3, 0x83, 0x45, 0x78, + 0x24, 0x62, 0xc0, 0x4f, 0x09, 0xdc, 0x68, 0x51, + }), + uint256(std::vector{ + 0x77, 0xfd, 0x20, 0xb3, 0x00, 0x94, 0x67, 0x65, + 0xa8, 0x7f, 0x24, 0xbd, 0x04, 0x50, 0x73, 0x72, + 0x9c, 0xbd, 0x7b, 0x66, 0xeb, 0x8f, 0xa1, 0x40, + 0xb5, 0x83, 0xfa, 0xa9, 0xd1, 0x42, 0x58, 0x01, + }), + uint256(std::vector{ + 0xcb, 0xaa, 0x57, 0x6b, 0x17, 0x99, 0xb5, 0x8f, + 0xf3, 0xa6, 0xde, 0xcb, 0xba, 0x91, 0x9b, 0x0b, + 0x68, 0xd7, 0xc8, 0x93, 0xe4, 0x6f, 0xde, 0x99, + 0x87, 0x68, 0xe8, 0x7e, 0x35, 0x0a, 0x07, 0x25, + }), + uint256(std::vector{ + 0x45, 0xfe, 0x81, 0xb1, 0x8c, 0xa3, 0x00, 0x74, + 0xd0, 0x12, 0x0d, 0x2b, 0x1a, 0x0d, 0x10, 0xb3, + 0xa0, 0x50, 0x93, 0x35, 0x12, 0xdb, 0x8e, 0xe3, + 0x4e, 0x52, 0x47, 0x3d, 0x4f, 0x08, 0xa2, 0x67, + }), + uint256(std::vector{ + 0x0e, 0x60, 0xa1, 0xf0, 0x12, 0x1f, 0x59, 0x1e, + 0x55, 0x1d, 0x3e, 0xd1, 0x86, 0x5b, 0x50, 0xa7, + 0x5d, 0x7c, 0xcf, 0xf1, 0x28, 0x9d, 0xf7, 0xc4, + 0x4d, 0xd4, 0x65, 0xa5, 0x43, 0x17, 0xf5, 0x6a, + }), + uint256(std::vector{ + 0xce, 0xdf, 0xb1, 0x84, 0xdd, 0x92, 0xa0, 0xcb, + 0xfc, 0x11, 0xe8, 0xbe, 0x69, 0x7b, 0x47, 0x69, + 0x88, 0xed, 0x5f, 0x39, 0x36, 0x9a, 0xbd, 0xd9, + 0x0c, 0x61, 0x54, 0x49, 0x88, 0x60, 0x1c, 0x0d, + }), + uint256(std::vector{ + 0xf3, 0x62, 0x68, 0x66, 0x12, 0x64, 0x9a, 0x31, + 0x3b, 0xa4, 0x64, 0x43, 0x7a, 0x0c, 0xad, 0x0e, + 0x7e, 0x3d, 0x7e, 0x1b, 0x4b, 0x37, 0x43, 0xf9, + 0x0e, 0x05, 0xa2, 0x10, 0x0a, 0x49, 0x5f, 0x42, + }), + uint256(std::vector{ + 0x7d, 0xea, 0xe5, 0xf3, 0xbb, 0xde, 0xff, 0xd3, + 0xf8, 0x52, 0x71, 0xa0, 0x8b, 0x5e, 0xc3, 0x1f, + 0x16, 0xf9, 0x37, 0x96, 0x4a, 0xe7, 0x08, 0xfd, + 0xff, 0x7c, 0x13, 0xe5, 0xa4, 0xf3, 0xdf, 0x6b, + }), + uint256(std::vector{ + 0x40, 0xcc, 0xf0, 0xfc, 0x1e, 0xab, 0x6d, 0x85, + 0x02, 0xbd, 0x93, 0xdc, 0x31, 0x34, 0x2d, 0xfd, + 0x57, 0xdf, 0x5b, 0xbb, 0x5d, 0x70, 0xa1, 0xbf, + 0x6b, 0x92, 0xef, 0xc6, 0x1e, 0xc9, 0xa2, 0x58, + }), + uint256(std::vector{ + 0xd7, 0x80, 0x25, 0x49, 0x1f, 0x1b, 0xca, 0x85, + 0x07, 0xf6, 0x4f, 0x25, 0x87, 0x2d, 0xd0, 0x23, + 0x88, 0x47, 0x9a, 0x1a, 0x22, 0x51, 0x26, 0xe4, + 0x0d, 0x2f, 0xe4, 0x18, 0xb9, 0x8e, 0x0e, 0x2c, + }), + uint256(std::vector{ + 0x0d, 0xb7, 0x29, 0x46, 0x85, 0xc8, 0xa0, 0x72, + 0x5f, 0x15, 0x84, 0x6e, 0xa5, 0x89, 0x9e, 0xa0, + 0xe9, 0x86, 0xc2, 0x70, 0x7b, 0xd7, 0xb4, 0x12, + 0x95, 0x44, 0x12, 0xf2, 0x6a, 0xbf, 0x55, 0x0a, + }), + uint256(std::vector{ + 0xb7, 0xe2, 0x90, 0xbe, 0x95, 0x55, 0xcf, 0x75, + 0x54, 0x86, 0x50, 0xda, 0x6d, 0x47, 0xc8, 0x93, + 0xae, 0xf7, 0xf8, 0xc6, 0xdd, 0x27, 0x35, 0x49, + 0x94, 0x95, 0xf6, 0x36, 0x59, 0x0d, 0xae, 0x0a, + }), + uint256(std::vector{ + 0x2d, 0xd2, 0x53, 0x2a, 0x85, 0x8c, 0x30, 0x01, + 0x45, 0xa6, 0x5e, 0x35, 0x1f, 0x91, 0xbe, 0x6a, + 0xfe, 0xab, 0x59, 0x7c, 0x41, 0xef, 0x07, 0x3f, + 0x50, 0xb6, 0x22, 0xd5, 0x86, 0xff, 0x59, 0x27, + }), + uint256(std::vector{ + 0x97, 0x2f, 0x0c, 0x5c, 0x6f, 0x9a, 0xeb, 0x0e, + 0x38, 0xbf, 0x83, 0x19, 0xf3, 0xa5, 0xfc, 0xdc, + 0x8f, 0xd8, 0x78, 0x2e, 0x41, 0x88, 0x73, 0x0c, + 0xd0, 0x82, 0xd9, 0xba, 0xbc, 0x58, 0x98, 0x51, + }), + uint256(std::vector{ + 0x00, 0x1e, 0x57, 0x7b, 0x0f, 0x43, 0x90, 0x18, + 0x2b, 0x4a, 0xe4, 0x3d, 0x32, 0x9b, 0x3a, 0xa8, + 0x83, 0x5d, 0xae, 0x1b, 0xb7, 0x9e, 0x60, 0x4b, + 0x7d, 0x2d, 0xa0, 0xe9, 0x0d, 0x06, 0x09, 0x29, + }), + uint256(std::vector{ + 0xaa, 0x6e, 0x70, 0xa9, 0x1e, 0xbc, 0x54, 0xee, + 0xfc, 0xe5, 0xff, 0xd5, 0xb6, 0x75, 0xda, 0xf3, + 0xf1, 0xd9, 0x40, 0xa8, 0x45, 0x1f, 0xcb, 0x01, + 0x08, 0x1f, 0xa9, 0xd4, 0xf2, 0x62, 0x43, 0x6f, + }), + uint256(std::vector{ + 0xd7, 0x70, 0x38, 0xbf, 0x67, 0xe6, 0x31, 0x75, + 0x29, 0x40, 0x23, 0x12, 0x51, 0xd7, 0xfe, 0x85, + 0xaf, 0x52, 0xdb, 0xdd, 0x6a, 0xab, 0x37, 0xc7, + 0xa5, 0xec, 0x32, 0xb6, 0x5f, 0xe6, 0xde, 0x03, + }), + uint256(std::vector{ + 0xd2, 0x27, 0xa1, 0x7a, 0x7e, 0x0c, 0xf9, 0x6d, + 0xce, 0xdd, 0x9f, 0xc7, 0xbc, 0xe4, 0x3c, 0x6c, + 0x1d, 0x66, 0xba, 0xdd, 0x75, 0x43, 0xa8, 0x87, + 0xc8, 0x65, 0x6c, 0x54, 0x7e, 0xcf, 0xb2, 0x4f, + }), + uint256(std::vector{ + 0x70, 0xe8, 0xa5, 0x21, 0x95, 0x15, 0x83, 0xe5, + 0x3f, 0xc0, 0x58, 0x5c, 0x70, 0x7e, 0xce, 0xda, + 0x89, 0xb7, 0xa7, 0xd1, 0xaf, 0x41, 0xd1, 0xa0, + 0x15, 0xd7, 0x97, 0xfa, 0x76, 0xc0, 0xf5, 0x69, + }), + uint256(std::vector{ + 0xe4, 0x85, 0xa9, 0x68, 0x55, 0xe8, 0x72, 0xfc, + 0x50, 0x90, 0x15, 0x0e, 0x2c, 0xd2, 0x4e, 0x10, + 0x59, 0x1d, 0x35, 0x16, 0x6e, 0xb0, 0xeb, 0x30, + 0xfc, 0xdf, 0xac, 0x93, 0xb0, 0x1d, 0x28, 0x1c, + }), + uint256(std::vector{ + 0xe4, 0xa1, 0x9f, 0xeb, 0xdf, 0x2a, 0x86, 0x89, + 0x6e, 0x41, 0xf2, 0xce, 0xdc, 0xf2, 0xae, 0x58, + 0x46, 0x71, 0x80, 0x2e, 0x6a, 0x46, 0x7e, 0x84, + 0x39, 0xca, 0xb5, 0xd6, 0x18, 0x43, 0x41, 0x6b, + }), + uint256(std::vector{ + 0xe9, 0x27, 0x83, 0x88, 0x47, 0x80, 0x6a, 0x43, + 0xbd, 0x6c, 0x60, 0x88, 0xe3, 0x9f, 0x65, 0xb8, + 0xb3, 0xe5, 0x8b, 0x2d, 0xb5, 0xf7, 0xad, 0x56, + 0x43, 0xd9, 0x1e, 0x06, 0x59, 0xa2, 0x8a, 0x2a, + }), + uint256(std::vector{ + 0x0b, 0xd3, 0xa8, 0x18, 0xe8, 0x3f, 0x9c, 0xd2, + 0xff, 0x4f, 0x62, 0x01, 0x1a, 0x51, 0x01, 0x76, + 0xac, 0x32, 0xf5, 0x44, 0x8e, 0x6e, 0x15, 0x45, + 0x15, 0x04, 0x3c, 0x59, 0x26, 0xd5, 0x1c, 0x6f, + }), + uint256(std::vector{ + 0xce, 0x41, 0x34, 0x45, 0xe0, 0x37, 0x90, 0x49, + 0x8f, 0xe7, 0x2d, 0x8e, 0x01, 0x91, 0x5e, 0x7f, + 0xf1, 0x20, 0xae, 0x35, 0xb3, 0xb5, 0x90, 0xd2, + 0x1b, 0x7f, 0x74, 0xde, 0xe1, 0x83, 0x0f, 0x0d, + }), + uint256(std::vector{ + 0x60, 0x0e, 0x6f, 0x93, 0xe7, 0x3d, 0x7a, 0xbd, + 0x4e, 0xe0, 0xa6, 0x5c, 0xb1, 0xb1, 0x9a, 0xa3, + 0xec, 0xc5, 0x25, 0x68, 0x9d, 0xbf, 0x17, 0x77, + 0x96, 0x58, 0x74, 0x1b, 0x95, 0xc1, 0x5a, 0x55, + }), +}; + +PedersenHash PedersenHash::EmptyRoot(size_t depth) { + return pedersen_empty_roots.at(depth); +} + SHA256Compress SHA256Compress::combine( const SHA256Compress& a, const SHA256Compress& b, @@ -51,6 +436,409 @@ SHA256Compress SHA256Compress::combine( return res; } +static const std::array sha256_empty_roots = { + uint256(std::vector{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }), + uint256(std::vector{ + 0xda, 0x56, 0x98, 0xbe, 0x17, 0xb9, 0xb4, 0x69, + 0x62, 0x33, 0x57, 0x99, 0x77, 0x9f, 0xbe, 0xca, + 0x8c, 0xe5, 0xd4, 0x91, 0xc0, 0xd2, 0x62, 0x43, + 0xba, 0xfe, 0xf9, 0xea, 0x18, 0x37, 0xa9, 0xd8, + }), + uint256(std::vector{ + 0xdc, 0x76, 0x6f, 0xab, 0x49, 0x2c, 0xcf, 0x3d, + 0x1e, 0x49, 0xd4, 0xf3, 0x74, 0xb5, 0x23, 0x5f, + 0xa5, 0x65, 0x06, 0xaa, 0xc2, 0x22, 0x4d, 0x39, + 0xf9, 0x43, 0xfc, 0xd4, 0x92, 0x02, 0x97, 0x4c, + }), + uint256(std::vector{ + 0x3f, 0x0a, 0x40, 0x61, 0x81, 0x10, 0x59, 0x68, + 0xfd, 0xae, 0xe3, 0x06, 0x79, 0xe3, 0x27, 0x3c, + 0x66, 0xb7, 0x2b, 0xf9, 0xa7, 0xf5, 0xde, 0xbb, + 0xf3, 0xb5, 0xa0, 0xa2, 0x6e, 0x35, 0x9f, 0x92, + }), + uint256(std::vector{ + 0x26, 0xb0, 0x05, 0x26, 0x94, 0xfc, 0x42, 0xfd, + 0xff, 0x93, 0xe6, 0xfb, 0x5a, 0x71, 0xd3, 0x8c, + 0x3d, 0xd7, 0xdc, 0x5b, 0x6a, 0xd7, 0x10, 0xeb, + 0x04, 0x8c, 0x66, 0x02, 0x33, 0x13, 0x7f, 0xab, + }), + uint256(std::vector{ + 0x01, 0x09, 0xec, 0xc0, 0x72, 0x26, 0x59, 0xff, + 0x83, 0x45, 0x0b, 0x8f, 0x7b, 0x88, 0x46, 0xe6, + 0x7b, 0x28, 0x59, 0xf3, 0x3c, 0x30, 0xd9, 0xb7, + 0xac, 0xd5, 0xbf, 0x39, 0xca, 0xe5, 0x4e, 0x31, + }), + uint256(std::vector{ + 0x3f, 0x90, 0x9b, 0x8c, 0xe3, 0xd7, 0xff, 0xd8, + 0xa5, 0xb3, 0x09, 0x08, 0xf6, 0x05, 0xa0, 0x3b, + 0x0d, 0xb8, 0x51, 0x69, 0x55, 0x8d, 0xdc, 0x1d, + 0xa7, 0xbb, 0xbc, 0xc9, 0xb0, 0x9f, 0xd3, 0x25, + }), + uint256(std::vector{ + 0x40, 0x46, 0x0f, 0xa6, 0xbc, 0x69, 0x2a, 0x06, + 0xf4, 0x75, 0x21, 0xa6, 0x72, 0x5a, 0x54, 0x7c, + 0x02, 0x8a, 0x6a, 0x24, 0x0d, 0x84, 0x09, 0xf1, + 0x65, 0xe6, 0x3c, 0xb5, 0x4d, 0xa2, 0xd2, 0x3f, + }), + uint256(std::vector{ + 0x8c, 0x08, 0x56, 0x74, 0x24, 0x9b, 0x43, 0xda, + 0x1b, 0x9a, 0x31, 0xa0, 0xe8, 0x20, 0xe8, 0x1e, + 0x75, 0xf3, 0x42, 0x80, 0x7b, 0x03, 0xb6, 0xb9, + 0xe6, 0x49, 0x83, 0x21, 0x7b, 0xc2, 0xb3, 0x8e, + }), + uint256(std::vector{ + 0xa0, 0x83, 0x45, 0x0c, 0x1b, 0xa2, 0xa3, 0xa7, + 0xbe, 0x76, 0xfa, 0xd9, 0xd1, 0x3b, 0xc3, 0x7b, + 0xe4, 0xbf, 0x83, 0xbd, 0x3e, 0x59, 0xfc, 0x37, + 0x5a, 0x36, 0xba, 0x62, 0xdc, 0x62, 0x02, 0x98, + }), + uint256(std::vector{ + 0x1d, 0xdd, 0xda, 0xbc, 0x2c, 0xaa, 0x2d, 0xe9, + 0xef, 0xf9, 0xe1, 0x8c, 0x8c, 0x5a, 0x39, 0x40, + 0x6d, 0x79, 0x36, 0xe8, 0x89, 0xbc, 0x16, 0xcf, + 0xab, 0xb1, 0x44, 0xf5, 0xc0, 0x02, 0x26, 0x82, + }), + uint256(std::vector{ + 0xc2, 0x2d, 0x8f, 0x0b, 0x5e, 0x40, 0x56, 0xe5, + 0xf3, 0x18, 0xba, 0x22, 0x09, 0x1c, 0xc0, 0x7d, + 0xb5, 0x69, 0x4f, 0xbe, 0xb5, 0xe8, 0x7e, 0xf0, + 0xd7, 0xe2, 0xc5, 0x7c, 0xa3, 0x52, 0x35, 0x9e, + }), + uint256(std::vector{ + 0x89, 0xa4, 0x34, 0xae, 0x1f, 0xeb, 0xd7, 0x68, + 0x7e, 0xce, 0xea, 0x21, 0xd0, 0x7f, 0x20, 0xa2, + 0x51, 0x24, 0x49, 0xd0, 0x8c, 0xe2, 0xee, 0xe5, + 0x58, 0x71, 0xcd, 0xb9, 0xd4, 0x6c, 0x12, 0x33, + }), + uint256(std::vector{ + 0x73, 0x33, 0xdb, 0xff, 0xbd, 0x11, 0xf0, 0x92, + 0x47, 0xa2, 0xb3, 0x3a, 0x01, 0x3e, 0xc4, 0xc4, + 0x34, 0x20, 0x29, 0xd8, 0x51, 0xe2, 0x2b, 0xa4, + 0x85, 0xd4, 0x46, 0x18, 0x51, 0x37, 0x0c, 0x15, + }), + uint256(std::vector{ + 0x5d, 0xad, 0x84, 0x4a, 0xb9, 0x46, 0x6b, 0x70, + 0xf7, 0x45, 0x13, 0x71, 0x95, 0xca, 0x22, 0x1b, + 0x48, 0xf3, 0x46, 0xab, 0xd1, 0x45, 0xfb, 0x5e, + 0xfc, 0x23, 0xa8, 0xb4, 0xba, 0x50, 0x80, 0x22, + }), + uint256(std::vector{ + 0x50, 0x7e, 0x0d, 0xae, 0x81, 0xcb, 0xfb, 0xe4, + 0x57, 0xfd, 0x37, 0x0e, 0xf1, 0xca, 0x42, 0x01, + 0xc2, 0xb6, 0x40, 0x10, 0x83, 0xdd, 0xab, 0x44, + 0x0e, 0x4a, 0x03, 0x8d, 0xc1, 0xe3, 0x58, 0xc4, + }), + uint256(std::vector{ + 0xbd, 0xcd, 0xb3, 0x29, 0x31, 0x88, 0xc9, 0x80, + 0x7d, 0x80, 0x82, 0x67, 0x01, 0x86, 0x84, 0xcf, + 0xec, 0xe0, 0x7a, 0xc3, 0x5a, 0x42, 0xc0, 0x0f, + 0x2c, 0x79, 0xb4, 0x00, 0x38, 0x25, 0x30, 0x5d, + }), + uint256(std::vector{ + 0xba, 0xb5, 0x80, 0x09, 0x72, 0xa1, 0x6c, 0x2c, + 0x22, 0x53, 0x0c, 0x66, 0x06, 0x6d, 0x0a, 0x58, + 0x67, 0xe9, 0x87, 0xbe, 0xd2, 0x1a, 0x6d, 0x5a, + 0x45, 0x0b, 0x68, 0x3c, 0xf1, 0xcf, 0xd7, 0x09, + }), + uint256(std::vector{ + 0x11, 0xaa, 0x0b, 0x4a, 0xd2, 0x9b, 0x13, 0xb0, + 0x57, 0xa3, 0x16, 0x19, 0xd6, 0x50, 0x0d, 0x63, + 0x6c, 0xd7, 0x35, 0xcd, 0xd0, 0x7d, 0x81, 0x1e, + 0xa2, 0x65, 0xec, 0x4b, 0xcb, 0xbb, 0xd0, 0x58, + }), + uint256(std::vector{ + 0x51, 0x45, 0xb1, 0xb0, 0x55, 0xc2, 0xdf, 0x02, + 0xb9, 0x56, 0x75, 0xe3, 0x79, 0x7b, 0x91, 0xde, + 0x1b, 0x84, 0x6d, 0x25, 0x00, 0x3c, 0x0a, 0x80, + 0x3d, 0x08, 0x90, 0x07, 0x28, 0xf2, 0xcd, 0x6a, + }), + uint256(std::vector{ + 0x03, 0x23, 0xf2, 0x85, 0x0b, 0xf3, 0x44, 0x4f, + 0x4b, 0x4c, 0x5c, 0x09, 0xa6, 0x05, 0x7e, 0xc7, + 0x16, 0x91, 0x90, 0xf4, 0x5a, 0xcb, 0x9e, 0x46, + 0x98, 0x4a, 0xb3, 0xdf, 0xce, 0xc4, 0xf0, 0x6a, + }), + uint256(std::vector{ + 0x67, 0x15, 0x46, 0xe2, 0x6b, 0x1d, 0xa1, 0xaf, + 0x75, 0x45, 0x31, 0xe2, 0x6d, 0x8a, 0x6a, 0x51, + 0x07, 0x3a, 0x57, 0xdd, 0xd7, 0x2d, 0xc4, 0x72, + 0xef, 0xb4, 0x3f, 0xcb, 0x25, 0x7c, 0xff, 0xff, + }), + uint256(std::vector{ + 0xbb, 0x23, 0xa9, 0xbb, 0xa5, 0x6d, 0xe5, 0x7c, + 0xb2, 0x84, 0xb0, 0xd2, 0xb0, 0x1c, 0x64, 0x2c, + 0xf7, 0x9c, 0x9a, 0x55, 0x63, 0xf0, 0x06, 0x7a, + 0x21, 0x29, 0x24, 0x12, 0x14, 0x5b, 0xd7, 0x8a, + }), + uint256(std::vector{ + 0xf3, 0x0c, 0xc8, 0x36, 0xb9, 0xf7, 0x1b, 0x4e, + 0x7e, 0xe3, 0xc7, 0x2b, 0x1f, 0xd2, 0x53, 0x26, + 0x8a, 0xf9, 0xa2, 0x7e, 0x9d, 0x72, 0x91, 0xa2, + 0x3d, 0x02, 0x82, 0x1b, 0x21, 0xdd, 0xfd, 0x16, + }), + uint256(std::vector{ + 0x58, 0xa2, 0x75, 0x3d, 0xad, 0xe1, 0x03, 0xce, + 0xcb, 0xcd, 0xa5, 0x0b, 0x5e, 0xbf, 0xce, 0x31, + 0xe1, 0x2d, 0x41, 0xd5, 0x84, 0x1d, 0xcc, 0x95, + 0x62, 0x0f, 0x7b, 0x3d, 0x50, 0xa1, 0xb9, 0xa1, + }), + uint256(std::vector{ + 0x92, 0x5e, 0x6d, 0x47, 0x4a, 0x5d, 0x8d, 0x30, + 0x04, 0xf2, 0x9d, 0xa0, 0xdd, 0x78, 0xd3, 0x0a, + 0xe3, 0x82, 0x4c, 0xe7, 0x9d, 0xfe, 0x49, 0x34, + 0xbb, 0x29, 0xec, 0x3a, 0xfa, 0xf3, 0xd5, 0x21, + }), + uint256(std::vector{ + 0x08, 0xf2, 0x79, 0x61, 0x86, 0x16, 0xbc, 0xdd, + 0x4e, 0xad, 0xc9, 0xc7, 0xa9, 0x06, 0x26, 0x91, + 0xa5, 0x9b, 0x43, 0xb0, 0x7e, 0x2c, 0x1e, 0x23, + 0x7f, 0x17, 0xbd, 0x18, 0x9c, 0xd6, 0xa8, 0xfe, + }), + uint256(std::vector{ + 0xc9, 0x2b, 0x32, 0xdb, 0x42, 0xf4, 0x2e, 0x2b, + 0xf0, 0xa5, 0x9d, 0xf9, 0x05, 0x5b, 0xe5, 0xc6, + 0x69, 0xd3, 0x24, 0x2d, 0xf4, 0x53, 0x57, 0x65, + 0x9b, 0x75, 0xae, 0x2c, 0x27, 0xa7, 0x6f, 0x50, + }), + uint256(std::vector{ + 0xc0, 0xdb, 0x2a, 0x74, 0x99, 0x8c, 0x50, 0xeb, + 0x7b, 0xa6, 0x53, 0x4f, 0x6d, 0x41, 0x0e, 0xfc, + 0x27, 0xc4, 0xbb, 0x88, 0xac, 0xb0, 0x22, 0x2c, + 0x79, 0x06, 0xea, 0x28, 0xa3, 0x27, 0xb5, 0x11, + }), + uint256(std::vector{ + 0xd7, 0xc6, 0x12, 0xc8, 0x17, 0x79, 0x31, 0x91, + 0xa1, 0xe6, 0x86, 0x52, 0x12, 0x18, 0x76, 0xd6, + 0xb3, 0xbd, 0xe4, 0x0f, 0x4f, 0xa5, 0x2b, 0xc3, + 0x14, 0x14, 0x5c, 0xe6, 0xe5, 0xcd, 0xd2, 0x59, + }), + uint256(std::vector{ + 0xb2, 0x23, 0x70, 0x10, 0x6c, 0x67, 0xa1, 0x72, + 0x09, 0xf6, 0x13, 0x0b, 0xc0, 0x9f, 0x73, 0x5d, + 0x83, 0xaa, 0x2c, 0x04, 0xfc, 0x4f, 0xe7, 0x2e, + 0xa5, 0xd8, 0x0b, 0x21, 0x67, 0x23, 0xe7, 0xce, + }), + uint256(std::vector{ + 0x9f, 0x67, 0xd5, 0xf6, 0x64, 0x66, 0x4c, 0x90, + 0x19, 0x40, 0xee, 0xe3, 0xd0, 0x2d, 0xd5, 0xb3, + 0xe4, 0xb9, 0x2e, 0x7b, 0x42, 0x82, 0x0c, 0x42, + 0xfc, 0x51, 0x59, 0xe9, 0x1b, 0x41, 0x17, 0x2a, + }), + uint256(std::vector{ + 0xac, 0x58, 0xcd, 0x13, 0x88, 0xfe, 0xc2, 0x90, + 0xd3, 0x98, 0xf1, 0x94, 0x4b, 0x56, 0x44, 0x49, + 0xa6, 0x3c, 0x81, 0x58, 0x80, 0x56, 0x6b, 0xd1, + 0xd1, 0x89, 0xf7, 0x83, 0x9e, 0x3b, 0x0c, 0x8c, + }), + uint256(std::vector{ + 0x56, 0x98, 0xea, 0xe7, 0xc8, 0x51, 0x5e, 0xd0, + 0x5a, 0x70, 0x33, 0x9b, 0xdf, 0x7c, 0x10, 0x28, + 0xe7, 0xac, 0xca, 0x13, 0xa4, 0xfa, 0x97, 0xd9, + 0x53, 0x8f, 0x01, 0xac, 0x8d, 0x88, 0x9a, 0xe3, + }), + uint256(std::vector{ + 0x2d, 0x49, 0x95, 0x77, 0x0a, 0x76, 0xfb, 0x93, + 0x31, 0x4c, 0xa7, 0x4b, 0x35, 0x24, 0xea, 0x1d, + 0xb5, 0x68, 0x8a, 0xd0, 0xa7, 0x61, 0x83, 0xea, + 0x17, 0x20, 0x4a, 0x8f, 0x02, 0x4a, 0x9f, 0x3b, + }), + uint256(std::vector{ + 0x5e, 0x89, 0x92, 0xc1, 0xb0, 0x72, 0xc1, 0x6e, + 0x9e, 0x28, 0xa8, 0x53, 0x58, 0xfb, 0x5f, 0xb6, + 0x90, 0x1a, 0x81, 0x58, 0x77, 0x66, 0xda, 0xdb, + 0x7a, 0xa0, 0xb9, 0x73, 0xde, 0xd2, 0xf2, 0x64, + }), + uint256(std::vector{ + 0xe9, 0x5d, 0xb7, 0x1e, 0x1f, 0x72, 0x91, 0xba, + 0x54, 0x99, 0x46, 0x1b, 0xc7, 0x15, 0x20, 0x3e, + 0x29, 0xb8, 0x4b, 0xfa, 0x42, 0x83, 0xe3, 0xbb, + 0x7f, 0x47, 0x0a, 0x15, 0xd0, 0xe1, 0x58, 0x4e, + }), + uint256(std::vector{ + 0x41, 0xf0, 0x78, 0xbd, 0x18, 0x24, 0xc8, 0xa4, + 0xb7, 0x19, 0x64, 0xf3, 0x94, 0xaa, 0x59, 0x50, + 0x84, 0xd8, 0xeb, 0x17, 0xb9, 0x7a, 0x36, 0x30, + 0x43, 0x3a, 0xf7, 0x0d, 0x10, 0xe0, 0xef, 0xf6, + }), + uint256(std::vector{ + 0xa1, 0x91, 0x3f, 0xe6, 0xb2, 0x01, 0x32, 0x31, + 0x2f, 0x8c, 0x1f, 0x00, 0xdd, 0xd6, 0x3c, 0xec, + 0x7a, 0x03, 0xf5, 0xf1, 0xd7, 0xd8, 0x34, 0x92, + 0xfa, 0x28, 0x4c, 0x0b, 0x5d, 0x63, 0x20, 0xb0, + }), + uint256(std::vector{ + 0xba, 0x94, 0x40, 0xc4, 0xdb, 0xfc, 0xf5, 0x5c, + 0xeb, 0x60, 0x5a, 0x5b, 0x89, 0x90, 0xfc, 0x11, + 0xf8, 0xef, 0x22, 0x87, 0x0d, 0x8d, 0x12, 0xe1, + 0x30, 0xf9, 0x86, 0x49, 0x1e, 0xae, 0x84, 0xb3, + }), + uint256(std::vector{ + 0x49, 0xdb, 0x2d, 0x5e, 0x22, 0xb8, 0x01, 0x5c, + 0xae, 0x48, 0x10, 0xd7, 0x5e, 0x54, 0x01, 0x4c, + 0x54, 0x69, 0x86, 0x27, 0x38, 0xe1, 0x61, 0xec, + 0x96, 0xec, 0x20, 0x21, 0x87, 0x18, 0x82, 0x8a, + }), + uint256(std::vector{ + 0xd4, 0x85, 0x1f, 0xb8, 0x43, 0x1e, 0xdf, 0xbb, + 0x8b, 0x1e, 0x85, 0xad, 0xa6, 0x89, 0x59, 0x67, + 0xc2, 0xda, 0xc8, 0x7d, 0xf3, 0x44, 0x99, 0x2a, + 0x05, 0xfa, 0xf1, 0xec, 0xf8, 0x36, 0xee, 0xc9, + }), + uint256(std::vector{ + 0xe4, 0xab, 0x9f, 0x44, 0x70, 0xf0, 0x0c, 0xd1, + 0x96, 0xd4, 0x7c, 0x75, 0xc8, 0x2e, 0x7a, 0xda, + 0xf0, 0x6f, 0xe1, 0x7e, 0x04, 0x2e, 0x39, 0x53, + 0xd9, 0x3b, 0xb5, 0xd5, 0x6d, 0x8c, 0xd8, 0xfb, + }), + uint256(std::vector{ + 0x7e, 0x43, 0x20, 0x43, 0x48, 0x49, 0xec, 0xb3, + 0x57, 0xf1, 0xaf, 0xaa, 0xba, 0x21, 0xa5, 0x44, + 0x00, 0xef, 0x2d, 0x11, 0xcf, 0xf8, 0x3b, 0x93, + 0x7d, 0x87, 0xfd, 0xaf, 0xa4, 0x9f, 0x81, 0x99, + }), + uint256(std::vector{ + 0x02, 0x0a, 0xdc, 0x98, 0xd9, 0x6c, 0xfb, 0xbc, + 0xca, 0x15, 0xfc, 0x3a, 0xa0, 0x37, 0x60, 0xed, + 0x28, 0x66, 0x86, 0xc3, 0x5b, 0x5d, 0x92, 0xc7, + 0xcb, 0x64, 0xa9, 0x99, 0xb3, 0x94, 0xa8, 0x54, + }), + uint256(std::vector{ + 0x3a, 0x26, 0xb2, 0x9f, 0xe1, 0xac, 0xfd, 0xd6, + 0xc6, 0xa1, 0x51, 0xbc, 0xc3, 0xdb, 0xcb, 0x95, + 0xa1, 0x0e, 0xbe, 0x2f, 0x05, 0x53, 0xf8, 0x07, + 0x79, 0x56, 0x9b, 0x67, 0xb7, 0x24, 0x4e, 0x77, + }), + uint256(std::vector{ + 0xec, 0x2d, 0x09, 0x86, 0xe6, 0xa0, 0xdd, 0xf4, + 0x38, 0x97, 0xb2, 0xd4, 0xf2, 0x3b, 0xb0, 0x34, + 0xf5, 0x38, 0xff, 0xe0, 0x08, 0x27, 0xf3, 0x10, + 0xdc, 0x49, 0x63, 0xf3, 0x26, 0x7f, 0x0b, 0xfb, + }), + uint256(std::vector{ + 0xd4, 0x80, 0x73, 0xf8, 0x81, 0x9f, 0x81, 0xf0, + 0x35, 0x8e, 0x3f, 0xc3, 0x5a, 0x04, 0x7c, 0xc7, + 0x40, 0x82, 0xae, 0x1c, 0xb7, 0xee, 0x22, 0xfb, + 0x60, 0x9c, 0x01, 0x64, 0x93, 0x42, 0xd0, 0xe6, + }), + uint256(std::vector{ + 0xad, 0x80, 0x37, 0x60, 0x17, 0x93, 0xf1, 0x72, + 0x44, 0x1e, 0xcb, 0x00, 0xdc, 0x13, 0x8d, 0x9f, + 0xc5, 0x95, 0x71, 0x25, 0xec, 0xc3, 0x82, 0xec, + 0x65, 0xe3, 0x6f, 0x81, 0x7d, 0xc7, 0x99, 0xfb, + }), + uint256(std::vector{ + 0xca, 0x50, 0x0a, 0x54, 0x41, 0xf3, 0x6f, 0x4d, + 0xf6, 0x73, 0xd6, 0xb8, 0xed, 0x07, 0x5d, 0x36, + 0xda, 0xe2, 0xc7, 0xe6, 0x48, 0x14, 0x28, 0xc7, + 0x0a, 0x5a, 0x76, 0xb7, 0xa9, 0xbe, 0xbc, 0xe8, + }), + uint256(std::vector{ + 0x42, 0x2b, 0x6d, 0xdd, 0x47, 0x32, 0x31, 0xdc, + 0x4d, 0x56, 0xfe, 0x91, 0x34, 0x44, 0xcc, 0xd5, + 0x6f, 0x7c, 0x61, 0xf7, 0x47, 0xba, 0x57, 0xca, + 0x94, 0x6d, 0x5f, 0xef, 0x72, 0xd8, 0x40, 0xa0, + }), + uint256(std::vector{ + 0xab, 0x41, 0xf4, 0xec, 0xb7, 0xd7, 0x08, 0x96, + 0x15, 0x80, 0x0e, 0x19, 0xfc, 0xc5, 0x3b, 0x83, + 0x79, 0xed, 0x05, 0xee, 0x35, 0xc8, 0x25, 0x67, + 0x09, 0x55, 0x83, 0xfd, 0x90, 0xff, 0x30, 0x35, + }), + uint256(std::vector{ + 0xbb, 0xf7, 0x61, 0x82, 0x48, 0x35, 0x4c, 0xeb, + 0x1b, 0xc1, 0xfc, 0x9d, 0xbc, 0x42, 0xc4, 0x26, + 0xa4, 0xe2, 0xc1, 0xe0, 0xd4, 0x43, 0xc5, 0x68, + 0x3a, 0x92, 0x56, 0xc6, 0x2e, 0xcd, 0xc2, 0x6f, + }), + uint256(std::vector{ + 0xe5, 0x0a, 0xe7, 0x14, 0x79, 0xfc, 0x8e, 0xc5, + 0x69, 0x19, 0x2a, 0x13, 0x07, 0x2e, 0x01, 0x1a, + 0xfc, 0x24, 0x9f, 0x47, 0x1a, 0xf0, 0x95, 0x00, + 0xea, 0x39, 0xf7, 0x5d, 0x0a, 0xf8, 0x56, 0xbf, + }), + uint256(std::vector{ + 0xe7, 0x4c, 0x0b, 0x92, 0x20, 0x14, 0x7d, 0xb2, + 0xd5, 0x0a, 0x3b, 0x58, 0xd4, 0x13, 0x77, 0x5d, + 0x16, 0xc9, 0x84, 0x69, 0x0b, 0xe7, 0xd9, 0x0f, + 0x0b, 0xc4, 0x3d, 0x99, 0xdb, 0xa1, 0xb6, 0x89, + }), + uint256(std::vector{ + 0x29, 0x32, 0x4a, 0x0a, 0x48, 0xd1, 0x16, 0x57, + 0xa5, 0x1b, 0xa0, 0x8b, 0x00, 0x48, 0x79, 0xbf, + 0xcf, 0xc6, 0x6a, 0x1a, 0xcb, 0x7c, 0xe3, 0x6d, + 0xfe, 0x47, 0x8d, 0x26, 0x55, 0x48, 0x4b, 0x48, + }), + uint256(std::vector{ + 0x88, 0x95, 0x2e, 0x3d, 0x0a, 0xc0, 0x6c, 0xb1, + 0x6b, 0x66, 0x52, 0x01, 0x12, 0x22, 0x49, 0x65, + 0x9a, 0x22, 0x32, 0x5e, 0x01, 0xc8, 0x70, 0xf4, + 0x9e, 0x29, 0xda, 0x6b, 0x17, 0x57, 0xe0, 0x82, + }), + uint256(std::vector{ + 0xcd, 0xf8, 0x79, 0xf2, 0x43, 0x5b, 0x95, 0xaf, + 0x04, 0x2a, 0x3b, 0xf7, 0xb8, 0x50, 0xf7, 0x81, + 0x92, 0x46, 0xc8, 0x05, 0x28, 0x58, 0x03, 0xd6, + 0x7f, 0xfb, 0xf4, 0xf2, 0x95, 0xbe, 0xd0, 0x04, + }), + uint256(std::vector{ + 0xe0, 0x05, 0xe3, 0x24, 0x20, 0x0b, 0x4f, 0x42, + 0x8c, 0x62, 0xbc, 0x33, 0x31, 0xe6, 0x95, 0xc3, + 0x73, 0x60, 0x7c, 0xd0, 0xfa, 0xa9, 0x79, 0x03, + 0x41, 0xfa, 0x3b, 0xa1, 0xed, 0x22, 0x8b, 0xc5, + }), + uint256(std::vector{ + 0x35, 0x44, 0x47, 0x72, 0x7a, 0xa9, 0xa5, 0x3d, + 0xd8, 0x34, 0x5b, 0x6b, 0x6c, 0x69, 0x34, 0x43, + 0xe5, 0x6e, 0xf4, 0xae, 0xba, 0x13, 0xc4, 0x10, + 0x17, 0x9f, 0xc8, 0x58, 0x9e, 0x77, 0x33, 0xd5, + }), + uint256(std::vector{ + 0xda, 0x52, 0xdd, 0xa9, 0x1f, 0x28, 0x29, 0xc1, + 0x5c, 0x0e, 0x58, 0xd2, 0x9a, 0x95, 0x36, 0x0b, + 0x86, 0xab, 0x30, 0xcf, 0x0c, 0xac, 0x81, 0x01, + 0x83, 0x2a, 0x29, 0xf3, 0x8c, 0x31, 0x85, 0xf1, + }), + uint256(std::vector{ + 0xc7, 0xda, 0x78, 0x14, 0xe2, 0x28, 0xe1, 0x14, + 0x44, 0x11, 0xd7, 0x8b, 0x53, 0x60, 0x92, 0xfe, + 0x92, 0x0b, 0xcd, 0xfc, 0xc3, 0x6c, 0xf1, 0x9d, + 0x12, 0x59, 0x04, 0x7b, 0x26, 0x7d, 0x58, 0xb5, + }), + uint256(std::vector{ + 0xab, 0xa1, 0xf6, 0x8b, 0x6c, 0x2b, 0x4d, 0xb6, + 0xcc, 0x06, 0xa7, 0x34, 0x0e, 0x12, 0x31, 0x3c, + 0x4b, 0x4a, 0x4e, 0xa6, 0xde, 0xb1, 0x7d, 0xeb, + 0x3e, 0x1e, 0x66, 0xcd, 0x8e, 0xac, 0xf3, 0x2b, + }), + uint256(std::vector{ + 0xc1, 0x60, 0xae, 0x4f, 0x64, 0xab, 0x76, 0x4d, + 0x86, 0x4a, 0x52, 0xad, 0x5e, 0x33, 0x12, 0x6c, + 0x4b, 0x5c, 0xe1, 0x05, 0xa4, 0x7d, 0xee, 0xdd, + 0x75, 0xbc, 0x70, 0x19, 0x9a, 0x52, 0x47, 0xef, + }), + uint256(std::vector{ + 0xea, 0xdf, 0x23, 0xfc, 0x99, 0xd5, 0x14, 0xdd, + 0x8e, 0xa2, 0x04, 0xd2, 0x23, 0xe9, 0x8d, 0xa9, + 0x88, 0x83, 0x1f, 0x9b, 0x5d, 0x19, 0x40, 0x27, + 0x4c, 0xa5, 0x20, 0xb7, 0xfb, 0x17, 0x3d, 0x8a, + }), + uint256(std::vector{ + 0x5b, 0x8e, 0x14, 0xfa, 0xca, 0xc8, 0xa7, 0xc7, + 0xa3, 0xbf, 0xee, 0x8b, 0xae, 0x71, 0xf2, 0xf7, + 0x79, 0x3d, 0x3a, 0xd5, 0xfe, 0x33, 0x83, 0xf9, + 0x3a, 0xb6, 0x06, 0x1f, 0x2a, 0x11, 0xbb, 0x02 + }), +}; + +SHA256Compress SHA256Compress::EmptyRoot(size_t depth) { + return sha256_empty_roots.at(depth); +} + template class PathFiller { private: diff --git a/src/zcash/IncrementalMerkleTree.hpp b/src/zcash/IncrementalMerkleTree.hpp index 79a90bc5b..1ebb2b499 100644 --- a/src/zcash/IncrementalMerkleTree.hpp +++ b/src/zcash/IncrementalMerkleTree.hpp @@ -57,14 +57,9 @@ public: template class EmptyMerkleRoots { public: - EmptyMerkleRoots() { - empty_roots.at(0) = Hash::uncommitted(); - for (size_t d = 1; d <= Depth; d++) { - empty_roots.at(d) = Hash::combine(empty_roots.at(d-1), empty_roots.at(d-1), d-1); - } - } - Hash empty_root(size_t depth) { - return empty_roots.at(depth); + EmptyMerkleRoots() { } + Hash empty_root(size_t depth) const { + return Hash::EmptyRoot(depth); } template friend bool operator==(const EmptyMerkleRoots& a, @@ -227,6 +222,7 @@ public: static SHA256Compress uncommitted() { return SHA256Compress(); } + static SHA256Compress EmptyRoot(size_t); }; class PedersenHash : public uint256 { @@ -241,6 +237,7 @@ public: ); static PedersenHash uncommitted(); + static PedersenHash EmptyRoot(size_t); }; template diff --git a/src/zcash/Proof.cpp b/src/zcash/Proof.cpp index af87d1b81..7ab1298a8 100644 --- a/src/zcash/Proof.cpp +++ b/src/zcash/Proof.cpp @@ -3,249 +3,16 @@ #include "crypto/common.h" #include -#include -#include #include -using namespace libsnark; - -typedef alt_bn128_pp curve_pp; -typedef alt_bn128_pp::G1_type curve_G1; -typedef alt_bn128_pp::G2_type curve_G2; -typedef alt_bn128_pp::GT_type curve_GT; -typedef alt_bn128_pp::Fp_type curve_Fr; -typedef alt_bn128_pp::Fq_type curve_Fq; -typedef alt_bn128_pp::Fqe_type curve_Fq2; - -BOOST_STATIC_ASSERT(sizeof(mp_limb_t) == 8); - namespace libzcash { -// FE2IP as defined in the protocol spec and IEEE Std 1363a-2004. -bigint<8> fq2_to_bigint(const curve_Fq2 &e) -{ - auto modq = curve_Fq::field_char(); - auto c0 = e.c0.as_bigint(); - auto c1 = e.c1.as_bigint(); - - bigint<8> temp = c1 * modq; - temp += c0; - return temp; -} - -// Writes a bigint in big endian -template -void write_bigint(base_blob<8 * LIMBS * sizeof(mp_limb_t)> &blob, const bigint &val) -{ - auto ptr = blob.begin(); - for (ssize_t i = LIMBS-1; i >= 0; i--, ptr += 8) { - WriteBE64(ptr, val.data[i]); - } -} - -// Reads a bigint from big endian -template -bigint read_bigint(const base_blob<8 * LIMBS * sizeof(mp_limb_t)> &blob) -{ - bigint ret; - - auto ptr = blob.begin(); - - for (ssize_t i = LIMBS-1; i >= 0; i--, ptr += 8) { - ret.data[i] = ReadBE64(ptr); - } - - return ret; -} - -template<> -Fq::Fq(curve_Fq element) : data() -{ - write_bigint<4>(data, element.as_bigint()); -} - -template<> -curve_Fq Fq::to_libsnark_fq() const -{ - auto element_bigint = read_bigint<4>(data); - - // Check that the integer is smaller than the modulus - auto modq = curve_Fq::field_char(); - element_bigint.limit(modq, "element is not in Fq"); - - return curve_Fq(element_bigint); -} - -template<> -Fq2::Fq2(curve_Fq2 element) : data() -{ - write_bigint<8>(data, fq2_to_bigint(element)); -} - -template<> -curve_Fq2 Fq2::to_libsnark_fq2() const -{ - bigint<4> modq = curve_Fq::field_char(); - bigint<8> combined = read_bigint<8>(data); - bigint<5> res; - bigint<4> c0; - bigint<8>::div_qr(res, c0, combined, modq); - bigint<4> c1 = res.shorten(modq, "element is not in Fq2"); - - return curve_Fq2(curve_Fq(c0), curve_Fq(c1)); -} - -template<> -CompressedG1::CompressedG1(curve_G1 point) -{ - if (point.is_zero()) { - throw std::domain_error("curve point is zero"); - } - - point.to_affine_coordinates(); - - x = Fq(point.X); - y_lsb = point.Y.as_bigint().data[0] & 1; -} - -template<> -curve_G1 CompressedG1::to_libsnark_g1() const -{ - curve_Fq x_coordinate = x.to_libsnark_fq(); - - // y = +/- sqrt(x^3 + b) - auto y_coordinate = ((x_coordinate.squared() * x_coordinate) + alt_bn128_coeff_b).sqrt(); - - if ((y_coordinate.as_bigint().data[0] & 1) != y_lsb) { - y_coordinate = -y_coordinate; - } - - curve_G1 r = curve_G1::one(); - r.X = x_coordinate; - r.Y = y_coordinate; - r.Z = curve_Fq::one(); - - assert(r.is_well_formed()); - - return r; -} - -template<> -CompressedG2::CompressedG2(curve_G2 point) -{ - if (point.is_zero()) { - throw std::domain_error("curve point is zero"); - } - - point.to_affine_coordinates(); - - x = Fq2(point.X); - y_gt = fq2_to_bigint(point.Y) > fq2_to_bigint(-(point.Y)); -} - -template<> -curve_G2 CompressedG2::to_libsnark_g2() const -{ - auto x_coordinate = x.to_libsnark_fq2(); - - // y = +/- sqrt(x^3 + b) - auto y_coordinate = ((x_coordinate.squared() * x_coordinate) + alt_bn128_twist_coeff_b).sqrt(); - auto y_coordinate_neg = -y_coordinate; - - if ((fq2_to_bigint(y_coordinate) > fq2_to_bigint(y_coordinate_neg)) != y_gt) { - y_coordinate = y_coordinate_neg; - } - - curve_G2 r = curve_G2::one(); - r.X = x_coordinate; - r.Y = y_coordinate; - r.Z = curve_Fq2::one(); - - assert(r.is_well_formed()); - - if (alt_bn128_modulus_r * r != curve_G2::zero()) { - throw std::runtime_error("point is not in G2"); - } - - return r; -} - -template<> -PHGRProof::PHGRProof(const r1cs_ppzksnark_proof &proof) -{ - g_A = CompressedG1(proof.g_A.g); - g_A_prime = CompressedG1(proof.g_A.h); - g_B = CompressedG2(proof.g_B.g); - g_B_prime = CompressedG1(proof.g_B.h); - g_C = CompressedG1(proof.g_C.g); - g_C_prime = CompressedG1(proof.g_C.h); - g_K = CompressedG1(proof.g_K); - g_H = CompressedG1(proof.g_H); -} - -template<> -r1cs_ppzksnark_proof PHGRProof::to_libsnark_proof() const -{ - r1cs_ppzksnark_proof proof; - - proof.g_A.g = g_A.to_libsnark_g1(); - proof.g_A.h = g_A_prime.to_libsnark_g1(); - proof.g_B.g = g_B.to_libsnark_g2(); - proof.g_B.h = g_B_prime.to_libsnark_g1(); - proof.g_C.g = g_C.to_libsnark_g1(); - proof.g_C.h = g_C_prime.to_libsnark_g1(); - proof.g_K = g_K.to_libsnark_g1(); - proof.g_H = g_H.to_libsnark_g1(); - - return proof; -} - -PHGRProof PHGRProof::random_invalid() -{ - PHGRProof p; - p.g_A = curve_G1::random_element(); - p.g_A_prime = curve_G1::random_element(); - p.g_B = curve_G2::random_element(); - p.g_B_prime = curve_G1::random_element(); - p.g_C = curve_G1::random_element(); - p.g_C_prime = curve_G1::random_element(); - - p.g_K = curve_G1::random_element(); - p.g_H = curve_G1::random_element(); - - return p; -} - -static std::once_flag init_public_params_once_flag; - -void initialize_curve_params() -{ - std::call_once (init_public_params_once_flag, curve_pp::init_public_params); -} - ProofVerifier ProofVerifier::Strict() { - initialize_curve_params(); return ProofVerifier(true); } ProofVerifier ProofVerifier::Disabled() { - initialize_curve_params(); return ProofVerifier(false); } -template<> -bool ProofVerifier::check( - const r1cs_ppzksnark_verification_key& vk, - const r1cs_ppzksnark_processed_verification_key& pvk, - const r1cs_primary_input& primary_input, - const r1cs_ppzksnark_proof& proof -) -{ - if (perform_verification) { - return r1cs_ppzksnark_online_verifier_strong_IC(pvk, primary_input, proof); - } else { - return true; - } -} - } diff --git a/src/zcash/Proof.hpp b/src/zcash/Proof.hpp index e06095d57..7c9b7f7f5 100644 --- a/src/zcash/Proof.hpp +++ b/src/zcash/Proof.hpp @@ -16,12 +16,6 @@ private: public: Fq() : data() { } - template - Fq(libsnark_Fq element); - - template - libsnark_Fq to_libsnark_fq() const; - ADD_SERIALIZE_METHODS; template @@ -49,12 +43,6 @@ private: public: Fq2() : data() { } - template - Fq2(libsnark_Fq2 element); - - template - libsnark_Fq2 to_libsnark_fq2() const; - ADD_SERIALIZE_METHODS; template @@ -84,12 +72,6 @@ private: public: CompressedG1() : y_lsb(false), x() { } - template - CompressedG1(libsnark_G1 point); - - template - libsnark_G1 to_libsnark_g1() const; - ADD_SERIALIZE_METHODS; template @@ -134,12 +116,6 @@ private: public: CompressedG2() : y_gt(false), x() { } - template - CompressedG2(libsnark_G2 point); - - template - libsnark_G2 to_libsnark_g2() const; - ADD_SERIALIZE_METHODS; template @@ -190,17 +166,6 @@ private: public: PHGRProof() : g_A(), g_A_prime(), g_B(), g_B_prime(), g_C(), g_C_prime(), g_K(), g_H() { } - // Produces a compressed proof using a libsnark zkSNARK proof - template - PHGRProof(const libsnark_proof& proof); - - // Produces a libsnark zkSNARK proof out of this proof, - // or throws an exception if it is invalid. - template - libsnark_proof to_libsnark_proof() const; - - static PHGRProof random_invalid(); - ADD_SERIALIZE_METHODS; template diff --git a/src/zcash/circuit/commitment.tcc b/src/zcash/circuit/commitment.tcc deleted file mode 100644 index d1b0b10fa..000000000 --- a/src/zcash/circuit/commitment.tcc +++ /dev/null @@ -1,100 +0,0 @@ -template -class note_commitment_gadget : gadget { -private: - std::shared_ptr> block1; - std::shared_ptr> block2; - std::shared_ptr> hasher1; - std::shared_ptr> intermediate_hash; - std::shared_ptr> hasher2; - -public: - note_commitment_gadget( - protoboard &pb, - pb_variable& ZERO, - pb_variable_array& a_pk, - pb_variable_array& v, - pb_variable_array& rho, - pb_variable_array& r, - std::shared_ptr> result - ) : gadget(pb) { - pb_variable_array leading_byte = - from_bits({1, 0, 1, 1, 0, 0, 0, 0}, ZERO); - - pb_variable_array first_of_rho(rho.begin(), rho.begin()+184); - pb_variable_array last_of_rho(rho.begin()+184, rho.end()); - - intermediate_hash.reset(new digest_variable(pb, 256, "")); - - // final padding - pb_variable_array length_padding = - from_bits({ - // padding - 1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - - // length of message (840 bits) - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,1, - 0,1,0,0,1,0,0,0 - }, ZERO); - - block1.reset(new block_variable(pb, { - leading_byte, - a_pk, - v, - first_of_rho - }, "")); - - block2.reset(new block_variable(pb, { - last_of_rho, - r, - length_padding - }, "")); - - pb_linear_combination_array IV = SHA256_default_IV(pb); - - hasher1.reset(new sha256_compression_function_gadget( - pb, - IV, - block1->bits, - *intermediate_hash, - "")); - - pb_linear_combination_array IV2(intermediate_hash->bits); - - hasher2.reset(new sha256_compression_function_gadget( - pb, - IV2, - block2->bits, - *result, - "")); - } - - void generate_r1cs_constraints() { - hasher1->generate_r1cs_constraints(); - hasher2->generate_r1cs_constraints(); - } - - void generate_r1cs_witness() { - hasher1->generate_r1cs_witness(); - hasher2->generate_r1cs_witness(); - } -}; diff --git a/src/zcash/circuit/gadget.tcc b/src/zcash/circuit/gadget.tcc deleted file mode 100644 index 0a2ec7719..000000000 --- a/src/zcash/circuit/gadget.tcc +++ /dev/null @@ -1,349 +0,0 @@ -#include "zcash/circuit/utils.tcc" -#include "zcash/circuit/prfs.tcc" -#include "zcash/circuit/commitment.tcc" -#include "zcash/circuit/merkle.tcc" -#include "zcash/circuit/note.tcc" - -template -class joinsplit_gadget : gadget { -private: - // Verifier inputs - pb_variable_array zk_packed_inputs; - pb_variable_array zk_unpacked_inputs; - std::shared_ptr> unpacker; - - std::shared_ptr> zk_merkle_root; - std::shared_ptr> zk_h_sig; - std::array>, NumInputs> zk_input_nullifiers; - std::array>, NumInputs> zk_input_macs; - std::array>, NumOutputs> zk_output_commitments; - pb_variable_array zk_vpub_old; - pb_variable_array zk_vpub_new; - - // Aux inputs - pb_variable ZERO; - std::shared_ptr> zk_phi; - pb_variable_array zk_total_uint64; - - // Input note gadgets - std::array>, NumInputs> zk_input_notes; - std::array>, NumInputs> zk_mac_authentication; - - // Output note gadgets - std::array>, NumOutputs> zk_output_notes; - -public: - // PRF_pk only has a 1-bit domain separation "nonce" - // for different macs. - BOOST_STATIC_ASSERT(NumInputs <= 2); - - // PRF_rho only has a 1-bit domain separation "nonce" - // for different output `rho`. - BOOST_STATIC_ASSERT(NumOutputs <= 2); - - joinsplit_gadget(protoboard &pb) : gadget(pb) { - // Verification - { - // The verification inputs are all bit-strings of various - // lengths (256-bit digests and 64-bit integers) and so we - // pack them into as few field elements as possible. (The - // more verification inputs you have, the more expensive - // verification is.) - zk_packed_inputs.allocate(pb, verifying_field_element_size()); - pb.set_input_sizes(verifying_field_element_size()); - - alloc_uint256(zk_unpacked_inputs, zk_merkle_root); - alloc_uint256(zk_unpacked_inputs, zk_h_sig); - - for (size_t i = 0; i < NumInputs; i++) { - alloc_uint256(zk_unpacked_inputs, zk_input_nullifiers[i]); - alloc_uint256(zk_unpacked_inputs, zk_input_macs[i]); - } - - for (size_t i = 0; i < NumOutputs; i++) { - alloc_uint256(zk_unpacked_inputs, zk_output_commitments[i]); - } - - alloc_uint64(zk_unpacked_inputs, zk_vpub_old); - alloc_uint64(zk_unpacked_inputs, zk_vpub_new); - - assert(zk_unpacked_inputs.size() == verifying_input_bit_size()); - - // This gadget will ensure that all of the inputs we provide are - // boolean constrained. - unpacker.reset(new multipacking_gadget( - pb, - zk_unpacked_inputs, - zk_packed_inputs, - FieldT::capacity(), - "unpacker" - )); - } - - // We need a constant "zero" variable in some contexts. In theory - // it should never be necessary, but libsnark does not synthesize - // optimal circuits. - // - // The first variable of our constraint system is constrained - // to be one automatically for us, and is known as `ONE`. - ZERO.allocate(pb); - - zk_phi.reset(new digest_variable(pb, 252, "")); - - zk_total_uint64.allocate(pb, 64); - - for (size_t i = 0; i < NumInputs; i++) { - // Input note gadget for commitments, macs, nullifiers, - // and spend authority. - zk_input_notes[i].reset(new input_note_gadget( - pb, - ZERO, - zk_input_nullifiers[i], - *zk_merkle_root - )); - - // The input keys authenticate h_sig to prevent - // malleability. - zk_mac_authentication[i].reset(new PRF_pk_gadget( - pb, - ZERO, - zk_input_notes[i]->a_sk->bits, - zk_h_sig->bits, - i ? true : false, - zk_input_macs[i] - )); - } - - for (size_t i = 0; i < NumOutputs; i++) { - zk_output_notes[i].reset(new output_note_gadget( - pb, - ZERO, - zk_phi->bits, - zk_h_sig->bits, - i ? true : false, - zk_output_commitments[i] - )); - } - } - - void generate_r1cs_constraints() { - // The true passed here ensures all the inputs - // are boolean constrained. - unpacker->generate_r1cs_constraints(true); - - // Constrain `ZERO` - generate_r1cs_equals_const_constraint(this->pb, ZERO, FieldT::zero(), "ZERO"); - - // Constrain bitness of phi - zk_phi->generate_r1cs_constraints(); - - for (size_t i = 0; i < NumInputs; i++) { - // Constrain the JoinSplit input constraints. - zk_input_notes[i]->generate_r1cs_constraints(); - - // Authenticate h_sig with a_sk - zk_mac_authentication[i]->generate_r1cs_constraints(); - } - - for (size_t i = 0; i < NumOutputs; i++) { - // Constrain the JoinSplit output constraints. - zk_output_notes[i]->generate_r1cs_constraints(); - } - - // Value balance - { - linear_combination left_side = packed_addition(zk_vpub_old); - for (size_t i = 0; i < NumInputs; i++) { - left_side = left_side + packed_addition(zk_input_notes[i]->value); - } - - linear_combination right_side = packed_addition(zk_vpub_new); - for (size_t i = 0; i < NumOutputs; i++) { - right_side = right_side + packed_addition(zk_output_notes[i]->value); - } - - // Ensure that both sides are equal - this->pb.add_r1cs_constraint(r1cs_constraint( - 1, - left_side, - right_side - )); - - // #854: Ensure that left_side is a 64-bit integer. - for (size_t i = 0; i < 64; i++) { - generate_boolean_r1cs_constraint( - this->pb, - zk_total_uint64[i], - "" - ); - } - - this->pb.add_r1cs_constraint(r1cs_constraint( - 1, - left_side, - packed_addition(zk_total_uint64) - )); - } - } - - void generate_r1cs_witness( - const uint252& phi, - const uint256& rt, - const uint256& h_sig, - const std::array& inputs, - const std::array& outputs, - uint64_t vpub_old, - uint64_t vpub_new - ) { - // Witness `zero` - this->pb.val(ZERO) = FieldT::zero(); - - // Witness rt. This is not a sanity check. - // - // This ensures the read gadget constrains - // the intended root in the event that - // both inputs are zero-valued. - zk_merkle_root->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(rt) - ); - - // Witness public balance values - zk_vpub_old.fill_with_bits( - this->pb, - uint64_to_bool_vector(vpub_old) - ); - zk_vpub_new.fill_with_bits( - this->pb, - uint64_to_bool_vector(vpub_new) - ); - - { - // Witness total_uint64 bits - uint64_t left_side_acc = vpub_old; - for (size_t i = 0; i < NumInputs; i++) { - left_side_acc += inputs[i].note.value(); - } - - zk_total_uint64.fill_with_bits( - this->pb, - uint64_to_bool_vector(left_side_acc) - ); - } - - // Witness phi - zk_phi->bits.fill_with_bits( - this->pb, - uint252_to_bool_vector(phi) - ); - - // Witness h_sig - zk_h_sig->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(h_sig) - ); - - for (size_t i = 0; i < NumInputs; i++) { - // Witness the input information. - auto merkle_path = inputs[i].witness.path(); - zk_input_notes[i]->generate_r1cs_witness( - merkle_path, - inputs[i].key, - inputs[i].note - ); - - // Witness macs - zk_mac_authentication[i]->generate_r1cs_witness(); - } - - for (size_t i = 0; i < NumOutputs; i++) { - // Witness the output information. - zk_output_notes[i]->generate_r1cs_witness(outputs[i]); - } - - // [SANITY CHECK] Ensure that the intended root - // was witnessed by the inputs, even if the read - // gadget overwrote it. This allows the prover to - // fail instead of the verifier, in the event that - // the roots of the inputs do not match the - // treestate provided to the proving API. - zk_merkle_root->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(rt) - ); - - // This happens last, because only by now are all the - // verifier inputs resolved. - unpacker->generate_r1cs_witness_from_bits(); - } - - static r1cs_primary_input witness_map( - const uint256& rt, - const uint256& h_sig, - const std::array& macs, - const std::array& nullifiers, - const std::array& commitments, - uint64_t vpub_old, - uint64_t vpub_new - ) { - std::vector verify_inputs; - - insert_uint256(verify_inputs, rt); - insert_uint256(verify_inputs, h_sig); - - for (size_t i = 0; i < NumInputs; i++) { - insert_uint256(verify_inputs, nullifiers[i]); - insert_uint256(verify_inputs, macs[i]); - } - - for (size_t i = 0; i < NumOutputs; i++) { - insert_uint256(verify_inputs, commitments[i]); - } - - insert_uint64(verify_inputs, vpub_old); - insert_uint64(verify_inputs, vpub_new); - - assert(verify_inputs.size() == verifying_input_bit_size()); - auto verify_field_elements = pack_bit_vector_into_field_element_vector(verify_inputs); - assert(verify_field_elements.size() == verifying_field_element_size()); - return verify_field_elements; - } - - static size_t verifying_input_bit_size() { - size_t acc = 0; - - acc += 256; // the merkle root (anchor) - acc += 256; // h_sig - for (size_t i = 0; i < NumInputs; i++) { - acc += 256; // nullifier - acc += 256; // mac - } - for (size_t i = 0; i < NumOutputs; i++) { - acc += 256; // new commitment - } - acc += 64; // vpub_old - acc += 64; // vpub_new - - return acc; - } - - static size_t verifying_field_element_size() { - return div_ceil(verifying_input_bit_size(), FieldT::capacity()); - } - - void alloc_uint256( - pb_variable_array& packed_into, - std::shared_ptr>& var - ) { - var.reset(new digest_variable(this->pb, 256, "")); - packed_into.insert(packed_into.end(), var->bits.begin(), var->bits.end()); - } - - void alloc_uint64( - pb_variable_array& packed_into, - pb_variable_array& integer - ) { - integer.allocate(this->pb, 64, ""); - packed_into.insert(packed_into.end(), integer.begin(), integer.end()); - } -}; diff --git a/src/zcash/circuit/merkle.tcc b/src/zcash/circuit/merkle.tcc deleted file mode 100644 index 09f02ae9f..000000000 --- a/src/zcash/circuit/merkle.tcc +++ /dev/null @@ -1,60 +0,0 @@ -template -class merkle_tree_gadget : gadget { -private: - typedef sha256_two_to_one_hash_gadget sha256_gadget; - - pb_variable_array positions; - std::shared_ptr> authvars; - std::shared_ptr> auth; - -public: - merkle_tree_gadget( - protoboard& pb, - digest_variable leaf, - digest_variable root, - pb_variable& enforce - ) : gadget(pb) { - positions.allocate(pb, INCREMENTAL_MERKLE_TREE_DEPTH); - authvars.reset(new merkle_authentication_path_variable( - pb, INCREMENTAL_MERKLE_TREE_DEPTH, "auth" - )); - auth.reset(new merkle_tree_check_read_gadget( - pb, - INCREMENTAL_MERKLE_TREE_DEPTH, - positions, - leaf, - root, - *authvars, - enforce, - "" - )); - } - - void generate_r1cs_constraints() { - for (size_t i = 0; i < INCREMENTAL_MERKLE_TREE_DEPTH; i++) { - // TODO: This might not be necessary, and doesn't - // appear to be done in libsnark's tests, but there - // is no documentation, so let's do it anyway to - // be safe. - generate_boolean_r1cs_constraint( - this->pb, - positions[i], - "boolean_positions" - ); - } - - authvars->generate_r1cs_constraints(); - auth->generate_r1cs_constraints(); - } - - void generate_r1cs_witness(const MerklePath& path) { - // TODO: Change libsnark so that it doesn't require this goofy - // number thing in its API. - size_t path_index = convertVectorToInt(path.index); - - positions.fill_with_bits_of_uint64(this->pb, path_index); - - authvars->generate_r1cs_witness(path_index, path.authentication_path); - auth->generate_r1cs_witness(); - } -}; diff --git a/src/zcash/circuit/note.tcc b/src/zcash/circuit/note.tcc deleted file mode 100644 index c598c62ee..000000000 --- a/src/zcash/circuit/note.tcc +++ /dev/null @@ -1,244 +0,0 @@ -template -class note_gadget : public gadget { -public: - pb_variable_array value; - std::shared_ptr> r; - - note_gadget(protoboard &pb) : gadget(pb) { - value.allocate(pb, 64); - r.reset(new digest_variable(pb, 256, "")); - } - - void generate_r1cs_constraints() { - for (size_t i = 0; i < 64; i++) { - generate_boolean_r1cs_constraint( - this->pb, - value[i], - "boolean_value" - ); - } - - r->generate_r1cs_constraints(); - } - - void generate_r1cs_witness(const SproutNote& note) { - r->bits.fill_with_bits(this->pb, uint256_to_bool_vector(note.r)); - value.fill_with_bits(this->pb, uint64_to_bool_vector(note.value())); - } -}; - -template -class input_note_gadget : public note_gadget { -private: - std::shared_ptr> a_pk; - std::shared_ptr> rho; - - std::shared_ptr> commitment; - std::shared_ptr> commit_to_inputs; - - pb_variable value_enforce; - std::shared_ptr> witness_input; - - std::shared_ptr> spend_authority; - std::shared_ptr> expose_nullifiers; -public: - std::shared_ptr> a_sk; - - input_note_gadget( - protoboard& pb, - pb_variable& ZERO, - std::shared_ptr> nullifier, - digest_variable rt - ) : note_gadget(pb) { - a_sk.reset(new digest_variable(pb, 252, "")); - a_pk.reset(new digest_variable(pb, 256, "")); - rho.reset(new digest_variable(pb, 256, "")); - commitment.reset(new digest_variable(pb, 256, "")); - - spend_authority.reset(new PRF_addr_a_pk_gadget( - pb, - ZERO, - a_sk->bits, - a_pk - )); - - expose_nullifiers.reset(new PRF_nf_gadget( - pb, - ZERO, - a_sk->bits, - rho->bits, - nullifier - )); - - commit_to_inputs.reset(new note_commitment_gadget( - pb, - ZERO, - a_pk->bits, - this->value, - rho->bits, - this->r->bits, - commitment - )); - - value_enforce.allocate(pb); - - witness_input.reset(new merkle_tree_gadget( - pb, - *commitment, - rt, - value_enforce - )); - } - - void generate_r1cs_constraints() { - note_gadget::generate_r1cs_constraints(); - - a_sk->generate_r1cs_constraints(); - rho->generate_r1cs_constraints(); - - spend_authority->generate_r1cs_constraints(); - expose_nullifiers->generate_r1cs_constraints(); - - commit_to_inputs->generate_r1cs_constraints(); - - // value * (1 - enforce) = 0 - // Given `enforce` is boolean constrained: - // If `value` is zero, `enforce` _can_ be zero. - // If `value` is nonzero, `enforce` _must_ be one. - generate_boolean_r1cs_constraint(this->pb, value_enforce,""); - - this->pb.add_r1cs_constraint(r1cs_constraint( - packed_addition(this->value), - (1 - value_enforce), - 0 - ), ""); - - witness_input->generate_r1cs_constraints(); - } - - void generate_r1cs_witness( - const MerklePath& path, - const SproutSpendingKey& key, - const SproutNote& note - ) { - note_gadget::generate_r1cs_witness(note); - - // Witness a_sk for the input - a_sk->bits.fill_with_bits( - this->pb, - uint252_to_bool_vector(key) - ); - - // Witness a_pk for a_sk with PRF_addr - spend_authority->generate_r1cs_witness(); - - // [SANITY CHECK] Witness a_pk with note information - a_pk->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.a_pk) - ); - - // Witness rho for the input note - rho->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.rho) - ); - - // Witness the nullifier for the input note - expose_nullifiers->generate_r1cs_witness(); - - // Witness the commitment of the input note - commit_to_inputs->generate_r1cs_witness(); - - // [SANITY CHECK] Ensure the commitment is - // valid. - commitment->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.cm()) - ); - - // Set enforce flag for nonzero input value - this->pb.val(value_enforce) = (note.value() != 0) ? FieldT::one() : FieldT::zero(); - - // Witness merkle tree authentication path - witness_input->generate_r1cs_witness(path); - } -}; - -template -class output_note_gadget : public note_gadget { -private: - std::shared_ptr> rho; - std::shared_ptr> a_pk; - - std::shared_ptr> prevent_faerie_gold; - std::shared_ptr> commit_to_outputs; - -public: - output_note_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& phi, - pb_variable_array& h_sig, - bool nonce, - std::shared_ptr> commitment - ) : note_gadget(pb) { - rho.reset(new digest_variable(pb, 256, "")); - a_pk.reset(new digest_variable(pb, 256, "")); - - // Do not allow the caller to choose the same "rho" - // for any two valid notes in a given view of the - // blockchain. See protocol specification for more - // details. - prevent_faerie_gold.reset(new PRF_rho_gadget( - pb, - ZERO, - phi, - h_sig, - nonce, - rho - )); - - // Commit to the output notes publicly without - // disclosing them. - commit_to_outputs.reset(new note_commitment_gadget( - pb, - ZERO, - a_pk->bits, - this->value, - rho->bits, - this->r->bits, - commitment - )); - } - - void generate_r1cs_constraints() { - note_gadget::generate_r1cs_constraints(); - - a_pk->generate_r1cs_constraints(); - - prevent_faerie_gold->generate_r1cs_constraints(); - - commit_to_outputs->generate_r1cs_constraints(); - } - - void generate_r1cs_witness(const SproutNote& note) { - note_gadget::generate_r1cs_witness(note); - - prevent_faerie_gold->generate_r1cs_witness(); - - // [SANITY CHECK] Witness rho ourselves with the - // note information. - rho->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.rho) - ); - - a_pk->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.a_pk) - ); - - commit_to_outputs->generate_r1cs_witness(); - } -}; diff --git a/src/zcash/circuit/prfs.tcc b/src/zcash/circuit/prfs.tcc deleted file mode 100644 index 3f50ac9e5..000000000 --- a/src/zcash/circuit/prfs.tcc +++ /dev/null @@ -1,109 +0,0 @@ -template -class PRF_gadget : gadget { -private: - std::shared_ptr> block; - std::shared_ptr> hasher; - std::shared_ptr> result; - -public: - PRF_gadget( - protoboard& pb, - pb_variable& ZERO, - bool a, - bool b, - bool c, - bool d, - pb_variable_array x, - pb_variable_array y, - std::shared_ptr> result - ) : gadget(pb), result(result) { - - pb_linear_combination_array IV = SHA256_default_IV(pb); - - pb_variable_array discriminants; - discriminants.emplace_back(a ? ONE : ZERO); - discriminants.emplace_back(b ? ONE : ZERO); - discriminants.emplace_back(c ? ONE : ZERO); - discriminants.emplace_back(d ? ONE : ZERO); - - block.reset(new block_variable(pb, { - discriminants, - x, - y - }, "PRF_block")); - - hasher.reset(new sha256_compression_function_gadget( - pb, - IV, - block->bits, - *result, - "PRF_hasher")); - } - - void generate_r1cs_constraints() { - hasher->generate_r1cs_constraints(); - } - - void generate_r1cs_witness() { - hasher->generate_r1cs_witness(); - } -}; - -template -pb_variable_array gen256zeroes(pb_variable& ZERO) { - pb_variable_array ret; - while (ret.size() < 256) { - ret.emplace_back(ZERO); - } - - return ret; -} - -template -class PRF_addr_a_pk_gadget : public PRF_gadget { -public: - PRF_addr_a_pk_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& a_sk, - std::shared_ptr> result - ) : PRF_gadget(pb, ZERO, 1, 1, 0, 0, a_sk, gen256zeroes(ZERO), result) {} -}; - -template -class PRF_nf_gadget : public PRF_gadget { -public: - PRF_nf_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& a_sk, - pb_variable_array& rho, - std::shared_ptr> result - ) : PRF_gadget(pb, ZERO, 1, 1, 1, 0, a_sk, rho, result) {} -}; - -template -class PRF_pk_gadget : public PRF_gadget { -public: - PRF_pk_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& a_sk, - pb_variable_array& h_sig, - bool nonce, - std::shared_ptr> result - ) : PRF_gadget(pb, ZERO, 0, nonce, 0, 0, a_sk, h_sig, result) {} -}; - -template -class PRF_rho_gadget : public PRF_gadget { -public: - PRF_rho_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& phi, - pb_variable_array& h_sig, - bool nonce, - std::shared_ptr> result - ) : PRF_gadget(pb, ZERO, 0, nonce, 1, 0, phi, h_sig, result) {} -}; diff --git a/src/zcash/circuit/utils.tcc b/src/zcash/circuit/utils.tcc deleted file mode 100644 index fa7ae324a..000000000 --- a/src/zcash/circuit/utils.tcc +++ /dev/null @@ -1,75 +0,0 @@ -#include "uint252.h" - -template -pb_variable_array from_bits(std::vector bits, pb_variable& ZERO) { - pb_variable_array acc; - - BOOST_FOREACH(bool bit, bits) { - acc.emplace_back(bit ? ONE : ZERO); - } - - return acc; -} - -std::vector trailing252(std::vector input) { - if (input.size() != 256) { - throw std::length_error("trailing252 input invalid length"); - } - - return std::vector(input.begin() + 4, input.end()); -} - -template -std::vector to_bool_vector(T input) { - std::vector input_v(input.begin(), input.end()); - - return convertBytesVectorToVector(input_v); -} - -std::vector uint256_to_bool_vector(uint256 input) { - return to_bool_vector(input); -} - -std::vector uint252_to_bool_vector(uint252 input) { - return trailing252(to_bool_vector(input)); -} - -std::vector uint64_to_bool_vector(uint64_t input) { - auto num_bv = convertIntToVectorLE(input); - - return convertBytesVectorToVector(num_bv); -} - -void insert_uint256(std::vector& into, uint256 from) { - std::vector blob = uint256_to_bool_vector(from); - into.insert(into.end(), blob.begin(), blob.end()); -} - -void insert_uint64(std::vector& into, uint64_t from) { - std::vector num = uint64_to_bool_vector(from); - into.insert(into.end(), num.begin(), num.end()); -} - -template -T swap_endianness_u64(T v) { - if (v.size() != 64) { - throw std::length_error("invalid bit length for 64-bit unsigned integer"); - } - - for (size_t i = 0; i < 4; i++) { - for (size_t j = 0; j < 8; j++) { - std::swap(v[i*8 + j], v[((7-i)*8)+j]); - } - } - - return v; -} - -template -linear_combination packed_addition(pb_variable_array input) { - auto input_swapped = swap_endianness_u64(input); - - return pb_packing_sum(pb_variable_array( - input_swapped.rbegin(), input_swapped.rend() - )); -} diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 209b820b8..c3783e97a 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #include #include #include @@ -91,24 +93,6 @@ double benchmark_sleep() return timer_stop(tv_start); } -double benchmark_parameter_loading() -{ - // FIXME: this is duplicated with the actual loading code - boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key"; - boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key"; - - struct timeval tv_start; - timer_start(tv_start); - - auto newParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string()); - - double ret = timer_stop(tv_start); - - delete newParams; - - return ret; -} - double benchmark_create_joinsplit() { uint256 joinSplitPubKey; @@ -118,8 +102,7 @@ double benchmark_create_joinsplit() struct timeval tv_start; timer_start(tv_start); - JSDescription jsdesc(true, - *pzcashParams, + JSDescription jsdesc(*pzcashParams, joinSplitPubKey, anchor, {JSInput(), JSInput()}, diff --git a/src/zcbenchmarks.h b/src/zcbenchmarks.h index 363823838..49cf4b749 100644 --- a/src/zcbenchmarks.h +++ b/src/zcbenchmarks.h @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers #ifndef BENCHMARKS_H #define BENCHMARKS_H @@ -5,7 +6,6 @@ #include extern double benchmark_sleep(); -extern double benchmark_parameter_loading(); extern double benchmark_create_joinsplit(); extern std::vector benchmark_create_joinsplit_threaded(int nThreads); extern double benchmark_solve_equihash(); diff --git a/zcutil/build-win.sh b/zcutil/build-win.sh index e8c0465d9..ccf6657e8 100755 --- a/zcutil/build-win.sh +++ b/zcutil/build-win.sh @@ -18,7 +18,7 @@ echo $PWD cd $WD ./autogen.sh -CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site CXXFLAGS="-DPTW32_STATIC_LIB -DCURL_STATICLIB -DCURVE_ALT_BN128 -fopenmp -pthread" ./configure --prefix="${PREFIX}" --host=x86_64-w64-mingw32 --enable-static --disable-shared +CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site CXXFLAGS="-DPTW32_STATIC_LIB -DCURL_STATICLIB -fopenmp -pthread" ./configure --prefix="${PREFIX}" --host=x86_64-w64-mingw32 --enable-static --disable-shared sed -i 's/-lboost_system-mt /-lboost_system-mt-s /' configure cd src/ CC="${CC} -g " CXX="${CXX} -g " make V=1 komodod.exe komodo-cli.exe komodo-tx.exe