diff --git a/libsnark/common/data_structures/sparse_vector.tcc b/libsnark/common/data_structures/sparse_vector.tcc index 2e299df2..d99241c4 100644 --- a/libsnark/common/data_structures/sparse_vector.tcc +++ b/libsnark/common/data_structures/sparse_vector.tcc @@ -16,6 +16,10 @@ #include +#ifdef MULTICORE +#include +#endif + #include namespace libsnark { @@ -180,9 +184,11 @@ std::pair > sparse_vector::accumulate(const typename std: const typename std::vector::const_iterator &it_end, const size_t offset) const { - // TODO: does not really belong here. +#ifdef MULTICORE + const size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env var or call omp_set_num_threads() +#else const size_t chunks = 1; - const bool use_multiexp = true; +#endif T accumulated_value = T::zero(); sparse_vector resulting_vector; @@ -215,11 +221,12 @@ std::pair > sparse_vector::accumulate(const typename std: #ifdef DEBUG libff::print_indent(); printf("doing multiexp for w_%zu ... w_%zu\n", indices[first_pos], indices[last_pos]); #endif - accumulated_value = accumulated_value + libff::multi_exp(values.begin() + first_pos, - values.begin() + last_pos + 1, - it_begin + (indices[first_pos] - offset), - it_begin + (indices[last_pos] - offset) + 1, - chunks, use_multiexp); + accumulated_value = accumulated_value + libff::multi_exp( + values.begin() + first_pos, + values.begin() + last_pos + 1, + it_begin + (indices[first_pos] - offset), + it_begin + (indices[last_pos] - offset) + 1, + chunks); } } else @@ -250,11 +257,12 @@ std::pair > sparse_vector::accumulate(const typename std: #ifdef DEBUG libff::print_indent(); printf("doing multiexp for w_%zu ... w_%zu\n", indices[first_pos], indices[last_pos]); #endif - accumulated_value = accumulated_value + libff::multi_exp(values.begin() + first_pos, - values.begin() + last_pos + 1, - it_begin + (indices[first_pos] - offset), - it_begin + (indices[last_pos] - offset) + 1, - chunks, use_multiexp); + accumulated_value = accumulated_value + libff::multi_exp( + values.begin() + first_pos, + values.begin() + last_pos + 1, + it_begin + (indices[first_pos] - offset), + it_begin + (indices[last_pos] - offset) + 1, + chunks); } return std::make_pair(accumulated_value, resulting_vector); diff --git a/libsnark/knowledge_commitment/kc_multiexp.hpp b/libsnark/knowledge_commitment/kc_multiexp.hpp index 34a2b53f..ec85c175 100644 --- a/libsnark/knowledge_commitment/kc_multiexp.hpp +++ b/libsnark/knowledge_commitment/kc_multiexp.hpp @@ -17,6 +17,8 @@ Will probably go away in more general exp refactoring. */ +#include + #include namespace libsnark { @@ -25,17 +27,13 @@ template knowledge_commitment opt_window_wnaf_exp(const knowledge_commitment &base, const libff::bigint &scalar, const size_t scalar_bits); -template +template knowledge_commitment kc_multi_exp_with_mixed_addition(const knowledge_commitment_vector &vec, const size_t min_idx, const size_t max_idx, typename std::vector::const_iterator scalar_start, typename std::vector::const_iterator scalar_end, - const size_t chunks, - const bool use_multiexp=false); - -template -void kc_batch_to_special(std::vector > &vec); + const size_t chunks); template knowledge_commitment_vector kc_batch_exp(const size_t scalar_size, diff --git a/libsnark/knowledge_commitment/kc_multiexp.tcc b/libsnark/knowledge_commitment/kc_multiexp.tcc index 4521d659..e3d09e90 100644 --- a/libsnark/knowledge_commitment/kc_multiexp.tcc +++ b/libsnark/knowledge_commitment/kc_multiexp.tcc @@ -18,14 +18,13 @@ knowledge_commitment opt_window_wnaf_exp(const knowledge_commitment +template knowledge_commitment kc_multi_exp_with_mixed_addition(const knowledge_commitment_vector &vec, const size_t min_idx, const size_t max_idx, typename std::vector::const_iterator scalar_start, typename std::vector::const_iterator scalar_end, - const size_t chunks, - const bool use_multiexp) + const size_t chunks) { libff::enter_block("Process scalar vector"); auto index_it = std::lower_bound(vec.indices.begin(), vec.indices.end(), min_idx); @@ -86,77 +85,7 @@ knowledge_commitment kc_multi_exp_with_mixed_addition(const knowledge_co libff::print_indent(); printf("* Elements of w remaining: %zu (%0.2f%%)\n", num_other, 100.*num_other/(num_skip+num_add+num_other)); libff::leave_block("Process scalar vector"); - return acc + libff::multi_exp, FieldT>(g.begin(), g.end(), p.begin(), p.end(), chunks, use_multiexp); -} - -template -void kc_batch_to_special(std::vector > &vec) -{ - libff::enter_block("Batch-convert knowledge-commitments to special form"); - - std::vector g_vec; - g_vec.reserve(vec.size()); - - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].g.is_zero()) - { - g_vec.emplace_back(vec[i].g); - } - } - - libff::batch_to_special_all_non_zeros(g_vec); - auto g_it = g_vec.begin(); - T1 T1_zero_special = T1::zero(); - T1_zero_special.to_special(); - - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].g.is_zero()) - { - vec[i].g = *g_it; - ++g_it; - } - else - { - vec[i].g = T1_zero_special; - } - } - - g_vec.clear(); - - std::vector h_vec; - h_vec.reserve(vec.size()); - - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].h.is_zero()) - { - h_vec.emplace_back(vec[i].h); - } - } - - libff::batch_to_special_all_non_zeros(h_vec); - auto h_it = h_vec.begin(); - T2 T2_zero_special = T2::zero(); - T2_zero_special.to_special(); - - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].h.is_zero()) - { - vec[i].h = *h_it; - ++h_it; - } - else - { - vec[i].h = T2_zero_special; - } - } - - g_vec.clear(); - - libff::leave_block("Batch-convert knowledge-commitments to special form"); + return acc + libff::multi_exp, FieldT, Method>(g.begin(), g.end(), p.begin(), p.end(), chunks); } template @@ -249,7 +178,7 @@ knowledge_commitment_vector kc_batch_exp(const size_t scalar_size, tmp[i] = kc_batch_exp_internal(scalar_size, T1_window, T2_window, T1_table, T2_table, T1_coeff, T2_coeff, v, chunk_pos[i], chunk_pos[i+1], i == num_chunks - 1 ? last_chunk : chunk_size); #ifdef USE_MIXED_ADDITION - kc_batch_to_special(tmp[i].values); + libff::batch_to_special>(tmp[i].values); #endif } diff --git a/libsnark/knowledge_commitment/knowledge_commitment.hpp b/libsnark/knowledge_commitment/knowledge_commitment.hpp index 292e19fe..bd68d0a6 100644 --- a/libsnark/knowledge_commitment/knowledge_commitment.hpp +++ b/libsnark/knowledge_commitment/knowledge_commitment.hpp @@ -45,6 +45,11 @@ struct knowledge_commitment { knowledge_commitment& operator=(const knowledge_commitment &other) = default; knowledge_commitment& operator=(knowledge_commitment &&other) = default; knowledge_commitment operator+(const knowledge_commitment &other) const; + knowledge_commitment mixed_add(const knowledge_commitment &other) const; + knowledge_commitment dbl() const; + + void to_special(); + bool is_special() const; bool is_zero() const; bool operator==(const knowledge_commitment &other) const; @@ -56,6 +61,9 @@ struct knowledge_commitment { void print() const; static size_t size_in_bits(); + + static void batch_to_special_all_non_zeros( + std::vector > &vec); }; template diff --git a/libsnark/knowledge_commitment/knowledge_commitment.tcc b/libsnark/knowledge_commitment/knowledge_commitment.tcc index ab170018..712e77ec 100644 --- a/libsnark/knowledge_commitment/knowledge_commitment.tcc +++ b/libsnark/knowledge_commitment/knowledge_commitment.tcc @@ -43,6 +43,33 @@ knowledge_commitment knowledge_commitment::operator+(const knowled this->h + other.h); } +template +knowledge_commitment knowledge_commitment::mixed_add(const knowledge_commitment &other) const +{ + return knowledge_commitment(this->g.mixed_add(other.g), + this->h.mixed_add(other.h)); +} + +template +knowledge_commitment knowledge_commitment::dbl() const +{ + return knowledge_commitment(this->g.dbl(), + this->h.dbl()); +} + +template +void knowledge_commitment::to_special() +{ + this->g.to_special(); + this->h.to_special(); +} + +template +bool knowledge_commitment::is_special() const +{ + return this->g->is_special() && this->h->is_special(); +} + template bool knowledge_commitment::is_zero() const { @@ -106,6 +133,80 @@ std::istream& operator>>(std::istream& in, knowledge_commitment &kc) return in; } +template +void knowledge_commitment::batch_to_special_all_non_zeros( + std::vector > &vec) +{ + // it is guaranteed that every vec[i] is non-zero, + // but, for any i, *one* of vec[i].g and vec[i].h might still be zero, + // so we still have to handle zeros separately + + // we separately process g's first, then h's + // to lower memory consumption + std::vector g_vec; + g_vec.reserve(vec.size()); + + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].g.is_zero()) + { + g_vec.emplace_back(vec[i].g); + } + } + + T1::batch_to_special_all_non_zeros(g_vec); + auto g_it = g_vec.begin(); + T1 T1_zero_special = T1::zero(); + T1_zero_special.to_special(); + + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].g.is_zero()) + { + vec[i].g = *g_it; + ++g_it; + } + else + { + vec[i].g = T1_zero_special; + } + } + + g_vec.clear(); + + // exactly the same thing, but for h: + std::vector h_vec; + h_vec.reserve(vec.size()); + + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].h.is_zero()) + { + h_vec.emplace_back(vec[i].h); + } + } + + T2::batch_to_special_all_non_zeros(h_vec); + auto h_it = h_vec.begin(); + T2 T2_zero_special = T2::zero(); + T2_zero_special.to_special(); + + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].h.is_zero()) + { + vec[i].h = *h_it; + ++h_it; + } + else + { + vec[i].h = T2_zero_special; + } + } + + h_vec.clear(); +} + } // libsnark #endif // KNOWLEDGE_COMMITMENT_TCC_ diff --git a/libsnark/relations/arithmetic_programs/qap/qap.tcc b/libsnark/relations/arithmetic_programs/qap/qap.tcc index 0172b9b9..93ecd8d7 100644 --- a/libsnark/relations/arithmetic_programs/qap/qap.tcc +++ b/libsnark/relations/arithmetic_programs/qap/qap.tcc @@ -242,14 +242,22 @@ bool qap_instance_evaluation::is_satisfied(const qap_witness &wi FieldT ans_C = this->Ct[0] + witness.d3*this->Zt; FieldT ans_H = FieldT::zero(); - ans_A = ans_A + libff::naive_plain_exp(this->At.begin()+1, this->At.begin()+1+this->num_variables(), - witness.coefficients_for_ABCs.begin(), witness.coefficients_for_ABCs.begin()+this->num_variables()); - ans_B = ans_B + libff::naive_plain_exp(this->Bt.begin()+1, this->Bt.begin()+1+this->num_variables(), - witness.coefficients_for_ABCs.begin(), witness.coefficients_for_ABCs.begin()+this->num_variables()); - ans_C = ans_C + libff::naive_plain_exp(this->Ct.begin()+1, this->Ct.begin()+1+this->num_variables(), - witness.coefficients_for_ABCs.begin(), witness.coefficients_for_ABCs.begin()+this->num_variables()); - ans_H = ans_H + libff::naive_plain_exp(this->Ht.begin(), this->Ht.begin()+this->degree()+1, - witness.coefficients_for_H.begin(), witness.coefficients_for_H.begin()+this->degree()+1); + ans_A = ans_A + libff::inner_product(this->At.begin()+1, + this->At.begin()+1+this->num_variables(), + witness.coefficients_for_ABCs.begin(), + witness.coefficients_for_ABCs.begin()+this->num_variables()); + ans_B = ans_B + libff::inner_product(this->Bt.begin()+1, + this->Bt.begin()+1+this->num_variables(), + witness.coefficients_for_ABCs.begin(), + witness.coefficients_for_ABCs.begin()+this->num_variables()); + ans_C = ans_C + libff::inner_product(this->Ct.begin()+1, + this->Ct.begin()+1+this->num_variables(), + witness.coefficients_for_ABCs.begin(), + witness.coefficients_for_ABCs.begin()+this->num_variables()); + ans_H = ans_H + libff::inner_product(this->Ht.begin(), + this->Ht.begin()+this->degree()+1, + witness.coefficients_for_H.begin(), + witness.coefficients_for_H.begin()+this->degree()+1); if (ans_A * ans_B - ans_C != ans_H * this->Zt) { diff --git a/libsnark/relations/arithmetic_programs/ssp/ssp.tcc b/libsnark/relations/arithmetic_programs/ssp/ssp.tcc index 5905a126..45a413a8 100644 --- a/libsnark/relations/arithmetic_programs/ssp/ssp.tcc +++ b/libsnark/relations/arithmetic_programs/ssp/ssp.tcc @@ -209,10 +209,14 @@ bool ssp_instance_evaluation::is_satisfied(const ssp_witness &wi FieldT ans_V = this->Vt[0] + witness.d*this->Zt; FieldT ans_H = FieldT::zero(); - ans_V = ans_V + libff::naive_plain_exp(this->Vt.begin()+1, this->Vt.begin()+1+this->num_variables(), - witness.coefficients_for_Vs.begin(), witness.coefficients_for_Vs.begin()+this->num_variables()); - ans_H = ans_H + libff::naive_plain_exp(this->Ht.begin(), this->Ht.begin()+this->degree()+1, - witness.coefficients_for_H.begin(), witness.coefficients_for_H.begin()+this->degree()+1); + ans_V = ans_V + libff::inner_product(this->Vt.begin()+1, + this->Vt.begin()+1+this->num_variables(), + witness.coefficients_for_Vs.begin(), + witness.coefficients_for_Vs.begin()+this->num_variables()); + ans_H = ans_H + libff::inner_product(this->Ht.begin(), + this->Ht.begin()+this->degree()+1, + witness.coefficients_for_H.begin(), + witness.coefficients_for_H.begin()+this->degree()+1); if (ans_V.squared() - FieldT::one() != ans_H * this->Zt) { diff --git a/libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/r1cs_ppzkadsnark.tcc b/libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/r1cs_ppzkadsnark.tcc index 3ad34d78..3b3fb40f 100644 --- a/libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/r1cs_ppzkadsnark.tcc +++ b/libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/r1cs_ppzkadsnark.tcc @@ -24,6 +24,10 @@ See r1cs_ppzkadsnark.hpp . #include #include +#ifdef MULTICORE +#include +#endif + #include #include @@ -568,6 +572,9 @@ r1cs_ppzkadsnark_keypair r1cs_ppzkadsnark_generator(const r1cs_ppzkadsnark_ libff::enter_block("Compute the H-query", false); libff::G1_vector> H_query = batch_exp(libff::Fr>::size_in_bits(), g1_window, g1_table, Ht); +#ifdef USE_MIXED_ADDITION + libff::batch_to_special> >(H_query); +#endif libff::leave_block("Compute the H-query", false); libff::enter_block("Compute the K-query", false); @@ -696,52 +703,74 @@ r1cs_ppzkadsnark_proof r1cs_ppzkadsnark_prover(const r1cs_ppzkadsnark_provi libff::enter_block("Compute the proof"); libff::enter_block("Compute answer to A-query", false); - g_A = g_A + kc_multi_exp_with_mixed_addition>, libff::G1>, libff::Fr> >(pk.A_query, - 1+qap_wit.num_inputs(), 1+qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_inputs(), - qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, true); + g_A = g_A + kc_multi_exp_with_mixed_addition>, + libff::G1>, + libff::Fr>, + libff::multi_exp_method_bos_coster>( + pk.A_query, + 1+qap_wit.num_inputs(), 1+qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_inputs(), + qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks); libff::leave_block("Compute answer to A-query", false); libff::enter_block("Compute answer to Ain-query", false); - g_Ain = g_Ain + kc_multi_exp_with_mixed_addition>, libff::G1>, libff::Fr> >(pk.A_query, - 1, 1+qap_wit.num_inputs(), - qap_wit.coefficients_for_ABCs.begin(), - qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_inputs(), - chunks, true); + g_Ain = g_Ain + kc_multi_exp_with_mixed_addition>, + libff::G1>, + libff::Fr>, + libff::multi_exp_method_bos_coster>( + pk.A_query, + 1, 1+qap_wit.num_inputs(), + qap_wit.coefficients_for_ABCs.begin(), + qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_inputs(), + chunks); //std :: cout << "The input proof term: " << g_Ain << "\n"; libff::leave_block("Compute answer to Ain-query", false); libff::enter_block("Compute answer to B-query", false); - g_B = g_B + kc_multi_exp_with_mixed_addition>, libff::G1>, libff::Fr> >(pk.B_query, - 1, 1+qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin(), - qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, true); + g_B = g_B + kc_multi_exp_with_mixed_addition>, + libff::G1>, + libff::Fr>, + libff::multi_exp_method_bos_coster>( + pk.B_query, + 1, 1+qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin(), + qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks); libff::leave_block("Compute answer to B-query", false); libff::enter_block("Compute answer to C-query", false); - g_C = g_C + kc_multi_exp_with_mixed_addition>, libff::G1>, libff::Fr> >(pk.C_query, - 1, 1+qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin(), - qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, true); + g_C = g_C + kc_multi_exp_with_mixed_addition>, + libff::G1>, + libff::Fr>, + libff::multi_exp_method_bos_coster>( + pk.C_query, + 1, 1+qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin(), + qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks); libff::leave_block("Compute answer to C-query", false); libff::enter_block("Compute answer to H-query", false); - g_H = g_H + libff::multi_exp>, libff::Fr> >(pk.H_query.begin(), - pk.H_query.begin()+qap_wit.degree()+1, - qap_wit.coefficients_for_H.begin(), - qap_wit.coefficients_for_H.begin()+qap_wit.degree()+1, - chunks, true); + g_H = g_H + libff::multi_exp>, + libff::Fr>, + libff::multi_exp_method_BDLO12>( + pk.H_query.begin(), + pk.H_query.begin()+qap_wit.degree()+1, + qap_wit.coefficients_for_H.begin(), + qap_wit.coefficients_for_H.begin()+qap_wit.degree()+1, + chunks); libff::leave_block("Compute answer to H-query", false); libff::enter_block("Compute answer to K-query", false); - g_K = g_K + libff::multi_exp_with_mixed_addition>, libff::Fr> >(pk.K_query.begin()+1, - pk.K_query.begin()+1+qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin(), - qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, true); + g_K = g_K + libff::multi_exp_with_mixed_addition>, + libff::Fr>, + libff::multi_exp_method_bos_coster>( + pk.K_query.begin()+1, + pk.K_query.begin()+1+qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin(), + qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks); libff::leave_block("Compute answer to K-query", false); libff::enter_block("Compute extra auth terms", false); @@ -754,9 +783,12 @@ r1cs_ppzkadsnark_proof r1cs_ppzkadsnark_prover(const r1cs_ppzkadsnark_provi Ains.emplace_back(pk.A_query[i+1].g); } libff::G1> muA = dauth * pk.rA_i_Z_g1; - muA = muA + libff::multi_exp>, libff::Fr> >(Ains.begin(), Ains.begin()+qap_wit.num_inputs(), - mus.begin(), mus.begin()+qap_wit.num_inputs(), - chunks, true); + muA = muA + libff::multi_exp>, + libff::Fr>, + libff::multi_exp_method_bos_coster>( + Ains.begin(), Ains.begin()+qap_wit.num_inputs(), + mus.begin(), mus.begin()+qap_wit.num_inputs(), + chunks); // To Do: Decide whether to include relevant parts of auth_data in proof libff::leave_block("Compute extra auth terms", false); @@ -844,10 +876,13 @@ bool r1cs_ppzkadsnark_online_verifier(const r1cs_ppzkadsnark_processed_verificat } libff::leave_block("Compute PRFs"); libff::G1> prodA = sak.i * proof.g_Aau.g; - prodA = prodA + libff::multi_exp>, libff::Fr> >(pvk.Ain.begin(), - pvk.Ain.begin() + labels.size(), - lambdas.begin(), - lambdas.begin() + labels.size(), 1, true); + prodA = prodA + libff::multi_exp>, + libff::Fr>, + libff::multi_exp_method_bos_coster>( + pvk.Ain.begin(), + pvk.Ain.begin() + labels.size(), + lambdas.begin(), + lambdas.begin() + labels.size(), 1); bool result_auth = true; diff --git a/libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/r1cs_gg_ppzksnark.tcc b/libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/r1cs_gg_ppzksnark.tcc index c463d33f..0acb1905 100644 --- a/libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/r1cs_gg_ppzksnark.tcc +++ b/libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/r1cs_gg_ppzksnark.tcc @@ -24,6 +24,10 @@ See r1cs_gg_ppzksnark.hpp . #include #include +#ifdef MULTICORE +#include +#endif + #include #include @@ -326,16 +330,21 @@ r1cs_gg_ppzksnark_keypair r1cs_gg_ppzksnark_generator(const r1cs_gg_ppzksna libff::enter_block("Compute the B-query", false); knowledge_commitment_vector, libff::G1 > B_query = kc_batch_exp(libff::Fr::size_in_bits(), g2_window_size, g1_window_size, g2_table, g1_table, libff::Fr::one(), libff::Fr::one(), Bt, chunks); + // NOTE: if USE_MIXED_ADDITION is defined, + // kc_batch_exp will convert its output to special form internally libff::leave_block("Compute the B-query", false); libff::enter_block("Compute the H-query", false); libff::G1_vector H_query = batch_exp_with_coeff(g1_scalar_size, g1_window_size, g1_table, qap.Zt * delta_inverse, Ht); +#ifdef USE_MIXED_ADDITION + libff::batch_to_special >(H_query); +#endif libff::leave_block("Compute the H-query", false); libff::enter_block("Compute the L-query", false); libff::G1_vector L_query = batch_exp(g1_scalar_size, g1_window_size, g1_table, Lt); #ifdef USE_MIXED_ADDITION - batch_to_special >(L_query); + libff::batch_to_special >(L_query); #endif libff::leave_block("Compute the L-query", false); libff::leave_block("Generate queries"); @@ -430,44 +439,49 @@ r1cs_gg_ppzksnark_proof r1cs_gg_ppzksnark_prover(const r1cs_gg_ppzksnark_pr libff::Fr_vector const_padded_assignment(1, libff::Fr::one()); const_padded_assignment.insert(const_padded_assignment.end(), qap_wit.coefficients_for_ABCs.begin(), qap_wit.coefficients_for_ABCs.end()); - libff::G1 evaluation_At = libff::multi_exp_with_mixed_addition, libff::Fr >( + libff::G1 evaluation_At = libff::multi_exp_with_mixed_addition, + libff::Fr, + libff::multi_exp_method_BDLO12>( pk.A_query.begin(), pk.A_query.begin() + qap_wit.num_variables() + 1, const_padded_assignment.begin(), const_padded_assignment.begin() + qap_wit.num_variables() + 1, - chunks, - true); + chunks); libff::leave_block("Compute evaluation to A-query", false); libff::enter_block("Compute evaluation to B-query", false); - knowledge_commitment, libff::G1 > evaluation_Bt = kc_multi_exp_with_mixed_addition, libff::G1, libff::Fr >( + knowledge_commitment, libff::G1 > evaluation_Bt = kc_multi_exp_with_mixed_addition, + libff::G1, + libff::Fr, + libff::multi_exp_method_BDLO12>( pk.B_query, 0, qap_wit.num_variables() + 1, const_padded_assignment.begin(), const_padded_assignment.begin() + qap_wit.num_variables() + 1, - chunks, - true); + chunks); libff::leave_block("Compute evaluation to B-query", false); libff::enter_block("Compute evaluation to H-query", false); - libff::G1 evaluation_Ht = libff::multi_exp, libff::Fr >( + libff::G1 evaluation_Ht = libff::multi_exp, + libff::Fr, + libff::multi_exp_method_BDLO12>( pk.H_query.begin(), pk.H_query.begin() + (qap_wit.degree() - 1), qap_wit.coefficients_for_H.begin(), qap_wit.coefficients_for_H.begin() + (qap_wit.degree() - 1), - chunks, - true); + chunks); libff::leave_block("Compute evaluation to H-query", false); libff::enter_block("Compute evaluation to L-query", false); - libff::G1 evaluation_Lt = libff::multi_exp_with_mixed_addition, libff::Fr >( + libff::G1 evaluation_Lt = libff::multi_exp_with_mixed_addition, + libff::Fr, + libff::multi_exp_method_BDLO12>( pk.L_query.begin(), pk.L_query.end(), const_padded_assignment.begin() + qap_wit.num_inputs() + 1, const_padded_assignment.begin() + qap_wit.num_variables() + 1, - chunks, - true); + chunks); libff::leave_block("Compute evaluation to L-query", false); /* A = alpha + sum_i(a_i*A_i(t)) + r*delta */ diff --git a/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc b/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc index 58ae4c7e..21dea1da 100644 --- a/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc +++ b/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc @@ -24,6 +24,10 @@ See r1cs_ppzksnark.hpp . #include #include +#ifdef MULTICORE +#include +#endif + #include #include @@ -359,6 +363,9 @@ r1cs_ppzksnark_keypair r1cs_ppzksnark_generator(const r1cs_ppzksnark_constr libff::enter_block("Compute the H-query", false); libff::G1_vector H_query = batch_exp(libff::Fr::size_in_bits(), g1_window, g1_table, Ht); +#ifdef USE_MIXED_ADDITION + libff::batch_to_special >(H_query); +#endif libff::leave_block("Compute the H-query", false); libff::enter_block("Compute the K-query", false); @@ -475,36 +482,54 @@ r1cs_ppzksnark_proof r1cs_ppzksnark_prover(const r1cs_ppzksnark_proving_key libff::enter_block("Compute the proof"); libff::enter_block("Compute answer to A-query", false); - g_A = g_A + kc_multi_exp_with_mixed_addition, libff::G1, libff::Fr >(pk.A_query, - 1, 1+qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin(), qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, true); + g_A = g_A + kc_multi_exp_with_mixed_addition, + libff::G1, + libff::Fr, + libff::multi_exp_method_bos_coster>( + pk.A_query, + 1, 1+qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin(), qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks); libff::leave_block("Compute answer to A-query", false); libff::enter_block("Compute answer to B-query", false); - g_B = g_B + kc_multi_exp_with_mixed_addition, libff::G1, libff::Fr >(pk.B_query, - 1, 1+qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin(), qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, true); + g_B = g_B + kc_multi_exp_with_mixed_addition, + libff::G1, + libff::Fr, + libff::multi_exp_method_bos_coster>( + pk.B_query, + 1, 1+qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin(), qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks); libff::leave_block("Compute answer to B-query", false); libff::enter_block("Compute answer to C-query", false); - g_C = g_C + kc_multi_exp_with_mixed_addition, libff::G1, libff::Fr >(pk.C_query, - 1, 1+qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin(), qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, true); + g_C = g_C + kc_multi_exp_with_mixed_addition, + libff::G1, + libff::Fr, + libff::multi_exp_method_bos_coster>( + pk.C_query, + 1, 1+qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin(), qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks); libff::leave_block("Compute answer to C-query", false); libff::enter_block("Compute answer to H-query", false); - g_H = g_H + libff::multi_exp, libff::Fr >(pk.H_query.begin(), pk.H_query.begin()+qap_wit.degree()+1, - qap_wit.coefficients_for_H.begin(), qap_wit.coefficients_for_H.begin()+qap_wit.degree()+1, - chunks, true); + g_H = g_H + libff::multi_exp, + libff::Fr, + libff::multi_exp_method_BDLO12>( + pk.H_query.begin(), pk.H_query.begin()+qap_wit.degree()+1, + qap_wit.coefficients_for_H.begin(), qap_wit.coefficients_for_H.begin()+qap_wit.degree()+1, + chunks); libff::leave_block("Compute answer to H-query", false); libff::enter_block("Compute answer to K-query", false); - g_K = g_K + libff::multi_exp_with_mixed_addition, libff::Fr >(pk.K_query.begin()+1, pk.K_query.begin()+1+qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin(), qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, true); + g_K = g_K + libff::multi_exp_with_mixed_addition, + libff::Fr, + libff::multi_exp_method_bos_coster>( + pk.K_query.begin()+1, pk.K_query.begin()+1+qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin(), qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks); libff::leave_block("Compute answer to K-query", false); libff::leave_block("Compute the proof"); diff --git a/libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/uscs_ppzksnark.tcc b/libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/uscs_ppzksnark.tcc index 164a7a7d..5569f00a 100644 --- a/libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/uscs_ppzksnark.tcc +++ b/libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/uscs_ppzksnark.tcc @@ -22,6 +22,10 @@ #include #include +#ifdef MULTICORE +#include +#endif + #include #include @@ -263,18 +267,30 @@ uscs_ppzksnark_keypair uscs_ppzksnark_generator(const uscs_ppzksnark_constr libff::enter_block("Compute the query for V_g1", false); libff::G1_vector V_g1_query = batch_exp(libff::Fr::size_in_bits(), g1_window, g1_table, Vt_table_minus_Xt_table); +#ifdef USE_MIXED_ADDITION + libff::batch_to_special >(V_g1_query); +#endif libff::leave_block("Compute the query for V_g1", false); libff::enter_block("Compute the query for alpha_V_g1", false); libff::G1_vector alpha_V_g1_query = batch_exp_with_coeff(libff::Fr::size_in_bits(), g1_window, g1_table, alpha, Vt_table_minus_Xt_table); +#ifdef USE_MIXED_ADDITION + libff::batch_to_special >(alpha_V_g1_query); +#endif libff::leave_block("Compute the query for alpha_V_g1", false); libff::enter_block("Compute the query for H_g1", false); libff::G1_vector H_g1_query = batch_exp(libff::Fr::size_in_bits(), g1_window, g1_table, Ht_table); +#ifdef USE_MIXED_ADDITION + libff::batch_to_special >(H_g1_query); +#endif libff::leave_block("Compute the query for H_g1", false); libff::enter_block("Compute the query for V_g2", false); libff::G2_vector V_g2_query = batch_exp(libff::Fr::size_in_bits(), g2_window, g2_table, Vt_table); +#ifdef USE_MIXED_ADDITION + libff::batch_to_special >(V_g2_query); +#endif libff::leave_block("Compute the query for V_g2", false); libff::leave_block("Generate proof components"); @@ -359,31 +375,39 @@ uscs_ppzksnark_proof uscs_ppzksnark_prover(const uscs_ppzksnark_proving_key libff::enter_block("Compute the proof"); libff::enter_block("Compute V_g1, the 1st component of the proof", false); - V_g1 = V_g1 + libff::multi_exp_with_mixed_addition, libff::Fr >(pk.V_g1_query.begin(), pk.V_g1_query.begin()+(ssp_wit.num_variables()-ssp_wit.num_inputs()), - ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_inputs(), ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_variables(), - chunks, - true); + V_g1 = V_g1 + libff::multi_exp_with_mixed_addition, + libff::Fr, + libff::multi_exp_method_BDLO12>( + pk.V_g1_query.begin(), pk.V_g1_query.begin()+(ssp_wit.num_variables()-ssp_wit.num_inputs()), + ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_inputs(), ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_variables(), + chunks); libff::leave_block("Compute V_g1, the 1st component of the proof", false); libff::enter_block("Compute alpha_V_g1, the 2nd component of the proof", false); - alpha_V_g1 = alpha_V_g1 + libff::multi_exp_with_mixed_addition, libff::Fr >(pk.alpha_V_g1_query.begin(), pk.alpha_V_g1_query.begin()+(ssp_wit.num_variables()-ssp_wit.num_inputs()), - ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_inputs(), ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_variables(), - chunks, - true); + alpha_V_g1 = alpha_V_g1 + libff::multi_exp_with_mixed_addition, + libff::Fr, + libff::multi_exp_method_BDLO12>( + pk.alpha_V_g1_query.begin(), pk.alpha_V_g1_query.begin()+(ssp_wit.num_variables()-ssp_wit.num_inputs()), + ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_inputs(), ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_variables(), + chunks); libff::leave_block("Compute alpha_V_g1, the 2nd component of the proof", false); libff::enter_block("Compute H_g1, the 3rd component of the proof", false); - H_g1 = H_g1 + libff::multi_exp, libff::Fr >(pk.H_g1_query.begin(), pk.H_g1_query.begin()+ssp_wit.degree()+1, - ssp_wit.coefficients_for_H.begin(), ssp_wit.coefficients_for_H.begin()+ssp_wit.degree()+1, - chunks, - true); + H_g1 = H_g1 + libff::multi_exp, + libff::Fr, + libff::multi_exp_method_BDLO12>( + pk.H_g1_query.begin(), pk.H_g1_query.begin()+ssp_wit.degree()+1, + ssp_wit.coefficients_for_H.begin(), ssp_wit.coefficients_for_H.begin()+ssp_wit.degree()+1, + chunks); libff::leave_block("Compute H_g1, the 3rd component of the proof", false); libff::enter_block("Compute V_g2, the 4th component of the proof", false); - V_g2 = V_g2 + libff::multi_exp, libff::Fr >(pk.V_g2_query.begin()+1, pk.V_g2_query.begin()+ssp_wit.num_variables()+1, - ssp_wit.coefficients_for_Vs.begin(), ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_variables(), - chunks, - true); + V_g2 = V_g2 + libff::multi_exp, + libff::Fr, + libff::multi_exp_method_BDLO12>( + pk.V_g2_query.begin()+1, pk.V_g2_query.begin()+ssp_wit.num_variables()+1, + ssp_wit.coefficients_for_Vs.begin(), ssp_wit.coefficients_for_Vs.begin()+ssp_wit.num_variables(), + chunks); libff::leave_block("Compute V_g2, the 4th component of the proof", false); libff::leave_block("Compute the proof");