From 0c80f282455c437888472185d1edfe62d4e2457b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Fri, 17 Nov 2023 16:41:41 -0300 Subject: [PATCH 01/68] Added public input evals --- eth_verifier/lib/Oracles.sol | 69 ++++++++++++++++++++++++++++++++---- eth_verifier/lib/Proof.sol | 4 +-- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index a735731f..86625d68 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -7,6 +7,7 @@ import "./Evaluations.sol"; import "./Alphas.sol"; import "./sponge/Sponge.sol"; import "./Commitment.sol"; +import "./Proof.sol"; library Oracles { using {to_field_with_length, to_field} for ScalarChallenge; @@ -32,11 +33,17 @@ library Oracles { uint64 internal constant CHALLENGE_LENGTH_IN_LIMBS = 2; function fiat_shamir( + ProverProof memory proof, VerifierIndex storage index, PolyComm memory public_comm, + Scalar.FE[] memory public_input, + bool is_public_input_set, Sponge storage base_sponge, Sponge storage scalar_sponge ) public { + uint chunk_size = index.domain_size < index.max_poly_size ? + 1 : index.domain_size / index.max_poly_size; + Scalar.FE endo_coeff = Scalar.from(0); // FIXME: not zero base_sponge.reinit(); @@ -68,30 +75,80 @@ library Oracles { scalar_sponge.reinit(); scalar_sponge.absorb_scalar(base_sponge.digest_scalar()); - // often used values Scalar.FE zeta1 = zeta.pow(index.domain_size); Scalar.FE zetaw = zeta.mul(index.domain_gen); Scalar.FE[] memory evaluation_points = new Scalar.FE[](2); evaluation_points[0] = zeta; evaluation_points[1] = zetaw; - PointEvaluations memory powers_of_eval_points_for_chunks = PointEvaluations( zeta.pow(index.max_poly_size), zetaw.pow(index.max_poly_size) ); - //~ 20. Compute evaluations for the previous recursion challenges. SKIP + // TODO: Compute evaluations for the previous recursion challenges // retrieve ranges for the powers of alphas Alphas storage all_alphas = index.powers_of_alpha; all_alphas.instantiate(alpha); // evaluations of the public input - // if they are not present in the proof: - //~ 21. Evaluate the negated public polynomial (if present) at $\zeta$ and $\zeta\omega$. - // + + Scalar.FE[2][] public_evals; + if (proof.is_public_evals_set) { + public_evals = [proof.evals.zeta, proof.evals.zeta_omega]; + } else if (chunk_size > 1) { + // FIXME: error missing public input evaluation + } else if (is_public_input_set) { + // compute Lagrange base evaluation denominators + + Scalar.FE[] w = new Scalar.FE[](public_input.length); + Scalar.FE[] zeta_minus_x = new Scalar.FE[](public_input.length*2); + for (uint i = 0; i < public_input.length; i++) { + Scalar.FE w_i = index.domain_gen.pow(i); + w[i] = w_i; + zeta_minus_x[i] = zeta.sub(w_i).inv(); + zeta_minus_x[i + public_input.length] = zetaw.sub(w_i).inv(); + } + + // evaluate the negated public polynomial (if present) at $\zeta$ and $\zeta\omega$. + if (public_input.length == 0) { + Scalar.FE[] zero = new Scalar.FE[](1); + zero[0] = Scalar.zero(); + public_evals = [zero, zero]; + } else { + Scalar.FE pe_zeta = Scalar.zero(); + for (uint i = 0; i < public_input.length; i++) { + Scalar.FE p = public_input[i]; + Scalar.FE l = zeta_minus_x[i]; + Scalar.FE w_i = w[i]; + + pe_zeta = pe_zeta.add(l.neg().mul(p).mul(w_i)); + } + + Scalar.FE size_inv = Scalar.from(index.domain_size).inv(); + pe_zeta = pe_zeta.mul(zeta1.sub(Scalar.from(1))).mul(size_inv); + + Scalar.FE pe_zetaOmega = Scalar.zero(); + for (uint i = 0; i < public_input.length; i++) { + Scalar.FE p = public_input[i]; + Scalar.FE l = zeta_minus_x[i + public_input.length]; + Scalar.FE w_i = w[i]; + + pe_zetaOmega = pe_zetaOmega.add(l.neg().mul(p).mul(w_i)); + } + pe_zetaOmega = pe_zetaOmega + .mul(zetaw.pow(n).sub(Scalar.from(1))) + .mul(size_inv); + + public_evals = [[pe_zeta], [pe_zetaOmega]]; + } + } else { + // FIXME: error missing public input evaluation + } + + // TODO: absorb the unique evaluation of ft // -squeeze challenges- diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index c3ade411..4dea7214 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -8,6 +8,6 @@ struct ProverProof { } struct ProofEvaluations { - // array of length 1 serves as optional field - PointEvaluationsArray[] public_evals; + PointEvaluationsArray public_evals; + bool is_public_evals_set; // public_evals is optional } From 915c3e22ca5b71ac88b0f861a32661a22ba7e928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Fri, 17 Nov 2023 17:41:35 -0300 Subject: [PATCH 02/68] Fixes --- eth_verifier/lib/Oracles.sol | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index 86625d68..fab560a5 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -12,9 +12,11 @@ import "./Proof.sol"; library Oracles { using {to_field_with_length, to_field} for ScalarChallenge; using { + Scalar.neg, Scalar.add, + Scalar.sub, Scalar.mul, - Scalar.neg, + Scalar.inv, Scalar.double, Scalar.pow } for Scalar.FE; @@ -95,16 +97,16 @@ library Oracles { // evaluations of the public input - Scalar.FE[2][] public_evals; - if (proof.is_public_evals_set) { - public_evals = [proof.evals.zeta, proof.evals.zeta_omega]; + Scalar.FE[][2] memory public_evals; + if (proof.evals.is_public_evals_set) { + public_evals = [proof.evals.public_evals.zeta, proof.evals.public_evals.zeta_omega]; } else if (chunk_size > 1) { // FIXME: error missing public input evaluation } else if (is_public_input_set) { // compute Lagrange base evaluation denominators - Scalar.FE[] w = new Scalar.FE[](public_input.length); - Scalar.FE[] zeta_minus_x = new Scalar.FE[](public_input.length*2); + Scalar.FE[] memory w = new Scalar.FE[](public_input.length); + Scalar.FE[] memory zeta_minus_x = new Scalar.FE[](public_input.length*2); for (uint i = 0; i < public_input.length; i++) { Scalar.FE w_i = index.domain_gen.pow(i); w[i] = w_i; @@ -114,7 +116,7 @@ library Oracles { // evaluate the negated public polynomial (if present) at $\zeta$ and $\zeta\omega$. if (public_input.length == 0) { - Scalar.FE[] zero = new Scalar.FE[](1); + Scalar.FE[] memory zero = new Scalar.FE[](1); zero[0] = Scalar.zero(); public_evals = [zero, zero]; } else { @@ -139,10 +141,14 @@ library Oracles { pe_zetaOmega = pe_zetaOmega.add(l.neg().mul(p).mul(w_i)); } pe_zetaOmega = pe_zetaOmega - .mul(zetaw.pow(n).sub(Scalar.from(1))) + .mul(zetaw.pow(index.domain_size).sub(Scalar.from(1))) .mul(size_inv); - public_evals = [[pe_zeta], [pe_zetaOmega]]; + Scalar.FE[] memory pe_zeta_arr = new Scalar.FE[](1); + Scalar.FE[] memory pe_zetaOmega_arr = new Scalar.FE[](1); + pe_zeta_arr[0] = pe_zeta; + pe_zetaOmega_arr[0] = pe_zetaOmega; + public_evals = [pe_zeta_arr, pe_zetaOmega_arr]; } } else { // FIXME: error missing public input evaluation From 6ddd98d98d9d07140084734e65a14c9c3e6ee5b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Fri, 17 Nov 2023 18:22:37 -0300 Subject: [PATCH 03/68] Absorb public evals --- eth_verifier/lib/Oracles.sol | 5 +++++ eth_verifier/lib/sponge/Sponge.sol | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index fab560a5..13e5b399 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -25,6 +25,7 @@ library Oracles { KeccakSponge.reinit, KeccakSponge.absorb_base, KeccakSponge.absorb_scalar, + KeccakSponge.absorb_scalar_multiple, KeccakSponge.absorb_commitment, KeccakSponge.challenge_base, KeccakSponge.challenge_scalar, @@ -156,6 +157,10 @@ library Oracles { // TODO: absorb the unique evaluation of ft + // absorb the public evals + scalar_sponge.absorb_scalar_multiple(public_evals[0]); + scalar_sponge.absorb_scalar_multiple(public_evals[1]); + // -squeeze challenges- //~ 28. Create a list of all polynomials that have an evaluation proof. diff --git a/eth_verifier/lib/sponge/Sponge.sol b/eth_verifier/lib/sponge/Sponge.sol index bf7467fe..40288d4f 100644 --- a/eth_verifier/lib/sponge/Sponge.sol +++ b/eth_verifier/lib/sponge/Sponge.sol @@ -4,6 +4,7 @@ pragma solidity >=0.4.16 <0.9.0; import "../bn254/Fields.sol"; import "../bn254/BN254.sol"; import "../Commitment.sol"; +import "../Evaluations.sol"; struct Sponge { bytes state; @@ -55,6 +56,13 @@ library KeccakSponge { } } + function absorb_scalar_multiple(Sponge storage self, Scalar.FE[] memory elems) external { + bytes memory b = abi.encode(elems); + for (uint i = 0; i < b.length; i++) { + self.state.push(b[i]); + } + } + function absorb_g( Sponge storage self, BN254.G1Point memory point @@ -75,6 +83,13 @@ library KeccakSponge { } } + function absorb_evaluations(Sponge storage self, PointEvaluationsArray memory evals) external { + bytes memory b = abi.encode(evals); + for (uint i = 0; i < b.length; i++) { + self.state.push(b[i]); + } + } + function challenge_base( Sponge storage self ) external pure returns (Base.FE chal) { From ddc0ffc5e95c7f512316c8bd60b2a416094c3e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 20 Nov 2023 17:10:41 -0300 Subject: [PATCH 04/68] Added combined_evals and others --- eth_verifier/lib/Oracles.sol | 11 +++ eth_verifier/lib/Polynomial.sol | 26 +++++++ eth_verifier/lib/Proof.sol | 28 +++++++- eth_verifier/lib/msgpack/Deserialize.sol | 11 ++- eth_verifier/lib/sponge/Sponge.sol | 91 ++++++++++++++---------- eth_verifier/src/Verifier.sol | 4 +- eth_verifier/test/Integration.t.sol | 4 +- eth_verifier/test/State.t.sol | 4 +- 8 files changed, 128 insertions(+), 51 deletions(-) create mode 100644 eth_verifier/lib/Polynomial.sol diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index 13e5b399..22970ec6 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -27,11 +27,13 @@ library Oracles { KeccakSponge.absorb_scalar, KeccakSponge.absorb_scalar_multiple, KeccakSponge.absorb_commitment, + KeccakSponge.absorb_evaluations, KeccakSponge.challenge_base, KeccakSponge.challenge_scalar, KeccakSponge.digest_base, KeccakSponge.digest_scalar } for Sponge; + using {combine_evals} for ProofEvaluationsArray; uint64 internal constant CHALLENGE_LENGTH_IN_LIMBS = 2; @@ -160,6 +162,15 @@ library Oracles { // absorb the public evals scalar_sponge.absorb_scalar_multiple(public_evals[0]); scalar_sponge.absorb_scalar_multiple(public_evals[1]); + scalar_sponge.absorb_evaluations(proof.evals); + + ScalarChallenge memory v_chal = ScalarChallenge(scalar_sponge.challenge_scalar()); + Scalar.FE v = v_chal.to_field(endo_coeff); + + ScalarChallenge memory u_chal = ScalarChallenge(scalar_sponge.challenge_scalar()); + Scalar.FE u = u_chal.to_field(endo_coeff); + + proof.evals.combine_evals(powers_of_eval_points_for_chunks); // -squeeze challenges- diff --git a/eth_verifier/lib/Polynomial.sol b/eth_verifier/lib/Polynomial.sol new file mode 100644 index 00000000..aa9a6bbb --- /dev/null +++ b/eth_verifier/lib/Polynomial.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.4.16 <0.9.0; + +import "./bn254/Fields.sol"; + +library Polynomial { + using {Scalar.add, Scalar.mul} for Scalar.FE; + + struct Dense { + Scalar.FE[] coeffs; + } + + function evaluate(Dense memory self, Scalar.FE x) external pure returns (Scalar.FE result) { + result = Scalar.zero(); + for (uint i = 0; i < self.coeffs.length; i++) { + result = result.mul(x).add(self.coeffs[i]); + } + } + + function build_and_eval(Scalar.FE[] memory coeffs, Scalar.FE x) external pure returns (Scalar.FE result) { + result = Scalar.zero(); + for (uint i = 0; i < coeffs.length; i++) { + result = result.mul(x).add(coeffs[i]); + } + } +} diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index 4dea7214..61943c58 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -2,12 +2,38 @@ pragma solidity >=0.4.16 <0.9.0; import "./Evaluations.sol"; +import "./Polynomial.sol"; struct ProverProof { - ProofEvaluations evals; + ProofEvaluationsArray evals; } struct ProofEvaluations { + PointEvaluations public_evals; + bool is_public_evals_set; // public_evals is optional +} + +struct ProofEvaluationsArray { PointEvaluationsArray public_evals; bool is_public_evals_set; // public_evals is optional } + +function combine_evals( + ProofEvaluationsArray memory self, + PointEvaluations memory pt +) pure returns (ProofEvaluations memory) { + PointEvaluations memory public_evals; + if (self.is_public_evals_set) { + public_evals = PointEvaluations( + Polynomial.build_and_eval(self.public_evals.zeta, pt.zeta), + Polynomial.build_and_eval( + self.public_evals.zeta_omega, + pt.zeta_omega + ) + ); + } else { + public_evals = PointEvaluations(Scalar.zero(), Scalar.zero()); + } + + return ProofEvaluations(public_evals, self.is_public_evals_set); +} diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index d791820c..052f2b04 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -280,10 +280,10 @@ library MsgPk { final_i = i; } - function deserializeProofEvaluations( + function deserializeProofEvaluationsArray( bytes calldata data, uint256 i - ) public pure returns (ProofEvaluations memory evals, uint256 final_i) { + ) public pure returns (ProofEvaluationsArray memory evals, uint256 final_i) { // WARN: This works because the test circuit evaluations have one elem per array. ( PointEvaluations memory evals_non_array, @@ -295,16 +295,13 @@ library MsgPk { zeta[0] = evals_non_array.zeta; zeta_omega[0] = evals_non_array.zeta_omega; - PointEvaluationsArray memory _public_evals = PointEvaluationsArray( + PointEvaluationsArray memory public_evals = PointEvaluationsArray( zeta, zeta_omega ); // array needed to simulate an optional param - PointEvaluationsArray[] - memory public_evals = new PointEvaluationsArray[](1); - public_evals[0] = _public_evals; - evals = ProofEvaluations(public_evals); + evals = ProofEvaluationsArray(public_evals, true); final_i = _i; } diff --git a/eth_verifier/lib/sponge/Sponge.sol b/eth_verifier/lib/sponge/Sponge.sol index 40288d4f..bb3d2c40 100644 --- a/eth_verifier/lib/sponge/Sponge.sol +++ b/eth_verifier/lib/sponge/Sponge.sol @@ -4,7 +4,7 @@ pragma solidity >=0.4.16 <0.9.0; import "../bn254/Fields.sol"; import "../bn254/BN254.sol"; import "../Commitment.sol"; -import "../Evaluations.sol"; +import "../Proof.sol"; struct Sponge { bytes state; @@ -18,19 +18,20 @@ library KeccakSponge { } function absorb(Sponge storage self, bytes memory b) external { - for (uint i = 0; i < b.length; i++) { + for (uint256 i = 0; i < b.length; i++) { self.state.push(b[i]); } } - function squeeze( - Sponge memory self, - uint byte_count - ) public pure returns (bytes memory digest) { + function squeeze(Sponge memory self, uint256 byte_count) + public + pure + returns (bytes memory digest) + { digest = new bytes(byte_count); bytes32 output; - for (uint i = 0; i < byte_count; i++) { + for (uint256 i = 0; i < byte_count; i++) { if (i % 32 == 0) { output = keccak256(self.state); self.state = abi.encode(output); @@ -44,73 +45,89 @@ library KeccakSponge { function absorb_base(Sponge storage self, Base.FE elem) external { bytes memory b = abi.encode(elem); - for (uint i = 0; i < b.length; i++) { + for (uint256 i = 0; i < b.length; i++) { self.state.push(b[i]); } } function absorb_scalar(Sponge storage self, Scalar.FE elem) external { bytes memory b = abi.encode(elem); - for (uint i = 0; i < b.length; i++) { + for (uint256 i = 0; i < b.length; i++) { self.state.push(b[i]); } } - function absorb_scalar_multiple(Sponge storage self, Scalar.FE[] memory elems) external { + function absorb_scalar_multiple( + Sponge storage self, + Scalar.FE[] memory elems + ) external { bytes memory b = abi.encode(elems); - for (uint i = 0; i < b.length; i++) { + for (uint256 i = 0; i < b.length; i++) { self.state.push(b[i]); } } - function absorb_g( - Sponge storage self, - BN254.G1Point memory point - ) external { + function absorb_g(Sponge storage self, BN254.G1Point memory point) + external + { bytes memory b = abi.encode(point); - for (uint i = 0; i < b.length; i++) { + for (uint256 i = 0; i < b.length; i++) { self.state.push(b[i]); } } - function absorb_commitment( - Sponge storage self, - PolyComm memory comm - ) external { + function absorb_commitment(Sponge storage self, PolyComm memory comm) + external + { bytes memory b = abi.encode(comm); - for (uint i = 0; i < b.length; i++) { + for (uint256 i = 0; i < b.length; i++) { self.state.push(b[i]); } } - function absorb_evaluations(Sponge storage self, PointEvaluationsArray memory evals) external { - bytes memory b = abi.encode(evals); - for (uint i = 0; i < b.length; i++) { - self.state.push(b[i]); + function absorb_evaluations( + Sponge storage self, + ProofEvaluationsArray memory evals + ) external { + bytes[] memory b = new bytes[](1); + b[0] = evals.is_public_evals_set + ? abi.encode(evals.public_evals) + : abi.encode(0); + + for (uint256 i = 0; i < b.length; i++) { + self.state.push((b[0])[i]); } } - function challenge_base( - Sponge storage self - ) external pure returns (Base.FE chal) { + function challenge_base(Sponge storage self) + external + pure + returns (Base.FE chal) + { chal = Base.from_bytes_be(squeeze(self, 16)); } - function challenge_scalar( - Sponge storage self - ) external pure returns (Scalar.FE chal) { + function challenge_scalar(Sponge storage self) + external + pure + returns (Scalar.FE chal) + { chal = Scalar.from_bytes_be(squeeze(self, 16)); } - function digest_base( - Sponge storage self - ) external pure returns (Base.FE digest) { + function digest_base(Sponge storage self) + external + pure + returns (Base.FE digest) + { digest = Base.from_bytes_be(squeeze(self, 32)); } - function digest_scalar( - Sponge storage self - ) external pure returns (Scalar.FE digest) { + function digest_scalar(Sponge storage self) + external + pure + returns (Scalar.FE digest) + { digest = Scalar.from_bytes_be(squeeze(self, 32)); } } diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 6db94bfd..a9b1a649 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -60,7 +60,7 @@ contract KimchiVerifier { uint256 public_len, uint256 domain_size, uint256 max_poly_size, - ProofEvaluations memory evals + ProofEvaluationsArray memory evals ) public { for (uint i = 0; i < g.length; i++) { verifier_index.urs.g.push(g[i]); @@ -159,7 +159,7 @@ contract KimchiVerifier { ).commitment; } - Oracles.fiat_shamir(verifier_index, public_comm, base_sponge, scalar_sponge); + Oracles.fiat_shamir(proof, verifier_index, public_comm, public_inputs, true, base_sponge, scalar_sponge); } /* diff --git a/eth_verifier/test/Integration.t.sol b/eth_verifier/test/Integration.t.sol index ea517e98..0f643d6c 100644 --- a/eth_verifier/test/Integration.t.sol +++ b/eth_verifier/test/Integration.t.sol @@ -19,8 +19,8 @@ contract DeserializeTest is Test { KimchiVerifier verifier = new KimchiVerifier(); (BN254.G1Point[] memory g, BN254.G1Point memory h, uint256 _i0) = MsgPk .deserializeURS(urs_serialized); - (ProofEvaluations memory evals, uint256 _i1) = MsgPk - .deserializeProofEvaluations(evals_serialized, 0); + (ProofEvaluationsArray memory evals, uint256 _i1) = MsgPk + .deserializeProofEvaluationsArray(evals_serialized, 0); verifier.setup(g, h, 0, 32, 32, evals); verifier.partial_verify(new Scalar.FE[](0)); diff --git a/eth_verifier/test/State.t.sol b/eth_verifier/test/State.t.sol index 3f67563d..d2ca98bb 100644 --- a/eth_verifier/test/State.t.sol +++ b/eth_verifier/test/State.t.sol @@ -17,8 +17,8 @@ contract StateTest is Test { (BN254.G1Point[] memory g, BN254.G1Point memory h, uint256 _i0) = MsgPk .deserializeURS(urs_serialized); - (ProofEvaluations memory evals, uint256 _i1) = MsgPk - .deserializeProofEvaluations(evals_serialized, 0); + (ProofEvaluationsArray memory evals, uint256 _i1) = MsgPk + .deserializeProofEvaluationsArray(evals_serialized, 0); verifier = new KimchiVerifier(); verifier.setup(g, h, 0, 32, 32, evals); From ad0758cb045c9de547e3b139be58e476465ea362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 20 Nov 2023 18:00:23 -0300 Subject: [PATCH 05/68] Added get alphas --- eth_verifier/lib/Alphas.sol | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/eth_verifier/lib/Alphas.sol b/eth_verifier/lib/Alphas.sol index 822ac8a9..c346b04e 100644 --- a/eth_verifier/lib/Alphas.sol +++ b/eth_verifier/lib/Alphas.sol @@ -37,6 +37,42 @@ library AlphasLib { self.alphas.push(last_power); } } + + /// @notice retrieves the powers of alpha, upperbounded by `num` + function get_alphas(Alphas storage self, ArgumentType ty, uint num) external view returns (Scalar.FE[] memory pows) { + if (ty == ArgumentType.GateZero || + ty == ArgumentType.GateGeneric || + ty == ArgumentType.GatePoseidon || + ty == ArgumentType.GateCompleteAdd || + ty == ArgumentType.GateVarBaseMul || + ty == ArgumentType.GateEndoMul || + ty == ArgumentType.GateEndoMulScalar || + ty == ArgumentType.GateLookup || + ty == ArgumentType.GateCairoClaim || + ty == ArgumentType.GateCairoInstruction || + ty == ArgumentType.GateCairoFlags || + ty == ArgumentType.GateCairoTransition || + ty == ArgumentType.GateRangeCheck0 || + ty == ArgumentType.GateRangeCheck1 || + ty == ArgumentType.GateForeignFieldAdd || + ty == ArgumentType.GateForeignFieldMul || + ty == ArgumentType.GateXor16 || + ty == ArgumentType.GateRot64) + { + ty = ArgumentType.GateZero; + } + + uint[2] memory range = self.map[ty]; + if (num > range[1]) { + // FIXME: panic! asked for num alphas but there aren't as many. + } + + for (uint i = 0; i < num; i++) { + pows[i] = self.alphas[range[0]+i]; + } + // INFO: in kimchi this returns a "MustConsumeIterator", which warns you if + // not consumed entirely. + } } enum ArgumentType { From 36d39b605912418b6a9700859771f96df2a12882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 20 Nov 2023 18:41:09 -0300 Subject: [PATCH 06/68] Minor --- eth_verifier/lib/Oracles.sol | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index 22970ec6..0be4867d 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -170,11 +170,7 @@ library Oracles { ScalarChallenge memory u_chal = ScalarChallenge(scalar_sponge.challenge_scalar()); Scalar.FE u = u_chal.to_field(endo_coeff); - proof.evals.combine_evals(powers_of_eval_points_for_chunks); - - // -squeeze challenges- - - //~ 28. Create a list of all polynomials that have an evaluation proof. + ProofEvaluations memory evals = proof.evals.combine_evals(powers_of_eval_points_for_chunks); //~ 29. Compute the evaluation of $ft(\zeta)$. From baf4c3c6ba38c9045c8269cb61a7e87592aca432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Tue, 21 Nov 2023 13:10:56 -0300 Subject: [PATCH 07/68] Progress on ft eval --- eth_verifier/lib/Alphas.sol | 6 +++- eth_verifier/lib/Constants.sol | 7 ++++ eth_verifier/lib/Oracles.sol | 51 ++++++++++++++++++++++++++++-- eth_verifier/lib/Proof.sol | 12 +++++++ eth_verifier/lib/VerifierIndex.sol | 6 ++++ 5 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 eth_verifier/lib/Constants.sol diff --git a/eth_verifier/lib/Alphas.sol b/eth_verifier/lib/Alphas.sol index c346b04e..0c17dbb1 100644 --- a/eth_verifier/lib/Alphas.sol +++ b/eth_verifier/lib/Alphas.sol @@ -39,7 +39,11 @@ library AlphasLib { } /// @notice retrieves the powers of alpha, upperbounded by `num` - function get_alphas(Alphas storage self, ArgumentType ty, uint num) external view returns (Scalar.FE[] memory pows) { + function get_alphas(Alphas storage self, ArgumentType ty, uint num) + external + view + returns (Scalar.FE[] memory pows) + { if (ty == ArgumentType.GateZero || ty == ArgumentType.GateGeneric || ty == ArgumentType.GatePoseidon || diff --git a/eth_verifier/lib/Constants.sol b/eth_verifier/lib/Constants.sol new file mode 100644 index 00000000..f0fc6465 --- /dev/null +++ b/eth_verifier/lib/Constants.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.4.16 <0.9.0; + +library Constants { + uint public constant COLUMNS = 15; + uint public constant PERMUTS = 7; +} diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index 0be4867d..cef98dbe 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -8,6 +8,8 @@ import "./Alphas.sol"; import "./sponge/Sponge.sol"; import "./Commitment.sol"; import "./Proof.sol"; +import "./Polynomial.sol"; +import "./Constants.sol"; library Oracles { using {to_field_with_length, to_field} for ScalarChallenge; @@ -20,7 +22,7 @@ library Oracles { Scalar.double, Scalar.pow } for Scalar.FE; - using {AlphasLib.instantiate} for Alphas; + using {AlphasLib.instantiate, AlphasLib.get_alphas} for Alphas; using { KeccakSponge.reinit, KeccakSponge.absorb_base, @@ -172,7 +174,52 @@ library Oracles { ProofEvaluations memory evals = proof.evals.combine_evals(powers_of_eval_points_for_chunks); - //~ 29. Compute the evaluation of $ft(\zeta)$. + // compute the evaluation of $ft(\zeta)$. + Scalar.FE ft_eval0; + // FIXME: evaluate permutation vanishing poly in zeta + Scalar.FE permutation_vanishing_poly = Scalar.from(1); + Scalar.FE zeta1m1 = zeta1.sub(Scalar.from(1)); + + uint permutation_constraints = 3; + Scalar.FE[] memory alpha_pows = all_alphas.get_alphas(ArgumentType.Permutation, permutation_constraints); + Scalar.FE alpha0 = alpha_pows[0]; + Scalar.FE alpha1 = alpha_pows[1]; + Scalar.FE alpha2 = alpha_pows[2]; + // WARN: alpha_powers should be an iterator and alphai = alpha_powers.next(), for i = 0,1,2. + + Scalar.FE ft_eval0 = evals.w[Constants.PERMUTS - 1].zeta.add(gamma) + .mul(evals.z.zeta_omega) + .mul(alpha0) + .mul(permutation_vanishing_poly); + + for (uint i = 0; i < permuts - 1; i++) { + Scalar.FE w = evals.w[i]; + Scalar.FE s = evals.s[i]; + ft_eval0 = init.mul(beta.mul(s.zeta).add(w.zeta).add(gamma)); + } + + ft_eval0 = ft_eval0.sub( + Polynomial.build_and_eval( + public_evals[0], + powers_of_eval_points_for_chunks.zeta + )); + + Scalar.FE ev = alpha0.mul(permutation_vanishing_poly).mul(evals.z.zeta); + for (uint i = 0; i < permuts; i++) { + Scalar.FE w = evals.w[i]; + Scalar.FE s = index.shift[i]; + + ev = ev.mul(gamma.add(beta.mul(zeta).mul(s)).add(w.zeta)); + } + ft_eval0 = ft_eval0.sub(ev); + + Scalar.FE numerator = zeta1m1.mul(alpha1).mul(zeta.sub(index.w)) + .add(zeta1m1.mul(alpha2).mul(zeta.sub(Scalar.from(1)))) + .mul(Scalar.from(1).sub(evals.z.zeta)); + + Scalar.FE denominator = zeta.sub(index.w).mul(zeta.sub(Scalar.from(1))).inv(); + + ft_eval0 = ft_eval0.add(numerator.mul(denominator)); // evaluate final polynomial (PolishToken) // combined inner prod diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index 61943c58..ea6b59eb 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -3,14 +3,26 @@ pragma solidity >=0.4.16 <0.9.0; import "./Evaluations.sol"; import "./Polynomial.sol"; +import "./Constants.sol"; struct ProverProof { ProofEvaluationsArray evals; } struct ProofEvaluations { + // public inputs polynomials PointEvaluations public_evals; bool is_public_evals_set; // public_evals is optional + + // witness polynomials + PointEvaluations[15] w; // TODO: use Constants.COLUMNS + + // permutation polynomial + PointEvaluations z; + + // permutation polynomials + // (PERMUTS-1 evaluations because the last permutation is only used in commitment form) + PointEvaluations[7 - 1] s; // TODO: use Constants.PERMUTS } struct ProofEvaluationsArray { diff --git a/eth_verifier/lib/VerifierIndex.sol b/eth_verifier/lib/VerifierIndex.sol index 47c69ce6..85ab949d 100644 --- a/eth_verifier/lib/VerifierIndex.sol +++ b/eth_verifier/lib/VerifierIndex.sol @@ -8,12 +8,18 @@ import "./Alphas.sol"; import "./Evaluations.sol"; struct VerifierIndex { + // number of public inputs uint256 public_len; + // maximal size of polynomial section uint256 max_poly_size; URS urs; + // domain uint256 domain_size; Scalar.FE domain_gen; + /// The mapping between powers of alpha and constraints Alphas powers_of_alpha; + // wire shift coordinates + Scalar.FE[7] shift; // TODO: use Consants.PERMUTS } function verifier_digest(VerifierIndex storage index) returns (Base.FE) { From 244bf96efbb5bf1a8abe5d6b6e7312d39c17bfb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Tue, 21 Nov 2023 17:25:49 -0300 Subject: [PATCH 08/68] Added combined inner prod --- eth_verifier/lib/Commitment.sol | 43 ++++++++++++++++++++++++++++++ eth_verifier/lib/Oracles.sol | 22 +++++++-------- eth_verifier/lib/VerifierIndex.sol | 2 ++ 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index fe835a79..25bbeb73 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -182,3 +182,46 @@ function calculate_lagrange_bases( } } } + +// Computes the linearization of the evaluations of a (potentially split) polynomial. +// Each given `poly` is associated to a matrix where the rows represent the number of evaluated points, +// and the columns represent potential segments (if a polynomial was split in several parts). +// Note that if one of the polynomial comes specified with a degree bound, +// the evaluation for the last segment is potentially shifted to meet the proof. +function combined_inner_product( + Scalar.FE[] memory evaluation_points, + Scalar.FE polyscale, + Scalar.FE evalscale, + Scalar.FE[][][] poly_matrices, + //uint[] poly_shifted, // TODO: not necessary for fiat-shamir + uint srs_length +) pure returns (Scalar.FE res) { + res = Scalar.zero(); + Scalar.FE xi_i = Scalar.from(1); + + require(poly_matrices.length == poly_shifted.length); + for (uint i = 0; i < poly_matrices.length; i++) { + Scalar.FE[][] memory evals = poly_matrices[i]; + uint shifted = poly_shifted[i]; + + if (evals[0].length == 0) { + continue; + } + + uint rows = evals.length; + uint columns = evals.length[0]; + for (uint col = 0; col < columns; col++) { + Scalar.FE[] eval = new Scalar[](rows); // column that stores the segment + + for (uint j = 0; j < rows; j++) { + eval[j] = evals[col + j*columns]; + } + Scalar.FE term = Polynomial.build_and_eval(eval, evalscale); + + res = res.add(xi_i.mul(term)); + xi_i = xi_i.mul(polyscale); + } + + // TODO: shifted + } +} diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index cef98dbe..f0dc6137 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -175,9 +175,7 @@ library Oracles { ProofEvaluations memory evals = proof.evals.combine_evals(powers_of_eval_points_for_chunks); // compute the evaluation of $ft(\zeta)$. - Scalar.FE ft_eval0; - // FIXME: evaluate permutation vanishing poly in zeta - Scalar.FE permutation_vanishing_poly = Scalar.from(1); + Scalar.FE permutation_vanishing_poly = Scalar.from(1); // FIXME: evaluate poly in zeta Scalar.FE zeta1m1 = zeta1.sub(Scalar.from(1)); uint permutation_constraints = 3; @@ -192,10 +190,10 @@ library Oracles { .mul(alpha0) .mul(permutation_vanishing_poly); - for (uint i = 0; i < permuts - 1; i++) { - Scalar.FE w = evals.w[i]; - Scalar.FE s = evals.s[i]; - ft_eval0 = init.mul(beta.mul(s.zeta).add(w.zeta).add(gamma)); + for (uint i = 0; i < Constants.PERMUTS - 1; i++) { + PointEvaluations memory w = evals.w[i]; + PointEvaluations memory s = evals.s[i]; + ft_eval0 = ft_eval0.mul(beta.mul(s.zeta).add(w.zeta).add(gamma)); } ft_eval0 = ft_eval0.sub( @@ -205,8 +203,8 @@ library Oracles { )); Scalar.FE ev = alpha0.mul(permutation_vanishing_poly).mul(evals.z.zeta); - for (uint i = 0; i < permuts; i++) { - Scalar.FE w = evals.w[i]; + for (uint i = 0; i < Constants.PERMUTS; i++) { + PointEvaluations memory w = evals.w[i]; Scalar.FE s = index.shift[i]; ev = ev.mul(gamma.add(beta.mul(zeta).mul(s)).add(w.zeta)); @@ -221,8 +219,10 @@ library Oracles { ft_eval0 = ft_eval0.add(numerator.mul(denominator)); - // evaluate final polynomial (PolishToken) - // combined inner prod + // TODO: evaluate final polynomial (PolishToken) + + // TODO: evaluations of all columns + Scalar.FE combined_inner_prod = combined_inner_product(evaluation_points, v, u, es, index.max_poly_size); } struct ScalarChallenge { diff --git a/eth_verifier/lib/VerifierIndex.sol b/eth_verifier/lib/VerifierIndex.sol index 85ab949d..614cfa83 100644 --- a/eth_verifier/lib/VerifierIndex.sol +++ b/eth_verifier/lib/VerifierIndex.sol @@ -20,6 +20,8 @@ struct VerifierIndex { Alphas powers_of_alpha; // wire shift coordinates Scalar.FE[7] shift; // TODO: use Consants.PERMUTS + /// domain offset for zero-knowledge + Scalar.FE w; } function verifier_digest(VerifierIndex storage index) returns (Base.FE) { From 17c56ceb28ab6fe42690cddb0d124945137c5fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Tue, 21 Nov 2023 18:56:50 -0300 Subject: [PATCH 09/68] Fixing comb inn prod --- eth_verifier/lib/Commitment.sol | 13 ++++++++++--- eth_verifier/lib/Oracles.sol | 11 +++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 25bbeb73..c03e9769 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -192,7 +192,7 @@ function combined_inner_product( Scalar.FE[] memory evaluation_points, Scalar.FE polyscale, Scalar.FE evalscale, - Scalar.FE[][][] poly_matrices, + Scalar.FE[] memory flat_poly_matrices, // this is 3-dim; an array of matrices //uint[] poly_shifted, // TODO: not necessary for fiat-shamir uint srs_length ) pure returns (Scalar.FE res) { @@ -204,12 +204,12 @@ function combined_inner_product( Scalar.FE[][] memory evals = poly_matrices[i]; uint shifted = poly_shifted[i]; - if (evals[0].length == 0) { + if (evals[i].length == 0) { continue; } uint rows = evals.length; - uint columns = evals.length[0]; + uint columns = evals.length; for (uint col = 0; col < columns; col++) { Scalar.FE[] eval = new Scalar[](rows); // column that stores the segment @@ -225,3 +225,10 @@ function combined_inner_product( // TODO: shifted } } + +struct PolyMatrices { + Scalar.FE[] flat_data; + uint length; + uint[] rows; // per matrix + uint[] cols; // per matrix +} diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index f0dc6137..9a4e995a 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -221,6 +221,17 @@ library Oracles { // TODO: evaluate final polynomial (PolishToken) + uint es_length = 0; + es_length += public_evals[0].length; + es_length += public_evals[1].length; + es_length += [ft_eval0].length; + + uint matrix_count = 3; + + + Scalar.FE[] es_data = new Scalar.FE[](es_length); + PolyMatrices memory es = PolyMatrices(es_data, matrix_count) + es[0] = public_evals; // TODO: evaluations of all columns Scalar.FE combined_inner_prod = combined_inner_product(evaluation_points, v, u, es, index.max_poly_size); } From f12cbefa4a9b60d730df66f18601f711f4971e08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Wed, 22 Nov 2023 16:12:32 -0300 Subject: [PATCH 10/68] Fixed 3d array prob --- eth_verifier/lib/Commitment.sol | 23 ++++++++-------- eth_verifier/lib/Oracles.sol | 47 ++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index c03e9769..6dca5424 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -192,29 +192,27 @@ function combined_inner_product( Scalar.FE[] memory evaluation_points, Scalar.FE polyscale, Scalar.FE evalscale, - Scalar.FE[] memory flat_poly_matrices, // this is 3-dim; an array of matrices + PolyMatrices[] memory polys, //uint[] poly_shifted, // TODO: not necessary for fiat-shamir uint srs_length ) pure returns (Scalar.FE res) { res = Scalar.zero(); Scalar.FE xi_i = Scalar.from(1); - require(poly_matrices.length == poly_shifted.length); - for (uint i = 0; i < poly_matrices.length; i++) { - Scalar.FE[][] memory evals = poly_matrices[i]; - uint shifted = poly_shifted[i]; + //require(poly_matrices.length == poly_shifted.length); + for (uint i = 0; i < polys.length; i++) { + uint cols = polys.cols[i]; + uint rows = polys.rows[i]; - if (evals[i].length == 0) { + if (cols[i].length == 0) { continue; } - uint rows = evals.length; - uint columns = evals.length; - for (uint col = 0; col < columns; col++) { + for (uint col = 0; col < cols; col++) { Scalar.FE[] eval = new Scalar[](rows); // column that stores the segment for (uint j = 0; j < rows; j++) { - eval[j] = evals[col + j*columns]; + eval[j] = evals[polys.starts[i] + col*rows + j]; } Scalar.FE term = Polynomial.build_and_eval(eval, evalscale); @@ -229,6 +227,7 @@ function combined_inner_product( struct PolyMatrices { Scalar.FE[] flat_data; uint length; - uint[] rows; // per matrix - uint[] cols; // per matrix + uint[] rows; // row count per matrix + uint[] cols; // col count per matrix + uint[] starts; // index at which every matrix starts } diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index 9a4e995a..99c0dee1 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -221,18 +221,47 @@ library Oracles { // TODO: evaluate final polynomial (PolishToken) - uint es_length = 0; - es_length += public_evals[0].length; - es_length += public_evals[1].length; - es_length += [ft_eval0].length; + uint matrix_count = 2; + uint total_length = 0; + uint[] rows = new uint[](matrix_count); + uint[] cols = new uint[](matrix_count); + + // public evals + rows[0] = public_evals.length; + cols[0] = public_evals[0].length; + total_length += public_evals[0].length; + total_length += public_evals[1].length; + + // ft evals + total_length += [[ft_eval0]].length; + rows[1] = [[ft_eval0]].length; + cols[2] = [[ft_eval0]][0].length; + + // save the data in a flat array in a column-major so there's no neeed + // to transpose each matrix later. + Scalar.FE[] es_data = new Scalar.FE[](es_length); + uint[] starts = new uint[](matrix_count); + uint index = 0; + + starts[0] = index; + for (uint i = 0; i < rows[0] * cols[0]; i++) { + uint col = i % cols[0]; + uint row = i / cols[0]; + es_data[i] = public_evals[col][row]; + index++; + } - uint matrix_count = 3; + starts[1] = index; + for (uint i = 0; i < rows[1] * cols[1]; i++) { + uint col = i % cols[0]; + uint row = i / cols[0]; + es_data[i] = [[ft_eval0]][col][row]; // TODO: ft_eval1; + index++; + } + PolyMatrices memory es = PolyMatrices(es_data, matrix_count, rows, cols); + // TODO: add evaluations of all columns - Scalar.FE[] es_data = new Scalar.FE[](es_length); - PolyMatrices memory es = PolyMatrices(es_data, matrix_count) - es[0] = public_evals; - // TODO: evaluations of all columns Scalar.FE combined_inner_prod = combined_inner_product(evaluation_points, v, u, es, index.max_poly_size); } From 25d26cebbcc6d35447ee8b888b09566445e6538a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Wed, 22 Nov 2023 16:58:49 -0300 Subject: [PATCH 11/68] Fix compile errors: --- eth_verifier/lib/Commitment.sol | 20 +++- eth_verifier/lib/Oracles.sol | 27 +++-- eth_verifier/lib/Proof.sol | 34 +++++- eth_verifier/lib/msgpack/Deserialize.sol | 139 ++++++++++++++--------- 4 files changed, 149 insertions(+), 71 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 6dca5424..54c97207 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -4,8 +4,18 @@ pragma solidity >=0.4.16 <0.9.0; import "./bn254/BN254.sol"; import "./bn254/Fields.sol"; import "./Utils.sol"; +import "./Polynomial.sol"; using { BN254.add, BN254.scale_scalar } for BN254.G1Point; +using { + Scalar.neg, + Scalar.add, + Scalar.sub, + Scalar.mul, + Scalar.inv, + Scalar.double, + Scalar.pow +} for Scalar.FE; error MSMInvalidLengths(); @@ -192,7 +202,7 @@ function combined_inner_product( Scalar.FE[] memory evaluation_points, Scalar.FE polyscale, Scalar.FE evalscale, - PolyMatrices[] memory polys, + PolyMatrices memory polys, //uint[] poly_shifted, // TODO: not necessary for fiat-shamir uint srs_length ) pure returns (Scalar.FE res) { @@ -204,15 +214,15 @@ function combined_inner_product( uint cols = polys.cols[i]; uint rows = polys.rows[i]; - if (cols[i].length == 0) { + if (cols == 0) { continue; } for (uint col = 0; col < cols; col++) { - Scalar.FE[] eval = new Scalar[](rows); // column that stores the segment + Scalar.FE[] memory eval = new Scalar.FE[](rows); // column that stores the segment for (uint j = 0; j < rows; j++) { - eval[j] = evals[polys.starts[i] + col*rows + j]; + eval[j] = polys.data[polys.starts[i] + col*rows + j]; } Scalar.FE term = Polynomial.build_and_eval(eval, evalscale); @@ -225,7 +235,7 @@ function combined_inner_product( } struct PolyMatrices { - Scalar.FE[] flat_data; + Scalar.FE[] data; uint length; uint[] rows; // row count per matrix uint[] cols; // col count per matrix diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index 99c0dee1..3c857034 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -223,43 +223,42 @@ library Oracles { uint matrix_count = 2; uint total_length = 0; - uint[] rows = new uint[](matrix_count); - uint[] cols = new uint[](matrix_count); + uint[] memory rows = new uint[](matrix_count); + uint[] memory cols = new uint[](matrix_count); // public evals rows[0] = public_evals.length; cols[0] = public_evals[0].length; - total_length += public_evals[0].length; - total_length += public_evals[1].length; + total_length += rows[0] * cols[0]; // ft evals - total_length += [[ft_eval0]].length; rows[1] = [[ft_eval0]].length; - cols[2] = [[ft_eval0]][0].length; + cols[1] = [[ft_eval0]][0].length; + total_length += rows[1] * cols[1]; // save the data in a flat array in a column-major so there's no neeed // to transpose each matrix later. - Scalar.FE[] es_data = new Scalar.FE[](es_length); - uint[] starts = new uint[](matrix_count); - uint index = 0; + Scalar.FE[] memory es_data = new Scalar.FE[](total_length); + uint[] memory starts = new uint[](matrix_count); + uint curr = 0; - starts[0] = index; + starts[0] = curr; for (uint i = 0; i < rows[0] * cols[0]; i++) { uint col = i % cols[0]; uint row = i / cols[0]; es_data[i] = public_evals[col][row]; - index++; + curr++; } - starts[1] = index; + starts[1] = curr; for (uint i = 0; i < rows[1] * cols[1]; i++) { uint col = i % cols[0]; uint row = i / cols[0]; es_data[i] = [[ft_eval0]][col][row]; // TODO: ft_eval1; - index++; + curr++; } - PolyMatrices memory es = PolyMatrices(es_data, matrix_count, rows, cols); + PolyMatrices memory es = PolyMatrices(es_data, matrix_count, rows, cols, starts); // TODO: add evaluations of all columns Scalar.FE combined_inner_prod = combined_inner_product(evaluation_points, v, u, es, index.max_poly_size); diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index ea6b59eb..fb259b3e 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -28,6 +28,16 @@ struct ProofEvaluations { struct ProofEvaluationsArray { PointEvaluationsArray public_evals; bool is_public_evals_set; // public_evals is optional + + // witness polynomials + PointEvaluationsArray[15] w; // TODO: use Constants.COLUMNS + + // permutation polynomial + PointEvaluationsArray z; + + // permutation polynomials + // (PERMUTS-1 evaluations because the last permutation is only used in commitment form) + PointEvaluationsArray[7 - 1] s; // TODO: use Constants.PERMUTS } function combine_evals( @@ -47,5 +57,27 @@ function combine_evals( public_evals = PointEvaluations(Scalar.zero(), Scalar.zero()); } - return ProofEvaluations(public_evals, self.is_public_evals_set); + PointEvaluations[15] memory w; + for (uint i = 0; i < 15; i++) { + w[i] = PointEvaluations( + Polynomial.build_and_eval(self.w[i].zeta, pt.zeta), + Polynomial.build_and_eval(self.w[i].zeta_omega, pt.zeta_omega) + ); + } + + PointEvaluations memory z; + z = PointEvaluations( + Polynomial.build_and_eval(self.z.zeta, pt.zeta), + Polynomial.build_and_eval(self.z.zeta_omega, pt.zeta_omega) + ); + + PointEvaluations[7 - 1] memory s; + for (uint i = 0; i < 7 - 1; i++) { + s[i] = PointEvaluations( + Polynomial.build_and_eval(self.s[i].zeta, pt.zeta), + Polynomial.build_and_eval(self.s[i].zeta_omega, pt.zeta_omega) + ); + } + + return ProofEvaluations(public_evals, self.is_public_evals_set, w, z, s); } diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 052f2b04..3f356a3a 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -12,7 +12,7 @@ import "../Utils.sol"; library MsgPk { struct Stream { bytes data; - uint curr_index; + uint256 curr_index; } struct EncodedArray { @@ -24,7 +24,11 @@ library MsgPk { bytes[] values; } - function from_data(bytes calldata data) public pure returns (Stream memory) { + function from_data(bytes calldata data) + public + pure + returns (Stream memory) + { return Stream(data, 0); } @@ -39,20 +43,26 @@ library MsgPk { return self.data[self.curr_index]; } - function next_n( - Stream memory self, - uint n - ) public pure returns (bytes memory consumed) { + function next_n(Stream memory self, uint256 n) + public + pure + returns (bytes memory consumed) + { consumed = new bytes(n); - for (uint i = 1; i <= n; i++) { + for (uint256 i = 1; i <= n; i++) { consumed[i] = self.data[self.curr_index + i]; } self.curr_index += n; } error NonImplementedType(); + /// @notice deserializes the next type and returns the encoded data. - function trim_encode(Stream memory self) public pure returns (bytes memory) { + function trim_encode(Stream memory self) + public + pure + returns (bytes memory) + { bytes1 prefix = curr(self); if (prefix >> 5 == 0x05) { return abi.encode(deser_fixstr(self)); @@ -65,10 +75,14 @@ library MsgPk { } } - function deser_fixstr(Stream memory self) public pure returns (string memory) { + function deser_fixstr(Stream memory self) + public + pure + returns (string memory) + { bytes1 first = next(self); require(first >> 5 == 0x05, "not a fixstr"); - uint n = uint256(uint8(first & 0x1F)); // low nibble + lsb of high nibble + uint256 n = uint256(uint8(first & 0x1F)); // low nibble + lsb of high nibble return string(next_n(self, n)); } @@ -77,38 +91,45 @@ library MsgPk { require(next(self) == 0xC4, "not a stream of bin8 (bytes)"); // next byte is the length of the stream in one byte - uint n = uint256(uint8(next(self))); + uint256 n = uint256(uint8(next(self))); // read data return next_n(self, n); } - function deser_fixarr(Stream memory self) public pure returns (EncodedArray memory arr) { + function deser_fixarr(Stream memory self) + public + pure + returns (EncodedArray memory arr) + { bytes1 first = next(self); require(first >> 4 == 0x09, "not a fixarr"); - uint n = uint256(uint8(first & 0x0F)); // low nibble + uint256 n = uint256(uint8(first & 0x0F)); // low nibble arr = EncodedArray(new bytes[](n)); - for (uint i = 0; i < n; i++) { + for (uint256 i = 0; i < n; i++) { arr.values[i] = trim_encode(self); } } - function deser_fixmap(Stream memory self) public pure returns (EncodedMap memory map) { + function deser_fixmap(Stream memory self) + public + pure + returns (EncodedMap memory map) + { bytes1 first = next(self); require(first >> 4 == 0x08, "not a fixmap"); - uint n = uint256(uint8(first & 0x0F)); // low nibble + uint256 n = uint256(uint8(first & 0x0F)); // low nibble map = EncodedMap(new string[](n), new bytes[](n)); - for (uint i = 0; i < n; i++) { + for (uint256 i = 0; i < n; i++) { map.keys[i] = deser_fixstr(self); map.values[i] = trim_encode(self); } } - // !!! FUNCTIONS BELOW ARE DEPRECATED !!! function deserializeFinalCommitments(bytes calldata data) @@ -124,13 +145,15 @@ library MsgPk { quotient = abi.decode(data[64:128], (BN254.G1Point)); divisor = abi.decode(data[128:256], (BN254.G2Point)); } + /// @notice deserializes an array of G1Point and also returns the rest of the // data, excluding the consumed bytes. `i` is the index that we start to read // the data from. - function deserializeG1Point( - bytes calldata data, - uint256 i - ) public view returns (BN254.G1Point memory p, uint256 final_i) { + function deserializeG1Point(bytes calldata data, uint256 i) + public + view + returns (BN254.G1Point memory p, uint256 final_i) + { // read length of the data require(data[i] == 0xC4, "not a stream of bin8 (bytes)"); @@ -151,12 +174,14 @@ library MsgPk { /// @notice deserializes an URS excluding the lagrange bases, and also // returns the final index which points at the end of the consumed data. - function deserializeURS( - bytes calldata data - ) + function deserializeURS(bytes calldata data) public view - returns (BN254.G1Point[] memory, BN254.G1Point memory, uint256) + returns ( + BN254.G1Point[] memory, + BN254.G1Point memory, + uint256 + ) { uint256 i = 0; require(data[i] == 0x92, "not a fix array of two elements"); @@ -193,9 +218,11 @@ library MsgPk { return (g, h, final_i); } - function deserializeOpeningProof( - bytes calldata serialized_proof - ) public view returns (Kimchi.ProverProof memory proof) { + function deserializeOpeningProof(bytes calldata serialized_proof) + public + view + returns (Kimchi.ProverProof memory proof) + { uint256 i = 0; bytes1 firstbyte = serialized_proof[i]; // first byte is 0x92, indicating this is an array with 2 elements @@ -238,10 +265,11 @@ library MsgPk { return proof; } - function deserializeScalar( - bytes calldata data, - uint256 i - ) public pure returns (Scalar.FE scalar, uint256 final_i) { + function deserializeScalar(bytes calldata data, uint256 i) + public + pure + returns (Scalar.FE scalar, uint256 final_i) + { // read length of the data require(data[i] == 0xC4, "not a stream of bin8 (bytes)"); @@ -260,34 +288,36 @@ library MsgPk { final_i = i; } - function deserializePointEvals( - bytes calldata data, - uint256 i - ) public pure returns (PointEvaluations memory eval, uint256 final_i) { + function deserializePointEvals(bytes calldata data, uint256 i) + public + pure + returns (PointEvaluations memory eval, uint256 final_i) + { require(data[i] == 0x92, "not a fix array of two elements"); i += 1; require(data[i] == 0x91, "not a fix array of one element"); i += 1; - (Scalar.FE zeta, uint i0) = deserializeScalar(data, i); + (Scalar.FE zeta, uint256 i0) = deserializeScalar(data, i); i = i0; require(data[i] == 0x91, "not a fix array of one element"); i += 1; - (Scalar.FE zeta_omega, uint i1) = deserializeScalar(data, i); + (Scalar.FE zeta_omega, uint256 i1) = deserializeScalar(data, i); i = i1; eval = PointEvaluations(zeta, zeta_omega); final_i = i; } - function deserializeProofEvaluationsArray( - bytes calldata data, - uint256 i - ) public pure returns (ProofEvaluationsArray memory evals, uint256 final_i) { + function deserializeProofEvaluationsArray(bytes calldata data, uint256 i) + public + pure + returns (ProofEvaluationsArray memory evals, uint256 final_i) + { // WARN: This works because the test circuit evaluations have one elem per array. ( PointEvaluations memory evals_non_array, - uint _i + uint256 _i ) = deserializePointEvals(data, i); Scalar.FE[] memory zeta = new Scalar.FE[](1); @@ -300,15 +330,22 @@ library MsgPk { zeta_omega ); + PointEvaluationsArray[15] memory w; + Scalar.FE[] memory zero = new Scalar.FE[](1); + zero[0] = Scalar.zero(); + PointEvaluationsArray memory z = PointEvaluationsArray(zero, zero); + PointEvaluationsArray[7 - 1] memory s; + // array needed to simulate an optional param - evals = ProofEvaluationsArray(public_evals, true); + evals = ProofEvaluationsArray(public_evals, true, w, z, s); final_i = _i; } - function deserializeState( - bytes calldata data, - uint256 i - ) public view returns (State memory) { + function deserializeState(bytes calldata data, uint256 i) + public + view + returns (State memory) + { require(data[i] == 0x93, "not a fix array of three elements"); i += 1; @@ -329,7 +366,7 @@ library MsgPk { size = uint8(data[i]); i += 1; string memory hash_str = string(data[i:i + size]); - uint hash = Utils.str_to_uint(hash_str); + uint256 hash = Utils.str_to_uint(hash_str); i += size; // Block height: @@ -337,7 +374,7 @@ library MsgPk { size = uint8(data[i]) & 0x0f; i += 1; string memory height_str = string(data[i:i + size]); - uint block_height = Utils.str_to_uint(height_str); + uint256 block_height = Utils.str_to_uint(height_str); i += size; return State(creator, hash, block_height); From 992fe28ce0e4c16e1bde39be0201bb3b5829ce14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Wed, 22 Nov 2023 19:27:57 -0300 Subject: [PATCH 12/68] Add error --- eth_verifier/lib/Alphas.sol | 3 +++ eth_verifier/lib/msgpack/Deserialize.sol | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/eth_verifier/lib/Alphas.sol b/eth_verifier/lib/Alphas.sol index 0c17dbb1..44f8c3c9 100644 --- a/eth_verifier/lib/Alphas.sol +++ b/eth_verifier/lib/Alphas.sol @@ -2,6 +2,7 @@ pragma solidity >=0.4.16 <0.9.0; import "./bn254/Fields.sol"; +import "forge-std/console.sol"; using {Scalar.mul} for Scalar.FE; @@ -38,6 +39,7 @@ library AlphasLib { } } + error NotEnoughPowersOfAlpha(); /// @notice retrieves the powers of alpha, upperbounded by `num` function get_alphas(Alphas storage self, ArgumentType ty, uint num) external @@ -68,6 +70,7 @@ library AlphasLib { uint[2] memory range = self.map[ty]; if (num > range[1]) { + revert NotEnoughPowersOfAlpha(); // FIXME: panic! asked for num alphas but there aren't as many. } diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 3f356a3a..0d882aee 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -355,7 +355,6 @@ library MsgPk { // next byte is the length of the stream in one byte uint8 size = uint8(data[i]); i += 1; - console.log(size); string memory creator = string(data[i:i + size]); i += size; From 1dba6ef974f33db9182112162ee1c500cebc8325 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Thu, 23 Nov 2023 19:21:37 -0300 Subject: [PATCH 13/68] README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a27c133..2b2f2d1a 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This project introduces the proof generation, posting and verification of the va 4. Browser utility for smart contract users: Mina address is provided as an input. State is looked up against Mina and then shared as a Mina state lookup-merkle-proof wrapped inside an efficient proof system. 5. A solidity contract utility that smart contract developers or users can execute on an EVM chain to feed in a Mina state lookup proof that will check the state lookup against the latest posted Mina state proof to verify that this Mina state is valid. -## Disclaimer +## ⚠️ Disclaimer `mina_bridge` is in an early stage of development, currently it misses elemental features and correct functionality is not guaranteed. From bf151519706fd168fc3d87a08cd52e590aa65d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Thu, 30 Nov 2023 17:57:05 -0300 Subject: [PATCH 14/68] Deserialize VerifierIndex from KZG prover and fixes (#89) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add foreign group usage * KZG Prover generate verifier index * [WIP] Debug ForeignGroup assertEquals * Replaced job's OS. (#88) * Use foreign EC addition gate * Deserialize verifier index * Added remaining msgpack primitives * Go back to min Kimchi verifier * Use foreign EC op gates * Fix uint deser * Remove unused imports * Update o1js * Add public_len field * Add ForeignFieldMul gate case * Initialize alphas * Kimchi o1js prover: combine_point_evaluations function deleted (#91) Co-authored-by: Pablo Deymonnaz * Final fixes --------- Co-authored-by: gabrielbosio Co-authored-by: Tomás Casagrande <53660242+samoht9277@users.noreply.github.com> Co-authored-by: Gabriel Bosio <38794644+gabrielbosio@users.noreply.github.com> Co-authored-by: Pablo Deymonnaz Co-authored-by: Pablo Deymonnaz --- .github/workflows/ci.yaml | 6 +- .github/workflows/rust_ci.yaml | 2 +- .gitmodules | 2 +- eth_verifier/lib/Alphas.sol | 32 ++++++ eth_verifier/lib/Oracles.sol | 14 +-- eth_verifier/lib/Utils.sol | 1 + eth_verifier/lib/bn254/Fields.sol | 18 +-- eth_verifier/lib/msgpack/Deserialize.sol | 128 +++++++++++++++++++--- eth_verifier/src/Verifier.sol | 4 + eth_verifier/test/Deserialize.t.sol | 14 +++ eth_verifier/test/Fields.t.sol | 20 +++- eth_verifier/test/Integration.t.sol | 3 +- kzg_prover/Cargo.lock | 1 + kzg_prover/Cargo.toml | 2 +- kzg_prover/src/main.rs | 86 ++++----------- kzg_prover/src/snarky_gate.rs | 2 + public_input_gen/src/main.rs | 37 +++++-- verifier_circuit/o1js | 2 +- verifier_circuit/package-lock.json | 2 +- verifier_circuit/src/SRS.ts | 6 +- verifier_circuit/src/main.ts | 26 ++++- verifier_circuit/src/prover/prover.ts | 15 +-- verifier_circuit/src/verifier/verifier.ts | 36 ++++-- 23 files changed, 316 insertions(+), 143 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ec93b83f..48e3b3ef 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -21,7 +21,7 @@ jobs: verifier_circuit: name: Build and test EVM bridge - runs-on: ubuntu-22.04 + runs-on: ubuntu-selfhosted defaults: run: working-directory: ./verifier_circuit @@ -43,7 +43,7 @@ jobs: integration: name: Integration test - runs-on: ubuntu-22.04 + runs-on: ubuntu-selfhosted steps: - name: Checkout sources uses: actions/checkout@v4 @@ -57,7 +57,7 @@ jobs: demo_eth_verifier: name: Test demo's Solidity verifier - runs-on: ubuntu-22.04 + runs-on: ubuntu-selfhosted defaults: run: working-directory: ./eth_verifier diff --git a/.github/workflows/rust_ci.yaml b/.github/workflows/rust_ci.yaml index 14bcd71f..07767749 100644 --- a/.github/workflows/rust_ci.yaml +++ b/.github/workflows/rust_ci.yaml @@ -13,7 +13,7 @@ on: jobs: check: name: Check, fmt, clippy, test and run - runs-on: ubuntu-22.04 + runs-on: ubuntu-selfhosted defaults: run: working-directory: ./${{inputs.directory}} diff --git a/.gitmodules b/.gitmodules index b00e46c2..630682ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "verifier_circuit/o1js"] path = verifier_circuit/o1js url = https://github.com/lambdaclass/o1js.git - branch = wasm_kzg_prover + branch = foreign_ec_ops [submodule "kzg_prover/proof-systems"] path = kzg_prover/proof-systems url = https://github.com/lambdaclass/proof-systems.git diff --git a/eth_verifier/lib/Alphas.sol b/eth_verifier/lib/Alphas.sol index 44f8c3c9..6169fed1 100644 --- a/eth_verifier/lib/Alphas.sol +++ b/eth_verifier/lib/Alphas.sol @@ -27,6 +27,37 @@ struct Alphas { } library AlphasLib { + error CantRegisterNewConstraints(); + function register(Alphas storage self, ArgumentType ty, uint powers) public { + if (self.alphas.length != 0) { + revert CantRegisterNewConstraints(); + } + + if (ty == ArgumentType.GateGeneric || + ty == ArgumentType.GatePoseidon || + ty == ArgumentType.GateCompleteAdd || + ty == ArgumentType.GateVarBaseMul || + ty == ArgumentType.GateEndoMul || + ty == ArgumentType.GateEndoMulScalar || + ty == ArgumentType.GateLookup || + ty == ArgumentType.GateCairoClaim || + ty == ArgumentType.GateCairoInstruction || + ty == ArgumentType.GateCairoFlags || + ty == ArgumentType.GateCairoTransition || + ty == ArgumentType.GateRangeCheck0 || + ty == ArgumentType.GateRangeCheck1 || + ty == ArgumentType.GateForeignFieldAdd || + ty == ArgumentType.GateForeignFieldMul || + ty == ArgumentType.GateXor16 || + ty == ArgumentType.GateRot64) + { + ty = ArgumentType.GateZero; + } + + self.map[ty] = [self.next_power, powers]; + self.next_power += powers; + } + /// Instantiates the ranges with an actual field element `alpha`. /// Once you call this function, you cannot register new constraints. function instantiate(Alphas storage self, Scalar.FE alpha) internal { @@ -74,6 +105,7 @@ library AlphasLib { // FIXME: panic! asked for num alphas but there aren't as many. } + pows = new Scalar.FE[](num); for (uint i = 0; i < num; i++) { pows[i] = self.alphas[range[0]+i]; } diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index 3c857034..7a6faaaf 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -236,7 +236,7 @@ library Oracles { cols[1] = [[ft_eval0]][0].length; total_length += rows[1] * cols[1]; - // save the data in a flat array in a column-major so there's no neeed + // save the data in a flat array in a column-major so there's no need // to transpose each matrix later. Scalar.FE[] memory es_data = new Scalar.FE[](total_length); uint[] memory starts = new uint[](matrix_count); @@ -244,17 +244,17 @@ library Oracles { starts[0] = curr; for (uint i = 0; i < rows[0] * cols[0]; i++) { - uint col = i % cols[0]; - uint row = i / cols[0]; - es_data[i] = public_evals[col][row]; + uint col = i / rows[0]; + uint row = i % rows[0]; + es_data[i] = public_evals[row][col]; curr++; } starts[1] = curr; for (uint i = 0; i < rows[1] * cols[1]; i++) { - uint col = i % cols[0]; - uint row = i / cols[0]; - es_data[i] = [[ft_eval0]][col][row]; // TODO: ft_eval1; + uint col = i / rows[0]; + uint row = i % rows[0]; + es_data[i] = [[ft_eval0]][row][col]; // TODO: ft_eval1; curr++; } diff --git a/eth_verifier/lib/Utils.sol b/eth_verifier/lib/Utils.sol index af1a82d2..75475606 100644 --- a/eth_verifier/lib/Utils.sol +++ b/eth_verifier/lib/Utils.sol @@ -60,6 +60,7 @@ library Utils { } function get_twiddles(uint order) public view returns (Scalar.FE[] memory twiddles) { + Scalar.FE root = Scalar.get_primitive_root_of_unity(order); Scalar.FE root_inv = Scalar.get_primitive_root_of_unity(order).inv(); uint size = 1 << (order - 1); diff --git a/eth_verifier/lib/bn254/Fields.sol b/eth_verifier/lib/bn254/Fields.sol index 38bfec96..3046568d 100644 --- a/eth_verifier/lib/bn254/Fields.sol +++ b/eth_verifier/lib/bn254/Fields.sol @@ -50,7 +50,8 @@ library Base { } function inv(FE self) public view returns (FE) { - (uint inverse, uint gcd) = Aux.xgcd(FE.unwrap(self), MODULUS); + require(FE.unwrap(self) != 0, "tried to get inverse of 0"); + (uint gcd, uint inverse) = Aux.xgcd(FE.unwrap(self), MODULUS); require(gcd == 1, "gcd not 1"); return FE.wrap(inverse); @@ -99,6 +100,7 @@ library Base { } } +import {console} from "forge-std/console.sol"; /// @notice Implements 256 bit modular arithmetic over the scalar field of bn254. library Scalar { type FE is uint256; @@ -159,7 +161,8 @@ library Scalar { } function inv(FE self) public view returns (FE) { - (uint inverse, uint gcd) = Aux.xgcd(FE.unwrap(self), MODULUS); + require(FE.unwrap(self) != 0, "tried to get inverse of 0"); + (uint gcd, uint inverse) = Aux.xgcd(FE.unwrap(self), MODULUS); require(gcd == 1, "gcd not 1"); return FE.wrap(inverse); @@ -228,6 +231,7 @@ library Scalar { } require(FE.unwrap(pow(root, 1 << order)) == 1, "not a root of unity"); + return root; } } @@ -238,16 +242,16 @@ library Aux { function xgcd( uint a, uint b - ) public pure returns (uint s0, uint t0) { - uint r0 = a; + ) public pure returns (uint r0, uint s0) { + r0 = a; uint r1 = b; s0 = 1; uint s1 = 0; - t0 = 0; + uint t0 = 0; uint t1 = 1; uint n = 0; - while (r1 > 0) { + while (r1 != 0) { uint q = r0 / r1; r0 = r0 > q*r1 ? r0 - q*r1 : q*r1 - r0; // abs @@ -270,7 +274,7 @@ library Aux { t0 = t1; t1 = temp; - n++; + ++n; } if (n % 2 != 0) { diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 0d882aee..3cc7353d 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -8,6 +8,8 @@ import "../Evaluations.sol"; import "../Proof.sol"; import "../State.sol"; import "../Utils.sol"; +import "../VerifierIndex.sol"; +import "forge-std/console.sol"; library MsgPk { struct Stream { @@ -33,34 +35,34 @@ library MsgPk { } /// @notice returns current byte and advances index. - function next(Stream memory self) public pure returns (bytes1 b) { + function next(Stream memory self) public view returns (bytes1 b) { b = self.data[self.curr_index]; self.curr_index += 1; } /// @notice returns current byte without advancing index. - function curr(Stream memory self) public pure returns (bytes1) { + function curr(Stream memory self) public view returns (bytes1) { return self.data[self.curr_index]; } function next_n(Stream memory self, uint256 n) public - pure + view returns (bytes memory consumed) { consumed = new bytes(n); - for (uint256 i = 1; i <= n; i++) { + for (uint256 i = 0; i < n; i++) { consumed[i] = self.data[self.curr_index + i]; } self.curr_index += n; } - error NonImplementedType(); + error NotImplementedType(bytes1 prefix); /// @notice deserializes the next type and returns the encoded data. - function trim_encode(Stream memory self) + function deser_encode(Stream memory self) public - pure + view returns (bytes memory) { bytes1 prefix = curr(self); @@ -70,14 +72,26 @@ library MsgPk { return abi.encode(deser_bin8(self)); } else if (prefix >> 4 == 0x08) { return abi.encode(deser_fixmap(self)); + } else if (prefix >> 4 == 0x09) { + return abi.encode(deser_fixarr(self)); + } else if (prefix >> 2 == 0x33) { + return abi.encode(deser_uint(self)); + } else if (prefix >> 7 == 0x00) { + return abi.encode(deser_posfixint(self)); + } else if (prefix >> 7 == 0x00) { + return abi.encode(deser_posfixint(self)); + } else if (prefix == 0xc2 || prefix == 0xc3) { + return abi.encode(deser_bool(self)); + } else if (prefix == 0xc0) { + return abi.encode(deser_null(self)); } else { - revert NonImplementedType(); + revert NotImplementedType(prefix); } } function deser_fixstr(Stream memory self) public - pure + view returns (string memory) { bytes1 first = next(self); @@ -87,7 +101,7 @@ library MsgPk { return string(next_n(self, n)); } - function deser_bin8(Stream memory self) public pure returns (bytes memory) { + function deser_bin8(Stream memory self) public view returns (bytes memory) { require(next(self) == 0xC4, "not a stream of bin8 (bytes)"); // next byte is the length of the stream in one byte @@ -99,7 +113,7 @@ library MsgPk { function deser_fixarr(Stream memory self) public - pure + view returns (EncodedArray memory arr) { bytes1 first = next(self); @@ -109,13 +123,13 @@ library MsgPk { arr = EncodedArray(new bytes[](n)); for (uint256 i = 0; i < n; i++) { - arr.values[i] = trim_encode(self); + arr.values[i] = deser_encode(self); } } function deser_fixmap(Stream memory self) public - pure + view returns (EncodedMap memory map) { bytes1 first = next(self); @@ -126,10 +140,96 @@ library MsgPk { for (uint256 i = 0; i < n; i++) { map.keys[i] = deser_fixstr(self); - map.values[i] = trim_encode(self); + map.values[i] = deser_encode(self); + } + } + + function deser_map16(Stream memory self) + public + view + returns (EncodedMap memory map) + { + bytes1 first = next(self); + require(first == 0xde, "not a map16"); + // size is next two bytes: + + uint16 n = uint16(bytes2(next_n(self, 2))); + + map = EncodedMap(new string[](n), new bytes[](n)); + + for (uint16 i = 0; i < n; i++) { + map.keys[i] = deser_fixstr(self); + map.values[i] = deser_encode(self); + } + } + + function deser_uint(Stream memory self) public view returns (uint256) { + bytes1 first = next(self); + require(first >> 2 == 0x33, "not a uint"); + // 110011XX are uints of 8,16,32,64 bits. + + uint256 byte_count = 1 << uint8(first & 0x03); // mask with 11b + bytes memory b = next_n(self, byte_count); + if (byte_count == 1) { + return uint8(bytes1(b)); + } else if (byte_count == 2) { + return uint16(bytes2(b)); + } else if (byte_count == 3) { + return uint32(bytes4(b)); + } else if (byte_count == 4) { + return uint64(bytes8(b)); } } + function deser_posfixint(Stream memory self) public view returns (uint256) { + bytes1 first = next(self); + require(first >> 7 == 0x00, "not a positive fixint"); + + return uint256(uint8(first)); + } + + function deser_null(Stream memory self) + public + view + returns (string memory) + { + bytes1 first = next(self); + require(first == 0xc0, "not null"); + + return "null"; + } + + function deser_bool(Stream memory self) public view returns (bool) { + bytes1 first = next(self); + require(first == 0xc2 || first == 0xc3, "not a bool"); + + return first == 0xc3; // 0xc3 == true + } + + function deser_verifier_index( + Stream memory self, + VerifierIndex storage index + ) public { + EncodedMap memory map = deser_map16(self); + index.max_poly_size = abi.decode( + find_value(map, "max_poly_size"), + (uint256) + ); + index.public_len = abi.decode( + find_value(map, "public"), + (uint256) + ); + } + + function find_value(EncodedMap memory self, string memory key) + public + returns (bytes memory) + { + uint256 i = 0; + while (keccak256(bytes(self.keys[i])) != keccak256(bytes(key))) i++; + return self.values[i]; + } + // !!! FUNCTIONS BELOW ARE DEPRECATED !!! function deserializeFinalCommitments(bytes calldata data) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index a9b1a649..860631d1 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -45,6 +45,8 @@ library Kimchi { } contract KimchiVerifier { + using {AlphasLib.register} for Alphas; + VerifierIndex verifier_index; ProverProof proof; @@ -75,6 +77,8 @@ contract KimchiVerifier { verifier_index.public_len = public_len; verifier_index.domain_size = domain_size; verifier_index.max_poly_size = max_poly_size; + verifier_index.powers_of_alpha.register(ArgumentType.GateZero, 21); + verifier_index.powers_of_alpha.register(ArgumentType.Permutation, 3); proof.evals = evals; } diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index 1bea785c..0158146e 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -7,6 +7,8 @@ import "../src/Verifier.sol"; import "../lib/msgpack/Deserialize.sol"; contract DeserializeTest is Test { + VerifierIndex index; + // Test to check that the destructuring of the message pack byte array is correct. // If we know that g1Deserialize() is correct, then this asserts that the whole // deserialization is working. @@ -180,4 +182,16 @@ contract DeserializeTest is Test { assertEq(p.x, deserialized.x, "x not equal"); assertEq(p.y, deserialized.y, "y not equal"); } + + function test_deserialize_verifier_index() public { + bytes + memory verifier_index_serialized = hex"de0015a6646f6d61696ec4ac00200000000000000d00000000200000000000000000000000000000000000000000000000000000000000000180604384d657bfc5a27537a9a64a65524ccd53348302b79c969a6d50cb623010d3bd9b8d9ba44a762d3a8ee2f31bd37b66b278c8ea1d0062ae69b849ab6f00c95dd9ab5a200b3bca888197fa74dfc8c8b61c6adb24e1080461acbf58ed7016676666c6d4fbf3e7062d4acae95caea98b56cd337cb5b949aad9135a94525b13ad6d61785f706f6c795f73697a65cd4000a77a6b5f726f777303a67075626c696300af707265765f6368616c6c656e67657300aa7369676d615f636f6d6d9782a9756e7368696674656491c420364315ea1fe73fc3478a9823dc4a927119ff6e633fb41812a5605c9fc0ac72aaa773686966746564c082a9756e7368696674656491c420633a980d5940136aeb4eaa2145aad94dbbc1acd0ee911544ca9d65a8f860a40ca773686966746564c082a9756e7368696674656491c42011230853b13814d3fb7a1c6994c21e23ba083abe94ceaad63feffe686091b49da773686966746564c082a9756e7368696674656491c4201baa6d070773617ef0658e4a622a5a67497fbe8b91b905aacba29ba17f42741ea773686966746564c082a9756e7368696674656491c4208669bcc973be53b864a28e652f04ab5cf72ca20f246819dd6f15ad3d8d51f5a3a773686966746564c082a9756e7368696674656491c4201e3002266069d0191ba82c889749d17c4a22a7f2d85d0487d2df57d8f2a28094a773686966746564c082a9756e7368696674656491c420017b22822869b290ff28ac82a15e68b6003236e4154fe9f8f40fb374dcd5338fa773686966746564c0b1636f656666696369656e74735f636f6d6d9f82a9756e7368696674656491c420f08c0c257c5ec41234224482a6d9b42635b662425b25b86f8a60eddd8b8ccfa5a773686966746564c082a9756e7368696674656491c42078fce52175dd1b6afa55bcf432537240a066e61ccff2b30ebb46e99d5e2c3500a773686966746564c082a9756e7368696674656491c4203c8fecd0515ad1740d07a906080ced3300e0a185eafb7fe48b7f4af017d0e48ea773686966746564c082a9756e7368696674656491c4207c3532ca64a3ec2778fab0ef5b3ed566de2bbb34410bcc7cac35d43ceee62320a773686966746564c082a9756e7368696674656491c420894cf4855baaf3744ecd1251074f05530ba28700a331e659e796bfda9e3b941fa773686966746564c082a9756e7368696674656491c420df8aafd9d21ae04c63f3a70c8ef668b894e938961f5fc2a4451634aa272d7286a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c420434278e55a777606754cee725607035dba64830be1d3852409d80e0b36f71224a773686966746564c082a9756e7368696674656491c420cb201e2a3088fc2a7fe8c8bbcc77548db0df19c7cc053388323998b657a1f886a773686966746564c082a9756e7368696674656491c4208d944ead72329988cc3c56026a8e0f2827c9d9a694441f0fbca64c6c1aed5a84a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c0ac67656e657269635f636f6d6d82a9756e7368696674656491c4201af163363acc703294827809a39e668d2782ebcaf872d06f16576f6b996531a7a773686966746564c0a870736d5f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0b1636f6d706c6574655f6164645f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0a86d756c5f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0a9656d756c5f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0b3656e646f6d756c5f7363616c61725f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0b172616e67655f636865636b305f636f6d6d82a9756e7368696674656491c420191418104060244c3c0e4aaa96c0e68a3f09a8319dff7e3909f8f6c8ca62ee8da773686966746564c0b172616e67655f636865636b315f636f6d6d82a9756e7368696674656491c42081542bf55ad01c67c1f5ff901f7e3a55395206e6d1aff8040862052238673d2ba773686966746564c0b6666f726569676e5f6669656c645f6164645f636f6d6d82a9756e7368696674656491c420f41e7e08a4db448418f5596f62f687dcbc6eb7a55a4d93b7cfdea37197027b02a773686966746564c0b6666f726569676e5f6669656c645f6d756c5f636f6d6dc0a8786f725f636f6d6dc0a8726f745f636f6d6dc0a5736869667497c4200100000000000000000000000000000000000000000000000000000000000000c420e3a214e91334d0caf1eb85df5bd7524d73d5eb7aaf742a7eb2d40bfdc8cdb900c4206d0f44339a339fb8a4e49bf1099620aa649918482b95a397ae39b9ec5ad47700c420b40923bd78e619c80a7b39c0f3f11e48005519d2fef16a1f77d40545e5c77700c420f9c95cd6b11b38df7855fd4d2a036329adcad613f100b923109540356a597c00c4205a696526fa309c412c10e86604c3c0ad2cd9443dd85b823203721281cfbf3300c42043423bb307cec19f297c4188deb23acc7b5812719b2eaccbf1b7034ae6ace800ac6c6f6f6b75705f696e64657886b16a6f696e745f6c6f6f6b75705f75736564c2ac6c6f6f6b75705f7461626c659182a9756e7368696674656491c42059149f1484af342fa425e9f230ca246babfab7cdd72d0ff5bc3d1176614cce2da773686966746564c0b06c6f6f6b75705f73656c6563746f727384a3786f72c0a66c6f6f6b7570c0ab72616e67655f636865636b82a9756e7368696674656491c4204f4763225f13070a3c7d728bb86526080c7d75c4a6928ab8940c2c49b1d97c8ca773686966746564c0a566666d756cc0a97461626c655f69647382a9756e7368696674656491c420211e5d946fbeb572bb16898a1a1f8fef49484671f4a1ba7e746898276befff1ea773686966746564c0ab6c6f6f6b75705f696e666f83ab6d61785f7065725f726f7704ae6d61785f6a6f696e745f73697a6501a8666561747572657383a87061747465726e7384a3786f72c2a66c6f6f6b7570c2ab72616e67655f636865636bc3b1666f726569676e5f6669656c645f6d756cc2b16a6f696e745f6c6f6f6b75705f75736564c2b3757365735f72756e74696d655f7461626c6573c2b772756e74696d655f7461626c65735f73656c6563746f72c0"; + MsgPk.deser_verifier_index( + MsgPk.from_data(verifier_index_serialized), + index + ); + + assertEq(index.public_len, 0); + assertEq(index.max_poly_size, 16384); + } } diff --git a/eth_verifier/test/Fields.t.sol b/eth_verifier/test/Fields.t.sol index d50404f6..9e0e73f8 100644 --- a/eth_verifier/test/Fields.t.sol +++ b/eth_verifier/test/Fields.t.sol @@ -14,7 +14,7 @@ contract FieldsTest is Test { Base.FE one = Base.FE.wrap(1); Base.FE q_plus_one = q.add(one); - assertEq(Base.FE.unwrap(q_plus_one), 0, "p == 0 mod p"); + assertEq(Base.FE.unwrap(q_plus_one), 0, "p != 0 mod p"); } function test_add_scalar() public { @@ -22,6 +22,22 @@ contract FieldsTest is Test { Scalar.FE one = Scalar.FE.wrap(1); Scalar.FE q_plus_one = q.add(one); - assertEq(Scalar.FE.unwrap(q_plus_one), 0, "p == 0 mod p"); + assertEq(Scalar.FE.unwrap(q_plus_one), 0, "p != 0 mod p"); + } + + function test_inv_base() public { + Base.FE a = Base.from(Base.MODULUS - 1); + Base.FE b = a.inv(); + + Base.FE one = Base.from(1); + assertEq(Base.FE.unwrap(a.mul(b)), 1, "a * a.inv() != 1"); + } + + function test_inv_scalar() public { + Scalar.FE a = Scalar.from(42); + Scalar.FE b = a.inv(); + + Scalar.FE one = Scalar.from(1); + assertEq(Scalar.FE.unwrap(a.mul(b)), 1, "a * a.inv() != 1"); } } diff --git a/eth_verifier/test/Integration.t.sol b/eth_verifier/test/Integration.t.sol index 0f643d6c..d1bcafac 100644 --- a/eth_verifier/test/Integration.t.sol +++ b/eth_verifier/test/Integration.t.sol @@ -7,8 +7,9 @@ import "../lib/bn254/BN254.sol"; import "../src/Verifier.sol"; import "../lib/msgpack/Deserialize.sol"; import "../lib/Commitment.sol"; +import "../lib/Alphas.sol"; -contract DeserializeTest is Test { +contract Integration is Test { function test_partial_verify() public { // Data was taken from running the circuit_gen crate. bytes diff --git a/kzg_prover/Cargo.lock b/kzg_prover/Cargo.lock index 917bdd38..a89ccbba 100644 --- a/kzg_prover/Cargo.lock +++ b/kzg_prover/Cargo.lock @@ -411,6 +411,7 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" name = "kimchi" version = "0.1.0" dependencies = [ + "ark-bn254", "ark-ec", "ark-ff", "ark-poly", diff --git a/kzg_prover/Cargo.toml b/kzg_prover/Cargo.toml index 5315f8d9..dd360fa2 100644 --- a/kzg_prover/Cargo.toml +++ b/kzg_prover/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -kimchi = { path = "proof-systems/kimchi", version = "0.1.0" } +kimchi = { path = "proof-systems/kimchi", version = "0.1.0", features = ["bn254"] } poly-commitment = { path = "proof-systems/poly-commitment", version = "0.1.0" } ark-bn254 = "0.3.0" ark-ec = "0.3.0" diff --git a/kzg_prover/src/main.rs b/kzg_prover/src/main.rs index 186ef130..fac3b035 100644 --- a/kzg_prover/src/main.rs +++ b/kzg_prover/src/main.rs @@ -1,48 +1,39 @@ mod snarky_gate; -use std::{fs, ops::Neg}; +use std::{fs, ops::Neg, sync::Arc}; use ark_bn254::{G1Affine, G2Affine}; use ark_ec::{ - msm::VariableBaseMSM, short_weierstrass_jacobian::GroupAffine, AffineCurve, PairingEngine, - ProjectiveCurve, + msm::VariableBaseMSM, short_weierstrass_jacobian::GroupAffine, AffineCurve, ProjectiveCurve, }; use ark_ff::PrimeField; use ark_poly::{ - univariate::DenseOrSparsePolynomial, univariate::DensePolynomial, EvaluationDomain, - Evaluations, Polynomial, Radix2EvaluationDomain, UVPolynomial, + univariate::DensePolynomial, Evaluations, Polynomial, Radix2EvaluationDomain, UVPolynomial, }; use ark_serialize::{CanonicalSerialize, SerializationError}; use ark_std::{ - rand::{self, rngs::StdRng, SeedableRng}, + rand::{rngs::StdRng, SeedableRng}, UniformRand, }; -use hex; use kimchi::{ circuits::{ constraints::ConstraintSystem, domains::EvaluationDomains, gate::{CircuitGate, GateType}, - polynomials::generic::testing::create_circuit, }, - o1_utils::FieldHelpers, + curve::KimchiCurve, + prover_index::ProverIndex, }; use num_traits::{One, Zero}; use poly_commitment::{ commitment::{combine_commitments, combine_evaluations, Evaluation}, - evaluation_proof::{combine_polys, DensePolynomialOrEvaluations}, + evaluation_proof::{DensePolynomialOrEvaluations, OpeningProof}, pairing_proof::{PairingProof, PairingSRS}, srs::SRS, - PolyComm, SRS as _, + SRS as _, }; use snarky_gate::SnarkyGate; -type PolynomialsToCombine<'a> = &'a [( - DensePolynomialOrEvaluations<'a, ark_bn254::Fr, Radix2EvaluationDomain>, - Option, - PolyComm, -)]; - fn main() { let rng = &mut StdRng::from_seed([0u8; 32]); @@ -59,9 +50,9 @@ fn main() { let n = domain.d1.size as usize; let x = ark_bn254::Fr::rand(rng); - let srs = create_srs(x, n, domain); + let mut srs = create_srs(x, n, domain); - let polynomials = create_selector_dense_polynomials(cs, domain); + let polynomials = create_selector_dense_polynomials(cs.clone(), domain); let comms: Vec<_> = polynomials .iter() @@ -136,9 +127,17 @@ fn main() { points_serialized.extend(quotient_serialized); points_serialized.extend(divisor_serialized); + fs::write("../eth_verifier/proof.mpk", points_serialized).unwrap(); + + type G1 = GroupAffine; + let endo_q = G1::endos().1; + srs.full_srs.add_lagrange_basis(cs.domain.d1); + let prover_index = + ProverIndex::>::create(cs, endo_q, Arc::new(srs.clone().full_srs)); + let verifier_index = prover_index.verifier_index(); fs::write( - "../eth_verifier/proof.mpk", - points_serialized, + "../eth_verifier/verifier_index.mpk", + rmp_serde::to_vec(&verifier_index).unwrap(), ) .unwrap(); @@ -146,6 +145,7 @@ fn main() { "Is KZG proof valid?: {:?}", pairing_proof.verify(&srs, &evaluations, polyscale, &evaluation_points) ); + println!("{}", verifier_index.powers_of_alpha); } fn serialize_g1point_for_verifier(point: G1Affine) -> Result, SerializationError> { @@ -200,9 +200,7 @@ fn create_selector_dense_polynomials( domain: EvaluationDomains>, ) -> Vec>> { let foreign_field_add_selector = - selector_polynomial(GateType::ForeignFieldAdd, &cs.gates, &domain, &domain.d8); - let foreign_field_add_selector8 = - foreign_field_add_selector.evaluate_over_domain_by_ref(domain.d8); + selector_polynomial(GateType::ForeignFieldAdd, &cs.gates, &domain); let generic_selector = Evaluations::>::from_vec_and_domain( @@ -220,8 +218,6 @@ fn create_selector_dense_polynomials( ) .interpolate(); - let generic_selector4 = generic_selector.evaluate_over_domain_by_ref(cs.domain.d4); - let polynomials: Vec<_> = vec![foreign_field_add_selector, generic_selector]; polynomials } @@ -241,43 +237,6 @@ fn create_srs( } } -fn create_proof( - srs: &PairingSRS>, - plnms: PolynomialsToCombine, // vector of polynomial with optional degree bound and commitment randomness - elm: &[ark_bn254::Fr], // vector of evaluation points - polyscale: ark_bn254::Fr, // scaling factor for polynoms -) -> Option>> { - let (p, blinding_factor) = combine_polys::< - GroupAffine, - Radix2EvaluationDomain, - >(plnms, polyscale, srs.full_srs.g.len()); - let evals: Vec<_> = elm.iter().map(|pt| p.evaluate(pt)).collect(); - - let quotient_poly = { - let eval_polynomial = eval_polynomial(elm, &evals); - let divisor_polynomial = divisor_polynomial(elm); - let numerator_polynomial = &p - &eval_polynomial; - let (quotient, remainder) = DenseOrSparsePolynomial::divide_with_q_and_r( - &numerator_polynomial.into(), - &divisor_polynomial.into(), - )?; - if !remainder.is_zero() { - return None; - } - quotient - }; - - let quotient = srs - .full_srs - .commit_non_hiding("ient_poly, 1, None) - .unshifted[0]; - - Some(PairingProof { - quotient, - blinding: blinding_factor, - }) -} - /// The polynomial that evaluates to each of `evals` for the respective `elm`s. fn eval_polynomial( elm: &[ark_bn254::Fr], @@ -318,7 +277,6 @@ fn selector_polynomial( gate_type: GateType, gates: &[CircuitGate], domain: &EvaluationDomains, - target_domain: &Radix2EvaluationDomain, ) -> DensePolynomial { // Coefficient form Evaluations::<_, Radix2EvaluationDomain<_>>::from_vec_and_domain( diff --git a/kzg_prover/src/snarky_gate.rs b/kzg_prover/src/snarky_gate.rs index 2bfc84f4..f25e516b 100644 --- a/kzg_prover/src/snarky_gate.rs +++ b/kzg_prover/src/snarky_gate.rs @@ -38,6 +38,8 @@ impl Into> for SnarkyGate { GateType::Generic } else if self.r#type == "ForeignFieldAdd" { GateType::ForeignFieldAdd + } else if self.r#type == "ForeignFieldMul" { + GateType::ForeignFieldMul } else if self.r#type == "Zero" { GateType::Zero } else if self.r#type == "RangeCheck0" { diff --git a/public_input_gen/src/main.rs b/public_input_gen/src/main.rs index a286d198..ff0b3c5f 100644 --- a/public_input_gen/src/main.rs +++ b/public_input_gen/src/main.rs @@ -1,10 +1,12 @@ use std::fs; -use ark_ec::short_weierstrass_jacobian::GroupAffine; +use ark_ec::msm::VariableBaseMSM; +use ark_ec::short_weierstrass_jacobian::GroupProjective; use kimchi::mina_curves::pasta::{Fp, Fq, Pallas, PallasParameters}; use kimchi::o1_utils::FieldHelpers; use kimchi::poly_commitment::srs::SRS; use kimchi::precomputed_srs; +use num_traits::{One, Zero}; use serde::Serialize; use state_proof::{OpeningProof, StateProof}; @@ -53,22 +55,19 @@ fn prove_and_verify(srs: &SRS, opening: OpeningProof) { // verify the proof (propagate any errors) println!("Verifying dummy proof..."); - let sg_point = Pallas::new( + let sg = Pallas::new( Fp::from_hex(&opening.sg.0[2..]).unwrap(), Fp::from_hex(&opening.sg.1[2..]).unwrap(), false, ); - let z1_felt = Fq::from_hex(&opening.z_1[2..]).unwrap(); - let value_to_compare = compute_verification(srs, &sg_point); + let z1 = Fq::from_hex(&opening.z_1[2..]).unwrap(); + let value_to_compare = compute_msm_verification(srs, &sg, &z1); fs::write( "../verifier_circuit/src/inputs.json", serde_json::to_string(&Inputs { - sg: [ - sg_point.x.to_biguint().to_string(), - sg_point.y.to_biguint().to_string(), - ], - z1: z1_felt.to_biguint().to_string(), + sg: [sg.x.to_biguint().to_string(), sg.y.to_biguint().to_string()], + z1: z1.to_biguint().to_string(), expected: [ value_to_compare.x.to_biguint().to_string(), value_to_compare.y.to_biguint().to_string(), @@ -79,6 +78,22 @@ fn prove_and_verify(srs: &SRS, opening: OpeningProof) { .unwrap(); } -fn compute_verification(srs: &SRS, sg: &Pallas) -> GroupAffine { - *sg + srs.h +fn compute_msm_verification( + srs: &SRS, + sg: &Pallas, + z1: &Fq, +) -> GroupProjective { + let mut points = vec![srs.h]; + let mut scalars = vec![Fq::zero()]; + + let rand_base_i = Fq::one(); + let sg_rand_base_i = Fq::one(); + let neg_rand_base_i = -rand_base_i; + + points.push(*sg); + scalars.push(neg_rand_base_i * z1 - sg_rand_base_i); + + let scalars: Vec<_> = scalars.iter().map(|scalar| scalar.0).collect(); + + VariableBaseMSM::multi_scalar_mul(&points, &scalars) } diff --git a/verifier_circuit/o1js b/verifier_circuit/o1js index 8ee03d4c..09723bf2 160000 --- a/verifier_circuit/o1js +++ b/verifier_circuit/o1js @@ -1 +1 @@ -Subproject commit 8ee03d4c96141a878bd2037740bfe42849e1a1ff +Subproject commit 09723bf2e003d7a86f0933b6be42c6f96058807b diff --git a/verifier_circuit/package-lock.json b/verifier_circuit/package-lock.json index 0fe7ff07..2444461a 100644 --- a/verifier_circuit/package-lock.json +++ b/verifier_circuit/package-lock.json @@ -11071,7 +11071,7 @@ } }, "o1js": { - "version": "0.13.0", + "version": "0.13.1", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/verifier_circuit/src/SRS.ts b/verifier_circuit/src/SRS.ts index b20ca4fe..8e146962 100644 --- a/verifier_circuit/src/SRS.ts +++ b/verifier_circuit/src/SRS.ts @@ -1,9 +1,7 @@ -import lagrange_bases_json from "../test/lagrange_bases.json" assert { type: "json" }; -import { Field, Group, Scalar } from "o1js"; -import { BlindedCommitment, PolyComm } from "./poly_commitment/commitment.js"; +import { PolyComm } from "./poly_commitment/commitment.js"; import { readFileSync } from "fs"; -import { ForeignGroup } from "./foreign_fields/foreign_group.js"; import { ForeignField } from "./foreign_fields/foreign_field.js"; +import { ForeignGroup } from "o1js"; let srs_json; try { diff --git a/verifier_circuit/src/main.ts b/verifier_circuit/src/main.ts index afbaa893..22e9e944 100644 --- a/verifier_circuit/src/main.ts +++ b/verifier_circuit/src/main.ts @@ -1,9 +1,10 @@ import { readFileSync, writeFileSync } from "fs"; -import { Provable } from "o1js"; +import { ForeignGroup, Provable } from "o1js"; import { Verifier } from "./verifier/verifier.js"; import { ForeignField } from "./foreign_fields/foreign_field.js"; +import { ForeignScalar } from "./foreign_fields/foreign_scalar.js"; -let inputs: { sg: bigint[], expected: bigint[] }; +let inputs: { sg: bigint[], z1: bigint, expected: bigint[] }; try { inputs = JSON.parse(readFileSync("./src/inputs.json", "utf-8")); } catch (e) { @@ -14,9 +15,10 @@ try { 12368675093154914445558499940566677159678085503548847273105352744110357023892n, 13928325837869340024710380561463559827724328563792462791279614459373822978261n ], + z1: 4397093005605931442646816891053389885546297107331356987745997632505536565365n, expected: [ - 26065081609142297706924822385337762030176473849954371733717621265428419437080n, - 25403161885444353082762527911380081866142600044068732571611330580992014688540n + 5736868798632710640113734962596149556147058590963693818747480745427705446383n, + 20393541083676616749487157095022413656498918946278576790740950610414772498695n ] }; } @@ -25,14 +27,28 @@ console.log('O1JS loaded'); // ---------------------------------------------------- +ForeignGroup.curve = [ + "0", // a + "5", // b + "28948022309329048855892746252171976963363056481941560715954676764349967630337", // modulus + "1", // gen_x + "12418654782883325593414442427049395787963493412651469444558597405572177144507", // gen_y + "28948022309329048855892746252171976963363056481941647379679742748393362948097" // order +]; + // Convert JSON inputs to O1JS inputs so that we can pass them to the circuit let sg_x = ForeignField.from(inputs.sg[0]); let sg_y = ForeignField.from(inputs.sg[1]); +let z1 = ForeignScalar.from(inputs.z1); let expected_x = ForeignField.from(inputs.expected[0]) let expected_y = ForeignField.from(inputs.expected[1]); +let sg = new ForeignGroup(sg_x, sg_y); +let expected = new ForeignGroup(expected_x, expected_y); + + console.log("Writing circuit into file..."); -let { gates } = Provable.constraintSystem(() => Verifier.main(sg_x, sg_y, expected_x, expected_y)); +let { gates } = Provable.constraintSystem(() => Verifier.main(sg, z1, expected)); writeFileSync("../kzg_prover/gates.json", JSON.stringify(gates)); // ---------------------------------------------------- diff --git a/verifier_circuit/src/prover/prover.ts b/verifier_circuit/src/prover/prover.ts index d1ecb21f..d9fca352 100644 --- a/verifier_circuit/src/prover/prover.ts +++ b/verifier_circuit/src/prover/prover.ts @@ -499,18 +499,6 @@ export class ProofEvaluations { return this; } - // TODO: implement this!!!! - /* - Returns a new PointEvaluations struct with the combined evaluations. - */ - combine_point_evaluations(): PointEvaluations { - let zeta: Evals = Scalar.from(0) as Evals; - let zetaOmega: Evals = Scalar.from(0) as Evals; - - let ret = new PointEvaluations(zeta, zetaOmega); - return ret; - } - map(f: (e: Evals) => Evals2): ProofEvaluations { let { w, @@ -545,6 +533,9 @@ export class ProofEvaluations { ) } + /* + Returns a new PointEvaluations struct with the combined evaluations. + */ static combine( evals: ProofEvaluations>, pt: PointEvaluations diff --git a/verifier_circuit/src/verifier/verifier.ts b/verifier_circuit/src/verifier/verifier.ts index e394c31d..f367af49 100644 --- a/verifier_circuit/src/verifier/verifier.ts +++ b/verifier_circuit/src/verifier/verifier.ts @@ -1,14 +1,13 @@ import { readFileSync } from 'fs'; -import { circuitMain, Circuit, Group, Scalar, public_, Field } from 'o1js'; +import { circuitMain, Circuit, Group, Scalar, public_, Field, ForeignGroup } from 'o1js'; import { PolyComm } from '../poly_commitment/commitment.js'; import { SRS } from '../SRS.js'; import { Sponge } from './sponge.js'; import { Alphas } from '../alphas.js'; import { Polynomial } from '../polynomial.js'; import { Linearization, PolishToken } from '../prover/expr.js'; -import { ForeignScalar } from '../foreign_fields/foreign_scalar.js'; -import { ForeignGroup } from '../foreign_fields/foreign_group.js'; import { ForeignField } from '../foreign_fields/foreign_field.js'; +import { ForeignScalar } from '../foreign_fields/foreign_scalar.js'; let steps: bigint[][]; try { @@ -133,10 +132,31 @@ export class Verifier extends Circuit { static readonly PERMUTATION_CONSTRAINTS: number = 3; @circuitMain - static main(@public_ sg_x: ForeignField, @public_ sg_y: ForeignField, @public_ expected_x: ForeignField, @public_ expected_y: ForeignField) { - let sg = new ForeignGroup(sg_x, sg_y); - let actual = sg.add(h); - let expected = new ForeignGroup(expected_x, expected_y); - actual.assertEquals(expected); + static main(@public_ sg: ForeignGroup, @public_ z1: ForeignScalar, @public_ expected: ForeignGroup) { + let points = [h]; + let scalars = [ForeignScalar.from(0)]; + + let randBase = ForeignScalar.from(1); + let sgRandBase = ForeignScalar.from(1); + let negRandBase = randBase.neg(); + + points.push(sg); + scalars.push(negRandBase.mul(z1).sub(sgRandBase)); + + let result = Verifier.naiveMSM(points, scalars); + + result.assertEquals(expected); + } + + static naiveMSM(points: ForeignGroup[], scalars: ForeignScalar[]): ForeignGroup { + let result = new ForeignGroup(ForeignField.from(0), ForeignField.from(0)); + + for (let i = 0; i < points.length; i++) { + let point = points[i]; + let scalar = scalars[i]; + result = result.add(point.scale(scalar)); + } + + return result; } } From 85af66cda52c54b530ff348ce6cbc7316b6b0254 Mon Sep 17 00:00:00 2001 From: Gabriel Bosio <38794644+gabrielbosio@users.noreply.github.com> Date: Thu, 30 Nov 2023 19:02:17 -0300 Subject: [PATCH 15/68] Remove repeated lines Co-authored-by: Pablo Deymonnaz --- verifier_circuit/src/main.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/verifier_circuit/src/main.ts b/verifier_circuit/src/main.ts index 9a38b87b..feb81b69 100644 --- a/verifier_circuit/src/main.ts +++ b/verifier_circuit/src/main.ts @@ -59,10 +59,6 @@ let expected_x = ForeignField.from(inputs.expected.x); let expected_y = ForeignField.from(inputs.expected.y); let expected = new ForeignGroup(expected_x, expected_y); -let sg = new ForeignGroup(sg_x, sg_y); -let expected = new ForeignGroup(expected_x, expected_y); - - console.log("Writing circuit into file..."); let { gates } = Provable.constraintSystem(() => Verifier.main(openingProof, expected)); writeFileSync("../kzg_prover/gates.json", JSON.stringify(gates)); From b7182a67177c4e25b8edc67af0fd222a8005f978 Mon Sep 17 00:00:00 2001 From: Gabriel Bosio <38794644+gabrielbosio@users.noreply.github.com> Date: Thu, 30 Nov 2023 19:03:42 -0300 Subject: [PATCH 16/68] Remove unused import Co-authored-by: Pablo Deymonnaz --- verifier_circuit/src/main.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/verifier_circuit/src/main.ts b/verifier_circuit/src/main.ts index feb81b69..e40504ec 100644 --- a/verifier_circuit/src/main.ts +++ b/verifier_circuit/src/main.ts @@ -3,7 +3,6 @@ import { ForeignGroup, Provable } from "o1js"; import { Verifier } from "./verifier/verifier.js"; import { deserOpeningProof } from "./serde/serde_proof.js"; import { ForeignField } from "./foreign_fields/foreign_field.js"; -import { ForeignScalar } from "./foreign_fields/foreign_scalar.js"; let inputs; try { From 7ba792fac08537aa27fc295cc736977cb665ac2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Fri, 1 Dec 2023 16:55:28 -0300 Subject: [PATCH 17/68] Change o1js submodule commit --- verifier_circuit/o1js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifier_circuit/o1js b/verifier_circuit/o1js index 09723bf2..8ee03d4c 160000 --- a/verifier_circuit/o1js +++ b/verifier_circuit/o1js @@ -1 +1 @@ -Subproject commit 09723bf2e003d7a86f0933b6be42c6f96058807b +Subproject commit 8ee03d4c96141a878bd2037740bfe42849e1a1ff From 2e8c790603d0c1c2ac69c4e4487ac3ea05b4bb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Fri, 1 Dec 2023 18:27:12 -0300 Subject: [PATCH 18/68] Changed commit again --- verifier_circuit/o1js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifier_circuit/o1js b/verifier_circuit/o1js index 8ee03d4c..11d426c9 160000 --- a/verifier_circuit/o1js +++ b/verifier_circuit/o1js @@ -1 +1 @@ -Subproject commit 8ee03d4c96141a878bd2037740bfe42849e1a1ff +Subproject commit 11d426c949466dd25d3702dfc8e313eaaed01672 From bdfb5122c5fbba1903d3a7f86c9dec5c2eff3f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 4 Dec 2023 17:23:29 -0300 Subject: [PATCH 19/68] Ethereum verifier continued (#92) * KZG Prover generate verifier index * Deserialize verifier index * Added remaining msgpack primitives * Fix uint deser * Add public_len field * Initialize alphas * Final fixes * Add constraint count for pows of alpha * Added combined evaluations step * Added fake witness * Fixed issues regarding fake witness * Added comments, removed printlns * Satisfy copy constraints * Revert fake witness development * Added test circuit kzg proof * Disable test circuit proof gen * Added vanishing poly * Continuing final comm step --- eth_verifier/lib/Constants.sol | 3 + eth_verifier/lib/Oracles.sol | 37 ++++++- eth_verifier/lib/Polynomial.sol | 62 ++++++++++- eth_verifier/lib/Utils.sol | 168 +++++++++++++++++++++++++++-- eth_verifier/lib/VerifierIndex.sol | 3 + eth_verifier/lib/bn254/Fields.sol | 8 ++ eth_verifier/src/Verifier.sol | 46 +++++++- kzg_prover/Cargo.lock | 16 +++ kzg_prover/Cargo.toml | 2 +- kzg_prover/proof-systems | 2 +- kzg_prover/src/main.rs | 100 +++++++++++++++-- 11 files changed, 420 insertions(+), 27 deletions(-) diff --git a/eth_verifier/lib/Constants.sol b/eth_verifier/lib/Constants.sol index f0fc6465..8e7b663a 100644 --- a/eth_verifier/lib/Constants.sol +++ b/eth_verifier/lib/Constants.sol @@ -4,4 +4,7 @@ pragma solidity >=0.4.16 <0.9.0; library Constants { uint public constant COLUMNS = 15; uint public constant PERMUTS = 7; + + uint public constant PERMUTATION_CONSTRAINTS = 3; + uint public constant VARBASEMUL_CONSTRAINTS = 21; } diff --git a/eth_verifier/lib/Oracles.sol b/eth_verifier/lib/Oracles.sol index 7a6faaaf..5246af29 100644 --- a/eth_verifier/lib/Oracles.sol +++ b/eth_verifier/lib/Oracles.sol @@ -47,7 +47,7 @@ library Oracles { bool is_public_input_set, Sponge storage base_sponge, Sponge storage scalar_sponge - ) public { + ) public returns (Result memory) { uint chunk_size = index.domain_size < index.max_poly_size ? 1 : index.domain_size / index.max_poly_size; @@ -99,6 +99,7 @@ library Oracles { // retrieve ranges for the powers of alphas Alphas storage all_alphas = index.powers_of_alpha; all_alphas.instantiate(alpha); + // WARN: all_alphas should be a clone of index.powers_of_alpha. // evaluations of the public input @@ -262,6 +263,40 @@ library Oracles { // TODO: add evaluations of all columns Scalar.FE combined_inner_prod = combined_inner_product(evaluation_points, v, u, es, index.max_poly_size); + RandomOracles memory oracles = RandomOracles( + beta, + gamma, + alpha_chal, + alpha, + zeta, + v, + u, + alpha_chal, + v_chal, + u_chal + ); + + return Result(oracles, powers_of_eval_points_for_chunks); + } + + struct RandomOracles { + // joint_combiner + Scalar.FE beta; + Scalar.FE gamma; + ScalarChallenge alpha_chal; + Scalar.FE alpha; + Scalar.FE zeta; + Scalar.FE v; + Scalar.FE u; + ScalarChallenge zeta_chal; + ScalarChallenge v_chal; + ScalarChallenge u_chal; + } + + struct Result { + // sponges are stored in storage + RandomOracles oracles; + PointEvaluations powers_of_eval_points_for_chunks; } struct ScalarChallenge { diff --git a/eth_verifier/lib/Polynomial.sol b/eth_verifier/lib/Polynomial.sol index aa9a6bbb..87e682bb 100644 --- a/eth_verifier/lib/Polynomial.sol +++ b/eth_verifier/lib/Polynomial.sol @@ -2,9 +2,10 @@ pragma solidity >=0.4.16 <0.9.0; import "./bn254/Fields.sol"; +import "./Utils.sol"; library Polynomial { - using {Scalar.add, Scalar.mul} for Scalar.FE; + using {Scalar.add, Scalar.mul, Scalar.sub, Scalar.pow} for Scalar.FE; struct Dense { Scalar.FE[] coeffs; @@ -23,4 +24,63 @@ library Polynomial { result = result.mul(x).add(coeffs[i]); } } + + function constant_poly(Scalar.FE coeff) public pure returns (Dense memory) { + Scalar.FE[] memory coeffs = new Scalar.FE[](1); + coeffs[0] = coeff; + return Dense(coeffs); + } + + function sub(Dense memory self, Dense memory other) public view returns (Dense memory) { + uint n = Utils.max(self.coeffs.length, other.coeffs.length); + Scalar.FE[] memory coeffs_self_sub_other = new Scalar.FE[](n); + for (uint i = 0; i < n; i++) { + coeffs_self_sub_other[i] = self.coeffs[i].sub(other.coeffs[i]); + } + + return Dense(coeffs_self_sub_other); + } + + function mul(Dense memory self, Dense memory other) public view returns (Dense memory) { + // evaluate both polys with FFT and 2n degree bound (degree of the result poly) + uint count = Utils.max(self.coeffs.length, other.coeffs.length) * 2; + Scalar.FE[] memory evals_self = Utils.fft_resized(self.coeffs, count); + Scalar.FE[] memory evals_other = Utils.fft_resized(other.coeffs, count); + // padding with zeros results in more evaluations of the same polys + + require(evals_self.length == evals_other.length, "poly mul evals are not of the same length"); + uint n = evals_self.length; + + // point-wise multiplication + Scalar.FE[] memory evals_self_mul_other = new Scalar.FE[](n); + for (uint i = 0; i < n; i++) { + evals_self_mul_other[i] = evals_self[i].mul(evals_other[i]); + } + + // interpolate result poly + Scalar.FE[] memory coeffs_res = Utils.ifft(evals_self_mul_other); + return Dense(coeffs_res); + } + + function vanishes_on_last_n_rows(Scalar.FE domain_gen, uint domain_size, uint i) external view returns (Dense memory poly) { + if (i == 0) { + Scalar.FE[] memory const = new Scalar.FE[](1); + const[0] = Scalar.from(1); + return Dense(const); + } + + Scalar.FE[] memory coeffs = new Scalar.FE[](2); + coeffs[0] = Scalar.zero(); + coeffs[1] = Scalar.one(); + Dense memory x = Dense(coeffs); + + Scalar.FE term = domain_gen.pow(domain_size - i); + Dense memory acc = sub(x, constant_poly(term)); + for (uint j = 0; j < i - 1; i++) { + term = term.mul(domain_gen); + acc = mul(acc, sub(x, constant_poly(term))); + } + + return acc; + } } diff --git a/eth_verifier/lib/Utils.sol b/eth_verifier/lib/Utils.sol index 75475606..9f6cb0e5 100644 --- a/eth_verifier/lib/Utils.sol +++ b/eth_verifier/lib/Utils.sol @@ -7,7 +7,7 @@ import "./UtilsExternal.sol"; import "forge-std/console.sol"; using { BN254.add, BN254.neg, BN254.scalarMul } for BN254.G1Point; -using { Scalar.pow, Scalar.inv } for Scalar.FE; +using { Scalar.pow, Scalar.inv, Scalar.add, Scalar.mul, Scalar.neg } for Scalar.FE; library Utils { /// @notice implements iterative FFT via the Cooley-Tukey algorithm for BN254. @@ -59,19 +59,92 @@ library Utils { } } + /// @notice implements iterative FFT via the Cooley-Tukey algorithm for BN254 scalar field. + /// @notice needs a final bit reversing permutation of the output. + // Reference: Lambdaworks + // https://github.com/lambdaclass/lambdaworks/ + function nr_2radix_fft(Scalar.FE[] memory scalars, Scalar.FE[] memory twiddles) + public + view + returns (Scalar.FE[] memory results) + { + uint256 n = scalars.length; + require(is_power_of_two(n), "fft with size non power of two"); + + if (n == 1) { + return scalars; + } + + // divide input in groups, starting with 1, duplicating the number of groups in each stage. + uint group_count = 1; + uint group_size = scalars.length; + + // for each group, there'll be group_size / 2 butterflies. + // a butterfly is the atomic operation of a FFT, e.g: (a, b) = (a + wb, a - wb). + // The 0.5 factor is what gives FFT its performance, it recursively halves the problem size + // (group size). + + results = scalars; + + while (group_count < scalars.length) { + for (uint group = 0; group < group_count; group++) { + uint first_in_group = group * group_size; + uint first_in_next_group = first_in_group + group_size / 2; + + Scalar.FE w = twiddles[group]; // a twiddle factor is used per group + + for (uint i = first_in_group; i < first_in_next_group; i++) { + Scalar.FE wi = results[i + group_size / 2].mul(w); + + Scalar.FE y0 = results[i].add(wi); + Scalar.FE y1 = results[i].add(wi.neg()); + + results[i] = y0; + results[i + group_size / 2] = y1; + } + } + group_count *= 2; + group_size /= 2; + } + } + function get_twiddles(uint order) public view returns (Scalar.FE[] memory twiddles) { Scalar.FE root = Scalar.get_primitive_root_of_unity(order); - Scalar.FE root_inv = Scalar.get_primitive_root_of_unity(order).inv(); uint size = 1 << (order - 1); twiddles = new Scalar.FE[](size); - for (uint i = 0; i < size; i++) { - twiddles[i] = root_inv.pow(i); + twiddles[0] = Scalar.from(1); + for (uint i = 1; i < size; i++) { + twiddles[i] = twiddles[i - 1].mul(root); + } + } + + function get_twiddles_inv(uint order) public view returns (Scalar.FE[] memory twiddles) { + Scalar.FE root = Scalar.get_primitive_root_of_unity(order).inv(); + + uint size = 1 << (order - 1); + twiddles = new Scalar.FE[](size); + twiddles[0] = Scalar.from(1); + for (uint i = 1; i < size; i++) { + twiddles[i] = twiddles[i - 1].mul(root); + } + } + + /// @notice permutes the elements in bit-reverse order. + function bit_reverse_permut(Scalar.FE[] memory scalars) public view returns (Scalar.FE[] memory result){ + result = scalars; + for (uint i = 0; i < scalars.length; i++) { + uint bit_reverse_index = bit_reverse(i, scalars.length); + if (bit_reverse_index > i) { + Scalar.FE temp = result[i]; + result[i] = result[bit_reverse_index]; + result[bit_reverse_index] = temp; + } } } /// @notice permutes the elements in bit-reverse order. - function bit_reverse_permut(BN254.G1Point[] memory points) public pure returns (BN254.G1Point[] memory result){ + function bit_reverse_permut(BN254.G1Point[] memory points) public view returns (BN254.G1Point[] memory result){ result = points; for (uint i = 0; i < points.length; i++) { uint bit_reverse_index = bit_reverse(i, points.length); @@ -84,11 +157,29 @@ library Utils { } /// @notice reverses the `log2(size)` first bits of `i` - function bit_reverse(uint i, uint size) public pure returns (uint) { + function bit_reverse(uint i, uint size) public view returns (uint) { if (size == 1) return i; return UtilsExternal.reverseEndianness(i) >> (256 - max_log2(size)); } + /// @notice runs FFT for BN254. + function fft(BN254.G1Point[] memory points) public view returns (BN254.G1Point[] memory results) { + (uint size, uint order) = next_power_of_two(points.length); + + if (size > points.length) { + // zero padding + BN254.G1Point[] memory new_points = new BN254.G1Point[](size); + for (uint i = 0; i < size; i++) { + new_points[i] = i < points.length ? points[i] : BN254.point_at_inf(); + } + points = new_points; + } + + Scalar.FE[] memory twiddles = bit_reverse_permut(get_twiddles(order)); + BN254.G1Point[] memory unordered_res = nr_2radix_fft(points, twiddles); + return bit_reverse_permut(unordered_res); + } + /// @notice runs inverse FFT for BN254. function ifft(BN254.G1Point[] memory points) public view returns (BN254.G1Point[] memory results) { (uint size, uint order) = next_power_of_two(points.length); @@ -102,7 +193,65 @@ library Utils { points = new_points; } - BN254.G1Point[] memory unordered_res = nr_2radix_fft(points, get_twiddles(order)); + Scalar.FE[] memory twiddles = bit_reverse_permut(get_twiddles_inv(order)); + BN254.G1Point[] memory unordered_res = nr_2radix_fft(points, twiddles); + return bit_reverse_permut(unordered_res); + } + + /// @notice runs FFT for BN254 scalar field. + function fft(Scalar.FE[] memory scalars) public view returns (Scalar.FE[] memory results) { + (uint size, uint order) = next_power_of_two(scalars.length); + + if (size > scalars.length) { + // zero padding + Scalar.FE[] memory new_scalars = new Scalar.FE[](size); + for (uint i = 0; i < size; i++) { + new_scalars[i] = i < scalars.length ? scalars[i] : Scalar.zero(); + } + scalars = new_scalars; + } + + Scalar.FE[] memory twiddles = bit_reverse_permut(get_twiddles(order)); + Scalar.FE[] memory unordered_res = nr_2radix_fft(scalars, twiddles); + return bit_reverse_permut(unordered_res); + } + + /// @notice runs FFT for BN254 scalar field, padding with zeros to retrieve `count` elements. + /// @notice or the next power of two from that. + /// @notice `count` needs to be greater or equal than `scalars` length. + function fft_resized(Scalar.FE[] memory scalars, uint count) public view returns (Scalar.FE[] memory results) { + require(count >= scalars.length, "tried to execute resized fft with size smaller than input length"); + (uint size, uint order) = next_power_of_two(count); + + if (size > scalars.length) { + // zero padding + Scalar.FE[] memory new_scalars = new Scalar.FE[](size); + for (uint i = 0; i < size; i++) { + new_scalars[i] = i < scalars.length ? scalars[i] : Scalar.zero(); + } + scalars = new_scalars; + } + + Scalar.FE[] memory twiddles = bit_reverse_permut(get_twiddles(order)); + Scalar.FE[] memory unordered_res = nr_2radix_fft(scalars, twiddles); + return bit_reverse_permut(unordered_res); + } + + /// @notice runs inverse FFT for BN254 scalar field. + function ifft(Scalar.FE[] memory scalars) public view returns (Scalar.FE[] memory results) { + (uint size, uint order) = next_power_of_two(scalars.length); + + if (size > scalars.length) { + // zero padding + Scalar.FE[] memory new_scalars = new Scalar.FE[](size); + for (uint i = 0; i < size; i++) { + new_scalars[i] = i < scalars.length ? scalars[i] : Scalar.zero(); + } + scalars = new_scalars; + } + + Scalar.FE[] memory twiddles = bit_reverse_permut(get_twiddles_inv(order)); + Scalar.FE[] memory unordered_res = nr_2radix_fft(scalars, twiddles); return bit_reverse_permut(unordered_res); } @@ -167,6 +316,11 @@ library Utils { return a < b ? a : b; } + /// @notice returns maximum between a and b. + function max(uint a, uint b) public pure returns (uint) { + return a < b ? b : a; + } + /// @notice converts an ASCII string into a uint. error InvalidStringToUint(); function str_to_uint(string memory s) public pure returns (uint res) { diff --git a/eth_verifier/lib/VerifierIndex.sol b/eth_verifier/lib/VerifierIndex.sol index 614cfa83..04881144 100644 --- a/eth_verifier/lib/VerifierIndex.sol +++ b/eth_verifier/lib/VerifierIndex.sol @@ -12,6 +12,8 @@ struct VerifierIndex { uint256 public_len; // maximal size of polynomial section uint256 max_poly_size; + // the number of randomized rows to achieve zero knowledge + uint256 zk_rows; URS urs; // domain uint256 domain_size; @@ -22,6 +24,7 @@ struct VerifierIndex { Scalar.FE[7] shift; // TODO: use Consants.PERMUTS /// domain offset for zero-knowledge Scalar.FE w; + } function verifier_digest(VerifierIndex storage index) returns (Base.FE) { diff --git a/eth_verifier/lib/bn254/Fields.sol b/eth_verifier/lib/bn254/Fields.sol index 3046568d..e7c00a58 100644 --- a/eth_verifier/lib/bn254/Fields.sol +++ b/eth_verifier/lib/bn254/Fields.sol @@ -12,6 +12,10 @@ library Base { return FE.wrap(0); } + function one() public pure returns (FE) { + return FE.wrap(1); + } + function from(uint n) public pure returns (FE) { return FE.wrap(n % MODULUS); } @@ -118,6 +122,10 @@ library Scalar { return FE.wrap(0); } + function one() public pure returns (FE) { + return FE.wrap(1); + } + function from(uint n) public pure returns (FE) { return FE.wrap(n % MODULUS); } diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 860631d1..af5182e9 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -9,11 +9,13 @@ import "../lib/Oracles.sol"; import "../lib/Proof.sol"; import "../lib/State.sol"; import "../lib/VerifierIndex.sol"; -import "../lib/Commitment.sol"; +import "../lib/Constants.sol"; import "../lib/msgpack/Deserialize.sol"; +import "../lib/Alphas.sol"; using {BN254.neg} for BN254.G1Point; using {Scalar.neg} for Scalar.FE; +using {AlphasLib.get_alphas} for Alphas; library Kimchi { struct Proof { @@ -46,6 +48,7 @@ library Kimchi { contract KimchiVerifier { using {AlphasLib.register} for Alphas; + using {combine_evals} for ProofEvaluationsArray; VerifierIndex verifier_index; ProverProof proof; @@ -80,6 +83,10 @@ contract KimchiVerifier { verifier_index.powers_of_alpha.register(ArgumentType.GateZero, 21); verifier_index.powers_of_alpha.register(ArgumentType.Permutation, 3); + // TODO: Investigate about linearization and write a proper function for this + verifier_index.powers_of_alpha.register(ArgumentType.GateZero, Constants.VARBASEMUL_CONSTRAINTS); + verifier_index.powers_of_alpha.register(ArgumentType.Permutation, Constants.PERMUTATION_CONSTRAINTS); + proof.evals = evals; } @@ -120,6 +127,8 @@ contract KimchiVerifier { error IncorrectPublicInputLength(); function partial_verify(Scalar.FE[] memory public_inputs) public { + // Commit to the negated public input polynomial. + uint256 chunk_size = verifier_index.domain_size < verifier_index.max_poly_size ? 1 @@ -163,17 +172,44 @@ contract KimchiVerifier { ).commitment; } - Oracles.fiat_shamir(proof, verifier_index, public_comm, public_inputs, true, base_sponge, scalar_sponge); + Oracles.Result memory oracles_res = Oracles.fiat_shamir( + proof, + verifier_index, + public_comm, + public_inputs, + true, + base_sponge, + scalar_sponge + ); + + // Combine the chunked polynomials' evaluations + + proof.evals.combine_evals(oracles_res.powers_of_eval_points_for_chunks); + + // Compute the commitment to the linearized polynomial $f$. + Polynomial.Dense memory permutation_vanishing_polynomial = + Polynomial.vanishes_on_last_n_rows( + verifier_index.domain_gen, + verifier_index.domain_size, + verifier_index.zk_rows + ); + + Scalar.FE[] memory alphas = + verifier_index.powers_of_alpha.get_alphas( + ArgumentType.Permutation, + Constants.PERMUTATION_CONSTRAINTS + ); + + PolyComm[] memory commitments = new PolyComm[](0); } /* - This is a list of steps needed for verification, we need to determine which - ones can be skipped or simplified. + This is a list of steps needed for verification. Partial verification: 1. Check the length of evaluations insde the proof. 2. Commit to the negated public input poly - 3. Fiat-Shamir (MAY SKIP OR VASTLY SIMPLIFY) + 3. Fiat-Shamir (vastly simplify for now) 4. Combined chunk polynomials evaluations 5. Commitment to linearized polynomial f 6. Chunked commitment of ft diff --git a/kzg_prover/Cargo.lock b/kzg_prover/Cargo.lock index a89ccbba..2d3af2b3 100644 --- a/kzg_prover/Cargo.lock +++ b/kzg_prover/Cargo.lock @@ -234,6 +234,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -440,6 +446,7 @@ dependencies = [ "strum", "strum_macros", "thiserror", + "tiny-keccak", "turshi", ] @@ -989,6 +996,15 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "turshi" version = "0.1.0" diff --git a/kzg_prover/Cargo.toml b/kzg_prover/Cargo.toml index dd360fa2..cb87d076 100644 --- a/kzg_prover/Cargo.toml +++ b/kzg_prover/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -kimchi = { path = "proof-systems/kimchi", version = "0.1.0", features = ["bn254"] } +kimchi = { path = "proof-systems/kimchi", version = "0.1.0", features = ["bn254", "keccak-sponges"] } poly-commitment = { path = "proof-systems/poly-commitment", version = "0.1.0" } ark-bn254 = "0.3.0" ark-ec = "0.3.0" diff --git a/kzg_prover/proof-systems b/kzg_prover/proof-systems index 347f26ba..7cf4a3bb 160000 --- a/kzg_prover/proof-systems +++ b/kzg_prover/proof-systems @@ -1 +1 @@ -Subproject commit 347f26ba673e0d78fb199e902f7a9cea206468e5 +Subproject commit 7cf4a3bbdabf4ed2e890ea8b0cc348a5bb9406de diff --git a/kzg_prover/src/main.rs b/kzg_prover/src/main.rs index fac3b035..5ece737e 100644 --- a/kzg_prover/src/main.rs +++ b/kzg_prover/src/main.rs @@ -1,6 +1,6 @@ mod snarky_gate; -use std::{fs, ops::Neg, sync::Arc}; +use std::{array, fs, ops::Neg, sync::Arc}; use ark_bn254::{G1Affine, G2Affine}; use ark_ec::{ @@ -20,21 +20,48 @@ use kimchi::{ constraints::ConstraintSystem, domains::EvaluationDomains, gate::{CircuitGate, GateType}, + polynomials::generic::testing::{create_circuit, fill_in_witness}, + wires::COLUMNS, }, curve::KimchiCurve, - prover_index::ProverIndex, + groupmap::*, + keccak_sponge::{Keccak256FqSponge, Keccak256FrSponge}, + o1_utils::FieldHelpers, + proof::ProverProof, + prover_index::{self, ProverIndex}, + verifier::{batch_verify, Context}, }; use num_traits::{One, Zero}; use poly_commitment::{ - commitment::{combine_commitments, combine_evaluations, Evaluation}, - evaluation_proof::{DensePolynomialOrEvaluations, OpeningProof}, + commitment::{combine_commitments, combine_evaluations, CommitmentCurve, Evaluation}, + evaluation_proof::{combine_polys, DensePolynomialOrEvaluations, OpeningProof}, pairing_proof::{PairingProof, PairingSRS}, - srs::SRS, - SRS as _, + srs::{endos, SRS}, + PolyComm, SRS as _, }; use snarky_gate::SnarkyGate; +type PolynomialsToCombine<'a> = &'a [( + DensePolynomialOrEvaluations<'a, ark_bn254::Fr, Radix2EvaluationDomain>, + Option, + PolyComm, +)]; + +type BaseField = ark_bn254::Fq; +type ScalarField = ark_bn254::Fr; +type G1 = GroupAffine; + +type KeccakFqSponge = Keccak256FqSponge; +type KeccakFrSponge = Keccak256FrSponge; + +type KZGProof = PairingProof>; + fn main() { + generate_verifier_circuit_proof(); + //generate_test_proof(); +} + +fn generate_verifier_circuit_proof() { let rng = &mut StdRng::from_seed([0u8; 32]); let gates = read_gates_file(); @@ -95,7 +122,7 @@ fn main() { let polyscale = ark_bn254::Fr::rand(rng); - let pairing_proof = PairingProof::>::create( + let pairing_proof = KZGProof::create( &srs, polynomials_and_blinders.as_slice(), &evaluation_points, @@ -129,11 +156,9 @@ fn main() { fs::write("../eth_verifier/proof.mpk", points_serialized).unwrap(); - type G1 = GroupAffine; let endo_q = G1::endos().1; srs.full_srs.add_lagrange_basis(cs.domain.d1); - let prover_index = - ProverIndex::>::create(cs, endo_q, Arc::new(srs.clone().full_srs)); + let prover_index = ProverIndex::::create(cs, endo_q, Arc::new(srs.clone())); let verifier_index = prover_index.verifier_index(); fs::write( "../eth_verifier/verifier_index.mpk", @@ -142,12 +167,65 @@ fn main() { .unwrap(); println!( - "Is KZG proof valid?: {:?}", + "Is verifier circuit's KZG proof valid?: {:?}", pairing_proof.verify(&srs, &evaluations, polyscale, &evaluation_points) ); println!("{}", verifier_index.powers_of_alpha); } +fn generate_test_proof() { + let public_input: Vec = vec![42.into(); 5]; + let gates = create_circuit::(0, public_input.len()); + + // create witness + let mut witness: [Vec<_>; COLUMNS] = array::from_fn(|_| vec![0.into(); gates.len()]); + fill_in_witness::(0, &mut witness, &[]); + + let cs = ConstraintSystem::::create(gates) + .build() + .unwrap(); + + const ZK_ROWS: usize = 3; + let domain_size = cs.gates.len() + ZK_ROWS; + let domain = EvaluationDomains::create(domain_size).unwrap(); + + let n = domain.d1.size as usize; + + let srs = create_srs(42.into(), n, domain); + let endo_q = G1::endos().1; + let prover_index = + ProverIndex::>>::create( + cs, + endo_q, + Arc::new(srs.clone()), + ); + + let groupmap = ::Map::setup(); + let prover_proof = ProverProof::create::( + &groupmap, + witness, + &[], + &prover_index, + ) + .unwrap(); + + fs::write( + "../eth_verifier/verifier_index.mpk", + rmp_serde::to_vec(&prover_index.verifier_index()).unwrap(), + ) + .unwrap(); + + let context = Context { + verifier_index: &prover_index.verifier_index(), + proof: &prover_proof, + public_input: &public_input, + }; + + let verified = + batch_verify::(&groupmap, &[context]).is_ok(); + println!("Is test circuit's KZG proof valid?: {:?}", verified); +} + fn serialize_g1point_for_verifier(point: G1Affine) -> Result, SerializationError> { let mut point_serialized = vec![]; point.serialize_uncompressed(&mut point_serialized)?; From 816e3ac25768cd8dc32859bc97742c4e2a4d7cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 4 Dec 2023 18:36:19 -0300 Subject: [PATCH 20/68] Added perm scalars --- eth_verifier/src/Verifier.sol | 36 +++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index af5182e9..f50f4bf4 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -12,10 +12,12 @@ import "../lib/VerifierIndex.sol"; import "../lib/Constants.sol"; import "../lib/msgpack/Deserialize.sol"; import "../lib/Alphas.sol"; +import "../lib/Evaluations.sol"; using {BN254.neg} for BN254.G1Point; -using {Scalar.neg} for Scalar.FE; +using {Scalar.neg, Scalar.mul, Scalar.add} for Scalar.FE; using {AlphasLib.get_alphas} for Alphas; +using {Polynomial.evaluate} for Polynomial.Dense; library Kimchi { struct Proof { @@ -181,18 +183,19 @@ contract KimchiVerifier { base_sponge, scalar_sponge ); + Oracles.RandomOracles memory oracles = oracles_res.oracles; // Combine the chunked polynomials' evaluations - proof.evals.combine_evals(oracles_res.powers_of_eval_points_for_chunks); + ProofEvaluations memory evals = proof.evals.combine_evals(oracles_res.powers_of_eval_points_for_chunks); // Compute the commitment to the linearized polynomial $f$. - Polynomial.Dense memory permutation_vanishing_polynomial = + Scalar.FE permutation_vanishing_polynomial = Polynomial.vanishes_on_last_n_rows( verifier_index.domain_gen, verifier_index.domain_size, verifier_index.zk_rows - ); + ).evaluate(oracles.zeta); Scalar.FE[] memory alphas = verifier_index.powers_of_alpha.get_alphas( @@ -201,6 +204,31 @@ contract KimchiVerifier { ); PolyComm[] memory commitments = new PolyComm[](0); + Scalar.FE[] memory scalars = new Scalar.FE[](1); + scalars[0] = perm_scalars( + evals, + oracles.beta, + oracles.gamma, + alphas, // FIXME: change for iterator to take into account previous alphas + permutation_vanishing_polynomial + ); + } + + function perm_scalars( + ProofEvaluations memory e, + Scalar.FE beta, + Scalar.FE gamma, + Scalar.FE[] memory alphas, // array with the next 3 powers + Scalar.FE zkp_zeta // TODO: make an AlphaIterator type. + ) internal pure returns (Scalar.FE res) { + require(alphas.length == 3, "not enough powers of alpha for permutation"); + // TODO: alphas should be an iterator + + res = e.z.zeta_omega.mul(beta).mul(alphas[0]).mul(zkp_zeta); + uint len = Utils.min(e.w.length, e.s.length); + for (uint i = 0; i < len; i++) { + res = res.mul(gamma.add(beta.mul(e.s[i].zeta)).add(e.w[i].zeta)); + } } /* From c6daa598fcb3605e13ca48aaa3306fe59bdadfae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 4 Dec 2023 19:43:40 -0300 Subject: [PATCH 21/68] Added PolishToken --- eth_verifier/lib/expr/PolishToken.sol | 89 +++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 eth_verifier/lib/expr/PolishToken.sol diff --git a/eth_verifier/lib/expr/PolishToken.sol b/eth_verifier/lib/expr/PolishToken.sol new file mode 100644 index 00000000..247c9fdc --- /dev/null +++ b/eth_verifier/lib/expr/PolishToken.sol @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.4.16 <0.9.0; + +import "../bn254/Fields.sol"; + +// Variants like Mds, Literal and Cell have data associated to them. We will +// represent them as `bytes`. +struct PolishToken { + PolishTokenVariant variant; + bytes data; +} + +enum PolishTokenVariant { + Alpha, + Beta, + Gamma, + JointCombiner, + EndoCoefficient, + Mds, + Literal, + Cell, + Dup, + Pow, + Add, + Mul, + Sub, + VanishesOnZeroKnowledgeAndPreviousRows, + UnnormalizedLagrangeBasis, + Store, + Load, + /// Skip the given number of tokens if the feature is enabled. + SkipIf, + /// Skip the given number of tokens if the feature is disabled. + SkipIfNot +} + +struct PolishTokenMds { + uint row; + uint col; +} +type PolishTokenLiteral is Scalar.FE; +type PolishTokenCell is Variable; +type PolishTokenDup is uint; +type PolishTokenUnnormalizedLagrangeBasis is RowOffset; +type PolishTokenLoad is uint; +type PolishTokenSkipIf is uint; + +enum Column { + Placeholder // FIXME: +} + +enum CurrOrNext { + Curr, + Next +} + +struct Variable { + Column col; + CurrOrNext row; +} + +struct RowOffset { + bool zk_rows; + uint offset; +} + +// Variants like LookupPattern and TableWidth have data associated to them. +// We will represent them as a contiguous array of `bytes`. +struct FeatureFlag { + FeatureFlagVariant variant; + bytes data; +} + +enum FeatureFlagVariant { + RangeCheck0, + RangeCheck1, + ForeignFieldAdd, + ForeignFieldMul, + Xor, + Rot, + LookupTables, + RuntimeLookupTables, + // TODO: LookupPattern(LookupPattern), + /// Enabled if the table width is at least the given number + TableWidth + /// Enabled if the number of lookups per row is at least the given number + // TODO: LookupsPerRow(isize) +} +type FeatureFlagTableWidth is uint; From f974e9350f3b77c80b2df464e89900d05ebef4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Tue, 5 Dec 2023 13:17:12 -0300 Subject: [PATCH 22/68] Added new test circuit for the KZG prover --- kzg_prover/src/main.rs | 68 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/kzg_prover/src/main.rs b/kzg_prover/src/main.rs index 5ece737e..d6d3f1ee 100644 --- a/kzg_prover/src/main.rs +++ b/kzg_prover/src/main.rs @@ -20,17 +20,21 @@ use kimchi::{ constraints::ConstraintSystem, domains::EvaluationDomains, gate::{CircuitGate, GateType}, - polynomials::generic::testing::{create_circuit, fill_in_witness}, - wires::COLUMNS, + polynomials::{ + generic::testing::{create_circuit, fill_in_witness}, + range_check, + }, + wires::{Wire, COLUMNS}, }, curve::KimchiCurve, groupmap::*, keccak_sponge::{Keccak256FqSponge, Keccak256FrSponge}, - o1_utils::FieldHelpers, + o1_utils::{foreign_field::BigUintForeignFieldHelpers, BigUintFieldHelpers, FieldHelpers}, proof::ProverProof, prover_index::{self, ProverIndex}, verifier::{batch_verify, Context}, }; +use num::{bigint::RandBigInt, BigUint}; use num_traits::{One, Zero}; use poly_commitment::{ commitment::{combine_commitments, combine_evaluations, CommitmentCurve, Evaluation}, @@ -59,6 +63,64 @@ type KZGProof = PairingProof>; fn main() { generate_verifier_circuit_proof(); //generate_test_proof(); + generate_test_proof_ex(); +} + +fn generate_test_proof_ex() { + let rng = &mut StdRng::from_seed([255u8; 32]); + + // Create range-check gadget + let (mut next_row, mut gates) = CircuitGate::::create_multi_range_check(0); + + // Create witness + let witness = range_check::witness::create_multi::( + rng.gen_biguint_range(&BigUint::zero(), &BigUint::two_to_limb()) + .to_field() + .expect("failed to convert to field"), + rng.gen_biguint_range(&BigUint::zero(), &BigUint::two_to_limb()) + .to_field() + .expect("failed to convert to field"), + rng.gen_biguint_range(&BigUint::zero(), &BigUint::two_to_limb()) + .to_field() + .expect("failed to convert to field"), + ); + + // Temporary workaround for lookup-table/domain-size issue + for _ in 0..(1 << 13) { + gates.push(CircuitGate::zero(Wire::for_row(next_row))); + next_row += 1; + } + + // Create constraint system + let cs = ConstraintSystem::::create(gates) + //.lookup(vec![range_check::gadget::lookup_table()]) + .build() + .unwrap(); + + let x = ark_bn254::Fr::rand(rng); + let srs = Arc::new(create_srs(x, cs.gates.len(), cs.domain)); + + let ptr: &mut SRS = unsafe { &mut *(std::sync::Arc::as_ptr(&srs) as *mut _) }; + ptr.add_lagrange_basis(cs.domain.d1); + + let (_endo_r, endo_q) = G1::endos(); + let index = ProverIndex::::create(cs, *endo_q, srs); + let group_map = ::Map::setup(); + let proof = ProverProof::create_recursive::( + &group_map, + witness, + &[], + &index, + vec![], + None, + ) + .unwrap(); + + fs::write( + "../eth_verifier/prover_proof.mpk", + rmp_serde::to_vec_named(&proof).unwrap(), + ) + .unwrap(); } fn generate_verifier_circuit_proof() { From 8fdebcbccc25225dd8a2d4287fc47611ba728b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Tue, 5 Dec 2023 14:23:06 -0300 Subject: [PATCH 23/68] Added better comment to polishtoken --- eth_verifier/lib/expr/PolishToken.sol | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/eth_verifier/lib/expr/PolishToken.sol b/eth_verifier/lib/expr/PolishToken.sol index 247c9fdc..01940702 100644 --- a/eth_verifier/lib/expr/PolishToken.sol +++ b/eth_verifier/lib/expr/PolishToken.sol @@ -3,8 +3,13 @@ pragma solidity >=0.4.16 <0.9.0; import "../bn254/Fields.sol"; -// Variants like Mds, Literal and Cell have data associated to them. We will -// represent them as `bytes`. +// PolishToken is a tagged union type, whose variants can hold different data types. +// In Rust this can be implemented as an enum, in Typescript as a discriminated union. +// +// Here we'll use a struct, which will hold the `variant` tag as an enum and the +// `data` as bytes. The struct will be discriminated over its `variant` and after +// we can decode the bytes into the corresponding data type. + struct PolishToken { PolishTokenVariant variant; bytes data; From e368ffc01e2cc16e85270e126c147dd4a672d7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Tue, 5 Dec 2023 18:21:16 -0300 Subject: [PATCH 24/68] RPN progress --- eth_verifier/lib/Permutation.sol | 26 ++++ eth_verifier/lib/Proof.sol | 11 ++ eth_verifier/lib/expr/Expr.sol | 56 +++++++++ eth_verifier/lib/expr/ExprConstants.sol | 15 +++ eth_verifier/lib/expr/PolishToken.sol | 161 +++++++++++++++++------- 5 files changed, 227 insertions(+), 42 deletions(-) create mode 100644 eth_verifier/lib/Permutation.sol create mode 100644 eth_verifier/lib/expr/Expr.sol create mode 100644 eth_verifier/lib/expr/ExprConstants.sol diff --git a/eth_verifier/lib/Permutation.sol b/eth_verifier/lib/Permutation.sol new file mode 100644 index 00000000..b318e1c8 --- /dev/null +++ b/eth_verifier/lib/Permutation.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.4.16 <0.9.0; + +import "./bn254/Fields.sol"; + +using {Scalar.sub, Scalar.mul, Scalar.pow} for Scalar.FE; + +/// @notice valuates the polynomial +/// @notice (x - w^{n - i}) * (x - w^{n - i + 1}) * ... * (x - w^{n - 1}) +function eval_vanishes_on_last_n_rows( + Scalar.FE domain_gen, + uint domain_size, + uint i, + Scalar.FE x +) pure returns (Scalar.FE acc) { + if (i == 0) { + return Scalar.one(); + } + Scalar.FE term = domain_gen.pow(domain_size - i); + Scalar.FE acc = x.sub(term); + for (uint _ = 0; _ < i - 1; _++) { + term = term.mul(domain_gen); + acc = acc.mul(x.sub(term)); + } +} + diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index fb259b3e..5094f5a7 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -4,6 +4,7 @@ pragma solidity >=0.4.16 <0.9.0; import "./Evaluations.sol"; import "./Polynomial.sol"; import "./Constants.sol"; +import "./expr/Expr.sol"; struct ProverProof { ProofEvaluationsArray evals; @@ -81,3 +82,13 @@ function combine_evals( return ProofEvaluations(public_evals, self.is_public_evals_set, w, z, s); } + +function evaluate_column(ProofEvaluations memory self, Column ) + +function evaluate_variable( + Variable memory self, + ProofEvaluations memory evals +) pure returns (Scalar.FE) { + +} + diff --git a/eth_verifier/lib/expr/Expr.sol b/eth_verifier/lib/expr/Expr.sol new file mode 100644 index 00000000..baaa144e --- /dev/null +++ b/eth_verifier/lib/expr/Expr.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.4.16 <0.9.0; + +enum Column { + Placeholder // FIXME: + // Witness(usize), + // Z, + // LookupSorted(usize), + // LookupAggreg, + // LookupTable, + // LookupKindIndex(LookupPattern), + // LookupRuntimeSelector, + // LookupRuntimeTable, + // Index(GateType), + // Coefficient(usize), + // Permutation(usize), +} + +enum CurrOrNext { + Curr, + Next +} + +struct Variable { + Column col; + CurrOrNext row; +} + +struct RowOffset { + bool zk_rows; + uint offset; +} + +// Variants like LookupPattern and TableWidth have data associated to them. +// We will represent them as a contiguous array of `bytes`. +struct FeatureFlag { + FeatureFlagVariant variant; + bytes data; +} + +enum FeatureFlagVariant { + RangeCheck0, + RangeCheck1, + ForeignFieldAdd, + ForeignFieldMul, + Xor, + Rot, + LookupTables, + RuntimeLookupTables, + // TODO: LookupPattern(LookupPattern), + /// Enabled if the table width is at least the given number + TableWidth + /// Enabled if the number of lookups per row is at least the given number + // TODO: LookupsPerRow(isize) +} +type FeatureFlagTableWidth is uint; diff --git a/eth_verifier/lib/expr/ExprConstants.sol b/eth_verifier/lib/expr/ExprConstants.sol new file mode 100644 index 00000000..0bc2cc95 --- /dev/null +++ b/eth_verifier/lib/expr/ExprConstants.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.4.16 <0.9.0; + +import "../bn254/Fields.sol"; + +// @notice constants required to evaluate an expression. +struct ExprConstants { + Scalar.FE alpha; + Scalar.FE beta; + Scalar.FE gamma; + Scalar.FE joint_combiner; + Scalar.FE endo_coefficient; + Scalar.FE[] mds; // the MDS matrix in row/col major // FIXME: determine order + uint zk_rows; +} diff --git a/eth_verifier/lib/expr/PolishToken.sol b/eth_verifier/lib/expr/PolishToken.sol index 01940702..3af9194d 100644 --- a/eth_verifier/lib/expr/PolishToken.sol +++ b/eth_verifier/lib/expr/PolishToken.sol @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; +import "./Expr.sol"; +import "./ExprConstants.sol"; import "../bn254/Fields.sol"; +import "../Permutation.sol"; + +using {Scalar.mul, Scalar.sub, Scalar.pow, Scalar.inv} for Scalar.FE; // PolishToken is a tagged union type, whose variants can hold different data types. // In Rust this can be implemented as an enum, in Typescript as a discriminated union. @@ -15,6 +20,104 @@ struct PolishToken { bytes data; } +function evaluate( + PolishToken[] memory toks, + Scalar.FE d_gen, + uint d_size, + Scalar.FE pt, + ProofEvaluations memory evals, + ExprConstants memory c +) pure returns (Scalar.FE) { + Scalar.FE[] stack = new Scalar.FE[](toks.length); + uint stack_next = 0; // will keep track of last stack element's index + Scalar.FE[] cache = new Scalar.FE[](toks.length); + // WARN: Both arrays allocate the maximum memory the'll ever use, but it's + // WARN: pretty unlikely they'll need it all. + + uint skip_count = 0; + + for (uint i = 0; i < toks.length; i++) { + if (skip_count > 0) { + skip_count -= 1; + continue; + } + + PolishTokenVariant v = toks[i].variant; + if (v == PolishTokenVariant.Alpha) { + stack[stack_next] = c.alpha; + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Beta) { + stack[stack_next] = c.beta; + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Gamma) { + stack[stack_next] = c.gamma; + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.JointCombiner) { + stack[stack_next] = c.joint_combiner; + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.EndoCoefficient) { + stack[stack_next] = c.endo_coefficient; + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Mds) { + PolishTokenMds memory pos = abi.decode(v.data, (PolishTokenMds)); + stack[stack_next] = c.mds[pos.row + pos.col]; // FIXME: determine order + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.VanishesOnZeroKnowledgeAndPreviousRows ) { + stack[stack_next] = eval_vanishes_on_last_n_rows( + domain_gen, + domain_size, + c.zk_rows + 1, + pt + ); + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.UnnormalizedLagrangeBasis) { + PolishTokenUnnormalizedLagrangeBasis i = abi.decode(v.data, (PolishTokenUnnormalizedLagrangeBasis )); + + uint offset; + if (i.zk_rows) { + offset = -(c.zk_rows) + i.offset; + } else { + offset = i.offset; + } + + stack[stack_next] = unnormalized_lagrange_basis(domain_gen, domain_size, offset, pt); + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Literal) { + PolishTokenLiteral x = abi.decode(v.data, (PolishTokenLiteral)); + stack[stack_next] = x; + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Dup) { + stack[stack_next] = stack[stack_next - 1]; + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Cell) { + PolishTokenCell x = abi.decode(v.data, (PolishTokenCell)); + stack[stack_next] = stack[stack_next - 1]; + stack_next += 1; + continue; + } + } +} + enum PolishTokenVariant { Alpha, Beta, @@ -33,9 +136,9 @@ enum PolishTokenVariant { UnnormalizedLagrangeBasis, Store, Load, - /// Skip the given number of tokens if the feature is enabled. + // Skip the given number of tokens if the feature is enabled. SkipIf, - /// Skip the given number of tokens if the feature is disabled. + // Skip the given number of tokens if the feature is disabled. SkipIfNot } @@ -50,45 +153,19 @@ type PolishTokenUnnormalizedLagrangeBasis is RowOffset; type PolishTokenLoad is uint; type PolishTokenSkipIf is uint; -enum Column { - Placeholder // FIXME: -} - -enum CurrOrNext { - Curr, - Next -} - -struct Variable { - Column col; - CurrOrNext row; -} - -struct RowOffset { - bool zk_rows; - uint offset; -} - -// Variants like LookupPattern and TableWidth have data associated to them. -// We will represent them as a contiguous array of `bytes`. -struct FeatureFlag { - FeatureFlagVariant variant; - bytes data; -} +// @notice Compute the ith unnormalized lagrange basis +function unnormalized_lagrange_basis( + Scalar.FE domain_gen, + uint domain_size, + uint i, + Scalar.FE pt +) pure returns (Scalar.FE) { + Scalar.FE omega_i; + if (i < 0) { + omega_i = domain_gen.pow(-i).inv(); + } else { + omega_i = domain_gen.pow(i); + } -enum FeatureFlagVariant { - RangeCheck0, - RangeCheck1, - ForeignFieldAdd, - ForeignFieldMul, - Xor, - Rot, - LookupTables, - RuntimeLookupTables, - // TODO: LookupPattern(LookupPattern), - /// Enabled if the table width is at least the given number - TableWidth - /// Enabled if the number of lookups per row is at least the given number - // TODO: LookupsPerRow(isize) + return pt.pow(domain_size).sub(Scalar.one()).mul((pt.sub(omega_i)).inv()); } -type FeatureFlagTableWidth is uint; From 752abb4a5ad4dffa5ddf42ba708948aa47a20cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Wed, 6 Dec 2023 13:35:33 -0300 Subject: [PATCH 25/68] Finished preliminary rpn evaluation --- eth_verifier/lib/Proof.sol | 54 +++++++++++++-------- eth_verifier/lib/expr/Expr.sol | 45 +++++++++++++++--- eth_verifier/lib/expr/PolishToken.sol | 67 ++++++++++++++++++++++++++- 3 files changed, 138 insertions(+), 28 deletions(-) diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index 5094f5a7..829098fe 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -14,13 +14,10 @@ struct ProofEvaluations { // public inputs polynomials PointEvaluations public_evals; bool is_public_evals_set; // public_evals is optional - // witness polynomials PointEvaluations[15] w; // TODO: use Constants.COLUMNS - // permutation polynomial PointEvaluations z; - // permutation polynomials // (PERMUTS-1 evaluations because the last permutation is only used in commitment form) PointEvaluations[7 - 1] s; // TODO: use Constants.PERMUTS @@ -29,13 +26,10 @@ struct ProofEvaluations { struct ProofEvaluationsArray { PointEvaluationsArray public_evals; bool is_public_evals_set; // public_evals is optional - // witness polynomials PointEvaluationsArray[15] w; // TODO: use Constants.COLUMNS - // permutation polynomial PointEvaluationsArray z; - // permutation polynomials // (PERMUTS-1 evaluations because the last permutation is only used in commitment form) PointEvaluationsArray[7 - 1] s; // TODO: use Constants.PERMUTS @@ -59,7 +53,7 @@ function combine_evals( } PointEvaluations[15] memory w; - for (uint i = 0; i < 15; i++) { + for (uint256 i = 0; i < 15; i++) { w[i] = PointEvaluations( Polynomial.build_and_eval(self.w[i].zeta, pt.zeta), Polynomial.build_and_eval(self.w[i].zeta_omega, pt.zeta_omega) @@ -67,13 +61,13 @@ function combine_evals( } PointEvaluations memory z; - z = PointEvaluations( - Polynomial.build_and_eval(self.z.zeta, pt.zeta), - Polynomial.build_and_eval(self.z.zeta_omega, pt.zeta_omega) - ); + z = PointEvaluations( + Polynomial.build_and_eval(self.z.zeta, pt.zeta), + Polynomial.build_and_eval(self.z.zeta_omega, pt.zeta_omega) + ); PointEvaluations[7 - 1] memory s; - for (uint i = 0; i < 7 - 1; i++) { + for (uint256 i = 0; i < 7 - 1; i++) { s[i] = PointEvaluations( Polynomial.build_and_eval(self.s[i].zeta, pt.zeta), Polynomial.build_and_eval(self.s[i].zeta_omega, pt.zeta_omega) @@ -83,12 +77,34 @@ function combine_evals( return ProofEvaluations(public_evals, self.is_public_evals_set, w, z, s); } -function evaluate_column(ProofEvaluations memory self, Column ) - -function evaluate_variable( - Variable memory self, - ProofEvaluations memory evals -) pure returns (Scalar.FE) { - +function evaluate_column(ProofEvaluations memory self, Column col) + pure + returns (PointEvaluations memory) +{ + if (col.variant == ColumnVariant.Witness) { + uint256 i = abi.decode(col.data, (uint256)); + return self.w[i]; + } + if (col.variant == ColumnVariant.Z) { + return self.z; + } + if (col.variant == ColumnVariant.Permutation) { + uint256 i = abi.decode(col.data, (uint256)); + return self.w[i]; + } + revert; + // TODO: rest of variants, for this it's necessary to expand ProofEvaluations } +function evaluate_variable(Variable memory self, ProofEvaluations memory evals) + pure + returns (Scalar.FE) +{ + PointEvaluations memory point_evals = evaluate_column(evals, self.col); + if (self.row == CurrOrNext.Curr) { + return point_evals.zeta; + } + if (self.row == CurrOrNext.Next) { + return point_evals.zeta_omega; + } +} diff --git a/eth_verifier/lib/expr/Expr.sol b/eth_verifier/lib/expr/Expr.sol index baaa144e..80a38778 100644 --- a/eth_verifier/lib/expr/Expr.sol +++ b/eth_verifier/lib/expr/Expr.sol @@ -1,20 +1,29 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; -enum Column { - Placeholder // FIXME: - // Witness(usize), - // Z, +struct Column { + ColumnVariant variant; + bytes data; +} + +enum ColumnVariant { + Witness, + Z, + Index, + Coefficient, + Permutation + // TODO: // LookupSorted(usize), // LookupAggreg, // LookupTable, // LookupKindIndex(LookupPattern), // LookupRuntimeSelector, // LookupRuntimeTable, - // Index(GateType), - // Coefficient(usize), - // Permutation(usize), } +type ColumnWitness is uint; +//type ColumnIndex is GateType; // can't set an alias for an enum :( +type ColumnCoefficient is uint; +type ColumnPermutation is uint; enum CurrOrNext { Curr, @@ -54,3 +63,25 @@ enum FeatureFlagVariant { // TODO: LookupsPerRow(isize) } type FeatureFlagTableWidth is uint; + +enum GateType { + // Gate types + Zero, + Generic, + Poseidon, + CompleteAdd, + VarBaseMul, + EndoMul, + EndoMulScalar, + Lookup, + CairoClaim, + CairoInstruction, + CairoFlags, + CairoTransition, + RangeCheck0, + RangeCheck1, + ForeignFieldAdd, + ForeignFieldMul, + Xor16, + Rot64 +} diff --git a/eth_verifier/lib/expr/PolishToken.sol b/eth_verifier/lib/expr/PolishToken.sol index 3af9194d..ba383a07 100644 --- a/eth_verifier/lib/expr/PolishToken.sol +++ b/eth_verifier/lib/expr/PolishToken.sol @@ -5,6 +5,7 @@ import "./Expr.sol"; import "./ExprConstants.sol"; import "../bn254/Fields.sol"; import "../Permutation.sol"; +import "../Proof.sol"; using {Scalar.mul, Scalar.sub, Scalar.pow, Scalar.inv} for Scalar.FE; @@ -31,6 +32,7 @@ function evaluate( Scalar.FE[] stack = new Scalar.FE[](toks.length); uint stack_next = 0; // will keep track of last stack element's index Scalar.FE[] cache = new Scalar.FE[](toks.length); + uint cache_next = 0; // will keep track of last cache element's index // WARN: Both arrays allocate the maximum memory the'll ever use, but it's // WARN: pretty unlikely they'll need it all. @@ -110,12 +112,72 @@ function evaluate( continue; } if (v == PolishTokenVariant.Cell) { - PolishTokenCell x = abi.decode(v.data, (PolishTokenCell)); - stack[stack_next] = stack[stack_next - 1]; + Variable x = abi.decode(v.data, (PolishTokenCell)); // WARN: different types + stack[stack_next] = evaluate_variable(x, evals); + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Pow) { + uint n = abi.decode(v.data, (PolishTokenPow)); // WARN: different types + stack[stack_next - 1] = stack[stack_next - 1].pow(n); + continue; + } + if (v == PolishTokenVariant.Add) { + // pop x and y + Scalar.FE x = stack[stack_next - 1]; + stack_next -= 1; + Scalar.FE y = stack[stack_next - 1]; + stack_next -= 1; + + // push result + stack[stack_next] = x.add(y); + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Mul) { + // pop x and y + Scalar.FE x = stack[stack_next - 1]; + stack_next -= 1; + Scalar.FE y = stack[stack_next - 1]; + stack_next -= 1; + + // push result + stack[stack_next] = x.mul(y); + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Sub) { + // pop x and y + Scalar.FE x = stack[stack_next - 1]; + stack_next -= 1; + Scalar.FE y = stack[stack_next - 1]; + stack_next -= 1; + + // push result + stack[stack_next] = x.sub(y); + stack_next += 1; + continue; + } + if (v == PolishTokenVariant.Store) { + Scalar.FE x = stack[stack_next - 1]; + + cache[cache_next] = x; + cache_next += 1; + continue; + } + if (v == PolishTokenVariant.Load) { + uint i = abi.decode(v.data, (PolishTokenLoad)); // WARN: different types + Scalar.FE x = cache[i]; + + stack[stack_next] = x; stack_next += 1; continue; } + revert; + // TODO: SkipIf, SkipIfNot } + require(stack_next == 1); + return stack[0]; } enum PolishTokenVariant { @@ -149,6 +211,7 @@ struct PolishTokenMds { type PolishTokenLiteral is Scalar.FE; type PolishTokenCell is Variable; type PolishTokenDup is uint; +type PolishTokenPow is uint; type PolishTokenUnnormalizedLagrangeBasis is RowOffset; type PolishTokenLoad is uint; type PolishTokenSkipIf is uint; From 3ecc60dcc638f3ceeefdf8c48eb75683c6e396f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Wed, 6 Dec 2023 16:26:02 -0300 Subject: [PATCH 26/68] Fixes --- eth_verifier/lib/Permutation.sol | 2 +- eth_verifier/lib/Proof.sol | 4 +-- eth_verifier/lib/VerifierIndex.sol | 2 +- eth_verifier/lib/expr/Expr.sol | 2 +- eth_verifier/lib/expr/ExprConstants.sol | 2 +- eth_verifier/lib/expr/PolishToken.sol | 46 +++++++++++++------------ eth_verifier/src/Verifier.sol | 13 +++++++ 7 files changed, 43 insertions(+), 28 deletions(-) diff --git a/eth_verifier/lib/Permutation.sol b/eth_verifier/lib/Permutation.sol index b318e1c8..e5337593 100644 --- a/eth_verifier/lib/Permutation.sol +++ b/eth_verifier/lib/Permutation.sol @@ -18,7 +18,7 @@ function eval_vanishes_on_last_n_rows( } Scalar.FE term = domain_gen.pow(domain_size - i); Scalar.FE acc = x.sub(term); - for (uint _ = 0; _ < i - 1; _++) { + for (uint _j = 0; _j < i - 1; _j++) { term = term.mul(domain_gen); acc = acc.mul(x.sub(term)); } diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index 829098fe..2d7a8211 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -77,7 +77,7 @@ function combine_evals( return ProofEvaluations(public_evals, self.is_public_evals_set, w, z, s); } -function evaluate_column(ProofEvaluations memory self, Column col) +function evaluate_column(ProofEvaluations memory self, Column memory col) pure returns (PointEvaluations memory) { @@ -92,7 +92,7 @@ function evaluate_column(ProofEvaluations memory self, Column col) uint256 i = abi.decode(col.data, (uint256)); return self.w[i]; } - revert; + revert("unhandled column variant"); // TODO: rest of variants, for this it's necessary to expand ProofEvaluations } diff --git a/eth_verifier/lib/VerifierIndex.sol b/eth_verifier/lib/VerifierIndex.sol index 04881144..760bbe9c 100644 --- a/eth_verifier/lib/VerifierIndex.sol +++ b/eth_verifier/lib/VerifierIndex.sol @@ -13,7 +13,7 @@ struct VerifierIndex { // maximal size of polynomial section uint256 max_poly_size; // the number of randomized rows to achieve zero knowledge - uint256 zk_rows; + uint64 zk_rows; URS urs; // domain uint256 domain_size; diff --git a/eth_verifier/lib/expr/Expr.sol b/eth_verifier/lib/expr/Expr.sol index 80a38778..f23f4154 100644 --- a/eth_verifier/lib/expr/Expr.sol +++ b/eth_verifier/lib/expr/Expr.sol @@ -37,7 +37,7 @@ struct Variable { struct RowOffset { bool zk_rows; - uint offset; + int offset; } // Variants like LookupPattern and TableWidth have data associated to them. diff --git a/eth_verifier/lib/expr/ExprConstants.sol b/eth_verifier/lib/expr/ExprConstants.sol index 0bc2cc95..6530ef09 100644 --- a/eth_verifier/lib/expr/ExprConstants.sol +++ b/eth_verifier/lib/expr/ExprConstants.sol @@ -11,5 +11,5 @@ struct ExprConstants { Scalar.FE joint_combiner; Scalar.FE endo_coefficient; Scalar.FE[] mds; // the MDS matrix in row/col major // FIXME: determine order - uint zk_rows; + uint64 zk_rows; } diff --git a/eth_verifier/lib/expr/PolishToken.sol b/eth_verifier/lib/expr/PolishToken.sol index ba383a07..1c9c5d61 100644 --- a/eth_verifier/lib/expr/PolishToken.sol +++ b/eth_verifier/lib/expr/PolishToken.sol @@ -7,7 +7,7 @@ import "../bn254/Fields.sol"; import "../Permutation.sol"; import "../Proof.sol"; -using {Scalar.mul, Scalar.sub, Scalar.pow, Scalar.inv} for Scalar.FE; +using {Scalar.add, Scalar.mul, Scalar.sub, Scalar.pow, Scalar.inv} for Scalar.FE; // PolishToken is a tagged union type, whose variants can hold different data types. // In Rust this can be implemented as an enum, in Typescript as a discriminated union. @@ -23,15 +23,15 @@ struct PolishToken { function evaluate( PolishToken[] memory toks, - Scalar.FE d_gen, - uint d_size, + Scalar.FE domain_gen, + uint domain_size, Scalar.FE pt, ProofEvaluations memory evals, ExprConstants memory c -) pure returns (Scalar.FE) { - Scalar.FE[] stack = new Scalar.FE[](toks.length); +) view returns (Scalar.FE) { + Scalar.FE[] memory stack = new Scalar.FE[](toks.length); uint stack_next = 0; // will keep track of last stack element's index - Scalar.FE[] cache = new Scalar.FE[](toks.length); + Scalar.FE[] memory cache = new Scalar.FE[](toks.length); uint cache_next = 0; // will keep track of last cache element's index // WARN: Both arrays allocate the maximum memory the'll ever use, but it's // WARN: pretty unlikely they'll need it all. @@ -45,6 +45,7 @@ function evaluate( } PolishTokenVariant v = toks[i].variant; + bytes memory v_data = toks[i].data; if (v == PolishTokenVariant.Alpha) { stack[stack_next] = c.alpha; stack_next += 1; @@ -71,7 +72,7 @@ function evaluate( continue; } if (v == PolishTokenVariant.Mds) { - PolishTokenMds memory pos = abi.decode(v.data, (PolishTokenMds)); + PolishTokenMds memory pos = abi.decode(v_data, (PolishTokenMds)); stack[stack_next] = c.mds[pos.row + pos.col]; // FIXME: determine order stack_next += 1; continue; @@ -87,11 +88,11 @@ function evaluate( continue; } if (v == PolishTokenVariant.UnnormalizedLagrangeBasis) { - PolishTokenUnnormalizedLagrangeBasis i = abi.decode(v.data, (PolishTokenUnnormalizedLagrangeBasis )); + RowOffset memory i = abi.decode(v_data, (RowOffset)); - uint offset; + int offset; if (i.zk_rows) { - offset = -(c.zk_rows) + i.offset; + offset = i.offset - int(uint(c.zk_rows)); // 64 bit to 256 to signed 256 } else { offset = i.offset; } @@ -101,7 +102,7 @@ function evaluate( continue; } if (v == PolishTokenVariant.Literal) { - PolishTokenLiteral x = abi.decode(v.data, (PolishTokenLiteral)); + Scalar.FE x = abi.decode(v_data, (Scalar.FE)); stack[stack_next] = x; stack_next += 1; continue; @@ -112,13 +113,13 @@ function evaluate( continue; } if (v == PolishTokenVariant.Cell) { - Variable x = abi.decode(v.data, (PolishTokenCell)); // WARN: different types + Variable memory x = abi.decode(v_data, (Variable)); // WARN: different types stack[stack_next] = evaluate_variable(x, evals); stack_next += 1; continue; } if (v == PolishTokenVariant.Pow) { - uint n = abi.decode(v.data, (PolishTokenPow)); // WARN: different types + uint n = abi.decode(v_data, (uint)); // WARN: different types stack[stack_next - 1] = stack[stack_next - 1].pow(n); continue; } @@ -166,14 +167,14 @@ function evaluate( continue; } if (v == PolishTokenVariant.Load) { - uint i = abi.decode(v.data, (PolishTokenLoad)); // WARN: different types + uint i = abi.decode(v_data, (uint)); // WARN: different types Scalar.FE x = cache[i]; stack[stack_next] = x; stack_next += 1; continue; } - revert; + revert("unhandled polish token variant"); // TODO: SkipIf, SkipIfNot } require(stack_next == 1); @@ -208,26 +209,27 @@ struct PolishTokenMds { uint row; uint col; } -type PolishTokenLiteral is Scalar.FE; -type PolishTokenCell is Variable; +// type PolishTokenLiteral is Scalar.FE; // can't do this +// type PolishTokenCell is Variable; // can't do this type PolishTokenDup is uint; type PolishTokenPow is uint; -type PolishTokenUnnormalizedLagrangeBasis is RowOffset; +// type PolishTokenUnnormalizedLagrangeBasis is RowOffset; // can't do this type PolishTokenLoad is uint; type PolishTokenSkipIf is uint; +// TODO: maybe delete these types? // @notice Compute the ith unnormalized lagrange basis function unnormalized_lagrange_basis( Scalar.FE domain_gen, uint domain_size, - uint i, + int i, Scalar.FE pt -) pure returns (Scalar.FE) { +) view returns (Scalar.FE) { Scalar.FE omega_i; if (i < 0) { - omega_i = domain_gen.pow(-i).inv(); + omega_i = domain_gen.pow(uint(-i)).inv(); } else { - omega_i = domain_gen.pow(i); + omega_i = domain_gen.pow(uint(i)); } return pt.pow(domain_size).sub(Scalar.one()).mul((pt.sub(omega_i)).inv()); diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index f50f4bf4..709b2b18 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -13,6 +13,9 @@ import "../lib/Constants.sol"; import "../lib/msgpack/Deserialize.sol"; import "../lib/Alphas.sol"; import "../lib/Evaluations.sol"; +import "../lib/expr/Expr.sol"; +import "../lib/expr/PolishToken.sol"; +import "../lib/expr/ExprConstants.sol"; using {BN254.neg} for BN254.G1Point; using {Scalar.neg, Scalar.mul, Scalar.add} for Scalar.FE; @@ -212,6 +215,16 @@ contract KimchiVerifier { alphas, // FIXME: change for iterator to take into account previous alphas permutation_vanishing_polynomial ); + + ExprConstants memory constants = ExprConstants( + oracles.alpha, + oracles.beta, + oracles.gamma, + Scalar.from(0), // FIXME: joint_combiner in fiat-shamir + Scalar.from(0), // FIXME: endo_coefficient in verifier_index + new Scalar.FE[](0), // FIXME: keccak sponge mds + verifier_index.zk_rows + ); } function perm_scalars( From b96c5715a351a1e1c0225379d5b54236f865c7e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Wed, 6 Dec 2023 18:25:16 -0300 Subject: [PATCH 27/68] Test verifier index from new circuit --- eth_verifier/.gitignore | 3 +++ eth_verifier/lib/VerifierIndex.sol | 1 - eth_verifier/lib/msgpack/Deserialize.sol | 26 ++++++++++++++++++++++++ eth_verifier/test/Deserialize.t.sol | 3 ++- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/eth_verifier/.gitignore b/eth_verifier/.gitignore index 17246496..18bfe455 100644 --- a/eth_verifier/.gitignore +++ b/eth_verifier/.gitignore @@ -15,3 +15,6 @@ docs/ proof.mpk state.mpk + +prover_proof.mpk +verifier_index.mpk diff --git a/eth_verifier/lib/VerifierIndex.sol b/eth_verifier/lib/VerifierIndex.sol index 760bbe9c..303388cc 100644 --- a/eth_verifier/lib/VerifierIndex.sol +++ b/eth_verifier/lib/VerifierIndex.sol @@ -24,7 +24,6 @@ struct VerifierIndex { Scalar.FE[7] shift; // TODO: use Consants.PERMUTS /// domain offset for zero-knowledge Scalar.FE w; - } function verifier_digest(VerifierIndex storage index) returns (Base.FE) { diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 3cc7353d..5c63e155 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -74,6 +74,10 @@ library MsgPk { return abi.encode(deser_fixmap(self)); } else if (prefix >> 4 == 0x09) { return abi.encode(deser_fixarr(self)); + } else if (prefix == 0xde) { + return abi.encode(deser_map16(self)); + } else if (prefix == 0xdc) { + return abi.encode(deser_arr16(self)); } else if (prefix >> 2 == 0x33) { return abi.encode(deser_uint(self)); } else if (prefix >> 7 == 0x00) { @@ -144,6 +148,24 @@ library MsgPk { } } + function deser_arr16(Stream memory self) + public + view + returns (EncodedArray memory arr) + { + bytes1 first = next(self); + require(first == 0xdc, "not an arr16"); + // size is next two bytes: + + uint16 n = uint16(bytes2(next_n(self, 2))); + + arr = EncodedArray(new bytes[](n)); + + for (uint16 i = 0; i < n; i++) { + arr.values[i] = deser_encode(self); + } + } + function deser_map16(Stream memory self) public view @@ -219,6 +241,10 @@ library MsgPk { find_value(map, "public"), (uint256) ); + index.zk_rows = abi.decode( + find_value(map, "zk_rows"), + (uint64) + ); } function find_value(EncodedMap memory self, string memory key) diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index 0158146e..f80bb5aa 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -185,7 +185,7 @@ contract DeserializeTest is Test { function test_deserialize_verifier_index() public { bytes - memory verifier_index_serialized = hex"de0015a6646f6d61696ec4ac00200000000000000d00000000200000000000000000000000000000000000000000000000000000000000000180604384d657bfc5a27537a9a64a65524ccd53348302b79c969a6d50cb623010d3bd9b8d9ba44a762d3a8ee2f31bd37b66b278c8ea1d0062ae69b849ab6f00c95dd9ab5a200b3bca888197fa74dfc8c8b61c6adb24e1080461acbf58ed7016676666c6d4fbf3e7062d4acae95caea98b56cd337cb5b949aad9135a94525b13ad6d61785f706f6c795f73697a65cd4000a77a6b5f726f777303a67075626c696300af707265765f6368616c6c656e67657300aa7369676d615f636f6d6d9782a9756e7368696674656491c420364315ea1fe73fc3478a9823dc4a927119ff6e633fb41812a5605c9fc0ac72aaa773686966746564c082a9756e7368696674656491c420633a980d5940136aeb4eaa2145aad94dbbc1acd0ee911544ca9d65a8f860a40ca773686966746564c082a9756e7368696674656491c42011230853b13814d3fb7a1c6994c21e23ba083abe94ceaad63feffe686091b49da773686966746564c082a9756e7368696674656491c4201baa6d070773617ef0658e4a622a5a67497fbe8b91b905aacba29ba17f42741ea773686966746564c082a9756e7368696674656491c4208669bcc973be53b864a28e652f04ab5cf72ca20f246819dd6f15ad3d8d51f5a3a773686966746564c082a9756e7368696674656491c4201e3002266069d0191ba82c889749d17c4a22a7f2d85d0487d2df57d8f2a28094a773686966746564c082a9756e7368696674656491c420017b22822869b290ff28ac82a15e68b6003236e4154fe9f8f40fb374dcd5338fa773686966746564c0b1636f656666696369656e74735f636f6d6d9f82a9756e7368696674656491c420f08c0c257c5ec41234224482a6d9b42635b662425b25b86f8a60eddd8b8ccfa5a773686966746564c082a9756e7368696674656491c42078fce52175dd1b6afa55bcf432537240a066e61ccff2b30ebb46e99d5e2c3500a773686966746564c082a9756e7368696674656491c4203c8fecd0515ad1740d07a906080ced3300e0a185eafb7fe48b7f4af017d0e48ea773686966746564c082a9756e7368696674656491c4207c3532ca64a3ec2778fab0ef5b3ed566de2bbb34410bcc7cac35d43ceee62320a773686966746564c082a9756e7368696674656491c420894cf4855baaf3744ecd1251074f05530ba28700a331e659e796bfda9e3b941fa773686966746564c082a9756e7368696674656491c420df8aafd9d21ae04c63f3a70c8ef668b894e938961f5fc2a4451634aa272d7286a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c420434278e55a777606754cee725607035dba64830be1d3852409d80e0b36f71224a773686966746564c082a9756e7368696674656491c420cb201e2a3088fc2a7fe8c8bbcc77548db0df19c7cc053388323998b657a1f886a773686966746564c082a9756e7368696674656491c4208d944ead72329988cc3c56026a8e0f2827c9d9a694441f0fbca64c6c1aed5a84a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e7368696674656491c4200000000000000000000000000000000000000000000000000000000000000040a773686966746564c0ac67656e657269635f636f6d6d82a9756e7368696674656491c4201af163363acc703294827809a39e668d2782ebcaf872d06f16576f6b996531a7a773686966746564c0a870736d5f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0b1636f6d706c6574655f6164645f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0a86d756c5f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0a9656d756c5f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0b3656e646f6d756c5f7363616c61725f636f6d6d82a9756e7368696674656491c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c25a773686966746564c0b172616e67655f636865636b305f636f6d6d82a9756e7368696674656491c420191418104060244c3c0e4aaa96c0e68a3f09a8319dff7e3909f8f6c8ca62ee8da773686966746564c0b172616e67655f636865636b315f636f6d6d82a9756e7368696674656491c42081542bf55ad01c67c1f5ff901f7e3a55395206e6d1aff8040862052238673d2ba773686966746564c0b6666f726569676e5f6669656c645f6164645f636f6d6d82a9756e7368696674656491c420f41e7e08a4db448418f5596f62f687dcbc6eb7a55a4d93b7cfdea37197027b02a773686966746564c0b6666f726569676e5f6669656c645f6d756c5f636f6d6dc0a8786f725f636f6d6dc0a8726f745f636f6d6dc0a5736869667497c4200100000000000000000000000000000000000000000000000000000000000000c420e3a214e91334d0caf1eb85df5bd7524d73d5eb7aaf742a7eb2d40bfdc8cdb900c4206d0f44339a339fb8a4e49bf1099620aa649918482b95a397ae39b9ec5ad47700c420b40923bd78e619c80a7b39c0f3f11e48005519d2fef16a1f77d40545e5c77700c420f9c95cd6b11b38df7855fd4d2a036329adcad613f100b923109540356a597c00c4205a696526fa309c412c10e86604c3c0ad2cd9443dd85b823203721281cfbf3300c42043423bb307cec19f297c4188deb23acc7b5812719b2eaccbf1b7034ae6ace800ac6c6f6f6b75705f696e64657886b16a6f696e745f6c6f6f6b75705f75736564c2ac6c6f6f6b75705f7461626c659182a9756e7368696674656491c42059149f1484af342fa425e9f230ca246babfab7cdd72d0ff5bc3d1176614cce2da773686966746564c0b06c6f6f6b75705f73656c6563746f727384a3786f72c0a66c6f6f6b7570c0ab72616e67655f636865636b82a9756e7368696674656491c4204f4763225f13070a3c7d728bb86526080c7d75c4a6928ab8940c2c49b1d97c8ca773686966746564c0a566666d756cc0a97461626c655f69647382a9756e7368696674656491c420211e5d946fbeb572bb16898a1a1f8fef49484671f4a1ba7e746898276befff1ea773686966746564c0ab6c6f6f6b75705f696e666f83ab6d61785f7065725f726f7704ae6d61785f6a6f696e745f73697a6501a8666561747572657383a87061747465726e7384a3786f72c2a66c6f6f6b7570c2ab72616e67655f636865636bc3b1666f726569676e5f6669656c645f6d756cc2b16a6f696e745f6c6f6f6b75705f75736564c2b3757365735f72756e74696d655f7461626c6573c2b772756e74696d655f7461626c65735f73656c6563746f72c0"; + memory verifier_index_serialized = hex"DE0015A6646F6D61696E82A474797065A6427566666572A464617461DC00AC00400000000000000E00000000400000000000000000000000000000000000000000000000000000000000000140CCB0190CCCE6CC9CCC81CCABCC89CC97CCD87847CCBFCCC65752CCA76A7564CCA937631B66CCA7CCE1CC8C6330CC856E7C61CCC201CCAACCADCCE6CCAA2074CCE13ECCA9CCB4CCA8CCA8CCDC0DCCB8514E1FCC81CCE4CCD9CCCD5156CC962D10CC841C6434CCE9CCEECCF8CCC0717767CCB07609CCF4CC8C6ECC8E55420D6811CCE9CCE9CCE7066F031C28676666CCC6CCD4CCFBCCF3CCE7062D4ACCCACCE95CCCAECCA9CC8B56CCCD337CCCB5CCB949CCAACCD9135ACC94525B13AD6D61785F706F6C795F73697A65CD4000A77A6B5F726F777303A67075626C696300AF707265765F6368616C6C656E67657300AA7369676D615F636F6D6D9782A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC8E6A46CCC4CC9A5B053E3ACCD03ACCCACC896319CCAB43CC88CCAFCC887ECC84CCBC3DCCACCCFB49CCAB67CCDDCC93CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200F751F4138CC9FCCEFCCCACCC43ACCB9CCA01B0810CCAB2CCCB74C70CCDFCCD8CC9521CCC7CCA0CCCFCCA15019CCDECCA4A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCC903D4275CC90CC98CC987ACCE8CCA0CC946A33CCDACCB8CCBB386052CC93CCDF725A29CCC840CCF4CC87CCD6CCABCC99A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7526CCDDCC86CCA2CC9CCCD6CC8F0ACC937E062E56CCD25E3250CC90CC86CCC958CC84CCE0CCA5CC9701CC99CC8F7BCCA5A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC964300CC855F1C7BCCB37B55CC854C582F48CCC54938CCAB48CC815BCCD64A5ACCC62DCC8C37CCDDCCE403A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCF9322C5458CCD204CCDECC90CCE7CCFBCCED5E5ACCB2CCFC4651CCBA62297E0ACCFCCCF2CCCACCFBCCB0CCA05D0421A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCB3183ECCF8CCF4CC9410CCA465CCA4CCD145CC97CC9A4E5FCCB92FCCEACC81CCD7767434CC99CCC7CCC428CCEBCCBB6819A773686966746564C0B1636F656666696369656E74735F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C0AC67656E657269635F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A870736D5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B1636F6D706C6574655F6164645F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A86D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A9656D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B3656E646F6D756C5F7363616C61725F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B172616E67655F636865636B305F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020190C1BCC8C2123CC9301CCC0CCCD623DCCA5CC91CC84CCEBCC871B15076BCCF5CCC1CCD7497ACC8ACC99CCC2260ACCA4A773686966746564C0B172616E67655F636865636B315F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCFA37CCB2CCCFCCCB1A44CCE4CCF8204DCCB54FCC852335CCE0075ECC8D6BCC87CCB4CCA3CCB47444185C44CCEDCCAFA773686966746564C0B6666F726569676E5F6669656C645F6164645F636F6D6DC0B6666F726569676E5F6669656C645F6D756C5F636F6D6DC0A8786F725F636F6D6DC0A8726F745F636F6D6DC0A573686966749782A474797065A6427566666572A464617461DC0020010000000000000000000000000000000000000000000000000000000000000082A474797065A6427566666572A464617461DC0020CCE3CCA214CCE91334CCD0CCCACCF1CCEBCC85CCDF5BCCD7524D73CCD5CCEB7ACCAF742A7ECCB2CCD40BCCFDCCC8CCCDCCB90082A474797065A6427566666572A464617461DC00206D0F4433CC9A33CC9FCCB8CCA4CCE4CC9BCCF109CC9620CCAA64CC9918482BCC95CCA3CC97CCAE39CCB9CCEC5ACCD4770082A474797065A6427566666572A464617461DC0020CCB40923CCBD78CCE619CCC80A7B39CCC0CCF3CCF11E48005519CCD2CCFECCF16A1F77CCD40545CCE5CCC7770082A474797065A6427566666572A464617461DC0020CCF9CCC95CCCD6CCB11B38CCDF7855CCFD4D2A036329CCADCCCACCD613CCF100CCB92310CC9540356A597C0082A474797065A6427566666572A464617461DC00205A696526CCFA30CC9C412C10CCE86604CCC3CCC0CCAD2CCCD9443DCCD85BCC8232037212CC81CCCFCCBF330082A474797065A6427566666572A464617461DC002043423BCCB307CCCECCC1CC9F297C41CC88CCDECCB23ACCCC7B581271CC9B2ECCACCCCBCCF1CCB7034ACCE6CCACCCE800AC6C6F6F6B75705F696E64657886B16A6F696E745F6C6F6F6B75705F75736564C2AC6C6F6F6B75705F7461626C659182A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE6CCA15E7ECCA10ECCD2CC8F0F3361CCC7CCA7CCF45CCCED5E6D382017CC8CCC832CCCFCCCC0CCDF0E343ECCB1CC80A773686966746564C0B06C6F6F6B75705F73656C6563746F727384A3786F72C0A66C6F6F6B7570C0AB72616E67655F636865636B82A9756E736869667465649182A474797065A6427566666572A464617461DC00201B24636044CCD6CCED30CCC611CC85CCD45B2969CC98CCB811CCB754CCA5507C08CCD1CC9124CC9B37CCC01721A773686966746564C0A566666D756CC0A97461626C655F69647382A9756E736869667465649182A474797065A6427566666572A464617461DC00205F28CC8BCCB342CC8034CCA922CCB3CCE618CCEA3ECC811ECCDF61CC81CCB10B7ECCF6CCC859CCFD03CCEA2B39CCA70EA773686966746564C0AB6C6F6F6B75705F696E666F83AB6D61785F7065725F726F7704AE6D61785F6A6F696E745F73697A6501A8666561747572657383A87061747465726E7384A3786F72C2A66C6F6F6B7570C2AB72616E67655F636865636BC3B1666F726569676E5F6669656C645F6D756CC2B16A6F696E745F6C6F6F6B75705F75736564C2B3757365735F72756E74696D655F7461626C6573C2B772756E74696D655F7461626C65735F73656C6563746F72C0"; MsgPk.deser_verifier_index( MsgPk.from_data(verifier_index_serialized), index @@ -193,5 +193,6 @@ contract DeserializeTest is Test { assertEq(index.public_len, 0); assertEq(index.max_poly_size, 16384); + assertEq(index.zk_rows, 3); } } From 8220f09831d9e6d8185d233b0735cdf93585af6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Thu, 7 Dec 2023 18:34:23 -0300 Subject: [PATCH 28/68] WIP fixes for deserialization --- eth_verifier/lib/Utils.sol | 20 +++++++++++ eth_verifier/lib/VerifierIndex.sol | 20 +++++++++++ eth_verifier/lib/msgpack/Deserialize.sol | 44 +++++++++++++++++------- eth_verifier/test/Deserialize.t.sol | 2 +- kzg_prover/src/main.rs | 9 ++++- 5 files changed, 81 insertions(+), 14 deletions(-) diff --git a/eth_verifier/lib/Utils.sol b/eth_verifier/lib/Utils.sol index 9f6cb0e5..2653c681 100644 --- a/eth_verifier/lib/Utils.sol +++ b/eth_verifier/lib/Utils.sol @@ -335,4 +335,24 @@ library Utils { } } } + + /// @notice flattens an array of `bytes` (so 2D array of the `byte` type). + function flatten_bytes_array(bytes[] memory b, uint bytes_per_element) public pure returns (bytes memory) { + uint byte_count = b.length * bytes_per_element; + bytes memory flat_b = new bytes(byte_count); + for (uint i = 0; i < byte_count; i++) { + flat_b[i] = b[i / bytes_per_element][i % bytes_per_element]; + } + return flat_b; + } + + /// @notice flattens an array of `bytes` (so 2D array of the `byte` type) and reverses it. + function flatten_bytes_array_rev(bytes[] memory b, uint bytes_per_element) public pure returns (bytes memory) { + uint byte_count = b.length * bytes_per_element; + bytes memory flat_b = new bytes(byte_count); + for (uint i = 0; i < byte_count; i++) { + flat_b[byte_count - i - 1] = b[i / bytes_per_element][i % bytes_per_element]; + } + return flat_b; + } } diff --git a/eth_verifier/lib/VerifierIndex.sol b/eth_verifier/lib/VerifierIndex.sol index 303388cc..39dc9449 100644 --- a/eth_verifier/lib/VerifierIndex.sol +++ b/eth_verifier/lib/VerifierIndex.sol @@ -30,3 +30,23 @@ function verifier_digest(VerifierIndex storage index) returns (Base.FE) { // FIXME: todo! return Base.from(42); } + +/// @notice Defines a domain over which finite field (I)FFTs can be performed. Works +/// @notice only for fields that have a large multiplicative subgroup of size that is +/// @notice a power-of-2. +struct Domain { + // Multiplicative generator of the finite field. + Scalar.FE generator_inv; + // Inverse of the generator of the subgroup. + Scalar.FE group_gen_inv; + // A generator of the subgroup. + Scalar.FE group_gen; + // Inverse of the size in the field. + Scalar.FE size_inv; + // Size of the domain as a field element. + Scalar.FE size_as_field_element; + // `log_2(self.size)`. + uint32 log_size_of_group; + // The size of the domain. + uint64 size; +} diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 5c63e155..7f80a998 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -26,7 +26,7 @@ library MsgPk { bytes[] values; } - function from_data(bytes calldata data) + function new_stream(bytes calldata data) public pure returns (Stream memory) @@ -82,8 +82,6 @@ library MsgPk { return abi.encode(deser_uint(self)); } else if (prefix >> 7 == 0x00) { return abi.encode(deser_posfixint(self)); - } else if (prefix >> 7 == 0x00) { - return abi.encode(deser_posfixint(self)); } else if (prefix == 0xc2 || prefix == 0xc3) { return abi.encode(deser_bool(self)); } else if (prefix == 0xc0) { @@ -203,11 +201,11 @@ library MsgPk { } } - function deser_posfixint(Stream memory self) public view returns (uint256) { + function deser_posfixint(Stream memory self) public view returns (uint8) { bytes1 first = next(self); require(first >> 7 == 0x00, "not a positive fixint"); - return uint256(uint8(first)); + return uint8(first); } function deser_null(Stream memory self) @@ -237,22 +235,44 @@ library MsgPk { find_value(map, "max_poly_size"), (uint256) ); - index.public_len = abi.decode( - find_value(map, "public"), - (uint256) + index.public_len = abi.decode(find_value(map, "public"), (uint256)); + index.zk_rows = abi.decode(find_value(map, "zk_rows"), (uint64)); + + EncodedMap memory domain_map = abi.decode( + find_value(map, "domain"), + (EncodedMap) ); - index.zk_rows = abi.decode( - find_value(map, "zk_rows"), - (uint64) + EncodedArray memory data_arr = abi.decode( + find_value(domain_map, "data"), + (EncodedArray) ); + + bytes memory domain_b = Utils.flatten_bytes_array_rev(data_arr.values, 32); + console.logBytes(domain_b); + + Domain memory domain = abi.decode(domain_b, (Domain)); + + console.log(domain.size); + console.log(domain.log_size_of_group); + console.log(Scalar.FE.unwrap(domain.group_gen)); + + //console.logBytes(b); + //console.log(b.length); } + error EncodedMapKeyNotFound(); function find_value(EncodedMap memory self, string memory key) public returns (bytes memory) { uint256 i = 0; - while (keccak256(bytes(self.keys[i])) != keccak256(bytes(key))) i++; + while ( + i != self.keys.length && + keccak256(bytes(self.keys[i])) != keccak256(bytes(key)) + ) { + i++; + } + if (i == self.keys.length) revert EncodedMapKeyNotFound(); return self.values[i]; } diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index f80bb5aa..2f05eabb 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -187,7 +187,7 @@ contract DeserializeTest is Test { bytes memory verifier_index_serialized = hex"DE0015A6646F6D61696E82A474797065A6427566666572A464617461DC00AC00400000000000000E00000000400000000000000000000000000000000000000000000000000000000000000140CCB0190CCCE6CC9CCC81CCABCC89CC97CCD87847CCBFCCC65752CCA76A7564CCA937631B66CCA7CCE1CC8C6330CC856E7C61CCC201CCAACCADCCE6CCAA2074CCE13ECCA9CCB4CCA8CCA8CCDC0DCCB8514E1FCC81CCE4CCD9CCCD5156CC962D10CC841C6434CCE9CCEECCF8CCC0717767CCB07609CCF4CC8C6ECC8E55420D6811CCE9CCE9CCE7066F031C28676666CCC6CCD4CCFBCCF3CCE7062D4ACCCACCE95CCCAECCA9CC8B56CCCD337CCCB5CCB949CCAACCD9135ACC94525B13AD6D61785F706F6C795F73697A65CD4000A77A6B5F726F777303A67075626C696300AF707265765F6368616C6C656E67657300AA7369676D615F636F6D6D9782A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC8E6A46CCC4CC9A5B053E3ACCD03ACCCACC896319CCAB43CC88CCAFCC887ECC84CCBC3DCCACCCFB49CCAB67CCDDCC93CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200F751F4138CC9FCCEFCCCACCC43ACCB9CCA01B0810CCAB2CCCB74C70CCDFCCD8CC9521CCC7CCA0CCCFCCA15019CCDECCA4A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCC903D4275CC90CC98CC987ACCE8CCA0CC946A33CCDACCB8CCBB386052CC93CCDF725A29CCC840CCF4CC87CCD6CCABCC99A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7526CCDDCC86CCA2CC9CCCD6CC8F0ACC937E062E56CCD25E3250CC90CC86CCC958CC84CCE0CCA5CC9701CC99CC8F7BCCA5A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC964300CC855F1C7BCCB37B55CC854C582F48CCC54938CCAB48CC815BCCD64A5ACCC62DCC8C37CCDDCCE403A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCF9322C5458CCD204CCDECC90CCE7CCFBCCED5E5ACCB2CCFC4651CCBA62297E0ACCFCCCF2CCCACCFBCCB0CCA05D0421A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCB3183ECCF8CCF4CC9410CCA465CCA4CCD145CC97CC9A4E5FCCB92FCCEACC81CCD7767434CC99CCC7CCC428CCEBCCBB6819A773686966746564C0B1636F656666696369656E74735F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C0AC67656E657269635F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A870736D5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B1636F6D706C6574655F6164645F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A86D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A9656D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B3656E646F6D756C5F7363616C61725F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B172616E67655F636865636B305F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020190C1BCC8C2123CC9301CCC0CCCD623DCCA5CC91CC84CCEBCC871B15076BCCF5CCC1CCD7497ACC8ACC99CCC2260ACCA4A773686966746564C0B172616E67655F636865636B315F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCFA37CCB2CCCFCCCB1A44CCE4CCF8204DCCB54FCC852335CCE0075ECC8D6BCC87CCB4CCA3CCB47444185C44CCEDCCAFA773686966746564C0B6666F726569676E5F6669656C645F6164645F636F6D6DC0B6666F726569676E5F6669656C645F6D756C5F636F6D6DC0A8786F725F636F6D6DC0A8726F745F636F6D6DC0A573686966749782A474797065A6427566666572A464617461DC0020010000000000000000000000000000000000000000000000000000000000000082A474797065A6427566666572A464617461DC0020CCE3CCA214CCE91334CCD0CCCACCF1CCEBCC85CCDF5BCCD7524D73CCD5CCEB7ACCAF742A7ECCB2CCD40BCCFDCCC8CCCDCCB90082A474797065A6427566666572A464617461DC00206D0F4433CC9A33CC9FCCB8CCA4CCE4CC9BCCF109CC9620CCAA64CC9918482BCC95CCA3CC97CCAE39CCB9CCEC5ACCD4770082A474797065A6427566666572A464617461DC0020CCB40923CCBD78CCE619CCC80A7B39CCC0CCF3CCF11E48005519CCD2CCFECCF16A1F77CCD40545CCE5CCC7770082A474797065A6427566666572A464617461DC0020CCF9CCC95CCCD6CCB11B38CCDF7855CCFD4D2A036329CCADCCCACCD613CCF100CCB92310CC9540356A597C0082A474797065A6427566666572A464617461DC00205A696526CCFA30CC9C412C10CCE86604CCC3CCC0CCAD2CCCD9443DCCD85BCC8232037212CC81CCCFCCBF330082A474797065A6427566666572A464617461DC002043423BCCB307CCCECCC1CC9F297C41CC88CCDECCB23ACCCC7B581271CC9B2ECCACCCCBCCF1CCB7034ACCE6CCACCCE800AC6C6F6F6B75705F696E64657886B16A6F696E745F6C6F6F6B75705F75736564C2AC6C6F6F6B75705F7461626C659182A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE6CCA15E7ECCA10ECCD2CC8F0F3361CCC7CCA7CCF45CCCED5E6D382017CC8CCC832CCCFCCCC0CCDF0E343ECCB1CC80A773686966746564C0B06C6F6F6B75705F73656C6563746F727384A3786F72C0A66C6F6F6B7570C0AB72616E67655F636865636B82A9756E736869667465649182A474797065A6427566666572A464617461DC00201B24636044CCD6CCED30CCC611CC85CCD45B2969CC98CCB811CCB754CCA5507C08CCD1CC9124CC9B37CCC01721A773686966746564C0A566666D756CC0A97461626C655F69647382A9756E736869667465649182A474797065A6427566666572A464617461DC00205F28CC8BCCB342CC8034CCA922CCB3CCE618CCEA3ECC811ECCDF61CC81CCB10B7ECCF6CCC859CCFD03CCEA2B39CCA70EA773686966746564C0AB6C6F6F6B75705F696E666F83AB6D61785F7065725F726F7704AE6D61785F6A6F696E745F73697A6501A8666561747572657383A87061747465726E7384A3786F72C2A66C6F6F6B7570C2AB72616E67655F636865636BC3B1666F726569676E5F6669656C645F6D756CC2B16A6F696E745F6C6F6F6B75705F75736564C2B3757365735F72756E74696D655F7461626C6573C2B772756E74696D655F7461626C65735F73656C6563746F72C0"; MsgPk.deser_verifier_index( - MsgPk.from_data(verifier_index_serialized), + MsgPk.new_stream(verifier_index_serialized), index ); diff --git a/kzg_prover/src/main.rs b/kzg_prover/src/main.rs index d6d3f1ee..a965063d 100644 --- a/kzg_prover/src/main.rs +++ b/kzg_prover/src/main.rs @@ -116,11 +116,19 @@ fn generate_test_proof_ex() { ) .unwrap(); + println!("{}", index.verifier_index().domain.size); + println!("{}", index.verifier_index().domain.log_size_of_group); + fs::write( "../eth_verifier/prover_proof.mpk", rmp_serde::to_vec_named(&proof).unwrap(), ) .unwrap(); + fs::write( + "../eth_verifier/verifier_index.mpk", + rmp_serde::to_vec_named(&index.verifier_index()).unwrap(), + ) + .unwrap(); } fn generate_verifier_circuit_proof() { @@ -232,7 +240,6 @@ fn generate_verifier_circuit_proof() { "Is verifier circuit's KZG proof valid?: {:?}", pairing_proof.verify(&srs, &evaluations, polyscale, &evaluation_points) ); - println!("{}", verifier_index.powers_of_alpha); } fn generate_test_proof() { From d6b54eb4b5d8e63cf9b0257858ac3affaa16a267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Fri, 8 Dec 2023 16:07:57 -0300 Subject: [PATCH 29/68] Final fixes --- eth_verifier/lib/Utils.sol | 21 +++++--------- eth_verifier/lib/VerifierIndex.sol | 20 ------------- eth_verifier/lib/msgpack/Deserialize.sol | 37 +++++++++++++++++------- eth_verifier/test/Deserialize.t.sol | 5 ++++ kzg_prover/src/main.rs | 3 -- 5 files changed, 39 insertions(+), 47 deletions(-) diff --git a/eth_verifier/lib/Utils.sol b/eth_verifier/lib/Utils.sol index 2653c681..c6c150a4 100644 --- a/eth_verifier/lib/Utils.sol +++ b/eth_verifier/lib/Utils.sol @@ -336,22 +336,15 @@ library Utils { } } - /// @notice flattens an array of `bytes` (so 2D array of the `byte` type). - function flatten_bytes_array(bytes[] memory b, uint bytes_per_element) public pure returns (bytes memory) { - uint byte_count = b.length * bytes_per_element; + /// @notice flattens an array of `bytes` (so 2D array of the `byte` type) + /// @notice assumed to be padded so every element is 32 bytes long. + // + // @notice this function will both flat and remove the padding. + function flatten_padded_bytes_array(bytes[] memory b) public view returns (bytes memory) { + uint byte_count = b.length; bytes memory flat_b = new bytes(byte_count); for (uint i = 0; i < byte_count; i++) { - flat_b[i] = b[i / bytes_per_element][i % bytes_per_element]; - } - return flat_b; - } - - /// @notice flattens an array of `bytes` (so 2D array of the `byte` type) and reverses it. - function flatten_bytes_array_rev(bytes[] memory b, uint bytes_per_element) public pure returns (bytes memory) { - uint byte_count = b.length * bytes_per_element; - bytes memory flat_b = new bytes(byte_count); - for (uint i = 0; i < byte_count; i++) { - flat_b[byte_count - i - 1] = b[i / bytes_per_element][i % bytes_per_element]; + flat_b[i] = b[i][32 - 1]; } return flat_b; } diff --git a/eth_verifier/lib/VerifierIndex.sol b/eth_verifier/lib/VerifierIndex.sol index 39dc9449..303388cc 100644 --- a/eth_verifier/lib/VerifierIndex.sol +++ b/eth_verifier/lib/VerifierIndex.sol @@ -30,23 +30,3 @@ function verifier_digest(VerifierIndex storage index) returns (Base.FE) { // FIXME: todo! return Base.from(42); } - -/// @notice Defines a domain over which finite field (I)FFTs can be performed. Works -/// @notice only for fields that have a large multiplicative subgroup of size that is -/// @notice a power-of-2. -struct Domain { - // Multiplicative generator of the finite field. - Scalar.FE generator_inv; - // Inverse of the generator of the subgroup. - Scalar.FE group_gen_inv; - // A generator of the subgroup. - Scalar.FE group_gen; - // Inverse of the size in the field. - Scalar.FE size_inv; - // Size of the domain as a field element. - Scalar.FE size_as_field_element; - // `log_2(self.size)`. - uint32 log_size_of_group; - // The size of the domain. - uint64 size; -} diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 7f80a998..beda2a93 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -247,17 +247,34 @@ library MsgPk { (EncodedArray) ); - bytes memory domain_b = Utils.flatten_bytes_array_rev(data_arr.values, 32); - console.logBytes(domain_b); - - Domain memory domain = abi.decode(domain_b, (Domain)); - - console.log(domain.size); - console.log(domain.log_size_of_group); - console.log(Scalar.FE.unwrap(domain.group_gen)); + // data_arr will hold an array of `bytes` arrays, where each `bytes` + // is a 32 sized byte array which represents only one byte, but padded + // with 31 zero bytes. e.g: + // data_arr[0]: 0x00000000000000000000000000000000000000000000000000000000000000a7 + // data_arr[1]: 0x0000000000000000000000000000000000000000000000000000000000000040 + // data_arr[3]: 0x000000000000000000000000000000000000000000000000000000000000002e + // + // this is becasue of Solidity's RLP encoding of every byte. + // We're interested in removing this padding and flattening all the arrays: + + bytes memory domain_b = Utils.flatten_padded_bytes_array(data_arr.values); + + // The domain info is in a packed, little endian serialization format. + // So we'll need to manually deserialize the parameters that we're + // interested in: + + // domain_size is 64 bit and the first element, so 8 bytes and no offset: + index.domain_size = 0; + for (uint i = 0; i < 8; i++) { + index.domain_size += uint(uint8(domain_b[i])) << (i*8); + } - //console.logBytes(b); - //console.log(b.length); + // domain_gen is 256 bit and there're 8+4+32+32=76 bytes before it: + uint domain_gen = 0; + for (uint i = 0; i < 32; i++) { + domain_gen += uint(uint8(domain_b[i + 76])) << (i*8); + } + index.domain_gen = Scalar.from(domain_gen); } error EncodedMapKeyNotFound(); diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index 2f05eabb..64e1a35e 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -194,5 +194,10 @@ contract DeserializeTest is Test { assertEq(index.public_len, 0); assertEq(index.max_poly_size, 16384); assertEq(index.zk_rows, 3); + assertEq(index.domain_size, 16384); + assertEq( + Scalar.FE.unwrap(index.domain_gen), + 20619701001583904760601357484951574588621083236087856586626117568842480512645 + ); } } diff --git a/kzg_prover/src/main.rs b/kzg_prover/src/main.rs index a965063d..c500a1da 100644 --- a/kzg_prover/src/main.rs +++ b/kzg_prover/src/main.rs @@ -116,9 +116,6 @@ fn generate_test_proof_ex() { ) .unwrap(); - println!("{}", index.verifier_index().domain.size); - println!("{}", index.verifier_index().domain.log_size_of_group); - fs::write( "../eth_verifier/prover_proof.mpk", rmp_serde::to_vec_named(&proof).unwrap(), From 1ed168aac853372b4dca5997ebe2c61805f1e4c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Fri, 8 Dec 2023 20:28:31 -0300 Subject: [PATCH 30/68] Deserialized part of the prover proof --- eth_verifier/lib/msgpack/Deserialize.sol | 147 ++++++++++++++++++----- eth_verifier/test/Deserialize.t.sol | 20 +++ kzg_prover/src/main.rs | 6 + 3 files changed, 141 insertions(+), 32 deletions(-) diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index beda2a93..18ab6fe2 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -8,6 +8,7 @@ import "../Evaluations.sol"; import "../Proof.sol"; import "../State.sol"; import "../Utils.sol"; +import "../UtilsExternal.sol"; import "../VerifierIndex.sol"; import "forge-std/console.sol"; @@ -57,6 +58,24 @@ library MsgPk { self.curr_index += n; } + error EncodedMapKeyNotFound(); + + function find_value(EncodedMap memory self, string memory key) + public + pure + returns (bytes memory) + { + uint256 i = 0; + while ( + i != self.keys.length && + keccak256(bytes(self.keys[i])) != keccak256(bytes(key)) + ) { + i++; + } + if (i == self.keys.length) revert EncodedMapKeyNotFound(); + return self.values[i]; + } + error NotImplementedType(bytes1 prefix); /// @notice deserializes the next type and returns the encoded data. @@ -66,8 +85,13 @@ library MsgPk { returns (bytes memory) { bytes1 prefix = curr(self); - if (prefix >> 5 == 0x05) { - return abi.encode(deser_fixstr(self)); + if ( + prefix >> 5 == 0x05 || + prefix == 0xd9 || + prefix == 0xda || + prefix == 0xdb + ) { + return abi.encode(deser_str(self)); } else if (prefix == 0xC4) { return abi.encode(deser_bin8(self)); } else if (prefix >> 4 == 0x08) { @@ -91,16 +115,39 @@ library MsgPk { } } - function deser_fixstr(Stream memory self) - public - view - returns (string memory) - { + function deser_str(Stream memory self) public view returns (string memory) { bytes1 first = next(self); - require(first >> 5 == 0x05, "not a fixstr"); - uint256 n = uint256(uint8(first & 0x1F)); // low nibble + lsb of high nibble + require( + first >> 5 == 0x05 || + first == 0xd9 || + first == 0xda || + first == 0xdb, + "not a fixstr or strX" + ); - return string(next_n(self, n)); + if (first >> 5 == 0x05) { + // fixstr + uint256 n = uint256(uint8(first & 0x1F)); // low nibble + lsb of high nibble + return string(next_n(self, n)); + } else { + // strX + + // get length of string in bytes `n` + uint256 n_byte_count = uint256(uint8(first & 0x03)); // least significant 2 bits + bytes memory n_bytes = next_n(self, n_byte_count); + uint256 n = 0; + if (n_byte_count == 1) { + n = uint8(bytes1(n_bytes)); + } else if (n_byte_count == 2) { + n = uint16(bytes2(n_bytes)); + } else if (n_byte_count == 3) { + n = uint32(bytes4(n_bytes)); + } else { + revert("deser_str unexpected length"); + } + + return string(next_n(self, n)); + } } function deser_bin8(Stream memory self) public view returns (bytes memory) { @@ -141,7 +188,7 @@ library MsgPk { map = EncodedMap(new string[](n), new bytes[](n)); for (uint256 i = 0; i < n; i++) { - map.keys[i] = deser_fixstr(self); + map.keys[i] = deser_str(self); map.values[i] = deser_encode(self); } } @@ -178,7 +225,7 @@ library MsgPk { map = EncodedMap(new string[](n), new bytes[](n)); for (uint16 i = 0; i < n; i++) { - map.keys[i] = deser_fixstr(self); + map.keys[i] = deser_str(self); map.values[i] = deser_encode(self); } } @@ -229,7 +276,7 @@ library MsgPk { function deser_verifier_index( Stream memory self, VerifierIndex storage index - ) public { + ) external { EncodedMap memory map = deser_map16(self); index.max_poly_size = abi.decode( find_value(map, "max_poly_size"), @@ -257,7 +304,9 @@ library MsgPk { // this is becasue of Solidity's RLP encoding of every byte. // We're interested in removing this padding and flattening all the arrays: - bytes memory domain_b = Utils.flatten_padded_bytes_array(data_arr.values); + bytes memory domain_b = Utils.flatten_padded_bytes_array( + data_arr.values + ); // The domain info is in a packed, little endian serialization format. // So we'll need to manually deserialize the parameters that we're @@ -265,32 +314,66 @@ library MsgPk { // domain_size is 64 bit and the first element, so 8 bytes and no offset: index.domain_size = 0; - for (uint i = 0; i < 8; i++) { - index.domain_size += uint(uint8(domain_b[i])) << (i*8); + for (uint256 i = 0; i < 8; i++) { + index.domain_size += uint256(uint8(domain_b[i])) << (i * 8); } // domain_gen is 256 bit and there're 8+4+32+32=76 bytes before it: - uint domain_gen = 0; - for (uint i = 0; i < 32; i++) { - domain_gen += uint(uint8(domain_b[i + 76])) << (i*8); + uint256 domain_gen = 0; + for (uint256 i = 0; i < 32; i++) { + domain_gen += uint256(uint8(domain_b[i + 76])) << (i * 8); } index.domain_gen = Scalar.from(domain_gen); } - error EncodedMapKeyNotFound(); - function find_value(EncodedMap memory self, string memory key) - public - returns (bytes memory) + function deser_prover_proof(Stream memory self, ProverProof storage prover_proof) + external { - uint256 i = 0; - while ( - i != self.keys.length && - keccak256(bytes(self.keys[i])) != keccak256(bytes(key)) - ) { - i++; - } - if (i == self.keys.length) revert EncodedMapKeyNotFound(); - return self.values[i]; + EncodedMap memory map = deser_fixmap(self); + + EncodedMap memory all_evals_map = abi.decode( + find_value(map, "evals"), + (EncodedMap) + ); + + PointEvaluations memory public_evals = deser_eval_single( + all_evals_map, + "public" + ); + } + + function deser_eval_single( + EncodedMap memory all_evals_map, + string memory name + ) public pure returns (PointEvaluations memory) { + EncodedMap memory eval_map = abi.decode( + find_value(all_evals_map, name), + (EncodedMap) + ); + + EncodedArray memory zeta_arr = abi.decode( + find_value(eval_map, "zeta"), + (EncodedArray) + ); + EncodedArray memory zeta_omega_arr = abi.decode( + find_value(eval_map, "zeta_omega"), + (EncodedArray) + ); + + EncodedMap memory zeta_map = abi.decode( + zeta_arr.values[0], + (EncodedMap) + ); + EncodedArray memory zeta_data_arr = abi.decode( + find_value(zeta_map, "data"), + (EncodedArray) + ); + // WARN: test proof has single value evaluations. + uint256 zeta_data = uint256(bytes32(zeta_data_arr.values[0])); + zeta_data = UtilsExternal.reverseEndianness(zeta_data); + Scalar.FE zeta = Scalar.from(zeta_data); + + return PointEvaluations(zeta, zeta); } // !!! FUNCTIONS BELOW ARE DEPRECATED !!! diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index 64e1a35e..b0d4d6c0 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -5,9 +5,11 @@ import {Test, console2} from "forge-std/Test.sol"; import "../lib/bn254/BN254.sol"; import "../src/Verifier.sol"; import "../lib/msgpack/Deserialize.sol"; +import "../lib/Proof.sol"; contract DeserializeTest is Test { VerifierIndex index; + ProverProof proof; // Test to check that the destructuring of the message pack byte array is correct. // If we know that g1Deserialize() is correct, then this asserts that the whole @@ -200,4 +202,22 @@ contract DeserializeTest is Test { 20619701001583904760601357484951574588621083236087856586626117568842480512645 ); } + + function test_deserialize_prover_proof() public { + bytes + memory prover_proof_serialized = hex"85AB636F6D6D69746D656E747384A6775F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCD843CC8C68CCADCCC65F0FCCE95332CCD3566E1C7BCCA626764ECCFF30CCEE14CC9560790764CCE7CCC4CC9CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE7CCFBCCD1CC92CCBF523131CCDD2FCCB807CCF8CCF7CCCFCCADCCE7CCDF6256CCE8CC9ECC91CCF0CC9C0CCCB11050050FCC85A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC3CCE17360CCCC5FCCA1CCAD260C0ECCDFCC98CCCBCC8ECCD2367F0B2553654257CCA5CC82CC96CC9361CCF379CC89A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020465CCCB06ACC97CCCC1FCCBA62156DCCEA4A0ACCCF78CC98CCAECCBECCDFCCE1CCD212537BCCCF5970CC8C3A3E30A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCAACCAECCD8302DCC9FCCF808CCA76DCCB646CCA345CCA70BCCFFCCBA5865357522CCF6CCEF443634CC81CCA7CC8A0CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002010CCDC62CCE86ACCA0CCFBCCCCCCA934CC8ACCB97ACCE3552B5E7442112820503713CCCD7E30CCC4CC8936CC92A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00207833045124CC8BCCFA087CCCC77969CC8B17CCDECCD5CCEACCD3CCB8CCC147CC907DCCFF0042CCB9CCADCCE444CCF1CC80A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201A49CCD234CCEE0ACC985DCCD452CCB8CCC365CCBA5F7FCCE57874CCE5CCB8CCAE7C24CCA7CCFFCCDF7F06CCCECCBF16A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00203BCCF60A24CCEF2F1B14CCE9CCF71BCCC23ECCEA0C5ACC9C0DCC9E377232CCD501CCBACCCFCCD9CCF9CCF3CCDACCCF00A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201ECCA4CCCFCCEF710FCCE8CC9B32CC81CC84323C601ACCB1516005CCFFCCEB2FCC90CCBE654CCCFD5D486FCC862FA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7DCCDC5F6ACC8132CCC008CCF9CCE3CCCACC94CC8ACCA83D7ECCC5CC835ECC97CC8ACC95CC9CCCE3CCCA0B58CCDF4FCCE314A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020351B53CCB8CCA6CCDB78CCA61D4865276D69CCDD49361E620A32611E1ECC80CCFE51CC94CCB74C2410A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC830DCC89CCADCCBCCCC9CCD3CC82CCE60114CCCBCCBFCCD5CC8D40723DCCE6CC8354CC9509CCB731CCCACC9ECCD7CCB7CCDECCD7CCABA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC2CCF328CCED33CCDC6264CCEDCCEC4633CCCCCCA8CCBBCCDACCC24345CC99CCA565CCC23ACCB144CCAACCC459CC924809A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00204DCCBE7C3A5F1E2B7ECC867965CCCBCCD65A7D771ACC81CCEECCF724CCE2010DCCF1CCF63CCCFC4C56CCB5CC9FA773686966746564C0A67A5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCCB4CC8052CC9A247A2B51425B50705BCCEACCD7CC85CC8664CCBCCC84CCB1CCD318CCB96BCCEA55CC9049CCEBCCA7A773686966746564C0A6745F636F6D6D82A9756E736869667465649782A474797065A6427566666572A464617461DC00203ACCF406CCEBCCEBCCE72979CCF063CCB06BCCA8CCF74A34CCA22B5D4B5E30CCF8CCFD3F7BCC9F11CCC254101582A474797065A6427566666572A464617461DC002071CCF6CC9CCCADCCA4565520CCE9CCA5CCF4CCEBCCA0CCDB1B1E3D760224025A4DCC806BCC9DCCA7CC8CCCA951CCEC0C82A474797065A6427566666572A464617461DC002056CCC151CC80CCF762CCAFCCA4CCD9CCC968CCA6CCAA64CCD60CCCF1CCC4CC9FCCDB6A2D6863CCFFCCAB48796F37CC8D2682A474797065A6427566666572A464617461DC0020CCAECCF3665BCCDFCC97CCBE7CCCE6CCF8CCB70F62CCAE197764CC9ACCB80ACCA416CCE3CCB00E78CCAD265613CCA50B82A474797065A6427566666572A464617461DC0020CCF81C0359CC95CCFCCCA479CCB2CC9DCCEDCC9626CCCECCB6CCEDCCAE642A3DCCF37ECCF56B665BCCD950CCD32C780882A474797065A6427566666572A464617461DC0020CCF6CCF06B74CCA433591E30CCE6CCE1CC93CC8ACC9C56042F3867714FCCC72E7ACC891ECCBB71603DCCE4CCAF82A474797065A6427566666572A464617461DC0020CCCFCCCFCCB3560BCC83CC95CCCC33CCEACC9E6DCC921BCCB4CCCACCA864CCECCCC33776734D657CCCD52BCCAC204BCC94A773686966746564C0A66C6F6F6B757083A6736F727465649582A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE9CCF5195B6ACCD6CC96CCA1325F2D6C79CCFF6CCCD9CC9ACCFE77CC932BCCE3CC994073CCF2CCFBCCC779CCE56C27A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC975DCCC0CCDD6BCCC7CC9ECC8CCCDA681A17CCDA2CCC9F7BCC916F483D41CCA00A68CCB718CCC722CCBE422E18A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002021CCC1CC8C4370687F69CCA0CCAA533BCCCA0C5BCCE847CCBA78CC83CC8BCCA103CCC67668CCDCCC812405CCA0CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002019CCD34CCCF25BCCE82955CC974A26663E0F70CCA6596FCCACCC9B7CCCAECC83CCA6556F410771CC92CCF611A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002045CCF9105CCC8FCCA1CC9E2638607BCC8A2B0266CCEDCCFACC9361CC80CCC1CCE1CC8A3C5B08CCCC5FCC8921CCC2CCA7A773686966746564C0A661676772656782A9756E736869667465649182A474797065A6427566666572A464617461DC00201DCCC905CCCBCCFC7F19CCB5CCCCCCECCCB4CC965DCCA5CC87573F535C6A15CCBD0FCCC0CCA81D07023818CCA21FA773686966746564C0A772756E74696D65C0A570726F6F6682A871756F7469656E7482A474797065A6427566666572A464617461DC0020CCDD7E3BCC86CC99622CCCFD7F08221DCCD8191504CCAB386202CCC50A6ACCB1CC8ECCF663CCBECC9F0A53CC99A8626C696E64696E6782A474797065A6427566666572A464617461DC00207B6778CCBECCFD13CCB616CCEDCCDBCCAA7B1FCCD214CCC4CCD3CC9A4DCCC0306ACCC3CCF3CCD1CCAFCCF64D6858CCB61DA56576616C73DE001AA67075626C696382A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000A1779F82A47A6574619182A474797065A6427566666572A464617461DC0020CC91CCABCC853859CCDB5FCC8FCCC276CCAACCC5183119CC84CC863231CCB456CCB608CC9336CCC3CCC0CCC0CCEACCAB2D2CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD7CCB3CCC07450CCC178CCBB5B14CCE3CCB5CCB22C70CCEBCC8E770ACCE329284A08CC84CCA5CCDF6BCCC1752E0882A47A6574619182A474797065A6427566666572A464617461DC0020134ECCAECCD96164CCA0CCD8CCBF0B71CC9C5C78CCE3CC8E21CC81CCDF10CCBD02462ECCA8CC9D03CCCECCF06D6F15AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD256CCA01BCCABCCF549CCC62908CCFDCCE5CCF537CCC24BCCF645CCCC2948CCEC3ACCD9CC9ACCAECCC2CCE30ACCCD301D82A47A6574619182A474797065A6427566666572A464617461DC0020CCC2CCEBCC96142945380379CCEFCC95130D6914CC925FCCF623CCA4CCB21BCCE00FCCCA00CCA5CCA44113CCC206AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00203ECCD2CCD9CCADCCB110CCA05F6B0DCCF5CCD435373FCC896DCCC16ECCA81E29CC982A5D422835CCAC4B090C82A47A6574619182A474797065A6427566666572A464617461DC0020162ECCAECCE714CCE053CC94CCFECCB612CCA31371CC8D3856CCD9CCE603CCECCCB2CCE9CCEB39CCDBCC86CCB445251216AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCBACCF04E4E7ACCE2CCCECCBBCCB2CCC2CC8ACCB7CCF06A71CC9F685ACCF1CCC9CCA454CCDC0549CCFFCCD545CC8B4A1A1682A47A6574619182A474797065A6427566666572A464617461DC00200F4B02CCDA68CCDFCCE9CCA8366FCCAACCD70ECCCE3ACCA84BCCC3CC80CCC149CCB077CCA20BCC9DCCBF5FCCEC7ECCBC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002066CCA178CCA84845CCE35ECCEA08CCD4CCB1CCEBCCD5CCF6221C0F74CCDCCCCBCCCDCCDFCCDD62CCEECCEC4D6DCCD4CCC40982A47A6574619182A474797065A6427566666572A464617461DC00206ECCE833CCF62BCCF044CCE1CCA3CC9B25604DCC982CCCA1CCFC6ECC9A61CCA4CCE973CCEF0A71CCBFCCD90617CC9422AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205848CCFC1BCCFC647567CCCFCCF76ACCC176CCFACC92560B6C3E3D6FCC90CCF6CC9FCC9ACC88CC811160CC91CCC20682A47A6574619182A474797065A6427566666572A464617461DC0020CC864757CCB36C11CC86182C11CC832E08CC86466ECC8A49187BCC8BCCEFCC90CCC87171CCA62040CC9ACCC22FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD0CCAECCFFCC91CCA0CC9FCC9625CC9522CCD5204E2BCCC0CC91507408CCFACCCB5B202C57CCF23A46CCE37D7D2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCE95ACC9E46CCFCCCBA232C37CCC335CCF9CCF9303CCCFFCCC85669CCEFCCB107CC99CCFACCF7CC924F2827CCAE0102AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002009CCB537CC9D6607CCFECCFDCCE14801CCF6CCB3CCA2CCB6CCE2CCDFCCE5CCC83027334FCCAE22221BCCCF1A0F1C0082A47A6574619182A474797065A6427566666572A464617461DC0020CCC6CCCD1ACCBF41233DCCA617CC9C4406CCD861CC91CCF60E4412CCAB4FCCB1CC9F447BCCB3CCABCC9E7836CC960CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002037CC80CCAECCBD56CCB5CCBC50CCC3CC9746CC995BCCB628CCB674CCACCCF7CCC55D653142CC9FCCCA71CCC9CCE3CCEACC8C0A82A47A6574619182A474797065A6427566666572A464617461DC0020CCB1CC8348CCDACCD87DCCD0CCDC29CC826D03672D64CCAE4963CCE37ECCB205114ACCDECCB5CC9F1E1B72CCAC03AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF5793436CC87574F2ACCAA5020CCA91E1CCC8451CC81015ECC8E35267C063CCC86CCB87CCCA002CCFF2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCD33CCCAECCD038CCD63324CC9B1DCC9ACC9FCC8040CC9A39CCF7CCEACCCCCCE17ECCE5CCADCCEE18CCB0CC8509497ECC882DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD32B42CCF447CCDD023CCCD4CCB76D50CC9DCCD2CC8054CCF456CCC709CCA017CCC104CC9A65CCA37439CC96CCA61782A47A6574619182A474797065A6427566666572A464617461DC00200A5D16CC8FCCC1CCF516CC8843CCDBCCFD74CCD8102B5928CCA244CCDC29CCE8CCC4714DCC935628CCB52ECC8D18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCEA45CCBE2C29CCDFCC805ECCE5CCABCCB3CCAB05CCEDCCE125CCB2CCFDCC8ECCAD6549CCF1CCA57DCCE9CCD647CCE6CCA7650E82A47A6574619182A474797065A6427566666572A464617461DC00204854CCAE40CCFCCC8F3BCC935E2477CCCCCCC90D0C115D72CCAD63CCA537CC9873CC8770CCEFCCBA12CCFDCCB01BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCDC2DCCD655CCAC0B6311CC9944CC8E39CCDECC81CCBBCCB1CCE45C32CCA4CCBD5A1D4314CCFFCC9010CCF24B2B82A47A6574619182A474797065A6427566666572A464617461DC00201135CCDBCCDC6F7FCCDC26CC845449CCC771CC881029CCC1CC80CCD5CCAE61CC866DCCCF6CCCF81C1C73CC871A2FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002048CCCBCC81CC906F47CC98CC8F3E3C04CCD4CC9874CCA50A3E3D31CCE6CCCCCC8772CC8ECCBC07CCDA05CCCE273A3082A47A6574619182A474797065A6427566666572A464617461DC00207DCCCCCCCECCBACC9D4373CCAF6F1D07CCD00FCCD42344CCD5CCB3CCE0CCF36A7937CC8DCCFB350BCC8E7F73CC9D26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00206C2D746FCCD1CCF94654CCB7CCC4CCC7CCE36051CCB019CCCBCCE870CCE5CCD43ACCED10CC93CCFFCCEB4C67CCA05D30A17A82A47A6574619182A474797065A6427566666572A464617461DC00203303576F49CCD5CCA8CCD0CCE87BCC9703CCFCCCEACC9FCC9102CCCC69CC8ACCE4CCEF6945CCA5CCDF1F2B7262652AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCE747CCA774CC98CCA2CCA610CC9FCCEDCCEC22CCEC150E732818CCFF3727CCD4CCDA31CCE1CCB5587160CCAACCC603A1739682A47A6574619182A474797065A6427566666572A464617461DC002051CCF4CCA0CCA2CCDC4BCCCFCCC2CCDC5CCCFBCCF2CC9FCC9CCCB9CC9FCCA7315741CCFF73CC99CCFF41CCE8CC95CCE6CCD6CCB7001DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF21D4C5ACC954338CCE1CCC56206CCC45705CCE503CCDD28CCEE64CCF633CCA6CCF677CCFACCF8CCB5CC8A45CC9F0E82A47A6574619182A474797065A6427566666572A464617461DC0020CCEFCC81CCD54E2E33CC860C37CCE8CCA5CC96CCFF1ACC802ACCEACCBDCCD6275770CC841F36CCA6CCD5CCCCCCA13CCCC71AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF63A5E6C3ECCF63DCCED4ACC8F75CCDF2ECCBF5ECC95CCC8CCA4CC992926CC996DCCE9CCAD60CCD30122CCE2201782A47A6574619182A474797065A6427566666572A464617461DC00201ECCAA57CCA3CC9BCCDDCCBFCCFCCCD13074CCF7CCFACCD84DCCB434CCC4CCDA5FCCF866CCE6CCD5CCC6CCCD70CCC653CCDDCC882EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020332374CCBA79025BCC9916CCD7CCD90CCCDC5CCCE0CCA8CCE368CC9F590136CCCB15CCC868CC8BCCA809CC84CCF30082A47A6574619182A474797065A6427566666572A464617461DC002018CC88415E4CCC9E64720DCCF873CCAC561748CCEA26CCF9CC8B153D61CCF34BCCCDCCA62710CCC9500C1BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA1CC80CC81CCEC3CCCC6CCF9CC9A5E1ECCC7CCF9CCA2CCF2217743437DCC8BCCF7CCDFCCC3CCC51ECCDECC96CCA0CC8438091182A47A6574619182A474797065A6427566666572A464617461DC0020CCCC40CC942544CCB12E2F46CCF4CCA1CC8ACCC2596C113363CCDF2FCCAF41CCFECCD5CCE5CCFDCCFD7C33107E26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002011CCAF34CCA9470870CCE7CCF411CCC2CC8741CCDD52CCAB55CCC1CCCECC876ACC870305622F7ACCCBCC8761CCB00982A47A6574619182A474797065A6427566666572A464617461DC0020CCEC6741CCFECCA4CCF6CCF91FCCE6CCDCCC9E5E746B2857CCFFCC962B4ACCCECCE7CCE9CCD429CCB4CCD2CC8D1FCC8DCCFC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC81CCA9CCE6CCC546CCA8555ECCF82607CCCECC9563CCDC31CCA3CCD8CCDA2BCCA4CCBE18616426697D696ECC831DAC636F656666696369656E74739F82A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B067656E657269635F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B1706F736569646F6E5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B5636F6D706C6574655F6164645F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AC6D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AD656D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B7656E646F6D756C5F7363616C61725F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B572616E67655F636865636B305F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCA8CC92CCB340CCC520573BCCF5CCC60BCCABCCBDCCE7CC8F15CCE2CCEDCCEE31CC9B484D5FCCD62CCCC2CCC3391ACCFF2EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC9D37CCAE26CC8702CCBB67CCFFCCBACC841DCCEB383113CCFBCCB3CCE6CC8FCCF0CCBFCCEFCCDB1B6F622645CC830F27B572616E67655F636865636B315F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCF2CC90CCC8CCA4CC8DCC92CCE7CCDFCCA93938044316CCBE6D37CCC9023A2A54CCD9043B0ECCBECCF912350703AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC941CCCCA71CCDA09CC8DCCD162CCF4CCBACCA814CCEE5BCC9ACCF9216D7CCC990E0ACCFECCB7CCB37B397CCC85CCBA15BA666F726569676E5F6669656C645F6164645F73656C6563746F72C0BA666F726569676E5F6669656C645F6D756C5F73656C6563746F72C0AC786F725F73656C6563746F72C0AC726F745F73656C6563746F72C0B26C6F6F6B75705F6167677265676174696F6E82A47A6574619182A474797065A6427566666572A464617461DC0020CCBB1ACCD376CCEECCF0CCA750CC8B711ACC97CC8160CCE1CCC5CCFCCCF0CCE0412861CCEF5128CCF4CC99CCCE39CCC4CCF80DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002032CC903FCCD27BCC9ECC9CCCAFCCBC39CCC1CCC3CC9BCCA36D0570CCA114CCAE2CCC9F1203CCBD60CCA31D7ACCBB0514AC6C6F6F6B75705F7461626C6582A47A6574619182A474797065A6427566666572A464617461DC00203D663E7E6610CCB1CC844863CC803466590A2A1CCCA451CCC755393BCCD3CCC762CC822B44CCA8CCB02BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC8ACC985A1D271113CCCACCE0CCA7CCEACCB5CC86CC845CCCB8CCCD2E27CCDF38CCD30E76CCC81832CC94CC8ECCF4CCAB1FAD6C6F6F6B75705F736F727465649582A47A6574619182A474797065A6427566666572A464617461DC002003CCF1CC8FCC8CCC843B1ACCC26DCCDE6ECCE46E64CCC9CCE971CCDECCC4CC84CCFE2FCCBACCFBCC8737CCACCC8756CC945F23AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA3326726CCABCCD7CC904C23CC927068CC920F59CCB7CCEA17CCCFCC8878CC91CCC13ACCE36C3F4725CC8B222882A47A6574619182A474797065A6427566666572A464617461DC0020CCF52ECCB7683352CCA3CCF176CCEECCD461CCCC0C3ACCD905CC80CCAF4E25CCBE29CCA8CC99CCD87ECC8ACCC20FCCB90DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00207BCCD5CCC6CC9228CCE1CCBA3E037ACC854FCC9A6BCCCC492CCCA7CCA7CCF5CCEF3FCC862278CCC732CCDD45CCFCCCD02782A47A6574619182A474797065A6427566666572A464617461DC0020CC9741CCC7CCC0CCFC6F6A6768377ECCD94ACCB1CCC92FCCE66129CCE7CCC8CC8436CCB3CCBE2DCC8BCCF418CCB20415AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205772CCCF1B0A32CCFDCCE247CCC3CCDD6CCC8126CC83CCFCCCBE5F31CCA53521CC85CCBA72CCBDCC85344265701282A47A6574619182A474797065A6427566666572A464617461DC0020CCB4CCA0CCEA22046DCC87CCB2427F4954CC82CC84CCADCCD10BCCB7CCD7CC990044CCF4CCDFCCD95FCCD5CCD27167CCBE18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF569CC93331A635C4465CCE85C6CCC8121CCBBCC93CCD7CC8DCCE6CCFACCE4CCE817CCD95270384D500ECCCB1582A47A6574619182A474797065A6427566666572A464617461DC0020CCB7CCCB1F526A127353CCDBCC97CCB7CCCB32CC82CCB26FCCE9CCBACCC4CCB8CCE915CC9F65CCBBCCDD42412A0F771DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002005CCABCCEE75CCBA63CC9C0824CCCCCCFD6ACCC6CCE1CCC4CCF2CCACCCA9CCACCCA2CCD90716CCD746CCA3CCCD00002D4C26B472756E74696D655F6C6F6F6B75705F7461626C65C0BD72756E74696D655F6C6F6F6B75705F7461626C655F73656C6563746F72C0B3786F725F6C6F6F6B75705F73656C6563746F72C0BB6C6F6F6B75705F676174655F6C6F6F6B75705F73656C6563746F72C0BB72616E67655F636865636B5F6C6F6F6B75705F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCBD2ECCC43CCCBD197CCCC3112429CCCC1FCC83CCC26DCCBBCCB77DCC87CCDD691844CCA257CCB678CCEDCC9FCCEC1FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCE5404D5BCCA94DCCD57A78CCBE50CCFA5417CCF3CCCE46CCD5CCC4CCFDCCDCCC8226CCE5CC906A7861CCEF6C0FD921666F726569676E5F6669656C645F6D756C5F6C6F6F6B75705F73656C6563746F72C0A866745F6576616C3182A474797065A6427566666572A464617461DC00202E74CCF4CCB84B766ECCB00ACCC6CCFD70306ECCA8CCA2CC870ACCD8780864005B306ECC8DCC957CCCD04916AF707265765F6368616C6C656E67657390"; + MsgPk.deser_prover_proof( + MsgPk.new_stream(prover_proof_serialized), + proof + ); + + //assertEq(index.public_len, 0); + //assertEq(index.max_poly_size, 16384); + //assertEq(index.zk_rows, 3); + //assertEq(index.domain_size, 16384); + //assertEq( + // Scalar.FE.unwrap(index.domain_gen), + // 20619701001583904760601357484951574588621083236087856586626117568842480512645 + //); + } } diff --git a/kzg_prover/src/main.rs b/kzg_prover/src/main.rs index c500a1da..e52c2d74 100644 --- a/kzg_prover/src/main.rs +++ b/kzg_prover/src/main.rs @@ -105,6 +105,7 @@ fn generate_test_proof_ex() { let (_endo_r, endo_q) = G1::endos(); let index = ProverIndex::::create(cs, *endo_q, srs); + let group_map = ::Map::setup(); let proof = ProverProof::create_recursive::( &group_map, @@ -126,6 +127,11 @@ fn generate_test_proof_ex() { rmp_serde::to_vec_named(&index.verifier_index()).unwrap(), ) .unwrap(); + fs::write( + "../eth_verifier/urs.mpk", + rmp_serde::to_vec_named(&index.verifier_index().srs().verifier_srs).unwrap(), + ) + .unwrap(); } fn generate_verifier_circuit_proof() { From 2c31f7c4a9ed5cdec65c6ed569deb7adfdc68128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 11 Dec 2023 13:07:11 -0300 Subject: [PATCH 31/68] Deserialize public evals --- eth_verifier/lib/Utils.sol | 14 ++++- eth_verifier/lib/msgpack/Deserialize.sol | 68 +++++++++++++++--------- eth_verifier/test/Deserialize.t.sol | 5 +- 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/eth_verifier/lib/Utils.sol b/eth_verifier/lib/Utils.sol index c6c150a4..3a4b2d17 100644 --- a/eth_verifier/lib/Utils.sol +++ b/eth_verifier/lib/Utils.sol @@ -340,7 +340,7 @@ library Utils { /// @notice assumed to be padded so every element is 32 bytes long. // // @notice this function will both flat and remove the padding. - function flatten_padded_bytes_array(bytes[] memory b) public view returns (bytes memory) { + function flatten_padded_bytes_array(bytes[] memory b) public pure returns (bytes memory) { uint byte_count = b.length; bytes memory flat_b = new bytes(byte_count); for (uint i = 0; i < byte_count; i++) { @@ -348,4 +348,16 @@ library Utils { } return flat_b; } + + /// @notice uses `flatten_padded_bytes_array()` to flat and remove the padding + /// @notice of a `bytes[]` and reinterprets the result as a little-endian uint256. + function padded_bytes_array_to_uint256(bytes[] memory b) public pure returns (uint256 integer) { + bytes memory data_b = flatten_padded_bytes_array(b); + require(data_b.length == 32, "not enough bytes in array"); + + integer = 0; + for (uint256 i = 0; i < 32; i++) { + integer += uint256(uint8(data_b[i])) << (i * 8); + } + } } diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 18ab6fe2..1007d3dc 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -326,9 +326,10 @@ library MsgPk { index.domain_gen = Scalar.from(domain_gen); } - function deser_prover_proof(Stream memory self, ProverProof storage prover_proof) - external - { + function deser_prover_proof( + Stream memory self, + ProverProof storage prover_proof + ) external { EncodedMap memory map = deser_fixmap(self); EncodedMap memory all_evals_map = abi.decode( @@ -336,16 +337,14 @@ library MsgPk { (EncodedMap) ); - PointEvaluations memory public_evals = deser_eval_single( - all_evals_map, - "public" - ); + prover_proof.evals.public_evals = deser_evals(all_evals_map, "public"); } - function deser_eval_single( - EncodedMap memory all_evals_map, - string memory name - ) public pure returns (PointEvaluations memory) { + function deser_evals(EncodedMap memory all_evals_map, string memory name) + public + pure + returns (PointEvaluationsArray memory) + { EncodedMap memory eval_map = abi.decode( find_value(all_evals_map, name), (EncodedMap) @@ -359,21 +358,42 @@ library MsgPk { find_value(eval_map, "zeta_omega"), (EncodedArray) ); + require(zeta_arr.values.length == zeta_omega_arr.values.length); + uint256 length = zeta_arr.values.length; + + Scalar.FE[] memory zetas = new Scalar.FE[](length); + Scalar.FE[] memory zeta_omegas = new Scalar.FE[](length); + for (uint256 i = 0; i < zeta_arr.values.length; i++) { + EncodedMap memory zeta_map = abi.decode( + zeta_arr.values[i], + (EncodedMap) + ); + EncodedMap memory zeta_omega_map = abi.decode( + zeta_omega_arr.values[i], + (EncodedMap) + ); - EncodedMap memory zeta_map = abi.decode( - zeta_arr.values[0], - (EncodedMap) - ); - EncodedArray memory zeta_data_arr = abi.decode( - find_value(zeta_map, "data"), - (EncodedArray) - ); - // WARN: test proof has single value evaluations. - uint256 zeta_data = uint256(bytes32(zeta_data_arr.values[0])); - zeta_data = UtilsExternal.reverseEndianness(zeta_data); - Scalar.FE zeta = Scalar.from(zeta_data); + EncodedArray memory zeta_data_arr = abi.decode( + find_value(zeta_map, "data"), + (EncodedArray) + ); + EncodedArray memory zeta_omega_data_arr = abi.decode( + find_value(zeta_omega_map, "data"), + (EncodedArray) + ); + + uint256 zeta_inner = Utils.padded_bytes_array_to_uint256( + zeta_data_arr.values + ); + uint256 zeta_omega_inner = Utils.padded_bytes_array_to_uint256( + zeta_omega_data_arr.values + ); + + zetas[i] = Scalar.from(zeta_inner); + zeta_omegas[i] = Scalar.from(zeta_omega_inner); + } - return PointEvaluations(zeta, zeta); + return PointEvaluationsArray(zetas, zeta_omegas); } // !!! FUNCTIONS BELOW ARE DEPRECATED !!! diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index b0d4d6c0..e1d60a0d 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -9,7 +9,7 @@ import "../lib/Proof.sol"; contract DeserializeTest is Test { VerifierIndex index; - ProverProof proof; + ProverProof prover_proof; // Test to check that the destructuring of the message pack byte array is correct. // If we know that g1Deserialize() is correct, then this asserts that the whole @@ -208,9 +208,10 @@ contract DeserializeTest is Test { memory prover_proof_serialized = hex"85AB636F6D6D69746D656E747384A6775F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCD843CC8C68CCADCCC65F0FCCE95332CCD3566E1C7BCCA626764ECCFF30CCEE14CC9560790764CCE7CCC4CC9CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE7CCFBCCD1CC92CCBF523131CCDD2FCCB807CCF8CCF7CCCFCCADCCE7CCDF6256CCE8CC9ECC91CCF0CC9C0CCCB11050050FCC85A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC3CCE17360CCCC5FCCA1CCAD260C0ECCDFCC98CCCBCC8ECCD2367F0B2553654257CCA5CC82CC96CC9361CCF379CC89A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020465CCCB06ACC97CCCC1FCCBA62156DCCEA4A0ACCCF78CC98CCAECCBECCDFCCE1CCD212537BCCCF5970CC8C3A3E30A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCAACCAECCD8302DCC9FCCF808CCA76DCCB646CCA345CCA70BCCFFCCBA5865357522CCF6CCEF443634CC81CCA7CC8A0CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002010CCDC62CCE86ACCA0CCFBCCCCCCA934CC8ACCB97ACCE3552B5E7442112820503713CCCD7E30CCC4CC8936CC92A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00207833045124CC8BCCFA087CCCC77969CC8B17CCDECCD5CCEACCD3CCB8CCC147CC907DCCFF0042CCB9CCADCCE444CCF1CC80A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201A49CCD234CCEE0ACC985DCCD452CCB8CCC365CCBA5F7FCCE57874CCE5CCB8CCAE7C24CCA7CCFFCCDF7F06CCCECCBF16A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00203BCCF60A24CCEF2F1B14CCE9CCF71BCCC23ECCEA0C5ACC9C0DCC9E377232CCD501CCBACCCFCCD9CCF9CCF3CCDACCCF00A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201ECCA4CCCFCCEF710FCCE8CC9B32CC81CC84323C601ACCB1516005CCFFCCEB2FCC90CCBE654CCCFD5D486FCC862FA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7DCCDC5F6ACC8132CCC008CCF9CCE3CCCACC94CC8ACCA83D7ECCC5CC835ECC97CC8ACC95CC9CCCE3CCCA0B58CCDF4FCCE314A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020351B53CCB8CCA6CCDB78CCA61D4865276D69CCDD49361E620A32611E1ECC80CCFE51CC94CCB74C2410A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC830DCC89CCADCCBCCCC9CCD3CC82CCE60114CCCBCCBFCCD5CC8D40723DCCE6CC8354CC9509CCB731CCCACC9ECCD7CCB7CCDECCD7CCABA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC2CCF328CCED33CCDC6264CCEDCCEC4633CCCCCCA8CCBBCCDACCC24345CC99CCA565CCC23ACCB144CCAACCC459CC924809A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00204DCCBE7C3A5F1E2B7ECC867965CCCBCCD65A7D771ACC81CCEECCF724CCE2010DCCF1CCF63CCCFC4C56CCB5CC9FA773686966746564C0A67A5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCCB4CC8052CC9A247A2B51425B50705BCCEACCD7CC85CC8664CCBCCC84CCB1CCD318CCB96BCCEA55CC9049CCEBCCA7A773686966746564C0A6745F636F6D6D82A9756E736869667465649782A474797065A6427566666572A464617461DC00203ACCF406CCEBCCEBCCE72979CCF063CCB06BCCA8CCF74A34CCA22B5D4B5E30CCF8CCFD3F7BCC9F11CCC254101582A474797065A6427566666572A464617461DC002071CCF6CC9CCCADCCA4565520CCE9CCA5CCF4CCEBCCA0CCDB1B1E3D760224025A4DCC806BCC9DCCA7CC8CCCA951CCEC0C82A474797065A6427566666572A464617461DC002056CCC151CC80CCF762CCAFCCA4CCD9CCC968CCA6CCAA64CCD60CCCF1CCC4CC9FCCDB6A2D6863CCFFCCAB48796F37CC8D2682A474797065A6427566666572A464617461DC0020CCAECCF3665BCCDFCC97CCBE7CCCE6CCF8CCB70F62CCAE197764CC9ACCB80ACCA416CCE3CCB00E78CCAD265613CCA50B82A474797065A6427566666572A464617461DC0020CCF81C0359CC95CCFCCCA479CCB2CC9DCCEDCC9626CCCECCB6CCEDCCAE642A3DCCF37ECCF56B665BCCD950CCD32C780882A474797065A6427566666572A464617461DC0020CCF6CCF06B74CCA433591E30CCE6CCE1CC93CC8ACC9C56042F3867714FCCC72E7ACC891ECCBB71603DCCE4CCAF82A474797065A6427566666572A464617461DC0020CCCFCCCFCCB3560BCC83CC95CCCC33CCEACC9E6DCC921BCCB4CCCACCA864CCECCCC33776734D657CCCD52BCCAC204BCC94A773686966746564C0A66C6F6F6B757083A6736F727465649582A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE9CCF5195B6ACCD6CC96CCA1325F2D6C79CCFF6CCCD9CC9ACCFE77CC932BCCE3CC994073CCF2CCFBCCC779CCE56C27A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC975DCCC0CCDD6BCCC7CC9ECC8CCCDA681A17CCDA2CCC9F7BCC916F483D41CCA00A68CCB718CCC722CCBE422E18A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002021CCC1CC8C4370687F69CCA0CCAA533BCCCA0C5BCCE847CCBA78CC83CC8BCCA103CCC67668CCDCCC812405CCA0CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002019CCD34CCCF25BCCE82955CC974A26663E0F70CCA6596FCCACCC9B7CCCAECC83CCA6556F410771CC92CCF611A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002045CCF9105CCC8FCCA1CC9E2638607BCC8A2B0266CCEDCCFACC9361CC80CCC1CCE1CC8A3C5B08CCCC5FCC8921CCC2CCA7A773686966746564C0A661676772656782A9756E736869667465649182A474797065A6427566666572A464617461DC00201DCCC905CCCBCCFC7F19CCB5CCCCCCECCCB4CC965DCCA5CC87573F535C6A15CCBD0FCCC0CCA81D07023818CCA21FA773686966746564C0A772756E74696D65C0A570726F6F6682A871756F7469656E7482A474797065A6427566666572A464617461DC0020CCDD7E3BCC86CC99622CCCFD7F08221DCCD8191504CCAB386202CCC50A6ACCB1CC8ECCF663CCBECC9F0A53CC99A8626C696E64696E6782A474797065A6427566666572A464617461DC00207B6778CCBECCFD13CCB616CCEDCCDBCCAA7B1FCCD214CCC4CCD3CC9A4DCCC0306ACCC3CCF3CCD1CCAFCCF64D6858CCB61DA56576616C73DE001AA67075626C696382A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000A1779F82A47A6574619182A474797065A6427566666572A464617461DC0020CC91CCABCC853859CCDB5FCC8FCCC276CCAACCC5183119CC84CC863231CCB456CCB608CC9336CCC3CCC0CCC0CCEACCAB2D2CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD7CCB3CCC07450CCC178CCBB5B14CCE3CCB5CCB22C70CCEBCC8E770ACCE329284A08CC84CCA5CCDF6BCCC1752E0882A47A6574619182A474797065A6427566666572A464617461DC0020134ECCAECCD96164CCA0CCD8CCBF0B71CC9C5C78CCE3CC8E21CC81CCDF10CCBD02462ECCA8CC9D03CCCECCF06D6F15AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD256CCA01BCCABCCF549CCC62908CCFDCCE5CCF537CCC24BCCF645CCCC2948CCEC3ACCD9CC9ACCAECCC2CCE30ACCCD301D82A47A6574619182A474797065A6427566666572A464617461DC0020CCC2CCEBCC96142945380379CCEFCC95130D6914CC925FCCF623CCA4CCB21BCCE00FCCCA00CCA5CCA44113CCC206AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00203ECCD2CCD9CCADCCB110CCA05F6B0DCCF5CCD435373FCC896DCCC16ECCA81E29CC982A5D422835CCAC4B090C82A47A6574619182A474797065A6427566666572A464617461DC0020162ECCAECCE714CCE053CC94CCFECCB612CCA31371CC8D3856CCD9CCE603CCECCCB2CCE9CCEB39CCDBCC86CCB445251216AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCBACCF04E4E7ACCE2CCCECCBBCCB2CCC2CC8ACCB7CCF06A71CC9F685ACCF1CCC9CCA454CCDC0549CCFFCCD545CC8B4A1A1682A47A6574619182A474797065A6427566666572A464617461DC00200F4B02CCDA68CCDFCCE9CCA8366FCCAACCD70ECCCE3ACCA84BCCC3CC80CCC149CCB077CCA20BCC9DCCBF5FCCEC7ECCBC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002066CCA178CCA84845CCE35ECCEA08CCD4CCB1CCEBCCD5CCF6221C0F74CCDCCCCBCCCDCCDFCCDD62CCEECCEC4D6DCCD4CCC40982A47A6574619182A474797065A6427566666572A464617461DC00206ECCE833CCF62BCCF044CCE1CCA3CC9B25604DCC982CCCA1CCFC6ECC9A61CCA4CCE973CCEF0A71CCBFCCD90617CC9422AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205848CCFC1BCCFC647567CCCFCCF76ACCC176CCFACC92560B6C3E3D6FCC90CCF6CC9FCC9ACC88CC811160CC91CCC20682A47A6574619182A474797065A6427566666572A464617461DC0020CC864757CCB36C11CC86182C11CC832E08CC86466ECC8A49187BCC8BCCEFCC90CCC87171CCA62040CC9ACCC22FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD0CCAECCFFCC91CCA0CC9FCC9625CC9522CCD5204E2BCCC0CC91507408CCFACCCB5B202C57CCF23A46CCE37D7D2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCE95ACC9E46CCFCCCBA232C37CCC335CCF9CCF9303CCCFFCCC85669CCEFCCB107CC99CCFACCF7CC924F2827CCAE0102AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002009CCB537CC9D6607CCFECCFDCCE14801CCF6CCB3CCA2CCB6CCE2CCDFCCE5CCC83027334FCCAE22221BCCCF1A0F1C0082A47A6574619182A474797065A6427566666572A464617461DC0020CCC6CCCD1ACCBF41233DCCA617CC9C4406CCD861CC91CCF60E4412CCAB4FCCB1CC9F447BCCB3CCABCC9E7836CC960CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002037CC80CCAECCBD56CCB5CCBC50CCC3CC9746CC995BCCB628CCB674CCACCCF7CCC55D653142CC9FCCCA71CCC9CCE3CCEACC8C0A82A47A6574619182A474797065A6427566666572A464617461DC0020CCB1CC8348CCDACCD87DCCD0CCDC29CC826D03672D64CCAE4963CCE37ECCB205114ACCDECCB5CC9F1E1B72CCAC03AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF5793436CC87574F2ACCAA5020CCA91E1CCC8451CC81015ECC8E35267C063CCC86CCB87CCCA002CCFF2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCD33CCCAECCD038CCD63324CC9B1DCC9ACC9FCC8040CC9A39CCF7CCEACCCCCCE17ECCE5CCADCCEE18CCB0CC8509497ECC882DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD32B42CCF447CCDD023CCCD4CCB76D50CC9DCCD2CC8054CCF456CCC709CCA017CCC104CC9A65CCA37439CC96CCA61782A47A6574619182A474797065A6427566666572A464617461DC00200A5D16CC8FCCC1CCF516CC8843CCDBCCFD74CCD8102B5928CCA244CCDC29CCE8CCC4714DCC935628CCB52ECC8D18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCEA45CCBE2C29CCDFCC805ECCE5CCABCCB3CCAB05CCEDCCE125CCB2CCFDCC8ECCAD6549CCF1CCA57DCCE9CCD647CCE6CCA7650E82A47A6574619182A474797065A6427566666572A464617461DC00204854CCAE40CCFCCC8F3BCC935E2477CCCCCCC90D0C115D72CCAD63CCA537CC9873CC8770CCEFCCBA12CCFDCCB01BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCDC2DCCD655CCAC0B6311CC9944CC8E39CCDECC81CCBBCCB1CCE45C32CCA4CCBD5A1D4314CCFFCC9010CCF24B2B82A47A6574619182A474797065A6427566666572A464617461DC00201135CCDBCCDC6F7FCCDC26CC845449CCC771CC881029CCC1CC80CCD5CCAE61CC866DCCCF6CCCF81C1C73CC871A2FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002048CCCBCC81CC906F47CC98CC8F3E3C04CCD4CC9874CCA50A3E3D31CCE6CCCCCC8772CC8ECCBC07CCDA05CCCE273A3082A47A6574619182A474797065A6427566666572A464617461DC00207DCCCCCCCECCBACC9D4373CCAF6F1D07CCD00FCCD42344CCD5CCB3CCE0CCF36A7937CC8DCCFB350BCC8E7F73CC9D26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00206C2D746FCCD1CCF94654CCB7CCC4CCC7CCE36051CCB019CCCBCCE870CCE5CCD43ACCED10CC93CCFFCCEB4C67CCA05D30A17A82A47A6574619182A474797065A6427566666572A464617461DC00203303576F49CCD5CCA8CCD0CCE87BCC9703CCFCCCEACC9FCC9102CCCC69CC8ACCE4CCEF6945CCA5CCDF1F2B7262652AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCE747CCA774CC98CCA2CCA610CC9FCCEDCCEC22CCEC150E732818CCFF3727CCD4CCDA31CCE1CCB5587160CCAACCC603A1739682A47A6574619182A474797065A6427566666572A464617461DC002051CCF4CCA0CCA2CCDC4BCCCFCCC2CCDC5CCCFBCCF2CC9FCC9CCCB9CC9FCCA7315741CCFF73CC99CCFF41CCE8CC95CCE6CCD6CCB7001DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF21D4C5ACC954338CCE1CCC56206CCC45705CCE503CCDD28CCEE64CCF633CCA6CCF677CCFACCF8CCB5CC8A45CC9F0E82A47A6574619182A474797065A6427566666572A464617461DC0020CCEFCC81CCD54E2E33CC860C37CCE8CCA5CC96CCFF1ACC802ACCEACCBDCCD6275770CC841F36CCA6CCD5CCCCCCA13CCCC71AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF63A5E6C3ECCF63DCCED4ACC8F75CCDF2ECCBF5ECC95CCC8CCA4CC992926CC996DCCE9CCAD60CCD30122CCE2201782A47A6574619182A474797065A6427566666572A464617461DC00201ECCAA57CCA3CC9BCCDDCCBFCCFCCCD13074CCF7CCFACCD84DCCB434CCC4CCDA5FCCF866CCE6CCD5CCC6CCCD70CCC653CCDDCC882EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020332374CCBA79025BCC9916CCD7CCD90CCCDC5CCCE0CCA8CCE368CC9F590136CCCB15CCC868CC8BCCA809CC84CCF30082A47A6574619182A474797065A6427566666572A464617461DC002018CC88415E4CCC9E64720DCCF873CCAC561748CCEA26CCF9CC8B153D61CCF34BCCCDCCA62710CCC9500C1BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA1CC80CC81CCEC3CCCC6CCF9CC9A5E1ECCC7CCF9CCA2CCF2217743437DCC8BCCF7CCDFCCC3CCC51ECCDECC96CCA0CC8438091182A47A6574619182A474797065A6427566666572A464617461DC0020CCCC40CC942544CCB12E2F46CCF4CCA1CC8ACCC2596C113363CCDF2FCCAF41CCFECCD5CCE5CCFDCCFD7C33107E26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002011CCAF34CCA9470870CCE7CCF411CCC2CC8741CCDD52CCAB55CCC1CCCECC876ACC870305622F7ACCCBCC8761CCB00982A47A6574619182A474797065A6427566666572A464617461DC0020CCEC6741CCFECCA4CCF6CCF91FCCE6CCDCCC9E5E746B2857CCFFCC962B4ACCCECCE7CCE9CCD429CCB4CCD2CC8D1FCC8DCCFC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC81CCA9CCE6CCC546CCA8555ECCF82607CCCECC9563CCDC31CCA3CCD8CCDA2BCCA4CCBE18616426697D696ECC831DAC636F656666696369656E74739F82A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B067656E657269635F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B1706F736569646F6E5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B5636F6D706C6574655F6164645F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AC6D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AD656D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B7656E646F6D756C5F7363616C61725F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B572616E67655F636865636B305F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCA8CC92CCB340CCC520573BCCF5CCC60BCCABCCBDCCE7CC8F15CCE2CCEDCCEE31CC9B484D5FCCD62CCCC2CCC3391ACCFF2EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC9D37CCAE26CC8702CCBB67CCFFCCBACC841DCCEB383113CCFBCCB3CCE6CC8FCCF0CCBFCCEFCCDB1B6F622645CC830F27B572616E67655F636865636B315F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCF2CC90CCC8CCA4CC8DCC92CCE7CCDFCCA93938044316CCBE6D37CCC9023A2A54CCD9043B0ECCBECCF912350703AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC941CCCCA71CCDA09CC8DCCD162CCF4CCBACCA814CCEE5BCC9ACCF9216D7CCC990E0ACCFECCB7CCB37B397CCC85CCBA15BA666F726569676E5F6669656C645F6164645F73656C6563746F72C0BA666F726569676E5F6669656C645F6D756C5F73656C6563746F72C0AC786F725F73656C6563746F72C0AC726F745F73656C6563746F72C0B26C6F6F6B75705F6167677265676174696F6E82A47A6574619182A474797065A6427566666572A464617461DC0020CCBB1ACCD376CCEECCF0CCA750CC8B711ACC97CC8160CCE1CCC5CCFCCCF0CCE0412861CCEF5128CCF4CC99CCCE39CCC4CCF80DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002032CC903FCCD27BCC9ECC9CCCAFCCBC39CCC1CCC3CC9BCCA36D0570CCA114CCAE2CCC9F1203CCBD60CCA31D7ACCBB0514AC6C6F6F6B75705F7461626C6582A47A6574619182A474797065A6427566666572A464617461DC00203D663E7E6610CCB1CC844863CC803466590A2A1CCCA451CCC755393BCCD3CCC762CC822B44CCA8CCB02BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC8ACC985A1D271113CCCACCE0CCA7CCEACCB5CC86CC845CCCB8CCCD2E27CCDF38CCD30E76CCC81832CC94CC8ECCF4CCAB1FAD6C6F6F6B75705F736F727465649582A47A6574619182A474797065A6427566666572A464617461DC002003CCF1CC8FCC8CCC843B1ACCC26DCCDE6ECCE46E64CCC9CCE971CCDECCC4CC84CCFE2FCCBACCFBCC8737CCACCC8756CC945F23AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA3326726CCABCCD7CC904C23CC927068CC920F59CCB7CCEA17CCCFCC8878CC91CCC13ACCE36C3F4725CC8B222882A47A6574619182A474797065A6427566666572A464617461DC0020CCF52ECCB7683352CCA3CCF176CCEECCD461CCCC0C3ACCD905CC80CCAF4E25CCBE29CCA8CC99CCD87ECC8ACCC20FCCB90DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00207BCCD5CCC6CC9228CCE1CCBA3E037ACC854FCC9A6BCCCC492CCCA7CCA7CCF5CCEF3FCC862278CCC732CCDD45CCFCCCD02782A47A6574619182A474797065A6427566666572A464617461DC0020CC9741CCC7CCC0CCFC6F6A6768377ECCD94ACCB1CCC92FCCE66129CCE7CCC8CC8436CCB3CCBE2DCC8BCCF418CCB20415AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205772CCCF1B0A32CCFDCCE247CCC3CCDD6CCC8126CC83CCFCCCBE5F31CCA53521CC85CCBA72CCBDCC85344265701282A47A6574619182A474797065A6427566666572A464617461DC0020CCB4CCA0CCEA22046DCC87CCB2427F4954CC82CC84CCADCCD10BCCB7CCD7CC990044CCF4CCDFCCD95FCCD5CCD27167CCBE18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF569CC93331A635C4465CCE85C6CCC8121CCBBCC93CCD7CC8DCCE6CCFACCE4CCE817CCD95270384D500ECCCB1582A47A6574619182A474797065A6427566666572A464617461DC0020CCB7CCCB1F526A127353CCDBCC97CCB7CCCB32CC82CCB26FCCE9CCBACCC4CCB8CCE915CC9F65CCBBCCDD42412A0F771DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002005CCABCCEE75CCBA63CC9C0824CCCCCCFD6ACCC6CCE1CCC4CCF2CCACCCA9CCACCCA2CCD90716CCD746CCA3CCCD00002D4C26B472756E74696D655F6C6F6F6B75705F7461626C65C0BD72756E74696D655F6C6F6F6B75705F7461626C655F73656C6563746F72C0B3786F725F6C6F6F6B75705F73656C6563746F72C0BB6C6F6F6B75705F676174655F6C6F6F6B75705F73656C6563746F72C0BB72616E67655F636865636B5F6C6F6F6B75705F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCBD2ECCC43CCCBD197CCCC3112429CCCC1FCC83CCC26DCCBBCCB77DCC87CCDD691844CCA257CCB678CCEDCC9FCCEC1FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCE5404D5BCCA94DCCD57A78CCBE50CCFA5417CCF3CCCE46CCD5CCC4CCFDCCDCCC8226CCE5CC906A7861CCEF6C0FD921666F726569676E5F6669656C645F6D756C5F6C6F6F6B75705F73656C6563746F72C0A866745F6576616C3182A474797065A6427566666572A464617461DC00202E74CCF4CCB84B766ECCB00ACCC6CCFD70306ECCA8CCA2CC870ACCD8780864005B306ECC8DCC957CCCD04916AF707265765F6368616C6C656E67657390"; MsgPk.deser_prover_proof( MsgPk.new_stream(prover_proof_serialized), - proof + prover_proof ); + console.log(Scalar.FE.unwrap(prover_proof.evals.public_evals.zeta[0])); //assertEq(index.public_len, 0); //assertEq(index.max_poly_size, 16384); //assertEq(index.zk_rows, 3); From af96bcab8f6bf973d202d01ca8c6f6787b70dbb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 11 Dec 2023 14:29:37 -0300 Subject: [PATCH 32/68] Deserialize rest of evals --- eth_verifier/lib/Utils.sol | 3 +- eth_verifier/lib/msgpack/Deserialize.sol | 82 ++++++++++++++++++++++++ eth_verifier/test/Deserialize.t.sol | 14 ++-- kzg_prover/src/main.rs | 2 + 4 files changed, 91 insertions(+), 10 deletions(-) diff --git a/eth_verifier/lib/Utils.sol b/eth_verifier/lib/Utils.sol index 3a4b2d17..babb31ec 100644 --- a/eth_verifier/lib/Utils.sol +++ b/eth_verifier/lib/Utils.sol @@ -357,7 +357,8 @@ library Utils { integer = 0; for (uint256 i = 0; i < 32; i++) { - integer += uint256(uint8(data_b[i])) << (i * 8); + integer += uint256(uint8(data_b[i])); + integer <<= 8; } } } diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 1007d3dc..c579e614 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -338,6 +338,25 @@ library MsgPk { ); prover_proof.evals.public_evals = deser_evals(all_evals_map, "public"); + prover_proof.evals.is_public_evals_set = true; + + prover_proof.evals.z = deser_evals(all_evals_map, "z"); + + PointEvaluationsArray[] memory w = deser_evals_array( + all_evals_map, + "w" + ); + for (uint256 i = 0; i < 15; i++) { + prover_proof.evals.w[i] = w[i]; + } + + PointEvaluationsArray[] memory s = deser_evals_array( + all_evals_map, + "s" + ); + for (uint256 i = 0; i < 6; i++) { + prover_proof.evals.w[i] = w[i]; + } } function deser_evals(EncodedMap memory all_evals_map, string memory name) @@ -396,6 +415,69 @@ library MsgPk { return PointEvaluationsArray(zetas, zeta_omegas); } + function deser_evals_array( + EncodedMap memory all_evals_map, + string memory name + ) public pure returns (PointEvaluationsArray[] memory evals) { + EncodedArray memory eval_array = abi.decode( + find_value(all_evals_map, name), + (EncodedArray) + ); + uint256 length = eval_array.values.length; + evals = new PointEvaluationsArray[](length); + + for (uint256 eval = 0; eval < length; eval++) { + EncodedMap memory eval_map = abi.decode( + eval_array.values[eval], + (EncodedMap) + ); + + EncodedArray memory zeta_arr = abi.decode( + find_value(eval_map, "zeta"), + (EncodedArray) + ); + EncodedArray memory zeta_omega_arr = abi.decode( + find_value(eval_map, "zeta_omega"), + (EncodedArray) + ); + require(zeta_arr.values.length == zeta_omega_arr.values.length); + uint256 length = zeta_arr.values.length; + + Scalar.FE[] memory zetas = new Scalar.FE[](length); + Scalar.FE[] memory zeta_omegas = new Scalar.FE[](length); + for (uint256 i = 0; i < zeta_arr.values.length; i++) { + EncodedMap memory zeta_map = abi.decode( + zeta_arr.values[i], + (EncodedMap) + ); + EncodedMap memory zeta_omega_map = abi.decode( + zeta_omega_arr.values[i], + (EncodedMap) + ); + + EncodedArray memory zeta_data_arr = abi.decode( + find_value(zeta_map, "data"), + (EncodedArray) + ); + EncodedArray memory zeta_omega_data_arr = abi.decode( + find_value(zeta_omega_map, "data"), + (EncodedArray) + ); + + uint256 zeta_inner = Utils.padded_bytes_array_to_uint256( + zeta_data_arr.values + ); + uint256 zeta_omega_inner = Utils.padded_bytes_array_to_uint256( + zeta_omega_data_arr.values + ); + + zetas[i] = Scalar.from(zeta_inner); + zeta_omegas[i] = Scalar.from(zeta_omega_inner); + } + evals[eval] = PointEvaluationsArray(zetas, zeta_omegas); + } + } + // !!! FUNCTIONS BELOW ARE DEPRECATED !!! function deserializeFinalCommitments(bytes calldata data) diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index e1d60a0d..8bf0312c 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -211,14 +211,10 @@ contract DeserializeTest is Test { prover_proof ); - console.log(Scalar.FE.unwrap(prover_proof.evals.public_evals.zeta[0])); - //assertEq(index.public_len, 0); - //assertEq(index.max_poly_size, 16384); - //assertEq(index.zk_rows, 3); - //assertEq(index.domain_size, 16384); - //assertEq( - // Scalar.FE.unwrap(index.domain_gen), - // 20619701001583904760601357484951574588621083236087856586626117568842480512645 - //); + assertEq(Scalar.FE.unwrap(prover_proof.evals.public_evals.zeta[0]), 0); + assertEq( + Scalar.FE.unwrap(prover_proof.evals.z.zeta[0]), + 1511422324807084075612225175004431441562364525077650304716743095141219510784 + ); } } diff --git a/kzg_prover/src/main.rs b/kzg_prover/src/main.rs index e52c2d74..8daa4289 100644 --- a/kzg_prover/src/main.rs +++ b/kzg_prover/src/main.rs @@ -117,6 +117,8 @@ fn generate_test_proof_ex() { ) .unwrap(); + println!("{:#?}", proof.evals.z.zeta); + fs::write( "../eth_verifier/prover_proof.mpk", rmp_serde::to_vec_named(&proof).unwrap(), From 2a1a57b6729860516032903fcb7ea3eccd93311f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 11 Dec 2023 16:05:28 -0300 Subject: [PATCH 33/68] Finish deserializing index and proof --- eth_verifier/lib/Utils.sol | 9 +- eth_verifier/lib/VerifierIndex.sol | 4 +- eth_verifier/lib/msgpack/Deserialize.sol | 116 +++++++++++++---------- eth_verifier/src/Verifier.sol | 2 +- eth_verifier/test/Deserialize.t.sol | 11 ++- 5 files changed, 81 insertions(+), 61 deletions(-) diff --git a/eth_verifier/lib/Utils.sol b/eth_verifier/lib/Utils.sol index babb31ec..1a173ab3 100644 --- a/eth_verifier/lib/Utils.sol +++ b/eth_verifier/lib/Utils.sol @@ -350,15 +350,10 @@ library Utils { } /// @notice uses `flatten_padded_bytes_array()` to flat and remove the padding - /// @notice of a `bytes[]` and reinterprets the result as a little-endian uint256. + /// @notice of a `bytes[]` and reinterprets the result as a big-endian uint256. function padded_bytes_array_to_uint256(bytes[] memory b) public pure returns (uint256 integer) { bytes memory data_b = flatten_padded_bytes_array(b); require(data_b.length == 32, "not enough bytes in array"); - - integer = 0; - for (uint256 i = 0; i < 32; i++) { - integer += uint256(uint8(data_b[i])); - integer <<= 8; - } + return uint256(bytes32(data_b)); } } diff --git a/eth_verifier/lib/VerifierIndex.sol b/eth_verifier/lib/VerifierIndex.sol index 303388cc..bc9f447d 100644 --- a/eth_verifier/lib/VerifierIndex.sol +++ b/eth_verifier/lib/VerifierIndex.sol @@ -16,12 +16,12 @@ struct VerifierIndex { uint64 zk_rows; URS urs; // domain - uint256 domain_size; + uint64 domain_size; Scalar.FE domain_gen; /// The mapping between powers of alpha and constraints Alphas powers_of_alpha; // wire shift coordinates - Scalar.FE[7] shift; // TODO: use Consants.PERMUTS + Scalar.FE[7] shift; // TODO: use Consants.PERMUTS /// domain offset for zero-knowledge Scalar.FE w; } diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index c579e614..28ef65c1 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -13,6 +13,8 @@ import "../VerifierIndex.sol"; import "forge-std/console.sol"; library MsgPk { + using {Scalar.pow} for Scalar.FE; + struct Stream { bytes data; uint256 curr_index; @@ -273,24 +275,16 @@ library MsgPk { return first == 0xc3; // 0xc3 == true } - function deser_verifier_index( - Stream memory self, - VerifierIndex storage index - ) external { - EncodedMap memory map = deser_map16(self); - index.max_poly_size = abi.decode( - find_value(map, "max_poly_size"), - (uint256) - ); - index.public_len = abi.decode(find_value(map, "public"), (uint256)); - index.zk_rows = abi.decode(find_value(map, "zk_rows"), (uint64)); + function deser_buffer(EncodedMap memory self) + public + pure + returns (bytes memory data) + { + bytes memory type_name = abi.decode(find_value(self, "type"), (bytes)); + require(keccak256(type_name) == keccak256("Buffer")); - EncodedMap memory domain_map = abi.decode( - find_value(map, "domain"), - (EncodedMap) - ); EncodedArray memory data_arr = abi.decode( - find_value(domain_map, "data"), + find_value(self, "data"), (EncodedArray) ); @@ -304,10 +298,44 @@ library MsgPk { // this is becasue of Solidity's RLP encoding of every byte. // We're interested in removing this padding and flattening all the arrays: - bytes memory domain_b = Utils.flatten_padded_bytes_array( - data_arr.values + data = Utils.flatten_padded_bytes_array(data_arr.values); + } + + function deser_buffer_to_uint256(EncodedMap memory self) + public + pure + returns (uint256 integer) + { + bytes memory type_name = abi.decode(find_value(self, "type"), (bytes)); + require(keccak256(type_name) == keccak256("Buffer")); + + EncodedArray memory data_arr = abi.decode( + find_value(self, "data"), + (EncodedArray) + ); + + integer = Utils.padded_bytes_array_to_uint256(data_arr.values); + } + + function deser_verifier_index( + Stream memory self, + VerifierIndex storage index + ) external { + EncodedMap memory map = deser_map16(self); + index.public_len = abi.decode(find_value(map, "public"), (uint256)); + index.max_poly_size = abi.decode( + find_value(map, "max_poly_size"), + (uint256) + ); + index.zk_rows = abi.decode(find_value(map, "zk_rows"), (uint64)); + + EncodedMap memory domain_map = abi.decode( + find_value(map, "domain"), + (EncodedMap) ); + bytes memory domain_b = deser_buffer(domain_map); + // The domain info is in a packed, little endian serialization format. // So we'll need to manually deserialize the parameters that we're // interested in: @@ -315,7 +343,7 @@ library MsgPk { // domain_size is 64 bit and the first element, so 8 bytes and no offset: index.domain_size = 0; for (uint256 i = 0; i < 8; i++) { - index.domain_size += uint256(uint8(domain_b[i])) << (i * 8); + index.domain_size += uint64(uint8(domain_b[i])) << (i * 8); } // domain_gen is 256 bit and there're 8+4+32+32=76 bytes before it: @@ -324,6 +352,22 @@ library MsgPk { domain_gen += uint256(uint8(domain_b[i + 76])) << (i * 8); } index.domain_gen = Scalar.from(domain_gen); + + // wire shift coordinates + EncodedArray memory shift_arr = abi.decode( + find_value(map, "shift"), + (EncodedArray) + ); + require(shift_arr.values.length == 7, "shift array is not of length 7"); + for (uint256 i = 0; i < 7; i++) { + uint256 inner = deser_buffer_to_uint256( + abi.decode(shift_arr.values[i], (EncodedMap)) + ); + index.shift[i] = Scalar.from(inner); + } + + // domain offset for zero-knowledge + index.w = index.domain_gen.pow(index.domain_size - index.zk_rows); } function deser_prover_proof( @@ -392,21 +436,8 @@ library MsgPk { (EncodedMap) ); - EncodedArray memory zeta_data_arr = abi.decode( - find_value(zeta_map, "data"), - (EncodedArray) - ); - EncodedArray memory zeta_omega_data_arr = abi.decode( - find_value(zeta_omega_map, "data"), - (EncodedArray) - ); - - uint256 zeta_inner = Utils.padded_bytes_array_to_uint256( - zeta_data_arr.values - ); - uint256 zeta_omega_inner = Utils.padded_bytes_array_to_uint256( - zeta_omega_data_arr.values - ); + uint256 zeta_inner = deser_buffer_to_uint256(zeta_map); + uint256 zeta_omega_inner = deser_buffer_to_uint256(zeta_omega_map); zetas[i] = Scalar.from(zeta_inner); zeta_omegas[i] = Scalar.from(zeta_omega_inner); @@ -455,20 +486,9 @@ library MsgPk { (EncodedMap) ); - EncodedArray memory zeta_data_arr = abi.decode( - find_value(zeta_map, "data"), - (EncodedArray) - ); - EncodedArray memory zeta_omega_data_arr = abi.decode( - find_value(zeta_omega_map, "data"), - (EncodedArray) - ); - - uint256 zeta_inner = Utils.padded_bytes_array_to_uint256( - zeta_data_arr.values - ); - uint256 zeta_omega_inner = Utils.padded_bytes_array_to_uint256( - zeta_omega_data_arr.values + uint256 zeta_inner = deser_buffer_to_uint256(zeta_map); + uint256 zeta_omega_inner = deser_buffer_to_uint256( + zeta_omega_map ); zetas[i] = Scalar.from(zeta_inner); diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 709b2b18..550c5684 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -68,7 +68,7 @@ contract KimchiVerifier { BN254.G1Point[] memory g, BN254.G1Point memory h, uint256 public_len, - uint256 domain_size, + uint64 domain_size, uint256 max_poly_size, ProofEvaluationsArray memory evals ) public { diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index 8bf0312c..878ea2d3 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -204,17 +204,22 @@ contract DeserializeTest is Test { } function test_deserialize_prover_proof() public { + // This serialized index was manually modified to make `public_evals` + // equal to 256. bytes - memory prover_proof_serialized = hex"85AB636F6D6D69746D656E747384A6775F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCD843CC8C68CCADCCC65F0FCCE95332CCD3566E1C7BCCA626764ECCFF30CCEE14CC9560790764CCE7CCC4CC9CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE7CCFBCCD1CC92CCBF523131CCDD2FCCB807CCF8CCF7CCCFCCADCCE7CCDF6256CCE8CC9ECC91CCF0CC9C0CCCB11050050FCC85A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC3CCE17360CCCC5FCCA1CCAD260C0ECCDFCC98CCCBCC8ECCD2367F0B2553654257CCA5CC82CC96CC9361CCF379CC89A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020465CCCB06ACC97CCCC1FCCBA62156DCCEA4A0ACCCF78CC98CCAECCBECCDFCCE1CCD212537BCCCF5970CC8C3A3E30A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCAACCAECCD8302DCC9FCCF808CCA76DCCB646CCA345CCA70BCCFFCCBA5865357522CCF6CCEF443634CC81CCA7CC8A0CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002010CCDC62CCE86ACCA0CCFBCCCCCCA934CC8ACCB97ACCE3552B5E7442112820503713CCCD7E30CCC4CC8936CC92A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00207833045124CC8BCCFA087CCCC77969CC8B17CCDECCD5CCEACCD3CCB8CCC147CC907DCCFF0042CCB9CCADCCE444CCF1CC80A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201A49CCD234CCEE0ACC985DCCD452CCB8CCC365CCBA5F7FCCE57874CCE5CCB8CCAE7C24CCA7CCFFCCDF7F06CCCECCBF16A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00203BCCF60A24CCEF2F1B14CCE9CCF71BCCC23ECCEA0C5ACC9C0DCC9E377232CCD501CCBACCCFCCD9CCF9CCF3CCDACCCF00A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201ECCA4CCCFCCEF710FCCE8CC9B32CC81CC84323C601ACCB1516005CCFFCCEB2FCC90CCBE654CCCFD5D486FCC862FA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7DCCDC5F6ACC8132CCC008CCF9CCE3CCCACC94CC8ACCA83D7ECCC5CC835ECC97CC8ACC95CC9CCCE3CCCA0B58CCDF4FCCE314A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020351B53CCB8CCA6CCDB78CCA61D4865276D69CCDD49361E620A32611E1ECC80CCFE51CC94CCB74C2410A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC830DCC89CCADCCBCCCC9CCD3CC82CCE60114CCCBCCBFCCD5CC8D40723DCCE6CC8354CC9509CCB731CCCACC9ECCD7CCB7CCDECCD7CCABA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC2CCF328CCED33CCDC6264CCEDCCEC4633CCCCCCA8CCBBCCDACCC24345CC99CCA565CCC23ACCB144CCAACCC459CC924809A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00204DCCBE7C3A5F1E2B7ECC867965CCCBCCD65A7D771ACC81CCEECCF724CCE2010DCCF1CCF63CCCFC4C56CCB5CC9FA773686966746564C0A67A5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCCB4CC8052CC9A247A2B51425B50705BCCEACCD7CC85CC8664CCBCCC84CCB1CCD318CCB96BCCEA55CC9049CCEBCCA7A773686966746564C0A6745F636F6D6D82A9756E736869667465649782A474797065A6427566666572A464617461DC00203ACCF406CCEBCCEBCCE72979CCF063CCB06BCCA8CCF74A34CCA22B5D4B5E30CCF8CCFD3F7BCC9F11CCC254101582A474797065A6427566666572A464617461DC002071CCF6CC9CCCADCCA4565520CCE9CCA5CCF4CCEBCCA0CCDB1B1E3D760224025A4DCC806BCC9DCCA7CC8CCCA951CCEC0C82A474797065A6427566666572A464617461DC002056CCC151CC80CCF762CCAFCCA4CCD9CCC968CCA6CCAA64CCD60CCCF1CCC4CC9FCCDB6A2D6863CCFFCCAB48796F37CC8D2682A474797065A6427566666572A464617461DC0020CCAECCF3665BCCDFCC97CCBE7CCCE6CCF8CCB70F62CCAE197764CC9ACCB80ACCA416CCE3CCB00E78CCAD265613CCA50B82A474797065A6427566666572A464617461DC0020CCF81C0359CC95CCFCCCA479CCB2CC9DCCEDCC9626CCCECCB6CCEDCCAE642A3DCCF37ECCF56B665BCCD950CCD32C780882A474797065A6427566666572A464617461DC0020CCF6CCF06B74CCA433591E30CCE6CCE1CC93CC8ACC9C56042F3867714FCCC72E7ACC891ECCBB71603DCCE4CCAF82A474797065A6427566666572A464617461DC0020CCCFCCCFCCB3560BCC83CC95CCCC33CCEACC9E6DCC921BCCB4CCCACCA864CCECCCC33776734D657CCCD52BCCAC204BCC94A773686966746564C0A66C6F6F6B757083A6736F727465649582A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE9CCF5195B6ACCD6CC96CCA1325F2D6C79CCFF6CCCD9CC9ACCFE77CC932BCCE3CC994073CCF2CCFBCCC779CCE56C27A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC975DCCC0CCDD6BCCC7CC9ECC8CCCDA681A17CCDA2CCC9F7BCC916F483D41CCA00A68CCB718CCC722CCBE422E18A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002021CCC1CC8C4370687F69CCA0CCAA533BCCCA0C5BCCE847CCBA78CC83CC8BCCA103CCC67668CCDCCC812405CCA0CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002019CCD34CCCF25BCCE82955CC974A26663E0F70CCA6596FCCACCC9B7CCCAECC83CCA6556F410771CC92CCF611A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002045CCF9105CCC8FCCA1CC9E2638607BCC8A2B0266CCEDCCFACC9361CC80CCC1CCE1CC8A3C5B08CCCC5FCC8921CCC2CCA7A773686966746564C0A661676772656782A9756E736869667465649182A474797065A6427566666572A464617461DC00201DCCC905CCCBCCFC7F19CCB5CCCCCCECCCB4CC965DCCA5CC87573F535C6A15CCBD0FCCC0CCA81D07023818CCA21FA773686966746564C0A772756E74696D65C0A570726F6F6682A871756F7469656E7482A474797065A6427566666572A464617461DC0020CCDD7E3BCC86CC99622CCCFD7F08221DCCD8191504CCAB386202CCC50A6ACCB1CC8ECCF663CCBECC9F0A53CC99A8626C696E64696E6782A474797065A6427566666572A464617461DC00207B6778CCBECCFD13CCB616CCEDCCDBCCAA7B1FCCD214CCC4CCD3CC9A4DCCC0306ACCC3CCF3CCD1CCAFCCF64D6858CCB61DA56576616C73DE001AA67075626C696382A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000A1779F82A47A6574619182A474797065A6427566666572A464617461DC0020CC91CCABCC853859CCDB5FCC8FCCC276CCAACCC5183119CC84CC863231CCB456CCB608CC9336CCC3CCC0CCC0CCEACCAB2D2CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD7CCB3CCC07450CCC178CCBB5B14CCE3CCB5CCB22C70CCEBCC8E770ACCE329284A08CC84CCA5CCDF6BCCC1752E0882A47A6574619182A474797065A6427566666572A464617461DC0020134ECCAECCD96164CCA0CCD8CCBF0B71CC9C5C78CCE3CC8E21CC81CCDF10CCBD02462ECCA8CC9D03CCCECCF06D6F15AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD256CCA01BCCABCCF549CCC62908CCFDCCE5CCF537CCC24BCCF645CCCC2948CCEC3ACCD9CC9ACCAECCC2CCE30ACCCD301D82A47A6574619182A474797065A6427566666572A464617461DC0020CCC2CCEBCC96142945380379CCEFCC95130D6914CC925FCCF623CCA4CCB21BCCE00FCCCA00CCA5CCA44113CCC206AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00203ECCD2CCD9CCADCCB110CCA05F6B0DCCF5CCD435373FCC896DCCC16ECCA81E29CC982A5D422835CCAC4B090C82A47A6574619182A474797065A6427566666572A464617461DC0020162ECCAECCE714CCE053CC94CCFECCB612CCA31371CC8D3856CCD9CCE603CCECCCB2CCE9CCEB39CCDBCC86CCB445251216AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCBACCF04E4E7ACCE2CCCECCBBCCB2CCC2CC8ACCB7CCF06A71CC9F685ACCF1CCC9CCA454CCDC0549CCFFCCD545CC8B4A1A1682A47A6574619182A474797065A6427566666572A464617461DC00200F4B02CCDA68CCDFCCE9CCA8366FCCAACCD70ECCCE3ACCA84BCCC3CC80CCC149CCB077CCA20BCC9DCCBF5FCCEC7ECCBC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002066CCA178CCA84845CCE35ECCEA08CCD4CCB1CCEBCCD5CCF6221C0F74CCDCCCCBCCCDCCDFCCDD62CCEECCEC4D6DCCD4CCC40982A47A6574619182A474797065A6427566666572A464617461DC00206ECCE833CCF62BCCF044CCE1CCA3CC9B25604DCC982CCCA1CCFC6ECC9A61CCA4CCE973CCEF0A71CCBFCCD90617CC9422AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205848CCFC1BCCFC647567CCCFCCF76ACCC176CCFACC92560B6C3E3D6FCC90CCF6CC9FCC9ACC88CC811160CC91CCC20682A47A6574619182A474797065A6427566666572A464617461DC0020CC864757CCB36C11CC86182C11CC832E08CC86466ECC8A49187BCC8BCCEFCC90CCC87171CCA62040CC9ACCC22FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD0CCAECCFFCC91CCA0CC9FCC9625CC9522CCD5204E2BCCC0CC91507408CCFACCCB5B202C57CCF23A46CCE37D7D2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCE95ACC9E46CCFCCCBA232C37CCC335CCF9CCF9303CCCFFCCC85669CCEFCCB107CC99CCFACCF7CC924F2827CCAE0102AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002009CCB537CC9D6607CCFECCFDCCE14801CCF6CCB3CCA2CCB6CCE2CCDFCCE5CCC83027334FCCAE22221BCCCF1A0F1C0082A47A6574619182A474797065A6427566666572A464617461DC0020CCC6CCCD1ACCBF41233DCCA617CC9C4406CCD861CC91CCF60E4412CCAB4FCCB1CC9F447BCCB3CCABCC9E7836CC960CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002037CC80CCAECCBD56CCB5CCBC50CCC3CC9746CC995BCCB628CCB674CCACCCF7CCC55D653142CC9FCCCA71CCC9CCE3CCEACC8C0A82A47A6574619182A474797065A6427566666572A464617461DC0020CCB1CC8348CCDACCD87DCCD0CCDC29CC826D03672D64CCAE4963CCE37ECCB205114ACCDECCB5CC9F1E1B72CCAC03AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF5793436CC87574F2ACCAA5020CCA91E1CCC8451CC81015ECC8E35267C063CCC86CCB87CCCA002CCFF2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCD33CCCAECCD038CCD63324CC9B1DCC9ACC9FCC8040CC9A39CCF7CCEACCCCCCE17ECCE5CCADCCEE18CCB0CC8509497ECC882DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD32B42CCF447CCDD023CCCD4CCB76D50CC9DCCD2CC8054CCF456CCC709CCA017CCC104CC9A65CCA37439CC96CCA61782A47A6574619182A474797065A6427566666572A464617461DC00200A5D16CC8FCCC1CCF516CC8843CCDBCCFD74CCD8102B5928CCA244CCDC29CCE8CCC4714DCC935628CCB52ECC8D18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCEA45CCBE2C29CCDFCC805ECCE5CCABCCB3CCAB05CCEDCCE125CCB2CCFDCC8ECCAD6549CCF1CCA57DCCE9CCD647CCE6CCA7650E82A47A6574619182A474797065A6427566666572A464617461DC00204854CCAE40CCFCCC8F3BCC935E2477CCCCCCC90D0C115D72CCAD63CCA537CC9873CC8770CCEFCCBA12CCFDCCB01BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCDC2DCCD655CCAC0B6311CC9944CC8E39CCDECC81CCBBCCB1CCE45C32CCA4CCBD5A1D4314CCFFCC9010CCF24B2B82A47A6574619182A474797065A6427566666572A464617461DC00201135CCDBCCDC6F7FCCDC26CC845449CCC771CC881029CCC1CC80CCD5CCAE61CC866DCCCF6CCCF81C1C73CC871A2FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002048CCCBCC81CC906F47CC98CC8F3E3C04CCD4CC9874CCA50A3E3D31CCE6CCCCCC8772CC8ECCBC07CCDA05CCCE273A3082A47A6574619182A474797065A6427566666572A464617461DC00207DCCCCCCCECCBACC9D4373CCAF6F1D07CCD00FCCD42344CCD5CCB3CCE0CCF36A7937CC8DCCFB350BCC8E7F73CC9D26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00206C2D746FCCD1CCF94654CCB7CCC4CCC7CCE36051CCB019CCCBCCE870CCE5CCD43ACCED10CC93CCFFCCEB4C67CCA05D30A17A82A47A6574619182A474797065A6427566666572A464617461DC00203303576F49CCD5CCA8CCD0CCE87BCC9703CCFCCCEACC9FCC9102CCCC69CC8ACCE4CCEF6945CCA5CCDF1F2B7262652AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCE747CCA774CC98CCA2CCA610CC9FCCEDCCEC22CCEC150E732818CCFF3727CCD4CCDA31CCE1CCB5587160CCAACCC603A1739682A47A6574619182A474797065A6427566666572A464617461DC002051CCF4CCA0CCA2CCDC4BCCCFCCC2CCDC5CCCFBCCF2CC9FCC9CCCB9CC9FCCA7315741CCFF73CC99CCFF41CCE8CC95CCE6CCD6CCB7001DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF21D4C5ACC954338CCE1CCC56206CCC45705CCE503CCDD28CCEE64CCF633CCA6CCF677CCFACCF8CCB5CC8A45CC9F0E82A47A6574619182A474797065A6427566666572A464617461DC0020CCEFCC81CCD54E2E33CC860C37CCE8CCA5CC96CCFF1ACC802ACCEACCBDCCD6275770CC841F36CCA6CCD5CCCCCCA13CCCC71AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF63A5E6C3ECCF63DCCED4ACC8F75CCDF2ECCBF5ECC95CCC8CCA4CC992926CC996DCCE9CCAD60CCD30122CCE2201782A47A6574619182A474797065A6427566666572A464617461DC00201ECCAA57CCA3CC9BCCDDCCBFCCFCCCD13074CCF7CCFACCD84DCCB434CCC4CCDA5FCCF866CCE6CCD5CCC6CCCD70CCC653CCDDCC882EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020332374CCBA79025BCC9916CCD7CCD90CCCDC5CCCE0CCA8CCE368CC9F590136CCCB15CCC868CC8BCCA809CC84CCF30082A47A6574619182A474797065A6427566666572A464617461DC002018CC88415E4CCC9E64720DCCF873CCAC561748CCEA26CCF9CC8B153D61CCF34BCCCDCCA62710CCC9500C1BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA1CC80CC81CCEC3CCCC6CCF9CC9A5E1ECCC7CCF9CCA2CCF2217743437DCC8BCCF7CCDFCCC3CCC51ECCDECC96CCA0CC8438091182A47A6574619182A474797065A6427566666572A464617461DC0020CCCC40CC942544CCB12E2F46CCF4CCA1CC8ACCC2596C113363CCDF2FCCAF41CCFECCD5CCE5CCFDCCFD7C33107E26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002011CCAF34CCA9470870CCE7CCF411CCC2CC8741CCDD52CCAB55CCC1CCCECC876ACC870305622F7ACCCBCC8761CCB00982A47A6574619182A474797065A6427566666572A464617461DC0020CCEC6741CCFECCA4CCF6CCF91FCCE6CCDCCC9E5E746B2857CCFFCC962B4ACCCECCE7CCE9CCD429CCB4CCD2CC8D1FCC8DCCFC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC81CCA9CCE6CCC546CCA8555ECCF82607CCCECC9563CCDC31CCA3CCD8CCDA2BCCA4CCBE18616426697D696ECC831DAC636F656666696369656E74739F82A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B067656E657269635F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B1706F736569646F6E5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B5636F6D706C6574655F6164645F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AC6D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AD656D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B7656E646F6D756C5F7363616C61725F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B572616E67655F636865636B305F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCA8CC92CCB340CCC520573BCCF5CCC60BCCABCCBDCCE7CC8F15CCE2CCEDCCEE31CC9B484D5FCCD62CCCC2CCC3391ACCFF2EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC9D37CCAE26CC8702CCBB67CCFFCCBACC841DCCEB383113CCFBCCB3CCE6CC8FCCF0CCBFCCEFCCDB1B6F622645CC830F27B572616E67655F636865636B315F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCF2CC90CCC8CCA4CC8DCC92CCE7CCDFCCA93938044316CCBE6D37CCC9023A2A54CCD9043B0ECCBECCF912350703AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC941CCCCA71CCDA09CC8DCCD162CCF4CCBACCA814CCEE5BCC9ACCF9216D7CCC990E0ACCFECCB7CCB37B397CCC85CCBA15BA666F726569676E5F6669656C645F6164645F73656C6563746F72C0BA666F726569676E5F6669656C645F6D756C5F73656C6563746F72C0AC786F725F73656C6563746F72C0AC726F745F73656C6563746F72C0B26C6F6F6B75705F6167677265676174696F6E82A47A6574619182A474797065A6427566666572A464617461DC0020CCBB1ACCD376CCEECCF0CCA750CC8B711ACC97CC8160CCE1CCC5CCFCCCF0CCE0412861CCEF5128CCF4CC99CCCE39CCC4CCF80DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002032CC903FCCD27BCC9ECC9CCCAFCCBC39CCC1CCC3CC9BCCA36D0570CCA114CCAE2CCC9F1203CCBD60CCA31D7ACCBB0514AC6C6F6F6B75705F7461626C6582A47A6574619182A474797065A6427566666572A464617461DC00203D663E7E6610CCB1CC844863CC803466590A2A1CCCA451CCC755393BCCD3CCC762CC822B44CCA8CCB02BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC8ACC985A1D271113CCCACCE0CCA7CCEACCB5CC86CC845CCCB8CCCD2E27CCDF38CCD30E76CCC81832CC94CC8ECCF4CCAB1FAD6C6F6F6B75705F736F727465649582A47A6574619182A474797065A6427566666572A464617461DC002003CCF1CC8FCC8CCC843B1ACCC26DCCDE6ECCE46E64CCC9CCE971CCDECCC4CC84CCFE2FCCBACCFBCC8737CCACCC8756CC945F23AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA3326726CCABCCD7CC904C23CC927068CC920F59CCB7CCEA17CCCFCC8878CC91CCC13ACCE36C3F4725CC8B222882A47A6574619182A474797065A6427566666572A464617461DC0020CCF52ECCB7683352CCA3CCF176CCEECCD461CCCC0C3ACCD905CC80CCAF4E25CCBE29CCA8CC99CCD87ECC8ACCC20FCCB90DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00207BCCD5CCC6CC9228CCE1CCBA3E037ACC854FCC9A6BCCCC492CCCA7CCA7CCF5CCEF3FCC862278CCC732CCDD45CCFCCCD02782A47A6574619182A474797065A6427566666572A464617461DC0020CC9741CCC7CCC0CCFC6F6A6768377ECCD94ACCB1CCC92FCCE66129CCE7CCC8CC8436CCB3CCBE2DCC8BCCF418CCB20415AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205772CCCF1B0A32CCFDCCE247CCC3CCDD6CCC8126CC83CCFCCCBE5F31CCA53521CC85CCBA72CCBDCC85344265701282A47A6574619182A474797065A6427566666572A464617461DC0020CCB4CCA0CCEA22046DCC87CCB2427F4954CC82CC84CCADCCD10BCCB7CCD7CC990044CCF4CCDFCCD95FCCD5CCD27167CCBE18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF569CC93331A635C4465CCE85C6CCC8121CCBBCC93CCD7CC8DCCE6CCFACCE4CCE817CCD95270384D500ECCCB1582A47A6574619182A474797065A6427566666572A464617461DC0020CCB7CCCB1F526A127353CCDBCC97CCB7CCCB32CC82CCB26FCCE9CCBACCC4CCB8CCE915CC9F65CCBBCCDD42412A0F771DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002005CCABCCEE75CCBA63CC9C0824CCCCCCFD6ACCC6CCE1CCC4CCF2CCACCCA9CCACCCA2CCD90716CCD746CCA3CCCD00002D4C26B472756E74696D655F6C6F6F6B75705F7461626C65C0BD72756E74696D655F6C6F6F6B75705F7461626C655F73656C6563746F72C0B3786F725F6C6F6F6B75705F73656C6563746F72C0BB6C6F6F6B75705F676174655F6C6F6F6B75705F73656C6563746F72C0BB72616E67655F636865636B5F6C6F6F6B75705F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCBD2ECCC43CCCBD197CCCC3112429CCCC1FCC83CCC26DCCBBCCB77DCC87CCDD691844CCA257CCB678CCEDCC9FCCEC1FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCE5404D5BCCA94DCCD57A78CCBE50CCFA5417CCF3CCCE46CCD5CCC4CCFDCCDCCC8226CCE5CC906A7861CCEF6C0FD921666F726569676E5F6669656C645F6D756C5F6C6F6F6B75705F73656C6563746F72C0A866745F6576616C3182A474797065A6427566666572A464617461DC00202E74CCF4CCB84B766ECCB00ACCC6CCFD70306ECCA8CCA2CC870ACCD8780864005B306ECC8DCC957CCCD04916AF707265765F6368616C6C656E67657390"; + memory prover_proof_serialized = hex"85AB636F6D6D69746D656E747384A6775F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCD843CC8C68CCADCCC65F0FCCE95332CCD3566E1C7BCCA626764ECCFF30CCEE14CC9560790764CCE7CCC4CC9CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE7CCFBCCD1CC92CCBF523131CCDD2FCCB807CCF8CCF7CCCFCCADCCE7CCDF6256CCE8CC9ECC91CCF0CC9C0CCCB11050050FCC85A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC3CCE17360CCCC5FCCA1CCAD260C0ECCDFCC98CCCBCC8ECCD2367F0B2553654257CCA5CC82CC96CC9361CCF379CC89A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020465CCCB06ACC97CCCC1FCCBA62156DCCEA4A0ACCCF78CC98CCAECCBECCDFCCE1CCD212537BCCCF5970CC8C3A3E30A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCAACCAECCD8302DCC9FCCF808CCA76DCCB646CCA345CCA70BCCFFCCBA5865357522CCF6CCEF443634CC81CCA7CC8A0CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002010CCDC62CCE86ACCA0CCFBCCCCCCA934CC8ACCB97ACCE3552B5E7442112820503713CCCD7E30CCC4CC8936CC92A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00207833045124CC8BCCFA087CCCC77969CC8B17CCDECCD5CCEACCD3CCB8CCC147CC907DCCFF0042CCB9CCADCCE444CCF1CC80A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201A49CCD234CCEE0ACC985DCCD452CCB8CCC365CCBA5F7FCCE57874CCE5CCB8CCAE7C24CCA7CCFFCCDF7F06CCCECCBF16A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00203BCCF60A24CCEF2F1B14CCE9CCF71BCCC23ECCEA0C5ACC9C0DCC9E377232CCD501CCBACCCFCCD9CCF9CCF3CCDACCCF00A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201ECCA4CCCFCCEF710FCCE8CC9B32CC81CC84323C601ACCB1516005CCFFCCEB2FCC90CCBE654CCCFD5D486FCC862FA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7DCCDC5F6ACC8132CCC008CCF9CCE3CCCACC94CC8ACCA83D7ECCC5CC835ECC97CC8ACC95CC9CCCE3CCCA0B58CCDF4FCCE314A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020351B53CCB8CCA6CCDB78CCA61D4865276D69CCDD49361E620A32611E1ECC80CCFE51CC94CCB74C2410A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC830DCC89CCADCCBCCCC9CCD3CC82CCE60114CCCBCCBFCCD5CC8D40723DCCE6CC8354CC9509CCB731CCCACC9ECCD7CCB7CCDECCD7CCABA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC2CCF328CCED33CCDC6264CCEDCCEC4633CCCCCCA8CCBBCCDACCC24345CC99CCA565CCC23ACCB144CCAACCC459CC924809A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00204DCCBE7C3A5F1E2B7ECC867965CCCBCCD65A7D771ACC81CCEECCF724CCE2010DCCF1CCF63CCCFC4C56CCB5CC9FA773686966746564C0A67A5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCCB4CC8052CC9A247A2B51425B50705BCCEACCD7CC85CC8664CCBCCC84CCB1CCD318CCB96BCCEA55CC9049CCEBCCA7A773686966746564C0A6745F636F6D6D82A9756E736869667465649782A474797065A6427566666572A464617461DC00203ACCF406CCEBCCEBCCE72979CCF063CCB06BCCA8CCF74A34CCA22B5D4B5E30CCF8CCFD3F7BCC9F11CCC254101582A474797065A6427566666572A464617461DC002071CCF6CC9CCCADCCA4565520CCE9CCA5CCF4CCEBCCA0CCDB1B1E3D760224025A4DCC806BCC9DCCA7CC8CCCA951CCEC0C82A474797065A6427566666572A464617461DC002056CCC151CC80CCF762CCAFCCA4CCD9CCC968CCA6CCAA64CCD60CCCF1CCC4CC9FCCDB6A2D6863CCFFCCAB48796F37CC8D2682A474797065A6427566666572A464617461DC0020CCAECCF3665BCCDFCC97CCBE7CCCE6CCF8CCB70F62CCAE197764CC9ACCB80ACCA416CCE3CCB00E78CCAD265613CCA50B82A474797065A6427566666572A464617461DC0020CCF81C0359CC95CCFCCCA479CCB2CC9DCCEDCC9626CCCECCB6CCEDCCAE642A3DCCF37ECCF56B665BCCD950CCD32C780882A474797065A6427566666572A464617461DC0020CCF6CCF06B74CCA433591E30CCE6CCE1CC93CC8ACC9C56042F3867714FCCC72E7ACC891ECCBB71603DCCE4CCAF82A474797065A6427566666572A464617461DC0020CCCFCCCFCCB3560BCC83CC95CCCC33CCEACC9E6DCC921BCCB4CCCACCA864CCECCCC33776734D657CCCD52BCCAC204BCC94A773686966746564C0A66C6F6F6B757083A6736F727465649582A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE9CCF5195B6ACCD6CC96CCA1325F2D6C79CCFF6CCCD9CC9ACCFE77CC932BCCE3CC994073CCF2CCFBCCC779CCE56C27A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC975DCCC0CCDD6BCCC7CC9ECC8CCCDA681A17CCDA2CCC9F7BCC916F483D41CCA00A68CCB718CCC722CCBE422E18A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002021CCC1CC8C4370687F69CCA0CCAA533BCCCA0C5BCCE847CCBA78CC83CC8BCCA103CCC67668CCDCCC812405CCA0CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002019CCD34CCCF25BCCE82955CC974A26663E0F70CCA6596FCCACCC9B7CCCAECC83CCA6556F410771CC92CCF611A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002045CCF9105CCC8FCCA1CC9E2638607BCC8A2B0266CCEDCCFACC9361CC80CCC1CCE1CC8A3C5B08CCCC5FCC8921CCC2CCA7A773686966746564C0A661676772656782A9756E736869667465649182A474797065A6427566666572A464617461DC00201DCCC905CCCBCCFC7F19CCB5CCCCCCECCCB4CC965DCCA5CC87573F535C6A15CCBD0FCCC0CCA81D07023818CCA21FA773686966746564C0A772756E74696D65C0A570726F6F6682A871756F7469656E7482A474797065A6427566666572A464617461DC0020CCDD7E3BCC86CC99622CCCFD7F08221DCCD8191504CCAB386202CCC50A6ACCB1CC8ECCF663CCBECC9F0A53CC99A8626C696E64696E6782A474797065A6427566666572A464617461DC00207B6778CCBECCFD13CCB616CCEDCCDBCCAA7B1FCCD214CCC4CCD3CC9A4DCCC0306ACCC3CCF3CCD1CCAFCCF64D6858CCB61DA56576616C73DE001AA67075626C696382A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000100AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000A1779F82A47A6574619182A474797065A6427566666572A464617461DC0020CC91CCABCC853859CCDB5FCC8FCCC276CCAACCC5183119CC84CC863231CCB456CCB608CC9336CCC3CCC0CCC0CCEACCAB2D2CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD7CCB3CCC07450CCC178CCBB5B14CCE3CCB5CCB22C70CCEBCC8E770ACCE329284A08CC84CCA5CCDF6BCCC1752E0882A47A6574619182A474797065A6427566666572A464617461DC0020134ECCAECCD96164CCA0CCD8CCBF0B71CC9C5C78CCE3CC8E21CC81CCDF10CCBD02462ECCA8CC9D03CCCECCF06D6F15AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD256CCA01BCCABCCF549CCC62908CCFDCCE5CCF537CCC24BCCF645CCCC2948CCEC3ACCD9CC9ACCAECCC2CCE30ACCCD301D82A47A6574619182A474797065A6427566666572A464617461DC0020CCC2CCEBCC96142945380379CCEFCC95130D6914CC925FCCF623CCA4CCB21BCCE00FCCCA00CCA5CCA44113CCC206AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00203ECCD2CCD9CCADCCB110CCA05F6B0DCCF5CCD435373FCC896DCCC16ECCA81E29CC982A5D422835CCAC4B090C82A47A6574619182A474797065A6427566666572A464617461DC0020162ECCAECCE714CCE053CC94CCFECCB612CCA31371CC8D3856CCD9CCE603CCECCCB2CCE9CCEB39CCDBCC86CCB445251216AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCBACCF04E4E7ACCE2CCCECCBBCCB2CCC2CC8ACCB7CCF06A71CC9F685ACCF1CCC9CCA454CCDC0549CCFFCCD545CC8B4A1A1682A47A6574619182A474797065A6427566666572A464617461DC00200F4B02CCDA68CCDFCCE9CCA8366FCCAACCD70ECCCE3ACCA84BCCC3CC80CCC149CCB077CCA20BCC9DCCBF5FCCEC7ECCBC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002066CCA178CCA84845CCE35ECCEA08CCD4CCB1CCEBCCD5CCF6221C0F74CCDCCCCBCCCDCCDFCCDD62CCEECCEC4D6DCCD4CCC40982A47A6574619182A474797065A6427566666572A464617461DC00206ECCE833CCF62BCCF044CCE1CCA3CC9B25604DCC982CCCA1CCFC6ECC9A61CCA4CCE973CCEF0A71CCBFCCD90617CC9422AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205848CCFC1BCCFC647567CCCFCCF76ACCC176CCFACC92560B6C3E3D6FCC90CCF6CC9FCC9ACC88CC811160CC91CCC20682A47A6574619182A474797065A6427566666572A464617461DC0020CC864757CCB36C11CC86182C11CC832E08CC86466ECC8A49187BCC8BCCEFCC90CCC87171CCA62040CC9ACCC22FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD0CCAECCFFCC91CCA0CC9FCC9625CC9522CCD5204E2BCCC0CC91507408CCFACCCB5B202C57CCF23A46CCE37D7D2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCE95ACC9E46CCFCCCBA232C37CCC335CCF9CCF9303CCCFFCCC85669CCEFCCB107CC99CCFACCF7CC924F2827CCAE0102AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002009CCB537CC9D6607CCFECCFDCCE14801CCF6CCB3CCA2CCB6CCE2CCDFCCE5CCC83027334FCCAE22221BCCCF1A0F1C0082A47A6574619182A474797065A6427566666572A464617461DC0020CCC6CCCD1ACCBF41233DCCA617CC9C4406CCD861CC91CCF60E4412CCAB4FCCB1CC9F447BCCB3CCABCC9E7836CC960CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002037CC80CCAECCBD56CCB5CCBC50CCC3CC9746CC995BCCB628CCB674CCACCCF7CCC55D653142CC9FCCCA71CCC9CCE3CCEACC8C0A82A47A6574619182A474797065A6427566666572A464617461DC0020CCB1CC8348CCDACCD87DCCD0CCDC29CC826D03672D64CCAE4963CCE37ECCB205114ACCDECCB5CC9F1E1B72CCAC03AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF5793436CC87574F2ACCAA5020CCA91E1CCC8451CC81015ECC8E35267C063CCC86CCB87CCCA002CCFF2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCD33CCCAECCD038CCD63324CC9B1DCC9ACC9FCC8040CC9A39CCF7CCEACCCCCCE17ECCE5CCADCCEE18CCB0CC8509497ECC882DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD32B42CCF447CCDD023CCCD4CCB76D50CC9DCCD2CC8054CCF456CCC709CCA017CCC104CC9A65CCA37439CC96CCA61782A47A6574619182A474797065A6427566666572A464617461DC00200A5D16CC8FCCC1CCF516CC8843CCDBCCFD74CCD8102B5928CCA244CCDC29CCE8CCC4714DCC935628CCB52ECC8D18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCEA45CCBE2C29CCDFCC805ECCE5CCABCCB3CCAB05CCEDCCE125CCB2CCFDCC8ECCAD6549CCF1CCA57DCCE9CCD647CCE6CCA7650E82A47A6574619182A474797065A6427566666572A464617461DC00204854CCAE40CCFCCC8F3BCC935E2477CCCCCCC90D0C115D72CCAD63CCA537CC9873CC8770CCEFCCBA12CCFDCCB01BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCDC2DCCD655CCAC0B6311CC9944CC8E39CCDECC81CCBBCCB1CCE45C32CCA4CCBD5A1D4314CCFFCC9010CCF24B2B82A47A6574619182A474797065A6427566666572A464617461DC00201135CCDBCCDC6F7FCCDC26CC845449CCC771CC881029CCC1CC80CCD5CCAE61CC866DCCCF6CCCF81C1C73CC871A2FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002048CCCBCC81CC906F47CC98CC8F3E3C04CCD4CC9874CCA50A3E3D31CCE6CCCCCC8772CC8ECCBC07CCDA05CCCE273A3082A47A6574619182A474797065A6427566666572A464617461DC00207DCCCCCCCECCBACC9D4373CCAF6F1D07CCD00FCCD42344CCD5CCB3CCE0CCF36A7937CC8DCCFB350BCC8E7F73CC9D26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00206C2D746FCCD1CCF94654CCB7CCC4CCC7CCE36051CCB019CCCBCCE870CCE5CCD43ACCED10CC93CCFFCCEB4C67CCA05D30A17A82A47A6574619182A474797065A6427566666572A464617461DC00203303576F49CCD5CCA8CCD0CCE87BCC9703CCFCCCEACC9FCC9102CCCC69CC8ACCE4CCEF6945CCA5CCDF1F2B7262652AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCE747CCA774CC98CCA2CCA610CC9FCCEDCCEC22CCEC150E732818CCFF3727CCD4CCDA31CCE1CCB5587160CCAACCC603A1739682A47A6574619182A474797065A6427566666572A464617461DC002051CCF4CCA0CCA2CCDC4BCCCFCCC2CCDC5CCCFBCCF2CC9FCC9CCCB9CC9FCCA7315741CCFF73CC99CCFF41CCE8CC95CCE6CCD6CCB7001DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF21D4C5ACC954338CCE1CCC56206CCC45705CCE503CCDD28CCEE64CCF633CCA6CCF677CCFACCF8CCB5CC8A45CC9F0E82A47A6574619182A474797065A6427566666572A464617461DC0020CCEFCC81CCD54E2E33CC860C37CCE8CCA5CC96CCFF1ACC802ACCEACCBDCCD6275770CC841F36CCA6CCD5CCCCCCA13CCCC71AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF63A5E6C3ECCF63DCCED4ACC8F75CCDF2ECCBF5ECC95CCC8CCA4CC992926CC996DCCE9CCAD60CCD30122CCE2201782A47A6574619182A474797065A6427566666572A464617461DC00201ECCAA57CCA3CC9BCCDDCCBFCCFCCCD13074CCF7CCFACCD84DCCB434CCC4CCDA5FCCF866CCE6CCD5CCC6CCCD70CCC653CCDDCC882EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020332374CCBA79025BCC9916CCD7CCD90CCCDC5CCCE0CCA8CCE368CC9F590136CCCB15CCC868CC8BCCA809CC84CCF30082A47A6574619182A474797065A6427566666572A464617461DC002018CC88415E4CCC9E64720DCCF873CCAC561748CCEA26CCF9CC8B153D61CCF34BCCCDCCA62710CCC9500C1BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA1CC80CC81CCEC3CCCC6CCF9CC9A5E1ECCC7CCF9CCA2CCF2217743437DCC8BCCF7CCDFCCC3CCC51ECCDECC96CCA0CC8438091182A47A6574619182A474797065A6427566666572A464617461DC0020CCCC40CC942544CCB12E2F46CCF4CCA1CC8ACCC2596C113363CCDF2FCCAF41CCFECCD5CCE5CCFDCCFD7C33107E26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002011CCAF34CCA9470870CCE7CCF411CCC2CC8741CCDD52CCAB55CCC1CCCECC876ACC870305622F7ACCCBCC8761CCB00982A47A6574619182A474797065A6427566666572A464617461DC0020CCEC6741CCFECCA4CCF6CCF91FCCE6CCDCCC9E5E746B2857CCFFCC962B4ACCCECCE7CCE9CCD429CCB4CCD2CC8D1FCC8DCCFC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC81CCA9CCE6CCC546CCA8555ECCF82607CCCECC9563CCDC31CCA3CCD8CCDA2BCCA4CCBE18616426697D696ECC831DAC636F656666696369656E74739F82A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B067656E657269635F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B1706F736569646F6E5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B5636F6D706C6574655F6164645F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AC6D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AD656D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B7656E646F6D756C5F7363616C61725F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B572616E67655F636865636B305F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCA8CC92CCB340CCC520573BCCF5CCC60BCCABCCBDCCE7CC8F15CCE2CCEDCCEE31CC9B484D5FCCD62CCCC2CCC3391ACCFF2EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC9D37CCAE26CC8702CCBB67CCFFCCBACC841DCCEB383113CCFBCCB3CCE6CC8FCCF0CCBFCCEFCCDB1B6F622645CC830F27B572616E67655F636865636B315F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCF2CC90CCC8CCA4CC8DCC92CCE7CCDFCCA93938044316CCBE6D37CCC9023A2A54CCD9043B0ECCBECCF912350703AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC941CCCCA71CCDA09CC8DCCD162CCF4CCBACCA814CCEE5BCC9ACCF9216D7CCC990E0ACCFECCB7CCB37B397CCC85CCBA15BA666F726569676E5F6669656C645F6164645F73656C6563746F72C0BA666F726569676E5F6669656C645F6D756C5F73656C6563746F72C0AC786F725F73656C6563746F72C0AC726F745F73656C6563746F72C0B26C6F6F6B75705F6167677265676174696F6E82A47A6574619182A474797065A6427566666572A464617461DC0020CCBB1ACCD376CCEECCF0CCA750CC8B711ACC97CC8160CCE1CCC5CCFCCCF0CCE0412861CCEF5128CCF4CC99CCCE39CCC4CCF80DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002032CC903FCCD27BCC9ECC9CCCAFCCBC39CCC1CCC3CC9BCCA36D0570CCA114CCAE2CCC9F1203CCBD60CCA31D7ACCBB0514AC6C6F6F6B75705F7461626C6582A47A6574619182A474797065A6427566666572A464617461DC00203D663E7E6610CCB1CC844863CC803466590A2A1CCCA451CCC755393BCCD3CCC762CC822B44CCA8CCB02BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC8ACC985A1D271113CCCACCE0CCA7CCEACCB5CC86CC845CCCB8CCCD2E27CCDF38CCD30E76CCC81832CC94CC8ECCF4CCAB1FAD6C6F6F6B75705F736F727465649582A47A6574619182A474797065A6427566666572A464617461DC002003CCF1CC8FCC8CCC843B1ACCC26DCCDE6ECCE46E64CCC9CCE971CCDECCC4CC84CCFE2FCCBACCFBCC8737CCACCC8756CC945F23AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA3326726CCABCCD7CC904C23CC927068CC920F59CCB7CCEA17CCCFCC8878CC91CCC13ACCE36C3F4725CC8B222882A47A6574619182A474797065A6427566666572A464617461DC0020CCF52ECCB7683352CCA3CCF176CCEECCD461CCCC0C3ACCD905CC80CCAF4E25CCBE29CCA8CC99CCD87ECC8ACCC20FCCB90DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00207BCCD5CCC6CC9228CCE1CCBA3E037ACC854FCC9A6BCCCC492CCCA7CCA7CCF5CCEF3FCC862278CCC732CCDD45CCFCCCD02782A47A6574619182A474797065A6427566666572A464617461DC0020CC9741CCC7CCC0CCFC6F6A6768377ECCD94ACCB1CCC92FCCE66129CCE7CCC8CC8436CCB3CCBE2DCC8BCCF418CCB20415AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205772CCCF1B0A32CCFDCCE247CCC3CCDD6CCC8126CC83CCFCCCBE5F31CCA53521CC85CCBA72CCBDCC85344265701282A47A6574619182A474797065A6427566666572A464617461DC0020CCB4CCA0CCEA22046DCC87CCB2427F4954CC82CC84CCADCCD10BCCB7CCD7CC990044CCF4CCDFCCD95FCCD5CCD27167CCBE18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF569CC93331A635C4465CCE85C6CCC8121CCBBCC93CCD7CC8DCCE6CCFACCE4CCE817CCD95270384D500ECCCB1582A47A6574619182A474797065A6427566666572A464617461DC0020CCB7CCCB1F526A127353CCDBCC97CCB7CCCB32CC82CCB26FCCE9CCBACCC4CCB8CCE915CC9F65CCBBCCDD42412A0F771DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002005CCABCCEE75CCBA63CC9C0824CCCCCCFD6ACCC6CCE1CCC4CCF2CCACCCA9CCACCCA2CCD90716CCD746CCA3CCCD00002D4C26B472756E74696D655F6C6F6F6B75705F7461626C65C0BD72756E74696D655F6C6F6F6B75705F7461626C655F73656C6563746F72C0B3786F725F6C6F6F6B75705F73656C6563746F72C0BB6C6F6F6B75705F676174655F6C6F6F6B75705F73656C6563746F72C0BB72616E67655F636865636B5F6C6F6F6B75705F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCBD2ECCC43CCCBD197CCCC3112429CCCC1FCC83CCC26DCCBBCCB77DCC87CCDD691844CCA257CCB678CCEDCC9FCCEC1FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCE5404D5BCCA94DCCD57A78CCBE50CCFA5417CCF3CCCE46CCD5CCC4CCFDCCDCCC8226CCE5CC906A7861CCEF6C0FD921666F726569676E5F6669656C645F6D756C5F6C6F6F6B75705F73656C6563746F72C0A866745F6576616C3182A474797065A6427566666572A464617461DC00202E74CCF4CCB84B766ECCB00ACCC6CCFD70306ECCA8CCA2CC870ACCD8780864005B306ECC8DCC957CCCD04916AF707265765F6368616C6C656E67657390"; MsgPk.deser_prover_proof( MsgPk.new_stream(prover_proof_serialized), prover_proof ); - assertEq(Scalar.FE.unwrap(prover_proof.evals.public_evals.zeta[0]), 0); + assertEq( + Scalar.FE.unwrap(prover_proof.evals.public_evals.zeta[0]), + 256 + ); assertEq( Scalar.FE.unwrap(prover_proof.evals.z.zeta[0]), - 1511422324807084075612225175004431441562364525077650304716743095141219510784 + 1185616399363588256963486679032130114413868343618131345040286155216030688553 ); } } From 9839350773a51ff00fd635244abbace5bec27ecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 11 Dec 2023 16:46:22 -0300 Subject: [PATCH 34/68] Integrated verifier with deserializer --- eth_verifier/src/Verifier.sol | 49 ++++++++++++++++++----------- eth_verifier/test/Deserialize.t.sol | 2 +- eth_verifier/test/Integration.t.sol | 25 ++++++++------- eth_verifier/test/State.t.sol | 9 +----- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 550c5684..5bcfe4c0 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -65,36 +65,47 @@ contract KimchiVerifier { bool state_available; function setup( - BN254.G1Point[] memory g, - BN254.G1Point memory h, - uint256 public_len, - uint64 domain_size, - uint256 max_poly_size, - ProofEvaluationsArray memory evals + bytes memory urs_serialized ) public { - for (uint i = 0; i < g.length; i++) { - verifier_index.urs.g.push(g[i]); - } + (BN254.G1Point[] memory g, BN254.G1Point memory h, uint256 _i0) = MsgPk + .deserializeURS(urs_serialized); + verifier_index.urs.g = g; verifier_index.urs.h = h; - calculate_lagrange_bases( - g, - h, - domain_size, - verifier_index.urs.lagrange_bases_unshifted - ); - verifier_index.public_len = public_len; - verifier_index.domain_size = domain_size; - verifier_index.max_poly_size = max_poly_size; + verifier_index.powers_of_alpha.register(ArgumentType.GateZero, 21); verifier_index.powers_of_alpha.register(ArgumentType.Permutation, 3); // TODO: Investigate about linearization and write a proper function for this verifier_index.powers_of_alpha.register(ArgumentType.GateZero, Constants.VARBASEMUL_CONSTRAINTS); verifier_index.powers_of_alpha.register(ArgumentType.Permutation, Constants.PERMUTATION_CONSTRAINTS); + } + + function verify_with_index( + bytes calldata verifier_index_serialized, + bytes calldata prover_proof_serialized + ) public returns (bool) { + MsgPk.deser_verifier_index( + MsgPk.new_stream(verifier_index_serialized), + verifier_index + ); + MsgPk.deser_prover_proof( + MsgPk.new_stream(prover_proof_serialized), + proof + ); + + calculate_lagrange_bases( + verifier_index.urs.g, + verifier_index.urs.h, + verifier_index.domain_size, + verifier_index.urs.lagrange_bases_unshifted + ); - proof.evals = evals; + partial_verify(new Scalar.FE[](0)); + return false; } + /// @notice this is currently deprecated but remains as to not break + /// @notice the demo. function verify_state( bytes calldata state_serialized, bytes calldata proof_serialized diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index 878ea2d3..d064b612 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -204,7 +204,7 @@ contract DeserializeTest is Test { } function test_deserialize_prover_proof() public { - // This serialized index was manually modified to make `public_evals` + // The serialized proof was manually modified to make `public_evals` // equal to 256. bytes memory prover_proof_serialized = hex"85AB636F6D6D69746D656E747384A6775F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCD843CC8C68CCADCCC65F0FCCE95332CCD3566E1C7BCCA626764ECCFF30CCEE14CC9560790764CCE7CCC4CC9CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE7CCFBCCD1CC92CCBF523131CCDD2FCCB807CCF8CCF7CCCFCCADCCE7CCDF6256CCE8CC9ECC91CCF0CC9C0CCCB11050050FCC85A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC3CCE17360CCCC5FCCA1CCAD260C0ECCDFCC98CCCBCC8ECCD2367F0B2553654257CCA5CC82CC96CC9361CCF379CC89A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020465CCCB06ACC97CCCC1FCCBA62156DCCEA4A0ACCCF78CC98CCAECCBECCDFCCE1CCD212537BCCCF5970CC8C3A3E30A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCAACCAECCD8302DCC9FCCF808CCA76DCCB646CCA345CCA70BCCFFCCBA5865357522CCF6CCEF443634CC81CCA7CC8A0CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002010CCDC62CCE86ACCA0CCFBCCCCCCA934CC8ACCB97ACCE3552B5E7442112820503713CCCD7E30CCC4CC8936CC92A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00207833045124CC8BCCFA087CCCC77969CC8B17CCDECCD5CCEACCD3CCB8CCC147CC907DCCFF0042CCB9CCADCCE444CCF1CC80A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201A49CCD234CCEE0ACC985DCCD452CCB8CCC365CCBA5F7FCCE57874CCE5CCB8CCAE7C24CCA7CCFFCCDF7F06CCCECCBF16A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00203BCCF60A24CCEF2F1B14CCE9CCF71BCCC23ECCEA0C5ACC9C0DCC9E377232CCD501CCBACCCFCCD9CCF9CCF3CCDACCCF00A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201ECCA4CCCFCCEF710FCCE8CC9B32CC81CC84323C601ACCB1516005CCFFCCEB2FCC90CCBE654CCCFD5D486FCC862FA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7DCCDC5F6ACC8132CCC008CCF9CCE3CCCACC94CC8ACCA83D7ECCC5CC835ECC97CC8ACC95CC9CCCE3CCCA0B58CCDF4FCCE314A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020351B53CCB8CCA6CCDB78CCA61D4865276D69CCDD49361E620A32611E1ECC80CCFE51CC94CCB74C2410A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC830DCC89CCADCCBCCCC9CCD3CC82CCE60114CCCBCCBFCCD5CC8D40723DCCE6CC8354CC9509CCB731CCCACC9ECCD7CCB7CCDECCD7CCABA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC2CCF328CCED33CCDC6264CCEDCCEC4633CCCCCCA8CCBBCCDACCC24345CC99CCA565CCC23ACCB144CCAACCC459CC924809A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00204DCCBE7C3A5F1E2B7ECC867965CCCBCCD65A7D771ACC81CCEECCF724CCE2010DCCF1CCF63CCCFC4C56CCB5CC9FA773686966746564C0A67A5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCCB4CC8052CC9A247A2B51425B50705BCCEACCD7CC85CC8664CCBCCC84CCB1CCD318CCB96BCCEA55CC9049CCEBCCA7A773686966746564C0A6745F636F6D6D82A9756E736869667465649782A474797065A6427566666572A464617461DC00203ACCF406CCEBCCEBCCE72979CCF063CCB06BCCA8CCF74A34CCA22B5D4B5E30CCF8CCFD3F7BCC9F11CCC254101582A474797065A6427566666572A464617461DC002071CCF6CC9CCCADCCA4565520CCE9CCA5CCF4CCEBCCA0CCDB1B1E3D760224025A4DCC806BCC9DCCA7CC8CCCA951CCEC0C82A474797065A6427566666572A464617461DC002056CCC151CC80CCF762CCAFCCA4CCD9CCC968CCA6CCAA64CCD60CCCF1CCC4CC9FCCDB6A2D6863CCFFCCAB48796F37CC8D2682A474797065A6427566666572A464617461DC0020CCAECCF3665BCCDFCC97CCBE7CCCE6CCF8CCB70F62CCAE197764CC9ACCB80ACCA416CCE3CCB00E78CCAD265613CCA50B82A474797065A6427566666572A464617461DC0020CCF81C0359CC95CCFCCCA479CCB2CC9DCCEDCC9626CCCECCB6CCEDCCAE642A3DCCF37ECCF56B665BCCD950CCD32C780882A474797065A6427566666572A464617461DC0020CCF6CCF06B74CCA433591E30CCE6CCE1CC93CC8ACC9C56042F3867714FCCC72E7ACC891ECCBB71603DCCE4CCAF82A474797065A6427566666572A464617461DC0020CCCFCCCFCCB3560BCC83CC95CCCC33CCEACC9E6DCC921BCCB4CCCACCA864CCECCCC33776734D657CCCD52BCCAC204BCC94A773686966746564C0A66C6F6F6B757083A6736F727465649582A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE9CCF5195B6ACCD6CC96CCA1325F2D6C79CCFF6CCCD9CC9ACCFE77CC932BCCE3CC994073CCF2CCFBCCC779CCE56C27A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC975DCCC0CCDD6BCCC7CC9ECC8CCCDA681A17CCDA2CCC9F7BCC916F483D41CCA00A68CCB718CCC722CCBE422E18A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002021CCC1CC8C4370687F69CCA0CCAA533BCCCA0C5BCCE847CCBA78CC83CC8BCCA103CCC67668CCDCCC812405CCA0CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002019CCD34CCCF25BCCE82955CC974A26663E0F70CCA6596FCCACCC9B7CCCAECC83CCA6556F410771CC92CCF611A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002045CCF9105CCC8FCCA1CC9E2638607BCC8A2B0266CCEDCCFACC9361CC80CCC1CCE1CC8A3C5B08CCCC5FCC8921CCC2CCA7A773686966746564C0A661676772656782A9756E736869667465649182A474797065A6427566666572A464617461DC00201DCCC905CCCBCCFC7F19CCB5CCCCCCECCCB4CC965DCCA5CC87573F535C6A15CCBD0FCCC0CCA81D07023818CCA21FA773686966746564C0A772756E74696D65C0A570726F6F6682A871756F7469656E7482A474797065A6427566666572A464617461DC0020CCDD7E3BCC86CC99622CCCFD7F08221DCCD8191504CCAB386202CCC50A6ACCB1CC8ECCF663CCBECC9F0A53CC99A8626C696E64696E6782A474797065A6427566666572A464617461DC00207B6778CCBECCFD13CCB616CCEDCCDBCCAA7B1FCCD214CCC4CCD3CC9A4DCCC0306ACCC3CCF3CCD1CCAFCCF64D6858CCB61DA56576616C73DE001AA67075626C696382A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000100AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000A1779F82A47A6574619182A474797065A6427566666572A464617461DC0020CC91CCABCC853859CCDB5FCC8FCCC276CCAACCC5183119CC84CC863231CCB456CCB608CC9336CCC3CCC0CCC0CCEACCAB2D2CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD7CCB3CCC07450CCC178CCBB5B14CCE3CCB5CCB22C70CCEBCC8E770ACCE329284A08CC84CCA5CCDF6BCCC1752E0882A47A6574619182A474797065A6427566666572A464617461DC0020134ECCAECCD96164CCA0CCD8CCBF0B71CC9C5C78CCE3CC8E21CC81CCDF10CCBD02462ECCA8CC9D03CCCECCF06D6F15AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD256CCA01BCCABCCF549CCC62908CCFDCCE5CCF537CCC24BCCF645CCCC2948CCEC3ACCD9CC9ACCAECCC2CCE30ACCCD301D82A47A6574619182A474797065A6427566666572A464617461DC0020CCC2CCEBCC96142945380379CCEFCC95130D6914CC925FCCF623CCA4CCB21BCCE00FCCCA00CCA5CCA44113CCC206AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00203ECCD2CCD9CCADCCB110CCA05F6B0DCCF5CCD435373FCC896DCCC16ECCA81E29CC982A5D422835CCAC4B090C82A47A6574619182A474797065A6427566666572A464617461DC0020162ECCAECCE714CCE053CC94CCFECCB612CCA31371CC8D3856CCD9CCE603CCECCCB2CCE9CCEB39CCDBCC86CCB445251216AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCBACCF04E4E7ACCE2CCCECCBBCCB2CCC2CC8ACCB7CCF06A71CC9F685ACCF1CCC9CCA454CCDC0549CCFFCCD545CC8B4A1A1682A47A6574619182A474797065A6427566666572A464617461DC00200F4B02CCDA68CCDFCCE9CCA8366FCCAACCD70ECCCE3ACCA84BCCC3CC80CCC149CCB077CCA20BCC9DCCBF5FCCEC7ECCBC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002066CCA178CCA84845CCE35ECCEA08CCD4CCB1CCEBCCD5CCF6221C0F74CCDCCCCBCCCDCCDFCCDD62CCEECCEC4D6DCCD4CCC40982A47A6574619182A474797065A6427566666572A464617461DC00206ECCE833CCF62BCCF044CCE1CCA3CC9B25604DCC982CCCA1CCFC6ECC9A61CCA4CCE973CCEF0A71CCBFCCD90617CC9422AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205848CCFC1BCCFC647567CCCFCCF76ACCC176CCFACC92560B6C3E3D6FCC90CCF6CC9FCC9ACC88CC811160CC91CCC20682A47A6574619182A474797065A6427566666572A464617461DC0020CC864757CCB36C11CC86182C11CC832E08CC86466ECC8A49187BCC8BCCEFCC90CCC87171CCA62040CC9ACCC22FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD0CCAECCFFCC91CCA0CC9FCC9625CC9522CCD5204E2BCCC0CC91507408CCFACCCB5B202C57CCF23A46CCE37D7D2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCE95ACC9E46CCFCCCBA232C37CCC335CCF9CCF9303CCCFFCCC85669CCEFCCB107CC99CCFACCF7CC924F2827CCAE0102AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002009CCB537CC9D6607CCFECCFDCCE14801CCF6CCB3CCA2CCB6CCE2CCDFCCE5CCC83027334FCCAE22221BCCCF1A0F1C0082A47A6574619182A474797065A6427566666572A464617461DC0020CCC6CCCD1ACCBF41233DCCA617CC9C4406CCD861CC91CCF60E4412CCAB4FCCB1CC9F447BCCB3CCABCC9E7836CC960CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002037CC80CCAECCBD56CCB5CCBC50CCC3CC9746CC995BCCB628CCB674CCACCCF7CCC55D653142CC9FCCCA71CCC9CCE3CCEACC8C0A82A47A6574619182A474797065A6427566666572A464617461DC0020CCB1CC8348CCDACCD87DCCD0CCDC29CC826D03672D64CCAE4963CCE37ECCB205114ACCDECCB5CC9F1E1B72CCAC03AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF5793436CC87574F2ACCAA5020CCA91E1CCC8451CC81015ECC8E35267C063CCC86CCB87CCCA002CCFF2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCD33CCCAECCD038CCD63324CC9B1DCC9ACC9FCC8040CC9A39CCF7CCEACCCCCCE17ECCE5CCADCCEE18CCB0CC8509497ECC882DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD32B42CCF447CCDD023CCCD4CCB76D50CC9DCCD2CC8054CCF456CCC709CCA017CCC104CC9A65CCA37439CC96CCA61782A47A6574619182A474797065A6427566666572A464617461DC00200A5D16CC8FCCC1CCF516CC8843CCDBCCFD74CCD8102B5928CCA244CCDC29CCE8CCC4714DCC935628CCB52ECC8D18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCEA45CCBE2C29CCDFCC805ECCE5CCABCCB3CCAB05CCEDCCE125CCB2CCFDCC8ECCAD6549CCF1CCA57DCCE9CCD647CCE6CCA7650E82A47A6574619182A474797065A6427566666572A464617461DC00204854CCAE40CCFCCC8F3BCC935E2477CCCCCCC90D0C115D72CCAD63CCA537CC9873CC8770CCEFCCBA12CCFDCCB01BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCDC2DCCD655CCAC0B6311CC9944CC8E39CCDECC81CCBBCCB1CCE45C32CCA4CCBD5A1D4314CCFFCC9010CCF24B2B82A47A6574619182A474797065A6427566666572A464617461DC00201135CCDBCCDC6F7FCCDC26CC845449CCC771CC881029CCC1CC80CCD5CCAE61CC866DCCCF6CCCF81C1C73CC871A2FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002048CCCBCC81CC906F47CC98CC8F3E3C04CCD4CC9874CCA50A3E3D31CCE6CCCCCC8772CC8ECCBC07CCDA05CCCE273A3082A47A6574619182A474797065A6427566666572A464617461DC00207DCCCCCCCECCBACC9D4373CCAF6F1D07CCD00FCCD42344CCD5CCB3CCE0CCF36A7937CC8DCCFB350BCC8E7F73CC9D26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00206C2D746FCCD1CCF94654CCB7CCC4CCC7CCE36051CCB019CCCBCCE870CCE5CCD43ACCED10CC93CCFFCCEB4C67CCA05D30A17A82A47A6574619182A474797065A6427566666572A464617461DC00203303576F49CCD5CCA8CCD0CCE87BCC9703CCFCCCEACC9FCC9102CCCC69CC8ACCE4CCEF6945CCA5CCDF1F2B7262652AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCE747CCA774CC98CCA2CCA610CC9FCCEDCCEC22CCEC150E732818CCFF3727CCD4CCDA31CCE1CCB5587160CCAACCC603A1739682A47A6574619182A474797065A6427566666572A464617461DC002051CCF4CCA0CCA2CCDC4BCCCFCCC2CCDC5CCCFBCCF2CC9FCC9CCCB9CC9FCCA7315741CCFF73CC99CCFF41CCE8CC95CCE6CCD6CCB7001DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF21D4C5ACC954338CCE1CCC56206CCC45705CCE503CCDD28CCEE64CCF633CCA6CCF677CCFACCF8CCB5CC8A45CC9F0E82A47A6574619182A474797065A6427566666572A464617461DC0020CCEFCC81CCD54E2E33CC860C37CCE8CCA5CC96CCFF1ACC802ACCEACCBDCCD6275770CC841F36CCA6CCD5CCCCCCA13CCCC71AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF63A5E6C3ECCF63DCCED4ACC8F75CCDF2ECCBF5ECC95CCC8CCA4CC992926CC996DCCE9CCAD60CCD30122CCE2201782A47A6574619182A474797065A6427566666572A464617461DC00201ECCAA57CCA3CC9BCCDDCCBFCCFCCCD13074CCF7CCFACCD84DCCB434CCC4CCDA5FCCF866CCE6CCD5CCC6CCCD70CCC653CCDDCC882EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020332374CCBA79025BCC9916CCD7CCD90CCCDC5CCCE0CCA8CCE368CC9F590136CCCB15CCC868CC8BCCA809CC84CCF30082A47A6574619182A474797065A6427566666572A464617461DC002018CC88415E4CCC9E64720DCCF873CCAC561748CCEA26CCF9CC8B153D61CCF34BCCCDCCA62710CCC9500C1BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA1CC80CC81CCEC3CCCC6CCF9CC9A5E1ECCC7CCF9CCA2CCF2217743437DCC8BCCF7CCDFCCC3CCC51ECCDECC96CCA0CC8438091182A47A6574619182A474797065A6427566666572A464617461DC0020CCCC40CC942544CCB12E2F46CCF4CCA1CC8ACCC2596C113363CCDF2FCCAF41CCFECCD5CCE5CCFDCCFD7C33107E26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002011CCAF34CCA9470870CCE7CCF411CCC2CC8741CCDD52CCAB55CCC1CCCECC876ACC870305622F7ACCCBCC8761CCB00982A47A6574619182A474797065A6427566666572A464617461DC0020CCEC6741CCFECCA4CCF6CCF91FCCE6CCDCCC9E5E746B2857CCFFCC962B4ACCCECCE7CCE9CCD429CCB4CCD2CC8D1FCC8DCCFC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC81CCA9CCE6CCC546CCA8555ECCF82607CCCECC9563CCDC31CCA3CCD8CCDA2BCCA4CCBE18616426697D696ECC831DAC636F656666696369656E74739F82A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B067656E657269635F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B1706F736569646F6E5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B5636F6D706C6574655F6164645F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AC6D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AD656D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B7656E646F6D756C5F7363616C61725F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B572616E67655F636865636B305F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCA8CC92CCB340CCC520573BCCF5CCC60BCCABCCBDCCE7CC8F15CCE2CCEDCCEE31CC9B484D5FCCD62CCCC2CCC3391ACCFF2EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC9D37CCAE26CC8702CCBB67CCFFCCBACC841DCCEB383113CCFBCCB3CCE6CC8FCCF0CCBFCCEFCCDB1B6F622645CC830F27B572616E67655F636865636B315F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCF2CC90CCC8CCA4CC8DCC92CCE7CCDFCCA93938044316CCBE6D37CCC9023A2A54CCD9043B0ECCBECCF912350703AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC941CCCCA71CCDA09CC8DCCD162CCF4CCBACCA814CCEE5BCC9ACCF9216D7CCC990E0ACCFECCB7CCB37B397CCC85CCBA15BA666F726569676E5F6669656C645F6164645F73656C6563746F72C0BA666F726569676E5F6669656C645F6D756C5F73656C6563746F72C0AC786F725F73656C6563746F72C0AC726F745F73656C6563746F72C0B26C6F6F6B75705F6167677265676174696F6E82A47A6574619182A474797065A6427566666572A464617461DC0020CCBB1ACCD376CCEECCF0CCA750CC8B711ACC97CC8160CCE1CCC5CCFCCCF0CCE0412861CCEF5128CCF4CC99CCCE39CCC4CCF80DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002032CC903FCCD27BCC9ECC9CCCAFCCBC39CCC1CCC3CC9BCCA36D0570CCA114CCAE2CCC9F1203CCBD60CCA31D7ACCBB0514AC6C6F6F6B75705F7461626C6582A47A6574619182A474797065A6427566666572A464617461DC00203D663E7E6610CCB1CC844863CC803466590A2A1CCCA451CCC755393BCCD3CCC762CC822B44CCA8CCB02BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC8ACC985A1D271113CCCACCE0CCA7CCEACCB5CC86CC845CCCB8CCCD2E27CCDF38CCD30E76CCC81832CC94CC8ECCF4CCAB1FAD6C6F6F6B75705F736F727465649582A47A6574619182A474797065A6427566666572A464617461DC002003CCF1CC8FCC8CCC843B1ACCC26DCCDE6ECCE46E64CCC9CCE971CCDECCC4CC84CCFE2FCCBACCFBCC8737CCACCC8756CC945F23AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA3326726CCABCCD7CC904C23CC927068CC920F59CCB7CCEA17CCCFCC8878CC91CCC13ACCE36C3F4725CC8B222882A47A6574619182A474797065A6427566666572A464617461DC0020CCF52ECCB7683352CCA3CCF176CCEECCD461CCCC0C3ACCD905CC80CCAF4E25CCBE29CCA8CC99CCD87ECC8ACCC20FCCB90DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00207BCCD5CCC6CC9228CCE1CCBA3E037ACC854FCC9A6BCCCC492CCCA7CCA7CCF5CCEF3FCC862278CCC732CCDD45CCFCCCD02782A47A6574619182A474797065A6427566666572A464617461DC0020CC9741CCC7CCC0CCFC6F6A6768377ECCD94ACCB1CCC92FCCE66129CCE7CCC8CC8436CCB3CCBE2DCC8BCCF418CCB20415AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205772CCCF1B0A32CCFDCCE247CCC3CCDD6CCC8126CC83CCFCCCBE5F31CCA53521CC85CCBA72CCBDCC85344265701282A47A6574619182A474797065A6427566666572A464617461DC0020CCB4CCA0CCEA22046DCC87CCB2427F4954CC82CC84CCADCCD10BCCB7CCD7CC990044CCF4CCDFCCD95FCCD5CCD27167CCBE18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF569CC93331A635C4465CCE85C6CCC8121CCBBCC93CCD7CC8DCCE6CCFACCE4CCE817CCD95270384D500ECCCB1582A47A6574619182A474797065A6427566666572A464617461DC0020CCB7CCCB1F526A127353CCDBCC97CCB7CCCB32CC82CCB26FCCE9CCBACCC4CCB8CCE915CC9F65CCBBCCDD42412A0F771DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002005CCABCCEE75CCBA63CC9C0824CCCCCCFD6ACCC6CCE1CCC4CCF2CCACCCA9CCACCCA2CCD90716CCD746CCA3CCCD00002D4C26B472756E74696D655F6C6F6F6B75705F7461626C65C0BD72756E74696D655F6C6F6F6B75705F7461626C655F73656C6563746F72C0B3786F725F6C6F6F6B75705F73656C6563746F72C0BB6C6F6F6B75705F676174655F6C6F6F6B75705F73656C6563746F72C0BB72616E67655F636865636B5F6C6F6F6B75705F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCBD2ECCC43CCCBD197CCCC3112429CCCC1FCC83CCC26DCCBBCCB77DCC87CCDD691844CCA257CCB678CCEDCC9FCCEC1FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCE5404D5BCCA94DCCD57A78CCBE50CCFA5417CCF3CCCE46CCD5CCC4CCFDCCDCCC8226CCE5CC906A7861CCEF6C0FD921666F726569676E5F6669656C645F6D756C5F6C6F6F6B75705F73656C6563746F72C0A866745F6576616C3182A474797065A6427566666572A464617461DC00202E74CCF4CCB84B766ECCB00ACCC6CCFD70306ECCA8CCA2CC870ACCD8780864005B306ECC8DCC957CCCD04916AF707265765F6368616C6C656E67657390"; diff --git a/eth_verifier/test/Integration.t.sol b/eth_verifier/test/Integration.t.sol index d1bcafac..5d20608a 100644 --- a/eth_verifier/test/Integration.t.sol +++ b/eth_verifier/test/Integration.t.sol @@ -10,20 +10,21 @@ import "../lib/Commitment.sol"; import "../lib/Alphas.sol"; contract Integration is Test { - function test_partial_verify() public { - // Data was taken from running the circuit_gen crate. - bytes - memory urs_serialized = hex"92dc0020c4200100000000000000000000000000000000000000000000000000000000000000c42055a8e8d2b2221c2e7641eb8f5b656e352c9e7b5aca91da8ca92fe127e7fb2c21c42003bc09f3825fafdefe1cb25b4a296b60f2129a1c3a90826c3dc2021be421aa8ec4206422698aa4f80a088fd4e0d3a3cd517c2cb1f280cb95c9313823b8f8060f1786c4203558cb03f0cf841ed3a8145a7a8084e182731a9628779ef59d3bc47bae8a1192c4202ac41dd231cb8e97ffc3281b20e6799c0ae18afc13d3de1b4b363a0cd070baa7c420b6205dfa129f52601adfd87829901f06f1fd32e22a71f44b769d674448f05d83c4205d1b9b83cdcba66ff9424c7242c67394d7956dabf5407f4105124b7239d43e80c420e95ffc0999a8997b045430aa564c7bd9a25303e8a5ebbe4a99f6329b7f2a64aac4206cca50f1237f867fee63ac65249d6911494680f42d0e71386b1586be39092f9cc4204b9b17d64b384a65d7c80c8ab0f5fff75c69fd147835599753beea03152a3923c4205c0f706b036ed361e787af70acea3533d6e349869e83368979fdbbf382a4900bc420da6652a81754a6263e677d23a55bd729205f5fb64fa39b6771d9b811e5548bafc4208db1ad69d758362a4ecacff98a6910a95b3c2697e455271b2d7c078f1894eb1fc42010f56f1046a1121b1df5c401969b5acbf80eef8bfd5438270e09243413382788c4200cca37d1a3a721792dc232bb6a95bd14143350b6784bcdd4898a0bb34dd8bd2cc4202b7a1991e05b77d911d15ae590ff6f6ad7d1ed572b34654e3ce92e38e4839425c4201977ca4631e9eea53c7ba59d334c14dac7ee1071d6bf6ebf2ab7450c16975d23c4209eb742379ee8664a8bf9c18a40a534bb2961020bd0077cd0b603d2a8b9fe5a17c4201c50af6002db8dfa5a310ce795dcb06de94ead6687687263fd59acbc8612f180c4205241cbed55fbe1193f366e7ea8ad11bc97742eb35ca39129c4931b9bef64df1ec420646e69eb7d4682ad6bff24d40bf22184694c569246385cc127b3ec4a99875a85c42046b77ed1e120130743344ea9372ea58118604c730800e0d7038f2c80211f4f90c4208f20f3c39a09b5615bd8b2a09eec7dbc11b5ea1f8fe7eb0d5a69c1264412d199c42095f0b87ed771c169a8b6c0a6e21b13ab715407a4e6637a0b8fe0a1e3278f32a7c420a80440e1a07157bad23d7a7d3ddd7445f578021650016fc4bfb3324ed967c82bc4202b94fd0b89e7e2c9d245a4e94a539b14c5db26ed5ba4b3989ef0ba0712d4582ec42068f583079aa73425184a328127be63421eae683a25be94a0aa697ce74b5b972dc4209fa10b770e452852612ea392b8521683999d0a168c5eb85a6925d1ffe21d418ac420826a0976821c9309ed896678a97634a2fb1392a64ab8c59c8380012ffb601189c4203096ba3ed0b597fa29da6caa9000a409702b1f945561e82d02ab77b0cfdb649fc4204a718bc27174d557e036bcbcb9874ce5a6e1a63ccbe491e509d4201bfcb50806c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c250a"; - bytes - memory evals_serialized = hex"9291c420000000000000000000000000000000000000000000000000000000000000000091c42000000000000000000000000000000000000000000000000000000000000000000a"; + bytes prover_proof_serialized = + hex"85AB636F6D6D69746D656E747384A6775F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCD843CC8C68CCADCCC65F0FCCE95332CCD3566E1C7BCCA626764ECCFF30CCEE14CC9560790764CCE7CCC4CC9CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE7CCFBCCD1CC92CCBF523131CCDD2FCCB807CCF8CCF7CCCFCCADCCE7CCDF6256CCE8CC9ECC91CCF0CC9C0CCCB11050050FCC85A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC3CCE17360CCCC5FCCA1CCAD260C0ECCDFCC98CCCBCC8ECCD2367F0B2553654257CCA5CC82CC96CC9361CCF379CC89A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020465CCCB06ACC97CCCC1FCCBA62156DCCEA4A0ACCCF78CC98CCAECCBECCDFCCE1CCD212537BCCCF5970CC8C3A3E30A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCAACCAECCD8302DCC9FCCF808CCA76DCCB646CCA345CCA70BCCFFCCBA5865357522CCF6CCEF443634CC81CCA7CC8A0CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002010CCDC62CCE86ACCA0CCFBCCCCCCA934CC8ACCB97ACCE3552B5E7442112820503713CCCD7E30CCC4CC8936CC92A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00207833045124CC8BCCFA087CCCC77969CC8B17CCDECCD5CCEACCD3CCB8CCC147CC907DCCFF0042CCB9CCADCCE444CCF1CC80A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201A49CCD234CCEE0ACC985DCCD452CCB8CCC365CCBA5F7FCCE57874CCE5CCB8CCAE7C24CCA7CCFFCCDF7F06CCCECCBF16A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00203BCCF60A24CCEF2F1B14CCE9CCF71BCCC23ECCEA0C5ACC9C0DCC9E377232CCD501CCBACCCFCCD9CCF9CCF3CCDACCCF00A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201ECCA4CCCFCCEF710FCCE8CC9B32CC81CC84323C601ACCB1516005CCFFCCEB2FCC90CCBE654CCCFD5D486FCC862FA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7DCCDC5F6ACC8132CCC008CCF9CCE3CCCACC94CC8ACCA83D7ECCC5CC835ECC97CC8ACC95CC9CCCE3CCCA0B58CCDF4FCCE314A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020351B53CCB8CCA6CCDB78CCA61D4865276D69CCDD49361E620A32611E1ECC80CCFE51CC94CCB74C2410A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC830DCC89CCADCCBCCCC9CCD3CC82CCE60114CCCBCCBFCCD5CC8D40723DCCE6CC8354CC9509CCB731CCCACC9ECCD7CCB7CCDECCD7CCABA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC2CCF328CCED33CCDC6264CCEDCCEC4633CCCCCCA8CCBBCCDACCC24345CC99CCA565CCC23ACCB144CCAACCC459CC924809A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00204DCCBE7C3A5F1E2B7ECC867965CCCBCCD65A7D771ACC81CCEECCF724CCE2010DCCF1CCF63CCCFC4C56CCB5CC9FA773686966746564C0A67A5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCCB4CC8052CC9A247A2B51425B50705BCCEACCD7CC85CC8664CCBCCC84CCB1CCD318CCB96BCCEA55CC9049CCEBCCA7A773686966746564C0A6745F636F6D6D82A9756E736869667465649782A474797065A6427566666572A464617461DC00203ACCF406CCEBCCEBCCE72979CCF063CCB06BCCA8CCF74A34CCA22B5D4B5E30CCF8CCFD3F7BCC9F11CCC254101582A474797065A6427566666572A464617461DC002071CCF6CC9CCCADCCA4565520CCE9CCA5CCF4CCEBCCA0CCDB1B1E3D760224025A4DCC806BCC9DCCA7CC8CCCA951CCEC0C82A474797065A6427566666572A464617461DC002056CCC151CC80CCF762CCAFCCA4CCD9CCC968CCA6CCAA64CCD60CCCF1CCC4CC9FCCDB6A2D6863CCFFCCAB48796F37CC8D2682A474797065A6427566666572A464617461DC0020CCAECCF3665BCCDFCC97CCBE7CCCE6CCF8CCB70F62CCAE197764CC9ACCB80ACCA416CCE3CCB00E78CCAD265613CCA50B82A474797065A6427566666572A464617461DC0020CCF81C0359CC95CCFCCCA479CCB2CC9DCCEDCC9626CCCECCB6CCEDCCAE642A3DCCF37ECCF56B665BCCD950CCD32C780882A474797065A6427566666572A464617461DC0020CCF6CCF06B74CCA433591E30CCE6CCE1CC93CC8ACC9C56042F3867714FCCC72E7ACC891ECCBB71603DCCE4CCAF82A474797065A6427566666572A464617461DC0020CCCFCCCFCCB3560BCC83CC95CCCC33CCEACC9E6DCC921BCCB4CCCACCA864CCECCCC33776734D657CCCD52BCCAC204BCC94A773686966746564C0A66C6F6F6B757083A6736F727465649582A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE9CCF5195B6ACCD6CC96CCA1325F2D6C79CCFF6CCCD9CC9ACCFE77CC932BCCE3CC994073CCF2CCFBCCC779CCE56C27A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC975DCCC0CCDD6BCCC7CC9ECC8CCCDA681A17CCDA2CCC9F7BCC916F483D41CCA00A68CCB718CCC722CCBE422E18A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002021CCC1CC8C4370687F69CCA0CCAA533BCCCA0C5BCCE847CCBA78CC83CC8BCCA103CCC67668CCDCCC812405CCA0CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002019CCD34CCCF25BCCE82955CC974A26663E0F70CCA6596FCCACCC9B7CCCAECC83CCA6556F410771CC92CCF611A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002045CCF9105CCC8FCCA1CC9E2638607BCC8A2B0266CCEDCCFACC9361CC80CCC1CCE1CC8A3C5B08CCCC5FCC8921CCC2CCA7A773686966746564C0A661676772656782A9756E736869667465649182A474797065A6427566666572A464617461DC00201DCCC905CCCBCCFC7F19CCB5CCCCCCECCCB4CC965DCCA5CC87573F535C6A15CCBD0FCCC0CCA81D07023818CCA21FA773686966746564C0A772756E74696D65C0A570726F6F6682A871756F7469656E7482A474797065A6427566666572A464617461DC0020CCDD7E3BCC86CC99622CCCFD7F08221DCCD8191504CCAB386202CCC50A6ACCB1CC8ECCF663CCBECC9F0A53CC99A8626C696E64696E6782A474797065A6427566666572A464617461DC00207B6778CCBECCFD13CCB616CCEDCCDBCCAA7B1FCCD214CCC4CCD3CC9A4DCCC0306ACCC3CCF3CCD1CCAFCCF64D6858CCB61DA56576616C73DE001AA67075626C696382A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000A1779F82A47A6574619182A474797065A6427566666572A464617461DC0020CC91CCABCC853859CCDB5FCC8FCCC276CCAACCC5183119CC84CC863231CCB456CCB608CC9336CCC3CCC0CCC0CCEACCAB2D2CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD7CCB3CCC07450CCC178CCBB5B14CCE3CCB5CCB22C70CCEBCC8E770ACCE329284A08CC84CCA5CCDF6BCCC1752E0882A47A6574619182A474797065A6427566666572A464617461DC0020134ECCAECCD96164CCA0CCD8CCBF0B71CC9C5C78CCE3CC8E21CC81CCDF10CCBD02462ECCA8CC9D03CCCECCF06D6F15AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD256CCA01BCCABCCF549CCC62908CCFDCCE5CCF537CCC24BCCF645CCCC2948CCEC3ACCD9CC9ACCAECCC2CCE30ACCCD301D82A47A6574619182A474797065A6427566666572A464617461DC0020CCC2CCEBCC96142945380379CCEFCC95130D6914CC925FCCF623CCA4CCB21BCCE00FCCCA00CCA5CCA44113CCC206AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00203ECCD2CCD9CCADCCB110CCA05F6B0DCCF5CCD435373FCC896DCCC16ECCA81E29CC982A5D422835CCAC4B090C82A47A6574619182A474797065A6427566666572A464617461DC0020162ECCAECCE714CCE053CC94CCFECCB612CCA31371CC8D3856CCD9CCE603CCECCCB2CCE9CCEB39CCDBCC86CCB445251216AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCBACCF04E4E7ACCE2CCCECCBBCCB2CCC2CC8ACCB7CCF06A71CC9F685ACCF1CCC9CCA454CCDC0549CCFFCCD545CC8B4A1A1682A47A6574619182A474797065A6427566666572A464617461DC00200F4B02CCDA68CCDFCCE9CCA8366FCCAACCD70ECCCE3ACCA84BCCC3CC80CCC149CCB077CCA20BCC9DCCBF5FCCEC7ECCBC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002066CCA178CCA84845CCE35ECCEA08CCD4CCB1CCEBCCD5CCF6221C0F74CCDCCCCBCCCDCCDFCCDD62CCEECCEC4D6DCCD4CCC40982A47A6574619182A474797065A6427566666572A464617461DC00206ECCE833CCF62BCCF044CCE1CCA3CC9B25604DCC982CCCA1CCFC6ECC9A61CCA4CCE973CCEF0A71CCBFCCD90617CC9422AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205848CCFC1BCCFC647567CCCFCCF76ACCC176CCFACC92560B6C3E3D6FCC90CCF6CC9FCC9ACC88CC811160CC91CCC20682A47A6574619182A474797065A6427566666572A464617461DC0020CC864757CCB36C11CC86182C11CC832E08CC86466ECC8A49187BCC8BCCEFCC90CCC87171CCA62040CC9ACCC22FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD0CCAECCFFCC91CCA0CC9FCC9625CC9522CCD5204E2BCCC0CC91507408CCFACCCB5B202C57CCF23A46CCE37D7D2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCE95ACC9E46CCFCCCBA232C37CCC335CCF9CCF9303CCCFFCCC85669CCEFCCB107CC99CCFACCF7CC924F2827CCAE0102AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002009CCB537CC9D6607CCFECCFDCCE14801CCF6CCB3CCA2CCB6CCE2CCDFCCE5CCC83027334FCCAE22221BCCCF1A0F1C0082A47A6574619182A474797065A6427566666572A464617461DC0020CCC6CCCD1ACCBF41233DCCA617CC9C4406CCD861CC91CCF60E4412CCAB4FCCB1CC9F447BCCB3CCABCC9E7836CC960CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002037CC80CCAECCBD56CCB5CCBC50CCC3CC9746CC995BCCB628CCB674CCACCCF7CCC55D653142CC9FCCCA71CCC9CCE3CCEACC8C0A82A47A6574619182A474797065A6427566666572A464617461DC0020CCB1CC8348CCDACCD87DCCD0CCDC29CC826D03672D64CCAE4963CCE37ECCB205114ACCDECCB5CC9F1E1B72CCAC03AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF5793436CC87574F2ACCAA5020CCA91E1CCC8451CC81015ECC8E35267C063CCC86CCB87CCCA002CCFF2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCD33CCCAECCD038CCD63324CC9B1DCC9ACC9FCC8040CC9A39CCF7CCEACCCCCCE17ECCE5CCADCCEE18CCB0CC8509497ECC882DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD32B42CCF447CCDD023CCCD4CCB76D50CC9DCCD2CC8054CCF456CCC709CCA017CCC104CC9A65CCA37439CC96CCA61782A47A6574619182A474797065A6427566666572A464617461DC00200A5D16CC8FCCC1CCF516CC8843CCDBCCFD74CCD8102B5928CCA244CCDC29CCE8CCC4714DCC935628CCB52ECC8D18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCEA45CCBE2C29CCDFCC805ECCE5CCABCCB3CCAB05CCEDCCE125CCB2CCFDCC8ECCAD6549CCF1CCA57DCCE9CCD647CCE6CCA7650E82A47A6574619182A474797065A6427566666572A464617461DC00204854CCAE40CCFCCC8F3BCC935E2477CCCCCCC90D0C115D72CCAD63CCA537CC9873CC8770CCEFCCBA12CCFDCCB01BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCDC2DCCD655CCAC0B6311CC9944CC8E39CCDECC81CCBBCCB1CCE45C32CCA4CCBD5A1D4314CCFFCC9010CCF24B2B82A47A6574619182A474797065A6427566666572A464617461DC00201135CCDBCCDC6F7FCCDC26CC845449CCC771CC881029CCC1CC80CCD5CCAE61CC866DCCCF6CCCF81C1C73CC871A2FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002048CCCBCC81CC906F47CC98CC8F3E3C04CCD4CC9874CCA50A3E3D31CCE6CCCCCC8772CC8ECCBC07CCDA05CCCE273A3082A47A6574619182A474797065A6427566666572A464617461DC00207DCCCCCCCECCBACC9D4373CCAF6F1D07CCD00FCCD42344CCD5CCB3CCE0CCF36A7937CC8DCCFB350BCC8E7F73CC9D26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00206C2D746FCCD1CCF94654CCB7CCC4CCC7CCE36051CCB019CCCBCCE870CCE5CCD43ACCED10CC93CCFFCCEB4C67CCA05D30A17A82A47A6574619182A474797065A6427566666572A464617461DC00203303576F49CCD5CCA8CCD0CCE87BCC9703CCFCCCEACC9FCC9102CCCC69CC8ACCE4CCEF6945CCA5CCDF1F2B7262652AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCE747CCA774CC98CCA2CCA610CC9FCCEDCCEC22CCEC150E732818CCFF3727CCD4CCDA31CCE1CCB5587160CCAACCC603A1739682A47A6574619182A474797065A6427566666572A464617461DC002051CCF4CCA0CCA2CCDC4BCCCFCCC2CCDC5CCCFBCCF2CC9FCC9CCCB9CC9FCCA7315741CCFF73CC99CCFF41CCE8CC95CCE6CCD6CCB7001DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF21D4C5ACC954338CCE1CCC56206CCC45705CCE503CCDD28CCEE64CCF633CCA6CCF677CCFACCF8CCB5CC8A45CC9F0E82A47A6574619182A474797065A6427566666572A464617461DC0020CCEFCC81CCD54E2E33CC860C37CCE8CCA5CC96CCFF1ACC802ACCEACCBDCCD6275770CC841F36CCA6CCD5CCCCCCA13CCCC71AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF63A5E6C3ECCF63DCCED4ACC8F75CCDF2ECCBF5ECC95CCC8CCA4CC992926CC996DCCE9CCAD60CCD30122CCE2201782A47A6574619182A474797065A6427566666572A464617461DC00201ECCAA57CCA3CC9BCCDDCCBFCCFCCCD13074CCF7CCFACCD84DCCB434CCC4CCDA5FCCF866CCE6CCD5CCC6CCCD70CCC653CCDDCC882EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020332374CCBA79025BCC9916CCD7CCD90CCCDC5CCCE0CCA8CCE368CC9F590136CCCB15CCC868CC8BCCA809CC84CCF30082A47A6574619182A474797065A6427566666572A464617461DC002018CC88415E4CCC9E64720DCCF873CCAC561748CCEA26CCF9CC8B153D61CCF34BCCCDCCA62710CCC9500C1BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA1CC80CC81CCEC3CCCC6CCF9CC9A5E1ECCC7CCF9CCA2CCF2217743437DCC8BCCF7CCDFCCC3CCC51ECCDECC96CCA0CC8438091182A47A6574619182A474797065A6427566666572A464617461DC0020CCCC40CC942544CCB12E2F46CCF4CCA1CC8ACCC2596C113363CCDF2FCCAF41CCFECCD5CCE5CCFDCCFD7C33107E26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002011CCAF34CCA9470870CCE7CCF411CCC2CC8741CCDD52CCAB55CCC1CCCECC876ACC870305622F7ACCCBCC8761CCB00982A47A6574619182A474797065A6427566666572A464617461DC0020CCEC6741CCFECCA4CCF6CCF91FCCE6CCDCCC9E5E746B2857CCFFCC962B4ACCCECCE7CCE9CCD429CCB4CCD2CC8D1FCC8DCCFC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC81CCA9CCE6CCC546CCA8555ECCF82607CCCECC9563CCDC31CCA3CCD8CCDA2BCCA4CCBE18616426697D696ECC831DAC636F656666696369656E74739F82A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B067656E657269635F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B1706F736569646F6E5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B5636F6D706C6574655F6164645F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AC6D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AD656D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B7656E646F6D756C5F7363616C61725F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B572616E67655F636865636B305F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCA8CC92CCB340CCC520573BCCF5CCC60BCCABCCBDCCE7CC8F15CCE2CCEDCCEE31CC9B484D5FCCD62CCCC2CCC3391ACCFF2EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC9D37CCAE26CC8702CCBB67CCFFCCBACC841DCCEB383113CCFBCCB3CCE6CC8FCCF0CCBFCCEFCCDB1B6F622645CC830F27B572616E67655F636865636B315F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCF2CC90CCC8CCA4CC8DCC92CCE7CCDFCCA93938044316CCBE6D37CCC9023A2A54CCD9043B0ECCBECCF912350703AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC941CCCCA71CCDA09CC8DCCD162CCF4CCBACCA814CCEE5BCC9ACCF9216D7CCC990E0ACCFECCB7CCB37B397CCC85CCBA15BA666F726569676E5F6669656C645F6164645F73656C6563746F72C0BA666F726569676E5F6669656C645F6D756C5F73656C6563746F72C0AC786F725F73656C6563746F72C0AC726F745F73656C6563746F72C0B26C6F6F6B75705F6167677265676174696F6E82A47A6574619182A474797065A6427566666572A464617461DC0020CCBB1ACCD376CCEECCF0CCA750CC8B711ACC97CC8160CCE1CCC5CCFCCCF0CCE0412861CCEF5128CCF4CC99CCCE39CCC4CCF80DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002032CC903FCCD27BCC9ECC9CCCAFCCBC39CCC1CCC3CC9BCCA36D0570CCA114CCAE2CCC9F1203CCBD60CCA31D7ACCBB0514AC6C6F6F6B75705F7461626C6582A47A6574619182A474797065A6427566666572A464617461DC00203D663E7E6610CCB1CC844863CC803466590A2A1CCCA451CCC755393BCCD3CCC762CC822B44CCA8CCB02BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC8ACC985A1D271113CCCACCE0CCA7CCEACCB5CC86CC845CCCB8CCCD2E27CCDF38CCD30E76CCC81832CC94CC8ECCF4CCAB1FAD6C6F6F6B75705F736F727465649582A47A6574619182A474797065A6427566666572A464617461DC002003CCF1CC8FCC8CCC843B1ACCC26DCCDE6ECCE46E64CCC9CCE971CCDECCC4CC84CCFE2FCCBACCFBCC8737CCACCC8756CC945F23AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA3326726CCABCCD7CC904C23CC927068CC920F59CCB7CCEA17CCCFCC8878CC91CCC13ACCE36C3F4725CC8B222882A47A6574619182A474797065A6427566666572A464617461DC0020CCF52ECCB7683352CCA3CCF176CCEECCD461CCCC0C3ACCD905CC80CCAF4E25CCBE29CCA8CC99CCD87ECC8ACCC20FCCB90DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00207BCCD5CCC6CC9228CCE1CCBA3E037ACC854FCC9A6BCCCC492CCCA7CCA7CCF5CCEF3FCC862278CCC732CCDD45CCFCCCD02782A47A6574619182A474797065A6427566666572A464617461DC0020CC9741CCC7CCC0CCFC6F6A6768377ECCD94ACCB1CCC92FCCE66129CCE7CCC8CC8436CCB3CCBE2DCC8BCCF418CCB20415AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205772CCCF1B0A32CCFDCCE247CCC3CCDD6CCC8126CC83CCFCCCBE5F31CCA53521CC85CCBA72CCBDCC85344265701282A47A6574619182A474797065A6427566666572A464617461DC0020CCB4CCA0CCEA22046DCC87CCB2427F4954CC82CC84CCADCCD10BCCB7CCD7CC990044CCF4CCDFCCD95FCCD5CCD27167CCBE18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF569CC93331A635C4465CCE85C6CCC8121CCBBCC93CCD7CC8DCCE6CCFACCE4CCE817CCD95270384D500ECCCB1582A47A6574619182A474797065A6427566666572A464617461DC0020CCB7CCCB1F526A127353CCDBCC97CCB7CCCB32CC82CCB26FCCE9CCBACCC4CCB8CCE915CC9F65CCBBCCDD42412A0F771DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002005CCABCCEE75CCBA63CC9C0824CCCCCCFD6ACCC6CCE1CCC4CCF2CCACCCA9CCACCCA2CCD90716CCD746CCA3CCCD00002D4C26B472756E74696D655F6C6F6F6B75705F7461626C65C0BD72756E74696D655F6C6F6F6B75705F7461626C655F73656C6563746F72C0B3786F725F6C6F6F6B75705F73656C6563746F72C0BB6C6F6F6B75705F676174655F6C6F6F6B75705F73656C6563746F72C0BB72616E67655F636865636B5F6C6F6F6B75705F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCBD2ECCC43CCCBD197CCCC3112429CCCC1FCC83CCC26DCCBBCCB77DCC87CCDD691844CCA257CCB678CCEDCC9FCCEC1FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCE5404D5BCCA94DCCD57A78CCBE50CCFA5417CCF3CCCE46CCD5CCC4CCFDCCDCCC8226CCE5CC906A7861CCEF6C0FD921666F726569676E5F6669656C645F6D756C5F6C6F6F6B75705F73656C6563746F72C0A866745F6576616C3182A474797065A6427566666572A464617461DC00202E74CCF4CCB84B766ECCB00ACCC6CCFD70306ECCA8CCA2CC870ACCD8780864005B306ECC8DCC957CCCD04916AF707265765F6368616C6C656E67657390"; + bytes verifier_index_serialized = + hex"DE0015A6646F6D61696E82A474797065A6427566666572A464617461DC00AC00400000000000000E00000000400000000000000000000000000000000000000000000000000000000000000140CCB0190CCCE6CC9CCC81CCABCC89CC97CCD87847CCBFCCC65752CCA76A7564CCA937631B66CCA7CCE1CC8C6330CC856E7C61CCC201CCAACCADCCE6CCAA2074CCE13ECCA9CCB4CCA8CCA8CCDC0DCCB8514E1FCC81CCE4CCD9CCCD5156CC962D10CC841C6434CCE9CCEECCF8CCC0717767CCB07609CCF4CC8C6ECC8E55420D6811CCE9CCE9CCE7066F031C28676666CCC6CCD4CCFBCCF3CCE7062D4ACCCACCE95CCCAECCA9CC8B56CCCD337CCCB5CCB949CCAACCD9135ACC94525B13AD6D61785F706F6C795F73697A65CD4000A77A6B5F726F777303A67075626C696300AF707265765F6368616C6C656E67657300AA7369676D615F636F6D6D9782A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC8E6A46CCC4CC9A5B053E3ACCD03ACCCACC896319CCAB43CC88CCAFCC887ECC84CCBC3DCCACCCFB49CCAB67CCDDCC93CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200F751F4138CC9FCCEFCCCACCC43ACCB9CCA01B0810CCAB2CCCB74C70CCDFCCD8CC9521CCC7CCA0CCCFCCA15019CCDECCA4A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCC903D4275CC90CC98CC987ACCE8CCA0CC946A33CCDACCB8CCBB386052CC93CCDF725A29CCC840CCF4CC87CCD6CCABCC99A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7526CCDDCC86CCA2CC9CCCD6CC8F0ACC937E062E56CCD25E3250CC90CC86CCC958CC84CCE0CCA5CC9701CC99CC8F7BCCA5A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC964300CC855F1C7BCCB37B55CC854C582F48CCC54938CCAB48CC815BCCD64A5ACCC62DCC8C37CCDDCCE403A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCF9322C5458CCD204CCDECC90CCE7CCFBCCED5E5ACCB2CCFC4651CCBA62297E0ACCFCCCF2CCCACCFBCCB0CCA05D0421A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCB3183ECCF8CCF4CC9410CCA465CCA4CCD145CC97CC9A4E5FCCB92FCCEACC81CCD7767434CC99CCC7CCC428CCEBCCBB6819A773686966746564C0B1636F656666696369656E74735F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C0AC67656E657269635F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A870736D5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B1636F6D706C6574655F6164645F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A86D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A9656D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B3656E646F6D756C5F7363616C61725F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B172616E67655F636865636B305F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020190C1BCC8C2123CC9301CCC0CCCD623DCCA5CC91CC84CCEBCC871B15076BCCF5CCC1CCD7497ACC8ACC99CCC2260ACCA4A773686966746564C0B172616E67655F636865636B315F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCFA37CCB2CCCFCCCB1A44CCE4CCF8204DCCB54FCC852335CCE0075ECC8D6BCC87CCB4CCA3CCB47444185C44CCEDCCAFA773686966746564C0B6666F726569676E5F6669656C645F6164645F636F6D6DC0B6666F726569676E5F6669656C645F6D756C5F636F6D6DC0A8786F725F636F6D6DC0A8726F745F636F6D6DC0A573686966749782A474797065A6427566666572A464617461DC0020010000000000000000000000000000000000000000000000000000000000000082A474797065A6427566666572A464617461DC0020CCE3CCA214CCE91334CCD0CCCACCF1CCEBCC85CCDF5BCCD7524D73CCD5CCEB7ACCAF742A7ECCB2CCD40BCCFDCCC8CCCDCCB90082A474797065A6427566666572A464617461DC00206D0F4433CC9A33CC9FCCB8CCA4CCE4CC9BCCF109CC9620CCAA64CC9918482BCC95CCA3CC97CCAE39CCB9CCEC5ACCD4770082A474797065A6427566666572A464617461DC0020CCB40923CCBD78CCE619CCC80A7B39CCC0CCF3CCF11E48005519CCD2CCFECCF16A1F77CCD40545CCE5CCC7770082A474797065A6427566666572A464617461DC0020CCF9CCC95CCCD6CCB11B38CCDF7855CCFD4D2A036329CCADCCCACCD613CCF100CCB92310CC9540356A597C0082A474797065A6427566666572A464617461DC00205A696526CCFA30CC9C412C10CCE86604CCC3CCC0CCAD2CCCD9443DCCD85BCC8232037212CC81CCCFCCBF330082A474797065A6427566666572A464617461DC002043423BCCB307CCCECCC1CC9F297C41CC88CCDECCB23ACCCC7B581271CC9B2ECCACCCCBCCF1CCB7034ACCE6CCACCCE800AC6C6F6F6B75705F696E64657886B16A6F696E745F6C6F6F6B75705F75736564C2AC6C6F6F6B75705F7461626C659182A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE6CCA15E7ECCA10ECCD2CC8F0F3361CCC7CCA7CCF45CCCED5E6D382017CC8CCC832CCCFCCCC0CCDF0E343ECCB1CC80A773686966746564C0B06C6F6F6B75705F73656C6563746F727384A3786F72C0A66C6F6F6B7570C0AB72616E67655F636865636B82A9756E736869667465649182A474797065A6427566666572A464617461DC00201B24636044CCD6CCED30CCC611CC85CCD45B2969CC98CCB811CCB754CCA5507C08CCD1CC9124CC9B37CCC01721A773686966746564C0A566666D756CC0A97461626C655F69647382A9756E736869667465649182A474797065A6427566666572A464617461DC00205F28CC8BCCB342CC8034CCA922CCB3CCE618CCEA3ECC811ECCDF61CC81CCB10B7ECCF6CCC859CCFD03CCEA2B39CCA70EA773686966746564C0AB6C6F6F6B75705F696E666F83AB6D61785F7065725F726F7704AE6D61785F6A6F696E745F73697A6501A8666561747572657383A87061747465726E7384A3786F72C2A66C6F6F6B7570C2AB72616E67655F636865636BC3B1666F726569676E5F6669656C645F6D756CC2B16A6F696E745F6C6F6F6B75705F75736564C2B3757365735F72756E74696D655F7461626C6573C2B772756E74696D655F7461626C65735F73656C6563746F72C0"; + bytes urs_serialized = + hex"92dc0020c4200100000000000000000000000000000000000000000000000000000000000000c42055a8e8d2b2221c2e7641eb8f5b656e352c9e7b5aca91da8ca92fe127e7fb2c21c42003bc09f3825fafdefe1cb25b4a296b60f2129a1c3a90826c3dc2021be421aa8ec4206422698aa4f80a088fd4e0d3a3cd517c2cb1f280cb95c9313823b8f8060f1786c4203558cb03f0cf841ed3a8145a7a8084e182731a9628779ef59d3bc47bae8a1192c4202ac41dd231cb8e97ffc3281b20e6799c0ae18afc13d3de1b4b363a0cd070baa7c420b6205dfa129f52601adfd87829901f06f1fd32e22a71f44b769d674448f05d83c4205d1b9b83cdcba66ff9424c7242c67394d7956dabf5407f4105124b7239d43e80c420e95ffc0999a8997b045430aa564c7bd9a25303e8a5ebbe4a99f6329b7f2a64aac4206cca50f1237f867fee63ac65249d6911494680f42d0e71386b1586be39092f9cc4204b9b17d64b384a65d7c80c8ab0f5fff75c69fd147835599753beea03152a3923c4205c0f706b036ed361e787af70acea3533d6e349869e83368979fdbbf382a4900bc420da6652a81754a6263e677d23a55bd729205f5fb64fa39b6771d9b811e5548bafc4208db1ad69d758362a4ecacff98a6910a95b3c2697e455271b2d7c078f1894eb1fc42010f56f1046a1121b1df5c401969b5acbf80eef8bfd5438270e09243413382788c4200cca37d1a3a721792dc232bb6a95bd14143350b6784bcdd4898a0bb34dd8bd2cc4202b7a1991e05b77d911d15ae590ff6f6ad7d1ed572b34654e3ce92e38e4839425c4201977ca4631e9eea53c7ba59d334c14dac7ee1071d6bf6ebf2ab7450c16975d23c4209eb742379ee8664a8bf9c18a40a534bb2961020bd0077cd0b603d2a8b9fe5a17c4201c50af6002db8dfa5a310ce795dcb06de94ead6687687263fd59acbc8612f180c4205241cbed55fbe1193f366e7ea8ad11bc97742eb35ca39129c4931b9bef64df1ec420646e69eb7d4682ad6bff24d40bf22184694c569246385cc127b3ec4a99875a85c42046b77ed1e120130743344ea9372ea58118604c730800e0d7038f2c80211f4f90c4208f20f3c39a09b5615bd8b2a09eec7dbc11b5ea1f8fe7eb0d5a69c1264412d199c42095f0b87ed771c169a8b6c0a6e21b13ab715407a4e6637a0b8fe0a1e3278f32a7c420a80440e1a07157bad23d7a7d3ddd7445f578021650016fc4bfb3324ed967c82bc4202b94fd0b89e7e2c9d245a4e94a539b14c5db26ed5ba4b3989ef0ba0712d4582ec42068f583079aa73425184a328127be63421eae683a25be94a0aa697ce74b5b972dc4209fa10b770e452852612ea392b8521683999d0a168c5eb85a6925d1ffe21d418ac420826a0976821c9309ed896678a97634a2fb1392a64ab8c59c8380012ffb601189c4203096ba3ed0b597fa29da6caa9000a409702b1f945561e82d02ab77b0cfdb649fc4204a718bc27174d557e036bcbcb9874ce5a6e1a63ccbe491e509d4201bfcb50806c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c250a"; + function test_partial_verify() public { KimchiVerifier verifier = new KimchiVerifier(); - (BN254.G1Point[] memory g, BN254.G1Point memory h, uint256 _i0) = MsgPk - .deserializeURS(urs_serialized); - (ProofEvaluationsArray memory evals, uint256 _i1) = MsgPk - .deserializeProofEvaluationsArray(evals_serialized, 0); - verifier.setup(g, h, 0, 32, 32, evals); - verifier.partial_verify(new Scalar.FE[](0)); + verifier.setup(urs_serialized); + + verifier.verify_with_index( + verifier_index_serialized, + prover_proof_serialized + ); } } diff --git a/eth_verifier/test/State.t.sol b/eth_verifier/test/State.t.sol index d2ca98bb..12d45b31 100644 --- a/eth_verifier/test/State.t.sol +++ b/eth_verifier/test/State.t.sol @@ -12,16 +12,9 @@ contract StateTest is Test { // Initialize contract. Code was taken from integration test bytes memory urs_serialized = hex"92dc0020c4200100000000000000000000000000000000000000000000000000000000000000c42055a8e8d2b2221c2e7641eb8f5b656e352c9e7b5aca91da8ca92fe127e7fb2c21c42003bc09f3825fafdefe1cb25b4a296b60f2129a1c3a90826c3dc2021be421aa8ec4206422698aa4f80a088fd4e0d3a3cd517c2cb1f280cb95c9313823b8f8060f1786c4203558cb03f0cf841ed3a8145a7a8084e182731a9628779ef59d3bc47bae8a1192c4202ac41dd231cb8e97ffc3281b20e6799c0ae18afc13d3de1b4b363a0cd070baa7c420b6205dfa129f52601adfd87829901f06f1fd32e22a71f44b769d674448f05d83c4205d1b9b83cdcba66ff9424c7242c67394d7956dabf5407f4105124b7239d43e80c420e95ffc0999a8997b045430aa564c7bd9a25303e8a5ebbe4a99f6329b7f2a64aac4206cca50f1237f867fee63ac65249d6911494680f42d0e71386b1586be39092f9cc4204b9b17d64b384a65d7c80c8ab0f5fff75c69fd147835599753beea03152a3923c4205c0f706b036ed361e787af70acea3533d6e349869e83368979fdbbf382a4900bc420da6652a81754a6263e677d23a55bd729205f5fb64fa39b6771d9b811e5548bafc4208db1ad69d758362a4ecacff98a6910a95b3c2697e455271b2d7c078f1894eb1fc42010f56f1046a1121b1df5c401969b5acbf80eef8bfd5438270e09243413382788c4200cca37d1a3a721792dc232bb6a95bd14143350b6784bcdd4898a0bb34dd8bd2cc4202b7a1991e05b77d911d15ae590ff6f6ad7d1ed572b34654e3ce92e38e4839425c4201977ca4631e9eea53c7ba59d334c14dac7ee1071d6bf6ebf2ab7450c16975d23c4209eb742379ee8664a8bf9c18a40a534bb2961020bd0077cd0b603d2a8b9fe5a17c4201c50af6002db8dfa5a310ce795dcb06de94ead6687687263fd59acbc8612f180c4205241cbed55fbe1193f366e7ea8ad11bc97742eb35ca39129c4931b9bef64df1ec420646e69eb7d4682ad6bff24d40bf22184694c569246385cc127b3ec4a99875a85c42046b77ed1e120130743344ea9372ea58118604c730800e0d7038f2c80211f4f90c4208f20f3c39a09b5615bd8b2a09eec7dbc11b5ea1f8fe7eb0d5a69c1264412d199c42095f0b87ed771c169a8b6c0a6e21b13ab715407a4e6637a0b8fe0a1e3278f32a7c420a80440e1a07157bad23d7a7d3ddd7445f578021650016fc4bfb3324ed967c82bc4202b94fd0b89e7e2c9d245a4e94a539b14c5db26ed5ba4b3989ef0ba0712d4582ec42068f583079aa73425184a328127be63421eae683a25be94a0aa697ce74b5b972dc4209fa10b770e452852612ea392b8521683999d0a168c5eb85a6925d1ffe21d418ac420826a0976821c9309ed896678a97634a2fb1392a64ab8c59c8380012ffb601189c4203096ba3ed0b597fa29da6caa9000a409702b1f945561e82d02ab77b0cfdb649fc4204a718bc27174d557e036bcbcb9874ce5a6e1a63ccbe491e509d4201bfcb50806c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c250a"; - bytes - memory evals_serialized = hex"9291c420000000000000000000000000000000000000000000000000000000000000000091c42000000000000000000000000000000000000000000000000000000000000000000a"; - - (BN254.G1Point[] memory g, BN254.G1Point memory h, uint256 _i0) = MsgPk - .deserializeURS(urs_serialized); - (ProofEvaluationsArray memory evals, uint256 _i1) = MsgPk - .deserializeProofEvaluationsArray(evals_serialized, 0); verifier = new KimchiVerifier(); - verifier.setup(g, h, 0, 32, 32, evals); + verifier.setup(urs_serialized); } function test_verify_retrieve() public { From 39fc6cc9e617236abbcb6611220c7cfba4df8289 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Tue, 12 Dec 2023 17:55:23 -0300 Subject: [PATCH 35/68] Inicial code and comments for final_verify function --- eth_verifier/src/Verifier.sol | 96 ++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 19 deletions(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 550c5684..ed6fd920 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -89,8 +89,14 @@ contract KimchiVerifier { verifier_index.powers_of_alpha.register(ArgumentType.Permutation, 3); // TODO: Investigate about linearization and write a proper function for this - verifier_index.powers_of_alpha.register(ArgumentType.GateZero, Constants.VARBASEMUL_CONSTRAINTS); - verifier_index.powers_of_alpha.register(ArgumentType.Permutation, Constants.PERMUTATION_CONSTRAINTS); + verifier_index.powers_of_alpha.register( + ArgumentType.GateZero, + Constants.VARBASEMUL_CONSTRAINTS + ); + verifier_index.powers_of_alpha.register( + ArgumentType.Permutation, + Constants.PERMUTATION_CONSTRAINTS + ); proof.evals = evals; } @@ -190,20 +196,22 @@ contract KimchiVerifier { // Combine the chunked polynomials' evaluations - ProofEvaluations memory evals = proof.evals.combine_evals(oracles_res.powers_of_eval_points_for_chunks); + ProofEvaluations memory evals = proof.evals.combine_evals( + oracles_res.powers_of_eval_points_for_chunks + ); // Compute the commitment to the linearized polynomial $f$. - Scalar.FE permutation_vanishing_polynomial = - Polynomial.vanishes_on_last_n_rows( + Scalar.FE permutation_vanishing_polynomial = Polynomial + .vanishes_on_last_n_rows( verifier_index.domain_gen, verifier_index.domain_size, verifier_index.zk_rows - ).evaluate(oracles.zeta); + ) + .evaluate(oracles.zeta); - Scalar.FE[] memory alphas = - verifier_index.powers_of_alpha.get_alphas( - ArgumentType.Permutation, - Constants.PERMUTATION_CONSTRAINTS + Scalar.FE[] memory alphas = verifier_index.powers_of_alpha.get_alphas( + ArgumentType.Permutation, + Constants.PERMUTATION_CONSTRAINTS ); PolyComm[] memory commitments = new PolyComm[](0); @@ -234,7 +242,10 @@ contract KimchiVerifier { Scalar.FE[] memory alphas, // array with the next 3 powers Scalar.FE zkp_zeta // TODO: make an AlphaIterator type. ) internal pure returns (Scalar.FE res) { - require(alphas.length == 3, "not enough powers of alpha for permutation"); + require( + alphas.length == 3, + "not enough powers of alpha for permutation" + ); // TODO: alphas should be an iterator res = e.z.zeta_omega.mul(beta).mul(alphas[0]).mul(zkp_zeta); @@ -244,6 +255,61 @@ contract KimchiVerifier { } } + function final_verify(Scalar.FE[] memory public_inputs) public { + /* + Final verification: + 1. Combine commitments, compute final poly commitment (MSM) + 2. Combine evals + 3. Commit divisor and eval polynomials + 4. Compute numerator commitment + 5. Compute scaled quotient + 6. Check numerator == scaled_quotient + */ + /* + pub fn verify( + &self, + srs: &PairingSRS, // SRS + evaluations: &Vec>, // commitments to the polynomials + polyscale: G::ScalarField, // scaling factor for polynoms + elm: &[G::ScalarField], // vector of evaluation points + ) -> bool { + let poly_commitment = { + let mut scalars: Vec = Vec::new(); + let mut points = Vec::new(); + combine_commitments( + evaluations, + &mut scalars, + &mut points, + polyscale, + F::one(), // TODO: This is inefficient + ); + let scalars: Vec<_> = scalars.iter().map(|x| x.into_repr()).collect(); + + VariableBaseMSM::multi_scalar_mul(&points, &scalars) + }; + let evals = combine_evaluations(evaluations, polyscale); + let blinding_commitment = srs.full_srs.h.mul(self.blinding); + let divisor_commitment = srs + .verifier_srs + .commit_non_hiding(&divisor_polynomial(elm), 1, None) + .unshifted[0]; + let eval_commitment = srs + .full_srs + .commit_non_hiding(&eval_polynomial(elm, &evals), 1, None) + .unshifted[0] + .into_projective(); + let numerator_commitment = { poly_commitment - eval_commitment - blinding_commitment }; + + let numerator = Pair::pairing( + numerator_commitment, + Pair::G2Affine::prime_subgroup_generator(), + ); + let scaled_quotient = Pair::pairing(self.quotient, divisor_commitment); + numerator == scaled_quotient + } + */ + } + /* This is a list of steps needed for verification. @@ -255,14 +321,6 @@ contract KimchiVerifier { 5. Commitment to linearized polynomial f 6. Chunked commitment of ft 7. List poly commitments for final verification - - Final verification: - 1. Combine commitments, compute final poly commitment (MSM) - 2. Combine evals - 3. Commit divisor and eval polynomials - 4. Compute numerator commitment - 5. Compute scaled quotient - 6. Check numerator == scaled_quotient */ /* TODO WIP From a9ddd81e030ad6ce818fd14520c5b7bd13738d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Wed, 13 Dec 2023 18:09:25 -0300 Subject: [PATCH 36/68] Added lagrange bases deserialization --- eth_verifier/.gitignore | 1 + eth_verifier/lib/Commitment.sol | 35 +++++++++++++++++++----- eth_verifier/lib/Utils.sol | 3 ++ eth_verifier/lib/msgpack/Deserialize.sol | 26 ++++++++++++++++++ eth_verifier/script/Deploy.s.sol | 4 +-- eth_verifier/script/Verify.s.sol | 25 +++++++++++++++++ 6 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 eth_verifier/script/Verify.s.sol diff --git a/eth_verifier/.gitignore b/eth_verifier/.gitignore index 18bfe455..a24bbce4 100644 --- a/eth_verifier/.gitignore +++ b/eth_verifier/.gitignore @@ -18,3 +18,4 @@ state.mpk prover_proof.mpk verifier_index.mpk +urs.mpk diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 54c97207..6462d606 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -34,23 +34,44 @@ struct PolyComm { struct PolyCommFlat { BN254.G1Point[] unshifteds; - uint unshifted_length; + uint[] unshifted_lengths; } function poly_comm_unflat(PolyCommFlat memory com) pure returns (PolyComm[] memory res) { - // FIXME: assumes that every unshifted is the same length - - res = new PolyComm[](com.unshifteds.length / com.unshifted_length); - for (uint i = 0; i < res.length; i++) { - uint n = com.unshifted_length; + uint comm_count = com.unshifted_lengths.length; + res = new PolyComm[](comm_count); + uint index = 0; + for (uint i = 0; i < comm_count; i++) { + uint n = com.unshifted_lengths[i]; BN254.G1Point[] memory unshifted = new BN254.G1Point[](n); for (uint j = 0; j < n; j++) { - unshifted[j] = com.unshifteds[j + i*n]; + unshifted[j] = com.unshifteds[index]; + index++; } res[i] = PolyComm(unshifted); } } +function poly_comm_flat(PolyComm[] memory com) pure returns (PolyCommFlat memory) { + uint total_length = 0; + uint[] unshifted_lengths = new uint[](com.length); + for (uint i = 0; i < com.length; i++) { + total_length += com[i].unshifted.length; + unshifted_lengths[i] = com[i].unshifted.length; + } + BN254.G1Point[] unshifteds = new BN254.G1Point[](total_length); + + uint index = 0; + for (uint i = 0; i < com.length; i++) { + for (uint j = 0; j < com[i].unshifted.length; j++) { + unshifteds[index] = com[i].unshifted[j]; + index++; + } + } + + return PolyCommFlat(unshifteds, unshifted_lengths); +} + // @notice Executes multi-scalar multiplication between scalars `elm` and commitments `com`. // @notice If empty, returns a commitment with the point at infinity. function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) diff --git a/eth_verifier/lib/Utils.sol b/eth_verifier/lib/Utils.sol index 1a173ab3..d130ec69 100644 --- a/eth_verifier/lib/Utils.sol +++ b/eth_verifier/lib/Utils.sol @@ -195,6 +195,9 @@ library Utils { Scalar.FE[] memory twiddles = bit_reverse_permut(get_twiddles_inv(order)); BN254.G1Point[] memory unordered_res = nr_2radix_fft(points, twiddles); + console.log(twiddles.length); + console.log(unordered_res.length); + require(false, "adsasdasd"); return bit_reverse_permut(unordered_res); } diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 28ef65c1..3781d2bf 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -498,6 +498,32 @@ library MsgPk { } } + function deser_lagrange_bases( + EncodedMap memory map, + mapping(uint256 => PolyCommFlat) storage lagrange_bases_unshifted, + uint64 domain_size + ) public pure returns (PointEvaluationsArray[] memory evals) { + for (uint i = 0; i < map.keys.length; i++) { + EncodedArray memory comms = abi.decode(map.values[i], (EncodedArray)); + PolyComm[] memory polycomms = new PolyComm[](comms.values.length); + + for (uint j = 0; j < comms.values.length; j++) { + EncodedMap memory comm = abi.decode(comms.values[i], (EncodedMap)); + EncodedArray memory unshifted_arr = abi.decode(find_value(comm, "unshifted"), (EncodedArray)); + + uint unshifted_length = unshifted_arr.values.length; + BN254.G1Point[] unshifted = new BN254.G1Point[](unshifted_length); + for (uint k = 0; k < unshifted_length; k++) { + EncodedMap memory unshifted_buffer = abi.decode(unshifted_arr.values[k], (EncodedMap)); + unshifted[k] = BN254.g1Deserialize(bytes32(deser_buffer(unshifted_buffer))); + } + + polycomms[j] = PolyComm(unshifted); + } + lagrange_bases_unshifted[bytes32(bytes(map.keys[i]))] = poly_comm_flat(polycomms); + } + } + // !!! FUNCTIONS BELOW ARE DEPRECATED !!! function deserializeFinalCommitments(bytes calldata data) diff --git a/eth_verifier/script/Deploy.s.sol b/eth_verifier/script/Deploy.s.sol index 5a9c4fb4..757cfd8a 100644 --- a/eth_verifier/script/Deploy.s.sol +++ b/eth_verifier/script/Deploy.s.sol @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.4.16 <0.9.0; import {Script, console2} from "forge-std/Script.sol"; import {KimchiVerifier} from "../src/Verifier.sol"; diff --git a/eth_verifier/script/Verify.s.sol b/eth_verifier/script/Verify.s.sol new file mode 100644 index 00000000..1dcf8bd2 --- /dev/null +++ b/eth_verifier/script/Verify.s.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.4.16 <0.9.0; + +import {Script, console2} from "forge-std/Script.sol"; +import {KimchiVerifier} from "../src/Verifier.sol"; +import "forge-std/console.sol"; + +contract Verify is Script { + function run() public { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(deployerPrivateKey); + + KimchiVerifier verifier = new KimchiVerifier(); + + verifier.setup(vm.readFileBinary("urs.mpk")); + + bool success = verifier.verify_with_index( + vm.readFileBinary("verifier_index.mpk"), + vm.readFileBinary("proof.mpk") + ); + console.log(success); + + vm.stopBroadcast(); + } +} From 30e9f121ac48f1c3cc8e3f2b0d4f6c70cf22847f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Wed, 13 Dec 2023 18:22:56 -0300 Subject: [PATCH 37/68] Fixes --- eth_verifier/lib/Commitment.sol | 10 +++++++--- eth_verifier/lib/msgpack/Deserialize.sol | 6 +++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 6462d606..8cbd426b 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -54,12 +54,12 @@ function poly_comm_unflat(PolyCommFlat memory com) pure returns (PolyComm[] memo function poly_comm_flat(PolyComm[] memory com) pure returns (PolyCommFlat memory) { uint total_length = 0; - uint[] unshifted_lengths = new uint[](com.length); + uint[] memory unshifted_lengths = new uint[](com.length); for (uint i = 0; i < com.length; i++) { total_length += com[i].unshifted.length; unshifted_lengths[i] = com[i].unshifted.length; } - BN254.G1Point[] unshifteds = new BN254.G1Point[](total_length); + BN254.G1Point[] memory unshifteds = new BN254.G1Point[](total_length); uint index = 0; for (uint i = 0; i < com.length; i++) { @@ -205,7 +205,11 @@ function calculate_lagrange_bases( } PolyCommFlat storage bases_unshifted = lagrange_bases_unshifted[domain_size]; - bases_unshifted.unshifted_length = unshifted.length; + uint[] memory unshifted_lengths = new uint[](num_unshifteds); + for (uint i = 0; i < num_unshifteds; i++) { + unshifted_lengths[i] = 0; + } + bases_unshifted.unshifted_lengths = unshifted_lengths; for (uint i = 0; i < domain_size; i++) { for (uint j = 0; j < unshifted.length; j++) { diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 3781d2bf..1b16e591 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -502,7 +502,7 @@ library MsgPk { EncodedMap memory map, mapping(uint256 => PolyCommFlat) storage lagrange_bases_unshifted, uint64 domain_size - ) public pure returns (PointEvaluationsArray[] memory evals) { + ) public returns (PointEvaluationsArray[] memory evals) { for (uint i = 0; i < map.keys.length; i++) { EncodedArray memory comms = abi.decode(map.values[i], (EncodedArray)); PolyComm[] memory polycomms = new PolyComm[](comms.values.length); @@ -512,7 +512,7 @@ library MsgPk { EncodedArray memory unshifted_arr = abi.decode(find_value(comm, "unshifted"), (EncodedArray)); uint unshifted_length = unshifted_arr.values.length; - BN254.G1Point[] unshifted = new BN254.G1Point[](unshifted_length); + BN254.G1Point[] memory unshifted = new BN254.G1Point[](unshifted_length); for (uint k = 0; k < unshifted_length; k++) { EncodedMap memory unshifted_buffer = abi.decode(unshifted_arr.values[k], (EncodedMap)); unshifted[k] = BN254.g1Deserialize(bytes32(deser_buffer(unshifted_buffer))); @@ -520,7 +520,7 @@ library MsgPk { polycomms[j] = PolyComm(unshifted); } - lagrange_bases_unshifted[bytes32(bytes(map.keys[i]))] = poly_comm_flat(polycomms); + lagrange_bases_unshifted[uint256(bytes32(bytes(map.keys[i])))] = poly_comm_flat(polycomms); } } From 77b0412e4feb60d055fd8eaad4152b9e6c7c146b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Wed, 13 Dec 2023 19:28:54 -0300 Subject: [PATCH 38/68] Added PairingURS and started deser function --- eth_verifier/lib/Commitment.sol | 5 +++++ eth_verifier/lib/Utils.sol | 3 --- eth_verifier/lib/msgpack/Deserialize.sol | 15 +++++++++++++++ kzg_prover/src/main.rs | 14 +++++--------- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 8cbd426b..54b0bbd5 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -22,6 +22,11 @@ error MSMInvalidLengths(); struct URS { BN254.G1Point[] g; BN254.G1Point h; +} + +struct PairingURS { + URS full_srs; + URS verifier_srs; mapping(uint256 => PolyCommFlat) lagrange_bases_unshifted; } diff --git a/eth_verifier/lib/Utils.sol b/eth_verifier/lib/Utils.sol index d130ec69..1a173ab3 100644 --- a/eth_verifier/lib/Utils.sol +++ b/eth_verifier/lib/Utils.sol @@ -195,9 +195,6 @@ library Utils { Scalar.FE[] memory twiddles = bit_reverse_permut(get_twiddles_inv(order)); BN254.G1Point[] memory unordered_res = nr_2radix_fft(points, twiddles); - console.log(twiddles.length); - console.log(unordered_res.length); - require(false, "adsasdasd"); return bit_reverse_permut(unordered_res); } diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 1b16e591..d83787b2 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -524,6 +524,21 @@ library MsgPk { } } + function deser_pairing_urs(Stream memory self, URS storage urs) public { + EncodedMap memory urs_map = deser_fixmap(self); + + EncodedMap memory full_urs = abi.decode(find_value(urs_map, "full_srs"), (EncodedMap)); + EncodedMap memory verifier_urs = abi.decode(find_value(urs_map, "verifier_srs"), (EncodedMap)); + + EncodedArray memory full_urs_g = abi.decode(find_value(full_urs, "g"), (EncodedArray)); + EncodedMap memory full_urs_h = abi.decode(find_value(full_urs, "h"), (EncodedMap)); + + EncodedArray memory verifier_urs_g = abi.decode(find_value(verifier_urs_g, "g"), (EncodedArray)); + EncodedMap memory verifier_urs_h = abi.decode(find_value(verifier_urs_g, "h"), (EncodedMap)); + + + } + // !!! FUNCTIONS BELOW ARE DEPRECATED !!! function deserializeFinalCommitments(bytes calldata data) diff --git a/kzg_prover/src/main.rs b/kzg_prover/src/main.rs index 8daa4289..233df8d5 100644 --- a/kzg_prover/src/main.rs +++ b/kzg_prover/src/main.rs @@ -1,6 +1,6 @@ mod snarky_gate; -use std::{array, fs, ops::Neg, sync::Arc}; +use std::{array, collections::HashMap, fs, ops::Neg, sync::Arc}; use ark_bn254::{G1Affine, G2Affine}; use ark_ec::{ @@ -98,13 +98,11 @@ fn generate_test_proof_ex() { .unwrap(); let x = ark_bn254::Fr::rand(rng); - let srs = Arc::new(create_srs(x, cs.gates.len(), cs.domain)); - - let ptr: &mut SRS = unsafe { &mut *(std::sync::Arc::as_ptr(&srs) as *mut _) }; - ptr.add_lagrange_basis(cs.domain.d1); + let mut srs = create_srs(x, cs.gates.len(), cs.domain); + srs.full_srs.add_lagrange_basis(cs.domain.d1); let (_endo_r, endo_q) = G1::endos(); - let index = ProverIndex::::create(cs, *endo_q, srs); + let index = ProverIndex::::create(cs, *endo_q, Arc::new(srs.clone())); let group_map = ::Map::setup(); let proof = ProverProof::create_recursive::( @@ -117,8 +115,6 @@ fn generate_test_proof_ex() { ) .unwrap(); - println!("{:#?}", proof.evals.z.zeta); - fs::write( "../eth_verifier/prover_proof.mpk", rmp_serde::to_vec_named(&proof).unwrap(), @@ -131,7 +127,7 @@ fn generate_test_proof_ex() { .unwrap(); fs::write( "../eth_verifier/urs.mpk", - rmp_serde::to_vec_named(&index.verifier_index().srs().verifier_srs).unwrap(), + rmp_serde::to_vec_named(&srs).unwrap(), ) .unwrap(); } From f12070760f5f618138ba948153bab51d1ec0aa25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Thu, 14 Dec 2023 12:47:23 -0300 Subject: [PATCH 39/68] Finished writing URS deserializer and forge script --- eth_verifier/Makefile | 4 ++ eth_verifier/foundry.toml | 2 +- eth_verifier/lib/Commitment.sol | 4 +- eth_verifier/lib/VerifierIndex.sol | 1 - eth_verifier/lib/msgpack/Deserialize.sol | 47 +++++++++++++++++++----- eth_verifier/src/Verifier.sol | 26 ++++++------- 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/eth_verifier/Makefile b/eth_verifier/Makefile index dbcd7592..642ace36 100644 --- a/eth_verifier/Makefile +++ b/eth_verifier/Makefile @@ -13,3 +13,7 @@ run_node: deploy_and_verify: PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ forge script script/Deploy.s.sol:DeployAndVerify --via-ir --broadcast --rpc-url http://localhost:8545 + +verify: + PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ + forge script script/Verify.s.sol:Verify --via-ir --broadcast --rpc-url http://localhost:8545 diff --git a/eth_verifier/foundry.toml b/eth_verifier/foundry.toml index 51f136ce..ab0cd1e9 100644 --- a/eth_verifier/foundry.toml +++ b/eth_verifier/foundry.toml @@ -2,6 +2,6 @@ src = "src" out = "out" libs = ["lib"] -fs_permissions = [{ access = "read", path = "./proof.mpk"}, { access = "read", path = "./state.mpk"}] +fs_permissions = [{ access = "read", path = "./proof.mpk"}, { access = "read", path = "./state.mpk"}, { access = "read", path = "./urs.mpk"}] # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 54b0bbd5..c77357e6 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -25,8 +25,8 @@ struct URS { } struct PairingURS { - URS full_srs; - URS verifier_srs; + URS full_urs; + URS verifier_urs; mapping(uint256 => PolyCommFlat) lagrange_bases_unshifted; } diff --git a/eth_verifier/lib/VerifierIndex.sol b/eth_verifier/lib/VerifierIndex.sol index bc9f447d..ad1cf8ea 100644 --- a/eth_verifier/lib/VerifierIndex.sol +++ b/eth_verifier/lib/VerifierIndex.sol @@ -14,7 +14,6 @@ struct VerifierIndex { uint256 max_poly_size; // the number of randomized rows to achieve zero knowledge uint64 zk_rows; - URS urs; // domain uint64 domain_size; Scalar.FE domain_gen; diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index d83787b2..b2e5b19f 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -500,9 +500,8 @@ library MsgPk { function deser_lagrange_bases( EncodedMap memory map, - mapping(uint256 => PolyCommFlat) storage lagrange_bases_unshifted, - uint64 domain_size - ) public returns (PointEvaluationsArray[] memory evals) { + mapping(uint256 => PolyCommFlat) storage lagrange_bases_unshifted + ) public { for (uint i = 0; i < map.keys.length; i++) { EncodedArray memory comms = abi.decode(map.values[i], (EncodedArray)); PolyComm[] memory polycomms = new PolyComm[](comms.values.length); @@ -524,19 +523,47 @@ library MsgPk { } } - function deser_pairing_urs(Stream memory self, URS storage urs) public { + function deser_pairing_urs(Stream memory self, PairingURS storage urs) public { + // full_srs and verifier_srs fields EncodedMap memory urs_map = deser_fixmap(self); - EncodedMap memory full_urs = abi.decode(find_value(urs_map, "full_srs"), (EncodedMap)); - EncodedMap memory verifier_urs = abi.decode(find_value(urs_map, "verifier_srs"), (EncodedMap)); + EncodedMap memory full_urs_serialized = abi.decode(find_value(urs_map, "full_srs"), (EncodedMap)); + EncodedMap memory verifier_urs_serialized = abi.decode(find_value(urs_map, "verifier_srs"), (EncodedMap)); - EncodedArray memory full_urs_g = abi.decode(find_value(full_urs, "g"), (EncodedArray)); - EncodedMap memory full_urs_h = abi.decode(find_value(full_urs, "h"), (EncodedMap)); + // get data from g and h fields (g is an array of buffers and h is a buffer) + EncodedArray memory full_urs_g_serialized = abi.decode(find_value(full_urs_serialized, "g"), (EncodedArray)); + EncodedMap memory full_urs_h_serialized = abi.decode(find_value(full_urs_serialized, "h"), (EncodedMap)); - EncodedArray memory verifier_urs_g = abi.decode(find_value(verifier_urs_g, "g"), (EncodedArray)); - EncodedMap memory verifier_urs_h = abi.decode(find_value(verifier_urs_g, "h"), (EncodedMap)); + EncodedArray memory verifier_urs_g_serialized = abi.decode(find_value(verifier_urs_serialized, "g"), (EncodedArray)); + EncodedMap memory verifier_urs_h_serialized = abi.decode(find_value(verifier_urs_serialized, "h"), (EncodedMap)); + // deserialized and save g for both URS + uint full_urs_g_length = full_urs_g_serialized.values.length; + BN254.G1Point[] memory full_urs_g = new BN254.G1Point[](full_urs_g_length); + for (uint i = 0; i < full_urs_g_length; i++) { + full_urs_g[i] = BN254.g1Deserialize(bytes32(deser_buffer(abi.decode(full_urs_g_serialized.values[i], (EncodedMap))))); + } + + uint verifier_urs_g_length = verifier_urs_g_serialized.values.length; + BN254.G1Point[] memory verifier_urs_g = new BN254.G1Point[](verifier_urs_g_length); + for (uint i = 0; i < verifier_urs_g_length; i++) { + verifier_urs_g[i] = BN254.g1Deserialize(bytes32(deser_buffer(abi.decode(verifier_urs_g_serialized.values[i], (EncodedMap))))); + } + + // deserialized and save h for both URS + BN254.G1Point memory full_urs_h = BN254.g1Deserialize(bytes32(deser_buffer(full_urs_h_serialized))); + BN254.G1Point memory verifier_urs_h = BN254.g1Deserialize(bytes32(deser_buffer(verifier_urs_h_serialized))); + + // store values + urs.full_urs.g = full_urs_g; + urs.full_urs.h = full_urs_h; + + urs.verifier_urs.g = verifier_urs_g; + urs.verifier_urs.h = verifier_urs_h; + // deserialize and store lagrange bases + EncodedMap memory lagrange_b_serialized = abi.decode(find_value(full_urs_serialized, "lagrange_bases"), (EncodedMap)); + deser_lagrange_bases(lagrange_b_serialized, urs.lagrange_bases_unshifted); } // !!! FUNCTIONS BELOW ARE DEPRECATED !!! diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 5bcfe4c0..eee5289a 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -57,6 +57,7 @@ contract KimchiVerifier { VerifierIndex verifier_index; ProverProof proof; + PairingURS urs; Sponge base_sponge; Sponge scalar_sponge; @@ -67,10 +68,7 @@ contract KimchiVerifier { function setup( bytes memory urs_serialized ) public { - (BN254.G1Point[] memory g, BN254.G1Point memory h, uint256 _i0) = MsgPk - .deserializeURS(urs_serialized); - verifier_index.urs.g = g; - verifier_index.urs.h = h; + MsgPk.deser_pairing_urs(MsgPk.new_stream(urs_serialized), urs); verifier_index.powers_of_alpha.register(ArgumentType.GateZero, 21); verifier_index.powers_of_alpha.register(ArgumentType.Permutation, 3); @@ -93,14 +91,15 @@ contract KimchiVerifier { proof ); - calculate_lagrange_bases( - verifier_index.urs.g, - verifier_index.urs.h, - verifier_index.domain_size, - verifier_index.urs.lagrange_bases_unshifted - ); + //calculate_lagrange_bases( + // verifier_index.urs.g, + // verifier_index.urs.h, + // verifier_index.domain_size, + // verifier_index.urs.lagrange_bases_unshifted + //); partial_verify(new Scalar.FE[](0)); + // final_verify(); return false; } @@ -153,8 +152,7 @@ contract KimchiVerifier { if (public_inputs.length != verifier_index.public_len) { revert IncorrectPublicInputLength(); } - PolyCommFlat memory lgr_comm_flat = verifier_index - .urs + PolyCommFlat memory lgr_comm_flat = urs .lagrange_bases_unshifted[verifier_index.domain_size]; PolyComm[] memory comm = new PolyComm[](verifier_index.public_len); PolyComm[] memory lgr_comm = poly_comm_unflat(lgr_comm_flat); @@ -166,7 +164,7 @@ contract KimchiVerifier { if (public_inputs.length == 0) { BN254.G1Point[] memory blindings = new BN254.G1Point[](chunk_size); for (uint256 i = 0; i < chunk_size; i++) { - blindings[i] = verifier_index.urs.h; + blindings[i] = urs.full_urs.h; } public_comm = PolyComm(blindings); } else { @@ -182,7 +180,7 @@ contract KimchiVerifier { blinders[i] = Scalar.FE.wrap(1); } public_comm = mask_custom( - verifier_index.urs, + urs.full_urs, public_comm_tmp, blinders ).commitment; From 57434c52a6cb03d4471e73e3b6938e6ad1e1b99a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Thu, 14 Dec 2023 15:45:56 -0300 Subject: [PATCH 40/68] Fix EncodedMap non-string keys --- eth_verifier/lib/msgpack/Deserialize.sol | 70 ++++++++++++------------ eth_verifier/script/Verify.s.sol | 4 +- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index b2e5b19f..eb56d3bf 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -25,7 +25,7 @@ library MsgPk { } struct EncodedMap { - string[] keys; + bytes[] keys; // encoded strings or integers bytes[] values; } @@ -60,9 +60,9 @@ library MsgPk { self.curr_index += n; } - error EncodedMapKeyNotFound(); + error EncodedMapKeyNotFound(bytes key, bytes[] stored_keys); - function find_value(EncodedMap memory self, string memory key) + function find_value(EncodedMap memory self, bytes memory key) public pure returns (bytes memory) @@ -70,11 +70,11 @@ library MsgPk { uint256 i = 0; while ( i != self.keys.length && - keccak256(bytes(self.keys[i])) != keccak256(bytes(key)) + keccak256(self.keys[i]) != keccak256(key) ) { i++; } - if (i == self.keys.length) revert EncodedMapKeyNotFound(); + if (i == self.keys.length) revert EncodedMapKeyNotFound(key, self.keys); return self.values[i]; } @@ -187,10 +187,10 @@ library MsgPk { require(first >> 4 == 0x08, "not a fixmap"); uint256 n = uint256(uint8(first & 0x0F)); // low nibble - map = EncodedMap(new string[](n), new bytes[](n)); + map = EncodedMap(new bytes[](n), new bytes[](n)); for (uint256 i = 0; i < n; i++) { - map.keys[i] = deser_str(self); + map.keys[i] = deser_encode(self); map.values[i] = deser_encode(self); } } @@ -224,10 +224,10 @@ library MsgPk { uint16 n = uint16(bytes2(next_n(self, 2))); - map = EncodedMap(new string[](n), new bytes[](n)); + map = EncodedMap(new bytes[](n), new bytes[](n)); for (uint16 i = 0; i < n; i++) { - map.keys[i] = deser_str(self); + map.keys[i] = deser_encode(self); map.values[i] = deser_encode(self); } } @@ -280,11 +280,11 @@ library MsgPk { pure returns (bytes memory data) { - bytes memory type_name = abi.decode(find_value(self, "type"), (bytes)); + bytes memory type_name = abi.decode(find_value(self, abi.encode("type")), (bytes)); require(keccak256(type_name) == keccak256("Buffer")); EncodedArray memory data_arr = abi.decode( - find_value(self, "data"), + find_value(self, abi.encode("data")), (EncodedArray) ); @@ -306,11 +306,11 @@ library MsgPk { pure returns (uint256 integer) { - bytes memory type_name = abi.decode(find_value(self, "type"), (bytes)); + bytes memory type_name = abi.decode(find_value(self, abi.encode("type")), (bytes)); require(keccak256(type_name) == keccak256("Buffer")); EncodedArray memory data_arr = abi.decode( - find_value(self, "data"), + find_value(self, abi.encode("data")), (EncodedArray) ); @@ -322,15 +322,15 @@ library MsgPk { VerifierIndex storage index ) external { EncodedMap memory map = deser_map16(self); - index.public_len = abi.decode(find_value(map, "public"), (uint256)); + index.public_len = abi.decode(find_value(map, abi.encode("public")), (uint256)); index.max_poly_size = abi.decode( - find_value(map, "max_poly_size"), + find_value(map, abi.encode("max_poly_size")), (uint256) ); - index.zk_rows = abi.decode(find_value(map, "zk_rows"), (uint64)); + index.zk_rows = abi.decode(find_value(map, abi.encode("zk_rows")), (uint64)); EncodedMap memory domain_map = abi.decode( - find_value(map, "domain"), + find_value(map, abi.encode("domain")), (EncodedMap) ); @@ -355,7 +355,7 @@ library MsgPk { // wire shift coordinates EncodedArray memory shift_arr = abi.decode( - find_value(map, "shift"), + find_value(map, abi.encode("shift")), (EncodedArray) ); require(shift_arr.values.length == 7, "shift array is not of length 7"); @@ -377,7 +377,7 @@ library MsgPk { EncodedMap memory map = deser_fixmap(self); EncodedMap memory all_evals_map = abi.decode( - find_value(map, "evals"), + find_value(map, abi.encode("evals")), (EncodedMap) ); @@ -409,16 +409,16 @@ library MsgPk { returns (PointEvaluationsArray memory) { EncodedMap memory eval_map = abi.decode( - find_value(all_evals_map, name), + find_value(all_evals_map, abi.encode(name)), (EncodedMap) ); EncodedArray memory zeta_arr = abi.decode( - find_value(eval_map, "zeta"), + find_value(eval_map, abi.encode("zeta")), (EncodedArray) ); EncodedArray memory zeta_omega_arr = abi.decode( - find_value(eval_map, "zeta_omega"), + find_value(eval_map, abi.encode("zeta_omega")), (EncodedArray) ); require(zeta_arr.values.length == zeta_omega_arr.values.length); @@ -451,7 +451,7 @@ library MsgPk { string memory name ) public pure returns (PointEvaluationsArray[] memory evals) { EncodedArray memory eval_array = abi.decode( - find_value(all_evals_map, name), + find_value(all_evals_map, abi.encode(name)), (EncodedArray) ); uint256 length = eval_array.values.length; @@ -464,11 +464,11 @@ library MsgPk { ); EncodedArray memory zeta_arr = abi.decode( - find_value(eval_map, "zeta"), + find_value(eval_map, abi.encode("zeta")), (EncodedArray) ); EncodedArray memory zeta_omega_arr = abi.decode( - find_value(eval_map, "zeta_omega"), + find_value(eval_map, abi.encode("zeta_omega")), (EncodedArray) ); require(zeta_arr.values.length == zeta_omega_arr.values.length); @@ -508,7 +508,7 @@ library MsgPk { for (uint j = 0; j < comms.values.length; j++) { EncodedMap memory comm = abi.decode(comms.values[i], (EncodedMap)); - EncodedArray memory unshifted_arr = abi.decode(find_value(comm, "unshifted"), (EncodedArray)); + EncodedArray memory unshifted_arr = abi.decode(find_value(comm, abi.encode("unshifted")), (EncodedArray)); uint unshifted_length = unshifted_arr.values.length; BN254.G1Point[] memory unshifted = new BN254.G1Point[](unshifted_length); @@ -519,23 +519,25 @@ library MsgPk { polycomms[j] = PolyComm(unshifted); } - lagrange_bases_unshifted[uint256(bytes32(bytes(map.keys[i])))] = poly_comm_flat(polycomms); + lagrange_bases_unshifted[abi.decode(map.keys[i], (uint256))] = poly_comm_flat(polycomms); } } function deser_pairing_urs(Stream memory self, PairingURS storage urs) public { // full_srs and verifier_srs fields + console.log("before"); EncodedMap memory urs_map = deser_fixmap(self); + console.log("after"); - EncodedMap memory full_urs_serialized = abi.decode(find_value(urs_map, "full_srs"), (EncodedMap)); - EncodedMap memory verifier_urs_serialized = abi.decode(find_value(urs_map, "verifier_srs"), (EncodedMap)); + EncodedMap memory full_urs_serialized = abi.decode(find_value(urs_map, abi.encode("full_srs")), (EncodedMap)); + EncodedMap memory verifier_urs_serialized = abi.decode(find_value(urs_map, abi.encode("verifier_srs")), (EncodedMap)); // get data from g and h fields (g is an array of buffers and h is a buffer) - EncodedArray memory full_urs_g_serialized = abi.decode(find_value(full_urs_serialized, "g"), (EncodedArray)); - EncodedMap memory full_urs_h_serialized = abi.decode(find_value(full_urs_serialized, "h"), (EncodedMap)); + EncodedArray memory full_urs_g_serialized = abi.decode(find_value(full_urs_serialized, abi.encode("g")), (EncodedArray)); + EncodedMap memory full_urs_h_serialized = abi.decode(find_value(full_urs_serialized, abi.encode("h")), (EncodedMap)); - EncodedArray memory verifier_urs_g_serialized = abi.decode(find_value(verifier_urs_serialized, "g"), (EncodedArray)); - EncodedMap memory verifier_urs_h_serialized = abi.decode(find_value(verifier_urs_serialized, "h"), (EncodedMap)); + EncodedArray memory verifier_urs_g_serialized = abi.decode(find_value(verifier_urs_serialized, abi.encode("g")), (EncodedArray)); + EncodedMap memory verifier_urs_h_serialized = abi.decode(find_value(verifier_urs_serialized, abi.encode("h")), (EncodedMap)); // deserialized and save g for both URS uint full_urs_g_length = full_urs_g_serialized.values.length; @@ -562,7 +564,7 @@ library MsgPk { urs.verifier_urs.h = verifier_urs_h; // deserialize and store lagrange bases - EncodedMap memory lagrange_b_serialized = abi.decode(find_value(full_urs_serialized, "lagrange_bases"), (EncodedMap)); + EncodedMap memory lagrange_b_serialized = abi.decode(find_value(full_urs_serialized, abi.encode("lagrange_bases")), (EncodedMap)); deser_lagrange_bases(lagrange_b_serialized, urs.lagrange_bases_unshifted); } diff --git a/eth_verifier/script/Verify.s.sol b/eth_verifier/script/Verify.s.sol index 1dcf8bd2..1f0c8263 100644 --- a/eth_verifier/script/Verify.s.sol +++ b/eth_verifier/script/Verify.s.sol @@ -11,8 +11,8 @@ contract Verify is Script { vm.startBroadcast(deployerPrivateKey); KimchiVerifier verifier = new KimchiVerifier(); - - verifier.setup(vm.readFileBinary("urs.mpk")); + bytes memory urs_serialized = vm.readFileBinary("urs.mpk"); + verifier.setup(urs_serialized); bool success = verifier.verify_with_index( vm.readFileBinary("verifier_index.mpk"), From 571f8d460084ec5a6ab7ee6843959f39992ce539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Thu, 14 Dec 2023 16:34:25 -0300 Subject: [PATCH 41/68] Remove duplicated function --- kzg_prover/src/main.rs | 53 ------------------------------------------ 1 file changed, 53 deletions(-) diff --git a/kzg_prover/src/main.rs b/kzg_prover/src/main.rs index e0ac70e4..7b738ab6 100644 --- a/kzg_prover/src/main.rs +++ b/kzg_prover/src/main.rs @@ -297,59 +297,6 @@ fn generate_test_proof() { println!("Is test circuit's KZG proof valid?: {:?}", verified); } -fn generate_test_proof() { - let public_input: Vec = vec![42.into(); 5]; - let gates = create_circuit::(0, public_input.len()); - - // create witness - let mut witness: [Vec<_>; COLUMNS] = array::from_fn(|_| vec![0.into(); gates.len()]); - fill_in_witness::(0, &mut witness, &[]); - - let cs = ConstraintSystem::::create(gates) - .build() - .unwrap(); - - const ZK_ROWS: usize = 3; - let domain_size = cs.gates.len() + ZK_ROWS; - let domain = EvaluationDomains::create(domain_size).unwrap(); - - let n = domain.d1.size as usize; - - let srs = create_srs(42.into(), n, domain); - let endo_q = G1::endos().1; - let prover_index = - ProverIndex::>>::create( - cs, - endo_q, - Arc::new(srs.clone()), - ); - - let groupmap = ::Map::setup(); - let prover_proof = ProverProof::create::( - &groupmap, - witness, - &[], - &prover_index, - ) - .unwrap(); - - fs::write( - "../eth_verifier/verifier_index.mpk", - rmp_serde::to_vec(&prover_index.verifier_index()).unwrap(), - ) - .unwrap(); - - let context = Context { - verifier_index: &prover_index.verifier_index(), - proof: &prover_proof, - public_input: &public_input, - }; - - let verified = - batch_verify::(&groupmap, &[context]).is_ok(); - println!("Is test circuit's KZG proof valid?: {:?}", verified); -} - fn serialize_g1point_for_verifier(point: G1Affine) -> Result, SerializationError> { let mut point_serialized = vec![]; point.serialize_uncompressed(&mut point_serialized)?; From 7f17a60dd0f5f35084cc2d682b7412047fc5141d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Fri, 15 Dec 2023 17:46:25 -0300 Subject: [PATCH 42/68] Remove logs --- eth_verifier/lib/msgpack/Deserialize.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index eb56d3bf..00cf55fc 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -525,9 +525,7 @@ library MsgPk { function deser_pairing_urs(Stream memory self, PairingURS storage urs) public { // full_srs and verifier_srs fields - console.log("before"); EncodedMap memory urs_map = deser_fixmap(self); - console.log("after"); EncodedMap memory full_urs_serialized = abi.decode(find_value(urs_map, abi.encode("full_srs")), (EncodedMap)); EncodedMap memory verifier_urs_serialized = abi.decode(find_value(urs_map, abi.encode("verifier_srs")), (EncodedMap)); From 79943a956e34c4a9dbdb6f833fc7e03302cdd91c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Fri, 15 Dec 2023 19:28:07 -0300 Subject: [PATCH 43/68] Random URS and lagrange bases --- eth_verifier/foundry.toml | 7 ++++++- eth_verifier/lib/Commitment.sol | 28 ++++++++++++++++++++++++++++ eth_verifier/src/Verifier.sol | 7 ++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/eth_verifier/foundry.toml b/eth_verifier/foundry.toml index ab0cd1e9..a093cf81 100644 --- a/eth_verifier/foundry.toml +++ b/eth_verifier/foundry.toml @@ -2,6 +2,11 @@ src = "src" out = "out" libs = ["lib"] -fs_permissions = [{ access = "read", path = "./proof.mpk"}, { access = "read", path = "./state.mpk"}, { access = "read", path = "./urs.mpk"}] +fs_permissions = [ + { access = "read", path = "./proof.mpk"}, + { access = "read", path = "./state.mpk"}, + { access = "read", path = "./urs.mpk"}, + { access = "read", path = "./verifier_index.mpk"} +] # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index c77357e6..c8ed298d 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -24,12 +24,40 @@ struct URS { BN254.G1Point h; } +function create_trusted_setup(Scalar.FE x, uint depth) view returns (URS memory) { + Scalar.FE x_pow = Scalar.one(); + BN254.G1Point[] memory g = new BN254.G1Point[](depth); + BN254.G1Point memory h = BN254.P1(); // should be blake2b hash + + for (uint i = 0; i < depth; i++) { + g[i] = BN254.P1().scale_scalar(x_pow); + x_pow = x_pow.mul(x); + } + + return URS(g, h); +} + struct PairingURS { URS full_urs; URS verifier_urs; mapping(uint256 => PolyCommFlat) lagrange_bases_unshifted; } +function random_lagrange_bases(PairingURS storage urs, uint domain_size) { + uint n = domain_size; + + uint[] memory u_lengths = new uint[](1); + u_lengths[0] = domain_size; + + BN254.G1Point[] memory unshifteds = new BN254.G1Point[](domain_size); + for (uint i = 0; i < domain_size; i++) { + unshifteds[i] = BN254.P1(); + } + + PolyCommFlat memory comms = PolyCommFlat(unshifteds, u_lengths); + urs.lagrange_bases_unshifted[domain_size] = comms; +} + struct PolyComm { BN254.G1Point[] unshifted; //BN254G1Point shifted; diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index eee5289a..53a0bf7d 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -68,7 +68,12 @@ contract KimchiVerifier { function setup( bytes memory urs_serialized ) public { - MsgPk.deser_pairing_urs(MsgPk.new_stream(urs_serialized), urs); + //MsgPk.deser_pairing_urs(MsgPk.new_stream(urs_serialized), urs); + // URS deserialization is WIP, we'll generate a random one for now: + Scalar.FE x = Scalar.from(42); + uint max_domain_size = 16384; + urs.full_urs = create_trusted_setup(x, max_domain_size); + urs.verifier_urs = create_trusted_setup(x, 3); verifier_index.powers_of_alpha.register(ArgumentType.GateZero, 21); verifier_index.powers_of_alpha.register(ArgumentType.Permutation, 3); From 5f1ad803c0c91b54e837e015e3f1beacb1220bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 18 Dec 2023 12:29:42 -0300 Subject: [PATCH 44/68] Temporarily remove URS serialization --- eth_verifier/script/Verify.s.sol | 12 ++++++++---- eth_verifier/src/Verifier.sol | 4 +--- eth_verifier/test/Deserialize.t.sol | 3 +-- eth_verifier/test/Integration.t.sol | 6 +++--- eth_verifier/test/State.t.sol | 6 +++--- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/eth_verifier/script/Verify.s.sol b/eth_verifier/script/Verify.s.sol index 1f0c8263..d2ef0d54 100644 --- a/eth_verifier/script/Verify.s.sol +++ b/eth_verifier/script/Verify.s.sol @@ -6,17 +6,21 @@ import {KimchiVerifier} from "../src/Verifier.sol"; import "forge-std/console.sol"; contract Verify is Script { + bytes verifier_index_binary = + hex"de0015a6646f6d61696e82a474797065a6427566666572a464617461dc00ac00400000000000000e00000000400000000000000000000000000000000000000000000000000000000000000140ccb0190ccce6cc9ccc81ccabcc89cc97ccd87847ccbfccc65752cca76a7564cca937631b66cca7cce1cc8c6330cc856e7c61ccc201ccaaccadcce6ccaa2074cce13ecca9ccb4cca8cca8ccdc0dccb8514e1fcc81cce4ccd9cccd5156cc962d10cc841c6434cce9cceeccf8ccc0717767ccb07609ccf4cc8c6ecc8e55420d6811cce9cce9cce7066f031c28676666ccc6ccd4ccfbccf3cce7062d4acccacce95cccaecca9cc8b56cccd337cccb5ccb949ccaaccd9135acc94525b13ad6d61785f706f6c795f73697a65cd4000a77a6b5f726f777303a67075626c696300af707265765f6368616c6c656e67657300aa7369676d615f636f6d6d9782a9756e736869667465649182a474797065a6427566666572a464617461dc0020cc8e6a46ccc4cc9a5b053e3accd03acccacc896319ccab43cc88ccafcc887ecc84ccbc3dccacccfb49ccab67ccddcc93cc8aa773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200f751f4138cc9fccefcccaccc43accb9cca01b0810ccab2cccb74c70ccdfccd8cc9521ccc7cca0cccfcca15019ccdecca4a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00205ccc903d4275cc90cc98cc987acce8cca0cc946a33ccdaccb8ccbb386052cc93ccdf725a29ccc840ccf4cc87ccd6ccabcc99a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccdd7526ccddcc86cca2cc9cccd6cc8f0acc937e062e56ccd25e3250cc90cc86ccc958cc84cce0cca5cc9701cc99cc8f7bcca5a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020cc964300cc855f1c7bccb37b55cc854c582f48ccc54938ccab48cc815bccd64a5accc62dcc8c37ccddcce403a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccf9322c5458ccd204ccdecc90cce7ccfbcced5e5accb2ccfc4651ccba62297e0accfcccf2cccaccfbccb0cca05d0421a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccb3183eccf8ccf4cc9410cca465cca4ccd145cc97cc9a4e5fccb92fcceacc81ccd7767434cc99ccc7ccc428ccebccbb6819a773686966746564c0b1636f656666696369656e74735f636f6d6d9f82a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c0ac67656e657269635f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0a870736d5f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0b1636f6d706c6574655f6164645f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0a86d756c5f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0a9656d756c5f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0b3656e646f6d756c5f7363616c61725f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0b172616e67655f636865636b305f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020190c1bcc8c2123cc9301ccc0cccd623dcca5cc91cc84ccebcc871b15076bccf5ccc1ccd7497acc8acc99ccc2260acca4a773686966746564c0b172616e67655f636865636b315f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccfa37ccb2cccfcccb1a44cce4ccf8204dccb54fcc852335cce0075ecc8d6bcc87ccb4cca3ccb47444185c44ccedccafa773686966746564c0b6666f726569676e5f6669656c645f6164645f636f6d6dc0b6666f726569676e5f6669656c645f6d756c5f636f6d6dc0a8786f725f636f6d6dc0a8726f745f636f6d6dc0a573686966749782a474797065a6427566666572a464617461dc0020010000000000000000000000000000000000000000000000000000000000000082a474797065a6427566666572a464617461dc0020cce3cca214cce91334ccd0cccaccf1ccebcc85ccdf5bccd7524d73ccd5cceb7accaf742a7eccb2ccd40bccfdccc8cccdccb90082a474797065a6427566666572a464617461dc00206d0f4433cc9a33cc9fccb8cca4cce4cc9bccf109cc9620ccaa64cc9918482bcc95cca3cc97ccae39ccb9ccec5accd4770082a474797065a6427566666572a464617461dc0020ccb40923ccbd78cce619ccc80a7b39ccc0ccf3ccf11e48005519ccd2ccfeccf16a1f77ccd40545cce5ccc7770082a474797065a6427566666572a464617461dc0020ccf9ccc95cccd6ccb11b38ccdf7855ccfd4d2a036329ccadcccaccd613ccf100ccb92310cc9540356a597c0082a474797065a6427566666572a464617461dc00205a696526ccfa30cc9c412c10cce86604ccc3ccc0ccad2cccd9443dccd85bcc8232037212cc81cccfccbf330082a474797065a6427566666572a464617461dc002043423bccb307ccceccc1cc9f297c41cc88ccdeccb23acccc7b581271cc9b2eccaccccbccf1ccb7034acce6ccaccce800ac6c6f6f6b75705f696e64657886b16a6f696e745f6c6f6f6b75705f75736564c2ac6c6f6f6b75705f7461626c659182a9756e736869667465649182a474797065a6427566666572a464617461dc0020cce6cca15e7ecca10eccd2cc8f0f3361ccc7cca7ccf45ccced5e6d382017cc8ccc832cccfcccc0ccdf0e343eccb1cc80a773686966746564c0b06c6f6f6b75705f73656c6563746f727384a3786f72c0a66c6f6f6b7570c0ab72616e67655f636865636b82a9756e736869667465649182a474797065a6427566666572a464617461dc00201b24636044ccd6cced30ccc611cc85ccd45b2969cc98ccb811ccb754cca5507c08ccd1cc9124cc9b37ccc01721a773686966746564c0a566666d756cc0a97461626c655f69647382a9756e736869667465649182a474797065a6427566666572a464617461dc00205f28cc8bccb342cc8034cca922ccb3cce618ccea3ecc811eccdf61cc81ccb10b7eccf6ccc859ccfd03ccea2b39cca70ea773686966746564c0ab6c6f6f6b75705f696e666f83ab6d61785f7065725f726f7704ae6d61785f6a6f696e745f73697a6501a8666561747572657383a87061747465726e7384a3786f72c2a66c6f6f6b7570c2ab72616e67655f636865636bc3b1666f726569676e5f6669656c645f6d756cc2b16a6f696e745f6c6f6f6b75705f75736564c2b3757365735f72756e74696d655f7461626c6573c2b772756e74696d655f7461626c65735f73656c6563746f72c0"; + bytes proof_binary = + hex"85ab636f6d6d69746d656e747384a6775f636f6d6d9f82a9756e736869667465649182a474797065a6427566666572a464617461dc002046ccdbcc9576ccfc514a0c5e5a53ccdaccddcc8dccc83ecc9ecce2316e7b48cccf6f6a0bcc91cca2cc97752821a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccfbcc8e22ccdeccd16fcccecc926dcce24d592065ccd77cccf77e1279227dcca9ccccccc6ccc2170fccb765ccc8cca8a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020cc895a52ccb03017cc8d7842cc95377fcc94ccf8ccfacc92ccf378590eccfb5255cc876eccaaccd7cc88cca7cc8530cc80a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00207dcc9fccd832cc9bccaccc92cceeccc2cca210ccafcc8f19ccfbcc97ccf004ccb9cc987a70ccc8ccfcccad7c59ccbe59cc86cc92ccaaa773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020cca5cc8accdd1d02cc863205ccedcccdcc976a0262ccadccca14cce0cce925545f08cc8f7b22ccfbcc82ccdfcca0cca0cc89a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020cce53609ccf52cccdbcca9cc90cce91f6eccd17111ccb3cca3ccf5ccdc45ccb8ccfcccf5cceb6328603eccd9ccafccdbcca8cc94a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020382a2e2228ccecccad76025c50cc82ccbe02ccb6cc99ccaecce03ccc85cca9cc98cc8accc8500fccc6592bccc662cc80a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc002073ccd8ccd0ccec275538ccc4cc804b0fccfa0accc16ccc85ccbbccd94439ccbc34ccdc522dcce454ccf9ccec133a08a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccd365cc8b3a32cccfcc8f1c386b4273ccf12cccb9cc97ccba32cce2cc9f59ccae4bccc81e25cc9815ccc3ccf87d1fa773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00203056ccbaccc95dcc9eccd976ccef1264cc84ccfb13ccf601cc8c357fcceb031779cca811ccb21d1eccc1cc8359cc91a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00205fcce1ccf3cc91ccc91559765825ccc6cce3ccf2cc95506d0d2a59ccac1e4c3accf83e4accd64accf8cca7ccdacc88a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00206426ccd2ccb3ccd4cca51d3d57cca2643e1c10cc9d281163cccc71ccc3381eccbc7c56ccffcc9e4dccecccc110a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc002017cc81ccd7656f72434acced28cc9dcca422cce45bcc96cca82765ccc8ccc66870ccbacc93ccfb3f220dcc9320cca5a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc002034ccee4d3909ccf7ccf0cccdccbecca3cc82772128ccbdccd6cc8dccae0b207649cc96ccde03ccb267ccaacc9b584ecc84a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020cccf621620ccfaccf5ccc028ccdb7e6b51ccd34accea53230230ccb8cc81425dccfd5d0ecca136611e2a22a773686966746564c0a67a5f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc00205acc906740cc9ecc8fcca636ccb80a31643e611fccb3ccf3cc81ccaa4c57ccd41fcca62a24ccd0ccc1ccfaccba5bcc99a773686966746564c0a6745f636f6d6d82a9756e736869667465649782a474797065a6427566666572a464617461dc0020cca7cc84275f2657cc8fccc33b5801ccbc2ccce87dccd3cced77306accdfccf967cc993950ccc65d364540cca582a474797065a6427566666572a464617461dc0020ccc7ccd2386dcc91cc8acc87ccf7ccd2ccb3ccc822cca9ccc0ccb25c7615cc9fccfd42ccda710e1acca24850cc9b5f523082a474797065a6427566666572a464617461dc00204423ccfeccb2ccecccb6ccac7b776c7d3a45ccd93e6e27cc9175ccc729cca1ccb90accdc2dccdc79cc9945cca21e82a474797065a6427566666572a464617461dc0020ccf34650ccca4009cceeccf6cc9dccabccc7ccee061c6b00ccf0ccefccdfccbe7639cc952dccdb542eccd42319ccd61b82a474797065a6427566666572a464617461dc0020ccf8ccccccd17ecc9454ccf4034fccafccad55cc8f65ccf0ccb405cce2517172ccafcc9309cc9dccaacc8a202eccc3ccdccc8782a474797065a6427566666572a464617461dc00201b67ccc761ccb2ccd8265accdfccca14cc96ccdc5a5fccef77ccd1053eccb55322ccb7ccc922ccf64837cc90ccad0182a474797065a6427566666572a464617461dc0020cca1103accceccec7c10cc93ccd25775ccceccf0361d52cceb173a465755ccf1ccfacc975e4025cc90cce0ccca23a773686966746564c0a66c6f6f6b757083a6736f727465649582a9756e736869667465649182a474797065a6427566666572a464617461dc0020cc94ccb421ccb7252ecca7ccfd413dccf17f71ccb95319ccaa3c2367cce53a3bccceccde62ccd646cce0cc8e5cccada773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00201e2eccd952ccbb584003cc90ccffcc8ccc98cca75bcc9616230b3834ccbe7bccc8ccb82e194bccb9415e3accafa773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020cccfcc934678ccd80d70ccadccf3ccc55a7fccb6ccfe74ccc214ccd900ccd673cc9c5851452b735162ccd5cc82ccada773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020cce130ccc238ccde2f74cce14a2accda78ccffccd2ccb6cc82cc8bccad7eccc648ccb737cc967d71cce3084a41cc961ba773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccc45132cc881e2324ccc0cca331cc9d1eccfa7748ccc9642469ccf121ccf7ccef11432dccfcccdd7ecc8fcc9ccc98a773686966746564c0a661676772656782a9756e736869667465649182a474797065a6427566666572a464617461dc00201d5dcccbccd52c19ccc9ccefcc9b30cce8cc9b646dccd419763c0eccb04d1677cc8f274957ccb70a04ccd6ccaea773686966746564c0a772756e74696d65c0a570726f6f6682a871756f7469656e7482a474797065a6427566666572a464617461dc0020ccf6ccd312122536cce4ccfeccb5cccfccc51eccac2236514f5563cca842cca1ccb2ccd2ccebccdd76ccd1ccdaccac51cc9aa8626c696e64696e6782a474797065a6427566666572a464617461dc002041ccc148ccf6040bcc933422ccefccfaccde5bccebcc84ccb7ccc5cce17a406571cc8609cc95cca8ccca41cc9ccc863d2ba56576616c73de001aa67075626c696382a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000a1779f82a47a6574619182a474797065a6427566666572a464617461dc0020ccf7ccefccbccce2ccb568cc9d07ccff65cc8bccd8cc9333cc9dccbdcc94cc9d4a19ccd9ccd9cca329440d7c26ccd0ccf0ccf308aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020cc981575ccd516ccf7ccd7470ecc820965cc8e25165277cccdccba5e0a45cca05bcce662cc8d05cca4ccf2412d82a47a6574619182a474797065a6427566666572a464617461dc0020cca7ccceccba7034cca9cc9accf0306ecca72fccd61a4f0566cc92ccb1cc82206722643b4acc9cccb6cc8d0d112caa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccb9ccdf5450ccdbcca7cca5250258cca5cca2ccfeccb13cccfdccf6cc97cc80ccbd73cc99cc8dccd3ccd0ccbcccacccbccc8fccc17e2082a47a6574619182a474797065a6427566666572a464617461dc0020ccbaccc6cc85547c1bccc7ccc7cca7ccbc027eccd173cc86255d654acc8dcce83b211c00ccefccd7ccfeccd4ccdb0827aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccef47cc92ccd2cca0cc8b4c255e6a46453d3762ccdecc9466cceacccb7e071b25ccd01b4dccffcca2ccaacca82d82a47a6574619182a474797065a6427566666572a464617461dc0020ccdbccc009cc9047ccdaccb12b044fccd5461b0ccca24f52ccfacc860d35ccc33dcc83cc98510b571dccbeccdd13aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00201c6e3fccba5ccc85cc89cca703ccdacca270cce7cc9dccde55ccc3cc8041ccdb39ccbdcc95ccf2cceecc93ccc6ccc8ccf8ccc9512682a47a6574619182a474797065a6427566666572a464617461dc00202eccebcca90eccd609ccecccef3b4a61ccabccc40a4a6f31cce46c6d2b4eccad72ccfbccf4ccc30b1accb21a0aaa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccbbccbdccebccebccd3cc933758cc8d4051ccf0302c4c62cccd026accc2ccb4ccd7cccd524601ccc21359cca1ccfb2382a47a6574619182a474797065a6427566666572a464617461dc00201dcc9bcca0cccaccf538ccd97bcce4cca8cce843303fccb843ccb0ccc0ccbcccd5ccfbcc8f4dccd67a5805ccc5cce6cccdcc8d2eaa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020463341ccea67ccde6f19ccc35973cccd116124cccf19ccc37b4b2a2410cc88444957ccf0ccb8cc8bcc852282a47a6574619182a474797065a6427566666572a464617461dc0020ccd7ccb14fccf141cce7ccb6cc9f47ccb1ccfc2a621b622d15ccfc53ccc06c76cce0cc986c3ecc92ccc2ccd0ccabccf01aaa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00204dccf67f4d2dcc863c5d08ccab30083254cc92ccc4cca66f4d6e7668ccb1ccc7cc96ccdeccc4cccaccf1411a0482a47a6574619182a474797065a6427566666572a464617461dc0020ccbfcccf785accd61c42ccfd7accca6b3a72ccfb2a1cccd7662560232fcccacce04e48cc93cce2cce0ccd15b22aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020cce8ccdbccf8cc9b1912cce87206ccb5ccf5ccd6cccdccb819ccde55cc8015cc870eccf8cc9dccf442cca97ecc8bccf6ccf20e2082a47a6574619182a474797065a6427566666572a464617461dc0020ccc07007cc98ccb1ccd1ccb54138362062ccf922ccbdcce6cc9acc9460cc874f554520155eccadcced7d4a0521aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020cc8bcc90ccad646ccc856bccbecca4cccd43651477cccbccac6acc9dcce6cc8f1c50ccf1cca85ccc8eccebccc564ccafccf91e82a47a6574619182a474797065a6427566666572a464617461dc0020ccc634391c454accdacc8766ccb7cc940944ccf70309ccaeccb5ccb81a42cc98cce23d670e21cce26ecc943a06aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccceccdd14ccf37e26ccb67bcce7ccf5cce2ccf7220accbacce9280ccc85cccbccc0cc98486e001eccd5ccbdcca2061b2e82a47a6574619182a474797065a6427566666572a464617461dc00201516cccc11ccef60cca2ccf748cca6ccc8757d13cce0cca1cc95ccf3cccf7a4f3bcc9dccf066573f47ccc0ccc8cc9d1aaa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc002057cce1cccdcca33b21250e360accf5cc94401812545e51cc88556acce161ccbb5648cca627cce5cc92352382a47a6574619182a474797065a6427566666572a464617461dc00200a7bccf066ccdb5d76cca2ccf1ccdbccc22710cc9c1ecca6cca8cc936c77551c7bccad591712ccc1ccd61e6a14aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020cc8fccd1ccd272cccfccbeccbdccd811ccdcccee48ccef53565043ccd6cc82ccfb65587f6cccdbccf7cccdccf2cc9eccedcce40a82a47a6574619182a474797065a6427566666572a464617461dc00200b44ccbdcc85cc8a1dcc8d186229ccc634cc9221632e3ccc9ccc88cc9a50cc87ccb7ccd66acca56ecceaccc3ccaa1a26aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccdecc95ccadccdf7910163117cc97cce941367368ccbf487608ccfa731537ccfb47cc81cce750ccc4ccf1ccdb2082a47a6574619182a474797065a6427566666572a464617461dc0020ccd31bccf155cc9acc993d36cc9512cce2ccf811ccd2cca5cca3cc9dccca71cc941e2532ccafccf7ccbbccc961361e0b26aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00206106ccee71384cccb0ccf6ccfacceb2f43cc8cccd670ccd7ccd1cc860ccce620ccee1f524e1d32ccddccbbcc946f2082a47a6574619182a474797065a6427566666572a464617461dc00204444ccc2cc96ccbccc8b6c3a1fcce436ccab0e41cc8450cc9dccfbcc9dcc815446ccb3ccfb514844ccc51106cca900aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020082a45ccd7ccf1cc9acc8fcc8651cc9acc9d50cc89cca30e465b4fcc9f4ccc9a4120cc9a52ccdfccfd0219ccc9cca11aa17a82a47a6574619182a474797065a6427566666572a464617461dc002024cceccccc6accb93b47cccf654138cc8e756e0b23ccf9cca76ecca6ccd3cccd142c692c4a28cce5ccf06a17aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccfdcc89cc9f16215e5ecca93bcc9fccf0ccc8ccfbccdf50087754cc86ccf2cc85ccffccbfccc8ccfa25523ecc9841ccd700a1739682a47a6574619182a474797065a6427566666572a464617461dc002035cc80cce3cc896e74260643ccc4050202143a6ccca810ccd5ccd5784733cccd684d1ecc89ccebccefccf616aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccadccd4ccbd1a64cca1532fccfccca7ccaa7c5307ccb0ccac7c0b3e3524ccc019ccf2ccad4accf4ccad3765ccdb2c82a47a6574619182a474797065a6427566666572a464617461dc002032ccf8ccfaccdd60ccb04f6c3f04ccd94667ccbdcc8f1dccc6cc87ccb35b48ccebcc8b357b700544ccfe6c7a24aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00204564ccf823cc8458cc8e42ccae3c1eccdcccf80c01ccc9ccba5ccc8acc8b6e046a4f26cc94cce835ccb218cceb0482a47a6574619182a474797065a6427566666572a464617461dc00200bcca97e35cce7ccf76fcc876dccfd44cce2ccae6d0cccc908ccaeccb22a15ccb4ccc2ccc4ccbbcca4cce8ccab4b5c5606aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc002014cce334cca9773f59ccf1cc95cccf68cce8ccccccfa6a5acc97cce01b1accbb07ccab49ccd253ccb367cce44cccb00b82a47a6574619182a474797065a6427566666572a464617461dc0020753c61cca071cc9ecc8d3b54322b23ccc85b6dccdcccb2ccf2cce9cca249656b59ccfc1c294830ccdd0207aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020cc81cca5ccef75cca70059cce3cc89ccfecc94ccd26768cc9ccccacca6ccdeccfdccd1ccf0cceecc98ccefccd55410ccfeccc259ccc61582a47a6574619182a474797065a6427566666572a464617461dc0020ccf4ccd8ccab7121cc8dcccf2fccc01ecc9e71cce93bccc97fccc2ccf727693c3f0dccb0ccc7ccee5dccdbcc9333ccb314aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccb8cce727cc84ccaeccf45ccc89cc82cca8cc9a79485bccdccca2ccc8ccb4ccb1ccdaccfeccc7cca10eccaa6ecc85071807cc802882a47a6574619182a474797065a6427566666572a464617461dc002062456a79cccf7dcc9cccf9ccd0411216cc8660ccecccb45350043cccbf0046ccb169ccf35528cc92cca2ccee07aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccb2ccd0cc890accd0ccb526ccf8cc87ccdf13cceecce6cc9e7e033c0577321d0bccdb33ccd32431ccb77b24ccc62aac636f656666696369656e74739f82a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020000000000000000000000000000000000000000000000000000000000000000082a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000b067656e657269635f73656c6563746f7282a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000b1706f736569646f6e5f73656c6563746f7282a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000b5636f6d706c6574655f6164645f73656c6563746f7282a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000ac6d756c5f73656c6563746f7282a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000ad656d756c5f73656c6563746f7282a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000b7656e646f6d756c5f7363616c61725f73656c6563746f7282a47a6574619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000000b572616e67655f636865636b305f73656c6563746f7282a47a6574619182a474797065a6427566666572a464617461dc0020ccd9cce41fccefccaaccf9ccb5145702272f7d3d60ccc6cc9c414dcca3cc8206ccf66e19cca1cc84cc9943cca40723aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc002069ccbe78cc99cc904a11cce304cc882e3dcc9ccccd2fccce6320cc9b0233ccb5cc86cceaccccccbe42cc9cccd261ccc61fb572616e67655f636865636b315f73656c6563746f7282a47a6574619182a474797065a6427566666572a464617461dc0020ccc7ccb75eccb746cc906d3eccf8cca6ccd5ccf4cc9eccce0a6eccb8ccbdccfe2b6d1d1f5ecc8bcca6cce6cca6ccd368ccd209aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00206acca4ccae47ccf6cc95cc91cc82660326cc8accfacc9bccadccc013332229ccacccb823232e37220b0fcce0cce31cba666f726569676e5f6669656c645f6164645f73656c6563746f72c0ba666f726569676e5f6669656c645f6d756c5f73656c6563746f72c0ac786f725f73656c6563746f72c0ac726f745f73656c6563746f72c0b26c6f6f6b75705f6167677265676174696f6e82a47a6574619182a474797065a6427566666572a464617461dc0020cccaccbc79cc97ccdfcce14c0d5918ccbcccac48cce452ccfc47cccdccce56ccabccc3cccb54cc9b1118cc9d0e08ccc108aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00206accc656ccc9436f74ccb557cc93cc8ecccf6c67cc8b3e0d0b4e167660cc9eccd0ccf5ccde0a73cccbccb73f27ac6c6f6f6b75705f7461626c6582a47a6574619182a474797065a6427566666572a464617461dc0020ccab51ccf2cce4cceccceccca96d0fccc5ccec1d7e71ccb0ccc4ccf0cce728ccee3fcca9ccb224cc8a48ccea18ccc368cccc16aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccc6ccf5cc9fcceccc85cc9acc89460accef2f731643cc9d5c01ccd82dcc943d6cccbecce65fccb9cc830f5a742a1bad6c6f6f6b75705f736f727465649582a47a6574619182a474797065a6427566666572a464617461dc00200a5acc9e0033ccfdcccb3f700d3953ccd4ccf310ccb2ccfeccb53a2ccca4ccd3cce2cce8ccdc2fcc99cc95ccfdcc88cce718aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020cc94ccb723cc94ccfbccae44cce3ccba3dcc84ccedccca255179ccaeccf8ccc8cc8c1acc882eccfa3d0accd9485d5eccff0782a47a6574619182a474797065a6427566666572a464617461dc0020ccc365cc8805cc942b64cca0674fccbeccca5ccca8ccb1013b5accb32f3146ccb6ccaccc94cccdccd5cc8accd0cc9a3510aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc002018cccdccaccc88cc8073264b02cca5cccdcce4cc881ccca8cce666ccee76ccdacce7ccc3cca3ccd0cce1cca7ccf4cc8f5b07ccf62c82a47a6574619182a474797065a6427566666572a464617461dc002069cc88cc8e2dcca0ccf814cca8ccf2ccc2ccd3cc96ccb874cc83cca5cc90575ccceeccacccb3ccf76eccd8cc9ccc8e640852cc9d24aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc002003ccadccaa28ccc02308cca153ccac68ccf501cc9c00ccaecc877f630d3acca26750cc93ccb4165c23ccf7ccd50282a47a6574619182a474797065a6427566666572a464617461dc0020523a05652ecc8cccef0fcc8e76044acc95cce929ccdacc882632cc86cca8cc8a2fcc83ccac5834ccd121ccad711daa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020ccf63fcc8902cca355cca667451accd86ecce4ccb6cc8acce2ccc8ccc331696fcce404cc8d2c3a2fccd534ccc0cc8b1782a47a6574619182a474797065a6427566666572a464617461dc0020ccf3cc9805ccd77cccebcce1666d3f0a23cc8a0acc815bcc81cce5403a21ccb9ccc5ccdb1007ccf7cca9387e7410aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc00200b6ecce129ccac063902786dccd12dcc8b5ccc8925cc83cc941652cce72c63ccc87847cceb33ccf803041cb472756e74696d655f6c6f6f6b75705f7461626c65c0bd72756e74696d655f6c6f6f6b75705f7461626c655f73656c6563746f72c0b3786f725f6c6f6f6b75705f73656c6563746f72c0bb6c6f6f6b75705f676174655f6c6f6f6b75705f73656c6563746f72c0bb72616e67655f636865636b5f6c6f6f6b75705f73656c6563746f7282a47a6574619182a474797065a6427566666572a464617461dc002015ccba591a407170cca4ccaacccd3acc98ccd4724d5acc8ccc97cce61421cc95cc87ccdc20ccebcca31d6071cc8608aa7a6574615f6f6d6567619182a474797065a6427566666572a464617461dc0020cc991acc86cca8397b2e60ccd2ccc17042cced4fccb4ccd4ccd2ccb83accd6cc954579ccb35cccfc196d425c1816d921666f726569676e5f6669656c645f6d756c5f6c6f6f6b75705f73656c6563746f72c0a866745f6576616c3182a474797065a6427566666572a464617461dc0020cccc18ccb921783ecce52a3c7e3d1acc92ccf61b25392748cc8934184e0200ccb8ccb33023cca0060faf707265765f6368616c6c656e67657390"; + function run() public { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); vm.startBroadcast(deployerPrivateKey); KimchiVerifier verifier = new KimchiVerifier(); - bytes memory urs_serialized = vm.readFileBinary("urs.mpk"); - verifier.setup(urs_serialized); + verifier.setup(); bool success = verifier.verify_with_index( - vm.readFileBinary("verifier_index.mpk"), - vm.readFileBinary("proof.mpk") + verifier_index_binary, + proof_binary ); console.log(success); diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 53a0bf7d..4f73a6c0 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -65,9 +65,7 @@ contract KimchiVerifier { State internal state; bool state_available; - function setup( - bytes memory urs_serialized - ) public { + function setup() public { //MsgPk.deser_pairing_urs(MsgPk.new_stream(urs_serialized), urs); // URS deserialization is WIP, we'll generate a random one for now: Scalar.FE x = Scalar.from(42); diff --git a/eth_verifier/test/Deserialize.t.sol b/eth_verifier/test/Deserialize.t.sol index d064b612..3c6ea0ec 100644 --- a/eth_verifier/test/Deserialize.t.sol +++ b/eth_verifier/test/Deserialize.t.sol @@ -187,12 +187,11 @@ contract DeserializeTest is Test { function test_deserialize_verifier_index() public { bytes - memory verifier_index_serialized = hex"DE0015A6646F6D61696E82A474797065A6427566666572A464617461DC00AC00400000000000000E00000000400000000000000000000000000000000000000000000000000000000000000140CCB0190CCCE6CC9CCC81CCABCC89CC97CCD87847CCBFCCC65752CCA76A7564CCA937631B66CCA7CCE1CC8C6330CC856E7C61CCC201CCAACCADCCE6CCAA2074CCE13ECCA9CCB4CCA8CCA8CCDC0DCCB8514E1FCC81CCE4CCD9CCCD5156CC962D10CC841C6434CCE9CCEECCF8CCC0717767CCB07609CCF4CC8C6ECC8E55420D6811CCE9CCE9CCE7066F031C28676666CCC6CCD4CCFBCCF3CCE7062D4ACCCACCE95CCCAECCA9CC8B56CCCD337CCCB5CCB949CCAACCD9135ACC94525B13AD6D61785F706F6C795F73697A65CD4000A77A6B5F726F777303A67075626C696300AF707265765F6368616C6C656E67657300AA7369676D615F636F6D6D9782A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC8E6A46CCC4CC9A5B053E3ACCD03ACCCACC896319CCAB43CC88CCAFCC887ECC84CCBC3DCCACCCFB49CCAB67CCDDCC93CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200F751F4138CC9FCCEFCCCACCC43ACCB9CCA01B0810CCAB2CCCB74C70CCDFCCD8CC9521CCC7CCA0CCCFCCA15019CCDECCA4A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCC903D4275CC90CC98CC987ACCE8CCA0CC946A33CCDACCB8CCBB386052CC93CCDF725A29CCC840CCF4CC87CCD6CCABCC99A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7526CCDDCC86CCA2CC9CCCD6CC8F0ACC937E062E56CCD25E3250CC90CC86CCC958CC84CCE0CCA5CC9701CC99CC8F7BCCA5A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC964300CC855F1C7BCCB37B55CC854C582F48CCC54938CCAB48CC815BCCD64A5ACCC62DCC8C37CCDDCCE403A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCF9322C5458CCD204CCDECC90CCE7CCFBCCED5E5ACCB2CCFC4651CCBA62297E0ACCFCCCF2CCCACCFBCCB0CCA05D0421A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCB3183ECCF8CCF4CC9410CCA465CCA4CCD145CC97CC9A4E5FCCB92FCCEACC81CCD7767434CC99CCC7CCC428CCEBCCBB6819A773686966746564C0B1636F656666696369656E74735F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C0AC67656E657269635F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A870736D5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B1636F6D706C6574655F6164645F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A86D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A9656D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B3656E646F6D756C5F7363616C61725F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B172616E67655F636865636B305F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020190C1BCC8C2123CC9301CCC0CCCD623DCCA5CC91CC84CCEBCC871B15076BCCF5CCC1CCD7497ACC8ACC99CCC2260ACCA4A773686966746564C0B172616E67655F636865636B315F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCFA37CCB2CCCFCCCB1A44CCE4CCF8204DCCB54FCC852335CCE0075ECC8D6BCC87CCB4CCA3CCB47444185C44CCEDCCAFA773686966746564C0B6666F726569676E5F6669656C645F6164645F636F6D6DC0B6666F726569676E5F6669656C645F6D756C5F636F6D6DC0A8786F725F636F6D6DC0A8726F745F636F6D6DC0A573686966749782A474797065A6427566666572A464617461DC0020010000000000000000000000000000000000000000000000000000000000000082A474797065A6427566666572A464617461DC0020CCE3CCA214CCE91334CCD0CCCACCF1CCEBCC85CCDF5BCCD7524D73CCD5CCEB7ACCAF742A7ECCB2CCD40BCCFDCCC8CCCDCCB90082A474797065A6427566666572A464617461DC00206D0F4433CC9A33CC9FCCB8CCA4CCE4CC9BCCF109CC9620CCAA64CC9918482BCC95CCA3CC97CCAE39CCB9CCEC5ACCD4770082A474797065A6427566666572A464617461DC0020CCB40923CCBD78CCE619CCC80A7B39CCC0CCF3CCF11E48005519CCD2CCFECCF16A1F77CCD40545CCE5CCC7770082A474797065A6427566666572A464617461DC0020CCF9CCC95CCCD6CCB11B38CCDF7855CCFD4D2A036329CCADCCCACCD613CCF100CCB92310CC9540356A597C0082A474797065A6427566666572A464617461DC00205A696526CCFA30CC9C412C10CCE86604CCC3CCC0CCAD2CCCD9443DCCD85BCC8232037212CC81CCCFCCBF330082A474797065A6427566666572A464617461DC002043423BCCB307CCCECCC1CC9F297C41CC88CCDECCB23ACCCC7B581271CC9B2ECCACCCCBCCF1CCB7034ACCE6CCACCCE800AC6C6F6F6B75705F696E64657886B16A6F696E745F6C6F6F6B75705F75736564C2AC6C6F6F6B75705F7461626C659182A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE6CCA15E7ECCA10ECCD2CC8F0F3361CCC7CCA7CCF45CCCED5E6D382017CC8CCC832CCCFCCCC0CCDF0E343ECCB1CC80A773686966746564C0B06C6F6F6B75705F73656C6563746F727384A3786F72C0A66C6F6F6B7570C0AB72616E67655F636865636B82A9756E736869667465649182A474797065A6427566666572A464617461DC00201B24636044CCD6CCED30CCC611CC85CCD45B2969CC98CCB811CCB754CCA5507C08CCD1CC9124CC9B37CCC01721A773686966746564C0A566666D756CC0A97461626C655F69647382A9756E736869667465649182A474797065A6427566666572A464617461DC00205F28CC8BCCB342CC8034CCA922CCB3CCE618CCEA3ECC811ECCDF61CC81CCB10B7ECCF6CCC859CCFD03CCEA2B39CCA70EA773686966746564C0AB6C6F6F6B75705F696E666F83AB6D61785F7065725F726F7704AE6D61785F6A6F696E745F73697A6501A8666561747572657383A87061747465726E7384A3786F72C2A66C6F6F6B7570C2AB72616E67655F636865636BC3B1666F726569676E5F6669656C645F6D756CC2B16A6F696E745F6C6F6F6B75705F75736564C2B3757365735F72756E74696D655F7461626C6573C2B772756E74696D655F7461626C65735F73656C6563746F72C0"; + memory verifier_index_serialized = hex"de0015a6646f6d61696e82a474797065a6427566666572a464617461dc00ac00400000000000000e00000000400000000000000000000000000000000000000000000000000000000000000140ccb0190ccce6cc9ccc81ccabcc89cc97ccd87847ccbfccc65752cca76a7564cca937631b66cca7cce1cc8c6330cc856e7c61ccc201ccaaccadcce6ccaa2074cce13ecca9ccb4cca8cca8ccdc0dccb8514e1fcc81cce4ccd9cccd5156cc962d10cc841c6434cce9cceeccf8ccc0717767ccb07609ccf4cc8c6ecc8e55420d6811cce9cce9cce7066f031c28676666ccc6ccd4ccfbccf3cce7062d4acccacce95cccaecca9cc8b56cccd337cccb5ccb949ccaaccd9135acc94525b13ad6d61785f706f6c795f73697a65cd4000a77a6b5f726f777303a67075626c696300af707265765f6368616c6c656e67657300aa7369676d615f636f6d6d9782a9756e736869667465649182a474797065a6427566666572a464617461dc0020cc8e6a46ccc4cc9a5b053e3accd03acccacc896319ccab43cc88ccafcc887ecc84ccbc3dccacccfb49ccab67ccddcc93cc8aa773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200f751f4138cc9fccefcccaccc43accb9cca01b0810ccab2cccb74c70ccdfccd8cc9521ccc7cca0cccfcca15019ccdecca4a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00205ccc903d4275cc90cc98cc987acce8cca0cc946a33ccdaccb8ccbb386052cc93ccdf725a29ccc840ccf4cc87ccd6ccabcc99a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccdd7526ccddcc86cca2cc9cccd6cc8f0acc937e062e56ccd25e3250cc90cc86ccc958cc84cce0cca5cc9701cc99cc8f7bcca5a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020cc964300cc855f1c7bccb37b55cc854c582f48ccc54938ccab48cc815bccd64a5accc62dcc8c37ccddcce403a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccf9322c5458ccd204ccdecc90cce7ccfbcced5e5accb2ccfc4651ccba62297e0accfcccf2cccaccfbccb0cca05d0421a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccb3183eccf8ccf4cc9410cca465cca4ccd145cc97cc9a4e5fccb92fcceacc81ccd7767434cc99ccc7ccc428ccebccbb6819a773686966746564c0b1636f656666696369656e74735f636f6d6d9f82a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c082a9756e736869667465649182a474797065a6427566666572a464617461dc00200000000000000000000000000000000000000000000000000000000000000040a773686966746564c0ac67656e657269635f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0a870736d5f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0b1636f6d706c6574655f6164645f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0a86d756c5f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0a9656d756c5f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0b3656e646f6d756c5f7363616c61725f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020723737cccf1cccc96bccb40021504a4fccf45d21cc914ecc94cc84ccf2113d66545a3826cc91cc9acc9c25a773686966746564c0b172616e67655f636865636b305f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020190c1bcc8c2123cc9301ccc0cccd623dcca5cc91cc84ccebcc871b15076bccf5ccc1ccd7497acc8acc99ccc2260acca4a773686966746564c0b172616e67655f636865636b315f636f6d6d82a9756e736869667465649182a474797065a6427566666572a464617461dc0020ccfa37ccb2cccfcccb1a44cce4ccf8204dccb54fcc852335cce0075ecc8d6bcc87ccb4cca3ccb47444185c44ccedccafa773686966746564c0b6666f726569676e5f6669656c645f6164645f636f6d6dc0b6666f726569676e5f6669656c645f6d756c5f636f6d6dc0a8786f725f636f6d6dc0a8726f745f636f6d6dc0a573686966749782a474797065a6427566666572a464617461dc0020010000000000000000000000000000000000000000000000000000000000000082a474797065a6427566666572a464617461dc0020cce3cca214cce91334ccd0cccaccf1ccebcc85ccdf5bccd7524d73ccd5cceb7accaf742a7eccb2ccd40bccfdccc8cccdccb90082a474797065a6427566666572a464617461dc00206d0f4433cc9a33cc9fccb8cca4cce4cc9bccf109cc9620ccaa64cc9918482bcc95cca3cc97ccae39ccb9ccec5accd4770082a474797065a6427566666572a464617461dc0020ccb40923ccbd78cce619ccc80a7b39ccc0ccf3ccf11e48005519ccd2ccfeccf16a1f77ccd40545cce5ccc7770082a474797065a6427566666572a464617461dc0020ccf9ccc95cccd6ccb11b38ccdf7855ccfd4d2a036329ccadcccaccd613ccf100ccb92310cc9540356a597c0082a474797065a6427566666572a464617461dc00205a696526ccfa30cc9c412c10cce86604ccc3ccc0ccad2cccd9443dccd85bcc8232037212cc81cccfccbf330082a474797065a6427566666572a464617461dc002043423bccb307ccceccc1cc9f297c41cc88ccdeccb23acccc7b581271cc9b2eccaccccbccf1ccb7034acce6ccaccce800ac6c6f6f6b75705f696e64657886b16a6f696e745f6c6f6f6b75705f75736564c2ac6c6f6f6b75705f7461626c659182a9756e736869667465649182a474797065a6427566666572a464617461dc0020cce6cca15e7ecca10eccd2cc8f0f3361ccc7cca7ccf45ccced5e6d382017cc8ccc832cccfcccc0ccdf0e343eccb1cc80a773686966746564c0b06c6f6f6b75705f73656c6563746f727384a3786f72c0a66c6f6f6b7570c0ab72616e67655f636865636b82a9756e736869667465649182a474797065a6427566666572a464617461dc00201b24636044ccd6cced30ccc611cc85ccd45b2969cc98ccb811ccb754cca5507c08ccd1cc9124cc9b37ccc01721a773686966746564c0a566666d756cc0a97461626c655f69647382a9756e736869667465649182a474797065a6427566666572a464617461dc00205f28cc8bccb342cc8034cca922ccb3cce618ccea3ecc811eccdf61cc81ccb10b7eccf6ccc859ccfd03ccea2b39cca70ea773686966746564c0ab6c6f6f6b75705f696e666f83ab6d61785f7065725f726f7704ae6d61785f6a6f696e745f73697a6501a8666561747572657383a87061747465726e7384a3786f72c2a66c6f6f6b7570c2ab72616e67655f636865636bc3b1666f726569676e5f6669656c645f6d756cc2b16a6f696e745f6c6f6f6b75705f75736564c2b3757365735f72756e74696d655f7461626c6573c2b772756e74696d655f7461626c65735f73656c6563746f72c0"; MsgPk.deser_verifier_index( MsgPk.new_stream(verifier_index_serialized), index ); - assertEq(index.public_len, 0); assertEq(index.max_poly_size, 16384); assertEq(index.zk_rows, 3); diff --git a/eth_verifier/test/Integration.t.sol b/eth_verifier/test/Integration.t.sol index 5d20608a..e9683e78 100644 --- a/eth_verifier/test/Integration.t.sol +++ b/eth_verifier/test/Integration.t.sol @@ -14,13 +14,13 @@ contract Integration is Test { hex"85AB636F6D6D69746D656E747384A6775F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCD843CC8C68CCADCCC65F0FCCE95332CCD3566E1C7BCCA626764ECCFF30CCEE14CC9560790764CCE7CCC4CC9CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE7CCFBCCD1CC92CCBF523131CCDD2FCCB807CCF8CCF7CCCFCCADCCE7CCDF6256CCE8CC9ECC91CCF0CC9C0CCCB11050050FCC85A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC3CCE17360CCCC5FCCA1CCAD260C0ECCDFCC98CCCBCC8ECCD2367F0B2553654257CCA5CC82CC96CC9361CCF379CC89A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020465CCCB06ACC97CCCC1FCCBA62156DCCEA4A0ACCCF78CC98CCAECCBECCDFCCE1CCD212537BCCCF5970CC8C3A3E30A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCAACCAECCD8302DCC9FCCF808CCA76DCCB646CCA345CCA70BCCFFCCBA5865357522CCF6CCEF443634CC81CCA7CC8A0CA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002010CCDC62CCE86ACCA0CCFBCCCCCCA934CC8ACCB97ACCE3552B5E7442112820503713CCCD7E30CCC4CC8936CC92A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00207833045124CC8BCCFA087CCCC77969CC8B17CCDECCD5CCEACCD3CCB8CCC147CC907DCCFF0042CCB9CCADCCE444CCF1CC80A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201A49CCD234CCEE0ACC985DCCD452CCB8CCC365CCBA5F7FCCE57874CCE5CCB8CCAE7C24CCA7CCFFCCDF7F06CCCECCBF16A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00203BCCF60A24CCEF2F1B14CCE9CCF71BCCC23ECCEA0C5ACC9C0DCC9E377232CCD501CCBACCCFCCD9CCF9CCF3CCDACCCF00A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00201ECCA4CCCFCCEF710FCCE8CC9B32CC81CC84323C601ACCB1516005CCFFCCEB2FCC90CCBE654CCCFD5D486FCC862FA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7DCCDC5F6ACC8132CCC008CCF9CCE3CCCACC94CC8ACCA83D7ECCC5CC835ECC97CC8ACC95CC9CCCE3CCCA0B58CCDF4FCCE314A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020351B53CCB8CCA6CCDB78CCA61D4865276D69CCDD49361E620A32611E1ECC80CCFE51CC94CCB74C2410A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC830DCC89CCADCCBCCCC9CCD3CC82CCE60114CCCBCCBFCCD5CC8D40723DCCE6CC8354CC9509CCB731CCCACC9ECCD7CCB7CCDECCD7CCABA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCC2CCF328CCED33CCDC6264CCEDCCEC4633CCCCCCA8CCBBCCDACCC24345CC99CCA565CCC23ACCB144CCAACCC459CC924809A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00204DCCBE7C3A5F1E2B7ECC867965CCCBCCD65A7D771ACC81CCEECCF724CCE2010DCCF1CCF63CCCFC4C56CCB5CC9FA773686966746564C0A67A5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCCB4CC8052CC9A247A2B51425B50705BCCEACCD7CC85CC8664CCBCCC84CCB1CCD318CCB96BCCEA55CC9049CCEBCCA7A773686966746564C0A6745F636F6D6D82A9756E736869667465649782A474797065A6427566666572A464617461DC00203ACCF406CCEBCCEBCCE72979CCF063CCB06BCCA8CCF74A34CCA22B5D4B5E30CCF8CCFD3F7BCC9F11CCC254101582A474797065A6427566666572A464617461DC002071CCF6CC9CCCADCCA4565520CCE9CCA5CCF4CCEBCCA0CCDB1B1E3D760224025A4DCC806BCC9DCCA7CC8CCCA951CCEC0C82A474797065A6427566666572A464617461DC002056CCC151CC80CCF762CCAFCCA4CCD9CCC968CCA6CCAA64CCD60CCCF1CCC4CC9FCCDB6A2D6863CCFFCCAB48796F37CC8D2682A474797065A6427566666572A464617461DC0020CCAECCF3665BCCDFCC97CCBE7CCCE6CCF8CCB70F62CCAE197764CC9ACCB80ACCA416CCE3CCB00E78CCAD265613CCA50B82A474797065A6427566666572A464617461DC0020CCF81C0359CC95CCFCCCA479CCB2CC9DCCEDCC9626CCCECCB6CCEDCCAE642A3DCCF37ECCF56B665BCCD950CCD32C780882A474797065A6427566666572A464617461DC0020CCF6CCF06B74CCA433591E30CCE6CCE1CC93CC8ACC9C56042F3867714FCCC72E7ACC891ECCBB71603DCCE4CCAF82A474797065A6427566666572A464617461DC0020CCCFCCCFCCB3560BCC83CC95CCCC33CCEACC9E6DCC921BCCB4CCCACCA864CCECCCC33776734D657CCCD52BCCAC204BCC94A773686966746564C0A66C6F6F6B757083A6736F727465649582A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE9CCF5195B6ACCD6CC96CCA1325F2D6C79CCFF6CCCD9CC9ACCFE77CC932BCCE3CC994073CCF2CCFBCCC779CCE56C27A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC975DCCC0CCDD6BCCC7CC9ECC8CCCDA681A17CCDA2CCC9F7BCC916F483D41CCA00A68CCB718CCC722CCBE422E18A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002021CCC1CC8C4370687F69CCA0CCAA533BCCCA0C5BCCE847CCBA78CC83CC8BCCA103CCC67668CCDCCC812405CCA0CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002019CCD34CCCF25BCCE82955CC974A26663E0F70CCA6596FCCACCC9B7CCCAECC83CCA6556F410771CC92CCF611A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC002045CCF9105CCC8FCCA1CC9E2638607BCC8A2B0266CCEDCCFACC9361CC80CCC1CCE1CC8A3C5B08CCCC5FCC8921CCC2CCA7A773686966746564C0A661676772656782A9756E736869667465649182A474797065A6427566666572A464617461DC00201DCCC905CCCBCCFC7F19CCB5CCCCCCECCCB4CC965DCCA5CC87573F535C6A15CCBD0FCCC0CCA81D07023818CCA21FA773686966746564C0A772756E74696D65C0A570726F6F6682A871756F7469656E7482A474797065A6427566666572A464617461DC0020CCDD7E3BCC86CC99622CCCFD7F08221DCCD8191504CCAB386202CCC50A6ACCB1CC8ECCF663CCBECC9F0A53CC99A8626C696E64696E6782A474797065A6427566666572A464617461DC00207B6778CCBECCFD13CCB616CCEDCCDBCCAA7B1FCCD214CCC4CCD3CC9A4DCCC0306ACCC3CCF3CCD1CCAFCCF64D6858CCB61DA56576616C73DE001AA67075626C696382A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000A1779F82A47A6574619182A474797065A6427566666572A464617461DC0020CC91CCABCC853859CCDB5FCC8FCCC276CCAACCC5183119CC84CC863231CCB456CCB608CC9336CCC3CCC0CCC0CCEACCAB2D2CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD7CCB3CCC07450CCC178CCBB5B14CCE3CCB5CCB22C70CCEBCC8E770ACCE329284A08CC84CCA5CCDF6BCCC1752E0882A47A6574619182A474797065A6427566666572A464617461DC0020134ECCAECCD96164CCA0CCD8CCBF0B71CC9C5C78CCE3CC8E21CC81CCDF10CCBD02462ECCA8CC9D03CCCECCF06D6F15AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD256CCA01BCCABCCF549CCC62908CCFDCCE5CCF537CCC24BCCF645CCCC2948CCEC3ACCD9CC9ACCAECCC2CCE30ACCCD301D82A47A6574619182A474797065A6427566666572A464617461DC0020CCC2CCEBCC96142945380379CCEFCC95130D6914CC925FCCF623CCA4CCB21BCCE00FCCCA00CCA5CCA44113CCC206AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00203ECCD2CCD9CCADCCB110CCA05F6B0DCCF5CCD435373FCC896DCCC16ECCA81E29CC982A5D422835CCAC4B090C82A47A6574619182A474797065A6427566666572A464617461DC0020162ECCAECCE714CCE053CC94CCFECCB612CCA31371CC8D3856CCD9CCE603CCECCCB2CCE9CCEB39CCDBCC86CCB445251216AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCBACCF04E4E7ACCE2CCCECCBBCCB2CCC2CC8ACCB7CCF06A71CC9F685ACCF1CCC9CCA454CCDC0549CCFFCCD545CC8B4A1A1682A47A6574619182A474797065A6427566666572A464617461DC00200F4B02CCDA68CCDFCCE9CCA8366FCCAACCD70ECCCE3ACCA84BCCC3CC80CCC149CCB077CCA20BCC9DCCBF5FCCEC7ECCBC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002066CCA178CCA84845CCE35ECCEA08CCD4CCB1CCEBCCD5CCF6221C0F74CCDCCCCBCCCDCCDFCCDD62CCEECCEC4D6DCCD4CCC40982A47A6574619182A474797065A6427566666572A464617461DC00206ECCE833CCF62BCCF044CCE1CCA3CC9B25604DCC982CCCA1CCFC6ECC9A61CCA4CCE973CCEF0A71CCBFCCD90617CC9422AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205848CCFC1BCCFC647567CCCFCCF76ACCC176CCFACC92560B6C3E3D6FCC90CCF6CC9FCC9ACC88CC811160CC91CCC20682A47A6574619182A474797065A6427566666572A464617461DC0020CC864757CCB36C11CC86182C11CC832E08CC86466ECC8A49187BCC8BCCEFCC90CCC87171CCA62040CC9ACCC22FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD0CCAECCFFCC91CCA0CC9FCC9625CC9522CCD5204E2BCCC0CC91507408CCFACCCB5B202C57CCF23A46CCE37D7D2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCE95ACC9E46CCFCCCBA232C37CCC335CCF9CCF9303CCCFFCCC85669CCEFCCB107CC99CCFACCF7CC924F2827CCAE0102AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002009CCB537CC9D6607CCFECCFDCCE14801CCF6CCB3CCA2CCB6CCE2CCDFCCE5CCC83027334FCCAE22221BCCCF1A0F1C0082A47A6574619182A474797065A6427566666572A464617461DC0020CCC6CCCD1ACCBF41233DCCA617CC9C4406CCD861CC91CCF60E4412CCAB4FCCB1CC9F447BCCB3CCABCC9E7836CC960CAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002037CC80CCAECCBD56CCB5CCBC50CCC3CC9746CC995BCCB628CCB674CCACCCF7CCC55D653142CC9FCCCA71CCC9CCE3CCEACC8C0A82A47A6574619182A474797065A6427566666572A464617461DC0020CCB1CC8348CCDACCD87DCCD0CCDC29CC826D03672D64CCAE4963CCE37ECCB205114ACCDECCB5CC9F1E1B72CCAC03AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF5793436CC87574F2ACCAA5020CCA91E1CCC8451CC81015ECC8E35267C063CCC86CCB87CCCA002CCFF2D82A47A6574619182A474797065A6427566666572A464617461DC0020CCD33CCCAECCD038CCD63324CC9B1DCC9ACC9FCC8040CC9A39CCF7CCEACCCCCCE17ECCE5CCADCCEE18CCB0CC8509497ECC882DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCD32B42CCF447CCDD023CCCD4CCB76D50CC9DCCD2CC8054CCF456CCC709CCA017CCC104CC9A65CCA37439CC96CCA61782A47A6574619182A474797065A6427566666572A464617461DC00200A5D16CC8FCCC1CCF516CC8843CCDBCCFD74CCD8102B5928CCA244CCDC29CCE8CCC4714DCC935628CCB52ECC8D18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCEA45CCBE2C29CCDFCC805ECCE5CCABCCB3CCAB05CCEDCCE125CCB2CCFDCC8ECCAD6549CCF1CCA57DCCE9CCD647CCE6CCA7650E82A47A6574619182A474797065A6427566666572A464617461DC00204854CCAE40CCFCCC8F3BCC935E2477CCCCCCC90D0C115D72CCAD63CCA537CC9873CC8770CCEFCCBA12CCFDCCB01BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCDC2DCCD655CCAC0B6311CC9944CC8E39CCDECC81CCBBCCB1CCE45C32CCA4CCBD5A1D4314CCFFCC9010CCF24B2B82A47A6574619182A474797065A6427566666572A464617461DC00201135CCDBCCDC6F7FCCDC26CC845449CCC771CC881029CCC1CC80CCD5CCAE61CC866DCCCF6CCCF81C1C73CC871A2FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002048CCCBCC81CC906F47CC98CC8F3E3C04CCD4CC9874CCA50A3E3D31CCE6CCCCCC8772CC8ECCBC07CCDA05CCCE273A3082A47A6574619182A474797065A6427566666572A464617461DC00207DCCCCCCCECCBACC9D4373CCAF6F1D07CCD00FCCD42344CCD5CCB3CCE0CCF36A7937CC8DCCFB350BCC8E7F73CC9D26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00206C2D746FCCD1CCF94654CCB7CCC4CCC7CCE36051CCB019CCCBCCE870CCE5CCD43ACCED10CC93CCFFCCEB4C67CCA05D30A17A82A47A6574619182A474797065A6427566666572A464617461DC00203303576F49CCD5CCA8CCD0CCE87BCC9703CCFCCCEACC9FCC9102CCCC69CC8ACCE4CCEF6945CCA5CCDF1F2B7262652AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCE747CCA774CC98CCA2CCA610CC9FCCEDCCEC22CCEC150E732818CCFF3727CCD4CCDA31CCE1CCB5587160CCAACCC603A1739682A47A6574619182A474797065A6427566666572A464617461DC002051CCF4CCA0CCA2CCDC4BCCCFCCC2CCDC5CCCFBCCF2CC9FCC9CCCB9CC9FCCA7315741CCFF73CC99CCFF41CCE8CC95CCE6CCD6CCB7001DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF21D4C5ACC954338CCE1CCC56206CCC45705CCE503CCDD28CCEE64CCF633CCA6CCF677CCFACCF8CCB5CC8A45CC9F0E82A47A6574619182A474797065A6427566666572A464617461DC0020CCEFCC81CCD54E2E33CC860C37CCE8CCA5CC96CCFF1ACC802ACCEACCBDCCD6275770CC841F36CCA6CCD5CCCCCCA13CCCC71AAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF63A5E6C3ECCF63DCCED4ACC8F75CCDF2ECCBF5ECC95CCC8CCA4CC992926CC996DCCE9CCAD60CCD30122CCE2201782A47A6574619182A474797065A6427566666572A464617461DC00201ECCAA57CCA3CC9BCCDDCCBFCCFCCCD13074CCF7CCFACCD84DCCB434CCC4CCDA5FCCF866CCE6CCD5CCC6CCCD70CCC653CCDDCC882EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020332374CCBA79025BCC9916CCD7CCD90CCCDC5CCCE0CCA8CCE368CC9F590136CCCB15CCC868CC8BCCA809CC84CCF30082A47A6574619182A474797065A6427566666572A464617461DC002018CC88415E4CCC9E64720DCCF873CCAC561748CCEA26CCF9CC8B153D61CCF34BCCCDCCA62710CCC9500C1BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA1CC80CC81CCEC3CCCC6CCF9CC9A5E1ECCC7CCF9CCA2CCF2217743437DCC8BCCF7CCDFCCC3CCC51ECCDECC96CCA0CC8438091182A47A6574619182A474797065A6427566666572A464617461DC0020CCCC40CC942544CCB12E2F46CCF4CCA1CC8ACCC2596C113363CCDF2FCCAF41CCFECCD5CCE5CCFDCCFD7C33107E26AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002011CCAF34CCA9470870CCE7CCF411CCC2CC8741CCDD52CCAB55CCC1CCCECC876ACC870305622F7ACCCBCC8761CCB00982A47A6574619182A474797065A6427566666572A464617461DC0020CCEC6741CCFECCA4CCF6CCF91FCCE6CCDCCC9E5E746B2857CCFFCC962B4ACCCECCE7CCE9CCD429CCB4CCD2CC8D1FCC8DCCFC02AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC81CCA9CCE6CCC546CCA8555ECCF82607CCCECC9563CCDC31CCA3CCD8CCDA2BCCA4CCBE18616426697D696ECC831DAC636F656666696369656E74739F82A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020000000000000000000000000000000000000000000000000000000000000000082A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B067656E657269635F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B1706F736569646F6E5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B5636F6D706C6574655F6164645F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AC6D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AD656D756C5F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B7656E646F6D756C5F7363616C61725F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000000B572616E67655F636865636B305F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCA8CC92CCB340CCC520573BCCF5CCC60BCCABCCBDCCE7CC8F15CCE2CCEDCCEE31CC9B484D5FCCD62CCCC2CCC3391ACCFF2EAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC9D37CCAE26CC8702CCBB67CCFFCCBACC841DCCEB383113CCFBCCB3CCE6CC8FCCF0CCBFCCEFCCDB1B6F622645CC830F27B572616E67655F636865636B315F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCF2CC90CCC8CCA4CC8DCC92CCE7CCDFCCA93938044316CCBE6D37CCC9023A2A54CCD9043B0ECCBECCF912350703AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC941CCCCA71CCDA09CC8DCCD162CCF4CCBACCA814CCEE5BCC9ACCF9216D7CCC990E0ACCFECCB7CCB37B397CCC85CCBA15BA666F726569676E5F6669656C645F6164645F73656C6563746F72C0BA666F726569676E5F6669656C645F6D756C5F73656C6563746F72C0AC786F725F73656C6563746F72C0AC726F745F73656C6563746F72C0B26C6F6F6B75705F6167677265676174696F6E82A47A6574619182A474797065A6427566666572A464617461DC0020CCBB1ACCD376CCEECCF0CCA750CC8B711ACC97CC8160CCE1CCC5CCFCCCF0CCE0412861CCEF5128CCF4CC99CCCE39CCC4CCF80DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002032CC903FCCD27BCC9ECC9CCCAFCCBC39CCC1CCC3CC9BCCA36D0570CCA114CCAE2CCC9F1203CCBD60CCA31D7ACCBB0514AC6C6F6F6B75705F7461626C6582A47A6574619182A474797065A6427566666572A464617461DC00203D663E7E6610CCB1CC844863CC803466590A2A1CCCA451CCC755393BCCD3CCC762CC822B44CCA8CCB02BAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CC8ACC985A1D271113CCCACCE0CCA7CCEACCB5CC86CC845CCCB8CCCD2E27CCDF38CCD30E76CCC81832CC94CC8ECCF4CCAB1FAD6C6F6F6B75705F736F727465649582A47A6574619182A474797065A6427566666572A464617461DC002003CCF1CC8FCC8CCC843B1ACCC26DCCDE6ECCE46E64CCC9CCE971CCDECCC4CC84CCFE2FCCBACCFBCC8737CCACCC8756CC945F23AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCA3326726CCABCCD7CC904C23CC927068CC920F59CCB7CCEA17CCCFCC8878CC91CCC13ACCE36C3F4725CC8B222882A47A6574619182A474797065A6427566666572A464617461DC0020CCF52ECCB7683352CCA3CCF176CCEECCD461CCCC0C3ACCD905CC80CCAF4E25CCBE29CCA8CC99CCD87ECC8ACCC20FCCB90DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00207BCCD5CCC6CC9228CCE1CCBA3E037ACC854FCC9A6BCCCC492CCCA7CCA7CCF5CCEF3FCC862278CCC732CCDD45CCFCCCD02782A47A6574619182A474797065A6427566666572A464617461DC0020CC9741CCC7CCC0CCFC6F6A6768377ECCD94ACCB1CCC92FCCE66129CCE7CCC8CC8436CCB3CCBE2DCC8BCCF418CCB20415AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC00205772CCCF1B0A32CCFDCCE247CCC3CCDD6CCC8126CC83CCFCCCBE5F31CCA53521CC85CCBA72CCBDCC85344265701282A47A6574619182A474797065A6427566666572A464617461DC0020CCB4CCA0CCEA22046DCC87CCB2427F4954CC82CC84CCADCCD10BCCB7CCD7CC990044CCF4CCDFCCD95FCCD5CCD27167CCBE18AA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC0020CCF569CC93331A635C4465CCE85C6CCC8121CCBBCC93CCD7CC8DCCE6CCFACCE4CCE817CCD95270384D500ECCCB1582A47A6574619182A474797065A6427566666572A464617461DC0020CCB7CCCB1F526A127353CCDBCC97CCB7CCCB32CC82CCB26FCCE9CCBACCC4CCB8CCE915CC9F65CCBBCCDD42412A0F771DAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002005CCABCCEE75CCBA63CC9C0824CCCCCCFD6ACCC6CCE1CCC4CCF2CCACCCA9CCACCCA2CCD90716CCD746CCA3CCCD00002D4C26B472756E74696D655F6C6F6F6B75705F7461626C65C0BD72756E74696D655F6C6F6F6B75705F7461626C655F73656C6563746F72C0B3786F725F6C6F6F6B75705F73656C6563746F72C0BB6C6F6F6B75705F676174655F6C6F6F6B75705F73656C6563746F72C0BB72616E67655F636865636B5F6C6F6F6B75705F73656C6563746F7282A47A6574619182A474797065A6427566666572A464617461DC0020CCBD2ECCC43CCCBD197CCCC3112429CCCC1FCC83CCC26DCCBBCCB77DCC87CCDD691844CCA257CCB678CCEDCC9FCCEC1FAA7A6574615F6F6D6567619182A474797065A6427566666572A464617461DC002022CCE5404D5BCCA94DCCD57A78CCBE50CCFA5417CCF3CCCE46CCD5CCC4CCFDCCDCCC8226CCE5CC906A7861CCEF6C0FD921666F726569676E5F6669656C645F6D756C5F6C6F6F6B75705F73656C6563746F72C0A866745F6576616C3182A474797065A6427566666572A464617461DC00202E74CCF4CCB84B766ECCB00ACCC6CCFD70306ECCA8CCA2CC870ACCD8780864005B306ECC8DCC957CCCD04916AF707265765F6368616C6C656E67657390"; bytes verifier_index_serialized = hex"DE0015A6646F6D61696E82A474797065A6427566666572A464617461DC00AC00400000000000000E00000000400000000000000000000000000000000000000000000000000000000000000140CCB0190CCCE6CC9CCC81CCABCC89CC97CCD87847CCBFCCC65752CCA76A7564CCA937631B66CCA7CCE1CC8C6330CC856E7C61CCC201CCAACCADCCE6CCAA2074CCE13ECCA9CCB4CCA8CCA8CCDC0DCCB8514E1FCC81CCE4CCD9CCCD5156CC962D10CC841C6434CCE9CCEECCF8CCC0717767CCB07609CCF4CC8C6ECC8E55420D6811CCE9CCE9CCE7066F031C28676666CCC6CCD4CCFBCCF3CCE7062D4ACCCACCE95CCCAECCA9CC8B56CCCD337CCCB5CCB949CCAACCD9135ACC94525B13AD6D61785F706F6C795F73697A65CD4000A77A6B5F726F777303A67075626C696300AF707265765F6368616C6C656E67657300AA7369676D615F636F6D6D9782A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC8E6A46CCC4CC9A5B053E3ACCD03ACCCACC896319CCAB43CC88CCAFCC887ECC84CCBC3DCCACCCFB49CCAB67CCDDCC93CC8AA773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200F751F4138CC9FCCEFCCCACCC43ACCB9CCA01B0810CCAB2CCCB74C70CCDFCCD8CC9521CCC7CCA0CCCFCCA15019CCDECCA4A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00205CCC903D4275CC90CC98CC987ACCE8CCA0CC946A33CCDACCB8CCBB386052CC93CCDF725A29CCC840CCF4CC87CCD6CCABCC99A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCDD7526CCDDCC86CCA2CC9CCCD6CC8F0ACC937E062E56CCD25E3250CC90CC86CCC958CC84CCE0CCA5CC9701CC99CC8F7BCCA5A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CC964300CC855F1C7BCCB37B55CC854C582F48CCC54938CCAB48CC815BCCD64A5ACCC62DCC8C37CCDDCCE403A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCF9322C5458CCD204CCDECC90CCE7CCFBCCED5E5ACCB2CCFC4651CCBA62297E0ACCFCCCF2CCCACCFBCCB0CCA05D0421A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCB3183ECCF8CCF4CC9410CCA465CCA4CCD145CC97CC9A4E5FCCB92FCCEACC81CCD7767434CC99CCC7CCC428CCEBCCBB6819A773686966746564C0B1636F656666696369656E74735F636F6D6D9F82A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C082A9756E736869667465649182A474797065A6427566666572A464617461DC00200000000000000000000000000000000000000000000000000000000000000040A773686966746564C0AC67656E657269635F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A870736D5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B1636F6D706C6574655F6164645F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A86D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0A9656D756C5F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B3656E646F6D756C5F7363616C61725F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25A773686966746564C0B172616E67655F636865636B305F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020190C1BCC8C2123CC9301CCC0CCCD623DCCA5CC91CC84CCEBCC871B15076BCCF5CCC1CCD7497ACC8ACC99CCC2260ACCA4A773686966746564C0B172616E67655F636865636B315F636F6D6D82A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCFA37CCB2CCCFCCCB1A44CCE4CCF8204DCCB54FCC852335CCE0075ECC8D6BCC87CCB4CCA3CCB47444185C44CCEDCCAFA773686966746564C0B6666F726569676E5F6669656C645F6164645F636F6D6DC0B6666F726569676E5F6669656C645F6D756C5F636F6D6DC0A8786F725F636F6D6DC0A8726F745F636F6D6DC0A573686966749782A474797065A6427566666572A464617461DC0020010000000000000000000000000000000000000000000000000000000000000082A474797065A6427566666572A464617461DC0020CCE3CCA214CCE91334CCD0CCCACCF1CCEBCC85CCDF5BCCD7524D73CCD5CCEB7ACCAF742A7ECCB2CCD40BCCFDCCC8CCCDCCB90082A474797065A6427566666572A464617461DC00206D0F4433CC9A33CC9FCCB8CCA4CCE4CC9BCCF109CC9620CCAA64CC9918482BCC95CCA3CC97CCAE39CCB9CCEC5ACCD4770082A474797065A6427566666572A464617461DC0020CCB40923CCBD78CCE619CCC80A7B39CCC0CCF3CCF11E48005519CCD2CCFECCF16A1F77CCD40545CCE5CCC7770082A474797065A6427566666572A464617461DC0020CCF9CCC95CCCD6CCB11B38CCDF7855CCFD4D2A036329CCADCCCACCD613CCF100CCB92310CC9540356A597C0082A474797065A6427566666572A464617461DC00205A696526CCFA30CC9C412C10CCE86604CCC3CCC0CCAD2CCCD9443DCCD85BCC8232037212CC81CCCFCCBF330082A474797065A6427566666572A464617461DC002043423BCCB307CCCECCC1CC9F297C41CC88CCDECCB23ACCCC7B581271CC9B2ECCACCCCBCCF1CCB7034ACCE6CCACCCE800AC6C6F6F6B75705F696E64657886B16A6F696E745F6C6F6F6B75705F75736564C2AC6C6F6F6B75705F7461626C659182A9756E736869667465649182A474797065A6427566666572A464617461DC0020CCE6CCA15E7ECCA10ECCD2CC8F0F3361CCC7CCA7CCF45CCCED5E6D382017CC8CCC832CCCFCCCC0CCDF0E343ECCB1CC80A773686966746564C0B06C6F6F6B75705F73656C6563746F727384A3786F72C0A66C6F6F6B7570C0AB72616E67655F636865636B82A9756E736869667465649182A474797065A6427566666572A464617461DC00201B24636044CCD6CCED30CCC611CC85CCD45B2969CC98CCB811CCB754CCA5507C08CCD1CC9124CC9B37CCC01721A773686966746564C0A566666D756CC0A97461626C655F69647382A9756E736869667465649182A474797065A6427566666572A464617461DC00205F28CC8BCCB342CC8034CCA922CCB3CCE618CCEA3ECC811ECCDF61CC81CCB10B7ECCF6CCC859CCFD03CCEA2B39CCA70EA773686966746564C0AB6C6F6F6B75705F696E666F83AB6D61785F7065725F726F7704AE6D61785F6A6F696E745F73697A6501A8666561747572657383A87061747465726E7384A3786F72C2A66C6F6F6B7570C2AB72616E67655F636865636BC3B1666F726569676E5F6669656C645F6D756CC2B16A6F696E745F6C6F6F6B75705F75736564C2B3757365735F72756E74696D655F7461626C6573C2B772756E74696D655F7461626C65735F73656C6563746F72C0"; - bytes urs_serialized = - hex"92dc0020c4200100000000000000000000000000000000000000000000000000000000000000c42055a8e8d2b2221c2e7641eb8f5b656e352c9e7b5aca91da8ca92fe127e7fb2c21c42003bc09f3825fafdefe1cb25b4a296b60f2129a1c3a90826c3dc2021be421aa8ec4206422698aa4f80a088fd4e0d3a3cd517c2cb1f280cb95c9313823b8f8060f1786c4203558cb03f0cf841ed3a8145a7a8084e182731a9628779ef59d3bc47bae8a1192c4202ac41dd231cb8e97ffc3281b20e6799c0ae18afc13d3de1b4b363a0cd070baa7c420b6205dfa129f52601adfd87829901f06f1fd32e22a71f44b769d674448f05d83c4205d1b9b83cdcba66ff9424c7242c67394d7956dabf5407f4105124b7239d43e80c420e95ffc0999a8997b045430aa564c7bd9a25303e8a5ebbe4a99f6329b7f2a64aac4206cca50f1237f867fee63ac65249d6911494680f42d0e71386b1586be39092f9cc4204b9b17d64b384a65d7c80c8ab0f5fff75c69fd147835599753beea03152a3923c4205c0f706b036ed361e787af70acea3533d6e349869e83368979fdbbf382a4900bc420da6652a81754a6263e677d23a55bd729205f5fb64fa39b6771d9b811e5548bafc4208db1ad69d758362a4ecacff98a6910a95b3c2697e455271b2d7c078f1894eb1fc42010f56f1046a1121b1df5c401969b5acbf80eef8bfd5438270e09243413382788c4200cca37d1a3a721792dc232bb6a95bd14143350b6784bcdd4898a0bb34dd8bd2cc4202b7a1991e05b77d911d15ae590ff6f6ad7d1ed572b34654e3ce92e38e4839425c4201977ca4631e9eea53c7ba59d334c14dac7ee1071d6bf6ebf2ab7450c16975d23c4209eb742379ee8664a8bf9c18a40a534bb2961020bd0077cd0b603d2a8b9fe5a17c4201c50af6002db8dfa5a310ce795dcb06de94ead6687687263fd59acbc8612f180c4205241cbed55fbe1193f366e7ea8ad11bc97742eb35ca39129c4931b9bef64df1ec420646e69eb7d4682ad6bff24d40bf22184694c569246385cc127b3ec4a99875a85c42046b77ed1e120130743344ea9372ea58118604c730800e0d7038f2c80211f4f90c4208f20f3c39a09b5615bd8b2a09eec7dbc11b5ea1f8fe7eb0d5a69c1264412d199c42095f0b87ed771c169a8b6c0a6e21b13ab715407a4e6637a0b8fe0a1e3278f32a7c420a80440e1a07157bad23d7a7d3ddd7445f578021650016fc4bfb3324ed967c82bc4202b94fd0b89e7e2c9d245a4e94a539b14c5db26ed5ba4b3989ef0ba0712d4582ec42068f583079aa73425184a328127be63421eae683a25be94a0aa697ce74b5b972dc4209fa10b770e452852612ea392b8521683999d0a168c5eb85a6925d1ffe21d418ac420826a0976821c9309ed896678a97634a2fb1392a64ab8c59c8380012ffb601189c4203096ba3ed0b597fa29da6caa9000a409702b1f945561e82d02ab77b0cfdb649fc4204a718bc27174d557e036bcbcb9874ce5a6e1a63ccbe491e509d4201bfcb50806c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c250a"; + // bytes urs_serialized = + // hex"92dc0020c4200100000000000000000000000000000000000000000000000000000000000000c42055a8e8d2b2221c2e7641eb8f5b656e352c9e7b5aca91da8ca92fe127e7fb2c21c42003bc09f3825fafdefe1cb25b4a296b60f2129a1c3a90826c3dc2021be421aa8ec4206422698aa4f80a088fd4e0d3a3cd517c2cb1f280cb95c9313823b8f8060f1786c4203558cb03f0cf841ed3a8145a7a8084e182731a9628779ef59d3bc47bae8a1192c4202ac41dd231cb8e97ffc3281b20e6799c0ae18afc13d3de1b4b363a0cd070baa7c420b6205dfa129f52601adfd87829901f06f1fd32e22a71f44b769d674448f05d83c4205d1b9b83cdcba66ff9424c7242c67394d7956dabf5407f4105124b7239d43e80c420e95ffc0999a8997b045430aa564c7bd9a25303e8a5ebbe4a99f6329b7f2a64aac4206cca50f1237f867fee63ac65249d6911494680f42d0e71386b1586be39092f9cc4204b9b17d64b384a65d7c80c8ab0f5fff75c69fd147835599753beea03152a3923c4205c0f706b036ed361e787af70acea3533d6e349869e83368979fdbbf382a4900bc420da6652a81754a6263e677d23a55bd729205f5fb64fa39b6771d9b811e5548bafc4208db1ad69d758362a4ecacff98a6910a95b3c2697e455271b2d7c078f1894eb1fc42010f56f1046a1121b1df5c401969b5acbf80eef8bfd5438270e09243413382788c4200cca37d1a3a721792dc232bb6a95bd14143350b6784bcdd4898a0bb34dd8bd2cc4202b7a1991e05b77d911d15ae590ff6f6ad7d1ed572b34654e3ce92e38e4839425c4201977ca4631e9eea53c7ba59d334c14dac7ee1071d6bf6ebf2ab7450c16975d23c4209eb742379ee8664a8bf9c18a40a534bb2961020bd0077cd0b603d2a8b9fe5a17c4201c50af6002db8dfa5a310ce795dcb06de94ead6687687263fd59acbc8612f180c4205241cbed55fbe1193f366e7ea8ad11bc97742eb35ca39129c4931b9bef64df1ec420646e69eb7d4682ad6bff24d40bf22184694c569246385cc127b3ec4a99875a85c42046b77ed1e120130743344ea9372ea58118604c730800e0d7038f2c80211f4f90c4208f20f3c39a09b5615bd8b2a09eec7dbc11b5ea1f8fe7eb0d5a69c1264412d199c42095f0b87ed771c169a8b6c0a6e21b13ab715407a4e6637a0b8fe0a1e3278f32a7c420a80440e1a07157bad23d7a7d3ddd7445f578021650016fc4bfb3324ed967c82bc4202b94fd0b89e7e2c9d245a4e94a539b14c5db26ed5ba4b3989ef0ba0712d4582ec42068f583079aa73425184a328127be63421eae683a25be94a0aa697ce74b5b972dc4209fa10b770e452852612ea392b8521683999d0a168c5eb85a6925d1ffe21d418ac420826a0976821c9309ed896678a97634a2fb1392a64ab8c59c8380012ffb601189c4203096ba3ed0b597fa29da6caa9000a409702b1f945561e82d02ab77b0cfdb649fc4204a718bc27174d557e036bcbcb9874ce5a6e1a63ccbe491e509d4201bfcb50806c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c250a"; function test_partial_verify() public { KimchiVerifier verifier = new KimchiVerifier(); - verifier.setup(urs_serialized); + verifier.setup(); verifier.verify_with_index( verifier_index_serialized, diff --git a/eth_verifier/test/State.t.sol b/eth_verifier/test/State.t.sol index 12d45b31..f4fdae3d 100644 --- a/eth_verifier/test/State.t.sol +++ b/eth_verifier/test/State.t.sol @@ -10,11 +10,11 @@ contract StateTest is Test { function setUp() public virtual { // Initialize contract. Code was taken from integration test - bytes - memory urs_serialized = hex"92dc0020c4200100000000000000000000000000000000000000000000000000000000000000c42055a8e8d2b2221c2e7641eb8f5b656e352c9e7b5aca91da8ca92fe127e7fb2c21c42003bc09f3825fafdefe1cb25b4a296b60f2129a1c3a90826c3dc2021be421aa8ec4206422698aa4f80a088fd4e0d3a3cd517c2cb1f280cb95c9313823b8f8060f1786c4203558cb03f0cf841ed3a8145a7a8084e182731a9628779ef59d3bc47bae8a1192c4202ac41dd231cb8e97ffc3281b20e6799c0ae18afc13d3de1b4b363a0cd070baa7c420b6205dfa129f52601adfd87829901f06f1fd32e22a71f44b769d674448f05d83c4205d1b9b83cdcba66ff9424c7242c67394d7956dabf5407f4105124b7239d43e80c420e95ffc0999a8997b045430aa564c7bd9a25303e8a5ebbe4a99f6329b7f2a64aac4206cca50f1237f867fee63ac65249d6911494680f42d0e71386b1586be39092f9cc4204b9b17d64b384a65d7c80c8ab0f5fff75c69fd147835599753beea03152a3923c4205c0f706b036ed361e787af70acea3533d6e349869e83368979fdbbf382a4900bc420da6652a81754a6263e677d23a55bd729205f5fb64fa39b6771d9b811e5548bafc4208db1ad69d758362a4ecacff98a6910a95b3c2697e455271b2d7c078f1894eb1fc42010f56f1046a1121b1df5c401969b5acbf80eef8bfd5438270e09243413382788c4200cca37d1a3a721792dc232bb6a95bd14143350b6784bcdd4898a0bb34dd8bd2cc4202b7a1991e05b77d911d15ae590ff6f6ad7d1ed572b34654e3ce92e38e4839425c4201977ca4631e9eea53c7ba59d334c14dac7ee1071d6bf6ebf2ab7450c16975d23c4209eb742379ee8664a8bf9c18a40a534bb2961020bd0077cd0b603d2a8b9fe5a17c4201c50af6002db8dfa5a310ce795dcb06de94ead6687687263fd59acbc8612f180c4205241cbed55fbe1193f366e7ea8ad11bc97742eb35ca39129c4931b9bef64df1ec420646e69eb7d4682ad6bff24d40bf22184694c569246385cc127b3ec4a99875a85c42046b77ed1e120130743344ea9372ea58118604c730800e0d7038f2c80211f4f90c4208f20f3c39a09b5615bd8b2a09eec7dbc11b5ea1f8fe7eb0d5a69c1264412d199c42095f0b87ed771c169a8b6c0a6e21b13ab715407a4e6637a0b8fe0a1e3278f32a7c420a80440e1a07157bad23d7a7d3ddd7445f578021650016fc4bfb3324ed967c82bc4202b94fd0b89e7e2c9d245a4e94a539b14c5db26ed5ba4b3989ef0ba0712d4582ec42068f583079aa73425184a328127be63421eae683a25be94a0aa697ce74b5b972dc4209fa10b770e452852612ea392b8521683999d0a168c5eb85a6925d1ffe21d418ac420826a0976821c9309ed896678a97634a2fb1392a64ab8c59c8380012ffb601189c4203096ba3ed0b597fa29da6caa9000a409702b1f945561e82d02ab77b0cfdb649fc4204a718bc27174d557e036bcbcb9874ce5a6e1a63ccbe491e509d4201bfcb50806c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c250a"; + // bytes + // memory urs_serialized = hex"92dc0020c4200100000000000000000000000000000000000000000000000000000000000000c42055a8e8d2b2221c2e7641eb8f5b656e352c9e7b5aca91da8ca92fe127e7fb2c21c42003bc09f3825fafdefe1cb25b4a296b60f2129a1c3a90826c3dc2021be421aa8ec4206422698aa4f80a088fd4e0d3a3cd517c2cb1f280cb95c9313823b8f8060f1786c4203558cb03f0cf841ed3a8145a7a8084e182731a9628779ef59d3bc47bae8a1192c4202ac41dd231cb8e97ffc3281b20e6799c0ae18afc13d3de1b4b363a0cd070baa7c420b6205dfa129f52601adfd87829901f06f1fd32e22a71f44b769d674448f05d83c4205d1b9b83cdcba66ff9424c7242c67394d7956dabf5407f4105124b7239d43e80c420e95ffc0999a8997b045430aa564c7bd9a25303e8a5ebbe4a99f6329b7f2a64aac4206cca50f1237f867fee63ac65249d6911494680f42d0e71386b1586be39092f9cc4204b9b17d64b384a65d7c80c8ab0f5fff75c69fd147835599753beea03152a3923c4205c0f706b036ed361e787af70acea3533d6e349869e83368979fdbbf382a4900bc420da6652a81754a6263e677d23a55bd729205f5fb64fa39b6771d9b811e5548bafc4208db1ad69d758362a4ecacff98a6910a95b3c2697e455271b2d7c078f1894eb1fc42010f56f1046a1121b1df5c401969b5acbf80eef8bfd5438270e09243413382788c4200cca37d1a3a721792dc232bb6a95bd14143350b6784bcdd4898a0bb34dd8bd2cc4202b7a1991e05b77d911d15ae590ff6f6ad7d1ed572b34654e3ce92e38e4839425c4201977ca4631e9eea53c7ba59d334c14dac7ee1071d6bf6ebf2ab7450c16975d23c4209eb742379ee8664a8bf9c18a40a534bb2961020bd0077cd0b603d2a8b9fe5a17c4201c50af6002db8dfa5a310ce795dcb06de94ead6687687263fd59acbc8612f180c4205241cbed55fbe1193f366e7ea8ad11bc97742eb35ca39129c4931b9bef64df1ec420646e69eb7d4682ad6bff24d40bf22184694c569246385cc127b3ec4a99875a85c42046b77ed1e120130743344ea9372ea58118604c730800e0d7038f2c80211f4f90c4208f20f3c39a09b5615bd8b2a09eec7dbc11b5ea1f8fe7eb0d5a69c1264412d199c42095f0b87ed771c169a8b6c0a6e21b13ab715407a4e6637a0b8fe0a1e3278f32a7c420a80440e1a07157bad23d7a7d3ddd7445f578021650016fc4bfb3324ed967c82bc4202b94fd0b89e7e2c9d245a4e94a539b14c5db26ed5ba4b3989ef0ba0712d4582ec42068f583079aa73425184a328127be63421eae683a25be94a0aa697ce74b5b972dc4209fa10b770e452852612ea392b8521683999d0a168c5eb85a6925d1ffe21d418ac420826a0976821c9309ed896678a97634a2fb1392a64ab8c59c8380012ffb601189c4203096ba3ed0b597fa29da6caa9000a409702b1f945561e82d02ab77b0cfdb649fc4204a718bc27174d557e036bcbcb9874ce5a6e1a63ccbe491e509d4201bfcb50806c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c250a"; verifier = new KimchiVerifier(); - verifier.setup(urs_serialized); + verifier.setup(); } function test_verify_retrieve() public { From b706662f0530709dacd2025dd9f1127ac4cfc883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9fano=20Bargas?= Date: Mon, 18 Dec 2023 13:05:14 -0300 Subject: [PATCH 45/68] Small fixes --- eth_verifier/lib/Polynomial.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eth_verifier/lib/Polynomial.sol b/eth_verifier/lib/Polynomial.sol index 87e682bb..facdcb66 100644 --- a/eth_verifier/lib/Polynomial.sol +++ b/eth_verifier/lib/Polynomial.sol @@ -32,7 +32,7 @@ library Polynomial { } function sub(Dense memory self, Dense memory other) public view returns (Dense memory) { - uint n = Utils.max(self.coeffs.length, other.coeffs.length); + uint n = Utils.min(self.coeffs.length, other.coeffs.length); Scalar.FE[] memory coeffs_self_sub_other = new Scalar.FE[](n); for (uint i = 0; i < n; i++) { coeffs_self_sub_other[i] = self.coeffs[i].sub(other.coeffs[i]); @@ -76,7 +76,7 @@ library Polynomial { Scalar.FE term = domain_gen.pow(domain_size - i); Dense memory acc = sub(x, constant_poly(term)); - for (uint j = 0; j < i - 1; i++) { + for (uint j = 0; j < i - 1; j++) { term = term.mul(domain_gen); acc = mul(acc, sub(x, constant_poly(term))); } From 8cc7dd428741d56ed4a2e013b4287f162f2318fc Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Mon, 18 Dec 2023 18:11:05 -0300 Subject: [PATCH 46/68] minor spaces --- eth_verifier/src/Verifier.sol | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index ed6fd920..615c0090 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -287,19 +287,24 @@ contract KimchiVerifier { VariableBaseMSM::multi_scalar_mul(&points, &scalars) }; + */ + /* let evals = combine_evaluations(evaluations, polyscale); let blinding_commitment = srs.full_srs.h.mul(self.blinding); let divisor_commitment = srs .verifier_srs .commit_non_hiding(&divisor_polynomial(elm), 1, None) .unshifted[0]; + */ + /* let eval_commitment = srs .full_srs .commit_non_hiding(&eval_polynomial(elm, &evals), 1, None) .unshifted[0] .into_projective(); let numerator_commitment = { poly_commitment - eval_commitment - blinding_commitment }; - + */ + /* let numerator = Pair::pairing( numerator_commitment, Pair::G2Affine::prime_subgroup_generator(), From 008d8808e4cb3a1fecb209d6ed4c588a47356705 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Mon, 18 Dec 2023 18:31:28 -0300 Subject: [PATCH 47/68] Cargo lock updated --- kzg_prover/Cargo.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/kzg_prover/Cargo.lock b/kzg_prover/Cargo.lock index 890bf9aa..2d3af2b3 100644 --- a/kzg_prover/Cargo.lock +++ b/kzg_prover/Cargo.lock @@ -508,7 +508,6 @@ dependencies = [ name = "mina-curves" version = "0.1.0" dependencies = [ - "ark-bn254", "ark-ec", "ark-ff", ] From 1bc0052a70b1ea8ec6b9be083355050ba5c31e2b Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Tue, 19 Dec 2023 18:05:51 -0300 Subject: [PATCH 48/68] eval_polynomial function in solidity --- eth_verifier/lib/bn254/Fields.sol | 39 +++++++++---------------- eth_verifier/src/Verifier.sol | 47 ++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/eth_verifier/lib/bn254/Fields.sol b/eth_verifier/lib/bn254/Fields.sol index e7c00a58..ed76ce6a 100644 --- a/eth_verifier/lib/bn254/Fields.sol +++ b/eth_verifier/lib/bn254/Fields.sol @@ -29,19 +29,13 @@ library Base { return FE.wrap(integer % MODULUS); } - function add( - FE self, - FE other - ) public pure returns (FE res) { + function add(FE self, FE other) public pure returns (FE res) { assembly { res := addmod(self, other, MODULUS) // addmod has arbitrary precision } } - function mul( - FE self, - FE other - ) public pure returns (FE res) { + function mul(FE self, FE other) public pure returns (FE res) { assembly { res := mulmod(self, other, MODULUS) // mulmod has arbitrary precision } @@ -105,16 +99,17 @@ library Base { } import {console} from "forge-std/console.sol"; + /// @notice Implements 256 bit modular arithmetic over the scalar field of bn254. library Scalar { type FE is uint256; - using { add, mul, inv, neg, sub } for FE; + using {add, mul, inv, neg, sub} for FE; uint256 public constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - uint256 public constant TWO_ADIC_PRIMITIVE_ROOT_OF_UNITY = + uint256 public constant TWO_ADIC_PRIMITIVE_ROOT_OF_UNITY = 19103219067921713944291392827692070036145651957329286315305642004821462161904; uint256 public constant TWO_ADICITY = 28; @@ -142,19 +137,13 @@ library Scalar { return FE.wrap(integer % MODULUS); } - function add( - FE self, - FE other - ) public pure returns (FE res) { + function add(FE self, FE other) public pure returns (FE res) { assembly { res := addmod(self, other, MODULUS) // addmod has arbitrary precision } } - function mul( - FE self, - FE other - ) public pure returns (FE res) { + function mul(FE self, FE other) public pure returns (FE res) { assembly { res := mulmod(self, other, MODULUS) // mulmod has arbitrary precision } @@ -168,7 +157,7 @@ library Scalar { res = mul(self, self); } - function inv(FE self) public view returns (FE) { + function inv(FE self) public pure returns (FE) { require(FE.unwrap(self) != 0, "tried to get inverse of 0"); (uint gcd, uint inverse) = Aux.xgcd(FE.unwrap(self), MODULUS); require(gcd == 1, "gcd not 1"); @@ -219,6 +208,7 @@ library Scalar { } error RootOfUnityError(); + /// @notice returns a primitive root of unity of order $2^{order}$. // Reference: Lambdaworks // https://github.com/lambdaclass/lambdaworks/ @@ -247,10 +237,7 @@ library Aux { /// @notice Extended euclidean algorithm. Returns [gcd, Bezout_a] /// @notice so gcd = a*Bezout_a + b*Bezout_b. /// @notice source: https://www.extendedeuclideanalgorithm.com/code - function xgcd( - uint a, - uint b - ) public pure returns (uint r0, uint s0) { + function xgcd(uint a, uint b) public pure returns (uint r0, uint s0) { r0 = a; uint r1 = b; s0 = 1; @@ -261,21 +248,21 @@ library Aux { uint n = 0; while (r1 != 0) { uint q = r0 / r1; - r0 = r0 > q*r1 ? r0 - q*r1 : q*r1 - r0; // abs + r0 = r0 > q * r1 ? r0 - q * r1 : q * r1 - r0; // abs // swap r0, r1 uint temp = r0; r0 = r1; r1 = temp; - s0 = s0 + q*s1; + s0 = s0 + q * s1; // swap s0, s1 temp = s0; s0 = s1; s1 = temp; - t0 = t0 + q*t1; + t0 = t0 + q * t1; // swap t0, t1 temp = t0; diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 59525511..a7f78860 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -18,7 +18,13 @@ import "../lib/expr/PolishToken.sol"; import "../lib/expr/ExprConstants.sol"; using {BN254.neg} for BN254.G1Point; -using {Scalar.neg, Scalar.mul, Scalar.add} for Scalar.FE; +using { + Scalar.neg, + Scalar.mul, + Scalar.add, + Scalar.inv, + Scalar.sub +} for Scalar.FE; using {AlphasLib.get_alphas} for Alphas; using {Polynomial.evaluate} for Polynomial.Dense; @@ -325,6 +331,45 @@ contract KimchiVerifier { */ } + /// The polynomial that evaluates to each of `evals` for the respective `elm`s. + function eval_polynomial( + Scalar.FE[] memory elm, + Scalar.FE[] memory evals + ) public pure returns (Polynomial.Dense memory) { + require(elm.length == evals.length, "lengths don't match"); + require(elm.length == 2, "length must be 2"); + Scalar.FE zeta = elm[0]; + Scalar.FE zeta_omega = elm[1]; + Scalar.FE eval_zeta = evals[0]; + Scalar.FE eval_zeta_omega = evals[1]; + + // The polynomial that evaluates to `p(zeta)` at `zeta` and `p(zeta_omega)` at + // `zeta_omega`. + // We write `p(x) = a + bx`, which gives + // ```text + // p(zeta) = a + b * zeta + // p(zeta_omega) = a + b * zeta_omega + // ``` + // and so + // ```text + // b = (p(zeta_omega) - p(zeta)) / (zeta_omega - zeta) + // a = p(zeta) - b * zeta + // ``` + + // Compute b + Scalar.FE num_b = eval_zeta_omega.add(eval_zeta.neg()); + Scalar.FE den_b_inv = zeta_omega.add(zeta.neg()).inv(); + Scalar.FE b = num_b.mul(den_b_inv); + + // Compute a + Scalar.FE a = eval_zeta.sub(b.mul(zeta)); + + Scalar.FE[] memory coeffs = new Scalar.FE[](2); + coeffs[0] = a; + coeffs[1] = b; + return Polynomial.Dense(coeffs); + } + /* This is a list of steps needed for verification. From 58046d73dbf3deab8eb6d0eaccf844fe20014db3 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Thu, 21 Dec 2023 16:49:31 -0300 Subject: [PATCH 49/68] Evaluation struct --- eth_verifier/lib/Evaluations.sol | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/eth_verifier/lib/Evaluations.sol b/eth_verifier/lib/Evaluations.sol index 6e67d71c..12d78572 100644 --- a/eth_verifier/lib/Evaluations.sol +++ b/eth_verifier/lib/Evaluations.sol @@ -2,6 +2,7 @@ pragma solidity >=0.4.16 <0.9.0; import "./bn254/Fields.sol"; +import "./Polynomial.sol"; struct PointEvaluations { /// evaluation at the challenge point zeta @@ -16,3 +17,13 @@ struct PointEvaluationsArray { /// Evaluation at `zeta . omega`, the product of the challenge point and the group generator Scalar.FE[] zeta_omega; } + +/// Contains the evaluation of a polynomial commitment at a set of points. +struct Evaluation { + /// The commitment of the polynomial being evaluated + Polynomial.Dense commitment; + /// Contains an evaluation table + Scalar.FE[][] evaluations; + /// optional degree bound + uint128 degree_bound; +} From 58305424a97d8fed272bec3ce2f543f67c75b492 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Fri, 22 Dec 2023 15:27:13 -0300 Subject: [PATCH 50/68] first attemp of combineCommitments --- eth_verifier/src/Verifier.sol | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index a7f78860..e3cedcc1 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -370,6 +370,48 @@ contract KimchiVerifier { return Polynomial.Dense(coeffs); } + function combineCommitments( + Evaluation[] memory evaluations, + Scalar.FE[] memory scalars, + uint256[] memory points, + Scalar.FE polyscale, + Scalar.FE rand_base + ) internal { + // Initialize xi_i to 1 + uint256 xi_i = 1; + + // Iterate over the evaluations + for (uint256 i = 0; i < evaluations.length; i++) { + // Filter out evaluations with an empty commitment + if (evaluations[i].unshifted.length > 0) { + // Iterate over the polynomial segments + for (uint256 j = 0; j < evaluations[i].unshifted.length; j++) { + // Add the scalar rand_base * xi_i to the scalars vector + scalars[i * 2] = rand_base * xi_i; + // Add the point to the points vector + points[i * 2] = evaluations[i].unshifted[j]; + + // Multiply xi_i by polyscale + xi_i *= polyscale; + } + + // If the evaluation has a degree bound and a non-zero shifted commitment + if ( + evaluations[i].degree_bound > 0 && + evaluations[i].shifted.length > 0 + ) { + // Add the scalar rand_base * xi_i to the scalars vector + scalars[i * 2 + 1] = rand_base * xi_i; + // Add the point to the points vector + points[i * 2 + 1] = evaluations[i].shifted[0]; + + // Multiply xi_i by polyscale + xi_i *= polyscale; + } + } + } + } + /* This is a list of steps needed for verification. From 7d4f2d0277b0467d17b78261cd3801ba3c6cfdfd Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Fri, 22 Dec 2023 15:33:42 -0300 Subject: [PATCH 51/68] Evaluation corrected --- eth_verifier/lib/Evaluations.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eth_verifier/lib/Evaluations.sol b/eth_verifier/lib/Evaluations.sol index 12d78572..ec84e137 100644 --- a/eth_verifier/lib/Evaluations.sol +++ b/eth_verifier/lib/Evaluations.sol @@ -3,6 +3,7 @@ pragma solidity >=0.4.16 <0.9.0; import "./bn254/Fields.sol"; import "./Polynomial.sol"; +import "./Commitment.sol"; struct PointEvaluations { /// evaluation at the challenge point zeta @@ -21,7 +22,7 @@ struct PointEvaluationsArray { /// Contains the evaluation of a polynomial commitment at a set of points. struct Evaluation { /// The commitment of the polynomial being evaluated - Polynomial.Dense commitment; + PolyComm commitment; /// Contains an evaluation table Scalar.FE[][] evaluations; /// optional degree bound From 776637457aaeafb013cd2a889ca904a298f9e055 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Fri, 22 Dec 2023 16:48:17 -0300 Subject: [PATCH 52/68] wip --- eth_verifier/src/Verifier.sol | 83 ++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index e3cedcc1..02187795 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -370,44 +370,75 @@ contract KimchiVerifier { return Polynomial.Dense(coeffs); } + /* +/// Contains the evaluation of a polynomial commitment at a set of points. +struct Evaluation { + /// The commitment of the polynomial being evaluated + Polynomial.Dense commitment; + /// Contains an evaluation table + Scalar.FE[][] evaluations; + /// optional degree bound + uint128 degree_bound; +} + */ + function combineCommitments( Evaluation[] memory evaluations, - Scalar.FE[] memory scalars, - uint256[] memory points, Scalar.FE polyscale, Scalar.FE rand_base - ) internal { + ) internal returns (Scalar.FE[] memory) { + BN254.G1Point[] memory points; + Scalar.FE[] memory scalars; + // Initialize xi_i to 1 - uint256 xi_i = 1; + Scalar.FE xi_i = Scalar.FE.wrap(1); // Iterate over the evaluations for (uint256 i = 0; i < evaluations.length; i++) { // Filter out evaluations with an empty commitment - if (evaluations[i].unshifted.length > 0) { - // Iterate over the polynomial segments - for (uint256 j = 0; j < evaluations[i].unshifted.length; j++) { - // Add the scalar rand_base * xi_i to the scalars vector - scalars[i * 2] = rand_base * xi_i; - // Add the point to the points vector - points[i * 2] = evaluations[i].unshifted[j]; - - // Multiply xi_i by polyscale - xi_i *= polyscale; - } + if (evaluations[i].commitment.unshifted.length == 0) { + continue; + } + + // Iterate over the polynomial segments + for ( + uint256 j = 0; + j < evaluations[i].commitment.unshifted.length; + j++ + ) { + Scalar.FE comm_ch = evaluations[i].commitment.unshifted[j]; + points.push(comm_ch); + /* + // iterating over the polynomial segments + for comm_ch in &commitment.unshifted { + scalars.push(rand_base * xi_i); + points.push(*comm_ch); - // If the evaluation has a degree bound and a non-zero shifted commitment - if ( - evaluations[i].degree_bound > 0 && - evaluations[i].shifted.length > 0 - ) { - // Add the scalar rand_base * xi_i to the scalars vector - scalars[i * 2 + 1] = rand_base * xi_i; - // Add the point to the points vector - points[i * 2 + 1] = evaluations[i].shifted[0]; - - // Multiply xi_i by polyscale xi_i *= polyscale; } + */ + + // Add the scalar rand_base * xi_i to the scalars vector + //scalars[i * 2] = rand_base.mul(xi_i); + // Add the point to the points vector + //points[i * 2] = evaluations[i].commitment.unshifted[j]; + + // Multiply xi_i by polyscale + xi_i *= polyscale; + } + + // If the evaluation has a degree bound and a non-zero shifted commitment + if ( + evaluations[i].degree_bound > 0 && + evaluations[i].shifted.length > 0 + ) { + // Add the scalar rand_base * xi_i to the scalars vector + scalars[i * 2 + 1] = rand_base * xi_i; + // Add the point to the points vector + points[i * 2 + 1] = evaluations[i].shifted[0]; + + // Multiply xi_i by polyscale + xi_i *= polyscale; } } } From 4413c5bb9e7fab8f28a44f30239c2fc4a3ee8558 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Tue, 2 Jan 2024 16:53:12 -0300 Subject: [PATCH 53/68] function deserializeScalar removed --- eth_verifier/lib/msgpack/Deserialize.sol | 46 ------------------------ 1 file changed, 46 deletions(-) diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index bf7df8ee..a5ca4a68 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -719,52 +719,6 @@ library MsgPk { return (g, h, final_i); } - // TODO: this function is not used anywhere, but it's useful for debugging - function deserializeOpeningProof( - bytes calldata serialized_proof - ) public view returns (Kimchi.ProverProof memory proof) { - uint256 i = 0; - bytes1 firstbyte = serialized_proof[i]; - // first byte is 0x92, indicating this is an array with 2 elements - require(firstbyte == 0x92, "first byte is not 0x92"); - - // read length of the data - i += 1; - require(serialized_proof[i] == 0xC4, "second byte is not 0xC4"); - - // next byte is the length of the data in one byte - i += 1; - require(serialized_proof[i] == 0x20, "size of element is not 32 bytes"); - - // read data - i += 1; - bytes32 data_quotient = abi.decode( - serialized_proof[i:i + 32], - (bytes32) - ); - - proof.opening_proof_quotient = BN254.g1Deserialize(data_quotient); - - // read blinding - i += 32; - // read length of the data - require(serialized_proof[i] == 0xC4, "second byte is not 0xC4"); - - // next byte is the length of the data in one byte - i += 1; - require(serialized_proof[i] == 0x20, "size of element is not 32 bytes"); - - // read data - i += 1; - uint256 data_blinding = abi.decode( - serialized_proof[i:i + 32], - (uint256) - ); - - proof.opening_proof_blinding = data_blinding; - return proof; - } - function deserializeScalar( bytes calldata data, uint256 i From 9b748fe57f610e5b361292cbc5da9f2313a1eb0c Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Tue, 2 Jan 2024 19:10:57 -0300 Subject: [PATCH 54/68] correction in combineCommitments --- eth_verifier/src/Verifier.sol | 54 +++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index d7895c12..5256b145 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -390,8 +390,20 @@ struct Evaluation { Scalar.FE polyscale, Scalar.FE rand_base ) internal returns (Scalar.FE[] memory) { - BN254.G1Point[] memory points; - Scalar.FE[] memory scalars; + uint256 vec_length = 0; + // Calculate the max length of the points and scalars vectors + // Iterate over the evaluations + for (uint256 i = 0; i < evaluations.length; i++) { + // Filter out evaluations with an empty commitment + if (evaluations[i].commitment.unshifted.length == 0) { + continue; + } + + vec_length += evaluations[i].commitment.unshifted.length + 1; + } + BN254.G1Point[] memory points = new BN254.G1Point[](vec_length); + Scalar.FE[] memory scalars = new Scalar.FE[](vec_length); + uint256 index = 0; // index of the element to assign in the vectors // Initialize xi_i to 1 Scalar.FE xi_i = Scalar.FE.wrap(1); @@ -403,33 +415,38 @@ struct Evaluation { continue; } - // Iterate over the polynomial segments + // iterating over the polynomial segments for ( uint256 j = 0; j < evaluations[i].commitment.unshifted.length; j++ ) { - Scalar.FE comm_ch = evaluations[i].commitment.unshifted[j]; - points.push(comm_ch); - /* - // iterating over the polynomial segments - for comm_ch in &commitment.unshifted { - scalars.push(rand_base * xi_i); - points.push(*comm_ch); - - xi_i *= polyscale; - } - */ - // Add the scalar rand_base * xi_i to the scalars vector - //scalars[i * 2] = rand_base.mul(xi_i); + scalars[index] = rand_base.mul(xi_i); // Add the point to the points vector - //points[i * 2] = evaluations[i].commitment.unshifted[j]; + points[index] = evaluations[i].commitment.unshifted[j]; // Multiply xi_i by polyscale - xi_i *= polyscale; + xi_i = xi_i.mul(polyscale); + + // Increment the index + index++; } + /* + if let Some(_m) = degree_bound { + if let Some(comm_ch) = commitment.shifted { + if !comm_ch.is_zero() { + // polyscale^i sum_j evalscale^j elm_j^{N - m} f(elm_j) + scalars.push(rand_base * xi_i); + points.push(comm_ch); + + xi_i *= polyscale; + } + } + } + */ + /* TODO: FIX this with the previous version of the code // If the evaluation has a degree bound and a non-zero shifted commitment if ( evaluations[i].degree_bound > 0 && @@ -443,6 +460,7 @@ struct Evaluation { // Multiply xi_i by polyscale xi_i *= polyscale; } + */ } } From 4195e4c2707f5e756bccaab9f0e614f9acbff66d Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 15:08:16 -0300 Subject: [PATCH 55/68] changing format --- eth_verifier/lib/Commitment.sol | 176 ++++++++++++++----------------- eth_verifier/lib/Evaluations.sol | 2 +- eth_verifier/lib/Proof.sol | 26 ++--- eth_verifier/src/Verifier.sol | 158 ++++++++------------------- 4 files changed, 136 insertions(+), 226 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 8a476125..50cb757d 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -6,16 +6,8 @@ import "./bn254/Fields.sol"; import "./Utils.sol"; import "./Polynomial.sol"; -using { BN254.add, BN254.scale_scalar } for BN254.G1Point; -using { - Scalar.neg, - Scalar.add, - Scalar.sub, - Scalar.mul, - Scalar.inv, - Scalar.double, - Scalar.pow -} for Scalar.FE; +using {BN254.add, BN254.scale_scalar} for BN254.G1Point; +using {Scalar.neg, Scalar.add, Scalar.sub, Scalar.mul, Scalar.inv, Scalar.double, Scalar.pow} for Scalar.FE; error MSMInvalidLengths(); @@ -24,12 +16,12 @@ struct URS { BN254.G1Point h; } -function create_trusted_setup(Scalar.FE x, uint depth) view returns (URS memory) { +function create_trusted_setup(Scalar.FE x, uint256 depth) view returns (URS memory) { Scalar.FE x_pow = Scalar.one(); BN254.G1Point[] memory g = new BN254.G1Point[](depth); BN254.G1Point memory h = BN254.P1(); // should be blake2b hash - for (uint i = 0; i < depth; i++) { + for (uint256 i = 0; i < depth; i++) { g[i] = BN254.P1().scale_scalar(x_pow); x_pow = x_pow.mul(x); } @@ -43,14 +35,14 @@ struct PairingURS { mapping(uint256 => PolyCommFlat) lagrange_bases_unshifted; } -function random_lagrange_bases(PairingURS storage urs, uint domain_size) { - uint n = domain_size; +function random_lagrange_bases(PairingURS storage urs, uint256 domain_size) { + uint256 n = domain_size; - uint[] memory u_lengths = new uint[](1); + uint256[] memory u_lengths = new uint[](1); u_lengths[0] = domain_size; BN254.G1Point[] memory unshifteds = new BN254.G1Point[](domain_size); - for (uint i = 0; i < domain_size; i++) { + for (uint256 i = 0; i < domain_size; i++) { unshifteds[i] = BN254.P1(); } @@ -58,11 +50,11 @@ function random_lagrange_bases(PairingURS storage urs, uint domain_size) { urs.lagrange_bases_unshifted[domain_size] = comms; } +// WARN: The field shifted is optional but in Solidity we can't have that. +// for our test circuit it's not necessary, we can just ignore it, using infinity. +//BN254.G1Point shifted; struct PolyComm { BN254.G1Point[] unshifted; - //BN254G1Point shifted; - // WARN: The previous field is optional but in Solidity we can't have that. - // for our test circuit it's not necessary } // @notice this structure flattens the fields of `PolyComm`. @@ -70,36 +62,38 @@ struct PolyComm { // in a mapping. struct PolyCommFlat { BN254.G1Point[] unshifteds; - uint[] unshifted_lengths; + uint256[] unshifted_lengths; } function poly_comm_unflat(PolyCommFlat memory com) pure returns (PolyComm[] memory res) { - uint comm_count = com.unshifted_lengths.length; - res = new PolyComm[](comm_count); - uint index = 0; - for (uint i = 0; i < comm_count; i++) { - uint n = com.unshifted_lengths[i]; + uint256 comm_count = com.unshifted_lengths.length; + res = new PolyComm[](comm_count); + uint256 index = 0; + for (uint256 i = 0; i < comm_count; i++) { + uint256 n = com.unshifted_lengths[i]; BN254.G1Point[] memory unshifted = new BN254.G1Point[](n); - for (uint j = 0; j < n; j++) { + for (uint256 j = 0; j < n; j++) { unshifted[j] = com.unshifteds[index]; index++; } + // TODO: shifted is fixed to infinity + //BN254.G1Point shifted = BN254.point_at_inf(); res[i] = PolyComm(unshifted); } } function poly_comm_flat(PolyComm[] memory com) pure returns (PolyCommFlat memory) { - uint total_length = 0; - uint[] memory unshifted_lengths = new uint[](com.length); - for (uint i = 0; i < com.length; i++) { + uint256 total_length = 0; + uint256[] memory unshifted_lengths = new uint[](com.length); + for (uint256 i = 0; i < com.length; i++) { total_length += com[i].unshifted.length; unshifted_lengths[i] = com[i].unshifted.length; } BN254.G1Point[] memory unshifteds = new BN254.G1Point[](total_length); - uint index = 0; - for (uint i = 0; i < com.length; i++) { - for (uint j = 0; j < com[i].unshifted.length; j++) { + uint256 index = 0; + for (uint256 i = 0; i < com.length; i++) { + for (uint256 j = 0; j < com[i].unshifted.length; j++) { unshifteds[index] = com[i].unshifted[j]; index++; } @@ -110,10 +104,7 @@ function poly_comm_flat(PolyComm[] memory com) pure returns (PolyCommFlat memory // @notice Executes multi-scalar multiplication between scalars `elm` and commitments `com`. // @notice If empty, returns a commitment with the point at infinity. -function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) - view - returns (PolyComm memory) -{ +function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) view returns (PolyComm memory) { if (com.length == 0 || elm.length == 0) { BN254.G1Point[] memory z = new BN254.G1Point[](1); z[0] = BN254.point_at_inf(); @@ -135,13 +126,12 @@ function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) } BN254.G1Point[] memory unshifted = new BN254.G1Point[](unshifted_len); - for (uint chunk = 0; chunk < unshifted_len; chunk++) { - + for (uint256 chunk = 0; chunk < unshifted_len; chunk++) { // zip with elements and filter scalars that don't have an associated chunk. // first get the count of elements that have a chunk: - uint chunk_length = 0; - for (uint i = 0; i < n; i++) { + uint256 chunk_length = 0; + for (uint256 i = 0; i < n; i++) { if (com[i].unshifted.length > chunk) { chunk_length++; } @@ -150,8 +140,8 @@ function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) // fill arrays BN254.G1Point[] memory points = new BN254.G1Point[](chunk_length); Scalar.FE[] memory scalars = new Scalar.FE[](chunk_length); - uint index = 0; - for (uint i = 0; i < n; i++) { + uint256 index = 0; + for (uint256 i = 0; i < n; i++) { if (com[i].unshifted.length > chunk) { points[index] = (com[i].unshifted[chunk]); scalars[index] = (elm[i]); @@ -166,10 +156,7 @@ function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) } // @notice Execute a simple multi-scalar multiplication -function naive_msm(BN254.G1Point[] memory points, Scalar.FE[] memory scalars) - view - returns (BN254.G1Point memory) -{ +function naive_msm(BN254.G1Point[] memory points, Scalar.FE[] memory scalars) view returns (BN254.G1Point memory) { BN254.G1Point memory result = BN254.point_at_inf(); for (uint256 i = 0; i < points.length; i++) { @@ -189,16 +176,15 @@ error InvalidPolycommLength(); // @notice Turns a non-hiding polynomial commitment into a hidding polynomial commitment. // @notice Transforms each given `` into `( + wH, w)`. // INFO: since we are ignoring shifted elements of a commitment, `blinders` only needs to be a Scalar[] -function mask_custom( - URS storage urs, - PolyComm memory com, - Scalar.FE[] memory blinders -) view returns (BlindedCommitment memory) { +function mask_custom(URS storage urs, PolyComm memory com, Scalar.FE[] memory blinders) + view + returns (BlindedCommitment memory) +{ if (com.unshifted.length != blinders.length) { revert InvalidPolycommLength(); } - uint u_len = com.unshifted.length; + uint256 u_len = com.unshifted.length; BN254.G1Point[] memory unshifted = new BN254.G1Point[](u_len); for (uint256 i = 0; i < u_len; i++) { BN254.G1Point memory g_masked = urs.h.scale_scalar(blinders[i]); @@ -213,45 +199,45 @@ function mask_custom( function calculate_lagrange_bases( BN254.G1Point[] memory g, BN254.G1Point memory h, - uint domain_size, + uint256 domain_size, mapping(uint256 => PolyCommFlat) storage lagrange_bases_unshifted ) { - uint urs_size = g.length; - uint num_unshifteds = (domain_size + urs_size - 1) / urs_size; - BN254.G1Point[][] memory unshifted = new BN254.G1Point[][](num_unshifteds); - - // For each chunk - for (uint i = 0; i < num_unshifteds; i++) { - // Initialize the vector with zero curve points - BN254.G1Point[] memory lg = new BN254.G1Point[](domain_size); - for (uint j = 0; j < lg.length; j++) { - lg[j] = BN254.point_at_inf(); - } - - // Overwrite the terms corresponding to that chunk with the SRS curve points - uint start_offset = i * urs_size; - uint num_terms = Utils.min((i + 1) * urs_size, domain_size) - start_offset; - for (uint j = 0; j < num_terms; j++) { - lg[start_offset + j] = g[j]; - } - // Apply the IFFT - BN254.G1Point[] memory lg_fft = Utils.ifft(lg); - // Append the 'partial Langrange polynomials' to the vector of unshifted chunks - unshifted[i] = lg_fft; + uint256 urs_size = g.length; + uint256 num_unshifteds = (domain_size + urs_size - 1) / urs_size; + BN254.G1Point[][] memory unshifted = new BN254.G1Point[][](num_unshifteds); + + // For each chunk + for (uint256 i = 0; i < num_unshifteds; i++) { + // Initialize the vector with zero curve points + BN254.G1Point[] memory lg = new BN254.G1Point[](domain_size); + for (uint256 j = 0; j < lg.length; j++) { + lg[j] = BN254.point_at_inf(); } - PolyCommFlat storage bases_unshifted = lagrange_bases_unshifted[domain_size]; - uint[] memory unshifted_lengths = new uint[](num_unshifteds); - for (uint i = 0; i < num_unshifteds; i++) { - unshifted_lengths[i] = 0; + // Overwrite the terms corresponding to that chunk with the SRS curve points + uint256 start_offset = i * urs_size; + uint256 num_terms = Utils.min((i + 1) * urs_size, domain_size) - start_offset; + for (uint256 j = 0; j < num_terms; j++) { + lg[start_offset + j] = g[j]; } - bases_unshifted.unshifted_lengths = unshifted_lengths; + // Apply the IFFT + BN254.G1Point[] memory lg_fft = Utils.ifft(lg); + // Append the 'partial Langrange polynomials' to the vector of unshifted chunks + unshifted[i] = lg_fft; + } - for (uint i = 0; i < domain_size; i++) { - for (uint j = 0; j < unshifted.length; j++) { - bases_unshifted.unshifteds.push(unshifted[j][i]); - } + PolyCommFlat storage bases_unshifted = lagrange_bases_unshifted[domain_size]; + uint256[] memory unshifted_lengths = new uint[](num_unshifteds); + for (uint256 i = 0; i < num_unshifteds; i++) { + unshifted_lengths[i] = 0; + } + bases_unshifted.unshifted_lengths = unshifted_lengths; + + for (uint256 i = 0; i < domain_size; i++) { + for (uint256 j = 0; j < unshifted.length; j++) { + bases_unshifted.unshifteds.push(unshifted[j][i]); } + } } // Computes the linearization of the evaluations of a (potentially split) polynomial. @@ -265,25 +251,25 @@ function combined_inner_product( Scalar.FE evalscale, PolyMatrices memory polys, //uint[] poly_shifted, // TODO: not necessary for fiat-shamir - uint srs_length + uint256 srs_length ) pure returns (Scalar.FE res) { res = Scalar.zero(); Scalar.FE xi_i = Scalar.from(1); //require(poly_matrices.length == poly_shifted.length); - for (uint i = 0; i < polys.length; i++) { - uint cols = polys.cols[i]; - uint rows = polys.rows[i]; + for (uint256 i = 0; i < polys.length; i++) { + uint256 cols = polys.cols[i]; + uint256 rows = polys.rows[i]; if (cols == 0) { continue; } - for (uint col = 0; col < cols; col++) { + for (uint256 col = 0; col < cols; col++) { Scalar.FE[] memory eval = new Scalar.FE[](rows); // column that stores the segment - for (uint j = 0; j < rows; j++) { - eval[j] = polys.data[polys.starts[i] + col*rows + j]; + for (uint256 j = 0; j < rows; j++) { + eval[j] = polys.data[polys.starts[i] + col * rows + j]; } Scalar.FE term = Polynomial.build_and_eval(eval, evalscale); @@ -305,8 +291,8 @@ function combined_inner_product( // relevant: https://github.com/o1-labs/proof-systems/blob/a27270040c08eb2c99e37f90833ee7bfb1fd22f5/kimchi/src/verifier.rs#L566 struct PolyMatrices { Scalar.FE[] data; - uint length; - uint[] rows; // row count per matrix - uint[] cols; // col count per matrix - uint[] starts; // index at which every matrix starts + uint256 length; + uint256[] rows; // row count per matrix + uint256[] cols; // col count per matrix + uint256[] starts; // index at which every matrix starts } diff --git a/eth_verifier/lib/Evaluations.sol b/eth_verifier/lib/Evaluations.sol index ec84e137..191f42de 100644 --- a/eth_verifier/lib/Evaluations.sol +++ b/eth_verifier/lib/Evaluations.sol @@ -22,7 +22,7 @@ struct PointEvaluationsArray { /// Contains the evaluation of a polynomial commitment at a set of points. struct Evaluation { /// The commitment of the polynomial being evaluated - PolyComm commitment; + PolyComm commitment; // TODO: Dense /// Contains an evaluation table Scalar.FE[][] evaluations; /// optional degree bound diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index 2d7a8211..752927a5 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -35,18 +35,15 @@ struct ProofEvaluationsArray { PointEvaluationsArray[7 - 1] s; // TODO: use Constants.PERMUTS } -function combine_evals( - ProofEvaluationsArray memory self, - PointEvaluations memory pt -) pure returns (ProofEvaluations memory) { +function combine_evals(ProofEvaluationsArray memory self, PointEvaluations memory pt) + pure + returns (ProofEvaluations memory) +{ PointEvaluations memory public_evals; if (self.is_public_evals_set) { public_evals = PointEvaluations( Polynomial.build_and_eval(self.public_evals.zeta, pt.zeta), - Polynomial.build_and_eval( - self.public_evals.zeta_omega, - pt.zeta_omega - ) + Polynomial.build_and_eval(self.public_evals.zeta_omega, pt.zeta_omega) ); } else { public_evals = PointEvaluations(Scalar.zero(), Scalar.zero()); @@ -62,8 +59,7 @@ function combine_evals( PointEvaluations memory z; z = PointEvaluations( - Polynomial.build_and_eval(self.z.zeta, pt.zeta), - Polynomial.build_and_eval(self.z.zeta_omega, pt.zeta_omega) + Polynomial.build_and_eval(self.z.zeta, pt.zeta), Polynomial.build_and_eval(self.z.zeta_omega, pt.zeta_omega) ); PointEvaluations[7 - 1] memory s; @@ -77,10 +73,7 @@ function combine_evals( return ProofEvaluations(public_evals, self.is_public_evals_set, w, z, s); } -function evaluate_column(ProofEvaluations memory self, Column memory col) - pure - returns (PointEvaluations memory) -{ +function evaluate_column(ProofEvaluations memory self, Column memory col) pure returns (PointEvaluations memory) { if (col.variant == ColumnVariant.Witness) { uint256 i = abi.decode(col.data, (uint256)); return self.w[i]; @@ -96,10 +89,7 @@ function evaluate_column(ProofEvaluations memory self, Column memory col) // TODO: rest of variants, for this it's necessary to expand ProofEvaluations } -function evaluate_variable(Variable memory self, ProofEvaluations memory evals) - pure - returns (Scalar.FE) -{ +function evaluate_variable(Variable memory self, ProofEvaluations memory evals) pure returns (Scalar.FE) { PointEvaluations memory point_evals = evaluate_column(evals, self.col); if (self.row == CurrOrNext.Curr) { return point_evals.zeta; diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 5256b145..126726fc 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -18,13 +18,7 @@ import "../lib/expr/PolishToken.sol"; import "../lib/expr/ExprConstants.sol"; using {BN254.neg} for BN254.G1Point; -using { - Scalar.neg, - Scalar.mul, - Scalar.add, - Scalar.inv, - Scalar.sub -} for Scalar.FE; +using {Scalar.neg, Scalar.mul, Scalar.add, Scalar.inv, Scalar.sub} for Scalar.FE; using {AlphasLib.get_alphas} for Alphas; using {Polynomial.evaluate} for Polynomial.Dense; @@ -75,7 +69,7 @@ contract KimchiVerifier { //MsgPk.deser_pairing_urs(MsgPk.new_stream(urs_serialized), urs); // URS deserialization is WIP, we'll generate a random one for now: Scalar.FE x = Scalar.from(42); - uint max_domain_size = 16384; + uint256 max_domain_size = 16384; urs.full_urs = create_trusted_setup(x, max_domain_size); urs.verifier_urs = create_trusted_setup(x, 3); @@ -83,28 +77,16 @@ contract KimchiVerifier { verifier_index.powers_of_alpha.register(ArgumentType.Permutation, 3); // TODO: Investigate about linearization and write a proper function for this - verifier_index.powers_of_alpha.register( - ArgumentType.GateZero, - Constants.VARBASEMUL_CONSTRAINTS - ); - verifier_index.powers_of_alpha.register( - ArgumentType.Permutation, - Constants.PERMUTATION_CONSTRAINTS - ); + verifier_index.powers_of_alpha.register(ArgumentType.GateZero, Constants.VARBASEMUL_CONSTRAINTS); + verifier_index.powers_of_alpha.register(ArgumentType.Permutation, Constants.PERMUTATION_CONSTRAINTS); } - function verify_with_index( - bytes calldata verifier_index_serialized, - bytes calldata prover_proof_serialized - ) public returns (bool) { - MsgPk.deser_verifier_index( - MsgPk.new_stream(verifier_index_serialized), - verifier_index - ); - MsgPk.deser_prover_proof( - MsgPk.new_stream(prover_proof_serialized), - proof - ); + function verify_with_index(bytes calldata verifier_index_serialized, bytes calldata prover_proof_serialized) + public + returns (bool) + { + MsgPk.deser_verifier_index(MsgPk.new_stream(verifier_index_serialized), verifier_index); + MsgPk.deser_prover_proof(MsgPk.new_stream(prover_proof_serialized), proof); //calculate_lagrange_bases( // verifier_index.urs.g, @@ -120,10 +102,7 @@ contract KimchiVerifier { /// @notice this is currently deprecated but remains as to not break /// @notice the demo. - function verify_state( - bytes calldata state_serialized, - bytes calldata proof_serialized - ) public returns (bool) { + function verify_state(bytes calldata state_serialized, bytes calldata proof_serialized) public returns (bool) { // 1. Deserialize proof and setup // For now, proof consists in the concatenation of the bytes that @@ -132,18 +111,10 @@ contract KimchiVerifier { // BEWARE: quotient must be negated. - ( - BN254.G1Point memory numerator, - BN254.G1Point memory quotient, - BN254.G2Point memory divisor - ) = MsgPk.deserializeFinalCommitments(proof_serialized); - - bool success = BN254.pairingProd2( - numerator, - BN254.P2(), - quotient, - divisor - ); + (BN254.G1Point memory numerator, BN254.G1Point memory quotient, BN254.G2Point memory divisor) = + MsgPk.deserializeFinalCommitments(proof_serialized); + + bool success = BN254.pairingProd2(numerator, BN254.P2(), quotient, divisor); // 3. If success, deserialize and store state if (success) { @@ -160,17 +131,14 @@ contract KimchiVerifier { function partial_verify(Scalar.FE[] memory public_inputs) public { // Commit to the negated public input polynomial. - uint256 chunk_size = verifier_index.domain_size < - verifier_index.max_poly_size + uint256 chunk_size = verifier_index.domain_size < verifier_index.max_poly_size ? 1 : verifier_index.domain_size / verifier_index.max_poly_size; if (public_inputs.length != verifier_index.public_len) { revert IncorrectPublicInputLength(); } - PolyCommFlat memory lgr_comm_flat = urs.lagrange_bases_unshifted[ - verifier_index.domain_size - ]; + PolyCommFlat memory lgr_comm_flat = urs.lagrange_bases_unshifted[verifier_index.domain_size]; PolyComm[] memory comm = new PolyComm[](verifier_index.public_len); PolyComm[] memory lgr_comm = poly_comm_unflat(lgr_comm_flat); // INFO: can use unchecked on for loops to save gas @@ -186,52 +154,36 @@ contract KimchiVerifier { public_comm = PolyComm(blindings); } else { Scalar.FE[] memory elm = new Scalar.FE[](public_inputs.length); - for (uint i = 0; i < elm.length; i++) { + for (uint256 i = 0; i < elm.length; i++) { elm[i] = public_inputs[i].neg(); } PolyComm memory public_comm_tmp = polycomm_msm(comm, elm); Scalar.FE[] memory blinders = new Scalar.FE[]( public_comm_tmp.unshifted.length ); - for (uint i = 0; i < public_comm_tmp.unshifted.length; i++) { + for (uint256 i = 0; i < public_comm_tmp.unshifted.length; i++) { blinders[i] = Scalar.FE.wrap(1); } - public_comm = mask_custom(urs.full_urs, public_comm_tmp, blinders) - .commitment; + public_comm = mask_custom(urs.full_urs, public_comm_tmp, blinders).commitment; } // Execute fiat-shamir with a Keccak sponge - Oracles.Result memory oracles_res = Oracles.fiat_shamir( - proof, - verifier_index, - public_comm, - public_inputs, - true, - base_sponge, - scalar_sponge - ); + Oracles.Result memory oracles_res = + Oracles.fiat_shamir(proof, verifier_index, public_comm, public_inputs, true, base_sponge, scalar_sponge); Oracles.RandomOracles memory oracles = oracles_res.oracles; // Combine the chunked polynomials' evaluations - ProofEvaluations memory evals = proof.evals.combine_evals( - oracles_res.powers_of_eval_points_for_chunks - ); + ProofEvaluations memory evals = proof.evals.combine_evals(oracles_res.powers_of_eval_points_for_chunks); // Compute the commitment to the linearized polynomial $f$. - Scalar.FE permutation_vanishing_polynomial = Polynomial - .vanishes_on_last_n_rows( - verifier_index.domain_gen, - verifier_index.domain_size, - verifier_index.zk_rows - ) - .evaluate(oracles.zeta); - - Scalar.FE[] memory alphas = verifier_index.powers_of_alpha.get_alphas( - ArgumentType.Permutation, - Constants.PERMUTATION_CONSTRAINTS - ); + Scalar.FE permutation_vanishing_polynomial = Polynomial.vanishes_on_last_n_rows( + verifier_index.domain_gen, verifier_index.domain_size, verifier_index.zk_rows + ).evaluate(oracles.zeta); + + Scalar.FE[] memory alphas = + verifier_index.powers_of_alpha.get_alphas(ArgumentType.Permutation, Constants.PERMUTATION_CONSTRAINTS); PolyComm[] memory commitments = new PolyComm[](0); Scalar.FE[] memory scalars = new Scalar.FE[](1); @@ -261,15 +213,12 @@ contract KimchiVerifier { Scalar.FE[] memory alphas, // array with the next 3 powers Scalar.FE zkp_zeta // TODO: make an AlphaIterator type. ) internal pure returns (Scalar.FE res) { - require( - alphas.length == 3, - "not enough powers of alpha for permutation" - ); + require(alphas.length == 3, "not enough powers of alpha for permutation"); // TODO: alphas should be an iterator res = e.z.zeta_omega.mul(beta).mul(alphas[0]).mul(zkp_zeta); - uint len = Utils.min(e.w.length, e.s.length); - for (uint i = 0; i < len; i++) { + uint256 len = Utils.min(e.w.length, e.s.length); + for (uint256 i = 0; i < len; i++) { res = res.mul(gamma.add(beta.mul(e.s[i].zeta)).add(e.w[i].zeta)); } } @@ -335,10 +284,11 @@ contract KimchiVerifier { } /// The polynomial that evaluates to each of `evals` for the respective `elm`s. - function eval_polynomial( - Scalar.FE[] memory elm, - Scalar.FE[] memory evals - ) public pure returns (Polynomial.Dense memory) { + function eval_polynomial(Scalar.FE[] memory elm, Scalar.FE[] memory evals) + public + pure + returns (Polynomial.Dense memory) + { require(elm.length == evals.length, "lengths don't match"); require(elm.length == 2, "length must be 2"); Scalar.FE zeta = elm[0]; @@ -373,23 +323,10 @@ contract KimchiVerifier { return Polynomial.Dense(coeffs); } - /* -/// Contains the evaluation of a polynomial commitment at a set of points. -struct Evaluation { - /// The commitment of the polynomial being evaluated - Polynomial.Dense commitment; - /// Contains an evaluation table - Scalar.FE[][] evaluations; - /// optional degree bound - uint128 degree_bound; -} - */ - - function combineCommitments( - Evaluation[] memory evaluations, - Scalar.FE polyscale, - Scalar.FE rand_base - ) internal returns (Scalar.FE[] memory) { + function combineCommitments(Evaluation[] memory evaluations, Scalar.FE polyscale, Scalar.FE rand_base) + internal + returns (Scalar.FE[] memory) + { uint256 vec_length = 0; // Calculate the max length of the points and scalars vectors // Iterate over the evaluations @@ -416,11 +353,7 @@ struct Evaluation { } // iterating over the polynomial segments - for ( - uint256 j = 0; - j < evaluations[i].commitment.unshifted.length; - j++ - ) { + for (uint256 j = 0; j < evaluations[i].commitment.unshifted.length; j++) { // Add the scalar rand_base * xi_i to the scalars vector scalars[index] = rand_base.mul(xi_i); // Add the point to the points vector @@ -433,6 +366,8 @@ struct Evaluation { index++; } + // If the evaluation has a degree bound and a non-zero shifted commitment + //if (evaluations[i].degree_bound > 0 && evaluations[i].commitment.shifted.length > 0) {} /* if let Some(_m) = degree_bound { if let Some(comm_ch) = commitment.shifted { @@ -447,7 +382,6 @@ struct Evaluation { } */ /* TODO: FIX this with the previous version of the code - // If the evaluation has a degree bound and a non-zero shifted commitment if ( evaluations[i].degree_bound > 0 && evaluations[i].shifted.length > 0 @@ -510,7 +444,7 @@ struct Evaluation { } /// @notice retrieves the hash of the state after this block - function retrieve_state_hash() public view returns (uint) { + function retrieve_state_hash() public view returns (uint256) { if (!state_available) { revert UnavailableState(); } @@ -518,7 +452,7 @@ struct Evaluation { } /// @notice retrieves the block height - function retrieve_state_height() public view returns (uint) { + function retrieve_state_height() public view returns (uint256) { if (!state_available) { revert UnavailableState(); } From 0afd2bc18ff2618fa50fce3e7ee024617c07e2e9 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 15:13:45 -0300 Subject: [PATCH 56/68] format deserialize --- eth_verifier/lib/msgpack/Deserialize.sol | 416 ++++++----------------- 1 file changed, 112 insertions(+), 304 deletions(-) diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index a5ca4a68..e71192e6 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -29,9 +29,7 @@ library MsgPk { bytes[] values; } - function new_stream( - bytes calldata data - ) public pure returns (Stream memory) { + function new_stream(bytes calldata data) public pure returns (Stream memory) { return Stream(data, 0); } @@ -46,10 +44,7 @@ library MsgPk { return self.data[self.curr_index]; } - function next_n( - Stream memory self, - uint256 n - ) public view returns (bytes memory consumed) { + function next_n(Stream memory self, uint256 n) public view returns (bytes memory consumed) { consumed = new bytes(n); for (uint256 i = 0; i < n; i++) { consumed[i] = self.data[self.curr_index + i]; @@ -59,14 +54,9 @@ library MsgPk { error EncodedMapKeyNotFound(bytes key, bytes[] stored_keys); - function find_value( - EncodedMap memory self, - bytes memory key - ) public pure returns (bytes memory) { + function find_value(EncodedMap memory self, bytes memory key) public pure returns (bytes memory) { uint256 i = 0; - while ( - i != self.keys.length && keccak256(self.keys[i]) != keccak256(key) - ) { + while (i != self.keys.length && keccak256(self.keys[i]) != keccak256(key)) { i++; } if (i == self.keys.length) revert EncodedMapKeyNotFound(key, self.keys); @@ -76,16 +66,9 @@ library MsgPk { error NotImplementedType(bytes1 prefix); /// @notice deserializes the next type and returns the encoded data. - function deser_encode( - Stream memory self - ) public view returns (bytes memory) { + function deser_encode(Stream memory self) public view returns (bytes memory) { bytes1 prefix = curr(self); - if ( - prefix >> 5 == 0x05 || - prefix == 0xd9 || - prefix == 0xda || - prefix == 0xdb - ) { + if (prefix >> 5 == 0x05 || prefix == 0xd9 || prefix == 0xda || prefix == 0xdb) { return abi.encode(deser_str(self)); } else if (prefix == 0xC4) { return abi.encode(deser_bin8(self)); @@ -112,13 +95,7 @@ library MsgPk { function deser_str(Stream memory self) public view returns (string memory) { bytes1 first = next(self); - require( - first >> 5 == 0x05 || - first == 0xd9 || - first == 0xda || - first == 0xdb, - "not a fixstr or strX" - ); + require(first >> 5 == 0x05 || first == 0xd9 || first == 0xda || first == 0xdb, "not a fixstr or strX"); if (first >> 5 == 0x05) { // fixstr @@ -155,9 +132,7 @@ library MsgPk { return next_n(self, n); } - function deser_fixarr( - Stream memory self - ) public view returns (EncodedArray memory arr) { + function deser_fixarr(Stream memory self) public view returns (EncodedArray memory arr) { bytes1 first = next(self); require(first >> 4 == 0x09, "not a fixarr"); uint256 n = uint256(uint8(first & 0x0F)); // low nibble @@ -169,9 +144,7 @@ library MsgPk { } } - function deser_fixmap( - Stream memory self - ) public view returns (EncodedMap memory map) { + function deser_fixmap(Stream memory self) public view returns (EncodedMap memory map) { bytes1 first = next(self); require(first >> 4 == 0x08, "not a fixmap"); uint256 n = uint256(uint8(first & 0x0F)); // low nibble @@ -184,9 +157,7 @@ library MsgPk { } } - function deser_arr16( - Stream memory self - ) public view returns (EncodedArray memory arr) { + function deser_arr16(Stream memory self) public view returns (EncodedArray memory arr) { bytes1 first = next(self); require(first == 0xdc, "not an arr16"); // size is next two bytes: @@ -200,9 +171,7 @@ library MsgPk { } } - function deser_map16( - Stream memory self - ) public view returns (EncodedMap memory map) { + function deser_map16(Stream memory self) public view returns (EncodedMap memory map) { bytes1 first = next(self); require(first == 0xde, "not a map16"); // size is next two bytes: @@ -242,9 +211,7 @@ library MsgPk { return uint8(first); } - function deser_null( - Stream memory self - ) public view returns (string memory) { + function deser_null(Stream memory self) public view returns (string memory) { bytes1 first = next(self); require(first == 0xc0, "not null"); @@ -258,19 +225,11 @@ library MsgPk { return first == 0xc3; // 0xc3 == true } - function deser_buffer( - EncodedMap memory self - ) public pure returns (bytes memory data) { - bytes memory type_name = abi.decode( - find_value(self, abi.encode("type")), - (bytes) - ); + function deser_buffer(EncodedMap memory self) public pure returns (bytes memory data) { + bytes memory type_name = abi.decode(find_value(self, abi.encode("type")), (bytes)); require(keccak256(type_name) == keccak256("Buffer")); - EncodedArray memory data_arr = abi.decode( - find_value(self, abi.encode("data")), - (EncodedArray) - ); + EncodedArray memory data_arr = abi.decode(find_value(self, abi.encode("data")), (EncodedArray)); // data_arr will hold an array of `bytes` arrays, where each `bytes` // is a 32 sized byte array which represents only one byte, but padded @@ -285,45 +244,22 @@ library MsgPk { data = Utils.flatten_padded_bytes_array(data_arr.values); } - function deser_buffer_to_uint256( - EncodedMap memory self - ) public pure returns (uint256 integer) { - bytes memory type_name = abi.decode( - find_value(self, abi.encode("type")), - (bytes) - ); + function deser_buffer_to_uint256(EncodedMap memory self) public pure returns (uint256 integer) { + bytes memory type_name = abi.decode(find_value(self, abi.encode("type")), (bytes)); require(keccak256(type_name) == keccak256("Buffer")); - EncodedArray memory data_arr = abi.decode( - find_value(self, abi.encode("data")), - (EncodedArray) - ); + EncodedArray memory data_arr = abi.decode(find_value(self, abi.encode("data")), (EncodedArray)); integer = Utils.padded_bytes_array_to_uint256(data_arr.values); } - function deser_verifier_index( - Stream memory self, - VerifierIndex storage index - ) external { + function deser_verifier_index(Stream memory self, VerifierIndex storage index) external { EncodedMap memory map = deser_map16(self); - index.public_len = abi.decode( - find_value(map, abi.encode("public")), - (uint256) - ); - index.max_poly_size = abi.decode( - find_value(map, abi.encode("max_poly_size")), - (uint256) - ); - index.zk_rows = abi.decode( - find_value(map, abi.encode("zk_rows")), - (uint64) - ); + index.public_len = abi.decode(find_value(map, abi.encode("public")), (uint256)); + index.max_poly_size = abi.decode(find_value(map, abi.encode("max_poly_size")), (uint256)); + index.zk_rows = abi.decode(find_value(map, abi.encode("zk_rows")), (uint64)); - EncodedMap memory domain_map = abi.decode( - find_value(map, abi.encode("domain")), - (EncodedMap) - ); + EncodedMap memory domain_map = abi.decode(find_value(map, abi.encode("domain")), (EncodedMap)); bytes memory domain_b = deser_buffer(domain_map); @@ -345,15 +281,10 @@ library MsgPk { index.domain_gen = Scalar.from(domain_gen); // wire shift coordinates - EncodedArray memory shift_arr = abi.decode( - find_value(map, abi.encode("shift")), - (EncodedArray) - ); + EncodedArray memory shift_arr = abi.decode(find_value(map, abi.encode("shift")), (EncodedArray)); require(shift_arr.values.length == 7, "shift array is not of length 7"); for (uint256 i = 0; i < 7; i++) { - uint256 inner = deser_buffer_to_uint256( - abi.decode(shift_arr.values[i], (EncodedMap)) - ); + uint256 inner = deser_buffer_to_uint256(abi.decode(shift_arr.values[i], (EncodedMap))); index.shift[i] = Scalar.from(inner); } @@ -361,70 +292,44 @@ library MsgPk { index.w = index.domain_gen.pow(index.domain_size - index.zk_rows); } - function deser_prover_proof( - Stream memory self, - ProverProof storage prover_proof - ) external { + function deser_prover_proof(Stream memory self, ProverProof storage prover_proof) external { EncodedMap memory map = deser_fixmap(self); - EncodedMap memory all_evals_map = abi.decode( - find_value(map, abi.encode("evals")), - (EncodedMap) - ); + EncodedMap memory all_evals_map = abi.decode(find_value(map, abi.encode("evals")), (EncodedMap)); prover_proof.evals.public_evals = deser_evals(all_evals_map, "public"); prover_proof.evals.is_public_evals_set = true; prover_proof.evals.z = deser_evals(all_evals_map, "z"); - PointEvaluationsArray[] memory w = deser_evals_array( - all_evals_map, - "w" - ); + PointEvaluationsArray[] memory w = deser_evals_array(all_evals_map, "w"); for (uint256 i = 0; i < 15; i++) { prover_proof.evals.w[i] = w[i]; } - PointEvaluationsArray[] memory s = deser_evals_array( - all_evals_map, - "s" - ); + PointEvaluationsArray[] memory s = deser_evals_array(all_evals_map, "s"); for (uint256 i = 0; i < 6; i++) { prover_proof.evals.w[i] = w[i]; } } - function deser_evals( - EncodedMap memory all_evals_map, - string memory name - ) public pure returns (PointEvaluationsArray memory) { - EncodedMap memory eval_map = abi.decode( - find_value(all_evals_map, abi.encode(name)), - (EncodedMap) - ); + function deser_evals(EncodedMap memory all_evals_map, string memory name) + public + pure + returns (PointEvaluationsArray memory) + { + EncodedMap memory eval_map = abi.decode(find_value(all_evals_map, abi.encode(name)), (EncodedMap)); - EncodedArray memory zeta_arr = abi.decode( - find_value(eval_map, abi.encode("zeta")), - (EncodedArray) - ); - EncodedArray memory zeta_omega_arr = abi.decode( - find_value(eval_map, abi.encode("zeta_omega")), - (EncodedArray) - ); + EncodedArray memory zeta_arr = abi.decode(find_value(eval_map, abi.encode("zeta")), (EncodedArray)); + EncodedArray memory zeta_omega_arr = abi.decode(find_value(eval_map, abi.encode("zeta_omega")), (EncodedArray)); require(zeta_arr.values.length == zeta_omega_arr.values.length); uint256 length = zeta_arr.values.length; Scalar.FE[] memory zetas = new Scalar.FE[](length); Scalar.FE[] memory zeta_omegas = new Scalar.FE[](length); for (uint256 i = 0; i < zeta_arr.values.length; i++) { - EncodedMap memory zeta_map = abi.decode( - zeta_arr.values[i], - (EncodedMap) - ); - EncodedMap memory zeta_omega_map = abi.decode( - zeta_omega_arr.values[i], - (EncodedMap) - ); + EncodedMap memory zeta_map = abi.decode(zeta_arr.values[i], (EncodedMap)); + EncodedMap memory zeta_omega_map = abi.decode(zeta_omega_arr.values[i], (EncodedMap)); uint256 zeta_inner = deser_buffer_to_uint256(zeta_map); uint256 zeta_omega_inner = deser_buffer_to_uint256(zeta_omega_map); @@ -436,50 +341,32 @@ library MsgPk { return PointEvaluationsArray(zetas, zeta_omegas); } - function deser_evals_array( - EncodedMap memory all_evals_map, - string memory name - ) public pure returns (PointEvaluationsArray[] memory evals) { - EncodedArray memory eval_array = abi.decode( - find_value(all_evals_map, abi.encode(name)), - (EncodedArray) - ); + function deser_evals_array(EncodedMap memory all_evals_map, string memory name) + public + pure + returns (PointEvaluationsArray[] memory evals) + { + EncodedArray memory eval_array = abi.decode(find_value(all_evals_map, abi.encode(name)), (EncodedArray)); uint256 length = eval_array.values.length; evals = new PointEvaluationsArray[](length); for (uint256 eval = 0; eval < length; eval++) { - EncodedMap memory eval_map = abi.decode( - eval_array.values[eval], - (EncodedMap) - ); + EncodedMap memory eval_map = abi.decode(eval_array.values[eval], (EncodedMap)); - EncodedArray memory zeta_arr = abi.decode( - find_value(eval_map, abi.encode("zeta")), - (EncodedArray) - ); - EncodedArray memory zeta_omega_arr = abi.decode( - find_value(eval_map, abi.encode("zeta_omega")), - (EncodedArray) - ); + EncodedArray memory zeta_arr = abi.decode(find_value(eval_map, abi.encode("zeta")), (EncodedArray)); + EncodedArray memory zeta_omega_arr = + abi.decode(find_value(eval_map, abi.encode("zeta_omega")), (EncodedArray)); require(zeta_arr.values.length == zeta_omega_arr.values.length); uint256 length = zeta_arr.values.length; Scalar.FE[] memory zetas = new Scalar.FE[](length); Scalar.FE[] memory zeta_omegas = new Scalar.FE[](length); for (uint256 i = 0; i < zeta_arr.values.length; i++) { - EncodedMap memory zeta_map = abi.decode( - zeta_arr.values[i], - (EncodedMap) - ); - EncodedMap memory zeta_omega_map = abi.decode( - zeta_omega_arr.values[i], - (EncodedMap) - ); + EncodedMap memory zeta_map = abi.decode(zeta_arr.values[i], (EncodedMap)); + EncodedMap memory zeta_omega_map = abi.decode(zeta_omega_arr.values[i], (EncodedMap)); uint256 zeta_inner = deser_buffer_to_uint256(zeta_map); - uint256 zeta_omega_inner = deser_buffer_to_uint256( - zeta_omega_map - ); + uint256 zeta_omega_inner = deser_buffer_to_uint256(zeta_omega_map); zetas[i] = Scalar.from(zeta_inner); zeta_omegas[i] = Scalar.from(zeta_omega_inner); @@ -492,123 +379,73 @@ library MsgPk { EncodedMap memory map, mapping(uint256 => PolyCommFlat) storage lagrange_bases_unshifted ) public { - for (uint i = 0; i < map.keys.length; i++) { - EncodedArray memory comms = abi.decode( - map.values[i], - (EncodedArray) - ); + for (uint256 i = 0; i < map.keys.length; i++) { + EncodedArray memory comms = abi.decode(map.values[i], (EncodedArray)); PolyComm[] memory polycomms = new PolyComm[](comms.values.length); - for (uint j = 0; j < comms.values.length; j++) { - EncodedMap memory comm = abi.decode( - comms.values[i], - (EncodedMap) - ); - EncodedArray memory unshifted_arr = abi.decode( - find_value(comm, abi.encode("unshifted")), - (EncodedArray) - ); + for (uint256 j = 0; j < comms.values.length; j++) { + EncodedMap memory comm = abi.decode(comms.values[i], (EncodedMap)); + EncodedArray memory unshifted_arr = + abi.decode(find_value(comm, abi.encode("unshifted")), (EncodedArray)); - uint unshifted_length = unshifted_arr.values.length; + uint256 unshifted_length = unshifted_arr.values.length; BN254.G1Point[] memory unshifted = new BN254.G1Point[]( unshifted_length ); - for (uint k = 0; k < unshifted_length; k++) { - EncodedMap memory unshifted_buffer = abi.decode( - unshifted_arr.values[k], - (EncodedMap) - ); - unshifted[k] = BN254.g1Deserialize( - bytes32(deser_buffer(unshifted_buffer)) - ); + for (uint256 k = 0; k < unshifted_length; k++) { + EncodedMap memory unshifted_buffer = abi.decode(unshifted_arr.values[k], (EncodedMap)); + unshifted[k] = BN254.g1Deserialize(bytes32(deser_buffer(unshifted_buffer))); } polycomms[j] = PolyComm(unshifted); } - lagrange_bases_unshifted[ - abi.decode(map.keys[i], (uint256)) - ] = poly_comm_flat(polycomms); + lagrange_bases_unshifted[abi.decode(map.keys[i], (uint256))] = poly_comm_flat(polycomms); } } - function deser_pairing_urs( - Stream memory self, - PairingURS storage urs - ) public { + function deser_pairing_urs(Stream memory self, PairingURS storage urs) public { // full_srs and verifier_srs fields EncodedMap memory urs_map = deser_fixmap(self); - EncodedMap memory full_urs_serialized = abi.decode( - find_value(urs_map, abi.encode("full_srs")), - (EncodedMap) - ); - EncodedMap memory verifier_urs_serialized = abi.decode( - find_value(urs_map, abi.encode("verifier_srs")), - (EncodedMap) - ); + EncodedMap memory full_urs_serialized = abi.decode(find_value(urs_map, abi.encode("full_srs")), (EncodedMap)); + EncodedMap memory verifier_urs_serialized = + abi.decode(find_value(urs_map, abi.encode("verifier_srs")), (EncodedMap)); // get data from g and h fields (g is an array of buffers and h is a buffer) - EncodedArray memory full_urs_g_serialized = abi.decode( - find_value(full_urs_serialized, abi.encode("g")), - (EncodedArray) - ); - EncodedMap memory full_urs_h_serialized = abi.decode( - find_value(full_urs_serialized, abi.encode("h")), - (EncodedMap) - ); + EncodedArray memory full_urs_g_serialized = + abi.decode(find_value(full_urs_serialized, abi.encode("g")), (EncodedArray)); + EncodedMap memory full_urs_h_serialized = + abi.decode(find_value(full_urs_serialized, abi.encode("h")), (EncodedMap)); - EncodedArray memory verifier_urs_g_serialized = abi.decode( - find_value(verifier_urs_serialized, abi.encode("g")), - (EncodedArray) - ); - EncodedMap memory verifier_urs_h_serialized = abi.decode( - find_value(verifier_urs_serialized, abi.encode("h")), - (EncodedMap) - ); + EncodedArray memory verifier_urs_g_serialized = + abi.decode(find_value(verifier_urs_serialized, abi.encode("g")), (EncodedArray)); + EncodedMap memory verifier_urs_h_serialized = + abi.decode(find_value(verifier_urs_serialized, abi.encode("h")), (EncodedMap)); // deserialized and save g for both URS - uint full_urs_g_length = full_urs_g_serialized.values.length; + uint256 full_urs_g_length = full_urs_g_serialized.values.length; BN254.G1Point[] memory full_urs_g = new BN254.G1Point[]( full_urs_g_length ); - for (uint i = 0; i < full_urs_g_length; i++) { - full_urs_g[i] = BN254.g1Deserialize( - bytes32( - deser_buffer( - abi.decode( - full_urs_g_serialized.values[i], - (EncodedMap) - ) - ) - ) - ); + for (uint256 i = 0; i < full_urs_g_length; i++) { + full_urs_g[i] = + BN254.g1Deserialize(bytes32(deser_buffer(abi.decode(full_urs_g_serialized.values[i], (EncodedMap))))); } - uint verifier_urs_g_length = verifier_urs_g_serialized.values.length; + uint256 verifier_urs_g_length = verifier_urs_g_serialized.values.length; BN254.G1Point[] memory verifier_urs_g = new BN254.G1Point[]( verifier_urs_g_length ); - for (uint i = 0; i < verifier_urs_g_length; i++) { + for (uint256 i = 0; i < verifier_urs_g_length; i++) { verifier_urs_g[i] = BN254.g1Deserialize( - bytes32( - deser_buffer( - abi.decode( - verifier_urs_g_serialized.values[i], - (EncodedMap) - ) - ) - ) + bytes32(deser_buffer(abi.decode(verifier_urs_g_serialized.values[i], (EncodedMap)))) ); } // deserialized and save h for both URS - BN254.G1Point memory full_urs_h = BN254.g1Deserialize( - bytes32(deser_buffer(full_urs_h_serialized)) - ); - BN254.G1Point memory verifier_urs_h = BN254.g1Deserialize( - bytes32(deser_buffer(verifier_urs_h_serialized)) - ); + BN254.G1Point memory full_urs_h = BN254.g1Deserialize(bytes32(deser_buffer(full_urs_h_serialized))); + BN254.G1Point memory verifier_urs_h = BN254.g1Deserialize(bytes32(deser_buffer(verifier_urs_h_serialized))); // store values urs.full_urs.g = full_urs_g; @@ -618,14 +455,9 @@ library MsgPk { urs.verifier_urs.h = verifier_urs_h; // deserialize and store lagrange bases - EncodedMap memory lagrange_b_serialized = abi.decode( - find_value(full_urs_serialized, abi.encode("lagrange_bases")), - (EncodedMap) - ); - deser_lagrange_bases( - lagrange_b_serialized, - urs.lagrange_bases_unshifted - ); + EncodedMap memory lagrange_b_serialized = + abi.decode(find_value(full_urs_serialized, abi.encode("lagrange_bases")), (EncodedMap)); + deser_lagrange_bases(lagrange_b_serialized, urs.lagrange_bases_unshifted); } /* WARN: @@ -634,16 +466,10 @@ library MsgPk { * them with the new WIP deserializer. Please prefer using functions above. */ - function deserializeFinalCommitments( - bytes calldata data - ) + function deserializeFinalCommitments(bytes calldata data) public view - returns ( - BN254.G1Point memory numerator, - BN254.G1Point memory quotient, - BN254.G2Point memory divisor - ) + returns (BN254.G1Point memory numerator, BN254.G1Point memory quotient, BN254.G2Point memory divisor) { numerator = abi.decode(data[:64], (BN254.G1Point)); quotient = abi.decode(data[64:128], (BN254.G1Point)); @@ -653,10 +479,11 @@ library MsgPk { /// @notice deserializes an array of G1Point and also returns the rest of the // data, excluding the consumed bytes. `i` is the index that we start to read // the data from. - function deserializeG1Point( - bytes calldata data, - uint256 i - ) public view returns (BN254.G1Point memory p, uint256 final_i) { + function deserializeG1Point(bytes calldata data, uint256 i) + public + view + returns (BN254.G1Point memory p, uint256 final_i) + { // read length of the data require(data[i] == 0xC4, "not a stream of bin8 (bytes)"); @@ -677,9 +504,7 @@ library MsgPk { /// @notice deserializes an URS excluding the lagrange bases, and also // returns the final index which points at the end of the consumed data. - function deserializeURS( - bytes calldata data - ) + function deserializeURS(bytes calldata data) public view returns (BN254.G1Point[] memory, BN254.G1Point memory, uint256) @@ -688,28 +513,21 @@ library MsgPk { require(data[i] == 0x92, "not a fix array of two elements"); i += 1; - require( - data[i] == 0xdc || data[i] == 0xdd, - "not an array16 or array32" - ); + require(data[i] == 0xdc || data[i] == 0xdd, "not an array16 or array32"); // 0xdc means that the next 2 bytes represent the size, // 0xdd means that the next 4 bytes represent the size. uint256 byte_count = data[i] == 0xdc ? 2 : 4; // next bytes are size of the array i += 1; - uint256 size = uint256(bytes32(data[i:i + byte_count])) >> - ((32 - byte_count) * 8); + uint256 size = uint256(bytes32(data[i:i + byte_count])) >> ((32 - byte_count) * 8); // shift is necessary because conversion pads with zeros to the left BN254.G1Point[] memory g = new BN254.G1Point[](size); i += byte_count; // read elements for (uint256 elem = 0; elem < size; elem++) { - (BN254.G1Point memory p, uint256 new_index) = deserializeG1Point( - data, - i - ); + (BN254.G1Point memory p, uint256 new_index) = deserializeG1Point(data, i); g[elem] = p; i = new_index; } @@ -719,10 +537,11 @@ library MsgPk { return (g, h, final_i); } - function deserializeScalar( - bytes calldata data, - uint256 i - ) public pure returns (Scalar.FE scalar, uint256 final_i) { + function deserializeScalar(bytes calldata data, uint256 i) + public + pure + returns (Scalar.FE scalar, uint256 final_i) + { // read length of the data require(data[i] == 0xC4, "not a stream of bin8 (bytes)"); @@ -741,10 +560,11 @@ library MsgPk { final_i = i; } - function deserializePointEvals( - bytes calldata data, - uint256 i - ) public pure returns (PointEvaluations memory eval, uint256 final_i) { + function deserializePointEvals(bytes calldata data, uint256 i) + public + pure + returns (PointEvaluations memory eval, uint256 final_i) + { require(data[i] == 0x92, "not a fix array of two elements"); i += 1; require(data[i] == 0x91, "not a fix array of one element"); @@ -761,29 +581,20 @@ library MsgPk { final_i = i; } - function deserializeProofEvaluationsArray( - bytes calldata data, - uint256 i - ) + function deserializeProofEvaluationsArray(bytes calldata data, uint256 i) public pure returns (ProofEvaluationsArray memory evals, uint256 final_i) { // WARN: This works because the test circuit evaluations have one elem per array. - ( - PointEvaluations memory evals_non_array, - uint256 _i - ) = deserializePointEvals(data, i); + (PointEvaluations memory evals_non_array, uint256 _i) = deserializePointEvals(data, i); Scalar.FE[] memory zeta = new Scalar.FE[](1); Scalar.FE[] memory zeta_omega = new Scalar.FE[](1); zeta[0] = evals_non_array.zeta; zeta_omega[0] = evals_non_array.zeta_omega; - PointEvaluationsArray memory public_evals = PointEvaluationsArray( - zeta, - zeta_omega - ); + PointEvaluationsArray memory public_evals = PointEvaluationsArray(zeta, zeta_omega); PointEvaluationsArray[15] memory w; Scalar.FE[] memory zero = new Scalar.FE[](1); @@ -796,10 +607,7 @@ library MsgPk { final_i = _i; } - function deserializeState( - bytes calldata data, - uint256 i - ) public view returns (State memory) { + function deserializeState(bytes calldata data, uint256 i) public view returns (State memory) { require(data[i] == 0x93, "not a fix array of three elements"); i += 1; From 99ef9abbc6d31397378e27c59e36fe23a0635035 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 16:08:14 -0300 Subject: [PATCH 57/68] format Commitment.sol --- eth_verifier/lib/Commitment.sol | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 2485cba9..5fffe331 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -196,14 +196,11 @@ function mask_custom(URS storage urs, PolyComm memory com, Scalar.FE[] memory bl // @notice multiplies each commitment chunk of f with powers of zeta^n // @notice note that it ignores the shifted part. -function chunk_commitment( - PolyComm memory self, - Scalar.FE zeta_n -) view returns (PolyComm memory) { +function chunk_commitment(PolyComm memory self, Scalar.FE zeta_n) view returns (PolyComm memory) { BN254.G1Point memory res = BN254.point_at_inf(); - uint length = self.unshifted.length; - for (uint i = 0; i < length; i++) { + uint256 length = self.unshifted.length; + for (uint256 i = 0; i < length; i++) { BN254.G1Point memory chunk = self.unshifted[length - i - 1]; res = res.scale_scalar(zeta_n); @@ -217,11 +214,7 @@ function chunk_commitment( } // @notice substracts two polynomial commitments -function sub_polycomms( - PolyComm memory self, - PolyComm memory other -) pure returns (PolyComm memory) -{ +function sub_polycomms(PolyComm memory self, PolyComm memory other) pure returns (PolyComm memory) { // TODO: implement this! } From 68ed45341e3317915f54d9c25eddf7f6714f20e2 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 16:25:34 -0300 Subject: [PATCH 58/68] reformat code to avoid merge conflicts --- eth_verifier/lib/Commitment.sol | 189 +++++------ eth_verifier/lib/Proof.sol | 28 +- eth_verifier/lib/bn254/Fields.sol | 83 ++--- eth_verifier/lib/msgpack/Deserialize.sol | 407 +++++++---------------- eth_verifier/src/Verifier.sol | 102 ++---- 5 files changed, 266 insertions(+), 543 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 8635aa9f..2e0d8873 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -6,16 +6,8 @@ import "./bn254/Fields.sol"; import "./Utils.sol"; import "./Polynomial.sol"; -using { BN254.add, BN254.scale_scalar } for BN254.G1Point; -using { - Scalar.neg, - Scalar.add, - Scalar.sub, - Scalar.mul, - Scalar.inv, - Scalar.double, - Scalar.pow -} for Scalar.FE; +using {BN254.add, BN254.scale_scalar} for BN254.G1Point; +using {Scalar.neg, Scalar.add, Scalar.sub, Scalar.mul, Scalar.inv, Scalar.double, Scalar.pow} for Scalar.FE; error MSMInvalidLengths(); @@ -24,12 +16,12 @@ struct URS { BN254.G1Point h; } -function create_trusted_setup(Scalar.FE x, uint depth) view returns (URS memory) { +function create_trusted_setup(Scalar.FE x, uint256 depth) view returns (URS memory) { Scalar.FE x_pow = Scalar.one(); BN254.G1Point[] memory g = new BN254.G1Point[](depth); BN254.G1Point memory h = BN254.P1(); // should be blake2b hash - for (uint i = 0; i < depth; i++) { + for (uint256 i = 0; i < depth; i++) { g[i] = BN254.P1().scale_scalar(x_pow); x_pow = x_pow.mul(x); } @@ -43,14 +35,14 @@ struct PairingURS { mapping(uint256 => PolyCommFlat) lagrange_bases_unshifted; } -function random_lagrange_bases(PairingURS storage urs, uint domain_size) { - uint n = domain_size; +function random_lagrange_bases(PairingURS storage urs, uint256 domain_size) { + uint256 n = domain_size; - uint[] memory u_lengths = new uint[](1); + uint256[] memory u_lengths = new uint[](1); u_lengths[0] = domain_size; BN254.G1Point[] memory unshifteds = new BN254.G1Point[](domain_size); - for (uint i = 0; i < domain_size; i++) { + for (uint256 i = 0; i < domain_size; i++) { unshifteds[i] = BN254.P1(); } @@ -60,27 +52,27 @@ function random_lagrange_bases(PairingURS storage urs, uint domain_size) { struct PolyComm { BN254.G1Point[] unshifted; - //BN254G1Point shifted; - // WARN: The previous field is optional but in Solidity we can't have that. - // for our test circuit it's not necessary } +//BN254G1Point shifted; +// WARN: The previous field is optional but in Solidity we can't have that. +// for our test circuit it's not necessary // @notice this structure flattens the fields of `PolyComm`. // its motivation lies in Solidity's inability to store nested arrays // in a mapping. struct PolyCommFlat { BN254.G1Point[] unshifteds; - uint[] unshifted_lengths; + uint256[] unshifted_lengths; } function poly_comm_unflat(PolyCommFlat memory com) pure returns (PolyComm[] memory res) { - uint comm_count = com.unshifted_lengths.length; - res = new PolyComm[](comm_count); - uint index = 0; - for (uint i = 0; i < comm_count; i++) { - uint n = com.unshifted_lengths[i]; + uint256 comm_count = com.unshifted_lengths.length; + res = new PolyComm[](comm_count); + uint256 index = 0; + for (uint256 i = 0; i < comm_count; i++) { + uint256 n = com.unshifted_lengths[i]; BN254.G1Point[] memory unshifted = new BN254.G1Point[](n); - for (uint j = 0; j < n; j++) { + for (uint256 j = 0; j < n; j++) { unshifted[j] = com.unshifteds[index]; index++; } @@ -89,17 +81,17 @@ function poly_comm_unflat(PolyCommFlat memory com) pure returns (PolyComm[] memo } function poly_comm_flat(PolyComm[] memory com) pure returns (PolyCommFlat memory) { - uint total_length = 0; - uint[] memory unshifted_lengths = new uint[](com.length); - for (uint i = 0; i < com.length; i++) { + uint256 total_length = 0; + uint256[] memory unshifted_lengths = new uint[](com.length); + for (uint256 i = 0; i < com.length; i++) { total_length += com[i].unshifted.length; unshifted_lengths[i] = com[i].unshifted.length; } BN254.G1Point[] memory unshifteds = new BN254.G1Point[](total_length); - uint index = 0; - for (uint i = 0; i < com.length; i++) { - for (uint j = 0; j < com[i].unshifted.length; j++) { + uint256 index = 0; + for (uint256 i = 0; i < com.length; i++) { + for (uint256 j = 0; j < com[i].unshifted.length; j++) { unshifteds[index] = com[i].unshifted[j]; index++; } @@ -110,10 +102,7 @@ function poly_comm_flat(PolyComm[] memory com) pure returns (PolyCommFlat memory // @notice Executes multi-scalar multiplication between scalars `elm` and commitments `com`. // @notice If empty, returns a commitment with the point at infinity. -function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) - view - returns (PolyComm memory) -{ +function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) view returns (PolyComm memory) { if (com.length == 0 || elm.length == 0) { BN254.G1Point[] memory z = new BN254.G1Point[](1); z[0] = BN254.point_at_inf(); @@ -135,13 +124,12 @@ function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) } BN254.G1Point[] memory unshifted = new BN254.G1Point[](unshifted_len); - for (uint chunk = 0; chunk < unshifted_len; chunk++) { - + for (uint256 chunk = 0; chunk < unshifted_len; chunk++) { // zip with elements and filter scalars that don't have an associated chunk. // first get the count of elements that have a chunk: - uint chunk_length = 0; - for (uint i = 0; i < n; i++) { + uint256 chunk_length = 0; + for (uint256 i = 0; i < n; i++) { if (com[i].unshifted.length > chunk) { chunk_length++; } @@ -150,8 +138,8 @@ function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) // fill arrays BN254.G1Point[] memory points = new BN254.G1Point[](chunk_length); Scalar.FE[] memory scalars = new Scalar.FE[](chunk_length); - uint index = 0; - for (uint i = 0; i < n; i++) { + uint256 index = 0; + for (uint256 i = 0; i < n; i++) { if (com[i].unshifted.length > chunk) { points[index] = (com[i].unshifted[chunk]); scalars[index] = (elm[i]); @@ -166,10 +154,7 @@ function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) } // @notice Execute a simple multi-scalar multiplication -function naive_msm(BN254.G1Point[] memory points, Scalar.FE[] memory scalars) - view - returns (BN254.G1Point memory) -{ +function naive_msm(BN254.G1Point[] memory points, Scalar.FE[] memory scalars) view returns (BN254.G1Point memory) { BN254.G1Point memory result = BN254.point_at_inf(); for (uint256 i = 0; i < points.length; i++) { @@ -189,16 +174,15 @@ error InvalidPolycommLength(); // @notice Turns a non-hiding polynomial commitment into a hidding polynomial commitment. // @notice Transforms each given `` into `( + wH, w)`. // INFO: since we are ignoring shifted elements of a commitment, `blinders` only needs to be a Scalar[] -function mask_custom( - URS storage urs, - PolyComm memory com, - Scalar.FE[] memory blinders -) view returns (BlindedCommitment memory) { +function mask_custom(URS storage urs, PolyComm memory com, Scalar.FE[] memory blinders) + view + returns (BlindedCommitment memory) +{ if (com.unshifted.length != blinders.length) { revert InvalidPolycommLength(); } - uint u_len = com.unshifted.length; + uint256 u_len = com.unshifted.length; BN254.G1Point[] memory unshifted = new BN254.G1Point[](u_len); for (uint256 i = 0; i < u_len; i++) { BN254.G1Point memory g_masked = urs.h.scale_scalar(blinders[i]); @@ -210,14 +194,11 @@ function mask_custom( // @notice multiplies each commitment chunk of f with powers of zeta^n // @notice note that it ignores the shifted part. -function chunk_commitment( - PolyComm memory self, - Scalar.FE zeta_n -) view returns (PolyComm memory) { +function chunk_commitment(PolyComm memory self, Scalar.FE zeta_n) view returns (PolyComm memory) { BN254.G1Point memory res = BN254.point_at_inf(); - uint length = self.unshifted.length; - for (uint i = 0; i < length; i++) { + uint256 length = self.unshifted.length; + for (uint256 i = 0; i < length; i++) { BN254.G1Point memory chunk = self.unshifted[length - i - 1]; res = res.scale_scalar(zeta_n); @@ -231,11 +212,7 @@ function chunk_commitment( } // @notice substracts two polynomial commitments -function sub_polycomms( - PolyComm memory self, - PolyComm memory other -) pure returns (PolyComm memory) -{ +function sub_polycomms(PolyComm memory self, PolyComm memory other) pure returns (PolyComm memory) { // TODO: implement this! } @@ -244,45 +221,45 @@ function sub_polycomms( function calculate_lagrange_bases( BN254.G1Point[] memory g, BN254.G1Point memory h, - uint domain_size, + uint256 domain_size, mapping(uint256 => PolyCommFlat) storage lagrange_bases_unshifted ) { - uint urs_size = g.length; - uint num_unshifteds = (domain_size + urs_size - 1) / urs_size; - BN254.G1Point[][] memory unshifted = new BN254.G1Point[][](num_unshifteds); - - // For each chunk - for (uint i = 0; i < num_unshifteds; i++) { - // Initialize the vector with zero curve points - BN254.G1Point[] memory lg = new BN254.G1Point[](domain_size); - for (uint j = 0; j < lg.length; j++) { - lg[j] = BN254.point_at_inf(); - } - - // Overwrite the terms corresponding to that chunk with the SRS curve points - uint start_offset = i * urs_size; - uint num_terms = Utils.min((i + 1) * urs_size, domain_size) - start_offset; - for (uint j = 0; j < num_terms; j++) { - lg[start_offset + j] = g[j]; - } - // Apply the IFFT - BN254.G1Point[] memory lg_fft = Utils.ifft(lg); - // Append the 'partial Langrange polynomials' to the vector of unshifted chunks - unshifted[i] = lg_fft; + uint256 urs_size = g.length; + uint256 num_unshifteds = (domain_size + urs_size - 1) / urs_size; + BN254.G1Point[][] memory unshifted = new BN254.G1Point[][](num_unshifteds); + + // For each chunk + for (uint256 i = 0; i < num_unshifteds; i++) { + // Initialize the vector with zero curve points + BN254.G1Point[] memory lg = new BN254.G1Point[](domain_size); + for (uint256 j = 0; j < lg.length; j++) { + lg[j] = BN254.point_at_inf(); } - PolyCommFlat storage bases_unshifted = lagrange_bases_unshifted[domain_size]; - uint[] memory unshifted_lengths = new uint[](num_unshifteds); - for (uint i = 0; i < num_unshifteds; i++) { - unshifted_lengths[i] = 0; + // Overwrite the terms corresponding to that chunk with the SRS curve points + uint256 start_offset = i * urs_size; + uint256 num_terms = Utils.min((i + 1) * urs_size, domain_size) - start_offset; + for (uint256 j = 0; j < num_terms; j++) { + lg[start_offset + j] = g[j]; } - bases_unshifted.unshifted_lengths = unshifted_lengths; + // Apply the IFFT + BN254.G1Point[] memory lg_fft = Utils.ifft(lg); + // Append the 'partial Langrange polynomials' to the vector of unshifted chunks + unshifted[i] = lg_fft; + } - for (uint i = 0; i < domain_size; i++) { - for (uint j = 0; j < unshifted.length; j++) { - bases_unshifted.unshifteds.push(unshifted[j][i]); - } + PolyCommFlat storage bases_unshifted = lagrange_bases_unshifted[domain_size]; + uint256[] memory unshifted_lengths = new uint[](num_unshifteds); + for (uint256 i = 0; i < num_unshifteds; i++) { + unshifted_lengths[i] = 0; + } + bases_unshifted.unshifted_lengths = unshifted_lengths; + + for (uint256 i = 0; i < domain_size; i++) { + for (uint256 j = 0; j < unshifted.length; j++) { + bases_unshifted.unshifteds.push(unshifted[j][i]); } + } } // Computes the linearization of the evaluations of a (potentially split) polynomial. @@ -296,25 +273,25 @@ function combined_inner_product( Scalar.FE evalscale, PolyMatrices memory polys, //uint[] poly_shifted, // TODO: not necessary for fiat-shamir - uint srs_length + uint256 srs_length ) pure returns (Scalar.FE res) { res = Scalar.zero(); Scalar.FE xi_i = Scalar.from(1); //require(poly_matrices.length == poly_shifted.length); - for (uint i = 0; i < polys.length; i++) { - uint cols = polys.cols[i]; - uint rows = polys.rows[i]; + for (uint256 i = 0; i < polys.length; i++) { + uint256 cols = polys.cols[i]; + uint256 rows = polys.rows[i]; if (cols == 0) { continue; } - for (uint col = 0; col < cols; col++) { + for (uint256 col = 0; col < cols; col++) { Scalar.FE[] memory eval = new Scalar.FE[](rows); // column that stores the segment - for (uint j = 0; j < rows; j++) { - eval[j] = polys.data[polys.starts[i] + col*rows + j]; + for (uint256 j = 0; j < rows; j++) { + eval[j] = polys.data[polys.starts[i] + col * rows + j]; } Scalar.FE term = Polynomial.build_and_eval(eval, evalscale); @@ -336,8 +313,8 @@ function combined_inner_product( // relevant: https://github.com/o1-labs/proof-systems/blob/a27270040c08eb2c99e37f90833ee7bfb1fd22f5/kimchi/src/verifier.rs#L566 struct PolyMatrices { Scalar.FE[] data; - uint length; - uint[] rows; // row count per matrix - uint[] cols; // col count per matrix - uint[] starts; // index at which every matrix starts + uint256 length; + uint256[] rows; // row count per matrix + uint256[] cols; // col count per matrix + uint256[] starts; // index at which every matrix starts } diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index d213cd07..1096081e 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -41,21 +41,18 @@ struct ProverCommitments { PolyComm[15] w_comm; // TODO: use Constants.COLUMNS PolyComm z_comm; PolyComm t_comm; - // TODO: lookup commitments } +// TODO: lookup commitments -function combine_evals( - ProofEvaluationsArray memory self, - PointEvaluations memory pt -) pure returns (ProofEvaluations memory) { +function combine_evals(ProofEvaluationsArray memory self, PointEvaluations memory pt) + pure + returns (ProofEvaluations memory) +{ PointEvaluations memory public_evals; if (self.is_public_evals_set) { public_evals = PointEvaluations( Polynomial.build_and_eval(self.public_evals.zeta, pt.zeta), - Polynomial.build_and_eval( - self.public_evals.zeta_omega, - pt.zeta_omega - ) + Polynomial.build_and_eval(self.public_evals.zeta_omega, pt.zeta_omega) ); } else { public_evals = PointEvaluations(Scalar.zero(), Scalar.zero()); @@ -71,8 +68,7 @@ function combine_evals( PointEvaluations memory z; z = PointEvaluations( - Polynomial.build_and_eval(self.z.zeta, pt.zeta), - Polynomial.build_and_eval(self.z.zeta_omega, pt.zeta_omega) + Polynomial.build_and_eval(self.z.zeta, pt.zeta), Polynomial.build_and_eval(self.z.zeta_omega, pt.zeta_omega) ); PointEvaluations[7 - 1] memory s; @@ -86,10 +82,7 @@ function combine_evals( return ProofEvaluations(public_evals, self.is_public_evals_set, w, z, s); } -function evaluate_column(ProofEvaluations memory self, Column memory col) - pure - returns (PointEvaluations memory) -{ +function evaluate_column(ProofEvaluations memory self, Column memory col) pure returns (PointEvaluations memory) { if (col.variant == ColumnVariant.Witness) { uint256 i = abi.decode(col.data, (uint256)); return self.w[i]; @@ -105,10 +98,7 @@ function evaluate_column(ProofEvaluations memory self, Column memory col) // TODO: rest of variants, for this it's necessary to expand ProofEvaluations } -function evaluate_variable(Variable memory self, ProofEvaluations memory evals) - pure - returns (Scalar.FE) -{ +function evaluate_variable(Variable memory self, ProofEvaluations memory evals) pure returns (Scalar.FE) { PointEvaluations memory point_evals = evaluate_column(evals, self.col); if (self.row == CurrOrNext.Curr) { return point_evals.zeta; diff --git a/eth_verifier/lib/bn254/Fields.sol b/eth_verifier/lib/bn254/Fields.sol index e7c00a58..3f46ab07 100644 --- a/eth_verifier/lib/bn254/Fields.sol +++ b/eth_verifier/lib/bn254/Fields.sol @@ -5,8 +5,7 @@ pragma solidity >=0.4.16 <0.9.0; library Base { type FE is uint256; - uint256 public constant MODULUS = - 21888242871839275222246405745257275088696311157297823662689037894645226208583; + uint256 public constant MODULUS = 21888242871839275222246405745257275088696311157297823662689037894645226208583; function zero() public pure returns (FE) { return FE.wrap(0); @@ -16,32 +15,26 @@ library Base { return FE.wrap(1); } - function from(uint n) public pure returns (FE) { + function from(uint256 n) public pure returns (FE) { return FE.wrap(n % MODULUS); } function from_bytes_be(bytes memory b) public pure returns (FE) { uint256 integer = 0; - for (uint i = 0; i < 32; i++) { + for (uint256 i = 0; i < 32; i++) { integer <<= 8; integer += uint8(b[i]); } return FE.wrap(integer % MODULUS); } - function add( - FE self, - FE other - ) public pure returns (FE res) { + function add(FE self, FE other) public pure returns (FE res) { assembly { res := addmod(self, other, MODULUS) // addmod has arbitrary precision } } - function mul( - FE self, - FE other - ) public pure returns (FE res) { + function mul(FE self, FE other) public pure returns (FE res) { assembly { res := mulmod(self, other, MODULUS) // mulmod has arbitrary precision } @@ -55,7 +48,7 @@ library Base { function inv(FE self) public view returns (FE) { require(FE.unwrap(self) != 0, "tried to get inverse of 0"); - (uint gcd, uint inverse) = Aux.xgcd(FE.unwrap(self), MODULUS); + (uint256 gcd, uint256 inverse) = Aux.xgcd(FE.unwrap(self), MODULUS); require(gcd == 1, "gcd not 1"); return FE.wrap(inverse); @@ -73,7 +66,7 @@ library Base { // Reference: Lambdaworks // https://github.com/lambdaclass/lambdaworks/ - function pow(FE self, uint exponent) public pure returns (FE result) { + function pow(FE self, uint256 exponent) public pure returns (FE result) { if (exponent == 0) { return FE.wrap(1); } else if (exponent == 1) { @@ -106,15 +99,15 @@ library Base { import {console} from "forge-std/console.sol"; /// @notice Implements 256 bit modular arithmetic over the scalar field of bn254. + library Scalar { type FE is uint256; - using { add, mul, inv, neg, sub } for FE; + using {add, mul, inv, neg, sub} for FE; - uint256 public constant MODULUS = - 21888242871839275222246405745257275088548364400416034343698204186575808495617; + uint256 public constant MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - uint256 public constant TWO_ADIC_PRIMITIVE_ROOT_OF_UNITY = + uint256 public constant TWO_ADIC_PRIMITIVE_ROOT_OF_UNITY = 19103219067921713944291392827692070036145651957329286315305642004821462161904; uint256 public constant TWO_ADICITY = 28; @@ -126,15 +119,15 @@ library Scalar { return FE.wrap(1); } - function from(uint n) public pure returns (FE) { + function from(uint256 n) public pure returns (FE) { return FE.wrap(n % MODULUS); } function from_bytes_be(bytes memory b) public pure returns (FE) { uint256 integer = 0; - uint count = b.length <= 32 ? b.length : 32; + uint256 count = b.length <= 32 ? b.length : 32; - for (uint i = 0; i < count; i++) { + for (uint256 i = 0; i < count; i++) { integer <<= 8; integer += uint8(b[i]); } @@ -142,19 +135,13 @@ library Scalar { return FE.wrap(integer % MODULUS); } - function add( - FE self, - FE other - ) public pure returns (FE res) { + function add(FE self, FE other) public pure returns (FE res) { assembly { res := addmod(self, other, MODULUS) // addmod has arbitrary precision } } - function mul( - FE self, - FE other - ) public pure returns (FE res) { + function mul(FE self, FE other) public pure returns (FE res) { assembly { res := mulmod(self, other, MODULUS) // mulmod has arbitrary precision } @@ -170,7 +157,7 @@ library Scalar { function inv(FE self) public view returns (FE) { require(FE.unwrap(self) != 0, "tried to get inverse of 0"); - (uint gcd, uint inverse) = Aux.xgcd(FE.unwrap(self), MODULUS); + (uint256 gcd, uint256 inverse) = Aux.xgcd(FE.unwrap(self), MODULUS); require(gcd == 1, "gcd not 1"); return FE.wrap(inverse); @@ -188,7 +175,7 @@ library Scalar { // Reference: Lambdaworks // https://github.com/lambdaclass/lambdaworks/ - function pow(FE self, uint exponent) public pure returns (FE result) { + function pow(FE self, uint256 exponent) public pure returns (FE result) { if (exponent == 0) { return FE.wrap(1); } else if (exponent == 1) { @@ -222,9 +209,8 @@ library Scalar { /// @notice returns a primitive root of unity of order $2^{order}$. // Reference: Lambdaworks // https://github.com/lambdaclass/lambdaworks/ - function get_primitive_root_of_unity( - uint order - ) public view returns (FE root) { + + function get_primitive_root_of_unity(uint256 order) public view returns (FE root) { if (order == 0) { return FE.wrap(1); } @@ -232,9 +218,9 @@ library Scalar { revert RootOfUnityError(); } - uint log_power = TWO_ADICITY - order; + uint256 log_power = TWO_ADICITY - order; FE root = from(TWO_ADIC_PRIMITIVE_ROOT_OF_UNITY); - for (uint i = 0; i < log_power; i++) { + for (uint256 i = 0; i < log_power; i++) { root = square(root); } @@ -247,35 +233,32 @@ library Aux { /// @notice Extended euclidean algorithm. Returns [gcd, Bezout_a] /// @notice so gcd = a*Bezout_a + b*Bezout_b. /// @notice source: https://www.extendedeuclideanalgorithm.com/code - function xgcd( - uint a, - uint b - ) public pure returns (uint r0, uint s0) { + function xgcd(uint256 a, uint256 b) public pure returns (uint256 r0, uint256 s0) { r0 = a; - uint r1 = b; + uint256 r1 = b; s0 = 1; - uint s1 = 0; - uint t0 = 0; - uint t1 = 1; + uint256 s1 = 0; + uint256 t0 = 0; + uint256 t1 = 1; - uint n = 0; + uint256 n = 0; while (r1 != 0) { - uint q = r0 / r1; - r0 = r0 > q*r1 ? r0 - q*r1 : q*r1 - r0; // abs + uint256 q = r0 / r1; + r0 = r0 > q * r1 ? r0 - q * r1 : q * r1 - r0; // abs // swap r0, r1 - uint temp = r0; + uint256 temp = r0; r0 = r1; r1 = temp; - s0 = s0 + q*s1; + s0 = s0 + q * s1; // swap s0, s1 temp = s0; s0 = s1; s1 = temp; - t0 = t0 + q*t1; + t0 = t0 + q * t1; // swap t0, t1 temp = t0; diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index d362f3b9..93ffc25a 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -29,11 +29,7 @@ library MsgPk { bytes[] values; } - function new_stream(bytes memory data) - public - pure - returns (Stream memory) - { + function new_stream(bytes memory data) public pure returns (Stream memory) { return Stream(data, 0); } @@ -48,11 +44,7 @@ library MsgPk { return self.data[self.curr_index]; } - function next_n(Stream memory self, uint256 n) - public - view - returns (bytes memory consumed) - { + function next_n(Stream memory self, uint256 n) public view returns (bytes memory consumed) { consumed = new bytes(n); for (uint256 i = 0; i < n; i++) { consumed[i] = self.data[self.curr_index + i]; @@ -63,16 +55,9 @@ library MsgPk { error EncodedMapKeyNotFound(bytes key, bytes[] stored_keys); /// @notice returns the bytes corresponding to the queried key - function find_value(EncodedMap memory self, bytes memory key) - public - pure - returns (bytes memory) - { + function find_value(EncodedMap memory self, bytes memory key) public pure returns (bytes memory) { uint256 i = 0; - while ( - i != self.keys.length && - keccak256(self.keys[i]) != keccak256(key) - ) { + while (i != self.keys.length && keccak256(self.keys[i]) != keccak256(key)) { i++; } if (i == self.keys.length) revert EncodedMapKeyNotFound(key, self.keys); @@ -81,16 +66,9 @@ library MsgPk { /// @notice like find_value() but returns a boolean that indicates if /// @notice the key exists. If not found, the resulted bytes will be empty. - function find_value_or_fail(EncodedMap memory self, bytes memory key) - public - pure - returns (bytes memory, bool) - { + function find_value_or_fail(EncodedMap memory self, bytes memory key) public pure returns (bytes memory, bool) { uint256 i = 0; - while ( - i != self.keys.length && - keccak256(self.keys[i]) != keccak256(key) - ) { + while (i != self.keys.length && keccak256(self.keys[i]) != keccak256(key)) { i++; } if (i == self.keys.length) return (new bytes(0), false); @@ -100,18 +78,9 @@ library MsgPk { error NotImplementedType(bytes1 prefix); /// @notice deserializes the next type and returns the encoded data. - function deser_encode(Stream memory self) - public - view - returns (bytes memory) - { + function deser_encode(Stream memory self) public view returns (bytes memory) { bytes1 prefix = curr(self); - if ( - prefix >> 5 == 0x05 || - prefix == 0xd9 || - prefix == 0xda || - prefix == 0xdb - ) { + if (prefix >> 5 == 0x05 || prefix == 0xd9 || prefix == 0xda || prefix == 0xdb) { return abi.encode(deser_str(self)); } else if (prefix == 0xC4) { return abi.encode(deser_bin8(self)); @@ -140,13 +109,7 @@ library MsgPk { function deser_str(Stream memory self) public view returns (string memory) { bytes1 first = next(self); - require( - first >> 5 == 0x05 || - first == 0xd9 || - first == 0xda || - first == 0xdb, - "not a fixstr or strX" - ); + require(first >> 5 == 0x05 || first == 0xd9 || first == 0xda || first == 0xdb, "not a fixstr or strX"); if (first >> 5 == 0x05) { // fixstr @@ -183,11 +146,7 @@ library MsgPk { return next_n(self, n); } - function deser_fixarr(Stream memory self) - public - view - returns (EncodedArray memory arr) - { + function deser_fixarr(Stream memory self) public view returns (EncodedArray memory arr) { bytes1 first = next(self); require(first >> 4 == 0x09, "not a fixarr"); uint256 n = uint256(uint8(first & 0x0F)); // low nibble @@ -199,11 +158,7 @@ library MsgPk { } } - function deser_fixmap(Stream memory self) - public - view - returns (EncodedMap memory map) - { + function deser_fixmap(Stream memory self) public view returns (EncodedMap memory map) { bytes1 first = next(self); require(first >> 4 == 0x08, "not a fixmap"); uint256 n = uint256(uint8(first & 0x0F)); // low nibble @@ -216,11 +171,7 @@ library MsgPk { } } - function deser_arr16(Stream memory self) - public - view - returns (EncodedArray memory arr) - { + function deser_arr16(Stream memory self) public view returns (EncodedArray memory arr) { bytes1 first = next(self); require(first == 0xdc, "not an arr16"); // size is next two bytes: @@ -234,11 +185,7 @@ library MsgPk { } } - function deser_arr32(Stream memory self) - public - view - returns (EncodedArray memory arr) - { + function deser_arr32(Stream memory self) public view returns (EncodedArray memory arr) { bytes1 first = next(self); require(first == 0xdd, "not an arr32"); // size is next two bytes: @@ -252,11 +199,7 @@ library MsgPk { } } - function deser_map16(Stream memory self) - public - view - returns (EncodedMap memory map) - { + function deser_map16(Stream memory self) public view returns (EncodedMap memory map) { bytes1 first = next(self); require(first == 0xde, "not a map16"); // size is next two bytes: @@ -304,10 +247,10 @@ library MsgPk { bytes1 pad_byte = b[0] & 0x40 == 0x40 ? bytes1(0xFF) : bytes1(0x00); bytes memory padded_b = new bytes(32); - for (uint i = 0; i < 32 - b.length; i++) { + for (uint256 i = 0; i < 32 - b.length; i++) { padded_b[i] = pad_byte; } - for (uint i = b.length; i < 32; i++) { + for (uint256 i = b.length; i < 32; i++) { padded_b[i] = b[i - b.length]; } @@ -329,11 +272,7 @@ library MsgPk { return uint8(first); } - function deser_null(Stream memory self) - public - view - returns (string memory) - { + function deser_null(Stream memory self) public view returns (string memory) { bytes1 first = next(self); require(first == 0xc0, "not null"); @@ -347,18 +286,11 @@ library MsgPk { return first == 0xc3; // 0xc3 == true } - function deser_buffer(EncodedMap memory self) - public - pure - returns (bytes memory data) - { + function deser_buffer(EncodedMap memory self) public pure returns (bytes memory data) { bytes memory type_name = abi.decode(find_value(self, abi.encode("type")), (bytes)); require(keccak256(type_name) == keccak256("Buffer")); - EncodedArray memory data_arr = abi.decode( - find_value(self, abi.encode("data")), - (EncodedArray) - ); + EncodedArray memory data_arr = abi.decode(find_value(self, abi.encode("data")), (EncodedArray)); // data_arr will hold an array of `bytes` arrays, where each `bytes` // is a 32 sized byte array which represents only one byte, but padded @@ -373,38 +305,22 @@ library MsgPk { data = Utils.flatten_padded_bytes_array(data_arr.values); } - function deser_buffer_to_uint256(EncodedMap memory self) - public - pure - returns (uint256 integer) - { + function deser_buffer_to_uint256(EncodedMap memory self) public pure returns (uint256 integer) { bytes memory type_name = abi.decode(find_value(self, abi.encode("type")), (bytes)); require(keccak256(type_name) == keccak256("Buffer")); - EncodedArray memory data_arr = abi.decode( - find_value(self, abi.encode("data")), - (EncodedArray) - ); + EncodedArray memory data_arr = abi.decode(find_value(self, abi.encode("data")), (EncodedArray)); integer = Utils.padded_bytes_array_to_uint256(data_arr.values); } - function deser_verifier_index( - Stream memory self, - VerifierIndex storage index - ) external { + function deser_verifier_index(Stream memory self, VerifierIndex storage index) external { EncodedMap memory map = deser_map16(self); index.public_len = abi.decode(find_value(map, abi.encode("public")), (uint256)); - index.max_poly_size = abi.decode( - find_value(map, abi.encode("max_poly_size")), - (uint256) - ); + index.max_poly_size = abi.decode(find_value(map, abi.encode("max_poly_size")), (uint256)); index.zk_rows = abi.decode(find_value(map, abi.encode("zk_rows")), (uint64)); - EncodedMap memory domain_map = abi.decode( - find_value(map, abi.encode("domain")), - (EncodedMap) - ); + EncodedMap memory domain_map = abi.decode(find_value(map, abi.encode("domain")), (EncodedMap)); bytes memory domain_b = deser_buffer(domain_map); @@ -426,15 +342,10 @@ library MsgPk { index.domain_gen = Scalar.from(domain_gen); // wire shift coordinates - EncodedArray memory shift_arr = abi.decode( - find_value(map, abi.encode("shift")), - (EncodedArray) - ); + EncodedArray memory shift_arr = abi.decode(find_value(map, abi.encode("shift")), (EncodedArray)); require(shift_arr.values.length == 7, "shift array is not of length 7"); for (uint256 i = 0; i < 7; i++) { - uint256 inner = deser_buffer_to_uint256( - abi.decode(shift_arr.values[i], (EncodedMap)) - ); + uint256 inner = deser_buffer_to_uint256(abi.decode(shift_arr.values[i], (EncodedMap))); index.shift[i] = Scalar.from(inner); } @@ -442,52 +353,31 @@ library MsgPk { index.w = index.domain_gen.pow(index.domain_size - index.zk_rows); // commitments - EncodedArray memory sigma_comm_arr = abi.decode( - find_value(map, abi.encode("sigma_comm")), - (EncodedArray) - ); - EncodedArray memory coefficients_comm_arr = abi.decode( - find_value(map, abi.encode("coefficients_comm")), - (EncodedArray) - ); + EncodedArray memory sigma_comm_arr = abi.decode(find_value(map, abi.encode("sigma_comm")), (EncodedArray)); + EncodedArray memory coefficients_comm_arr = + abi.decode(find_value(map, abi.encode("coefficients_comm")), (EncodedArray)); PolyComm[7] memory sigma_comm; - for (uint i = 0; i < sigma_comm.length; i++) { - sigma_comm[i] = deser_poly_comm(abi.decode( - sigma_comm_arr.values[i], - (EncodedMap)) - ); + for (uint256 i = 0; i < sigma_comm.length; i++) { + sigma_comm[i] = deser_poly_comm(abi.decode(sigma_comm_arr.values[i], (EncodedMap))); } PolyComm[15] memory coefficients_comm; - for (uint i = 0; i < coefficients_comm.length; i++) { - coefficients_comm[i] = deser_poly_comm(abi.decode( - coefficients_comm_arr.values[i], - (EncodedMap)) - ); + for (uint256 i = 0; i < coefficients_comm.length; i++) { + coefficients_comm[i] = deser_poly_comm(abi.decode(coefficients_comm_arr.values[i], (EncodedMap))); } index.sigma_comm = sigma_comm; index.coefficients_comm = coefficients_comm; } - function deser_poly_comm(EncodedMap memory map) - public - view - returns (PolyComm memory) - { - EncodedArray memory unshifted_arr = abi.decode( - find_value(map, abi.encode("unshifted")), - (EncodedArray) - ); + function deser_poly_comm(EncodedMap memory map) public view returns (PolyComm memory) { + EncodedArray memory unshifted_arr = abi.decode(find_value(map, abi.encode("unshifted")), (EncodedArray)); - uint len = unshifted_arr.values.length; + uint256 len = unshifted_arr.values.length; BN254.G1Point[] memory unshifted = new BN254.G1Point[](len); - for (uint i = 0; i < len; i++) { - EncodedMap memory buffer = abi.decode( - unshifted_arr.values[i], - (EncodedMap) - ); + for (uint256 i = 0; i < len; i++) { + EncodedMap memory buffer = abi.decode(unshifted_arr.values[i], (EncodedMap)); unshifted[i] = BN254.g1Deserialize(bytes32(deser_buffer(buffer))); } // TODO: shifted part @@ -495,66 +385,39 @@ library MsgPk { return PolyComm(unshifted); } - function deser_prover_proof( - Stream memory self, - ProverProof storage prover_proof - ) external { + function deser_prover_proof(Stream memory self, ProverProof storage prover_proof) external { EncodedMap memory map = deser_fixmap(self); // deserialize evaluations - EncodedMap memory all_evals_map = abi.decode( - find_value(map, abi.encode("evals")), - (EncodedMap) - ); + EncodedMap memory all_evals_map = abi.decode(find_value(map, abi.encode("evals")), (EncodedMap)); prover_proof.evals.public_evals = deser_evals(all_evals_map, "public"); prover_proof.evals.is_public_evals_set = true; prover_proof.evals.z = deser_evals(all_evals_map, "z"); - PointEvaluationsArray[] memory w = deser_evals_array( - all_evals_map, - "w" - ); + PointEvaluationsArray[] memory w = deser_evals_array(all_evals_map, "w"); for (uint256 i = 0; i < 15; i++) { prover_proof.evals.w[i] = w[i]; } - PointEvaluationsArray[] memory s = deser_evals_array( - all_evals_map, - "s" - ); + PointEvaluationsArray[] memory s = deser_evals_array(all_evals_map, "s"); for (uint256 i = 0; i < 6; i++) { prover_proof.evals.w[i] = w[i]; } // deserialize commitments - EncodedMap memory comm_map = abi.decode( - find_value(map, abi.encode("commitments")), - (EncodedMap) - ); - - EncodedArray memory w_comm_arr = abi.decode( - find_value(comm_map, abi.encode("w_comm")), - (EncodedArray) - ); - EncodedMap memory z_comm_map = abi.decode( - find_value(comm_map, abi.encode("z_comm")), - (EncodedMap) - ); - EncodedMap memory t_comm_map = abi.decode( - find_value(comm_map, abi.encode("t_comm")), - (EncodedMap) - ); + EncodedMap memory comm_map = abi.decode(find_value(map, abi.encode("commitments")), (EncodedMap)); + + EncodedArray memory w_comm_arr = abi.decode(find_value(comm_map, abi.encode("w_comm")), (EncodedArray)); + EncodedMap memory z_comm_map = abi.decode(find_value(comm_map, abi.encode("z_comm")), (EncodedMap)); + EncodedMap memory t_comm_map = abi.decode(find_value(comm_map, abi.encode("t_comm")), (EncodedMap)); PolyComm[15] memory w_comm; - for (uint i = 0; i < w_comm.length; i++) { - w_comm[i] = deser_poly_comm(abi.decode( - w_comm_arr.values[i], - (EncodedMap)) - ); + for (uint256 i = 0; i < w_comm.length; i++) { + w_comm[i] = deser_poly_comm(abi.decode(w_comm_arr.values[i], (EncodedMap))); } PolyComm memory z_comm = deser_poly_comm(z_comm_map); PolyComm memory t_comm = deser_poly_comm(t_comm_map); @@ -569,33 +432,18 @@ library MsgPk { pure returns (PointEvaluationsArray memory) { - EncodedMap memory eval_map = abi.decode( - find_value(all_evals_map, abi.encode(name)), - (EncodedMap) - ); - - EncodedArray memory zeta_arr = abi.decode( - find_value(eval_map, abi.encode("zeta")), - (EncodedArray) - ); - EncodedArray memory zeta_omega_arr = abi.decode( - find_value(eval_map, abi.encode("zeta_omega")), - (EncodedArray) - ); + EncodedMap memory eval_map = abi.decode(find_value(all_evals_map, abi.encode(name)), (EncodedMap)); + + EncodedArray memory zeta_arr = abi.decode(find_value(eval_map, abi.encode("zeta")), (EncodedArray)); + EncodedArray memory zeta_omega_arr = abi.decode(find_value(eval_map, abi.encode("zeta_omega")), (EncodedArray)); require(zeta_arr.values.length == zeta_omega_arr.values.length); uint256 length = zeta_arr.values.length; Scalar.FE[] memory zetas = new Scalar.FE[](length); Scalar.FE[] memory zeta_omegas = new Scalar.FE[](length); for (uint256 i = 0; i < zeta_arr.values.length; i++) { - EncodedMap memory zeta_map = abi.decode( - zeta_arr.values[i], - (EncodedMap) - ); - EncodedMap memory zeta_omega_map = abi.decode( - zeta_omega_arr.values[i], - (EncodedMap) - ); + EncodedMap memory zeta_map = abi.decode(zeta_arr.values[i], (EncodedMap)); + EncodedMap memory zeta_omega_map = abi.decode(zeta_omega_arr.values[i], (EncodedMap)); uint256 zeta_inner = deser_buffer_to_uint256(zeta_map); uint256 zeta_omega_inner = deser_buffer_to_uint256(zeta_omega_map); @@ -607,50 +455,32 @@ library MsgPk { return PointEvaluationsArray(zetas, zeta_omegas); } - function deser_evals_array( - EncodedMap memory all_evals_map, - string memory name - ) public pure returns (PointEvaluationsArray[] memory evals) { - EncodedArray memory eval_array = abi.decode( - find_value(all_evals_map, abi.encode(name)), - (EncodedArray) - ); + function deser_evals_array(EncodedMap memory all_evals_map, string memory name) + public + pure + returns (PointEvaluationsArray[] memory evals) + { + EncodedArray memory eval_array = abi.decode(find_value(all_evals_map, abi.encode(name)), (EncodedArray)); uint256 length = eval_array.values.length; evals = new PointEvaluationsArray[](length); for (uint256 eval = 0; eval < length; eval++) { - EncodedMap memory eval_map = abi.decode( - eval_array.values[eval], - (EncodedMap) - ); + EncodedMap memory eval_map = abi.decode(eval_array.values[eval], (EncodedMap)); - EncodedArray memory zeta_arr = abi.decode( - find_value(eval_map, abi.encode("zeta")), - (EncodedArray) - ); - EncodedArray memory zeta_omega_arr = abi.decode( - find_value(eval_map, abi.encode("zeta_omega")), - (EncodedArray) - ); + EncodedArray memory zeta_arr = abi.decode(find_value(eval_map, abi.encode("zeta")), (EncodedArray)); + EncodedArray memory zeta_omega_arr = + abi.decode(find_value(eval_map, abi.encode("zeta_omega")), (EncodedArray)); require(zeta_arr.values.length == zeta_omega_arr.values.length); uint256 length = zeta_arr.values.length; Scalar.FE[] memory zetas = new Scalar.FE[](length); Scalar.FE[] memory zeta_omegas = new Scalar.FE[](length); for (uint256 i = 0; i < zeta_arr.values.length; i++) { - EncodedMap memory zeta_map = abi.decode( - zeta_arr.values[i], - (EncodedMap) - ); - EncodedMap memory zeta_omega_map = abi.decode( - zeta_omega_arr.values[i], - (EncodedMap) - ); + EncodedMap memory zeta_map = abi.decode(zeta_arr.values[i], (EncodedMap)); + EncodedMap memory zeta_omega_map = abi.decode(zeta_omega_arr.values[i], (EncodedMap)); uint256 zeta_inner = deser_buffer_to_uint256(zeta_map); - uint256 zeta_omega_inner = deser_buffer_to_uint256( - zeta_omega_map - ); + uint256 zeta_omega_inner = deser_buffer_to_uint256(zeta_omega_map); zetas[i] = Scalar.from(zeta_inner); zeta_omegas[i] = Scalar.from(zeta_omega_inner); @@ -663,17 +493,18 @@ library MsgPk { EncodedMap memory map, mapping(uint256 => PolyCommFlat) storage lagrange_bases_unshifted ) public { - for (uint i = 0; i < map.keys.length; i++) { + for (uint256 i = 0; i < map.keys.length; i++) { EncodedArray memory comms = abi.decode(map.values[i], (EncodedArray)); PolyComm[] memory polycomms = new PolyComm[](comms.values.length); - for (uint j = 0; j < comms.values.length; j++) { + for (uint256 j = 0; j < comms.values.length; j++) { EncodedMap memory comm = abi.decode(comms.values[i], (EncodedMap)); - EncodedArray memory unshifted_arr = abi.decode(find_value(comm, abi.encode("unshifted")), (EncodedArray)); + EncodedArray memory unshifted_arr = + abi.decode(find_value(comm, abi.encode("unshifted")), (EncodedArray)); - uint unshifted_length = unshifted_arr.values.length; + uint256 unshifted_length = unshifted_arr.values.length; BN254.G1Point[] memory unshifted = new BN254.G1Point[](unshifted_length); - for (uint k = 0; k < unshifted_length; k++) { + for (uint256 k = 0; k < unshifted_length; k++) { EncodedMap memory unshifted_buffer = abi.decode(unshifted_arr.values[k], (EncodedMap)); unshifted[k] = BN254.g1Deserialize(bytes32(deser_buffer(unshifted_buffer))); } @@ -691,26 +522,34 @@ library MsgPk { EncodedMap memory urs_map = deser_fixmap(self); EncodedMap memory full_urs_serialized = abi.decode(find_value(urs_map, abi.encode("full_srs")), (EncodedMap)); - EncodedMap memory verifier_urs_serialized = abi.decode(find_value(urs_map, abi.encode("verifier_srs")), (EncodedMap)); + EncodedMap memory verifier_urs_serialized = + abi.decode(find_value(urs_map, abi.encode("verifier_srs")), (EncodedMap)); // get data from g and h fields (g is an array of buffers and h is a buffer) - EncodedArray memory full_urs_g_serialized = abi.decode(find_value(full_urs_serialized, abi.encode("g")), (EncodedArray)); - EncodedMap memory full_urs_h_serialized = abi.decode(find_value(full_urs_serialized, abi.encode("h")), (EncodedMap)); + EncodedArray memory full_urs_g_serialized = + abi.decode(find_value(full_urs_serialized, abi.encode("g")), (EncodedArray)); + EncodedMap memory full_urs_h_serialized = + abi.decode(find_value(full_urs_serialized, abi.encode("h")), (EncodedMap)); - EncodedArray memory verifier_urs_g_serialized = abi.decode(find_value(verifier_urs_serialized, abi.encode("g")), (EncodedArray)); - EncodedMap memory verifier_urs_h_serialized = abi.decode(find_value(verifier_urs_serialized, abi.encode("h")), (EncodedMap)); + EncodedArray memory verifier_urs_g_serialized = + abi.decode(find_value(verifier_urs_serialized, abi.encode("g")), (EncodedArray)); + EncodedMap memory verifier_urs_h_serialized = + abi.decode(find_value(verifier_urs_serialized, abi.encode("h")), (EncodedMap)); // deserialized and save g for both URS - uint full_urs_g_length = full_urs_g_serialized.values.length; + uint256 full_urs_g_length = full_urs_g_serialized.values.length; BN254.G1Point[] memory full_urs_g = new BN254.G1Point[](full_urs_g_length); - for (uint i = 0; i < full_urs_g_length; i++) { - full_urs_g[i] = BN254.g1Deserialize(bytes32(deser_buffer(abi.decode(full_urs_g_serialized.values[i], (EncodedMap))))); + for (uint256 i = 0; i < full_urs_g_length; i++) { + full_urs_g[i] = + BN254.g1Deserialize(bytes32(deser_buffer(abi.decode(full_urs_g_serialized.values[i], (EncodedMap))))); } - uint verifier_urs_g_length = verifier_urs_g_serialized.values.length; + uint256 verifier_urs_g_length = verifier_urs_g_serialized.values.length; BN254.G1Point[] memory verifier_urs_g = new BN254.G1Point[](verifier_urs_g_length); - for (uint i = 0; i < verifier_urs_g_length; i++) { - verifier_urs_g[i] = BN254.g1Deserialize(bytes32(deser_buffer(abi.decode(verifier_urs_g_serialized.values[i], (EncodedMap))))); + for (uint256 i = 0; i < verifier_urs_g_length; i++) { + verifier_urs_g[i] = BN254.g1Deserialize( + bytes32(deser_buffer(abi.decode(verifier_urs_g_serialized.values[i], (EncodedMap)))) + ); } // deserialized and save h for both URS @@ -725,7 +564,8 @@ library MsgPk { urs.verifier_urs.h = verifier_urs_h; // deserialize and store lagrange bases - EncodedMap memory lagrange_b_serialized = abi.decode(find_value(full_urs_serialized, abi.encode("lagrange_bases")), (EncodedMap)); + EncodedMap memory lagrange_b_serialized = + abi.decode(find_value(full_urs_serialized, abi.encode("lagrange_bases")), (EncodedMap)); deser_lagrange_bases(lagrange_b_serialized, urs.lagrange_bases_unshifted); } @@ -734,7 +574,7 @@ library MsgPk { EncodedArray memory arr = deser_arr32(self); PolishToken[] memory constant_term = new PolishToken[](arr.values.length); - for (uint i = 0; i < arr.values.length; i++) { + for (uint256 i = 0; i < arr.values.length; i++) { EncodedMap memory value_map = abi.decode(arr.values[i], (EncodedMap)); constant_term[i] = deser_polishtoken(value_map); } @@ -795,12 +635,12 @@ library MsgPk { } (bytes memory coefficient_value, bool is_coefficient) = find_value_or_fail(col_map, abi.encode("Coefficient")); if (is_coefficient) { - uint i = deser_uint(new_stream(coefficient_value)); + uint256 i = deser_uint(new_stream(coefficient_value)); return Column(ColumnVariant.Coefficient, abi.encode(i)); } (bytes memory permutation_value, bool is_permutation) = find_value_or_fail(col_map, abi.encode("Permutation")); if (is_permutation) { - uint i = deser_uint(new_stream(permutation_value)); + uint256 i = deser_uint(new_stream(permutation_value)); return Column(ColumnVariant.Permutation, abi.encode(i)); } revert("Couldn't match any Column variant while deserializing a column."); @@ -839,8 +679,8 @@ library MsgPk { (bytes memory mds_value, bool is_mds) = find_value_or_fail(map, abi.encode("mds")); if (is_mds) { EncodedMap memory mds_map = abi.decode(mds_value, (EncodedMap)); - uint row = abi.decode(find_value(mds_map, abi.encode("row")), (uint)); - uint col = abi.decode(find_value(mds_map, abi.encode("col")), (uint)); + uint256 row = abi.decode(find_value(mds_map, abi.encode("row")), (uint256)); + uint256 col = abi.decode(find_value(mds_map, abi.encode("col")), (uint256)); return PolishToken(PolishTokenVariant.Mds, abi.encode(PolishTokenMds(row, col))); } (bytes memory literal_value, bool is_literal) = find_value_or_fail(map, abi.encode("literal")); @@ -868,20 +708,20 @@ library MsgPk { } (bytes memory pow_value, bool is_pow) = find_value_or_fail(map, abi.encode("pow")); if (is_pow) { - uint pow = deser_uint(new_stream(pow_value)); + uint256 pow = deser_uint(new_stream(pow_value)); return PolishToken(PolishTokenVariant.Pow, abi.encode(pow)); } (bytes memory ulag_value, bool is_ulag) = find_value_or_fail(map, abi.encode("unnormalizedlagrangebasis")); if (is_ulag) { EncodedMap memory rowoffset_map = abi.decode(ulag_value, (EncodedMap)); bool zk_rows = abi.decode(find_value(rowoffset_map, abi.encode("zk_rows")), (bool)); - int offset = abi.decode(find_value(rowoffset_map, abi.encode("offset")), (int)); + int256 offset = abi.decode(find_value(rowoffset_map, abi.encode("offset")), (int256)); RowOffset memory rowoffset = RowOffset(zk_rows, offset); return PolishToken(PolishTokenVariant.UnnormalizedLagrangeBasis, abi.encode(rowoffset)); } (bytes memory load_value, bool is_load) = find_value_or_fail(map, abi.encode("load")); if (is_load) { - uint i = deser_uint(new_stream(load_value)); + uint256 i = deser_uint(new_stream(load_value)); return PolishToken(PolishTokenVariant.Load, abi.encode(i)); } } @@ -896,11 +736,7 @@ library MsgPk { function deserializeFinalCommitments(bytes calldata data) public view - returns ( - BN254.G1Point memory numerator, - BN254.G1Point memory quotient, - BN254.G2Point memory divisor - ) + returns (BN254.G1Point memory numerator, BN254.G1Point memory quotient, BN254.G2Point memory divisor) { numerator = abi.decode(data[:64], (BN254.G1Point)); quotient = abi.decode(data[64:128], (BN254.G1Point)); @@ -938,38 +774,27 @@ library MsgPk { function deserializeURS(bytes calldata data) public view - returns ( - BN254.G1Point[] memory, - BN254.G1Point memory, - uint256 - ) + returns (BN254.G1Point[] memory, BN254.G1Point memory, uint256) { uint256 i = 0; require(data[i] == 0x92, "not a fix array of two elements"); i += 1; - require( - data[i] == 0xdc || data[i] == 0xdd, - "not an array16 or array32" - ); + require(data[i] == 0xdc || data[i] == 0xdd, "not an array16 or array32"); // 0xdc means that the next 2 bytes represent the size, // 0xdd means that the next 4 bytes represent the size. uint256 byte_count = data[i] == 0xdc ? 2 : 4; // next bytes are size of the array i += 1; - uint256 size = uint256(bytes32(data[i:i + byte_count])) >> - ((32 - byte_count) * 8); + uint256 size = uint256(bytes32(data[i:i + byte_count])) >> ((32 - byte_count) * 8); // shift is necessary because conversion pads with zeros to the left BN254.G1Point[] memory g = new BN254.G1Point[](size); i += byte_count; // read elements for (uint256 elem = 0; elem < size; elem++) { - (BN254.G1Point memory p, uint256 new_index) = deserializeG1Point( - data, - i - ); + (BN254.G1Point memory p, uint256 new_index) = deserializeG1Point(data, i); g[elem] = p; i = new_index; } @@ -1029,20 +854,14 @@ library MsgPk { returns (ProofEvaluationsArray memory evals, uint256 final_i) { // WARN: This works because the test circuit evaluations have one elem per array. - ( - PointEvaluations memory evals_non_array, - uint256 _i - ) = deserializePointEvals(data, i); + (PointEvaluations memory evals_non_array, uint256 _i) = deserializePointEvals(data, i); Scalar.FE[] memory zeta = new Scalar.FE[](1); Scalar.FE[] memory zeta_omega = new Scalar.FE[](1); zeta[0] = evals_non_array.zeta; zeta_omega[0] = evals_non_array.zeta_omega; - PointEvaluationsArray memory public_evals = PointEvaluationsArray( - zeta, - zeta_omega - ); + PointEvaluationsArray memory public_evals = PointEvaluationsArray(zeta, zeta_omega); PointEvaluationsArray[15] memory w; Scalar.FE[] memory zero = new Scalar.FE[](1); @@ -1055,11 +874,7 @@ library MsgPk { final_i = _i; } - function deserializeState(bytes calldata data, uint256 i) - public - view - returns (State memory) - { + function deserializeState(bytes calldata data, uint256 i) public view returns (State memory) { require(data[i] == 0x93, "not a fix array of three elements"); i += 1; diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 2ccf7e53..1151d48f 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -70,7 +70,7 @@ contract KimchiVerifier { //MsgPk.deser_pairing_urs(MsgPk.new_stream(urs_serialized), urs); // URS deserialization is WIP, we'll generate a random one for now: Scalar.FE x = Scalar.from(42); - uint max_domain_size = 16384; + uint256 max_domain_size = 16384; urs.full_urs = create_trusted_setup(x, max_domain_size); urs.verifier_urs = create_trusted_setup(x, 3); @@ -82,18 +82,12 @@ contract KimchiVerifier { verifier_index.powers_of_alpha.register(ArgumentType.Permutation, Constants.PERMUTATION_CONSTRAINTS); } - function verify_with_index( - bytes calldata verifier_index_serialized, - bytes calldata prover_proof_serialized - ) public returns (bool) { - MsgPk.deser_verifier_index( - MsgPk.new_stream(verifier_index_serialized), - verifier_index - ); - MsgPk.deser_prover_proof( - MsgPk.new_stream(prover_proof_serialized), - proof - ); + function verify_with_index(bytes calldata verifier_index_serialized, bytes calldata prover_proof_serialized) + public + returns (bool) + { + MsgPk.deser_verifier_index(MsgPk.new_stream(verifier_index_serialized), verifier_index); + MsgPk.deser_prover_proof(MsgPk.new_stream(prover_proof_serialized), proof); //calculate_lagrange_bases( // verifier_index.urs.g, @@ -109,10 +103,7 @@ contract KimchiVerifier { /// @notice this is currently deprecated but remains as to not break /// @notice the demo. - function verify_state( - bytes calldata state_serialized, - bytes calldata proof_serialized - ) public returns (bool) { + function verify_state(bytes calldata state_serialized, bytes calldata proof_serialized) public returns (bool) { // 1. Deserialize proof and setup // For now, proof consists in the concatenation of the bytes that @@ -121,18 +112,10 @@ contract KimchiVerifier { // BEWARE: quotient must be negated. - ( - BN254.G1Point memory numerator, - BN254.G1Point memory quotient, - BN254.G2Point memory divisor - ) = MsgPk.deserializeFinalCommitments(proof_serialized); - - bool success = BN254.pairingProd2( - numerator, - BN254.P2(), - quotient, - divisor - ); + (BN254.G1Point memory numerator, BN254.G1Point memory quotient, BN254.G2Point memory divisor) = + MsgPk.deserializeFinalCommitments(proof_serialized); + + bool success = BN254.pairingProd2(numerator, BN254.P2(), quotient, divisor); // 3. If success, deserialize and store state if (success) { @@ -149,16 +132,14 @@ contract KimchiVerifier { function partial_verify(Scalar.FE[] memory public_inputs) public { // Commit to the negated public input polynomial. - uint256 chunk_size = verifier_index.domain_size < - verifier_index.max_poly_size + uint256 chunk_size = verifier_index.domain_size < verifier_index.max_poly_size ? 1 : verifier_index.domain_size / verifier_index.max_poly_size; if (public_inputs.length != verifier_index.public_len) { revert IncorrectPublicInputLength(); } - PolyCommFlat memory lgr_comm_flat = urs - .lagrange_bases_unshifted[verifier_index.domain_size]; + PolyCommFlat memory lgr_comm_flat = urs.lagrange_bases_unshifted[verifier_index.domain_size]; PolyComm[] memory comm = new PolyComm[](verifier_index.public_len); PolyComm[] memory lgr_comm = poly_comm_unflat(lgr_comm_flat); // INFO: can use unchecked on for loops to save gas @@ -174,34 +155,23 @@ contract KimchiVerifier { public_comm = PolyComm(blindings); } else { Scalar.FE[] memory elm = new Scalar.FE[](public_inputs.length); - for (uint i = 0; i < elm.length; i++) { + for (uint256 i = 0; i < elm.length; i++) { elm[i] = public_inputs[i].neg(); } PolyComm memory public_comm_tmp = polycomm_msm(comm, elm); Scalar.FE[] memory blinders = new Scalar.FE[]( public_comm_tmp.unshifted.length ); - for (uint i = 0; i < public_comm_tmp.unshifted.length; i++) { + for (uint256 i = 0; i < public_comm_tmp.unshifted.length; i++) { blinders[i] = Scalar.FE.wrap(1); } - public_comm = mask_custom( - urs.full_urs, - public_comm_tmp, - blinders - ).commitment; + public_comm = mask_custom(urs.full_urs, public_comm_tmp, blinders).commitment; } // Execute fiat-shamir with a Keccak sponge - Oracles.Result memory oracles_res = Oracles.fiat_shamir( - proof, - verifier_index, - public_comm, - public_inputs, - true, - base_sponge, - scalar_sponge - ); + Oracles.Result memory oracles_res = + Oracles.fiat_shamir(proof, verifier_index, public_comm, public_inputs, true, base_sponge, scalar_sponge); Oracles.RandomOracles memory oracles = oracles_res.oracles; // Combine the chunked polynomials' evaluations @@ -209,22 +179,16 @@ contract KimchiVerifier { ProofEvaluations memory evals = proof.evals.combine_evals(oracles_res.powers_of_eval_points_for_chunks); // Compute the commitment to the linearized polynomial $f$. - Scalar.FE permutation_vanishing_polynomial = - Polynomial.vanishes_on_last_n_rows( - verifier_index.domain_gen, - verifier_index.domain_size, - verifier_index.zk_rows + Scalar.FE permutation_vanishing_polynomial = Polynomial.vanishes_on_last_n_rows( + verifier_index.domain_gen, verifier_index.domain_size, verifier_index.zk_rows ).evaluate(oracles.zeta); Scalar.FE[] memory alphas = - verifier_index.powers_of_alpha.get_alphas( - ArgumentType.Permutation, - Constants.PERMUTATION_CONSTRAINTS - ); + verifier_index.powers_of_alpha.get_alphas(ArgumentType.Permutation, Constants.PERMUTATION_CONSTRAINTS); Linearization memory linear = verifier_index.linearization; - PolyComm[] memory commitments = new PolyComm[](linear.index_terms.length + 1); + PolyComm[] memory commitments = new PolyComm[](linear.index_terms.length + 1); // FIXME: todo! initialize `commitments` with sigma_comm Scalar.FE[] memory scalars = new Scalar.FE[](linear.index_terms.length + 1); @@ -246,18 +210,12 @@ contract KimchiVerifier { verifier_index.zk_rows ); - for (uint i = 0; i < linear.index_terms.length; i++) { + for (uint256 i = 0; i < linear.index_terms.length; i++) { Column memory col = linear.index_terms[i].col; PolishToken[] memory tokens = linear.index_terms[i].coeff; - Scalar.FE scalar = evaluate( - tokens, - verifier_index.domain_gen, - verifier_index.domain_size, - oracles.zeta, - evals, - constants - ); + Scalar.FE scalar = + evaluate(tokens, verifier_index.domain_gen, verifier_index.domain_size, oracles.zeta, evals, constants); scalars[i + 1] = scalar; commitments[i + 1] = get_column(verifier_index, proof, col); @@ -282,8 +240,8 @@ contract KimchiVerifier { // TODO: alphas should be an iterator res = e.z.zeta_omega.mul(beta).mul(alphas[0]).mul(zkp_zeta); - uint len = Utils.min(e.w.length, e.s.length); - for (uint i = 0; i < len; i++) { + uint256 len = Utils.min(e.w.length, e.s.length); + for (uint256 i = 0; i < len; i++) { res = res.mul(gamma.add(beta.mul(e.s[i].zeta)).add(e.w[i].zeta)); } } @@ -342,7 +300,7 @@ contract KimchiVerifier { } /// @notice retrieves the hash of the state after this block - function retrieve_state_hash() public view returns (uint) { + function retrieve_state_hash() public view returns (uint256) { if (!state_available) { revert UnavailableState(); } @@ -350,7 +308,7 @@ contract KimchiVerifier { } /// @notice retrieves the block height - function retrieve_state_height() public view returns (uint) { + function retrieve_state_height() public view returns (uint256) { if (!state_available) { revert UnavailableState(); } From c83f1081b6442bf0f71bd92570d88810eee058f9 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 16:45:33 -0300 Subject: [PATCH 59/68] changes in Fields reverted --- eth_verifier/lib/bn254/Fields.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/eth_verifier/lib/bn254/Fields.sol b/eth_verifier/lib/bn254/Fields.sol index fa765b17..442e9f1f 100644 --- a/eth_verifier/lib/bn254/Fields.sol +++ b/eth_verifier/lib/bn254/Fields.sol @@ -100,7 +100,6 @@ library Base { import {console} from "forge-std/console.sol"; /// @notice Implements 256 bit modular arithmetic over the scalar field of bn254. - library Scalar { type FE is uint256; @@ -156,7 +155,7 @@ library Scalar { res = mul(self, self); } - function inv(FE self) public pure returns (FE) { + function inv(FE self) public view returns (FE) { require(FE.unwrap(self) != 0, "tried to get inverse of 0"); (uint256 gcd, uint256 inverse) = Aux.xgcd(FE.unwrap(self), MODULUS); require(gcd == 1, "gcd not 1"); @@ -207,7 +206,6 @@ library Scalar { } error RootOfUnityError(); - /// @notice returns a primitive root of unity of order $2^{order}$. // Reference: Lambdaworks // https://github.com/lambdaclass/lambdaworks/ From 7597cb793b14e06b3583509f98b3f35f9288e18a Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 17:03:49 -0300 Subject: [PATCH 60/68] Fields.sol modified to avoid conflics --- eth_verifier/lib/bn254/Fields.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth_verifier/lib/bn254/Fields.sol b/eth_verifier/lib/bn254/Fields.sol index 442e9f1f..3f46ab07 100644 --- a/eth_verifier/lib/bn254/Fields.sol +++ b/eth_verifier/lib/bn254/Fields.sol @@ -98,8 +98,8 @@ library Base { } import {console} from "forge-std/console.sol"; - /// @notice Implements 256 bit modular arithmetic over the scalar field of bn254. + library Scalar { type FE is uint256; From 5dd88c7b825e8d8ba386385763cb9307d3fcadff Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 17:18:50 -0300 Subject: [PATCH 61/68] eval_polynomial changed to view --- eth_verifier/src/Verifier.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 2324e62c..b64f9601 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -309,7 +309,7 @@ contract KimchiVerifier { /// The polynomial that evaluates to each of `evals` for the respective `elm`s. function eval_polynomial(Scalar.FE[] memory elm, Scalar.FE[] memory evals) public - pure + view returns (Polynomial.Dense memory) { require(elm.length == evals.length, "lengths don't match"); From f80793318f4cc8eda4c761918e89fd7ada597a64 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 17:29:01 -0300 Subject: [PATCH 62/68] Small fixes in comments --- eth_verifier/lib/Commitment.sol | 6 +++--- eth_verifier/lib/Proof.sol | 2 +- eth_verifier/lib/msgpack/Deserialize.sol | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 6d0d5d55..9fc1de00 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -50,9 +50,9 @@ function random_lagrange_bases(PairingURS storage urs, uint256 domain_size) { urs.lagrange_bases_unshifted[domain_size] = comms; } -//BN254G1Point shifted; -// WARN: The previous field is optional but in Solidity we can't have that. -// for our test circuit it's not necessary +// WARN: The field shifted is optional but in Solidity we can't have that. +// for our test circuit it's not necessary, we can just ignore it, using infinity. +//BN254.G1Point shifted; struct PolyComm { BN254.G1Point[] unshifted; } diff --git a/eth_verifier/lib/Proof.sol b/eth_verifier/lib/Proof.sol index 1096081e..a40c705c 100644 --- a/eth_verifier/lib/Proof.sol +++ b/eth_verifier/lib/Proof.sol @@ -37,12 +37,12 @@ struct ProofEvaluationsArray { PointEvaluationsArray[7 - 1] s; // TODO: use Constants.PERMUTS } +// TODO: add lookup commitments struct ProverCommitments { PolyComm[15] w_comm; // TODO: use Constants.COLUMNS PolyComm z_comm; PolyComm t_comm; } -// TODO: lookup commitments function combine_evals(ProofEvaluationsArray memory self, PointEvaluations memory pt) pure diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 93ffc25a..4cdedfcc 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -511,6 +511,7 @@ library MsgPk { polycomms[j] = PolyComm(unshifted); } + lagrange_bases_unshifted[abi.decode(map.keys[i], (uint256))] = poly_comm_flat(polycomms); } } @@ -728,10 +729,10 @@ library MsgPk { } /* WARN: - * Functions below are part of the previous deserializer implementation, - * and are still used for functions related to the demo. The goal is to replace - * them with the new WIP deserializer. Please prefer using functions above. - */ + * Functions below are part of the previous deserializer implementation, + * and are still used for functions related to the demo. The goal is to replace + * them with the new WIP deserializer. Please prefer using functions above. + */ function deserializeFinalCommitments(bytes calldata data) public From 2d279ba6961dec870a1098c3447974e5fcaeca00 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 17:37:01 -0300 Subject: [PATCH 63/68] shifted attribute added in PolyComm --- eth_verifier/lib/Commitment.sol | 22 +++++++++++++++------- eth_verifier/lib/msgpack/Deserialize.sol | 10 ++++++---- eth_verifier/src/Verifier.sol | 4 +++- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/eth_verifier/lib/Commitment.sol b/eth_verifier/lib/Commitment.sol index 5fffe331..cbf05c15 100644 --- a/eth_verifier/lib/Commitment.sol +++ b/eth_verifier/lib/Commitment.sol @@ -52,9 +52,9 @@ function random_lagrange_bases(PairingURS storage urs, uint256 domain_size) { // WARN: The field shifted is optional but in Solidity we can't have that. // for our test circuit it's not necessary, we can just ignore it, using infinity. -//BN254.G1Point shifted; struct PolyComm { BN254.G1Point[] unshifted; + BN254.G1Point shifted; } // @notice this structure flattens the fields of `PolyComm`. @@ -77,8 +77,8 @@ function poly_comm_unflat(PolyCommFlat memory com) pure returns (PolyComm[] memo index++; } // TODO: shifted is fixed to infinity - //BN254.G1Point shifted = BN254.point_at_inf(); - res[i] = PolyComm(unshifted); + BN254.G1Point memory shifted = BN254.point_at_inf(); + res[i] = PolyComm(unshifted, shifted); } } @@ -108,7 +108,9 @@ function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) view return if (com.length == 0 || elm.length == 0) { BN254.G1Point[] memory z = new BN254.G1Point[](1); z[0] = BN254.point_at_inf(); - return PolyComm(z); + // TODO: shifted is fixed to infinity + BN254.G1Point memory shifted = BN254.point_at_inf(); + return PolyComm(z, shifted); } if (com.length != elm.length) { @@ -152,7 +154,9 @@ function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm) view return BN254.G1Point memory chunk_msm = naive_msm(points, scalars); unshifted[chunk] = chunk_msm; } - return PolyComm(unshifted); + // TODO: shifted is fixed to infinity + BN254.G1Point memory shifted = BN254.point_at_inf(); + return PolyComm(unshifted, shifted); } // @notice Execute a simple multi-scalar multiplication @@ -191,7 +195,9 @@ function mask_custom(URS storage urs, PolyComm memory com, Scalar.FE[] memory bl unshifted[i] = (g_masked.add(com.unshifted[i])); } - return BlindedCommitment(PolyComm(unshifted), blinders); + // TODO: shifted is fixed to infinity + BN254.G1Point memory shifted = BN254.point_at_inf(); + return BlindedCommitment(PolyComm(unshifted, shifted), blinders); } // @notice multiplies each commitment chunk of f with powers of zeta^n @@ -210,7 +216,9 @@ function chunk_commitment(PolyComm memory self, Scalar.FE zeta_n) view returns ( BN254.G1Point[] memory unshifted = new BN254.G1Point[](1); unshifted[0] = res; - return PolyComm(unshifted); + // TODO: shifted is fixed to infinity + BN254.G1Point memory shifted = BN254.point_at_inf(); + return PolyComm(unshifted, shifted); } // @notice substracts two polynomial commitments diff --git a/eth_verifier/lib/msgpack/Deserialize.sol b/eth_verifier/lib/msgpack/Deserialize.sol index 4cdedfcc..fa164c02 100644 --- a/eth_verifier/lib/msgpack/Deserialize.sol +++ b/eth_verifier/lib/msgpack/Deserialize.sol @@ -380,9 +380,9 @@ library MsgPk { EncodedMap memory buffer = abi.decode(unshifted_arr.values[i], (EncodedMap)); unshifted[i] = BN254.g1Deserialize(bytes32(deser_buffer(buffer))); } - // TODO: shifted part - - return PolyComm(unshifted); + // TODO: shifted is fixed to infinity + BN254.G1Point memory shifted = BN254.point_at_inf(); + return PolyComm(unshifted, shifted); } function deser_prover_proof(Stream memory self, ProverProof storage prover_proof) external { @@ -509,7 +509,9 @@ library MsgPk { unshifted[k] = BN254.g1Deserialize(bytes32(deser_buffer(unshifted_buffer))); } - polycomms[j] = PolyComm(unshifted); + // TODO: shifted is fixed to infinity + BN254.G1Point memory shifted = BN254.point_at_inf(); + polycomms[j] = PolyComm(unshifted, shifted); } lagrange_bases_unshifted[abi.decode(map.keys[i], (uint256))] = poly_comm_flat(polycomms); diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index b64f9601..b40fbcfb 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -152,7 +152,9 @@ contract KimchiVerifier { for (uint256 i = 0; i < chunk_size; i++) { blindings[i] = urs.full_urs.h; } - public_comm = PolyComm(blindings); + // TODO: shifted is fixed to infinity + BN254.G1Point memory shifted = BN254.point_at_inf(); + public_comm = PolyComm(blindings, shifted); } else { Scalar.FE[] memory elm = new Scalar.FE[](public_inputs.length); for (uint256 i = 0; i < elm.length; i++) { From 87d591016ef8828b22ecb7d6ef3cdbe0c8570027 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 19:12:08 -0300 Subject: [PATCH 64/68] combineCommitments --- eth_verifier/src/Verifier.sol | 36 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index b40fbcfb..f5aa861e 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -314,7 +314,7 @@ contract KimchiVerifier { view returns (Polynomial.Dense memory) { - require(elm.length == evals.length, "lengths don't match"); + require(elm.length == evals.length, "lengths don\'t match"); require(elm.length == 2, "length must be 2"); Scalar.FE zeta = elm[0]; Scalar.FE zeta_omega = elm[1]; @@ -392,34 +392,22 @@ contract KimchiVerifier { } // If the evaluation has a degree bound and a non-zero shifted commitment - //if (evaluations[i].degree_bound > 0 && evaluations[i].commitment.shifted.length > 0) {} - /* - if let Some(_m) = degree_bound { - if let Some(comm_ch) = commitment.shifted { - if !comm_ch.is_zero() { - // polyscale^i sum_j evalscale^j elm_j^{N - m} f(elm_j) - scalars.push(rand_base * xi_i); - points.push(comm_ch); - - xi_i *= polyscale; - } - } - } - */ - /* TODO: FIX this with the previous version of the code - if ( - evaluations[i].degree_bound > 0 && - evaluations[i].shifted.length > 0 - ) { + if (evaluations[i].degree_bound > 0 && evaluations[i].commitment.shifted.x != 0) { + //// polyscale^i sum_j evalscale^j elm_j^{N - m} f(elm_j) + //scalars.push(rand_base * xi_i); + //points.push(comm_ch); + //xi_i *= polyscale; + // Add the scalar rand_base * xi_i to the scalars vector - scalars[i * 2 + 1] = rand_base * xi_i; + scalars[index] = rand_base.mul(xi_i); // Add the point to the points vector - points[i * 2 + 1] = evaluations[i].shifted[0]; + points[index] = evaluations[i].commitment.shifted; // Multiply xi_i by polyscale - xi_i *= polyscale; + xi_i = xi_i.mul(polyscale); + // Increment the index + index++; } - */ } } From f99cefe8182a26d75635e136fa3ef3a0eaad5564 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Wed, 3 Jan 2024 19:15:59 -0300 Subject: [PATCH 65/68] comment removed --- eth_verifier/src/Verifier.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index f5aa861e..0b6a7a52 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -394,9 +394,6 @@ contract KimchiVerifier { // If the evaluation has a degree bound and a non-zero shifted commitment if (evaluations[i].degree_bound > 0 && evaluations[i].commitment.shifted.x != 0) { //// polyscale^i sum_j evalscale^j elm_j^{N - m} f(elm_j) - //scalars.push(rand_base * xi_i); - //points.push(comm_ch); - //xi_i *= polyscale; // Add the scalar rand_base * xi_i to the scalars vector scalars[index] = rand_base.mul(xi_i); From d0dc4fb066be6580c0cc2ff9fa146a699949cdd5 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Thu, 4 Jan 2024 12:28:59 -0300 Subject: [PATCH 66/68] Reordering code in order to merge it --- eth_verifier/src/Verifier.sol | 116 ++++++++++++++++------------------ 1 file changed, 56 insertions(+), 60 deletions(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index 0b6a7a52..aa1f5df5 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -248,66 +248,6 @@ contract KimchiVerifier { } } - function final_verify(Scalar.FE[] memory public_inputs) public { - /* - Final verification: - 1. Combine commitments, compute final poly commitment (MSM) - 2. Combine evals - 3. Commit divisor and eval polynomials - 4. Compute numerator commitment - 5. Compute scaled quotient - 6. Check numerator == scaled_quotient - */ - /* - pub fn verify( - &self, - srs: &PairingSRS, // SRS - evaluations: &Vec>, // commitments to the polynomials - polyscale: G::ScalarField, // scaling factor for polynoms - elm: &[G::ScalarField], // vector of evaluation points - ) -> bool { - let poly_commitment = { - let mut scalars: Vec = Vec::new(); - let mut points = Vec::new(); - combine_commitments( - evaluations, - &mut scalars, - &mut points, - polyscale, - F::one(), // TODO: This is inefficient - ); - let scalars: Vec<_> = scalars.iter().map(|x| x.into_repr()).collect(); - - VariableBaseMSM::multi_scalar_mul(&points, &scalars) - }; - */ - /* - let evals = combine_evaluations(evaluations, polyscale); - let blinding_commitment = srs.full_srs.h.mul(self.blinding); - let divisor_commitment = srs - .verifier_srs - .commit_non_hiding(&divisor_polynomial(elm), 1, None) - .unshifted[0]; - */ - /* - let eval_commitment = srs - .full_srs - .commit_non_hiding(&eval_polynomial(elm, &evals), 1, None) - .unshifted[0] - .into_projective(); - let numerator_commitment = { poly_commitment - eval_commitment - blinding_commitment }; - */ - /* - let numerator = Pair::pairing( - numerator_commitment, - Pair::G2Affine::prime_subgroup_generator(), - ); - let scaled_quotient = Pair::pairing(self.quotient, divisor_commitment); - numerator == scaled_quotient - } - */ - } - /// The polynomial that evaluates to each of `evals` for the respective `elm`s. function eval_polynomial(Scalar.FE[] memory elm, Scalar.FE[] memory evals) public @@ -419,8 +359,64 @@ contract KimchiVerifier { 5. Commitment to linearized polynomial f 6. Chunked commitment of ft 7. List poly commitments for final verification + + Final verification: + 1. Combine commitments, compute final poly commitment (MSM) + 2. Combine evals + 3. Commit divisor and eval polynomials + 4. Compute numerator commitment + 5. Compute scaled quotient + 6. Check numerator == scaled_quotient */ + function final_verify(Scalar.FE[] memory public_inputs) public { + /* + pub fn verify( + &self, + srs: &PairingSRS, // SRS + evaluations: &Vec>, // commitments to the polynomials + polyscale: G::ScalarField, // scaling factor for polynoms + elm: &[G::ScalarField], // vector of evaluation points + ) -> bool { + let poly_commitment = { + let mut scalars: Vec = Vec::new(); + let mut points = Vec::new(); + combine_commitments( + evaluations, + &mut scalars, + &mut points, + polyscale, + F::one(), // TODO: This is inefficient + ); + let scalars: Vec<_> = scalars.iter().map(|x| x.into_repr()).collect(); + + VariableBaseMSM::multi_scalar_mul(&points, &scalars) + }; + + let evals = combine_evaluations(evaluations, polyscale); + let blinding_commitment = srs.full_srs.h.mul(self.blinding); + let divisor_commitment = srs + .verifier_srs + .commit_non_hiding(&divisor_polynomial(elm), 1, None) + .unshifted[0]; + + let eval_commitment = srs + .full_srs + .commit_non_hiding(&eval_polynomial(elm, &evals), 1, None) + .unshifted[0] + .into_projective(); + let numerator_commitment = { poly_commitment - eval_commitment - blinding_commitment }; + + let numerator = Pair::pairing( + numerator_commitment, + Pair::G2Affine::prime_subgroup_generator(), + ); + let scaled_quotient = Pair::pairing(self.quotient, divisor_commitment); + numerator == scaled_quotient + } + */ + } + /* TODO WIP function deserialize_proof( uint256[] calldata public_inputs, From 732eb8ef64cbf12cb413f1c78b99692010316b53 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Thu, 4 Jan 2024 12:32:58 -0300 Subject: [PATCH 67/68] fn name change --- eth_verifier/src/Verifier.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index aa1f5df5..d3ce3704 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -249,7 +249,7 @@ contract KimchiVerifier { } /// The polynomial that evaluates to each of `evals` for the respective `elm`s. - function eval_polynomial(Scalar.FE[] memory elm, Scalar.FE[] memory evals) + function evalPolynomial(Scalar.FE[] memory elm, Scalar.FE[] memory evals) public view returns (Polynomial.Dense memory) From 0afb5e5af0534e55b18be80aece10c16d3eadf20 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Thu, 4 Jan 2024 12:46:39 -0300 Subject: [PATCH 68/68] Remove unnecessary code comments --- eth_verifier/src/Verifier.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/eth_verifier/src/Verifier.sol b/eth_verifier/src/Verifier.sol index d3ce3704..688f847f 100644 --- a/eth_verifier/src/Verifier.sol +++ b/eth_verifier/src/Verifier.sol @@ -333,8 +333,6 @@ contract KimchiVerifier { // If the evaluation has a degree bound and a non-zero shifted commitment if (evaluations[i].degree_bound > 0 && evaluations[i].commitment.shifted.x != 0) { - //// polyscale^i sum_j evalscale^j elm_j^{N - m} f(elm_j) - // Add the scalar rand_base * xi_i to the scalars vector scalars[index] = rand_base.mul(xi_i); // Add the point to the points vector