diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4c162ba6a..19850e969 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,12 +51,3 @@ jobs: submodules: recursive - name: Execute run: CI_CHECK_FORMAT=1 CI_USE_DOCKER=1 CI_CONFIG=${{ matrix.config }} scripts/ci build - - build-linux-release-pghr13: - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v1 - with: - submodules: recursive - - name: Execute - run: CI_USE_DOCKER=1 CI_CONFIG=Release CI_ZKSNARK=PGHR13 scripts/ci build diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d4037fee..171f22ab3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,8 @@ set(ZETH_VERSION_MINOR 3) # Configure a header file to pass some of the CMake settings # to the source code configure_file( - "${PROJECT_SOURCE_DIR}/zethConfig.h.in" - "${PROJECT_BINARY_DIR}/zethConfig.h" + "${PROJECT_SOURCE_DIR}/zeth_config.h.in" + "${PROJECT_BINARY_DIR}/zeth_config.h" ) # Flags and compilation options to chose the type of zksnark diff --git a/depends/libsnark b/depends/libsnark index d4b4b19ef..df467b716 160000 --- a/depends/libsnark +++ b/depends/libsnark @@ -1 +1 @@ -Subproject commit d4b4b19efdc8dc1659637eeb3baa59e3f31db79f +Subproject commit df467b716b9839507f3ea071cb7ad7c5c2b1f4ad diff --git a/libzeth/CMakeLists.txt b/libzeth/CMakeLists.txt index 52c4ee364..301ddf07b 100644 --- a/libzeth/CMakeLists.txt +++ b/libzeth/CMakeLists.txt @@ -38,21 +38,14 @@ string(TOLOWER ${ZKSNARK} ZKSNARK_NAME) file( GLOB_RECURSE ZETH_SOURCE - types/**.?pp types/**.tcc + + core/**.?pp core/**.tcc + snarks/**.?pp snarks/**.tcc + serialization/**.?pp serialization/**.tcc circuits/**.?pp circuits/**.tcc - circuit_wrapper.??? - commitments/**.?pp commitments/**.tcc - libsnark_helpers/**.?pp libsnark_helpers/**.tcc - snarks/${ZKSNARK_NAME}/core/**.??? - snarks/${ZKSNARK_NAME}/api/**.??? - # We only implement the MPC for Groth16 for now - snarks/groth16/mpc/**.??? - snarks_alias.hpp - include_libsnark.hpp - util.?pp util.tcc - util_api.?pp util_api.tcc - zeth.h + mpc/**.?pp mpc/**.tcc ) + add_library( zeth diff --git a/libzeth/circuits/binary_operation.hpp b/libzeth/circuits/binary_operation.hpp index b790a5f92..49810d5bf 100644 --- a/libzeth/circuits/binary_operation.hpp +++ b/libzeth/circuits/binary_operation.hpp @@ -5,8 +5,8 @@ #ifndef __ZETH_CIRCUITS_BINARY_OPERATION_HPP__ #define __ZETH_CIRCUITS_BINARY_OPERATION_HPP__ -#include "libzeth/circuits/circuits_utils.hpp" -#include "libzeth/types/bits.hpp" +#include "libzeth/circuits/circuit_utils.hpp" +#include "libzeth/core/bits.hpp" #include "math.h" #include @@ -45,7 +45,6 @@ template class xor_gadget : public libsnark::gadget template class xor_constant_gadget : public libsnark::gadget { - private: const libsnark::pb_variable_array a; const libsnark::pb_variable_array b; @@ -119,6 +118,7 @@ class double_bit32_sum_eq_gadget : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/binary_operation.tcc" -#endif // __ZETH_CIRCUITS_BINARY_OPERATION_HPP__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_BINARY_OPERATION_HPP__ diff --git a/libzeth/circuits/binary_operation.tcc b/libzeth/circuits/binary_operation.tcc index 920d2d605..c3aecabe2 100644 --- a/libzeth/circuits/binary_operation.tcc +++ b/libzeth/circuits/binary_operation.tcc @@ -5,8 +5,8 @@ #ifndef __ZETH_CIRCUITS_BINARY_OPERATION_TCC__ #define __ZETH_CIRCUITS_BINARY_OPERATION_TCC__ -#include "libzeth/circuits/circuits_utils.hpp" -#include "libzeth/types/bits.hpp" +#include "libzeth/circuits/circuit_utils.hpp" +#include "libzeth/core/bits.hpp" #include #include @@ -25,7 +25,7 @@ xor_gadget::xor_gadget( { assert(a.size() == b.size()); assert(b.size() == res.size()); -}; +} template void xor_gadget::generate_r1cs_constraints() { @@ -37,7 +37,7 @@ template void xor_gadget::generate_r1cs_constraints() 2 * a[i], b[i], a[i] + b[i] - res[i]), FMT(this->annotation_prefix, " xored_bits_%zu", i)); } -}; +} template void xor_gadget::generate_r1cs_witness() { @@ -49,7 +49,7 @@ template void xor_gadget::generate_r1cs_witness() this->pb.val(res[i]) = this->pb.val(a[i]) + this->pb.val(b[i]); } } -}; +} template xor_constant_gadget::xor_constant_gadget( @@ -68,7 +68,7 @@ xor_constant_gadget::xor_constant_gadget( assert(a.size() == b.size()); assert(b.size() == c.size()); assert(c.size() == res.size()); -}; +} template void xor_constant_gadget::generate_r1cs_constraints() @@ -97,7 +97,7 @@ void xor_constant_gadget::generate_r1cs_constraints() b[i] * (FieldT("1") - FieldT("2") * c[i])), FMT(this->annotation_prefix, " rotated_xored_bits_%zu", i)); } -}; +} template void xor_constant_gadget::generate_r1cs_witness() @@ -116,7 +116,7 @@ void xor_constant_gadget::generate_r1cs_witness() this->pb.val(res[i]) = FieldT("1"); } } -}; +} template xor_rot_gadget::xor_rot_gadget( @@ -134,7 +134,7 @@ xor_rot_gadget::xor_rot_gadget( { assert(a.size() == b.size()); assert(b.size() == res.size()); -}; +} template void xor_rot_gadget::generate_r1cs_constraints() @@ -146,7 +146,7 @@ void xor_rot_gadget::generate_r1cs_constraints() 2 * a[i], b[i], a[i] + b[i] - res[(i + shift) % a.size()]), FMT(this->annotation_prefix, " rotated_xored_bits_%zu", i)); } -}; +} template void xor_rot_gadget::generate_r1cs_witness() { @@ -160,7 +160,7 @@ template void xor_rot_gadget::generate_r1cs_witness() this->pb.val(a[i]) + this->pb.val(b[i]); } } -}; +} template double_bit32_sum_eq_gadget::double_bit32_sum_eq_gadget( @@ -174,7 +174,7 @@ double_bit32_sum_eq_gadget::double_bit32_sum_eq_gadget( assert(a.size() == 32); assert(a.size() == b.size()); assert(a.size() == res.size()); -}; +} template void double_bit32_sum_eq_gadget::generate_r1cs_constraints( @@ -246,7 +246,7 @@ void double_bit32_sum_eq_gadget::generate_r1cs_constraints( (left_side - packed_addition(res) - pow(2, 32)), 0), FMT(this->annotation_prefix, " sum_equal_sum_constraint")); -}; +} template void double_bit32_sum_eq_gadget::generate_r1cs_witness() @@ -260,8 +260,8 @@ void double_bit32_sum_eq_gadget::generate_r1cs_witness() bits32 left_side_acc = binary_addition<32>(a_bits32, b_bits32, false); res.fill_with_bits(this->pb, get_vector_from_bits32(left_side_acc)); -}; +} } // namespace libzeth -#endif // __ZETH_CIRCUITS_BINARY_OPERATION_TCC__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_BINARY_OPERATION_TCC__ diff --git a/libzeth/circuits/blake2s/blake2s.hpp b/libzeth/circuits/blake2s/blake2s.hpp index 8a9eb78eb..b362ada21 100644 --- a/libzeth/circuits/blake2s/blake2s.hpp +++ b/libzeth/circuits/blake2s/blake2s.hpp @@ -7,9 +7,9 @@ #include "libzeth/circuits/binary_operation.hpp" #include "libzeth/circuits/blake2s/blake2s_comp.hpp" -#include "libzeth/circuits/circuits_utils.hpp" -#include "libzeth/types/bits.hpp" -#include "libzeth/util.hpp" +#include "libzeth/circuits/circuit_utils.hpp" +#include "libzeth/core/bits.hpp" +#include "libzeth/core/utils.hpp" #include #include @@ -165,6 +165,7 @@ template class BLAKE2s_256 : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/blake2s/blake2s.tcc" #endif // __ZETH_CIRCUITS_BLAKE2S_HPP__ diff --git a/libzeth/circuits/blake2s/blake2s.tcc b/libzeth/circuits/blake2s/blake2s.tcc index be34a386b..6dd230f1a 100644 --- a/libzeth/circuits/blake2s/blake2s.tcc +++ b/libzeth/circuits/blake2s/blake2s.tcc @@ -10,6 +10,8 @@ namespace libzeth { +static const size_t BYTE_LEN = 8; + /// This gadget implements the interface of the HashT template template BLAKE2s_256::BLAKE2s_256( diff --git a/libzeth/circuits/blake2s/blake2s_comp.hpp b/libzeth/circuits/blake2s/blake2s_comp.hpp index f53b6a298..787767506 100644 --- a/libzeth/circuits/blake2s/blake2s_comp.hpp +++ b/libzeth/circuits/blake2s/blake2s_comp.hpp @@ -7,9 +7,9 @@ #include "libzeth/circuits/binary_operation.hpp" #include "libzeth/circuits/blake2s/g_primitive.hpp" -#include "libzeth/circuits/circuits_utils.hpp" -#include "libzeth/types/bits.hpp" -#include "libzeth/util.hpp" +#include "libzeth/circuits/circuit_utils.hpp" +#include "libzeth/core/bits.hpp" +#include "libzeth/core/utils.hpp" #include #include diff --git a/libzeth/circuits/blake2s/g_primitive.hpp b/libzeth/circuits/blake2s/g_primitive.hpp index 5e4d1947f..dc5c08df0 100644 --- a/libzeth/circuits/blake2s/g_primitive.hpp +++ b/libzeth/circuits/blake2s/g_primitive.hpp @@ -6,8 +6,8 @@ #define __ZETH_CIRCUITS_G_PRIMITIVE_HPP__ #include "libzeth/circuits/binary_operation.hpp" -#include "libzeth/circuits/circuits_utils.hpp" -#include "libzeth/types/bits.hpp" +#include "libzeth/circuits/circuit_utils.hpp" +#include "libzeth/core/bits.hpp" #include #include @@ -69,6 +69,7 @@ template class g_primitive : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/blake2s/g_primitive.tcc" -#endif // __ZETH_CIRCUITS_G_PRIMITIVE_HPP__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_G_PRIMITIVE_HPP__ diff --git a/libzeth/circuits/blake2s/g_primitive.tcc b/libzeth/circuits/blake2s/g_primitive.tcc index 3f6b59a75..b05ad3dea 100644 --- a/libzeth/circuits/blake2s/g_primitive.tcc +++ b/libzeth/circuits/blake2s/g_primitive.tcc @@ -100,4 +100,4 @@ template void g_primitive::generate_r1cs_witness() } // namespace libzeth -#endif // __ZETH_CIRCUITS_G_PRIMITIVE_TCC__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_G_PRIMITIVE_TCC__ diff --git a/libzeth/circuit_types.hpp b/libzeth/circuits/circuit_types.hpp similarity index 72% rename from libzeth/circuit_types.hpp rename to libzeth/circuits/circuit_types.hpp index f17da91b9..1418c2c62 100644 --- a/libzeth/circuit_types.hpp +++ b/libzeth/circuits/circuit_types.hpp @@ -2,12 +2,13 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_CIRCUIT_TYPES_HPP__ -#define __ZETH_CIRCUIT_TYPES_HPP__ +#ifndef __ZETH_CIRCUITS_CIRCUIT_TYPES_HPP__ +#define __ZETH_CIRCUITS_CIRCUIT_TYPES_HPP__ -#include "libzeth/circuit_wrapper.hpp" #include "libzeth/circuits/blake2s/blake2s.hpp" -#include "libzeth/include_libsnark.hpp" +#include "libzeth/circuits/circuit_wrapper.hpp" +#include "libzeth/circuits/mimc/mimc_mp.hpp" +#include "libzeth/core/include_libsnark.hpp" // Types that must be common across all executable, defined once here. Outside // of tests, these should not be set anywhere else in the code. Do not include @@ -30,4 +31,4 @@ using HashTreeT = MiMC_mp_gadget; } // namespace libzeth -#endif // __ZETH_CIRCUIT_TYPES_HPP__ +#endif // __ZETH_CIRCUITS_CIRCUIT_TYPES_HPP__ diff --git a/libzeth/circuits/circuits_utils.cpp b/libzeth/circuits/circuit_utils.cpp similarity index 86% rename from libzeth/circuits/circuits_utils.cpp rename to libzeth/circuits/circuit_utils.cpp index 7628e65e5..0ac12adc3 100644 --- a/libzeth/circuits/circuits_utils.cpp +++ b/libzeth/circuits/circuit_utils.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/circuits/circuits_utils.hpp" +#include "libzeth/circuits/circuit_utils.hpp" namespace libzeth { @@ -25,4 +25,4 @@ std::vector convert_to_binary(size_t n) return res; } -} // namespace libzeth \ No newline at end of file +} // namespace libzeth diff --git a/libzeth/circuits/circuits_utils.hpp b/libzeth/circuits/circuit_utils.hpp similarity index 70% rename from libzeth/circuits/circuits_utils.hpp rename to libzeth/circuits/circuit_utils.hpp index 8da0d2ccb..69f3eb9e4 100644 --- a/libzeth/circuits/circuits_utils.hpp +++ b/libzeth/circuits/circuit_utils.hpp @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_CIRCUITS_CIRCUITS_UTILS_HPP__ -#define __ZETH_CIRCUITS_CIRCUITS_UTILS_HPP__ +#ifndef __ZETH_CIRCUITS_CIRCUIT_UTILS_HPP__ +#define __ZETH_CIRCUITS_CIRCUIT_UTILS_HPP__ -#include "libzeth/types/bits.hpp" +#include "libzeth/core/bits.hpp" #include @@ -22,6 +22,7 @@ libsnark::pb_variable_array from_bits( std::vector bits, const libsnark::pb_variable &ZERO); } // namespace libzeth -#include "libzeth/circuits/circuits_utils.tcc" -#endif // __ZETH_CIRCUITS_CIRCUITS_UTILS_HPP__ \ No newline at end of file +#include "libzeth/circuits/circuit_utils.tcc" + +#endif // __ZETH_CIRCUITS_CIRCUIT_UTILS_HPP__ diff --git a/libzeth/circuits/circuits_utils.tcc b/libzeth/circuits/circuit_utils.tcc similarity index 100% rename from libzeth/circuits/circuits_utils.tcc rename to libzeth/circuits/circuit_utils.tcc diff --git a/libzeth/circuit_wrapper.hpp b/libzeth/circuits/circuit_wrapper.hpp similarity index 63% rename from libzeth/circuit_wrapper.hpp rename to libzeth/circuits/circuit_wrapper.hpp index af22f2613..3d4f0e059 100644 --- a/libzeth/circuit_wrapper.hpp +++ b/libzeth/circuits/circuit_wrapper.hpp @@ -2,46 +2,36 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_CIRCUIT_WRAPPER_HPP__ -#define __ZETH_CIRCUIT_WRAPPER_HPP__ +#ifndef __ZETH_CIRCUITS_CIRCUIT_WRAPPER_HPP__ +#define __ZETH_CIRCUITS_CIRCUIT_WRAPPER_HPP__ #include "libzeth/circuits/joinsplit.tcc" -#include "libzeth/libsnark_helpers/libsnark_helpers.hpp" -#include "libzeth/types/note.hpp" - -// zkSNARK specific aliases and imports -#include "libzeth/snarks_alias.hpp" -#include "libzeth/snarks_core_imports.hpp" +#include "libzeth/core/note.hpp" +#include "libzeth/serialization/file_io.hpp" +#include "libzeth/zeth_constants.hpp" namespace libzeth { +/// Wrapper around the joinsplit circuit, using parameterized schemes for +/// hashing, and a snark scheme for generating keys and proofs. template< - typename FieldT, typename HashT, typename HashTreeT, typename ppT, + typename snarkT, size_t NumInputs, size_t NumOutputs, size_t TreeDepth> class circuit_wrapper { public: - boost::filesystem::path setup_path; - std::shared_ptr> - joinsplit_g; + using FieldT = libff::Fr; - circuit_wrapper(const boost::filesystem::path setup_path = "") - : setup_path(setup_path){}; + circuit_wrapper(const boost::filesystem::path setup_path = ""); // Generate the trusted setup - keyPairT generate_trusted_setup() const; + typename snarkT::KeypairT generate_trusted_setup() const; #ifdef DEBUG // Used to debug the constraint system @@ -50,7 +40,7 @@ class circuit_wrapper #endif // Generate a proof and returns an extended proof - extended_proof prove( + extended_proof prove( const FieldT &root, const std::array, NumInputs> &inputs, const std::array &outputs, @@ -58,10 +48,22 @@ class circuit_wrapper bits64 vpub_out, const bits256 h_sig_in, const bits256 phi_in, - const provingKeyT &proving_key) const; + const typename snarkT::ProvingKeyT &proving_key) const; + +private: + boost::filesystem::path setup_path; + std::shared_ptr> + joinsplit_g; }; } // namespace libzeth -#include "libzeth/circuit_wrapper.tcc" -#endif // __ZETH_CIRCUIT_WRAPPER_HPP__ +#include "libzeth/circuits/circuit_wrapper.tcc" + +#endif // __ZETH_CIRCUITS_CIRCUIT_WRAPPER_HPP__ diff --git a/libzeth/circuit_wrapper.tcc b/libzeth/circuits/circuit_wrapper.tcc similarity index 75% rename from libzeth/circuit_wrapper.tcc rename to libzeth/circuits/circuit_wrapper.tcc index 66a9cc502..b2f0c0d21 100644 --- a/libzeth/circuit_wrapper.tcc +++ b/libzeth/circuits/circuit_wrapper.tcc @@ -2,28 +2,47 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_CIRCUIT_WRAPPER_TCC__ -#define __ZETH_CIRCUIT_WRAPPER_TCC__ +#ifndef __ZETH_CIRCUITS_CIRCUIT_WRAPPER_TCC__ +#define __ZETH_CIRCUITS_CIRCUIT_WRAPPER_TCC__ -#include "libzeth/snarks_alias.hpp" -#include "libzeth/zeth.h" +#include "libzeth/circuits/circuit_wrapper.hpp" namespace libzeth { template< - typename FieldT, typename HashT, typename HashTreeT, typename ppT, + typename snarkT, size_t NumInputs, size_t NumOutputs, size_t TreeDepth> -keyPairT circuit_wrapper< - FieldT, +circuit_wrapper< HashT, HashTreeT, ppT, + snarkT, + NumInputs, + NumOutputs, + TreeDepth>::circuit_wrapper(const boost::filesystem::path setup_path) + : setup_path(setup_path) +{ +} + +template< + typename HashT, + typename HashTreeT, + typename ppT, + typename snarkT, + size_t NumInputs, + size_t NumOutputs, + size_t TreeDepth> +typename snarkT::KeypairT circuit_wrapper< + HashT, + HashTreeT, + ppT, + snarkT, NumInputs, NumOutputs, TreeDepth>::generate_trusted_setup() const @@ -36,26 +55,26 @@ keyPairT circuit_wrapper< // Generate a verification and proving key (trusted setup) // and write them in a file - keyPairT keypair = gen_trusted_setup(pb); - write_setup(keypair, this->setup_path); + typename snarkT::KeypairT keypair = snarkT::generate_setup(pb); + serialize_setup_to_file(keypair, this->setup_path); return keypair; } #ifdef DEBUG template< - typename FieldT, typename HashT, typename HashTreeT, typename ppT, + typename snarkT, size_t NumInputs, size_t NumOutputs, size_t TreeDepth> void circuit_wrapper< - FieldT, HashT, HashTreeT, ppT, + snarkT, NumInputs, NumOutputs, TreeDepth>::dump_constraint_system(boost::filesystem::path file_path) const @@ -71,18 +90,18 @@ void circuit_wrapper< #endif template< - typename FieldT, typename HashT, typename HashTreeT, typename ppT, + typename snarkT, size_t NumInputs, size_t NumOutputs, size_t TreeDepth> -extended_proof circuit_wrapper< - FieldT, +extended_proof circuit_wrapper< HashT, HashTreeT, ppT, + snarkT, NumInputs, NumOutputs, TreeDepth>:: @@ -94,7 +113,7 @@ extended_proof circuit_wrapper< bits64 vpub_out, const bits256 h_sig_in, const bits256 phi_in, - const provingKeyT &proving_key) const + const typename snarkT::ProvingKeyT &proving_key) const { // left hand side and right hand side of the joinsplit bits64 lhs_value = vpub_in; @@ -131,13 +150,14 @@ extended_proof circuit_wrapper< std::cout << "******* [DEBUG] Satisfiability result: " << is_valid_witness << " *******" << std::endl; - proofT proof = libzeth::gen_proof(pb, proving_key); + typename snarkT::ProofT proof = snarkT::generate_proof(pb, proving_key); libsnark::r1cs_primary_input> primary_input = pb.primary_input(); // Instantiate an extended_proof from the proof we generated and the given // primary_input - extended_proof ext_proof = extended_proof(proof, primary_input); + extended_proof ext_proof = + extended_proof(proof, primary_input); // Write the extended proof in a file (Default path is taken if not // specified) @@ -148,4 +168,4 @@ extended_proof circuit_wrapper< } // namespace libzeth -#endif // __ZETH_CIRCUIT_WRAPPER_TCC__ +#endif // __ZETH_CIRCUITS_CIRCUIT_WRAPPER_TCC__ diff --git a/libzeth/circuits/commitments/commitment.hpp b/libzeth/circuits/commitments/commitment.hpp index 6a3859455..f947cd5d1 100644 --- a/libzeth/circuits/commitments/commitment.hpp +++ b/libzeth/circuits/commitments/commitment.hpp @@ -5,7 +5,7 @@ // Content Taken and adapted from Zcash // https://github.com/zcash/zcash/blob/master/src/zcash/circuit/commitment.tcc -#include "libzeth/zeth.h" +#include "libzeth/zeth_constants.hpp" #include #include @@ -78,6 +78,7 @@ class COMM_cm_gadget : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/commitments/commitment.tcc" -#endif // __ZETH_CIRCUITS_COMMITMENT_HPP__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_COMMITMENT_HPP__ diff --git a/libzeth/circuits/joinsplit.tcc b/libzeth/circuits/joinsplit.tcc index 5e8586c2b..ced01f630 100644 --- a/libzeth/circuits/joinsplit.tcc +++ b/libzeth/circuits/joinsplit.tcc @@ -5,14 +5,11 @@ #ifndef __ZETH_CIRCUITS_JOINSPLIT_TCC__ #define __ZETH_CIRCUITS_JOINSPLIT_TCC__ -// Contains the circuits for the notes #include "libzeth/circuits/notes/note.hpp" -#include "libzeth/types/joinsplit.hpp" -// Contains the definitions of the constants we use -#include "libzeth/zeth.h" -// Contains functions for safe arithmetic #include "libzeth/circuits/safe_arithmetic.hpp" -#include "libzeth/types/merkle_tree_field.hpp" +#include "libzeth/core/joinsplit_input.hpp" +#include "libzeth/core/merkle_tree_field.hpp" +#include "libzeth/zeth_constants.hpp" #include diff --git a/libzeth/circuits/merkle_tree/merkle_path_authenticator.hpp b/libzeth/circuits/merkle_tree/merkle_path_authenticator.hpp index a2857d9eb..144547276 100644 --- a/libzeth/circuits/merkle_tree/merkle_path_authenticator.hpp +++ b/libzeth/circuits/merkle_tree/merkle_path_authenticator.hpp @@ -49,6 +49,7 @@ class merkle_path_authenticator : public merkle_path_compute }; } // namespace libzeth + #include "libzeth/circuits/merkle_tree/merkle_path_authenticator.tcc" -#endif // __ZETH_CIRCUITS_MERKLE_PATH_AUTHENTICATOR_HPP__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MERKLE_PATH_AUTHENTICATOR_HPP__ diff --git a/libzeth/circuits/merkle_tree/merkle_path_authenticator.tcc b/libzeth/circuits/merkle_tree/merkle_path_authenticator.tcc index 11d4e25b8..d02814171 100644 --- a/libzeth/circuits/merkle_tree/merkle_path_authenticator.tcc +++ b/libzeth/circuits/merkle_tree/merkle_path_authenticator.tcc @@ -54,4 +54,4 @@ bool merkle_path_authenticator::is_valid() } // namespace libzeth -#endif // __ZETH_CIRCUITS_MERKLE_PATH_AUTHENTICATOR_TCC__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MERKLE_PATH_AUTHENTICATOR_TCC__ diff --git a/libzeth/circuits/merkle_tree/merkle_path_compute.hpp b/libzeth/circuits/merkle_tree/merkle_path_compute.hpp index 2a1ea1a7a..abec3e2a0 100644 --- a/libzeth/circuits/merkle_tree/merkle_path_compute.hpp +++ b/libzeth/circuits/merkle_tree/merkle_path_compute.hpp @@ -49,6 +49,7 @@ class merkle_path_compute : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/merkle_tree/merkle_path_compute.tcc" -#endif // __ZETH_CIRCUITS_MERKLE_PATH_COMPUTE_HPP__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MERKLE_PATH_COMPUTE_HPP__ diff --git a/libzeth/circuits/merkle_tree/merkle_path_compute.tcc b/libzeth/circuits/merkle_tree/merkle_path_compute.tcc index ebc3ea772..e6cdf6dab 100644 --- a/libzeth/circuits/merkle_tree/merkle_path_compute.tcc +++ b/libzeth/circuits/merkle_tree/merkle_path_compute.tcc @@ -100,4 +100,4 @@ const libsnark::pb_variable merkle_path_compute:: } // namespace libzeth -#endif // __ZETH_CIRCUITS_MERKLE_PATH_COMPUTE_TCC__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MERKLE_PATH_COMPUTE_TCC__ diff --git a/libzeth/circuits/merkle_tree/merkle_path_selector.hpp b/libzeth/circuits/merkle_tree/merkle_path_selector.hpp index 8186b28d2..9fadaea4d 100644 --- a/libzeth/circuits/merkle_tree/merkle_path_selector.hpp +++ b/libzeth/circuits/merkle_tree/merkle_path_selector.hpp @@ -69,6 +69,7 @@ class merkle_path_selector : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/merkle_tree/merkle_path_selector.tcc" -#endif // __ZETH_CIRCUITS_MERKLE_PATH_SELECTOR_HPP___ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MERKLE_PATH_SELECTOR_HPP___ diff --git a/libzeth/circuits/merkle_tree/merkle_path_selector.tcc b/libzeth/circuits/merkle_tree/merkle_path_selector.tcc index b7768be7e..745146d09 100644 --- a/libzeth/circuits/merkle_tree/merkle_path_selector.tcc +++ b/libzeth/circuits/merkle_tree/merkle_path_selector.tcc @@ -77,4 +77,4 @@ const libsnark::pb_variable &merkle_path_selector::get_right() } // namespace libzeth -#endif // __ZETH_CIRCUITS_MERKLE_PATH_SELECTOR_TCC__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MERKLE_PATH_SELECTOR_TCC__ diff --git a/libzeth/circuits/mimc/mimc.hpp b/libzeth/circuits/mimc/mimc.hpp index cf815a9c7..1c4f0cfa3 100644 --- a/libzeth/circuits/mimc/mimc.hpp +++ b/libzeth/circuits/mimc/mimc.hpp @@ -53,6 +53,7 @@ class MiMCe7_permutation_gadget : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/mimc/mimc.tcc" -#endif // __ZETH_CIRCUITS_MIMC_HPP__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MIMC_HPP__ diff --git a/libzeth/circuits/mimc/mimc.tcc b/libzeth/circuits/mimc/mimc.tcc index def2f14a7..b8f0967c5 100644 --- a/libzeth/circuits/mimc/mimc.tcc +++ b/libzeth/circuits/mimc/mimc.tcc @@ -275,4 +275,4 @@ void MiMCe7_permutation_gadget::setup_sha3_constants() } // namespace libzeth -#endif // __ZETH_CIRCUITS_MIMC_TCC__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MIMC_TCC__ diff --git a/libzeth/circuits/mimc/mimc_mp.hpp b/libzeth/circuits/mimc/mimc_mp.hpp index 46c92a587..143edbcb3 100644 --- a/libzeth/circuits/mimc/mimc_mp.hpp +++ b/libzeth/circuits/mimc/mimc_mp.hpp @@ -46,6 +46,7 @@ template class MiMC_mp_gadget : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/mimc/mimc_mp.tcc" -#endif // __ZETH_CIRCUITS_MIMC_MP_HPP__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MIMC_MP_HPP__ diff --git a/libzeth/circuits/mimc/mimc_mp.tcc b/libzeth/circuits/mimc/mimc_mp.tcc index 055260f1a..9c47f96a8 100644 --- a/libzeth/circuits/mimc/mimc_mp.tcc +++ b/libzeth/circuits/mimc/mimc_mp.tcc @@ -87,4 +87,4 @@ FieldT MiMC_mp_gadget::get_hash(const FieldT x, FieldT y) } // namespace libzeth -#endif // __ZETH_CIRCUITS_MIMC_MP_TCC__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MIMC_MP_TCC__ diff --git a/libzeth/circuits/mimc/mimc_round.hpp b/libzeth/circuits/mimc/mimc_round.hpp index 45cefed93..7e34faf06 100644 --- a/libzeth/circuits/mimc/mimc_round.hpp +++ b/libzeth/circuits/mimc/mimc_round.hpp @@ -5,7 +5,7 @@ #ifndef __ZETH_CIRCUITS_MIMC_ROUND_HPP__ #define __ZETH_CIRCUITS_MIMC_ROUND_HPP__ -#include "libzeth/circuits/circuits_utils.hpp" +#include "libzeth/circuits/circuit_utils.hpp" #include @@ -62,6 +62,7 @@ class MiMCe7_round_gadget : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/mimc/mimc_round.tcc" -#endif // __ZETH_CIRCUITS_MIMC_ROUND_HPP__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MIMC_ROUND_HPP__ diff --git a/libzeth/circuits/mimc/mimc_round.tcc b/libzeth/circuits/mimc/mimc_round.tcc index 9c7ac96a6..a613b0ed7 100644 --- a/libzeth/circuits/mimc/mimc_round.tcc +++ b/libzeth/circuits/mimc/mimc_round.tcc @@ -95,4 +95,4 @@ const libsnark::pb_variable &MiMCe7_round_gadget::result() const } // namespace libzeth -#endif // __ZETH_CIRCUITS_MIMC_ROUND_TCC__ \ No newline at end of file +#endif // __ZETH_CIRCUITS_MIMC_ROUND_TCC__ diff --git a/libzeth/circuits/notes/note.hpp b/libzeth/circuits/notes/note.hpp index efa99677c..d927832cb 100644 --- a/libzeth/circuits/notes/note.hpp +++ b/libzeth/circuits/notes/note.hpp @@ -5,18 +5,12 @@ // Content Taken and adapted from Zcash // https://github.com/zcash/zcash/blob/master/src/zcash/circuit/note.tcc -#include "libzeth/circuits/merkle_tree/merkle_path_authenticator.hpp" - -// Get the prfs and commitments circuits +#include "libzeth/circuits/circuit_utils.hpp" #include "libzeth/circuits/commitments/commitment.hpp" +#include "libzeth/circuits/merkle_tree/merkle_path_authenticator.hpp" #include "libzeth/circuits/prfs/prf.hpp" -// Get the utils functions -#include "libzeth/circuits/circuits_utils.hpp" - -// Get the bits typedefs and associated functions -#include "libzeth/types/bits.hpp" -// Get the zeth_note class -#include "libzeth/types/note.hpp" +#include "libzeth/core/bits.hpp" +#include "libzeth/core/note.hpp" namespace libzeth { @@ -122,6 +116,7 @@ class output_note_gadget : public note_gadget }; } // namespace libzeth + #include "libzeth/circuits/notes/note.tcc" #endif // __ZETH_CIRCUITS_NOTE_HPP__ diff --git a/libzeth/circuits/prfs/prf.hpp b/libzeth/circuits/prfs/prf.hpp index 538d3e081..011a87746 100644 --- a/libzeth/circuits/prfs/prf.hpp +++ b/libzeth/circuits/prfs/prf.hpp @@ -5,7 +5,7 @@ // Content Taken and adapted from Zcash // https://github.com/zcash/zcash/blob/master/src/zcash/circuit/prfs.tcc -#include "libzeth/circuits/circuits_utils.hpp" +#include "libzeth/circuits/circuit_utils.hpp" #include @@ -129,6 +129,7 @@ class PRF_rho_gadget : public PRF_gadget }; } // namespace libzeth + #include "libzeth/circuits/prfs/prf.tcc" #endif // __ZETH_CIRCUITS_PRF_HPP__ diff --git a/libzeth/circuits/sha256/sha256_ethereum.hpp b/libzeth/circuits/sha256/sha256_ethereum.hpp index 710703ce8..d2ed9ae6b 100644 --- a/libzeth/circuits/sha256/sha256_ethereum.hpp +++ b/libzeth/circuits/sha256/sha256_ethereum.hpp @@ -8,8 +8,6 @@ // This gadget implements the interface of the HashT template #include -#include -#include #include #include #include @@ -61,6 +59,7 @@ class sha256_ethereum : public libsnark::gadget }; } // namespace libzeth + #include "libzeth/circuits/sha256/sha256_ethereum.tcc" #endif // __ZETH_CIRCUITS_SHA256_ETHEREUM_HPP__ diff --git a/libzeth/circuits/sha256/sha256_ethereum.tcc b/libzeth/circuits/sha256/sha256_ethereum.tcc index f7ac1df57..c619c6723 100644 --- a/libzeth/circuits/sha256/sha256_ethereum.tcc +++ b/libzeth/circuits/sha256/sha256_ethereum.tcc @@ -6,7 +6,7 @@ // https://gist.github.com/kobigurk/24c25e68219df87c348f1a78db51bb52 // Get the from_bits function -#include "libzeth/circuits/circuits_utils.hpp" +#include "libzeth/circuits/circuit_utils.hpp" // This gadget implements the interface of the HashT template diff --git a/libzeth/core/bits.cpp b/libzeth/core/bits.cpp new file mode 100644 index 000000000..e40a59b2c --- /dev/null +++ b/libzeth/core/bits.cpp @@ -0,0 +1,80 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#include "libzeth/core/bits.hpp" + +#include "libzeth/core/utils.hpp" + +namespace libzeth +{ + +bits384 get_bits384_from_vector(std::vector vect) +{ + return dump_vector_in_array<384>(vect); +} + +bits256 get_bits256_from_vector(std::vector vect) +{ + return dump_vector_in_array<256>(vect); +} + +bits64 get_bits64_from_vector(std::vector vect) +{ + return dump_vector_in_array<64>(vect); +} + +bits384 get_bits384_from_hexadecimal_str(std::string str) +{ + if (str.length() != 96) { + throw std::length_error( + "Invalid string length for the given hex digest (should be " + "96)"); + } + + return get_bits384_from_vector(hexadecimal_str_to_binary_vector(str)); +} + +bits256 get_bits256_from_hexadecimal_str(std::string str) +{ + if (str.length() != 64) { + throw std::length_error( + "Invalid string length for the given hex digest (should be " + "64)"); + } + + return get_bits256_from_vector(hexadecimal_str_to_binary_vector(str)); +} + +bits64 get_bits64_from_hexadecimal_str(std::string str) +{ + if (str.length() != 16) { + throw std::length_error( + "Invalid string length for the given hex digest (should be " + "16)"); + } + + return get_bits64_from_vector(hexadecimal_str_to_binary_vector(str)); +} + +std::vector get_vector_from_bits384(bits384 arr) +{ + return dump_array_in_vector<384>(arr); +} + +std::vector get_vector_from_bits256(bits256 arr) +{ + return dump_array_in_vector<256>(arr); +} + +std::vector get_vector_from_bits64(bits64 arr) +{ + return dump_array_in_vector<64>(arr); +} + +std::vector get_vector_from_bits32(bits32 arr) +{ + return dump_array_in_vector<32>(arr); +} + +} // namespace libzeth diff --git a/libzeth/types/bits.hpp b/libzeth/core/bits.hpp similarity index 64% rename from libzeth/types/bits.hpp rename to libzeth/core/bits.hpp index 4e08308f2..f67cec992 100644 --- a/libzeth/types/bits.hpp +++ b/libzeth/core/bits.hpp @@ -2,13 +2,12 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_TYPES_BITS_HPP__ -#define __ZETH_TYPES_BITS_HPP__ - -#include "libzeth/zeth.h" +#ifndef __ZETH_CORE_BITS_HPP__ +#define __ZETH_CORE_BITS_HPP__ #include #include +#include #include namespace libzeth @@ -20,20 +19,27 @@ typedef std::array bits64; typedef std::array bits32; template using bits_addr = std::array; -// Dump a vector into an array +/// Pour content of boolean vector into an array of booleans template std::array dump_vector_in_array(std::vector vect); +/// "Construct" `bits` types from boolean vectors bits384 get_bits384_from_vector(std::vector vect); bits256 get_bits256_from_vector(std::vector vect); bits64 get_bits64_from_vector(std::vector vect); template bits_addr get_bits_addr_from_vector(const std::vector &vect); -// Dump an array into a vector +/// "Construct" `bits` types from hexadecimal strings +bits384 get_bits384_from_hexadecimal_str(std::string hex_str); +bits256 get_bits256_from_hexadecimal_str(std::string hex_str); +bits64 get_bits64_from_hexadecimal_str(std::string hex_str); + +/// Pour content of boolean array into a vector of booleans template std::vector dump_array_in_vector(std::array arr); +/// Retrieve boolean vectors from `bits` types std::vector get_vector_from_bits384(bits384 arr); std::vector get_vector_from_bits256(bits256 arr); std::vector get_vector_from_bits64(bits64 arr); @@ -41,11 +47,14 @@ std::vector get_vector_from_bits32(bits32 arr); template std::vector get_vector_from_bits_addr(const bits_addr &arr); +/// XOR two binary strings of the same length. +/// The strings are represented as arrays of booleans. template std::array binary_xor( std::array A, std::array B); -// Sum 2 binary strings +/// Sum two binary strings of the same length. +/// The strings are represented as arrays of booleans. template std::array binary_addition( std::array A, @@ -53,6 +62,7 @@ std::array binary_addition( bool withCarry = false); } // namespace libzeth -#include "libzeth/types/bits.tcc" -#endif // __ZETH_TYPES_BITS_HPP__ +#include "libzeth/core/bits.tcc" + +#endif // __ZETH_CORE_BITS_HPP__ diff --git a/libzeth/types/bits.tcc b/libzeth/core/bits.tcc similarity index 94% rename from libzeth/types/bits.tcc rename to libzeth/core/bits.tcc index 8110572a6..fff503b3d 100644 --- a/libzeth/types/bits.tcc +++ b/libzeth/core/bits.tcc @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_TYPES_BITS_TCC__ -#define __ZETH_TYPES_BITS_TCC__ +#ifndef __ZETH_CORE_BITS_TCC__ +#define __ZETH_CORE_BITS_TCC__ -#include "libzeth/types/bits.hpp" +#include "libzeth/core/bits.hpp" namespace libzeth { @@ -88,4 +88,4 @@ std::array binary_xor( } // namespace libzeth -#endif // __ZETH_TYPES_BITS_TCC__ +#endif // __ZETH_CORE_BITS_TCC__ diff --git a/libzeth/snarks/groth16/mpc/chacha_rng.cpp b/libzeth/core/chacha_rng.cpp similarity index 98% rename from libzeth/snarks/groth16/mpc/chacha_rng.cpp rename to libzeth/core/chacha_rng.cpp index fe06717ed..d06e79980 100644 --- a/libzeth/snarks/groth16/mpc/chacha_rng.cpp +++ b/libzeth/core/chacha_rng.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/chacha_rng.hpp" +#include "libzeth/core/chacha_rng.hpp" #include #include diff --git a/libzeth/snarks/groth16/mpc/chacha_rng.hpp b/libzeth/core/chacha_rng.hpp similarity index 85% rename from libzeth/snarks/groth16/mpc/chacha_rng.hpp rename to libzeth/core/chacha_rng.hpp index 01149371b..6aec3801a 100644 --- a/libzeth/snarks/groth16/mpc/chacha_rng.hpp +++ b/libzeth/core/chacha_rng.hpp @@ -2,8 +2,8 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_MPC_CHACHA_RNG_HPP__ -#define __ZETH_SNARKS_GROTH16_MPC_CHACHA_RNG_HPP__ +#ifndef __ZETH_CORE_CHACHA_RNG_HPP__ +#define __ZETH_CORE_CHACHA_RNG_HPP__ #include #include @@ -43,4 +43,4 @@ class chacha_rng } // namespace libzeth -#endif // __ZETH_SNARKS_GROTH16_MPC_CHACHA_RNG_HPP__ +#endif // __ZETH_CORE_CHACHA_RNG_HPP__ diff --git a/libzeth/snarks/groth16/mpc/evaluator_from_lagrange.hpp b/libzeth/core/evaluator_from_lagrange.hpp similarity index 74% rename from libzeth/snarks/groth16/mpc/evaluator_from_lagrange.hpp rename to libzeth/core/evaluator_from_lagrange.hpp index f6a98b6dd..fdc59d31c 100644 --- a/libzeth/snarks/groth16/mpc/evaluator_from_lagrange.hpp +++ b/libzeth/core/evaluator_from_lagrange.hpp @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_EVALUATOR_FROM_LAGRANGE_HPP__ -#define __ZETH_SNARKS_GROTH16_EVALUATOR_FROM_LAGRANGE_HPP__ +#ifndef __ZETH_CORE_EVALUATOR_FROM_LAGRANGE_HPP__ +#define __ZETH_CORE_EVALUATOR_FROM_LAGRANGE_HPP__ -#include "libzeth/include_libsnark.hpp" +#include "libzeth/core/include_libsnark.hpp" #include @@ -32,6 +32,7 @@ template class evaluator_from_lagrange }; } // namespace libzeth -#include "libzeth/snarks/groth16/mpc/evaluator_from_lagrange.tcc" -#endif // __ZETH_SNARKS_GROTH16_EVALUATOR_FROM_LAGRANGE_HPP__ +#include "libzeth/core/evaluator_from_lagrange.tcc" + +#endif // __ZETH_CORE_EVALUATOR_FROM_LAGRANGE_HPP__ diff --git a/libzeth/snarks/groth16/mpc/evaluator_from_lagrange.tcc b/libzeth/core/evaluator_from_lagrange.tcc similarity index 82% rename from libzeth/snarks/groth16/mpc/evaluator_from_lagrange.tcc rename to libzeth/core/evaluator_from_lagrange.tcc index 3d7c0db0c..43beb9d8f 100644 --- a/libzeth/snarks/groth16/mpc/evaluator_from_lagrange.tcc +++ b/libzeth/core/evaluator_from_lagrange.tcc @@ -2,11 +2,11 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_EVALUATOR_FROM_LAGRANGE_TCC__ -#define __ZETH_SNARKS_GROTH16_EVALUATOR_FROM_LAGRANGE_TCC__ +#ifndef __ZETH_CORE_EVALUATOR_FROM_LAGRANGE_TCC__ +#define __ZETH_CORE_EVALUATOR_FROM_LAGRANGE_TCC__ -#include "libzeth/snarks/groth16/mpc/evaluator_from_lagrange.hpp" -#include "libzeth/snarks/groth16/mpc/multi_exp.hpp" +#include "libzeth/core/evaluator_from_lagrange.hpp" +#include "libzeth/core/multi_exp.hpp" namespace libzeth { @@ -46,4 +46,4 @@ GroupT evaluator_from_lagrange::evaluate_from_lagrange_factors( } // namespace libzeth -#endif // __ZETH_SNARKS_GROTH16_EVALUATOR_FROM_LAGRANGE_TCC__ +#endif // __ZETH_CORE_EVALUATOR_FROM_LAGRANGE_TCC__ diff --git a/libzeth/libsnark_helpers/extended_proof.hpp b/libzeth/core/extended_proof.hpp similarity index 60% rename from libzeth/libsnark_helpers/extended_proof.hpp rename to libzeth/core/extended_proof.hpp index fd1fffc26..2ca317fde 100644 --- a/libzeth/libsnark_helpers/extended_proof.hpp +++ b/libzeth/core/extended_proof.hpp @@ -2,12 +2,11 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_EXTENDED_PROOF_HPP__ -#define __ZETH_EXTENDED_PROOF_HPP__ +#ifndef __ZETH_CORE_EXTENDED_PROOF_HPP__ +#define __ZETH_CORE_EXTENDED_PROOF_HPP__ -#include "libzeth/libsnark_helpers/debug_helpers.hpp" -#include "libzeth/snarks_alias.hpp" -#include "libzeth/zeth.h" +#include "libzeth/core/include_libsnark.hpp" +#include "libzeth/serialization/filesystem_util.hpp" namespace libzeth { @@ -15,23 +14,23 @@ namespace libzeth // An extended_proof is a data structure containing a proof and the // corresponding primary inputs It corresponds to the data needed for the // verifier to be able to run the verifying algorithm. -template class extended_proof +template class extended_proof { private: - std::shared_ptr> proof; + std::shared_ptr proof; std::shared_ptr>> primary_inputs; public: extended_proof( - proofT &in_proof, - libsnark::r1cs_primary_input> &in_primary_input); - const proofT &get_proof() const; - const libsnark::r1cs_primary_input> &get_primary_input() + typename snarkT::ProofT &in_proof, + libsnark::r1cs_primary_input> &in_primary_inputs); + const typename snarkT::ProofT &get_proof() const; + const libsnark::r1cs_primary_input> &get_primary_inputs() const; // Write on disk - void write_primary_input(boost::filesystem::path path = "") const; + void write_primary_inputs(boost::filesystem::path path = "") const; void write_proof(boost::filesystem::path path = "") const; void write_extended_proof(boost::filesystem::path path = "") const; @@ -42,6 +41,6 @@ template class extended_proof } // namespace libzeth -#include "libzeth/libsnark_helpers/extended_proof.tcc" +#include "libzeth/core/extended_proof.tcc" -#endif +#endif // __ZETH_CORE_EXTENDED_PROOF_HPP__ diff --git a/libzeth/libsnark_helpers/extended_proof.tcc b/libzeth/core/extended_proof.tcc similarity index 56% rename from libzeth/libsnark_helpers/extended_proof.tcc rename to libzeth/core/extended_proof.tcc index ed962707f..b97a7fae1 100644 --- a/libzeth/libsnark_helpers/extended_proof.tcc +++ b/libzeth/core/extended_proof.tcc @@ -2,41 +2,41 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_EXTENDED_PROOF_TCC__ -#define __ZETH_EXTENDED_PROOF_TCC__ +#ifndef __ZETH_TYPES_EXTENDED_PROOF_TCC__ +#define __ZETH_TYPES_EXTENDED_PROOF_TCC__ -// Snark dependent implementation for generate_trusted_setup() and prove() -// functions -#include "libzeth/snarks_core_imports.hpp" +#include "libzeth/core/extended_proof.hpp" +#include "libzeth/core/field_element_utils.hpp" namespace libzeth { -template -extended_proof::extended_proof( - proofT &in_proof, - libsnark::r1cs_primary_input> &in_primary_input) +template +extended_proof::extended_proof( + typename snarkT::ProofT &in_proof, + libsnark::r1cs_primary_input> &in_primary_inputs) { - this->proof = std::make_shared>(in_proof); - this->primary_inputs = + proof = std::make_shared(in_proof); + primary_inputs = std::make_shared>>( - in_primary_input); + in_primary_inputs); } -template const proofT &extended_proof::get_proof() const +template +const typename snarkT::ProofT &extended_proof::get_proof() const { return *this->proof; } -template +template const libsnark::r1cs_primary_input> - &extended_proof::get_primary_input() const + &extended_proof::get_primary_inputs() const { return *this->primary_inputs; } -template -void extended_proof::write_primary_input( +template +void extended_proof::write_primary_inputs( boost::filesystem::path path) const { if (path.empty()) { @@ -57,7 +57,7 @@ void extended_proof::write_primary_input( << "["; // 1 should always be the first variable passed for (size_t i = 0; i < *this->primary_inputs.size(); ++i) { ss << "\"0x" - << hex_from_libsnark_bigint>( + << libsnark_bigint_to_hexadecimal_str>( *this->primary_inputs[i].as_bigint()) << "\""; if (i < *this->primary_inputs.size() - 1) { @@ -73,14 +73,15 @@ void extended_proof::write_primary_input( fh.close(); } -template void extended_proof::dump_primary_inputs() const +template +void extended_proof::dump_primary_inputs() const { std::cout << "{\n"; std::cout << " \"inputs\" :" << "["; // 1 should always be the first variable passed for (size_t i = 0; i < (*this->primary_inputs).size(); ++i) { std::cout << "\"0x" - << hex_from_libsnark_bigint>( + << libsnark_bigint_to_hexadecimal_str>( (*this->primary_inputs)[i].as_bigint()) << "\""; if (i < (*this->primary_inputs).size() - 1) { @@ -91,24 +92,26 @@ template void extended_proof::dump_primary_inputs() const std::cout << "}"; } -template -void extended_proof::write_proof(boost::filesystem::path path) const +template +void extended_proof::write_proof( + boost::filesystem::path path) const { - proof_to_json(*this->proof, path); + snarkT::proof_to_json(*this->proof, path); } -template -void extended_proof::write_extended_proof( +template +void extended_proof::write_extended_proof( boost::filesystem::path path) const { - proof_and_inputs_to_json(*this->proof, *this->primary_inputs, path); + snarkT::proof_and_inputs_to_json(*proof, *primary_inputs, path); } -template void extended_proof::dump_proof() const +template +void extended_proof::dump_proof() const { - display_proof(*this->proof); + snarkT::display_proof(*this->proof); } } // namespace libzeth -#endif // __ZETH_EXTENDED_PROOF_TCC__ +#endif // __ZETH_TYPES_EXTENDED_PROOF_TCC__ diff --git a/libzeth/core/field_element_utils.hpp b/libzeth/core/field_element_utils.hpp new file mode 100644 index 000000000..626cd2aa7 --- /dev/null +++ b/libzeth/core/field_element_utils.hpp @@ -0,0 +1,71 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_CORE_FIELD_ELEMENT_UTILS_HPP__ +#define __ZETH_CORE_FIELD_ELEMENT_UTILS_HPP__ + +#include "include_libff.hpp" + +namespace libzeth +{ + +/// WARNING: The following function assumes that NAILS are NOT used +/// See Section 8.2 (page 68): https://gmplib.org/gmp-man-6.2.0.pdf +/// In other words, we assume below that: +/// - GMP_NUMB_BITS = GMP_LIMB_BITS and thus, +/// - GMP_NAIL_BITS = 0 +/// +/// This function decomposes a bigint into an array of bytes. +/// +/// For instance, if the number of bits in a Limb is 64, +/// and we have `input_bigint = [Limb0, Limb1, Limb2, Limb3]`, +/// where every Limb{i} is of type `mp_limb_t`, then the function returns +/// +/// x = [x0, ..., x7, x8, ..., x15, x16, ..., x23, x24, ..., x31] +/// ^ ^ ^ ^ ^ ^ ^ ^ +/// |_______| |________| |_________| |_________| +/// | | | | +/// Limb3 Limb2 Limb1 Limb0 +/// +/// where all x_i's are bytes (uint8_t) +template +std::string libsnark_bigint_to_hexadecimal_str( + const libff::bigint &limbs); + +/// WARNING: The following function assumes that NAILS are NOT used +/// See Section 8.2 (page 68): https://gmplib.org/gmp-man-6.2.0.pdf +/// In other words, we assume below that: +/// - GMP_NUMB_BITS = GMP_LIMB_BITS and thus, +/// - GMP_NAIL_BITS = 0 +/// +/// This function recomposes a bigint from an array of bytes. +/// +/// For instance, if the number of bits in a Limb is 64, and we have as input: +/// x = [x0, ..., x7, x8, ..., x15, x16, ..., x23, x24, ..., x31] +/// ^ ^ ^ ^ ^ ^ ^ ^ +/// |_______| |________| |_________| |_________| +/// | | | | +/// Limb3 Limb2 Limb1 Limb0 +/// where all x_i's are bytes (uint8_t) +/// +/// then the function returns: +/// and we have `res_bigint = [Limb0, Limb1, Limb2, Limb3]`, +/// where every Limb{i} is of type `mp_limb_t`, +template +libff::bigint bytes_to_libsnark_bigint( + const uint8_t bytes[(FieldT::num_bits + 8 - 1) / 8]); + +/// Convert an hexadecimal string to a field element +template +FieldT hexadecimal_str_to_field_element(std::string field_str); + +/// Convert a field element to an hexadecimal string +template +std::string field_element_to_hexadecimal_str(FieldT field_el); + +} // namespace libzeth + +#include "libzeth/core/field_element_utils.tcc" + +#endif // __ZETH_CORE_FIELD_ELEMENT_UTILS_HPP__ diff --git a/libzeth/core/field_element_utils.tcc b/libzeth/core/field_element_utils.tcc new file mode 100644 index 000000000..c9df05152 --- /dev/null +++ b/libzeth/core/field_element_utils.tcc @@ -0,0 +1,95 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_FIELD_ELEMENT_UTILS_TCC__ +#define __ZETH_FIELD_ELEMENT_UTILS_TCC__ + +#include "libzeth/core/field_element_utils.hpp" +#include "libzeth/core/utils.hpp" + +#include + +/// This file uses types and preprocessor variables defined in the `gmp.h` +/// header: +/// - `mp_size_t` +/// - `GMP_LIMB_BITS` +/// - `GMP_NAIL_BITS` + +namespace libzeth +{ + +template +std::string libsnark_bigint_to_hexadecimal_str( + const libff::bigint &limbs) +{ + const unsigned bytes_per_limb = (GMP_LIMB_BITS + 8 - 1) / 8; + + uint8_t x[bytes_per_limb * FieldT::num_limbs]; + for (unsigned i = 0; i < FieldT::num_limbs; i++) { + for (unsigned j = 0; j < bytes_per_limb; j++) { + x[i * 8 + j] = uint8_t( + uint64_t(limbs.data[(FieldT::num_limbs - 1) - i]) >> + (GMP_LIMB_BITS - 8 * (j + 1))); + } + } + + std::stringstream ss; + + // Display every byte as 2 hexadecimal characters + ss << std::setfill('0'); + for (unsigned i = 0; i < bytes_per_limb * FieldT::num_limbs; i++) { + ss << std::hex << std::setw(2) << (int)x[i]; + } + std::string str = ss.str(); + + return str; +} + +template +libff::bigint bytes_to_libsnark_bigint( + const uint8_t bytes[((GMP_LIMB_BITS + 8 - 1) / 8) * FieldT::num_limbs]) +{ + const unsigned bytes_per_limb = (GMP_LIMB_BITS + 8 - 1) / 8; + + libff::bigint res; + + for (unsigned i = 0; i < FieldT::num_limbs; i++) { + for (unsigned j = 0; j < bytes_per_limb; j++) { + res.data[FieldT::num_limbs - i - 1] |= + mp_limb_t(bytes[i * 8 + j]) << (GMP_LIMB_BITS - 8 * (j + 1)); + } + } + return res; +} + +template +FieldT hexadecimal_str_to_field_element(std::string field_str) +{ + // Remove prefix if any + erase_substring(field_str, std::string("0x")); + + // 1 byte will be populated by 2 hexadecimal characters + uint8_t val[field_str.size() / 2]; + + char cstr[field_str.size() + 1]; + strcpy(cstr, field_str.c_str()); + + int res = hexadecimal_str_to_byte_array(cstr, val); + if (res == 0) { + throw std::invalid_argument("Invalid hexadecimal string"); + } + + libff::bigint el = bytes_to_libsnark_bigint(val); + return FieldT(el); +} + +template +std::string field_element_to_hexadecimal_str(FieldT field_el) +{ + return libsnark_bigint_to_hexadecimal_str(field_el.as_bigint()); +} + +} // namespace libzeth + +#endif // __ZETH_FIELD_ELEMENT_UTILS_TCC__ diff --git a/libzeth/core/group_element_utils.hpp b/libzeth/core/group_element_utils.hpp new file mode 100644 index 000000000..39d0ae962 --- /dev/null +++ b/libzeth/core/group_element_utils.hpp @@ -0,0 +1,31 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_CORE_GROUP_ELEMENT_UTILS_HPP__ +#define __ZETH_CORE_GROUP_ELEMENT_UTILS_HPP__ + +#include "include_libff.hpp" + +namespace libzeth +{ + +/// Convert a group element of G1 to an hexadecimal string. +/// This function assumes that the group element is in affine +/// form, and that both coordinates (X, Y) are elements of a +/// prime field. +template +std::string point_g1_affine_to_hexadecimal_str(const libff::G1 &point); + +/// Convert a group element of G2 to an hexadecimal string. +/// This function assumes that the group element is in affine +/// form, and that both coordinates (X, Y) are elements of a +/// an extension field of degree 2. +template +std::string point_g2_affine_to_hexadecimal_str(const libff::G2 &point); + +} // namespace libzeth + +#include "libzeth/core/group_element_utils.tcc" + +#endif // __ZETH_CORE_GROUP_ELEMENT_UTILS_HPP__ diff --git a/libzeth/core/group_element_utils.tcc b/libzeth/core/group_element_utils.tcc new file mode 100644 index 000000000..90daf8bf6 --- /dev/null +++ b/libzeth/core/group_element_utils.tcc @@ -0,0 +1,49 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__ +#define __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__ + +#include "libzeth/core/field_element_utils.hpp" + +namespace libzeth +{ + +template +std::string point_g1_affine_to_hexadecimal_str(const libff::G1 &point) +{ + libff::G1 affine_p = point; + affine_p.to_affine_coordinates(); + return "\"0x" + + libsnark_bigint_to_hexadecimal_str>( + affine_p.X.as_bigint()) + + "\", \"0x" + + libsnark_bigint_to_hexadecimal_str>( + affine_p.Y.as_bigint()) + + "\""; +} + +template +std::string point_g2_affine_to_hexadecimal_str(const libff::G2 &point) +{ + libff::G2 affine_p = point; + affine_p.to_affine_coordinates(); + return "[\"0x" + + libsnark_bigint_to_hexadecimal_str>( + affine_p.X.c1.as_bigint()) + + "\", \"0x" + + libsnark_bigint_to_hexadecimal_str>( + affine_p.X.c0.as_bigint()) + + "\"],\n [\"0x" + + libsnark_bigint_to_hexadecimal_str>( + affine_p.Y.c1.as_bigint()) + + "\", \"0x" + + libsnark_bigint_to_hexadecimal_str>( + affine_p.Y.c0.as_bigint()) + + "\"]"; +} + +} // namespace libzeth + +#endif // __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__ diff --git a/libzeth/core/include_libff.hpp b/libzeth/core/include_libff.hpp new file mode 100644 index 000000000..748014cf0 --- /dev/null +++ b/libzeth/core/include_libff.hpp @@ -0,0 +1,14 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_CORE_INCLUDE_LIBFF__ +#define __ZETH_CORE_INCLUDE_LIBFF__ + +// Include minimal set of libff types for curve-independent operations. + +#include +#include +#include + +#endif // __ZETH_CORE_INCLUDE_LIBFF__ diff --git a/libzeth/core/include_libsnark.hpp b/libzeth/core/include_libsnark.hpp new file mode 100644 index 000000000..ceccc7d5e --- /dev/null +++ b/libzeth/core/include_libsnark.hpp @@ -0,0 +1,16 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_CORE_INCLUDE_LIBSNARK_HPP__ +#define __ZETH_CORE_INCLUDE_LIBSNARK_HPP__ + +// Include minimal libsnark headers for snark-independent processing of +// circuits. + +#include "libzeth/core/include_libff.hpp" + +#include +#include + +#endif // __ZETH_CORE_INCLUDE_LIBSNARK_HPP__ diff --git a/libzeth/types/joinsplit.hpp b/libzeth/core/joinsplit_input.hpp similarity index 86% rename from libzeth/types/joinsplit.hpp rename to libzeth/core/joinsplit_input.hpp index 258d2eaa1..ed956b7b8 100644 --- a/libzeth/types/joinsplit.hpp +++ b/libzeth/core/joinsplit_input.hpp @@ -2,11 +2,11 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_TYPES_JOINSPLIT_HPP__ -#define __ZETH_TYPES_JOINSPLIT_HPP__ +#ifndef __ZETH_CORE_JOINSPLIT_INPUT_HPP__ +#define __ZETH_CORE_JOINSPLIT_INPUT_HPP__ -#include "libzeth/types/bits.hpp" -#include "libzeth/types/note.hpp" +#include "libzeth/core/bits.hpp" +#include "libzeth/core/note.hpp" #include #include @@ -48,4 +48,4 @@ template class joinsplit_input } // namespace libzeth -#endif // __ZETH_TYPES_JOINSPLIT_HPP__ +#endif // __ZETH_CORE_JOINSPLIT_INPUT_HPP__ diff --git a/libzeth/types/merkle_tree_field.hpp b/libzeth/core/merkle_tree_field.hpp similarity index 86% rename from libzeth/types/merkle_tree_field.hpp rename to libzeth/core/merkle_tree_field.hpp index 0685550ec..41d0a3da4 100644 --- a/libzeth/types/merkle_tree_field.hpp +++ b/libzeth/core/merkle_tree_field.hpp @@ -2,10 +2,11 @@ // Content taken and adapted from: // https://github.com/scipr-lab/libsnark/blob/master/libsnark/common/data_structures/merkle_tree.hpp -#ifndef __ZETH_TYPES_MERKLE_TREE_FIELD_HPP__ -#define __ZETH_TYPES_MERKLE_TREE_FIELD_HPP__ +#ifndef __ZETH_CORE_MERKLE_TREE_FIELD_HPP__ +#define __ZETH_CORE_MERKLE_TREE_FIELD_HPP__ + +#include "libzeth/core/include_libff.hpp" -#include #include #include #include @@ -51,6 +52,7 @@ template class merkle_tree_field }; } // namespace libzeth -#include "libzeth/types/merkle_tree_field.tcc" -#endif // __ZETH_TYPES_MERKLE_TREE_FIELD_HPP__ +#include "libzeth/core/merkle_tree_field.tcc" + +#endif // __ZETH_CORE_MERKLE_TREE_FIELD_HPP__ diff --git a/libzeth/types/merkle_tree_field.tcc b/libzeth/core/merkle_tree_field.tcc similarity index 97% rename from libzeth/types/merkle_tree_field.tcc rename to libzeth/core/merkle_tree_field.tcc index c6e91c3c1..d6f1f3c69 100644 --- a/libzeth/types/merkle_tree_field.tcc +++ b/libzeth/core/merkle_tree_field.tcc @@ -2,10 +2,10 @@ // Content taken and adapted from: // https://github.com/scipr-lab/libsnark/blob/master/libsnark/common/data_structures/merkle_tree.tcc -#ifndef __ZETH_TYPES_MERKLE_TREE_FIELD_TCC__ -#define __ZETH_TYPES_MERKLE_TREE_FIELD_TCC__ +#ifndef __ZETH_CORE_MERKLE_TREE_FIELD_TCC__ +#define __ZETH_CORE_MERKLE_TREE_FIELD_TCC__ -#include "libzeth/circuits/mimc/mimc_mp.hpp" +#include "libzeth/core/merkle_tree_field.hpp" #include #include @@ -233,4 +233,4 @@ void merkle_tree_field::dump() const } // namespace libzeth -#endif // __ZETH_TYPES_MERKLE_TREE_FIELD_TCC__ +#endif // __ZETH_CORE_MERKLE_TREE_FIELD_TCC__ diff --git a/libzeth/core/multi_exp.hpp b/libzeth/core/multi_exp.hpp new file mode 100644 index 000000000..6a4032e39 --- /dev/null +++ b/libzeth/core/multi_exp.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_CORE_MULTI_EXP_HPP__ +#define __ZETH_CORE_MULTI_EXP_HPP__ + +#include "libzeth/core/include_libff.hpp" + +namespace libzeth +{ + +template +GroupT multi_exp( + typename std::vector::const_iterator gs_start, + typename std::vector::const_iterator gs_end, + typename std::vector::const_iterator fs_start, + typename std::vector::const_iterator fs_end); + +template +GroupT multi_exp( + const std::vector &gs, const libff::Fr_vector &fs); + +} // namespace libzeth + +#include "libzeth/core/multi_exp.tcc" + +#endif // __ZETH_CORE_MULTI_EXP_HPP__ diff --git a/libzeth/snarks/groth16/mpc/multi_exp.tcc b/libzeth/core/multi_exp.tcc similarity index 54% rename from libzeth/snarks/groth16/mpc/multi_exp.tcc rename to libzeth/core/multi_exp.tcc index 8a38434ac..209a2ded8 100644 --- a/libzeth/snarks/groth16/mpc/multi_exp.tcc +++ b/libzeth/core/multi_exp.tcc @@ -2,24 +2,23 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_MULTI_EXP_TCC__ -#define __ZETH_SNARKS_GROTH16_MULTI_EXP_TCC__ +#ifndef __ZETH_CORE_MULTI_EXP_TCC__ +#define __ZETH_CORE_MULTI_EXP_TCC__ -#include "libzeth/snarks/groth16/mpc/multi_exp.hpp" +#include "libzeth/core/multi_exp.hpp" namespace libzeth { -template +template GroupT multi_exp( - typename std::vector>::const_iterator gs_start, - typename std::vector>::const_iterator gs_end, - typename std::vector>::const_iterator fs_start, - typename std::vector>::const_iterator fs_end) + typename std::vector::const_iterator gs_start, + typename std::vector::const_iterator gs_end, + typename std::vector::const_iterator fs_start, + typename std::vector::const_iterator fs_end) { - using Fr = libff::Fr; const libff::multi_exp_method Method = libff::multi_exp_method_BDLO12; - return libff::multi_exp_with_mixed_addition( + return libff::multi_exp_with_mixed_addition( gs_start, gs_end, fs_start, fs_end, 1); } @@ -37,4 +36,4 @@ GroupT multi_exp(const std::vector &gs, const libff::Fr_vector &fs) } // namespace libzeth -#endif // __ZETH_SNARKS_GROTH16_MULTI_EXP_TCC__ +#endif // __ZETH_CORE_MULTI_EXP_TCC__ diff --git a/libzeth/types/note.hpp b/libzeth/core/note.hpp similarity index 88% rename from libzeth/types/note.hpp rename to libzeth/core/note.hpp index 034de8423..44567519a 100644 --- a/libzeth/types/note.hpp +++ b/libzeth/core/note.hpp @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_TYPES_NOTE_HPP__ -#define __ZETH_TYPES_NOTE_HPP__ +#ifndef __ZETH_CORE_NOTE_HPP__ +#define __ZETH_CORE_NOTE_HPP__ -#include "libzeth/types/bits.hpp" +#include "libzeth/core/bits.hpp" #include @@ -53,4 +53,4 @@ class zeth_note : public base_note } // namespace libzeth -#endif // __ZETH_TYPES_NOTE_HPP__ \ No newline at end of file +#endif // __ZETH_CORE_NOTE_HPP__ diff --git a/libzeth/util.cpp b/libzeth/core/utils.cpp similarity index 78% rename from libzeth/util.cpp rename to libzeth/core/utils.cpp index e50f965c5..17743e25a 100644 --- a/libzeth/util.cpp +++ b/libzeth/core/utils.cpp @@ -2,11 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/util.hpp" - -#include "libzeth/zeth.h" +#include "libzeth/core/utils.hpp" #include +#include #include #include #include @@ -14,13 +13,12 @@ namespace libzeth { -// Takes an hexadecimal string and converts it into a binary vector -std::vector hex_to_binary_vector(std::string hex_str) +std::vector hexadecimal_str_to_binary_vector(std::string hex_str) { std::vector result; std::vector tmp; - std::vector zero_vector( - hex_str.length() * 4, 0); // Each hex character is encoded on 4bits + // Each hex character is encoded on 4 bits + std::vector zero_vector(hex_str.length() * 4, 0); const std::vector vect0 = {0, 0, 0, 0}; const std::vector vect1 = {0, 0, 0, 1}; @@ -117,39 +115,13 @@ std::vector hex_to_binary_vector(std::string hex_str) return result; } -// Takes an hexadecimal digest and converts it into a binary vector -std::vector hex_digest_to_binary_vector(std::string hex_str) -{ - return hex_to_binary_vector(hex_str); -} - -bits384 hex_value_to_bits384(std::string str) +std::vector hexadecimal_digest_to_binary_vector(std::string hex_str) { - return get_bits384_from_vector(hex_to_binary_vector(str)); -} - -bits256 hex_digest_to_bits256(std::string str) -{ - if (str.length() != 64) { - throw std::length_error( - "Invalid string length for the given hex digest (should be " - "64)"); - } - - return get_bits256_from_vector(hex_to_binary_vector(str)); -} - -bits64 hex_value_to_bits64(std::string str) -{ - if (str.length() != 16) { - throw std::length_error( - "Invalid string length for the given hex digest (should be " - "16)"); - } - - return get_bits64_from_vector(hex_to_binary_vector(str)); + return hexadecimal_str_to_binary_vector(hex_str); } +/// Returns the binary representation of the given +/// unsigned integer of type `size_t`. std::vector convert_uint_to_binary(size_t x) { std::vector ret; @@ -203,22 +175,6 @@ std::string hexadecimal_str_to_binary_str(const std::string &s) return out; } -/// Takes an hexadecimal string and converts it to an array of bytes (uint8_t*) -int hexadecimal_str_to_binary(char *source_str, uint8_t *dest_buffer) -{ - char *line = source_str; - char *data = line; - int offset; - int read_byte; - int data_len = 0; - - while (sscanf(data, "%02x%n", &read_byte, &offset) == 1) { - dest_buffer[data_len++] = read_byte; - data += offset; - } - return data_len; -} - std::string binary_str_to_hexadecimal_str(const void *s, const size_t size) { std::string out; @@ -227,7 +183,6 @@ std::string binary_str_to_hexadecimal_str(const void *s, const size_t size) const uint8_t *in = (const uint8_t *)s; for (size_t i = 0; i < size; ++i) { const uint8_t byte = in[i]; - // printf("byte: %x\n", (uint32_t)byte); out.push_back(nibble_hex(byte >> 4)); out.push_back(nibble_hex(byte & 0x0f)); } @@ -243,7 +198,6 @@ std::string binary_str_to_hexadecimal_str(const std::string &s) const uint8_t *in = (const uint8_t *)s.c_str(); for (size_t i = 0; i < s.size(); ++i) { const uint8_t byte = in[i]; - // printf("byte: %x\n", (int)(int8_t)byte); out.push_back(nibble_hex(byte >> 4)); out.push_back(nibble_hex(byte & 0x0f)); } @@ -251,6 +205,21 @@ std::string binary_str_to_hexadecimal_str(const std::string &s) return out; } +int hexadecimal_str_to_byte_array(char *source_str, uint8_t *dest_buffer) +{ + char *line = source_str; + char *data = line; + int offset; + int read_byte; + int data_len = 0; + + while (sscanf(data, "%02x%n", &read_byte, &offset) == 1) { + dest_buffer[data_len++] = read_byte; + data += offset; + } + return data_len; +} + void erase_substring(std::string &string, const std::string &substring) { size_t position = string.find(substring); diff --git a/libzeth/core/utils.hpp b/libzeth/core/utils.hpp new file mode 100644 index 000000000..98c6e90ca --- /dev/null +++ b/libzeth/core/utils.hpp @@ -0,0 +1,78 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_CORE_UTILS_HPP__ +#define __ZETH_CORE_UTILS_HPP__ + +#include "libzeth/core/bits.hpp" + +#include +#include +#include +#include + +namespace libzeth +{ + +/// Takes a container with a `size()` method containing a multiple of 8 +/// elements. The elements (considered to be bit-like) are divided into "bytes" +/// (groups of 8), and the order of these "bytes" is reversed. The order of +/// "bits" within each "byte" is preserved. +template T swap_byte_endianness(T v); + +/// Returns the binary encoding of the address of a leaf node in a binary tree. +/// The resulting binary encoding is correctly padded such that its length +/// corresponds to the depth of the tree. +/// This function throws an exception if called for an `address` which +/// is bigger than the MAX_ADDRESS = 2^{TreeDepth} +template +std::vector address_bits_from_address(size_t address); + +/// Takes an hexadecimal string and converts it into a binary vector. +/// This function throws an exception if called with an invalid hexadecimal +/// string. +std::vector hexadecimal_str_to_binary_vector(std::string str); + +/// Takes an hexadecimal digest and converts it into a binary vector. +/// This function throws an exception if called with an invalid hexadecimal +/// digest. +std::vector hexadecimal_digest_to_binary_vector(std::string str); + +/// Returns the little endian binary encoding of the integer x. +std::vector convert_uint_to_binary(size_t x); + +std::string hexadecimal_str_to_binary_str(const std::string &s); +std::string binary_str_to_hexadecimal_str(const void *s, const size_t size); +std::string binary_str_to_hexadecimal_str(const std::string &s); + +/// Takes an hexadecimal string and converts it to an array of bytes (uint8_t*). +/// The result is written in the `dest_buffer` passed as argument during the +/// function call. +/// The function returns the number of bytes converted. +int hexadecimal_str_to_byte_array(char *source_str, uint8_t *dest_buffer); + +/// Function that erases the given `substring` from the string +/// passed as first argument. +void erase_substring(std::string &string, const std::string &substring); + +/// interface for StructuredT typed below: +/// { +/// bool is_well_formed() const; +/// } +/// +/// Throw if input is not well-formed. The type being checked should conform +/// to the StructuredT interface above. +template +void check_well_formed(const StructuredT &v, const char *name); + +/// For some iterable container of objects comforming to StructuredT, throw if +/// any entry is not well-formed. +template +bool container_is_well_formed(const StructuredTs &values); + +} // namespace libzeth + +#include "libzeth/core/utils.tcc" + +#endif // __ZETH_CORE_UTILS_HPP__ diff --git a/libzeth/util.tcc b/libzeth/core/utils.tcc similarity index 60% rename from libzeth/util.tcc rename to libzeth/core/utils.tcc index 47597183f..f89d71fdd 100644 --- a/libzeth/util.tcc +++ b/libzeth/core/utils.tcc @@ -2,16 +2,17 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_UTIL_TCC__ -#define __ZETH_UTIL_TCC__ +#ifndef __ZETH_CORE_UTILS_TCC__ +#define __ZETH_CORE_UTILS_TCC__ -#include "libzeth/util.hpp" +#include "libzeth/core/utils.hpp" + +#include +#include // required for std::length_error on linux namespace libzeth { -// Takes a containers with a size method and reverse the elements' order -// The elements should represent bits template T swap_byte_endianness(T v) { size_t len = v.size(); @@ -39,8 +40,8 @@ std::vector address_bits_from_address(size_t address) std::vector binary = convert_uint_to_binary(address); std::vector result(TreeDepth, 0); + // Address encoded on more bits that the address space allows if (binary.size() > TreeDepth) { - // Address encoded on more bits that the address space allows throw std::invalid_argument("Address overflow"); } @@ -50,6 +51,7 @@ std::vector address_bits_from_address(size_t address) for (size_t i = 0; i < binary.size(); i++) { result[i] = binary[i]; } + // We return the "back padded" vector return result; } @@ -57,30 +59,6 @@ std::vector address_bits_from_address(size_t address) return binary; } -/// Function that converts an hexadecimal string into a field element. -/// This function throws a `invalid_argument` exception if the conversion fails. -template -FieldT hexadecimal_str_to_field_element(std::string field_str) -{ - // Remove prefix if any - erase_substring(field_str, std::string("0x")); - - // 1 byte will be populated by 2 hexadecimal characters - uint8_t val[field_str.size() / 2]; - - char cstr[field_str.size() + 1]; - strcpy(cstr, field_str.c_str()); - - int res = hexadecimal_str_to_binary(cstr, val); - if (res == 0) { - throw std::invalid_argument("Invalid hexadecimal string"); - } - - libff::bigint el = - libsnark_bigint_from_bytes(val); - return FieldT(el); -} - template bool container_is_well_formed(const StructuredTs &values) { @@ -101,14 +79,6 @@ void check_well_formed(const StructuredT &v, const char *name) } } -template -void check_well_formed_(const StructuredT &v, const char *name) -{ - if (!is_well_formed(v)) { - throw std::invalid_argument(std::string(name) + " not well-formed"); - } -} - } // namespace libzeth -#endif // __ZETH_UTIL_TCC__ +#endif // __ZETH_CORE_UTILS_TCC__ diff --git a/libzeth/include_libsnark.hpp b/libzeth/include_libsnark.hpp deleted file mode 100644 index 211d7e126..000000000 --- a/libzeth/include_libsnark.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#pragma once - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" - -#if defined(ZKSNARK_GROTH16) -#include -#include -#include -#include -#elif defined(ZKSNARK_PGHR13) -#include -#include -#include -#include -#else -#error ZKSNARK not defined -#endif - -#pragma GCC diagnostic pop diff --git a/libzeth/libsnark_helpers/debug_helpers.cpp b/libzeth/libsnark_helpers/debug_helpers.cpp deleted file mode 100644 index c1b12f28b..000000000 --- a/libzeth/libsnark_helpers/debug_helpers.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#include "libzeth/libsnark_helpers/debug_helpers.hpp" - -#include "libzeth/util.hpp" - -namespace libzeth -{ - -boost::filesystem::path get_path_to_setup_directory() -{ - const char *path = std::getenv("ZETH_TRUSTED_SETUP_DIR"); - if (nullptr == path) { - // Fallback destination if the ZETH_TRUSTED_SETUP_DIR env var is not set - return "../trusted_setup"; - } - - return boost::filesystem::path(path); -} - -boost::filesystem::path get_path_to_debug_directory() -{ - const char *path_to_debug_directory = std::getenv("ZETH_DEBUG_DIR"); - if (path_to_debug_directory == NULL) { - // Fallback destination if the ZETH_DEBUG_DIR env var is not set - path_to_debug_directory = "../debug"; - } - - boost::filesystem::path setup_dir(path_to_debug_directory); - return setup_dir; -} - -bool replace(std::string &str, const std::string &from, const std::string &to) -{ - size_t start_pos = str.find(from); - if (start_pos == std::string::npos) { - return false; - } - - str.replace(start_pos, from.length(), to); - return true; -} - -} // namespace libzeth \ No newline at end of file diff --git a/libzeth/libsnark_helpers/debug_helpers.hpp b/libzeth/libsnark_helpers/debug_helpers.hpp deleted file mode 100644 index e4ff1c139..000000000 --- a/libzeth/libsnark_helpers/debug_helpers.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_DEBUG_HELPERS_HPP__ -#define __ZETH_DEBUG_HELPERS_HPP__ - -#include -#include -#include -#include -#include - -namespace libzeth -{ - -template -std::string hex_from_libsnark_bigint( - const libff::bigint &limbs); - -template -libff::bigint libsnark_bigint_from_bytes( - const uint8_t bytes[(FieldT::num_bits + 8 - 1) / 8]); - -template -std::string point_g1_affine_as_hex(const libff::G1 &point); - -template -std::string point_g2_affine_as_hex(const libff::G2 &point); - -boost::filesystem::path get_path_to_setup_directory(); -boost::filesystem::path get_path_to_debug_directory(); - -bool replace(std::string &str, const std::string &from, const std::string &to); - -} // namespace libzeth -#include "libzeth/libsnark_helpers/debug_helpers.tcc" - -#endif // __ZETH_DEBUG_HELPERS_HPP__ diff --git a/libzeth/libsnark_helpers/debug_helpers.tcc b/libzeth/libsnark_helpers/debug_helpers.tcc deleted file mode 100644 index 9261a267c..000000000 --- a/libzeth/libsnark_helpers/debug_helpers.tcc +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_DEBUG_HELPERS_TCC__ -#define __ZETH_DEBUG_HELPERS_TCC__ - -#include -#include -#include -#include -#include -#include - -// This file uses types and preprocessor variables defined in the `gmp.h` -// header: -// - `mp_size_t` -// - `GMP_LIMB_BITS` -// - `GMP_NAIL_BITS` - -namespace libzeth -{ - -// WARNING: The following function assumes that NAILS are NOT used -// See Section 8.2 (page 68): https://gmplib.org/gmp-man-6.2.0.pdf -// In other words, we assume below that: -// - GMP_NUMB_BITS = GMP_LIMB_BITS and thus, -// - GMP_NAIL_BITS = 0 -// -// This function decomposes a bigint into an array of bytes. -// -// For instance, if the number of bits in a Limb is 64, -// and we have `input_bigint = [Limb0, Limb1, Limb2, Limb3]`, -// where every Limb{i} is of type `mp_limb_t`, then the function returns -// -// x = [x0, ..., x7, x8, ..., x15, x16, ..., x23, x24, ..., x31] -// ^ ^ ^ ^ ^ ^ ^ ^ -// |_______| |________| |_________| |_________| -// | | | | -// Limb3 Limb2 Limb1 Limb0 -// -// where all x_i's are bytes (uint8_t) -template -std::string hex_from_libsnark_bigint( - const libff::bigint &limbs) -{ - const unsigned bytes_per_limb = (GMP_LIMB_BITS + 8 - 1) / 8; - - uint8_t x[bytes_per_limb * FieldT::num_limbs]; - for (unsigned i = 0; i < FieldT::num_limbs; i++) { - for (unsigned j = 0; j < bytes_per_limb; j++) { - x[i * 8 + j] = uint8_t( - uint64_t(limbs.data[(FieldT::num_limbs - 1) - i]) >> - (GMP_LIMB_BITS - 8 * (j + 1))); - } - } - - std::stringstream ss; - - // Display every byte as 2 hexadecimal characters - ss << std::setfill('0'); - for (unsigned i = 0; i < bytes_per_limb * FieldT::num_limbs; i++) { - ss << std::hex << std::setw(2) << (int)x[i]; - } - std::string str = ss.str(); - - return str; -} - -// WARNING: The following function assumes that NAILS are NOT used -// See Section 8.2 (page 68): https://gmplib.org/gmp-man-6.2.0.pdf -// In other words, we assume below that: -// - GMP_NUMB_BITS = GMP_LIMB_BITS and thus, -// - GMP_NAIL_BITS = 0 -// -// This function recomposes a bigint from an array of bytes. -// -// For instance, if the number of bits in a Limb is 64, and we have as input: -// x = [x0, ..., x7, x8, ..., x15, x16, ..., x23, x24, ..., x31] -// ^ ^ ^ ^ ^ ^ ^ ^ -// |_______| |________| |_________| |_________| -// | | | | -// Limb3 Limb2 Limb1 Limb0 -// where all x_i's are bytes (uint8_t) -// -// then the function returns: -// and we have `res_bigint = [Limb0, Limb1, Limb2, Limb3]`, -// where every Limb{i} is of type `mp_limb_t`, -template -libff::bigint libsnark_bigint_from_bytes( - const uint8_t bytes[((GMP_LIMB_BITS + 8 - 1) / 8) * FieldT::num_limbs]) -{ - const unsigned bytes_per_limb = (GMP_LIMB_BITS + 8 - 1) / 8; - - libff::bigint res; - - for (unsigned i = 0; i < FieldT::num_limbs; i++) { - for (unsigned j = 0; j < bytes_per_limb; j++) { - res.data[FieldT::num_limbs - i - 1] |= - mp_limb_t(bytes[i * 8 + j]) << (GMP_LIMB_BITS - 8 * (j + 1)); - } - } - return res; -} - -template -std::string point_g1_affine_as_hex(const libff::G1 &point) -{ - libff::G1 affine_p = point; - affine_p.to_affine_coordinates(); - return "\"0x" + - hex_from_libsnark_bigint>(affine_p.X.as_bigint()) + - "\", \"0x" + - hex_from_libsnark_bigint>(affine_p.Y.as_bigint()) + - "\""; -} - -template -std::string point_g2_affine_as_hex(const libff::G2 &point) -{ - libff::G2 affine_p = point; - affine_p.to_affine_coordinates(); - return "[\"0x" + - hex_from_libsnark_bigint>(affine_p.X.c1.as_bigint()) + - "\", \"0x" + - hex_from_libsnark_bigint>(affine_p.X.c0.as_bigint()) + - "\"],\n [\"0x" + - hex_from_libsnark_bigint>(affine_p.Y.c1.as_bigint()) + - "\", \"0x" + - hex_from_libsnark_bigint>(affine_p.Y.c0.as_bigint()) + - "\"]"; -} - -} // namespace libzeth - -#endif // __ZETH_DEBUG_HELPERS_TCC__ diff --git a/libzeth/libsnark_helpers/libsnark_helpers.hpp b/libzeth/libsnark_helpers/libsnark_helpers.hpp deleted file mode 100644 index ead1759c2..000000000 --- a/libzeth/libsnark_helpers/libsnark_helpers.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// DISCLAIMER: -// Content taken and adapted from: -// wraplibsnark.cpp (originally written by Jacob Eberhardt and Dennis Kuhnert) - -#ifndef __ZETH_LIBSNARK_HELPERS_HPP__ -#define __ZETH_LIBSNARK_HELPERS_HPP__ - -#include "libzeth/libsnark_helpers/debug_helpers.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Contains required interfaces and types (keypair, proof, generator, prover, -// verifier) -#include "libzeth/libsnark_helpers/extended_proof.hpp" -#include "libzeth/snarks_alias.hpp" -#include "libzeth/snarks_core_imports.hpp" -#include "libzeth/zeth.h" - -namespace libzeth -{ - -template -void write_to_file(boost::filesystem::path path, serializableT &obj); -template -serializableT load_from_file(boost::filesystem::path path); - -template -void serialize_proving_key_to_file( - provingKeyT &pk, boost::filesystem::path pk_path); -template -provingKeyT deserialize_proving_key_from_file( - boost::filesystem::path pk_path); -template -void serialize_verification_key_to_file( - verificationKeyT &vk, boost::filesystem::path vk_path); -template -verificationKeyT deserialize_verification_key_from_file( - boost::filesystem::path vk_path); - -template -void write_setup(keyPairT keypair, boost::filesystem::path setup_dir = ""); - -template -void fill_stringstream_with_json_constraints( - libsnark::linear_combination> constraints, - std::stringstream &ss); -template -void r1cs_to_json( - libsnark::protoboard> pb, boost::filesystem::path path = ""); - -} // namespace libzeth -#include "libzeth/libsnark_helpers/libsnark_helpers.tcc" - -#endif // __ZETH_LIBSNARK_HELPERS_HPP__ diff --git a/libzeth/snarks/groth16/mpc/hash_utils.cpp b/libzeth/mpc/groth16/hash_utils.cpp similarity index 97% rename from libzeth/snarks/groth16/mpc/hash_utils.cpp rename to libzeth/mpc/groth16/hash_utils.cpp index e668f8030..d7d5e5b34 100644 --- a/libzeth/snarks/groth16/mpc/hash_utils.cpp +++ b/libzeth/mpc/groth16/hash_utils.cpp @@ -2,9 +2,9 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/hash_utils.hpp" +#include "libzeth/mpc/groth16/hash_utils.hpp" -#include "libzeth/util.hpp" +#include "libzeth/core/utils.hpp" namespace libzeth { diff --git a/libzeth/snarks/groth16/mpc/hash_utils.hpp b/libzeth/mpc/groth16/hash_utils.hpp similarity index 94% rename from libzeth/snarks/groth16/mpc/hash_utils.hpp rename to libzeth/mpc/groth16/hash_utils.hpp index ff4319936..0d4d59236 100644 --- a/libzeth/snarks/groth16/mpc/hash_utils.hpp +++ b/libzeth/mpc/groth16/hash_utils.hpp @@ -2,8 +2,8 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_MPC_HASH_UTILS_HPP__ -#define __ZETH_SNARKS_GROTH16_MPC_HASH_UTILS_HPP__ +#ifndef __ZETH_MPC_GROTH16_HASH_UTILS_HPP__ +#define __ZETH_MPC_GROTH16_HASH_UTILS_HPP__ #include #include @@ -93,4 +93,4 @@ class hash_istream_wrapper : public std::istream } // namespace libzeth -#endif // __ZETH_SNARKS_GROTH16_MPC_HASH_UTILS_HPP__ +#endif // __ZETH_MPC_GROTH16_HASH_UTILS_HPP__ diff --git a/libzeth/snarks/groth16/mpc/mpc_utils.hpp b/libzeth/mpc/groth16/mpc_utils.hpp similarity index 85% rename from libzeth/snarks/groth16/mpc/mpc_utils.hpp rename to libzeth/mpc/groth16/mpc_utils.hpp index 4cce19076..ce1d190b8 100644 --- a/libzeth/snarks/groth16/mpc/mpc_utils.hpp +++ b/libzeth/mpc/groth16/mpc_utils.hpp @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_MPC_UTILS_HPP__ -#define __ZETH_SNARKS_GROTH16_MPC_UTILS_HPP__ +#ifndef __ZETH_MPC_GROTH16_MPC_UTILS_HPP__ +#define __ZETH_MPC_GROTH16_MPC_UTILS_HPP__ -#include "libzeth/include_libsnark.hpp" +#include "libzeth/snarks/groth16/groth16_snark.hpp" #include @@ -31,9 +31,9 @@ namespace libzeth template class srs_powersoftau; template class srs_lagrange_evaluations; -/// Output from linear combination $L_1$ - the linear combination of elements -/// in powersoftau, based on a specific circuit. Implements the interfaces of -/// StructuredT and ReadableT templates. +/// Output from linear combination $L_1$ - the linear combination of +/// elements in powersoftau, based on a specific circuit. Implements the +/// interfaces of StructuredT and ReadableT templates. template class srs_mpc_layer_L1 { public: @@ -75,6 +75,7 @@ srs_mpc_layer_L1 mpc_compute_linearcombination( const libsnark::qap_instance> &qap); } // namespace libzeth -#include "libzeth/snarks/groth16/mpc/mpc_utils.tcc" -#endif // __ZETH_SNARKS_GROTH16_MPC_UTILS_HPP__ +#include "libzeth/mpc/groth16/mpc_utils.tcc" + +#endif // __ZETH_MPC_GROTH16_MPC_UTILS_HPP__ diff --git a/libzeth/snarks/groth16/mpc/mpc_utils.tcc b/libzeth/mpc/groth16/mpc_utils.tcc similarity index 95% rename from libzeth/snarks/groth16/mpc/mpc_utils.tcc rename to libzeth/mpc/groth16/mpc_utils.tcc index 6749893db..ea609a294 100644 --- a/libzeth/snarks/groth16/mpc/mpc_utils.tcc +++ b/libzeth/mpc/groth16/mpc_utils.tcc @@ -2,14 +2,14 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_MPC_UTILS_TCC__ -#define __ZETH_SNARKS_GROTH16_MPC_UTILS_TCC__ +#ifndef __ZETH_MPC_GROTH16_MPC_UTILS_TCC__ +#define __ZETH_MPC_GROTH16_MPC_UTILS_TCC__ -#include "libzeth/snarks/groth16/mpc/evaluator_from_lagrange.hpp" -#include "libzeth/snarks/groth16/mpc/mpc_utils.hpp" -#include "libzeth/snarks/groth16/mpc/multi_exp.hpp" -#include "libzeth/snarks/groth16/mpc/phase2.hpp" -#include "libzeth/util.hpp" +#include "libzeth/core/evaluator_from_lagrange.hpp" +#include "libzeth/core/multi_exp.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/mpc/groth16/mpc_utils.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" #include #include @@ -258,4 +258,4 @@ srs_mpc_layer_L1 mpc_compute_linearcombination( } // namespace libzeth -#endif // __ZETH_SNARKS_GROTH16_MPC_UTILS_TCC__ +#endif // __ZETH_MPC_GROTH16_MPC_UTILS_TCC__ diff --git a/libzeth/snarks/groth16/mpc/phase2.cpp b/libzeth/mpc/groth16/phase2.cpp similarity index 97% rename from libzeth/snarks/groth16/mpc/phase2.cpp rename to libzeth/mpc/groth16/phase2.cpp index f4addc7c8..7e40d1f66 100644 --- a/libzeth/snarks/groth16/mpc/phase2.cpp +++ b/libzeth/mpc/groth16/phase2.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/phase2.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" namespace libzeth { diff --git a/libzeth/snarks/groth16/mpc/phase2.hpp b/libzeth/mpc/groth16/phase2.hpp similarity index 88% rename from libzeth/snarks/groth16/mpc/phase2.hpp rename to libzeth/mpc/groth16/phase2.hpp index 15d41a43d..da9d4b9ac 100644 --- a/libzeth/snarks/groth16/mpc/phase2.hpp +++ b/libzeth/mpc/groth16/phase2.hpp @@ -2,30 +2,30 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_MPC_PHASE2_HPP__ -#define __ZETH_SNARKS_GROTH16_MPC_PHASE2_HPP__ +#ifndef __ZETH_MPC_GROTH16_PHASE2_HPP__ +#define __ZETH_MPC_GROTH16_PHASE2_HPP__ -#include "libzeth/include_libsnark.hpp" -#include "libzeth/snarks/groth16/mpc/hash_utils.hpp" +#include "libzeth/mpc/groth16/hash_utils.hpp" +#include "libzeth/snarks/groth16/groth16_snark.hpp" -// Structures and operations related to the "Phase 2" MPC described in -// [BoweGM17]. Parts of the implementation use techniques from the -// "Phase2" library from "zk-SNARK MPCs, made easy". -// -// References: -// -// \[BoweGM17] -// "Scalable Multi-party Computation for zk-SNARK Parameters in the Random -// Beacon Model" -// Sean Bowe and Ariel Gabizon and Ian Miers, -// IACR Cryptology ePrint Archive 2017, -// -// -// "Phase2" (From "zk-SNARK MPCs, made easy" library -// https://github.com/ebfull/phase2) -// -// "Sapling MPC" ("Multi-party computation for Zcash's Sapling zk-SNARK public -// parameters" https://github.com/zcash-hackworks/sapling-mpc) +/// Structures and operations related to the "Phase 2" MPC described in +/// [BoweGM17]. Parts of the implementation use techniques from the +/// "Phase2" library from "zk-SNARK MPCs, made easy". +/// +/// References: +/// +/// \[BoweGM17] +/// "Scalable Multi-party Computation for zk-SNARK Parameters in the Random +/// Beacon Model" +/// Sean Bowe and Ariel Gabizon and Ian Miers, +/// IACR Cryptology ePrint Archive 2017, +/// +/// +/// "Phase2" (From "zk-SNARK MPCs, made easy" library +/// https://github.com/ebfull/phase2) +/// +/// "Sapling MPC" ("Multi-party computation for Zcash's Sapling zk-SNARK public +/// parameters" https://github.com/zcash-hackworks/sapling-mpc) namespace libzeth { @@ -295,25 +295,8 @@ libsnark::r1cs_gg_ppzksnark_keypair mpc_create_key_pair( libsnark::r1cs_constraint_system> &&cs, const libsnark::qap_instance> &qap); -/// Check proving key entries -template -bool is_well_formed(const libsnark::r1cs_gg_ppzksnark_proving_key &pk); - -/// Check verification key entries -template -bool is_well_formed( - const libsnark::r1cs_gg_ppzksnark_verification_key &vk); - -/// Write a keypair to a stream. -template -void mpc_write_keypair( - std::ostream &out, const libsnark::r1cs_gg_ppzksnark_keypair keypair); - -/// Read a keypair from a stream. -template -libsnark::r1cs_gg_ppzksnark_keypair mpc_read_keypair(std::istream &in); - } // namespace libzeth -#include "libzeth/snarks/groth16/mpc/phase2.tcc" -#endif // __ZETH_SNARKS_GROTH16_MPC_PHASE2_HPP__ +#include "libzeth/mpc/groth16/phase2.tcc" + +#endif // __ZETH_MPC_GROTH16_PHASE2_HPP__ diff --git a/libzeth/snarks/groth16/mpc/phase2.tcc b/libzeth/mpc/groth16/phase2.tcc similarity index 91% rename from libzeth/snarks/groth16/mpc/phase2.tcc rename to libzeth/mpc/groth16/phase2.tcc index d9a5764a5..edd94e599 100644 --- a/libzeth/snarks/groth16/mpc/phase2.tcc +++ b/libzeth/mpc/groth16/phase2.tcc @@ -2,15 +2,14 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_MPC_PHASE2_TCC__ -#define __ZETH_SNARKS_GROTH16_MPC_PHASE2_TCC__ +#ifndef __ZETH_MPC_GROTH16_PHASE2_TCC__ +#define __ZETH_MPC_GROTH16_PHASE2_TCC__ -#include "libzeth/snarks/groth16/mpc/phase2.hpp" -// This comment preserves include order under clang-format. -#include "libzeth/snarks/groth16/mpc/chacha_rng.hpp" -#include "libzeth/snarks/groth16/mpc/mpc_utils.hpp" -#include "libzeth/snarks/groth16/mpc/powersoftau_utils.hpp" -#include "libzeth/util.hpp" +#include "libzeth/core/chacha_rng.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/mpc/groth16/mpc_utils.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" +#include "libzeth/mpc/groth16/powersoftau_utils.hpp" #include @@ -741,60 +740,6 @@ libsnark::r1cs_gg_ppzksnark_keypair mpc_create_key_pair( std::move(pk), std::move(vk)); } -template -bool is_well_formed(const libsnark::r1cs_gg_ppzksnark_proving_key &pk) -{ - if (!pk.alpha_g1.is_well_formed() || !pk.beta_g1.is_well_formed() || - !pk.beta_g2.is_well_formed() || !pk.delta_g1.is_well_formed() || - !pk.delta_g2.is_well_formed() || - !container_is_well_formed(pk.A_query) || - !container_is_well_formed(pk.L_query)) { - return false; - } - - using knowledge_commitment = - libsnark::knowledge_commitment, libff::G1>; - for (const knowledge_commitment &b : pk.B_query.values) { - if (!b.g.is_well_formed() || !b.h.is_well_formed()) { - return false; - } - } - - return true; -} - -template -bool is_well_formed(const libsnark::r1cs_gg_ppzksnark_verification_key &vk) -{ - if (!vk.alpha_g1.is_well_formed() || !vk.beta_g2.is_well_formed() || - !vk.delta_g2.is_well_formed() || !vk.ABC_g1.first.is_well_formed()) { - return false; - } - - return container_is_well_formed(vk.ABC_g1.rest.values); -} - -template -void mpc_write_keypair( - std::ostream &out, const libsnark::r1cs_gg_ppzksnark_keypair keypair) -{ - check_well_formed_(keypair.pk, "proving key (read)"); - check_well_formed_(keypair.vk, "verification key (read)"); - out << keypair.pk; - out << keypair.vk; -} - -template -libsnark::r1cs_gg_ppzksnark_keypair mpc_read_keypair(std::istream &in) -{ - libsnark::r1cs_gg_ppzksnark_keypair keypair; - in >> keypair.pk; - in >> keypair.vk; - check_well_formed_(keypair.pk, "proving key (read)"); - check_well_formed_(keypair.vk, "verification key (read)"); - return keypair; -} - } // namespace libzeth -#endif // __ZETH_SNARKS_GROTH16_MPC_PHASE2_TCC__ +#endif // __ZETH_MPC_GROTH16_PHASE2_TCC__ diff --git a/libzeth/snarks/groth16/mpc/powersoftau_utils.cpp b/libzeth/mpc/groth16/powersoftau_utils.cpp similarity index 88% rename from libzeth/snarks/groth16/mpc/powersoftau_utils.cpp rename to libzeth/mpc/groth16/powersoftau_utils.cpp index 8cf51e9ea..52775e2fe 100644 --- a/libzeth/snarks/groth16/mpc/powersoftau_utils.cpp +++ b/libzeth/mpc/groth16/powersoftau_utils.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/powersoftau_utils.hpp" +#include "libzeth/mpc/groth16/powersoftau_utils.hpp" namespace libzeth { @@ -119,15 +119,12 @@ void write_powersoftau_fp2( } // namespace -// Functions below are only implemented for the alt_bn128 curve type. -using ppT = libff::alt_bn128_pp; - -void read_powersoftau_fr(std::istream &in, libff::Fr &out) +void read_powersoftau_fr(std::istream &in, libff::alt_bn128_Fr &out) { read_powersoftau_fp(in, out); } -void read_powersoftau_g1(std::istream &in, libff::G1 &out) +void read_powersoftau_g1(std::istream &in, libff::alt_bn128_G1 &out) { uint8_t marker; in.read((char *)&marker, 1); @@ -135,15 +132,15 @@ void read_powersoftau_g1(std::istream &in, libff::G1 &out) switch (marker) { case 0x00: // zero - out = libff::G1::zero(); + out = libff::alt_bn128_G1::zero(); break; case 0x04: { // Uncompressed - libff::Fq x; - libff::Fq y; + libff::alt_bn128_Fq x; + libff::alt_bn128_Fq y; read_powersoftau_fp(in, x); read_powersoftau_fp(in, y); - out = libff::G1(x, y, libff::Fq::one()); + out = libff::alt_bn128_G1(x, y, libff::Fq::one()); break; } default: @@ -157,7 +154,7 @@ void read_powersoftau_fq2(std::istream &in, libff::alt_bn128_Fq2 &out) read_powersoftau_fp2(in, out); } -void read_powersoftau_g2(std::istream &in, libff::G2 &out) +void read_powersoftau_g2(std::istream &in, libff::alt_bn128_G2 &out) { uint8_t marker; in.read((char *)&marker, 1); @@ -165,7 +162,7 @@ void read_powersoftau_g2(std::istream &in, libff::G2 &out) switch (marker) { case 0x00: // zero - out = libff::G2::zero(); + out = libff::alt_bn128_G2::zero(); break; case 0x04: @@ -181,7 +178,7 @@ void read_powersoftau_g2(std::istream &in, libff::G2 &out) } } -void write_powersoftau_fr(std::ostream &out, const libff::Fr &fr) +void write_powersoftau_fr(std::ostream &out, const libff::alt_bn128_Fr &fr) { write_powersoftau_fp(out, fr); } @@ -191,7 +188,7 @@ void write_powersoftau_fq2(std::ostream &out, const libff::alt_bn128_Fq2 &fq2) write_powersoftau_fp2(out, fq2); } -void write_powersoftau_g1(std::ostream &out, const libff::G1 &g1) +void write_powersoftau_g1(std::ostream &out, const libff::alt_bn128_G1 &g1) { if (g1.is_zero()) { const uint8_t zero = 0; @@ -208,7 +205,7 @@ void write_powersoftau_g1(std::ostream &out, const libff::G1 &g1) write_powersoftau_fp(out, copy.Y); } -void write_powersoftau_g2(std::ostream &out, const libff::G2 &g2) +void write_powersoftau_g2(std::ostream &out, const libff::alt_bn128_G2 &g2) { if (g2.is_zero()) { const uint8_t zero = 0; @@ -225,10 +222,10 @@ void write_powersoftau_g2(std::ostream &out, const libff::G2 &g2) write_powersoftau_fp2(out, copy.Y); } -srs_powersoftau powersoftau_load(std::istream &in, size_t n) +srs_powersoftau powersoftau_load(std::istream &in, size_t n) { - using G1 = libff::G1; - using G2 = libff::G2; + using G1 = libff::G1; + using G2 = libff::G2; // From: // @@ -290,7 +287,7 @@ srs_powersoftau powersoftau_load(std::istream &in, size_t n) G2 beta_g2; read_powersoftau_g2(in, beta_g2); - srs_powersoftau pot( + srs_powersoftau pot( std::move(tau_powers_g1), std::move(tau_powers_g2), std::move(alpha_tau_powers_g1), @@ -300,7 +297,8 @@ srs_powersoftau powersoftau_load(std::istream &in, size_t n) return pot; } -void powersoftau_write(std::ostream &out, const srs_powersoftau &pot) +void powersoftau_write( + std::ostream &out, const srs_powersoftau &pot) { check_well_formed(pot, "powersoftau (write)"); diff --git a/libzeth/snarks/groth16/mpc/powersoftau_utils.hpp b/libzeth/mpc/groth16/powersoftau_utils.hpp similarity index 85% rename from libzeth/snarks/groth16/mpc/powersoftau_utils.hpp rename to libzeth/mpc/groth16/powersoftau_utils.hpp index 5fb39e3d9..153791e09 100644 --- a/libzeth/snarks/groth16/mpc/powersoftau_utils.hpp +++ b/libzeth/mpc/groth16/powersoftau_utils.hpp @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH_POWERSOFTAU_UTILS_HPP__ -#define __ZETH_SNARKS_GROTH_POWERSOFTAU_UTILS_HPP__ +#ifndef __ZETH_MPC_GROTH16_POWERSOFTAU_UTILS_HPP__ +#define __ZETH_MPC_GROTH16_POWERSOFTAU_UTILS_HPP__ -#include "libzeth/include_libsnark.hpp" +#include "libzeth/snarks/groth16/groth16_snark.hpp" #include #include @@ -14,8 +14,8 @@ namespace libzeth { /// Output from the first phase of the MPC (powersoftau). The structure -/// matches that data exactly (no indication of degree, etc), so that it can be -/// loaded directly. Implements the interface of StructuredT. +/// matches that data exactly (no indication of degree, etc), so that it can +/// be loaded directly. Implements the interface of StructuredT. template class srs_powersoftau { public: @@ -88,6 +88,9 @@ srs_powersoftau dummy_powersoftau_from_secrets( /// interest. template srs_powersoftau dummy_powersoftau(size_t n); +/// The POT code here is specific to the ppT = libff::alt_bn128_pp curve. +using srs_pot_pp = libff::alt_bn128_pp; + // Utility functions for reading and writing data as formatted by the // powersoftau process. @@ -106,16 +109,15 @@ void write_powersoftau_g2(std::ostream &out, const libff::alt_bn128_G2 &g2); /// https://github.com/clearmatics/powersoftau /// /// Expect at least 'n' powers in the file. -srs_powersoftau powersoftau_load( - std::istream &in, size_t n); +srs_powersoftau powersoftau_load(std::istream &in, size_t n); /// Write powersoftau data, in the format compatible with /// powersoftau_load. void powersoftau_write( - std::ostream &in, const srs_powersoftau &pot); + std::ostream &in, const srs_powersoftau &pot); -/// Implements the SameRatio described in "Scalable Multi-party Computation for -/// zk-SNARK Parameters in the Random Beacon Model" +/// Implements the SameRatio described in "Scalable Multi-party Computation +/// for zk-SNARK Parameters in the Random Beacon Model" /// http://eprint.iacr.org/2017/1050 template bool same_ratio( @@ -131,7 +133,8 @@ bool same_ratio( /// b1 = b1s[0] * r_0 + ... + b1s[n] * r_n /// and check same_ratio((a1, b1), (a2, b2)). /// -/// (Based on merge_pairs function from https://github.com/ebfull/powersoftau/) +/// (Based on merge_pairs function from +/// https://github.com/ebfull/powersoftau/) template bool same_ratio_vectors( const std::vector> &a1s, @@ -147,8 +150,8 @@ bool same_ratio_vectors( const std::vector> &a2s, const std::vector> &b2s); -/// Checks that consecutive entries in a1s all have a ratio consistent with (a2, -/// b2). +/// Checks that consecutive entries in a1s all have a ratio consistent with +/// (a2, b2). template bool same_ratio_consecutive( const std::vector> &a1s, @@ -166,14 +169,15 @@ bool same_ratio_consecutive( template bool powersoftau_is_well_formed(const srs_powersoftau &pot); -/// Compute the evaluation of the lagrange polynomials in G1 and G2, along with -/// some useful factors. The results can be cached and used against any QAP, -/// provided its domain size matched. +/// Compute the evaluation of the lagrange polynomials in G1 and G2, along +/// with some useful factors. The results can be cached and used against any +/// QAP, provided its domain size matched. template srs_lagrange_evaluations powersoftau_compute_lagrange_evaluations( const srs_powersoftau &pot, const size_t n); } // namespace libzeth -#include "libzeth/snarks/groth16/mpc/powersoftau_utils.tcc" -#endif // __ZETH_SNARKS_GROTH_POWERSOFTAU_UTILS_HPP__ +#include "libzeth/mpc/groth16/powersoftau_utils.tcc" + +#endif // __ZETH_MPC_GROTH16_POWERSOFTAU_UTILS_HPP__ diff --git a/libzeth/snarks/groth16/mpc/powersoftau_utils.tcc b/libzeth/mpc/groth16/powersoftau_utils.tcc similarity index 98% rename from libzeth/snarks/groth16/mpc/powersoftau_utils.tcc rename to libzeth/mpc/groth16/powersoftau_utils.tcc index 9704d0625..a4930d1aa 100644 --- a/libzeth/snarks/groth16/mpc/powersoftau_utils.tcc +++ b/libzeth/mpc/groth16/powersoftau_utils.tcc @@ -2,11 +2,11 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_SNARKS_GROTH16_POWERSOFTAU_UTILS_TCC__ -#define __ZETH_SNARKS_GROTH16_POWERSOFTAU_UTILS_TCC__ +#ifndef __ZETH_MPC_GROTH16_POWERSOFTAU_UTILS_TCC__ +#define __ZETH_MPC_GROTH16_POWERSOFTAU_UTILS_TCC__ -#include "libzeth/snarks/groth16/mpc/powersoftau_utils.hpp" -#include "libzeth/util.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/mpc/groth16/powersoftau_utils.hpp" #include @@ -617,4 +617,4 @@ srs_lagrange_evaluations powersoftau_compute_lagrange_evaluations( } // namespace libzeth -#endif // __ZETH_SNARKS_GROTH16_POWERSOFTAU_UTILS_TCC__ +#endif // __ZETH_MPC_GROTH16_POWERSOFTAU_UTILS_TCC__ diff --git a/libzeth/serialization/api/api_io.cpp b/libzeth/serialization/api/api_io.cpp new file mode 100644 index 000000000..aad4e1926 --- /dev/null +++ b/libzeth/serialization/api/api_io.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#include "libzeth/serialization/api/api_io.hpp" + +namespace libzeth +{ + +zeth_note parse_zeth_note(const zeth_proto::ZethNote ¬e) +{ + bits256 note_apk = get_bits256_from_hexadecimal_str(note.apk()); + bits64 note_value = get_bits64_from_hexadecimal_str(note.value()); + bits256 note_rho = get_bits256_from_hexadecimal_str(note.rho()); + bits256 note_trap_r = get_bits256_from_hexadecimal_str(note.trap_r()); + + return zeth_note(note_apk, note_value, note_rho, note_trap_r); +} + +} // namespace libzeth diff --git a/libzeth/util_api.hpp b/libzeth/serialization/api/api_io.hpp similarity index 50% rename from libzeth/util_api.hpp rename to libzeth/serialization/api/api_io.hpp index d3b5f2ce7..4d9120e5b 100644 --- a/libzeth/util_api.hpp +++ b/libzeth/serialization/api/api_io.hpp @@ -2,19 +2,22 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_UTIL_API_HPP__ -#define __ZETH_UTIL_API_HPP__ +#ifndef __ZETH_SERIALIZATION_API_IO_HPP__ +#define __ZETH_SERIALIZATION_API_IO_HPP__ -#include "api/snark_messages.pb.h" -#include "api/zeth_messages.pb.h" -#include "libzeth/libsnark_helpers/debug_helpers.hpp" -#include "libzeth/libsnark_helpers/extended_proof.hpp" -#include "libzeth/types/bits.hpp" -#include "libzeth/types/joinsplit.hpp" -#include "libzeth/types/note.hpp" -#include "libzeth/util.hpp" +#include "libzeth/core/bits.hpp" +#include "libzeth/core/extended_proof.hpp" +#include "libzeth/core/include_libff.hpp" +#include "libzeth/core/include_libsnark.hpp" +#include "libzeth/core/joinsplit_input.hpp" +#include "libzeth/core/note.hpp" +#include "libzeth/core/utils.hpp" -#include +#include +#include + +/// This set of function allows to consume RPC calls data +/// and to format zeth data structures into proto messages namespace libzeth { @@ -27,17 +30,6 @@ template joinsplit_input parse_joinsplit_input( const zeth_proto::JoinsplitInput &input); -template -zeth_proto::HexPointBaseGroup1Affine format_hexPointBaseGroup1Affine( - const libff::G1 &point); - -template -zeth_proto::HexPointBaseGroup2Affine format_hexPointBaseGroup2Affine( - const libff::G2 &point); - -template -std::string format_primary_inputs(std::vector> public_inputs); - template libff::G1 parse_hexPointBaseGroup1Affine( const zeth_proto::HexPointBaseGroup1Affine &point); @@ -50,34 +42,36 @@ template std::vector> parse_str_primary_inputs(std::string input_str); template -libzeth::extended_proof parse_groth16_extended_proof( - const zeth_proto::ExtendedProof &ext_proof); +libsnark::accumulation_vector> parse_str_accumulation_vector( + std::string acc_vector_str); template -libzeth::extended_proof parse_pghr13_extended_proof( - const zeth_proto::ExtendedProof &ext_proof); +zeth_proto::HexPointBaseGroup1Affine format_hexPointBaseGroup1Affine( + const libff::G1 &point); template -libzeth::extended_proof parse_extended_proof( - const zeth_proto::ExtendedProof &ext_proof); +zeth_proto::HexPointBaseGroup2Affine format_hexPointBaseGroup2Affine( + const libff::G2 &point); template -libsnark::accumulation_vector> parse_str_accumulation_vector( - std::string acc_vector_str); +std::string format_primary_inputs(std::vector> public_inputs); -template -libsnark::r1cs_gg_ppzksnark_verification_key parse_groth16_vk( - const zeth_proto::VerificationKey &verification_key); +template +void format_extendedProof( + extended_proof &ext_proof, + zeth_proto::ExtendedProof *message); template -libsnark::r1cs_ppzksnark_verification_key parse_pghr13_vk( - const zeth_proto::VerificationKey &verification_key); +std::string format_accumulation_vector(std::vector> acc_vector); -template -libzeth::verificationKeyT parse_verification_key( - const zeth_proto::VerificationKey &verification_key); +template +void format_verificationKey( + const typename snarkApiT::snarkT::VerifKeyT &vk, + zeth_proto::VerificationKey *message); } // namespace libzeth -#include "libzeth/util_api.tcc" -#endif // __ZETH_UTIL_API_HPP__ +// templatized implementations +#include "libzeth/serialization/api/api_io.tcc" + +#endif // __ZETH_SERIALIZATION_API_IO_HPP__ diff --git a/libzeth/util_api.tcc b/libzeth/serialization/api/api_io.tcc similarity index 53% rename from libzeth/util_api.tcc rename to libzeth/serialization/api/api_io.tcc index 31d8aa6eb..7b84e1ae4 100644 --- a/libzeth/util_api.tcc +++ b/libzeth/serialization/api/api_io.tcc @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_UTIL_API_TCC__ -#define __ZETH_UTIL_API_TCC__ +#ifndef __ZETH_SERIALIZATION_API_API_IO_TCC__ +#define __ZETH_SERIALIZATION_API_API_IO_TCC__ -#include "libzeth/util_api.hpp" +#include "libzeth/serialization/api/api_io.hpp" namespace libzeth { @@ -28,8 +28,10 @@ joinsplit_input parse_joinsplit_input( bits_addr input_address_bits = get_bits_addr_from_vector( address_bits_from_address(inputAddress)); - bits256 input_spending_ask = hex_digest_to_bits256(input.spending_ask()); - bits256 input_nullifier = hex_digest_to_bits256(input.nullifier()); + bits256 input_spending_ask = + get_bits256_from_hexadecimal_str(input.spending_ask()); + bits256 input_nullifier = + get_bits256_from_hexadecimal_str(input.nullifier()); std::vector input_merkle_path; for (size_t i = 0; i < TreeDepth; i++) { @@ -45,69 +47,6 @@ joinsplit_input parse_joinsplit_input( input_nullifier); } -template -zeth_proto::HexPointBaseGroup1Affine format_hexPointBaseGroup1Affine( - const libff::G1 &point) -{ - libff::G1 aff = point; - aff.to_affine_coordinates(); - std::string x_coord = - "0x" + hex_from_libsnark_bigint>(aff.X.as_bigint()); - std::string y_coord = - "0x" + hex_from_libsnark_bigint>(aff.Y.as_bigint()); - - zeth_proto::HexPointBaseGroup1Affine res; - res.set_x_coord(x_coord); - res.set_y_coord(y_coord); - - return res; -} - -template -zeth_proto::HexPointBaseGroup2Affine format_hexPointBaseGroup2Affine( - const libff::G2 &point) -{ - libff::G2 aff = point; - aff.to_affine_coordinates(); - std::string x_c1_coord = - "0x" + hex_from_libsnark_bigint>(aff.X.c1.as_bigint()); - std::string x_c0_coord = - "0x" + hex_from_libsnark_bigint>(aff.X.c0.as_bigint()); - std::string y_c1_coord = - "0x" + hex_from_libsnark_bigint>(aff.Y.c1.as_bigint()); - std::string y_c0_coord = - "0x" + hex_from_libsnark_bigint>(aff.Y.c0.as_bigint()); - - zeth_proto::HexPointBaseGroup2Affine res; - res.set_x_c0_coord(x_c0_coord); - res.set_x_c1_coord(x_c1_coord); - res.set_y_c0_coord(y_c0_coord); - res.set_y_c1_coord(y_c1_coord); - - return res; -} - -template -std::string format_primary_inputs(std::vector> public_inputs) -{ - std::stringstream ss; - ss << "["; - for (size_t i = 0; i < public_inputs.size(); ++i) { - ss << "\"0x" - << libzeth::hex_from_libsnark_bigint>( - public_inputs[i].as_bigint()) - << "\""; - if (i < public_inputs.size() - 1) { - ss << ", "; - } - } - ss << "]"; - std::string inputs_json_str = ss.str(); - - return inputs_json_str; -} - -/// Parse points in affine coordinates template libff::G1 parse_hexPointBaseGroup1Affine( const zeth_proto::HexPointBaseGroup1Affine &point) @@ -122,7 +61,6 @@ libff::G1 parse_hexPointBaseGroup1Affine( return res; } -/// Parse points in affine coordinates template libff::G2 parse_hexPointBaseGroup2Affine( const zeth_proto::HexPointBaseGroup2Affine &point) @@ -175,85 +113,10 @@ std::vector> parse_str_primary_inputs(std::string input_str) return res; } -template -libzeth::extended_proof parse_groth16_extended_proof( - const zeth_proto::ExtendedProof &ext_proof) -{ - const zeth_proto::ExtendedProofGROTH16 &e_proof = - ext_proof.groth16_extended_proof(); - // G1 - libff::G1 a = parse_hexPointBaseGroup1Affine(e_proof.a()); - // G2 - libff::G2 b = parse_hexPointBaseGroup2Affine(e_proof.b()); - // G1 - libff::G1 c = parse_hexPointBaseGroup1Affine(e_proof.c()); - - std::vector> inputs = - libsnark::r1cs_primary_input>( - parse_str_primary_inputs(e_proof.inputs())); - - libsnark::r1cs_gg_ppzksnark_proof proof( - std::move(a), std::move(b), std::move(c)); - libzeth::extended_proof res(proof, inputs); - - return res; -} - -template -libzeth::extended_proof parse_pghr13_extended_proof( - const zeth_proto::ExtendedProof &ext_proof) -{ - const zeth_proto::ExtendedProofPGHR13 &e_proof = - ext_proof.pghr13_extended_proof(); - - libff::G1 a = parse_hexPointBaseGroup1Affine(e_proof.a()); - libff::G1 a_p = parse_hexPointBaseGroup1Affine(e_proof.a_p()); - libsnark::knowledge_commitment, libff::G1> g_A(a, a_p); - - libff::G2 b = parse_hexPointBaseGroup2Affine(e_proof.b()); - libff::G1 b_p = parse_hexPointBaseGroup1Affine(e_proof.b_p()); - libsnark::knowledge_commitment, libff::G1> g_B(b, b_p); - - libff::G1 c = parse_hexPointBaseGroup1Affine(e_proof.c()); - libff::G1 c_p = parse_hexPointBaseGroup1Affine(e_proof.c_p()); - libsnark::knowledge_commitment, libff::G1> g_C(c, c_p); - - libff::G1 h = parse_hexPointBaseGroup1Affine(e_proof.h()); - libff::G1 k = parse_hexPointBaseGroup1Affine(e_proof.k()); - - libsnark::r1cs_ppzksnark_proof proof( - std::move(g_A), - std::move(g_B), - std::move(g_C), - std::move(h), - std::move(k)); - libsnark::r1cs_primary_input> inputs = - libsnark::r1cs_primary_input>( - parse_str_primary_inputs(e_proof.inputs())); - libzeth::extended_proof res(proof, inputs); - - return res; -} - -template -libzeth::extended_proof parse_extended_proof( - const zeth_proto::ExtendedProof &ext_proof) -{ -#ifdef ZKSNARK_PGHR13 - return parse_pghr13_extended_proof(ext_proof); -#elif ZKSNARK_GROTH16 - return parse_groth16_extended_proof(ext_proof); -#else -#error You must define one of the SNARK_* symbols indicated into the CMakelists.txt file. -#endif -} - template libsnark::accumulation_vector> parse_str_accumulation_vector( std::string acc_vector_str) { - // std::string input_str = "[[one0, one1], [two0, two1], [three0, three1], - // [four0, four1]]"; char *cstr = new char[acc_vector_str.length() + 1]; std::strcpy(cstr, acc_vector_str.c_str()); char *pos; @@ -317,83 +180,73 @@ libsnark::accumulation_vector> parse_str_accumulation_vector( } template -libsnark::r1cs_gg_ppzksnark_verification_key parse_groth16_vk( - const zeth_proto::VerificationKey &verification_key) +zeth_proto::HexPointBaseGroup1Affine format_hexPointBaseGroup1Affine( + const libff::G1 &point) { - const zeth_proto::VerificationKeyGROTH16 &verif_key = - verification_key.groth16_verification_key(); - // G1 - libff::G1 alpha_g1 = - parse_hexPointBaseGroup1Affine(verif_key.alpha_g1()); - // G2 - libff::G2 beta_g2 = - parse_hexPointBaseGroup2Affine(verif_key.beta_g2()); - // G2 - libff::G2 delta_g2 = - parse_hexPointBaseGroup2Affine(verif_key.delta_g2()); - - // Parse the accumulation vector which has been stringyfied - // and which is in the form: - // [ - // [point 1], - // [point 2], - // ... - // ] - libsnark::accumulation_vector> abc_g1 = - parse_str_accumulation_vector(verif_key.abc_g1()); - - libsnark::r1cs_gg_ppzksnark_verification_key vk( - alpha_g1, beta_g2, delta_g2, abc_g1); - - return vk; + libff::G1 aff = point; + aff.to_affine_coordinates(); + std::string x_coord = + "0x" + + libsnark_bigint_to_hexadecimal_str>(aff.X.as_bigint()); + std::string y_coord = + "0x" + + libsnark_bigint_to_hexadecimal_str>(aff.Y.as_bigint()); + + zeth_proto::HexPointBaseGroup1Affine res; + res.set_x_coord(x_coord); + res.set_y_coord(y_coord); + + return res; } template -libsnark::r1cs_ppzksnark_verification_key parse_pghr13_vk( - const zeth_proto::VerificationKey &verification_key) +zeth_proto::HexPointBaseGroup2Affine format_hexPointBaseGroup2Affine( + const libff::G2 &point) { - const zeth_proto::VerificationKeyPGHR13 &verif_key = - verification_key.pghr13_verification_key(); - // G2 - libff::G2 a = parse_hexPointBaseGroup2Affine(verif_key.a()); - // G1 - libff::G1 b = parse_hexPointBaseGroup1Affine(verif_key.b()); - // G2 - libff::G2 c = parse_hexPointBaseGroup2Affine(verif_key.c()); - // G2 - libff::G1 gamma = - parse_hexPointBaseGroup2Affine(verif_key.gamma()); - // G1 - libff::G1 gamma_beta_g1 = - parse_hexPointBaseGroup1Affine(verif_key.gamma_beta_g1()); - // G2 - libff::G2 gamma_beta_g2 = - parse_hexPointBaseGroup2Affine(verif_key.gamma_beta_g2()); - // G2 - libff::G2 z = parse_hexPointBaseGroup2Affine(verif_key.z()); - - libsnark::accumulation_vector> ic = - parse_str_accumulation_vector(verif_key.ic()); - - libsnark::r1cs_ppzksnark_verification_key vk( - a, b, c, gamma, gamma_beta_g1, gamma_beta_g2, z, ic); - - return vk; + libff::G2 aff = point; + aff.to_affine_coordinates(); + std::string x_c1_coord = + "0x" + libsnark_bigint_to_hexadecimal_str>( + aff.X.c1.as_bigint()); + std::string x_c0_coord = + "0x" + libsnark_bigint_to_hexadecimal_str>( + aff.X.c0.as_bigint()); + std::string y_c1_coord = + "0x" + libsnark_bigint_to_hexadecimal_str>( + aff.Y.c1.as_bigint()); + std::string y_c0_coord = + "0x" + libsnark_bigint_to_hexadecimal_str>( + aff.Y.c0.as_bigint()); + + zeth_proto::HexPointBaseGroup2Affine res; + res.set_x_c0_coord(x_c0_coord); + res.set_x_c1_coord(x_c1_coord); + res.set_y_c0_coord(y_c0_coord); + res.set_y_c1_coord(y_c1_coord); + + return res; } template -libzeth::verificationKeyT parse_verification_key( - const zeth_proto::VerificationKey &verification_key) +std::string format_primary_inputs(std::vector> public_inputs) { -#ifdef ZKSNARK_PGHR13 - return parse_pghr13_vk(verification_key); -#elif ZKSNARK_GROTH16 - return parse_groth16_vk(verification_key); -#else -#error You must define one of the SNARK_* symbols indicated into the CMakelists.txt file. -#endif + std::stringstream ss; + ss << "["; + for (size_t i = 0; i < public_inputs.size(); ++i) { + ss << "\"0x" + << libzeth::libsnark_bigint_to_hexadecimal_str>( + public_inputs[i].as_bigint()) + << "\""; + if (i < public_inputs.size() - 1) { + ss << ", "; + } + } + ss << "]"; + std::string inputs_json_str = ss.str(); + + return inputs_json_str; } } // namespace libzeth -#endif // __ZETH_UTIL_API_TCC__ +#endif // __ZETH_SERIALIZATION_API_API_IO_TCC__ diff --git a/libzeth/serialization/file_io.hpp b/libzeth/serialization/file_io.hpp new file mode 100644 index 000000000..d22189e01 --- /dev/null +++ b/libzeth/serialization/file_io.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SERIALIZATION_FILE_IO_HPP__ +#define __ZETH_SERIALIZATION_FILE_IO_HPP__ + +#include "libzeth/core/extended_proof.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace libzeth +{ + +template +void write_to_file(boost::filesystem::path path, serializableT &obj); + +template +serializableT load_from_file(boost::filesystem::path path); + +template +void serialize_proving_key_to_file( + const typename snarkT::ProvingKeyT &pk, boost::filesystem::path pk_path); + +template +typename snarkT::ProvingKeyT deserialize_proving_key_from_file( + boost::filesystem::path pk_path); + +template +void serialize_verification_key_to_file( + const typename snarkT::VerifKeyT &vk, boost::filesystem::path vk_path); + +template +typename snarkT::VerifKeyT deserialize_verification_key_from_file( + boost::filesystem::path vk_path); + +template +void serialize_setup_to_file( + const typename snarkT::KeypairT &keypair, + boost::filesystem::path setup_path = ""); + +template +void fill_stringstream_with_json_constraints( + libsnark::linear_combination> constraints, + std::stringstream &ss); + +template +void r1cs_to_json( + libsnark::protoboard> pb, + boost::filesystem::path r1cs_path = ""); + +} // namespace libzeth + +#include "libzeth/serialization/file_io.tcc" + +#endif // __ZETH_SERIALIZATION_FILE_IO_HPP__ diff --git a/libzeth/libsnark_helpers/libsnark_helpers.tcc b/libzeth/serialization/file_io.tcc similarity index 66% rename from libzeth/libsnark_helpers/libsnark_helpers.tcc rename to libzeth/serialization/file_io.tcc index 1326da453..e1e38c630 100644 --- a/libzeth/libsnark_helpers/libsnark_helpers.tcc +++ b/libzeth/serialization/file_io.tcc @@ -2,18 +2,20 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZETH_LIBSNARK_HELPERS_TCC__ -#define __ZETH_LIBSNARK_HELPERS_TCC__ +#ifndef __ZETH_SERIALIZATION_FILE_IO_TCC__ +#define __ZETH_SERIALIZATION_FILE_IO_TCC__ + +#include "libzeth/serialization/file_io.hpp" namespace libzeth { -// SerializableT represents any type that overloads the operator<< and -// operator>> of ostream and istream Note: Both r1cs_ppzksnark_proving_key and -// r1cs_ppzksnark_verifying_key implement these overloading, so both of them can -// easily be writen and loaded from files +/// SerializableT represents any type that overloads the operator<< and +/// operator>> of ostream and istream Note: Both r1cs_ppzksnark_proving_key and +/// r1cs_ppzksnark_verifying_key implement these overloading, so both of them +/// can easily be writen and loaded from files template -void write_to_file(boost::filesystem::path path, serializableT &obj) +void write_to_file(boost::filesystem::path path, const serializableT &obj) { // Convert the boost path into char* const char *str_path = path.string().c_str(); @@ -29,7 +31,7 @@ void write_to_file(boost::filesystem::path path, serializableT &obj) fh << ss.rdbuf(); fh.flush(); fh.close(); -}; +} template serializableT load_from_file(boost::filesystem::path path) @@ -55,59 +57,63 @@ serializableT load_from_file(boost::filesystem::path path) ss >> obj; return obj; -}; +} -template +template void serialize_proving_key_to_file( - provingKeyT &pk, boost::filesystem::path pk_path) + const typename snarkT::ProvingKeyT &pk, boost::filesystem::path pk_path) { - write_to_file>(pk_path, pk); -}; + write_to_file(pk_path, pk); +} -template -provingKeyT deserialize_proving_key_from_file( +template +typename snarkT::ProvingKeyT deserialize_proving_key_from_file( boost::filesystem::path pk_path) { - return load_from_file>(pk_path); -}; + return load_from_file(pk_path); +} -template +template void serialize_verification_key_to_file( - verificationKeyT &vk, boost::filesystem::path vk_path) + const typename snarkT::VerifKeyT &vk, boost::filesystem::path vk_path) { - write_to_file>(vk_path, vk); -}; + write_to_file(vk_path, vk); +} -template -verificationKeyT deserialize_verification_key_from_file( +template +typename snarkT::VerifKeyT deserialize_verification_key_from_file( boost::filesystem::path vk_path) { - return load_from_file>(vk_path); -}; + return load_from_file(vk_path); +} -template -void write_setup(keyPairT keypair, boost::filesystem::path setup_dir) +template +void serialize_setup_to_file( + const typename snarkT::KeypairT &keypair, + boost::filesystem::path setup_path) { - if (setup_dir.empty()) { - setup_dir = get_path_to_setup_directory(); + if (setup_path.empty()) { + setup_path = get_path_to_setup_directory(); } boost::filesystem::path vk_json("vk.json"); boost::filesystem::path vk_raw("vk.raw"); boost::filesystem::path pk_raw("pk.raw"); - boost::filesystem::path path_vk_json = setup_dir / vk_json; - boost::filesystem::path path_vk_raw = setup_dir / vk_raw; - boost::filesystem::path path_pk_raw = setup_dir / pk_raw; + boost::filesystem::path path_vk_json = setup_path / vk_json; + boost::filesystem::path path_vk_raw = setup_path / vk_raw; + boost::filesystem::path path_pk_raw = setup_path / pk_raw; - provingKeyT proving_key = keypair.pk; - verificationKeyT verification_key = keypair.vk; + typename snarkT::ProvingKeyT proving_key = keypair.pk; + typename snarkT::VerifKeyT verification_key = keypair.vk; - verification_key_to_json(verification_key, path_vk_json); + // Write the verification key in json format + snarkT::verification_key_to_json(verification_key, path_vk_json); - serialize_verification_key_to_file(verification_key, path_vk_raw); - serialize_proving_key_to_file(proving_key, path_pk_raw); -}; + // Write the verification and proving keys in raw format + serialize_verification_key_to_file(verification_key, path_vk_raw); + serialize_proving_key_to_file(proving_key, path_pk_raw); +} template void fill_stringstream_with_json_constraints( @@ -124,27 +130,27 @@ void fill_stringstream_with_json_constraints( ss << "{"; ss << "\"index\":" << lt.index << ","; ss << "\"value\":" - << "\"0x" + - hex_from_libsnark_bigint>(lt.coeff.as_bigint()) + << "\"0x" + libsnark_bigint_to_hexadecimal_str>( + lt.coeff.as_bigint()) << "\""; ss << "}"; count++; } ss << "]"; -}; +} template void r1cs_to_json( - libsnark::protoboard> pb, boost::filesystem::path path) + libsnark::protoboard> pb, boost::filesystem::path r1cs_path) { - if (path.empty()) { + if (r1cs_path.empty()) { // Used for debugging purpose boost::filesystem::path tmp_path = get_path_to_debug_directory(); boost::filesystem::path r1cs_json_file("r1cs.json"); - path = tmp_path / r1cs_json_file; + r1cs_path = tmp_path / r1cs_json_file; } // Convert the boost path into char* - const char *str_path = path.string().c_str(); + const char *str_path = r1cs_path.string().c_str(); // output inputs, right now need to compile with debug flag so that the // `variable_annotations` exists. Having trouble setting that up so will @@ -208,8 +214,8 @@ void r1cs_to_json( fh << ss.rdbuf(); fh.flush(); fh.close(); -}; +} } // namespace libzeth -#endif // __ZETH_LIBSNARK_HELPERS_TCC__ +#endif // __ZETH_SERIALIZATION_FILE_IO_TCC__ diff --git a/libzeth/serialization/filesystem_util.cpp b/libzeth/serialization/filesystem_util.cpp new file mode 100644 index 000000000..b51762afc --- /dev/null +++ b/libzeth/serialization/filesystem_util.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#include "libzeth/serialization/filesystem_util.hpp" + +namespace libzeth +{ + +boost::filesystem::path get_path_to_setup_directory() +{ + const char *path = std::getenv("ZETH_TRUSTED_SETUP_DIR"); + if (nullptr == path) { + // Fallback destination if the ZETH_TRUSTED_SETUP_DIR env var is not set + // We assume below that `std::getenv("HOME")` does not return `nullptr` + boost::filesystem::path home_path = + boost::filesystem::path(std::getenv("HOME")); + boost::filesystem::path zeth_setup("zeth_setup"); + boost::filesystem::path default_path = home_path / zeth_setup; + + return default_path; + } + + return boost::filesystem::path(path); +} + +boost::filesystem::path get_path_to_debug_directory() +{ + const char *path = std::getenv("ZETH_DEBUG_DIR"); + if (nullptr == path) { + // Fallback destination if the ZETH_DEBUG_DIR env var is not set + // We assume below that `std::getenv("HOME")` does not return `nullptr` + boost::filesystem::path home_path = + boost::filesystem::path(std::getenv("HOME")); + boost::filesystem::path zeth_debug("zeth_debug"); + boost::filesystem::path default_path = home_path / zeth_debug; + } + + return boost::filesystem::path(path); +} + +} // namespace libzeth diff --git a/libzeth/serialization/filesystem_util.hpp b/libzeth/serialization/filesystem_util.hpp new file mode 100644 index 000000000..6327ced19 --- /dev/null +++ b/libzeth/serialization/filesystem_util.hpp @@ -0,0 +1,33 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SERIALIZATION_FILESYSTEM_UTIL_HPP__ +#define __ZETH_SERIALIZATION_FILESYSTEM_UTIL_HPP__ + +#include "libzeth/core/include_libff.hpp" + +#include +#include +#include +#include + +namespace libzeth +{ + +/// This function returns the path to the setup directory in which the +/// SRS will be written. +/// This function assumes that the host OS is compliant with the POSIX +/// specification since it assumes that the HOME environment variable is set. +/// See: https://pubs.opengroup.org/onlinepubs/9699919799/ +boost::filesystem::path get_path_to_setup_directory(); + +/// This function returns the path to the debug directory used in Zeth. +/// This function assumes that the host OS is compliant with the POSIX +/// specification since it assumes that the HOME environment variable is set. +/// See: https://pubs.opengroup.org/onlinepubs/9699919799/ +boost::filesystem::path get_path_to_debug_directory(); + +} // namespace libzeth + +#endif // __ZETH_SERIALIZATION_FILESYSTEM_UTIL_HPP__ diff --git a/libzeth/snarks/default/default_api_handler.hpp b/libzeth/snarks/default/default_api_handler.hpp new file mode 100644 index 000000000..4c085f357 --- /dev/null +++ b/libzeth/snarks/default/default_api_handler.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_DEFAULT_DEFAULT_API_HANDLER_HPP__ +#define __ZETH_SNARKS_DEFAULT_DEFAULT_API_HANDLER_HPP__ + +#include "libzeth/snarks/default/default_snark.hpp" + +#if defined(ZKSNARK_PGHR13) +#include "libzeth/snarks/pghr13/pghr13_api_handler.hpp" +namespace libzeth +{ +template using default_api_handler = pghr13_api_handler; +} // namespace libzeth + +#elif defined(ZKSNARK_GROTH16) +#include "libzeth/snarks/groth16/groth16_api_handler.hpp" +namespace libzeth +{ +template using default_api_handler = groth16_api_handler; +} // namespace libzeth + +#else +#error No recognized SNARK_* macro defined (see CMakelists.txt). +#endif + +#endif // __ZETH_SNARKS_DEFAULT_DEFAULT_API_HANDLER_HPP__ diff --git a/libzeth/snarks/default/default_snark.hpp b/libzeth/snarks/default/default_snark.hpp new file mode 100644 index 000000000..5143492e6 --- /dev/null +++ b/libzeth/snarks/default/default_snark.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_DEFAULT_DEFAULT_SNARK_HPP__ +#define __ZETH_SNARKS_DEFAULT_DEFAULT_SNARK_HPP__ + +#if defined(ZKSNARK_PGHR13) +#include "libzeth/snarks/pghr13/pghr13_snark.hpp" +namespace libzeth +{ +template using default_snark = pghr13_snark; +} // namespace libzeth + +#elif defined(ZKSNARK_GROTH16) +#include "libzeth/snarks/groth16/groth16_snark.hpp" +namespace libzeth +{ +template using default_snark = groth16_snark; +} // namespace libzeth + +#else +#error No recognized SNARK_* macro defined (see CMakelists.txt). +#endif + +#endif // __ZETH_SNARKS_DEFAULT_DEFAULT_SNARK_HPP__ diff --git a/libzeth/snarks/groth16/api/response.hpp b/libzeth/snarks/groth16/api/response.hpp deleted file mode 100644 index 9a4023083..000000000 --- a/libzeth/snarks/groth16/api/response.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_RESPONSE_HPP__ -#define __ZETH_RESPONSE_HPP__ - -#include "api/snark_messages.grpc.pb.h" -#include "libzeth/libsnark_helpers/extended_proof.hpp" -#include "libzeth/util_api.hpp" - -namespace libzeth -{ - -template -void prepare_proof_response( - extended_proof &ext_proof, zeth_proto::ExtendedProof *message); -template -void prepare_verification_key_response( - libsnark::r1cs_gg_ppzksnark_verification_key &vk, - zeth_proto::VerificationKey *message); - -} // namespace libzeth -#include "libzeth/snarks/groth16/api/response.tcc" - -#endif // __ZETH_RESPONSE_HPP__ diff --git a/libzeth/snarks/groth16/api/response.tcc b/libzeth/snarks/groth16/api/response.tcc deleted file mode 100644 index 3b5d30c7e..000000000 --- a/libzeth/snarks/groth16/api/response.tcc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_RESPONSE_TCC__ -#define __ZETH_RESPONSE_TCC__ - -namespace libzeth -{ - -template -void prepare_proof_response( - extended_proof &ext_proof, zeth_proto::ExtendedProof *message) -{ - libsnark::r1cs_gg_ppzksnark_proof proof_obj = ext_proof.get_proof(); - - zeth_proto::HexPointBaseGroup1Affine *a = - new zeth_proto::HexPointBaseGroup1Affine(); - zeth_proto::HexPointBaseGroup2Affine *b = - new zeth_proto::HexPointBaseGroup2Affine(); // in G2 - zeth_proto::HexPointBaseGroup1Affine *c = - new zeth_proto::HexPointBaseGroup1Affine(); - - a->CopyFrom(format_hexPointBaseGroup1Affine(proof_obj.g_A)); - b->CopyFrom(format_hexPointBaseGroup2Affine(proof_obj.g_B)); // in G2 - c->CopyFrom(format_hexPointBaseGroup1Affine(proof_obj.g_C)); - - libsnark::r1cs_ppzksnark_primary_input public_inputs = - ext_proof.get_primary_input(); - - std::string inputs_json_str = - format_primary_inputs(std::vector>(public_inputs)); - - // Note on memory safety: set_allocated deleted the allocated objects - // See: - // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object - zeth_proto::ExtendedProofGROTH16 *grpc_extended_groth16_proof_obj = - message->mutable_groth16_extended_proof(); - - grpc_extended_groth16_proof_obj->set_allocated_a(a); - grpc_extended_groth16_proof_obj->set_allocated_b(b); - grpc_extended_groth16_proof_obj->set_allocated_c(c); - grpc_extended_groth16_proof_obj->set_inputs(inputs_json_str); -} - -template -void prepare_verification_key_response( - libsnark::r1cs_gg_ppzksnark_verification_key &vk, - zeth_proto::VerificationKey *message) -{ - zeth_proto::HexPointBaseGroup1Affine *a = - new zeth_proto::HexPointBaseGroup1Affine(); // in G1 - zeth_proto::HexPointBaseGroup2Affine *b = - new zeth_proto::HexPointBaseGroup2Affine(); // in G2 - zeth_proto::HexPointBaseGroup2Affine *d = - new zeth_proto::HexPointBaseGroup2Affine(); // in G2 - - a->CopyFrom(format_hexPointBaseGroup1Affine(vk.alpha_g1)); // in G1 - b->CopyFrom(format_hexPointBaseGroup2Affine(vk.beta_g2)); // in G2 - d->CopyFrom(format_hexPointBaseGroup2Affine(vk.delta_g2)); // in G2 - - std::stringstream ss; - unsigned abc_length = vk.ABC_g1.rest.indices.size() + 1; - ss << "[[" << point_g1_affine_as_hex(vk.ABC_g1.first) << "]"; - for (size_t i = 1; i < abc_length; ++i) { - auto vk_abc_i = - point_g1_affine_as_hex(vk.ABC_g1.rest.values[i - 1]); - ss << ",[" << vk_abc_i << "]"; - } - ss << "]"; - std::string abc_json_str = ss.str(); - - // Note on memory safety: set_allocated deleted the allocated objects - // See: - // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object - zeth_proto::VerificationKeyGROTH16 *grpc_verification_key_groth16 = - message->mutable_groth16_verification_key(); - - grpc_verification_key_groth16->set_allocated_alpha_g1(a); - grpc_verification_key_groth16->set_allocated_beta_g2(b); - grpc_verification_key_groth16->set_allocated_delta_g2(d); - grpc_verification_key_groth16->set_abc_g1(abc_json_str); -}; - -} // namespace libzeth - -#endif // __ZETH_RESPONSE_TCC__ diff --git a/libzeth/snarks/groth16/core/computation.hpp b/libzeth/snarks/groth16/core/computation.hpp deleted file mode 100644 index 3d29d7bfd..000000000 --- a/libzeth/snarks/groth16/core/computation.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_COMPUTATION_HPP__ -#define __ZETH_COMPUTATION_HPP__ - -#include "libzeth/libsnark_helpers/debug_helpers.hpp" -#include "libzeth/libsnark_helpers/extended_proof.hpp" - -#include -#include - -namespace libzeth -{ - -template -libsnark::r1cs_gg_ppzksnark_proof gen_proof( - const libsnark::protoboard> &pb, - const libsnark::r1cs_gg_ppzksnark_proving_key &proving_key); - -template -libsnark::r1cs_gg_ppzksnark_keypair gen_trusted_setup( - const libsnark::protoboard> &pb); - -template -bool verify( - const libzeth::extended_proof &ext_proof, - const libsnark::r1cs_gg_ppzksnark_verification_key &verification_key); - -} // namespace libzeth - -#include "libzeth/snarks/groth16/core/computation.tcc" - -#endif // __ZETH_COMPUTATION_HPP__ diff --git a/libzeth/snarks/groth16/core/computation.tcc b/libzeth/snarks/groth16/core/computation.tcc deleted file mode 100644 index 3a2649b6a..000000000 --- a/libzeth/snarks/groth16/core/computation.tcc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_COMPUTATION_TCC__ -#define __ZETH_COMPUTATION_TCC__ - -#include "libzeth/snarks/groth16/core/computation.hpp" - -namespace libzeth -{ - -// Generate the proof and returns a struct {proof, primary_input} -template -libsnark::r1cs_gg_ppzksnark_proof gen_proof( - const libsnark::protoboard> &pb, - const libsnark::r1cs_gg_ppzksnark_proving_key &proving_key) -{ - // See: - // https://github.com/scipr-lab/libsnark/blob/92a80f74727091fdc40e6021dc42e9f6b67d5176/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp#L81 - // For the definition of r1cs_primary_input and r1cs_auxiliary_input - libsnark::r1cs_primary_input> primary_input = - pb.primary_input(); - libsnark::r1cs_auxiliary_input> auxiliary_input = - pb.auxiliary_input(); - - // Generate proof from public input, auxiliary input - // (private/secret data), and proving key. For now, force a pow2 - // domain, in case the key came from the MPC. - proofT proof = libsnark::r1cs_gg_ppzksnark_prover( - proving_key, primary_input, auxiliary_input, true); - - return proof; -}; - -// Run the trusted setup and returns a struct {proving_key, verifying_key} -template -libsnark::r1cs_gg_ppzksnark_keypair gen_trusted_setup( - const libsnark::protoboard> &pb) -{ - // Generate verification and proving key (Trusted setup) from the R1CS - // (defined in the ZoKrates/wraplibsnark.cpp file) This function, basically - // reduces the R1CS into a QAP, and then encodes the QAP, along with a - // secret s and its set of powers, plus the alpha, beta, and the rest of the - // entries, in order to form the CRS (crs_f, shortcrs_f, as denoted in - // [GGPR12]) - - return libsnark::r1cs_gg_ppzksnark_generator( - pb.get_constraint_system(), true); -}; - -// Verification of a proof -template -bool verify( - const libzeth::extended_proof &ext_proof, - const libsnark::r1cs_gg_ppzksnark_verification_key &verification_key) -{ - return libsnark::r1cs_gg_ppzksnark_verifier_strong_IC( - verification_key, ext_proof.get_primary_input(), ext_proof.get_proof()); -}; - -} // namespace libzeth - -#endif // __ZETH_COMPUTATION_TCC__ diff --git a/libzeth/snarks/groth16/core/helpers.hpp b/libzeth/snarks/groth16/core/helpers.hpp deleted file mode 100644 index 096438f0a..000000000 --- a/libzeth/snarks/groth16/core/helpers.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_HELPERS_HPP__ -#define __ZETH_HELPERS_HPP__ - -#include "libzeth/libsnark_helpers/debug_helpers.hpp" - -#include -#include -#include - -namespace libzeth -{ - -template -void export_verification_key(libsnark::r1cs_gg_ppzksnark_keypair keypair); - -template -void display_proof(libsnark::r1cs_gg_ppzksnark_proof proof); - -template -void verification_key_to_json( - libsnark::r1cs_gg_ppzksnark_keypair keypair, - boost::filesystem::path path = ""); - -template -void proof_and_inputs_to_json( - libsnark::r1cs_gg_ppzksnark_proof proof, - libsnark::r1cs_ppzksnark_primary_input input, - boost::filesystem::path path = ""); - -template -void proof_to_json( - libsnark::r1cs_gg_ppzksnark_proof proof, boost::filesystem::path path); - -} // namespace libzeth -#include "libzeth/snarks/groth16/core/helpers.tcc" - -#endif // __ZETH_HELPERS_HPP__ diff --git a/libzeth/snarks/groth16/core/helpers.tcc b/libzeth/snarks/groth16/core/helpers.tcc deleted file mode 100644 index 6bff23d8d..000000000 --- a/libzeth/snarks/groth16/core/helpers.tcc +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_HELPER_TCC__ -#define __ZETH_HELPER_TCC__ - -namespace libzeth -{ - -template -void export_verification_key(libsnark::r1cs_gg_ppzksnark_keypair keypair) -{ - unsigned abc_length = keypair.vk.ABC_g1.rest.indices.size() + 1; - - std::cout << "\tVerification key in Solidity compliant format:{" - << "\n" - << "\t\tvk.alpha = Pairing.G1Point(" - << point_g1_affine_as_hex(keypair.vk.alpha_g1) << ");" - << "\n" - << "\t\tvk.beta = Pairing.G2Point(" - << point_g2_affine_as_hex(keypair.vk.beta_g2) << ");" - << "\n" - << "\t\tvk.delta = Pairing.G2Point(" - << point_g2_affine_as_hex(keypair.vk.delta_g2) << ");" - << "\n" - << "\t\tvk.ABC = new Pairing.G1Point[](" << abc_length << ");" - << "\n" - << "\t\tvk.ABC[0] = Pairing.G1Point(" - << point_g1_affine_as_hex(keypair.vk.ABC_g1.first) << ");" - << "\n"; - for (size_t i = 1; i < abc_length; ++i) { - auto vk_abc_i = - point_g1_affine_as_hex(keypair.vk.ABC_g1.rest.values[i - 1]); - std::cout << "\t\tvk.ABC[" << i << "] = Pairing.G1Point(" << vk_abc_i - << ");" - << "\n"; - } - // We flush std::cout only once at the end of the function - std::cout << "\t\t}" << std::endl; -}; - -template -void display_proof(libsnark::r1cs_gg_ppzksnark_proof proof) -{ - std::cout << "Proof:" - << "\n" - << "proof.A = Pairing.G1Point(" - << point_g1_affine_as_hex(proof.g_A) << ");" - << "\n" - << "proof.B = Pairing.G2Point(" - << point_g2_affine_as_hex(proof.g_B) << ");" - << "\n" - << "proof.C = Pairing.G1Point(" - << point_g1_affine_as_hex(proof.g_C) - // We flush std::cout only once at the end of the function - << ");" << std::endl; -}; - -template -void verification_key_to_json( - libsnark::r1cs_gg_ppzksnark_verification_key vk, - boost::filesystem::path path) -{ - if (path.empty()) { - boost::filesystem::path tmp_path = get_path_to_setup_directory(); - boost::filesystem::path vk_json_file("vk.json"); - path = tmp_path / vk_json_file; - } - // Convert boost path to char* - const char *str_path = path.string().c_str(); - - std::stringstream ss; - std::ofstream fh; - fh.open(str_path, std::ios::binary); - unsigned abc_length = vk.ABC_g1.rest.indices.size() + 1; - - ss << "{" - << "\n" - << "\t\"alpha\"" - << " :[" << point_g1_affine_as_hex(vk.alpha_g1) << "]," - << "\n" - << "\t\"beta\"" - << " :[" << point_g2_affine_as_hex(vk.beta_g2) << "]," - << "\n" - << "\t\"delta\"" - << " :[" << point_g2_affine_as_hex(vk.delta_g2) << "]," - << "\n"; - ss << "\t\"ABC\"" - << " :[[" << point_g1_affine_as_hex(vk.ABC_g1.first) << "]"; - for (size_t i = 1; i < abc_length; ++i) { - auto vk_abc_i = - point_g1_affine_as_hex(vk.ABC_g1.rest.values[i - 1]); - ss << ",[" << vk_abc_i << "]"; - } - ss << "]" - << "\n"; - ss << "}"; - - ss.rdbuf()->pubseekpos(0, std::ios_base::out); - fh << ss.rdbuf(); - fh.flush(); - fh.close(); -}; - -template -void proof_to_json( - libsnark::r1cs_gg_ppzksnark_proof proof, boost::filesystem::path path) -{ - if (path.empty()) { - // Used for a debugging purpose - boost::filesystem::path tmp_path = get_path_to_debug_directory(); - boost::filesystem::path proof_json_file("proof.json"); - path = tmp_path / proof_json_file; - } - // Convert the boost path into char* - const char *str_path = path.string().c_str(); - - std::stringstream ss; - std::ofstream fh; - fh.open(str_path, std::ios::binary); - - ss << "{" - << "\n" - << "\t\"a\" :[" << point_g1_affine_as_hex(proof.g_A) << "]," - << "\n" - << "\t\"b\" :[" << point_g2_affine_as_hex(proof.g_B) << "]," - << "\n" - << "\t\"c\" :[" << point_g1_affine_as_hex(proof.g_C) << "]," - << "\n" - << "}"; - - ss.rdbuf()->pubseekpos(0, std::ios_base::out); - fh << ss.rdbuf(); - fh.flush(); - fh.close(); -}; - -template -void proof_and_inputs_to_json( - libsnark::r1cs_gg_ppzksnark_proof proof, - libsnark::r1cs_ppzksnark_primary_input input, - boost::filesystem::path path) -{ - if (path.empty()) { - // Used for a debugging purpose - boost::filesystem::path tmp_path = get_path_to_debug_directory(); - boost::filesystem::path proof_and_inputs_json_file( - "proof_and_inputs.json"); - path = tmp_path / proof_and_inputs_json_file; - } - // Convert the boost path into char* - const char *str_path = path.string().c_str(); - - std::stringstream ss; - std::ofstream fh; - fh.open(str_path, std::ios::binary); - - ss << "{" - << "\n" - << "\t\"a\" :[" << point_g1_affine_as_hex(proof.g_A) << "]," - << "\n" - << "\t\"b\" :[" << point_g2_affine_as_hex(proof.g_B) << "]," - << "\n" - << "\t\"c\" :[" << point_g1_affine_as_hex(proof.g_C) << "]," - << "\n" - << "\t\"inputs\" :["; - for (size_t i = 0; i < input.size(); ++i) { - ss << "\"0x" - << hex_from_libsnark_bigint>(input[i].as_bigint()) - << "\""; - if (i < input.size() - 1) { - ss << ", "; - } - } - ss << "]" - << "\n"; - ss << "}"; - - ss.rdbuf()->pubseekpos(0, std::ios_base::out); - fh << ss.rdbuf(); - fh.flush(); - fh.close(); -}; - -} // namespace libzeth - -#endif // __ZETH_HELPERS_TCC__ diff --git a/libzeth/snarks/groth16/groth16_api_handler.hpp b/libzeth/snarks/groth16/groth16_api_handler.hpp new file mode 100644 index 000000000..95b91cd5f --- /dev/null +++ b/libzeth/snarks/groth16/groth16_api_handler.hpp @@ -0,0 +1,49 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_GROTH16_GROTH16_API_HANDLER_HPP__ +#define __ZETH_SNARKS_GROTH16_GROTH16_API_HANDLER_HPP__ + +#include "libzeth/core/extended_proof.hpp" +#include "libzeth/snarks/groth16/groth16_snark.hpp" + +#include + +namespace libzeth +{ + +/// Implementation of API-related functions for the Groth16 snark. +template class groth16_api_handler +{ +public: + using snarkT = groth16_snark; + + static void format_extended_proof( + const extended_proof &ext_proof, + zeth_proto::ExtendedProof *message); + + static void format_verification_key( + const typename snarkT::VerifKeyT &vk, + zeth_proto::VerificationKey *message); + + static libzeth::extended_proof parse_extended_proof( + const zeth_proto::ExtendedProof &ext_proof); + + static typename snarkT::VerifKeyT parse_verification_key( + const zeth_proto::VerificationKey &verification_key); + + static void prepare_proof_response( + const extended_proof &ext_proof, + zeth_proto::ExtendedProof *message); + + static void prepare_verification_key_response( + const typename snarkT::VerifKeyT &vk, + zeth_proto::VerificationKey *message); +}; + +} // namespace libzeth + +#include "libzeth/snarks/groth16/groth16_api_handler.tcc" + +#endif // __ZETH_SNARKS_GROTH16_GROTH16_API_HANDLER_HPP__ diff --git a/libzeth/snarks/groth16/groth16_api_handler.tcc b/libzeth/snarks/groth16/groth16_api_handler.tcc new file mode 100644 index 000000000..f41065a59 --- /dev/null +++ b/libzeth/snarks/groth16/groth16_api_handler.tcc @@ -0,0 +1,216 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_GROTH16_GROTH16_API_HANDLER_TCC__ +#define __ZETH_SNARKS_GROTH16_GROTH16_API_HANDLER_TCC__ + +#include "libzeth/core/field_element_utils.hpp" +#include "libzeth/serialization/api/api_io.hpp" +#include "libzeth/snarks/groth16/groth16_api_handler.hpp" + +namespace libzeth +{ + +template +void groth16_api_handler::format_extended_proof( + const extended_proof::snarkT> &ext_proof, + zeth_proto::ExtendedProof *message) +{ + libsnark::r1cs_gg_ppzksnark_proof proof_obj = ext_proof.get_proof(); + + zeth_proto::HexPointBaseGroup1Affine *a = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup2Affine *b = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup1Affine *c = + new zeth_proto::HexPointBaseGroup1Affine(); + + a->CopyFrom(format_hexPointBaseGroup1Affine(proof_obj.g_A)); + b->CopyFrom(format_hexPointBaseGroup2Affine(proof_obj.g_B)); // in G2 + c->CopyFrom(format_hexPointBaseGroup1Affine(proof_obj.g_C)); + + libsnark::r1cs_gg_ppzksnark_primary_input public_inputs = + ext_proof.get_primary_inputs(); + + std::string inputs_json_str = + format_primary_inputs(std::vector>(public_inputs)); + + // Note on memory safety: set_allocated deleted the allocated objects. See: + // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object + zeth_proto::ExtendedProofGROTH16 *grpc_extended_groth16_proof_obj = + message->mutable_groth16_extended_proof(); + + grpc_extended_groth16_proof_obj->set_allocated_a(a); + grpc_extended_groth16_proof_obj->set_allocated_b(b); + grpc_extended_groth16_proof_obj->set_allocated_c(c); + grpc_extended_groth16_proof_obj->set_inputs(inputs_json_str); +} + +template +void groth16_api_handler::format_verification_key( + const typename groth16_api_handler::snarkT::VerifKeyT &vk, + zeth_proto::VerificationKey *message) +{ + zeth_proto::HexPointBaseGroup1Affine *a = + new zeth_proto::HexPointBaseGroup1Affine(); // in G1 + zeth_proto::HexPointBaseGroup2Affine *b = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup2Affine *d = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + + a->CopyFrom(format_hexPointBaseGroup1Affine(vk.alpha_g1)); // in G1 + b->CopyFrom(format_hexPointBaseGroup2Affine(vk.beta_g2)); // in G2 + d->CopyFrom(format_hexPointBaseGroup2Affine(vk.delta_g2)); // in G2 + + std::stringstream ss; + unsigned abc_length = vk.ABC_g1.rest.indices.size() + 1; + ss << "[[" << point_g1_affine_to_hexadecimal_str(vk.ABC_g1.first) + << "]"; + for (size_t i = 1; i < abc_length; ++i) { + auto vk_abc_i = point_g1_affine_to_hexadecimal_str( + vk.ABC_g1.rest.values[i - 1]); + ss << ",[" << vk_abc_i << "]"; + } + ss << "]"; + std::string abc_json_str = ss.str(); + + // Note on memory safety: set_allocated deleted the allocated objects + // See: + // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object + zeth_proto::VerificationKeyGROTH16 *grpc_verification_key_groth16 = + message->mutable_groth16_verification_key(); + + grpc_verification_key_groth16->set_allocated_alpha_g1(a); + grpc_verification_key_groth16->set_allocated_beta_g2(b); + grpc_verification_key_groth16->set_allocated_delta_g2(d); + grpc_verification_key_groth16->set_abc_g1(abc_json_str); +} + +template +libzeth::extended_proof> groth16_api_handler< + ppT>::parse_extended_proof(const zeth_proto::ExtendedProof &ext_proof) +{ + const zeth_proto::ExtendedProofGROTH16 &e_proof = + ext_proof.groth16_extended_proof(); + // G1 + libff::G1 a = parse_hexPointBaseGroup1Affine(e_proof.a()); + // G2 + libff::G2 b = parse_hexPointBaseGroup2Affine(e_proof.b()); + // G1 + libff::G1 c = parse_hexPointBaseGroup1Affine(e_proof.c()); + + std::vector> inputs = + libsnark::r1cs_primary_input>( + parse_str_primary_inputs(e_proof.inputs())); + + libsnark::r1cs_gg_ppzksnark_proof proof( + std::move(a), std::move(b), std::move(c)); + libzeth::extended_proof> res(proof, inputs); + + return res; +} + +template +typename groth16_snark::VerifKeyT groth16_api_handler:: + parse_verification_key(const zeth_proto::VerificationKey &verification_key) +{ + const zeth_proto::VerificationKeyGROTH16 &verif_key = + verification_key.groth16_verification_key(); + // G1 + libff::G1 alpha_g1 = + parse_hexPointBaseGroup1Affine(verif_key.alpha_g1()); + // G2 + libff::G2 beta_g2 = + parse_hexPointBaseGroup2Affine(verif_key.beta_g2()); + // G2 + libff::G2 delta_g2 = + parse_hexPointBaseGroup2Affine(verif_key.delta_g2()); + + libsnark::accumulation_vector> abc_g1 = + parse_str_accumulation_vector(verif_key.abc_g1()); + + libsnark::r1cs_gg_ppzksnark_verification_key vk( + alpha_g1, beta_g2, delta_g2, abc_g1); + + return vk; +} + +template +void groth16_api_handler::prepare_proof_response( + const extended_proof &ext_proof, + zeth_proto::ExtendedProof *message) +{ + libsnark::r1cs_gg_ppzksnark_proof proof_obj = ext_proof.get_proof(); + + zeth_proto::HexPointBaseGroup1Affine *a = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup2Affine *b = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup1Affine *c = + new zeth_proto::HexPointBaseGroup1Affine(); + + a->CopyFrom(format_hexPointBaseGroup1Affine(proof_obj.g_A)); + b->CopyFrom(format_hexPointBaseGroup2Affine(proof_obj.g_B)); // in G2 + c->CopyFrom(format_hexPointBaseGroup1Affine(proof_obj.g_C)); + + libsnark::r1cs_gg_ppzksnark_primary_input public_inputs = + ext_proof.get_primary_input(); + + std::string inputs_json_str = + format_primary_inputs(std::vector>(public_inputs)); + + // Note on memory safety: set_allocated deleted the allocated objects + // See: + // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object + zeth_proto::ExtendedProofGROTH16 *grpc_extended_groth16_proof_obj = + message->mutable_groth16_extended_proof(); + + grpc_extended_groth16_proof_obj->set_allocated_a(a); + grpc_extended_groth16_proof_obj->set_allocated_b(b); + grpc_extended_groth16_proof_obj->set_allocated_c(c); + grpc_extended_groth16_proof_obj->set_inputs(inputs_json_str); +} + +template +void groth16_api_handler::prepare_verification_key_response( + const typename snarkT::VerifKeyT &vk, zeth_proto::VerificationKey *message) +{ + zeth_proto::HexPointBaseGroup1Affine *a = + new zeth_proto::HexPointBaseGroup1Affine(); // in G1 + zeth_proto::HexPointBaseGroup2Affine *b = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup2Affine *d = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + + a->CopyFrom(format_hexPointBaseGroup1Affine(vk.alpha_g1)); // in G1 + b->CopyFrom(format_hexPointBaseGroup2Affine(vk.beta_g2)); // in G2 + d->CopyFrom(format_hexPointBaseGroup2Affine(vk.delta_g2)); // in G2 + + std::stringstream ss; + unsigned abc_length = vk.ABC_g1.rest.indices.size() + 1; + ss << "[[" << point_g1_affine_to_hexadecimal_str(vk.ABC_g1.first) + << "]"; + for (size_t i = 1; i < abc_length; ++i) { + auto vk_abc_i = point_g1_affine_to_hexadecimal_str( + vk.ABC_g1.rest.values[i - 1]); + ss << ",[" << vk_abc_i << "]"; + } + ss << "]"; + std::string abc_json_str = ss.str(); + + // Note on memory safety: set_allocated deleted the allocated objects + // See: + // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object + zeth_proto::VerificationKeyGROTH16 *grpc_verification_key_groth16 = + message->mutable_groth16_verification_key(); + + grpc_verification_key_groth16->set_allocated_alpha_g1(a); + grpc_verification_key_groth16->set_allocated_beta_g2(b); + grpc_verification_key_groth16->set_allocated_delta_g2(d); + grpc_verification_key_groth16->set_abc_g1(abc_json_str); +} + +} // namespace libzeth + +#endif // __ZETH_SNARKS_GROTH16_GROTH16_API_HANDLER_TCC__ diff --git a/libzeth/snarks/groth16/groth16_snark.hpp b/libzeth/snarks/groth16/groth16_snark.hpp new file mode 100644 index 000000000..3870bec85 --- /dev/null +++ b/libzeth/snarks/groth16/groth16_snark.hpp @@ -0,0 +1,76 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_GROTH16_GROTH16_SNARK_HPP__ +#define __ZETH_SNARKS_GROTH16_GROTH16_SNARK_HPP__ + +#include +#include +#include + +namespace libzeth +{ + +/// Core types and operations for the GROTH16 snark +template class groth16_snark +{ +public: + typedef libsnark::r1cs_gg_ppzksnark_proving_key ProvingKeyT; + typedef libsnark::r1cs_gg_ppzksnark_verification_key VerifKeyT; + typedef libsnark::r1cs_gg_ppzksnark_keypair KeypairT; + typedef libsnark::r1cs_gg_ppzksnark_proof ProofT; + + // Run the trusted setup and return the keypair for the circuit + static KeypairT generate_setup( + const libsnark::protoboard> &pb); + + // Generate the proof + static ProofT generate_proof( + const libsnark::protoboard> &pb, + const ProvingKeyT &proving_key); + + // Verification of a proof + static bool verify( + const libsnark::r1cs_primary_input> &primary_inputs, + const ProofT &proof, + const VerifKeyT &verification_key); + + // TODO: These should be refactored to be generic calls in terms of simple + // snark-specific methods. + + static void export_verification_key(const KeypairT &keypair); + + static void display_proof(const ProofT &proof); + + static void verification_key_to_json( + const VerifKeyT &vk, boost::filesystem::path path = ""); + + static void proof_and_inputs_to_json( + const ProofT &proof, + const libsnark::r1cs_primary_input> &input, + boost::filesystem::path path = ""); + + static void proof_to_json( + const ProofT &proof, boost::filesystem::path path); + + /// Write a keypair to a stream. + static void write_keypair(std::ostream &out, const KeypairT &keypair); + + /// Read a keypair from a stream. + static KeypairT read_keypair(std::istream &in); +}; + +/// Check well-formedness of a proving key +template +static bool is_well_formed(const typename groth16_snark::ProvingKeyT &pk); + +/// Check well-formedness of a verification key +template +static bool is_well_formed(const typename groth16_snark::VerifKeyT &vk); + +} // namespace libzeth + +#include "libzeth/snarks/groth16/groth16_snark.tcc" + +#endif // __ZETH_SNARKS_GROTH16_GROTH16_SNARK_HPP__ diff --git a/libzeth/snarks/groth16/groth16_snark.tcc b/libzeth/snarks/groth16/groth16_snark.tcc new file mode 100644 index 000000000..441c5b845 --- /dev/null +++ b/libzeth/snarks/groth16/groth16_snark.tcc @@ -0,0 +1,311 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_GROTH16_GROTH16_SNARK_TCC__ +#define __ZETH_SNARKS_GROTH16_GROTH16_SNARK_TCC__ + +#include "libzeth/core/group_element_utils.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/serialization/filesystem_util.hpp" // TODO: remove this +#include "libzeth/snarks/groth16/groth16_snark.hpp" + +namespace libzeth +{ + +template +typename groth16_snark::KeypairT groth16_snark::generate_setup( + const libsnark::protoboard> &pb) +{ + // Generate verification and proving key from the R1CS + return libsnark::r1cs_gg_ppzksnark_generator( + pb.get_constraint_system(), true); +} + +template +typename groth16_snark::ProofT groth16_snark::generate_proof( + const libsnark::protoboard> &pb, + const typename groth16_snark::ProvingKeyT &proving_key) +{ + libsnark::r1cs_primary_input> primary_input = + pb.primary_input(); + libsnark::r1cs_auxiliary_input> auxiliary_input = + pb.auxiliary_input(); + + // Generate proof from public input, auxiliary input and proving key. + // For now, force a pow2 domain, in case the key came from the MPC. + libsnark::r1cs_gg_ppzksnark_proof proof = + libsnark::r1cs_gg_ppzksnark_prover( + proving_key, primary_input, auxiliary_input, true); + + return proof; +} + +template +bool groth16_snark::verify( + const libsnark::r1cs_primary_input> &primary_inputs, + const groth16_snark::ProofT &proof, + const groth16_snark::VerifKeyT &verification_key) +{ + return libsnark::r1cs_gg_ppzksnark_verifier_strong_IC( + verification_key, primary_inputs, proof); +} + +template +void groth16_snark::export_verification_key( + const groth16_snark::KeypairT &keypair) +{ + unsigned abc_length = keypair.vk.ABC_g1.rest.indices.size() + 1; + + std::cout << "\tVerification key in Solidity compliant format:{" + << "\n" + << "\t\tvk.alpha = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(keypair.vk.alpha_g1) + << ");" + << "\n" + << "\t\tvk.beta = Pairing.G2Point(" + << point_g2_affine_to_hexadecimal_str(keypair.vk.beta_g2) + << ");" + << "\n" + << "\t\tvk.delta = Pairing.G2Point(" + << point_g2_affine_to_hexadecimal_str(keypair.vk.delta_g2) + << ");" + << "\n" + << "\t\tvk.ABC = new Pairing.G1Point[](" << abc_length << ");" + << "\n" + << "\t\tvk.ABC[0] = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str( + keypair.vk.ABC_g1.first) + << ");" + << "\n"; + for (size_t i = 1; i < abc_length; ++i) { + auto vk_abc_i = point_g1_affine_to_hexadecimal_str( + keypair.vk.ABC_g1.rest.values[i - 1]); + std::cout << "\t\tvk.ABC[" << i << "] = Pairing.G1Point(" << vk_abc_i + << ");" + << "\n"; + } + // We flush std::cout only once at the end of the function + std::cout << "\t\t}" << std::endl; +} + +template +void groth16_snark::display_proof( + const typename groth16_snark::ProofT &proof) +{ + std::cout << "Proof:" + << "\n" + << "proof.A = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(proof.g_A) << ");" + << "\n" + << "proof.B = Pairing.G2Point(" + << point_g2_affine_to_hexadecimal_str(proof.g_B) << ");" + << "\n" + << "proof.C = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(proof.g_C) + // We flush std::cout only once at the end of the function + << ");" << std::endl; +} + +template +void groth16_snark::verification_key_to_json( + const typename groth16_snark::VerifKeyT &vk, + boost::filesystem::path path) +{ + if (path.empty()) { + boost::filesystem::path tmp_path = get_path_to_setup_directory(); + boost::filesystem::path vk_json_file("vk.json"); + path = tmp_path / vk_json_file; + } + // Convert boost path to char* + const char *str_path = path.string().c_str(); + + std::stringstream ss; + std::ofstream fh; + fh.open(str_path, std::ios::binary); + unsigned abc_length = vk.ABC_g1.rest.indices.size() + 1; + + ss << "{" + << "\n" + << "\t\"alpha\"" + << " :[" << point_g1_affine_to_hexadecimal_str(vk.alpha_g1) << "]," + << "\n" + << "\t\"beta\"" + << " :[" << point_g2_affine_to_hexadecimal_str(vk.beta_g2) << "]," + << "\n" + << "\t\"delta\"" + << " :[" << point_g2_affine_to_hexadecimal_str(vk.delta_g2) << "]," + << "\n"; + ss << "\t\"ABC\"" + << " :[[" << point_g1_affine_to_hexadecimal_str(vk.ABC_g1.first) + << "]"; + for (size_t i = 1; i < abc_length; ++i) { + auto vk_abc_i = point_g1_affine_to_hexadecimal_str( + vk.ABC_g1.rest.values[i - 1]); + ss << ",[" << vk_abc_i << "]"; + } + ss << "]" + << "\n"; + ss << "}"; + + ss.rdbuf()->pubseekpos(0, std::ios_base::out); + fh << ss.rdbuf(); + fh.flush(); + fh.close(); +} + +template +void groth16_snark::proof_and_inputs_to_json( + const typename groth16_snark::ProofT &proof, + const libsnark::r1cs_primary_input> &input, + boost::filesystem::path path) +{ + if (path.empty()) { + // Used for debugging + boost::filesystem::path tmp_path = get_path_to_debug_directory(); + boost::filesystem::path proof_and_inputs_json_file( + "proof_and_inputs.json"); + path = tmp_path / proof_and_inputs_json_file; + } + + // Convert the boost path into char* + const char *str_path = path.string().c_str(); + + std::stringstream ss; + std::ofstream fh; + fh.open(str_path, std::ios::binary); + + ss << "{" + << "\n" + << "\t\"a\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_A) + << "]," + << "\n" + << "\t\"b\" :[" << point_g2_affine_to_hexadecimal_str(proof.g_B) + << "]," + << "\n" + << "\t\"c\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_C) + << "]," + << "\n" + << "\t\"inputs\" :["; + for (size_t i = 0; i < input.size(); ++i) { + ss << "\"0x" + << libsnark_bigint_to_hexadecimal_str>( + input[i].as_bigint()) + << "\""; + if (i < input.size() - 1) { + ss << ", "; + } + } + ss << "]" + << "\n"; + ss << "}"; + + ss.rdbuf()->pubseekpos(0, std::ios_base::out); + fh << ss.rdbuf(); + fh.flush(); + fh.close(); +} + +template +void groth16_snark::proof_to_json( + const typename groth16_snark::ProofT &proof, + boost::filesystem::path path) +{ + if (path.empty()) { + // Used for a debugging purpose + boost::filesystem::path tmp_path = get_path_to_debug_directory(); + boost::filesystem::path proof_json_file("proof.json"); + path = tmp_path / proof_json_file; + } + // Convert the boost path into char* + const char *str_path = path.string().c_str(); + + std::stringstream ss; + std::ofstream fh; + fh.open(str_path, std::ios::binary); + + ss << "{" + << "\n" + << "\t\"a\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_A) + << "]," + << "\n" + << "\t\"b\" :[" << point_g2_affine_to_hexadecimal_str(proof.g_B) + << "]," + << "\n" + << "\t\"c\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_C) + << "]," + << "\n" + << "}"; + + ss.rdbuf()->pubseekpos(0, std::ios_base::out); + fh << ss.rdbuf(); + fh.flush(); + fh.close(); +} + +template +void groth16_snark::write_keypair( + std::ostream &out, const typename groth16_snark::KeypairT &keypair) +{ + if (!is_well_formed(keypair.pk)) { + throw std::invalid_argument("proving key (write) not well-formed"); + } + if (!is_well_formed(keypair.vk)) { + throw std::invalid_argument("verification key (write) not well-formed"); + } + out << keypair.pk; + out << keypair.vk; +} + +template +typename groth16_snark::KeypairT groth16_snark::read_keypair( + std::istream &in) +{ + libsnark::r1cs_gg_ppzksnark_keypair keypair; + in >> keypair.pk; + in >> keypair.vk; + if (!is_well_formed(keypair.pk)) { + throw std::invalid_argument("proving key (read) not well-formed"); + } + if (!is_well_formed(keypair.vk)) { + throw std::invalid_argument("verification key (read) not well-formed"); + } + return keypair; +} + +template +bool is_well_formed(const typename groth16_snark::ProvingKeyT &pk) +{ + if (!pk.alpha_g1.is_well_formed() || !pk.beta_g1.is_well_formed() || + !pk.beta_g2.is_well_formed() || !pk.delta_g1.is_well_formed() || + !pk.delta_g2.is_well_formed() || + !container_is_well_formed(pk.A_query) || + !container_is_well_formed(pk.L_query)) { + return false; + } + + using knowledge_commitment = + libsnark::knowledge_commitment, libff::G1>; + for (const knowledge_commitment &b : pk.B_query.values) { + if (!b.g.is_well_formed() || !b.h.is_well_formed()) { + return false; + } + } + + return true; +} + +template +bool is_well_formed(const typename groth16_snark::VerifKeyT &vk) +{ + if (!vk.alpha_g1.is_well_formed() || !vk.beta_g2.is_well_formed() || + !vk.delta_g2.is_well_formed() || !vk.ABC_g1.first.is_well_formed()) { + return false; + } + + return container_is_well_formed(vk.ABC_g1.rest.values); +} + +} // namespace libzeth + +#endif // __ZETH_SNARKS_GROTH16_GROTH16_SNARK_TCC__ diff --git a/libzeth/snarks/groth16/mpc/multi_exp.hpp b/libzeth/snarks/groth16/mpc/multi_exp.hpp deleted file mode 100644 index ef68acf57..000000000 --- a/libzeth/snarks/groth16/mpc/multi_exp.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_SNARKS_GRPOTH16_MULTI_EXP_HPP__ -#define __ZETH_SNARKS_GRPOTH16_MULTI_EXP_HPP__ - -#include "libzeth/include_libsnark.hpp" - -namespace libzeth -{ - -template -GroupT multi_exp( - typename std::vector>::const_iterator gs_start, - typename std::vector>::const_iterator gs_end, - typename std::vector>::const_iterator fs_start, - typename std::vector>::const_iterator fs_end); - -template -GroupT multi_exp( - const std::vector &gs, const libff::Fr_vector &fs); - -} // namespace libzeth -#include "libzeth/snarks/groth16/mpc/multi_exp.tcc" - -#endif // __ZETH_SNARKS_GRPOTH16_MULTI_EXP_HPP__ diff --git a/libzeth/snarks/pghr13/api/response.hpp b/libzeth/snarks/pghr13/api/response.hpp deleted file mode 100644 index 7b12452a1..000000000 --- a/libzeth/snarks/pghr13/api/response.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_RESPONSE_HPP__ -#define __ZETH_RESPONSE_HPP__ - -#include "api/snark_messages.grpc.pb.h" -#include "libzeth/libsnark_helpers/extended_proof.hpp" -#include "libzeth/util_api.hpp" - -namespace libzeth -{ - -template -void prepare_proof_response( - extended_proof &ext_proof, zeth_proto::ExtendedProof *message); -template -void prepare_verification_key_response( - libsnark::r1cs_ppzksnark_verification_key &vk, - zeth_proto::VerificationKey *message); - -} // namespace libzeth -#include "libzeth/snarks/pghr13/api/response.tcc" - -#endif // __ZETH_RESPONSE_HPP__ diff --git a/libzeth/snarks/pghr13/api/response.tcc b/libzeth/snarks/pghr13/api/response.tcc deleted file mode 100644 index e3055f9a6..000000000 --- a/libzeth/snarks/pghr13/api/response.tcc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_RESPONSE_TCC__ -#define __ZETH_RESPONSE_TCC__ - -namespace libzeth -{ - -template -void prepare_proof_response( - extended_proof &ext_proof, zeth_proto::ExtendedProof *message) -{ - libsnark::r1cs_ppzksnark_proof proofObj = ext_proof.get_proof(); - - zeth_proto::HexPointBaseGroup1Affine *a = - new zeth_proto::HexPointBaseGroup1Affine(); - zeth_proto::HexPointBaseGroup1Affine *a_p = - new zeth_proto::HexPointBaseGroup1Affine(); - zeth_proto::HexPointBaseGroup2Affine *b = - new zeth_proto::HexPointBaseGroup2Affine(); // in G2 - zeth_proto::HexPointBaseGroup1Affine *b_p = - new zeth_proto::HexPointBaseGroup1Affine(); - zeth_proto::HexPointBaseGroup1Affine *c = - new zeth_proto::HexPointBaseGroup1Affine(); - zeth_proto::HexPointBaseGroup1Affine *c_p = - new zeth_proto::HexPointBaseGroup1Affine(); - zeth_proto::HexPointBaseGroup1Affine *h = - new zeth_proto::HexPointBaseGroup1Affine(); - zeth_proto::HexPointBaseGroup1Affine *k = - new zeth_proto::HexPointBaseGroup1Affine(); - - a->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_A.g)); - a_p->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_A.h)); - b->CopyFrom(format_hexPointBaseGroup2Affine(proofObj.g_B.g)); // in G2 - b_p->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_B.h)); - c->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_C.g)); - c_p->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_C.h)); - h->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_H)); - k->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_K)); - - libsnark::r1cs_ppzksnark_primary_input pub_inputs = - ext_proof.get_primary_input(); - - std::string inputs_json_str = - format_primary_inputs(std::vector>(public_inputs)); - - // Note on memory safety: set_allocated deleted the allocated objects - // See: - // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object - zeth_proto::ExtendedProofPGHR13 *grpc_extended_pghr13_proof_obj = - message->mutable_pghr13_extended_proof(); - - grpc_extended_pghr13_proof_obj->set_allocated_a(a); - grpc_extended_pghr13_proof_obj->set_allocated_a_p(a_p); - grpc_extended_pghr13_proof_obj->set_allocated_b(b); - grpc_extended_pghr13_proof_obj->set_allocated_b_p(b_p); - grpc_extended_pghr13_proof_obj->set_allocated_c(c); - grpc_extended_pghr13_proof_obj->set_allocated_c_p(c_p); - grpc_extended_pghr13_proof_obj->set_allocated_h(h); - grpc_extended_pghr13_proof_obj->set_allocated_k(k); - grpc_extended_pghr13_proof_obj->set_inputs(inputs_json); -} - -template -void prepare_verification_key_response( - libsnark::r1cs_ppzksnark_verification_key &vk, - zeth_proto::VerificationKey *message) -{ - zeth_proto::HexPointBaseGroup2Affine *a = - new zeth_proto::HexPointBaseGroup2Affine(); // in G2 - zeth_proto::HexPointBaseGroup1Affine *b = - new zeth_proto::HexPointBaseGroup1Affine(); // in G1 - zeth_proto::HexPointBaseGroup2Affine *c = - new zeth_proto::HexPointBaseGroup2Affine(); // in G2 - zeth_proto::HexPointBaseGroup2Affine *g = - new zeth_proto::HexPointBaseGroup2Affine(); // in G2 - zeth_proto::HexPointBaseGroup1Affine *gb1 = - new zeth_proto::HexPointBaseGroup1Affine(); // in G1 - zeth_proto::HexPointBaseGroup2Affine *gb2 = - new zeth_proto::HexPointBaseGroup2Affine(); // in G2 - zeth_proto::HexPointBaseGroup2Affine *z = - new zeth_proto::HexPointBaseGroup2Affine(); // in G2 - - a->CopyFrom(format_hexPointBaseGroup2Affine(vk.alphaA_g2)); // in G2 - b->CopyFrom(format_hexPointBaseGroup1Affine(vk.alphaB_g1)); // in G1 - c->CopyFrom(format_hexPointBaseGroup2Affine(vk.alphaC_g2)); // in G2 - g->CopyFrom(format_hexPointBaseGroup2Affine(vk.gamma_g2)); // in G2 - gb1->CopyFrom( - format_hexPointBaseGroup1Affine(vk.gamma_beta_g1)); // in G1 - gb2->CopyFrom( - format_hexPointBaseGroup2Affine(vk.gamma_beta_g2)); // in G2 - z->CopyFrom(format_hexPointBaseGroup2Affine(vk.rC_Z_g2)); // in G2 - - std::stringstream ss; - unsigned ic_length = vk.encoded_IC_query.rest.indices.size() + 1; - ss << "[[" << point_g1_affine_as_hex(vk.encoded_IC_query.first) << "]"; - for (size_t i = 1; i < ic_length; ++i) { - auto vk_ic_i = - point_g1_affine_as_hex(vk.encoded_IC_query.rest.values[i - 1]); - ss << ",[" << vk_ic_i << "]"; - } - ss << "]"; - std::string ic_json = ss.str(); - - // Note on memory safety: set_allocated deleted the allocated objects - // See: - // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object - zeth_proto::VerificationKeyPGHR13 *grpc_verification_key_pghr13 = - message->mutable_pghr13_verification_key(); - - grpc_verification_key_pghr13->set_allocated_a(a); - grpc_verification_key_pghr13->set_allocated_b(b); - grpc_verification_key_pghr13->set_allocated_c(c); - grpc_verification_key_pghr13->set_allocated_gamma(g); - grpc_verification_key_pghr13->set_allocated_gamma_beta_g1(gb1); - grpc_verification_key_pghr13->set_allocated_gamma_beta_g2(gb2); - grpc_verification_key_pghr13->set_allocated_z(z); - grpc_verification_key_pghr13->set_ic(ic_json); -}; - -} // namespace libzeth - -#endif // __ZETH_RESPONSE_TCC__ diff --git a/libzeth/snarks/pghr13/core/computation.hpp b/libzeth/snarks/pghr13/core/computation.hpp deleted file mode 100644 index 21729737e..000000000 --- a/libzeth/snarks/pghr13/core/computation.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_COMPUTATION_HPP__ -#define __ZETH_COMPUTATION_HPP__ - -#include "libzeth/libsnark_helpers/extended_proof.hpp" - -#include -#include - -namespace libzeth -{ - -template -libsnark::r1cs_ppzksnark_proof gen_proof( - const libsnark::protoboard> &pb, - const libsnark::r1cs_ppzksnark_proving_key &proving_key); -template -libsnark::r1cs_ppzksnark_keypair gen_trusted_setup( - const libsnark::protoboard> &pb); -template -bool verify( - const libzeth::extended_proof &ext_proof, - const libsnark::r1cs_ppzksnark_verification_key &verification_key); - -} // namespace libzeth -#include "libzeth/snarks/pghr13/core/computation.tcc" - -#endif // __ZETH_COMPUTATION_HPP__ diff --git a/libzeth/snarks/pghr13/core/computation.tcc b/libzeth/snarks/pghr13/core/computation.tcc deleted file mode 100644 index 7b2d09cd8..000000000 --- a/libzeth/snarks/pghr13/core/computation.tcc +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_COMPUTATION_TCC__ -#define __ZETH_COMPUTATION_TCC__ - -namespace libzeth -{ - -// Generate the proof and returns a struct {proof, primary_input} -template -libsnark::r1cs_ppzksnark_proof gen_proof( - const libsnark::protoboard> &pb, - const libsnark::r1cs_ppzksnark_proving_key &proving_key) -{ - // See: - // https://github.com/scipr-lab/libsnark/blob/92a80f74727091fdc40e6021dc42e9f6b67d5176/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp#L81 - // For the definition of r1cs_primary_input and r1cs_auxiliary_input - libsnark::r1cs_primary_input> primary_input = - pb.primary_input(); - libsnark::r1cs_auxiliary_input> auxiliary_input = - pb.auxiliary_input(); - - // Generate proof from public input, auxiliary input (private/secret data), - // and proving key - proofT proof = libsnark::r1cs_ppzksnark_prover( - proving_key, primary_input, auxiliary_input); - - return proof; -}; - -// Run the trusted setup and returns a struct {proving_key, verifying_key} -template -libsnark::r1cs_ppzksnark_keypair gen_trusted_setup( - const libsnark::protoboard> &pb) -{ - // Generate verification and proving key (Trusted setup) from the R1CS - // (defined in the ZoKrates/wraplibsnark.cpp file) This function, basically - // reduces the R1CS into a QAP, and then encodes the QAP, along with a - // secret s and its set of powers, plus the alpha, beta, gamma, and the rest - // of the entries, in order to form the CRS (crs_f, shortcrs_f, as denoted - // in [GGPR12]) - return libsnark::r1cs_ppzksnark_generator(pb.get_constraint_system()); -}; - -// Verification of a proof -template -bool verify( - const libzeth::extended_proof &ext_proof, - const libsnark::r1cs_ppzksnark_verification_key &verification_key) -{ - return libsnark::r1cs_ppzksnark_verifier_strong_IC( - verification_key, ext_proof.get_primary_input(), ext_proof.get_proof()); -}; - -} // namespace libzeth - -#endif // __ZETH_COMPUTATION_TCC__ diff --git a/libzeth/snarks/pghr13/core/helpers.hpp b/libzeth/snarks/pghr13/core/helpers.hpp deleted file mode 100644 index 0d2b245fd..000000000 --- a/libzeth/snarks/pghr13/core/helpers.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_HELPERS_HPP__ -#define __ZETH_HELPERS_HPP__ - -#include "libzeth/libsnark_helpers/debug_helpers.hpp" - -#include -#include -#include - -namespace libzeth -{ - -template -void export_verification_key(libsnark::r1cs_ppzksnark_keypair keypair); -template -void display_proof(libsnark::r1cs_ppzksnark_proof proof); -template -void verification_key_to_json( - libsnark::r1cs_ppzksnark_keypair keypair, - boost::filesystem::path path = ""); -template -void proof_and_inputs_to_json( - libsnark::r1cs_ppzksnark_proof proof, - libsnark::r1cs_ppzksnark_primary_input input, - boost::filesystem::path path = ""); -template -void proof_to_json( - libsnark::r1cs_ppzksnark_proof proof, boost::filesystem::path path); - -} // namespace libzeth -#include "libzeth/snarks/pghr13/core/helpers.tcc" - -#endif // __ZETH_HELPERS_HPP__ diff --git a/libzeth/snarks/pghr13/core/helpers.tcc b/libzeth/snarks/pghr13/core/helpers.tcc deleted file mode 100644 index c5b421b6a..000000000 --- a/libzeth/snarks/pghr13/core/helpers.tcc +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_HELPER_TCC__ -#define __ZETH_HELPER_TCC__ - -namespace libzeth -{ -template -void export_verification_key(libsnark::r1cs_ppzksnark_keypair keypair) -{ - unsigned ic_length = keypair.vk.encoded_IC_query.rest.indices.size() + 1; - - std::cout << "\tVerification key in Solidity compliant format:{" - << "\n" - << "\t\tvk.A = Pairing.G2Point(" - << point_g2_affine_as_hex(keypair.vk.alphaA_g2) << ");" - << "\n" - << "\t\tvk.B = Pairing.G1Point(" - << point_g1_affine_as_hex(keypair.vk.alphaB_g1) << ");" - << "\n" - << "\t\tvk.C = Pairing.G2Point(" - << point_g2_affine_as_hex(keypair.vk.alphaC_g2) << ");" - << "\n" - << "\t\tvk.gamma = Pairing.G2Point(" - << point_g2_affine_as_hex(keypair.vk.gamma_g2) << ");" - << "\n" - << "\t\tvk.gammaBeta1 = Pairing.G1Point(" - << point_g1_affine_as_hex(keypair.vk.gamma_beta_g1) << ");" - << "\n" - << "\t\tvk.gammaBeta2 = Pairing.G2Point(" - << point_g2_affine_as_hex(keypair.vk.gamma_beta_g2) << ");" - << "\n" - << "\t\tvk.Z = Pairing.G2Point(" - << point_g2_affine_as_hex(keypair.vk.rC_Z_g2) << ");" - << "\n" - << "\t\tvk.IC = new Pairing.G1Point[](" << ic_length << ");" - << "\t\tvk.IC[0] = Pairing.G1Point(" - << point_g1_affine_as_hex(keypair.vk.encoded_IC_query.first) - << ");" << std::endl; - for (size_t i = 1; i < ic_length; ++i) { - auto vk_ic_i = point_g1_affine_as_hex( - keypair.vk.encoded_IC_query.rest.values[i - 1]); - std::cout << "\t\tvk.IC[" << i << "] = Pairing.G1Point(" << vk_ic_i - << ");" << std::endl; - } - std::cout << "\t\t}" << std::endl; -}; - -template -void display_proof(libsnark::r1cs_ppzksnark_proof proof) -{ - std::cout << "Proof:" - << "\n" - << "proof.A = Pairing.G1Point(" - << point_g1_affine_as_hex(proof.g_A.g) << ");" - << "\n" - << "proof.A_p = Pairing.G1Point(" - << point_g1_affine_as_hex(proof.g_A.h) << ");" - << "\n" - << "proof.B = Pairing.G2Point(" - << point_g2_affine_as_hex(proof.g_B.g) << ");" - << "\n" - << "proof.B_p = Pairing.G1Point(" - << point_g1_affine_as_hex(proof.g_B.h) << ");" - << "\n" - << "proof.C = Pairing.G1Point(" - << point_g1_affine_as_hex(proof.g_C.g) << ");" - << "\n" - << "proof.C_p = Pairing.G1Point(" - << point_g1_affine_as_hex(proof.g_C.h) << ");" - << "\n" - << "proof.H = Pairing.G1Point(" - << point_g1_affine_as_hex(proof.g_H) << ");" - << "\n" - << "proof.K = Pairing.G1Point(" - << point_g1_affine_as_hex(proof.g_K) << ");" << std::endl; -}; - -template -void verification_key_to_json( - libsnark::r1cs_ppzksnark_verification_key vk, - boost::filesystem::path path) -{ - if (path.empty()) { - boost::filesystem::path tmp_path = get_path_to_setup_directory(); - boost::filesystem::path vk_json_file("vk.json"); - path = tmp_path / vk_json_file; - } - // Convert boost path to char* - const char *str_path = path.string().c_str(); - - std::stringstream ss; - std::ofstream fh; - fh.open(str_path, std::ios::binary); - unsigned ic_length = vk.encoded_IC_query.rest.indices.size() + 1; - - ss << "{\n"; - ss << " \"a\" :[" << point_g2_affine_as_hex(vk.alphaA_g2) << "],\n"; - ss << " \"b\" :[" << point_g1_affine_as_hex(vk.alphaB_g1) << "],\n"; - ss << " \"c\" :[" << point_g2_affine_as_hex(vk.alphaC_g2) << "],\n"; - ss << " \"g\" :[" << point_g2_affine_as_hex(vk.gamma_g2) << "],\n"; - ss << " \"gb1\" :[" << point_g1_affine_as_hex(vk.gamma_beta_g1) - << "],\n"; - ss << " \"gb2\" :[" << point_g2_affine_as_hex(vk.gamma_beta_g2) - << "],\n"; - ss << " \"z\" :[" << point_g2_affine_as_hex(vk.rC_Z_g2) << "],\n"; - - ss << "\"IC\" :[[" << point_g1_affine_as_hex(vk.encoded_IC_query.first) - << "]"; - - for (size_t i = 1; i < ic_length; ++i) { - auto vk_ic_i = - point_g1_affine_as_hex(vk.encoded_IC_query.rest.values[i - 1]); - ss << ",[" << vk_ic_i << "]"; - } - - ss << "]"; - ss << "}"; - ss.rdbuf()->pubseekpos(0, std::ios_base::out); - fh << ss.rdbuf(); - fh.flush(); - fh.close(); -}; - -template -void proof_to_json( - libsnark::r1cs_ppzksnark_proof proof, boost::filesystem::path path) -{ - if (path.empty()) { - // Used for debugging purpose - boost::filesystem::path tmp_path = get_path_to_debug_directory(); - boost::filesystem::path proof_json("proof.json"); - path = tmp_path / proof_json; - } - // Convert the boost path into char* - const char *str_path = path.string().c_str(); - - std::stringstream ss; - std::ofstream fh; - fh.open(str_path, std::ios::binary); - - ss << "{\n"; - ss << " \"a\" :[" << point_g1_affine_as_hex(proof.g_A.g) << "],\n"; - ss << " \"a_p\" :[" << point_g1_affine_as_hex(proof.g_A.h) << "],\n"; - ss << " \"b\" :[" << point_g2_affine_as_hex(proof.g_B.g) << "],\n"; - ss << " \"b_p\" :[" << point_g1_affine_as_hex(proof.g_B.h) << "],\n"; - ss << " \"c\" :[" << point_g1_affine_as_hex(proof.g_C.g) << "],\n"; - ss << " \"c_p\" :[" << point_g1_affine_as_hex(proof.g_C.h) << "],\n"; - ss << " \"h\" :[" << point_g1_affine_as_hex(proof.g_H) << "],\n"; - ss << " \"k\" :[" << point_g1_affine_as_hex(proof.g_K) << "]\n"; - ss << "}"; - - ss.rdbuf()->pubseekpos(0, std::ios_base::out); - fh << ss.rdbuf(); - fh.flush(); - fh.close(); -}; - -template -void proof_and_inputs_to_json( - libsnark::r1cs_ppzksnark_proof proof, - libsnark::r1cs_ppzksnark_primary_input input, - boost::filesystem::path path) -{ - if (path.empty()) { - // Used for debugging purpose - boost::filesystem::path tmp_path = get_path_to_debug_directory(); - boost::filesystem::path proof_and_input_json_file( - "proof_and_input.json"); - path = tmp_path / proof_and_input_json_file; - } - // Convert the boost path into char* - const char *str_path = path.string().c_str(); - - std::stringstream ss; - std::ofstream fh; - fh.open(str_path, std::ios::binary); - - ss << "{\n"; - ss << " \"a\" :[" << point_g1_affine_as_hex(proof.g_A.g) << "],\n"; - ss << " \"a_p\" :[" << point_g1_affine_as_hex(proof.g_A.h) << "],\n"; - ss << " \"b\" :[" << point_g2_affine_as_hex(proof.g_B.g) << "],\n"; - ss << " \"b_p\" :[" << point_g1_affine_as_hex(proof.g_B.h) << "],\n"; - ss << " \"c\" :[" << point_g1_affine_as_hex(proof.g_C.g) << "],\n"; - ss << " \"c_p\" :[" << point_g1_affine_as_hex(proof.g_C.h) << "],\n"; - ss << " \"h\" :[" << point_g1_affine_as_hex(proof.g_H) << "],\n"; - ss << " \"k\" :[" << point_g1_affine_as_hex(proof.g_K) << "],\n"; - ss << " \"input\" :" - << "["; // 1 should always be the first variable passed - for (size_t i = 0; i < input.size(); ++i) { - ss << "\"0x" - << hex_from_libsnark_bigint>(input[i].as_bigint()) - << "\""; - if (i < input.size() - 1) { - ss << ", "; - } - } - ss << "]\n"; - ss << "}"; - - ss.rdbuf()->pubseekpos(0, std::ios_base::out); - fh << ss.rdbuf(); - fh.flush(); - fh.close(); -}; -} // namespace libzeth - -#endif // __ZETH_HELPERS_TCC__ diff --git a/libzeth/snarks/pghr13/pghr13_api_handler.hpp b/libzeth/snarks/pghr13/pghr13_api_handler.hpp new file mode 100644 index 000000000..2e75d3770 --- /dev/null +++ b/libzeth/snarks/pghr13/pghr13_api_handler.hpp @@ -0,0 +1,48 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_PGHR13_PGHR13_API_HANDLER_HPP__ +#define __ZETH_SNARKS_PGHR13_PGHR13_API_HANDLER_HPP__ + +#include "api/snark_messages.grpc.pb.h" +#include "libzeth/snarks/pghr13/pghr13_snark.hpp" +#include "libzeth/types/extended_proof.hpp" + +namespace libzeth +{ + +/// Implementation of API-related functions for the PGHR13 snark. +template class pghr13_api_handler +{ +public: + using snarkT = pghr13_snark; + + static void format_extended_proof( + const extended_proof &ext_proof, + zeth_proto::ExtendedProof *message); + + static void format_verification_key( + const typename snarkT::VerifKeyT &vk, + zeth_proto::VerificationKey *message); + + static libzeth::extended_proof parse_extended_proof( + const zeth_proto::ExtendedProof &ext_proof); + + static typename snarkT::VerifKeyT parse_verification_key( + const zeth_proto::VerificationKey &verification_key); + + static void prepare_proof_response( + const extended_proof &ext_proof, + zeth_proto::ExtendedProof *message); + + static void prepare_verification_key_response( + const typename snarkT::VerifKeyT &vk, + zeth_proto::VerificationKey *message); +}; + +} // namespace libzeth + +#include "libzeth/snarks/pghr13/pghr13_api_handler.tcc" + +#endif // __ZETH_SNARKS_PGHR13_PGHR13_API_HANDLER_HPP__ diff --git a/libzeth/snarks/pghr13/pghr13_api_handler.tcc b/libzeth/snarks/pghr13/pghr13_api_handler.tcc new file mode 100644 index 000000000..35ff7d59d --- /dev/null +++ b/libzeth/snarks/pghr13/pghr13_api_handler.tcc @@ -0,0 +1,313 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_PGHR13_PGHR13_API_HANDLER_TCC__ +#define __ZETH_SNARKS_PGHR13_PGHR13_API_HANDLER_TCC__ + +#include "libzeth/sciprlab_libs_util.hpp" +#include "libzeth/serialization/api/api_io.hpp" +#include "libzeth/snarks/pghr13/pghr13_api_handler.hpp" + +namespace libzeth +{ + +template +void pghr13_api_handler::format_extended_proof( + const extended_proof &ext_proof, + zeth_proto::ExtendedProof *message) +{ + libsnark::r1cs_ppzksnark_proof proofObj = ext_proof.get_proof(); + + zeth_proto::HexPointBaseGroup1Affine *a = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *a_p = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup2Affine *b = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup1Affine *b_p = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *c = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *c_p = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *h = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *k = + new zeth_proto::HexPointBaseGroup1Affine(); + + a->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_A.g)); + a_p->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_A.h)); + b->CopyFrom(format_hexPointBaseGroup2Affine(proofObj.g_B.g)); // in G2 + b_p->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_B.h)); + c->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_C.g)); + c_p->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_C.h)); + h->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_H)); + k->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_K)); + + libsnark::r1cs_ppzksnark_primary_input pub_inputs = + ext_proof.get_primary_inputs(); + + std::string inputs_json = + format_primary_inputs(std::vector>(pub_inputs)); + + // Note on memory safety: set_allocated deleted the allocated objects + // See: + // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object + zeth_proto::ExtendedProofPGHR13 *grpc_extended_pghr13_proof_obj = + message->mutable_pghr13_extended_proof(); + + grpc_extended_pghr13_proof_obj->set_allocated_a(a); + grpc_extended_pghr13_proof_obj->set_allocated_a_p(a_p); + grpc_extended_pghr13_proof_obj->set_allocated_b(b); + grpc_extended_pghr13_proof_obj->set_allocated_b_p(b_p); + grpc_extended_pghr13_proof_obj->set_allocated_c(c); + grpc_extended_pghr13_proof_obj->set_allocated_c_p(c_p); + grpc_extended_pghr13_proof_obj->set_allocated_h(h); + grpc_extended_pghr13_proof_obj->set_allocated_k(k); + grpc_extended_pghr13_proof_obj->set_inputs(inputs_json); +} + +template +void pghr13_api_handler::format_verification_key( + const typename snarkT::VerifKeyT &vk, zeth_proto::VerificationKey *message) +{ + zeth_proto::HexPointBaseGroup2Affine *a = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup1Affine *b = + new zeth_proto::HexPointBaseGroup1Affine(); // in G1 + zeth_proto::HexPointBaseGroup2Affine *c = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup2Affine *g = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup1Affine *gb1 = + new zeth_proto::HexPointBaseGroup1Affine(); // in G1 + zeth_proto::HexPointBaseGroup2Affine *gb2 = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup2Affine *z = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + + a->CopyFrom(format_hexPointBaseGroup2Affine(vk.alphaA_g2)); // in G2 + b->CopyFrom(format_hexPointBaseGroup1Affine(vk.alphaB_g1)); // in G1 + c->CopyFrom(format_hexPointBaseGroup2Affine(vk.alphaC_g2)); // in G2 + g->CopyFrom(format_hexPointBaseGroup2Affine(vk.gamma_g2)); // in G2 + gb1->CopyFrom( + format_hexPointBaseGroup1Affine(vk.gamma_beta_g1)); // in G1 + gb2->CopyFrom( + format_hexPointBaseGroup2Affine(vk.gamma_beta_g2)); // in G2 + z->CopyFrom(format_hexPointBaseGroup2Affine(vk.rC_Z_g2)); // in G2 + + std::stringstream ss; + unsigned ic_length = vk.encoded_IC_query.rest.indices.size() + 1; + ss << "[[" + << point_g1_affine_to_hexadecimal_str(vk.encoded_IC_query.first) + << "]"; + for (size_t i = 1; i < ic_length; ++i) { + auto vk_ic_i = point_g1_affine_to_hexadecimal_str( + vk.encoded_IC_query.rest.values[i - 1]); + ss << ",[" << vk_ic_i << "]"; + } + ss << "]"; + std::string ic_json = ss.str(); + + // Note on memory safety: set_allocated deleted the allocated objects + // See: + // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object + zeth_proto::VerificationKeyPGHR13 *grpc_verification_key_pghr13 = + message->mutable_pghr13_verification_key(); + + grpc_verification_key_pghr13->set_allocated_a(a); + grpc_verification_key_pghr13->set_allocated_b(b); + grpc_verification_key_pghr13->set_allocated_c(c); + grpc_verification_key_pghr13->set_allocated_gamma(g); + grpc_verification_key_pghr13->set_allocated_gamma_beta_g1(gb1); + grpc_verification_key_pghr13->set_allocated_gamma_beta_g2(gb2); + grpc_verification_key_pghr13->set_allocated_z(z); + grpc_verification_key_pghr13->set_ic(ic_json); +} + +template +libzeth::extended_proof> pghr13_api_handler< + ppT>::parse_extended_proof(const zeth_proto::ExtendedProof &ext_proof) +{ + const zeth_proto::ExtendedProofPGHR13 &e_proof = + ext_proof.pghr13_extended_proof(); + + libff::G1 a = parse_hexPointBaseGroup1Affine(e_proof.a()); + libff::G1 a_p = parse_hexPointBaseGroup1Affine(e_proof.a_p()); + libsnark::knowledge_commitment, libff::G1> g_A(a, a_p); + + libff::G2 b = parse_hexPointBaseGroup2Affine(e_proof.b()); + libff::G1 b_p = parse_hexPointBaseGroup1Affine(e_proof.b_p()); + libsnark::knowledge_commitment, libff::G1> g_B(b, b_p); + + libff::G1 c = parse_hexPointBaseGroup1Affine(e_proof.c()); + libff::G1 c_p = parse_hexPointBaseGroup1Affine(e_proof.c_p()); + libsnark::knowledge_commitment, libff::G1> g_C(c, c_p); + + libff::G1 h = parse_hexPointBaseGroup1Affine(e_proof.h()); + libff::G1 k = parse_hexPointBaseGroup1Affine(e_proof.k()); + + libsnark::r1cs_ppzksnark_proof proof( + std::move(g_A), + std::move(g_B), + std::move(g_C), + std::move(h), + std::move(k)); + libsnark::r1cs_primary_input> inputs = + libsnark::r1cs_primary_input>( + parse_str_primary_inputs(e_proof.inputs())); + libzeth::extended_proof res(proof, inputs); + return res; +} + +template +typename pghr13_snark::VerifKeyT pghr13_api_handler:: + parse_verification_key(const zeth_proto::VerificationKey &verification_key) +{ + const zeth_proto::VerificationKeyPGHR13 &verif_key = + verification_key.pghr13_verification_key(); + // G2 + libff::G2 a = parse_hexPointBaseGroup2Affine(verif_key.a()); + // G1 + libff::G1 b = parse_hexPointBaseGroup1Affine(verif_key.b()); + // G2 + libff::G2 c = parse_hexPointBaseGroup2Affine(verif_key.c()); + // G2 + libff::G1 gamma = + parse_hexPointBaseGroup2Affine(verif_key.gamma()); + // G1 + libff::G1 gamma_beta_g1 = + parse_hexPointBaseGroup1Affine(verif_key.gamma_beta_g1()); + // G2 + libff::G2 gamma_beta_g2 = + parse_hexPointBaseGroup2Affine(verif_key.gamma_beta_g2()); + // G2 + libff::G2 z = parse_hexPointBaseGroup2Affine(verif_key.z()); + + libsnark::accumulation_vector> ic = + parse_str_accumulation_vector(verif_key.ic()); + + libsnark::r1cs_ppzksnark_verification_key vk( + a, b, c, gamma, gamma_beta_g1, gamma_beta_g2, z, ic); + + return vk; +} + +template +void pghr13_api_handler::prepare_proof_response( + const extended_proof &ext_proof, + zeth_proto::ExtendedProof *message) +{ + libsnark::r1cs_ppzksnark_proof proofObj = ext_proof.get_proof(); + + zeth_proto::HexPointBaseGroup1Affine *a = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *a_p = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup2Affine *b = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup1Affine *b_p = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *c = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *c_p = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *h = + new zeth_proto::HexPointBaseGroup1Affine(); + zeth_proto::HexPointBaseGroup1Affine *k = + new zeth_proto::HexPointBaseGroup1Affine(); + + a->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_A.g)); + a_p->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_A.h)); + b->CopyFrom(format_hexPointBaseGroup2Affine(proofObj.g_B.g)); // in G2 + b_p->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_B.h)); + c->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_C.g)); + c_p->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_C.h)); + h->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_H)); + k->CopyFrom(format_hexPointBaseGroup1Affine(proofObj.g_K)); + + libsnark::r1cs_ppzksnark_primary_input pub_inputs = + ext_proof.get_primary_input(); + + std::string inputs_json = + format_primary_inputs(std::vector>(pub_inputs)); + + // Note on memory safety: set_allocated deleted the allocated objects + // See: + // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object + zeth_proto::ExtendedProofPGHR13 *grpc_extended_pghr13_proof_obj = + message->mutable_pghr13_extended_proof(); + + grpc_extended_pghr13_proof_obj->set_allocated_a(a); + grpc_extended_pghr13_proof_obj->set_allocated_a_p(a_p); + grpc_extended_pghr13_proof_obj->set_allocated_b(b); + grpc_extended_pghr13_proof_obj->set_allocated_b_p(b_p); + grpc_extended_pghr13_proof_obj->set_allocated_c(c); + grpc_extended_pghr13_proof_obj->set_allocated_c_p(c_p); + grpc_extended_pghr13_proof_obj->set_allocated_h(h); + grpc_extended_pghr13_proof_obj->set_allocated_k(k); + grpc_extended_pghr13_proof_obj->set_inputs(inputs_json); +} + +template +void pghr13_api_handler::prepare_verification_key_response( + const typename snarkT::VerifKeyT &vk, zeth_proto::VerificationKey *message) +{ + zeth_proto::HexPointBaseGroup2Affine *a = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup1Affine *b = + new zeth_proto::HexPointBaseGroup1Affine(); // in G1 + zeth_proto::HexPointBaseGroup2Affine *c = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup2Affine *g = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup1Affine *gb1 = + new zeth_proto::HexPointBaseGroup1Affine(); // in G1 + zeth_proto::HexPointBaseGroup2Affine *gb2 = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + zeth_proto::HexPointBaseGroup2Affine *z = + new zeth_proto::HexPointBaseGroup2Affine(); // in G2 + + a->CopyFrom(format_hexPointBaseGroup2Affine(vk.alphaA_g2)); // in G2 + b->CopyFrom(format_hexPointBaseGroup1Affine(vk.alphaB_g1)); // in G1 + c->CopyFrom(format_hexPointBaseGroup2Affine(vk.alphaC_g2)); // in G2 + g->CopyFrom(format_hexPointBaseGroup2Affine(vk.gamma_g2)); // in G2 + gb1->CopyFrom( + format_hexPointBaseGroup1Affine(vk.gamma_beta_g1)); // in G1 + gb2->CopyFrom( + format_hexPointBaseGroup2Affine(vk.gamma_beta_g2)); // in G2 + z->CopyFrom(format_hexPointBaseGroup2Affine(vk.rC_Z_g2)); // in G2 + + std::stringstream ss; + unsigned ic_length = vk.encoded_IC_query.rest.indices.size() + 1; + ss << "[[" + << point_g1_affine_to_hexadecimal_str(vk.encoded_IC_query.first) + << "]"; + for (size_t i = 1; i < ic_length; ++i) { + auto vk_ic_i = point_g1_affine_to_hexadecimal_str( + vk.encoded_IC_query.rest.values[i - 1]); + ss << ",[" << vk_ic_i << "]"; + } + ss << "]"; + std::string ic_json = ss.str(); + + // Note on memory safety: set_allocated deleted the allocated objects + // See: + // https://stackoverflow.com/questions/33960999/protobuf-will-set-allocated-delete-the-allocated-object + zeth_proto::VerificationKeyPGHR13 *grpc_verification_key_pghr13 = + message->mutable_pghr13_verification_key(); + + grpc_verification_key_pghr13->set_allocated_a(a); + grpc_verification_key_pghr13->set_allocated_b(b); + grpc_verification_key_pghr13->set_allocated_c(c); + grpc_verification_key_pghr13->set_allocated_gamma(g); + grpc_verification_key_pghr13->set_allocated_gamma_beta_g1(gb1); + grpc_verification_key_pghr13->set_allocated_gamma_beta_g2(gb2); + grpc_verification_key_pghr13->set_allocated_z(z); + grpc_verification_key_pghr13->set_ic(ic_json); +} + +} // namespace libzeth + +#endif // __ZETH_SNARKS_PGHR13_PGHR13_API_HANDLER_TCC__ diff --git a/libzeth/snarks/pghr13/pghr13_snark.hpp b/libzeth/snarks/pghr13/pghr13_snark.hpp new file mode 100644 index 000000000..ac5f0822f --- /dev/null +++ b/libzeth/snarks/pghr13/pghr13_snark.hpp @@ -0,0 +1,61 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_PGHR13_PGHR13_SNARK_HPP__ +#define __ZETH_SNARKS_PGHR13_PGHR13_SNARK_HPP__ + +#include +#include +#include + +namespace libzeth +{ + +template class pghr13_snark +{ +public: + typedef libsnark::r1cs_ppzksnark_proving_key ProvingKeyT; + typedef libsnark::r1cs_ppzksnark_verification_key VerifKeyT; + typedef libsnark::r1cs_ppzksnark_keypair KeypairT; + typedef libsnark::r1cs_ppzksnark_proof ProofT; + + static KeypairT generate_setup( + const libsnark::protoboard> &pb); + + static ProofT generate_proof( + const libsnark::protoboard> &pb, + const ProvingKeyT &proving_key); + + static bool verify( + const libsnark::r1cs_primary_input> &primary_inputs, + const ProofT &proof, + const VerifKeyT &verification_key); + + static void export_verification_key(const KeypairT &keypair); + + static void display_proof(const ProofT &proof); + + static void verification_key_to_json( + const VerifKeyT &keypair, boost::filesystem::path path = ""); + + static void proof_and_inputs_to_json( + const ProofT &proof, + const libsnark::r1cs_primary_input> &input, + boost::filesystem::path path = ""); + + static void proof_to_json( + const ProofT &proof, boost::filesystem::path path); + + /// Write a keypair to a stream. + static void write_keypair(std::ostream &out, const KeypairT &keypair); + + /// Read a keypair from a stream. + static KeypairT read_keypair(std::istream &in); +}; + +} // namespace libzeth + +#include "libzeth/snarks/pghr13/pghr13_snark.tcc" + +#endif // __ZETH_SNARKS_PGHR13_PGHR13_SNARK_HPP__ diff --git a/libzeth/snarks/pghr13/pghr13_snark.tcc b/libzeth/snarks/pghr13/pghr13_snark.tcc new file mode 100644 index 000000000..64e9a41b0 --- /dev/null +++ b/libzeth/snarks/pghr13/pghr13_snark.tcc @@ -0,0 +1,301 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SNARKS_PGHR13_PGHR13_SNARK_TCC__ +#define __ZETH_SNARKS_PGHR13_PGHR13_SNARK_TCC__ + +#include "libzeth/core/field_element_utils.hpp" +#include "libzeth/serialization/filesystem_util.hpp" // TODO: remove this +#include "libzeth/snarks/pghr13/pghr13_snark.hpp" + +namespace libzeth +{ + +template +typename pghr13_snark::KeypairT pghr13_snark::generate_setup( + const libsnark::protoboard> &pb) +{ + return libsnark::r1cs_ppzksnark_generator(pb.get_constraint_system()); +} + +template +typename pghr13_snark::ProofT pghr13_snark::generate_proof( + const libsnark::protoboard> &pb, + const pghr13_snark::ProvingKeyT &proving_key) +{ + // See: + // https://github.com/scipr-lab/libsnark/blob/92a80f74727091fdc40e6021dc42e9f6b67d5176/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp#L81 + // For the definition of r1cs_primary_input and r1cs_auxiliary_input + libsnark::r1cs_primary_input> primary_input = + pb.primary_input(); + libsnark::r1cs_auxiliary_input> auxiliary_input = + pb.auxiliary_input(); + + // Generate proof from public input, auxiliary input (private/secret data), + // and proving key + ProofT proof = libsnark::r1cs_ppzksnark_prover( + proving_key, primary_input, auxiliary_input); + + return proof; +} + +template +bool pghr13_snark::verify( + const libsnark::r1cs_primary_input> &primary_inputs, + const pghr13_snark::ProofT &proof, + const pghr13_snark::VerifKeyT &verification_key) +{ + return libsnark::r1cs_ppzksnark_verifier_strong_IC( + verification_key, primary_inputs, proof); +} + +template +void pghr13_snark::export_verification_key( + const pghr13_snark::KeypairT &keypair) +{ + unsigned ic_length = keypair.vk.encoded_IC_query.rest.indices.size() + 1; + + std::cout + << "\tVerification key in Solidity compliant format:{" + << "\n" + << "\t\tvk.A = Pairing.G2Point(" + << point_g2_affine_to_hexadecimal_str(keypair.vk.alphaA_g2) << ");" + << "\n" + << "\t\tvk.B = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(keypair.vk.alphaB_g1) << ");" + << "\n" + << "\t\tvk.C = Pairing.G2Point(" + << point_g2_affine_to_hexadecimal_str(keypair.vk.alphaC_g2) << ");" + << "\n" + << "\t\tvk.gamma = Pairing.G2Point(" + << point_g2_affine_to_hexadecimal_str(keypair.vk.gamma_g2) << ");" + << "\n" + << "\t\tvk.gammaBeta1 = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(keypair.vk.gamma_beta_g1) + << ");" + << "\n" + << "\t\tvk.gammaBeta2 = Pairing.G2Point(" + << point_g2_affine_to_hexadecimal_str(keypair.vk.gamma_beta_g2) + << ");" + << "\n" + << "\t\tvk.Z = Pairing.G2Point(" + << point_g2_affine_to_hexadecimal_str(keypair.vk.rC_Z_g2) << ");" + << "\n" + << "\t\tvk.IC = new Pairing.G1Point[](" << ic_length << ");" + << "\t\tvk.IC[0] = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str( + keypair.vk.encoded_IC_query.first) + << ");" << std::endl; + for (size_t i = 1; i < ic_length; ++i) { + auto vk_ic_i = point_g1_affine_to_hexadecimal_str( + keypair.vk.encoded_IC_query.rest.values[i - 1]); + std::cout << "\t\tvk.IC[" << i << "] = Pairing.G1Point(" << vk_ic_i + << ");" << std::endl; + } + std::cout << "\t\t}" << std::endl; +} + +template +void pghr13_snark::display_proof(const pghr13_snark::ProofT &proof) +{ + std::cout << "Proof:" + << "\n" + << "proof.A = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(proof.g_A.g) << ");" + << "\n" + << "proof.A_p = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(proof.g_A.h) << ");" + << "\n" + << "proof.B = Pairing.G2Point(" + << point_g2_affine_to_hexadecimal_str(proof.g_B.g) << ");" + << "\n" + << "proof.B_p = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(proof.g_B.h) << ");" + << "\n" + << "proof.C = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(proof.g_C.g) << ");" + << "\n" + << "proof.C_p = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(proof.g_C.h) << ");" + << "\n" + << "proof.H = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(proof.g_H) << ");" + << "\n" + << "proof.K = Pairing.G1Point(" + << point_g1_affine_to_hexadecimal_str(proof.g_K) << ");" + << std::endl; +} + +template +void pghr13_snark::verification_key_to_json( + const pghr13_snark::VerifKeyT &vk, boost::filesystem::path path) +{ + if (path.empty()) { + boost::filesystem::path tmp_path = get_path_to_setup_directory(); + boost::filesystem::path vk_json_file("vk.json"); + path = tmp_path / vk_json_file; + } + // Convert boost path to char* + const char *str_path = path.string().c_str(); + + std::stringstream ss; + std::ofstream fh; + fh.open(str_path, std::ios::binary); + unsigned ic_length = vk.encoded_IC_query.rest.indices.size() + 1; + + ss << "{\n"; + ss << " \"a\" :[" << point_g2_affine_to_hexadecimal_str(vk.alphaA_g2) + << "],\n"; + ss << " \"b\" :[" << point_g1_affine_to_hexadecimal_str(vk.alphaB_g1) + << "],\n"; + ss << " \"c\" :[" << point_g2_affine_to_hexadecimal_str(vk.alphaC_g2) + << "],\n"; + ss << " \"g\" :[" << point_g2_affine_to_hexadecimal_str(vk.gamma_g2) + << "],\n"; + ss << " \"gb1\" :[" + << point_g1_affine_to_hexadecimal_str(vk.gamma_beta_g1) << "],\n"; + ss << " \"gb2\" :[" + << point_g2_affine_to_hexadecimal_str(vk.gamma_beta_g2) << "],\n"; + ss << " \"z\" :[" << point_g2_affine_to_hexadecimal_str(vk.rC_Z_g2) + << "],\n"; + + ss << "\"IC\" :[[" + << point_g1_affine_to_hexadecimal_str(vk.encoded_IC_query.first) + << "]"; + + for (size_t i = 1; i < ic_length; ++i) { + auto vk_ic_i = point_g1_affine_to_hexadecimal_str( + vk.encoded_IC_query.rest.values[i - 1]); + ss << ",[" << vk_ic_i << "]"; + } + + ss << "]"; + ss << "}"; + ss.rdbuf()->pubseekpos(0, std::ios_base::out); + fh << ss.rdbuf(); + fh.flush(); + fh.close(); +} + +template +void pghr13_snark::proof_and_inputs_to_json( + const pghr13_snark::ProofT &proof, + const libsnark::r1cs_primary_input> &input, + boost::filesystem::path path) +{ + if (path.empty()) { + // Used for debugging purpose + boost::filesystem::path tmp_path = get_path_to_debug_directory(); + boost::filesystem::path proof_and_input_json_file( + "proof_and_input.json"); + path = tmp_path / proof_and_input_json_file; + } + // Convert the boost path into char* + const char *str_path = path.string().c_str(); + + std::stringstream ss; + std::ofstream fh; + fh.open(str_path, std::ios::binary); + + ss << "{\n"; + ss << " \"a\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_A.g) + << "],\n"; + ss << " \"a_p\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_A.h) + << "],\n"; + ss << " \"b\" :[" << point_g2_affine_to_hexadecimal_str(proof.g_B.g) + << "],\n"; + ss << " \"b_p\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_B.h) + << "],\n"; + ss << " \"c\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_C.g) + << "],\n"; + ss << " \"c_p\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_C.h) + << "],\n"; + ss << " \"h\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_H) + << "],\n"; + ss << " \"k\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_K) + << "],\n"; + ss << " \"input\" :" + << "["; // 1 should always be the first variable passed + for (size_t i = 0; i < input.size(); ++i) { + ss << "\"0x" + << libsnark_bigint_to_hexadecimal_str>( + input[i].as_bigint()) + << "\""; + if (i < input.size() - 1) { + ss << ", "; + } + } + ss << "]\n"; + ss << "}"; + + ss.rdbuf()->pubseekpos(0, std::ios_base::out); + fh << ss.rdbuf(); + fh.flush(); + fh.close(); +} + +template +void pghr13_snark::proof_to_json( + const pghr13_snark::ProofT &proof, boost::filesystem::path path) +{ + if (path.empty()) { + // Used for debugging purpose + boost::filesystem::path tmp_path = get_path_to_debug_directory(); + boost::filesystem::path proof_json("proof.json"); + path = tmp_path / proof_json; + } + // Convert the boost path into char* + const char *str_path = path.string().c_str(); + + std::stringstream ss; + std::ofstream fh; + fh.open(str_path, std::ios::binary); + + ss << "{\n"; + ss << " \"a\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_A.g) + << "],\n"; + ss << " \"a_p\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_A.h) + << "],\n"; + ss << " \"b\" :[" << point_g2_affine_to_hexadecimal_str(proof.g_B.g) + << "],\n"; + ss << " \"b_p\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_B.h) + << "],\n"; + ss << " \"c\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_C.g) + << "],\n"; + ss << " \"c_p\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_C.h) + << "],\n"; + ss << " \"h\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_H) + << "],\n"; + ss << " \"k\" :[" << point_g1_affine_to_hexadecimal_str(proof.g_K) + << "]\n"; + ss << "}"; + + ss.rdbuf()->pubseekpos(0, std::ios_base::out); + fh << ss.rdbuf(); + fh.flush(); + fh.close(); +} + +template +void pghr13_snark::write_keypair( + std::ostream &out, const pghr13_snark::KeypairT &keypair) +{ + out << keypair.pk; + out << keypair.vk; +} + +template +typename pghr13_snark::KeypairT pghr13_snark::read_keypair( + std::istream &in) +{ + pghr13_snark::ProvingKeyT pk; + pghr13_snark::VerifKeyT vk; + in >> pk; + in >> vk; + return pghr13_snark::KeypairT(pk, vk); +} + +} // namespace libzeth + +#endif // __ZETH_SNARKS_PGHR13_PGHR13_SNARK_TCC__ diff --git a/libzeth/snarks_alias.hpp b/libzeth/snarks_alias.hpp deleted file mode 100644 index 37f2c71ce..000000000 --- a/libzeth/snarks_alias.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_SNARKS_ALIAS_HPP__ -#define __ZETH_SNARKS_ALIAS_HPP__ - -// ------------------------- Pick a zkSNARK ------------------------- - -#ifdef ZKSNARK_PGHR13 -#define LIBZETH_SNARK_DEFINED -#include -namespace libzeth -{ -template -using provingKeyT = libsnark::r1cs_ppzksnark_proving_key; -template -using verificationKeyT = libsnark::r1cs_ppzksnark_verification_key; -template using proofT = libsnark::r1cs_ppzksnark_proof; -template using keyPairT = libsnark::r1cs_ppzksnark_keypair; -} // namespace libzeth -#endif - -#ifdef ZKSNARK_GROTH16 -#define LIBZETH_SNARK_DEFINED -#include -namespace libzeth -{ -template -using provingKeyT = libsnark::r1cs_gg_ppzksnark_proving_key; -template -using verificationKeyT = libsnark::r1cs_gg_ppzksnark_verification_key; -template using proofT = libsnark::r1cs_gg_ppzksnark_proof; -template -using keyPairT = libsnark::r1cs_gg_ppzksnark_keypair; -} // namespace libzeth -#endif - -#ifndef LIBZETH_SNARK_DEFINED -#error You must define one of the SNARK_* symbols indicated into the CMakelists.txt file. -#endif - -#endif // __ZETH_SNARKS_ALIAS_HPP__ diff --git a/libzeth/snarks_api_imports.hpp b/libzeth/snarks_api_imports.hpp deleted file mode 100644 index b71a102f8..000000000 --- a/libzeth/snarks_api_imports.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_SNARKS_API_IMPORTS_HPP__ -#define __ZETH_SNARKS_API_IMPORTS_HPP__ - -#ifdef ZKSNARK_PGHR13 -#include "libzeth/snarks/pghr13/api/response.hpp" -#elif ZKSNARK_GROTH16 -#include "libzeth/snarks/groth16/api/response.hpp" -#else -#error You must define one of the SNARK_* symbols indicated into the CMakelists.txt file. -#endif - -#endif // __ZETH_SNARKS_API_IMPORTS_HPP__ diff --git a/libzeth/snarks_core_imports.hpp b/libzeth/snarks_core_imports.hpp deleted file mode 100644 index 2676f8958..000000000 --- a/libzeth/snarks_core_imports.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_SNARKS_CORE_IMPORTS_HPP__ -#define __ZETH_SNARKS_CORE_IMPORTS_HPP__ - -#ifdef ZKSNARK_PGHR13 -#include "libzeth/snarks/pghr13/core/computation.hpp" -#include "libzeth/snarks/pghr13/core/helpers.hpp" -#elif ZKSNARK_GROTH16 -#include "libzeth/snarks/groth16/core/computation.hpp" -#include "libzeth/snarks/groth16/core/helpers.hpp" -#include "libzeth/snarks/groth16/mpc/mpc_utils.hpp" -#include "libzeth/snarks/groth16/mpc/phase2.hpp" -#else -#error You must define one of the SNARK_* symbols indicated into the CMakelists.txt file. -#endif - -#endif // __ZETH_SNARKS_CORE_IMPORTS_HPP__ diff --git a/libzeth/test/binary_operation_test.cpp b/libzeth/test/binary_operation_test.cpp index fa02f6167..fa9fadc0f 100644 --- a/libzeth/test/binary_operation_test.cpp +++ b/libzeth/test/binary_operation_test.cpp @@ -3,14 +3,11 @@ // SPDX-License-Identifier: LGPL-3.0+ #include "libzeth/circuits/binary_operation.hpp" -#include "libzeth/snarks_alias.hpp" +#include "libzeth/circuits/circuit_utils.hpp" +#include "libzeth/core/include_libff.hpp" +#include "libzeth/core/utils.hpp" -#include "gtest/gtest.h" -#include - -// Access the `from_bits` function and other utils -#include "libzeth/circuits/circuits_utils.hpp" -#include "libzeth/util.hpp" +#include using namespace libzeth; diff --git a/libzeth/test/blake2s_test.cpp b/libzeth/test/blake2s_test.cpp index 8586a5a6a..a6bf473dd 100644 --- a/libzeth/test/blake2s_test.cpp +++ b/libzeth/test/blake2s_test.cpp @@ -4,19 +4,16 @@ #include "libzeth/circuits/blake2s/blake2s.hpp" #include "libzeth/circuits/blake2s/g_primitive.hpp" -#include "libzeth/snarks_alias.hpp" +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/circuits/circuit_utils.hpp" +#include "libzeth/core/utils.hpp" -#include "gtest/gtest.h" -#include - -// Access the `from_bits` function and other utils -#include "libzeth/circuits/circuits_utils.hpp" -#include "libzeth/util.hpp" +#include using namespace libsnark; using namespace libzeth; -typedef libff::default_ec_pp ppT; +typedef libzeth::ppT ppT; typedef libff::Fr FieldT; namespace @@ -484,7 +481,7 @@ TEST(TestBlake2s, TestTrue2) blake2s_gadget.generate_r1cs_witness(); // blake2s(b"zeth") - bits256 expected = hex_digest_to_bits256( + bits256 expected = get_bits256_from_hexadecimal_str( "b5f199b422df36c99363725d886e64c07ffd8852063adbbfbb86f43716ffab0e"); ASSERT_EQ(get_vector_from_bits256(expected), output.bits.get_bits(pb)); diff --git a/libzeth/test/commitments_test.cpp b/libzeth/test/commitments_test.cpp index 9ec430083..f7ac6a6ab 100644 --- a/libzeth/test/commitments_test.cpp +++ b/libzeth/test/commitments_test.cpp @@ -3,23 +3,19 @@ // SPDX-License-Identifier: LGPL-3.0+ #include "libzeth/circuits/blake2s/blake2s.hpp" -#include "libzeth/circuits/circuits_utils.hpp" +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/circuits/circuit_utils.hpp" #include "libzeth/circuits/commitments/commitment.hpp" -#include "libzeth/util.hpp" -#include "libzeth/zeth.h" +#include "libzeth/core/utils.hpp" +#include "libzeth/zeth_constants.hpp" -#include "gtest/gtest.h" -#include -#include -#include - -// Header to use the merkle tree data structure +#include #include using namespace libzeth; // Instantiation of the templates for the tests -typedef libff::default_ec_pp ppT; +typedef libzeth::ppT ppT; typedef libff::Fr FieldT; typedef BLAKE2s_256 HashT; @@ -33,17 +29,16 @@ TEST(TestCOMMs, TestCOMMGadget) ZERO.allocate(pb, "zero"); pb.val(ZERO) = FieldT::zero(); - bits256 trap_r_bits256 = hex_digest_to_bits256( + bits256 trap_r_bits256 = get_bits256_from_hexadecimal_str( "0F000000000000FF00000000000000FF00000000000000FF00000000000000FF"); - bits64 value_bits64 = hex_value_to_bits64("2F0000000000000F"); - bits256 rho_bits256 = - hex_digest_to_bits256("FFFF000000000000000000000000000000" - "000000000000000000000000009009"); - bits256 a_pk_bits256 = - hex_digest_to_bits256("5c36fea42b82800d74304aa4f875142b42" - "1b4f2847e7c41c1077fbbcfd63f886"); - FieldT cm = FieldT("5198426621382268363215668966254183876371659610992196341" - "1853437166529959660400"); + bits64 value_bits64 = get_bits64_from_hexadecimal_str("2F0000000000000F"); + bits256 rho_bits256 = get_bits256_from_hexadecimal_str( + "FFFF000000000000000000000000000000000000000000000000000000009009"); + bits256 a_pk_bits256 = get_bits256_from_hexadecimal_str( + "5c36fea42b82800d74304aa4f875142b421b4f2847e7c41c1077fbbcfd63f886"); + FieldT cm = FieldT( + "5198426621382268363215668966254183876371659610992196341185343716" + "6529959660400"); // hex: 0xAF000000000000FF00000000000000FF00000000000000FF00000000000000FF libsnark::pb_variable_array a_pk; diff --git a/libzeth/test/hex_to_field_test.cpp b/libzeth/test/hex_to_field_test.cpp index 645a89470..ccfe4f2dd 100644 --- a/libzeth/test/hex_to_field_test.cpp +++ b/libzeth/test/hex_to_field_test.cpp @@ -2,34 +2,29 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/libsnark_helpers/debug_helpers.hpp" -#include "libzeth/util.hpp" -#include "libzeth/zeth.h" +#include "libzeth/core/field_element_utils.hpp" +#include "libzeth/core/utils.hpp" -#include "gtest/gtest.h" -#include -#include -#include - -// Access zeth configuration constants -#include "assert.h" -#include "libzeth/zeth.h" +#include +#include // Instantiation of the templates for the tests -typedef libff::default_ec_pp ppT; -typedef libff::Fr FieldT; +using pp = libff::default_ec_pp; +using field = libff::Fr; namespace { + TEST(TestHexConvertion, TestHexToFieldTrue) { - FieldT starting_field_element = FieldT::random_element(); - std::string field_el_str = libzeth::hex_from_libsnark_bigint( - starting_field_element.as_bigint()); + field starting_field_element = field::random_element(); + std::string field_el_str = + libzeth::libsnark_bigint_to_hexadecimal_str( + starting_field_element.as_bigint()); // We read the string and convert it back to a field element - FieldT retrieved_field_element = - libzeth::hexadecimal_str_to_field_element(field_el_str); + field retrieved_field_element = + libzeth::hexadecimal_str_to_field_element(field_el_str); bool res = false; res = (starting_field_element == retrieved_field_element); @@ -38,16 +33,15 @@ TEST(TestHexConvertion, TestHexToFieldTrue) TEST(TestHexConvertion, TestHexToFieldFalse) { - FieldT starting_field_element = FieldT::random_element(); - FieldT modified_field_element = starting_field_element + FieldT::one(); + field starting_field_element = field::random_element(); + field modified_field_element = starting_field_element + field::one(); std::string modified_field_el_str = - libzeth::hex_from_libsnark_bigint( + libzeth::libsnark_bigint_to_hexadecimal_str( modified_field_element.as_bigint()); // We read the string and convert it back to a field element - FieldT retrieved_field_element = - libzeth::hexadecimal_str_to_field_element( - modified_field_el_str); + field retrieved_field_element = + libzeth::hexadecimal_str_to_field_element(modified_field_el_str); bool res = false; res = (starting_field_element == retrieved_field_element); @@ -60,8 +54,8 @@ TEST(TestHexConvertion, TestHexToFieldBadString) bool res = true; try { - FieldT computed_field_element = - libzeth::hexadecimal_str_to_field_element(sample); + field computed_field_element = + libzeth::hexadecimal_str_to_field_element(sample); libff::UNUSED(computed_field_element); } catch (const std::exception &exc) { res = false; @@ -76,7 +70,7 @@ int main(int argc, char **argv) { // /!\ WARNING: Do once for all tests. Do not // forget to do this !!!! - ppT::init_public_params(); + pp::init_public_params(); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/libzeth/test/merkle_tree_test.cpp b/libzeth/test/merkle_tree_test.cpp index 2fff1cdaf..32b239fdf 100644 --- a/libzeth/test/merkle_tree_test.cpp +++ b/libzeth/test/merkle_tree_test.cpp @@ -2,17 +2,17 @@ // // SPDX-License-Identifier: LGPL-3.0+ +#include "libzeth/circuits/circuit_types.hpp" #include "libzeth/circuits/merkle_tree/merkle_path_authenticator.hpp" #include "libzeth/circuits/merkle_tree/merkle_path_selector.hpp" #include "libzeth/circuits/mimc/mimc_mp.hpp" #include "gtest/gtest.h" -#include using namespace libzeth; // Instantiation of the templates for the tests -typedef libff::default_ec_pp ppT; +typedef libzeth::ppT ppT; typedef libff::Fr FieldT; typedef MiMC_mp_gadget HashTreeT; diff --git a/libzeth/test/mimc_mp_test.cpp b/libzeth/test/mimc_mp_test.cpp index 3812f519e..f0bc2ee86 100644 --- a/libzeth/test/mimc_mp_test.cpp +++ b/libzeth/test/mimc_mp_test.cpp @@ -2,14 +2,14 @@ // // SPDX-License-Identifier: LGPL-3.0+ +#include "libzeth/circuits/circuit_types.hpp" #include "libzeth/circuits/mimc/mimc_mp.hpp" #include "gtest/gtest.h" -#include using namespace libzeth; -typedef libff::default_ec_pp ppT; +typedef libzeth::ppT ppT; typedef libff::Fr FieldT; namespace diff --git a/libzeth/test/mpc_test.cpp b/libzeth/test/mpc_test.cpp index 36dcdc27a..6091674d2 100644 --- a/libzeth/test/mpc_test.cpp +++ b/libzeth/test/mpc_test.cpp @@ -2,16 +2,17 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/circuit_types.hpp" +#include "libzeth/circuits/circuit_types.hpp" #include "libzeth/circuits/sha256/sha256_ethereum.hpp" -#include "libzeth/snarks/groth16/mpc/chacha_rng.hpp" -#include "libzeth/snarks/groth16/mpc/evaluator_from_lagrange.hpp" -#include "libzeth/snarks/groth16/mpc/mpc_utils.hpp" -#include "libzeth/snarks/groth16/mpc/multi_exp.hpp" -#include "libzeth/snarks/groth16/mpc/phase2.hpp" -#include "libzeth/snarks/groth16/mpc/powersoftau_utils.hpp" +#include "libzeth/core/chacha_rng.hpp" +#include "libzeth/core/evaluator_from_lagrange.hpp" +#include "libzeth/core/multi_exp.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/mpc/groth16/mpc_utils.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" +#include "libzeth/mpc/groth16/powersoftau_utils.hpp" +#include "libzeth/snarks/groth16/groth16_snark.hpp" #include "libzeth/test/simple_test.hpp" -#include "libzeth/util.hpp" #include #include @@ -20,6 +21,7 @@ using namespace libzeth; using namespace libsnark; +using PP = srs_pot_pp; using Fr = libff::Fr; using G1 = libff::G1; using G2 = libff::G2; @@ -451,16 +453,16 @@ TEST(MPCTests, KeyPairReadWrite) std::string keypair_serialized; { std::ostringstream out; - mpc_write_keypair(out, keypair); + groth16_snark::write_keypair(out, keypair); keypair_serialized = out.str(); } - r1cs_gg_ppzksnark_keypair keypair_deserialized = [&]() { + typename groth16_snark::KeypairT keypair_deserialized = [&]() { std::istringstream in(keypair_serialized); in.exceptions( std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit); - return mpc_read_keypair(in); + return groth16_snark::read_keypair(in); }(); ASSERT_EQ(keypair.pk, keypair_deserialized.pk); diff --git a/libzeth/test/mpc_test_hash.cpp b/libzeth/test/mpc_test_hash.cpp index 4c12591bf..16212035b 100644 --- a/libzeth/test/mpc_test_hash.cpp +++ b/libzeth/test/mpc_test_hash.cpp @@ -2,8 +2,8 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/hash_utils.hpp" -#include "libzeth/util.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/mpc/groth16/hash_utils.hpp" #include diff --git a/libzeth/test/note_test.cpp b/libzeth/test/note_test.cpp index 30d5241fa..8d76c4fe2 100644 --- a/libzeth/test/note_test.cpp +++ b/libzeth/test/note_test.cpp @@ -2,34 +2,20 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "gtest/gtest.h" -#include -#include -#include - -// Header to use the merkle tree data structure -#include "libzeth/types/merkle_tree_field.hpp" - -// Header to use the blake2s gadget #include "libzeth/circuits/blake2s/blake2s.hpp" - -// Access the `from_bits` function and other utils -#include "libzeth/circuits/circuits_utils.hpp" -#include "libzeth/util.hpp" - -// Access the defined constants -#include "libzeth/zeth.h" - -// Bring the types in scope -#include "libzeth/types/bits.hpp" -#include "libzeth/types/note.hpp" - -// Gadget to test +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/circuits/circuit_utils.hpp" #include "libzeth/circuits/notes/note.hpp" +#include "libzeth/core/bits.hpp" +#include "libzeth/core/merkle_tree_field.hpp" +#include "libzeth/core/note.hpp" +#include "libzeth/core/utils.hpp" + +#include using namespace libzeth; -typedef libff::default_ec_pp ppT; +typedef libzeth::ppT ppT; // Should be alt_bn128 in the CMakeLists.txt typedef libff::Fr FieldT; @@ -51,12 +37,12 @@ TEST(TestNoteCircuits, TestInputNoteGadget) libff::enter_block( "Initialize the coins' data (nullifier, a_sk and a_pk, cm, rho)", true); - bits256 trap_r_bits256 = hex_digest_to_bits256( + bits256 trap_r_bits256 = get_bits256_from_hexadecimal_str( "0F000000000000FF00000000000000FF00000000000000FF00000000000000FF"); - bits64 value_bits64 = hex_value_to_bits64("2F0000000000000F"); - bits256 a_sk_bits256 = hex_digest_to_bits256( + bits64 value_bits64 = get_bits64_from_hexadecimal_str("2F0000000000000F"); + bits256 a_sk_bits256 = get_bits256_from_hexadecimal_str( "FF0000000000000000000000000000000000000000000000000000000000000F"); - bits256 rho_bits256 = hex_digest_to_bits256( + bits256 rho_bits256 = get_bits256_from_hexadecimal_str( "FFFF000000000000000000000000000000000000000000000000000000009009"); // Get a_pk from a_sk (PRF) @@ -67,7 +53,7 @@ TEST(TestNoteCircuits, TestInputNoteGadget) // 0x0000000000000000000000000000000000000000000000000000000000000000 // a_pk = blake2s( 1100 || [a_sk]_252 || 0^256) // Generated directly from a_sk and hashlib blake2s - bits256 a_pk_bits256 = hex_digest_to_bits256( + bits256 a_pk_bits256 = get_bits256_from_hexadecimal_str( "f172d7299ac8ac974ea59413e4a87691826df038ba24a2b52d5c5d15c2cc8c49"); // Get nf from a_sk and rho (PRF) @@ -77,7 +63,7 @@ TEST(TestNoteCircuits, TestInputNoteGadget) // 0xEFF0000000000000000000000000000000000000000000000000000000000000 // rho = FFFF000000000000000000000000000000000000000000000000000000009009 // The test vector generated directly from a_sk and hashlib blake2s, gives: - bits256 nf_bits256 = hex_digest_to_bits256( + bits256 nf_bits256 = get_bits256_from_hexadecimal_str( "ff2f41920346251f6e7c67062149f98bc90c915d3d3020927ca01deab5da0fd7"); // Get the coin's commitment (COMM) @@ -169,12 +155,12 @@ TEST(TestNoteCircuits, TestOutputNoteGadget) libff::enter_block( "Initialize the output coins' data (a_pk, cm, rho)", true); - bits256 trap_r_bits256 = hex_digest_to_bits256( + bits256 trap_r_bits256 = get_bits256_from_hexadecimal_str( "0F000000000000FF00000000000000FF00000000000000FF00000000000000FF"); - bits64 value_bits64 = hex_value_to_bits64("2F0000000000000F"); - bits256 rho_bits256 = hex_digest_to_bits256( + bits64 value_bits64 = get_bits64_from_hexadecimal_str("2F0000000000000F"); + bits256 rho_bits256 = get_bits256_from_hexadecimal_str( "FFFF000000000000000000000000000000000000000000000000000000009009"); - bits256 a_pk_bits256 = hex_digest_to_bits256( + bits256 a_pk_bits256 = get_bits256_from_hexadecimal_str( "6461f753bfe21ba2219ced74875b8dbd8c114c3c79d7e41306dd82118de1895b"); // Get the coin's commitment (COMM) diff --git a/libzeth/test/packed_addition_test.cpp b/libzeth/test/packed_addition_test.cpp index 57fbd3564..933a1ca61 100644 --- a/libzeth/test/packed_addition_test.cpp +++ b/libzeth/test/packed_addition_test.cpp @@ -2,28 +2,19 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "util.hpp" - -#include "gtest/gtest.h" -#include -#include -#include - -// Access zeth configuration constants -#include "libzeth/zeth.h" - -// Include the type we need -#include "libzeth/circuits/circuits_utils.hpp" +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/circuits/circuit_utils.hpp" #include "libzeth/circuits/notes/note.hpp" -#include "libzeth/types/bits.hpp" -#include "libzeth/types/joinsplit.hpp" -#include "libzeth/types/note.hpp" +#include "libzeth/core/bits.hpp" +#include "libzeth/core/joinsplit_input.hpp" +#include "libzeth/core/note.hpp" +#include "libzeth/core/utils.hpp" -using namespace libzeth; +#include -typedef libff::default_ec_pp ppT; +using namespace libzeth; -// Should be alt_bn128 in the CMakeLists.txt +typedef libzeth::ppT ppT; typedef libff::Fr FieldT; namespace @@ -61,13 +52,19 @@ TEST(TestPackedAddition, TestPackedAddition1) // === Witness value_left1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("000000000000000A"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("000000000000000A"))); value_left2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("000000000000000A"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("000000000000000A"))); // 0A + 0A = 14 in hexa value_right1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000014"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000014"))); bool witness_bool = pb.is_satisfied(); std::cout << "************* SAT result: " << witness_bool @@ -114,17 +111,25 @@ TEST(TestPackedAddition, TestPackedAddition2) std::cout << "[DEBUG] Defining the witnesses" << std::endl; // 0x3782DACE9D900000 = 4ETH value_left1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("3782DACE9D900000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("3782DACE9D900000"))); // 0x3782DACE9D900000 = 4ETH value_left2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("3782DACE9D900000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("3782DACE9D900000"))); // 0x6124FEE993BC0000 = 7ETH value_right1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("6124FEE993BC0000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("6124FEE993BC0000"))); // 0x0DE0B6B3A7640000 = 1ETH value_right2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0DE0B6B3A7640000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0DE0B6B3A7640000"))); bool witness_bool = pb.is_satisfied(); std::cout << "************* SAT result: " << witness_bool @@ -177,18 +182,30 @@ TEST(TestPackedAddition, TestPackedAddition3) // === Witness std::cout << "[DEBUG] Defining the witnesses" << std::endl; v_pub_in.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000010"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000010"))); in_val_note1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("2F0000000000000F"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("2F0000000000000F"))); in_val_note2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); v_pub_out.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("000000000000000B"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("000000000000000B"))); out_val_note1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("1A00000000000012"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("1A00000000000012"))); out_val_note2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("1500000000000002"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("1500000000000002"))); bool witness_bool = pb.is_satisfied(); std::cout << "************* SAT result: " << witness_bool @@ -245,23 +262,35 @@ TEST(TestPackedAddition, TestPackedAddition4) std::cout << "[DEBUG] Defining the witnesses" << std::endl; // 0xFA80001400000000 = 18.050427392400293888 // ETH v_pub_in.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("FA80001400000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("FA80001400000000"))); in_val_note1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); in_val_note2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); v_pub_out.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); // 0x8530000A00000000 = 9.597170848876199936 ETH out_val_note1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("8530000A00000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("8530000A00000000"))); // 0x7550000A00000000 = 8.453256543524093952 ETH out_val_note2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("7550000A00000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("7550000A00000000"))); bool witness_bool = pb.is_satisfied(); std::cout << "************* SAT result: " << witness_bool @@ -314,23 +343,35 @@ TEST(TestPackedAddition, TestPackedAddition5) std::cout << "[DEBUG] Defining the witnesses" << std::endl; // 0x6124FEE993BC0000 = 7ETH v_pub_in.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("6124FEE993BC0000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("6124FEE993BC0000"))); in_val_note1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); in_val_note2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); v_pub_out.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); // 0x3782DACE9D900000 = 4ETH out_val_note1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("3782DACE9D900000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("3782DACE9D900000"))); // 0x29A2241AF62C0000 = 3ETH out_val_note2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("29A2241AF62C0000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("29A2241AF62C0000"))); bool witness_bool = pb.is_satisfied(); std::cout << "************* SAT result: " << witness_bool @@ -383,22 +424,34 @@ TEST(TestPackedAddition, TestPackedAddition6) std::cout << "[DEBUG] Defining the witnesses" << std::endl; // 0x6124FEE993BC0000 = 7ETH v_pub_in.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("6124FEE993BC0000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("6124FEE993BC0000"))); in_val_note1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); in_val_note2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); v_pub_out.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("0000000000000000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("0000000000000000"))); // 0x3782DACE9D900000 = 4.000000000000000001ETH out_val_note1.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("3782DACE9D900001"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("3782DACE9D900001"))); // 0x29A2241AF62C0000 = 3ETH out_val_note2.fill_with_bits( - pb, libff::bit_vector(hex_to_binary_vector("29A2241AF62C0000"))); + pb, + libff::bit_vector( + hexadecimal_str_to_binary_vector("29A2241AF62C0000"))); bool witness_bool = pb.is_satisfied(); std::cout << "************* SAT result: " << witness_bool diff --git a/libzeth/test/powersoftau_test.cpp b/libzeth/test/powersoftau_test.cpp index 536d042d6..afc51082d 100644 --- a/libzeth/test/powersoftau_test.cpp +++ b/libzeth/test/powersoftau_test.cpp @@ -2,9 +2,9 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/evaluator_from_lagrange.hpp" -#include "libzeth/snarks/groth16/mpc/powersoftau_utils.hpp" -#include "libzeth/util.hpp" +#include "libzeth/core/evaluator_from_lagrange.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/mpc/groth16/powersoftau_utils.hpp" #include #include diff --git a/libzeth/test/prfs_test.cpp b/libzeth/test/prfs_test.cpp index 9aeb6f936..2947a2483 100644 --- a/libzeth/test/prfs_test.cpp +++ b/libzeth/test/prfs_test.cpp @@ -2,35 +2,21 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "gtest/gtest.h" -#include -#include -#include - -// Header to use the merkle tree data structure -#include - -// Used to instantiate our templates -#include -#include -#include - -// Header to use the blake2s gadget #include "libzeth/circuits/blake2s/blake2s.hpp" - -// Access the `from_bits` function and other utils -#include "libzeth/circuits/circuits_utils.hpp" -#include "libzeth/util.hpp" - -// Gadget to test +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/circuits/circuit_utils.hpp" #include "libzeth/circuits/prfs/prf.hpp" +#include "libzeth/core/utils.hpp" + +#include +#include using namespace libsnark; using namespace libzeth; -typedef libff::default_ec_pp ppT; -// Should be alt_bn128 in the CMakeLists.txt +typedef libzeth::ppT ppT; typedef libff::Fr FieldT; + // We use our hash function to do the tests typedef BLAKE2s_256 HashT; @@ -144,7 +130,7 @@ TEST(TestPRFs, TestPRFAddrApkGadget) // function Note: (we want to make sure that we generate the same digests // both on-chain and off-chain) libsnark::pb_variable_array a_pk_expected = from_bits( - hex_digest_to_binary_vector( + hexadecimal_digest_to_binary_vector( "2390c9e5370be7355f220b29caf3912ef970d828b73976ae9bfeb1402ce4c1f9"), ZERO); @@ -259,7 +245,7 @@ TEST(TestPRFs, TestPRFNFGadget) // blake2s function (we want to make sure that we generate the same digests // both on-chain and off-chain) libsnark::pb_variable_array nf_expected = from_bits( - hex_digest_to_binary_vector( + hexadecimal_digest_to_binary_vector( "ea43866d185e1bdb84713b699a2966d929d1392488c010c603e46a4cb92986f8"), ZERO); @@ -374,7 +360,7 @@ TEST(TestPRFs, TestPRFPKGadget) // blake2s function (we want to make sure that we generate the same digests // both on-chain and off-chain) libsnark::pb_variable_array h_expected0 = from_bits( - hex_digest_to_binary_vector( + hexadecimal_digest_to_binary_vector( "8527fb92081cf832659a188163287f98b8c919401ba619d6ebd30dc0f1aedeff"), ZERO); @@ -390,7 +376,7 @@ TEST(TestPRFs, TestPRFPKGadget) prf_pk_gadget0->generate_r1cs_witness(); libsnark::pb_variable_array h_expected1 = from_bits( - hex_digest_to_binary_vector( + hexadecimal_digest_to_binary_vector( "aea510673ff50225bec4bd918c102ea0c9b117b93534644ee70b74522b204b29"), ZERO); @@ -504,7 +490,7 @@ TEST(TestPRFs, TestPRFRhoGadget) // function (we want to make sure that we generate the same digests both // on-chain and off-chain) libsnark::pb_variable_array rho_expected0 = from_bits( - hex_digest_to_binary_vector( + hexadecimal_digest_to_binary_vector( "d7b7c4536bbba1aaca684706ba0df170af95515d573ad93e30015e1c40ebc539"), ZERO); @@ -520,7 +506,7 @@ TEST(TestPRFs, TestPRFRhoGadget) prf_rho_gadget0->generate_r1cs_witness(); libsnark::pb_variable_array rho_expected1 = from_bits( - hex_digest_to_binary_vector( + hexadecimal_digest_to_binary_vector( "bb17f6088e47a8b2ac8e3d57588d52fed63079dc2b7045561d6d5e7288384249"), ZERO); diff --git a/libzeth/test/prover_test.cpp b/libzeth/test/prover_test.cpp index f04c0fc81..a9f28f228 100644 --- a/libzeth/test/prover_test.cpp +++ b/libzeth/test/prover_test.cpp @@ -2,51 +2,42 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "gtest/gtest.h" -#include -#include -#include -#include -#include - -// Header to use the merkle tree data structure to keep a local merkle tree +#include "libzeth/circuits/blake2s/blake2s.hpp" +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/circuits/circuit_wrapper.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/snarks/groth16/groth16_snark.hpp" +#include "libzeth/snarks/pghr13/pghr13_snark.hpp" + +#include +#include #include -// Have access to a chrono to measure the rough time of execution of a set of -// instructions -#include "libzeth/snarks_alias.hpp" +// Use the default ppT and other options from the circuit code, but force the +// Merkle tree depth to 4. Parameterize the test code on the snark, so that +// this code can test all available snark schemes, indepedent of the build +// configuration. -#include -// Import only the core components of the SNARK (not the API components) -#include "libzeth/circuit_wrapper.hpp" -#include "libzeth/circuits/blake2s/blake2s.hpp" -#include "libzeth/libsnark_helpers/libsnark_helpers.hpp" -#include "libzeth/snarks_core_imports.hpp" -#include "libzeth/util.hpp" +static const size_t TreeDepth = 4; using namespace libzeth; -// Instantiation of the templates for the tests -typedef libff::default_ec_pp ppT; - -// Should be alt_bn128 in the CMakeLists.txt -typedef libff::Fr FieldT; -typedef BLAKE2s_256 HashT; -typedef MiMC_mp_gadget HashTreeT; -static const size_t TreeDepth = 4; +template +using prover = circuit_wrapper; namespace { +template bool TestValidJS2In2Case1( - circuit_wrapper &prover, - libzeth::keyPairT keypair) + const prover &prover, const typename snarkT::KeypairT &keypair) { // --- General setup for the tests --- // libff::print_header( - "test JS 2-2: IN => vpub_in = 0x0, note0 = 0x2F0000000000000F, note1 = " - "0x0 || OUT => vpub_out = 0x1700000000000007, note0 = " - "0x1800000000000008, note1 = 0x0"); + "test JS 2-2:\n" + " IN => vpub_in=0x0, note0=0x2F0000000000000F, note1=0x0\n" + " OUT=> vpub_out=0x1700000000000007, note0=0x1800000000000008, " + "note1=0x0"); libff::enter_block("Instantiate merkle tree for the tests", true); // Create a merkle tree to run our tests @@ -62,16 +53,16 @@ bool TestValidJS2In2Case1( libff::enter_block("Create joinsplit_input", true); // Create the zeth note data for the commitment we will insert in the tree // (commitment to spend in this test) - bits256 trap_r_bits256 = hex_digest_to_bits256( + bits256 trap_r_bits256 = get_bits256_from_hexadecimal_str( "0F000000000000FF00000000000000FF00000000000000FF00000000000000FF"); - bits64 value_bits64 = hex_value_to_bits64("2F0000000000000F"); - bits256 a_sk_bits256 = hex_digest_to_bits256( + bits64 value_bits64 = get_bits64_from_hexadecimal_str("2F0000000000000F"); + bits256 a_sk_bits256 = get_bits256_from_hexadecimal_str( "FF0000000000000000000000000000000000000000000000000000000000000F"); - bits256 rho_bits256 = hex_digest_to_bits256( + bits256 rho_bits256 = get_bits256_from_hexadecimal_str( "FFFF000000000000000000000000000000000000000000000000000000009009"); - bits256 a_pk_bits256 = hex_digest_to_bits256( + bits256 a_pk_bits256 = get_bits256_from_hexadecimal_str( "f172d7299ac8ac974ea59413e4a87691826df038ba24a2b52d5c5d15c2cc8c49"); - bits256 nf_bits256 = hex_digest_to_bits256( + bits256 nf_bits256 = get_bits256_from_hexadecimal_str( "ff2f41920346251f6e7c67062149f98bc90c915d3d3020927ca01deab5da0fd7"); FieldT cm_field = FieldT("1042337073265819561558789652115525918926201435246" "16864409706009242461667751082"); @@ -80,9 +71,9 @@ bool TestValidJS2In2Case1( for (size_t i = 0; i < TreeDepth; ++i) { address_bits.push_back((address_commitment >> i) & 0x1); } - bits256 h_sig = hex_digest_to_bits256( + bits256 h_sig = get_bits256_from_hexadecimal_str( "6838aac4d8247655715d3dfb9b32573da2b7d3360ba89ccdaaa7923bb24c99f7"); - bits256 phi = hex_digest_to_bits256( + bits256 phi = get_bits256_from_hexadecimal_str( "403794c0e20e3bf36b820d8f7aef5505e5d1c7ac265d5efbcc3030a74a3f701b"); // We insert the commitment to the zeth note in the merkle tree @@ -95,8 +86,8 @@ bool TestValidJS2In2Case1( a_pk_bits256, value_bits64, rho_bits256, trap_r_bits256); zeth_note note_dummy_input( a_pk_bits256, - hex_value_to_bits64("0000000000000000"), - hex_digest_to_bits256( + get_bits64_from_hexadecimal_str("0000000000000000"), + get_bits256_from_hexadecimal_str( "AAAA00000000000000000000000000000000000000000000000000000000EEE" "E"), trap_r_bits256); @@ -121,11 +112,12 @@ bool TestValidJS2In2Case1( libff::leave_block("Create joinsplit_input", true); libff::enter_block("Create JSOutput/zeth_note", true); - bits64 value_out_bits64 = hex_value_to_bits64("1800000000000008"); - bits256 a_pk_out_bits256 = hex_digest_to_bits256( + bits64 value_out_bits64 = + get_bits64_from_hexadecimal_str("1800000000000008"); + bits256 a_pk_out_bits256 = get_bits256_from_hexadecimal_str( "7777f753bfe21ba2219ced74875b8dbd8c114c3c79d7e41306dd82118de1895b"); bits256 rho_out_bits256; - bits256 trap_r_out_bits256 = hex_digest_to_bits256( + bits256 trap_r_out_bits256 = get_bits256_from_hexadecimal_str( "11000000000000990000000000000099000000000000007700000000000000FF"); zeth_note note_output( @@ -135,21 +127,22 @@ bool TestValidJS2In2Case1( trap_r_out_bits256); zeth_note note_dummy_output( a_pk_out_bits256, - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), rho_out_bits256, trap_r_out_bits256); - bits64 value_pub_out_bits64 = hex_value_to_bits64("1700000000000007"); + bits64 value_pub_out_bits64 = + get_bits64_from_hexadecimal_str("1700000000000007"); std::array outputs; outputs[0] = note_output; outputs[1] = note_dummy_output; libff::leave_block("Create JSOutput/zeth_note", true); libff::enter_block("Generate proof", true); - extended_proof ext_proof = prover.prove( + extended_proof ext_proof = prover.prove( updated_root_value, inputs, outputs, - hex_value_to_bits64("0000000000000000"), // vpub_in = 0 + get_bits64_from_hexadecimal_str("0000000000000000"), // vpub_in = 0 value_pub_out_bits64, h_sig, phi, @@ -158,8 +151,9 @@ bool TestValidJS2In2Case1( libff::enter_block("Verify proof", true); // Get the verification key - libzeth::verificationKeyT vk = keypair.vk; - bool res = libzeth::verify(ext_proof, vk); + typename snarkT::VerifKeyT vk = keypair.vk; + bool res = snarkT::verify( + ext_proof.get_primary_inputs(), ext_proof.get_proof(), vk); std::cout << "Does the proof verify? " << res << std::endl; libff::leave_block("Verify proof", true); @@ -171,14 +165,15 @@ bool TestValidJS2In2Case1( return res; } +template bool TestValidJS2In2Case2( - circuit_wrapper &prover, - libzeth::keyPairT keypair) + const prover &prover, const typename snarkT::KeypairT &keypair) { libff::print_header( - "Starting test: IN => v_pub = 0, note0 = 0x2F0000000000000F, note1 = " - "0x0 || OUT => v_pub = 0x000000000000000B, note0 = 0x1A00000000000002, " - "note1 = 0x1500000000000002"); + "Starting test:\n" + " IN => v_pub=0, note0=0x2F0000000000000F, note1=0x0\n" + " OUT=> v_pub=0x000000000000000B, note0=0x1A00000000000002," + " note1=0x1500000000000002"); libff::enter_block("Instantiate merkle tree for the tests", true); // Create a merkle tree to run our tests @@ -194,16 +189,16 @@ bool TestValidJS2In2Case2( libff::enter_block("Create joinsplit_input", true); // Create the zeth note data for the commitment we will insert in the tree // (commitment to spend in this test) - bits256 trap_r_bits256 = hex_digest_to_bits256( + bits256 trap_r_bits256 = get_bits256_from_hexadecimal_str( "0F000000000000FF00000000000000FF00000000000000FF00000000000000FF"); - bits64 value_bits64 = hex_value_to_bits64("2F0000000000000F"); - bits256 a_sk_bits256 = hex_digest_to_bits256( + bits64 value_bits64 = get_bits64_from_hexadecimal_str("2F0000000000000F"); + bits256 a_sk_bits256 = get_bits256_from_hexadecimal_str( "FF0000000000000000000000000000000000000000000000000000000000000F"); - bits256 rho_bits256 = hex_digest_to_bits256( + bits256 rho_bits256 = get_bits256_from_hexadecimal_str( "FFFF000000000000000000000000000000000000000000000000000000009009"); - bits256 a_pk_bits256 = hex_digest_to_bits256( + bits256 a_pk_bits256 = get_bits256_from_hexadecimal_str( "f172d7299ac8ac974ea59413e4a87691826df038ba24a2b52d5c5d15c2cc8c49"); - bits256 nf_bits256 = hex_digest_to_bits256( + bits256 nf_bits256 = get_bits256_from_hexadecimal_str( "ff2f41920346251f6e7c67062149f98bc90c915d3d3020927ca01deab5da0fd7"); FieldT cm_field = FieldT("1042337073265819561558789652115525918926201435246" "16864409706009242461667751082"); @@ -212,9 +207,9 @@ bool TestValidJS2In2Case2( for (size_t i = 0; i < TreeDepth; ++i) { address_bits.push_back((address_commitment >> i) & 0x1); } - bits256 h_sig = hex_digest_to_bits256( + bits256 h_sig = get_bits256_from_hexadecimal_str( "6838aac4d8247655715d3dfb9b32573da2b7d3360ba89ccdaaa7923bb24c99f7"); - bits256 phi = hex_digest_to_bits256( + bits256 phi = get_bits256_from_hexadecimal_str( "403794c0e20e3bf36b820d8f7aef5505e5d1c7ac265d5efbcc3030a74a3f701b"); // We insert the commitment to the zeth note in the merkle tree @@ -230,7 +225,7 @@ bool TestValidJS2In2Case2( trap_r_bits256); zeth_note note_input1( a_pk_bits256, - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), rho_bits256, trap_r_bits256); joinsplit_input input0( @@ -254,19 +249,19 @@ bool TestValidJS2In2Case2( libff::leave_block("Create joinsplit_input", true); libff::enter_block("Create JSOutput/zeth_note", true); - bits256 a_pk_out_bits256 = hex_digest_to_bits256( + bits256 a_pk_out_bits256 = get_bits256_from_hexadecimal_str( "7777f753bfe21ba2219ced74875b8dbd8c114c3c79d7e41306dd82118de1895b"); bits256 rho_out_bits256; - bits256 trap_r_out_bits256 = hex_digest_to_bits256( + bits256 trap_r_out_bits256 = get_bits256_from_hexadecimal_str( "11000000000000990000000000000099000000000000007700000000000000FF"); zeth_note note_output0( a_pk_out_bits256, - hex_value_to_bits64("1A00000000000002"), + get_bits64_from_hexadecimal_str("1A00000000000002"), rho_out_bits256, trap_r_out_bits256); zeth_note note_output1( a_pk_out_bits256, - hex_value_to_bits64("1500000000000002"), + get_bits64_from_hexadecimal_str("1500000000000002"), rho_out_bits256, trap_r_out_bits256); std::array outputs; @@ -277,14 +272,14 @@ bool TestValidJS2In2Case2( libff::enter_block("Generate proof", true); // RHS = 0x1A00000000000002 + 0x1500000000000002 + 0x000000000000000B = // 2F0000000000000F (LHS) - extended_proof ext_proof = prover.prove( + extended_proof ext_proof = prover.prove( updated_root_value, inputs, outputs, // vpub_in = 0x0 - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), // vpub_out = 0x000000000000000B - hex_value_to_bits64("000000000000000B"), + get_bits64_from_hexadecimal_str("000000000000000B"), h_sig, phi, keypair.pk); @@ -292,8 +287,9 @@ bool TestValidJS2In2Case2( libff::enter_block("Verify proof", true); // Get the verification key - libzeth::verificationKeyT vk = keypair.vk; - bool res = libzeth::verify(ext_proof, vk); + typename snarkT::VerifKeyT vk = keypair.vk; + bool res = snarkT::verify( + ext_proof.get_primary_inputs(), ext_proof.get_proof(), vk); std::cout << "Does the proof verify? " << res << std::endl; libff::leave_block("Verify proof", true); @@ -305,15 +301,16 @@ bool TestValidJS2In2Case2( return res; } +template bool TestValidJS2In2Case3( - circuit_wrapper &prover, - libzeth::keyPairT keypair) + const prover &prover, const typename snarkT::KeypairT &keypair) { // --- General setup for the tests --- // libff::print_header( - "Starting test: IN => v_pub = 0x0000000000000010, note0 = " - "0x2F0000000000000F, note1 = 0x0 || OUT => v_pub = 0x000000000000000B, " - "note0 = 0x1A00000000000012, note1 = 0x1500000000000002"); + "Starting test:\n" + " IN => v_pub=0x0000000000000010, note0=0x2F0000000000000F, note1=0x0\n" + " OUT=> v_pub=0x000000000000000B, note0=0x1A00000000000012," + " note1=0x1500000000000002"); libff::enter_block("Instantiate merkle tree for the tests", true); // Create a merkle tree to run our tests @@ -329,31 +326,28 @@ bool TestValidJS2In2Case3( libff::enter_block("Create joinsplit_input", true); // Create the zeth note data for the commitment we will insert in the tree // (commitment to spend in this test) - bits256 trap_r_bits256 = hex_digest_to_bits256( + bits256 trap_r_bits256 = get_bits256_from_hexadecimal_str( "0F000000000000FF00000000000000FF00000000000000FF00000000000000FF"); - bits64 value_bits64 = hex_value_to_bits64("2F0000000000000F"); - bits256 a_sk_bits256 = - hex_digest_to_bits256("FF00000000000000000000000000000000" - "00000000000000000000000000000F"); - bits256 rho_bits256 = - hex_digest_to_bits256("FFFF000000000000000000000000000000" - "000000000000000000000000009009"); - bits256 a_pk_bits256 = - hex_digest_to_bits256("f172d7299ac8ac974ea59413e4a8769182" - "6df038ba24a2b52d5c5d15c2cc8c49"); - bits256 nf_bits256 = - hex_digest_to_bits256("ff2f41920346251f6e7c67062149f98bc9" - "0c915d3d3020927ca01deab5da0fd7"); - FieldT cm_field = FieldT("1042337073265819561558789652115525918926201435246" - "16864409706009242461667751082"); + bits64 value_bits64 = get_bits64_from_hexadecimal_str("2F0000000000000F"); + bits256 a_sk_bits256 = get_bits256_from_hexadecimal_str( + "FF0000000000000000000000000000000000000000000000000000000000000F"); + bits256 rho_bits256 = get_bits256_from_hexadecimal_str( + "FFFF000000000000000000000000000000000000000000000000000000009009"); + bits256 a_pk_bits256 = get_bits256_from_hexadecimal_str( + "f172d7299ac8ac974ea59413e4a87691826df038ba24a2b52d5c5d15c2cc8c49"); + bits256 nf_bits256 = get_bits256_from_hexadecimal_str( + "ff2f41920346251f6e7c67062149f98bc90c915d3d3020927ca01deab5da0fd7"); + FieldT cm_field = FieldT( + "1042337073265819561558789652115525918926201435246168644097060092" + "42461667751082"); const size_t address_commitment = 1; libff::bit_vector address_bits; for (size_t i = 0; i < TreeDepth; ++i) { address_bits.push_back((address_commitment >> i) & 0x1); } - bits256 h_sig = hex_digest_to_bits256( + bits256 h_sig = get_bits256_from_hexadecimal_str( "6838aac4d8247655715d3dfb9b32573da2b7d3360ba89ccdaaa7923bb24c99f7"); - bits256 phi = hex_digest_to_bits256( + bits256 phi = get_bits256_from_hexadecimal_str( "403794c0e20e3bf36b820d8f7aef5505e5d1c7ac265d5efbcc3030a74a3f701b"); // We insert the commitment to the zeth note in the merkle tree @@ -369,7 +363,7 @@ bool TestValidJS2In2Case3( trap_r_bits256); zeth_note note_input1( a_pk_bits256, - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), rho_bits256, trap_r_bits256); joinsplit_input input0( @@ -393,20 +387,20 @@ bool TestValidJS2In2Case3( libff::leave_block("Create joinsplit_input", true); libff::enter_block("Create JSOutput/zeth_note", true); - bits256 a_pk_out_bits256 = hex_digest_to_bits256( + bits256 a_pk_out_bits256 = get_bits256_from_hexadecimal_str( "7777f753bfe21ba2219ced74875b8dbd8c114c3c79d7e41306dd82118de1895b"); bits256 rho_out_bits256; - bits256 trap_r_out_bits256 = hex_digest_to_bits256( + bits256 trap_r_out_bits256 = get_bits256_from_hexadecimal_str( "11000000000000990000000000000099000000000000007700000000000000FF"); zeth_note note_output0( a_pk_out_bits256, - hex_value_to_bits64("1A00000000000012"), + get_bits64_from_hexadecimal_str("1A00000000000012"), rho_out_bits256, trap_r_out_bits256); zeth_note note_output1( a_pk_out_bits256, - hex_value_to_bits64("1500000000000002"), + get_bits64_from_hexadecimal_str("1500000000000002"), rho_out_bits256, trap_r_out_bits256); std::array outputs; @@ -417,13 +411,13 @@ bool TestValidJS2In2Case3( libff::enter_block("Generate proof", true); // (RHS) 0x1A00000000000012 + 0x1500000000000002 + 0x000000000000000B = // 2F0000000000000F + 0x0000000000000010 + 0x0 (LHS) - extended_proof ext_proof = prover.prove( + extended_proof ext_proof = prover.prove( updated_root_value, inputs, outputs, - hex_value_to_bits64( + get_bits64_from_hexadecimal_str( "0000000000000010"), // v_pub_in = 0x0000000000000010 - hex_value_to_bits64( + get_bits64_from_hexadecimal_str( "000000000000000B"), // v_pub_out = 0x000000000000000B h_sig, phi, @@ -432,8 +426,9 @@ bool TestValidJS2In2Case3( libff::enter_block("Verify proof", true); // Get the verification key - libzeth::verificationKeyT vk = keypair.vk; - bool res = libzeth::verify(ext_proof, vk); + typename snarkT::VerifKeyT vk = keypair.vk; + bool res = snarkT::verify( + ext_proof.get_primary_inputs(), ext_proof.get_proof(), vk); std::cout << "Does the proof verfy? " << res << std::endl; libff::leave_block("Verify proof", true); @@ -445,14 +440,15 @@ bool TestValidJS2In2Case3( return res; } +template bool TestValidJS2In2Deposit( - circuit_wrapper &prover, - libzeth::keyPairT keypair) + const prover &prover, const typename snarkT::KeypairT &keypair) { // --- General setup for the tests --- // - libff::print_header("Starting test: IN => v_pub = 0x6124FEE993BC0000, " - "note0 = 0x0, note1 = 0x0 || OUT => v_pub = 0x0, note0 " - "= 0x3782DACE9D900000, note1 = 0x29A2241AF62C0000"); + libff::print_header( + "Starting test:\n" + " IN => v_pub=0x6124FEE993BC0000, note0=0x0, note1=0x0\n" + " OUT=> v_pub=0x0, note0=0x3782DACE9D900000, note1=0x29A2241AF62C0000"); libff::enter_block("Instantiate merkle tree for the tests", true); // Create a merkle tree to run our tests @@ -468,20 +464,16 @@ bool TestValidJS2In2Deposit( libff::enter_block("Create joinsplit_input", true); // Create the zeth note data for the commitment we will insert in the tree // (commitment to spend in this test) - bits256 trap_r_bits256 = hex_digest_to_bits256( + bits256 trap_r_bits256 = get_bits256_from_hexadecimal_str( "0F000000000000FF00000000000000FF00000000000000FF00000000000000FF"); - bits256 a_sk_bits256 = - hex_digest_to_bits256("FF00000000000000000000000000000000" - "00000000000000000000000000000F"); - bits256 rho_bits256 = - hex_digest_to_bits256("FFFF000000000000000000000000000000" - "000000000000000000000000009009"); - bits256 a_pk_bits256 = - hex_digest_to_bits256("f172d7299ac8ac974ea59413e4a8769182" - "6df038ba24a2b52d5c5d15c2cc8c49"); - bits256 nf_bits256 = - hex_digest_to_bits256("ff2f41920346251f6e7c67062149f98bc9" - "0c915d3d3020927ca01deab5da0fd7"); + bits256 a_sk_bits256 = get_bits256_from_hexadecimal_str( + "FF0000000000000000000000000000000000000000000000000000000000000F"); + bits256 rho_bits256 = get_bits256_from_hexadecimal_str( + "FFFF000000000000000000000000000000000000000000000000000000009009"); + bits256 a_pk_bits256 = get_bits256_from_hexadecimal_str( + "f172d7299ac8ac974ea59413e4a87691826df038ba24a2b52d5c5d15c2cc8c49"); + bits256 nf_bits256 = get_bits256_from_hexadecimal_str( + "ff2f41920346251f6e7c67062149f98bc90c915d3d3020927ca01deab5da0fd7"); FieldT cm_field = FieldT("8049045390937310931330301778888084231593485252743" "182393007013989361193264682"); @@ -490,9 +482,9 @@ bool TestValidJS2In2Deposit( for (size_t i = 0; i < TreeDepth; ++i) { address_bits.push_back((address_commitment >> i) & 0x1); } - bits256 h_sig = hex_digest_to_bits256( + bits256 h_sig = get_bits256_from_hexadecimal_str( "6838aac4d8247655715d3dfb9b32573da2b7d3360ba89ccdaaa7923bb24c99f7"); - bits256 phi = hex_digest_to_bits256( + bits256 phi = get_bits256_from_hexadecimal_str( "403794c0e20e3bf36b820d8f7aef5505e5d1c7ac265d5efbcc3030a74a3f701b"); // We insert the commitment to the zeth note in the merkle tree @@ -503,12 +495,12 @@ bool TestValidJS2In2Deposit( // JS Inputs zeth_note note_input0( a_pk_bits256, - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), rho_bits256, trap_r_bits256); zeth_note note_input1( a_pk_bits256, - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), rho_bits256, trap_r_bits256); joinsplit_input input0( @@ -532,19 +524,19 @@ bool TestValidJS2In2Deposit( libff::leave_block("Create joinsplit_input", true); libff::enter_block("Create JSOutput/zeth_note", true); - bits256 a_pk_out_bits256 = hex_digest_to_bits256( + bits256 a_pk_out_bits256 = get_bits256_from_hexadecimal_str( "7777f753bfe21ba2219ced74875b8dbd8c114c3c79d7e41306dd82118de1895b"); bits256 rho_out_bits256; - bits256 trap_r_out_bits256 = hex_digest_to_bits256( + bits256 trap_r_out_bits256 = get_bits256_from_hexadecimal_str( "11000000000000990000000000000099000000000000007700000000000000FF"); zeth_note note_output0( a_pk_out_bits256, - hex_value_to_bits64("3782DACE9D900000"), + get_bits64_from_hexadecimal_str("3782DACE9D900000"), rho_out_bits256, trap_r_out_bits256); zeth_note note_output1( a_pk_out_bits256, - hex_value_to_bits64("29A2241AF62C0000"), + get_bits64_from_hexadecimal_str("29A2241AF62C0000"), rho_out_bits256, trap_r_out_bits256); std::array outputs; @@ -555,14 +547,14 @@ bool TestValidJS2In2Deposit( libff::enter_block("Generate proof", true); // RHS = 0x0 + 0x3782DACE9D900000 + 0x29A2241AF62C0000 = 0x6124FEE993BC0000 // (LHS) - extended_proof ext_proof = prover.prove( + extended_proof ext_proof = prover.prove( updated_root_value, inputs, outputs, // v_pub_in = 0x6124FEE993BC0000 - hex_value_to_bits64("6124FEE993BC0000"), + get_bits64_from_hexadecimal_str("6124FEE993BC0000"), // v_pub_out = 0x000000000000000B - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), h_sig, phi, keypair.pk); @@ -570,8 +562,9 @@ bool TestValidJS2In2Deposit( libff::enter_block("Verify proof", true); // Get the verification key - libzeth::verificationKeyT vk = keypair.vk; - bool res = libzeth::verify(ext_proof, vk); + typename snarkT::VerifKeyT vk = keypair.vk; + bool res = snarkT::verify( + ext_proof.get_primary_inputs(), ext_proof.get_proof(), vk); ext_proof.dump_primary_inputs(); std::cout << "Does the proof verify? " << res << std::endl; @@ -585,14 +578,15 @@ bool TestValidJS2In2Deposit( return res; } +template bool TestInvalidJS2In2( - circuit_wrapper &prover, - libzeth::keyPairT keypair) + const prover &prover, const typename snarkT::KeypairT &keypair) { // --- General setup for the tests --- // - libff::print_header("Starting test: IN => v_pub = 0xFA80001400000000, " - "note0 = 0x0, note1 = 0x0 || OUT => v_pub = 0x0, note0 " - "= 0x8530000A00000001, note1 = 0x7550000A00000000"); + libff::print_header( + "Starting test:\n" + " IN => v_pub=0xFA80001400000000, note0=0x0, note1=0x0\n" + " OUT=> v_pub=0x0, note0=0x8530000A00000001, note1=0x7550000A00000000"); libff::enter_block("Instantiate merkle tree for the tests", true); // Create a merkle tree to run our tests @@ -608,15 +602,15 @@ bool TestInvalidJS2In2( libff::enter_block("Create joinsplit_input", true); // Create the zeth note data for the commitment we will insert in the tree // (commitment to spend in this test) - bits256 trap_r_bits256 = hex_digest_to_bits256( + bits256 trap_r_bits256 = get_bits256_from_hexadecimal_str( "0F000000000000FF00000000000000FF00000000000000FF00000000000000FF"); - bits256 a_sk_bits256 = hex_digest_to_bits256( + bits256 a_sk_bits256 = get_bits256_from_hexadecimal_str( "FF0000000000000000000000000000000000000000000000000000000000000F"); - bits256 rho_bits256 = hex_digest_to_bits256( + bits256 rho_bits256 = get_bits256_from_hexadecimal_str( "FFFF000000000000000000000000000000000000000000000000000000009009"); - bits256 a_pk_bits256 = hex_digest_to_bits256( + bits256 a_pk_bits256 = get_bits256_from_hexadecimal_str( "f172d7299ac8ac974ea59413e4a87691826df038ba24a2b52d5c5d15c2cc8c49"); - bits256 nf_bits256 = hex_digest_to_bits256( + bits256 nf_bits256 = get_bits256_from_hexadecimal_str( "ff2f41920346251f6e7c67062149f98bc90c915d3d3020927ca01deab5da0fd7"); FieldT cm_field = FieldT("8049045390937310931330301778888084231593485252743" "182393007013989361193264682"); @@ -626,9 +620,9 @@ bool TestInvalidJS2In2( for (size_t i = 0; i < TreeDepth; ++i) { address_bits.push_back((address_commitment >> i) & 0x1); } - bits256 h_sig = hex_digest_to_bits256( + bits256 h_sig = get_bits256_from_hexadecimal_str( "6838aac4d8247655715d3dfb9b32573da2b7d3360ba89ccdaaa7923bb24c99f7"); - bits256 phi = hex_digest_to_bits256( + bits256 phi = get_bits256_from_hexadecimal_str( "403794c0e20e3bf36b820d8f7aef5505e5d1c7ac265d5efbcc3030a74a3f701b"); // We insert the commitment to the zeth note in the merkle tree @@ -639,12 +633,12 @@ bool TestInvalidJS2In2( // JS Inputs zeth_note note_input0( a_pk_bits256, - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), rho_bits256, trap_r_bits256); zeth_note note_input1( a_pk_bits256, - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), rho_bits256, trap_r_bits256); joinsplit_input input0( @@ -668,22 +662,22 @@ bool TestInvalidJS2In2( libff::leave_block("Create joinsplit_input", true); libff::enter_block("Create JSOutput/zeth_note", true); - bits256 a_pk_out_bits256 = hex_digest_to_bits256( + bits256 a_pk_out_bits256 = get_bits256_from_hexadecimal_str( "7777f753bfe21ba2219ced74875b8dbd8c114c3c79d7e41306dd82118de1895b"); bits256 rho_out_bits256; - bits256 trap_r_out_bits256 = hex_digest_to_bits256( + bits256 trap_r_out_bits256 = get_bits256_from_hexadecimal_str( "11000000000000990000000000000099000000000000007700000000000000FF"); // 0x8530000A00000000 = 9.597170848876199937 ETH zeth_note note_output0( a_pk_out_bits256, - hex_value_to_bits64("8530000A00000001"), + get_bits64_from_hexadecimal_str("8530000A00000001"), rho_out_bits256, trap_r_out_bits256); // 0x7550000A00000000 = 8.453256543524093952 ETH zeth_note note_output1( a_pk_out_bits256, - hex_value_to_bits64("7550000A00000000"), + get_bits64_from_hexadecimal_str("7550000A00000000"), rho_out_bits256, trap_r_out_bits256); std::array outputs; @@ -696,14 +690,14 @@ bool TestInvalidJS2In2( // 0x8530000A00000001 (9.597170848876199937 ETH) + 0x7550000A00000000 // (8.453256543524093952 ETH) = RHS LHS = 18.050427392400293888 ETH RHS // = 18.050427392400293889 ETH (1 wei higher than LHS) - extended_proof ext_proof = prover.prove( + extended_proof ext_proof = prover.prove( updated_root_value, inputs, outputs, // vpub_in = 0xFA80001400000000 = 18.050427392400293888 ETH - hex_value_to_bits64("FA80001400000000"), + get_bits64_from_hexadecimal_str("FA80001400000000"), // vpub_out = 0x0 - hex_value_to_bits64("0000000000000000"), + get_bits64_from_hexadecimal_str("0000000000000000"), h_sig, phi, keypair.pk); @@ -711,8 +705,9 @@ bool TestInvalidJS2In2( libff::enter_block("Verify proof", true); // Get the verification key - libzeth::verificationKeyT vk = keypair.vk; - bool res = libzeth::verify(ext_proof, vk); + typename snarkT::VerifKeyT vk = keypair.vk; + bool res = snarkT::verify( + ext_proof.get_primary_inputs(), ext_proof.get_proof(), vk); std::cout << "Does the proof verify ? " << res << std::endl; libff::leave_block("Verify proof", true); @@ -724,14 +719,13 @@ bool TestInvalidJS2In2( return res; } -TEST(MainTests, ProofGenAndVerifJS2to2) +template static void run_prover_tests() { // Run the trusted setup once for all tests, and keep the keypair in memory // for the duration of the tests - circuit_wrapper - proverJS2to2; + prover proverJS2to2; - libzeth::keyPairT keypair = proverJS2to2.generate_trusted_setup(); + typename snarkT::KeypairT keypair = proverJS2to2.generate_trusted_setup(); bool res = false; res = TestValidJS2In2Case1(proverJS2to2, keypair); @@ -746,14 +740,30 @@ TEST(MainTests, ProofGenAndVerifJS2to2) res = TestValidJS2In2Deposit(proverJS2to2, keypair); ASSERT_TRUE(res); - // The following test is expected to throw an exception because the LHS =/= - // RHS + // The following is expected to throw an exception because LHS =/= RHS. + // Ensure that the exception is thrown. + ASSERT_THROW( + (res = TestInvalidJS2In2(proverJS2to2, keypair)), + std::invalid_argument); + try { + res = false; res = TestInvalidJS2In2(proverJS2to2, keypair); - ASSERT_TRUE(res); + res = true; } catch (const std::invalid_argument &e) { std::cerr << "Invalid argument exception: " << e.what() << '\n'; } + ASSERT_FALSE(res); +} + +TEST(MainTestsGroth16, ProofGenAndVerifJS2to2) +{ + run_prover_tests>(); +} + +TEST(MainTestsPghr12, ProofGenAndVerifJS2to2) +{ + run_prover_tests>(); } } // namespace diff --git a/libzeth/test/sha256_test.cpp b/libzeth/test/sha256_test.cpp index 7aae2d25e..ebbaaff02 100644 --- a/libzeth/test/sha256_test.cpp +++ b/libzeth/test/sha256_test.cpp @@ -2,35 +2,19 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "gtest/gtest.h" -#include -#include -#include - -// Header to use the merkle tree data structure -#include - -// Used to instantiate our templates -#include -#include -#include - -// Header to use the sha256_ethereum gadget +#include "circuits/circuit_types.hpp" +#include "circuits/circuit_utils.hpp" #include "circuits/sha256/sha256_ethereum.hpp" - -// Access the `from_bits` function and other utils -#include "circuits/circuits_utils.hpp" +#include "types/bits.tcc" #include "util.hpp" -// Use the bits256 type util functions -#include "types/bits.tcc" +#include +#include using namespace libsnark; using namespace libzeth; -typedef libff::default_ec_pp ppT; - -// Should be alt_bn128 in the CMakeLists.txt +typedef libzeth::ppT ppT; typedef libff::Fr FieldT; // We use our hash function to do the tests @@ -135,8 +119,8 @@ TEST(TestSHA256, TestHash) // on-chain and off-chain) Solidity version v0.5.0 std::string test_vector_res_str = "a4cc8f23d1dfeab58d7af00b3422f22dd60b9c608af5f30744073653236562c3"; - libsnark::pb_variable_array expected = - from_bits(hex_digest_to_binary_vector(test_vector_res_str), ZERO); + libsnark::pb_variable_array expected = from_bits( + hexadecimal_digest_to_binary_vector(test_vector_res_str), ZERO); hasher->generate_r1cs_constraints(true); hasher->generate_r1cs_witness(); @@ -173,11 +157,11 @@ TEST(TestSHA256, TestHashWithZeroLeg) "a631eca6f9fc96e9b0135804aceb5e97df404c3877d14e7f5ea67b4c120cec44"; libff::bit_vector left_bits = - libff::bit_vector(hex_digest_to_binary_vector(left_str)); + libff::bit_vector(hexadecimal_digest_to_binary_vector(left_str)); libff::bit_vector right_bits = - libff::bit_vector(hex_digest_to_binary_vector(right_str)); + libff::bit_vector(hexadecimal_digest_to_binary_vector(right_str)); libff::bit_vector expected_bits = - libff::bit_vector(hex_digest_to_binary_vector(expected_str)); + libff::bit_vector(hexadecimal_digest_to_binary_vector(expected_str)); left.fill_with_bits(pb, left_bits); right.fill_with_bits(pb, right_bits); diff --git a/libzeth/test/simple_test.cpp b/libzeth/test/simple_test.cpp index 37b8f4110..3335e0f24 100644 --- a/libzeth/test/simple_test.cpp +++ b/libzeth/test/simple_test.cpp @@ -4,7 +4,7 @@ #include "simple_test.hpp" -#include "util.hpp" +#include "core/utils.hpp" #include diff --git a/libzeth/test/simple_test.hpp b/libzeth/test/simple_test.hpp index 5ed784a1f..a8da1380b 100644 --- a/libzeth/test/simple_test.hpp +++ b/libzeth/test/simple_test.hpp @@ -5,7 +5,7 @@ #ifndef __ZETH_TEST_SIMPLE_TEST_HPP__ #define __ZETH_TEST_SIMPLE_TEST_HPP__ -#include "libzeth/include_libsnark.hpp" +#include "libzeth/core/include_libsnark.hpp" namespace libzeth { diff --git a/libzeth/types/bits.cpp b/libzeth/types/bits.cpp deleted file mode 100644 index e5d0c85e1..000000000 --- a/libzeth/types/bits.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#include "libzeth/types/bits.hpp" - -namespace libzeth -{ - -bits384 get_bits384_from_vector(std::vector vect) -{ - return dump_vector_in_array<384>(vect); -} - -bits256 get_bits256_from_vector(std::vector vect) -{ - return dump_vector_in_array<256>(vect); -} - -bits64 get_bits64_from_vector(std::vector vect) -{ - return dump_vector_in_array<64>(vect); -} - -std::vector get_vector_from_bits384(bits384 arr) -{ - return dump_array_in_vector<384>(arr); -} - -std::vector get_vector_from_bits256(bits256 arr) -{ - return dump_array_in_vector<256>(arr); -} - -std::vector get_vector_from_bits64(bits64 arr) -{ - return dump_array_in_vector<64>(arr); -} - -std::vector get_vector_from_bits32(bits32 arr) -{ - return dump_array_in_vector<32>(arr); -} - -} // namespace libzeth diff --git a/libzeth/util.hpp b/libzeth/util.hpp deleted file mode 100644 index a8f7d8917..000000000 --- a/libzeth/util.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#ifndef __ZETH_UTIL_HPP__ -#define __ZETH_UTIL_HPP__ - -#include "libzeth/libsnark_helpers/debug_helpers.hpp" -#include "libzeth/types/bits.hpp" - -#include -#include -#include -#include -#include - -namespace libzeth -{ - -template T swap_byte_endianness(T v); - -std::vector hex_to_binary_vector(std::string str); -std::vector hex_digest_to_binary_vector(std::string str); -bits384 hex_value_to_bits384(std::string digest_hex_str); -bits256 hex_digest_to_bits256(std::string digest_hex_str); -bits64 hex_value_to_bits64(std::string value_hex_str); - -// Returns the little endian binary encoding of the integer x. -std::vector convert_uint_to_binary(size_t x); - -template -std::vector address_bits_from_address(size_t address); - -template -FieldT hexadecimal_str_to_field_element(std::string input); - -std::string hexadecimal_str_to_binary_str(const std::string &s); -int hexadecimal_str_to_binary(char *source_str, uint8_t *dest_buffer); -std::string binary_str_to_hexadecimal_str(const void *s, const size_t size); -std::string binary_str_to_hexadecimal_str(const std::string &s); -void erase_substring(std::string &string, const std::string &substring); - -// interface for StructuredT typed below: -// { -// bool is_well_formed() const; -// } - -// Throw if input is not well-formed. The type being checked should conform -// to the StructuredT interface above. -template -void check_well_formed(const StructuredT &v, const char *name); - -// Throw if input is not well-formed. The type being checked should conform -// to the StructuredT interface above. -template -void check_well_formed_(const StructuredT &v, const char *name); - -// For some iterable container of objects comforming to StructuredT, throw if -// any entry is not well-formed. -template -bool container_is_well_formed(const StructuredTs &values); - -} // namespace libzeth -#include "libzeth/util.tcc" - -#endif // __ZETH_UTIL_HPP__ diff --git a/libzeth/util_api.cpp b/libzeth/util_api.cpp deleted file mode 100644 index 4979a4f50..000000000 --- a/libzeth/util_api.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -#include "libzeth/util_api.hpp" - -// Message formatting and parsing utility - -namespace libzeth -{ - -zeth_note parse_zeth_note(const zeth_proto::ZethNote ¬e) -{ - bits256 note_apk = hex_digest_to_bits256(note.apk()); - bits64 note_value = hex_value_to_bits64(note.value()); - bits256 note_rho = hex_digest_to_bits256(note.rho()); - bits256 note_trap_r = hex_digest_to_bits256(note.trap_r()); - - return zeth_note(note_apk, note_value, note_rho, note_trap_r); -} - -} // namespace libzeth diff --git a/libzeth/zeth.h b/libzeth/zeth.h deleted file mode 100644 index 0dcb77b01..000000000 --- a/libzeth/zeth.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __ZETH_CONSTANTS__ -#define __ZETH_CONSTANTS__ - -#include - -namespace libzeth -{ - -static const size_t ZETH_NUM_JS_INPUTS = 2; -static const size_t ZETH_NUM_JS_OUTPUTS = 2; - -static const size_t ZETH_MERKLE_TREE_DEPTH = 32; - -static const size_t ZETH_V_SIZE = 64; // 64 bits for the value -static const size_t ZETH_RHO_SIZE = 256; // 256 bits for rho -static const size_t ZETH_PHI_SIZE = 256; // 256 bits for phi -static const size_t ZETH_HSIG_SIZE = 256; // 256 bits for h_sig -static const size_t ZETH_A_SK_SIZE = 256; // 256 bits for a_sk -static const size_t ZETH_A_PK_SIZE = 256; // 256 bits for a_pk -static const size_t ZETH_R_SIZE = 256; // 256 bits for r - -static const size_t BYTE_LEN = 8; - -} // namespace libzeth - -#endif // __ZETH_CONSTANTS__ diff --git a/libzeth/zeth_constants.hpp b/libzeth/zeth_constants.hpp new file mode 100644 index 000000000..2490d5323 --- /dev/null +++ b/libzeth/zeth_constants.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_ZETH_CONSTANTS_HPP__ +#define __ZETH_ZETH_CONSTANTS_HPP__ + +#include + +namespace libzeth +{ + +static const size_t ZETH_NUM_JS_INPUTS = 2; +static const size_t ZETH_NUM_JS_OUTPUTS = 2; + +static const size_t ZETH_MERKLE_TREE_DEPTH = 32; + +static const size_t ZETH_V_SIZE = 64; // 64 bits for the value +static const size_t ZETH_RHO_SIZE = 256; // 256 bits for rho +static const size_t ZETH_PHI_SIZE = 256; // 256 bits for phi +static const size_t ZETH_HSIG_SIZE = 256; // 256 bits for h_sig +static const size_t ZETH_A_SK_SIZE = 256; // 256 bits for a_sk +static const size_t ZETH_A_PK_SIZE = 256; // 256 bits for a_pk +static const size_t ZETH_R_SIZE = 256; // 256 bits for r + +} // namespace libzeth + +#endif // __ZETH_ZETH_CONSTANTS_HPP__ diff --git a/mpc_tools/mpc_phase2/cli/mpc_common.hpp b/mpc_tools/mpc_phase2/cli/mpc_common.hpp index bcf8c3e20..7d2fd9467 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_common.hpp +++ b/mpc_tools/mpc_phase2/cli/mpc_common.hpp @@ -5,7 +5,8 @@ #ifndef __ZETH_MPC_CLI_COMMON_HPP__ #define __ZETH_MPC_CLI_COMMON_HPP__ -#include "libzeth/circuit_types.hpp" +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/mpc/groth16/hash_utils.hpp" #include #include diff --git a/mpc_tools/mpc_phase2/cli/mpc_create_keypair.cpp b/mpc_tools/mpc_phase2/cli/mpc_create_keypair.cpp index 6b84e06fa..e5ae73504 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_create_keypair.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_create_keypair.cpp @@ -2,11 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/phase2.hpp" -// This comment preserves include order under clang-format. -#include "libzeth/snarks/groth16/mpc/mpc_utils.hpp" -#include "libzeth/snarks/groth16/mpc/powersoftau_utils.hpp" -#include "libzeth/util.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/mpc/groth16/mpc_utils.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" +#include "libzeth/mpc/groth16/powersoftau_utils.hpp" #include "mpc_common.hpp" #include @@ -173,7 +172,7 @@ class mpc_create_keypair : public subcommand { std::ofstream out( keypair_out_file, std::ios_base::binary | std::ios_base::out); - mpc_write_keypair(out, keypair); + groth16_snark::write_keypair(out, keypair); } libff::leave_block("Writing keypair file"); diff --git a/mpc_tools/mpc_phase2/cli/mpc_dummy_phase2.cpp b/mpc_tools/mpc_phase2/cli/mpc_dummy_phase2.cpp index 795653e2e..229031b11 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_dummy_phase2.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_dummy_phase2.cpp @@ -2,10 +2,9 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/mpc_utils.hpp" -#include "libzeth/snarks/groth16/mpc/phase2.hpp" -#include "libzeth/util.hpp" -#include "libzeth/zeth.h" +#include "libzeth/core/utils.hpp" +#include "libzeth/mpc/groth16/mpc_utils.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" #include "mpc_common.hpp" using namespace libzeth; diff --git a/mpc_tools/mpc_phase2/cli/mpc_linear_combination.cpp b/mpc_tools/mpc_phase2/cli/mpc_linear_combination.cpp index b1bb674f6..4672aec33 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_linear_combination.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_linear_combination.cpp @@ -3,9 +3,9 @@ // SPDX-License-Identifier: LGPL-3.0+ #include "libzeth/circuits/blake2s/blake2s_comp.hpp" -#include "libzeth/snarks/groth16/mpc/mpc_utils.hpp" -#include "libzeth/snarks/groth16/mpc/powersoftau_utils.hpp" -#include "libzeth/util.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/mpc/groth16/mpc_utils.hpp" +#include "libzeth/mpc/groth16/powersoftau_utils.hpp" #include "mpc_common.hpp" #include diff --git a/mpc_tools/mpc_phase2/cli/mpc_phase2_begin.cpp b/mpc_tools/mpc_phase2/cli/mpc_phase2_begin.cpp index ac71ec0f9..0821f9975 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_phase2_begin.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_phase2_begin.cpp @@ -2,8 +2,8 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/mpc_utils.hpp" -#include "libzeth/snarks/groth16/mpc/phase2.hpp" +#include "libzeth/mpc/groth16/mpc_utils.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" #include "mpc_common.hpp" #include diff --git a/mpc_tools/mpc_phase2/cli/mpc_phase2_contribute.cpp b/mpc_tools/mpc_phase2/cli/mpc_phase2_contribute.cpp index b3ea12ced..81573b064 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_phase2_contribute.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_phase2_contribute.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/phase2.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" #include "mpc_common.hpp" using namespace libzeth; diff --git a/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_contribution.cpp b/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_contribution.cpp index a010dea31..eaff879f6 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_contribution.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_contribution.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/phase2.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" #include "mpc_common.hpp" using namespace libzeth; diff --git a/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_transcript.cpp b/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_transcript.cpp index 287ec42ca..2c435c03e 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_transcript.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_transcript.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/snarks/groth16/mpc/phase2.hpp" +#include "libzeth/mpc/groth16/phase2.hpp" #include "mpc_common.hpp" #include diff --git a/mpc_tools/mpc_phase2/mpc_client.cpp b/mpc_tools/mpc_phase2/mpc_client.cpp index 37d99c164..a4802a8ce 100644 --- a/mpc_tools/mpc_phase2/mpc_client.cpp +++ b/mpc_tools/mpc_phase2/mpc_client.cpp @@ -6,7 +6,7 @@ // is, participants in the MPC that only contribute and potentially validate // the final transcript. -#include "libzeth/circuit_wrapper.hpp" +#include "libzeth/circuits/circuit_wrapper.hpp" #include "mpc_common.hpp" void zeth_protoboard(libsnark::protoboard &pb) diff --git a/mpc_tools/mpc_phase2/mpc_coord.cpp b/mpc_tools/mpc_phase2/mpc_coord.cpp index 825ac9952..ace191567 100644 --- a/mpc_tools/mpc_phase2/mpc_coord.cpp +++ b/mpc_tools/mpc_phase2/mpc_coord.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/circuit_wrapper.hpp" +#include "libzeth/circuits/circuit_wrapper.hpp" #include "mpc_common.hpp" void zeth_protoboard(libsnark::protoboard &pb) diff --git a/mpc_tools/pot_process/pot_process.cpp b/mpc_tools/pot_process/pot_process.cpp index f54a94c57..2b32cd868 100644 --- a/mpc_tools/pot_process/pot_process.cpp +++ b/mpc_tools/pot_process/pot_process.cpp @@ -5,8 +5,8 @@ /// Small utility to check powersoftau output and to compute the evaluation of /// Lagrange polynomials at tau. -#include "libzeth/circuit_types.hpp" -#include "libzeth/snarks/groth16/mpc/powersoftau_utils.hpp" +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/mpc/groth16/powersoftau_utils.hpp" #include #include diff --git a/prover_server/prover_server.cpp b/prover_server/prover_server.cpp index 4bfcad226..a7ea16233 100644 --- a/prover_server/prover_server.cpp +++ b/prover_server/prover_server.cpp @@ -2,14 +2,16 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzeth/circuit_types.hpp" -#include "libzeth/libsnark_helpers/libsnark_helpers.hpp" -#include "libzeth/snarks_alias.hpp" -#include "libzeth/util.hpp" -#include "libzeth/util_api.hpp" -#include "libzeth/zeth.h" -#include "zethConfig.h" - +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/core/extended_proof.hpp" +#include "libzeth/core/utils.hpp" +#include "libzeth/serialization/api/api_io.hpp" +#include "libzeth/serialization/file_io.hpp" +#include "libzeth/snarks/default/default_api_handler.hpp" +#include "libzeth/zeth_constants.hpp" +#include "zeth_config.h" + +#include #include #include #include @@ -18,21 +20,13 @@ #include #include #include +#include #include #include #include -// Necessary header to parse the data -#include - -// Include the file generated by gRPC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#include "api/prover.grpc.pb.h" -#pragma GCC diagnostic pop - -// Include the API for the given SNARK -#include "libzeth/snarks_api_imports.hpp" +using snark = libzeth::default_snark; +using api_handler = libzeth::default_api_handler; namespace proto = google::protobuf; namespace po = boost::program_options; @@ -43,30 +37,32 @@ namespace po = boost::program_options; class prover_server final : public zeth_proto::Prover::Service { private: + using FieldT = libff::Fr; + libzeth::circuit_wrapper< - libzeth::FieldT, libzeth::HashT, libzeth::HashTreeT, libzeth::ppT, + snark, libzeth::ZETH_NUM_JS_INPUTS, libzeth::ZETH_NUM_JS_OUTPUTS, libzeth::ZETH_MERKLE_TREE_DEPTH> prover; // The keypair is the result of the setup - libzeth::keyPairT keypair; + snark::KeypairT keypair; public: explicit prover_server( libzeth::circuit_wrapper< - libzeth::FieldT, libzeth::HashT, libzeth::HashTreeT, libzeth::ppT, + snark, libzeth::ZETH_NUM_JS_INPUTS, libzeth::ZETH_NUM_JS_OUTPUTS, libzeth::ZETH_MERKLE_TREE_DEPTH> &prover, - libzeth::keyPairT &keypair) + snark::KeypairT &keypair) : prover(prover), keypair(keypair) { } @@ -81,8 +77,7 @@ class prover_server final : public zeth_proto::Prover::Service std::cout << "[DEBUG] Preparing verification key for response..." << std::endl; try { - libzeth::prepare_verification_key_response( - this->keypair.vk, response); + api_handler::format_verification_key(this->keypair.vk, response); } catch (const std::exception &e) { std::cout << "[ERROR] " << e.what() << std::endl; return grpc::Status( @@ -110,14 +105,15 @@ class prover_server final : public zeth_proto::Prover::Service libzeth::FieldT root = libzeth::hexadecimal_str_to_field_element( proof_inputs->mk_root()); - libzeth::bits64 vpub_in = - libzeth::hex_value_to_bits64(proof_inputs->pub_in_value()); - libzeth::bits64 vpub_out = - libzeth::hex_value_to_bits64(proof_inputs->pub_out_value()); + libzeth::bits64 vpub_in = libzeth::get_bits64_from_hexadecimal_str( + proof_inputs->pub_in_value()); + libzeth::bits64 vpub_out = libzeth::get_bits64_from_hexadecimal_str( + proof_inputs->pub_out_value()); libzeth::bits256 h_sig_in = - libzeth::hex_digest_to_bits256(proof_inputs->h_sig()); + libzeth::get_bits256_from_hexadecimal_str( + proof_inputs->h_sig()); libzeth::bits256 phi_in = - libzeth::hex_digest_to_bits256(proof_inputs->phi()); + libzeth::get_bits256_from_hexadecimal_str(proof_inputs->phi()); if (libzeth::ZETH_NUM_JS_INPUTS != proof_inputs->js_inputs_size()) { throw std::invalid_argument("Invalid number of JS inputs"); @@ -167,7 +163,7 @@ class prover_server final : public zeth_proto::Prover::Service std::cout << "[DEBUG] Data parsed successfully" << std::endl; std::cout << "[DEBUG] Generating the proof..." << std::endl; - libzeth::extended_proof ext_proof = + libzeth::extended_proof ext_proof = this->prover.prove( root, joinsplit_inputs, @@ -183,7 +179,7 @@ class prover_server final : public zeth_proto::Prover::Service ext_proof.dump_primary_inputs(); std::cout << "[DEBUG] Preparing response..." << std::endl; - libzeth::prepare_proof_response(ext_proof, proof); + api_handler::format_extended_proof(ext_proof, proof); } catch (const std::exception &e) { std::cout << "[ERROR] " << e.what() << std::endl; @@ -235,14 +231,14 @@ void display_server_start_message() static void RunServer( libzeth::circuit_wrapper< - libzeth::FieldT, libzeth::HashT, libzeth::HashTreeT, libzeth::ppT, + snark, libzeth::ZETH_NUM_JS_INPUTS, libzeth::ZETH_NUM_JS_OUTPUTS, libzeth::ZETH_MERKLE_TREE_DEPTH> &prover, - libzeth::keyPairT &keypair) + typename snark::KeypairT &keypair) { // Listen for incoming connections on 0.0.0.0:50051 std::string server_address("0.0.0.0:50051"); @@ -269,13 +265,12 @@ static void RunServer( } #ifdef ZKSNARK_GROTH16 -static libzeth::keyPairT load_keypair( - const std::string &keypair_file) +static snark::KeypairT load_keypair(const std::string &keypair_file) { std::ifstream in(keypair_file, std::ios_base::in | std::ios_base::binary); in.exceptions( std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit); - return libzeth::mpc_read_keypair(in); + return snark::read_keypair(in); } #endif @@ -332,15 +327,15 @@ int main(int argc, char **argv) libzeth::ppT::init_public_params(); libzeth::circuit_wrapper< - libzeth::FieldT, libzeth::HashT, libzeth::HashTreeT, libzeth::ppT, + snark, libzeth::ZETH_NUM_JS_INPUTS, libzeth::ZETH_NUM_JS_OUTPUTS, libzeth::ZETH_MERKLE_TREE_DEPTH> prover; - libzeth::keyPairT keypair = [&keypair_file, &prover]() { + snark::KeypairT keypair = [&keypair_file, &prover]() { if (!keypair_file.empty()) { #ifdef ZKSNARK_GROTH16 std::cout << "[INFO] Loading keypair: " << keypair_file diff --git a/scripts/format b/scripts/format index 7883845ed..27c7309dd 100755 --- a/scripts/format +++ b/scripts/format @@ -1,14 +1,17 @@ #!/usr/bin/env bash +CLANG_FORMAT=clang-format + +${CLANG_FORMAT} --version if [ "" == "$1" ] ; then files=`git ls-files '*.cpp' '*.cc' '*.hpp' '*.hh' '*.tcc'` for f in $files ; do echo "FORMATTING $f" - clang-format -style=file -i $f + ${CLANG_FORMAT} -style=file -i $f done else for f in $@ ; do echo "FORMATTING $f" - clang-format -style=file -i $f + ${CLANG_FORMAT} -style=file -i $f done fi diff --git a/zeth-contracts/contracts/Pghr13Mixer.sol b/zeth-contracts/contracts/Pghr13Mixer.sol index 17280fd1e..9a18fe49d 100644 --- a/zeth-contracts/contracts/Pghr13Mixer.sol +++ b/zeth-contracts/contracts/Pghr13Mixer.sol @@ -6,6 +6,7 @@ pragma solidity ^0.5.0; pragma experimental ABIEncoderV2; import "./OTSchnorrVerifier.sol"; +import "./Pairing.sol"; import "./BaseMixer.sol"; contract Pghr13Mixer is BaseMixer { diff --git a/zethConfig.h.in b/zeth_config.h.in similarity index 100% rename from zethConfig.h.in rename to zeth_config.h.in