From 4890d589a124dda134c54c2ddc2c583d1f25689b Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 6 Aug 2020 16:58:55 +0100 Subject: [PATCH 01/13] libzecale: simplication of the groth16 verification key gadget --- .../r1cs_gg_ppzksnark_verifier_gadget.hpp | 4 - .../r1cs_gg_ppzksnark_verifier_gadget.tcc | 117 ++++++------------ 2 files changed, 38 insertions(+), 83 deletions(-) diff --git a/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.hpp b/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.hpp index c44d33f0..f37cd119 100644 --- a/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.hpp +++ b/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.hpp @@ -61,7 +61,6 @@ class r1cs_gg_ppzksnark_verification_key_variable std::shared_ptr> alpha_g1; std::shared_ptr> beta_g2; std::shared_ptr> delta_g2; - std::shared_ptr> encoded_ABC_base; std::vector>> ABC_g1; @@ -69,9 +68,6 @@ class r1cs_gg_ppzksnark_verification_key_variable libsnark::pb_linear_combination_array all_vars; size_t input_size; - std::vector>> all_G1_vars; - std::vector>> all_G2_vars; - std::shared_ptr> packer; // Unfortunately, g++ 4.9 and g++ 5.0 have a bug related to diff --git a/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.tcc b/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.tcc index ddb42a3f..a5e11867 100644 --- a/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.tcc +++ b/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.tcc @@ -103,58 +103,42 @@ r1cs_gg_ppzksnark_verification_key_variable:: const size_t input_size, const std::string &annotation_prefix) : libsnark::gadget(pb, annotation_prefix) + , alpha_g1(new libsnark::G1_variable( + pb, FMT(annotation_prefix, " alpha_g1"))) + , beta_g2(new libsnark::G2_variable( + pb, FMT(annotation_prefix, " beta_g2"))) + , delta_g2(new libsnark::G2_variable( + pb, FMT(annotation_prefix, " delta_g2"))) + , encoded_ABC_base(new libsnark::G1_variable( + pb, FMT(annotation_prefix, " encoded_ABC_base"))) , all_bits(all_bits) , input_size(input_size) { -#ifndef NDEBUG - // alpha_g1, ABC_g1 - const size_t num_G1 = 1 + (input_size + 1); - // beta_g2, delta_g2 - const size_t num_G2 = 2; -#endif - - assert( - all_bits.size() == - (libsnark::G1_variable::size_in_bits() * num_G1 + - libsnark::G2_variable::size_in_bits() * num_G2)); - - this->alpha_g1.reset(new libsnark::G1_variable( - pb, FMT(annotation_prefix, " alpha_g1"))); - this->beta_g2.reset( - new libsnark::G2_variable(pb, FMT(annotation_prefix, " beta_g2"))); - this->delta_g2.reset(new libsnark::G2_variable( - pb, FMT(annotation_prefix, " delta_g2"))); - - all_G1_vars = {this->alpha_g1}; - all_G2_vars = {this->beta_g2, this->delta_g2}; - - this->ABC_g1.resize(input_size); - this->encoded_ABC_base.reset(new libsnark::G1_variable( - pb, FMT(annotation_prefix, " encoded_ABC_base"))); - this->all_G1_vars.emplace_back(this->encoded_ABC_base); - + assert(all_bits.size() == size_in_bits(input_size)); + + // Populate all_vars with all elements. + all_vars.insert( + all_vars.end(), alpha_g1->all_vars.begin(), alpha_g1->all_vars.end()); + all_vars.insert( + all_vars.end(), beta_g2->all_vars.begin(), beta_g2->all_vars.end()); + all_vars.insert( + all_vars.end(), delta_g2->all_vars.begin(), delta_g2->all_vars.end()); + all_vars.insert( + all_vars.end(), + encoded_ABC_base->all_vars.begin(), + encoded_ABC_base->all_vars.end()); + + // Allocate variables for ABC_g1 elements (and add to all_vars list) + ABC_g1.reserve(input_size); for (size_t i = 0; i < input_size; ++i) { - this->ABC_g1[i].reset(new libsnark::G1_variable( + ABC_g1.emplace_back(new libsnark::G1_variable( pb, FMT(annotation_prefix, " ABC_g1[%zu]", i))); - all_G1_vars.emplace_back(this->ABC_g1[i]); - } - - for (auto &G1_var : all_G1_vars) { - all_vars.insert( - all_vars.end(), G1_var->all_vars.begin(), G1_var->all_vars.end()); - } - - for (auto &G2_var : all_G2_vars) { + const libsnark::G1_variable &ivar = *(ABC_g1.back()); all_vars.insert( - all_vars.end(), G2_var->all_vars.begin(), G2_var->all_vars.end()); + all_vars.end(), ivar.all_vars.begin(), ivar.all_vars.end()); } - - assert(all_G1_vars.size() == num_G1); - assert(all_G2_vars.size() == num_G2); assert( - all_vars.size() == - (num_G1 * libsnark::G1_variable::num_variables() + - num_G2 * libsnark::G2_variable::num_variables())); + all_vars.size() == size_in_bits(input_size) / FieldT::size_in_bits()); packer.reset(new libsnark::multipacking_gadget( pb, @@ -175,28 +159,13 @@ template void r1cs_gg_ppzksnark_verification_key_variable::generate_r1cs_witness( const libsnark::r1cs_gg_ppzksnark_verification_key> &vk) { - std::vector>> G1_elems; - std::vector>> G2_elems; - - G1_elems = {vk.alpha_g1}; - G2_elems = {vk.beta_g2, vk.delta_g2}; - - assert(vk.ABC_g1.rest.indices.size() == input_size); - G1_elems.emplace_back(vk.ABC_g1.first); + alpha_g1->generate_r1cs_witness(vk.alpha_g1); + beta_g2->generate_r1cs_witness(vk.beta_g2); + delta_g2->generate_r1cs_witness(vk.delta_g2); + encoded_ABC_base->generate_r1cs_witness(vk.ABC_g1.first); for (size_t i = 0; i < input_size; ++i) { assert(vk.ABC_g1.rest.indices[i] == i); - G1_elems.emplace_back(vk.ABC_g1.rest.values[i]); - } - - assert(G1_elems.size() == all_G1_vars.size()); - assert(G2_elems.size() == all_G2_vars.size()); - - for (size_t i = 0; i < G1_elems.size(); ++i) { - all_G1_vars[i]->generate_r1cs_witness(G1_elems[i]); - } - - for (size_t i = 0; i < G2_elems.size(); ++i) { - all_G2_vars[i]->generate_r1cs_witness(G2_elems[i]); + ABC_g1[i]->generate_r1cs_witness(vk.ABC_g1.rest.values[i]); } packer->generate_r1cs_witness_from_packed(); @@ -223,18 +192,8 @@ size_t r1cs_gg_ppzksnark_verification_key_variable::size_in_bits( { const size_t num_G1 = 1 + (input_size + 1); const size_t num_G2 = 2; - const size_t result = libsnark::G1_variable::size_in_bits() * num_G1 + - libsnark::G2_variable::size_in_bits() * num_G2; - printf( - "G1_size_in_bits = %zu, G2_size_in_bits = %zu\n", - libsnark::G1_variable::size_in_bits(), - libsnark::G2_variable::size_in_bits()); - printf( - "r1cs_gg_ppzksnark_verification_key_variable::size_in_bits(%zu) = " - "%zu\n", - input_size, - result); - return result; + return libsnark::G1_variable::size_in_bits() * num_G1 + + libsnark::G2_variable::size_in_bits() * num_G2; } template @@ -245,16 +204,16 @@ libff::bit_vector r1cs_gg_ppzksnark_verification_key_variable:: { typedef libff::Fr FieldT; - const size_t input_size_in_elts = r1cs_vk.ABC_g1.rest.indices.size(); + const size_t num_inputs_in_elts = r1cs_vk.ABC_g1.rest.indices.size(); const size_t vk_size_in_bits = r1cs_gg_ppzksnark_verification_key_variable::size_in_bits( - input_size_in_elts); + num_inputs_in_elts); libsnark::protoboard pb; libsnark::pb_variable_array vk_bits; vk_bits.allocate(pb, vk_size_in_bits, " vk_size_in_bits"); r1cs_gg_ppzksnark_verification_key_variable vk( - pb, vk_bits, input_size_in_elts, " translation_step_vk"); + pb, vk_bits, num_inputs_in_elts, " translation_step_vk"); vk.generate_r1cs_witness(r1cs_vk); return vk.get_bits(); From ecc4541c296210ee8e5d576002638279fb50b44c Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 6 Aug 2020 18:21:59 +0100 Subject: [PATCH 02/13] libzecale: cache protoboard on aggregator_circuit_wrapper (for efficiency and in preparation for extending the circuit) --- .../circuits/aggregator_circuit_wrapper.hpp | 10 ++-- .../circuits/aggregator_circuit_wrapper.tcc | 60 ++++++------------- 2 files changed, 25 insertions(+), 45 deletions(-) diff --git a/libzecale/circuits/aggregator_circuit_wrapper.hpp b/libzecale/circuits/aggregator_circuit_wrapper.hpp index 74278a59..09acd444 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.hpp +++ b/libzecale/circuits/aggregator_circuit_wrapper.hpp @@ -25,16 +25,18 @@ class aggregator_circuit_wrapper private: using wsnark = typename wverifierT::snark; - const size_t num_inputs_per_nested_proof; + const size_t _num_inputs_per_nested_proof; - // TODO: Cache the circuit to save reconstructing it at every call. + libsnark::protoboard> _pb; + aggregator_gadget + _aggregator_gadget; public: explicit aggregator_circuit_wrapper(const size_t inputs_per_nested_proof); typename wsnark::keypair generate_trusted_setup() const; - libsnark::protoboard> get_constraint_system() const; + const libsnark::protoboard> &get_constraint_system() const; /// Generate a proof and returns an extended proof extended_proof prove( @@ -42,7 +44,7 @@ class aggregator_circuit_wrapper const std::array< const libzeth::extended_proof *, NumProofs> &extended_proofs, - const typename wsnark::proving_key &aggregator_proving_key) const; + const typename wsnark::proving_key &aggregator_proving_key); }; } // namespace libzecale diff --git a/libzecale/circuits/aggregator_circuit_wrapper.tcc b/libzecale/circuits/aggregator_circuit_wrapper.tcc index 6426bc2f..acc10fe7 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.tcc +++ b/libzecale/circuits/aggregator_circuit_wrapper.tcc @@ -5,6 +5,8 @@ #ifndef __ZECALE_CORE_AGGREGATOR_CIRCUIT_WRAPPER_TCC__ #define __ZECALE_CORE_AGGREGATOR_CIRCUIT_WRAPPER_TCC__ +#include "libzecale/circuits/aggregator_circuit_wrapper.hpp" + #include using namespace libzeth; @@ -20,8 +22,11 @@ template< size_t NumProofs> aggregator_circuit_wrapper:: aggregator_circuit_wrapper(const size_t inputs_per_nested_proof) - : num_inputs_per_nested_proof(inputs_per_nested_proof) + : _num_inputs_per_nested_proof(inputs_per_nested_proof) + , _pb() + , _aggregator_gadget(_pb, _num_inputs_per_nested_proof) { + _aggregator_gadget.generate_r1cs_constraints(); } template< @@ -37,15 +42,8 @@ typename wverifierT::snark::keypair aggregator_circuit_wrapper< wverifierT, NumProofs>::generate_trusted_setup() const { - libsnark::protoboard> pb; - aggregator_gadget g( - pb, num_inputs_per_nested_proof); - g.generate_r1cs_constraints(); - // Generate a verification and proving key (trusted setup) - typename wsnark::keypair keypair = wsnark::generate_setup(pb); - - return keypair; + return wsnark::generate_setup(_pb); } template< @@ -54,18 +52,11 @@ template< typename nsnarkT, typename wverifierT, size_t NumProofs> -libsnark::protoboard> aggregator_circuit_wrapper< - nppT, - wppT, - nsnarkT, - wverifierT, - NumProofs>::get_constraint_system() const +const libsnark::protoboard> + &aggregator_circuit_wrapper:: + get_constraint_system() const { - libsnark::protoboard> pb; - aggregator_gadget g( - pb, num_inputs_per_nested_proof); - g.generate_r1cs_constraints(); - return pb; + return _pb; } template< @@ -85,41 +76,28 @@ libzeth::extended_proof aggregator_circuit_wra const std::array< const libzeth::extended_proof *, NumProofs> &extended_proofs, - const typename wsnark::proving_key &aggregator_proving_key) const + const typename wsnark::proving_key &aggregator_proving_key) { for (const libzeth::extended_proof *ep : extended_proofs) { - if (ep->get_primary_inputs().size() != num_inputs_per_nested_proof) { + if (ep->get_primary_inputs().size() != _num_inputs_per_nested_proof) { throw std::runtime_error( "attempt to aggregate proof with invalid number of inputs"); } } - libsnark::protoboard> pb; - - aggregator_gadget g( - pb, num_inputs_per_nested_proof); - g.generate_r1cs_constraints(); // We pass to the witness generation function the elements defined over the // "other curve". See: // https://github.com/scipr-lab/libsnark/blob/master/libsnark/gadgetlib1/gadgets/verifiers/r1cs_ppzksnark_verifier_gadget.hpp#L98 - g.generate_r1cs_witness(nested_vk, extended_proofs); + _aggregator_gadget.generate_r1cs_witness(nested_vk, extended_proofs); - bool is_valid_witness = pb.is_satisfied(); + bool is_valid_witness = _pb.is_satisfied(); std::cout << "*** [DEBUG] Satisfiability result: " << is_valid_witness << " ***" << std::endl; - typename wsnark::proof proof = - wsnark::generate_proof(pb, aggregator_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 - libzeth::extended_proof ext_proof = - extended_proof( - std::move(proof), std::move(primary_input)); - - return ext_proof; + // Return an extended_proof for the given witness. + return extended_proof( + wsnark::generate_proof(_pb, aggregator_proving_key), + _pb.primary_input()); } } // namespace libzecale From 1fa9b37b3d32ed46fa0867a23d802b0d41d302e9 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 10 Aug 2020 12:27:55 +0100 Subject: [PATCH 03/13] libzecale: tiny cleanup in groth16 verification key variable --- .../groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.tcc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.tcc b/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.tcc index a5e11867..6cab157b 100644 --- a/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.tcc +++ b/libzecale/circuits/groth16_verifier/r1cs_gg_ppzksnark_verifier_gadget.tcc @@ -205,9 +205,7 @@ libff::bit_vector r1cs_gg_ppzksnark_verification_key_variable:: typedef libff::Fr FieldT; const size_t num_inputs_in_elts = r1cs_vk.ABC_g1.rest.indices.size(); - const size_t vk_size_in_bits = - r1cs_gg_ppzksnark_verification_key_variable::size_in_bits( - num_inputs_in_elts); + const size_t vk_size_in_bits = size_in_bits(num_inputs_in_elts); libsnark::protoboard pb; libsnark::pb_variable_array vk_bits; From 06d05f35cc4e78ac579bae0673b5b1c9a9f9983f Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 10 Aug 2020 14:29:07 +0100 Subject: [PATCH 04/13] libzecale: fix type parameters for proof verification gadgets. test for mixing groth16 / pghr13. --- aggregator_server/aggregator_server.cpp | 19 ++-- .../circuits/aggregator_circuit_wrapper.hpp | 24 ++--- .../circuits/aggregator_circuit_wrapper.tcc | 60 ++++------- libzecale/circuits/aggregator_gadget.hpp | 21 ++-- libzecale/circuits/aggregator_gadget.tcc | 53 +++------ .../groth16_verifier_parameters.hpp | 2 +- .../pghr13_verifier_parameters.hpp | 2 +- .../aggregator/aggregator_dummy_test.cpp | 101 ++++++++++-------- .../tests/aggregator/aggregator_test.cpp | 55 +++++----- 9 files changed, 153 insertions(+), 184 deletions(-) diff --git a/aggregator_server/aggregator_server.cpp b/aggregator_server/aggregator_server.cpp index 1a58444b..36a574e6 100644 --- a/aggregator_server/aggregator_server.cpp +++ b/aggregator_server/aggregator_server.cpp @@ -51,28 +51,28 @@ using npp = libzecale::other_curve; #if defined(ZECALE_SNARK_PGHR13) #include #include -using wverifier = libzecale::pghr13_verifier_parameters; +using wsnark = libzeth::pghr13_snark; using wapi_handler = libzeth::pghr13_api_handler; -using nsnark = libzeth::pghr13_snark; +using nverifier = libzecale::pghr13_verifier_parameters; using napi_handler = libzeth::pghr13_api_handler; #elif defined(ZECALE_SNARK_GROTH16) #include #include -using wverifier = libzecale::groth16_verifier_parameters; +using wsnark = libzeth::groth16_snark; using wapi_handler = libzeth::groth16_api_handler; -using nsnark = libzeth::groth16_snark; +using nverifier = libzecale::groth16_verifier_parameters; using napi_handler = libzeth::groth16_api_handler; #else #error "ZECALE_SNARK_* variable not set to supported ZK snark" #endif -using wsnark = typename wverifier::snark; +using nsnark = typename nverifier::snark; static const size_t batch_size = 2; static const size_t num_inputs_per_nested_proof = 1; -using aggregator_circuit_wrapper = libzecale:: - aggregator_circuit_wrapper; +using aggregator_circuit_wrapper = + libzecale::aggregator_circuit_wrapper; /// The aggregator_server class inherits from the Aggregator service defined in /// the proto files, and provides an implementation of the service. @@ -401,9 +401,8 @@ int main(int argc, char **argv) npp::init_public_params(); wpp::init_public_params(); - libzecale:: - aggregator_circuit_wrapper - aggregator(num_inputs_per_nested_proof); + libzecale::aggregator_circuit_wrapper + aggregator(num_inputs_per_nested_proof); wsnark::keypair keypair = [&keypair_file, &aggregator]() { if (!keypair_file.empty()) { #ifdef ZKSNARK_GROTH16 diff --git a/libzecale/circuits/aggregator_circuit_wrapper.hpp b/libzecale/circuits/aggregator_circuit_wrapper.hpp index 09acd444..3961676c 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.hpp +++ b/libzecale/circuits/aggregator_circuit_wrapper.hpp @@ -6,6 +6,7 @@ #define __ZECALE_CORE_AGGREGATOR_CIRCUIT_WRAPPER_HPP__ #include "libzecale/circuits/aggregator_gadget.hpp" +#include "libzecale/circuits/pairing/pairing_params.hpp" #include @@ -14,37 +15,32 @@ using namespace libzeth; namespace libzecale { -template< - typename nppT, - typename wppT, - typename nsnarkT, - typename wverifierT, - size_t NumProofs> +template class aggregator_circuit_wrapper { private: - using wsnark = typename wverifierT::snark; + using npp = other_curve; + using nsnark = typename nverifierT::snark; const size_t _num_inputs_per_nested_proof; libsnark::protoboard> _pb; - aggregator_gadget - _aggregator_gadget; + aggregator_gadget _aggregator_gadget; public: explicit aggregator_circuit_wrapper(const size_t inputs_per_nested_proof); - typename wsnark::keypair generate_trusted_setup() const; + typename wsnarkT::keypair generate_trusted_setup() const; const libsnark::protoboard> &get_constraint_system() const; /// Generate a proof and returns an extended proof - extended_proof prove( - const typename nsnarkT::verification_key &nested_vk, + extended_proof prove( + const typename nsnark::verification_key &nested_vk, const std::array< - const libzeth::extended_proof *, + const libzeth::extended_proof *, NumProofs> &extended_proofs, - const typename wsnark::proving_key &aggregator_proving_key); + const typename wsnarkT::proving_key &aggregator_proving_key); }; } // namespace libzecale diff --git a/libzecale/circuits/aggregator_circuit_wrapper.tcc b/libzecale/circuits/aggregator_circuit_wrapper.tcc index acc10fe7..4d5399d5 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.tcc +++ b/libzecale/circuits/aggregator_circuit_wrapper.tcc @@ -14,13 +14,8 @@ using namespace libzeth; namespace libzecale { -template< - typename nppT, - typename wppT, - typename nsnarkT, - typename wverifierT, - size_t NumProofs> -aggregator_circuit_wrapper:: +template +aggregator_circuit_wrapper:: aggregator_circuit_wrapper(const size_t inputs_per_nested_proof) : _num_inputs_per_nested_proof(inputs_per_nested_proof) , _pb() @@ -29,56 +24,39 @@ aggregator_circuit_wrapper:: _aggregator_gadget.generate_r1cs_constraints(); } -template< - typename nppT, - typename wppT, - typename nsnarkT, - typename wverifierT, - size_t NumProofs> -typename wverifierT::snark::keypair aggregator_circuit_wrapper< - nppT, +template +typename wsnarkT::keypair aggregator_circuit_wrapper< wppT, - nsnarkT, - wverifierT, + wsnarkT, + nverifierT, NumProofs>::generate_trusted_setup() const { // Generate a verification and proving key (trusted setup) - return wsnark::generate_setup(_pb); + return wsnarkT::generate_setup(_pb); } -template< - typename nppT, - typename wppT, - typename nsnarkT, - typename wverifierT, - size_t NumProofs> +template const libsnark::protoboard> - &aggregator_circuit_wrapper:: + &aggregator_circuit_wrapper:: get_constraint_system() const { return _pb; } -template< - typename nppT, - typename wppT, - typename nsnarkT, - typename wverifierT, - size_t NumProofs> -libzeth::extended_proof aggregator_circuit_wrapper< - nppT, +template +libzeth::extended_proof aggregator_circuit_wrapper< wppT, - nsnarkT, - wverifierT, + wsnarkT, + nverifierT, NumProofs>:: prove( - const typename nsnarkT::verification_key &nested_vk, + const typename nsnark::verification_key &nested_vk, const std::array< - const libzeth::extended_proof *, + const libzeth::extended_proof *, NumProofs> &extended_proofs, - const typename wsnark::proving_key &aggregator_proving_key) + const typename wsnarkT::proving_key &aggregator_proving_key) { - for (const libzeth::extended_proof *ep : extended_proofs) { + for (const libzeth::extended_proof *ep : extended_proofs) { if (ep->get_primary_inputs().size() != _num_inputs_per_nested_proof) { throw std::runtime_error( "attempt to aggregate proof with invalid number of inputs"); @@ -95,8 +73,8 @@ libzeth::extended_proof aggregator_circuit_wra << " ***" << std::endl; // Return an extended_proof for the given witness. - return extended_proof( - wsnark::generate_proof(_pb, aggregator_proving_key), + return extended_proof( + wsnarkT::generate_proof(_pb, aggregator_proving_key), _pb.primary_input()); } diff --git a/libzecale/circuits/aggregator_gadget.hpp b/libzecale/circuits/aggregator_gadget.hpp index a7d0055e..980bd9ed 100644 --- a/libzecale/circuits/aggregator_gadget.hpp +++ b/libzecale/circuits/aggregator_gadget.hpp @@ -5,6 +5,8 @@ #ifndef __ZECALE_CIRCUITS_AGGREGATOR_GADGET_HPP_ #define __ZECALE_CIRCUITS_AGGREGATOR_GADGET_HPP_ +#include "libzecale/circuits/pairing/pairing_params.hpp" + #include #include #include @@ -27,19 +29,16 @@ namespace libzecale /// In order to aggregate proofs, we require that the base field of the curve /// used in the nested proof (nppT here) be the scalar field for the wrapping /// pairing (wppT). -template< - typename nppT, - typename wppT, - typename nsnarkT, - typename wverifierT, - size_t NumProofs> +template class aggregator_gadget : libsnark::gadget> { private: - using verifier_gadget = typename wverifierT::verifier_gadget; - using proof_variable_gadget = typename wverifierT::proof_variable_gadget; + using npp = other_curve; + using nsnark = typename nverifierT::snark; + using verifier_gadget = typename nverifierT::verifier_gadget; + using proof_variable_gadget = typename nverifierT::proof_variable_gadget; using verification_key_variable_gadget = - typename wverifierT::verification_key_variable_gadget; + typename nverifierT::verification_key_variable_gadget; using input_packing_gadget = libsnark::multipacking_gadget>; const size_t num_inputs_per_nested_proof; @@ -94,9 +93,9 @@ class aggregator_gadget : libsnark::gadget> /// Set the wppT scalar variables based on the nested verification key, /// proofs and inputs in nppT. void generate_r1cs_witness( - const typename nsnarkT::verification_key &in_nested_vk, + const typename nsnark::verification_key &in_nested_vk, const std::array< - const libzeth::extended_proof *, + const libzeth::extended_proof *, NumProofs> &in_extended_proofs); }; diff --git a/libzecale/circuits/aggregator_gadget.tcc b/libzecale/circuits/aggregator_gadget.tcc index 257d6886..7cb6d1ba 100644 --- a/libzecale/circuits/aggregator_gadget.tcc +++ b/libzecale/circuits/aggregator_gadget.tcc @@ -10,17 +10,11 @@ namespace libzecale { -template< - typename nppT, - typename wppT, - typename nsnarkT, - typename wverifierT, - size_t NumProofs> -aggregator_gadget:: - aggregator_gadget( - libsnark::protoboard> &pb, - const size_t inputs_per_nested_proof, - const std::string &annotation_prefix) +template +aggregator_gadget::aggregator_gadget( + libsnark::protoboard> &pb, + const size_t inputs_per_nested_proof, + const std::string &annotation_prefix) : libsnark::gadget>(pb, annotation_prefix) , num_inputs_per_nested_proof(inputs_per_nested_proof) { @@ -32,7 +26,7 @@ aggregator_gadget:: // // TODO: if num_bits are equal then also check that `libff::Fr::mod` // <= `libff::Fr::num_bits`. - assert(libff::Fr::num_bits <= libff::Fr::num_bits); + assert(libff::Fr::num_bits <= libff::Fr::num_bits); // TODO: allocations of these "public" variables should happen outside of // the gadget. @@ -57,7 +51,7 @@ aggregator_gadget:: // Allocate the bit representation of the public inputs and initialize the // input packers. - const size_t num_bits_per_input = libff::Fr::size_in_bits(); + const size_t num_bits_per_input = libff::Fr::size_in_bits(); const size_t num_input_bits_per_nested_proof = num_inputs_per_nested_proof * num_bits_per_input; for (size_t i = 0; i < NumProofs; i++) { @@ -109,21 +103,15 @@ aggregator_gadget:: pb, *nested_vk, nested_primary_inputs_bits[i], - libff::Fr::size_in_bits(), + libff::Fr::size_in_bits(), *nested_proofs[i], nested_proofs_results[i], FMT(this->annotation_prefix, " verifiers[%zu]", i))); } } -template< - typename nppT, - typename wppT, - typename nsnarkT, - typename wverifierT, - size_t NumProofs> -void aggregator_gadget:: - generate_r1cs_constraints() +template +void aggregator_gadget::generate_r1cs_constraints() { // Generate constraints for the verification key nested_vk->generate_r1cs_constraints(true); // ensure bitness @@ -137,18 +125,11 @@ void aggregator_gadget:: } } -template< - typename nppT, - typename wppT, - typename nsnarkT, - typename wverifierT, - size_t NumProofs> -void aggregator_gadget:: - generate_r1cs_witness( - const typename nsnarkT::verification_key &in_nested_vk, - const std::array< - const libzeth::extended_proof *, - NumProofs> &in_extended_proofs) +template +void aggregator_gadget::generate_r1cs_witness( + const typename nsnark::verification_key &in_nested_vk, + const std::array *, NumProofs> + &in_extended_proofs) { // Witness the VK nested_vk->generate_r1cs_witness(in_nested_vk); @@ -163,11 +144,11 @@ void aggregator_gadget:: // populate `nested_primary_inputs_bits`, andn then the // `nested_primary_input_packers` are used to convert to variables of // the circuit (elements of libff::Fr). - const libsnark::r1cs_primary_input> + const libsnark::r1cs_primary_input> &other_curve_primary_inputs = in_extended_proofs[i]->get_primary_inputs(); const libff::bit_vector input_bits = - libff::convert_field_element_vector_to_bit_vector>( + libff::convert_field_element_vector_to_bit_vector>( other_curve_primary_inputs); nested_primary_inputs_bits[i].fill_with_bits(this->pb, input_bits); nested_primary_input_packers[i]->generate_r1cs_witness_from_bits(); diff --git a/libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp b/libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp index b8a2f791..301f5c4a 100644 --- a/libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp +++ b/libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp @@ -16,7 +16,7 @@ namespace libzecale template class groth16_verifier_parameters { public: - using snark = libzeth::groth16_snark; + using snark = libzeth::groth16_snark>; using verifier_gadget = r1cs_gg_ppzksnark_verifier_gadget; using proof_variable_gadget = r1cs_gg_ppzksnark_proof_variable; diff --git a/libzecale/circuits/pghr13_verifier/pghr13_verifier_parameters.hpp b/libzecale/circuits/pghr13_verifier/pghr13_verifier_parameters.hpp index 00d47fd3..185d3f39 100644 --- a/libzecale/circuits/pghr13_verifier/pghr13_verifier_parameters.hpp +++ b/libzecale/circuits/pghr13_verifier/pghr13_verifier_parameters.hpp @@ -14,7 +14,7 @@ namespace libzecale template class pghr13_verifier_parameters { public: - using snark = libzeth::pghr13_snark; + using snark = libzeth::pghr13_snark>; using verifier_gadget = libsnark::r1cs_ppzksnark_verifier_gadget; using proof_variable_gadget = libsnark::r1cs_ppzksnark_proof_variable; diff --git a/libzecale/tests/aggregator/aggregator_dummy_test.cpp b/libzecale/tests/aggregator/aggregator_dummy_test.cpp index a7ae143a..2ca06617 100644 --- a/libzecale/tests/aggregator/aggregator_dummy_test.cpp +++ b/libzecale/tests/aggregator/aggregator_dummy_test.cpp @@ -6,6 +6,7 @@ #include "libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp" #include "libzecale/circuits/pairing/bw6_761_pairing_params.hpp" #include "libzecale/circuits/pairing/mnt_pairing_params.hpp" +#include "libzecale/circuits/pghr13_verifier/pghr13_verifier_parameters.hpp" #include "libzecale/tests/circuits/dummy_application.hpp" #include @@ -39,20 +40,22 @@ void fp_from_fp( } template< - typename nppT, - typename nsnarkT, typename wppT, - typename wverifierT, + typename wsnarkT, + typename nverifierT, size_t batch_size> void test_aggregator_with_batch( - const typename nsnarkT::keypair &nkp, - const proof_batch &batch, - const typename wverifierT::snark::keypair &wkeypair, - aggregator_circuit_wrapper + const typename nverifierT::snark::keypair &nkp, + const proof_batch< + libzecale::other_curve, + typename nverifierT::snark, + batch_size> &batch, + const typename wsnarkT::keypair &wkeypair, + aggregator_circuit_wrapper &aggregator, const std::array, batch_size> &expected_results) { - using wsnarkT = typename wverifierT::snark; + using npp = libzecale::other_curve; // Generate proof and check it. const libzeth::extended_proof wpf = @@ -70,7 +73,7 @@ void test_aggregator_with_batch( for (size_t proof_idx = 0; proof_idx < batch_size; ++proof_idx) { // Check that each input from the batch appears as expected in the // nested primary input list. - for (const libff::Fr &ninput : + for (const libff::Fr &ninput : batch[proof_idx]->get_primary_inputs()) { libff::Fr ninput_w; fp_from_fp(ninput_w, ninput); @@ -82,33 +85,33 @@ void test_aggregator_with_batch( } } -template +template void test_aggregate_dummy_application() { - using nppT = other_curve; - using wsnarkT = typename wverifierT::snark; + using npp = other_curve; + using nsnark = typename nverifierT::snark; static const size_t batch_size = 2; static const size_t public_inputs_per_proof = 1; // Nested keypair and proofs - test::dummy_app_wrapper dummy_app; - const typename nsnarkT::keypair nkp = dummy_app.generate_keypair(); + test::dummy_app_wrapper dummy_app; + const typename nsnark::keypair nkp = dummy_app.generate_keypair(); - const libzeth::extended_proof npf1 = + const libzeth::extended_proof npf1 = dummy_app.prove(5, nkp.pk); ASSERT_EQ(public_inputs_per_proof, npf1.get_primary_inputs().size()); std::cout << "NESTED_PROOF 1:\n"; npf1.write_json(std::cout); - const libzeth::extended_proof npf2 = + const libzeth::extended_proof npf2 = dummy_app.prove(9, nkp.pk); ASSERT_EQ(public_inputs_per_proof, npf2.get_primary_inputs().size()); std::cout << "\nNESTED_PROOF 2:\n"; npf2.write_json(std::cout); // Wrapper keypair - aggregator_circuit_wrapper + aggregator_circuit_wrapper aggregator(public_inputs_per_proof); const typename wsnarkT::keypair wkeypair = aggregator.generate_trusted_setup(); @@ -122,41 +125,41 @@ void test_aggregate_dummy_application() {libff::Fr::one(), libff::Fr::one()}); } -template +template void test_aggregate_dummy_application_with_invalid_proof() { - using nppT = other_curve; - using wsnarkT = typename wverifierT::snark; + using npp = other_curve; + using nsnark = typename nverifierT::snark; static const size_t batch_size = 2; static const size_t public_inputs_per_proof = 1; // Nested keypair and proofs - test::dummy_app_wrapper dummy_app; - const typename nsnarkT::keypair nkp = dummy_app.generate_keypair(); + test::dummy_app_wrapper dummy_app; + const typename nsnark::keypair nkp = dummy_app.generate_keypair(); - const libzeth::extended_proof npf1 = + const libzeth::extended_proof npf1 = dummy_app.prove(5, nkp.pk); ASSERT_EQ(public_inputs_per_proof, npf1.get_primary_inputs().size()); std::cout << "NESTED_PROOF 1:\n"; npf1.write_json(std::cout); - const libzeth::extended_proof npf2 = + const libzeth::extended_proof npf2 = dummy_app.prove(9, nkp.pk); ASSERT_EQ(public_inputs_per_proof, npf2.get_primary_inputs().size()); // Corrupt the 2nd proof by copying the proof and inputs and adjusting. - typename nsnarkT::proof proof2 = npf2.get_proof(); - libsnark::r1cs_primary_input> inputs2 = + typename nsnark::proof proof2 = npf2.get_proof(); + libsnark::r1cs_primary_input> inputs2 = npf2.get_primary_inputs(); - inputs2[0] = inputs2[0] + libff::Fr::one(); - const libzeth::extended_proof npf2_invalid = - libzeth::extended_proof(std::move(proof2), {inputs2[0]}); + inputs2[0] = inputs2[0] + libff::Fr::one(); + const libzeth::extended_proof npf2_invalid = + libzeth::extended_proof(std::move(proof2), {inputs2[0]}); std::cout << "\nNESTED_PROOF 2:\n"; npf2_invalid.write_json(std::cout); // Wrapper keypair - aggregator_circuit_wrapper + aggregator_circuit_wrapper aggregator(public_inputs_per_proof); const typename wsnarkT::keypair wkeypair = aggregator.generate_trusted_setup(); @@ -170,30 +173,40 @@ void test_aggregate_dummy_application_with_invalid_proof() {libff::Fr::one(), libff::Fr::zero()}); } -TEST(AggregatorTest, AggregateDummyApplicationMnt4Mnt6Groth16) +TEST(AggregatorTest, AggregateDummyApplicationMnt4Groth16Mnt6Groth16) { using wpp = libff::mnt6_pp; - using wverifier = groth16_verifier_parameters; - using npp = other_curve; - using nsnark = libzeth::groth16_snark; - test_aggregate_dummy_application(); + using wsnark = libzeth::groth16_snark; + using nverifier = groth16_verifier_parameters; + test_aggregate_dummy_application(); test_aggregate_dummy_application_with_invalid_proof< - nsnark, wpp, - wverifier>(); + wsnark, + nverifier>(); } -TEST(AggregatorTest, AggregateDummyApplicationBls12Bw6Groth16) +TEST(AggregatorTest, AggregateDummyApplicationBls12Groth16Bw6Groth16) { using wpp = libff::bw6_761_pp; - using wverifier = groth16_verifier_parameters; - using npp = other_curve; - using nsnark = libzeth::groth16_snark; - test_aggregate_dummy_application(); + using wsnark = groth16_snark; + using nverifier = groth16_verifier_parameters; + test_aggregate_dummy_application(); test_aggregate_dummy_application_with_invalid_proof< - nsnark, wpp, - wverifier>(); + wsnark, + nverifier>(); +} + +TEST(AggregatorTest, AggregateDummyApplicationBls12Groth16Bw6Pghr13) +{ + using wpp = libff::bw6_761_pp; + using wsnark = libzeth::pghr13_snark; + using nverifier = groth16_verifier_parameters; + test_aggregate_dummy_application(); + test_aggregate_dummy_application_with_invalid_proof< + wpp, + wsnark, + nverifier>(); } } // namespace diff --git a/libzecale/tests/aggregator/aggregator_test.cpp b/libzecale/tests/aggregator/aggregator_test.cpp index 44b57cf7..b1545725 100644 --- a/libzecale/tests/aggregator/aggregator_test.cpp +++ b/libzecale/tests/aggregator/aggregator_test.cpp @@ -194,19 +194,23 @@ libzeth::extended_proof generate_valid_zeth_proof( /// Here we use the same proof system to generate the "zeth proofs" /// and the Zecale proofs, but we could use different proofs systems. /// We use the same SNARK for simplicity. -template +template bool test_valid_aggregation_batch_proofs( - aggregator_circuit_wrapper + aggregator_circuit_wrapper &aggregator_prover, - typename wverifierT::snark::keypair &aggregator_keypair, - typename nsnarkT::keypair &zeth_keypair, - const std::array *, batch_size> - &nested_proofs) + typename wsnarkT::keypair &aggregator_keypair, + typename nverifierT::snark::keypair &zeth_keypair, + const std::array< + const libzeth::extended_proof< + libzecale::other_curve, + typename nverifierT::snark> *, + batch_size> &nested_proofs) { - using wsnark = typename wverifierT::snark; + using npp = libzecale::other_curve; + using nsnark = typename nverifierT::snark; libff::enter_block("Generate Aggregate proof", true); - libzeth::extended_proof ext_proof = aggregator_prover.prove( + libzeth::extended_proof ext_proof = aggregator_prover.prove( // This should cause a crash because the primary inputs are // packed in Zeth and are processed as unpacked here. zeth_keypair.vk, @@ -215,8 +219,8 @@ bool test_valid_aggregation_batch_proofs( libff::leave_block("Generate Aggregate proof", true); libff::enter_block("Verify Aggregate proof", true); - typename wsnark::verification_key vk = aggregator_keypair.vk; - bool res = wsnark::verify( + typename wsnarkT::verification_key vk = aggregator_keypair.vk; + bool res = wsnarkT::verify( ext_proof.get_primary_inputs(), ext_proof.get_proof(), vk); std::cout << "Does the proof verify? " << res << std::endl; libff::leave_block("Verify Aggregate proof", true); @@ -227,32 +231,33 @@ bool test_valid_aggregation_batch_proofs( return res; } -template +template void aggregator_test() { - using wsnark = typename wverifierT::snark; + using npp = libzecale::other_curve; + using nsnark = typename nverifierT::snark; std::cout << "[DEBUG] Entering test for the aggregator" << std::endl; // Run the trusted setup once for all tests, and keep the keypair in memory // for the duration of the tests libzeth::circuit_wrapper< - hash, - hashTree, - nppT, - nsnarkT, + hash, + hashTree, + npp, + nsnark, inputs_number, outputs_number, tree_depth> zeth_prover; std::cout << "[DEBUG] Before Zeth trusted setup" << std::endl; - typename nsnarkT::keypair zeth_keypair = + typename nsnark::keypair zeth_keypair = zeth_prover.generate_trusted_setup(); // Test to aggregate a single proof (i.e. generate a proof for the // verification of the proof) std::cout << "[DEBUG] Before gen Zeth proof" << std::endl; - libzeth::extended_proof valid_proof = + libzeth::extended_proof valid_proof = generate_valid_zeth_proof(zeth_prover, zeth_keypair); /* @@ -261,8 +266,8 @@ void aggregator_test() * invalid_proof.get_primary_input **/ - std::array *, batch_size> - batch = {&valid_proof, &valid_proof}; + std::array *, batch_size> batch = + {&valid_proof, &valid_proof}; // Make sure that the number of primary inputs matches the one we set in the // `aggregator_prover` circuit std::cout << "[DEBUG] nested_proofs[0].get_primary_inputs().size(): " @@ -272,10 +277,10 @@ void aggregator_test() std::cout << "[DEBUG] Before creation of the Aggregator prover" << std::endl; - aggregator_circuit_wrapper + aggregator_circuit_wrapper aggregator_prover(num_zeth_inputs); std::cout << "[DEBUG] Before gen Aggregator setup" << std::endl; - typename wsnark::keypair aggregator_keypair = + typename wsnarkT::keypair aggregator_keypair = aggregator_prover.generate_trusted_setup(); std::cout << "[DEBUG] Before first test" << std::endl; @@ -288,18 +293,16 @@ void aggregator_test() template void aggregator_test_groth16() { aggregator_test< - nppT, wppT, - libzeth::groth16_snark, + libzeth::groth16_snark, libzecale::groth16_verifier_parameters>(); } template void aggregator_test_pghr13() { aggregator_test< - nppT, wppT, - libzeth::pghr13_snark, + libzeth::pghr13_snark, libzecale::pghr13_verifier_parameters>(); } From f57e59733f87575698e855b4790b075067ae5f07 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 10 Aug 2020 12:47:07 +0100 Subject: [PATCH 05/13] libzecale: verification key hash gadget and tests --- .../circuits/verification_key_hash_gadget.hpp | 63 +++++++++ .../circuits/verification_key_hash_gadget.tcc | 77 +++++++++++ .../tests/circuits/dummy_application.hpp | 1 + .../verification_key_hash_gadget_test.cpp | 121 ++++++++++++++++++ 4 files changed, 262 insertions(+) create mode 100644 libzecale/circuits/verification_key_hash_gadget.hpp create mode 100644 libzecale/circuits/verification_key_hash_gadget.tcc create mode 100644 libzecale/tests/circuits/verification_key_hash_gadget_test.cpp diff --git a/libzecale/circuits/verification_key_hash_gadget.hpp b/libzecale/circuits/verification_key_hash_gadget.hpp new file mode 100644 index 00000000..46432bd7 --- /dev/null +++ b/libzecale/circuits/verification_key_hash_gadget.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZECALE_CIRCUITS_VERIFICATION_KEY_HASH_GADGET_HPP__ +#define __ZECALE_CIRCUITS_VERIFICATION_KEY_HASH_GADGET_HPP__ + +#include +#include + +namespace libzecale +{ + +/// Gadget to produce the hash of a verification key for nested proofs. As with +/// generic hash gadgets, the boolean-ness of the input bits is not checked. +/// This should be performed by the verification_key_variable_gadget object. +/// +/// Note that the hash is produced from the concatenation of the unpadded bit +/// strings of the key elements. Therefore, there is no guarantee that the +/// input to the hash will be a whole number of bytes and threfore it may be +/// non-trivial to reproduce the hash on other platforms. A static function is +/// provided here to perform that computation. +template +class verification_key_hash_gadget : public libsnark::gadget> +{ +public: + using FieldT = libff::Fr; + using nsnark = typename nverifierT::snark; + using verification_key_variable = + typename nverifierT::verification_key_variable_gadget; + + /// Holder for the vk bits as input to the hash + libsnark::block_variable _vk_block; + + /// Holder for output bits + libsnark::digest_variable _vk_digest; + + /// Gadget to hash vk bits. + hashT _hash_gadget; + + /// Packer gadget to pack the output from _hash_gadget into a single field + /// element. + libsnark::packing_gadget _hash_packer; + + verification_key_hash_gadget( + libsnark::protoboard &pb, + verification_key_variable &verifcation_key, + libsnark::pb_variable &verification_key_hash, + const std::string &annotation); + void generate_r1cs_constraints(); + void generate_r1cs_witness(); + + // TODO: should not require the second parameter, but there is no generic + // method to extract the number of inputs from the verification key. + static FieldT compute_hash( + const typename nsnark::verification_key &vk, size_t num_inputs); +}; + +} // namespace libzecale + +#include "libzecale/circuits/verification_key_hash_gadget.tcc" + +#endif // __ZECALE_CIRCUITS_VERIFICATION_KEY_HASH_GADGET_HPP__ diff --git a/libzecale/circuits/verification_key_hash_gadget.tcc b/libzecale/circuits/verification_key_hash_gadget.tcc new file mode 100644 index 00000000..64aa9ffc --- /dev/null +++ b/libzecale/circuits/verification_key_hash_gadget.tcc @@ -0,0 +1,77 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZECALE_CIRCUITS_VERIFICAION_KEY_HASH_GADGET_TCC__ +#define __ZECALE_CIRCUITS_VERIFICAION_KEY_HASH_GADGET_TCC__ + +#include "libzecale/circuits/verification_key_hash_gadget.hpp" + +namespace libzecale +{ + +template +verification_key_hash_gadget:: + verification_key_hash_gadget( + libsnark::protoboard &pb, + verification_key_variable &verification_key, + libsnark::pb_variable &verification_key_hash, + const std::string &annotation_prefix) + : libsnark::gadget(pb, annotation_prefix) + , _vk_block( + pb, {verification_key.all_bits}, FMT(annotation_prefix, " _vk_block")) + , _vk_digest( + pb, hashT::get_digest_len(), FMT(annotation_prefix, " _vk_digest")) + , _hash_gadget( + pb, _vk_block, _vk_digest, FMT(annotation_prefix, " _hash_gadget")) + , _hash_packer( + pb, + _vk_digest.bits, + verification_key_hash, + FMT(annotation_prefix, " _vk_hash_packer")) +{ +} + +template +void verification_key_hash_gadget:: + generate_r1cs_constraints() +{ + _hash_gadget.generate_r1cs_constraints(); + _vk_digest.generate_r1cs_constraints(); + _hash_packer.generate_r1cs_constraints(false); +} + +template +void verification_key_hash_gadget:: + generate_r1cs_witness() +{ + _hash_gadget.generate_r1cs_witness(); + _hash_packer.generate_r1cs_witness_from_bits(); +} + +template +libff::Fr verification_key_hash_gadget:: + compute_hash(const typename nsnark::verification_key &vk, size_t num_inputs) +{ + const size_t num_bits = + nverifierT::verification_key_variable_gadget::size_in_bits(num_inputs); + + libsnark::protoboard pb; + libsnark::pb_variable> nvk_hash; + nvk_hash.allocate(pb, "nvk_hash"); + libsnark::pb_variable_array nvk_bits; + nvk_bits.allocate(pb, num_bits, "nvk_bits"); + typename nverifierT::verification_key_variable_gadget nvk( + pb, nvk_bits, num_inputs, "nvk"); + libzecale::verification_key_hash_gadget + nvk_hash_gadget(pb, nvk, nvk_hash, "nvk_hash_gadget"); + nvk.generate_r1cs_constraints(false); + nvk_hash_gadget.generate_r1cs_constraints(); + nvk.generate_r1cs_witness(vk); + nvk_hash_gadget.generate_r1cs_witness(); + return pb.val(nvk_hash); +} + +} // namespace libzecale + +#endif // __ZECALE_CIRCUITS_VERIFICAION_KEY_HASH_GADGET_TCC__ diff --git a/libzecale/tests/circuits/dummy_application.hpp b/libzecale/tests/circuits/dummy_application.hpp index 8106e9ed..64c37be0 100644 --- a/libzecale/tests/circuits/dummy_application.hpp +++ b/libzecale/tests/circuits/dummy_application.hpp @@ -39,6 +39,7 @@ template class dummy_app_wrapper { public: using FieldT = libff::Fr; + static const size_t num_primary_inputs = 1; libsnark::protoboard _pb; libsnark::pb_variable _a; diff --git a/libzecale/tests/circuits/verification_key_hash_gadget_test.cpp b/libzecale/tests/circuits/verification_key_hash_gadget_test.cpp new file mode 100644 index 00000000..cd4afbe8 --- /dev/null +++ b/libzecale/tests/circuits/verification_key_hash_gadget_test.cpp @@ -0,0 +1,121 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#include "libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp" +#include "libzecale/circuits/pairing/bw6_761_pairing_params.hpp" +#include "libzecale/circuits/verification_key_hash_gadget.hpp" +#include "libzecale/tests/circuits/dummy_application.hpp" + +#include +#include +#include +#include + +namespace +{ + +template +void verification_key_hash_test() +{ + using FieldT = libff::Fr; + using npp = libzecale::other_curve; + using nsnark = typename nverifierT::snark; + + libzecale::test::dummy_app_wrapper dummy_app; + const size_t num_inputs = + libzecale::test::dummy_app_wrapper::num_primary_inputs; + const typename nsnark::keypair nkeypair1 = dummy_app.generate_keypair(); + const typename nsnark::keypair nkeypair2 = dummy_app.generate_keypair(); + + const FieldT vk1_hash = libzecale::verification_key_hash_gadget< + wppT, + nverifierT, + hash_gadgetT>::compute_hash(nkeypair1.vk, num_inputs); + const FieldT vk2_hash = libzecale::verification_key_hash_gadget< + wppT, + nverifierT, + hash_gadgetT>::compute_hash(nkeypair2.vk, num_inputs); + + ASSERT_NE(vk1_hash, vk2_hash); +} + +template +void verification_key_hash_gadget_test() +{ + using FieldT = libff::Fr; + using npp = libzecale::other_curve; + using nsnark = typename nverifierT::snark; + + const size_t num_nested_inputs = + libzecale::test::dummy_app_wrapper::num_primary_inputs; + libzecale::test::dummy_app_wrapper dummy_app; + const typename nsnark::keypair nkeypair = dummy_app.generate_keypair(); + + // Compute the hash via the static compute method. + const FieldT nvk_hash_value = libzecale::verification_key_hash_gadget< + wppT, + nverifierT, + hash_gadgetT>::compute_hash(nkeypair.vk, num_nested_inputs); + + // Set up a protoboard with hash as primary input. + libsnark::protoboard pb; + + libsnark::pb_variable> nvk_hash; + nvk_hash.allocate(pb, "nvk_hash"); + pb.set_input_sizes(1); + + // Verification key and bits + const size_t num_bits = + nverifierT::verification_key_variable_gadget::size_in_bits( + num_nested_inputs); + std::cout << "VK variable requires " << std::to_string(num_bits) + << " bits.\n"; + libsnark::pb_variable_array nvk_bits; + nvk_bits.allocate(pb, num_bits, "nvk_bits"); + + typename nverifierT::verification_key_variable_gadget nvk( + pb, nvk_bits, num_nested_inputs, "nvk"); + + // Gadget to check the hash + libzecale::verification_key_hash_gadget + nvk_hash_gadget(pb, nvk, nvk_hash, "nvk_hash_gadget"); + + // Constraints + + nvk.generate_r1cs_constraints(true); + nvk_hash_gadget.generate_r1cs_constraints(); + + // Witness + + nvk.generate_r1cs_witness(nkeypair.vk); + nvk_hash_gadget.generate_r1cs_witness(); + + // Show final hash value in Fr. + + const libff::Fr hash_value = pb.val(nvk_hash); + std::cout << "\nVK hash value: "; + libzeth::field_element_write_json(hash_value, std::cout); + std::cout << "\n"; + + ASSERT_EQ(nvk_hash_value, hash_value); +} + +TEST(VerificationKeyHashTest, HashGadgetTest) +{ + using wpp = libff::bw6_761_pp; + verification_key_hash_gadget_test< + wpp, + libzecale::groth16_verifier_parameters, + libzeth::BLAKE2s_256>>(); +} + +} // namespace + +int main(int argc, char **argv) +{ + libff::bw6_761_pp::init_public_params(); + libff::bls12_377_pp::init_public_params(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From e6ff5decca0e9e2afa3e0da275ce0edc052a8b0a Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 11 Aug 2020 13:18:35 +0100 Subject: [PATCH 06/13] libzecale: move variable allocation and circuit control to the aggregator_circuit_wrapper --- .../circuits/aggregator_circuit_wrapper.hpp | 32 ++++++- .../circuits/aggregator_circuit_wrapper.tcc | 79 +++++++++++++--- libzecale/circuits/aggregator_gadget.hpp | 40 +++------ libzecale/circuits/aggregator_gadget.tcc | 90 ++++--------------- 4 files changed, 130 insertions(+), 111 deletions(-) diff --git a/libzecale/circuits/aggregator_circuit_wrapper.hpp b/libzecale/circuits/aggregator_circuit_wrapper.hpp index 3961676c..2c62806e 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.hpp +++ b/libzecale/circuits/aggregator_circuit_wrapper.hpp @@ -21,11 +21,41 @@ class aggregator_circuit_wrapper private: using npp = other_curve; using nsnark = typename nverifierT::snark; + using verification_key_variable_gadget = + typename nverifierT::verification_key_variable_gadget; + using proof_variable_gadget = typename nverifierT::proof_variable_gadget; const size_t _num_inputs_per_nested_proof; libsnark::protoboard> _pb; - aggregator_gadget _aggregator_gadget; + + /// (Primary) The nested primary inputs lie in the scalar field + /// `libff::Fr`, and must be represented as elements of + /// `libff::Fr` for use in the wrapper proof. + std::array>, NumProofs> + _nested_primary_inputs; + + /// (Primary) The array of the results of the verifiers. 1 meaning that the + /// nested proof is valid, 0 meaning it may not be valid. + std::array>, NumProofs> + _nested_proof_results; + + /// (Auxiliary) Verification key used to verify the nested proofs. Consists + /// of group elements of `nppT`, which again, can be represented using + /// elements in `libff::Fr`. + std::shared_ptr _nested_vk; + + /// (Auxiliary) The nested proofs (defined over `nppT`) to verify. As above, + /// these are verified by virtue of the fact that the base field for nppT is + /// the scalar field of wppT. These gadgets handle take a witness in the + /// form of a proof with group elements from nppT and represent them as + /// variables in the wppT scalar field. + /// (Variables are expected to be auxiliary inputs). + std::array, NumProofs> + _nested_proofs; + + std::shared_ptr> + _aggregator_gadget; public: explicit aggregator_circuit_wrapper(const size_t inputs_per_nested_proof); diff --git a/libzecale/circuits/aggregator_circuit_wrapper.tcc b/libzecale/circuits/aggregator_circuit_wrapper.tcc index 4d5399d5..d69571e5 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.tcc +++ b/libzecale/circuits/aggregator_circuit_wrapper.tcc @@ -17,11 +17,58 @@ namespace libzecale template aggregator_circuit_wrapper:: aggregator_circuit_wrapper(const size_t inputs_per_nested_proof) - : _num_inputs_per_nested_proof(inputs_per_nested_proof) - , _pb() - , _aggregator_gadget(_pb, _num_inputs_per_nested_proof) + : _num_inputs_per_nested_proof(inputs_per_nested_proof), _pb() { - _aggregator_gadget.generate_r1cs_constraints(); + // The order of allocation here is important as it determines which inputs + // are primary. + + // For each proof in a batch, allocate primary inputs and results. These + // are the primary inputs. Note: both inputs and results will be + // populated by the aggregator gadget. + for (size_t i = 0; i < NumProofs; i++) { + _nested_primary_inputs[i].allocate( + _pb, + _num_inputs_per_nested_proof, + FMT("", "_nested_primary_inputs_bits[%zu]", i)); + + _nested_proof_results[i].allocate( + _pb, FMT("", "_nested_proof_results[%zu]", i)); + } + + // Set the number of primary inputs. + const size_t total_primary_inputs = + NumProofs * (inputs_per_nested_proof + 1); + _pb.set_input_sizes(total_primary_inputs); + + // Allocate vk and the intermediate bit representation + const size_t vk_size_in_bits = + verification_key_variable_gadget::size_in_bits( + _num_inputs_per_nested_proof); + libsnark::pb_variable_array> nested_vk_bits; + nested_vk_bits.allocate(_pb, vk_size_in_bits, "nested_vk_bits"); + _nested_vk.reset(new verification_key_variable_gadget( + _pb, nested_vk_bits, _num_inputs_per_nested_proof, "_nested_vk")); + + // Allocate proof variables. + for (size_t i = 0; i < NumProofs; i++) { + _nested_proofs[i].reset( + new proof_variable_gadget(_pb, FMT("", "_nested_proofs[%zu]", i))); + } + + _aggregator_gadget.reset(new aggregator_gadget( + _pb, + *_nested_vk, + _nested_primary_inputs, + _nested_proofs, + _nested_proof_results, + "_aggregator_gadget")); + + // Initialize all constraints in the circuit. + _nested_vk->generate_r1cs_constraints(true); + for (size_t i = 0; i < NumProofs; ++i) { + _nested_proofs[i]->generate_r1cs_constraints(); + } + _aggregator_gadget->generate_r1cs_constraints(); } template @@ -56,21 +103,33 @@ libzeth::extended_proof aggregator_circuit_wrapper< NumProofs> &extended_proofs, const typename wsnarkT::proving_key &aggregator_proving_key) { - for (const libzeth::extended_proof *ep : extended_proofs) { - if (ep->get_primary_inputs().size() != _num_inputs_per_nested_proof) { + // Witness the proofs and construct the array of primary inputs (in npp). + // These will be used to populate _nested_primary_inputs. + std::array> *, NumProofs> + nested_inputs{}; + for (size_t i = 0; i < NumProofs; ++i) { + const libzeth::extended_proof &ep = *(extended_proofs[i]); + if (ep.get_primary_inputs().size() != _num_inputs_per_nested_proof) { throw std::runtime_error( "attempt to aggregate proof with invalid number of inputs"); } + + nested_inputs[i] = &ep.get_primary_inputs(); + _nested_proofs[i]->generate_r1cs_witness(ep.get_proof()); } - // We pass to the witness generation function the elements defined over the - // "other curve". See: - // https://github.com/scipr-lab/libsnark/blob/master/libsnark/gadgetlib1/gadgets/verifiers/r1cs_ppzksnark_verifier_gadget.hpp#L98 - _aggregator_gadget.generate_r1cs_witness(nested_vk, extended_proofs); + // Witness the verification key + _nested_vk->generate_r1cs_witness(nested_vk); + + // Pass the input values (in npp) to the aggregator gadget. + _aggregator_gadget->generate_r1cs_witness(nested_inputs); +#ifdef DEBUG + // Check the validity of the circuit. bool is_valid_witness = _pb.is_satisfied(); std::cout << "*** [DEBUG] Satisfiability result: " << is_valid_witness << " ***" << std::endl; +#endif // Return an extended_proof for the given witness. return extended_proof( diff --git a/libzecale/circuits/aggregator_gadget.hpp b/libzecale/circuits/aggregator_gadget.hpp index 980bd9ed..1bc1b317 100644 --- a/libzecale/circuits/aggregator_gadget.hpp +++ b/libzecale/circuits/aggregator_gadget.hpp @@ -43,20 +43,10 @@ class aggregator_gadget : libsnark::gadget> const size_t num_inputs_per_nested_proof; - /// The nested primary inputs lie in the scalar field `libff::Fr`, - /// and must be represented as elements of `libff::Fr` for use in the - /// wrapper proof. This gadget assumes that libff::Fr can be - /// represented as a single `libff::Fr`, and internally asserts this. - /// (Expected to be primary inputs to the wrapping statement). + // Required in order to generate the bit strings from witness value. std::array>, NumProofs> nested_primary_inputs; - /// The array of the results of the verifiers. 1 meaning that the nested - /// proof is valid, 0 meaning it may not be valid. (Expected to be a - /// primary inputs to the wrapping statement). - std::array>, NumProofs> - nested_proofs_results; - /// The binary representation of inputs to the nested Fr inputs. Each /// entry is the concatenation of all bits of the inputs to the a single /// nested proof. (Expected to be an auxiliary input). @@ -67,35 +57,29 @@ class aggregator_gadget : libsnark::gadget> std::vector> nested_primary_input_packers; - /// The nested proofs (defined over `nppT`) to verify. As above, these are - /// verified by virtue of the fact that the base field for nppT is the - /// scalar field of wppT. These gadgets take a witness in the form of a - /// proof with group elements from nppT and represent them as variables in - /// the wppT scalar field. (Variables are expected to be auxiliary inputs). - std::array, NumProofs> nested_proofs; - - /// (Nested) verification key used to verify the nested proofs. Consists of - /// group elements of `nppT`, which again, can be represented using - /// elements in `libff::Fr`. - std::shared_ptr nested_vk; - - /// Gadgets that verify the proofs and inputs against nested_vk. + // Gadgets that verify the proofs and inputs against nested_vk. std::array, NumProofs> verifiers; public: aggregator_gadget( libsnark::protoboard> &pb, - const size_t inputs_per_nested_proof, - const std::string &annotation_prefix = "aggregator_gadget"); + const verification_key_variable_gadget &vk, + const std::array< + libsnark::pb_variable_array>, + NumProofs> &inputs, + const std::array, NumProofs> + &proofs, + const std::array>, NumProofs> + &proof_results, + const std::string &annotation_prefix); void generate_r1cs_constraints(); /// Set the wppT scalar variables based on the nested verification key, /// proofs and inputs in nppT. void generate_r1cs_witness( - const typename nsnark::verification_key &in_nested_vk, const std::array< - const libzeth::extended_proof *, + const libsnark::r1cs_primary_input> *, NumProofs> &in_extended_proofs); }; diff --git a/libzecale/circuits/aggregator_gadget.tcc b/libzecale/circuits/aggregator_gadget.tcc index 7cb6d1ba..3443668c 100644 --- a/libzecale/circuits/aggregator_gadget.tcc +++ b/libzecale/circuits/aggregator_gadget.tcc @@ -13,10 +13,16 @@ namespace libzecale template aggregator_gadget::aggregator_gadget( libsnark::protoboard> &pb, - const size_t inputs_per_nested_proof, + const verification_key_variable_gadget &vk, + const std::array>, NumProofs> + &inputs, + const std::array, NumProofs> &proofs, + const std::array>, NumProofs> + &proof_results, const std::string &annotation_prefix) : libsnark::gadget>(pb, annotation_prefix) - , num_inputs_per_nested_proof(inputs_per_nested_proof) + , num_inputs_per_nested_proof(vk.input_size) + , nested_primary_inputs(inputs) { // Assert that a single input of a nested proof (element of // libff::Fr) can be encoded in a single input of the wrapping proof @@ -28,27 +34,6 @@ aggregator_gadget::aggregator_gadget( // <= `libff::Fr::num_bits`. assert(libff::Fr::num_bits <= libff::Fr::num_bits); - // TODO: allocations of these "public" variables should happen outside of - // the gadget. - - // Allocate the primary inputs and results first (these are expected to be - // public). - for (size_t i = 0; i < NumProofs; i++) { - nested_primary_inputs[i].allocate( - pb, - num_inputs_per_nested_proof, - FMT(this->annotation_prefix, - " nested_primary_inputs_bits[%zu]", - i)); - - // Allocation of the results - nested_proofs_results[i].allocate( - pb, FMT(this->annotation_prefix, " nested_proofs_results[%zu]", i)); - } - - // TODO: Allocate (or accept) a variable to store the hash of the VK (to - // avoid proofs generated with a malicious keypair). - // Allocate the bit representation of the public inputs and initialize the // input packers. const size_t num_bits_per_input = libff::Fr::size_in_bits(); @@ -65,47 +50,20 @@ aggregator_gadget::aggregator_gadget( nested_primary_input_packers.emplace_back(new input_packing_gadget( pb, nested_primary_inputs_bits[i], - nested_primary_inputs[i], + inputs[i], num_bits_per_input, FMT(annotation_prefix, " nested_input_packers[%zu]", i))); } - // TODO: this should be done by the caller - not by a gadget. - - // Set the number of primary inputs. - const size_t total_primary_inputs = - NumProofs * (num_inputs_per_nested_proof + 1); - pb.set_input_sizes(total_primary_inputs); - - // The nested VK is interpreted as an array of bits. The number of primary - // inputs is required since it determines the size of the nested VK. - const size_t vk_size_in_bits = - verification_key_variable_gadget::size_in_bits( - num_inputs_per_nested_proof); - libsnark::pb_variable_array> nested_vk_bits; - nested_vk_bits.allocate( - pb, vk_size_in_bits, FMT(this->annotation_prefix, " vk_size_in_bits")); - nested_vk.reset(new verification_key_variable_gadget( - pb, - nested_vk_bits, - num_inputs_per_nested_proof, - FMT(this->annotation_prefix, " nested_vk"))); - - // Allocate proof variable gadgets - for (size_t i = 0; i < NumProofs; i++) { - nested_proofs[i].reset(new proof_variable_gadget( - pb, FMT(this->annotation_prefix, " nested_proofs[%zu]", i))); - } - // Initialize the verifier gadgets for (size_t i = 0; i < NumProofs; i++) { verifiers[i].reset(new verifier_gadget( pb, - *nested_vk, + vk, nested_primary_inputs_bits[i], libff::Fr::size_in_bits(), - *nested_proofs[i], - nested_proofs_results[i], + *proofs[i], + proof_results[i], FMT(this->annotation_prefix, " verifiers[%zu]", i))); } } @@ -113,40 +71,28 @@ aggregator_gadget::aggregator_gadget( template void aggregator_gadget::generate_r1cs_constraints() { - // Generate constraints for the verification key - nested_vk->generate_r1cs_constraints(true); // ensure bitness - // Generate constraints (including boolean-ness of the bit representations) // for input packers, nested proofs and the proof verifiers. for (size_t i = 0; i < NumProofs; i++) { nested_primary_input_packers[i]->generate_r1cs_constraints(true); - nested_proofs[i]->generate_r1cs_constraints(); verifiers[i]->generate_r1cs_constraints(); } } template void aggregator_gadget::generate_r1cs_witness( - const typename nsnark::verification_key &in_nested_vk, - const std::array *, NumProofs> - &in_extended_proofs) + const std::array< + const libsnark::r1cs_primary_input> *, + NumProofs> &nested_inputs) { - // Witness the VK - nested_vk->generate_r1cs_witness(in_nested_vk); - for (size_t i = 0; i < NumProofs; i++) { - // Witness the nested_proofs - nested_proofs[i]->generate_r1cs_witness( - in_extended_proofs[i]->get_proof()); - - // Witness the nested_prinary_inputs. This is done by input values are + // Witness the nested_primary_inputs. This is done by input values are // of type libff::Fr. They are converted to bit arrays to - // populate `nested_primary_inputs_bits`, andn then the + // populate `nested_primary_inputs_bits`, and the // `nested_primary_input_packers` are used to convert to variables of // the circuit (elements of libff::Fr). const libsnark::r1cs_primary_input> - &other_curve_primary_inputs = - in_extended_proofs[i]->get_primary_inputs(); + &other_curve_primary_inputs = *(nested_inputs[i]); const libff::bit_vector input_bits = libff::convert_field_element_vector_to_bit_vector>( other_curve_primary_inputs); From 2e53988b8059c8c01ecffac102ad45c602a1b2cd Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 24 Aug 2020 14:33:50 +0100 Subject: [PATCH 07/13] libzecale: verification key hash check in aggregator circuit --- aggregator_server/aggregator_server.cpp | 10 ++-- .../circuits/aggregator_circuit_wrapper.hpp | 39 +++++++++++++- .../circuits/aggregator_circuit_wrapper.tcc | 52 ++++++++++++++++--- .../aggregator/aggregator_dummy_test.cpp | 34 ++++++++++-- .../tests/aggregator/aggregator_test.cpp | 18 ++++--- 5 files changed, 131 insertions(+), 22 deletions(-) diff --git a/aggregator_server/aggregator_server.cpp b/aggregator_server/aggregator_server.cpp index 36a574e6..766e6ea7 100644 --- a/aggregator_server/aggregator_server.cpp +++ b/aggregator_server/aggregator_server.cpp @@ -67,12 +67,13 @@ using napi_handler = libzeth::groth16_api_handler; #endif using nsnark = typename nverifier::snark; +using hash = libzeth::BLAKE2s_256>; static const size_t batch_size = 2; static const size_t num_inputs_per_nested_proof = 1; -using aggregator_circuit_wrapper = - libzecale::aggregator_circuit_wrapper; +using aggregator_circuit_wrapper = libzecale:: + aggregator_circuit_wrapper; /// The aggregator_server class inherits from the Aggregator service defined in /// the proto files, and provides an implementation of the service. @@ -401,8 +402,9 @@ int main(int argc, char **argv) npp::init_public_params(); wpp::init_public_params(); - libzecale::aggregator_circuit_wrapper - aggregator(num_inputs_per_nested_proof); + libzecale:: + aggregator_circuit_wrapper + aggregator(num_inputs_per_nested_proof); wsnark::keypair keypair = [&keypair_file, &aggregator]() { if (!keypair_file.empty()) { #ifdef ZKSNARK_GROTH16 diff --git a/libzecale/circuits/aggregator_circuit_wrapper.hpp b/libzecale/circuits/aggregator_circuit_wrapper.hpp index 2c62806e..6d2bc119 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.hpp +++ b/libzecale/circuits/aggregator_circuit_wrapper.hpp @@ -7,6 +7,7 @@ #include "libzecale/circuits/aggregator_gadget.hpp" #include "libzecale/circuits/pairing/pairing_params.hpp" +#include "libzecale/circuits/verification_key_hash_gadget.hpp" #include @@ -15,7 +16,33 @@ using namespace libzeth; namespace libzecale { -template +/// Creates a circuit for creating a wrapping proof aggregating a batch of +/// nested proofs. Inputs are allocated as follows: +/// +/// +/// +/// ... +/// +/// +/// ... +/// ... +/// ... +/// +/// ... +/// +/// +/// +/// where: +/// N = NumProofs, +/// M = num_inputs_per_nested_proof, +/// input[i,j] = j-th input to i-th proof, +/// result[i] = result of i-th proof verification) +template< + typename wppT, + typename wsnarkT, + typename nverifierT, + typename hashT, + size_t NumProofs> class aggregator_circuit_wrapper { private: @@ -29,6 +56,11 @@ class aggregator_circuit_wrapper libsnark::protoboard> _pb; + /// (Primary) Variable holding the hash of the verification key for nested + /// proofs. Verified against the actual verification key values, by the + /// _nested_vk_hash_gadget. + libsnark::pb_variable> _nested_vk_hash; + /// (Primary) The nested primary inputs lie in the scalar field /// `libff::Fr`, and must be represented as elements of /// `libff::Fr` for use in the wrapper proof. @@ -54,6 +86,11 @@ class aggregator_circuit_wrapper std::array, NumProofs> _nested_proofs; + /// Gadget to check the hash of the nested verification key. + std::shared_ptr> + _nested_vk_hash_gadget; + + /// Gadget to aggregate proofs. std::shared_ptr> _aggregator_gadget; diff --git a/libzecale/circuits/aggregator_circuit_wrapper.tcc b/libzecale/circuits/aggregator_circuit_wrapper.tcc index d69571e5..07d355ec 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.tcc +++ b/libzecale/circuits/aggregator_circuit_wrapper.tcc @@ -14,14 +14,22 @@ using namespace libzeth; namespace libzecale { -template -aggregator_circuit_wrapper:: +template< + typename wppT, + typename wsnarkT, + typename nverifierT, + typename hashT, + size_t NumProofs> +aggregator_circuit_wrapper:: aggregator_circuit_wrapper(const size_t inputs_per_nested_proof) : _num_inputs_per_nested_proof(inputs_per_nested_proof), _pb() { // The order of allocation here is important as it determines which inputs // are primary. + // Input for hash of nested verification key. + _nested_vk_hash.allocate(_pb, FMT("", "_nested_vk_hash")); + // For each proof in a batch, allocate primary inputs and results. These // are the primary inputs. Note: both inputs and results will be // populated by the aggregator gadget. @@ -37,7 +45,7 @@ aggregator_circuit_wrapper:: // Set the number of primary inputs. const size_t total_primary_inputs = - NumProofs * (inputs_per_nested_proof + 1); + 1 + NumProofs * (inputs_per_nested_proof + 1); _pb.set_input_sizes(total_primary_inputs); // Allocate vk and the intermediate bit representation @@ -55,6 +63,15 @@ aggregator_circuit_wrapper:: new proof_variable_gadget(_pb, FMT("", "_nested_proofs[%zu]", i))); } + // Nested verification key hash gadget + _nested_vk_hash_gadget.reset( + new verification_key_hash_gadget( + _pb, + *_nested_vk, + _nested_vk_hash, + FMT("", "_nested_vk_hash_gadget"))); + + // Aggregator gadget _aggregator_gadget.reset(new aggregator_gadget( _pb, *_nested_vk, @@ -68,33 +85,51 @@ aggregator_circuit_wrapper:: for (size_t i = 0; i < NumProofs; ++i) { _nested_proofs[i]->generate_r1cs_constraints(); } + _nested_vk_hash_gadget->generate_r1cs_constraints(); _aggregator_gadget->generate_r1cs_constraints(); } -template +template< + typename wppT, + typename wsnarkT, + typename nverifierT, + typename hashT, + size_t NumProofs> typename wsnarkT::keypair aggregator_circuit_wrapper< wppT, wsnarkT, nverifierT, + hashT, NumProofs>::generate_trusted_setup() const { // Generate a verification and proving key (trusted setup) return wsnarkT::generate_setup(_pb); } -template +template< + typename wppT, + typename wsnarkT, + typename nverifierT, + typename hashT, + size_t NumProofs> const libsnark::protoboard> - &aggregator_circuit_wrapper:: + &aggregator_circuit_wrapper:: get_constraint_system() const { return _pb; } -template +template< + typename wppT, + typename wsnarkT, + typename nverifierT, + typename hashT, + size_t NumProofs> libzeth::extended_proof aggregator_circuit_wrapper< wppT, wsnarkT, nverifierT, + hashT, NumProofs>:: prove( const typename nsnark::verification_key &nested_vk, @@ -121,6 +156,9 @@ libzeth::extended_proof aggregator_circuit_wrapper< // Witness the verification key _nested_vk->generate_r1cs_witness(nested_vk); + // Witness hash of verification keypair + _nested_vk_hash_gadget->generate_r1cs_witness(); + // Pass the input values (in npp) to the aggregator gadget. _aggregator_gadget->generate_r1cs_witness(nested_inputs); diff --git a/libzecale/tests/aggregator/aggregator_dummy_test.cpp b/libzecale/tests/aggregator/aggregator_dummy_test.cpp index 2ca06617..577db827 100644 --- a/libzecale/tests/aggregator/aggregator_dummy_test.cpp +++ b/libzecale/tests/aggregator/aggregator_dummy_test.cpp @@ -10,9 +10,12 @@ #include "libzecale/tests/circuits/dummy_application.hpp" #include +#include using namespace libzecale; +template using hash = libzeth::BLAKE2s_256>; + namespace { @@ -45,14 +48,19 @@ template< typename nverifierT, size_t batch_size> void test_aggregator_with_batch( + const size_t num_inputs_per_nested_proof, const typename nverifierT::snark::keypair &nkp, const proof_batch< libzecale::other_curve, typename nverifierT::snark, batch_size> &batch, const typename wsnarkT::keypair &wkeypair, - aggregator_circuit_wrapper - &aggregator, + aggregator_circuit_wrapper< + wppT, + wsnarkT, + nverifierT, + hash, + batch_size> &aggregator, const std::array, batch_size> &expected_results) { using npp = libzecale::other_curve; @@ -70,6 +78,12 @@ void test_aggregator_with_batch( wpf.get_primary_inputs(); size_t winput_idx = 0; + // Check the nested vk hash + libff::Fr expect_nested_vk_hash = + verification_key_hash_gadget>:: + compute_hash(nkp.vk, num_inputs_per_nested_proof); + ASSERT_EQ(expect_nested_vk_hash, winputs[winput_idx++]); + for (size_t proof_idx = 0; proof_idx < batch_size; ++proof_idx) { // Check that each input from the batch appears as expected in the // nested primary input list. @@ -111,13 +125,19 @@ void test_aggregate_dummy_application() npf2.write_json(std::cout); // Wrapper keypair - aggregator_circuit_wrapper + aggregator_circuit_wrapper< + wppT, + wsnarkT, + nverifierT, + hash, + batch_size> aggregator(public_inputs_per_proof); const typename wsnarkT::keypair wkeypair = aggregator.generate_trusted_setup(); // Create and check a batched proof. test_aggregator_with_batch( + public_inputs_per_proof, nkp, {{&npf1, &npf2}}, wkeypair, @@ -159,13 +179,19 @@ void test_aggregate_dummy_application_with_invalid_proof() npf2_invalid.write_json(std::cout); // Wrapper keypair - aggregator_circuit_wrapper + aggregator_circuit_wrapper< + wppT, + wsnarkT, + nverifierT, + hash, + batch_size> aggregator(public_inputs_per_proof); const typename wsnarkT::keypair wkeypair = aggregator.generate_trusted_setup(); // Create and check a batched proof test_aggregator_with_batch( + public_inputs_per_proof, nkp, {{&npf1, &npf2_invalid}}, wkeypair, diff --git a/libzecale/tests/aggregator/aggregator_test.cpp b/libzecale/tests/aggregator/aggregator_test.cpp index b1545725..6e24ee77 100644 --- a/libzecale/tests/aggregator/aggregator_test.cpp +++ b/libzecale/tests/aggregator/aggregator_test.cpp @@ -196,8 +196,12 @@ libzeth::extended_proof generate_valid_zeth_proof( /// We use the same SNARK for simplicity. template bool test_valid_aggregation_batch_proofs( - aggregator_circuit_wrapper - &aggregator_prover, + aggregator_circuit_wrapper< + wppT, + wsnarkT, + nverifierT, + hash, + batch_size> &aggregator_prover, typename wsnarkT::keypair &aggregator_keypair, typename nverifierT::snark::keypair &zeth_keypair, const std::array< @@ -206,9 +210,6 @@ bool test_valid_aggregation_batch_proofs( typename nverifierT::snark> *, batch_size> &nested_proofs) { - using npp = libzecale::other_curve; - using nsnark = typename nverifierT::snark; - libff::enter_block("Generate Aggregate proof", true); libzeth::extended_proof ext_proof = aggregator_prover.prove( // This should cause a crash because the primary inputs are @@ -277,7 +278,12 @@ void aggregator_test() std::cout << "[DEBUG] Before creation of the Aggregator prover" << std::endl; - aggregator_circuit_wrapper + aggregator_circuit_wrapper< + wppT, + wsnarkT, + nverifierT, + hash, + batch_size> aggregator_prover(num_zeth_inputs); std::cout << "[DEBUG] Before gen Aggregator setup" << std::endl; typename wsnarkT::keypair aggregator_keypair = From 46696b122e1791b1b4ff615bf8a80a360e8fd216 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 24 Aug 2020 17:23:09 +0100 Subject: [PATCH 08/13] aggregator_server: small change to console output --- aggregator_server/aggregator_server.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aggregator_server/aggregator_server.cpp b/aggregator_server/aggregator_server.cpp index 766e6ea7..c0b21da1 100644 --- a/aggregator_server/aggregator_server.cpp +++ b/aggregator_server/aggregator_server.cpp @@ -239,10 +239,11 @@ class aggregator_server final : public zecale_proto::Aggregator::Service std::array *, batch_size> nested_proofs; for (size_t i = 0; i < batch_size; ++i) { + nested_proofs[i] = &batch[i].extended_proof(); + std::cout << "[DEBUG] got tx " << std::to_string(i) << " with ext proof:\n"; - batch[i].extended_proof().write_json(std::cout); - nested_proofs[i] = &batch[i].extended_proof(); + nested_proofs[i]->write_json(std::cout); } // Retrieve the nested verification key for this application. From 348fa2b7ae612be5943fe634cb78f8bf2d2e3526 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 24 Aug 2020 17:24:10 +0100 Subject: [PATCH 09/13] libzecale: delete invalid circuit wrapper operations - detect further memory bugs --- libzecale/circuits/aggregator_circuit_wrapper.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libzecale/circuits/aggregator_circuit_wrapper.hpp b/libzecale/circuits/aggregator_circuit_wrapper.hpp index 6d2bc119..2401e5c8 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.hpp +++ b/libzecale/circuits/aggregator_circuit_wrapper.hpp @@ -97,6 +97,11 @@ class aggregator_circuit_wrapper public: explicit aggregator_circuit_wrapper(const size_t inputs_per_nested_proof); + aggregator_circuit_wrapper(const aggregator_circuit_wrapper &other) = + delete; + const aggregator_circuit_wrapper &operator=( + const aggregator_circuit_wrapper &other) = delete; + typename wsnarkT::keypair generate_trusted_setup() const; const libsnark::protoboard> &get_constraint_system() const; From f5e1cd9cc88508b01f55ad2a0db6218310223c24 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 24 Aug 2020 18:16:04 +0100 Subject: [PATCH 10/13] aggregator_server: remove some object copies causing invalid proof generation --- aggregator_server/aggregator_server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aggregator_server/aggregator_server.cpp b/aggregator_server/aggregator_server.cpp index c0b21da1..9a38075e 100644 --- a/aggregator_server/aggregator_server.cpp +++ b/aggregator_server/aggregator_server.cpp @@ -83,10 +83,10 @@ class aggregator_server final : public zecale_proto::Aggregator::Service using application_pool = libzecale::application_pool; - aggregator_circuit_wrapper aggregator; + aggregator_circuit_wrapper &aggregator; // The keypair is the result of the setup for the aggregation circuit - wsnark::keypair keypair; + const wsnark::keypair &keypair; // The nested verification key is the vk used to verify the nested proofs std::map application_pools; From afec9923979defcd7c91756a61ec2a6ade73d041 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 1 Sep 2020 15:25:39 +0100 Subject: [PATCH 11/13] libzecale: use null hash in most cases (avoid huge testing times until we have an optimized hash) --- aggregator_server/aggregator_server.cpp | 4 +- libzecale/circuits/null_hash_gadget.hpp | 33 ++++++++++++ libzecale/circuits/null_hash_gadget.tcc | 37 +++++++++++++ .../aggregator/aggregator_dummy_test.cpp | 54 +++++++++---------- .../tests/aggregator/aggregator_test.cpp | 7 ++- 5 files changed, 101 insertions(+), 34 deletions(-) create mode 100644 libzecale/circuits/null_hash_gadget.hpp create mode 100644 libzecale/circuits/null_hash_gadget.tcc diff --git a/aggregator_server/aggregator_server.cpp b/aggregator_server/aggregator_server.cpp index 9a38075e..a4e6f5c4 100644 --- a/aggregator_server/aggregator_server.cpp +++ b/aggregator_server/aggregator_server.cpp @@ -6,6 +6,7 @@ // the corresponding pairing parameters type. #include "libzecale/circuits/aggregator_circuit_wrapper.hpp" +#include "libzecale/circuits/null_hash_gadget.hpp" #include "libzecale/core/application_pool.hpp" #include "libzecale/serialization/proto_utils.hpp" #include "zecale_config.h" @@ -19,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -67,7 +67,7 @@ using napi_handler = libzeth::groth16_api_handler; #endif using nsnark = typename nverifier::snark; -using hash = libzeth::BLAKE2s_256>; +using hash = libzecale::null_hash_gadget>; static const size_t batch_size = 2; static const size_t num_inputs_per_nested_proof = 1; diff --git a/libzecale/circuits/null_hash_gadget.hpp b/libzecale/circuits/null_hash_gadget.hpp new file mode 100644 index 00000000..1d380666 --- /dev/null +++ b/libzecale/circuits/null_hash_gadget.hpp @@ -0,0 +1,33 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZECALE_CIRCUIT_NULL_HASH_GADGET_HPP__ +#define __ZECALE_CIRCUIT_NULL_HASH_GADGET_HPP__ + +namespace libzecale +{ + +/// A trivial hash gadget that can be used as a parameter to the +/// aggregator_circuit_wrapper to disable verification key hashing during +/// development. +template class null_hash_gadget +{ +public: + null_hash_gadget( + libsnark::protoboard &pb, + const libsnark::block_variable &input, + const libsnark::digest_variable &output, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(const bool ensure_output_bitness = true); + void generate_r1cs_witness(); + + static size_t get_digest_len(); +}; + +} // namespace libzecale + +#include "libzecale/circuits/null_hash_gadget.tcc" + +#endif // __ZECALE_CIRCUIT_NULL_HASH_GADGET_HPP__ diff --git a/libzecale/circuits/null_hash_gadget.tcc b/libzecale/circuits/null_hash_gadget.tcc new file mode 100644 index 00000000..fa002ebc --- /dev/null +++ b/libzecale/circuits/null_hash_gadget.tcc @@ -0,0 +1,37 @@ +// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZECALE_CIRCUIT_NULL_GADGET_HPP__ +#define __ZECALE_CIRCUIT_NULL_GADGET_HPP__ + +namespace libzecale +{ + +template +null_hash_gadget::null_hash_gadget( + libsnark::protoboard & /* pb */, + const libsnark::block_variable & /* input */, + const libsnark::digest_variable & /* output */, + const std::string & /* annotation_prefix */) +{ +} + +template +void null_hash_gadget::generate_r1cs_constraints( + const bool /* ensure_output_bitness */) +{ +} + +template void null_hash_gadget::generate_r1cs_witness() +{ +} + +template size_t null_hash_gadget::get_digest_len() +{ + return 0; +} + +} // namespace libzecale + +#endif // __ZECALE_CIRCUIT_NULL_GADGET_HPP__ diff --git a/libzecale/tests/aggregator/aggregator_dummy_test.cpp b/libzecale/tests/aggregator/aggregator_dummy_test.cpp index 577db827..528436f9 100644 --- a/libzecale/tests/aggregator/aggregator_dummy_test.cpp +++ b/libzecale/tests/aggregator/aggregator_dummy_test.cpp @@ -4,6 +4,7 @@ #include "libzecale/circuits/aggregator_circuit_wrapper.hpp" #include "libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp" +#include "libzecale/circuits/null_hash_gadget.hpp" #include "libzecale/circuits/pairing/bw6_761_pairing_params.hpp" #include "libzecale/circuits/pairing/mnt_pairing_params.hpp" #include "libzecale/circuits/pghr13_verifier/pghr13_verifier_parameters.hpp" @@ -14,7 +15,9 @@ using namespace libzecale; -template using hash = libzeth::BLAKE2s_256>; +template using full_hash = libzeth::BLAKE2s_256>; +template +using null_hash = libzecale::null_hash_gadget>; namespace { @@ -46,6 +49,7 @@ template< typename wppT, typename wsnarkT, typename nverifierT, + typename hashT, size_t batch_size> void test_aggregator_with_batch( const size_t num_inputs_per_nested_proof, @@ -55,12 +59,8 @@ void test_aggregator_with_batch( typename nverifierT::snark, batch_size> &batch, const typename wsnarkT::keypair &wkeypair, - aggregator_circuit_wrapper< - wppT, - wsnarkT, - nverifierT, - hash, - batch_size> &aggregator, + aggregator_circuit_wrapper + &aggregator, const std::array, batch_size> &expected_results) { using npp = libzecale::other_curve; @@ -80,9 +80,10 @@ void test_aggregator_with_batch( // Check the nested vk hash libff::Fr expect_nested_vk_hash = - verification_key_hash_gadget>:: - compute_hash(nkp.vk, num_inputs_per_nested_proof); - ASSERT_EQ(expect_nested_vk_hash, winputs[winput_idx++]); + verification_key_hash_gadget::compute_hash( + nkp.vk, num_inputs_per_nested_proof); + ASSERT_EQ(expect_nested_vk_hash, winputs[winput_idx]); + ++winput_idx; for (size_t proof_idx = 0; proof_idx < batch_size; ++proof_idx) { // Check that each input from the batch appears as expected in the @@ -99,7 +100,7 @@ void test_aggregator_with_batch( } } -template +template void test_aggregate_dummy_application() { using npp = other_curve; @@ -125,12 +126,7 @@ void test_aggregate_dummy_application() npf2.write_json(std::cout); // Wrapper keypair - aggregator_circuit_wrapper< - wppT, - wsnarkT, - nverifierT, - hash, - batch_size> + aggregator_circuit_wrapper aggregator(public_inputs_per_proof); const typename wsnarkT::keypair wkeypair = aggregator.generate_trusted_setup(); @@ -145,7 +141,7 @@ void test_aggregate_dummy_application() {libff::Fr::one(), libff::Fr::one()}); } -template +template void test_aggregate_dummy_application_with_invalid_proof() { using npp = other_curve; @@ -179,12 +175,7 @@ void test_aggregate_dummy_application_with_invalid_proof() npf2_invalid.write_json(std::cout); // Wrapper keypair - aggregator_circuit_wrapper< - wppT, - wsnarkT, - nverifierT, - hash, - batch_size> + aggregator_circuit_wrapper aggregator(public_inputs_per_proof); const typename wsnarkT::keypair wkeypair = aggregator.generate_trusted_setup(); @@ -204,11 +195,12 @@ TEST(AggregatorTest, AggregateDummyApplicationMnt4Groth16Mnt6Groth16) using wpp = libff::mnt6_pp; using wsnark = libzeth::groth16_snark; using nverifier = groth16_verifier_parameters; - test_aggregate_dummy_application(); + test_aggregate_dummy_application>(); test_aggregate_dummy_application_with_invalid_proof< wpp, wsnark, - nverifier>(); + nverifier, + null_hash>(); } TEST(AggregatorTest, AggregateDummyApplicationBls12Groth16Bw6Groth16) @@ -216,11 +208,12 @@ TEST(AggregatorTest, AggregateDummyApplicationBls12Groth16Bw6Groth16) using wpp = libff::bw6_761_pp; using wsnark = groth16_snark; using nverifier = groth16_verifier_parameters; - test_aggregate_dummy_application(); + test_aggregate_dummy_application>(); test_aggregate_dummy_application_with_invalid_proof< wpp, wsnark, - nverifier>(); + nverifier, + null_hash>(); } TEST(AggregatorTest, AggregateDummyApplicationBls12Groth16Bw6Pghr13) @@ -228,11 +221,12 @@ TEST(AggregatorTest, AggregateDummyApplicationBls12Groth16Bw6Pghr13) using wpp = libff::bw6_761_pp; using wsnark = libzeth::pghr13_snark; using nverifier = groth16_verifier_parameters; - test_aggregate_dummy_application(); + test_aggregate_dummy_application>(); test_aggregate_dummy_application_with_invalid_proof< wpp, wsnark, - nverifier>(); + nverifier, + null_hash>(); } } // namespace diff --git a/libzecale/tests/aggregator/aggregator_test.cpp b/libzecale/tests/aggregator/aggregator_test.cpp index 6e24ee77..54deaf7a 100644 --- a/libzecale/tests/aggregator/aggregator_test.cpp +++ b/libzecale/tests/aggregator/aggregator_test.cpp @@ -4,6 +4,7 @@ #include "libzecale/circuits/aggregator_circuit_wrapper.hpp" #include "libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp" +#include "libzecale/circuits/null_hash_gadget.hpp" #include "libzecale/circuits/pairing/bw6_761_pairing_params.hpp" #include "libzecale/circuits/pairing/mnt_pairing_params.hpp" #include "libzecale/circuits/pghr13_verifier/pghr13_verifier_parameters.hpp" @@ -40,6 +41,8 @@ static const size_t batch_size = 2; // [Root, NullifierS(2), CommitmentS(2), h_sig, h_iS(2), Residual Field, // Element] static const size_t num_zeth_inputs = 9; +template +using nested_key_hash = libzecale::null_hash_gadget>; using namespace libzecale; @@ -200,7 +203,7 @@ bool test_valid_aggregation_batch_proofs( wppT, wsnarkT, nverifierT, - hash, + nested_key_hash, batch_size> &aggregator_prover, typename wsnarkT::keypair &aggregator_keypair, typename nverifierT::snark::keypair &zeth_keypair, @@ -282,7 +285,7 @@ void aggregator_test() wppT, wsnarkT, nverifierT, - hash, + nested_key_hash, batch_size> aggregator_prover(num_zeth_inputs); std::cout << "[DEBUG] Before gen Aggregator setup" << std::endl; From 4943f217e0c1b872fbc7cb6a50e83eb8d09b5223 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 28 Sep 2020 13:19:45 +0100 Subject: [PATCH 12/13] aggreagtor_server: check the number of inputs in incoming transactions --- aggregator_server/aggregator_server.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/aggregator_server/aggregator_server.cpp b/aggregator_server/aggregator_server.cpp index a4e6f5c4..4f3efc65 100644 --- a/aggregator_server/aggregator_server.cpp +++ b/aggregator_server/aggregator_server.cpp @@ -184,12 +184,17 @@ class aggregator_server final : public zecale_proto::Aggregator::Service application_pool *const app_pool = application_pools.at(transaction->application_name()); - // Add the application to the list of applications supported by - // the server. + // Sanity-check the transaction (number of inputs). const libzecale::transaction_to_aggregate tx = libzecale:: transaction_to_aggregate_from_proto( *transaction); + if (tx.extended_proof().get_primary_inputs().size() != + num_inputs_per_nested_proof) { + throw std::invalid_argument("invalid number of inputs"); + } + + // Add the proof to the pool for the named application. app_pool->add_tx(tx); std::cout << "[DEBUG] Registered tx with ext proof:\n"; From 8eb8fb48b084595a06f78a4fa889fabe68cb0a4c Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 29 Sep 2020 09:26:24 +0100 Subject: [PATCH 13/13] libzecale: rename aggregator_circuit_wrapper -> aggregator_circuit --- aggregator_server/aggregator_server.cpp | 18 ++++++++---------- ...cuit_wrapper.hpp => aggregator_circuit.hpp} | 17 ++++++++--------- ...cuit_wrapper.tcc => aggregator_circuit.tcc} | 18 +++++++++--------- libzecale/circuits/null_hash_gadget.hpp | 2 +- .../tests/aggregator/aggregator_dummy_test.cpp | 12 ++++++------ libzecale/tests/aggregator/aggregator_test.cpp | 6 +++--- 6 files changed, 35 insertions(+), 38 deletions(-) rename libzecale/circuits/{aggregator_circuit_wrapper.hpp => aggregator_circuit.hpp} (88%) rename libzecale/circuits/{aggregator_circuit_wrapper.tcc => aggregator_circuit.tcc} (90%) diff --git a/aggregator_server/aggregator_server.cpp b/aggregator_server/aggregator_server.cpp index 4f3efc65..32062b9b 100644 --- a/aggregator_server/aggregator_server.cpp +++ b/aggregator_server/aggregator_server.cpp @@ -5,7 +5,7 @@ // Read the zecale config, include the appropriate pairing selector and define // the corresponding pairing parameters type. -#include "libzecale/circuits/aggregator_circuit_wrapper.hpp" +#include "libzecale/circuits/aggregator_circuit.hpp" #include "libzecale/circuits/null_hash_gadget.hpp" #include "libzecale/core/application_pool.hpp" #include "libzecale/serialization/proto_utils.hpp" @@ -72,8 +72,8 @@ using hash = libzecale::null_hash_gadget>; static const size_t batch_size = 2; static const size_t num_inputs_per_nested_proof = 1; -using aggregator_circuit_wrapper = libzecale:: - aggregator_circuit_wrapper; +using aggregator_circuit = + libzecale::aggregator_circuit; /// The aggregator_server class inherits from the Aggregator service defined in /// the proto files, and provides an implementation of the service. @@ -83,7 +83,7 @@ class aggregator_server final : public zecale_proto::Aggregator::Service using application_pool = libzecale::application_pool; - aggregator_circuit_wrapper &aggregator; + aggregator_circuit &aggregator; // The keypair is the result of the setup for the aggregation circuit const wsnark::keypair &keypair; @@ -93,7 +93,7 @@ class aggregator_server final : public zecale_proto::Aggregator::Service public: explicit aggregator_server( - aggregator_circuit_wrapper &aggregator, const wsnark::keypair &keypair) + aggregator_circuit &aggregator, const wsnark::keypair &keypair) : aggregator(aggregator), keypair(keypair) { } @@ -317,8 +317,7 @@ void display_server_start_message() } static void RunServer( - aggregator_circuit_wrapper &aggregator, - const typename wsnark::keypair &keypair) + aggregator_circuit &aggregator, const typename wsnark::keypair &keypair) { // Listen for incoming connections on 0.0.0.0:50052 // TODO: Move this in a config file @@ -408,9 +407,8 @@ int main(int argc, char **argv) npp::init_public_params(); wpp::init_public_params(); - libzecale:: - aggregator_circuit_wrapper - aggregator(num_inputs_per_nested_proof); + libzecale::aggregator_circuit + aggregator(num_inputs_per_nested_proof); wsnark::keypair keypair = [&keypair_file, &aggregator]() { if (!keypair_file.empty()) { #ifdef ZKSNARK_GROTH16 diff --git a/libzecale/circuits/aggregator_circuit_wrapper.hpp b/libzecale/circuits/aggregator_circuit.hpp similarity index 88% rename from libzecale/circuits/aggregator_circuit_wrapper.hpp rename to libzecale/circuits/aggregator_circuit.hpp index 2401e5c8..19126e0a 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.hpp +++ b/libzecale/circuits/aggregator_circuit.hpp @@ -2,8 +2,8 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZECALE_CORE_AGGREGATOR_CIRCUIT_WRAPPER_HPP__ -#define __ZECALE_CORE_AGGREGATOR_CIRCUIT_WRAPPER_HPP__ +#ifndef __ZECALE_CORE_AGGREGATOR_CIRCUIT_HPP__ +#define __ZECALE_CORE_AGGREGATOR_CIRCUIT_HPP__ #include "libzecale/circuits/aggregator_gadget.hpp" #include "libzecale/circuits/pairing/pairing_params.hpp" @@ -43,7 +43,7 @@ template< typename nverifierT, typename hashT, size_t NumProofs> -class aggregator_circuit_wrapper +class aggregator_circuit { private: using npp = other_curve; @@ -95,12 +95,11 @@ class aggregator_circuit_wrapper _aggregator_gadget; public: - explicit aggregator_circuit_wrapper(const size_t inputs_per_nested_proof); + explicit aggregator_circuit(const size_t inputs_per_nested_proof); - aggregator_circuit_wrapper(const aggregator_circuit_wrapper &other) = + aggregator_circuit(const aggregator_circuit &other) = delete; + const aggregator_circuit &operator=(const aggregator_circuit &other) = delete; - const aggregator_circuit_wrapper &operator=( - const aggregator_circuit_wrapper &other) = delete; typename wsnarkT::keypair generate_trusted_setup() const; @@ -117,6 +116,6 @@ class aggregator_circuit_wrapper } // namespace libzecale -#include "aggregator_circuit_wrapper.tcc" +#include "aggregator_circuit.tcc" -#endif // __ZECALE_CORE_AGGREGATOR_CIRCUIT_WRAPPER_HPP__ +#endif // __ZECALE_CORE_AGGREGATOR_CIRCUIT_HPP__ diff --git a/libzecale/circuits/aggregator_circuit_wrapper.tcc b/libzecale/circuits/aggregator_circuit.tcc similarity index 90% rename from libzecale/circuits/aggregator_circuit_wrapper.tcc rename to libzecale/circuits/aggregator_circuit.tcc index 07d355ec..98812ebb 100644 --- a/libzecale/circuits/aggregator_circuit_wrapper.tcc +++ b/libzecale/circuits/aggregator_circuit.tcc @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#ifndef __ZECALE_CORE_AGGREGATOR_CIRCUIT_WRAPPER_TCC__ -#define __ZECALE_CORE_AGGREGATOR_CIRCUIT_WRAPPER_TCC__ +#ifndef __ZECALE_CORE_AGGREGATOR_CIRCUIT_TCC__ +#define __ZECALE_CORE_AGGREGATOR_CIRCUIT_TCC__ -#include "libzecale/circuits/aggregator_circuit_wrapper.hpp" +#include "libzecale/circuits/aggregator_circuit.hpp" #include @@ -20,8 +20,8 @@ template< typename nverifierT, typename hashT, size_t NumProofs> -aggregator_circuit_wrapper:: - aggregator_circuit_wrapper(const size_t inputs_per_nested_proof) +aggregator_circuit:: + aggregator_circuit(const size_t inputs_per_nested_proof) : _num_inputs_per_nested_proof(inputs_per_nested_proof), _pb() { // The order of allocation here is important as it determines which inputs @@ -95,7 +95,7 @@ template< typename nverifierT, typename hashT, size_t NumProofs> -typename wsnarkT::keypair aggregator_circuit_wrapper< +typename wsnarkT::keypair aggregator_circuit< wppT, wsnarkT, nverifierT, @@ -113,7 +113,7 @@ template< typename hashT, size_t NumProofs> const libsnark::protoboard> - &aggregator_circuit_wrapper:: + &aggregator_circuit:: get_constraint_system() const { return _pb; @@ -125,7 +125,7 @@ template< typename nverifierT, typename hashT, size_t NumProofs> -libzeth::extended_proof aggregator_circuit_wrapper< +libzeth::extended_proof aggregator_circuit< wppT, wsnarkT, nverifierT, @@ -177,4 +177,4 @@ libzeth::extended_proof aggregator_circuit_wrapper< } // namespace libzecale -#endif // __ZECALE_CORE_AGGREGATOR_CIRCUIT_WRAPPER_TCC__ +#endif // __ZECALE_CORE_AGGREGATOR_CIRCUIT_TCC__ diff --git a/libzecale/circuits/null_hash_gadget.hpp b/libzecale/circuits/null_hash_gadget.hpp index 1d380666..8d846d40 100644 --- a/libzecale/circuits/null_hash_gadget.hpp +++ b/libzecale/circuits/null_hash_gadget.hpp @@ -9,7 +9,7 @@ namespace libzecale { /// A trivial hash gadget that can be used as a parameter to the -/// aggregator_circuit_wrapper to disable verification key hashing during +/// aggregator_circuit to disable verification key hashing during /// development. template class null_hash_gadget { diff --git a/libzecale/tests/aggregator/aggregator_dummy_test.cpp b/libzecale/tests/aggregator/aggregator_dummy_test.cpp index 528436f9..ee0bf59b 100644 --- a/libzecale/tests/aggregator/aggregator_dummy_test.cpp +++ b/libzecale/tests/aggregator/aggregator_dummy_test.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzecale/circuits/aggregator_circuit_wrapper.hpp" +#include "libzecale/circuits/aggregator_circuit.hpp" #include "libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp" #include "libzecale/circuits/null_hash_gadget.hpp" #include "libzecale/circuits/pairing/bw6_761_pairing_params.hpp" @@ -59,7 +59,7 @@ void test_aggregator_with_batch( typename nverifierT::snark, batch_size> &batch, const typename wsnarkT::keypair &wkeypair, - aggregator_circuit_wrapper + aggregator_circuit &aggregator, const std::array, batch_size> &expected_results) { @@ -126,8 +126,8 @@ void test_aggregate_dummy_application() npf2.write_json(std::cout); // Wrapper keypair - aggregator_circuit_wrapper - aggregator(public_inputs_per_proof); + aggregator_circuit aggregator( + public_inputs_per_proof); const typename wsnarkT::keypair wkeypair = aggregator.generate_trusted_setup(); @@ -175,8 +175,8 @@ void test_aggregate_dummy_application_with_invalid_proof() npf2_invalid.write_json(std::cout); // Wrapper keypair - aggregator_circuit_wrapper - aggregator(public_inputs_per_proof); + aggregator_circuit aggregator( + public_inputs_per_proof); const typename wsnarkT::keypair wkeypair = aggregator.generate_trusted_setup(); diff --git a/libzecale/tests/aggregator/aggregator_test.cpp b/libzecale/tests/aggregator/aggregator_test.cpp index 54deaf7a..5ffac314 100644 --- a/libzecale/tests/aggregator/aggregator_test.cpp +++ b/libzecale/tests/aggregator/aggregator_test.cpp @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -#include "libzecale/circuits/aggregator_circuit_wrapper.hpp" +#include "libzecale/circuits/aggregator_circuit.hpp" #include "libzecale/circuits/groth16_verifier/groth16_verifier_parameters.hpp" #include "libzecale/circuits/null_hash_gadget.hpp" #include "libzecale/circuits/pairing/bw6_761_pairing_params.hpp" @@ -199,7 +199,7 @@ libzeth::extended_proof generate_valid_zeth_proof( /// We use the same SNARK for simplicity. template bool test_valid_aggregation_batch_proofs( - aggregator_circuit_wrapper< + aggregator_circuit< wppT, wsnarkT, nverifierT, @@ -281,7 +281,7 @@ void aggregator_test() std::cout << "[DEBUG] Before creation of the Aggregator prover" << std::endl; - aggregator_circuit_wrapper< + aggregator_circuit< wppT, wsnarkT, nverifierT,