mirror of
https://git.hush.is/hush/hush3.git
synced 2025-09-24 00:04:19 -04:00
A bunch more libsnark deletions/updates
This commit is contained in:
parent
7e078e58c1
commit
4d965f53eb
@ -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 <stevenj@alum.mit.edu>
|
||||
# Copyright (c) 2015 John W. Peterson <jwpeterson@gmail.com>
|
||||
# Copyright (c) 2016 Nick R. Papior <nickpapior@gmail.com>
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# 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 <omp.h>
|
||||
|
||||
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
|
33
configure.ac
33
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])
|
||||
|
@ -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
|
@ -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 := \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
zcash/zip32.cpp
|
||||
|
||||
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)
|
||||
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)
|
||||
|
@ -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)
|
||||
|
@ -5,9 +5,6 @@
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
#include "util.h"
|
||||
|
||||
#include <libsnark/common/default_types/r1cs_ppzksnark_pp.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
|
||||
#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";
|
||||
|
@ -1,183 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "uint256.h"
|
||||
|
||||
#include "zcash/util.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <libsnark/common/default_types/r1cs_ppzksnark_pp.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
#include <libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp>
|
||||
#include <libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp>
|
||||
|
||||
#include "zcash/IncrementalMerkleTree.hpp"
|
||||
|
||||
using namespace libsnark;
|
||||
using namespace libzcash;
|
||||
|
||||
#include "zcash/circuit/utils.tcc"
|
||||
#include "zcash/circuit/merkle.tcc"
|
||||
|
||||
template<typename FieldT>
|
||||
void test_value_equals(uint64_t i) {
|
||||
protoboard<FieldT> pb;
|
||||
pb_variable_array<FieldT> num;
|
||||
num.allocate(pb, 64, "");
|
||||
num.fill_with_bits(pb, uint64_to_bool_vector(i));
|
||||
pb.add_r1cs_constraint(r1cs_constraint<FieldT>(
|
||||
packed_addition(num),
|
||||
FieldT::one(),
|
||||
FieldT::one() * i
|
||||
), "");
|
||||
ASSERT_TRUE(pb.is_satisfied());
|
||||
}
|
||||
|
||||
TEST(circuit, values)
|
||||
{
|
||||
typedef Fr<default_r1cs_ppzksnark_pp> FieldT;
|
||||
test_value_equals<FieldT>(0);
|
||||
test_value_equals<FieldT>(1);
|
||||
test_value_equals<FieldT>(3);
|
||||
test_value_equals<FieldT>(5391);
|
||||
test_value_equals<FieldT>(883128374);
|
||||
test_value_equals<FieldT>(173419028459);
|
||||
test_value_equals<FieldT>(2205843009213693953);
|
||||
}
|
||||
|
||||
TEST(circuit, endianness)
|
||||
{
|
||||
std::vector<unsigned char> 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<unsigned char> 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<unsigned char> bad = {0, 1, 2, 3};
|
||||
|
||||
ASSERT_THROW(swap_endianness_u64(bad), std::length_error);
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
bool test_merkle_gadget(
|
||||
bool enforce_a,
|
||||
bool enforce_b,
|
||||
bool write_root_first
|
||||
)
|
||||
{
|
||||
protoboard<FieldT> pb;
|
||||
digest_variable<FieldT> root(pb, 256, "root");
|
||||
pb.set_input_sizes(256);
|
||||
|
||||
digest_variable<FieldT> commitment1(pb, 256, "commitment1");
|
||||
digest_variable<FieldT> commitment2(pb, 256, "commitment2");
|
||||
|
||||
pb_variable<FieldT> commitment1_read;
|
||||
commitment1_read.allocate(pb);
|
||||
pb_variable<FieldT> commitment2_read;
|
||||
commitment2_read.allocate(pb);
|
||||
|
||||
merkle_tree_gadget<FieldT> mgadget1(pb, commitment1, root, commitment1_read);
|
||||
merkle_tree_gadget<FieldT> 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<default_r1cs_ppzksnark_pp> FieldT;
|
||||
|
||||
// Test the normal case
|
||||
ASSERT_TRUE(test_merkle_gadget<FieldT>(true, true, false));
|
||||
ASSERT_TRUE(test_merkle_gadget<FieldT>(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<FieldT>(true, false, false));
|
||||
ASSERT_TRUE(test_merkle_gadget<FieldT>(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<FieldT>(false, true, false));
|
||||
|
||||
// Test the last again, except this time write the root first.
|
||||
ASSERT_TRUE(test_merkle_gadget<FieldT>(false, true, true));
|
||||
}
|
@ -22,10 +22,9 @@ using namespace libzcash;
|
||||
|
||||
extern ZCJoinSplit* params;
|
||||
|
||||
typedef std::array<JSDescription, 2> 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<JSInput, 2>& inputs,
|
||||
const std::array<JSOutput, 2>& 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<JSInput, 2> inputs = {
|
||||
@ -89,7 +80,7 @@ void test_full_api(ZCJoinSplit* js)
|
||||
std::array<SproutNote, 2> 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<SproutNote, 2> 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,
|
||||
|
@ -1,14 +1,12 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#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 <libsnark/common/default_types/r1cs_ppzksnark_pp.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
#include <libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp>
|
||||
#include <libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#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<default_r1cs_ppzksnark_pp> FieldT;
|
||||
|
||||
protoboard<FieldT> pb;
|
||||
pb_variable_array<FieldT> positions;
|
||||
digest_variable<FieldT> commitment(pb, 256, "commitment");
|
||||
digest_variable<FieldT> root(pb, 256, "root");
|
||||
positions.allocate(pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, "pos");
|
||||
merkle_authentication_path_variable<FieldT, sha256_two_to_one_hash_gadget<FieldT>> authvars(pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, "auth");
|
||||
merkle_tree_check_read_gadget<FieldT, sha256_two_to_one_hash_gadget<FieldT>> 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<bool> commitment_bv;
|
||||
{
|
||||
uint256 witnessed_commitment = wit.element();
|
||||
std::vector<unsigned char> 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<bool> root_bv;
|
||||
{
|
||||
uint256 witroot = wit.root();
|
||||
std::vector<unsigned char> 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<libzcash::SHA256Compress, 65> 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<libzcash::PedersenHash, 63> 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");
|
||||
|
@ -1,702 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "zcash/Proof.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <libsnark/common/default_types/r1cs_ppzksnark_pp.hpp>
|
||||
#include <libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
|
||||
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<curve_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<curve_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<curve_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<curve_Fq2>();
|
||||
|
||||
ASSERT_TRUE(e == e4);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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<Fq>(s).to_libsnark_fq<curve_Fq>();
|
||||
}
|
||||
|
||||
curve_Fq2 deserialize_fq2(std::string s)
|
||||
{
|
||||
return deserialize_tv<Fq2>(s).to_libsnark_fq2<curve_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<curve_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<curve_G2>();
|
||||
|
||||
ASSERT_TRUE(e == e4);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(proofs, zksnark_serializes_properly)
|
||||
{
|
||||
auto example = libsnark::generate_r1cs_example_with_field_input<curve_Fr>(250, 4);
|
||||
example.constraint_system.swap_AB_if_beneficial();
|
||||
auto kp = libsnark::r1cs_ppzksnark_generator<curve_pp>(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<libsnark::r1cs_ppzksnark_proof<curve_pp>>();
|
||||
|
||||
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<curve_pp>(
|
||||
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<curve_pp>(
|
||||
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<libsnark::r1cs_ppzksnark_proof<curve_pp>>();
|
||||
|
||||
ASSERT_TRUE(proof == newproof);
|
||||
ASSERT_TRUE(libsnark::r1cs_ppzksnark_verifier_strong_IC<curve_pp>(
|
||||
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<curve_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<curve_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<curve_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<curve_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<curve_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<curve_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<curve_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<curve_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<curve_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<curve_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<curve_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<curve_G2>() == e);
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#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;
|
||||
}
|
@ -35,6 +35,391 @@ PedersenHash PedersenHash::uncommitted() {
|
||||
return res;
|
||||
}
|
||||
|
||||
static const std::array<PedersenHash, 65> pedersen_empty_roots = {
|
||||
uint256(std::vector<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<SHA256Compress, 66> sha256_empty_roots = {
|
||||
uint256(std::vector<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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<unsigned char>{
|
||||
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 <size_t Depth, typename Hash>
|
||||
class PathFiller {
|
||||
private:
|
||||
|
@ -57,14 +57,9 @@ public:
|
||||
template<size_t Depth, typename Hash>
|
||||
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 <size_t D, typename H>
|
||||
friend bool operator==(const EmptyMerkleRoots<D, H>& 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<size_t Depth, typename Hash>
|
||||
|
@ -3,249 +3,16 @@
|
||||
#include "crypto/common.h"
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <libsnark/common/default_types/r1cs_ppzksnark_pp.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
#include <mutex>
|
||||
|
||||
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<mp_size_t LIMBS>
|
||||
void write_bigint(base_blob<8 * LIMBS * sizeof(mp_limb_t)> &blob, const bigint<LIMBS> &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<mp_size_t LIMBS>
|
||||
bigint<LIMBS> read_bigint(const base_blob<8 * LIMBS * sizeof(mp_limb_t)> &blob)
|
||||
{
|
||||
bigint<LIMBS> 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<curve_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<curve_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<curve_pp> &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<curve_pp> PHGRProof::to_libsnark_proof() const
|
||||
{
|
||||
r1cs_ppzksnark_proof<curve_pp> proof;
|
||||
|
||||
proof.g_A.g = g_A.to_libsnark_g1<curve_G1>();
|
||||
proof.g_A.h = g_A_prime.to_libsnark_g1<curve_G1>();
|
||||
proof.g_B.g = g_B.to_libsnark_g2<curve_G2>();
|
||||
proof.g_B.h = g_B_prime.to_libsnark_g1<curve_G1>();
|
||||
proof.g_C.g = g_C.to_libsnark_g1<curve_G1>();
|
||||
proof.g_C.h = g_C_prime.to_libsnark_g1<curve_G1>();
|
||||
proof.g_K = g_K.to_libsnark_g1<curve_G1>();
|
||||
proof.g_H = g_H.to_libsnark_g1<curve_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<curve_pp>& vk,
|
||||
const r1cs_ppzksnark_processed_verification_key<curve_pp>& pvk,
|
||||
const r1cs_primary_input<curve_Fr>& primary_input,
|
||||
const r1cs_ppzksnark_proof<curve_pp>& proof
|
||||
)
|
||||
{
|
||||
if (perform_verification) {
|
||||
return r1cs_ppzksnark_online_verifier_strong_IC<curve_pp>(pvk, primary_input, proof);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,12 +16,6 @@ private:
|
||||
public:
|
||||
Fq() : data() { }
|
||||
|
||||
template<typename libsnark_Fq>
|
||||
Fq(libsnark_Fq element);
|
||||
|
||||
template<typename libsnark_Fq>
|
||||
libsnark_Fq to_libsnark_fq() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
@ -49,12 +43,6 @@ private:
|
||||
public:
|
||||
Fq2() : data() { }
|
||||
|
||||
template<typename libsnark_Fq2>
|
||||
Fq2(libsnark_Fq2 element);
|
||||
|
||||
template<typename libsnark_Fq2>
|
||||
libsnark_Fq2 to_libsnark_fq2() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
@ -84,12 +72,6 @@ private:
|
||||
public:
|
||||
CompressedG1() : y_lsb(false), x() { }
|
||||
|
||||
template<typename libsnark_G1>
|
||||
CompressedG1(libsnark_G1 point);
|
||||
|
||||
template<typename libsnark_G1>
|
||||
libsnark_G1 to_libsnark_g1() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
@ -134,12 +116,6 @@ private:
|
||||
public:
|
||||
CompressedG2() : y_gt(false), x() { }
|
||||
|
||||
template<typename libsnark_G2>
|
||||
CompressedG2(libsnark_G2 point);
|
||||
|
||||
template<typename libsnark_G2>
|
||||
libsnark_G2 to_libsnark_g2() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
@ -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<typename libsnark_proof>
|
||||
PHGRProof(const libsnark_proof& proof);
|
||||
|
||||
// Produces a libsnark zkSNARK proof out of this proof,
|
||||
// or throws an exception if it is invalid.
|
||||
template<typename libsnark_proof>
|
||||
libsnark_proof to_libsnark_proof() const;
|
||||
|
||||
static PHGRProof random_invalid();
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
|
@ -1,100 +0,0 @@
|
||||
template<typename FieldT>
|
||||
class note_commitment_gadget : gadget<FieldT> {
|
||||
private:
|
||||
std::shared_ptr<block_variable<FieldT>> block1;
|
||||
std::shared_ptr<block_variable<FieldT>> block2;
|
||||
std::shared_ptr<sha256_compression_function_gadget<FieldT>> hasher1;
|
||||
std::shared_ptr<digest_variable<FieldT>> intermediate_hash;
|
||||
std::shared_ptr<sha256_compression_function_gadget<FieldT>> hasher2;
|
||||
|
||||
public:
|
||||
note_commitment_gadget(
|
||||
protoboard<FieldT> &pb,
|
||||
pb_variable<FieldT>& ZERO,
|
||||
pb_variable_array<FieldT>& a_pk,
|
||||
pb_variable_array<FieldT>& v,
|
||||
pb_variable_array<FieldT>& rho,
|
||||
pb_variable_array<FieldT>& r,
|
||||
std::shared_ptr<digest_variable<FieldT>> result
|
||||
) : gadget<FieldT>(pb) {
|
||||
pb_variable_array<FieldT> leading_byte =
|
||||
from_bits({1, 0, 1, 1, 0, 0, 0, 0}, ZERO);
|
||||
|
||||
pb_variable_array<FieldT> first_of_rho(rho.begin(), rho.begin()+184);
|
||||
pb_variable_array<FieldT> last_of_rho(rho.begin()+184, rho.end());
|
||||
|
||||
intermediate_hash.reset(new digest_variable<FieldT>(pb, 256, ""));
|
||||
|
||||
// final padding
|
||||
pb_variable_array<FieldT> 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<FieldT>(pb, {
|
||||
leading_byte,
|
||||
a_pk,
|
||||
v,
|
||||
first_of_rho
|
||||
}, ""));
|
||||
|
||||
block2.reset(new block_variable<FieldT>(pb, {
|
||||
last_of_rho,
|
||||
r,
|
||||
length_padding
|
||||
}, ""));
|
||||
|
||||
pb_linear_combination_array<FieldT> IV = SHA256_default_IV(pb);
|
||||
|
||||
hasher1.reset(new sha256_compression_function_gadget<FieldT>(
|
||||
pb,
|
||||
IV,
|
||||
block1->bits,
|
||||
*intermediate_hash,
|
||||
""));
|
||||
|
||||
pb_linear_combination_array<FieldT> IV2(intermediate_hash->bits);
|
||||
|
||||
hasher2.reset(new sha256_compression_function_gadget<FieldT>(
|
||||
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();
|
||||
}
|
||||
};
|
@ -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<typename FieldT, size_t NumInputs, size_t NumOutputs>
|
||||
class joinsplit_gadget : gadget<FieldT> {
|
||||
private:
|
||||
// Verifier inputs
|
||||
pb_variable_array<FieldT> zk_packed_inputs;
|
||||
pb_variable_array<FieldT> zk_unpacked_inputs;
|
||||
std::shared_ptr<multipacking_gadget<FieldT>> unpacker;
|
||||
|
||||
std::shared_ptr<digest_variable<FieldT>> zk_merkle_root;
|
||||
std::shared_ptr<digest_variable<FieldT>> zk_h_sig;
|
||||
std::array<std::shared_ptr<digest_variable<FieldT>>, NumInputs> zk_input_nullifiers;
|
||||
std::array<std::shared_ptr<digest_variable<FieldT>>, NumInputs> zk_input_macs;
|
||||
std::array<std::shared_ptr<digest_variable<FieldT>>, NumOutputs> zk_output_commitments;
|
||||
pb_variable_array<FieldT> zk_vpub_old;
|
||||
pb_variable_array<FieldT> zk_vpub_new;
|
||||
|
||||
// Aux inputs
|
||||
pb_variable<FieldT> ZERO;
|
||||
std::shared_ptr<digest_variable<FieldT>> zk_phi;
|
||||
pb_variable_array<FieldT> zk_total_uint64;
|
||||
|
||||
// Input note gadgets
|
||||
std::array<std::shared_ptr<input_note_gadget<FieldT>>, NumInputs> zk_input_notes;
|
||||
std::array<std::shared_ptr<PRF_pk_gadget<FieldT>>, NumInputs> zk_mac_authentication;
|
||||
|
||||
// Output note gadgets
|
||||
std::array<std::shared_ptr<output_note_gadget<FieldT>>, 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<FieldT> &pb) : gadget<FieldT>(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<FieldT>(
|
||||
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<FieldT>(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<FieldT>(
|
||||
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<FieldT>(
|
||||
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<FieldT>(
|
||||
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<FieldT>(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<FieldT> 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<FieldT> 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<FieldT>(
|
||||
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<FieldT>(
|
||||
this->pb,
|
||||
zk_total_uint64[i],
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
this->pb.add_r1cs_constraint(r1cs_constraint<FieldT>(
|
||||
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<JSInput, NumInputs>& inputs,
|
||||
const std::array<SproutNote, NumOutputs>& 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<FieldT> witness_map(
|
||||
const uint256& rt,
|
||||
const uint256& h_sig,
|
||||
const std::array<uint256, NumInputs>& macs,
|
||||
const std::array<uint256, NumInputs>& nullifiers,
|
||||
const std::array<uint256, NumOutputs>& commitments,
|
||||
uint64_t vpub_old,
|
||||
uint64_t vpub_new
|
||||
) {
|
||||
std::vector<bool> 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<FieldT>(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<FieldT>& packed_into,
|
||||
std::shared_ptr<digest_variable<FieldT>>& var
|
||||
) {
|
||||
var.reset(new digest_variable<FieldT>(this->pb, 256, ""));
|
||||
packed_into.insert(packed_into.end(), var->bits.begin(), var->bits.end());
|
||||
}
|
||||
|
||||
void alloc_uint64(
|
||||
pb_variable_array<FieldT>& packed_into,
|
||||
pb_variable_array<FieldT>& integer
|
||||
) {
|
||||
integer.allocate(this->pb, 64, "");
|
||||
packed_into.insert(packed_into.end(), integer.begin(), integer.end());
|
||||
}
|
||||
};
|
@ -1,60 +0,0 @@
|
||||
template<typename FieldT>
|
||||
class merkle_tree_gadget : gadget<FieldT> {
|
||||
private:
|
||||
typedef sha256_two_to_one_hash_gadget<FieldT> sha256_gadget;
|
||||
|
||||
pb_variable_array<FieldT> positions;
|
||||
std::shared_ptr<merkle_authentication_path_variable<FieldT, sha256_gadget>> authvars;
|
||||
std::shared_ptr<merkle_tree_check_read_gadget<FieldT, sha256_gadget>> auth;
|
||||
|
||||
public:
|
||||
merkle_tree_gadget(
|
||||
protoboard<FieldT>& pb,
|
||||
digest_variable<FieldT> leaf,
|
||||
digest_variable<FieldT> root,
|
||||
pb_variable<FieldT>& enforce
|
||||
) : gadget<FieldT>(pb) {
|
||||
positions.allocate(pb, INCREMENTAL_MERKLE_TREE_DEPTH);
|
||||
authvars.reset(new merkle_authentication_path_variable<FieldT, sha256_gadget>(
|
||||
pb, INCREMENTAL_MERKLE_TREE_DEPTH, "auth"
|
||||
));
|
||||
auth.reset(new merkle_tree_check_read_gadget<FieldT, sha256_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<FieldT>(
|
||||
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();
|
||||
}
|
||||
};
|
@ -1,244 +0,0 @@
|
||||
template<typename FieldT>
|
||||
class note_gadget : public gadget<FieldT> {
|
||||
public:
|
||||
pb_variable_array<FieldT> value;
|
||||
std::shared_ptr<digest_variable<FieldT>> r;
|
||||
|
||||
note_gadget(protoboard<FieldT> &pb) : gadget<FieldT>(pb) {
|
||||
value.allocate(pb, 64);
|
||||
r.reset(new digest_variable<FieldT>(pb, 256, ""));
|
||||
}
|
||||
|
||||
void generate_r1cs_constraints() {
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
generate_boolean_r1cs_constraint<FieldT>(
|
||||
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<typename FieldT>
|
||||
class input_note_gadget : public note_gadget<FieldT> {
|
||||
private:
|
||||
std::shared_ptr<digest_variable<FieldT>> a_pk;
|
||||
std::shared_ptr<digest_variable<FieldT>> rho;
|
||||
|
||||
std::shared_ptr<digest_variable<FieldT>> commitment;
|
||||
std::shared_ptr<note_commitment_gadget<FieldT>> commit_to_inputs;
|
||||
|
||||
pb_variable<FieldT> value_enforce;
|
||||
std::shared_ptr<merkle_tree_gadget<FieldT>> witness_input;
|
||||
|
||||
std::shared_ptr<PRF_addr_a_pk_gadget<FieldT>> spend_authority;
|
||||
std::shared_ptr<PRF_nf_gadget<FieldT>> expose_nullifiers;
|
||||
public:
|
||||
std::shared_ptr<digest_variable<FieldT>> a_sk;
|
||||
|
||||
input_note_gadget(
|
||||
protoboard<FieldT>& pb,
|
||||
pb_variable<FieldT>& ZERO,
|
||||
std::shared_ptr<digest_variable<FieldT>> nullifier,
|
||||
digest_variable<FieldT> rt
|
||||
) : note_gadget<FieldT>(pb) {
|
||||
a_sk.reset(new digest_variable<FieldT>(pb, 252, ""));
|
||||
a_pk.reset(new digest_variable<FieldT>(pb, 256, ""));
|
||||
rho.reset(new digest_variable<FieldT>(pb, 256, ""));
|
||||
commitment.reset(new digest_variable<FieldT>(pb, 256, ""));
|
||||
|
||||
spend_authority.reset(new PRF_addr_a_pk_gadget<FieldT>(
|
||||
pb,
|
||||
ZERO,
|
||||
a_sk->bits,
|
||||
a_pk
|
||||
));
|
||||
|
||||
expose_nullifiers.reset(new PRF_nf_gadget<FieldT>(
|
||||
pb,
|
||||
ZERO,
|
||||
a_sk->bits,
|
||||
rho->bits,
|
||||
nullifier
|
||||
));
|
||||
|
||||
commit_to_inputs.reset(new note_commitment_gadget<FieldT>(
|
||||
pb,
|
||||
ZERO,
|
||||
a_pk->bits,
|
||||
this->value,
|
||||
rho->bits,
|
||||
this->r->bits,
|
||||
commitment
|
||||
));
|
||||
|
||||
value_enforce.allocate(pb);
|
||||
|
||||
witness_input.reset(new merkle_tree_gadget<FieldT>(
|
||||
pb,
|
||||
*commitment,
|
||||
rt,
|
||||
value_enforce
|
||||
));
|
||||
}
|
||||
|
||||
void generate_r1cs_constraints() {
|
||||
note_gadget<FieldT>::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<FieldT>(this->pb, value_enforce,"");
|
||||
|
||||
this->pb.add_r1cs_constraint(r1cs_constraint<FieldT>(
|
||||
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<FieldT>::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<typename FieldT>
|
||||
class output_note_gadget : public note_gadget<FieldT> {
|
||||
private:
|
||||
std::shared_ptr<digest_variable<FieldT>> rho;
|
||||
std::shared_ptr<digest_variable<FieldT>> a_pk;
|
||||
|
||||
std::shared_ptr<PRF_rho_gadget<FieldT>> prevent_faerie_gold;
|
||||
std::shared_ptr<note_commitment_gadget<FieldT>> commit_to_outputs;
|
||||
|
||||
public:
|
||||
output_note_gadget(
|
||||
protoboard<FieldT>& pb,
|
||||
pb_variable<FieldT>& ZERO,
|
||||
pb_variable_array<FieldT>& phi,
|
||||
pb_variable_array<FieldT>& h_sig,
|
||||
bool nonce,
|
||||
std::shared_ptr<digest_variable<FieldT>> commitment
|
||||
) : note_gadget<FieldT>(pb) {
|
||||
rho.reset(new digest_variable<FieldT>(pb, 256, ""));
|
||||
a_pk.reset(new digest_variable<FieldT>(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<FieldT>(
|
||||
pb,
|
||||
ZERO,
|
||||
phi,
|
||||
h_sig,
|
||||
nonce,
|
||||
rho
|
||||
));
|
||||
|
||||
// Commit to the output notes publicly without
|
||||
// disclosing them.
|
||||
commit_to_outputs.reset(new note_commitment_gadget<FieldT>(
|
||||
pb,
|
||||
ZERO,
|
||||
a_pk->bits,
|
||||
this->value,
|
||||
rho->bits,
|
||||
this->r->bits,
|
||||
commitment
|
||||
));
|
||||
}
|
||||
|
||||
void generate_r1cs_constraints() {
|
||||
note_gadget<FieldT>::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<FieldT>::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();
|
||||
}
|
||||
};
|
@ -1,109 +0,0 @@
|
||||
template<typename FieldT>
|
||||
class PRF_gadget : gadget<FieldT> {
|
||||
private:
|
||||
std::shared_ptr<block_variable<FieldT>> block;
|
||||
std::shared_ptr<sha256_compression_function_gadget<FieldT>> hasher;
|
||||
std::shared_ptr<digest_variable<FieldT>> result;
|
||||
|
||||
public:
|
||||
PRF_gadget(
|
||||
protoboard<FieldT>& pb,
|
||||
pb_variable<FieldT>& ZERO,
|
||||
bool a,
|
||||
bool b,
|
||||
bool c,
|
||||
bool d,
|
||||
pb_variable_array<FieldT> x,
|
||||
pb_variable_array<FieldT> y,
|
||||
std::shared_ptr<digest_variable<FieldT>> result
|
||||
) : gadget<FieldT>(pb), result(result) {
|
||||
|
||||
pb_linear_combination_array<FieldT> IV = SHA256_default_IV(pb);
|
||||
|
||||
pb_variable_array<FieldT> 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<FieldT>(pb, {
|
||||
discriminants,
|
||||
x,
|
||||
y
|
||||
}, "PRF_block"));
|
||||
|
||||
hasher.reset(new sha256_compression_function_gadget<FieldT>(
|
||||
pb,
|
||||
IV,
|
||||
block->bits,
|
||||
*result,
|
||||
"PRF_hasher"));
|
||||
}
|
||||
|
||||
void generate_r1cs_constraints() {
|
||||
hasher->generate_r1cs_constraints();
|
||||
}
|
||||
|
||||
void generate_r1cs_witness() {
|
||||
hasher->generate_r1cs_witness();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename FieldT>
|
||||
pb_variable_array<FieldT> gen256zeroes(pb_variable<FieldT>& ZERO) {
|
||||
pb_variable_array<FieldT> ret;
|
||||
while (ret.size() < 256) {
|
||||
ret.emplace_back(ZERO);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
class PRF_addr_a_pk_gadget : public PRF_gadget<FieldT> {
|
||||
public:
|
||||
PRF_addr_a_pk_gadget(
|
||||
protoboard<FieldT>& pb,
|
||||
pb_variable<FieldT>& ZERO,
|
||||
pb_variable_array<FieldT>& a_sk,
|
||||
std::shared_ptr<digest_variable<FieldT>> result
|
||||
) : PRF_gadget<FieldT>(pb, ZERO, 1, 1, 0, 0, a_sk, gen256zeroes(ZERO), result) {}
|
||||
};
|
||||
|
||||
template<typename FieldT>
|
||||
class PRF_nf_gadget : public PRF_gadget<FieldT> {
|
||||
public:
|
||||
PRF_nf_gadget(
|
||||
protoboard<FieldT>& pb,
|
||||
pb_variable<FieldT>& ZERO,
|
||||
pb_variable_array<FieldT>& a_sk,
|
||||
pb_variable_array<FieldT>& rho,
|
||||
std::shared_ptr<digest_variable<FieldT>> result
|
||||
) : PRF_gadget<FieldT>(pb, ZERO, 1, 1, 1, 0, a_sk, rho, result) {}
|
||||
};
|
||||
|
||||
template<typename FieldT>
|
||||
class PRF_pk_gadget : public PRF_gadget<FieldT> {
|
||||
public:
|
||||
PRF_pk_gadget(
|
||||
protoboard<FieldT>& pb,
|
||||
pb_variable<FieldT>& ZERO,
|
||||
pb_variable_array<FieldT>& a_sk,
|
||||
pb_variable_array<FieldT>& h_sig,
|
||||
bool nonce,
|
||||
std::shared_ptr<digest_variable<FieldT>> result
|
||||
) : PRF_gadget<FieldT>(pb, ZERO, 0, nonce, 0, 0, a_sk, h_sig, result) {}
|
||||
};
|
||||
|
||||
template<typename FieldT>
|
||||
class PRF_rho_gadget : public PRF_gadget<FieldT> {
|
||||
public:
|
||||
PRF_rho_gadget(
|
||||
protoboard<FieldT>& pb,
|
||||
pb_variable<FieldT>& ZERO,
|
||||
pb_variable_array<FieldT>& phi,
|
||||
pb_variable_array<FieldT>& h_sig,
|
||||
bool nonce,
|
||||
std::shared_ptr<digest_variable<FieldT>> result
|
||||
) : PRF_gadget<FieldT>(pb, ZERO, 0, nonce, 1, 0, phi, h_sig, result) {}
|
||||
};
|
@ -1,75 +0,0 @@
|
||||
#include "uint252.h"
|
||||
|
||||
template<typename FieldT>
|
||||
pb_variable_array<FieldT> from_bits(std::vector<bool> bits, pb_variable<FieldT>& ZERO) {
|
||||
pb_variable_array<FieldT> acc;
|
||||
|
||||
BOOST_FOREACH(bool bit, bits) {
|
||||
acc.emplace_back(bit ? ONE : ZERO);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
std::vector<bool> trailing252(std::vector<bool> input) {
|
||||
if (input.size() != 256) {
|
||||
throw std::length_error("trailing252 input invalid length");
|
||||
}
|
||||
|
||||
return std::vector<bool>(input.begin() + 4, input.end());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<bool> to_bool_vector(T input) {
|
||||
std::vector<unsigned char> input_v(input.begin(), input.end());
|
||||
|
||||
return convertBytesVectorToVector(input_v);
|
||||
}
|
||||
|
||||
std::vector<bool> uint256_to_bool_vector(uint256 input) {
|
||||
return to_bool_vector(input);
|
||||
}
|
||||
|
||||
std::vector<bool> uint252_to_bool_vector(uint252 input) {
|
||||
return trailing252(to_bool_vector(input));
|
||||
}
|
||||
|
||||
std::vector<bool> uint64_to_bool_vector(uint64_t input) {
|
||||
auto num_bv = convertIntToVectorLE(input);
|
||||
|
||||
return convertBytesVectorToVector(num_bv);
|
||||
}
|
||||
|
||||
void insert_uint256(std::vector<bool>& into, uint256 from) {
|
||||
std::vector<bool> blob = uint256_to_bool_vector(from);
|
||||
into.insert(into.end(), blob.begin(), blob.end());
|
||||
}
|
||||
|
||||
void insert_uint64(std::vector<bool>& into, uint64_t from) {
|
||||
std::vector<bool> num = uint64_to_bool_vector(from);
|
||||
into.insert(into.end(), num.begin(), num.end());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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<typename FieldT>
|
||||
linear_combination<FieldT> packed_addition(pb_variable_array<FieldT> input) {
|
||||
auto input_swapped = swap_endianness_u64(input);
|
||||
|
||||
return pb_packing_sum<FieldT>(pb_variable_array<FieldT>(
|
||||
input_swapped.rbegin(), input_swapped.rend()
|
||||
));
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
|
||||
#include <cstdio>
|
||||
#include <future>
|
||||
#include <map>
|
||||
@ -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()},
|
||||
|
@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
#ifndef BENCHMARKS_H
|
||||
#define BENCHMARKS_H
|
||||
|
||||
@ -5,7 +6,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
extern double benchmark_sleep();
|
||||
extern double benchmark_parameter_loading();
|
||||
extern double benchmark_create_joinsplit();
|
||||
extern std::vector<double> benchmark_create_joinsplit_threaded(int nThreads);
|
||||
extern double benchmark_solve_equihash();
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user