diff --git a/libsnark/zk_proof_systems/plonk/circuit.tcc b/libsnark/zk_proof_systems/plonk/circuit.tcc index bae016eff..06a14e3fb 100644 --- a/libsnark/zk_proof_systems/plonk/circuit.tcc +++ b/libsnark/zk_proof_systems/plonk/circuit.tcc @@ -9,8 +9,8 @@ #ifndef LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_CIRCUIT_TCC_ #define LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_CIRCUIT_TCC_ -/// Implementation of Common Preprocessed Input interfaces for a -/// ppzkSNARK for Plonk. See circuit.hpp . +// Implementation of Common Preprocessed Input interfaces for a +// ppzkSNARK for Plonk. See circuit.hpp . namespace libsnark { @@ -18,7 +18,7 @@ namespace libsnark // TODO: add here function for describing the target circuit through // the circuit_t structure -/// stuct constructor +// stuct constructor template circuit_t::circuit_t( size_t num_gates, diff --git a/libsnark/zk_proof_systems/plonk/prover.tcc b/libsnark/zk_proof_systems/plonk/prover.tcc index 4b1596113..5d79429e3 100644 --- a/libsnark/zk_proof_systems/plonk/prover.tcc +++ b/libsnark/zk_proof_systems/plonk/prover.tcc @@ -9,13 +9,13 @@ #ifndef LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_PROVER_TCC_ #define LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_PROVER_TCC_ -/// Implementation of Prover interfaces for a ppzkSNARK for Plonk. See -/// prover.hpp . +// Implementation of Prover interfaces for a ppzkSNARK for Plonk. See +// prover.hpp . namespace libsnark { -/// Prover round 0 output constructor +// Prover round 0 output constructor template round_zero_out_t::round_zero_out_t( const std::vector> &&zh_poly, @@ -25,18 +25,18 @@ round_zero_out_t::round_zero_out_t( { } -/// Prover Round 0 initialization -/// -/// Initialization -/// -/// INPUT -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] zh_poly: vanishing polynomial -/// \param[out] null_poly: 0 polynomial -/// \param[out] neg_one_poly: -1 polynomial +// Prover Round 0 initialization +// +// Initialization +// +// INPUT +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] zh_poly: vanishing polynomial +// \param[out] null_poly: 0 polynomial +// \param[out] neg_one_poly: -1 polynomial template round_zero_out_t plonk_prover::round_zero(const srs &srs) { @@ -62,7 +62,7 @@ round_zero_out_t plonk_prover::round_zero(const srs &srs) return round_zero_out; } -/// Prover round 1 output constructor +// Prover round 1 output constructor template round_one_out_t::round_one_out_t( const std::vector>> &&W_polys, @@ -74,28 +74,28 @@ round_one_out_t::round_one_out_t( { } -/// Prover Round 1 -/// -/// INPUT -/// \param[in] zh_poly: vanishing polynomial Zh (from round 0) -/// \param[in] null_poly: 0 polynomial (from round 0) -/// \param[in] neg_one_poly: -1 polynomial (from round 0) -/// \param[in] blind_scalars: blinding scalars b1, b2, ..., b9 (only -/// b1-b6 used in round 1) -/// \param[in] witness: witness values -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] W_polys: witness polynomials (Lagrange interpolation -/// of the witness values) -/// \param[out] W_polys_blinded: blinded witness polynomials -/// \param[out] W_polys_blinded_at_secret_g1: the blinded witness -/// polynomials evaluated at the secret input denoted -/// [a]_1, [b]_1, [c]_1 in [GWC19] -/// \param[out] transcript_hasher: accumulates the communication -/// transcript into a buffer to be hashed after prover -/// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). +// Prover Round 1 +// +// INPUT +// \param[in] zh_poly: vanishing polynomial Zh (from round 0) +// \param[in] null_poly: 0 polynomial (from round 0) +// \param[in] neg_one_poly: -1 polynomial (from round 0) +// \param[in] blind_scalars: blinding scalars b1, b2, ..., b9 (only +// b1-b6 used in round 1) +// \param[in] witness: witness values +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] W_polys: witness polynomials (Lagrange interpolation +// of the witness values) +// \param[out] W_polys_blinded: blinded witness polynomials +// \param[out] W_polys_blinded_at_secret_g1: the blinded witness +// polynomials evaluated at the secret input denoted +// [a]_1, [b]_1, [c]_1 in [GWC19] +// \param[out] transcript_hasher: accumulates the communication +// transcript into a buffer to be hashed after prover +// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). template round_one_out_t plonk_prover::round_one( const round_zero_out_t &round_zero_out, @@ -157,7 +157,7 @@ round_one_out_t plonk_prover::round_one( return round_one_out; } -/// Prover round 2 output +// Prover round 2 output template round_two_out_t::round_two_out_t( polynomial> &&z_poly, libff::G1 &&z_poly_at_secret_g1) @@ -165,23 +165,23 @@ round_two_out_t::round_two_out_t( { } -/// Prover Round 2 -/// -/// INPUT -/// \param[in] zh_poly: vanishing polynomial Zh (from round 0) -/// \param[in] blind_scalars: blinding scalars b1, b2, ..., b9 (only -/// b7,b8,b9 used in round 2) -/// \param[in] witness: witness values -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] z_poly: blinded accumulator poly z(x) -/// \param[out] z_poly_at_secret_g1: blinded accumulator poly z(x) -/// evaluated at secret -/// \param[out] transcript_hasher: accumulates the communication -/// transcript into a buffer to be hashed after prover -/// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). +// Prover Round 2 +// +// INPUT +// \param[in] zh_poly: vanishing polynomial Zh (from round 0) +// \param[in] blind_scalars: blinding scalars b1, b2, ..., b9 (only +// b7,b8,b9 used in round 2) +// \param[in] witness: witness values +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] z_poly: blinded accumulator poly z(x) +// \param[out] z_poly_at_secret_g1: blinded accumulator poly z(x) +// evaluated at secret +// \param[out] transcript_hasher: accumulates the communication +// transcript into a buffer to be hashed after prover +// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). template round_two_out_t plonk_prover::round_two( const libff::Fr &beta, @@ -227,7 +227,7 @@ round_two_out_t plonk_prover::round_two( return round_two_out; } -/// Prover round 3 output constructor +// Prover round 3 output constructor template round_three_out_t::round_three_out_t( std::vector> &&z_poly_xomega, @@ -241,30 +241,30 @@ round_three_out_t::round_three_out_t( { } -/// Prover Round 3 -/// -/// INPUT -/// \param[in] zh_poly: vanishing polynomial Zh (from Round 0) -/// \param[in] W_polys_blinded: blinded witness polynomials (from -/// Round 1) -/// \param[in] beta, gamma: permutation challenges -- hashes of -/// transcript (from round 2) -/// \param[in] z_poly: blinded accumulator poly z(x) (from Round 2) -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] t_poly_long: the quotient polynomial t(x) (see Round -/// 3, pp28 [GWC19]) -/// \param[out] t_poly: t(x) divided in three parts t(x) = t_lo(x) + -/// t_mid(x) x^n + t_hi(x) x^{2n} -/// \param[out] t_poly_at_secret_g1: t(x) evaluated at the secret -/// input zeta i.e. t(zeta) -/// \param[out] z_poly_xomega: the polynomial z(x*w) i.e. z(x) shifted -/// by w -/// \param[out] transcript_hasher: accumulates the communication -/// transcript into a buffer to be hashed after prover -/// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). +// Prover Round 3 +// +// INPUT +// \param[in] zh_poly: vanishing polynomial Zh (from Round 0) +// \param[in] W_polys_blinded: blinded witness polynomials (from +// Round 1) +// \param[in] beta, gamma: permutation challenges -- hashes of +// transcript (from round 2) +// \param[in] z_poly: blinded accumulator poly z(x) (from Round 2) +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] t_poly_long: the quotient polynomial t(x) (see Round +// 3, pp28 [GWC19]) +// \param[out] t_poly: t(x) divided in three parts t(x) = t_lo(x) + +// t_mid(x) x^n + t_hi(x) x^{2n} +// \param[out] t_poly_at_secret_g1: t(x) evaluated at the secret +// input zeta i.e. t(zeta) +// \param[out] z_poly_xomega: the polynomial z(x*w) i.e. z(x) shifted +// by w +// \param[out] transcript_hasher: accumulates the communication +// transcript into a buffer to be hashed after prover +// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). template round_three_out_t plonk_prover::round_three( const libff::Fr &alpha, @@ -496,7 +496,7 @@ round_three_out_t plonk_prover::round_three( return round_three_out; } -/// Prover round 4 output constructor +// Prover round 4 output constructor template round_four_out_t::round_four_out_t( libff::Fr &&a_zeta, @@ -516,40 +516,40 @@ round_four_out_t::round_four_out_t( { } -/// Prover Round 4 -/// -/// INPUT -/// \param[in] W_polys_blinded: blinded witness polynomials (from -/// Round 1) -/// \param[in] z_poly_xomega: the polynomial z(x*w) i.e. z(x) shifted -/// by w (from Round 3) -/// \param[in] t_poly_long: the quotient polynomial t(x) (see Round 3, -/// pp28 [GWC19]) (from Round 3) -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] a_zeta, b_zeta, c_zeta: the blinded witness -/// polynomials a(x), b(x), c(x) (denoted by -/// W_polys_blinded[] output from Round 1) evaluated at -/// x=zeta i.e. a(z), b(z), c(z) -/// \param[out] S_0_zeta, S_1_zeta: the permutation polynomials -/// S_sigma_1(x), S_sigma_2(x) from the common -/// preprocessed input (see [GWC19], Sect. 8.1) evaluated -/// at x=zeta i.e. S_sigma_1(z), S_sigma_2(z) -/// \param[out] z_poly_xomega_zeta: the polynomial z(x*w) i.e. z(x) -/// shifted by w (output from Round 3) evaluated at x=zeta -/// i.e. z(zeta*w) -/// \param[out] t_zeta: the quotient polynomial t(x) output from Round -/// 3, see pp28 [GWC19]) evaluated at x=zeta -/// i.e. t(z). IMPORTANT! the original Plonk proposal -/// [GWC19] does not output this parameter t_zeta. The -/// Python reference implementation \[PlonkPy] does, so we -/// do the same in order to match the test vectors. TODO -/// can remove t_zeta in the future -/// \param[out] transcript_hasher: accumulates the communication -/// transcript into a buffer to be hashed after prover -/// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). +// Prover Round 4 +// +// INPUT +// \param[in] W_polys_blinded: blinded witness polynomials (from +// Round 1) +// \param[in] z_poly_xomega: the polynomial z(x*w) i.e. z(x) shifted +// by w (from Round 3) +// \param[in] t_poly_long: the quotient polynomial t(x) (see Round 3, +// pp28 [GWC19]) (from Round 3) +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] a_zeta, b_zeta, c_zeta: the blinded witness +// polynomials a(x), b(x), c(x) (denoted by +// W_polys_blinded[] output from Round 1) evaluated at +// x=zeta i.e. a(z), b(z), c(z) +// \param[out] S_0_zeta, S_1_zeta: the permutation polynomials +// S_sigma_1(x), S_sigma_2(x) from the common +// preprocessed input (see [GWC19], Sect. 8.1) evaluated +// at x=zeta i.e. S_sigma_1(z), S_sigma_2(z) +// \param[out] z_poly_xomega_zeta: the polynomial z(x*w) i.e. z(x) +// shifted by w (output from Round 3) evaluated at x=zeta +// i.e. z(zeta*w) +// \param[out] t_zeta: the quotient polynomial t(x) output from Round +// 3, see pp28 [GWC19]) evaluated at x=zeta +// i.e. t(z). IMPORTANT! the original Plonk proposal +// [GWC19] does not output this parameter t_zeta. The +// Python reference implementation \[PlonkPy] does, so we +// do the same in order to match the test vectors. TODO +// can remove t_zeta in the future +// \param[out] transcript_hasher: accumulates the communication +// transcript into a buffer to be hashed after prover +// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). template round_four_out_t plonk_prover::round_four( const libff::Fr &zeta, @@ -606,7 +606,7 @@ round_four_out_t plonk_prover::round_four( return round_four_out; } -/// Prover round 5 output constructor +// Prover round 5 output constructor template round_five_out_t::round_five_out_t( libff::Fr &&r_zeta, @@ -618,53 +618,53 @@ round_five_out_t::round_five_out_t( { } -/// Prover Round 5 -/// -/// INPUT -/// \param[in] beta, gamma: permutation challenges -- hashes of -/// transcript (from round 2) -/// \param[in] alpha: quotinet challenge -- hash of transcript (from -/// round 3) -/// \param[in] zeta: evaluation challenge -- hash of transcript (from -/// round 4) -/// \param[in] a_zeta, b_zeta, c_zeta: the blinded witness polynomials -/// a(x), b(x), c(x) (denoted by W_polys_blinded[] output -/// from Round 1) evaluated at x=zeta i.e. a(z), b(z), c(z) -/// (from round 4) -/// \param[in] S_0_zeta, S_1_zeta: the permutation polynomials -/// S_sigma_1(x), S_sigma_2(x) from the common preprocessed -/// input (see [GWC19], Sect. 8.1) evaluated at x=zeta -/// i.e. S_sigma_1(z), S_sigma_2(z) (from round 4) -/// \param[in] t_zeta: the quotient polynomial t(x) output from Round -/// 3, see pp28 [GWC19]) evaluated at x=zeta -/// i.e. t(z). IMPORTANT! the original Plonk proposal -/// [GWC19] does not output this parameter t_zeta. The -/// Python reference implementation \[PlonkPy] does, so we -/// do the same in order to match the test vectors. TODO -/// can remove t_zeta in the future (from round 4) -/// \param[in] z_poly_xomega_zeta: the polynomial z(x*w) i.e. z(x) -/// shifted by w (output from Round 3) evaluated at x=zeta -/// i.e. z(zeta*w) (from round 4) -/// \param[in] W_polys_blinded: blinded witness polynomials (from -/// round 1) -/// \param[in] t_poly: t(x) divided in three parts t(x) = t_lo(x) + -/// t_mid(x) x^n + t_hi(x) x^{2n} (from round 3) -/// \param[in] z_poly: blinded accumulator poly z(x) (from round 2) -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] r_zeta: linearisation polynomial r(x) evaluated at -/// x=zeta ie. r(zeta) -/// \param[out] W_zeta_at_secret: commitment to opening proof -/// polynomial W_zeta(x) at secert input -/// i.e. [W_zeta(secret)]_1 -/// \param[out] W_zeta_omega_at_secret: commitment to opening proof -/// polynomial W_{zeta omega}(x) at secert input -/// i.e. [W_{zeta omega}(secret)]_1 -/// \param[out] transcript_hasher: accumulates the communication -/// transcript into a buffer to be hashed after prover -/// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). +// Prover Round 5 +// +// INPUT +// \param[in] beta, gamma: permutation challenges -- hashes of +// transcript (from round 2) +// \param[in] alpha: quotinet challenge -- hash of transcript (from +// round 3) +// \param[in] zeta: evaluation challenge -- hash of transcript (from +// round 4) +// \param[in] a_zeta, b_zeta, c_zeta: the blinded witness polynomials +// a(x), b(x), c(x) (denoted by W_polys_blinded[] output +// from Round 1) evaluated at x=zeta i.e. a(z), b(z), c(z) +// (from round 4) +// \param[in] S_0_zeta, S_1_zeta: the permutation polynomials +// S_sigma_1(x), S_sigma_2(x) from the common preprocessed +// input (see [GWC19], Sect. 8.1) evaluated at x=zeta +// i.e. S_sigma_1(z), S_sigma_2(z) (from round 4) +// \param[in] t_zeta: the quotient polynomial t(x) output from Round +// 3, see pp28 [GWC19]) evaluated at x=zeta +// i.e. t(z). IMPORTANT! the original Plonk proposal +// [GWC19] does not output this parameter t_zeta. The +// Python reference implementation \[PlonkPy] does, so we +// do the same in order to match the test vectors. TODO +// can remove t_zeta in the future (from round 4) +// \param[in] z_poly_xomega_zeta: the polynomial z(x*w) i.e. z(x) +// shifted by w (output from Round 3) evaluated at x=zeta +// i.e. z(zeta*w) (from round 4) +// \param[in] W_polys_blinded: blinded witness polynomials (from +// round 1) +// \param[in] t_poly: t(x) divided in three parts t(x) = t_lo(x) + +// t_mid(x) x^n + t_hi(x) x^{2n} (from round 3) +// \param[in] z_poly: blinded accumulator poly z(x) (from round 2) +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] r_zeta: linearisation polynomial r(x) evaluated at +// x=zeta ie. r(zeta) +// \param[out] W_zeta_at_secret: commitment to opening proof +// polynomial W_zeta(x) at secert input +// i.e. [W_zeta(secret)]_1 +// \param[out] W_zeta_omega_at_secret: commitment to opening proof +// polynomial W_{zeta omega}(x) at secert input +// i.e. [W_{zeta omega}(secret)]_1 +// \param[out] transcript_hasher: accumulates the communication +// transcript into a buffer to be hashed after prover +// rounds 1,2,3,4,5 (cf. fiat-shamir heuristic). template round_five_out_t plonk_prover::round_five( const libff::Fr &alpha, @@ -993,51 +993,51 @@ plonk_proof::plonk_proof( { } -/// Prover compute SNARK proof -/// -/// Pi ([a]_1, [b]_1, [c]_1, [z]_1, -/// [t_lo]_1, [t_mi]_1, [t_hi]_1, -/// \bar{a}, \bar{b}, \bar{c}, -/// \bar{S_sigma1}, \bar{S_sigma2}, \bar{z_w}, -/// [W_zeta]_1, [W_{zeta omega}]_1 -/// r_zeta) -/// -/// \note in the reference Python implementation \[PlonkPy], r_zeta -/// (the evaluation of the linearlization polynomial r(X) at zeta from -/// Prover round 5) is added to the pi-SNARK proof. In the paper this -/// is omitted, which seems to make the proof shorter by 1 element at -/// the epxense of a slightly heavier computation on the verifier's -/// side. Here we follow the reference implementation \[PlonkPy] to -/// make sure we match the test values. TODO: once all test vectors -/// are verified, we may remove r_zeta from the proof to be fully -/// compliant with the paper. -/// -/// Mapping code-to-paper quantities -/// -/// \param W_polys_blinded_at_secret_g1[a, b, c]: [a]_1, [b]_1, [c]_1 -/// (from Round 1) -/// \param z_poly_at_secret_g1: [z]_1 (from Round 2) -/// \param t_poly_at_secret_g1[lo, mi, hi]: [t_lo]_1, [t_mi]_1, -/// [t_hi]_1 (from Round 3) -/// \param a_zeta, b_zeta, c_zeta, S_0_zeta, S_1_zeta, -/// z_poly_xomega_zeta: \bar{a}, \bar{b}, \bar{c}, -/// \bar{S_sigma1}, \bar{S_sigma2}, \bar{z_w} (from Round 4) -/// \param W_zeta_at_secret, W_zeta_omega_at_secret: [W_zeta]_1, -/// [W_{zeta omega}]_1 (from Round 5) -/// -/// INPUT -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// \param[in] witness: all internal values and public input -/// corresponding to the given circuit -/// \param[in] blind_scalars: random blinding scalars b1, b2, ..., b9 -/// used in prover rounds 1 and 2 (see Sect. 8.3, roumds -/// 1,2 [GWC19]) -/// \param[in] transcript_hasher: hashes of the communication -/// transcript after prover rounds 1,2,3,4,5. -/// -/// OUTPUT -/// \param[out] proof: SNARK proof Pi (see above) +// Prover compute SNARK proof +// +// Pi ([a]_1, [b]_1, [c]_1, [z]_1, +// [t_lo]_1, [t_mi]_1, [t_hi]_1, +// \bar{a}, \bar{b}, \bar{c}, +// \bar{S_sigma1}, \bar{S_sigma2}, \bar{z_w}, +// [W_zeta]_1, [W_{zeta omega}]_1 +// r_zeta) +// +// \note in the reference Python implementation \[PlonkPy], r_zeta +// (the evaluation of the linearlization polynomial r(X) at zeta from +// Prover round 5) is added to the pi-SNARK proof. In the paper this +// is omitted, which seems to make the proof shorter by 1 element at +// the epxense of a slightly heavier computation on the verifier's +// side. Here we follow the reference implementation \[PlonkPy] to +// make sure we match the test values. TODO: once all test vectors +// are verified, we may remove r_zeta from the proof to be fully +// compliant with the paper. +// +// Mapping code-to-paper quantities +// +// \param W_polys_blinded_at_secret_g1[a, b, c]: [a]_1, [b]_1, [c]_1 +// (from Round 1) +// \param z_poly_at_secret_g1: [z]_1 (from Round 2) +// \param t_poly_at_secret_g1[lo, mi, hi]: [t_lo]_1, [t_mi]_1, +// [t_hi]_1 (from Round 3) +// \param a_zeta, b_zeta, c_zeta, S_0_zeta, S_1_zeta, +// z_poly_xomega_zeta: \bar{a}, \bar{b}, \bar{c}, +// \bar{S_sigma1}, \bar{S_sigma2}, \bar{z_w} (from Round 4) +// \param W_zeta_at_secret, W_zeta_omega_at_secret: [W_zeta]_1, +// [W_{zeta omega}]_1 (from Round 5) +// +// INPUT +// \param[in] srs: structured reference string containing also +// circuit-specific information +// \param[in] witness: all internal values and public input +// corresponding to the given circuit +// \param[in] blind_scalars: random blinding scalars b1, b2, ..., b9 +// used in prover rounds 1 and 2 (see Sect. 8.3, roumds +// 1,2 [GWC19]) +// \param[in] transcript_hasher: hashes of the communication +// transcript after prover rounds 1,2,3,4,5. +// +// OUTPUT +// \param[out] proof: SNARK proof Pi (see above) template plonk_proof plonk_prover::compute_proof( const srs &srs, @@ -1087,8 +1087,8 @@ plonk_proof plonk_prover::compute_proof( zeta, round_one_out, round_three_out, srs, hasher); printf("[%s:%d] Prover Round 5...\n", __FILE__, __LINE__); - /// - nu: opening challenge -- hash of transcript (denoted by v in - /// [GWC19]) + // - nu: opening challenge -- hash of transcript (denoted by v in + // [GWC19]) const libff::Fr nu = hasher.get_hash(); round_five_out_t round_five_out = plonk_prover::round_five( alpha, diff --git a/libsnark/zk_proof_systems/plonk/srs.tcc b/libsnark/zk_proof_systems/plonk/srs.tcc index 2648a9a40..d52488575 100644 --- a/libsnark/zk_proof_systems/plonk/srs.tcc +++ b/libsnark/zk_proof_systems/plonk/srs.tcc @@ -9,8 +9,8 @@ #ifndef LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_SRS_TCC_ #define LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_SRS_TCC_ -/// Implementation of SRS interfaces for a ppzkSNARK for Plonk. See -/// srs.hpp . +// Implementation of SRS interfaces for a ppzkSNARK for Plonk. See +// srs.hpp . namespace libsnark { @@ -58,13 +58,13 @@ srs::srs( { } -/// class plonk_verification_key +// class plonk_verification_key template plonk_verification_key::plonk_verification_key( std::vector> &&secret_powers_g2) : secret_powers_g2(std::move(secret_powers_g2)){}; -/// class plonk_keypair constructor +// class plonk_keypair constructor template plonk_keypair::plonk_keypair( plonk_proving_key &&pk, plonk_verification_key &&vk) @@ -72,7 +72,7 @@ plonk_keypair::plonk_keypair( { } -/// transcript_hasher constructor +// transcript_hasher constructor template transcript_hasher::transcript_hasher(std::vector &buffer) : buffer(std::move(buffer)) @@ -98,19 +98,19 @@ transcript_hasher::transcript_hasher(std::vector &buffer) }; } -/// clear the buffer (for now only for testing) +// clear the buffer (for now only for testing) template void transcript_hasher::buffer_clear() { this->buffer.clear(); } -/// get buffer size +// get buffer size template size_t transcript_hasher::buffer_size() { return this->buffer.size(); } -/// add an Fr element to the transcript buffer for hashing +// add an Fr element to the transcript buffer for hashing template void transcript_hasher::add_element(const libff::Fr &element) { @@ -127,7 +127,7 @@ void transcript_hasher::add_element(const libff::Fr &element) std::copy(str.begin(), str.end(), std::back_inserter(this->buffer)); } -/// add the coordinates of a G1 curve point to the transcript buffer for hashing +// add the coordinates of a G1 curve point to the transcript buffer for hashing template void transcript_hasher::add_element(const libff::G1 &element) { @@ -149,7 +149,7 @@ void transcript_hasher::add_element(const libff::G1 &element) std::copy(str.begin(), str.end(), std::back_inserter(this->buffer)); } -/// add the coordinates of a G2 curve point to the transcript buffer for hashing +// add the coordinates of a G2 curve point to the transcript buffer for hashing template void transcript_hasher::add_element(const libff::G2 &element) { @@ -171,10 +171,10 @@ void transcript_hasher::add_element(const libff::G2 &element) std::copy(str.begin(), str.end(), std::back_inserter(this->buffer)); } -/// dummy implementation of get_hash that directly returns the -/// expected hard-coded hashes for the purposes of unit testing TODO -/// to be replaced by a call to a proper hash function e.g. SHA2, -/// BLAKE, etc. +// dummy implementation of get_hash that directly returns the +// expected hard-coded hashes for the purposes of unit testing TODO +// to be replaced by a call to a proper hash function e.g. SHA2, +// BLAKE, etc. template libff::Fr transcript_hasher::get_hash() { size_t buffer_len = this->buffer.size(); @@ -258,11 +258,11 @@ template libff::Fr transcript_hasher::get_hash() return challenge; } -/// Compute a universal srs (usrs). It is composed *only* of encoded -/// powers of the secret value in the group generator. Therefore a usrs -/// is independent of any particular circuit. -/// -/// \note only for debug +// Compute a universal srs (usrs). It is composed *only* of encoded +// powers of the secret value in the group generator. Therefore a usrs +// is independent of any particular circuit. +// +// \note only for debug template usrs plonk_usrs_derive_from_secret( const libff::Fr &secret, const size_t max_degree) @@ -301,13 +301,13 @@ usrs plonk_usrs_derive_from_secret( return usrs(std::move(secret_powers_g1), std::move(secret_powers_g2)); } -/// Derive the (plain) SRS from the circuit description and the -/// USRS. The (plain) SRS is a specialization of the USRS for one -/// particular circuit i.e. -/// -/// usrs = -/// srs = (proving_key, verificataion_key) = derive(usrs, -/// circuit_description) +// Derive the (plain) SRS from the circuit description and the +// USRS. The (plain) SRS is a specialization of the USRS for one +// particular circuit i.e. +// +// usrs = +// srs = (proving_key, verificataion_key) = derive(usrs, +// circuit_description) template srs plonk_srs_derive_from_usrs( const usrs &usrs, const circuit_t &circuit) diff --git a/libsnark/zk_proof_systems/plonk/tests/example.tcc b/libsnark/zk_proof_systems/plonk/tests/example.tcc index a9dee03d2..2b90b121a 100644 --- a/libsnark/zk_proof_systems/plonk/tests/example.tcc +++ b/libsnark/zk_proof_systems/plonk/tests/example.tcc @@ -8,8 +8,8 @@ #ifndef LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_TESTS_EXAMPLE_TCC_ #define LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_TESTS_EXAMPLE_TCC_ -/// Instantiation of the test vector values from the Python implementation -/// of the Plonk protocol. \see example.hpp . +// Instantiation of the test vector values from the Python implementation +// of the Plonk protocol. \see example.hpp . namespace libsnark { diff --git a/libsnark/zk_proof_systems/plonk/utils.tcc b/libsnark/zk_proof_systems/plonk/utils.tcc index 13482419a..2cb62ae60 100644 --- a/libsnark/zk_proof_systems/plonk/utils.tcc +++ b/libsnark/zk_proof_systems/plonk/utils.tcc @@ -9,13 +9,13 @@ #ifndef LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_UTILS_TCC_ #define LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_UTILS_TCC_ -/// Implementation of interfaces for a ppzkSNARK for Plonk. See -/// utils.hpp . +// Implementation of interfaces for a ppzkSNARK for Plonk. See +// utils.hpp . namespace libsnark { -/// print the elements of a vector +// print the elements of a vector template void print_vector(const std::vector &v) { for (size_t i = 0; i < v.size(); ++i) { @@ -24,25 +24,61 @@ template void print_vector(const std::vector &v) } } -/// Interpolate a polynomial from a set of points through inverse FFT -/// -/// INPUT: -/// -/// \param[in] f_points[0..n-1]: a set of points (0,y0), (1,y1), -/// ... (n-1,y_{n-1}) s.t. y0=f_points[0], y1=f_points[1], -/// ... which we want to interpolate as a polynomial -/// -/// OUTPUT: -/// -/// \param[out] f_poly[0..n-1]: the coefficients [a0, a1, ..., a_{n-1}] -/// of the polynomial f(x) interpolating the set of points -/// f_points. For example if f_poly[0..n-1] = [a0, a1, ..., -/// a_{n-1}] then this represents the polynomial f(x) = -/// a0+a1x+a1x^2+...+a_{n-1}x^{n-1} such that -/// f(omega_i)=f_points[i], where omega_0, ..., omega_{n-1} -/// are the n roots of unity. -/// -/// \note uses libfqfft iFFT for the interpolation +// Compute the Lagrange basis polynomials for interpolating sets of +// n points +// +// INPUT: +// +// \param[in] npoints - number of points +// +// OUTPUT: +// +// \param[out] L[0..n-1][0..n-1]: Lagrange basis over the n roots of +// unity omega_0, ..., omega_{n-1} i.e. L[omega_i] = [a0, +// a1, ..., a_{n-1}] is a vector representing the +// coefficients of the i-th Lagrange polynomial L_i(x) = +// a0+a1x+a2x^2+..+a_{n-1}x^{n-1} s.t. L_i(x=omega_i)=1 +// and L_i(x\neq{omega_i)})=0 +// +// \note uses libfqfft iFFT for the interpolation +template +void plonk_compute_lagrange_basis( + const size_t npoints, std::vector> &L) +{ + assert(L.size() != 0); + assert(L.size() == L[0].size()); + assert(L.size() == npoints); + + std::shared_ptr> domain = + libfqfft::get_evaluation_domain(npoints); + for (size_t i = 0; i < npoints; ++i) { + polynomial u(npoints, FieldT(0)); + u[i] = FieldT(1); + // compute i-th Lagrange basis vector via inverse FFT + domain->iFFT(u); + L[i] = u; + } +} + +// Interpolate a polynomial from a set of points through inverse FFT +// +// INPUT: +// +// \param[in] f_points[0..n-1]: a set of points (0,y0), (1,y1), +// ... (n-1,y_{n-1}) s.t. y0=f_points[0], y1=f_points[1], +// ... which we want to interpolate as a polynomial +// +// OUTPUT: +// +// \param[out] f_poly[0..n-1]: the coefficients [a0, a1, ..., a_{n-1}] +// of the polynomial f(x) interpolating the set of points +// f_points. For example if f_poly[0..n-1] = [a0, a1, ..., +// a_{n-1}] then this represents the polynomial f(x) = +// a0+a1x+a1x^2+...+a_{n-1}x^{n-1} such that +// f(omega_i)=f_points[i], where omega_0, ..., omega_{n-1} +// are the n roots of unity. +// +// \note uses libfqfft iFFT for the interpolation template void plonk_interpolate_polynomial_from_points( const std::vector &f_points, polynomial &f_poly) @@ -54,11 +90,11 @@ void plonk_interpolate_polynomial_from_points( domain->iFFT(f_poly); } -/// Compute the selector polynomials of the given circuit (also -/// called here "q-polynomials"). See Sect. 8.1. The matrix -/// gates_matrix_transpose has 5 rows, each corresponding to the -/// values L, R, M, O and C for each gate; the number of columns is -/// equal to the number of gates. L_basis is the Lagrange basis. +// Compute the selector polynomials of the given circuit (also +// called here "q-polynomials"). See Sect. 8.1. The matrix +// gates_matrix_transpose has 5 rows, each corresponding to the +// values L, R, M, O and C for each gate; the number of columns is +// equal to the number of gates. L_basis is the Lagrange basis. template std::vector> plonk_compute_selector_polynomials( const size_t &num_gates, @@ -84,12 +120,12 @@ void plonk_compute_public_input_polynomial( plonk_interpolate_polynomial_from_points(PI_points, PI_poly); }; -/// This function computes the sets H, k1H, k2H. H is a -/// multiplicative subgroup containing the n-th roots of unity in Fr, -/// where \omega is a primitive n-th root of unity and a generator of -/// H i.e H = {1, \omega, ..., \omega^{n-1}}. k1, k2 \in Fr are chosen -/// such that H, H k1, H k2 are distinct cosets of H in Fr, and thus -/// consist of 3n distinct elements. \see [GWC19] pp26 (top). +// This function computes the sets H, k1H, k2H. H is a +// multiplicative subgroup containing the n-th roots of unity in Fr, +// where \omega is a primitive n-th root of unity and a generator of +// H i.e H = {1, \omega, ..., \omega^{n-1}}. k1, k2 \in Fr are chosen +// such that H, H k1, H k2 are distinct cosets of H in Fr, and thus +// consist of 3n distinct elements. \see [GWC19] pp26 (top). template void plonk_compute_roots_of_unity_omega( const size_t num_gates, @@ -126,14 +162,14 @@ void plonk_compute_roots_of_unity_omega( } } -/// This function computes the sets H, k1H, k2H, where H is a -/// multiplicative subgroup containing the n-th roots of unity in Fr and -/// \omega is a primitive n-th root of unity and a generator of -/// H ie. H = {1, \omega, ..., \omega^{n-1}}. k1, k2 \in Fr are chosen -/// such that H, H k1, H k2 are distinct cosets of H in Fr, and thus -/// consist of 3n distinct elements. \see [GWC19] pp26 (top) and Sect. 8. -/// -/// \note uses plonk_compute_roots_of_unity_omega +// This function computes the sets H, k1H, k2H, where H is a +// multiplicative subgroup containing the n-th roots of unity in Fr and +// \omega is a primitive n-th root of unity and a generator of +// H ie. H = {1, \omega, ..., \omega^{n-1}}. k1, k2 \in Fr are chosen +// such that H, H k1, H k2 are distinct cosets of H in Fr, and thus +// consist of 3n distinct elements. \see [GWC19] pp26 (top) and Sect. 8. +// +// \note uses plonk_compute_roots_of_unity_omega template void plonk_compute_cosets_H_k1H_k2H( const size_t num_gates, @@ -161,10 +197,10 @@ void plonk_compute_cosets_H_k1H_k2H( omega[base_k2].begin(), omega[base_k2].end(), back_inserter(H_gen)); } -/// permute the multiplicative subgroup H according to the wire -/// permutation: (see [GWC19] Sect. 8), \see -/// plonk_compute_roots_of_unity_omega, \see -/// plonk_roots_of_unity_omega_to_subgroup_H +// permute the multiplicative subgroup H according to the wire +// permutation: (see [GWC19] Sect. 8), \see +// plonk_compute_roots_of_unity_omega, \see +// plonk_roots_of_unity_omega_to_subgroup_H template std::vector plonk_permute_subgroup_H( const std::vector &H_gen, @@ -180,8 +216,8 @@ std::vector plonk_permute_subgroup_H( return H_gen_permute; } -/// compute the permutation polynomials S_sigma_1, S_sigma_2, -/// S_sigma_2 (see [GWC19], Sect. 8.1) +// compute the permutation polynomials S_sigma_1, S_sigma_2, +// S_sigma_2 (see [GWC19], Sect. 8.1) template std::vector> plonk_compute_permutation_polynomials( const std::vector &H_gen_permute, const size_t num_gates) @@ -222,21 +258,21 @@ libff::G1 plonk_multi_exp_G1( return product; } -/// Evaluate a polynomial F at the encoded secret input -/// \secret^i*G_1 ie. compute f(\secret)*G1 = [f(\secret)]_i -/// -/// INPUT -/// -/// \param[in] secret_powers_g1: \secret^i*G1: -/// 0\le{i} libff::G1 plonk_evaluate_poly_at_secret_G1( const std::vector> &secret_powers_g1, @@ -257,8 +293,8 @@ libff::G1 plonk_evaluate_poly_at_secret_G1( return f_poly_at_secret_g1; } -/// Evaluate a list of polynomials in the encrypted secret input: see -/// plonk_evaluate_poly_at_secret_G1 +// Evaluate a list of polynomials in the encrypted secret input: see +// plonk_evaluate_poly_at_secret_G1 template void plonk_evaluate_polys_at_secret_G1( const std::vector> &secret_powers_g1, @@ -275,10 +311,10 @@ void plonk_evaluate_polys_at_secret_G1( } } -/// Compute the factors in the product of the permutation polynomial -/// z(X) in Prover Round 2. Note that accumulator A[0]=1 and A[i], -/// i>0 is computed from values at i-1 for witness[i-1], H_gen[i-1], -/// H_gen_permute[i-1]m etc. +// Compute the factors in the product of the permutation polynomial +// z(X) in Prover Round 2. Note that accumulator A[0]=1 and A[i], +// i>0 is computed from values at i-1 for witness[i-1], H_gen[i-1], +// H_gen_permute[i-1]m etc. template FieldT plonk_compute_accumulator_factor( const size_t i, diff --git a/libsnark/zk_proof_systems/plonk/verifier.tcc b/libsnark/zk_proof_systems/plonk/verifier.tcc index 5380fe5b3..c7cf4f650 100644 --- a/libsnark/zk_proof_systems/plonk/verifier.tcc +++ b/libsnark/zk_proof_systems/plonk/verifier.tcc @@ -9,13 +9,13 @@ #ifndef LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_VERIFIER_TCC_ #define LIBSNARK_ZK_PROOF_SYSTEMS_PLONK_VERIFIER_TCC_ -/// Implementation of Verifier interfaces for a ppzkSNARK for Plonk. See -/// verifier.hpp . +// Implementation of Verifier interfaces for a ppzkSNARK for Plonk. See +// verifier.hpp . namespace libsnark { -/// struct verifier_preprocessed_input_t constructor +// struct verifier_preprocessed_input_t constructor template verifier_preprocessed_input_t::verifier_preprocessed_input_t( std::vector> &&Q_polys_at_secret_g1, @@ -25,17 +25,17 @@ verifier_preprocessed_input_t::verifier_preprocessed_input_t( { } -/// Verifier precomputation -/// -/// INPUT -/// \param[in] srs: structured reference string -/// -/// OUTPUT -/// \param[out] Q_polys_at_secret_g1: circuit selector polynomials Q evaluated -/// at -/// the secret input -/// \param[out] S_polys_at_secret_g1: permutation polynomials S evaluated at the -/// secret input +// Verifier precomputation +// +// INPUT +// \param[in] srs: structured reference string +// +// OUTPUT +// \param[out] Q_polys_at_secret_g1: circuit selector polynomials Q evaluated +// at +// the secret input +// \param[out] S_polys_at_secret_g1: permutation polynomials S evaluated at the +// secret input template verifier_preprocessed_input_t plonk_verifier::preprocessed_input( const srs &srs) @@ -55,34 +55,34 @@ verifier_preprocessed_input_t plonk_verifier::preprocessed_input( return preprocessed_input; } -/// Verifier Step 1: validate that elements belong to group G1 -/// -/// \attention This validation MUST be done by the caller. Empty -/// function here for consistency with the description in [GWC19] +// Verifier Step 1: validate that elements belong to group G1 +// +// \attention This validation MUST be done by the caller. Empty +// function here for consistency with the description in [GWC19] template void plonk_verifier::step_one(const plonk_proof &proof) { } -/// Verifier Step 2: validate that elements belong to scalar field Fr -/// -/// \attention This validation MUST be done by the caller. Empty -/// function here for consistency with the description in [GWC19] +// Verifier Step 2: validate that elements belong to scalar field Fr +// +// \attention This validation MUST be done by the caller. Empty +// function here for consistency with the description in [GWC19] template void plonk_verifier::step_two(const plonk_proof &proof) { } -/// Verifier Step 3: validate that the public input belongs to scalar -/// field Fr -/// -/// \attention This validation MUST be done by the caller. Empty -/// function here for consistency with the description in [GWC19] +// Verifier Step 3: validate that the public input belongs to scalar +// field Fr +// +// \attention This validation MUST be done by the caller. Empty +// function here for consistency with the description in [GWC19] template void plonk_verifier::step_three(const srs &srs) { } -/// struct step_four_out_t constructor +// struct step_four_out_t constructor template step_four_out_t::step_four_out_t( libff::Fr &beta, @@ -95,24 +95,24 @@ step_four_out_t::step_four_out_t( { } -/// Verifier Step 4: compute challenges hashed transcript as in prover -/// description, from the common inputs, public input, and elements of -/// pi-SNARK. TODO: fixed to the test vectors for now -/// -/// INPUT -/// \param[in] proof: SNARK proof produced by the prover -/// \param[in] transcript_hasher: hashes of the communication -/// transcript after prover rounds 1,2,3,4,5. -/// -/// OUTPUT -/// \param[out] beta, gamma: permutation challenges - hashes of -/// transcript -/// \param[out] alpha: quotinet challenge - hash of transcript -/// \param[out] zeta: evaluation challenge - hash of transcript -/// \param[out] nu: opening challenge - hash of transcript (denoted by -/// v in [GWC19]) -/// \param[out] u: multipoint evaluation challenge - hash of -/// transcript +// Verifier Step 4: compute challenges hashed transcript as in prover +// description, from the common inputs, public input, and elements of +// pi-SNARK. TODO: fixed to the test vectors for now +// +// INPUT +// \param[in] proof: SNARK proof produced by the prover +// \param[in] transcript_hasher: hashes of the communication +// transcript after prover rounds 1,2,3,4,5. +// +// OUTPUT +// \param[out] beta, gamma: permutation challenges - hashes of +// transcript +// \param[out] alpha: quotinet challenge - hash of transcript +// \param[out] zeta: evaluation challenge - hash of transcript +// \param[out] nu: opening challenge - hash of transcript (denoted by +// v in [GWC19]) +// \param[out] u: multipoint evaluation challenge - hash of +// transcript template step_four_out_t plonk_verifier::step_four( const plonk_proof &proof, transcript_hasher &hasher) @@ -167,24 +167,24 @@ step_four_out_t plonk_verifier::step_four( return step_four_out; } -/// struct step_five_out_t constructor +// struct step_five_out_t constructor template step_five_out_t::step_five_out_t(libff::Fr &&zh_zeta) : zh_zeta(zh_zeta) { } -/// Verifier Step 5: compute zero polynomial evaluation -/// -/// INPUT -/// \param[in] zeta: evaluation challenge -- hash of transcript (from -/// step 4) -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] zh_zeta: evaluation of vanishing polynomial Zh at -/// x=zeta i.e. Zh(zeta) +// Verifier Step 5: compute zero polynomial evaluation +// +// INPUT +// \param[in] zeta: evaluation challenge -- hash of transcript (from +// step 4) +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] zh_zeta: evaluation of vanishing polynomial Zh at +// x=zeta i.e. Zh(zeta) template step_five_out_t plonk_verifier::step_five( const step_four_out_t &step_four_out, const srs &srs) @@ -197,25 +197,25 @@ step_five_out_t plonk_verifier::step_five( return step_five_out; } -/// struct step_six_out_t constructor +// struct step_six_out_t constructor template step_six_out_t::step_six_out_t(libff::Fr &&L_0_zeta) : L_0_zeta(L_0_zeta) { } -/// Verifier Step 6: Compute Lagrange polynomial evaluation L1(zeta) -/// Note: the paper counts the L-polynomials from 1; we count from 0 -/// -/// INPUT -/// \param[in] zeta: evaluation challenge -- hash of transcript (from -/// step 4) -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] L_0_zeta: Lagrange polynomial evaluation of polynomial -/// L1 at x=zeta i.e. L1(zeta) +// Verifier Step 6: Compute Lagrange polynomial evaluation L1(zeta) +// Note: the paper counts the L-polynomials from 1; we count from 0 +// +// INPUT +// \param[in] zeta: evaluation challenge -- hash of transcript (from +// step 4) +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] L_0_zeta: Lagrange polynomial evaluation of polynomial +// L1 at x=zeta i.e. L1(zeta) template step_six_out_t plonk_verifier::step_six( const step_four_out_t &step_four_out, const srs &srs) @@ -226,25 +226,25 @@ step_six_out_t plonk_verifier::step_six( return step_six_out; } -/// struct step_seven_out_t constructor +// struct step_seven_out_t constructor template step_seven_out_t::step_seven_out_t(libff::Fr &&PI_zeta) : PI_zeta(PI_zeta) { } -/// Verifier Step 7: compute public input polynomial evaluation -/// PI(zeta) -/// -/// INPUT -/// \param[in] zeta: evaluation challenge -- hash of transcript (from -/// step 4) -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] PI_zeta: public input polynomial PI evaluated at -/// x=zeta i.e. PI(zeta) +// Verifier Step 7: compute public input polynomial evaluation +// PI(zeta) +// +// INPUT +// \param[in] zeta: evaluation challenge -- hash of transcript (from +// step 4) +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] PI_zeta: public input polynomial PI evaluated at +// x=zeta i.e. PI(zeta) template step_seven_out_t plonk_verifier::step_seven( const step_four_out_t &step_four_out, const srs &srs) @@ -256,40 +256,40 @@ step_seven_out_t plonk_verifier::step_seven( return step_seven_out; } -/// struct step_eight_out_t constructor +// struct step_eight_out_t constructor template step_eight_out_t::step_eight_out_t(libff::Fr &&r_prime_zeta) : r_prime_zeta(r_prime_zeta) { } -/// Verifier Step 8: compute quotient polynomial evaluation r'(zeta) = -/// r(zeta) - r0, where r0 is a constant term \note follows the Python -/// reference implementation, which slightly deviates from the paper -/// due to the presence of the r_zeta term in the proof (not present -/// in the paper). In particular, the reference code computes and -/// uses r'(zeta) in step 8, while the paper uses r0. In addition, the -/// reference code divides r'(zeta) by the vanishing polynomial at -/// zeta zh_zeta, while the paper does not do that (see also Step 9). -/// -/// INPUT -/// \param[in] beta, gamma: permutation challenges -- hashes of -/// transcript (from step 4) -/// \param[in] alpha: quotinet challenge -- hash of transcript (from -/// step 4) -/// \param[in] zeta: evaluation challenge -- hash of transcript (from -/// step 4) -/// \param[in] zh_zeta: evaluation of vanishing polynomial Zh at -/// x=zeta i.e. Zh(zeta) (from step 5) -/// \param[in] L_0_zeta: Lagrange polynomial evaluation of polynomial -/// L1 at x=zeta i.e. L1(zeta) (from step 6) -/// \param[in] PI_zeta: public input polynomial PI evaluated at x=zeta -/// i.e. PI(zeta) (from step 7) -/// \param[in] proof: SNARK proof produced by the prover -/// -/// OUTPUT -/// \param[out] r_prime_zeta: quotient polynomial evaluation r'(zeta) -/// = r(zeta) - r0, where r0 is a constant term +// Verifier Step 8: compute quotient polynomial evaluation r'(zeta) = +// r(zeta) - r0, where r0 is a constant term \note follows the Python +// reference implementation, which slightly deviates from the paper +// due to the presence of the r_zeta term in the proof (not present +// in the paper). In particular, the reference code computes and +// uses r'(zeta) in step 8, while the paper uses r0. In addition, the +// reference code divides r'(zeta) by the vanishing polynomial at +// zeta zh_zeta, while the paper does not do that (see also Step 9). +// +// INPUT +// \param[in] beta, gamma: permutation challenges -- hashes of +// transcript (from step 4) +// \param[in] alpha: quotinet challenge -- hash of transcript (from +// step 4) +// \param[in] zeta: evaluation challenge -- hash of transcript (from +// step 4) +// \param[in] zh_zeta: evaluation of vanishing polynomial Zh at +// x=zeta i.e. Zh(zeta) (from step 5) +// \param[in] L_0_zeta: Lagrange polynomial evaluation of polynomial +// L1 at x=zeta i.e. L1(zeta) (from step 6) +// \param[in] PI_zeta: public input polynomial PI evaluated at x=zeta +// i.e. PI(zeta) (from step 7) +// \param[in] proof: SNARK proof produced by the prover +// +// OUTPUT +// \param[out] r_prime_zeta: quotient polynomial evaluation r'(zeta) +// = r(zeta) - r0, where r0 is a constant term template step_eight_out_t plonk_verifier::step_eight( const step_four_out_t &step_four_out, @@ -322,47 +322,47 @@ step_eight_out_t plonk_verifier::step_eight( return step_eight_out; } -/// struct step_nine_out_t constructor +// struct step_nine_out_t constructor template step_nine_out_t::step_nine_out_t(libff::G1 &&D1) : D1(D1) { } -/// Verifier Step 9: compute first part of batched polynomial -/// commitment [D]_1 Note: the reference implemention differs from the -/// paper -- it does not add the following term to D1, but to F1 (Step -/// 10): -Zh(zeta)([t_lo]_1 + zeta^n [t_mid]_1 + zeta^2n -/// [t_hi]_1). Instead ([t_lo]_1 + zeta^n [t_mid]_1 + zeta^2n -/// [t_hi]_1) is added to F1 in Step 10 and the multiplication by -/// Zh(zeta) is accounted for by dividing by Zh(zeta) of r'(zeta) in -/// Step 8. -/// -/// INPUT -/// \param[in] beta, gamma: permutation challenges -- hashes of -/// transcript (from step 4) -/// \param[in] alpha: quotinet challenge -- hash of transcript (from -/// step 4) -/// \param[in] zeta: evaluation challenge -- hash of transcript (from -/// step 4) -/// \param[in] nu: opening challenge -- hash of transcript (denoted by -/// v in [GWC19]) (from step 4) -/// \param[in] u: multipoint evaluation challenge -- hash of -/// transcript (from step 4) -/// \param[in] L_0_zeta: Lagrange polynomial evaluation of polynomial -/// L1 at x=zeta i.e. L1(zeta) (from step 6) -/// \param[in] Q_polys_at_secret_g1: circuit selector polynomials Q -/// evaluated at the secret input (from verifier -/// preprocessed input) -/// \param[in] S_polys_at_secret_g1: permutation polynomials S -/// evaluated at the secret input (from verifier -/// preprocessed input) -/// \param[in] proof: SNARK proof produced by the prover -/// \param[in] preprocessed_input: verifier preprocessed input -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] D1: first part of batched polynomial commitment [D]_1 +// Verifier Step 9: compute first part of batched polynomial +// commitment [D]_1 Note: the reference implemention differs from the +// paper -- it does not add the following term to D1, but to F1 (Step +// 10): -Zh(zeta)([t_lo]_1 + zeta^n [t_mid]_1 + zeta^2n +// [t_hi]_1). Instead ([t_lo]_1 + zeta^n [t_mid]_1 + zeta^2n +// [t_hi]_1) is added to F1 in Step 10 and the multiplication by +// Zh(zeta) is accounted for by dividing by Zh(zeta) of r'(zeta) in +// Step 8. +// +// INPUT +// \param[in] beta, gamma: permutation challenges -- hashes of +// transcript (from step 4) +// \param[in] alpha: quotinet challenge -- hash of transcript (from +// step 4) +// \param[in] zeta: evaluation challenge -- hash of transcript (from +// step 4) +// \param[in] nu: opening challenge -- hash of transcript (denoted by +// v in [GWC19]) (from step 4) +// \param[in] u: multipoint evaluation challenge -- hash of +// transcript (from step 4) +// \param[in] L_0_zeta: Lagrange polynomial evaluation of polynomial +// L1 at x=zeta i.e. L1(zeta) (from step 6) +// \param[in] Q_polys_at_secret_g1: circuit selector polynomials Q +// evaluated at the secret input (from verifier +// preprocessed input) +// \param[in] S_polys_at_secret_g1: permutation polynomials S +// evaluated at the secret input (from verifier +// preprocessed input) +// \param[in] proof: SNARK proof produced by the prover +// \param[in] preprocessed_input: verifier preprocessed input +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] D1: first part of batched polynomial commitment [D]_1 template step_nine_out_t plonk_verifier::step_nine( const step_four_out_t &step_four_out, @@ -430,36 +430,36 @@ step_nine_out_t plonk_verifier::step_nine( return step_nine_out; } -/// struct step_ten_out_t constructor +// struct step_ten_out_t constructor template step_ten_out_t::step_ten_out_t(libff::G1 &&F1) : F1(F1) { } -/// Verifier Step 10: compute full batched polynomial commitment [F]_1 -/// = [D]_1 + v [a]_1 + v^2 [b]_1 + v^3 [c]_1 + v^4 [s_sigma_1]_1 + -/// v^5 [s_sigma_2]_1 Note: to [F]_1 the erefernce code also adds the -/// term ([t_lo]_1 + zeta^n [t_mid]_1 + zeta^2n [t_hi]_1) which is -/// addedto [D]_1 in the paper (see commenst to Steps 8,9) -/// -/// INPUT -/// \param[in] zeta: evaluation challenge -- hash of transcript (from -/// step 4) -/// \param[in] nu: opening challenge -- hash of transcript (denoted by -/// v in [GWC19]) (from step 4) -/// \param[in] u: multipoint evaluation challenge -- hash of -/// transcript (from step 4) -/// \param[in] D1: first part of batched polynomial commitment [D]_1 -/// (from step 9) -/// \param[in] S_polys_at_secret_g1: permutation polynomials S -/// evaluated at the secret input (from verifier -/// preprocessed input) -/// \param[in] proof: SNARK proof produced by the prover -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] F1: full batched polynomial commitment [F]_1 +// Verifier Step 10: compute full batched polynomial commitment [F]_1 +// = [D]_1 + v [a]_1 + v^2 [b]_1 + v^3 [c]_1 + v^4 [s_sigma_1]_1 + +// v^5 [s_sigma_2]_1 Note: to [F]_1 the erefernce code also adds the +// term ([t_lo]_1 + zeta^n [t_mid]_1 + zeta^2n [t_hi]_1) which is +// addedto [D]_1 in the paper (see commenst to Steps 8,9) +// +// INPUT +// \param[in] zeta: evaluation challenge -- hash of transcript (from +// step 4) +// \param[in] nu: opening challenge -- hash of transcript (denoted by +// v in [GWC19]) (from step 4) +// \param[in] u: multipoint evaluation challenge -- hash of +// transcript (from step 4) +// \param[in] D1: first part of batched polynomial commitment [D]_1 +// (from step 9) +// \param[in] S_polys_at_secret_g1: permutation polynomials S +// evaluated at the secret input (from verifier +// preprocessed input) +// \param[in] proof: SNARK proof produced by the prover +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] F1: full batched polynomial commitment [F]_1 template step_ten_out_t plonk_verifier::step_ten( const step_four_out_t &step_four_out, @@ -504,25 +504,25 @@ step_ten_out_t plonk_verifier::step_ten( return step_ten_out; } -/// struct step_eleven_out_t constructor +// struct step_eleven_out_t constructor template step_eleven_out_t::step_eleven_out_t(libff::G1 &&E1) : E1(E1) { } -/// Verifier Step 11: compute group-encoded batch evaluation [E]_1 -/// -/// INPUT -/// \param[in] nu: opening challenge -- hash of transcript (denoted by -/// v in [GWC19]) (from step 4) -/// \param[in] u: multipoint evaluation challenge -- hash of -/// transcript (from step 4) -/// \param[in] r_prime_zeta: quotient polynomial evaluation r'(zeta) = -/// r(zeta) - r0, where r0 is a constant term (from step 8) -/// \param[in] proof: SNARK proof produced by the prover -/// -/// OUTPUT -/// \param[out] E1: group-encoded batch evaluation [E]_1 +// Verifier Step 11: compute group-encoded batch evaluation [E]_1 +// +// INPUT +// \param[in] nu: opening challenge -- hash of transcript (denoted by +// v in [GWC19]) (from step 4) +// \param[in] u: multipoint evaluation challenge -- hash of +// transcript (from step 4) +// \param[in] r_prime_zeta: quotient polynomial evaluation r'(zeta) = +// r(zeta) - r0, where r0 is a constant term (from step 8) +// \param[in] proof: SNARK proof produced by the prover +// +// OUTPUT +// \param[out] E1: group-encoded batch evaluation [E]_1 template step_eleven_out_t plonk_verifier::step_eleven( const step_four_out_t &step_four_out, @@ -550,33 +550,33 @@ step_eleven_out_t plonk_verifier::step_eleven( return step_eleven_out; } -/// Verifier Step 12: batch validate all evaluations -/// -/// Checks the following equality -/// -/// e( [W_zeta]_1 + u [W_{zeta srs.omega_roots}]_1, [x]_2 ) * e( -zeta -/// [W_zeta ]_1 - u zeta srs.omega_roots [W_{zeta srs.omega_roots}]_1 -/// - [F]_1 + [E]_1, [1]_2 ) = Field(1) -/// -/// Denoted as: -/// -/// e(first_lhs, second_lhs) * e(first_rhs, second_rhs) = 1 -/// -/// INPUT -/// \param[in] zeta: evaluation challenge -- hash of transcript (from -/// step 4) -/// \param[in] u: multipoint evaluation challenge -- hash of -/// transcript (from step 4) -/// \param[in] F1: full batched polynomial commitment [F]_1 (from step -/// 10) -/// \param[in] E1: group-encoded batch evaluation [E]_1 (from step 11) -/// \param[in] proof: SNARK proof produced by the prover -/// \param[in] srs: structured reference string -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// -/// OUTPUT -/// \param[out] boolean 1/0 = valid/invalid proof +// Verifier Step 12: batch validate all evaluations +// +// Checks the following equality +// +// e( [W_zeta]_1 + u [W_{zeta srs.omega_roots}]_1, [x]_2 ) * e( -zeta +// [W_zeta ]_1 - u zeta srs.omega_roots [W_{zeta srs.omega_roots}]_1 +// - [F]_1 + [E]_1, [1]_2 ) = Field(1) +// +// Denoted as: +// +// e(first_lhs, second_lhs) * e(first_rhs, second_rhs) = 1 +// +// INPUT +// \param[in] zeta: evaluation challenge -- hash of transcript (from +// step 4) +// \param[in] u: multipoint evaluation challenge -- hash of +// transcript (from step 4) +// \param[in] F1: full batched polynomial commitment [F]_1 (from step +// 10) +// \param[in] E1: group-encoded batch evaluation [E]_1 (from step 11) +// \param[in] proof: SNARK proof produced by the prover +// \param[in] srs: structured reference string +// \param[in] srs: structured reference string containing also +// circuit-specific information +// +// OUTPUT +// \param[out] boolean 1/0 = valid/invalid proof template bool plonk_verifier::step_twelve( const step_four_out_t &step_four_out, @@ -620,26 +620,26 @@ bool plonk_verifier::step_twelve( return b_accept; } -/// \attention The first three steps (as given in [GWC19] -- see -/// below) MUST be executed by the caller: -/// -/// - Verifier Step 1: validate that elements belong to group G1 -/// - Verifier Step 2: validate that elements belong to scalar field -/// Fr -/// - Verifier Step 3: validate that the public input belongs to -/// scalar field Fr -/// . -/// Therefore verification starts from Step 4 of [GWC19] -/// -/// INPUT -/// \param[in] proof: SNARK proof produced by the prover -/// \param[in] srs: structured reference string containing also -/// circuit-specific information -/// \param[in] transcript_hasher: hashes of the communication -/// transcript after prover rounds 1,2,3,4,5. -/// -/// OUTPUT -/// \param[out] boolean 1/0 = valid/invalid proof +// \attention The first three steps (as given in [GWC19] -- see +// below) MUST be executed by the caller: +// +// - Verifier Step 1: validate that elements belong to group G1 +// - Verifier Step 2: validate that elements belong to scalar field +// Fr +// - Verifier Step 3: validate that the public input belongs to +// scalar field Fr +// . +// Therefore verification starts from Step 4 of [GWC19] +// +// INPUT +// \param[in] proof: SNARK proof produced by the prover +// \param[in] srs: structured reference string containing also +// circuit-specific information +// \param[in] transcript_hasher: hashes of the communication +// transcript after prover rounds 1,2,3,4,5. +// +// OUTPUT +// \param[out] boolean 1/0 = valid/invalid proof template bool plonk_verifier::verify_proof( const plonk_proof &proof,