diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a3e8ef7..20e18e0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,7 +41,7 @@ jobs: - name: Check proof verification status run: | - [[ $(cast call ${{steps.deployment.outputs.CONTRACT_ADDRESS}} "verify(uint32,uint256[],uint256[])(bool)" "3" "[1]" "[0]" --private-key $ANVIL_PRIVATE_KEY --rpc-url $ANVIL_URL) == true ]] && exit 0 || exit 1 + [[ $(cast call ${{steps.deployment.outputs.CONTRACT_ADDRESS}} "verify(uint32,uint256[],uint256[],bool)(bool)" "3" "[1]" "[0]" "true" --private-key $ANVIL_PRIVATE_KEY --rpc-url $ANVIL_URL) == true ]] && exit 0 || exit 1 unit-tests: strategy: diff --git a/src/NovaVerifierContract.sol b/src/NovaVerifierContract.sol index 02200db..64e45e1 100644 --- a/src/NovaVerifierContract.sol +++ b/src/NovaVerifierContract.sol @@ -2,14 +2,86 @@ pragma solidity ^0.8.16; import "@std/Test.sol"; +import "src/blocks/KeccakTranscript.sol"; +import "src/blocks/PolyEvalInstance.sol"; import "src/verifier/Step1.sol"; import "src/verifier/Step2.sol"; +import "src/verifier/Step3.sol"; import "src/NovaVerifierAbstractions.sol"; contract NovaVerifierContract { + struct IntermediateData { + Step3IntermediateData step3; + } + + struct Step3IntermediateData { + uint256[] tau; + uint256 gamma1; + uint256 gamma2; + uint256[] r_sat; + uint256[] U_X; + uint256 U_comm_W_x; + uint256 U_comm_W_y; + uint256 U_comm_E_x; + uint256 U_comm_E_y; + uint256 U_u; + PolyEvalInstanceLib.PolyEvalInstance u_vec_item_0; + } + + struct Step3PrecomputeOutput { + uint256[] tau; + PolyEvalInstanceLib.PolyEvalInstance u_step3; + uint256 c; + uint256[] rand_eq; + uint256[] coeffs; + uint256 U_u; + uint256[] U_X; + uint256 U_comm_W_x; + uint256 U_comm_W_y; + uint256 U_comm_E_x; + uint256 U_comm_E_y; + uint256 gamma1; + uint256 gamma2; + } + Abstractions.VerifierKey public vk; Abstractions.CompressedSnark public proof; + bool private printLogs; + + KeccakTranscriptLib.KeccakTranscript private transcriptPrimary; + KeccakTranscriptLib.KeccakTranscript private transcriptSecondary; + + function initialize() + private + pure + returns (KeccakTranscriptLib.KeccakTranscript memory, KeccakTranscriptLib.KeccakTranscript memory) + { + uint8[] memory init_input = new uint8[](16); // Rust's b"RelaxedR1CSSNARK" + init_input[0] = 0x52; + init_input[1] = 0x65; + init_input[2] = 0x6c; + init_input[3] = 0x61; + init_input[4] = 0x78; + init_input[5] = 0x65; + init_input[6] = 0x64; + init_input[7] = 0x52; + init_input[8] = 0x31; + init_input[9] = 0x43; + init_input[10] = 0x53; + init_input[11] = 0x53; + init_input[12] = 0x4e; + init_input[13] = 0x41; + init_input[14] = 0x52; + init_input[15] = 0x4b; + + KeccakTranscriptLib.KeccakTranscript memory transcriptPrimaryInstance = + KeccakTranscriptLib.instantiate(init_input); + KeccakTranscriptLib.KeccakTranscript memory transcriptSecondaryInstance = + KeccakTranscriptLib.instantiate(init_input); + return (transcriptPrimaryInstance, transcriptSecondaryInstance); + } + function pushToProof(Abstractions.CompressedSnark calldata input) public { proof = input; } @@ -18,11 +90,19 @@ contract NovaVerifierContract { vk = input; } - function verify(uint32 numSteps, uint256[] calldata z0_primary, uint256[] calldata z0_secondary) + function verify(uint32 numSteps, uint256[] calldata z0_primary, uint256[] calldata z0_secondary, bool enableLogs) public - view returns (bool) { + printLogs = enableLogs; + + (transcriptPrimary, transcriptSecondary) = initialize(); + + IntermediateData memory primaryData; + IntermediateData memory secondaryData; + + bool success; + // Step 1: // - checks that number of steps cannot be zero (https://github.com/lurk-lab/Nova/blob/solidity-verifier-pp-spartan/src/lib.rs#L680) // - checks if the (relaxed) R1CS instances have two public outputs (https://github.com/lurk-lab/Nova/blob/solidity-verifier-pp-spartan/src/lib.rs#L688) @@ -37,6 +117,334 @@ contract NovaVerifierContract { console.log("[Step2] false"); return false; } + + // Step 3: + // - folds the running instance and last instance to get a folded instance + // - checks the satisfiability of the folded instances using SNARKs proving the knowledge of their satisfying witnesses + // from: https://github.com/lurk-lab/Nova/blob/solidity-verifier-pp-spartan/src/spartan/ppsnark.rs#L1565 + + // Sumcheck protocol verification (secondary) part + (secondaryData, success) = verifyStep3Secondary(); + if (!success) { + console.log("[Step3 Secondary] false"); + return false; + } + + // Sumcheck protocol verification (primary) + (primaryData, success) = verifyStep3Primary(); + if (!success) { + console.log("[Step3 Primary] false"); + return false; + } + return true; } + + function verifyStep3Primary() private returns (IntermediateData memory, bool) { + Step3PrecomputeOutput memory precompute = verifyStep3PrecomputePrimary(); + + (uint256[] memory r_sat, bool success) = verifyStep3InnerPrimary(precompute); + + IntermediateData memory primary; + primary.step3 = Step3IntermediateData( + precompute.tau, + precompute.gamma1, + precompute.gamma2, + r_sat, + precompute.U_X, + precompute.U_comm_W_x, + precompute.U_comm_W_y, + precompute.U_comm_E_x, + precompute.U_comm_E_y, + precompute.U_u, + precompute.u_step3 + ); + + return (primary, success); + } + + function verifyStep3Secondary() private returns (IntermediateData memory, bool) { + Step3PrecomputeOutput memory precompute = verifyStep3PrecomputeSecondary(); + + (uint256[] memory r_sat, bool success) = verifyStep3InnerSecondary(precompute); + + IntermediateData memory secondary; + secondary.step3 = Step3IntermediateData( + precompute.tau, + precompute.gamma1, + precompute.gamma2, + r_sat, + precompute.U_X, + precompute.U_comm_W_x, + precompute.U_comm_W_y, + precompute.U_comm_E_x, + precompute.U_comm_E_y, + precompute.U_u, + precompute.u_step3 + ); + + return (secondary, success); + } + + function verifyStep3InnerPrimary(Step3PrecomputeOutput memory precompute) + private + returns (uint256[] memory, bool) + { + uint256 claim_sat_final; + uint256[] memory r_sat; + (claim_sat_final, r_sat, transcriptPrimary) = Step3Lib.compute_claim_sat_final_r_sat_primary( + proof.r_W_snark_primary, + vk.vk_primary, + transcriptPrimary, + precompute.u_step3.e, + precompute.coeffs, + Vesta.P_MOD, + printLogs + ); + + uint256 taus_bound_r_sat = EqPolinomialLib.evaluate(precompute.tau, r_sat, Vesta.P_MOD, Vesta.negateBase); + uint256 rand_eq_bound_r_sat = EqPolinomialLib.evaluate(precompute.rand_eq, r_sat, Vesta.P_MOD, Vesta.negateBase); + + if (printLogs) { + console.log("------------------[verifyStep3InnerPrimary]------------------"); + console.log("claim_sat_final"); + console.logBytes32(bytes32(claim_sat_final)); + console.log("r_sat"); + for (uint256 index = 0; index < r_sat.length; index++) { + console.logBytes32(bytes32(r_sat[index])); + } + console.log("taus_bound_r_sat"); + console.logBytes32(bytes32(taus_bound_r_sat)); + console.log("rand_eq_bound_r_sat"); + console.logBytes32(bytes32(rand_eq_bound_r_sat)); + } + + uint256 claim_inner_final = + Step3Lib.compute_claim_inner_final(proof.r_W_snark_primary, precompute.c, precompute.coeffs, Vesta.P_MOD); + + uint256 claim_mem_final = Step3Lib.compute_claim_mem_final( + proof.r_W_snark_primary, precompute.coeffs, rand_eq_bound_r_sat, Vesta.P_MOD, Vesta.negateBase + ); + + uint256 claim_outer_final = Step3Lib.compute_claim_outer_final( + proof.r_W_snark_primary, precompute.U_u, precompute.coeffs, taus_bound_r_sat, Vesta.P_MOD, Vesta.negateBase + ); + + return ( + r_sat, + Step3Lib.final_verification( + claim_mem_final, claim_outer_final, claim_inner_final, claim_sat_final, Vesta.P_MOD + ) + ); + } + + function verifyStep3InnerSecondary(Step3PrecomputeOutput memory precompute) + private + returns (uint256[] memory, bool) + { + uint256 claim_sat_final; + uint256[] memory r_sat; + (claim_sat_final, r_sat, transcriptSecondary) = Step3Lib.compute_claim_sat_final_r_sat_secondary( + proof.f_W_snark_secondary, + vk.vk_secondary, + transcriptSecondary, + precompute.u_step3.e, + precompute.coeffs, + Pallas.P_MOD, + printLogs + ); + + uint256 taus_bound_r_sat = EqPolinomialLib.evaluate(precompute.tau, r_sat, Pallas.P_MOD, Pallas.negateBase); + uint256 rand_eq_bound_r_sat = + EqPolinomialLib.evaluate(precompute.rand_eq, r_sat, Pallas.P_MOD, Pallas.negateBase); + + if (printLogs) { + console.log("------------------[verifyStep3InnerSecondary]------------------"); + console.log("claim_sat_final"); + console.logBytes32(bytes32(claim_sat_final)); + console.log("r_sat"); + for (uint256 index = 0; index < r_sat.length; index++) { + console.logBytes32(bytes32(r_sat[index])); + } + console.log("taus_bound_r_sat"); + console.logBytes32(bytes32(taus_bound_r_sat)); + console.log("rand_eq_bound_r_sat"); + console.logBytes32(bytes32(rand_eq_bound_r_sat)); + } + + uint256 claim_mem_final = Step3Lib.compute_claim_mem_final( + proof.f_W_snark_secondary, precompute.coeffs, rand_eq_bound_r_sat, Pallas.P_MOD, Pallas.negateBase + ); + + uint256 claim_outer_final = Step3Lib.compute_claim_outer_final( + proof.f_W_snark_secondary, + precompute.U_u, + precompute.coeffs, + taus_bound_r_sat, + Pallas.P_MOD, + Pallas.negateBase + ); + + uint256 claim_inner_final = + Step3Lib.compute_claim_inner_final(proof.f_W_snark_secondary, precompute.c, precompute.coeffs, Pallas.P_MOD); + + return ( + r_sat, + Step3Lib.final_verification( + claim_mem_final, claim_outer_final, claim_inner_final, claim_sat_final, Pallas.P_MOD + ) + ); + } + + function verifyStep3PrecomputePrimary() private returns (Step3PrecomputeOutput memory) { + Step3PrecomputeOutput memory precomputeOutput; + (transcriptPrimary, precomputeOutput.tau) = + Step3Lib.compute_tau_primary(proof, vk.vk_primary, transcriptPrimary, printLogs); + + (transcriptPrimary, precomputeOutput.c) = Step3Lib.compute_c_primary(proof.r_W_snark_primary, transcriptPrimary); + + precomputeOutput.u_step3 = + Step3Lib.compute_u_primary(proof.r_W_snark_primary, precomputeOutput.tau, precomputeOutput.c); + + (transcriptPrimary, precomputeOutput.gamma1) = Step3Lib.compute_gamma_1_primary(transcriptPrimary); + (transcriptPrimary, precomputeOutput.gamma2) = Step3Lib.compute_gamma_2_primary(transcriptPrimary); + + (transcriptPrimary, precomputeOutput.rand_eq) = + Step3Lib.compute_rand_eq_primary(proof.r_W_snark_primary, vk.vk_primary, transcriptPrimary); + + (transcriptPrimary, precomputeOutput.coeffs) = Step3Lib.compute_coeffs_primary(transcriptPrimary); + + precomputeOutput.U_u = proof.r_U_primary.u; + precomputeOutput.U_X = proof.r_U_primary.X; + Pallas.PallasAffinePoint memory U_comm_W = Pallas.decompress(proof.r_U_primary.comm_W); + Pallas.PallasAffinePoint memory U_comm_E = Pallas.decompress(proof.r_U_primary.comm_E); + precomputeOutput.U_comm_W_x = U_comm_W.x; + precomputeOutput.U_comm_W_y = U_comm_W.y; + precomputeOutput.U_comm_W_x = U_comm_E.x; + precomputeOutput.U_comm_W_y = U_comm_E.y; + + if (printLogs) { + uint256 index = 0; + console.log("------------------[verifyStep3PrecomputePrimary]------------------"); + console.log("proof.r_U_primary.comm_W"); + console.logBytes32(bytes32(proof.r_U_primary.comm_W)); + console.log("proof.r_U_primary.comm_E"); + console.logBytes32(bytes32(proof.r_U_primary.comm_E)); + console.log("proof.r_U_primary.X"); + for (index = 0; index < proof.r_U_primary.X.length; index++) { + console.logBytes32(bytes32(proof.r_U_primary.X[index])); + } + console.log("proof.r_U_primary.u"); + console.logBytes32(bytes32(proof.r_U_primary.u)); + console.log("tau"); + for (index = 0; index < precomputeOutput.tau.length; index++) { + console.logBytes32(bytes32(precomputeOutput.tau[index])); + } + console.log("c"); + console.logBytes32(bytes32(precomputeOutput.c)); + console.log("u_step3 c"); + console.logBytes32(bytes32(precomputeOutput.u_step3.c_x)); + console.logBytes32(bytes32(precomputeOutput.u_step3.c_y)); + console.log("u_step3 x"); + for (index = 0; index < precomputeOutput.u_step3.x.length; index++) { + console.logBytes32(bytes32(precomputeOutput.u_step3.x[index])); + } + console.log("u_step3 e"); + console.logBytes32(bytes32(precomputeOutput.u_step3.e)); + console.log("rand_eq"); + for (index = 0; index < precomputeOutput.rand_eq.length; index++) { + console.logBytes32(bytes32(precomputeOutput.rand_eq[index])); + } + + console.log("coeffs"); + for (index = 0; index < precomputeOutput.coeffs.length; index++) { + console.logBytes32(bytes32(precomputeOutput.coeffs[index])); + } + } + return precomputeOutput; + } + + function verifyStep3PrecomputeSecondary() private returns (Step3PrecomputeOutput memory) { + Step3PrecomputeOutput memory precomputeOutput; + + // f_U_secondary instance (RelaxedR1CSInstance with uncompressed commitments) + Vesta.VestaAffinePoint memory f_U_secondary_comm_W; + Vesta.VestaAffinePoint memory f_U_secondary_comm_E; + uint256[] memory f_U_secondary_X; + uint256 f_U_secondary_u; + + (f_U_secondary_comm_W, f_U_secondary_comm_E, f_U_secondary_X, f_U_secondary_u) = + Step3Lib.compute_f_U_secondary(proof, vk); + + (transcriptSecondary, precomputeOutput.tau) = Step3Lib.compute_tau_secondary( + proof, + vk.vk_secondary, + transcriptSecondary, + f_U_secondary_comm_W, + f_U_secondary_comm_E, + f_U_secondary_X, + f_U_secondary_u, + printLogs + ); + + (transcriptSecondary, precomputeOutput.c) = Step3Lib.compute_c_secondary(proof, transcriptSecondary); + + precomputeOutput.u_step3 = Step3Lib.compute_u_secondary(proof, precomputeOutput.tau, precomputeOutput.c); + + (transcriptSecondary, precomputeOutput.gamma1) = Step3Lib.compute_gamma_1_secondary(transcriptSecondary); + (transcriptSecondary, precomputeOutput.gamma2) = Step3Lib.compute_gamma_2_secondary(transcriptSecondary); + + (transcriptSecondary, precomputeOutput.rand_eq) = + Step3Lib.compute_rand_eq_secondary(proof, vk, transcriptSecondary); + + (transcriptSecondary, precomputeOutput.coeffs) = Step3Lib.compute_coeffs_secondary(transcriptSecondary); + + precomputeOutput.U_u = f_U_secondary_u; + precomputeOutput.U_X = f_U_secondary_X; + precomputeOutput.U_comm_W_x = f_U_secondary_comm_W.x; + precomputeOutput.U_comm_W_y = f_U_secondary_comm_W.y; + precomputeOutput.U_comm_E_x = f_U_secondary_comm_E.x; + precomputeOutput.U_comm_E_y = f_U_secondary_comm_E.y; + + if (printLogs) { + uint256 index = 0; + console.log("------------------[verifyStep3PrecomputeSecondary]------------------"); + console.log("f_U_secondary_comm_W"); + console.logBytes32(bytes32(f_U_secondary_comm_W.x)); + console.logBytes32(bytes32(f_U_secondary_comm_W.y)); + console.log("f_U_secondary_comm_E"); + console.logBytes32(bytes32(f_U_secondary_comm_E.x)); + console.logBytes32(bytes32(f_U_secondary_comm_E.y)); + console.log("f_U_secondary_X"); + for (index = 0; index < f_U_secondary_X.length; index++) { + console.logBytes32(bytes32(f_U_secondary_X[index])); + } + console.log("f_U_secondary_u"); + console.logBytes32(bytes32(f_U_secondary_u)); + console.log("tau"); + for (index = 0; index < precomputeOutput.tau.length; index++) { + console.logBytes32(bytes32(precomputeOutput.tau[index])); + } + console.log("c"); + console.logBytes32(bytes32(precomputeOutput.c)); + console.log("u_step3 c"); + console.logBytes32(bytes32(precomputeOutput.u_step3.c_x)); + console.logBytes32(bytes32(precomputeOutput.u_step3.c_y)); + console.log("u_step3 x"); + for (index = 0; index < precomputeOutput.u_step3.x.length; index++) { + console.logBytes32(bytes32(precomputeOutput.u_step3.x[index])); + } + console.log("u_step3 e"); + console.logBytes32(bytes32(precomputeOutput.u_step3.e)); + console.log("rand_eq"); + for (index = 0; index < precomputeOutput.rand_eq.length; index++) { + console.logBytes32(bytes32(precomputeOutput.rand_eq[index])); + } + console.log("coeffs"); + for (index = 0; index < precomputeOutput.coeffs.length; index++) { + console.logBytes32(bytes32(precomputeOutput.coeffs[index])); + } + } + return precomputeOutput; + } } diff --git a/src/blocks/EqPolynomial.sol b/src/blocks/EqPolynomial.sol index 061e62d..66de1d3 100644 --- a/src/blocks/EqPolynomial.sol +++ b/src/blocks/EqPolynomial.sol @@ -5,53 +5,14 @@ import "src/blocks/pasta/Vesta.sol"; import "src/blocks/pasta/Pallas.sol"; library EqPolinomialLib { - function evaluateVesta(uint256[] memory r, uint256[] memory rx) public pure returns (uint256) { - require(r.length == rx.length, "[EqPolinomialLib.evaluateVesta] wrong input data length"); - - uint256 modulusVesta = Vesta.P_MOD; - - uint256 resultIter = 0; - uint256 rx_inner = 0; - uint256 r_inner = 0; - uint256 tmp1 = 0; - uint256 tmp2 = 0; - uint256 tmp3 = 0; - uint256 tmp4 = 0; - uint256 minus_rx = 0; - uint256 minus_r = 0; - - uint256 result = 1; - for (uint256 i = 0; i < rx.length; i++) { - rx_inner = rx[i]; - r_inner = r[i]; - minus_rx = Vesta.negateBase(rx_inner); // Vesta - minus_r = Vesta.negateBase(r_inner); // Vesta - assembly { - // rx[i] * r[i] - tmp1 := mulmod(rx_inner, r_inner, modulusVesta) // Vesta - // 1 - rx[i] - tmp2 := addmod(1, minus_rx, modulusVesta) // Vesta - // 1 - r[i] - tmp3 := addmod(1, minus_r, modulusVesta) // Vesta - - // tmp1 + tmp2 * tmp3 - tmp4 := addmod(tmp1, mulmod(tmp2, tmp3, modulusVesta), modulusVesta) // Vesta - - // accumulate result - resultIter := mulmod(tmp4, result, modulusVesta) // Vesta - - result := resultIter - } - } - - return result; - } - - function evaluatePallas(uint256[] memory r, uint256[] memory rx) public pure returns (uint256) { + function evaluate( + uint256[] memory r, + uint256[] memory rx, + uint256 modulus, + function (uint256) returns (uint256) negateBase + ) internal returns (uint256) { require(r.length == rx.length, "[EqPolinomialLib.evaluatePallas] wrong input data length"); - uint256 modulusPallas = Pallas.P_MOD; - uint256 resultIter = 0; uint256 rx_inner = 0; uint256 r_inner = 0; @@ -66,21 +27,21 @@ library EqPolinomialLib { for (uint256 i = 0; i < rx.length; i++) { rx_inner = rx[i]; r_inner = r[i]; - minus_rx = Pallas.negateBase(rx_inner); // Pallas - minus_r = Pallas.negateBase(r_inner); // Pallas + minus_rx = negateBase(rx_inner); + minus_r = negateBase(r_inner); assembly { // rx[i] * r[i] - tmp1 := mulmod(rx_inner, r_inner, modulusPallas) // Pallas + tmp1 := mulmod(rx_inner, r_inner, modulus) // 1 - rx[i] - tmp2 := addmod(1, minus_rx, modulusPallas) // Pallas + tmp2 := addmod(1, minus_rx, modulus) // 1 - r[i] - tmp3 := addmod(1, minus_r, modulusPallas) // Pallas + tmp3 := addmod(1, minus_r, modulus) // tmp1 + tmp2 * tmp3 - tmp4 := addmod(tmp1, mulmod(tmp2, tmp3, modulusPallas), modulusPallas) // Pallas + tmp4 := addmod(tmp1, mulmod(tmp2, tmp3, modulus), modulus) // accumulate result - resultIter := mulmod(tmp4, result, modulusPallas) // Pallas + resultIter := mulmod(tmp4, result, modulus) result := resultIter } @@ -89,47 +50,14 @@ library EqPolinomialLib { return result; } - function evalsVesta(uint256[] memory r) public pure returns (uint256[] memory) { + function evals(uint256[] memory r, uint256 modulus, function (uint256) returns (uint256) negateBase) + internal + returns (uint256[] memory) + { uint256[] memory evalsResult = new uint256[](2 ** r.length); uint256 size = 1; evalsResult[0] = 1; - uint256 modulusVesta = Vesta.P_MOD; - - uint256 r_i = 0; - uint256 x = 0; - uint256 y = 0; - uint256 minus_y = 0; - for (uint256 i = 0; i < r.length; i++) { - r_i = r[r.length - i - 1]; - for (uint256 j = 0; j < size; j++) { - x = evalsResult[j]; - y = evalsResult[j + size]; - assembly { - y := mulmod(x, r_i, modulusVesta) // Vesta - } - - minus_y = Vesta.negateBase(y); // Vesta - - assembly { - x := addmod(x, minus_y, modulusVesta) // Vesta - } - - evalsResult[j] = x; - evalsResult[j + size] = y; - } - size *= 2; - } - return evalsResult; - } - - function evalsPallas(uint256[] memory r) public pure returns (uint256[] memory) { - uint256[] memory evalsResult = new uint256[](2 ** r.length); - uint256 size = 1; - evalsResult[0] = 1; - - uint256 modulusPallas = Pallas.P_MOD; - uint256 r_i = 0; uint256 x = 0; uint256 y = 0; @@ -140,13 +68,13 @@ library EqPolinomialLib { x = evalsResult[j]; y = evalsResult[j + size]; assembly { - y := mulmod(x, r_i, modulusPallas) // Pallas + y := mulmod(x, r_i, modulus) } - minus_y = Pallas.negateBase(y); // Pallas + minus_y = negateBase(y); assembly { - x := addmod(x, minus_y, modulusPallas) // Pallas + x := addmod(x, minus_y, modulus) } evalsResult[j] = x; diff --git a/src/verifier/step4/KeccakTranscript.sol b/src/blocks/KeccakTranscript.sol similarity index 74% rename from src/verifier/step4/KeccakTranscript.sol rename to src/blocks/KeccakTranscript.sol index e58ea4e..b332a89 100644 --- a/src/verifier/step4/KeccakTranscript.sol +++ b/src/blocks/KeccakTranscript.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.16; import "src/blocks/pasta/Vesta.sol"; import "src/blocks/pasta/Pallas.sol"; +import "src/NovaVerifierAbstractions.sol"; import "src/Utilities.sol"; library ScalarFromUniformLib { @@ -427,7 +428,7 @@ library KeccakTranscriptLib { uint8[] memory input_bytes = new uint8[](32); for (uint256 i = 0; i < 32; i++) { - input_bytes[i] = uint8(bytes32(input)[31 - i]); + input_bytes[i] = uint8(bytes1(bytes32(input)[31 - i])); } return input_bytes; @@ -470,6 +471,37 @@ library KeccakTranscriptLib { return absorb(keccak, label, input); } + function absorb(KeccakTranscript memory keccak, uint8[] memory label, Pallas.PallasAffinePoint[] memory points) + public + pure + returns (KeccakTranscript memory) + { + uint8[] memory output = new uint8[]((32 * 2 + 1) * points.length); + uint256 index = 0; + for (uint256 j = 0; j < points.length; j++) { + // write x coordinate + for (uint256 i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(points[j].x)[31 - i])); + index++; + } + // write y coordinate + for (uint256 i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(points[j].y)[31 - i])); + index++; + } + + // write byte indicating whether point is at infinity + if (Pallas.isInfinity(points[j])) { + output[index] = 0x00; + } else { + output[index] = 0x01; + } + index++; + } + + return absorb(keccak, label, output); + } + function absorb(KeccakTranscript memory keccak, uint8[] memory label, Vesta.VestaAffinePoint memory point) public pure @@ -498,6 +530,37 @@ library KeccakTranscriptLib { return absorb(keccak, label, input); } + function absorb(KeccakTranscript memory keccak, uint8[] memory label, Vesta.VestaAffinePoint[] memory points) + public + pure + returns (KeccakTranscript memory) + { + uint8[] memory output = new uint8[]((32 * 2 + 1) * points.length); + uint256 index = 0; + for (uint256 j = 0; j < points.length; j++) { + // write x coordinate + for (uint256 i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(points[j].x)[31 - i])); + index++; + } + // write y coordinate + for (uint256 i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(points[j].y)[31 - i])); + index++; + } + + // write byte indicating whether point is at infinity + if (Vesta.isInfinity(points[j])) { + output[index] = 0x00; + } else { + output[index] = 0x01; + } + index++; + } + + return absorb(keccak, label, output); + } + function absorb(KeccakTranscript memory keccak, uint8[] memory label, uint256[] memory inputs) public pure @@ -524,6 +587,177 @@ library KeccakTranscriptLib { return absorb(keccak, label, PolyLib.toTranscriptBytes(poly)); } + function absorb( + KeccakTranscript memory keccak, + uint8[] memory label, + Vesta.VestaAffinePoint memory comm_W, + Vesta.VestaAffinePoint memory comm_E, + uint256[] memory X, + uint256 u + ) public pure returns (KeccakTranscript memory) { + // comm_W: 32 (X) + 32 (Y) + 1 (1 byte indicating whether comm_W is point at infinity) + // comm_E: 32 (X) + 32 (Y) + 1 (1 byte indicating whether comm_E is point at infinity) + // u: 32 + // X: 32 * len(X) + uint8[] memory output = new uint8[](32 * 2 + 1 + 32 * 2 + 1 + 32 * X.length + 32); + + uint256 i = 0; + uint256 index = 0; + uint256 val; + + // write comm_W.x + val = comm_W.x; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + // write comm_W.y + val = comm_W.y; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + // write byte indicating whether comm_W is point at infinity + if (Vesta.isInfinity(comm_W)) { + output[index] = 0x00; + } else { + output[index] = 0x01; + } + index++; + + // write comm_E.x + val = comm_E.x; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + // write comm_E.y + val = comm_E.y; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + + // write byte indicating whether comm_E is point at infinity + if (Vesta.isInfinity(comm_E)) { + output[index] = 0x00; + } else { + output[index] = 0x01; + } + index++; + + // write u + val = u; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + + // write X + for (i = 0; i < X.length; i++) { + val = X[i]; + for (uint256 j = 0; j < 32; j++) { + output[index] = uint8(bytes1(bytes32(val)[31 - j])); + index++; + } + } + + require(index == output.length, "[KeccakTranscript::absorb(RelaxedR1CSInstance, Vesta)] unexpected length"); + + return absorb(keccak, label, output); + } + + function absorb( + KeccakTranscript memory keccak, + uint8[] memory label, + Pallas.PallasAffinePoint memory comm_W, + Pallas.PallasAffinePoint memory comm_E, + uint256[] memory X, + uint256 u + ) public pure returns (KeccakTranscript memory) { + // comm_W: 32 (X) + 32 (Y) + 1 (1 byte indicating whether comm_W is point at infinity) + // comm_E: 32 (X) + 32 (Y) + 1 (1 byte indicating whether comm_E is point at infinity) + // u: 32 + // X: 32 * len(X) + uint8[] memory output = new uint8[](32 * 2 + 1 + 32 * 2 + 1 + 32 * X.length + 32); + + uint256 i = 0; + uint256 index = 0; + uint256 val; + + // write comm_W.x + val = comm_W.x; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + // write comm_W.y + val = comm_W.y; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + // write byte indicating whether comm_W is point at infinity + if (Pallas.isInfinity(comm_W)) { + output[index] = 0x00; + } else { + output[index] = 0x01; + } + index++; + + // write comm_E.x + val = comm_E.x; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + // write comm_E.y + val = comm_E.y; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + + // write byte indicating whether comm_E is point at infinity + if (Pallas.isInfinity(comm_E)) { + output[index] = 0x00; + } else { + output[index] = 0x01; + } + index++; + + // write u + val = u; + for (i = 0; i < 32; i++) { + output[index] = uint8(bytes1(bytes32(val)[31 - i])); + index++; + } + + // write X + for (i = 0; i < X.length; i++) { + val = X[i]; + for (uint256 j = 0; j < 32; j++) { + output[index] = uint8(bytes1(bytes32(val)[31 - j])); + index++; + } + } + + require(index == output.length, "[KeccakTranscript::absorb(RelaxedR1CSInstance, Pallas)] unexpected length"); + + return absorb(keccak, label, output); + } + + function absorb(KeccakTranscript memory keccak, uint8[] memory label, Abstractions.RelaxedR1CSInstance memory U) + public + view + returns (KeccakTranscript memory) + { + Pallas.PallasAffinePoint memory comm_W = Pallas.decompress(U.comm_W); + Pallas.PallasAffinePoint memory comm_E = Pallas.decompress(U.comm_E); + + return absorb(keccak, label, comm_W, comm_E, U.X, U.u); + } + function squeeze(KeccakTranscript memory keccak, ScalarFromUniformLib.Curve curve, uint8[] memory label) public pure @@ -533,6 +767,12 @@ library KeccakTranscriptLib { uint256 index = 0; + // copy transcript + for (uint256 i = 0; i < keccak.transcript.length; i++) { + input[index + i] = keccak.transcript[i]; + } + index += keccak.transcript.length; + // copy DOM_SEP_TAG input[index] = uint8((DOM_SEP_TAG >> 24) & 0xFF); input[index + 1] = uint8((DOM_SEP_TAG >> 16) & 0xFF); @@ -551,12 +791,6 @@ library KeccakTranscriptLib { } index += keccak.state.length; - // copy transcript - for (uint256 i = 0; i < keccak.transcript.length; i++) { - input[index + i] = keccak.transcript[i]; - } - index += keccak.transcript.length; - // append label for (uint256 i = 0; i < label.length; i++) { input[index + i] = label[i]; diff --git a/src/blocks/PolyEvalInstance.sol b/src/blocks/PolyEvalInstance.sol new file mode 100644 index 0000000..48b4983 --- /dev/null +++ b/src/blocks/PolyEvalInstance.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.16; + +import "@std/Test.sol"; +import "src/blocks/pasta/Vesta.sol"; +import "src/blocks/pasta/Pallas.sol"; +import "src/Utilities.sol"; + +library PolyEvalInstanceLib { + struct PolyEvalInstance { + // c is an affine point + uint256 c_x; + uint256 c_y; + uint256[] x; + uint256 e; + } + + function pad(PolyEvalInstance[] memory p) public pure returns (PolyEvalInstance[] memory) { + uint256 j; + uint256 i; + uint256 x_length_max; + for (i = 0; i < p.length; i++) { + if (p[i].x.length > x_length_max) { + x_length_max = p[i].x.length; + } + } + + uint256[] memory x = new uint256[](x_length_max); + for (i = 0; i < p.length; i++) { + if (p[i].x.length < x_length_max) { + x = new uint256[](x_length_max); + for (j = x_length_max - p[i].x.length; j < x_length_max; j++) { + x[j] = p[i].x[j - (x_length_max - p[i].x.length)]; + } + p[i].x = x; + } + } + + return p; + } + + function batchPrimary( + Pallas.PallasAffinePoint[] memory comm_vec, + uint256[] memory x, + uint256[] memory eval_vec, + uint256 s + ) public view returns (PolyEvalInstance memory) { + require( + comm_vec.length == eval_vec.length, "[PolyEvalInstanceLib.batchPrimary]: comm_vec.length != eval_vec.length" + ); + + uint256[] memory powers_of_s = CommonUtilities.powers(s, comm_vec.length, Pallas.R_MOD); + uint256 e; + for (uint256 index = 0; index < eval_vec.length; index++) { + e = addmod(e, mulmod(powers_of_s[index], eval_vec[index], Pallas.R_MOD), Pallas.R_MOD); + } + + Pallas.PallasAffinePoint memory c_out = Pallas.PallasAffinePoint(0, 0); + Pallas.PallasAffinePoint memory temp = Pallas.PallasAffinePoint(0, 0); + for (uint256 index = 0; index < comm_vec.length; index++) { + temp = Pallas.scalarMul(comm_vec[index], powers_of_s[index]); + + c_out = Pallas.add(temp, c_out); + } + // x is just a copy of input + return PolyEvalInstance(c_out.x, c_out.y, x, e); + } + + function batchSecondary( + Vesta.VestaAffinePoint[] memory comm_vec, + uint256[] memory x, + uint256[] memory eval_vec, + uint256 s + ) public view returns (PolyEvalInstance memory) { + require( + comm_vec.length == eval_vec.length, + "[PolyEvalInstanceLib.batchSecondary]: comm_vec.length != eval_vec.length" + ); + + uint256[] memory powers_of_s = CommonUtilities.powers(s, comm_vec.length, Vesta.R_MOD); + + uint256 e; + for (uint256 index = 0; index < eval_vec.length; index++) { + e = addmod(e, mulmod(powers_of_s[index], eval_vec[index], Vesta.R_MOD), Vesta.R_MOD); + } + + Vesta.VestaAffinePoint memory c_out = Vesta.VestaAffinePoint(0, 0); + Vesta.VestaAffinePoint memory temp = Vesta.VestaAffinePoint(0, 0); + for (uint256 index = 0; index < comm_vec.length; index++) { + temp = Vesta.scalarMul(comm_vec[index], powers_of_s[index]); + + c_out = Vesta.add(temp, c_out); + } + + // x is just a copy of input + return PolyEvalInstance(c_out.x, c_out.y, x, e); + } +} diff --git a/src/verifier/step4/SumcheckLogic.sol b/src/blocks/Sumcheck.sol similarity index 98% rename from src/verifier/step4/SumcheckLogic.sol rename to src/blocks/Sumcheck.sol index 1a61df6..cd11e36 100644 --- a/src/verifier/step4/SumcheckLogic.sol +++ b/src/blocks/Sumcheck.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.16; import "src/blocks/pasta/Pallas.sol"; import "src/blocks/pasta/Vesta.sol"; -import "src/verifier/step4/KeccakTranscript.sol"; +import "src/blocks/KeccakTranscript.sol"; import "src/blocks/EqPolynomial.sol"; import "src/Utilities.sol"; @@ -40,7 +40,6 @@ library PrimarySumcheck { uint256 r_i; label[0] = 99; // c_label[0] = 99; (transcript, r_i) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curveVesta(), label); - r[i] = r_i; e = PolyLib.evaluate(poly, r_i, Pallas.R_MOD); @@ -87,7 +86,6 @@ library SecondarySumcheck { uint256 r_i; label[0] = 99; // c_label[0] = 99; (transcript, r_i) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); - r[i] = r_i; e = PolyLib.evaluate(poly, r_i, Vesta.R_MOD); diff --git a/src/verifier/Step3.sol b/src/verifier/Step3.sol new file mode 100644 index 0000000..06af186 --- /dev/null +++ b/src/verifier/Step3.sol @@ -0,0 +1,788 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.16; + +import "@std/Test.sol"; +import "src/blocks/pasta/Pallas.sol"; +import "src/blocks/pasta/Vesta.sol"; +import "src/blocks/poseidon/Sponge.sol"; +import "src/blocks/KeccakTranscript.sol"; +import "src/blocks/Sumcheck.sol"; +import "src/NovaVerifierAbstractions.sol"; +import "src/blocks/PolyEvalInstance.sol"; + +library Step3Lib { + uint32 private constant NUM_FE_FOR_RO = 24; + + function final_verification( + uint256 claim_mem_final_expected, + uint256 claim_outer_final_expected, + uint256 claim_inner_final_expected, + uint256 claim_sat_final, + uint256 modulus + ) public view returns (bool) { + uint256 actual = addmod( + addmod(claim_mem_final_expected, claim_outer_final_expected, modulus), claim_inner_final_expected, modulus + ); + + if (actual != claim_sat_final) { + console.log("------------------[Step3Lib::final_verification]------------------"); + console.log("claim_sat_final [expected]"); + console.logBytes32(bytes32(claim_sat_final)); + console.log("claim_sat_final [actual]"); + console.logBytes32(bytes32(actual)); + console.log("-------------------------------------------------"); + + console.log("claim_mem_final"); + console.logBytes32(bytes32(claim_mem_final_expected)); + + console.log("claim_outer_final"); + console.logBytes32(bytes32(claim_outer_final_expected)); + + console.log("claim_inner_final"); + console.logBytes32(bytes32(claim_inner_final_expected)); + + return false; + } + + return true; + } + + function compute_claim_inner_final( + Abstractions.RelaxedR1CSSNARK calldata proof, + uint256 c_inner, + uint256[] memory coeffs, + uint256 modulus + ) public view returns (uint256) { + if (coeffs.length < 10) { + console.log("[Step3Lib:compute_claim_inner_final] coeffs.len < 10"); + revert(); + } + + uint256 self_eval_val_A = proof.eval_val_A; + uint256 self_eval_val_B = proof.eval_val_B; + uint256 self_eval_val_C = proof.eval_val_C; + uint256 self_eval_E_col = proof.eval_E_col; + uint256 self_eval_E_row = proof.eval_E_row; + uint256 coeffs_9 = coeffs[9]; + + uint256 actual; + assembly { + let tmp := mulmod(c_inner, c_inner, modulus) + tmp := mulmod(tmp, self_eval_val_C, modulus) + tmp := addmod(tmp, self_eval_val_A, modulus) + actual := mulmod(c_inner, self_eval_val_B, modulus) + actual := addmod(actual, tmp, modulus) + actual := mulmod(actual, self_eval_E_col, modulus) + actual := mulmod(actual, self_eval_E_row, modulus) + actual := mulmod(actual, coeffs_9, modulus) + } + + return actual; + } + + function compute_claim_outer_final( + Abstractions.RelaxedR1CSSNARK storage proof, + uint256 r_U_primary_u, + uint256[] memory coeffs, + uint256 taus_bound_r_sat, + uint256 modulus, + function (uint256) returns (uint256) negateBase + ) internal returns (uint256) { + if (coeffs.length < 9) { + console.log("[Step3Lib:compute_claim_outer_final] coeffs.len < 9"); + revert(); + } + + uint256 actual = mulmod(r_U_primary_u, proof.eval_Cz, modulus); + actual = negateBase(actual); + uint256 minus_self_eval_E = negateBase(proof.eval_E); + uint256 coeffs_8 = coeffs[8]; + uint256 self_eval_Az = proof.eval_Az; + uint256 self_eval_Bz = proof.eval_Bz; + assembly { + let tmp := mulmod(self_eval_Az, self_eval_Bz, modulus) + tmp := addmod(tmp, minus_self_eval_E, modulus) + actual := addmod(actual, tmp, modulus) + actual := mulmod(actual, taus_bound_r_sat, modulus) + actual := mulmod(actual, coeffs_8, modulus) + } + return actual; + } + + function compute_claim_mem_final( + Abstractions.RelaxedR1CSSNARK storage proof, + uint256[] memory coeffs, + uint256 rand_eq_bound_r_sat, + uint256 modulus, + function (uint256) returns (uint256) negateBase + ) internal returns (uint256) { + uint256 len = 8; + if (coeffs.length < len) { + console.log("[Step3Lib:compute_claim_mem_final_expected] coeffs.length < len"); + revert(); + } + + if (proof.eval_left_arr.length != len) { + console.log( + "[Step3Lib:compute_claim_mem_final_expected] proof.f_W_snark_secondary.eval_left_arr.length != len" + ); + revert(); + } + if (proof.eval_right_arr.length != len) { + console.log( + "[Step3Lib:compute_claim_mem_final_expected] proof.f_W_snark_secondary.eval_right_arr.length != len" + ); + revert(); + } + if (proof.eval_output_arr.length != len) { + console.log( + "[Step3Lib:compute_claim_mem_final_expected] proof.f_W_snark_secondary.eval_output_arr.length != len" + ); + revert(); + } + + uint256 actual; + + uint256 coeffs_item; + uint256 eval_left_arr_item; + uint256 eval_right_arr_item; + + uint256 tmp; + for (uint256 index = 0; index < len; index++) { + coeffs_item = coeffs[index]; + eval_left_arr_item = proof.eval_left_arr[index]; + eval_right_arr_item = proof.eval_right_arr[index]; + tmp = negateBase(proof.eval_output_arr[index]); + assembly { + let tmp1 := mulmod(eval_left_arr_item, eval_right_arr_item, modulus) + tmp1 := addmod(tmp1, tmp, modulus) + tmp1 := mulmod(tmp1, rand_eq_bound_r_sat, modulus) + tmp1 := mulmod(tmp1, coeffs_item, modulus) + actual := addmod(actual, tmp1, modulus) + } + } + + return actual; + } + + function compute_sumcheck_claim(uint256 claim_inner, uint256[] memory coeffs, uint256 p_modulus) + private + pure + returns (uint256) + { + return mulmod(coeffs[9], claim_inner, p_modulus); + } + + function extract_sumcheck_proof(Abstractions.SumcheckProof calldata proof) + internal + pure + returns (PolyLib.SumcheckProof memory) + { + // TODO: simplify conversions between abstractions + Abstractions.CompressedPolys[] memory polys = proof.compressed_polys; + PolyLib.CompressedUniPoly[] memory compressed_polys = new PolyLib.CompressedUniPoly[](polys.length); + uint256 index = 0; + for (index = 0; index < polys.length; index++) { + compressed_polys[index] = PolyLib.CompressedUniPoly(polys[index].coeffs_except_linear_term); + } + return PolyLib.SumcheckProof(compressed_polys); + } + + function compute_claim_sat_final_r_sat_primary( + Abstractions.RelaxedR1CSSNARK calldata proof, + Abstractions.VerifierKeyS1 calldata vk, + KeccakTranscriptLib.KeccakTranscript memory transcript, + uint256 claim_inner, + uint256[] memory coeffs, + uint256 p_modulus, + bool enableLogging + ) public view returns (uint256, uint256[] memory, KeccakTranscriptLib.KeccakTranscript memory) { + PolyLib.SumcheckProof memory sumcheckProof = extract_sumcheck_proof(proof.sc_sat); + + if (enableLogging) { + console.log("-----------compute_claim_sat_final_r_sat_primary------------"); + console.log("CompressedUniPoly"); + for (uint256 index = 0; index < sumcheckProof.compressed_polys.length; index++) { + console.log(index); + for (uint256 i = 0; i < sumcheckProof.compressed_polys[index].coeffs_except_linear_term.length; i++) { + console.logBytes32(bytes32(sumcheckProof.compressed_polys[index].coeffs_except_linear_term[i])); + } + } + } + + // degreeBound is hardcoded to 3 in Rust + return PrimarySumcheck.verify( + sumcheckProof, + compute_sumcheck_claim(claim_inner, coeffs, p_modulus), + CommonUtilities.log2(vk.S_comm.N), + 3, + transcript + ); + } + + function compute_claim_sat_final_r_sat_secondary( + Abstractions.RelaxedR1CSSNARK calldata proof, + Abstractions.VerifierKeyS2 calldata vk, + KeccakTranscriptLib.KeccakTranscript memory transcript, + uint256 claim_inner, + uint256[] memory coeffs, + uint256 p_modulus, + bool enableLogging + ) public view returns (uint256, uint256[] memory, KeccakTranscriptLib.KeccakTranscript memory) { + PolyLib.SumcheckProof memory sumcheckProof = extract_sumcheck_proof(proof.sc_sat); + + if (enableLogging) { + console.log("-----------compute_claim_sat_final_r_sat_secondary------------"); + console.log("CompressedUniPoly"); + for (uint256 index = 0; index < sumcheckProof.compressed_polys.length; index++) { + console.log(index); + for (uint256 i = 0; i < sumcheckProof.compressed_polys[index].coeffs_except_linear_term.length; i++) { + console.logBytes32(bytes32(sumcheckProof.compressed_polys[index].coeffs_except_linear_term[i])); + } + } + } + + // degreeBound is hardcoded to 3 in Rust + return SecondarySumcheck.verify( + sumcheckProof, + compute_sumcheck_claim(claim_inner, coeffs, p_modulus), + CommonUtilities.log2(vk.S_comm.N), + 3, + transcript + ); + } + + function compute_coeffs_primary(KeccakTranscriptLib.KeccakTranscript memory transcript) + public + pure + returns (KeccakTranscriptLib.KeccakTranscript memory, uint256[] memory) + { + uint8[] memory label = new uint8[](1); + label[0] = 0x72; // Rust's b"r" + + // in Rust length of coeffs is hardcoded to 10 + uint256[] memory coeffs = new uint256[](10); + (transcript, coeffs[0]) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curveVesta(), label); + + for (uint256 index = 1; index < coeffs.length; index++) { + coeffs[index] = mulmod(coeffs[index - 1], coeffs[0], Vesta.P_MOD); + } + return (transcript, coeffs); + } + + function compute_coeffs_secondary(KeccakTranscriptLib.KeccakTranscript memory transcript) + public + pure + returns (KeccakTranscriptLib.KeccakTranscript memory, uint256[] memory) + { + uint8[] memory label = new uint8[](1); + label[0] = 0x72; // Rust's b"r" + + // in Rust length of coeffs is hardcoded to 10 + uint256[] memory coeffs = new uint256[](10); + (transcript, coeffs[0]) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + + for (uint256 index = 1; index < coeffs.length; index++) { + coeffs[index] = mulmod(coeffs[index - 1], coeffs[0], Pallas.P_MOD); + } + return (transcript, coeffs); + } + + function compute_rand_eq_primary( + Abstractions.RelaxedR1CSSNARK calldata proof, + Abstractions.VerifierKeyS1 calldata vk, + KeccakTranscriptLib.KeccakTranscript memory transcript + ) public view returns (KeccakTranscriptLib.KeccakTranscript memory, uint256[] memory) { + uint256[] memory claims_product_arr = proof.claims_product_arr; + require(claims_product_arr.length == 8, "[Step3.compute_rand_eq_primary]: claims_product_arr.length != 8"); + + uint256[] memory comm_output_arr = proof.comm_output_arr; + require(comm_output_arr.length == 8, "[Step3.compute_rand_eq_primary]: comm_output_arr.length != 8"); + + Pallas.PallasAffinePoint[] memory comm_output_vec = new Pallas.PallasAffinePoint[](comm_output_arr.length); + uint256 index; + for (index = 0; index < comm_output_vec.length; index++) { + comm_output_vec[index] = Pallas.decompress(comm_output_arr[index]); + } + + uint8[] memory label = new uint8[](1); + label[0] = 0x6f; // Rust's b"o" + + transcript = KeccakTranscriptLib.absorb(transcript, label, comm_output_vec); + + label[0] = 0x63; // Rust's b"c" + + transcript = KeccakTranscriptLib.absorb(transcript, label, claims_product_arr); + + uint256 num_rounds = CommonUtilities.log2(vk.S_comm.N); + + label[0] = 0x65; // Rust's b"e" + uint256[] memory rand_eq = new uint256[](num_rounds); + for (index = 0; index < num_rounds; index++) { + (transcript, rand_eq[index]) = + KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curveVesta(), label); + } + + return (transcript, rand_eq); + } + + function compute_rand_eq_secondary( + Abstractions.CompressedSnark calldata proof, + Abstractions.VerifierKey calldata vk, + KeccakTranscriptLib.KeccakTranscript memory transcript + ) public view returns (KeccakTranscriptLib.KeccakTranscript memory, uint256[] memory) { + uint256[] memory claims_product_arr = proof.f_W_snark_secondary.claims_product_arr; + require(claims_product_arr.length == 8, "[Step3.compute_rand_eq]: claims_product_arr.length != 8"); + + uint256[] memory comm_output_arr = proof.f_W_snark_secondary.comm_output_arr; + require(comm_output_arr.length == 8, "[Step3.compute_rand_eq]: comm_output_arr.length != 8"); + + Vesta.VestaAffinePoint[] memory comm_output_vec = new Vesta.VestaAffinePoint[](comm_output_arr.length); + uint256 index; + for (index = 0; index < comm_output_vec.length; index++) { + comm_output_vec[index] = Vesta.decompress(comm_output_arr[index]); + } + + uint8[] memory label = new uint8[](1); + label[0] = 0x6f; // Rust's b"o" + + transcript = KeccakTranscriptLib.absorb(transcript, label, comm_output_vec); + + label[0] = 0x63; // Rust's b"c" + + transcript = KeccakTranscriptLib.absorb(transcript, label, claims_product_arr); + + uint256 num_rounds = CommonUtilities.log2(vk.vk_secondary.S_comm.N); + + label[0] = 0x65; // Rust's b"e" + uint256[] memory rand_eq = new uint256[](num_rounds); + for (index = 0; index < num_rounds; index++) { + (transcript, rand_eq[index]) = + KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + } + + return (transcript, rand_eq); + } + + function compute_u_secondary(Abstractions.CompressedSnark calldata proof, uint256[] memory tau, uint256 c) + public + view + returns (PolyEvalInstanceLib.PolyEvalInstance memory) + { + uint256[] memory evals = new uint256[](3); + evals[0] = proof.f_W_snark_secondary.eval_Az_at_tau; + evals[1] = proof.f_W_snark_secondary.eval_Bz_at_tau; + evals[2] = proof.f_W_snark_secondary.eval_Cz_at_tau; + + Vesta.VestaAffinePoint[] memory comm_vec = new Vesta.VestaAffinePoint[](3); + comm_vec[0] = Vesta.decompress(proof.f_W_snark_secondary.comm_Az); + comm_vec[1] = Vesta.decompress(proof.f_W_snark_secondary.comm_Bz); + comm_vec[2] = Vesta.decompress(proof.f_W_snark_secondary.comm_Cz); + + return PolyEvalInstanceLib.batchSecondary(comm_vec, tau, evals, c); + } + + function compute_u_primary(Abstractions.RelaxedR1CSSNARK calldata proof, uint256[] memory tau, uint256 c) + public + view + returns (PolyEvalInstanceLib.PolyEvalInstance memory) + { + uint256[] memory evals = new uint256[](3); + evals[0] = proof.eval_Az_at_tau; + evals[1] = proof.eval_Bz_at_tau; + evals[2] = proof.eval_Cz_at_tau; + + Pallas.PallasAffinePoint[] memory comm_vec = new Pallas.PallasAffinePoint[](3); + comm_vec[0] = Pallas.decompress(proof.comm_Az); + comm_vec[1] = Pallas.decompress(proof.comm_Bz); + comm_vec[2] = Pallas.decompress(proof.comm_Cz); + + return PolyEvalInstanceLib.batchPrimary(comm_vec, tau, evals, c); + } + + function compute_c_secondary( + Abstractions.CompressedSnark calldata proof, + KeccakTranscriptLib.KeccakTranscript memory transcript + ) public view returns (KeccakTranscriptLib.KeccakTranscript memory, uint256) { + Vesta.VestaAffinePoint[] memory comms_E = new Vesta.VestaAffinePoint[](2); + comms_E[0] = Vesta.decompress(proof.f_W_snark_secondary.comm_E_row); + comms_E[1] = Vesta.decompress(proof.f_W_snark_secondary.comm_E_col); + + uint256[] memory evals = new uint256[](3); + evals[0] = proof.f_W_snark_secondary.eval_Az_at_tau; + evals[1] = proof.f_W_snark_secondary.eval_Bz_at_tau; + evals[2] = proof.f_W_snark_secondary.eval_Cz_at_tau; + + uint8[] memory label = new uint8[](1); + label[0] = 0x65; // Rust's b"e" + + transcript = KeccakTranscriptLib.absorb(transcript, label, evals); + transcript = KeccakTranscriptLib.absorb(transcript, label, comms_E); + + // Question to reference implementation: Do we need this absorbing, that duplicates one above? + transcript = KeccakTranscriptLib.absorb(transcript, label, evals); + + label[0] = 0x63; // Rust's b"c" + uint256 c; + (transcript, c) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + + return (transcript, c); + } + + function compute_c_primary( + Abstractions.RelaxedR1CSSNARK calldata proof, + KeccakTranscriptLib.KeccakTranscript memory transcript + ) public view returns (KeccakTranscriptLib.KeccakTranscript memory, uint256) { + Pallas.PallasAffinePoint[] memory comms_E = new Pallas.PallasAffinePoint[](2); + comms_E[0] = Pallas.decompress(proof.comm_E_row); + comms_E[1] = Pallas.decompress(proof.comm_E_col); + + uint256[] memory evals = new uint256[](3); + evals[0] = proof.eval_Az_at_tau; + evals[1] = proof.eval_Bz_at_tau; + evals[2] = proof.eval_Cz_at_tau; + + uint8[] memory label = new uint8[](1); + label[0] = 0x65; // Rust's b"e" + + transcript = KeccakTranscriptLib.absorb(transcript, label, evals); + transcript = KeccakTranscriptLib.absorb(transcript, label, comms_E); + + // Question to reference implemnetation: Do we need this absorbing, that duplicates one above? + transcript = KeccakTranscriptLib.absorb(transcript, label, evals); + + label[0] = 0x63; // Rust's b"c" + uint256 c; + (transcript, c) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curveVesta(), label); + + return (transcript, c); + } + + function compute_gamma_1_secondary(KeccakTranscriptLib.KeccakTranscript memory transcript) + public + pure + returns (KeccakTranscriptLib.KeccakTranscript memory, uint256) + { + uint8[] memory label = new uint8[](2); + label[0] = 0x67; // Rust's b"g1" + label[1] = 0x31; + + uint256 gamma_1; + (transcript, gamma_1) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + + return (transcript, gamma_1); + } + + function compute_gamma_2_secondary(KeccakTranscriptLib.KeccakTranscript memory transcript) + public + pure + returns (KeccakTranscriptLib.KeccakTranscript memory, uint256) + { + uint8[] memory label = new uint8[](2); + label[0] = 0x67; // Rust's b"g2" + label[1] = 0x32; + + uint256 gamma_2; + (transcript, gamma_2) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + + return (transcript, gamma_2); + } + + function compute_gamma_1_primary(KeccakTranscriptLib.KeccakTranscript memory transcript) + public + pure + returns (KeccakTranscriptLib.KeccakTranscript memory, uint256) + { + uint8[] memory label = new uint8[](2); + label[0] = 0x67; // Rust's b"g1" + label[1] = 0x31; + + uint256 gamma_1; + (transcript, gamma_1) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curveVesta(), label); + + return (transcript, gamma_1); + } + + function compute_gamma_2_primary(KeccakTranscriptLib.KeccakTranscript memory transcript) + public + pure + returns (KeccakTranscriptLib.KeccakTranscript memory, uint256) + { + uint8[] memory label = new uint8[](2); + label[0] = 0x67; // Rust's b"g2" + label[1] = 0x32; + + uint256 gamma_2; + (transcript, gamma_2) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curveVesta(), label); + + return (transcript, gamma_2); + } + + function compute_tau_primary( + Abstractions.CompressedSnark calldata proof, + Abstractions.VerifierKeyS1 calldata vk, + KeccakTranscriptLib.KeccakTranscript memory transcript, + bool useLogging + ) public view returns (KeccakTranscriptLib.KeccakTranscript memory, uint256[] memory) { + uint8[] memory label = new uint8[](2); // Rust's b"vk" + label[0] = 0x76; + label[1] = 0x6b; + + transcript = KeccakTranscriptLib.absorb(transcript, label, vk.digest); + + label = new uint8[](1); // Rust's b"U" + label[0] = 0x55; + transcript = KeccakTranscriptLib.absorb(transcript, label, proof.r_U_primary); + + label = new uint8[](1); // Rust's b"c" + label[0] = 0x63; + + Pallas.PallasAffinePoint[] memory commitments = new Pallas.PallasAffinePoint[](3); + commitments[0] = Pallas.decompress(proof.r_W_snark_primary.comm_Az); + commitments[1] = Pallas.decompress(proof.r_W_snark_primary.comm_Bz); + commitments[2] = Pallas.decompress(proof.r_W_snark_primary.comm_Cz); + + transcript = KeccakTranscriptLib.absorb(transcript, label, commitments); + + label = new uint8[](1); // Rust's b"t" + label[0] = 0x74; + + uint256[] memory tau = new uint256[](17); + + for (uint256 index = 0; index < tau.length; index++) { + (transcript, tau[index]) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curveVesta(), label); + } + + if (useLogging) { + console.log("----------------compute_tau_primary--------------"); + console.log("vk.digest"); + console.logBytes32(bytes32(vk.digest)); + console.log("proof.r_W_snark_primary.comm_Az"); + console.logBytes32(bytes32(proof.r_W_snark_primary.comm_Az)); + console.log("proof.r_W_snark_primary.comm_Bz"); + console.logBytes32(bytes32(proof.r_W_snark_primary.comm_Bz)); + console.log("proof.r_W_snark_primary.comm_Cz"); + console.logBytes32(bytes32(proof.r_W_snark_primary.comm_Cz)); + console.log("vk.S_comm.N"); + console.log(vk.S_comm.N); + } + + return (transcript, tau); + } + + function compute_tau_secondary( + Abstractions.CompressedSnark calldata proof, + Abstractions.VerifierKeyS2 calldata vk, + KeccakTranscriptLib.KeccakTranscript memory transcript, + Vesta.VestaAffinePoint memory f_U_secondary_comm_W, + Vesta.VestaAffinePoint memory f_U_secondary_comm_E, + uint256[] memory f_U_secondary_X, + uint256 f_U_secondary_u, + bool useLogging + ) public view returns (KeccakTranscriptLib.KeccakTranscript memory, uint256[] memory) { + uint8[] memory label = new uint8[](2); // Rust's b"vk" + label[0] = 0x76; + label[1] = 0x6b; + + transcript = KeccakTranscriptLib.absorb(transcript, label, vk.digest); + + label = new uint8[](1); // Rust's b"U" + label[0] = 0x55; + transcript = KeccakTranscriptLib.absorb( + transcript, label, f_U_secondary_comm_W, f_U_secondary_comm_E, f_U_secondary_X, f_U_secondary_u + ); + + label = new uint8[](1); // Rust's b"c" + label[0] = 0x63; + + Vesta.VestaAffinePoint[] memory commitments = new Vesta.VestaAffinePoint[](3); + commitments[0] = Vesta.decompress(proof.f_W_snark_secondary.comm_Az); + commitments[1] = Vesta.decompress(proof.f_W_snark_secondary.comm_Bz); + commitments[2] = Vesta.decompress(proof.f_W_snark_secondary.comm_Cz); + + transcript = KeccakTranscriptLib.absorb(transcript, label, commitments); + + label = new uint8[](1); // Rust's b"t" + label[0] = 0x74; + + uint256 num_rounds_sat = CommonUtilities.log2(vk.S_comm.N); + + uint256[] memory tau = new uint256[](num_rounds_sat); + + for (uint256 index = 0; index < tau.length; index++) { + (transcript, tau[index]) = + KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + } + + if (useLogging) { + console.log("----------------compute_tau_secondary--------------"); + console.log("vk.digest"); + console.logBytes32(bytes32(vk.digest)); + console.log("proof.f_W_snark_secondary.comm_Az"); + console.logBytes32(bytes32(proof.f_W_snark_secondary.comm_Az)); + console.log("proof.f_W_snark_secondary.comm_Bz"); + console.logBytes32(bytes32(proof.f_W_snark_secondary.comm_Bz)); + console.log("proof.f_W_snark_secondary.comm_Cz"); + console.logBytes32(bytes32(proof.f_W_snark_secondary.comm_Cz)); + console.log("vk.S_comm.N"); + console.log(vk.S_comm.N); + } + + return (transcript, tau); + } + + function compute_f_U_secondary(Abstractions.CompressedSnark calldata proof, Abstractions.VerifierKey calldata vk) + public + view + returns (Vesta.VestaAffinePoint memory, Vesta.VestaAffinePoint memory, uint256[] memory, uint256) + { + (uint256[] memory elementsToHash, Vesta.VestaAffinePoint memory comm_T) = + prepareElementsToHashSecondary(proof, vk); + + return foldInstanceSecondary( + Abstractions.RelaxedR1CSInstance( + proof.r_U_secondary.comm_W, proof.r_U_secondary.comm_E, proof.r_U_secondary.X, proof.r_U_secondary.u + ), + Abstractions.R1CSInstance(proof.l_u_secondary.comm_W, proof.l_u_secondary.X), + comm_T, + compute_r_secondary(elementsToHash) + ); + } + + function compute_r_secondary(uint256[] memory elementsToHash) private pure returns (uint256) { + SpongeOpLib.SpongeOp memory absorb = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Absorb, NUM_FE_FOR_RO); + SpongeOpLib.SpongeOp memory squeeze = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Squeeze, 1); + SpongeOpLib.SpongeOp[] memory pattern = new SpongeOpLib.SpongeOp[](2); + pattern[0] = absorb; + pattern[1] = squeeze; + + NovaSpongeVestaLib.SpongeU24Vesta memory sponge = NovaSpongeVestaLib.start(IOPatternLib.IOPattern(pattern), 0); + + sponge = NovaSpongeVestaLib.absorb(sponge, elementsToHash); + + (, uint256[] memory output) = NovaSpongeVestaLib.squeeze(sponge, 1); + + return output[0] & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; + } + + function prepareElementsToHashSecondary( + Abstractions.CompressedSnark calldata proof, + Abstractions.VerifierKey calldata vk + ) private view returns (uint256[] memory, Vesta.VestaAffinePoint memory) { + uint256 counter = 0; + uint256[] memory elementsToHash = new uint256[](NUM_FE_FOR_RO); + elementsToHash[counter] = vk.digest; + counter++; + + Vesta.VestaAffinePoint memory point; + //U1.absorb_in_ro + // Absorb comm_W + point = Vesta.decompress(proof.r_U_secondary.comm_W); + elementsToHash[counter] = point.x; + counter++; + elementsToHash[counter] = point.y; + counter++; + if (Vesta.isInfinity(point)) { + elementsToHash[counter] = 1; + } else { + elementsToHash[counter] = 0; + } + counter++; + + // Absorb comm_E + point = Vesta.decompress(proof.r_U_secondary.comm_E); + elementsToHash[counter] = point.x; + counter++; + elementsToHash[counter] = point.y; + counter++; + if (Vesta.isInfinity(point)) { + elementsToHash[counter] = 1; + } else { + elementsToHash[counter] = 0; + } + counter++; + + // Abosrb u + elementsToHash[counter] = proof.r_U_secondary.u; + counter++; + + // Absorb X + uint256 limb1; + uint256 limb2; + uint256 limb3; + uint256 limb4; + for (uint256 i = 0; i < proof.r_U_secondary.X.length; i++) { + (limb1, limb2, limb3, limb4) = Field.extractLimbs(proof.r_U_secondary.X[i]); + elementsToHash[counter] = limb1; + counter++; + elementsToHash[counter] = limb2; + counter++; + elementsToHash[counter] = limb3; + counter++; + elementsToHash[counter] = limb4; + counter++; + } + + //U2.absorb_in_ro + // Absorb comm_W + point = Vesta.decompress(proof.l_u_secondary.comm_W); + elementsToHash[counter] = point.x; + counter++; + elementsToHash[counter] = point.y; + counter++; + if (Vesta.isInfinity(point)) { + elementsToHash[counter] = 1; + } else { + elementsToHash[counter] = 0; + } + counter++; + + // Absorb X + for (uint256 i = 0; i < proof.l_u_secondary.X.length; i++) { + elementsToHash[counter] = proof.l_u_secondary.X[i]; + counter++; + } + + // Absorb comm_T + point = Vesta.fromBytes(bytes32(proof.nifs_compressed_comm_T)); + elementsToHash[counter] = point.x; + counter++; + elementsToHash[counter] = point.y; + counter++; + if (Vesta.isInfinity(point)) { + elementsToHash[counter] = 1; + } else { + elementsToHash[counter] = 0; + } + counter++; + + require(counter == NUM_FE_FOR_RO, "[Step3Lib.prepareElementsToHash] counter != NUM_FE_FOR_RO"); + + return (elementsToHash, point); + } + + function foldInstanceSecondary( + Abstractions.RelaxedR1CSInstance memory U1, + Abstractions.R1CSInstance memory u2, + Vesta.VestaAffinePoint memory comm_T, + uint256 r + ) private view returns (Vesta.VestaAffinePoint memory, Vesta.VestaAffinePoint memory, uint256[] memory, uint256) { + uint256[] memory x2 = u2.X; + Vesta.VestaAffinePoint memory comm_W_2 = Vesta.decompress(u2.comm_W); + + require(U1.X.length == x2.length, "[Step3.foldInstanceSecondary]: Witness vectors do not match length"); + + uint256[] memory X = new uint256[](U1.X.length); + + for (uint256 i = 0; i < x2.length; i++) { + X[i] = addmod(U1.X[i], mulmod(r, x2[i], Vesta.R_MOD), Vesta.R_MOD); + } + + return ( + Vesta.add(Vesta.decompress(U1.comm_W), Vesta.scalarMul(comm_W_2, r)), + Vesta.add(Vesta.decompress(U1.comm_E), Vesta.scalarMul(comm_T, r)), + X, + addmod(U1.u, r, Vesta.P_MOD) + ); + } +} diff --git a/src/verifier/step2/Step2Data.sol b/src/verifier/step2/Step2Data.sol deleted file mode 100644 index b8fdfdf..0000000 --- a/src/verifier/step2/Step2Data.sol +++ /dev/null @@ -1,723 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Do not change manually. This contract has been auto-generated by src/verifier/step2/step2-data-contract-gen.py -pragma solidity ^0.8.16; - -library PoseidonConstants { - struct Pallas { - uint256[] mixConstants; - uint256[] addRoundConstants; - } - - struct Vesta { - uint256[] mixConstants; - uint256[] addRoundConstants; - } - - function loadPallasConstants(uint256[] memory mixConstants, uint256[] memory addRoundConstants) - internal - pure - returns (Pallas memory) - { - return Pallas(mixConstants, addRoundConstants); - } - - function loadVestaConstants(uint256[] memory mixConstants, uint256[] memory addRoundConstants) - internal - pure - returns (Vesta memory) - { - return Vesta(mixConstants, addRoundConstants); - } - - function getPoseidonConstantsForBasicComparison() public pure returns (Pallas memory, Vesta memory) { - uint256[] memory mixConstantsPallas = new uint256[](25); - mixConstantsPallas[0] = 0x051eb851eb851eb851eb851eb851eb85217649adc34dd67d167e7ecb47ae147b; - mixConstantsPallas[1] = 0x0c4ec4ec4ec4ec4ec4ec4ec4ec4ec4ec555c587f3cdd925dec39ebdecec4ec4f; - mixConstantsPallas[2] = 0x1a12f684bda12f684bda12f684bda12f7642b01ad461bad25ad985b5e38e38e4; - mixConstantsPallas[3] = 0x19249249249249249249249249249249320972f54ccbf4264551c0ef64924925; - mixConstantsPallas[4] = 0x0b08d3dcb08d3dcb08d3dcb08d3dcb08d9c58d22a08007a3a7a6b028dcb08d3e; - mixConstantsPallas[5] = 0x2444444444444444444444444444444457b089e4276759f60a00021fe6666667; - mixConstantsPallas[6] = 0x339ce739ce739ce739ce739ce739ce73b88b83a1f6fc02b328f2e5644a5294a6; - mixConstantsPallas[7] = 0x3e0000000000000000000000000000002134643429029152bc63c76598000001; - mixConstantsPallas[8] = 0x26c9b26c9b26c9b26c9b26c9b26c9b26de785cb7c7937fb3a2a706611745d175; - mixConstantsPallas[9] = 0x3a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a799ab8a990026aa838d661508f0f0f10; - mixConstantsPallas[10] = 0x3a83a83a83a83a83a83a83a83a83a83aa2feb7c1dc9e2595935c8480ea0ea0eb; - mixConstantsPallas[11] = 0x138e38e38e38e38e38e38e38e38e38e398b204141f494c1dc42324486aaaaaab; - mixConstantsPallas[12] = 0x1d67c8a60dd67c8a60dd67c8a60dd67c9a206fcdbf158736319f24513759f22a; - mixConstantsPallas[13] = 0x30d79435e50d79435e50d79435e50d795d86b81ea8c8375f2acae8b4de50d795; - mixConstantsPallas[14] = 0x0834834834834834834834834834834838e83aff7de90c3e9d7bf29489d89d8a; - mixConstantsPallas[15] = 0x0b3333333333333333333333333333333932c12c1b3a4531a134b55caccccccd; - mixConstantsPallas[16] = 0x2a2576a2576a2576a2576a2576a2576a3c0907165d8a1aae45a720382bb512bc; - mixConstantsPallas[17] = 0x10c30c30c30c30c30c30c30c30c30c30cc064ca38887f819838bd5f4edb6db6e; - mixConstantsPallas[18] = 0x017d05f417d05f417d05f417d05f417d06c027475984c44e098407175f417d06; - mixConstantsPallas[19] = 0x2d1745d1745d1745d1745d1745d1745d2f6bebc8d801de0da048910411745d18; - mixConstantsPallas[20] = 0x02d82d82d82d82d82d82d82d82d82d82d9b37e44172b3e457e464670eeeeeeef; - mixConstantsPallas[21] = 0x1d37a6f4de9bd37a6f4de9bd37a6f4deab7945d73be5ec286ce28b348b21642d; - mixConstantsPallas[22] = 0x11b3bea3677d46cefa8d9df51b3bea36814f711f95a2e84e712d2e36a8d9df52; - mixConstantsPallas[23] = 0x3eaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacc3a75cc1e70b3eb05fc3fe810000001; - mixConstantsPallas[24] = 0x3c14e5e0a72f05397829cbc14e5e0a731080f81ba03dcfbbde2a6c9fcbc14e5f; - uint256[] memory addRoundConstantsPallas = new uint256[](259); - addRoundConstantsPallas[0] = 0x2c21df040fb486eda5e1b307392ad7917e2ae2eff450fd49a0f58b056dceb6b1; - addRoundConstantsPallas[1] = 0x06dd0930c41e65275f824307c57550b7712f02affcc2b202ff65458152f81e5b; - addRoundConstantsPallas[2] = 0x0f86feed14cf5ca45e38f023fe7d21bfeedab7cbc8ff68a194eb462acb868fed; - addRoundConstantsPallas[3] = 0x04e38ddcaf70374cd798d71b838412f3b685c12d0b8567ff1a849694626c0136; - addRoundConstantsPallas[4] = 0x3137015ea0699e21dc15eaea588aa6476babfff62c69a648930d6f599dbfd98a; - addRoundConstantsPallas[5] = 0x27b4ee7fcad7373eaf24dcc0d5ca838d5b2b67ffcc30320f913aba0099ba23b4; - addRoundConstantsPallas[6] = 0x0b25d3b8417075fe6fa1819f8252912b7cc2642c72e225dc6c3e59eb1014cb39; - addRoundConstantsPallas[7] = 0x1077a74d28bec60bbcebb879ed8778209a314827fdcbb838cf5fa396844cc744; - addRoundConstantsPallas[8] = 0x3020f64d9081ab756563512341a3cad5f74fbc0635421032ad15e8b0592d8f07; - addRoundConstantsPallas[9] = 0x3bb4d029a81d20c6c79f657b080d30f65ecd31d3ed47c963709364dceb5491ee; - addRoundConstantsPallas[10] = 0x3446e2e18ae8f55e4e51e1f8dcc93a0733dc01d37c68ff39773e6f18024953e2; - addRoundConstantsPallas[11] = 0x20193dec48c8686b543bb3561193df86675a449f01dc1daced860373f3b0ca07; - addRoundConstantsPallas[12] = 0x38767b551e6ab98296fb149d39792dc00ff333ab99562a5f5859cffd00f4127e; - addRoundConstantsPallas[13] = 0x22e00037b03a4bff29c042f5d5a5f66220f0296895d6699250b8820ba904e947; - addRoundConstantsPallas[14] = 0x2340cc0dc53743a48dae0f62420598c543b1ccd9b06885ab90c5bee68697de4f; - addRoundConstantsPallas[15] = 0x0912c078ff3316f34d17e8fd81dff91e754d03f2e71c2fc0077c8011a4c0a43b; - addRoundConstantsPallas[16] = 0x1befc1dc02a5153ccf17fa1fedce0e141a5639414d37190d03315d1a93376874; - addRoundConstantsPallas[17] = 0x2da148454a1783e8da2944df41c285ba76426d7dbee627d1c17af160d1bcce01; - addRoundConstantsPallas[18] = 0x1bc7f3d8f64effde6c9cfac1fcabf471d443ab4106c85c3d7f0e671eba1ac20f; - addRoundConstantsPallas[19] = 0x3d5a6dc890f4fecf6d3a9960ffc6d6754a5dbf88a0250e3358aa40ce63382ae0; - addRoundConstantsPallas[20] = 0x1f569abd6fc91f4a5e009ae3d8a6d0170ec74c986ef91d34299681e90aac79b3; - addRoundConstantsPallas[21] = 0x233e1bf16944f2889c616777c1b072202e42b7b216b8d4c9973157ecea58487a; - addRoundConstantsPallas[22] = 0x091c5fd8c64a3fa466d33c38303cfb0f07c141e4a8848ef899fb91385d62eaba; - addRoundConstantsPallas[23] = 0x3bdac8c3cda0b615c6f58c0d16ed58b8cf349b69f101925881f8b62d1fe6ca91; - addRoundConstantsPallas[24] = 0x02d9fc7d215eab28d1fb7c066fb9cb0c590ea899c10b3bd7a94394a732a23584; - addRoundConstantsPallas[25] = 0x2c3daf6894f377c8e9c7d9a31b31dc45681fe2036ab2cfcdcefea063515ef12d; - addRoundConstantsPallas[26] = 0x155b798c58ce7c35578c66b51514b1cab912b909c529ee61a4d445f7285511d6; - addRoundConstantsPallas[27] = 0x32624149c3235cdbe56d6d6708a88bf620a4d67e7ea59281adb95fbfd7ec9821; - addRoundConstantsPallas[28] = 0x26e9e5e6bebcd73cb6a78214366682f8af24ae7fe8e5ea1ca82d6e26b86353fe; - addRoundConstantsPallas[29] = 0x3e1ebef57f47b7e1d32a22ba041b40d8b639a0f679a968f456df12c1b2542523; - addRoundConstantsPallas[30] = 0x1444856297f58d298ae95c22107c381a9c72cac2249ae00c25bd3f0b8343fa89; - addRoundConstantsPallas[31] = 0x016e2b865a9999d1434244f6b76b4524c848cace7cd53b62d7ad928b44b1155d; - addRoundConstantsPallas[32] = 0x3faa3bf25d62d8ff404c2454c852ad2bf7f2839328a50ead0c123831c311c4b1; - addRoundConstantsPallas[33] = 0x04f3fdadc31299949ba97628eca613abd3233e653e5b0c235ba1a1105bc5201c; - addRoundConstantsPallas[34] = 0x1df9b657cd9b1c30d30b3b52d0f0bbfe155176256fab95e8a3746cf3a7a5b83e; - addRoundConstantsPallas[35] = 0x355436caefecaac6ddcd7d5c8bf6307fde07226d4bba2e4b25f238b5f32a0a72; - addRoundConstantsPallas[36] = 0x3f522b48187afcd01a61151a506b1f320fd1bcaf927e28f92a867fd0f56710ae; - addRoundConstantsPallas[37] = 0x01d85fbcbc623544c703d146623adb995366365fadc4ab8eb8fe77adf7fdabde; - addRoundConstantsPallas[38] = 0x0d37183976df15fb77a0c5a9ea5c9bcbaeb30278af5913e507eeace919495c85; - addRoundConstantsPallas[39] = 0x16257e6c1cbe3694d2713d5e8b644edba038fde8f7325a7a3ff5ae15d27eeee9; - addRoundConstantsPallas[40] = 0x214182471c10930b81a71ea3dae4f854980ff0a40a41474bfa41102ae9fdb798; - addRoundConstantsPallas[41] = 0x020ab79ab51fc29de47f7d43b4f79c1ea944ae0910bb5ba8a11ed4acf60583f6; - addRoundConstantsPallas[42] = 0x0992e769b52b33de91a5ebdb5b9a50c18f6fe7dfe4d8ce792a03568534d43736; - addRoundConstantsPallas[43] = 0x15df00e88ffadb8f04280b2808c2185ddee5c36f8d7aa10bbe2fb6c50eb2d889; - addRoundConstantsPallas[44] = 0x2a9c52cee901f6ebe72e158782ec5c55e9aef7a76fb5f6fddfad57b0302d0e71; - addRoundConstantsPallas[45] = 0x1b28d8e17af5696327918040b0c5055d3014dd7316336fd8907c406181d31c7d; - addRoundConstantsPallas[46] = 0x3332a051c6a8e26053ef04a686995574268ec1fd81c2fa3e94948ad6c8a725e0; - addRoundConstantsPallas[47] = 0x3cef9ab5c7f9045cd8be802f9d3f80c01745f824156657aba546a6f316409fa8; - addRoundConstantsPallas[48] = 0x26a1466b1195b1bc5ca8c513e869ea2594980dd50396d5d2b37fe3f3c9992a25; - addRoundConstantsPallas[49] = 0x216d5419ecd8dbca6be122a8ceca2961a84a2594c40aa9e3c3cb017b242d27b2; - addRoundConstantsPallas[50] = 0x1b9d858a46450bd97b7366556106cb84bbd7e1f4c08da8dfa1a28288c2b7689a; - addRoundConstantsPallas[51] = 0x04cd5e84df6505d0f4f302602b4e6872ed89d53fc0ee5eeecc9364e43dbc13dd; - addRoundConstantsPallas[52] = 0x08fe98fd8d927202385ac377380a2dc81afe1ef619d8b8acb753cc475fd56bfc; - addRoundConstantsPallas[53] = 0x3214e976da42622ad2a2c7d3208133ff4ca08fc1de5b58c76a8b61b0ba4be7b9; - addRoundConstantsPallas[54] = 0x18dd4f08c33fcb0084447c33e0ab8177d0de6ec451436c07668607d5045bf67b; - addRoundConstantsPallas[55] = 0x350f00f3ad4804ef961317fdd6cc39a4cd6a308fdfbfc86cbe45d9bf03baf14a; - addRoundConstantsPallas[56] = 0x00e66850cc7a937febd0a460659b49640fdc2ecc8359f883f32c446c9f02bdf0; - addRoundConstantsPallas[57] = 0x0212470da6b3d25f9a41a3dd9118ca4849ddf50d9ac0d806ff64a0a59a677e66; - addRoundConstantsPallas[58] = 0x0d12e59ebe2532e5e9fb9db2616eed0aaf5001a3fc7a589f8ab591f85bd33048; - addRoundConstantsPallas[59] = 0x125f26891e82e1b218af90e448af372b59d8e64809af1b8d2c11a898a71607ed; - addRoundConstantsPallas[60] = 0x2602da5d9137df3411e60842d2e318ee21d17a5a7f004a03d50fefc054dbfb08; - addRoundConstantsPallas[61] = 0x2d21a1c440d256f2ef6227ec85c7d10808599ac8079a31373cd35a5cb0874629; - addRoundConstantsPallas[62] = 0x1047e347185c1b1f12779a5ebd5dba8fb95f9be30a2594e67c742aa4dfe98c7a; - addRoundConstantsPallas[63] = 0x23b634cd15041879da9ab9b766003c617df0e4c8fa01d6340d4050dc19677fb4; - addRoundConstantsPallas[64] = 0x0c776e03fffab07f10712209ec6eb6892cde22f17f8152810e8d2aba399b77ce; - addRoundConstantsPallas[65] = 0x1b3f5e3f710833714c238a1b57b791131180ed6455368abb958858aa4c577c34; - addRoundConstantsPallas[66] = 0x098f0e62c5a636c203f8e33c6bd84ec2d74d779122e0877fc2b22b563ff15b68; - addRoundConstantsPallas[67] = 0x1825bbfa2848ecfc4684345751f9f85b0afae10aacb37530ca24ce4756d991b7; - addRoundConstantsPallas[68] = 0x2b32d8f8cf996ad8969a04e766ab6f04c89c86551e913e7fdbe73800a0d04b61; - addRoundConstantsPallas[69] = 0x348755e0b41bd33175b9dab70bc329ef886fdb4a9eb6a6c09ffec0d1aeb461a8; - addRoundConstantsPallas[70] = 0x05e8c7a63e0b496001a8c0abeba53dd20808b0917cc0a78e3ab4febcfab8decc; - addRoundConstantsPallas[71] = 0x31cecbbed6b4cb33ae132792771556902d1f342b04cdabf47aa8ab5bca02658f; - addRoundConstantsPallas[72] = 0x29d553deed565a6d566fe23d3ecf4bef310de1f9aeeac8b9b75427d31fc2c70d; - addRoundConstantsPallas[73] = 0x2f48904f67f015812a29704e311d7a5e209d259e21bb8a5fa61083ca2613aaab; - addRoundConstantsPallas[74] = 0x33d22cf9857c8b45d608faa0dad3dbba964be3f447303d3e354e9cb39326093c; - addRoundConstantsPallas[75] = 0x13b6c6ca606001f0bc186677ea1dcef7bde3b80b9c604758fbe28125e3ecd6ae; - addRoundConstantsPallas[76] = 0x1a1e23ecfa38cd89da409466a36fd5a6df65bdae731144b634e549b7d9d845e6; - addRoundConstantsPallas[77] = 0x14d9404c0395df51a7b73cf1f4643da68a9634522b3f27f1ef1199a5a0fcc015; - addRoundConstantsPallas[78] = 0x17ad33d6b18131300774a970ad794e5865e4220067a3f8a1b51d540559204c2a; - addRoundConstantsPallas[79] = 0x0a76c99ec6273f90116b73c8587f54621fbc7b1f32369efbc0181bbc87e66122; - addRoundConstantsPallas[80] = 0x370ab2bcc06473cd3cc244f08eadd5f5095495a7ad09c829ae8d43cf4f4cbe7b; - addRoundConstantsPallas[81] = 0x1d59de441fd1ca11c50598b320cc228dc28a5ce58efa8619348ebfb9da97ec7b; - addRoundConstantsPallas[82] = 0x0e331be3fd9e56261e5c21409dbfffd9853b0ed972efc7265db5f6e80799cef3; - addRoundConstantsPallas[83] = 0x07c116524002cf41c17231099d7845a2452665b40668b414767a806d8d805432; - addRoundConstantsPallas[84] = 0x105bfe015b162f959b648a6590b99e002a7adf844cb81953bc3fb018e311b7bf; - addRoundConstantsPallas[85] = 0x0baae6394777586beaf968170e6ab2fa37d08f89b1abc5e8e913a8e4e98202b6; - addRoundConstantsPallas[86] = 0x3af050fb745e7dc35326b7af8ba699aa1658a93954a4127e4d4b9cfae53ac411; - addRoundConstantsPallas[87] = 0x18ff21a0ac078e8393f8450238573c218e13922353dfadd8e19fe423a296f504; - addRoundConstantsPallas[88] = 0x1eff67798a707d5d6c44cef6020358e0827e8f1414946b96e8f44150a092a436; - addRoundConstantsPallas[89] = 0x314f3a5d2751fceff4b53c5bae2bdca1f95f87c5815dd7827222019e20c4c5ea; - addRoundConstantsPallas[90] = 0x01c80cc7a73cff0f9ec0fa11601010197d2a76dd326a0a7a15d822086569ae57; - addRoundConstantsPallas[91] = 0x3e540c2b583a3b26db74bef8fe8b475c41e0829eefabab5268bd1b39747ab0db; - addRoundConstantsPallas[92] = 0x0ba97ee95638e20efffc71d584e1c2380e35ccec57b7e68a3d0c8f23b6eb6354; - addRoundConstantsPallas[93] = 0x2073e0a653af0ab8c87e8de29b2bcdb54438081c1990ea2fabbea8960dea07fe; - addRoundConstantsPallas[94] = 0x21066ad5a11af5bc553a3649c77accbdf240c680a158d2863142cfa26d9de6ae; - addRoundConstantsPallas[95] = 0x22fb7fd0bc9096a15d6da2194fcb908aa2a46a320c4ae5a6ad3fd681120e35e6; - addRoundConstantsPallas[96] = 0x39e37a02d7f624f01e4b0bf852d1be77c2f04fb186f5fd16dac6565ce0cd5b02; - addRoundConstantsPallas[97] = 0x2928ee9de5e9b6359b0c99cad643d516eb1c6abcb717369d9ed01cdb04bb9695; - addRoundConstantsPallas[98] = 0x233c8006b4f10fd7711b066b9d447952004ffdf54e6841c033bc853762f2b0ab; - addRoundConstantsPallas[99] = 0x3bb67d92026e90be592755e092a74917d5ce5a9ee56a05b3ee18253792da8aef; - addRoundConstantsPallas[100] = 0x251ab428aa3c475d4a88cf8601189a0d305cb8514b778153f710270db14a4f6d; - addRoundConstantsPallas[101] = 0x18f938d8b59b6d4818b9ce04c07d243b5aad5a5cd3d09316fed34cbb31c26d59; - addRoundConstantsPallas[102] = 0x2a1ba45000093525a9e4349d2b038e0e1cb98882c4ec52f028e8e552b56e911f; - addRoundConstantsPallas[103] = 0x3f642fccf2590be8d3cf1c0935271f07b5548e1a1e0704a6bd643401fd4d2ed3; - addRoundConstantsPallas[104] = 0x11158fd4dd444002e401dee67005e3105b4347cf6aa36b1b12a9adaaf87f003a; - addRoundConstantsPallas[105] = 0x2527b7746ff2df8709c73aa8f9fe6d67e11ce47995ca167720a2f5e22eac1c03; - addRoundConstantsPallas[106] = 0x155648f82ccde0dda43865a464115ac28670ddf41c8ab79510a637b5d46b0e8b; - addRoundConstantsPallas[107] = 0x0444aa44377330fd93efed994ba4e4eed78a43a6095639ab05ea071717a0d979; - addRoundConstantsPallas[108] = 0x3a8f913c669cdeedad4775a9d20b9d81194debdfde2eece7c005c291b9df669f; - addRoundConstantsPallas[109] = 0x141739e9c686d38230ed67a3b64a0b04775efbe0b00b15da8d70344a8b279497; - addRoundConstantsPallas[110] = 0x01211ccf9b574aa67b8c4bed68587bd4da7d62e18a2ac6b35b3eaba3dd48a8ae; - addRoundConstantsPallas[111] = 0x168a8f02203c0a3b7c7650f53f41d4c7df100d2e712108804d17f36f50de66f1; - addRoundConstantsPallas[112] = 0x268f14d8f02396a28db2957eb3bbb2c9373bdef33bb56695922579764703bb09; - addRoundConstantsPallas[113] = 0x031c1ff5512f9b17ec2362ff6912575e7981a90965969861d00467796bde4df7; - addRoundConstantsPallas[114] = 0x018f63c356754f1659471b675ef1dcdbfcddbec434882228b836959371fd81d2; - addRoundConstantsPallas[115] = 0x28a62037b10eefb60994e71bc21276c4622d2bffcc71450f563858f3357704cd; - addRoundConstantsPallas[116] = 0x13f21a5ddb124069a54dbf53c7041cba60558e63566b05bb7acf7577c50605d2; - addRoundConstantsPallas[117] = 0x3226ec3130709e4280abe12f35d631c162484921c3800af30919fb0f4b8512bf; - addRoundConstantsPallas[118] = 0x1c6321b333d3d372f57b71b54881e318cdb3bcda8a651aa1232df2247ab49c33; - addRoundConstantsPallas[119] = 0x3fe169dc0b541a934d5cb31380c905d5f4c99d7e0dd6d887c5d876f56dfaa758; - addRoundConstantsPallas[120] = 0x34b38429428e6ac28282eeb59c10315d5133334c93d51bc4d62772bdb3349f28; - addRoundConstantsPallas[121] = 0x3892cca9e65a42a71c4cf1c8b48eb5d14b0a79ca14b549ff778803eabc00fb9f; - addRoundConstantsPallas[122] = 0x21e693e7d78ee66c62791736704efaf4b157ac4d45eb26f86a9087654286f6b8; - addRoundConstantsPallas[123] = 0x18ef59841f02d0b4715a26c56ce20288d33f0180e5cdf56a107d11cde1f7f13f; - addRoundConstantsPallas[124] = 0x3dac648d23acf56cd6f3d90f7e56c0b51c124b891a37ca4a2cbcbaeb670281e4; - addRoundConstantsPallas[125] = 0x1fd8f8a8d565a16aad6d08f624afa5906600d54cd4c40524afae043d7aeabfa2; - addRoundConstantsPallas[126] = 0x3befc28793f374653cbbe340c48560dcf78972041687c40237f730a78202b06f; - addRoundConstantsPallas[127] = 0x2cd870d83db91e5feab86a59a9fc78b8db800b71fd70db63756605be9ee687bc; - addRoundConstantsPallas[128] = 0x2914f071cb2b5bbec8642ce381711765edd0cab72130747acf84b7bfe79f9ade; - addRoundConstantsPallas[129] = 0x06425bd8c04990a08c1ebd294fd2cb7859c9feaa3d2335ea53f4d523ac4a94a5; - addRoundConstantsPallas[130] = 0x147c7bf347d062312a556f598a3bb8cef26fa5e722339a0b90501d0cbc37d8ae; - addRoundConstantsPallas[131] = 0x1ad7e874ad36ebcb34a4fa012c6e8d69d932c3f6f3a1f61a79768a21dd0cb9c6; - addRoundConstantsPallas[132] = 0x3f9ff41af6858f3ff683807b27832eabf13ae8743588e342677db95b8b07ef53; - addRoundConstantsPallas[133] = 0x2e706e3143c054e6cc869a92d96a0f94728f907b81aa1148281c72ef1e488a38; - addRoundConstantsPallas[134] = 0x18155c4402b4791a8460923efcb87d18d17a72238c1f9d01f261e2841e01df6f; - addRoundConstantsPallas[135] = 0x167cbf702c44c52a676f611aac79a8646504898ec2fa3d00d0242177abd951fe; - addRoundConstantsPallas[136] = 0x2492ccbc57b3ab3e9c6e9c6dbbed27946f7417fd2fbe6a9b77a4c458deffb1d7; - addRoundConstantsPallas[137] = 0x07fece98637504c28a31d1c6749170a4420e645a4f8068e43fb0852c4c8cb345; - addRoundConstantsPallas[138] = 0x294c8a75d41588dd18b0545b0a845e74ea43ce876d41c83fe29fd1066d014fd9; - addRoundConstantsPallas[139] = 0x22e0bee71c774790291fa791e9337d155b74b4dd5c28f5e849a3895ed5a61d95; - addRoundConstantsPallas[140] = 0x0ec03c310087aee085b99801c7ad30554baad1a9abae483b1e0f3047ba4759ee; - addRoundConstantsPallas[141] = 0x3f2f8cee9affb0ce2d519ee201260fa7671c5bce8192872f07bab513097691f7; - addRoundConstantsPallas[142] = 0x286a650c624950d11d0d0da9b991d767a511c39cd434916693a035ad8980c5eb; - addRoundConstantsPallas[143] = 0x010eb055c1062252261228a21d84488287efa0610a6ad79506c7cd859a54a088; - addRoundConstantsPallas[144] = 0x1976e682bedf1d6b48816da119d97f616844eca2aca37d28c11091f5ce38a5aa; - addRoundConstantsPallas[145] = 0x09e05a737699bdce96ca8e5ca253ae7735da1b4c0d765bbd430e764cc0d218f8; - addRoundConstantsPallas[146] = 0x036454622903525da69c3346b94cd133fcd63654d5d06c89329c1e185c6bccba; - addRoundConstantsPallas[147] = 0x0c56ff8a935b16147e89279ecf37441033c7a0b84b5836f63aafcffebb13def4; - addRoundConstantsPallas[148] = 0x3314a43acadcce3f3b991d158f2461df46bf3132fc05f6f6c051de4ebfa046dd; - addRoundConstantsPallas[149] = 0x01a035b33a26fc8cc6ebffeec7245c45babe8b0e2ebf6600b64c2eaa0994eb48; - addRoundConstantsPallas[150] = 0x0071e09fc83a15f66f3cc7f20650103992bb2b03e9fbe5536b66f25237702069; - addRoundConstantsPallas[151] = 0x13f0615177238cc74b5a556135c5f782adee09707c5c4be50959041df9179adb; - addRoundConstantsPallas[152] = 0x188a0c970fd2c041d74cf620ea1976dcb3885e9de2d01f190a3ffabcc03b91e4; - addRoundConstantsPallas[153] = 0x328d96c974e3b4c59aeaa93ababc21e3c61d310cd9d14281b70cf99bac96858c; - addRoundConstantsPallas[154] = 0x36df383a0fb66390408ea2a9bd966caab75e3e9e4c474d5060de790f74314a08; - addRoundConstantsPallas[155] = 0x303fcd0ec32a0ae001f35c49574a93344c132cc0243941bab011a81ad1c5e957; - addRoundConstantsPallas[156] = 0x01e634f04f74a6249f0f498742c3b2ab9152ae9d64302592636cc8da37ffa3f2; - addRoundConstantsPallas[157] = 0x192497164fd4b354d3c1ffced5bacf391bb95ded4230762766777577b3e7e4eb; - addRoundConstantsPallas[158] = 0x2365b15fac3216051d23f40e3adb548f9a3ffcd61907ff932e24ba61014d42a5; - addRoundConstantsPallas[159] = 0x1e29b4c369a254eb8e512e75e4af19c9eb49a7d01add75f466229cd998a82b32; - addRoundConstantsPallas[160] = 0x21aa14ad5c230f3e80098044fcf80ed09ecb2dab5c046b07207d03df7d17a31a; - addRoundConstantsPallas[161] = 0x26973715cf1cb6bd19d957ce1dc6af49cdc4966fad5eac189ce0bad37a8485db; - addRoundConstantsPallas[162] = 0x23627c6bdc1349d12637bf483a13b5a99acb48db50603d8d0122c1e1b1293228; - addRoundConstantsPallas[163] = 0x03c6caf2bfb76c6bc982415df328f5162450be1a63caeedb135f636da45c8a5b; - addRoundConstantsPallas[164] = 0x1539dbb4a7b9327b8f5a71c0be9ba840b45ed9d7b778b7a6123ac6f42f6a1bc4; - addRoundConstantsPallas[165] = 0x3f5baefc2ac3cd57659c805e54e01fa949fcd4d50e43d7cc7e0d191a79963415; - addRoundConstantsPallas[166] = 0x0d4f6f5b2238f01285cd647d40cb29560bb3501e7822ebe1522d1d545cf2a21b; - addRoundConstantsPallas[167] = 0x19618450e0584ce98cb72d93698432b594ffb791f204a1ffe3d182480cb2b972; - addRoundConstantsPallas[168] = 0x1e4d74ca3fedc3a152cedca2cd18a7ad9016bcf0f7bf77f263833362c7620a51; - addRoundConstantsPallas[169] = 0x3cdd75fd44556c360591584201380b92110e47dfe5eb0415009c79ed6cd765a5; - addRoundConstantsPallas[170] = 0x36136d0311e2ceca4c3fcc913df17116d13c9dc74a3e2c59cf4de69771774722; - addRoundConstantsPallas[171] = 0x156e1ab5a02629168ef489d2e43192e493ddefb2de0935a6f421e456be35dfe5; - addRoundConstantsPallas[172] = 0x20c778cfed4a7c97659133fc66edd807b256c638c1fbf31ce0c8903bc31fd0c8; - addRoundConstantsPallas[173] = 0x3abfb52bb6f5db9194bd20b9bab4def552d0133826db433bd1422b329ec5d755; - addRoundConstantsPallas[174] = 0x1010bed204759ef0014ec85de7c92783e4988f416aa0c2e04e806eb0f526ff0c; - addRoundConstantsPallas[175] = 0x1a5a92fe67d7e7782490ec18086dbd25a6af332ffe045a7918205d60a0700949; - addRoundConstantsPallas[176] = 0x11e4b4d2584578a8a5778fd8fc1ef679ea95565bc08abc55cebc6cc619954086; - addRoundConstantsPallas[177] = 0x11a0e539fb6fccb081869e6d4b9dd8ca1a52c13ba56f3607a003efe2fca7ce39; - addRoundConstantsPallas[178] = 0x30a8105c82245ffa5dfe16ee6ef7ac783c1282f6059601c75106c700b026aa53; - addRoundConstantsPallas[179] = 0x1a271bbb5bf8d3924d4020d7041c53e6e0dc21c9419ce4f46eb2aa3765f763fb; - addRoundConstantsPallas[180] = 0x123e3e5885231c480a31e4230752d4dd1a726cfe1138ca70dcd7e70c5096f169; - addRoundConstantsPallas[181] = 0x185e4f6d71c4eb24ebb333f638039d7f467617064525c2fe9fb3c2d4acb1c400; - addRoundConstantsPallas[182] = 0x15d09b838593b83dd83e9585521720b3cdb217d57b656ab5c28f8dd1c856a5c1; - addRoundConstantsPallas[183] = 0x137c24dc65f93bd9a60cfeb52278adde113af706dc11ad73b807bbfcfa0ff285; - addRoundConstantsPallas[184] = 0x1a82544241d9a1263f64de80c0a96cdfb590634b96ab01952458f815c8a995bc; - addRoundConstantsPallas[185] = 0x0173a252a31feaf68e836b89f58e3b9ac35ab983a1cf82547c56a955681e27d5; - addRoundConstantsPallas[186] = 0x29626b2396730c494b68b6023593c0fc6b35098797897d37967b66e2811bc28d; - addRoundConstantsPallas[187] = 0x2820aca99a03b0a63bcd78ad9972f87bcab2d93bf409c4dcd435ac90f652bc58; - addRoundConstantsPallas[188] = 0x1eb32a383f88036492fe457b86edfe35219a999b58f0bcca3bfd13b93a13b79f; - addRoundConstantsPallas[189] = 0x03a1ce581cf2ead479f7c1d529447ec2c46488bdbd95ee66ac66bb3e295a670d; - addRoundConstantsPallas[190] = 0x24e85ac89e8f083fc721ddd5631ca8eb0ab161e037d10d536eafa6d84a0406fc; - addRoundConstantsPallas[191] = 0x289868f08814395d9a79b7d0884ccf1431561542e1073952e5362f08c590c2ce; - addRoundConstantsPallas[192] = 0x2edd6f8c793bc7ad374fd1acb1da5d9dc8024932c3e57a2b4e8019cdaf9e9601; - addRoundConstantsPallas[193] = 0x22d9342c27020c5540e7c3bbc81b4385e52dbf5cfd268c282c3aca4d77cf8766; - addRoundConstantsPallas[194] = 0x33f985cace8a80ebec665fc19d54222bf8cbea6fea3652835a4ca0f8b76ffc28; - addRoundConstantsPallas[195] = 0x26b27e3d5d7db0082151c889f6fe206689e78c077a17be5796ad4b9afa99abc8; - addRoundConstantsPallas[196] = 0x39fde2c8e333a14f6fca5fcdb252a632319649d2333d5badb0264979d1ff814a; - addRoundConstantsPallas[197] = 0x18def914adfb3c3bf6a9447651c440d988fb273c80d45adbf0173fb726f71e53; - addRoundConstantsPallas[198] = 0x0e61f475e36092ec3d0d6c33422b78f515edef9f1a43a5a3bd4e298b8687d648; - addRoundConstantsPallas[199] = 0x319f8ed6e86211dc01737aaa5ce478b698c6d16889ab55925aea6dcc4b5ceb17; - addRoundConstantsPallas[200] = 0x3086954b9274aae4f138c6c71f608cd2050fa12b71aa81259338c7db8146b1d8; - addRoundConstantsPallas[201] = 0x127380e4c0a23bc75aa38f31a2a0c5989322d05726692b986ce8dc9cc8a965ff; - addRoundConstantsPallas[202] = 0x3619a867d17256d40399cbe2950aa4ba8a3b473ee9d4437850c96053758a89b2; - addRoundConstantsPallas[203] = 0x020e6edcf77dc0b72b7a68d1904319116153d1bbd41ad36a89e40d44cf4bc541; - addRoundConstantsPallas[204] = 0x25720931ccd5bc592ec47d14c5153453849f8b5ea90032e829a9b54f4001527f; - addRoundConstantsPallas[205] = 0x0449065c15e715b6385fb3c8c6379aa11f97f50aab487b3edd98394284a1f0ea; - addRoundConstantsPallas[206] = 0x0b83a107fba1858325f91fae7596939eedb65e3a6088dfb51c7f3a412e879263; - addRoundConstantsPallas[207] = 0x352ab16bb044e9000dce4d03716249d1b364651cb50d7e500752eadb7becb46d; - addRoundConstantsPallas[208] = 0x1698ce9218ec93d1bff280519b70a5cf62fdff474c7e951b38af907c7f9a65ba; - addRoundConstantsPallas[209] = 0x1008f5c2b4424b4a2f4696ce18359a17ad109438144c672e580314c83b723b59; - addRoundConstantsPallas[210] = 0x0349c3f72e489d155b8265f5c400798301ba564298f378261c212e791a0d3042; - addRoundConstantsPallas[211] = 0x3047ac23507ef50cd6ea3f9f83bed5e2b79fe91d5ee494a009ec101e56f4d630; - addRoundConstantsPallas[212] = 0x023bf7311b640f99cb5360b8adb078d378b764326e03b6618338fd1dee13b0ae; - addRoundConstantsPallas[213] = 0x3d479ed8ee7db60f741a6e4d27cfe0a27372f814fac7805af99af267cf1da9ac; - addRoundConstantsPallas[214] = 0x066b01af4055bc799dc20cd312d58038371f308af4bea50b5d57da2ec3b8b68b; - addRoundConstantsPallas[215] = 0x1106fd62d5d281710d201c68248703bdb1fd14c84ce00ef45f868a34b8fe9d66; - addRoundConstantsPallas[216] = 0x3e7ede20b6918fe8ec7c00f6ed3ca50fb059b61c97148a6d6334c208bd036493; - addRoundConstantsPallas[217] = 0x088c741f0f2313a22bfb7b89f7797b65d472f1347bbbcff191924e40b22dcb00; - addRoundConstantsPallas[218] = 0x3ab484b46615db7b093ec38e153c9ea084ebb965e53418c202e4bc710ea7224f; - addRoundConstantsPallas[219] = 0x0ddf21c5a4e22688096335d29bd112c605343576bea75c5149ba4a2880b81ebd; - addRoundConstantsPallas[220] = 0x132935a20ba4fab52f877d87314641eccfc75f542085ee2d9153bd33f8bc332a; - addRoundConstantsPallas[221] = 0x2ff7073570d45935501406b0d74c51bc9e350b2009436597f4d8d0a5d640ce07; - addRoundConstantsPallas[222] = 0x191f8bc99c837639e95711bc0b418ad4540f67d940b28a03fa6b23b54b7f20a7; - addRoundConstantsPallas[223] = 0x3e5d17f30e5012d44eac51ba54ad485216921dc58b56d825ae1d631c3c14bf32; - addRoundConstantsPallas[224] = 0x3c15b50b56a9a5309b0f227c09071213b11fd9b118bfc039b199434ca4043103; - addRoundConstantsPallas[225] = 0x38407bc0db552eec641f87129dffed6419d5d6803ad7551c6de4cb904fa55335; - addRoundConstantsPallas[226] = 0x278c6fc7c98997650ddd55d1d471360383e5182aecdd9260159bfdc105b46ac1; - addRoundConstantsPallas[227] = 0x3490f278b5e4d52352e294dc5b21e9c31ace883c015214e345c25c801b8bd1bf; - addRoundConstantsPallas[228] = 0x3b5cd93d1b1777c3fcc83053a997215cf34ad53ab5724c3887f1b7f43563bb2c; - addRoundConstantsPallas[229] = 0x13a84a8007185494b19d4f01fc9c4217dee38335d36ed0f72f40c5ff87da23ef; - addRoundConstantsPallas[230] = 0x0d543d2b4fb8223aefb5b9688087cedf28e0a4257e5b90005d9275ed9163ab1c; - addRoundConstantsPallas[231] = 0x28f3d6b2977d72f78c723d89945968806b54ef713aee3420d3348bae64c5c3fb; - addRoundConstantsPallas[232] = 0x1a0ebd729cecdd3490f22ddfe34a34fd43e1a88fa1367c48555afff3527e5c0d; - addRoundConstantsPallas[233] = 0x1104011e6e75b77aa07c336c2de0835a022f0d67d58a31030895822894c3ad96; - addRoundConstantsPallas[234] = 0x28e210ff3062240103de262cdb6850509a747acccf2b92f93ff5706d606cabb9; - addRoundConstantsPallas[235] = 0x2da27906abdda9b88f723767444868569e701a93e121d8f2c1e684c6546138c7; - addRoundConstantsPallas[236] = 0x2ab70f1634b85b12206346323d83f69463d7b87615bcda31e7e802f9bd64a257; - addRoundConstantsPallas[237] = 0x1006372ecc2592ae17dea81f40b4002dfe10089b2a7b8c5ba053f5b3b213cae0; - addRoundConstantsPallas[238] = 0x0e3793fe349db78ba83bae1dd7ff7b0ada08aea4de24256e84c1c0dc1584c648; - addRoundConstantsPallas[239] = 0x3f8e70e02cb2b106e9a642bfae82a78ab9c3fd37e043951604bf48d7ab0b600d; - addRoundConstantsPallas[240] = 0x30dbd0636e3e02d0e304e31edb0e15f0437589e7997f123070f9229dd76e49d7; - addRoundConstantsPallas[241] = 0x34a2bc74636323f23f2bfb0da0d3e5c05a6232e58d760546943f14ec4f8e68ef; - addRoundConstantsPallas[242] = 0x154b89fe2537bae74899861bf2d077d400d3b43456bb4a9256f986a8edb4b4a3; - addRoundConstantsPallas[243] = 0x30d33867b0a1d8c79a0c32416c6794d1b8d3465f2e3663b590cf3233ab2782dd; - addRoundConstantsPallas[244] = 0x0276c7dcfba3dd0fc518871b52e21b3909ba644ab2dc902fe2c4f079e4acef51; - addRoundConstantsPallas[245] = 0x2849cb8446f08c66736a1931eb19f7425412196fb3f0b8ae69a96c65b5bb502d; - addRoundConstantsPallas[246] = 0x2c6708baf67cab362ae31f646b7a75999980b31769456fc5a1b33a7ea8eafddf; - addRoundConstantsPallas[247] = 0x3ef874815aa9d2101ae7be493465f2aa0e6a635f2b0f40678493c3d4a332317d; - addRoundConstantsPallas[248] = 0x1c72f4d00c3ddfac7783246cf0e35710af0c77cc135e5e376f449e8ae6702543; - addRoundConstantsPallas[249] = 0x00ed085a81458e00731ebb3ff6e36c0d17a834ebd09873b02f4e7da876710591; - addRoundConstantsPallas[250] = 0x35f35dc87e5a06e94f71e09dc2a1ebd05156e25f631a0c38574a391b84ae4f5e; - addRoundConstantsPallas[251] = 0x31febe7d2955555c559e965a618b0e3dd6479f8d7229f1ba5d12bb5e6d80bbc6; - addRoundConstantsPallas[252] = 0x326cc5e0749a005039407421a8606d9eda16c4feaa0f6b8fb7b18bb79d58d357; - addRoundConstantsPallas[253] = 0x18204e3bfa00eb65e4f6da569bd097173947ef2c6d577477e25c95c51f2d7f8d; - addRoundConstantsPallas[254] = 0x218b4f703549de84752155afc8147fa035219b9bf50d559b86bf0b637c310c92; - addRoundConstantsPallas[255] = 0x387d30659687f9121f1866125a1a45b58871355b79fa6cd580b6d763eea01d79; - addRoundConstantsPallas[256] = 0x1fdf2408f37a4a0cbe5729acdf3955fae9dbb82cf2571a8c91bc9adea8a1c3a5; - addRoundConstantsPallas[257] = 0x26c76e0f672650540e3a4de95b9c593e3f759d9938c2bd5343f0fe1ab0f894ed; - addRoundConstantsPallas[258] = 0x0fae088826da30ed29252fe40e299d3f577e8815c0686af6b9edb156dc5eebc9; - Pallas memory pallas = loadPallasConstants(mixConstantsPallas, addRoundConstantsPallas); - uint256[] memory mixConstantsVesta = new uint256[](25); - mixConstantsVesta[0] = 0x2b851eb851eb851eb851eb851eb851eb9c6d7244fc465e59366daa20ae147ae2; - mixConstantsVesta[1] = 0x33b13b13b13b13b13b13b13b13b13b13ccea407ccca94d507b259686f6276277; - mixConstantsVesta[2] = 0x12f684bda12f684bda12f684bda12f685601f4709a8adcb36bef1642aaaaaaab; - mixConstantsVesta[3] = 0x19249249249249249249249249249249320972f54ce81dc4c0406ea864924925; - mixConstantsVesta[4] = 0x0f72c234f72c234f72c234f72c234f72ca7af8ca13f7bed45fa72fed7b9611a8; - mixConstantsVesta[5] = 0x2444444444444444444444444444444457b089e4278ff94a58060dc5e6666667; - mixConstantsVesta[6] = 0x0c6318c6318c6318c6318c6318c6318c69bb155a125ed65c6dbb2540318c6319; - mixConstantsVesta[7] = 0x3e00000000000000000000000000000021346434294803969fe4b3c7f8000001; - mixConstantsVesta[8] = 0x20f83e0f83e0f83e0f83e0f83e0f83e109e64ecf69c8b4150a340c855d1745d2; - mixConstantsVesta[9] = 0x01e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e2e3f570d31af5e8660215f970f0f0f1; - mixConstantsVesta[10] = 0x3a83a83a83a83a83a83a83a83a83a83aa2feb7c1dcdfb05587914c00ea0ea0eb; - mixConstantsVesta[11] = 0x3e38e38e38e38e38e38e38e38e38e38e5a366a117b17a42cba28810ac0000001; - mixConstantsVesta[12] = 0x03759f22983759f22983759f22983759f403d0eb076fd1c6c94ff108b3e45307; - mixConstantsVesta[13] = 0x0f286bca1af286bca1af286bca1af286c4bfe0dd6095bc3478cd6d954a1af287; - mixConstantsVesta[14] = 0x0d20d20d20d20d20d20d20d20d20d20d27d9f7ff2fe9fb412356c0a44ec4ec4f; - mixConstantsVesta[15] = 0x0b3333333333333333333333333333333932c12c1b46d0c05ef2cf8c2ccccccd; - mixConstantsVesta[16] = 0x1a895da895da895da895da895da895da9793e80499d37e3665def7589c18f9c2; - mixConstantsVesta[17] = 0x10c30c30c30c30c30c30c30c30c30c30cc064ca3889abe832ad59f1aedb6db6e; - mixConstantsVesta[18] = 0x3594d653594d653594d653594d653594f305860896e79f3c7570f47ae23b88ef; - mixConstantsVesta[19] = 0x38ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8d89007999420db7e8dca7ef485d1745e; - mixConstantsVesta[20] = 0x182d82d82d82d82d82d82d82d82d82d83a75b142c50aa6319004092e9999999a; - mixConstantsVesta[21] = 0x121642c8590b21642c8590b21642c85914d12b3c18f7ecf0b2c6210ee42c8591; - mixConstantsVesta[22] = 0x015c9882b9310572620ae4c415c9882b93cb08b3a90e0e7c8b27a2f5cefa8d9e; - mixConstantsVesta[23] = 0x3eaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacc3a75cc1eb6e558eeb01b9050000001; - mixConstantsVesta[24] = 0x29cbc14e5e0a72f05397829cbc14e5e0bd915eaf0b7b34cf60d57f6e5e0a72f1; - uint256[] memory addRoundConstantsVesta = new uint256[](259); - addRoundConstantsVesta[0] = 0x2c21df040fb486eda5e1b307392ad7917e2ae2eff450fd49a0f58b056dceb6b1; - addRoundConstantsVesta[1] = 0x06dd0930c41e65275f824307c57550b7712f02affcc2b202ff65458152f81e5b; - addRoundConstantsVesta[2] = 0x0f86feed14cf5ca45e38f023fe7d21bfeedab7cbc8ff68a194eb462acb868fed; - addRoundConstantsVesta[3] = 0x04e38ddcaf70374cd798d71b838412f3b685c12d0b8567ff1a849694626c0136; - addRoundConstantsVesta[4] = 0x3137015ea0699e21dc15eaea588aa6476babfff62c69a648930d6f599dbfd98a; - addRoundConstantsVesta[5] = 0x27b4ee7fcad7373eaf24dcc0d5ca838d5b2b67ffcc30320f913aba0099ba23b4; - addRoundConstantsVesta[6] = 0x0b25d3b8417075fe6fa1819f8252912b7cc2642c72e225dc6c3e59eb1014cb39; - addRoundConstantsVesta[7] = 0x1077a74d28bec60bbcebb879ed8778209a314827fdcbb838cf5fa396844cc744; - addRoundConstantsVesta[8] = 0x3020f64d9081ab756563512341a3cad5f74fbc0635421032ad15e8b0592d8f07; - addRoundConstantsVesta[9] = 0x3bb4d029a81d20c6c79f657b080d30f65ecd31d3ed47c963709364dceb5491ee; - addRoundConstantsVesta[10] = 0x3446e2e18ae8f55e4e51e1f8dcc93a0733dc01d37c68ff39773e6f18024953e2; - addRoundConstantsVesta[11] = 0x20193dec48c8686b543bb3561193df86675a449f01dc1daced860373f3b0ca07; - addRoundConstantsVesta[12] = 0x38767b551e6ab98296fb149d39792dc00ff333ab99562a5f5859cffd00f4127e; - addRoundConstantsVesta[13] = 0x22e00037b03a4bff29c042f5d5a5f66220f0296895d6699250b8820ba904e947; - addRoundConstantsVesta[14] = 0x2340cc0dc53743a48dae0f62420598c543b1ccd9b06885ab90c5bee68697de4f; - addRoundConstantsVesta[15] = 0x0912c078ff3316f34d17e8fd81dff91e754d03f2e71c2fc0077c8011a4c0a43b; - addRoundConstantsVesta[16] = 0x1befc1dc02a5153ccf17fa1fedce0e141a5639414d37190d03315d1a93376874; - addRoundConstantsVesta[17] = 0x2da148454a1783e8da2944df41c285ba76426d7dbee627d1c17af160d1bcce01; - addRoundConstantsVesta[18] = 0x1bc7f3d8f64effde6c9cfac1fcabf471d443ab4106c85c3d7f0e671eba1ac20f; - addRoundConstantsVesta[19] = 0x3d5a6dc890f4fecf6d3a9960ffc6d6754a5dbf88a0250e3358aa40ce63382ae0; - addRoundConstantsVesta[20] = 0x1f569abd6fc91f4a5e009ae3d8a6d0170ec74c986ef91d34299681e90aac79b3; - addRoundConstantsVesta[21] = 0x233e1bf16944f2889c616777c1b072202e42b7b216b8d4c9973157ecea58487a; - addRoundConstantsVesta[22] = 0x091c5fd8c64a3fa466d33c38303cfb0f07c141e4a8848ef899fb91385d62eaba; - addRoundConstantsVesta[23] = 0x3bdac8c3cda0b615c6f58c0d16ed58b8cf349b69f101925881f8b62d1fe6ca91; - addRoundConstantsVesta[24] = 0x02d9fc7d215eab28d1fb7c066fb9cb0c590ea899c10b3bd7a94394a732a23584; - addRoundConstantsVesta[25] = 0x2c3daf6894c6247f888c2adf1ec1c96716216607cfb8f801ca99edb7515ef12d; - addRoundConstantsVesta[26] = 0x155b798c6118e0e9199c7f04aa8db34040dc0339e2e535f3cec00f6f285511d6; - addRoundConstantsVesta[27] = 0x326241490c964a127f404e36b4e332a0e1221b1723300a715624adb3d7ec9821; - addRoundConstantsVesta[28] = 0x26e9e5f094dc8f13ab8a435546984a4b0c44f4e87dd75c107a77cdbeb86353fe; - addRoundConstantsVesta[29] = 0x3e1ebe95f9b39c756e479c6e45c93dfaff11b575f6bce97cc33a3d7db2542523; - addRoundConstantsVesta[30] = 0x1444881a36bd00d5a4cb74ac125b08bfa2ae2d5e3bc8ce593e6edf5f8343fa89; - addRoundConstantsVesta[31] = 0x016e1c17e920c651f8e1c869dfb7c3d52284b8e823fbdf52e777862f44b1155d; - addRoundConstantsVesta[32] = 0x3faa821966458c11824dd8e8b2854fcfe4054ba76a6a21b9e6914ba5c311c4b1; - addRoundConstantsVesta[33] = 0x04f2f9afa78f9a599fa92f9a3f2a4536aa04f1d99b9024476b0435845bc5201c; - addRoundConstantsVesta[34] = 0x1dfcd217a424d9d8cfbad9815a43fd0bc0f6b9b5625f1a4a26ce894ba7a5b83e; - addRoundConstantsVesta[35] = 0x354c4906623bb525d4caf2bb95d36ce7c818a4c62730a63c1cad213df32a0a72; - addRoundConstantsVesta[36] = 0x3f6320d62cb9f75a5a77c104b06e76403070999ca7aec73d6dbcbc28f56710ae; - addRoundConstantsVesta[37] = 0x01b9d7c3c011ce1009d07dfc178fc581c0e7cde9cf0fd2ca4dfe9635f7fdabde; - addRoundConstantsVesta[38] = 0x0d656d34ca837a7a36462697c112570527b09b134a0fdd07f5cd3dad19495c85; - addRoundConstantsVesta[39] = 0x15ea42a51406e8970c9e505122dbb679860b83eec9e4037bcbe53a09d27eeee9; - addRoundConstantsVesta[40] = 0x21812179af5903c8f86ed6d57bb7d52eae6c9e62cc3541fed668210ae9fdb798; - addRoundConstantsVesta[41] = 0x01d19a758ae249ef1b3e35a97c7bcc6b630f5cb00a29a515c4259804f60583f6; - addRoundConstantsVesta[42] = 0x09bd68b6c10bbaa68e4e112954953824bb900e6435f93c17d092387d34d43736; - addRoundConstantsVesta[43] = 0x15c517139bfa28614a527becccec0b32fca1229763d7c37c74a1ed190eb2d889; - addRoundConstantsVesta[44] = 0x2aa90b69569c4a140c80c4d5fd64855101cefaf774ee30ba513865a4302d0e71; - addRoundConstantsVesta[45] = 0x1b23f17614c5dbb4aa6062bd1f721957a6c91f77807877d6cc44e58581d31c7d; - addRoundConstantsVesta[46] = 0x33340e2fdd946748fe51391c4d0c6810b03d5d99120a8ef96004cc56c8a725e0; - addRoundConstantsVesta[47] = 0x3cef4ef2d1cfa679db174e0ed76ea5e38fa79361e7f6d432c497149316409fa8; - addRoundConstantsVesta[48] = 0x26a1505997e2ba88e6aed8d10ede4db2c30ccd0f5b2d9cd1ba45d277c9992a25; - addRoundConstantsVesta[49] = 0x216d537b54f5b9e88d18037e4ea7a2731853fd16bb321dad31b27f73242d27b2; - addRoundConstantsVesta[50] = 0x1b9d858a469520f02b83403ff339f3c3477f214657e5ba8273b935d0c2b7689a; - addRoundConstantsVesta[51] = 0x04cd5e84d0c2862f4cf057a1a628effa2e8ea8d34fbaf6522a3311c83dbc13dd; - addRoundConstantsVesta[52] = 0x08fe98fecf890c429be465e344231974b85012e06099af18c60da8f75fd56bfc; - addRoundConstantsVesta[53] = 0x3214e96584c1d05d07193aecaa1d1a84c93b3ed517e38be37c45e7c4ba4be7b9; - addRoundConstantsVesta[54] = 0x18dd4fb0f5ce6d50c2d53c73dab90fa27052580039e5553dd1c8e151045bf67b; - addRoundConstantsVesta[55] = 0x350efc2bbcdf97b0aa9ff6d09c035e087d633bddf58dadbb48bc7c4703baf14a; - addRoundConstantsVesta[56] = 0x00e6837287cc25e9fb09fa9aa0cdcb823c0295a881d73d5fa032d3ac9f02bdf0; - addRoundConstantsVesta[57] = 0x0211cbcbc36bd8a66396885e8f251768da612fbc3636770a75bf9d5d9a677e66; - addRoundConstantsVesta[58] = 0x0d14ae1ec7bb3ce07ac50a8d9aedf0d74c77358373e7b92790d866785bd33048; - addRoundConstantsVesta[59] = 0x1259b23d0fbb7ad62177bb025bb1a1a5f62e9bee142d9d0622e1707ca71607ed; - addRoundConstantsVesta[60] = 0x2610c1cb844a3fd709b98d9ab7760fbbfda77ef14f45b02c9c30e0e054dbfb08; - addRoundConstantsVesta[61] = 0x2d03e8dccf9ddd1046265a7673512273efac04cf646ecc98ccf5b2f0b0874629; - addRoundConstantsVesta[62] = 0x107d5d8e473a5e8f638ab7e1b22829f891f0e0819c8388659461dcacdfe98c7a; - addRoundConstantsVesta[63] = 0x236518c7cb4b6837b83c1b4b9a5e9164f50cf23650fa91d6da07a92c19677fb4; - addRoundConstantsVesta[64] = 0x0cdf11eb9056943c6b14ac059292c94cf817667b7dbd5c1220038d92399b77ce; - addRoundConstantsVesta[65] = 0x1ad01b3ed0a133969c2804d39db07e9da53af3244647412dec221e3a4c577c34; - addRoundConstantsVesta[66] = 0x09f2e33626b1e9aaeb23d541c28a33b366c7270b81b6943ff5735e763ff15b68; - addRoundConstantsVesta[67] = 0x17db7933fcc53fa59b7d2ec374a4cd1e22322bb13b7eb613b009e87356d991b7; - addRoundConstantsVesta[68] = 0x2b6019a5a5230edf078e80bf5910cda742d5b0c58c3e18a617fc38b4a0d04b61; - addRoundConstantsVesta[69] = 0x34712163ff28760ebfce63fe8a19d9933f0a53ce45d5a830376222f1aeb461a8; - addRoundConstantsVesta[70] = 0x05f15613603a7816df61ec3921810f907d046a112f33ba669289a82cfab8decc; - addRoundConstantsVesta[71] = 0x31cc4da76a63300c108547fd6f827af7a0d6d913c36afc227c49d667ca02658f; - addRoundConstantsVesta[72] = 0x29d5d7f31859f655b5b187568aa49121cef20eb1fb7e324f4a897c771fc2c70d; - addRoundConstantsVesta[73] = 0x2f487f00a180ce98d6a6aee966fbb6e066466857bb753dd6682b43862613aaab; - addRoundConstantsVesta[74] = 0x33d22e0dcad1e9a705b2ea6126ab87d7c2d7fc10c173998404841e639326093c; - addRoundConstantsVesta[75] = 0x13b6c6ca60c7aa032672f46c14f8720f7d90c44ae3d75c60c867648de3ecd6ae; - addRoundConstantsVesta[76] = 0x1a1e23ece73fe89b083edbb50a4a2151cd4f36dca69e56003f64536fd9d845e6; - addRoundConstantsVesta[77] = 0x14d9404da5973a55c2c7ca2478a16e04eb93484a19857ec231942d29a0fcc015; - addRoundConstantsVesta[78] = 0x17ad33c02825b6efa18c128360ebf0962a858118c6b26d543cb8ee0d59204c2a; - addRoundConstantsVesta[79] = 0x0a76ca79bfc966f7d21b15d5fa87d866aed2ab50b461a64bd962b78487e66122; - addRoundConstantsVesta[80] = 0x370aac8140e470cb14b8fe5c11cbae2bf363f9e40db8148a369b7e4b4f4cbe7b; - addRoundConstantsVesta[81] = 0x1d5a01ada129c3417c0980f9dd24ac10cbd0db6faad926fa0c57dcf5da97ec7b; - addRoundConstantsVesta[82] = 0x0e327ad33edba93f38c4d8b6b6a7d34b1b13d8ee0a7ba73ecbd7f2c40799cef3; - addRoundConstantsVesta[83] = 0x07c36b87389dc38688320511e5998aceede8c75922091ccecb27e4018d805432; - addRoundConstantsVesta[84] = 0x1054d9545f9a18880dc774a93e0baa4185f3f33caff1e68f6459b8a4e311b7bf; - addRoundConstantsVesta[85] = 0x0bbd20c5a549ddc0e4ecb4c4531620066efc6448ad1a79b70f48d6bce98202b6; - addRoundConstantsVesta[86] = 0x3ac94f537a91bf2a5208d6751eefcf70ca4b55c9ada2fe825be6596ee53ac411; - addRoundConstantsVesta[87] = 0x194561c289bfe83ddd0235e10112d13b4b5abd09900b166b651c4d03a296f504; - addRoundConstantsVesta[88] = 0x1e94c1628ba60c536009df8275c6e80d7eff37fd1cdf5b49b4e548c8a092a436; - addRoundConstantsVesta[89] = 0x31d7a00c1a72fcdb9c30c39e83b83a87fd5af397c869ef7f301f3d8620c4c5ea; - addRoundConstantsVesta[90] = 0x01357ea0b6a1b87a06d37b92a273b247342c4a750811f8c42d3f8eb46569ae57; - addRoundConstantsVesta[91] = 0x3ed7a84562726b6df1f24407089e54f23914cd9854318778faf1cad5747ab0db; - addRoundConstantsVesta[92] = 0x0b478439dbc4b769339c565d6136d328c4e35d14a25fe4682979de33b6eb6354; - addRoundConstantsVesta[93] = 0x20afa1674fb432d27f0b620d768daee54de65dab3daea2f2002ea4ae0dea07fe; - addRoundConstantsVesta[94] = 0x20e913298705b678ef46e7101cdf57e5a3a4563132f0b7fceda47bfa6d9de6ae; - addRoundConstantsVesta[95] = 0x2306d07251ecf48420baa2d065a9325dcd94e9f0b9f485f590a3c379120e35e6; - addRoundConstantsVesta[96] = 0x39e02d984f9daaa952a2f94216f5af96383e8d390153fd137ad50ac4e0cd5b02; - addRoundConstantsVesta[97] = 0x29299d85f58ce70693976995f0634869ce4ebb0dc6e7c929b76bfc9f04bb9695; - addRoundConstantsVesta[98] = 0x233c69174b475495d2f8654c735692e634a1c19855e9e92e72f701f362f2b0ab; - addRoundConstantsVesta[99] = 0x3bb67f005858ee8c367a52f625ebff357ec7f7fde6bdf5a2f83976b392da8aef; - addRoundConstantsVesta[100] = 0x35b3011402ea772f452b3a1960f9ee6b2957a67ca9bc4bb503dddfc8069b041b; - addRoundConstantsVesta[101] = 0x33ad69afe5925fbcd3c57093eba35ba597875df454b1d23c139b5042654202e9; - addRoundConstantsVesta[102] = 0x3dc6d1e7981a2561aaa265c55a552856d9c35b5dab9189f18f4080bdf99cffd6; - addRoundConstantsVesta[103] = 0x18e499fd89d4c85647123575c2501103db2ecd0da51d0f55d80fed6b132e0ead; - addRoundConstantsVesta[104] = 0x14e5e38904544263e1902013df711d81ac45e655cfa45713956310b43529c361; - addRoundConstantsVesta[105] = 0x061106cb353fc9bec97d7b3f98d2378aa271877172aa9b4bea28097bdb489b61; - addRoundConstantsVesta[106] = 0x11092fd23415cbe3215abd935e2a1ffa5ffd0b3c0d058b5b60169ed7c4d3eeac; - addRoundConstantsVesta[107] = 0x14d9ecefdc93f5095c86e30ab9d10d1aa83bad3c4eae9026d76b1832abf222bf; - addRoundConstantsVesta[108] = 0x0e3f8c8535059ee26f1a3061566cea58a9987bd06cf2f641e75796aaf3c195d2; - addRoundConstantsVesta[109] = 0x1a2b76a4954f888fa1aede5ce6c2b30119e31af2cd38dbcc90b6cbf1340b38f4; - addRoundConstantsVesta[110] = 0x30094e24e3f2700c5d05c12ce3f4578ed2e45a42eec110fd4dbad491895b54cc; - addRoundConstantsVesta[111] = 0x15be10dbf73ade05d742614d5f9792b183739cfa86a7c2006536e83156a05885; - addRoundConstantsVesta[112] = 0x1ac4357cb5415456cda5bd564d603d0f505f41364c734d34eeaac300fb5b5496; - addRoundConstantsVesta[113] = 0x38944223a90f9e2df098113d61b79f242b16fe4c7d159d648846e2cde34196c5; - addRoundConstantsVesta[114] = 0x0afd224f8460bdd9c3cea80ba3a1524d8d673ff24f0306e24e3a2416a4fae220; - addRoundConstantsVesta[115] = 0x1bbe619241c23ea023e558dcb7cbd2dffb2e74b341dc4f4b74cf93496f37ac72; - addRoundConstantsVesta[116] = 0x3b1323873ab78b1cb86a8ce4d11578d97089d03bec4140c55ce08793aa7c0fc6; - addRoundConstantsVesta[117] = 0x2ddc8181ccc20e3183906dc234ceea659cd67b2ddfd1defbd0a48b452ed1e342; - addRoundConstantsVesta[118] = 0x26c679a4ac2bde3feb38cc54a8b2d2ea6da9694a9e3c4da2959a0d93b61bf8d8; - addRoundConstantsVesta[119] = 0x0405bca1164ab2616627b5786ec31bbf857db1b8f17253a9f932f408c2961de5; - addRoundConstantsVesta[120] = 0x2396dab2a87264a2bc6cb71b375ca04e0c32764d10e018fe6bf6b1e9a9c79a11; - addRoundConstantsVesta[121] = 0x37722805a72e6ee6779abaeb32878bfda30cc58e0f88914784015c45d9a00d9f; - addRoundConstantsVesta[122] = 0x313a9649452d30d5aa8e3424f61b0d38a2c0be2aafe249e56e83c8baca1c744d; - addRoundConstantsVesta[123] = 0x3bc411eb3e806925d3f32ec09bef4461ccabe9837daacaf9e1fcde0968e505c0; - addRoundConstantsVesta[124] = 0x3103e5fde0c04d2be30857554de90ddd39834d576e433fe928a981964f3cf3dc; - addRoundConstantsVesta[125] = 0x383c63fadaad7e8a266efd71ea9b7cca3f0d52caf613d1f97dc007107ca581b8; - addRoundConstantsVesta[126] = 0x09006791af596109f85c85ad581902640726353448d72f2f6c8149257aa70ec4; - addRoundConstantsVesta[127] = 0x187a656dc616b20b0760c36e2ce20b8fdf31e14dafbae409107418d4f7e508e8; - addRoundConstantsVesta[128] = 0x0a35c7d2b13de1d8ac8d04ce5bd7e831a810f8c779f07897ce0472c9aa5ddec0; - addRoundConstantsVesta[129] = 0x0b5194ca037d1c71ee5d3b1cc72a19b69fbef617392620447ac8e95a66c68d3f; - addRoundConstantsVesta[130] = 0x35109ddbcf2d31bd928ba8207bae0ea6b03691a76c975fa063d1a2457507fb89; - addRoundConstantsVesta[131] = 0x30a15576d14abfed1323a778a4d3f698a9e304fc569f14e021c4be980de6198e; - addRoundConstantsVesta[132] = 0x0ed3c14a85cc8a4d8b37262376a5cc8fcf82c5cc5a96b49df8f454b100be4732; - addRoundConstantsVesta[133] = 0x0651ee25756af617d3e799d2992b8e562ac6dd293c9605f4a87dfed1fa38a82e; - addRoundConstantsVesta[134] = 0x0c4f2d63bd3fbb0bb4cd774fdcb402626c930c2f400131e9610efee482a9dff4; - addRoundConstantsVesta[135] = 0x315a4d05a1a409e1c201cba4da742a02122fd1d0e95bd094f42050c5b6b1ac55; - addRoundConstantsVesta[136] = 0x1dc8d8c2da046fab43d42e78777edb02d3328c09450188a2a635c2987f847538; - addRoundConstantsVesta[137] = 0x34c05331d6029fb846ad94572c265d6a86f84c63b2afcee6660c261158219166; - addRoundConstantsVesta[138] = 0x23b83a23b50a3ce3773b487ba302d659d5ccd83d068190f00bb465e21eb2048c; - addRoundConstantsVesta[139] = 0x080b4145be1ba5e1aabf2b2a9590ff06dfbb1f6831096a9e38989b696facc28c; - addRoundConstantsVesta[140] = 0x094302f1cb7ab156041adf8777762081a5bba2d095bdd712e352ff1cbf398cc9; - addRoundConstantsVesta[141] = 0x026e15f6819909c0250f39ca66261c8aa54a91c44e849691724895feb6dfaf93; - addRoundConstantsVesta[142] = 0x136cac8ea6bc464e12d94b96f5eca123eee81828d772d99b0be6cf91f52d0f04; - addRoundConstantsVesta[143] = 0x3344d8d37b5ff6a473f4e160a5b52be9afb2c723268e4899007939e0bbf33df9; - addRoundConstantsVesta[144] = 0x3ca55ac746e72daae9c29e57a3dc1bd9ba274843bf5540c7beabd2b5dfd26fbd; - addRoundConstantsVesta[145] = 0x077b5e90ff299dc06f25ce801c4e5495310f29aa67ede5a58ed906532b6b855a; - addRoundConstantsVesta[146] = 0x347438a7602d0719140902cfc35842b5e8eed64b6f2b075cf01a79cf4120f892; - addRoundConstantsVesta[147] = 0x288374d97e47fdea88add959b94ebd6d0f5ed82ed5a5eb70a108f569ef8a6404; - addRoundConstantsVesta[148] = 0x0ae66a7fa58247c45c6d5ddcd6d9ec0889ce0d2fd1ec30f461f3289aad5a9df4; - addRoundConstantsVesta[149] = 0x160cd880e0249e9f30d3a3392ba32311405770ff1ef65c13dd3bd295cb92c3f6; - addRoundConstantsVesta[150] = 0x3f0a76d651b02900adb3bd4e78b1afde28f7249af5b9b6f750db0b356ad49628; - addRoundConstantsVesta[151] = 0x0c2dcc38936f920db1f5c4bd637ed85300f56b59774bda5bc0820ed87c6b8037; - addRoundConstantsVesta[152] = 0x043f75019088a886de1b23b971442658042007e40e64d143356dee574e6f8b32; - addRoundConstantsVesta[153] = 0x1f13e993db5639d2c4249eb669f18237502bd8a8a7f2249f0e6ebd6c09228920; - addRoundConstantsVesta[154] = 0x19d2840e3c5f982afbcae2ca45b4f47c3f3586f85c7256336617057e848578db; - addRoundConstantsVesta[155] = 0x322257affd6b4574bec1efe8392e30df07611d2360e8f5cc96b234d896fc0ffe; - addRoundConstantsVesta[156] = 0x00a3015b68efb3338e4eacff53829a07f9d7009fd877e3f8a593183a9aaf9417; - addRoundConstantsVesta[157] = 0x053270e6946f488fce8497be3fe0636d7fa29dfa3d83e79d4f59751432ec263b; - addRoundConstantsVesta[158] = 0x1ac3b57d4e942d527060856baca33604091dfec97254cad3ca6461f282104f62; - addRoundConstantsVesta[159] = 0x092971ead15e64c8cd5d75a5becb13578e400c5d732385a048d5f96ab15e8434; - addRoundConstantsVesta[160] = 0x237cd7439b2da567c2c2af2f64f16915dc54fe294780e7409ee6fde118d6de7b; - addRoundConstantsVesta[161] = 0x2b2b8067cebd04628bbc16e794840dc2b2ec95a19e0a3202321392e7dc6fe0ad; - addRoundConstantsVesta[162] = 0x1348788c8cfe28cbe3ac593fb07a7f7527a0d385b7cb80e5ade8f28522e06663; - addRoundConstantsVesta[163] = 0x1dd8d9a1ea0b48d25fd9d88531b252c90ced231763b3c0878e7a104951277f19; - addRoundConstantsVesta[164] = 0x02cbfc36f959e99ee4fef13db6a22d46e26728deae7c863099adabc0ab9893be; - addRoundConstantsVesta[165] = 0x33417aec8c1100c029236cf54e6b2f748c73368579dec4c2efef47e987289f83; - addRoundConstantsVesta[166] = 0x317e5c49b7dc40b28fbaee9677ea53e11aa4d977345c41e1cbe3d5957ce8fe84; - addRoundConstantsVesta[167] = 0x063f42673c6d5714047ab4c5771004c7492c19c96afb223b8cb708fa0b2670b9; - addRoundConstantsVesta[168] = 0x3e6becb6b7aee6d1bc8c7404dcfb5ee89162a434b4b27ef82ef4a45fb911a6ec; - addRoundConstantsVesta[169] = 0x3b92e3ccdc64e39f2d359c5c05f52bdd0a213868d618b4d99c2239d4dcb35d60; - addRoundConstantsVesta[170] = 0x0c11e3984e345899e4b662c5928bd388eb1b0a6a5f8b4f466385b8a543322e4d; - addRoundConstantsVesta[171] = 0x2497542e2330fcc6989fb1e1a4ca342cbd6b90170ba756de026abe2122f0b784; - addRoundConstantsVesta[172] = 0x15e4aeb4722a4a9d0d4bec3c9e5d01dafc44b0c940d755db19d3afa10f43a5e8; - addRoundConstantsVesta[173] = 0x1cf5ff517ddd41ffa473cf1c7918969b6c6758aacd59db201d8f72145c60660e; - addRoundConstantsVesta[174] = 0x0961b111ca3b537be9980c1c92c993f2a9a8833cf4897d28be8bacfadb19775a; - addRoundConstantsVesta[175] = 0x03588fe15263a98d5ba09be9a8403a941bfe6dfd39d75c752c29676e065734ad; - addRoundConstantsVesta[176] = 0x269c5d85a8e0c0d0171a914339ec7f2249fd427d18d6902ec4cf6430e642579a; - addRoundConstantsVesta[177] = 0x205050ae7ccc4717a75672be5fd0237758cdc040055cb19c0893f0f99a5c4958; - addRoundConstantsVesta[178] = 0x3654fbe001f53a12f30cfc3f2b7176a535af126649f0da84326697cf167c7483; - addRoundConstantsVesta[179] = 0x301c645fd7225ed7be11cb13e550a43166c164008feff4f9b7970e7dc884d900; - addRoundConstantsVesta[180] = 0x2289690d52e4aae6184f33eb044b955263bcfea3bb4ef3c4fc013042fd4d7ef6; - addRoundConstantsVesta[181] = 0x25071458074dabfc224cae3f22abab0e29cd7fa8d32b35c6f15a71f5e845a27e; - addRoundConstantsVesta[182] = 0x131f7fd480359d2101c9810693657f925f4352dc98a1229a2d7a49024b7b6d44; - addRoundConstantsVesta[183] = 0x137c24dc6616f849f69e495ef55a1c36a162995bf9cd4d81e8c43130fa0ff285; - addRoundConstantsVesta[184] = 0x1a8254424214c687e6b8d4890bb12e1c0b9a72ba5bd1919297c7d6a5c8a995bc; - addRoundConstantsVesta[185] = 0x0173a25298507319460f00995491b6a7b638f8fdebb8832a1358d919681e27d5; - addRoundConstantsVesta[186] = 0x29626b24845077b3f8057181970ab0b5f9556834018b9bd9b797f686811bc28d; - addRoundConstantsVesta[187] = 0x2820ac9ccb1d80ed7d4fcf985d64edc75bc9e06a00aed214fd23bc70f652bc58; - addRoundConstantsVesta[188] = 0x1eb32ab48c76050fee4536119c70a810accd395b3f80532715b507c53a13b79f; - addRoundConstantsVesta[189] = 0x03a1cacf79352bf43f5dce7828f2456327cdeb269a0b36770a5138e2295a670d; - addRoundConstantsVesta[190] = 0x24e86ed71420f03240fa5ccc22b947e5f7b860eed5d0c5986138d8084a0406fc; - addRoundConstantsVesta[191] = 0x28980dcfe99a45c57eed5d364db000fd28781aa3c9d24a72eb3629e0c590c2ce; - addRoundConstantsVesta[192] = 0x2edec118abac6add95ac903bd4108491f574a42b148f44c5684d7089af9e9601; - addRoundConstantsVesta[193] = 0x22d52b94b2e26708cd0528aa96c74266f853b9204f62c70f430bc68577cf8766; - addRoundConstantsVesta[194] = 0x3403ce66ba1e14c7109c8afe753ccedbec8f907aa41af0c10e11e898b76ffc28; - addRoundConstantsVesta[195] = 0x269c81e0e4e34533875a1eaee82a52459648ad5b550da72421c361bafa99abc8; - addRoundConstantsVesta[196] = 0x3a2572ced1eb4bccd0d28888e6608e50f3a4c803f544b4e81ee305a1d1ff814a; - addRoundConstantsVesta[197] = 0x18a2f61c952b7f9427e9012d197c8efa46f846ff1e770fcf8cfe991326f71e53; - addRoundConstantsVesta[198] = 0x0eaea541f2b481746cdc5900970dce4186f7ecda8ab7355f67e16f2b8687d648; - addRoundConstantsVesta[199] = 0x314d37eb57f2f838deb6006ab4187a163fc9d91ab11ba5ae383cc0784b5ceb17; - addRoundConstantsVesta[200] = 0x30d078c4429cfb350d931b7f8b4f734434fbbbe94fbd68764561e77b8146b1d8; - addRoundConstantsVesta[201] = 0x123c88de6f677e497474638b3eec25494117d58662500e943434c568c8a965ff; - addRoundConstantsVesta[202] = 0x363b286e5ec504445e56e87e96d8cd677fdb14b3a70b666260e9137b758a89b2; - addRoundConstantsVesta[203] = 0x01fdfe42e1d216c64e7cc7d583a44d35336b7b2812b6fdea226e9278cf4bc541; - addRoundConstantsVesta[204] = 0x25785f12e20c1e266aa970351dc2ed7077a1da5096ae8276b3b2e49b4001527f; - addRoundConstantsVesta[205] = 0x04472dd860f4cb9256c77279d224c9510a162ba9c9e7817746e709ca84a1f0ea; - addRoundConstantsVesta[206] = 0x0b8402d8af5e4dfea99e4de8983466d76d2ddde966c9f70253ff325d2e879263; - addRoundConstantsVesta[207] = 0x352aa49a0759fc4bd8a4ccf37af6f2ec8bc3eef9ce407f677b54ddff7becb46d; - addRoundConstantsVesta[208] = 0x1698cf5ebc80000e8335c145f3a336708bbd73796029ae6c3b82a9e47f9a65ba; - addRoundConstantsVesta[209] = 0x1008f5c2b424fbf698a9fa97c17917fcc699429e4e41e697c64713dc3b723b59; - addRoundConstantsVesta[210] = 0x0349c3f733a13de52ab189d6be7068d5f3e46f5d2a38fd4f87d3cce11a0d3042; - addRoundConstantsVesta[211] = 0x3047ac22db1739e1339d16ae15597337e7302b040a10f17da3f481de56f4d630; - addRoundConstantsVesta[212] = 0x023bf7376ac6a632e720c1937ef7fa383c7c10fb9b5f5de67e452975ee13b0ae; - addRoundConstantsVesta[213] = 0x3d479e9bcd7e35b58ba9e742154bed06261cfa9dd9b0b819309b39d7cf1da9ac; - addRoundConstantsVesta[214] = 0x066b036b60e1f6573f7a9f71596c89f3e932335d353b7657f5903e6ac3b8b68b; - addRoundConstantsVesta[215] = 0x1106f38e3b460687a9d9d99b68231f6444d8f96e4eef770687bd1c6cb8fe9d66; - addRoundConstantsVesta[216] = 0x3e7f0ab90824c5db211910fb7b8c8eaad93e7677fe517ce9b774b664bd036493; - addRoundConstantsVesta[217] = 0x088bcf2f66b75b1bc74bb0b721b88c79ac210030303d32ee48c23120b22dcb00; - addRoundConstantsVesta[218] = 0x3ab67c8736b58253868aa240578f9796249616f14abb441738fc593d0ea7224f; - addRoundConstantsVesta[219] = 0x0dda1f0f78b39a03d4df50f1d16431f1147de8671aa81462b389f54c80b81ebd; - addRoundConstantsVesta[220] = 0x1333e84ded18e378ed48e24985f1bdc8bdff854c49db901d1dfd22bbf8bc332a; - addRoundConstantsVesta[221] = 0x2fe3cd766de2af0f83625c1658bc42e3ae1f0eafdc3cdd17425ad2d1d640ce07; - addRoundConstantsVesta[222] = 0x193cac236e4954cff1d6754d7f4a2024f889438842e71d6c929b54214b7f20a7; - addRoundConstantsVesta[223] = 0x3e37eac0b4f50cccf5324a9e4b69a55f21932c0b96e573f824be9a843c14bf32; - addRoundConstantsVesta[224] = 0x3c3d935be87c4fe0fafa1fa8a47c648fe04d75629ae99c35adeab1e8a4043103; - addRoundConstantsVesta[225] = 0x381cbf47b8e0d242ca8270ddd912918a823494dbafae709c8caa33544fa55335; - addRoundConstantsVesta[226] = 0x27a6fe4fffb4368ee97671e85e4bd340ea1d5cf7f2655b715508e1f505b46ac1; - addRoundConstantsVesta[227] = 0x3480c78cc603b55ef6bd8951444f6ae875cf3530ac85486b782f454c1b8bd1bf; - addRoundConstantsVesta[228] = 0x3b64c64e1af8f6e8ee8085175566520ce23f1ab5a5cb11ffed2637e43563bb2c; - addRoundConstantsVesta[229] = 0x13a53d53490b2cb446a66fd515505a38aef2213329bcc7554334dd8b87da23ef; - addRoundConstantsVesta[230] = 0x0d55208988c47738ab8d90c85cf5c77d2203d2f8700198f5f7ae209d9163ab1c; - addRoundConstantsVesta[231] = 0x28f3a7ac7c21ea03780c7afbc16af49fd4d8f654d59294a40d9878aa64c5c3fb; - addRoundConstantsVesta[232] = 0x1a0ec39ad353255adf32ea7cbb69f0031796e30c9c8a4476d1f60197527e5c0d; - addRoundConstantsVesta[233] = 0x110400bc3a2664291e67162f40d07b603adff7f5d1897c08dcab8b2094c3ad96; - addRoundConstantsVesta[234] = 0x28e210ff30a5385a1822a42efcd6dc9d46b60442253dab193828c081606cabb9; - addRoundConstantsVesta[235] = 0x2da279069f9857c0ee1dc7f60a948efb7b4b16194068ae483d24ffb2546138c7; - addRoundConstantsVesta[236] = 0x2ab70f1742eedcaa28ef6af2130cfea942b118bcf0266183ca9799a5bd64a257; - addRoundConstantsVesta[237] = 0x100637203c85c12938926f6910825cab42d6939f1f1933fca4976fb3b213cae0; - addRoundConstantsVesta[238] = 0x0e37948b9e4e80ea66eb21c590844b31ec10f587ff8045ab68286cfc1584c648; - addRoundConstantsVesta[239] = 0x3f8e6cda4a6e8cb53a7175149ca5fc7cfa238720f90e951a0d08dcfbab0b600d; - addRoundConstantsVesta[240] = 0x30dbe73c8a992d61325e0fe24b992c788f29d24ea1b4ab4de401b649d76e49d7; - addRoundConstantsVesta[241] = 0x34a254943cd4779d52ba790c4056f2432cee5b1c17025fb9e63a57f84f8e68ef; - addRoundConstantsVesta[242] = 0x154d0afd3060e5754f07387790d46a87ddb5ed5ad8252eb9dbff2224edb4b4a3; - addRoundConstantsVesta[243] = 0x30ce9dff55026a058480f505656670d3a86a9ef2a4acf7f493a049d7ab2782dd; - addRoundConstantsVesta[244] = 0x028285db78c9b6ef16284913f8e49652b798430f88562208e8aa416de4acef51; - addRoundConstantsVesta[245] = 0x2830ad8dcf5562ee7eb85a000cfde4af46179502e9ef35909b19a609b5bb502d; - addRoundConstantsVesta[246] = 0x2c9440f177e9f4a75b397ad59a68d69803a2d65b05d163b31a55db0aa8eafddf; - addRoundConstantsVesta[247] = 0x3eb3d475a0d615d68d62b2e378b0ec8ce3956a2b00cd78adb370a038a332317d; - addRoundConstantsVesta[248] = 0x1ccab1ca1853e18bd19ee87cbb1c0be61f73ef1a0bb6595569fe25e6e6702543; - addRoundConstantsVesta[249] = 0x008eca5ce639a4238337bd1c4496cb0c15cc84b60e66182dfa1f3c1c76710591; - addRoundConstantsVesta[250] = 0x3647f8b5acc7fe369c1f330b2bfa0e251fc8c3b2c6641553e091c23384ae4f5e; - addRoundConstantsVesta[251] = 0x31bfc6f5b812118b6afa3c9447126c8124e07d4496d0c9d4af7426966d80bbc6; - addRoundConstantsVesta[252] = 0x3293299006e315e89027f9fd11f60dab46cc0c9681497aaa8f3296639d58d357; - addRoundConstantsVesta[253] = 0x180d75944ad25e650ff7ead24ccd77360cc51639b63fc4c7ffe88b691f2d7f8d; - addRoundConstantsVesta[254] = 0x21929366b4353e2dc5a381d456a46784f2ecaa69151b9aee090efd0b7c310c92; - addRoundConstantsVesta[255] = 0x387b125488c5c5fee3c5f98bb9c8ae7418173e58a010420f6f0800f7eea01d79; - addRoundConstantsVesta[256] = 0x1fdf94493b060de5d3141a51c02df634da9e82e829563b66305a0b62a8a1c3a5; - addRoundConstantsVesta[257] = 0x26c75f58330aff6c764e63321575220be50fc67d86d6cc5d47ab263eb0f894ed; - addRoundConstantsVesta[258] = 0x0fae09732475ae274a5a0400e48e9807e8acaea40a10287c1c56b2aadc5eebc9; - Vesta memory vesta = loadVestaConstants(mixConstantsVesta, addRoundConstantsVesta); - return (pallas, vesta); - } -} - -library CommitmentLib { - struct Commitment { - uint256 X; - uint256 Y; - uint256 Z; - } - - function loadCommitment(uint256 x, uint256 y, uint256 z) public pure returns (Commitment memory) { - return Commitment(x, y, z); - } -} - -library RelaxedR1CSInstanceLib { - struct RelaxedR1CSInstance { - CommitmentLib.Commitment comm_W; - CommitmentLib.Commitment comm_E; - uint256[] X; - uint256 u; - } - - function loadRelaxedR1CSInstance( - CommitmentLib.Commitment memory comm_W, - CommitmentLib.Commitment memory comm_E, - uint256[] memory X, - uint256 u - ) public pure returns (RelaxedR1CSInstance memory) { - return RelaxedR1CSInstance(comm_W, comm_E, X, u); - } -} - -library NovaVerifierStep2DataLib { - struct CompressedSnarkStep2Primary { - uint256[] zn_primary; - RelaxedR1CSInstanceLib.RelaxedR1CSInstance r_U_secondary; - uint256 expected_l_u_primary_X_1; - } - - struct CompressedSnarkStep2Secondary { - uint256[] zn_secondary; - RelaxedR1CSInstanceLib.RelaxedR1CSInstance r_U_primary; - uint256 expected_l_u_secondary_X_1; - } - - struct VerifierKeyStep2 { - uint256 f_arity_primary; - uint256 f_arity_secondary; - uint256 r1cs_shape_primary_digest; - uint256 r1cs_shape_secondary_digest; - } - - function getCompressedSnarkStep2Primary() public pure returns (CompressedSnarkStep2Primary memory) { - uint256[] memory zn_primary = new uint256[](1); - zn_primary[0] = 0x0000000000000000000000000000000000000000000000000000000000000001; - uint256 comm_W_X = 0x32445cde770b4e4af66622856c2be20a2c94467bf50649dc1bc2b41c9541b6fe; - uint256 comm_W_Y = 0x06d098478dbc9726714d939c2489f60a31c574a6dbc7074e9ef385319874a3de; - uint256 comm_W_Z = 0x0000000000000000000000000000000000000000000000000000000000000000; - CommitmentLib.Commitment memory comm_W = CommitmentLib.loadCommitment(comm_W_X, comm_W_Y, comm_W_Z); - uint256 comm_E_X = 0x2266c86e7f19866c5851627331db008eb23b7f254e6e0619129e0c495c861284; - uint256 comm_E_Y = 0x0cb7605dcdd24dc1c7310c2d0da12d4e8dd1e4ac7e0cf23e914e3ec68edad5df; - uint256 comm_E_Z = 0x0000000000000000000000000000000000000000000000000000000000000000; - CommitmentLib.Commitment memory comm_E = CommitmentLib.loadCommitment(comm_E_X, comm_E_Y, comm_E_Z); - uint256[] memory X = new uint256[](2 * 4); - X[0] = 0x000000000000000000000000000000000000000000000000d39a7ed25e72441a; - X[1] = 0x00000000000000000000000000000000000000000000000013a2e59ba6b3e153; - X[2] = 0x000000000000000000000000000000000000000000000000e833f1d79b147091; - X[3] = 0x000000000000000000000000000000000000000000000000107b0ae1735bf84d; - X[4] = 0x000000000000000000000000000000000000000000000000338a2aa0a0f31d23; - X[5] = 0x0000000000000000000000000000000000000000000000005abb57e3760e3b2d; - X[6] = 0x000000000000000000000000000000000000000000000000000f484e5e7dcc5e; - X[7] = 0x000000000000000000000000000000000000000000000000171bab5abc567e31; - uint256 u = 0x000000000000000000000000000000011804c228713446acb2495858f1571f61; - RelaxedR1CSInstanceLib.RelaxedR1CSInstance memory relaxedR1csInstance = - RelaxedR1CSInstanceLib.loadRelaxedR1CSInstance(comm_W, comm_E, X, u); - uint256 expected_l_u_primary_X_1 = 0x038221039f55af9c7bc62b80657320a9d1618bc5877a07a16e6e206a52234a32; - return CompressedSnarkStep2Primary(zn_primary, relaxedR1csInstance, expected_l_u_primary_X_1); - } - - function getCompressedSnarkStep2Secondary() public pure returns (CompressedSnarkStep2Secondary memory) { - uint256[] memory zn_secondary = new uint256[](1); - zn_secondary[0] = 0x0000000000000000000000000000000000000000000000000000000000258b63; - uint256 comm_W_X = 0x2c31a4399bcf1d98e9289684b06084041778e3aa774716674f990b53a7eb761b; - uint256 comm_W_Y = 0x240501beeccb1cb64c91a8a49380cb46e5325671d2a5ec740b06179e60642ecf; - uint256 comm_W_Z = 0x0000000000000000000000000000000000000000000000000000000000000000; - CommitmentLib.Commitment memory comm_W = CommitmentLib.loadCommitment(comm_W_X, comm_W_Y, comm_W_Z); - uint256 comm_E_X = 0x3bfd67298ee6602bcb7c7d9370ce8a3157cfd0f12108db253b813e8eaa172ea9; - uint256 comm_E_Y = 0x3b4ca44368436de00040d9e84992dcba4b00f31e98e2bf5bd846ce568d63a825; - uint256 comm_E_Z = 0x0000000000000000000000000000000000000000000000000000000000000000; - CommitmentLib.Commitment memory comm_E = CommitmentLib.loadCommitment(comm_E_X, comm_E_Y, comm_E_Z); - uint256[] memory X = new uint256[](2 * 4); - X[0] = 0x0000000000000000000000000000000000000000000000008acd4055542bf541; - X[1] = 0x00000000000000000000000000000000000000000000000056c9dcbc44b435dd; - X[2] = 0x000000000000000000000000000000000000000000000000718194359f53d11f; - X[3] = 0x0000000000000000000000000000000000000000000000001afccc8b4eaa3bc1; - X[4] = 0x000000000000000000000000000000000000000000000000788507aa4e5e18e9; - X[5] = 0x000000000000000000000000000000000000000000000000c793cb930f745f5f; - X[6] = 0x00000000000000000000000000000000000000000000000052ca09ab0ec108a3; - X[7] = 0x0000000000000000000000000000000000000000000000000b3f6387ca3de17a; - uint256 u = 0x00000000000000000000000000000000cc6b54563b3f5aefcc072ff891dfb5eb; - RelaxedR1CSInstanceLib.RelaxedR1CSInstance memory relaxedR1csInstance = - RelaxedR1CSInstanceLib.loadRelaxedR1CSInstance(comm_W, comm_E, X, u); - uint256 expected_l_u_secondary_X_1 = 0x03ce69bf1e04bd1b76a92ef407cc40b41e47a382b064122a8bca3e39144e0cae; - return CompressedSnarkStep2Secondary(zn_secondary, relaxedR1csInstance, expected_l_u_secondary_X_1); - } - - function getVerifierKeyStep2() public pure returns (VerifierKeyStep2 memory) { - uint256 f_arity_primary = 1; - uint256 f_arity_secondary = 1; - uint256 r1cs_shape_secondary_digest = 0x03b750843494b51c2e24cd02b764d3fd73901b6f64328d97ffef6ee95168bd34; - uint256 r1cs_shape_primary_digest = 0x00f3d576562a91495d3763cc5d7394b640087c280c3870af2dbccacad38ea1dc; - return - VerifierKeyStep2(f_arity_primary, f_arity_secondary, r1cs_shape_primary_digest, r1cs_shape_secondary_digest); - } -} diff --git a/src/verifier/step2/Step2Logic.sol b/src/verifier/step2/Step2Logic.sol deleted file mode 100644 index d3f46d6..0000000 --- a/src/verifier/step2/Step2Logic.sol +++ /dev/null @@ -1,186 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.16; - -import "src/verifier/step2/Step2Data.sol"; -import "src/blocks/poseidon/Sponge.sol"; -import "@std/Test.sol"; - -library NovaVerifierStep2Lib { - uint256 private constant NUM_FE_WITHOUT_IO_FOR_CRHF = 17; - - // uses Pallas-based Poseidon - function verifySecondary( - PoseidonConstants.Pallas memory constants, - NovaVerifierStep2DataLib.CompressedSnarkStep2Secondary memory proofDataStep2Secondary, - NovaVerifierStep2DataLib.VerifierKeyStep2 memory vkStep2, - uint32 numSteps, - uint256[] memory z0_secondary - ) public pure { - // Compare first 25 mix / arc Poseidon constants from verifier key with expected ones - require( - NovaSpongePallasLib.constantsAreEqual(constants.mixConstants, constants.addRoundConstants), - "[verifySecondary] WrongPallasPoseidonConstantsError" - ); - - // check if the output secondary hash in R1CS instances point to the right running instance - uint256 elementsToHashLength = NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * vkStep2.f_arity_secondary; - uint256 counter = 0; - - uint256[] memory elementsToHash = new uint256[](elementsToHashLength); - elementsToHash[counter] = vkStep2.r1cs_shape_primary_digest; - counter++; - - elementsToHash[counter] = uint256(numSteps); - counter++; - - for (uint256 i = 0; i < z0_secondary.length; i++) { - elementsToHash[counter] = z0_secondary[i]; - counter++; - } - - for (uint256 i = 0; i < proofDataStep2Secondary.zn_secondary.length; i++) { - elementsToHash[counter] = proofDataStep2Secondary.zn_secondary[i]; - counter++; - } - - elementsToHash[counter] = proofDataStep2Secondary.r_U_primary.comm_W.X; - counter++; - - elementsToHash[counter] = proofDataStep2Secondary.r_U_primary.comm_W.Y; - counter++; - - elementsToHash[counter] = proofDataStep2Secondary.r_U_primary.comm_W.Z; - counter++; - - elementsToHash[counter] = proofDataStep2Secondary.r_U_primary.comm_E.X; - counter++; - - elementsToHash[counter] = proofDataStep2Secondary.r_U_primary.comm_E.Y; - counter++; - - elementsToHash[counter] = proofDataStep2Secondary.r_U_primary.comm_E.Z; - counter++; - - elementsToHash[counter] = proofDataStep2Secondary.r_U_primary.u; - counter++; - - for (uint256 i = 0; i < proofDataStep2Secondary.r_U_primary.X.length; i++) { - elementsToHash[counter] = proofDataStep2Secondary.r_U_primary.X[i]; - counter++; - } - - // Step2 execution (compare Pallas-based Poseidon hashes) - uint32 absorbLen = uint32(counter); - uint32 squeezeLen = 1; - uint32 domainSeparator = 0; - - SpongeOpLib.SpongeOp memory absorb = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Absorb, absorbLen); - SpongeOpLib.SpongeOp memory squeeze = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Squeeze, squeezeLen); - SpongeOpLib.SpongeOp[] memory pattern = new SpongeOpLib.SpongeOp[](2); - pattern[0] = absorb; - pattern[1] = squeeze; - IOPatternLib.IOPattern memory p = IOPatternLib.IOPattern(pattern); - - NovaSpongePallasLib.SpongeU24Pallas memory sponge = NovaSpongePallasLib.start(p, domainSeparator); - - sponge = NovaSpongePallasLib.absorb(sponge, elementsToHash); - - (, uint256[] memory output) = NovaSpongePallasLib.squeeze(sponge, squeezeLen); - sponge = NovaSpongePallasLib.finishNoFinalIOCounterCheck(sponge); - - // in Nova only 250 bits of output hash are significant - require( - (output[0] & 0x07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - == proofDataStep2Secondary.expected_l_u_secondary_X_1, - "[Pallas Poseidon hash mismatch (verifySecondary)] ProofVerifyError" - ); - } - - // uses Vesta-based Poseidon - function verifyPrimary( - PoseidonConstants.Vesta memory constants, - NovaVerifierStep2DataLib.CompressedSnarkStep2Primary memory proofDataStep2Primary, - NovaVerifierStep2DataLib.VerifierKeyStep2 memory vkStep2, - uint32 numSteps, - uint256[] memory z0_primary - ) public view { - // Compare first 25 mix / arc Poseidon constants from verifier key with expected ones - require( - NovaSpongeVestaLib.constantsAreEqual(constants.mixConstants, constants.addRoundConstants), - "[verifyPrimary] WrongVestaPoseidonConstantsError" - ); - - // check if the output primary hash in R1CS instances point to the right running instance - uint256 elementsToHashLength = NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * vkStep2.f_arity_primary; - uint256 counter = 0; - - uint256[] memory elementsToHash = new uint256[](elementsToHashLength); - elementsToHash[counter] = vkStep2.r1cs_shape_secondary_digest; - counter++; - - elementsToHash[counter] = uint256(numSteps); - counter++; - - for (uint256 i = 0; i < z0_primary.length; i++) { - elementsToHash[counter] = z0_primary[i]; - counter++; - } - - for (uint256 i = 0; i < proofDataStep2Primary.zn_primary.length; i++) { - elementsToHash[counter] = proofDataStep2Primary.zn_primary[i]; - counter++; - } - - elementsToHash[counter] = proofDataStep2Primary.r_U_secondary.comm_W.X; - counter++; - - elementsToHash[counter] = proofDataStep2Primary.r_U_secondary.comm_W.Y; - counter++; - - elementsToHash[counter] = proofDataStep2Primary.r_U_secondary.comm_W.Z; - counter++; - - elementsToHash[counter] = proofDataStep2Primary.r_U_secondary.comm_E.X; - counter++; - - elementsToHash[counter] = proofDataStep2Primary.r_U_secondary.comm_E.Y; - counter++; - - elementsToHash[counter] = proofDataStep2Primary.r_U_secondary.comm_E.Z; - counter++; - - elementsToHash[counter] = proofDataStep2Primary.r_U_secondary.u; - counter++; - - for (uint256 i = 0; i < proofDataStep2Primary.r_U_secondary.X.length; i++) { - elementsToHash[counter] = proofDataStep2Primary.r_U_secondary.X[i]; - counter++; - } - - // Step2 execution (compare Vesta-based Poseidon hashes) - uint32 absorbLen = uint32(counter); - uint32 sqeezeLen = 1; - uint32 domainSeparator = 0; - - SpongeOpLib.SpongeOp memory absorb = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Absorb, absorbLen); - SpongeOpLib.SpongeOp memory squeeze = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Squeeze, sqeezeLen); - SpongeOpLib.SpongeOp[] memory pattern = new SpongeOpLib.SpongeOp[](2); - pattern[0] = absorb; - pattern[1] = squeeze; - IOPatternLib.IOPattern memory p = IOPatternLib.IOPattern(pattern); - - NovaSpongeVestaLib.SpongeU24Vesta memory sponge = NovaSpongeVestaLib.start(p, domainSeparator); - - sponge = NovaSpongeVestaLib.absorb(sponge, elementsToHash); - - (, uint256[] memory output) = NovaSpongeVestaLib.squeeze(sponge, sqeezeLen); - sponge = NovaSpongeVestaLib.finishNoFinalIOCounterCheck(sponge); - - // in Nova only 250 bits of output hash are significant - require( - (output[0] & 0x07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - == proofDataStep2Primary.expected_l_u_primary_X_1, - "[Vesta Poseidon hash mismatch (verifyPrimary)] ProofVerifyError" - ); - } -} diff --git a/src/verifier/step2/step2-data-contract-gen.py b/src/verifier/step2/step2-data-contract-gen.py deleted file mode 100644 index a6afc36..0000000 --- a/src/verifier/step2/step2-data-contract-gen.py +++ /dev/null @@ -1,479 +0,0 @@ -from collections import namedtuple -import json -import os -import sys -import binascii - -PALLAS_MODULUS = 28948022309329048855892746252171976963363056481941560715954676764349967630337 -VESTA_MODULUS = 28948022309329048855892746252171976963363056481941647379679742748393362948097 - -def uncompressPoint(xCoordinate, modulus): - x = bytearray.fromhex(xCoordinate) - ysign = x[31] >> 7 - x[31] &= 0x7f - x.reverse() - x = int(binascii.hexlify(x), 16) - - if ((x == 0) & (ysign == 0)): - return (0, 0, 1) - - # compute x^3 + 5 and take sqrt of it in order to get y - x2 = (x * x) % modulus - x3 = (x2 * x) % modulus - x3 = (x3 + 5) % modulus - y = modular_sqrt(x3, modulus) - - sign = ((y & 0xff) & 1) - - if ((ysign ^ sign) == 1): - y = (modulus - y) % modulus - - return (x, y, 0) - -def modular_sqrt(a, p): - - def legendre_symbol(a, p): - """ Compute the Legendre symbol a|p using - Euler's criterion. p is a prime, a is - relatively prime to p (if p divides - a, then a|p = 0) - Returns 1 if a has a square root modulo - p, -1 otherwise. - """ - ls = pow(a, (p - 1) // 2, p) - return -1 if ls == p - 1 else ls - - """ Find a quadratic residue (mod p) of 'a'. p - must be an odd prime. - Solve the congruence of the form: - x^2 = a (mod p) - And returns x. Note that p - x is also a root. - 0 is returned is no square root exists for - these a and p. - The Tonelli-Shanks algorithm is used (except - for some simple cases in which the solution - is known from an identity). This algorithm - runs in polynomial time (unless the - generalized Riemann hypothesis is false). - """ - # Simple cases - # - if legendre_symbol(a, p) != 1: - return 0 - elif a == 0: - return 0 - elif p == 2: - return p - elif p % 4 == 3: - return pow(a, (p + 1) // 4, p) - - # Partition p-1 to s * 2^e for an odd s (i.e. - # reduce all the powers of 2 from p-1) - # - s = p - 1 - e = 0 - while s % 2 == 0: - s //= 2 - e += 1 - - # Find some 'n' with a legendre symbol n|p = -1. - # Shouldn't take long. - # - n = 2 - while legendre_symbol(n, p) != -1: - n += 1 - - # Here be dragons! - # Read the paper "Square roots from 1; 24, 51, - # 10 to Dan Shanks" by Ezra Brown for more - # information - # - - # x is a guess of the square root that gets better - # with each iteration. - # b is the "fudge factor" - by how much we're off - # with the guess. The invariant x^2 = ab (mod p) - # is maintained throughout the loop. - # g is used for successive powers of n to update - # both a and b - # r is the exponent - decreases with each update - # - x = pow(a, (s + 1) // 2, p) - b = pow(a, s, p) - g = pow(n, s, p) - r = e - - while True: - t = b - m = 0 - for m in range(r): - if t == 1: - break - t = pow(t, 2, p) - - if m == 0: - return x - - gs = pow(g, 2 ** (r - m - 1), p) - g = (gs * gs) % p - x = (x * gs) % p - b = (b * g) % p - r = m - -def getLimbs(input): - val = int(input, 16) - limb3 = reverseLimb(val & 0x000000000000000000000000000000000000000000000000ffffffffffffffff) - limb2 = reverseLimb((val & 0x00000000000000000000000000000000ffffffffffffffff0000000000000000) >> 64) - limb1 = reverseLimb((val & 0x0000000000000000ffffffffffffffff00000000000000000000000000000000) >> 128) - limb0 = reverseLimb(((val & 0xffffffffffffffff000000000000000000000000000000000000000000000000) >> 192)) - return (limb0, limb1, limb2, limb3) - -def reverseLimb(input): - hex = bytearray.fromhex(format(input, 'x')) - hex.reverse() - return int(binascii.hexlify(hex), 16) - -def step2DataContractGen(data): - o = "" - o = o + "pragma solidity ^0.8.16;" - - o = o + "library PoseidonConstants {\n" - o = o + "struct Pallas {\n" - o = o + "uint256[] mixConstants;\n" - o = o + "uint256[] addRoundConstants;\n" - o = o + "}\n" - o = o + "struct Vesta {\n" - o = o + "uint256[] mixConstants;\n" - o = o + "uint256[] addRoundConstants;\n" - o = o + "}\n" - o = o + "function loadPallasConstants(uint256[] memory mixConstants, uint256[] memory addRoundConstants) internal pure returns (Pallas memory) {\n" - o = o + "return Pallas(mixConstants, addRoundConstants);\n" - o = o + "}\n" - o = o + "function loadVestaConstants(uint256[] memory mixConstants, uint256[] memory addRoundConstants) internal pure returns (Vesta memory) {\n" - o = o + "return Vesta(mixConstants, addRoundConstants);\n" - o = o + "}\n" - o = o + "function getPoseidonConstantsForBasicComparison() public pure returns (Pallas memory, Vesta memory){\n" - - # primary constants - o = o + "uint256[] memory mixConstantsPallas = new uint256[](" + str(len(data.constants_mixConstantsPrimary[0])) + ");\n" - index = 0 - for mixConstant in data.constants_mixConstantsPrimary[0]: - val = bytearray.fromhex(('{0:0{1}x}'.format(int(mixConstant, 16), 64))) - val.reverse() - o = o + "mixConstantsPallas[" + str(index) + "] = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(val), 16), 64) + ";\n" - index = index + 1 - - o = o + "uint256[] memory addRoundConstantsPallas = new uint256[](" + str(len(data.constants_addRoundConstantsPrimary)) + ");\n" - index = 0 - for addRoundConstant in data.constants_addRoundConstantsPrimary: - val = bytearray.fromhex(('{0:0{1}x}'.format(int(addRoundConstant, 16), 64))) - val.reverse() - o = o + "addRoundConstantsPallas[" + str(index) + "] = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(val), 16), 64) + ";\n" - index = index + 1 - - o = o + "Pallas memory pallas = loadPallasConstants(mixConstantsPallas, addRoundConstantsPallas);\n" - - # secondary constants - o = o + "uint256[] memory mixConstantsVesta = new uint256[](" + str(len(data.constants_mixConstantsSecondary[0])) + ");\n" - index = 0 - for mixConstant in data.constants_mixConstantsSecondary[0]: - val = bytearray.fromhex(('{0:0{1}x}'.format(int(mixConstant, 16), 64))) - val.reverse() - o = o + "mixConstantsVesta[" + str(index) + "] = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(val), 16), 64) + ";\n" - index = index + 1 - - o = o + "uint256[] memory addRoundConstantsVesta = new uint256[](" + str(len(data.constants_addRoundConstantsSecondary)) + ");\n" - index = 0 - for addRoundConstant in data.constants_addRoundConstantsSecondary: - val = bytearray.fromhex(('{0:0{1}x}'.format(int(addRoundConstant, 16), 64))) - val.reverse() - o = o + "addRoundConstantsVesta[" + str(index) + "] = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(val), 16), 64) + ";\n" - index = index + 1 - - o = o + "Vesta memory vesta = loadVestaConstants(mixConstantsVesta, addRoundConstantsVesta);\n" - o = o + "return (pallas, vesta);\n" - o = o + "}\n" - o = o + "}\n" - - o = o + "library CommitmentLib {\n" - o = o + "struct Commitment {\n" - o = o + "uint256 X;\n" - o = o + "uint256 Y;\n" - o = o + "uint256 Z;\n" - o = o + "}\n" - o = o + "function loadCommitment(uint256 x, uint256 y, uint256 z) public pure returns (Commitment memory) {\n" - o = o + "return Commitment(x, y, z);\n" - o = o + "}\n" - o = o + "}\n" - - o = o + "library RelaxedR1CSInstanceLib {\n" - o = o + "struct RelaxedR1CSInstance {\n" - o = o + "CommitmentLib.Commitment comm_W;\n" - o = o + "CommitmentLib.Commitment comm_E;\n" - o = o + "uint256[] X;\n" - o = o + "uint256 u;\n" - o = o + "}\n" - o = o + "function loadRelaxedR1CSInstance(CommitmentLib.Commitment memory comm_W,CommitmentLib.Commitment memory comm_E, uint256[] memory X, uint256 u) public pure returns (RelaxedR1CSInstance memory) {\n" - o = o + "return RelaxedR1CSInstance(comm_W, comm_E, X, u);\n" - o = o + "}\n" - o = o + "}\n" - - o = o + "library NovaVerifierStep2DataLib {\n" - o = o + "struct CompressedSnarkStep2Primary {\n" - o = o + "uint256[] zn_primary;\n" - o = o + "RelaxedR1CSInstanceLib.RelaxedR1CSInstance r_U_secondary;\n" - o = o + "uint256 expected_l_u_primary_X_1;\n" - o = o + "}\n" - - o = o + "struct CompressedSnarkStep2Secondary {\n" - o = o + "uint256[] zn_secondary;\n" - o = o + "RelaxedR1CSInstanceLib.RelaxedR1CSInstance r_U_primary;\n" - o = o + "uint256 expected_l_u_secondary_X_1;\n" - o = o + "}\n" - - o = o + "struct VerifierKeyStep2 {\n" - o = o + "uint256 f_arity_primary;\n" - o = o + "uint256 f_arity_secondary;\n" - o = o + "uint256 r1cs_shape_primary_digest;\n" - o = o + "uint256 r1cs_shape_secondary_digest;\n" - o = o + "}\n" - - # getCompressedSnarkStep2Primary - o = o + "function getCompressedSnarkStep2Primary() public pure returns (CompressedSnarkStep2Primary memory) {\n" - zn_primary_len = len(data.zn_primary) - o = o + "uint256[] memory zn_primary = new uint256[](" + str(zn_primary_len) + ");\n" - index = 0 - for zn_primary_item in data.zn_primary: - val = bytearray.fromhex(('{0:0{1}x}'.format(int(zn_primary_item, 16), 64))) - val.reverse() - o = o + "zn_primary[" + str(index) + "] = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(val), 16), 64) + ";\n" - index = index + 1 - - (comm_W_X, comm_W_Y, comm_W_Z) = uncompressPoint(data.r_u_secondary_comm_W_comm, VESTA_MODULUS) - o = o + "uint256 comm_W_X = 0x" + '{0:0{1}x}'.format(comm_W_X, 64) + ";\n" - o = o + "uint256 comm_W_Y = 0x" + '{0:0{1}x}'.format(comm_W_Y, 64) + ";\n" - o = o + "uint256 comm_W_Z = 0x" + '{0:0{1}x}'.format(comm_W_Z, 64) + ";\n" - o = o + "CommitmentLib.Commitment memory comm_W = CommitmentLib.loadCommitment(comm_W_X, comm_W_Y, comm_W_Z);\n" - - (comm_E_X, comm_E_Y, comm_E_Z) = uncompressPoint(data.r_u_secondary_comm_E_comm, VESTA_MODULUS) - o = o + "uint256 comm_E_X = 0x" + '{0:0{1}x}'.format(comm_E_X, 64) + ";\n" - o = o + "uint256 comm_E_Y = 0x" + '{0:0{1}x}'.format(comm_E_Y, 64) + ";\n" - o = o + "uint256 comm_E_Z = 0x" + '{0:0{1}x}'.format(comm_E_Z, 64) + ";\n" - o = o + "CommitmentLib.Commitment memory comm_E = CommitmentLib.loadCommitment(comm_E_X, comm_E_Y, comm_E_Z);\n" - - o = o + "uint256[] memory X = new uint256[](" + str(len(data.r_u_secondary_X)) + " * 4);\n" - index = 0 - for X in data.r_u_secondary_X: - # every field element has 4 limbs - (limb0, limb1, limb2, limb3) = getLimbs(X) - o = o + "X[" + str(index) + "] = 0x" + '{0:0{1}x}'.format(limb0, 64) + ";\n" - o = o + "X[" + str(index + 1) + "] = 0x" + '{0:0{1}x}'.format(limb1, 64) + ";\n" - o = o + "X[" + str(index + 2) + "] = 0x" + '{0:0{1}x}'.format(limb2, 64) + ";\n" - o = o + "X[" + str(index + 3) + "] = 0x" + '{0:0{1}x}'.format(limb3, 64) + ";\n" - index = index + 4 - - u = bytearray.fromhex(('{0:0{1}x}'.format(int(data.r_u_secondary_u, 16), 64))) - u.reverse() - o = o + "uint256 u = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(u), 16), 64) + ";\n" - o = o + "RelaxedR1CSInstanceLib.RelaxedR1CSInstance memory relaxedR1csInstance = RelaxedR1CSInstanceLib.loadRelaxedR1CSInstance(comm_W, comm_E, X, u);\n" - expected_l_u_primary_X_1 = bytearray.fromhex(('{0:0{1}x}'.format(int(data.l_u_primary_x[1], 16), 64))) - expected_l_u_primary_X_1.reverse() - o = o + "uint256 expected_l_u_primary_X_1 = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(expected_l_u_primary_X_1), 16), 64) + ";\n" - o = o + "return CompressedSnarkStep2Primary(zn_primary, relaxedR1csInstance, expected_l_u_primary_X_1);\n" - o = o + "}\n" - - # getCompressedSnarkStep2Secondary - o = o + "function getCompressedSnarkStep2Secondary() public pure returns (CompressedSnarkStep2Secondary memory) {\n" - zn_secondary_len = len(data.zn_secondary) - o = o + "uint256[] memory zn_secondary = new uint256[](" + str(zn_secondary_len) + ");\n" - index = 0 - for zn_secondary_item in data.zn_secondary: - val = bytearray.fromhex(('{0:0{1}x}'.format(int(zn_secondary_item, 16), 64))) - val.reverse() - o = o + "zn_secondary[" + str(index) + "] = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(val), 16), 64) + ";\n" - index = index + 1 - - - (comm_W_X, comm_W_Y, comm_W_Z) = uncompressPoint(data.r_u_primary_comm_W_comm, PALLAS_MODULUS) - o = o + "uint256 comm_W_X = 0x" + '{0:0{1}x}'.format(comm_W_X, 64) + ";\n" - o = o + "uint256 comm_W_Y = 0x" + '{0:0{1}x}'.format(comm_W_Y, 64) + ";\n" - o = o + "uint256 comm_W_Z = 0x" + '{0:0{1}x}'.format(comm_W_Z, 64) + ";\n" - o = o + "CommitmentLib.Commitment memory comm_W = CommitmentLib.loadCommitment(comm_W_X, comm_W_Y, comm_W_Z);\n" - - (comm_E_X, comm_E_Y, comm_E_Z) = uncompressPoint(data.r_u_primary_comm_E_comm, PALLAS_MODULUS) - o = o + "uint256 comm_E_X = 0x" + '{0:0{1}x}'.format(comm_E_X, 64) + ";\n" - o = o + "uint256 comm_E_Y = 0x" + '{0:0{1}x}'.format(comm_E_Y, 64) + ";\n" - o = o + "uint256 comm_E_Z = 0x" + '{0:0{1}x}'.format(comm_E_Z, 64) + ";\n" - o = o + "CommitmentLib.Commitment memory comm_E = CommitmentLib.loadCommitment(comm_E_X, comm_E_Y, comm_E_Z);\n" - - o = o + "uint256[] memory X = new uint256[](" + str(len(data.r_u_primary_X)) + " * 4);\n" - index = 0 - for X in data.r_u_primary_X: - # every field element has 4 limbs - (limb0, limb1, limb2, limb3) = getLimbs(X) - o = o + "X[" + str(index) + "] = 0x" + '{0:0{1}x}'.format(limb0, 64) + ";\n" - o = o + "X[" + str(index + 1) + "] = 0x" + '{0:0{1}x}'.format(limb1, 64) + ";\n" - o = o + "X[" + str(index + 2) + "] = 0x" + '{0:0{1}x}'.format(limb2, 64) + ";\n" - o = o + "X[" + str(index + 3) + "] = 0x" + '{0:0{1}x}'.format(limb3, 64) + ";\n" - index = index + 4 - - - u = bytearray.fromhex(('{0:0{1}x}'.format(int(data.r_u_primary_u, 16), 64))) - u.reverse() - o = o + "uint256 u = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(u), 16), 64) + ";\n" - o = o + "RelaxedR1CSInstanceLib.RelaxedR1CSInstance memory relaxedR1csInstance = RelaxedR1CSInstanceLib.loadRelaxedR1CSInstance(comm_W, comm_E, X, u);\n" - - expected_l_u_secondary_X_1 = bytearray.fromhex(('{0:0{1}x}'.format(int(data.l_u_secondary_x[1], 16), 64))) - expected_l_u_secondary_X_1.reverse() - o = o + "uint256 expected_l_u_secondary_X_1 = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(expected_l_u_secondary_X_1), 16), 64) + ";\n" - o = o + "return CompressedSnarkStep2Secondary(zn_secondary, relaxedR1csInstance, expected_l_u_secondary_X_1);\n" - o = o + "}\n" - - # getVerifierKeyStep2 - o = o + "function getVerifierKeyStep2() public pure returns (VerifierKeyStep2 memory) {\n" - o = o + "uint256 f_arity_primary = " + str(data.f_arity_primary) + ";\n" - o = o + "uint256 f_arity_secondary = " + str(data.f_arity_secondary) + ";\n" - - r1cs_shape_secondary_digest = bytearray.fromhex(('{0:0{1}x}'.format(int(data.r1cs_shape_secondary_digest, 16), 64))) - r1cs_shape_secondary_digest.reverse() - o = o + "uint256 r1cs_shape_secondary_digest = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(r1cs_shape_secondary_digest), 16), 64) + ";\n" - - r1cs_shape_primary_digest = bytearray.fromhex(('{0:0{1}x}'.format(int(data.r1cs_shape_primary_digest, 16), 64))) - r1cs_shape_primary_digest.reverse() - o = o + "uint256 r1cs_shape_primary_digest = 0x" + "{0:0{1}x}".format(int(binascii.hexlify(r1cs_shape_primary_digest), 16), 64) + ";\n" - - o = o + "return VerifierKeyStep2(f_arity_primary, f_arity_secondary, r1cs_shape_primary_digest, r1cs_shape_secondary_digest);\n" - o = o + "}\n" - - o = o + "}" - - return o - -vk_file = sys.argv[1] -if not os.path.exists(vk_file): - print("verifier-key (json) input file is missing") - exit(1) - -vk_f = open(os.path.basename(vk_file)) -vk_data = json.load(vk_f) - -# Parse VerifyingKey -f_arity_primary = vk_data['F_arity_primary'] -f_arity_secondary = vk_data['F_arity_secondary'] -r1cs_shape_primary_digest = vk_data['r1cs_shape_primary_digest'] -r1cs_shape_secondary_digest = vk_data['r1cs_shape_secondary_digest'] - -ro_consts_primary = vk_data['ro_consts_primary'] -mds = ro_consts_primary['mds'] -constants_mixConstantsPrimary = mds['m'] -constants_addRoundConstantsPrimary = ro_consts_primary['crc'] - -ro_consts_secondary = vk_data['ro_consts_secondary'] -mds = ro_consts_secondary['mds'] -constants_mixConstantsSecondary = mds['m'] -constants_addRoundConstantsSecondary = ro_consts_secondary['crc'] - -proof_file = sys.argv[2] -if not os.path.exists(proof_file): - print("compressed snark (json) input file is missing") - exit(1) - -proof_f = open(os.path.basename(proof_file)) -proof_data = json.load(proof_f) - -# Parse CompressedSnark - -# zn_primary -zn_primary = proof_data['zn_primary'] - -# zn_secondary -zn_secondary = proof_data['zn_secondary'] - -# l_u_primary -l_u_primary = proof_data['l_u_primary'] -l_u_primary_x = l_u_primary['X'] - -# l_u_secondary -l_u_secondary = proof_data['l_u_secondary'] -l_u_secondary_x = l_u_secondary['X'] - -# r_u_secondary -r_u_secondary = proof_data['r_U_secondary'] -r_u_secondary_u = r_u_secondary['u'] - -r_u_secondary_X = r_u_secondary['X'] - -r_u_secondary_comm_E = r_u_secondary['comm_E'] -r_u_secondary_comm_E_comm = r_u_secondary_comm_E['comm'] - -r_u_secondary_comm_W = r_u_secondary['comm_W'] -r_u_secondary_comm_W_comm = r_u_secondary_comm_W['comm'] - -# r_u_primary -r_u_primary = proof_data['r_U_primary'] -r_u_primary_u = r_u_primary['u'] - -r_u_primary_X = r_u_primary['X'] - -r_u_primary_comm_E = r_u_primary['comm_E'] -r_u_primary_comm_E_comm = r_u_primary_comm_E['comm'] - -r_u_primary_comm_W = r_u_primary['comm_W'] -r_u_primary_comm_W_comm = r_u_primary_comm_W['comm'] - -Step2VerifierData = namedtuple( - '_Step2VerifierData', ( - 'constants_mixConstantsPrimary', - 'constants_addRoundConstantsPrimary', - 'constants_mixConstantsSecondary', - 'constants_addRoundConstantsSecondary', - - 'f_arity_primary', - 'r1cs_shape_secondary_digest', - 'zn_primary', - 'l_u_primary_x', - 'r_u_secondary_u', - 'r_u_secondary_X', - 'r_u_secondary_comm_E_comm', - 'r_u_secondary_comm_W_comm', - - 'f_arity_secondary', - 'r1cs_shape_primary_digest', - 'zn_secondary', - 'l_u_secondary_x', - 'r_u_primary_u', - 'r_u_primary_X', - 'r_u_primary_comm_E_comm', - 'r_u_primary_comm_W_comm' - ) -) - -parsedData = Step2VerifierData( - constants_mixConstantsPrimary, - constants_addRoundConstantsPrimary, - constants_mixConstantsSecondary, - constants_addRoundConstantsSecondary, - - f_arity_primary, - r1cs_shape_secondary_digest, - zn_primary, - l_u_primary_x, - r_u_secondary_u, - r_u_secondary_X, - r_u_secondary_comm_E_comm, - r_u_secondary_comm_W_comm, - - f_arity_secondary, - r1cs_shape_primary_digest, - zn_secondary, - l_u_secondary_x, - r_u_primary_u, - r_u_primary_X, - r_u_primary_comm_E_comm, - r_u_primary_comm_W_comm, -) - -data = step2DataContractGen(parsedData) -print("// SPDX-License-Identifier: Apache-2.0") -print("// Do not change manually. This contract has been auto-generated by", sys.argv[0]) -print(data) diff --git a/src/verifier/step3/Step3Data.sol b/src/verifier/step3/Step3Data.sol deleted file mode 100644 index fbb517a..0000000 --- a/src/verifier/step3/Step3Data.sol +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Do not change manually. This contract has been auto-generated by src/verifier/step3/step3-data-contract-gen.py -pragma solidity ^0.8.16; - -import "src/Utilities.sol"; - -library Step3Data { - /* This function returns the following results in order: - * pp_digest, NIFS instance, r_U comm_W, r_U comm_E, r_U X, r_U u - * l_u comm_W, l_u X - */ - function returnPrimaryData() - public - pure - returns (uint256, bytes32, uint256, uint256, uint256[] memory, uint256, uint256, uint256[] memory) - { - uint8[32] memory nifs_array; - nifs_array[0] = 129; - nifs_array[1] = 78; - nifs_array[2] = 43; - nifs_array[3] = 114; - nifs_array[4] = 14; - nifs_array[5] = 217; - nifs_array[6] = 55; - nifs_array[7] = 0; - nifs_array[8] = 141; - nifs_array[9] = 134; - nifs_array[10] = 81; - nifs_array[11] = 102; - nifs_array[12] = 170; - nifs_array[13] = 237; - nifs_array[14] = 6; - nifs_array[15] = 198; - nifs_array[16] = 55; - nifs_array[17] = 200; - nifs_array[18] = 187; - nifs_array[19] = 76; - nifs_array[20] = 24; - nifs_array[21] = 102; - nifs_array[22] = 243; - nifs_array[23] = 155; - nifs_array[24] = 138; - nifs_array[25] = 115; - nifs_array[26] = 129; - nifs_array[27] = 71; - nifs_array[28] = 160; - nifs_array[29] = 43; - nifs_array[30] = 56; - nifs_array[31] = 24; - bytes32 nifs = Field.uint8ArrayToBytes32(nifs_array); - uint256 r_U_comm_W = 0x1b76eba7530b994f67164777aae37817048460b0849628e9981dcf9b39a431ac; - uint256 r_U_comm_E = 0xa92e17aa8e3e813b25db0821f1d0cf57318ace70937d7ccb2b60e68e2967fdbb; - uint256[] memory r_U_X = new uint256[](2); - r_U_X[0] = 0x1afccc8b4eaa3bc1718194359f53d11f56c9dcbc44b435dd8acd4055542bf541; - r_U_X[1] = 0x0b3f6387ca3de17a52ca09ab0ec108a3c793cb930f745f5f788507aa4e5e18e9; - uint256 r_U_u = 0x00000000000000000000000000000000cc6b54563b3f5aefcc072ff891dfb5eb; - uint256 l_u_comm_W = 0x73cb2576d50f1f5e74dce3cf18a48deb5ee483e870d5e8e8a8605b07dfe1920c; - uint256[] memory l_u_X = new uint256[](2); - l_u_X[0] = 0x02d41d38dd6cad4a4b3d3c0d10aa819c7649c0eba9400203531f52d1fb6275ca; - l_u_X[1] = 0x038221039f55af9c7bc62b80657320a9d1618bc5877a07a16e6e206a52234a32; - return ( - 0x00f3d576562a91495d3763cc5d7394b640087c280c3870af2dbccacad38ea1dc, - nifs, - r_U_comm_W, - r_U_comm_E, - r_U_X, - r_U_u, - l_u_comm_W, - l_u_X - ); - } - - /* This function returns the following results in order: - * pp_digest, NIFS instance, r_U comm_W, r_U comm_E, r_U X, r_U u - * l_u comm_W, l_u X - */ - function returnSecondaryData() - public - pure - returns (uint256, bytes32, uint256, uint256, uint256[] memory, uint256, uint256, uint256[] memory) - { - uint8[32] memory nifs_array; - nifs_array[0] = 51; - nifs_array[1] = 28; - nifs_array[2] = 184; - nifs_array[3] = 191; - nifs_array[4] = 145; - nifs_array[5] = 149; - nifs_array[6] = 208; - nifs_array[7] = 155; - nifs_array[8] = 200; - nifs_array[9] = 88; - nifs_array[10] = 188; - nifs_array[11] = 40; - nifs_array[12] = 1; - nifs_array[13] = 24; - nifs_array[14] = 67; - nifs_array[15] = 125; - nifs_array[16] = 209; - nifs_array[17] = 153; - nifs_array[18] = 46; - nifs_array[19] = 23; - nifs_array[20] = 49; - nifs_array[21] = 243; - nifs_array[22] = 244; - nifs_array[23] = 155; - nifs_array[24] = 67; - nifs_array[25] = 33; - nifs_array[26] = 24; - nifs_array[27] = 58; - nifs_array[28] = 215; - nifs_array[29] = 175; - nifs_array[30] = 103; - nifs_array[31] = 6; - bytes32 nifs = Field.uint8ArrayToBytes32(nifs_array); - uint256 r_U_comm_W = 0xfeb641951cb4c21bdc4906f57b46942c0ae22b6c852266f64a4e0b77de5c4432; - uint256 r_U_comm_E = 0x8412865c490c9e1219066e4e257f3bb28e00db31736251586c86197f6ec866a2; - uint256[] memory r_U_X = new uint256[](2); - r_U_X[0] = 0x107b0ae1735bf84de833f1d79b14709113a2e59ba6b3e153d39a7ed25e72441a; - r_U_X[1] = 0x171bab5abc567e31000f484e5e7dcc5e5abb57e3760e3b2d338a2aa0a0f31d23; - uint256 r_U_u = 0x000000000000000000000000000000011804c228713446acb2495858f1571f61; - uint256 l_u_comm_W = 0xd07c3b4dd208f32a9e2d16213a976ad6f61dbdba7760478a85726dee9475e989; - uint256[] memory l_u_X = new uint256[](2); - l_u_X[0] = 0x038221039f55af9c7bc62b80657320a9d1618bc5877a07a16e6e206a52234a32; - l_u_X[1] = 0x03ce69bf1e04bd1b76a92ef407cc40b41e47a382b064122a8bca3e39144e0cae; - return ( - 0x03b750843494b51c2e24cd02b764d3fd73901b6f64328d97ffef6ee95168bd34, - nifs, - r_U_comm_W, - r_U_comm_E, - r_U_X, - r_U_u, - l_u_comm_W, - l_u_X - ); - } -} diff --git a/src/verifier/step3/Step3Logic.sol b/src/verifier/step3/Step3Logic.sol deleted file mode 100644 index 5cd5713..0000000 --- a/src/verifier/step3/Step3Logic.sol +++ /dev/null @@ -1,319 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.16; - -import "src/blocks/pasta/Pallas.sol"; -import "src/blocks/pasta/Vesta.sol"; -import "src/verifier/step2/Step2Data.sol"; -import "src/blocks/poseidon/Sponge.sol"; - -library NIFSPallas { - uint256 private constant MOD = Pallas.P_MOD; - uint256 private constant NUM_FE_FOR_RO = 24; - - struct NIFS { - bytes32 compressed_comm_T; - } - - struct R1CSInstance { - Pallas.PallasAffinePoint comm_W; - uint256[] X; - } - - struct RelaxedR1CSInstance { - Pallas.PallasAffinePoint comm_W; - Pallas.PallasAffinePoint comm_E; - uint256[] X; - uint256 u; - } - - function verify(NIFS memory nifs, uint256 pp_digest, RelaxedR1CSInstance calldata U1, R1CSInstance calldata U2) - public - view - returns (RelaxedR1CSInstance memory) - { - uint256 counter = 0; - - uint256[] memory elementsToHash = new uint256[](NUM_FE_FOR_RO); - - elementsToHash[counter] = pp_digest; - counter++; - - //U1.absorb_in_ro - // Absorb comm_W - elementsToHash[counter] = U1.comm_W.x; - counter++; - elementsToHash[counter] = U1.comm_W.y; - counter++; - if (Pallas.isInfinity(U1.comm_W)) { - elementsToHash[counter] = 1; - } else { - elementsToHash[counter] = 0; - } - counter++; - - // Absorb comm_E - elementsToHash[counter] = U1.comm_E.x; - counter++; - elementsToHash[counter] = U1.comm_E.y; - counter++; - if (Pallas.isInfinity(U1.comm_E)) { - elementsToHash[counter] = 1; - } else { - elementsToHash[counter] = 0; - } - counter++; - - // Abosrb u - elementsToHash[counter] = U1.u; - counter++; - - // Absorb X - for (uint256 i = 0; i < U1.X.length; i++) { - uint256 entry = U1.X[i]; - - (uint256 limb1, uint256 limb2, uint256 limb3, uint256 limb4) = Field.extractLimbs(entry); - elementsToHash[counter] = limb1; - counter++; - elementsToHash[counter] = limb2; - counter++; - elementsToHash[counter] = limb3; - counter++; - elementsToHash[counter] = limb4; - counter++; - } - - //U2.absorb_in_ro - // Absorb comm_W - elementsToHash[counter] = U2.comm_W.x; - counter++; - elementsToHash[counter] = U2.comm_W.y; - counter++; - if (Pallas.isInfinity(U2.comm_W)) { - elementsToHash[counter] = 1; - } else { - elementsToHash[counter] = 0; - } - counter++; - - // Absorb X - for (uint256 i = 0; i < U2.X.length; i++) { - elementsToHash[counter] = U2.X[i]; - counter++; - } - - // Absorb comm_T - Pallas.PallasAffinePoint memory comm_T = Pallas.fromBytes(nifs.compressed_comm_T); - elementsToHash[counter] = comm_T.x; - counter++; - elementsToHash[counter] = comm_T.y; - counter++; - if (Pallas.isInfinity(comm_T)) { - elementsToHash[counter] = 1; - } else { - elementsToHash[counter] = 0; - } - counter++; - - require(counter == NUM_FE_FOR_RO); - - SpongeOpLib.SpongeOp memory absorb = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Absorb, uint32(counter)); - SpongeOpLib.SpongeOp memory squeeze = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Squeeze, 1); - SpongeOpLib.SpongeOp[] memory pattern = new SpongeOpLib.SpongeOp[](2); - pattern[0] = absorb; - pattern[1] = squeeze; - IOPatternLib.IOPattern memory p = IOPatternLib.IOPattern(pattern); - - NovaSpongePallasLib.SpongeU24Pallas memory sponge = NovaSpongePallasLib.start(p, 0); - - sponge = NovaSpongePallasLib.absorb(sponge, elementsToHash); - - (, uint256[] memory output) = NovaSpongePallasLib.squeeze(sponge, 1); - sponge = NovaSpongePallasLib.finishNoFinalIOCounterCheck(sponge); - - RelaxedR1CSInstance memory result = - foldInstance(U1, U2, comm_T, output[0] & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff); - - return result; - } - - function foldInstance( - RelaxedR1CSInstance calldata U1, - R1CSInstance calldata u2, - Pallas.PallasAffinePoint memory comm_T, - uint256 r - ) public view returns (RelaxedR1CSInstance memory) { - uint256[] memory x2 = u2.X; - Pallas.PallasAffinePoint memory comm_W_2 = u2.comm_W; - - require(U1.X.length == x2.length, "[NIFSPallas.foldInstance]: Witness vectors do not match length"); - - uint256[] memory X = new uint256[](U1.X.length); - - for (uint256 i = 0; i < x2.length; i++) { - X[i] = addmod(U1.X[i], mulmod(r, x2[i], Pallas.R_MOD), Pallas.R_MOD); - } - - return RelaxedR1CSInstance( - Pallas.add(U1.comm_W, Pallas.scalarMul(comm_W_2, r)), - Pallas.add(U1.comm_E, Pallas.scalarMul(comm_T, r)), - X, - addmod(U1.u, r, Pallas.P_MOD) - ); - } -} - -library NIFSVesta { - uint256 private constant MOD = Vesta.P_MOD; - uint256 private constant NUM_FE_FOR_RO = 24; - - struct NIFS { - bytes32 compressed_comm_T; - } - - struct R1CSInstance { - Vesta.VestaAffinePoint comm_W; - uint256[] X; - } - - struct RelaxedR1CSInstance { - Vesta.VestaAffinePoint comm_W; - Vesta.VestaAffinePoint comm_E; - uint256[] X; - uint256 u; - } - - function verify(NIFS memory nifs, uint256 pp_digest, RelaxedR1CSInstance calldata U1, R1CSInstance calldata U2) - public - view - returns (RelaxedR1CSInstance memory) - { - uint256 counter = 0; - - uint256[] memory elementsToHash = new uint256[](NUM_FE_FOR_RO); - - elementsToHash[counter] = pp_digest; - counter++; - - //U1.absorb_in_ro - // Absorb comm_W - elementsToHash[counter] = U1.comm_W.x; - counter++; - elementsToHash[counter] = U1.comm_W.y; - counter++; - if (Vesta.isInfinity(U1.comm_W)) { - elementsToHash[counter] = 1; - } else { - elementsToHash[counter] = 0; - } - counter++; - - // Absorb comm_E - elementsToHash[counter] = U1.comm_E.x; - counter++; - elementsToHash[counter] = U1.comm_E.y; - counter++; - if (Vesta.isInfinity(U1.comm_E)) { - elementsToHash[counter] = 1; - } else { - elementsToHash[counter] = 0; - } - counter++; - - // Abosrb u - elementsToHash[counter] = U1.u; - counter++; - - // Absorb X - for (uint256 i = 0; i < U1.X.length; i++) { - uint256 entry = U1.X[i]; - (uint256 limb1, uint256 limb2, uint256 limb3, uint256 limb4) = Field.extractLimbs(entry); - - elementsToHash[counter] = limb1; - counter++; - elementsToHash[counter] = limb2; - counter++; - elementsToHash[counter] = limb3; - counter++; - elementsToHash[counter] = limb4; - counter++; - } - - //U2.absorb_in_ro - // Absorb comm_W - elementsToHash[counter] = U2.comm_W.x; - counter++; - elementsToHash[counter] = U2.comm_W.y; - counter++; - if (Vesta.isInfinity(U2.comm_W)) { - elementsToHash[counter] = 1; - } else { - elementsToHash[counter] = 0; - } - counter++; - - // Absorb X - for (uint256 i = 0; i < U2.X.length; i++) { - elementsToHash[counter] = U2.X[i]; - counter++; - } - - // Absorb comm_T - Vesta.VestaAffinePoint memory comm_T = Vesta.fromBytes(nifs.compressed_comm_T); - elementsToHash[counter] = comm_T.x; - counter++; - elementsToHash[counter] = comm_T.y; - counter++; - if (Vesta.isInfinity(comm_T)) { - elementsToHash[counter] = 1; - } else { - elementsToHash[counter] = 0; - } - counter++; - - require(counter == NUM_FE_FOR_RO); - - SpongeOpLib.SpongeOp memory absorb = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Absorb, uint32(counter)); - SpongeOpLib.SpongeOp memory squeeze = SpongeOpLib.SpongeOp(SpongeOpLib.SpongeOpType.Squeeze, 1); - SpongeOpLib.SpongeOp[] memory pattern = new SpongeOpLib.SpongeOp[](2); - pattern[0] = absorb; - pattern[1] = squeeze; - IOPatternLib.IOPattern memory p = IOPatternLib.IOPattern(pattern); - - NovaSpongeVestaLib.SpongeU24Vesta memory sponge = NovaSpongeVestaLib.start(p, 0); - - sponge = NovaSpongeVestaLib.absorb(sponge, elementsToHash); - - (, uint256[] memory output) = NovaSpongeVestaLib.squeeze(sponge, 1); - sponge = NovaSpongeVestaLib.finishNoFinalIOCounterCheck(sponge); - - RelaxedR1CSInstance memory result = - foldInstance(U1, U2, comm_T, output[0] & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff); - - return result; - } - - function foldInstance( - RelaxedR1CSInstance calldata U1, - R1CSInstance calldata u2, - Vesta.VestaAffinePoint memory comm_T, - uint256 r - ) public view returns (RelaxedR1CSInstance memory) { - uint256[] memory x2 = u2.X; - Vesta.VestaAffinePoint memory comm_W_2 = u2.comm_W; - - require(U1.X.length == x2.length, "[NIFSVesta.foldInstance]: Witness vectors do not match length"); - - uint256[] memory X = new uint256[](U1.X.length); - - for (uint256 i = 0; i < x2.length; i++) { - X[i] = addmod(U1.X[i], mulmod(r, x2[i], Vesta.R_MOD), Vesta.R_MOD); - } - - return RelaxedR1CSInstance( - Vesta.add(U1.comm_W, Vesta.scalarMul(comm_W_2, r)), - Vesta.add(U1.comm_E, Vesta.scalarMul(comm_T, r)), - X, - addmod(U1.u, r, Vesta.P_MOD) - ); - } -} diff --git a/src/verifier/step3/step3-data-contract-gen.py b/src/verifier/step3/step3-data-contract-gen.py deleted file mode 100644 index 4b9136e..0000000 --- a/src/verifier/step3/step3-data-contract-gen.py +++ /dev/null @@ -1,115 +0,0 @@ -import json -import sys -import os - -def h(s): - """ - Hexify a string - """ - return "0x" + s - -def reverse_bytes(val): - """ - Reverses the byte order of a hexdecimal number for ingest in Solidity contract - """ - ba = bytearray.fromhex(val) - ba.reverse() - return ba.hex() - -def step3DataContractGen(digest, nifs_secondary, r_U_secondary, l_u_secondary): - # Unpack nifs_secondary - nifs_secondary_repr = nifs_secondary["comm_T"]["comm"]["repr"] - output = f"\t\tuint8[32] memory nifs_array;\n" - for idx, val in enumerate(nifs_secondary_repr): - output += f"\t\tnifs_array[{idx}] = {val};\n" - - output += "\t\tbytes32 nifs = Field.uint8ArrayToBytes32(nifs_array);\n" - # Unpack r_U_secondary - comm_W = r_U_secondary["comm_W"]["comm"] - output += f"\t\tuint256 r_U_comm_W = {h(comm_W)};\n" - comm_E = r_U_secondary["comm_E"]["comm"] - output += f"\t\tuint256 r_U_comm_E = {h(comm_E)};\n" - r_X = r_U_secondary["X"] - output += f"\t\tuint256[] memory r_U_X = new uint256[]({len(r_X)});\n" - for idx, val in enumerate(r_X): - val = reverse_bytes(val) - output += f"\t\tr_U_X[{idx}] = {h(val)};\n" - r_U_u = r_U_secondary["u"] - r_U_u = reverse_bytes(r_U_u) - output += f"\t\tuint256 r_U_u = {h(r_U_u)};\n" - - # Unpack l_U_secondary - comm_W = l_u_secondary["comm_W"]["comm"] - output += f"\t\tuint256 l_u_comm_W = {h(comm_W)};\n" - l_X = l_u_secondary["X"] - output += f"\t\tuint256[] memory l_u_X = new uint256[]({len(l_X)});\n" - for idx, val in enumerate(l_X): - val = reverse_bytes(val) - output += f"\t\tl_u_X[{idx}] = {h(val)};\n" - - # Reverse digest - digest = reverse_bytes(digest) - - output += f"\t\treturn ({h(digest)}, nifs, r_U_comm_W, r_U_comm_E, r_U_X, r_U_u, l_u_comm_W, l_u_X);\n" - - return output - -vk_file = sys.argv[1] -if not os.path.exists(vk_file): - print("verifier-key (json) input file is missing") - exit(1) - -vk_f = open(os.path.basename(vk_file)) -vk_data = json.load(vk_f) -digest_primary = vk_data["r1cs_shape_primary_digest"] -digest_secondary = vk_data["r1cs_shape_secondary_digest"] - -proof_file = sys.argv[2] -if not os.path.exists(proof_file): - print("compressed snark (json) input file is missing") - exit(1) - -proof_f = open(os.path.basename(proof_file)) -proof_data = json.load(proof_f) -nifs_primary = proof_data["nifs_primary"] -r_U_primary = proof_data["r_U_primary"] -l_u_primary = proof_data["l_u_primary"] -nifs_secondary = proof_data["nifs_secondary"] -r_U_secondary = proof_data["r_U_secondary"] -l_u_secondary = proof_data["l_u_secondary"] - -header = "// SPDX-License-Identifier: Apache-2.0\n" -header += f"// Do not change manually. This contract has been auto-generated by {sys.argv[0]}\n" -header += "pragma solidity ^0.8.16;" -header += 'import "src/Utilities.sol";\n' - -function_doc = "\t/* This function returns the following results in order:\n" -function_doc += "\t* pp_digest, NIFS instance, r_U comm_W, r_U comm_E, r_U X, r_U u\n" -function_doc += "\t* l_u comm_W, l_u X\n" -function_doc += "\t*/\n" - -primary_data_function_def = function_doc -primary_data_function_def += "\tfunction returnPrimaryData()\n" -primary_data_function_def += "\t\tpublic\n" -primary_data_function_def += "\t\tpure\n" -primary_data_function_def += "\t\treturns (uint256, bytes32, uint256, uint256, uint256[] memory, uint256, uint256, uint256[] memory)\n" -primary_data_function_def += "\t{\n" -primary_data_function_def += step3DataContractGen(digest_primary, nifs_primary, r_U_primary, l_u_primary) -primary_data_function_def += "\t}\n\n" - -secondary_data_function_def = function_doc -secondary_data_function_def += "\tfunction returnSecondaryData()\n" -secondary_data_function_def += "\t\tpublic\n" -secondary_data_function_def += "\t\tpure\n" -secondary_data_function_def += "\t\treturns (uint256, bytes32, uint256, uint256, uint256[] memory, uint256, uint256, uint256[] memory)\n" -secondary_data_function_def += "\t{\n" -secondary_data_function_def += step3DataContractGen(digest_secondary, nifs_secondary, r_U_secondary, l_u_secondary) -secondary_data_function_def += "}\n\n" - -data_contract_body = "library Step3Data {\n" -data_contract_body += primary_data_function_def -data_contract_body += secondary_data_function_def -data_contract_body += "}" - -print(header) -print(data_contract_body) diff --git a/src/verifier/step4/SubStep2.sol b/src/verifier/step4/SubStep2.sol index 886aefc..edc6bea 100644 --- a/src/verifier/step4/SubStep2.sol +++ b/src/verifier/step4/SubStep2.sol @@ -15,12 +15,12 @@ library SpartanVerificationSubStep2Lib { uint256 eval_E, uint256 U_u, uint256 claim_outer_final - ) public pure { - uint256 taus_bound_rx = EqPolinomialLib.evaluateVesta(tau, r_x); + ) public { + uint256 modulusVesta = Vesta.P_MOD; - uint256 claim_outer_final_computed; + uint256 taus_bound_rx = EqPolinomialLib.evaluate(tau, r_x, modulusVesta, Vesta.negateBase); - uint256 modulusVesta = Vesta.P_MOD; + uint256 claim_outer_final_computed; uint256 tmp1; assembly { @@ -55,12 +55,12 @@ library SpartanVerificationSubStep2Lib { uint256 eval_E, uint256 U_u, uint256 claim_outer_final - ) public pure { - uint256 taus_bound_rx = EqPolinomialLib.evaluatePallas(tau, r_x); + ) public { + uint256 modulusPallas = Pallas.P_MOD; - uint256 claim_outer_final_computed; + uint256 taus_bound_rx = EqPolinomialLib.evaluate(tau, r_x, modulusPallas, Pallas.negateBase); - uint256 modulusPallas = Pallas.P_MOD; + uint256 claim_outer_final_computed; uint256 tmp1; assembly { diff --git a/src/verifier/step4/SumcheckData.sol b/src/verifier/step4/SumcheckData.sol deleted file mode 100644 index bc296c9..0000000 --- a/src/verifier/step4/SumcheckData.sol +++ /dev/null @@ -1,592 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Do not change manually. This contract has been auto-generated by src/verifier/step4/sumcheck-data-contract-gen.py -pragma solidity ^0.8.16; - -import "src/Utilities.sol"; -import "src/verifier/step4/SumcheckLogic.sol"; - -library SumcheckData { - // This function returns a SumcheckProof for the relevant corresponding field - function returnPrimaryOuterData() public pure returns (PolyLib.SumcheckProof memory) { - PolyLib.CompressedUniPoly[] memory proof_array = new PolyLib.CompressedUniPoly[](14); - uint256[] memory poly_array; - PolyLib.CompressedUniPoly memory poly; - poly_array = new uint256[](3); - poly_array[0] = 0x0000000000000000000000000000000000000000000000000000000000000000; - poly_array[1] = 0x3156ab3e1bea772559548817e8d23e4d60a57bc280baf032420e3c6133dd7e2f; - poly_array[2] = 0x1dff490409def9717737be07798dad2c3a6bc952eec88937c6076da01f9d9af0; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[0] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x2a0cd6f39b97ed92a45886a8e80a5944ed373498922050a3745f29c2ec6667ae; - poly_array[1] = 0x12fbd521f3fdb45f92e1bc9d045197000c74f40e67292ccac43f9b65f854b955; - poly_array[2] = 0x0bf922cb074481cf22bfe02c62561af632503238b4198aeb5e2bb5cf8dd0fac3; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[1] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x1a7160ebd6e443d51da504fa28e5168868012deaacfc8188014cde90744297bc; - poly_array[1] = 0x281222608e87d3d0d154e6621dbe68a181e5e646bbaab420859659a0e042dd4c; - poly_array[2] = 0x2ae2df351788ef2c603da9501a93ea6ea1080a1742c923a56e0daa7e0599cd1e; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[2] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x2cadc3a75b23fdebbcef67f3b2d193348ea927786e761d43406e4358d324c4d1; - poly_array[1] = 0x06d2d5a5f516f2734156ed7b78e9687e0a6a52c89456c09af0609fe5b27b1fca; - poly_array[2] = 0x0a1a4cee698d0bea9725c189f39509b1e3fb54dcbf0cfeb0ead4a679e30b6b97; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[3] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x21d36d5eeab44b9e1dab9a1941353a9b259b0e37f8130c97ac45e7ee1ee46e5d; - poly_array[1] = 0x09cd8f4b3cdb357a80b6d967f5c0f33335ba536e76092ed3ac9ce4b576777817; - poly_array[2] = 0x047de779ead5aef11c60969244ec4bdcf2ef7e7081f734a4239cfe4607768d6c; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[4] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x25291aac7c299b973f93613a17c13191037cb2fd01e2eccdf4697deaf0c9a04a; - poly_array[1] = 0x35f26c09cec10804a870e39ef1d192dd5609b1481229da10415680c367fce145; - poly_array[2] = 0x2b37031e0daac3039e35efc738ca354614b0263e45658a0c90de1dccd6735711; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[5] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x02563c53bdabeb954ec43901c61cb5ad9e81c2cb7dd31b9f46f80440078fd7fd; - poly_array[1] = 0x0807ce199363c83d6c6fbeb708cef45c4f96236b7e861812b879de1a205db161; - poly_array[2] = 0x32fcb855b9dd89717b27154af419b9389ad459a36f94730efe771b0f5940f633; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[6] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x2087b996187c4be4d5eb576a9b6d00d315ad25cee961c8f424621a41c6b0c971; - poly_array[1] = 0x1ef0832cd1a4ba98bf66682a990f9c56216fc31b39d2adecc94c5cc9b4031ab8; - poly_array[2] = 0x0b652696a88affcc0ab69d52903bcd3965f262ddf222c3fe2da3af2fa6a0f27a; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[7] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x36a3f10a14df17c5dde2ec64df992874659af5e22e4db23ad1ea73d66807c8ef; - poly_array[1] = 0x09c9b72ebe89f51aec378af41815f75964c4d8f993e5f9b1681e2b21a42385f9; - poly_array[2] = 0x1b75c4dd2c3cb3a62b90b02ea20c4051ca98c9d9c1424a2421f947c12c7d3eb7; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[8] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x2828a18fa8618435b512a4292b9fcea3b150859f50a3e74bb2a3ee15ae88da9c; - poly_array[1] = 0x1964a64964a1859af0d3d333762bbec3a22487ca091e6b89494ce72cef90130a; - poly_array[2] = 0x10e43d7966039b6cc7b1ced16fd886fe1ca375a8485b820f48611b822781226c; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[9] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x3eb95a4f74af56e31c0b35fe7498c938009c9bea670a61a8383dab0c4c429bfe; - poly_array[1] = 0x0dff761d89b94a2551136b0f4df357b400850910295952ad9ee5c2f85123e5e5; - poly_array[2] = 0x13e46518e76c51be58f3748832326568b0c2cd2e683ae9bb4b1ece9b93c56376; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[10] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x26592d33bfd615e40cfe4c9a0b8e56e88a2c8aa00c84f49b783b4f0c1c359706; - poly_array[1] = 0x29f1f0b13ba89df090f4d23bc74060929ca75281737b7200ec6ad66e94e3c1e2; - poly_array[2] = 0x36ede69bcd3a25e759a2b798f83b569a4906b688623ac23529b8cdc12355abc3; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[11] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x05d85babbee109ab6d627a03a8e8ea0d372d96cfa1929cee86ae5af797cb9657; - poly_array[1] = 0x2b9ce21b23851fcce3cc996e5c80da63f8818737d35957b31b0125bccfebe967; - poly_array[2] = 0x15f5eb776094fbed243e952d5c3512ec31b123db1af788fa9686b8b18b7d7168; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[12] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x07e180612d7bd63a41bd64c2e6c1b0c5edbe6fa6f318cba353edb77eecd59bac; - poly_array[1] = 0x1785c227874bcb2e816af7d0b1b39d6369dc3017b21cfdaccbbbdf3e9a63c9ca; - poly_array[2] = 0x3001d35ebe98119d070a55ea1544bcb729493df381bf7c80ffb0203b2956d7c9; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[13] = poly; - return PolyLib.SumcheckProof(proof_array); - } - - // This function returns a SumcheckProof for the relevant corresponding field - function returnPrimaryInnerData() public pure returns (PolyLib.SumcheckProof memory) { - PolyLib.CompressedUniPoly[] memory proof_array = new PolyLib.CompressedUniPoly[](15); - uint256[] memory poly_array; - PolyLib.CompressedUniPoly memory poly; - poly_array = new uint256[](2); - poly_array[0] = 0x1c4716f6500639b9ee9e0a493a76aa7c7aa8196dd10d4eeb40627f83ec901ab3; - poly_array[1] = 0x12ddcbfdc897aea3ddd931a65341be5be2cd518c188a73256a71b0b5d742f87a; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[0] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x1eacd6a8ccb244c64826baf09705d29d8ef995632ed1b70c7e7af712825d19e2; - poly_array[1] = 0x03ef3e2a0f4b278e998da912353b35a0c40e76e67f4d8b8213f2393d8f742b8d; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[1] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3fec761f5f12b29c168cc1fe7b27254666e8fed9d0eefbc314e634e30ef07d92; - poly_array[1] = 0x1d16b757b0e8d062872b6d3c5958e93ce78bf3e31be62d1b7ebf4c35c93c21fe; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[2] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x069a0ee19958d15bfed6947ab0a689a0f6e4384f651407760e1045e363015b9b; - poly_array[1] = 0x1e154ecac18821ead0126f8a850c4a9fc7c06e9078af0eb02a5362c2ab19ddba; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[3] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x0960f1909773fd0cd0142c4f988a17be72b09d5542276c24b10ac96c9f964b88; - poly_array[1] = 0x004fdcee2f0b851cd672ea49de9760f69e56fb6d7fec59445daba272d849dc06; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[4] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x21b81234955853a2affe69496b2831035b90d5b31eefd3bda3fdad37974efeab; - poly_array[1] = 0x22f8ec817975e9313c8ee3a49b477633ad32819965e0a6e6d821691a510eeb0b; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[5] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x38a2603ead84692ace689ec57ebe7cec1a9453fd2919c650b048740c8a2c39e3; - poly_array[1] = 0x254b089648bcfb1ac112cf795a7189a93555820e2e9489d0eeee4513a166e793; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[6] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x178f3b3f5ff04fd87346830452d7b923df016a390bc502f6ffe557120744290e; - poly_array[1] = 0x1b849c9bb28d386b2b3adad7183f80dea1242964ccb38188937129ba5fbc3a7a; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[7] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x02d85bd61ed1849b2f3e7b9be14a86055723a97303f0df2b04a533bffa285c16; - poly_array[1] = 0x3b4bbb46b769c1725e934257a561e01248e8876d9c8197c8b4a4f62ff53cbd65; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[8] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x102abddb1ed3784b298cd43c10ffabfed2d649332fb82ab7027daef4c6e6f845; - poly_array[1] = 0x3d57a9cf5588852f198f874e37ea5db4dc46a684c2d9a9b2186fdf60c497ce6a; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[9] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x020391cbc46173b9e1908c9f90bfbbf44ccd3328112f1a42482099dd60eb822e; - poly_array[1] = 0x1b2f8805ccd6bb1855294ac62537075a102441b5743caca629a0de56dc3d0bae; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[10] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x1e1639b26e4bc45cacfe52d84ff1e5a9333ef770aa814dbe444ba16345b07b89; - poly_array[1] = 0x2136cf7fba716952ec0dbb672c7d3e9e8200ac6ef547dc06f0e87317ec8acd30; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[11] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x32ca14ba8af6c53fc1e8cd50dcd3d718fb444f16a3e4e832a26195285489a961; - poly_array[1] = 0x2c8f9603d754035cc3efe1af4a55c24e498bd10e4d289a9cf4ebde41c78bb63f; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[12] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x1fd16fb6bf71d9b5e27c81cc22ca308b6ecf227c279a540fb78435d9661a92d2; - poly_array[1] = 0x0e7136096c545edbeaca24dad44083385fe147980df8b0d4149ac693d483a66e; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[13] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x0df4439409c23205c94fff01fab2978f40f8aee927a2a97ff3168af0a5d28fc8; - poly_array[1] = 0x0144eebfcf46c4d529bd5875de0d23df56c65a2eb54d7000b68837f01eacd58e; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[14] = poly; - return PolyLib.SumcheckProof(proof_array); - } - - // This function returns a SumcheckProof for the relevant corresponding field - function returnPrimaryBatchData() public pure returns (PolyLib.SumcheckProof memory) { - PolyLib.CompressedUniPoly[] memory proof_array = new PolyLib.CompressedUniPoly[](14); - uint256[] memory poly_array; - PolyLib.CompressedUniPoly memory poly; - poly_array = new uint256[](2); - poly_array[0] = 0x2155c5a20f5a1194e2ac3f9177909cef926c05e32fb7e9d22ef0d77d28688763; - poly_array[1] = 0x27fad0f1b0d77c1f120661e1a815714a8dad8f5ff4a2310c450fa9ab2e742e54; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[0] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x1eed419f37fe888cd7019a630b689deea4d7ed62a38ee9ec6d369f8034c85b09; - poly_array[1] = 0x3b70d8d30df9e02f4f7adb9bf411f1011f0d92bb13be7e28fc751867a6fd033c; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[1] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x02c9849afed1c30df760be1f226a08a7ce3590ea9c3b65d2dcf5894627c9d152; - poly_array[1] = 0x2b6ea31acdb0372acf50cba700488af46ce8a93950a59c156fde310099e0322b; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[2] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x39765fa514c503853592b2f72c557234c2efafba9815111959b6463678b15c5e; - poly_array[1] = 0x33a7ff8c7d32efdfafdee39e62c74afa54d488dc72dfe1ca78d0744fdf308ee1; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[3] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x2c391fa31a4e5650852011c5f16ada3f59db9ba0b4dafaef57099430348801d6; - poly_array[1] = 0x197b3e0837694a8ebab6d966f4a920f05af65dd30833e7dc0e913bf85ad37225; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[4] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x2d7be88f517910bc0fac0392ee91efe8d85a3a97d6a0d61afa3a0cb41712fe76; - poly_array[1] = 0x32843e5549400578b03af5fe731709f0a21d1c415b45d5c4b14f9fd149e66c1e; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[5] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x330b20e3b08c055a68e60d46f6b7b108fd953bbc7cde6ce77f0810887e2474f8; - poly_array[1] = 0x3a2d7c73d3d387ec99c36e57269e60cdcb76e747db777519f0b428306656db34; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[6] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3b6cf05c93b2ddce857281ab92c00820662ea883470eae0687fe528623881b2e; - poly_array[1] = 0x2bea6206030ca0310385056aab275eeb953faa84fe98143e6c450ca2bd914bfc; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[7] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3427a9cac1fadf65a0ee155dbce8116cc074c1e610f07b4f5f1488cbc4a3e0b8; - poly_array[1] = 0x23a552df25fa8ac97bf3441e7b4db68043c76ed2525ff794a31bcde16fb3e40c; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[8] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x0f83b9b92c770da002d1a2f26ff04acd3cbb2e5fa74e5b4751563f6e0d09ae57; - poly_array[1] = 0x2d83e394e01194e288428b4c5dbc4c25239fe6ed91e24c5e72a8d6efd7fc390e; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[9] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3f58d15471a50cb03e5ef99c687bc24c904dc825c944c528e267a8e0ca821806; - poly_array[1] = 0x0312eec0bd722003eaf7f6e00874f9770f2d3a988ec3f7fae804fab1d3269114; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[10] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x00c1c1243543a2e54373171f76be13e5942593734afef8b5b3c1a5bfb0bf2dc9; - poly_array[1] = 0x0bd82242c23980470f76eb13dfe88cf1ad2fc918f0cae76e63c9c34ff2dd58e2; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[11] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x0bec8b247b7b9aaa0f47ef1fa6e525878bf760049f601a4adeabb8d02223d171; - poly_array[1] = 0x1d4e02fdcd90b13c5b2bc528f50e11313a8e8b47f5177abd475c8bb23406510c; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[12] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3b314367a784bbad47b57679d0c57345027fea6e2e8d44c1ca6746971670fbe0; - poly_array[1] = 0x10c1a4c0d36de5eb0b5e3f733eeb644f9d29f4069afa840606b7e0a33214dbec; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[13] = poly; - return PolyLib.SumcheckProof(proof_array); - } - - // This function returns a SumcheckProof for the relevant corresponding field - function returnSecondaryOuterData() public pure returns (PolyLib.SumcheckProof memory) { - PolyLib.CompressedUniPoly[] memory proof_array = new PolyLib.CompressedUniPoly[](14); - uint256[] memory poly_array; - PolyLib.CompressedUniPoly memory poly; - poly_array = new uint256[](3); - poly_array[0] = 0x0000000000000000000000000000000000000000000000000000000000000000; - poly_array[1] = 0x090796c2a029b81e4b30b65a449b8f943a1cd5a119a5d6ea1865efebcc515975; - poly_array[2] = 0x067c67d9f00d27334795d0b6587f7de9e8bbb3ae85a2aa0730e87eb038750fd3; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[0] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x35ab7e62b24329fc2784fd4ddf143a4919e7b06b7f101b94c23325707d972598; - poly_array[1] = 0x0368440836408ed96cdeeda474fa6d50ca5304bcd994a59b04a35ad5cb82988c; - poly_array[2] = 0x0cd794be4f0dcd1962d1c3b94abf4869362315cde53e76c54ca6e69ffbb54fd1; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[1] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x1ac92b883ac9222ed2f099dc01a9a8698fdd2a981dc515a2908c73ee0779d4ed; - poly_array[1] = 0x05fa19839ccd1d979f724185a504eadf564e8cb13a35c789dc4c97862a1ab43f; - poly_array[2] = 0x3161fbce7771ce913d815456b42b3c129a9c3c120d8694ad5ddc53135bd7957c; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[2] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x3f8bfb004ecbb634983b60395e025445d813d52e2038661f2c2611e0efe87bb9; - poly_array[1] = 0x02e1a31742c3893a5022e217bd46588e69f284a88a1aab7fa821e9ae309e35f1; - poly_array[2] = 0x3f5038f7aada98ba046b1677110fc20c2308af4a7d4248a0fc20abac09fad80e; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[3] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x31411873831a3d0f76b6e21c1f0d638332453d84f73e6e62f597ea16d318f98a; - poly_array[1] = 0x181254eb869f39f12708a854068abfcf4fed2aedd2ffc2e28dcd00477b3b408a; - poly_array[2] = 0x2a38ce34a893f57f46230dc86c278af06f38201d09a5aac25fff21a362c19503; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[4] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x3b390cebb5321a5d374cfdc02f36e268e57436648adeb4a6f374d687e3b83f80; - poly_array[1] = 0x372ef3614d501411ece142d48fd34cb9cb092066f1257d38601b69788ad2eb7c; - poly_array[2] = 0x00c12c5100c9064d735aed7b10cc0ab283747058decbbb18a5b741acb8124bcd; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[5] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x1a904ae3fa645c6a5085fdd7e6a32aa13156989ceb38b27bcb6d50b93b9f5e50; - poly_array[1] = 0x2040c55e383b83f0aee66f0507d8b8dbad9712d946f0af4bf8b44927cef92620; - poly_array[2] = 0x0821176e32ab95c32676b38d8b9ab811c957f1831c9b27ab1f370ece48b671c6; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[6] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x17290df24a694e928dd665c9d347d71c787503678da8b85d0e68459512116b9e; - poly_array[1] = 0x1f2fb1f39a8e22a3837735fb2f050de5fe9db26f7c75abf1381dea16a557dec1; - poly_array[2] = 0x36a1cbeb839a6959595764789ff67be0e8a74f007ca7e7805794fbd6bad88b68; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[7] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x265113405d948ad03ae371265f568532c6ad37c400c92d667aa0140cd32969ac; - poly_array[1] = 0x22641d41c810605b33f7c87487722d6f41dabf9b1ceb8c99e8269a1f5a8c8037; - poly_array[2] = 0x0ced61caaabe14bf7895a0bdf4b841441aee4d43b5a7c4733b3472574f0a983d; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[8] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x1efdf83fe07484106737f606fbd1e3c29417a4d88fcd0969f6bc8cdfde0eec46; - poly_array[1] = 0x1b17694bef0a2f6d89acf07e0a830eb8088f07b6c2cb24d1108a6d3d83657a54; - poly_array[2] = 0x219f36cf1c636cb8e8f23931d44a1af19b5422d992773a1276c4c4ad7aeb81e6; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[9] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x3b1eb16f9af3e92be52401f4bc1a72e8819c7dada4bcb7085a1e660c6cd3b32c; - poly_array[1] = 0x0776b65ef71b553ccc400eb387c8eb1a5ee7205ad30c0fe2438373fd6a1bb7da; - poly_array[2] = 0x2151dbbf153f7aab0338111f1dad8709dae12680167d12fc3fa48aa5729ce042; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[10] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x008cd96ec564a9908459113718ebe2061337339f37d3c008e57ef3e0ce4c06f2; - poly_array[1] = 0x094407f4448f79930c8326c88624b016b7f6439a61664d2a7796d190a74d30c6; - poly_array[2] = 0x1bbbbb0e733aa832acf78c89ecfae9da618df4ad0addb0096d79d8feeb74df89; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[11] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x2589f6fbbb4b1b0fb0b2470bbc28d6cbf47536bd8c26c8e31e2acc3a10a761f6; - poly_array[1] = 0x34af65ce9841e688d2bfdeca1c90fa613bd53ccdd6027ccdbeb4749b41637824; - poly_array[2] = 0x109e02018ce3cfff0b3cbab192ee2848ab1653edfe520a57966a37827bff815b; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[12] = poly; - poly_array = new uint256[](3); - poly_array[0] = 0x3914ef9f52080f298240bedac07f6a3fbfe78a4b78b2012a43af5b9fed3eb2ab; - poly_array[1] = 0x03150bd2bc4fc7a377d012ace84edf8f266494b2a45e9e658df389a7970598f9; - poly_array[2] = 0x0e1d558f115e7184052f3a1a689989506165b26e4bfbcdde9245d38dd4b47149; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[13] = poly; - return PolyLib.SumcheckProof(proof_array); - } - - // This function returns a SumcheckProof for the relevant corresponding field - function returnSecondaryInnerData() public pure returns (PolyLib.SumcheckProof memory) { - PolyLib.CompressedUniPoly[] memory proof_array = new PolyLib.CompressedUniPoly[](15); - uint256[] memory poly_array; - PolyLib.CompressedUniPoly memory poly; - poly_array = new uint256[](2); - poly_array[0] = 0x2c5ad28caf2a30723db06b0c5f2daf1bd489089b295bea581a34b87ac4c992c5; - poly_array[1] = 0x11c867d92fbfd8321e07fa9f7bade6ca1e6485378644fb3c81ec92f75cd0f138; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[0] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x38db06de76eda60bb2ba837d498b852235666824b6a4a34fd4f0542a07eaf83c; - poly_array[1] = 0x0bc76064c182c83bf55acd1ef18e78b3edc84ccf6fbdc7cc13ab541423f1d777; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[1] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x107dc161b518391d870ad4776828cdbd7c2aa856ca05db4bca3ccebeb40b3e79; - poly_array[1] = 0x02cdd0b15810133f2614e9c3db70cce5703ebfe1942dedea4f8e814cdee6e9b9; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[2] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3acc1c97598f737e4f0a33c2a31448185bea391c46ca3c9a2d2f32b01cc00cfe; - poly_array[1] = 0x19159c6766b74f0cf6a164c5702700140c556041e42a9cd55f0395aaa3751d62; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[3] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3ddcb7ecc9a8a9746f03ddab3e84d35f5c5687db7777d1024f99715a2a0cf5e9; - poly_array[1] = 0x0f386d55fa899a2f680448f082f4044e94b16c619c0e00dc161abb316f5f055c; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[4] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x02bb0cd20cd33767bb2ced0bd20cf59964347983eb7d627679a10fec348dd93c; - poly_array[1] = 0x308611d1239b841723ea46beedd4ad6c18256cd7abace7ade92daffb85d432f1; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[5] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x091533e2c27b3de8b92b136f00258e310c4be08bf4deee63f6c2106d17226535; - poly_array[1] = 0x394e426b7ce6acc45aadb1149582754723398a47af7a048cad8c965a4a23edac; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[6] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x27f986cec5aa415f5c4f55605025a76fd3a3680513eb8cf846c2b807a1133a88; - poly_array[1] = 0x21073e2efb597f693306bfa1e7a9d69dc5017a496ceb6c60d4e24597de7bf386; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[7] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x089c618c7dd2d0d4cd214509ee66c061400af394292d26ab986a6d245396e726; - poly_array[1] = 0x3fc835443a5dcfcd52e21e2267cc07bd422c66cfe6c689d058da4f489361bdaf; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[8] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x02cc3866a95d1134d02f44744d2b9b07b7986ec7b0b9a86310e613973756329d; - poly_array[1] = 0x2ecadda0e35901a6d5d4619df0d1704f5b471c7e7ad17ce073628bd2688cea7a; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[9] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x187f6facad361cd0cb88c8b74b75d47b9d861d7822bbf19fe53106388af01b59; - poly_array[1] = 0x11bdfe5683e46f19bb9fd7052534090aff4c107f43ab0d972596ea4790a5b6c4; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[10] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x1cb6de6208c78deb1857e9c6e17561ca0f1b89430f6e03b4a9ca5963a14f62c1; - poly_array[1] = 0x2ffddcf67dd8dc7425ab39f6c9846052dd12e60627d1d434cc1d4febc6f096f1; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[11] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x2c6f01df34d61c82e0240a814a361eabf531e35c4e92df971e2b6ee6f933e490; - poly_array[1] = 0x195499856700d4f79a24519ecde2beee9d62249d638380691cb11a15a3d51b0f; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[12] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x08360997dd7d4470e3caefefc6189a980515f68cbe583138e24ea7225d7d463f; - poly_array[1] = 0x0ab471e96ccc91e240ee9c324d755cbc5df9ae23b784cd1958178d8b79c9360f; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[13] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x20350438adcd696b8d02f7fc56c0b61ec52a701e50a20f6d11fe7ff80bb3600b; - poly_array[1] = 0x196579d55c1006d34fe99b580bf70f1ca34cd057d73726f018de41e3004aa5e7; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[14] = poly; - return PolyLib.SumcheckProof(proof_array); - } - - // This function returns a SumcheckProof for the relevant corresponding field - function returnSecondaryBatchData() public pure returns (PolyLib.SumcheckProof memory) { - PolyLib.CompressedUniPoly[] memory proof_array = new PolyLib.CompressedUniPoly[](14); - uint256[] memory poly_array; - PolyLib.CompressedUniPoly memory poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3778dd47bff37eaa5f46f8cf0b8a83df26ab59e81d834880a62c98628dab18cb; - poly_array[1] = 0x36430699e436e3fd6d3a9d5c41285d72b43cbe9e7c0def5b430630beb883322e; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[0] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x23b2f8541fd8cca0087e7e772432296e6d5637b38694a0d3959dafec886a581d; - poly_array[1] = 0x380153e856d13c73bf6df99c746256f44790832f1b920537cb236e0700c41076; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[1] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x25264d4ca84b5fab52ed410c0b1edf4b73c283d36915442cdbf774b534d35b07; - poly_array[1] = 0x3bc4d96b1ff53b954914bf9695d6cae5dd7bd3857ff08cc9b44c525525d65e28; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[2] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x045c77586032794edc94fa6ef6baa4a1de0cae38cb0e50f292837e91a6c8da0f; - poly_array[1] = 0x3012c9f83f5d5897e253963d60f9e7764e5faefc3acdd2da0bc3357b77f56723; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[3] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3552e33e401d19eb6efd85b828f4da62edb71c482ecb551e2731611f116b6b37; - poly_array[1] = 0x1d77f649e9c08c2b722b7ea57e2b862f9a92c923e0d4e0bc29bb0c21d4a514f3; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[4] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x228c5e1529107612f903bf0006d376d2183fc2abfbed7097f53945c2fb99a2b1; - poly_array[1] = 0x263b63e884d49ce6ef5693aa4f4cd64efcee6b7c5c149585048aa2036609c209; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[5] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x31baa5e08c957f55acf5392f4e98c8b02ec7dc9142b6d2442cad8875c8ad1ac1; - poly_array[1] = 0x2d526b31084c79c9ba271b4f9dec0641b18fa4aded4fe24fb58f9e2262c7836f; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[6] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x15260793e8c1ebcdd6c40e7da3c223b56d99dddbc7835a708915f5da392065bf; - poly_array[1] = 0x33e63541161ad8a8f215e76fa48516d1736caefe88b8398e273444a1e3e5335c; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[7] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x3499aef515afcad923dd687caac79e2d8759ac186fa6353cc9af2e53078b4450; - poly_array[1] = 0x2070daf5b2e65015ee0a1adbe3037a2ee5f52d7b0c1da1e04bac11fadfb9d2e4; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[8] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x0b89d997302a0eb3e2d636852d43df2b478413a640c845dccbc4a71b9a1930be; - poly_array[1] = 0x088218b57f51763066db38c08963d7dff1dc61b08442f85d8b1cffd4a67de019; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[9] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x24beaaa573677f834b463dbdcd3877069039cba9c4480c0af736addb9ec539d8; - poly_array[1] = 0x1b77b1f53662c3bae203b71fde3886eccfc6a542cee8fa4e4584c21f524891d2; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[10] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x22c71df97cecf7de4475f48b77ddab8b514a000d732485eb0001ce5addb5f83d; - poly_array[1] = 0x1d9d3928f0d029539b68648d9ab43fbbe53f9abcda7bfe8b7e3e66a0ea9c08c9; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[11] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x31978a8cb06be3b5eacaf8f6cb648285b08e0440691a7f7e6108724cc74c2d35; - poly_array[1] = 0x1964ce18e81e22fcff8c793b878295a37d8960d07d878682ce5b1ac12686c41a; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[12] = poly; - poly_array = new uint256[](2); - poly_array[0] = 0x15c712d36849a0762b953a465e8c044fd7ca946dcf04265c68cd652859f5f9b1; - poly_array[1] = 0x04d0d2dfc250cd724074c023f2f099ffa61313893e0e4f84b4d99964e2186c29; - poly = PolyLib.CompressedUniPoly(poly_array); - proof_array[13] = poly; - return PolyLib.SumcheckProof(proof_array); - } - - // This function returns R1CS structure digest as a uint8[] - function returnPrimaryTranscriptData() public pure returns (uint8[] memory) { - uint8[] memory digest = new uint8[](32); - digest[0] = 0x23; - digest[1] = 0xa9; - digest[2] = 0x65; - digest[3] = 0xae; - digest[4] = 0xf5; - digest[5] = 0x44; - digest[6] = 0x37; - digest[7] = 0x51; - digest[8] = 0x77; - digest[9] = 0xe0; - digest[10] = 0xae; - digest[11] = 0x37; - digest[12] = 0x26; - digest[13] = 0x8b; - digest[14] = 0x5b; - digest[15] = 0x32; - digest[16] = 0xca; - digest[17] = 0x91; - digest[18] = 0x55; - digest[19] = 0x28; - digest[20] = 0xac; - digest[21] = 0x3b; - digest[22] = 0x12; - digest[23] = 0x23; - digest[24] = 0xe5; - digest[25] = 0x68; - digest[26] = 0xfb; - digest[27] = 0x1c; - digest[28] = 0xef; - digest[29] = 0x6b; - digest[30] = 0x41; - digest[31] = 0x03; - - return digest; - } - // This function returns R1CS structure digest as a uint8[] - - function returnSecondaryTranscriptData() public pure returns (uint8[] memory) { - uint8[] memory digest = new uint8[](32); - digest[0] = 0x11; - digest[1] = 0x73; - digest[2] = 0x20; - digest[3] = 0xb4; - digest[4] = 0x29; - digest[5] = 0x57; - digest[6] = 0x30; - digest[7] = 0x8a; - digest[8] = 0x3a; - digest[9] = 0x95; - digest[10] = 0xd2; - digest[11] = 0x08; - digest[12] = 0x54; - digest[13] = 0x2d; - digest[14] = 0xaa; - digest[15] = 0x4c; - digest[16] = 0xc7; - digest[17] = 0xbf; - digest[18] = 0xd6; - digest[19] = 0x6d; - digest[20] = 0x70; - digest[21] = 0xfc; - digest[22] = 0xa6; - digest[23] = 0xce; - digest[24] = 0x14; - digest[25] = 0x9e; - digest[26] = 0xd4; - digest[27] = 0x51; - digest[28] = 0x7c; - digest[29] = 0x6d; - digest[30] = 0xc2; - digest[31] = 0x01; - - return digest; - } -} diff --git a/src/verifier/step4/sumcheck-data-contract-gen.py b/src/verifier/step4/sumcheck-data-contract-gen.py deleted file mode 100644 index 911b519..0000000 --- a/src/verifier/step4/sumcheck-data-contract-gen.py +++ /dev/null @@ -1,160 +0,0 @@ -import json -import sys -import os -from enum import Enum - -class Version(Enum): - PRIMARY = "Primary" - SECONDARY = "Secondary" - - def get_curve(self) -> str: - match self: - case Version.PRIMARY: - return "Pallas" - case Version.SECONDARY: - return "Vesta" - -def h(s): - """ - Hexify a string - """ - return "0x" + s - -def reverse_bytes(val): - """ - Reverses the byte order of a hexdecimal number for ingest in Solidity contract - """ - ba = bytearray.fromhex(val) - ba.reverse() - return ba.hex() - -def sumcheck_data_contract_gen(data): - compressed_polynomials = data["compressed_polys"] - output = f"PolyLib.CompressedUniPoly[] memory proof_array = new PolyLib.CompressedUniPoly[]({len(compressed_polynomials)});\n" - output += "uint256[] memory poly_array;\n" - degree = len(compressed_polynomials[0]["coeffs_except_linear_term"]) - output += f"PolyLib.CompressedUniPoly memory poly;\n" - - for poly_idx, poly in enumerate(compressed_polynomials): - coeffs = poly["coeffs_except_linear_term"] - output += f"poly_array = new uint256[]({degree});\n" - for coeff_idx, coeff in enumerate(coeffs): - output += f"poly_array[{coeff_idx}] = {h(reverse_bytes(coeff))};\n" - output += f"poly = PolyLib.CompressedUniPoly(poly_array);\n" - output += f"proof_array[{poly_idx}] = poly;\n" - - output += f"return PolyLib.SumcheckProof(proof_array);\n" - return output - -def transcript_data_contract_gen(data): - output = f"uint8[] memory digest = new uint8[](32);\n" - for idx in range(32): - output += f"digest[{idx}] = {h(data[2*idx:2*(idx + 1)])};\n" - - output += "\nreturn digest;" - return output - -def function_decl(name: str) -> str: - output = f"function {name}()\n" - output += "public pure returns\n" - return output - -def sumcheck_function_return() -> str: - return f"(PolyLib.SumcheckProof memory)" + " {\n" - -vk_file = sys.argv[1] -if not os.path.exists(vk_file): - print("verifier-key (json) input file is missing") - exit(1) - -proof_file = sys.argv[2] -if not os.path.exists(proof_file): - print("compressed snark (json) input file is missing") - exit(1) - -proof_f = open(os.path.basename(proof_file)) -proof_data = json.load(proof_f) - -vk_f = open(os.path.basename(vk_file)) -vk_data = json.load(vk_f) - -header = "// SPDX-License-Identifier: Apache-2.0\n" -header += f"// Do not change manually. This contract has been auto-generated by {sys.argv[0]}\n" -header += "pragma solidity ^0.8.16;\n" -header += 'import "src/Utilities.sol";\n' -header += 'import "src/verifier/step4/SumcheckLogic.sol";\n' - -sumcheck_function_doc = "// This function returns a SumcheckProof for the relevant corresponding field\n" - -primary_data = proof_data["f_W_snark_primary"] - -primary_outer_data_def = sumcheck_function_doc -primary_outer_data_def += function_decl("returnPrimaryOuterData") -primary_outer_data_def += sumcheck_function_return() -primary_outer_data_def += sumcheck_data_contract_gen(primary_data["sc_proof_outer"]) -primary_outer_data_def += "}\n\n" - -primary_inner_data_def = sumcheck_function_doc -primary_inner_data_def += function_decl("returnPrimaryInnerData") -primary_inner_data_def += sumcheck_function_return() -primary_inner_data_def += sumcheck_data_contract_gen(primary_data["sc_proof_inner"]) -primary_inner_data_def += "}\n\n" - -primary_batch_data_def = sumcheck_function_doc -primary_batch_data_def += function_decl("returnPrimaryBatchData") -primary_batch_data_def += sumcheck_function_return() -primary_batch_data_def += sumcheck_data_contract_gen(primary_data["sc_proof_batch"]) -primary_batch_data_def += "}\n\n" - -secondary_data = proof_data["f_W_snark_secondary"] - -secondary_outer_data_def = sumcheck_function_doc -secondary_outer_data_def += function_decl("returnSecondaryOuterData") -secondary_outer_data_def += sumcheck_function_return() -secondary_outer_data_def += sumcheck_data_contract_gen(secondary_data["sc_proof_outer"]) -secondary_outer_data_def += "}\n\n" - -secondary_inner_data_def = sumcheck_function_doc -secondary_inner_data_def += function_decl("returnSecondaryInnerData") -secondary_inner_data_def += sumcheck_function_return() -secondary_inner_data_def += sumcheck_data_contract_gen(secondary_data["sc_proof_inner"]) -secondary_inner_data_def += "}\n\n" - -secondary_batch_data_def = sumcheck_function_doc -secondary_batch_data_def += function_decl("returnSecondaryBatchData") -secondary_batch_data_def += sumcheck_function_return() -secondary_batch_data_def += sumcheck_data_contract_gen(secondary_data["sc_proof_batch"]) -secondary_batch_data_def += "}\n\n" - -transcript_function_doc = "// This function returns R1CS structure digest as a uint8[]\n" - -primary_transcript_data = vk_data["vk_primary"]["comm"]["S"]["digest"] - -primary_transcript_data_def = transcript_function_doc -primary_transcript_data_def += function_decl("returnPrimaryTranscriptData") -primary_transcript_data_def += "(uint8[] memory) {\n" -primary_transcript_data_def += transcript_data_contract_gen(primary_transcript_data) -primary_transcript_data_def += "}\n" - -secondary_transcript_data = vk_data["vk_secondary"]["comm"]["S"]["digest"] - -secondary_transcript_data_def = transcript_function_doc -secondary_transcript_data_def += function_decl("returnSecondaryTranscriptData") -secondary_transcript_data_def += "(uint8[] memory) {\n" -secondary_transcript_data_def += transcript_data_contract_gen(secondary_transcript_data) -secondary_transcript_data_def += "}\n" - -data_contract_body = "library SumcheckData {\n" -data_contract_body += primary_outer_data_def -data_contract_body += primary_inner_data_def -data_contract_body += primary_batch_data_def -data_contract_body += secondary_outer_data_def -data_contract_body += secondary_inner_data_def -data_contract_body += secondary_batch_data_def -data_contract_body += primary_transcript_data_def -data_contract_body += secondary_transcript_data_def - -data_contract_body += "}\n" - -print(header) -print(data_contract_body) diff --git a/test/eq-evaluation-tests.t.sol b/test/eq-evaluation-tests.t.sol index 307f3de..9c90fee 100644 --- a/test/eq-evaluation-tests.t.sol +++ b/test/eq-evaluation-tests.t.sol @@ -41,7 +41,7 @@ contract EqEvaluationTest is Test { r_x[13] = 0x3d764ae71118a8a3c653b58c534db9fae607dd9c316cdd3675de0d62e0882bf1; uint256 expected = 0x1ecc7a4636c12e49b10abfeee2365a0c8d33720ef207c874decf5b635e5a0f5c; - uint256 tauBoundRx = EqPolinomialLib.evaluateVesta(tau, r_x); + uint256 tauBoundRx = EqPolinomialLib.evaluate(tau, r_x, Vesta.P_MOD, Vesta.negateBase); assertEq(expected, tauBoundRx); } @@ -80,7 +80,7 @@ contract EqEvaluationTest is Test { r_x[13] = 0x3d764ae71118a8a3c653b58c534db9fae607dd9c316cdd3675de0d62e0882bf1; uint256 expected = 0x3b107e7354c4abec25131c83747810862c123a8f30de4670b369b8660520fb5b; - uint256 rz_rx = EqPolinomialLib.evaluateVesta(r_z, r_x); + uint256 rz_rx = EqPolinomialLib.evaluate(r_z, r_x, Vesta.P_MOD, Vesta.negateBase); assertEq(rz_rx, expected); } @@ -119,7 +119,7 @@ contract EqEvaluationTest is Test { r_y[13] = 0x0d2d8f8c26d30b56b526ddf9b803f597db14b25fe78fe4dba4ce487d9fb4fcb4; uint256 expected = 0x3c9713a8eb8666e4e2717f2ca5c3bed2e9a4532e3603984212bbbccf5008bf3a; - uint256 rz_ry = EqPolinomialLib.evaluateVesta(r_z, r_y); + uint256 rz_ry = EqPolinomialLib.evaluate(r_z, r_y, Vesta.P_MOD, Vesta.negateBase); assertEq(rz_ry, expected); } @@ -158,7 +158,7 @@ contract EqEvaluationTest is Test { r_x[13] = 0x0218ba00634e903a39bd7ed1388141981ac7aaa0572ba61802aaf2b580667bf1; uint256 expected = 0x183f09f805c4694f9330edd10a2b68ea8bb8f026cea7e79f2e034b837b2daeb6; - uint256 tauBoundRx = EqPolinomialLib.evaluatePallas(tau, r_x); + uint256 tauBoundRx = EqPolinomialLib.evaluate(tau, r_x, Pallas.P_MOD, Pallas.negateBase); assertEq(expected, tauBoundRx); } @@ -197,7 +197,7 @@ contract EqEvaluationTest is Test { r_y[13] = 0x3e69c1910a9263ddee4a0cec382a858a67e33f74de3d76058fd6248cd8257cc8; uint256 expected = 0x38c914520e951ca5d3478b57612d8df23cdeaca6ba8181f3831e4a461bce7389; - uint256 rz_ry = EqPolinomialLib.evaluatePallas(r_z, r_y); + uint256 rz_ry = EqPolinomialLib.evaluate(r_z, r_y, Pallas.P_MOD, Pallas.negateBase); assertEq(rz_ry, expected); } @@ -236,7 +236,7 @@ contract EqEvaluationTest is Test { r_x[13] = 0x0218ba00634e903a39bd7ed1388141981ac7aaa0572ba61802aaf2b580667bf1; uint256 expected = 0x02548c885400ebd1e518ed3538d94c0d41e3b69ffc09cd4370784e6fd1ad9318; - uint256 rz_rx = EqPolinomialLib.evaluatePallas(r_z, r_x); + uint256 rz_rx = EqPolinomialLib.evaluate(r_z, r_x, Pallas.P_MOD, Pallas.negateBase); assertEq(rz_rx, expected); } @@ -258,7 +258,7 @@ contract EqEvaluationTest is Test { expectedEvals[6] = 0x329198484407a31b972f171b2b28f4c259859864440049b81bf066f8d2e604fc; expectedEvals[7] = 0x0a8496185c3002e47f4b749335065bd6885393f11b3b58acf6ea877d24010f26; - uint256[] memory evals = EqPolinomialLib.evalsVesta(tau); + uint256[] memory evals = EqPolinomialLib.evals(tau, Vesta.P_MOD, Vesta.negateBase); assertEq(evals.length, expectedEvalsLen); for (uint256 i = 0; i < expectedEvalsLen; i++) { @@ -292,7 +292,7 @@ contract EqEvaluationTest is Test { expectedEvals[14] = 0x38d419f8507619aa864bf547f461b89b484fa52f183b68d4c114d0d875c19bf6; expectedEvals[15] = 0x11b07c200bb9e939f8ff7f4b40a4a33b624a87be0c9498b5c21ca1c5ae3f7331; - uint256[] memory evals = EqPolinomialLib.evalsVesta(tau); + uint256[] memory evals = EqPolinomialLib.evals(tau, Vesta.P_MOD, Vesta.negateBase); assertEq(evals.length, expectedEvalsLen); for (uint256 i = 0; i < expectedEvalsLen; i++) { @@ -343,7 +343,7 @@ contract EqEvaluationTest is Test { expectedEvals[30] = 0x23ba308243e90dfcf16d3ae14e5616ff92736ec5d39502bba0aacc61bfb7983c; expectedEvals[31] = 0x243c947f20c3f640a5050152eb7799ddcdb4a2895c0de769e462161e5d361ac8; - uint256[] memory evals = EqPolinomialLib.evalsVesta(tau); + uint256[] memory evals = EqPolinomialLib.evals(tau, Vesta.P_MOD, Vesta.negateBase); assertEq(evals.length, expectedEvalsLen); for (uint256 i = 0; i < expectedEvalsLen; i++) { @@ -374,7 +374,7 @@ contract EqEvaluationTest is Test { uint256 expected_12846 = 0x08a280a50f2d4253c17ed47c5edfed39560f5189a430c102ef00960514e3300a; uint256 expected_16000 = 0x264db57dbf9e8cda1752e7c88c2380f2604c140067d1d6c294c92901fd80a1f0; - uint256[] memory evals = EqPolinomialLib.evalsVesta(tau); + uint256[] memory evals = EqPolinomialLib.evals(tau, Vesta.P_MOD, Vesta.negateBase); assertEq(evals.length, 2 ** tau.length); assertEq(evals[25], expected_25); assertEq(evals[380], expected_380); @@ -400,7 +400,7 @@ contract EqEvaluationTest is Test { expectedEvals[6] = 0x2a989e96c121b6c28703b7c1d25f70999289edad14e61a2e75e1e19827e322d5; expectedEvals[7] = 0x3d7934d32f5730a53a7d253443e80a39d81b07089588eb55bd4704d3c3528989; - uint256[] memory evals = EqPolinomialLib.evalsVesta(tau); + uint256[] memory evals = EqPolinomialLib.evals(tau, Vesta.P_MOD, Vesta.negateBase); assertEq(evals.length, expectedEvalsLen); for (uint256 i = 0; i < expectedEvalsLen; i++) { @@ -434,7 +434,7 @@ contract EqEvaluationTest is Test { expectedEvals[14] = 0x25e9154e274c6559fe95f6bc65f5c0b24f60e8ec9f3c3d47d78f143450ae95ac; expectedEvals[15] = 0x17901f85080acb4b3be72e77ddf2498788ba1e1bf64cae0de5b7f09f72a3f3dd; - uint256[] memory evals = EqPolinomialLib.evalsVesta(tau); + uint256[] memory evals = EqPolinomialLib.evals(tau, Vesta.P_MOD, Vesta.negateBase); assertEq(evals.length, expectedEvalsLen); for (uint256 i = 0; i < expectedEvalsLen; i++) { @@ -465,7 +465,7 @@ contract EqEvaluationTest is Test { uint256 expected_10990 = 0x266112cd25ef3a6db1c5fd29c974623019b257d81d2d6030b1d86608a13ae827; uint256 expected_15998 = 0x39fc62e9d005e4ba23a27f29736dcb7a77c88aabda02ccaec49cc5591778da41; - uint256[] memory evals = EqPolinomialLib.evalsVesta(tau); + uint256[] memory evals = EqPolinomialLib.evals(tau, Vesta.P_MOD, Vesta.negateBase); assertEq(evals.length, 2 ** tau.length); assertEq(evals[98], expected_98); assertEq(evals[284], expected_284); @@ -491,7 +491,7 @@ contract EqEvaluationTest is Test { r_x[12] = 0x070bb7c8b02abf2d75ef8b6b8fb3997745d1c041991e0d3af11d78b11f879920; r_x[13] = 0x0218ba00634e903a39bd7ed1388141981ac7aaa0572ba61802aaf2b580667bf1; - uint256[] memory T_x = EqPolinomialLib.evalsPallas(r_x); + uint256[] memory T_x = EqPolinomialLib.evals(r_x, Pallas.P_MOD, Pallas.negateBase); uint256 expectedLen = 16384; uint256 T_x_expected_0 = 0x3cac77591cd8693719d5c89c475a6c978fbeb6bdb3fffc9cb916a97d5c17f664; @@ -528,7 +528,7 @@ contract EqEvaluationTest is Test { r_y[13] = 0x1ed7da2e753c94332e034b046d37937577582b78c2cffa3ada412ac7d6446745; r_y[14] = 0x3e69c1910a9263ddee4a0cec382a858a67e33f74de3d76058fd6248cd8257cc8; - uint256[] memory T_y = EqPolinomialLib.evalsPallas(r_y); + uint256[] memory T_y = EqPolinomialLib.evals(r_y, Pallas.P_MOD, Pallas.negateBase); uint256 expectedLen = 32768; uint256 T_y_expected_0 = 0x3d1442de6e207afdf8f0c86bc413471387757ee37ba9f7474637c24bd81f7500; diff --git a/test/folding-verifier-tests.t.sol b/test/folding-verifier-tests.t.sol deleted file mode 100644 index 8214da1..0000000 --- a/test/folding-verifier-tests.t.sol +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.0; - -import "@std/Test.sol"; -import "src/blocks/pasta/Pallas.sol"; -import "src/blocks/pasta/Vesta.sol"; -import "src/Utilities.sol"; -import "src/verifier/step3/Step3Logic.sol"; -import "src/verifier/step3/Step3Data.sol"; - -contract FoldingVerifierTest is Test { - function testTinyInstanceFolding() public { - /* - Test vector generated using - - let mut csprng = ChaChaRng::from_seed([17u8; 32]); - - in test_tiny_r1cs_with - */ - - // unfolded initial R1CSInstance - Pallas.PallasAffinePoint memory u1_comm_W = Pallas.IntoAffine( - Pallas.PallasProjectivePoint( - 0x1c178ee13ca557d2c68c77ae48361df45fdaa5504297d1af622902242afcf154, - 0x330fab9610d3222bfd999f8297b647a902ef98b099aef8d93743a4f870ec904c, - 0x08f4a8de0b7df4347d41a278ee4a3be366ba18cb130c907271849c1d0387677b - ) - ); - - uint256[] memory u1_X = new uint256[](2); - u1_X[0] = 0x2ab11c4b451eab35b0e5407e4eacb780a317a34935c4c0d5511f6b00a493389f; - u1_X[1] = 0x0b475cff3a5f46b549451802e64ded130c5151037f31b5174ef9036746c5ba0e; - - NIFSPallas.R1CSInstance memory u1 = NIFSPallas.R1CSInstance(u1_comm_W, u1_X); - - // RelaxedR1CSInstance - - uint256[] memory r_U_X = new uint256[](2); - r_U_X[0] = 0x0; - r_U_X[1] = 0x0; - - NIFSPallas.RelaxedR1CSInstance memory r_U = - NIFSPallas.RelaxedR1CSInstance(Pallas.AffineInfinity(), Pallas.AffineInfinity(), r_U_X, 0); - - // NIFS instance - // result of the first NIFS::prove - NIFSPallas.NIFS memory input_nifs = NIFSPallas.NIFS( - Field.uint8ArrayToBytes32( - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - ) - ); - - Pallas.PallasAffinePoint memory res_U_comm_W = Pallas.IntoAffine( - Pallas.PallasProjectivePoint( - 0x1603f1814dac3534ae4091202fe2eb88832983a9fbaa5ebeec6d3dfabbdae892, - 0x0d022bd151c061d4e91f3ff131b39d0fba10919f860e831412a815dae1295b77, - 0x2f857938dfeddd66b08b95a7dba0d0b8b76d6f8ea1f64e96668fdd25a018436c - ) - ); - - uint256[] memory res_U_X = new uint256[](2); - - res_U_X[0] = 0x0699b06b6ebadaf9d40cba2d702f48fad255059f25d85441bcf706bc0510b95e; - res_U_X[1] = 0x3307f24938c5acb2fa00b27fc0a1e733f48bc7cf4a4558febed97167978bb576; - - uint256 res_U_u = 0x000000000000000000000000000000006cbba3b281698850b3c9ea90b6ccbb65; - - NIFSPallas.RelaxedR1CSInstance memory res = NIFSPallas.verify(input_nifs, 0, r_U, u1); - - // Check the resulting RelaxedR1CSInstance is the one obtained by proving - assertEq(res.comm_W.x, res_U_comm_W.x); - assertEq(res.comm_W.y, res_U_comm_W.y); - assert(Pallas.isInfinity(res.comm_E)); - assertEq(res.u, res_U_u); - assertEq(res.X, res_U_X); - - // Second input R1CSInstance - u1_comm_W = Pallas.IntoAffine( - Pallas.PallasProjectivePoint( - 0x166c397590b591b38485f4d4db866afd8aecd4255d00e70153d7cc3ce3186b51, - 0x274173e01c6133a2a90faa0296496c2661cd7c04d79c190ef6f43c1764565ca5, - 0x1d535198a7eb87ce16d7f0aa529729c1128637b3f83777d966be58c8f2a5b5b6 - ) - ); - - u1_X[0] = 0x0b475cff3a5f46b549451802e64ded130c5151037f31b5174ef9036746c5ba0e; - u1_X[1] = 0x188fbd43956fbf712f60b46fb3a0d608c99ae9f7f4f2d7f7becd150dee669089; - - u1 = NIFSPallas.R1CSInstance(u1_comm_W, u1_X); - - // Result of the second NIFS::prove - input_nifs = NIFSPallas.NIFS( - Field.uint8ArrayToBytes32( - [ - 168, - 57, - 208, - 82, - 169, - 86, - 167, - 134, - 12, - 8, - 190, - 237, - 144, - 237, - 99, - 68, - 3, - 22, - 144, - 12, - 90, - 70, - 28, - 172, - 86, - 202, - 180, - 126, - 45, - 205, - 39, - 5 - ] - ) - ); - - res_U_comm_W = Pallas.IntoAffine( - Pallas.PallasProjectivePoint( - 0x122238e71a344dde362e92c65f93690c6f356c6666db533f5d0f39e8ab134ab2, - 0x2a1550650218ca763a7cd9fe48e67d97a6c39fd69b7043fb39eaeced7c5ed721, - 0x0008d28e00b56e6dffbde9cc3caa4415789d013d2ca8f6b5483edee2087720c2 - ) - ); - - Pallas.PallasAffinePoint memory res_U_comm_E = Pallas.IntoAffine( - Pallas.PallasProjectivePoint( - 0x1e87a801f6b831cbce80ce8b1585cb690307ef8e871fbf0bbf58e199bd1801ee, - 0x1cccc4e22a8c9ce3716046a8d4bc6d7406164e0f89621d34460a566b8170b658, - 0x0534667e7d16b8e798bd1bca1242c6f5d4f7677eb37846cba8688f65a1c11cd2 - ) - ); - - res_U_X[0] = 0x3fa77fe734b081a54b7d6c05ab52246994ceee962993c5f1d8d1ba9b9a9f2292; - res_U_X[1] = 0x3bb3e2353aa89382debe2689f2e2b153d54a95d647d6a390c277f1d65e892815; - - res_U_u = 0x00000000000000000000000000000000bca88a0bf16269fef2be84cbdf620537; - - NIFSPallas.RelaxedR1CSInstance memory res2 = NIFSPallas.verify(input_nifs, 0, res, u1); - - assertEq(res2.comm_W.x, res_U_comm_W.x); - assertEq(res2.comm_W.y, res_U_comm_W.y); - assertEq(res2.comm_E.x, res_U_comm_E.x); - assertEq(res2.comm_E.y, res_U_comm_E.y); - assertEq(res2.u, res_U_u); - assertEq(res2.X, res_U_X); - } -} diff --git a/test/keccak-transcript-tests.t.sol b/test/keccak-transcript-tests.t.sol index f24e040..084d088 100644 --- a/test/keccak-transcript-tests.t.sol +++ b/test/keccak-transcript-tests.t.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.0; +pragma solidity ^0.8.16; import "@std/Test.sol"; -import "src/verifier/step4/KeccakTranscript.sol"; +import "src/blocks/KeccakTranscript.sol"; contract KeccakTranscriptContractTest is Test { function testScalarFromUniform() public { @@ -81,7 +81,9 @@ contract KeccakTranscriptContractTest is Test { assertEq(scalarVesta, expectedVesta); } - function testKeccakTranscriptPallas() public { + // Following test has been ported: https://github.com/lurk-lab/Nova/blob/solidity-verifier-pp-spartan/src/provider/keccak.rs#L138 + // TODO: For some reason, test vector passes if using Vesta curve parameters, but in reference implementation type of point is Pallas + function testKeccakTranscriptVesta() public { uint8[] memory input = new uint8[](4); // b"test" in Rust input[0] = 0x74; input[1] = 0x65; @@ -90,34 +92,47 @@ contract KeccakTranscriptContractTest is Test { KeccakTranscriptLib.KeccakTranscript memory transcript = KeccakTranscriptLib.instantiate(input); - uint256 input1 = 123456789; + uint256 input1 = 2; uint8[] memory label1 = new uint8[](2); // b"s1" in Rust label1[0] = 0x73; label1[1] = 0x31; - uint256 input2 = 987654321; + uint256 input2 = 5; uint8[] memory label2 = new uint8[](2); // b"s2" in Rust label2[0] = 0x73; label2[1] = 0x32; - KeccakTranscriptLib.KeccakTranscript memory transcript1 = KeccakTranscriptLib.absorb(transcript, label1, input1); - KeccakTranscriptLib.KeccakTranscript memory transcript2 = - KeccakTranscriptLib.absorb(transcript1, label2, input2); + transcript = KeccakTranscriptLib.absorb(transcript, label1, input1); + transcript = KeccakTranscriptLib.absorb(transcript, label2, input2); uint8[] memory squeezeLabel = new uint8[](2); // b"c1" in Rust squeezeLabel[0] = 0x63; squeezeLabel[1] = 0x31; - ScalarFromUniformLib.Curve curve = ScalarFromUniformLib.curvePallas(); - (, uint256 output) = KeccakTranscriptLib.squeeze(transcript2, curve, squeezeLabel); + ScalarFromUniformLib.Curve curve = ScalarFromUniformLib.curveVesta(); + uint256 output; + (transcript, output) = KeccakTranscriptLib.squeeze(transcript, curve, squeezeLabel); - uint256 expected = 0x3484d00943072ca9baa6dcd107e9bf09d599558b2a8b37ebd9e50e340c5d03a3; + uint256 expected = Field.reverse256(0x5ddffa8dc091862132788b8976af88b9a2c70594727e611c7217ba4c30c8c70a); + assertEq(output, expected); + + uint256 s3 = 128; + uint8[] memory label3 = new uint8[](2); // b"s3" in Rust + label3[0] = 0x73; + label3[1] = 0x33; + + transcript = KeccakTranscriptLib.absorb(transcript, label3, s3); + + // b"c2" in Rust + squeezeLabel[0] = 0x63; + squeezeLabel[1] = 0x32; + (, output) = KeccakTranscriptLib.squeeze(transcript, curve, squeezeLabel); + + expected = Field.reverse256(0x4d4bf42c065870395749fa1c4fb641df1e0d53f05309b03d5b1db7f0be3aa13d); assertEq(output, expected); } - // Following test has been ported: https://github.com/microsoft/Nova/blob/main/src/provider/keccak.rs#L107 - // TODO: For some reason, test vector passes if using Vesta curve parameters, but in reference implementation type of point is Pallas - function testKeccakTranscriptVesta() public { + function testKeccakTranscriptPallas() public { uint8[] memory input = new uint8[](4); // b"test" in Rust input[0] = 0x74; input[1] = 0x65; @@ -136,35 +151,33 @@ contract KeccakTranscriptContractTest is Test { label2[0] = 0x73; label2[1] = 0x32; - KeccakTranscriptLib.KeccakTranscript memory transcript1 = KeccakTranscriptLib.absorb(transcript, label1, input1); - KeccakTranscriptLib.KeccakTranscript memory transcript2 = - KeccakTranscriptLib.absorb(transcript1, label2, input2); + transcript = KeccakTranscriptLib.absorb(transcript, label1, input1); + transcript = KeccakTranscriptLib.absorb(transcript, label2, input2); uint8[] memory squeezeLabel = new uint8[](2); // b"c1" in Rust squeezeLabel[0] = 0x63; squeezeLabel[1] = 0x31; - ScalarFromUniformLib.Curve curve = ScalarFromUniformLib.curveVesta(); - (KeccakTranscriptLib.KeccakTranscript memory transcript3, uint256 output) = - KeccakTranscriptLib.squeeze(transcript2, curve, squeezeLabel); + ScalarFromUniformLib.Curve curve = ScalarFromUniformLib.curvePallas(); + uint256 output; + (transcript, output) = KeccakTranscriptLib.squeeze(transcript, curve, squeezeLabel); - uint256 expected = 0x0c34755d6b4566f930b8371afd2e4818ae49878a10527fd4443dbec811582d43; + uint256 expected = Field.reverse256(0xc64ec10ff9437f1053c8647b52358f10e59d80e7302a777dfecf8d49f0e29121); assertEq(output, expected); - uint256 input3 = 128; + uint256 s3 = 128; uint8[] memory label3 = new uint8[](2); // b"s3" in Rust label3[0] = 0x73; label3[1] = 0x33; - KeccakTranscriptLib.KeccakTranscript memory transcript4 = - KeccakTranscriptLib.absorb(transcript3, label3, input3); - uint8[] memory squeezeLabel1 = new uint8[](2); // b"c2" in Rust - squeezeLabel1[0] = 0x63; - squeezeLabel1[1] = 0x32; + transcript = KeccakTranscriptLib.absorb(transcript, label3, s3); - (, uint256 output1) = KeccakTranscriptLib.squeeze(transcript4, curve, squeezeLabel1); + // b"c2" in Rust + squeezeLabel[0] = 0x63; + squeezeLabel[1] = 0x32; + (, output) = KeccakTranscriptLib.squeeze(transcript, curve, squeezeLabel); - uint256 expected1 = 0x107a4d1de226bea79c5e636a56c7919b00f96e4567d7b1f318cdab538d90f765; - assertEq(output1, expected1); + expected = Field.reverse256(0xe3585da385704879ec03ef201dbf228e7b227a5af709f83f3ed5f92a5037d633); + assertEq(output, expected); } } diff --git a/test/nova-verifier-tests.t.sol b/test/nova-verifier-tests.t.sol index 96dd299..0c284d9 100644 --- a/test/nova-verifier-tests.t.sol +++ b/test/nova-verifier-tests.t.sol @@ -2,17 +2,14 @@ pragma solidity ^0.8.0; import "@std/Test.sol"; -import "src/verifier/step3/Step3Logic.sol"; -import "src/verifier/step3/Step3Data.sol"; import "src/blocks/poseidon/Sponge.sol"; import "src/verifier/step4/SubStep2.sol"; -import "src/verifier/step4/SumcheckLogic.sol"; -import "src/verifier/step4/SumcheckData.sol"; +import "src/blocks/Sumcheck.sol"; import "src/blocks/pasta/Pallas.sol"; import "src/blocks/pasta/Vesta.sol"; contract NovaVerifierContractTest is Test { - function testPrimaryVerificationStep4SubStep2() public pure { + function testPrimaryVerificationStep4SubStep2() public { uint256[] memory tau = new uint256[](14); tau[0] = 0x327f4af4db96711d3192cee19b1946d5b9d3c61e78d6f352261e11af7cbed55a; tau[1] = 0x2640290b59a25f849e020cb1b0063861e35a95a8c42a9cdd63928a4ea856adbf; @@ -57,7 +54,7 @@ contract NovaVerifierContractTest is Test { ); } - function testSecondaryVerificationStep4SubStep2() public pure { + function testSecondaryVerificationStep4SubStep2() public { uint256[] memory tau = new uint256[](14); tau[0] = 0x009c590b21fa438a0f41c61f879bde904d64caa038b18e804a5b45d294334b1e; tau[1] = 0x3d751f5428fbcf26b2ae69067c7fd14af5c1565070f12c8444ec6682ada61091; @@ -101,688 +98,4 @@ contract NovaVerifierContractTest is Test { tau, r_x, claim_Az, claim_Bz, claim_Cz, eval_E, U_u, claim_outer_final ); } - - function testNontrivialPrimaryFolding() public { - ( - uint256 S_digest, - bytes32 nifs, - uint256 r_W, - uint256 r_E, - uint256[] memory r_X, - uint256 r_u, - uint256 l_W, - uint256[] memory l_X - ) = Step3Data.returnPrimaryData(); - - NIFSPallas.RelaxedR1CSInstance memory result = NIFSPallas.verify( - NIFSPallas.NIFS(nifs), - S_digest, - NIFSPallas.RelaxedR1CSInstance(Pallas.decompress(r_W), Pallas.decompress(r_E), r_X, r_u), - NIFSPallas.R1CSInstance(Pallas.decompress(l_W), l_X) - ); - - uint256 expected_comm_W_x = 0x377d16c3de44e589fb6f0371093d648d2f3933db1c52aab0f28e76834ea98e8c; - uint256 expected_comm_W_y = 0x0985c3acbcdcfe95fd6531f819e82b17e5afdf8cc82187a4367c658bb9fb0a55; - uint256 expected_comm_W_z = 0x0406f654f562ba978cb48c15983ec87135382aef386bbe5d984980c6ef462323; - - Pallas.PallasAffinePoint memory expected_comm_W = - Pallas.IntoAffine(Pallas.PallasProjectivePoint(expected_comm_W_x, expected_comm_W_y, expected_comm_W_z)); - - uint256 expected_comm_E_x = 0x3fc650f5b92937a4a00c54c14da562de8dfca830c4bb82dd34debbaa5f847b19; - uint256 expected_comm_E_y = 0x12059c8862f4766782e3add45baad4e0dd5bc5e133baa9cc8fbd4f53ea857597; - uint256 expected_comm_E_z = 0x0741cc9fdbf8d776f052b3350776a93e038328478aa2926b319c62e9a46f1ab1; - - Pallas.PallasAffinePoint memory expected_comm_E = - Pallas.IntoAffine(Pallas.PallasProjectivePoint(expected_comm_E_x, expected_comm_E_y, expected_comm_E_z)); - - uint256[] memory expected_X = new uint256[](2); - expected_X[0] = 0x2e56d20a56a66f2ba12798f718d7d3071f18e03da5d4cac52190ba09ae72f46a; - expected_X[1] = 0x2875f52ba1a60c5b478f684b058d0e2bf2ce904bd0a377ce38699d1a2aa69fad; - - uint256 expected_u = 0x00000000000000000000000000000001a389d9eab44c587699bb449d20fe6530; - - assertEq(result.comm_W.x, expected_comm_W.x); - assertEq(result.comm_W.y, expected_comm_W.y); - assertEq(result.comm_E.x, expected_comm_E.x); - assertEq(result.comm_E.y, expected_comm_E.y); - assertEq(result.X, expected_X); - assertEq(result.u, expected_u); - } - - function testNontrivialSecondaryFolding() public { - ( - uint256 S_digest, - bytes32 nifs, - uint256 r_W, - uint256 r_E, - uint256[] memory r_X, - uint256 r_u, - uint256 l_W, - uint256[] memory l_X - ) = Step3Data.returnSecondaryData(); - - NIFSVesta.RelaxedR1CSInstance memory result = NIFSVesta.verify( - NIFSVesta.NIFS(nifs), - S_digest, - NIFSVesta.RelaxedR1CSInstance(Vesta.decompress(r_W), Vesta.decompress(r_E), r_X, r_u), - NIFSVesta.R1CSInstance(Vesta.decompress(l_W), l_X) - ); - - uint256 expected_comm_W_x = 0x16b45f4410b378a414b2303772e97ca21f97cedca866dc446a0c03701db8607f; - uint256 expected_comm_W_y = 0x08dd11b5cc6a77afcb553cb341b4c4e89b64593c4a4c79af5f8027ebfa5ba143; - uint256 expected_comm_W_z = 0x0193373d89342b5a3c0ade3a0d2f6d6f5c6f919265e2429bc019d1cf329d5c7e; - - Vesta.VestaAffinePoint memory expected_comm_W = - Vesta.IntoAffine(Vesta.VestaProjectivePoint(expected_comm_W_x, expected_comm_W_y, expected_comm_W_z)); - - uint256 expected_comm_E_x = 0x35cd0c83e99ab8826aeabdb360449a8138ac8efde6e791801fc4ba6024c5a9c1; - uint256 expected_comm_E_y = 0x3b8b16f35f6bc8cc10fb1988d19b7ca069b71c4378a9fab07b053eb71a394df7; - uint256 expected_comm_E_z = 0x38e70020eab8f6d0210659e5f28712a8031d29d382644c924d75c386d92461c6; - - Vesta.VestaAffinePoint memory expected_comm_E = - Vesta.IntoAffine(Vesta.VestaProjectivePoint(expected_comm_E_x, expected_comm_E_y, expected_comm_E_z)); - - uint256[] memory expected_X = new uint256[](2); - expected_X[0] = 0x32d8d912584abe410b9c9c56cc9efdb0261ed5a636e0fc823bd5b427cf9fcbee; - expected_X[1] = 0x25b86df67043654b4f2becbaf1ea152688dfeffdb1de89cdf0164c59b0330198; - - uint256 expected_u = 0x00000000000000000000000000000001e4444ecefc90a788e6a520cdef7c6e46; - - assertEq(result.comm_W.x, expected_comm_W.x); - assertEq(result.comm_W.y, expected_comm_W.y); - assertEq(result.comm_E.x, expected_comm_E.x); - assertEq(result.comm_E.y, expected_comm_E.y); - assertEq(result.X, expected_X); - assertEq(result.u, expected_u); - } - - function testSumcheckPrimary() public { - uint8[] memory input = new uint8[](16); // b"RelaxedR1CSSNARK" in Rust - input[0] = 0x52; - input[1] = 0x65; - input[2] = 0x6c; - input[3] = 0x61; - input[4] = 0x78; - input[5] = 0x65; - input[6] = 0x64; - input[7] = 0x52; - input[8] = 0x31; - input[9] = 0x43; - input[10] = 0x53; - input[11] = 0x53; - input[12] = 0x4e; - input[13] = 0x41; - input[14] = 0x52; - input[15] = 0x4b; - - KeccakTranscriptLib.KeccakTranscript memory transcript = KeccakTranscriptLib.instantiate(input); - - uint8[] memory vk_comm = SumcheckData.returnPrimaryTranscriptData(); - uint8[] memory vk_comm_label = new uint8[](1); - vk_comm_label[0] = 0x43; // b"C" - - uint8[] memory U = new uint8[](226); - U[0] = 0xab; - U[1] = 0xf4; - U[2] = 0xc0; - U[3] = 0x93; - U[4] = 0xd7; - U[5] = 0x1b; - U[6] = 0xd2; - U[7] = 0xab; - U[8] = 0x61; - U[9] = 0xa2; - U[10] = 0x84; - U[11] = 0x16; - U[12] = 0x3a; - U[13] = 0x36; - U[14] = 0xb2; - U[15] = 0x6c; - U[16] = 0x75; - U[17] = 0x42; - U[18] = 0x9c; - U[19] = 0x4e; - U[20] = 0x0a; - U[21] = 0xbe; - U[22] = 0x30; - U[23] = 0x25; - U[24] = 0x86; - U[25] = 0xb8; - U[26] = 0x75; - U[27] = 0x6f; - U[28] = 0x56; - U[29] = 0x1c; - U[30] = 0x3b; - U[31] = 0x22; - U[32] = 0x08; - U[33] = 0x4e; - U[34] = 0xc4; - U[35] = 0x00; - U[36] = 0xc1; - U[37] = 0xbc; - U[38] = 0x28; - U[39] = 0x22; - U[40] = 0x6d; - U[41] = 0xc7; - U[42] = 0x98; - U[43] = 0x66; - U[44] = 0x2a; - U[45] = 0x67; - U[46] = 0x8d; - U[47] = 0x47; - U[48] = 0xf0; - U[49] = 0x1e; - U[50] = 0x0c; - U[51] = 0x24; - U[52] = 0xee; - U[53] = 0xaa; - U[54] = 0x59; - U[55] = 0x69; - U[56] = 0xf7; - U[57] = 0xaa; - U[58] = 0xcf; - U[59] = 0x24; - U[60] = 0x19; - U[61] = 0x8c; - U[62] = 0x21; - U[63] = 0x05; - U[64] = 0x01; - U[65] = 0x94; - U[66] = 0x18; - U[67] = 0x0d; - U[68] = 0x05; - U[69] = 0x6f; - U[70] = 0xf8; - U[71] = 0x6d; - U[72] = 0xd8; - U[73] = 0xb2; - U[74] = 0x99; - U[75] = 0x7f; - U[76] = 0x5f; - U[77] = 0xd7; - U[78] = 0xe2; - U[79] = 0x53; - U[80] = 0xd4; - U[81] = 0x0d; - U[82] = 0xfb; - U[83] = 0xa2; - U[84] = 0x7a; - U[85] = 0x8b; - U[86] = 0x4c; - U[87] = 0xb9; - U[88] = 0x74; - U[89] = 0x62; - U[90] = 0xe6; - U[91] = 0xef; - U[92] = 0x3a; - U[93] = 0x52; - U[94] = 0x2b; - U[95] = 0xf0; - U[96] = 0x15; - U[97] = 0x78; - U[98] = 0x01; - U[99] = 0x35; - U[100] = 0x68; - U[101] = 0xf3; - U[102] = 0x63; - U[103] = 0x2c; - U[104] = 0x36; - U[105] = 0x67; - U[106] = 0x02; - U[107] = 0x01; - U[108] = 0xea; - U[109] = 0x3a; - U[110] = 0x89; - U[111] = 0x9f; - U[112] = 0x60; - U[113] = 0x25; - U[114] = 0x05; - U[115] = 0x1e; - U[116] = 0x74; - U[117] = 0xd3; - U[118] = 0x9a; - U[119] = 0x85; - U[120] = 0x6c; - U[121] = 0xf0; - U[122] = 0x96; - U[123] = 0x77; - U[124] = 0xff; - U[125] = 0xda; - U[126] = 0xea; - U[127] = 0x48; - U[128] = 0x34; - U[129] = 0x01; - U[130] = 0x30; - U[131] = 0x65; - U[132] = 0xfe; - U[133] = 0x20; - U[134] = 0x9d; - U[135] = 0x44; - U[136] = 0xbb; - U[137] = 0x99; - U[138] = 0x76; - U[139] = 0x58; - U[140] = 0x4c; - U[141] = 0xb4; - U[142] = 0xea; - U[143] = 0xd9; - U[144] = 0x89; - U[145] = 0xa3; - U[146] = 0x01; - U[147] = 0x00; - U[148] = 0x00; - U[149] = 0x00; - U[150] = 0x00; - U[151] = 0x00; - U[152] = 0x00; - U[153] = 0x00; - U[154] = 0x00; - U[155] = 0x00; - U[156] = 0x00; - U[157] = 0x00; - U[158] = 0x00; - U[159] = 0x00; - U[160] = 0x00; - U[161] = 0x00; - U[162] = 0x6a; - U[163] = 0xf4; - U[164] = 0x72; - U[165] = 0xae; - U[166] = 0x09; - U[167] = 0xba; - U[168] = 0x90; - U[169] = 0x21; - U[170] = 0xc5; - U[171] = 0xca; - U[172] = 0xd4; - U[173] = 0xa5; - U[174] = 0x3d; - U[175] = 0xe0; - U[176] = 0x18; - U[177] = 0x1f; - U[178] = 0x07; - U[179] = 0xd3; - U[180] = 0xd7; - U[181] = 0x18; - U[182] = 0xf7; - U[183] = 0x98; - U[184] = 0x27; - U[185] = 0xa1; - U[186] = 0x2b; - U[187] = 0x6f; - U[188] = 0xa6; - U[189] = 0x56; - U[190] = 0x0a; - U[191] = 0xd2; - U[192] = 0x56; - U[193] = 0x2e; - U[194] = 0xad; - U[195] = 0x9f; - U[196] = 0xa6; - U[197] = 0x2a; - U[198] = 0x1a; - U[199] = 0x9d; - U[200] = 0x69; - U[201] = 0x38; - U[202] = 0xce; - U[203] = 0x77; - U[204] = 0xa3; - U[205] = 0xd0; - U[206] = 0x4b; - U[207] = 0x90; - U[208] = 0xce; - U[209] = 0xf2; - U[210] = 0x2b; - U[211] = 0x0e; - U[212] = 0x8d; - U[213] = 0x05; - U[214] = 0x4b; - U[215] = 0x68; - U[216] = 0x8f; - U[217] = 0x47; - U[218] = 0x5b; - U[219] = 0x0c; - U[220] = 0xa6; - U[221] = 0xa1; - U[222] = 0x2b; - U[223] = 0xf5; - U[224] = 0x75; - U[225] = 0x28; - - uint8[] memory U_label = new uint8[](1); - U_label[0] = 0x55; // b"U" - - transcript = KeccakTranscriptLib.absorb(transcript, vk_comm_label, vk_comm); - transcript = KeccakTranscriptLib.absorb(transcript, U_label, U); - - ScalarFromUniformLib.Curve curve = ScalarFromUniformLib.curveVesta(); - - uint8[] memory t_label = new uint8[](1); - t_label[0] = 0x74; // b"t" - - for (uint256 idx = 0; idx < 14; idx++) { - (transcript,) = KeccakTranscriptLib.squeeze(transcript, curve, t_label); - } - - PolyLib.SumcheckProof memory outer_proof = SumcheckData.returnPrimaryOuterData(); - - uint256 claim_final; - uint256[] memory r_x = new uint256[](14); - - (claim_final, r_x, transcript) = PrimarySumcheck.verify(outer_proof, 0, 14, 3, transcript); - - uint256[] memory r_x_result = new uint256[](14); - r_x_result[0] = 0x265e1d73ee4ce9a23d98bf74a9807abd1c0bedf6368e8db884c05bd9336549bd; - r_x_result[1] = 0x3a009bec1c4dc776ba75c643de9e61b3070a4a6b3865b5751a3d6f517e483a4a; - r_x_result[2] = 0x3932891c1f17ba15d07baba47d6599058812a73225d11a554ced25ad00fd78dd; - r_x_result[3] = 0x140622b73b006b8470ed724172721f7d25f3efb2208f42c73e0658fbc493579b; - r_x_result[4] = 0x2516f6f6ccf854843d9319fad46a0dff2729c608af31c143590c347d0f0805c6; - r_x_result[5] = 0x28942f6ecc7b89c49bfaa569687a9b6902ace63343300e808e86d608eca3f9dc; - r_x_result[6] = 0x1ae6542e6085a0c42ae6e947813a6f701329263a1a59f823cb544e83dce0b9cf; - r_x_result[7] = 0x39979cf05d7d96da05aba4dd24e9f072d52e8efbf4740f1a857680a096193f8b; - r_x_result[8] = 0x2d887fae3954bcb89f20051c96f6812eb841ccc29c8b56e2879e445f74cb4331; - r_x_result[9] = 0x29fb4b14d5d53616b881719c4986e5aad92f7320fc1e6c89f301b8a81ab72896; - r_x_result[10] = 0x2d69fc2f360b3328cb723687589b065ff4250c414c817bd4f6b187583e103270; - r_x_result[11] = 0x06dc812740949078bc2487f020274042e7400e44f7a95d26c2cf6de8b7ba5099; - r_x_result[12] = 0x39ade5abede093bbb12d81f27c28cbc7149d1b1ad6e43c49424687fb4c29ae31; - r_x_result[13] = 0x3d764ae71118a8a3c653b58c534db9fae607dd9c316cdd3675de0d62e0882bf1; - - assertEq(claim_final, 0x346b738474d5b2cda8c002566f1a7004d06cab6b467303a2b7c4b04eaa6df733); - assertEq(r_x, r_x_result); - } - - function testSumcheckSecondary() public { - uint8[] memory input = new uint8[](16); // b"RelaxedR1CSSNARK" in Rust - input[0] = 0x52; - input[1] = 0x65; - input[2] = 0x6c; - input[3] = 0x61; - input[4] = 0x78; - input[5] = 0x65; - input[6] = 0x64; - input[7] = 0x52; - input[8] = 0x31; - input[9] = 0x43; - input[10] = 0x53; - input[11] = 0x53; - input[12] = 0x4e; - input[13] = 0x41; - input[14] = 0x52; - input[15] = 0x4b; - - KeccakTranscriptLib.KeccakTranscript memory transcript = KeccakTranscriptLib.instantiate(input); - - uint8[] memory vk_comm = SumcheckData.returnSecondaryTranscriptData(); - uint8[] memory vk_comm_label = new uint8[](1); - vk_comm_label[0] = 0x43; // b"C" - - uint8[] memory U = new uint8[](226); - U[0] = 0x58; - U[1] = 0x72; - U[2] = 0xeb; - U[3] = 0x4; - U[4] = 0x7; - U[5] = 0xd2; - U[6] = 0xe2; - U[7] = 0xeb; - U[8] = 0x41; - U[9] = 0x55; - U[10] = 0x85; - U[11] = 0xab; - U[12] = 0x31; - U[13] = 0xb1; - U[14] = 0x6a; - U[15] = 0xf7; - U[16] = 0xa7; - U[17] = 0xb0; - U[18] = 0xaa; - U[19] = 0x2a; - U[20] = 0x7e; - U[21] = 0xa9; - U[22] = 0x1f; - U[23] = 0x4d; - U[24] = 0x60; - U[25] = 0x85; - U[26] = 0x3; - U[27] = 0x58; - U[28] = 0xf3; - U[29] = 0xe9; - U[30] = 0xa4; - U[31] = 0x33; - U[32] = 0x23; - U[33] = 0x65; - U[34] = 0x80; - U[35] = 0xd; - U[36] = 0xf2; - U[37] = 0x4f; - U[38] = 0x9f; - U[39] = 0xc7; - U[40] = 0xb5; - U[41] = 0xa7; - U[42] = 0xc3; - U[43] = 0xa3; - U[44] = 0xb6; - U[45] = 0x2; - U[46] = 0x23; - U[47] = 0xc0; - U[48] = 0xe9; - U[49] = 0x95; - U[50] = 0x7c; - U[51] = 0x84; - U[52] = 0xd3; - U[53] = 0x1; - U[54] = 0xb5; - U[55] = 0xa0; - U[56] = 0x4c; - U[57] = 0x79; - U[58] = 0xd2; - U[59] = 0x65; - U[60] = 0x1; - U[61] = 0x3a; - U[62] = 0x84; - U[63] = 0x31; - U[64] = 0x1; - U[65] = 0xc; - U[66] = 0x74; - U[67] = 0x22; - U[68] = 0xf7; - U[69] = 0xea; - U[70] = 0xbb; - U[71] = 0x81; - U[72] = 0xb1; - U[73] = 0x86; - U[74] = 0x6c; - U[75] = 0xc; - U[76] = 0x6c; - U[77] = 0x7e; - U[78] = 0x9e; - U[79] = 0x6c; - U[80] = 0x43; - U[81] = 0x42; - U[82] = 0x5a; - U[83] = 0xa8; - U[84] = 0x84; - U[85] = 0x96; - U[86] = 0x38; - U[87] = 0x31; - U[88] = 0xfa; - U[89] = 0x89; - U[90] = 0x9e; - U[91] = 0x1c; - U[92] = 0x81; - U[93] = 0x10; - U[94] = 0xb3; - U[95] = 0x98; - U[96] = 0xf; - U[97] = 0xbb; - U[98] = 0x78; - U[99] = 0x40; - U[100] = 0x64; - U[101] = 0x89; - U[102] = 0x20; - U[103] = 0x96; - U[104] = 0xbc; - U[105] = 0x48; - U[106] = 0x82; - U[107] = 0x40; - U[108] = 0x7d; - U[109] = 0xef; - U[110] = 0xfb; - U[111] = 0x4b; - U[112] = 0x8c; - U[113] = 0xa4; - U[114] = 0xd9; - U[115] = 0x5e; - U[116] = 0xc6; - U[117] = 0xb4; - U[118] = 0x36; - U[119] = 0xbf; - U[120] = 0x55; - U[121] = 0xac; - U[122] = 0xa6; - U[123] = 0xc5; - U[124] = 0x10; - U[125] = 0xee; - U[126] = 0x7b; - U[127] = 0x54; - U[128] = 0x12; - U[129] = 0x1; - U[130] = 0x46; - U[131] = 0x6e; - U[132] = 0x7c; - U[133] = 0xef; - U[134] = 0xcd; - U[135] = 0x20; - U[136] = 0xa5; - U[137] = 0xe6; - U[138] = 0x88; - U[139] = 0xa7; - U[140] = 0x90; - U[141] = 0xfc; - U[142] = 0xce; - U[143] = 0x4e; - U[144] = 0x44; - U[145] = 0xe4; - U[146] = 0x1; - U[147] = 0x0; - U[148] = 0x0; - U[149] = 0x0; - U[150] = 0x0; - U[151] = 0x0; - U[152] = 0x0; - U[153] = 0x0; - U[154] = 0x0; - U[155] = 0x0; - U[156] = 0x0; - U[157] = 0x0; - U[158] = 0x0; - U[159] = 0x0; - U[160] = 0x0; - U[161] = 0x0; - U[162] = 0xee; - U[163] = 0xcb; - U[164] = 0x9f; - U[165] = 0xcf; - U[166] = 0x27; - U[167] = 0xb4; - U[168] = 0xd5; - U[169] = 0x3b; - U[170] = 0x82; - U[171] = 0xfc; - U[172] = 0xe0; - U[173] = 0x36; - U[174] = 0xa6; - U[175] = 0xd5; - U[176] = 0x1e; - U[177] = 0x26; - U[178] = 0xb0; - U[179] = 0xfd; - U[180] = 0x9e; - U[181] = 0xcc; - U[182] = 0x56; - U[183] = 0x9c; - U[184] = 0x9c; - U[185] = 0xb; - U[186] = 0x41; - U[187] = 0xbe; - U[188] = 0x4a; - U[189] = 0x58; - U[190] = 0x12; - U[191] = 0xd9; - U[192] = 0xd8; - U[193] = 0x32; - U[194] = 0x98; - U[195] = 0x1; - U[196] = 0x33; - U[197] = 0xb0; - U[198] = 0x59; - U[199] = 0x4c; - U[200] = 0x16; - U[201] = 0xf0; - U[202] = 0xcd; - U[203] = 0x89; - U[204] = 0xde; - U[205] = 0xb1; - U[206] = 0xfd; - U[207] = 0xef; - U[208] = 0xdf; - U[209] = 0x88; - U[210] = 0x26; - U[211] = 0x15; - U[212] = 0xea; - U[213] = 0xf1; - U[214] = 0xba; - U[215] = 0xec; - U[216] = 0x2b; - U[217] = 0x4f; - U[218] = 0x4b; - U[219] = 0x65; - U[220] = 0x43; - U[221] = 0x70; - U[222] = 0xf6; - U[223] = 0x6d; - U[224] = 0xb8; - U[225] = 0x25; - - uint8[] memory U_label = new uint8[](1); - U_label[0] = 0x55; // b"U" - - transcript = KeccakTranscriptLib.absorb(transcript, vk_comm_label, vk_comm); - transcript = KeccakTranscriptLib.absorb(transcript, U_label, U); - - ScalarFromUniformLib.Curve curve = ScalarFromUniformLib.curveVesta(); - - uint8[] memory t_label = new uint8[](1); - t_label[0] = 0x74; // b"t" - - for (uint256 idx = 0; idx < 14; idx++) { - (transcript,) = KeccakTranscriptLib.squeeze(transcript, curve, t_label); - } - - PolyLib.SumcheckProof memory outer_proof = SumcheckData.returnSecondaryOuterData(); - - uint256 claim_final; - uint256[] memory r_x = new uint256[](14); - - (claim_final, r_x, transcript) = SecondarySumcheck.verify(outer_proof, 0, 14, 3, transcript); - - uint256[] memory r_x_result = new uint256[](14); - r_x_result[0] = 0x0f165407419e8c2e7685d7d70bf99a758d8d7fbea89da907b3aeaa7bee833a56; - r_x_result[1] = 0x29560c2a6cfae551d9c4dca9c51099996b3d3c2bdd2498e787f046506ba52814; - r_x_result[2] = 0x362da2eabc9f9e7d98621f197a1302f443ce859376ef1855b994adeed58fe545; - r_x_result[3] = 0x3cca5c7ea86a6a28fe166886c9170d6c5c11c0c3a62ec3542461ab9d4570db8e; - r_x_result[4] = 0x011032bc2a262b1177be0d1a0819af301f07b2526b482a642c044e9f1fb235e0; - r_x_result[5] = 0x2457b45828d84cbec89fe251bf00eef3eef83c892343349798c252ddfa6ed892; - r_x_result[6] = 0x1e75806536a945babea5f7c8f9919c044ecac67b97598cb833253aebea65f43a; - r_x_result[7] = 0x26ffb40cd04ebeee0ef0534d2e0ab8f3bab0b7965896acc89e8ca6d73fb7998f; - r_x_result[8] = 0x0204eda144c122b0dd23f2730444b643873d2dfd24b3d9f6e4120699f8d67f17; - r_x_result[9] = 0x2a5748db09c9d1253f8accba25f25e6cf536baadf655939b25f762251b238433; - r_x_result[10] = 0x006775e2804bb5851a122fb8d1023ff427e3614f93b9dc201811638c88ce449b; - r_x_result[11] = 0x1ff82c34a25a9521840fe3fce05a08766cf8236f214871de953ffed41f5312ba; - r_x_result[12] = 0x070bb7c8b02abf2d75ef8b6b8fb3997745d1c041991e0d3af11d78b11f879920; - r_x_result[13] = 0x0218ba00634e903a39bd7ed1388141981ac7aaa0572ba61802aaf2b580667bf1; - - assertEq(claim_final, 0x157e00e739ad0d53d95e24c8ec0e97081a1f94bb9a4e94a4d198c5533aebc28b); - assertEq(r_x, r_x_result); - } } diff --git a/test/poly-eval-instance-tests.t.sol b/test/poly-eval-instance-tests.t.sol new file mode 100644 index 0000000..5af94bd --- /dev/null +++ b/test/poly-eval-instance-tests.t.sol @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.16; + +import "@std/Test.sol"; +import "src/blocks/pasta/Pallas.sol"; +import "src/blocks/pasta/Vesta.sol"; +import "src/blocks/PolyEvalInstance.sol"; + +contract PolyEvalInstanceTest is Test { + function testPolyEvalInstanceBatchPrimary() public { + uint256 c = 0x2bf7d5c8107fa9dfff6588835fd722abd21d80cfa1fc553807fa0d88af856c48; + uint256[] memory tau = new uint256[](17); + tau[0] = 0x15f5e9f471c313af5c8190c109c3a1fe9cee73d035bcd08a204898e795d8e497; + tau[1] = 0x026bc743ada824501ac59409a022aeaba83ebe9c6fe153969c47d3dbcba1be20; + tau[2] = 0x0235a660a3f8c7aa923e90ef914634b078bec35cd1b1ed8d763735655f16c86b; + tau[3] = 0x06b9cd3880fe5f9881f9fd2b0f15eaa134f0271faa129290886932018371f6a4; + tau[4] = 0x369f08f9d3a1b649e724e2ded5d88ae935ee5128bfc966a33b09fd298ce1f4f9; + tau[5] = 0x17c2194712668c76ac2ac0d4ddc7ae50995905fa689a153b3a46b539a40a0cb8; + tau[6] = 0x0416682dc67529249a90de425db7b2f08a44eefa18ff9a42dae68dd77e001d23; + tau[7] = 0x08414bd36fb4ec48989f9922cd0fa9ab1e1414d9bc3e7be4dd87166124351a6c; + tau[8] = 0x3714b73daef1dd873e79a9b670c7f403a506aaec54666f2a9daa8805ce3fa7df; + tau[9] = 0x3c23643dd2a5d6b64ba3f86d6ea4c347db24e45163421b450b20dc44e502da77; + tau[10] = 0x219bd827a1a9cfcbacb2d66370f8ab9af8449f0e779eeb441b0cc3e46ac24408; + tau[11] = 0x2a99b7d2d92e7ce4b1a5bb9893a58c94525afcc43ca64c9579217d5db1980289; + tau[12] = 0x244902bf184af91659be921be063244f4d9aacf94e19fd121446104850f2b1d9; + tau[13] = 0x1594eeac26b85866f2cf09dea1c5ee8920e8b4bfde8edba325f5e89ac9995ab6; + tau[14] = 0x2e6dee8a44ef6d3058da01d7e90582d1f5d6b2fd8f05eea54540fe77a8444f12; + tau[15] = 0x17798e8f0e66b1d6e1f53871eeaaabb28f680fda97a9ae07eb833be231310035; + tau[16] = 0x2a7e0ec4192134bc0102de30940d4fd26bb0cd60e11f74519f9d9a90bebeaf5f; + + uint256[] memory eval_vec = new uint256[](3); + eval_vec[0] = 0x392e7115e56e1204476bb7bd0822c98c92372549ce1a153358f22caa7d7a6580; + eval_vec[1] = 0x06aeecbdd8d4fdafbf0e4b0d739b60a084c4434f1b3fad4b6872907f1e6a6b61; + eval_vec[2] = 0x28fd09141451e22d1359c05a6185054e21f569ac2b02f4ddc50949cfaee53277; + + Pallas.PallasAffinePoint[] memory comm_vec = new Pallas.PallasAffinePoint[](3); + comm_vec[0] = Pallas.PallasAffinePoint( + 0x33f7fe7aadab0547f6aac7531ec6c508338ba5118aff5eeb68891acc847e3687, + 0x0e1a548676d1dfa14e19f32eb98e1b1bff230e8ba130b147c523c87a1a955e1d + ); + comm_vec[1] = Pallas.PallasAffinePoint( + 0x2417b2e8c58924f71273dea4ed0c6c9d03a89aaa03c1bd208128b41c6d92a93d, + 0x233f71da4d66c714fccf3de4e6ae4b9baf259eaf68d87ef22c3820ffd20f612d + ); + + comm_vec[2] = Pallas.PallasAffinePoint( + 0x2f11d5c141f26972584526f310ac8b01b2a2b52213e30ac920fe782d365958d3, + 0x2b9ba1235a1ef95ab89c4c25f520b7598d995e11e6257b587914cc426c4c31ef + ); + + PolyEvalInstanceLib.PolyEvalInstance memory actual = + PolyEvalInstanceLib.batchPrimary(comm_vec, tau, eval_vec, c); + + uint256 e_expected = 0x2b005e5de5ae62075c66de1c5343c86a235ffc0184fd317079c6687f53596bd4; + Vesta.VestaAffinePoint memory c_expected = Vesta.VestaAffinePoint( + 0x27f23d4d7603ec8b206a427a04da21bf3282a95e114447aee4a1ac76e4aacb4d, + 0x209850df39cd098612ab3329da5e21001c81c08b9be94d2bc90833cf7bde14e7 + ); + + assertEq(actual.e, e_expected); + assertEq(actual.c_x, c_expected.x); + assertEq(actual.c_y, c_expected.y); + assertEq(tau.length, actual.x.length); + for (uint256 index = 0; index < tau.length; index++) { + assertEq(tau[index], actual.x[index]); + } + } + + function testPolyEvalInstanceBatchSecondary() public { + uint256 c = 0x0b997b6ffdc3ec15ffa942ce26cb2144184c7e88eaa29770a3061b22c062ea1e; + + uint256[] memory tau = new uint256[](17); + tau[0] = 0x17c03663671666409d2e5656c3ee877145c7e32e3494e16dbbec709afd0709e6; + tau[1] = 0x38b515b8596f09d0f1c56b3da33dc7c7dd3b1fe25d0d04b87cd716dc23f2cc31; + tau[2] = 0x23ae00416f6e0bd1e292f12ba6cbd2c498509027b8a2d92f287314235f2b2a6d; + tau[3] = 0x35281c3c99450dd3bdb0fccdafdf3028ea4e5b11a59fd8d485191cf79344f9e4; + tau[4] = 0x3110a4ef81e06dd527736a4fa519e2dd25453adb5355b08e9c83bd6341274585; + tau[5] = 0x02f5cd90a9bb245b75139967f5e033ccdaa0a5c03aa8eb349ec36eed1a4ee8fc; + tau[6] = 0x3f7bbbc64bcd58d08a504d873192746a9f568042907f926b174b59a0247f6e8e; + tau[7] = 0x2a3cb49129f6437fc4fc78ea272a653b610569f37a21757078fa74b39340f832; + tau[8] = 0x246eaeb45c2eaa49fe0490501a77cea8f18497c2b7a35b9d86f0930e0e082b7f; + tau[9] = 0x2f401cf8151d3eb918d15212f026ebd4930794107e7cd915c789a4b1c7e5eadd; + tau[10] = 0x133bd93c31e8b783f39e71c9b40c96591649115e90b0bafbffa1823fffb10ba0; + tau[11] = 0x14605eada47c70ab4c51563dc9fbb4953df05924deef56cbf8189840774a3828; + tau[12] = 0x3a09b34278f95c71529c3374c6567cec43f5dd65c76f863469249d5c2ef43e9e; + tau[13] = 0x0d88b3a19bf13be9c4c868dcff22a6790cc07736b9ed457be5782809bb55e0e4; + tau[14] = 0x19430f84eabe5885bd7fcdb9630c471c8c6002ad54302818962e3f63293935f0; + tau[15] = 0x3c43f9fc4e8571b3b15190551fe246bc25d190cff304e99253123126baf888ef; + tau[16] = 0x0bde99a49b09b102f23fe24cf9790380c734acc82063014a243edbbe4b8ba3ed; + + uint256[] memory eval_vec = new uint256[](3); + eval_vec[0] = 0x03ceb0495f19505b379b535efae65b4aff31add3f912304bcc92df3ea5aae3d9; + eval_vec[1] = 0x2183da210706e672e013cfde880e41bf49dc13f12ab15a5741bd7d0d2adcab27; + eval_vec[2] = 0x16b1a33f9c928dce78632e3b85f165cb349011f4431d8e8aeda66956471adb0b; + + Vesta.VestaAffinePoint[] memory comm_vec = new Vesta.VestaAffinePoint[](3); + comm_vec[0] = Vesta.IntoAffine( + Vesta.VestaProjectivePoint( + 0x399fb61daa126807594503e6b5a9f4d41d47c0e94b77a54e33f9abc7500d8830, + 0x3c7525102839e143f08f1365392295980eecb695885acfb73e6c050a7d83e1f7, + 0x0000000000000000000000000000000000000000000000000000000000000001 + ) + ); + + comm_vec[1] = Vesta.IntoAffine( + Vesta.VestaProjectivePoint( + 0x2dea24643491790d8d700e24bab5daa86ffcb9dfc7f590c801116d74f04782a4, + 0x13cc89863fccababa979cae3f29d64a5f817e9293ab0a7ce19410a140da6eb0d, + 0x0000000000000000000000000000000000000000000000000000000000000001 + ) + ); + + comm_vec[2] = Vesta.IntoAffine( + Vesta.VestaProjectivePoint( + 0x11a118c96ba25b5e6ded741c1df681a55cfa8608aaedcb239dd264f851d22c32, + 0x2c2c0081a75a06c5c8dfc20e62f02ee1eb41d7ac03b3d53d188de772c676b1b5, + 0x0000000000000000000000000000000000000000000000000000000000000001 + ) + ); + + PolyEvalInstanceLib.PolyEvalInstance memory actual = + PolyEvalInstanceLib.batchSecondary(comm_vec, tau, eval_vec, c); + + uint256 e_expected = 0x2144bc0d13b5cfc99beab8db542dd270bd2a8af3911e754ca0ca0818a5b9a5ba; + Vesta.VestaAffinePoint memory c_expected = Vesta.VestaAffinePoint( + 0x15353461b0478bc4adc71d396fdb3d98aef58ac5184a56985b145ff8a72056cd, + 0x2042fe5212f18f19e509506eb626870011bfd54556493e761833a88dc40cadc0 + ); + + assertEq(actual.e, e_expected); + assertEq(actual.c_x, c_expected.x); + assertEq(actual.c_y, c_expected.y); + assertEq(tau.length, actual.x.length); + for (uint256 index = 0; index < tau.length; index++) { + assertEq(tau[index], actual.x[index]); + } + } + + function testPad() public { + PolyEvalInstanceLib.PolyEvalInstance[] memory a = new PolyEvalInstanceLib.PolyEvalInstance[](2); + + uint256[] memory x = new uint256[](10); + for (uint256 i = 0; i < x.length; i++) { + x[i] = 1; + } + + a[0] = PolyEvalInstanceLib.PolyEvalInstance(0, 0, x, 0); + + x = new uint256[](20); + for (uint256 i = 0; i < x.length; i++) { + x[i] = 1; + } + + a[1] = PolyEvalInstanceLib.PolyEvalInstance(0, 0, x, 0); + + PolyEvalInstanceLib.PolyEvalInstance[] memory a_padded = PolyEvalInstanceLib.pad(a); + + // they both now have max length + assertEq(a_padded[0].x.length, 20); + assertEq(a_padded[1].x.length, 20); + + // first 10 elements of a[0] are padded by zeroes + for (uint256 i = 0; i < 10; i++) { + assertEq(a_padded[0].x[i], 0); + } + // rest is the same + for (uint256 i = 10; i < 20; i++) { + assertEq(a_padded[0].x[i], 1); + } + } +} diff --git a/test/pp-spartan-step3.t.sol b/test/pp-spartan-step3.t.sol new file mode 100644 index 0000000..00ee71d --- /dev/null +++ b/test/pp-spartan-step3.t.sol @@ -0,0 +1,805 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.0; + +import "@std/Test.sol"; +import "src/blocks/pasta/Pallas.sol"; +import "src/blocks/pasta/Vesta.sol"; +import "src/blocks/EqPolynomial.sol"; +import "src/blocks/KeccakTranscript.sol"; +import "src/blocks/PolyEvalInstance.sol"; +import "src/blocks/Sumcheck.sol"; +import "src/NovaVerifierAbstractions.sol"; + +contract PpSpartanStep3Computations is Test { + function check_claim_inner_final_expected( + uint256 coeffs_9, + uint256 self_eval_E_row, + uint256 self_eval_E_col, + uint256 self_eval_val_A, + uint256 c_inner, + uint256 self_eval_val_B, + uint256 self_eval_val_C, + uint256 claim_inner_final_expected + ) private { + uint256 actual; + uint256 modulusPallas = Pallas.P_MOD; + assembly { + let tmp := mulmod(c_inner, c_inner, modulusPallas) + tmp := mulmod(tmp, self_eval_val_C, modulusPallas) + tmp := addmod(tmp, self_eval_val_A, modulusPallas) + actual := mulmod(c_inner, self_eval_val_B, modulusPallas) + actual := addmod(actual, tmp, modulusPallas) + actual := mulmod(actual, self_eval_E_col, modulusPallas) + actual := mulmod(actual, self_eval_E_row, modulusPallas) + actual := mulmod(actual, coeffs_9, modulusPallas) + } + + assertEq(actual, claim_inner_final_expected); + } + + function check_final_step3_verification( + uint256 claim_mem_final_expected, + uint256 claim_outer_final_expected, + uint256 claim_inner_final_expected, + uint256 claim_sat_final + ) private { + uint256 modulusPallas = Pallas.P_MOD; + uint256 actual = addmod( + addmod(claim_mem_final_expected, claim_outer_final_expected, modulusPallas), + claim_inner_final_expected, + modulusPallas + ); + + assertEq(actual, claim_sat_final); + } + + function check_claim_outer_final_expected( + uint256 coeffs_8, + uint256 taus_bound_r_sat, + uint256 self_eval_Az, + uint256 self_eval_Bz, + uint256 U_u, + uint256 self_eval_Cz, + uint256 self_eval_E, + uint256 claim_outer_final_expected + ) private { + uint256 modulusPallas = Pallas.P_MOD; + uint256 actual = mulmod(U_u, self_eval_Cz, modulusPallas); + actual = Pallas.negateBase(actual); + uint256 minus_self_eval_E = Pallas.negateBase(self_eval_E); + assembly { + let tmp := mulmod(self_eval_Az, self_eval_Bz, modulusPallas) + tmp := addmod(tmp, minus_self_eval_E, modulusPallas) + actual := addmod(actual, tmp, modulusPallas) + actual := mulmod(actual, taus_bound_r_sat, modulusPallas) + actual := mulmod(actual, coeffs_8, modulusPallas) + } + assertEq(actual, claim_outer_final_expected); + } + + function check_claim_mem_final_expected( + uint256 rand_eq_bound_r_sat, + uint256[] memory coeffs, + uint256[] memory eval_left_arr, + uint256[] memory eval_right_arr, + uint256[] memory eval_output_arr, + uint256 claim_mem_final_expected + ) private { + uint256 len = 8; + require(coeffs.length == len); + require(eval_left_arr.length == len); + require(eval_right_arr.length == len); + require(eval_output_arr.length == len); + + uint256 modulusPallas = Pallas.P_MOD; + + uint256 actual; + + uint256 coeffs_item; + uint256 eval_left_arr_item; + uint256 eval_right_arr_item; + + uint256 tmp; + for (uint256 index = 0; index < len; index++) { + coeffs_item = coeffs[index]; + eval_left_arr_item = eval_left_arr[index]; + eval_right_arr_item = eval_right_arr[index]; + tmp = Pallas.negateBase(eval_output_arr[index]); + assembly { + let tmp1 := mulmod(eval_left_arr_item, eval_right_arr_item, modulusPallas) + tmp1 := addmod(tmp1, tmp, modulusPallas) + tmp1 := mulmod(tmp1, rand_eq_bound_r_sat, modulusPallas) + tmp1 := mulmod(tmp1, coeffs_item, modulusPallas) + actual := addmod(actual, tmp1, modulusPallas) + } + } + + assertEq(actual, claim_mem_final_expected); + } + + function check_rand_eq_bound_r_sat(uint256[] memory r, uint256[] memory rx, uint256 rand_eq_bound_r_sat) public { + require(r.length == rx.length); + assertEq(rand_eq_bound_r_sat, EqPolinomialLib.evaluate(r, rx, Pallas.P_MOD, Pallas.negateBase)); + } + + function testFinalStep3Verification() public { + uint256 claim_mem_final_expected = 0x05d06b1baa19c95a2f5b0cda10585ac6380eebf0b4526f5ba1abb2d80d36f396; + uint256 claim_outer_final_expected = 0x2f323c788b0d9138ba80b6c93162c20bd230dcad68209bc523152ec3b57d0c5a; + + uint256 coeffs_9 = 0x0082b3fee7e08d0875839ed964a59b3d8890f3cc8c99951135bab451e481de45; + uint256 self_eval_E_row = 0x005497eef16105a1131cf3aa93ad21559b45da5348d16a767a14bb3230791bc1; + uint256 self_eval_E_col = 0x08e3e6ca6242951435f79a117fd229613e2de4a2038b530f04788e35ad298442; + uint256 self_eval_val_A = 0x2d0b4b68536b9e808c633cf9cf0b2dd7bc50323497bd8da52c62829458e9cffa; + uint256 c_inner = 0x0b997b6ffdc3ec15ffa942ce26cb2144184c7e88eaa29770a3061b22c062ea1e; + uint256 self_eval_val_B = 0x00a4606a4306ae6398aaead1738624314fb48672c0e63643187a81d03e38b818; + uint256 self_eval_val_C = 0x23a31846a3fcab9f5feea6ae88850868a6e50ad38c16dfc7c9e702ec20bba75f; + + uint256 claim_inner_final_expected = 0x2ad31f8f81c90ba58ee098a7ef2bfd7d8755651c837777432bfca54fba461d2f; + check_claim_inner_final_expected( + coeffs_9, + self_eval_E_row, + self_eval_E_col, + self_eval_val_A, + c_inner, + self_eval_val_B, + self_eval_val_C, + claim_inner_final_expected + ); + + uint256 claim_sat_final = 0x1fd5c723b6f0663878bc5c4b30e71a4f6f4e94be969d8948579055fe7cfa1d1e; + check_final_step3_verification( + claim_mem_final_expected, claim_outer_final_expected, claim_inner_final_expected, claim_sat_final + ); + } + + function test_claim_outer_final_expected_computation() public { + uint256 coeffs_8 = 0x0f93dbcda1deaf626a43adb3c60580f16d6b319032efe5d9bcc56227b04db6a5; + uint256 taus_bound_r_sat = 0x22f427ab378ad36181e799afb461c7959e81ead14d9cbb1cf817c3799fbdeaf1; + uint256 self_eval_Az = 0x38948ca0462a02bdb53b1901fe38b628d211950f7ec0253e4077d6ca8e46ea80; + uint256 self_eval_Bz = 0x0beb527e566ceb01dd437d13a42c9bd51fade27bb530bd8af14bb762ab40761e; + uint256 U_u = 0x00000000000000000000000000000001be290d4c014dff424259e57be62191c4; + uint256 self_eval_Cz = 0x1950e09255fee2c8de78a7efc81d13cfff43a5ef5eda973788b297020c8dd8c6; + uint256 self_eval_E = 0x230f7c5a5c32e6b78dfc1dc1c0fe06baae7fd45a912733b1cf52521d2a78bfc2; + uint256 claim_outer_final_expected = 0x2f323c788b0d9138ba80b6c93162c20bd230dcad68209bc523152ec3b57d0c5a; + + check_claim_outer_final_expected( + coeffs_8, + taus_bound_r_sat, + self_eval_Az, + self_eval_Bz, + U_u, + self_eval_Cz, + self_eval_E, + claim_outer_final_expected + ); + } + + function test_claim_mem_final_expected_computation() public { + uint256 rand_eq_bound_r_sat = 0x08fa71bd727e1f0539be7441ee184c610e4012207be66fc1fc948b009aa7cb84; + + uint256[] memory coeffs = new uint256[](8); + uint256[] memory eval_left_arr = new uint256[](8); + uint256[] memory eval_right_arr = new uint256[](8); + uint256[] memory eval_output_arr = new uint256[](8); + + coeffs[0] = 0x24abec2a07d73e7f6aa8c47c41c545063724e664fc177870725a479a48296c45; + eval_left_arr[0] = 0x147f44b4f49104ea3e17c46501eee96c38b17420cfcb4dbff6125e839cd2dc98; + eval_right_arr[0] = 0x1d30c0feed53c5159359c12bd56c50187c1ccee0804e38bb72d85c557084eb30; + eval_output_arr[0] = 0x1d8d0419087973cb02a3c2b0c151eb1ebd4ad532f0944c03509c5b672ee492c3; + + coeffs[1] = 0x252a854862eb46096810a4a4a9f35c0e40a12ea0ec1960d95626f2657a6a0422; + eval_left_arr[1] = 0x232136b762e2981a8e8b620e6d06d516fd0aaef3be4db2aa11df469787dc9ff6; + eval_right_arr[1] = 0x0a3dd62ec7710052c2d8b910c3d50895dd88068fd086143fcd7ddc77a0e20483; + eval_output_arr[1] = 0x034d3e85e320aa7efdd807ff2bf0045aa0f8dc06ef9eea0e9ebc6336aa8da0ff; + + coeffs[2] = 0x03d733614e8f8b22b7a014ddbaf7108a8b99575a73543fb38850fd59e5d26b65; + eval_left_arr[2] = 0x1cc43b30ada6c2048fd37949db1accb437b464f5076ffd3e831899ca0e7ba348; + eval_right_arr[2] = 0x0b9d03d2a9ebe77c68d8d9fbe633ad3a220995f87555248edef27cc5880e8235; + eval_output_arr[2] = 0x3b0a0751147350ff22d399dd19bf54b0393ffc6a88b82192a9ddaabb3998e3af; + + coeffs[3] = 0x26a82b7b3206cd44937ae80cb33d69f9e5ca95c456b92d0b4865d24a3850de3f; + eval_left_arr[3] = 0x23df3f6ffdd66ddd7919ae7fb7bf2f4abd1630c24fcf1a233f2cc1844bddd24e; + eval_right_arr[3] = 0x31576c56e0927b45323fd02aabfe5a77d1ec1d06fe146440adb34bbffeb21310; + eval_output_arr[3] = 0x25bb0fba5fcbb5830c92cfaef2d6f2085eb4e5660214cf3513390236aaad6bbb; + + coeffs[4] = 0x2722c59f6520030025c43aa9e486b5f0fee7e190f6751674328b28828227957a; + eval_left_arr[4] = 0x26a4428b87c121e12ddcdf5b885cf8d8d340e5e19281a3d74772f860e293c1e9; + eval_right_arr[4] = 0x1352bc60c8bc4319c2d97065fc4eadeafb0f566d4e0635f6ad5fb462d4426605; + eval_output_arr[4] = 0x20b253e21f96b20a29cc1fdd073a4a654fadd4e160735e988aaebfe343e1631c; + + coeffs[5] = 0x3cdff180a4b073740aeacc97898517c3cfa3b750827902d4b28bd583d1eeb77d; + eval_left_arr[5] = 0x3817aeae1fe8406de02bcc39db14a938344a14ccc2f93c9365c41b43a0a44198; + eval_right_arr[5] = 0x0a356cb567b8b9f61f3f26ee28f8d07274d4d1296fc682ce45af58a31596870e; + eval_output_arr[5] = 0x26eda459228ba2c75d3cab4b01c9b396f0b750247e56c573dd2599ad312ad7b8; + + coeffs[6] = 0x12dada10e0a1bd16bb48b32c39f644188987784e0ca26dbf0e1a5db5721357e6; + eval_left_arr[6] = 0x0ccff52e09e4e4c14eeaf3fe380c30e5b5e60fcb526abea502a4b14ff3199847; + eval_right_arr[6] = 0x0103bc38a0b33f6c9ad0a9609ee1cf7e25d1fb5486c4d13fbe68d7d24a4e50de; + eval_output_arr[6] = 0x209c4af8f703136125eb474143c5052cc5c206ef983377265fba782091b040f3; + + coeffs[7] = 0x0ae9211366b88ba710f1b05e0b5d961eebbf59c205e5dbc9384b93c195dd357c; + eval_left_arr[7] = 0x0dac2ac3dea7fe9bda6bdd1ed9f0d01606fa41dcfb8e7531d9d466f25143f761; + eval_right_arr[7] = 0x044251dcd2cb228142cef3294b52dfb9f2f4bbced579fdc823ac1d60dc07b167; + eval_output_arr[7] = 0x0f32b713bef952f9209a9dffc863d9265198387b13b25e17c7cef80450c79cd8; + + uint256 claim_mem_final_expected = 0x05d06b1baa19c95a2f5b0cda10585ac6380eebf0b4526f5ba1abb2d80d36f396; + check_claim_mem_final_expected( + rand_eq_bound_r_sat, coeffs, eval_left_arr, eval_right_arr, eval_output_arr, claim_mem_final_expected + ); + } + + function test_rand_eq_bound_r_sat_computation() public { + uint256[] memory r_sat = new uint256[](17); + r_sat[0] = 0x0c6d2bf540a735934ae40e93560708b56f4452a1b9c6ad435bcc5a3d718d636c; + r_sat[1] = 0x12356e9d5716fbc87d57127bf033d6c944a469d3594be6690ebea874852df9a2; + r_sat[2] = 0x11920f58b99610ea1e7df2b95803ac51e568be3261d8c57e53c5e7232b6a8100; + r_sat[3] = 0x07669895060aa6d19a26a3ca15b66c653f057411e3e249ad032bd4c3d454dd2c; + r_sat[4] = 0x1529ed49bcf02d198015331aaceda91523d4cb6480bf88ece2b9fdcb7455318d; + r_sat[5] = 0x1a143c3ea3b03de4235858e759e5a5f145becbe09e73034bc5deae7b448dafcd; + r_sat[6] = 0x33b78932e8c0a8560c559f8c6ffb88f47355f01af8d4db106cbfd0bb6813b48f; + r_sat[7] = 0x28137caa1e6c94ba725683445a2fda31dde080460f1194927ea3d705e4a2b4cc; + r_sat[8] = 0x2a1dc1db6e9d737c435c9c5f1e99a82ef22909045565c1d3d4a70e7f3476ddd0; + r_sat[9] = 0x1980c374b3934f56f94174320f07a2086f723271f06ec0341619e804fe0af261; + r_sat[10] = 0x3c13da89c92bed75f7441764335289c8688dbaad7592ffa27fc4af6c76234b9a; + r_sat[11] = 0x0821d484a68f72a551207bf5a27a57dddbe4f6c1352fce1210ac8139c5b4b423; + r_sat[12] = 0x1d70c72ceb8af51ff89f5b520643d1dcc35393e1255e9476b7ad4987324c467a; + r_sat[13] = 0x1cbcf9e4c122e494679ad733c241d0e908d2a3c9fdb65cafea3a8c6ff72e2517; + r_sat[14] = 0x0ef3b3e72135c28d158b117f3733d291c4789c2ac9c754bfe1e90a8fc5fbb208; + r_sat[15] = 0x17e5a84f6bbdd8e53f5ec117374d39b6a23fe37a58571e95da5b4c1820608245; + r_sat[16] = 0x3492aaf8252e21df8a00c0febe0c2c2476008b7210edc742afd161f7439adb4f; + + uint256[] memory rand_eq = new uint256[](17); + rand_eq[0] = 0x27aabc1f9396c2df912a57e820d33667cd6faf59faff531e15b5bca62a921b70; + rand_eq[1] = 0x1524b2421bd0dd7b069a6b49dee90441eda59d60b20a55aa4258680fbcaa85e1; + rand_eq[2] = 0x00e5845d3b1936d72023ad3a8689f2964a98c03c2c78fc7f425e0f4f96e18213; + rand_eq[3] = 0x1f8ba1693f2a89256bda343c8b3d3860567d0a92d44d2fe6f7bbfd84bd57f0a1; + rand_eq[4] = 0x23ed0a59c496ce4f398e5220c1303c8306c0ff9e771a8f96cd2c2f2dcccd3b5c; + rand_eq[5] = 0x2ec3b5d5d2abecc598a40e22a9dfee72f84daeeeef3a83c5578c1b3914ad50f0; + rand_eq[6] = 0x2970d36138f1f017849739810a4b75ee69bdb6b12e0cee98569a44b9aeb99385; + rand_eq[7] = 0x158b34cfc9d5d307a456510bc983e3347250f299c27e256973c49dc202837667; + rand_eq[8] = 0x3b0f02de0d028ce268b67b86a229233605fd773f49023b7e35a58744b071d80a; + rand_eq[9] = 0x1a8273e3ab009d5d0bfe641e757d165512e9cbbe7687a0609fed8a992a5efab7; + rand_eq[10] = 0x221cfbd667abec54452af2f875e418042135782375eafb8ea3d734b527678acb; + rand_eq[11] = 0x1a0d3935eb3ff77c80afbbe601a222c84e75291e4dc14e2c89398d8c728a9e1e; + rand_eq[12] = 0x1b36747432801cf05c1592a4e1e812983c4bf5fa7d9e64d4a044cc14fadb3c09; + rand_eq[13] = 0x1114d3c08a5ca3fdfe361d6cb328af82e6d9a2f164c88b106376643dcaea24a3; + rand_eq[14] = 0x343e36767bcd4cbfb305e132161f6ce70c1855edfdb43f785bebe23fda134c2f; + rand_eq[15] = 0x1e6e2af1f5c6431acdd75b6a5e891ed8cf8f986fc57ee6d8612d57fb2e7e9a09; + rand_eq[16] = 0x331dc38b0812198ddcd60fd252fd19f91a0485c826c58a07480ad75876cf44b1; + + uint256 rand_eq_bound_r_sat = 0x08fa71bd727e1f0539be7441ee184c610e4012207be66fc1fc948b009aa7cb84; + check_rand_eq_bound_r_sat(rand_eq, r_sat, rand_eq_bound_r_sat); + } + + function loadInputForTau() + private + view + returns ( + uint256, + Abstractions.RelaxedR1CSInstance memory, + Vesta.VestaAffinePoint memory, + Vesta.VestaAffinePoint memory, + Vesta.VestaAffinePoint memory + ) + { + uint256 vk_digest = 0x02fd7ec2a0975eb3c0e7cec9284b737d72e8eb4b77906ee1fe1439f47e8c2864; + + uint256 comm_Az = 0x30880d50c7abf9334ea5774be9c0471dd4f4a9b5e6034559076812aa1db69fb9; + uint256 comm_Bz = 0xa48247f0746d1101c890f5c7dfb9fc6fa8dab5ba240e708d0d7991346424eaad; + uint256 comm_Cz = 0x322cd251f864d29d23cbedaa0886fa5ca581f61d1c74ed6d5e5ba26bc918a191; + + Vesta.VestaAffinePoint memory comm_Az_decompressed = Vesta.decompress(comm_Az); + Vesta.VestaAffinePoint memory comm_Bz_decompressed = Vesta.decompress(comm_Bz); + Vesta.VestaAffinePoint memory comm_Cz_decompressed = Vesta.decompress(comm_Cz); + + uint256[] memory X = new uint256[](2); + X[0] = 0x1db2c0c8e0e4c94b326d04f9d69a496737eaa2852f693492700c6847a35726f2; + X[1] = 0x0b5b6a092d6d8406a62579e1cc2dc0b209c821e13fc3f2e846ecb90659ad413f; + + // f_U_secondary + Abstractions.RelaxedR1CSInstance memory U = Abstractions.RelaxedR1CSInstance( + 0x026f01a19cba6322e4e5cd0cdabe33f63912b1a4d027bf83ce3bc243ceb3d8a0, + 0xf683c96c795e436f971c676506780b0d78387bfb97c75abddb590ec701ae9711, + X, + 0x00000000000000000000000000000001be290d4c014dff424259e57be62191c4 + ); + + return (vk_digest, U, comm_Az_decompressed, comm_Bz_decompressed, comm_Cz_decompressed); + } + + function loadTranscript() private pure returns (KeccakTranscriptLib.KeccakTranscript memory) { + uint8[] memory init_input = new uint8[](16); // Rust's b"RelaxedR1CSSNARK" + init_input[0] = 0x52; + init_input[1] = 0x65; + init_input[2] = 0x6c; + init_input[3] = 0x61; + init_input[4] = 0x78; + init_input[5] = 0x65; + init_input[6] = 0x64; + init_input[7] = 0x52; + init_input[8] = 0x31; + init_input[9] = 0x43; + init_input[10] = 0x53; + init_input[11] = 0x53; + init_input[12] = 0x4e; + init_input[13] = 0x41; + init_input[14] = 0x52; + init_input[15] = 0x4b; + + KeccakTranscriptLib.KeccakTranscript memory transcript = KeccakTranscriptLib.instantiate(init_input); + return transcript; + } + + function loadInputForU() + private + view + returns (Vesta.VestaAffinePoint[] memory, Vesta.VestaAffinePoint[] memory, uint256[] memory) + { + uint256 comm_Az = 0x30880d50c7abf9334ea5774be9c0471dd4f4a9b5e6034559076812aa1db69fb9; + uint256 comm_Bz = 0xa48247f0746d1101c890f5c7dfb9fc6fa8dab5ba240e708d0d7991346424eaad; + uint256 comm_Cz = 0x322cd251f864d29d23cbedaa0886fa5ca581f61d1c74ed6d5e5ba26bc918a191; + + uint256 comm_E_row = 0xf12f26ac716736e7517e42b7db3807f9f7fd5c22f7adeb2a3141042e60de7b34; + uint256 comm_E_col = 0xb1d7f3abb6e94115a9cf21b2d84b74beb0ba412b8ab83805eda0f41b8871c825; + + Vesta.VestaAffinePoint[] memory comms_A_B_C = new Vesta.VestaAffinePoint[](3); + comms_A_B_C[0] = Vesta.decompress(comm_Az); + comms_A_B_C[1] = Vesta.decompress(comm_Bz); + comms_A_B_C[2] = Vesta.decompress(comm_Cz); + + Vesta.VestaAffinePoint[] memory comms_E = new Vesta.VestaAffinePoint[](2); + comms_E[0] = Vesta.decompress(comm_E_row); + comms_E[1] = Vesta.decompress(comm_E_col); + + uint256[] memory evals = new uint256[](3); + evals[0] = 0x03ceb0495f19505b379b535efae65b4aff31add3f912304bcc92df3ea5aae3d9; + evals[1] = 0x2183da210706e672e013cfde880e41bf49dc13f12ab15a5741bd7d0d2adcab27; + evals[2] = 0x16b1a33f9c928dce78632e3b85f165cb349011f4431d8e8aeda66956471adb0b; + + return (comms_A_B_C, comms_E, evals); + } + + function log2(uint256 x) public pure returns (uint256 y) { + assembly { + let arg := x + x := sub(x, 1) + x := or(x, div(x, 0x02)) + x := or(x, div(x, 0x04)) + x := or(x, div(x, 0x10)) + x := or(x, div(x, 0x100)) + x := or(x, div(x, 0x10000)) + x := or(x, div(x, 0x100000000)) + x := or(x, div(x, 0x10000000000000000)) + x := or(x, div(x, 0x100000000000000000000000000000000)) + x := add(x, 1) + let m := mload(0x40) + mstore(m, 0xf8f9cbfae6cc78fbefe7cdc3a1793dfcf4f0e8bbd8cec470b6a28a7a5a3e1efd) + mstore(add(m, 0x20), 0xf5ecf1b3e9debc68e1d9cfabc5997135bfb7a7a3938b7b606b5b4b3f2f1f0ffe) + mstore(add(m, 0x40), 0xf6e4ed9ff2d6b458eadcdf97bd91692de2d4da8fd2d0ac50c6ae9a8272523616) + mstore(add(m, 0x60), 0xc8c0b887b0a8a4489c948c7f847c6125746c645c544c444038302820181008ff) + mstore(add(m, 0x80), 0xf7cae577eec2a03cf3bad76fb589591debb2dd67e0aa9834bea6925f6a4a2e0e) + mstore(add(m, 0xa0), 0xe39ed557db96902cd38ed14fad815115c786af479b7e83247363534337271707) + mstore(add(m, 0xc0), 0xc976c13bb96e881cb166a933a55e490d9d56952b8d4e801485467d2362422606) + mstore(add(m, 0xe0), 0x753a6d1b65325d0c552a4d1345224105391a310b29122104190a110309020100) + mstore(0x40, add(m, 0x100)) + let magic := 0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff + let shift := 0x100000000000000000000000000000000000000000000000000000000000000 + let a := div(mul(x, magic), shift) + y := div(mload(add(m, sub(255, a))), shift) + y := add(y, mul(256, gt(arg, 0x8000000000000000000000000000000000000000000000000000000000000000))) + } + } + + function loadInputForCoeffsComputation() + private + view + returns (Vesta.VestaAffinePoint[] memory, uint256[] memory, uint256) + { + Vesta.VestaAffinePoint[] memory comm_output_vec = new Vesta.VestaAffinePoint[](8); + comm_output_vec[0] = Vesta.decompress(0x0a9b9b7ee032335d0a85236cd6efb0c1bb8351a1e12c70f1c5a76f48765ed2b6); + comm_output_vec[1] = Vesta.decompress(0x867afb36f39dbf8faf84537a2e85c9008ebdddb93252936ff1fedd8603ac59ab); + comm_output_vec[2] = Vesta.decompress(0x7b505036e82a3cd9d886cff311f664cbd55759fe3ef7bc7190e6343c4d3bac0c); + comm_output_vec[3] = Vesta.decompress(0xd4b4297f4dce110e2f754d3dfb075bceac114a23b33275b35867eb8896f4b48e); + comm_output_vec[4] = Vesta.decompress(0xde20988496bedc6544dbae8bca7ee4ef2d0130facb6375aac5e45deb2745fc1b); + comm_output_vec[5] = Vesta.decompress(0xdd89cf6e483488991d713fcb7a872f17d5c952ac40d160626088235c59ba8681); + comm_output_vec[6] = Vesta.decompress(0x03731a63eacddcf5d0629c3847eda49e806e6d3793a1f841a186c35f7b57c2a3); + comm_output_vec[7] = Vesta.decompress(0x4d296b374f831ec4034953ace07dfe058404b50903f20569df99d2b7b6df6d9b); + + uint256[] memory claims_product_arr = new uint256[](8); + claims_product_arr[0] = 0x13568ef1e6b2ca18ad197b05b83f9743f6193af87787186b3989d88361bed329; + claims_product_arr[1] = 0x29f9cf21fb46f6dd5a9016044996a5110d2ae6522ab7142808413b3e20e00a80; + claims_product_arr[2] = 0x3dd58d85d252507166814c5ee670f40e232c38844b41d72ea1d5e66e1f7cdd47; + claims_product_arr[3] = 0x1e0bd5b1fc3358d9d62e47b0c6bcc4299f35b716720f3ee96de3531ab0af1c49; + claims_product_arr[4] = 0x065b4666ee07456d3460d15425cfd579d842175d4240d2feb40cf57fb1176c4c; + claims_product_arr[5] = 0x12904bdd1583fb18c0c5288c0ed986db7d13805ad724cdb9687e02a6a5feea51; + claims_product_arr[6] = 0x21fe4f39d1763b38e056287c23d81790d8a816f24dd63aaa50377ffea2fc8c8f; + claims_product_arr[7] = 0x3358146ed220ece61c4e54a94aee5714c6283d5e284a5598082b4127f35296a3; + + return (comm_output_vec, claims_product_arr, 131072); + } + + function loadSumcheckProof() private pure returns (PolyLib.SumcheckProof memory) { + PolyLib.CompressedUniPoly[] memory polys = new PolyLib.CompressedUniPoly[](17); + + uint256[] memory poly = new uint256[](3); + poly[0] = 0x20b50e70008947fa3e7cf31b7879a79d2a6cb936ee78652882af5b4f0843af27; + poly[1] = 0x1c8a5e1b802c923dc62493963c5d1776588da8d8c4d789b6efb3494a1be430ba; + poly[2] = 0x155dc63bd05051f6c7ec858ee4290eaed9ccd56a23de611923f0915e6ba50863; + polys[0] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x1722d665c8b674b29fee4cacf2128b3446bf58a1937e6f93d10bbb10954869d8; + poly[1] = 0x0c16d59c075ab2b1921cd2754d30b46d4e7156ee62680a023b5d3c5ae4e5f7d3; + poly[2] = 0x0a571049df2765ac8884753fdaa39da56b699459ebbc88958f5d74454518fa4d; + polys[1] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x1202fb6428a95bc5b1f87e9813160e74221eb95df659fcd8b73c4c98b97a79db; + poly[1] = 0x15b9a81e65d0ee323f44863900f43efb6ef2f24e03c6685f93e4bd2eb8c36886; + poly[2] = 0x17ecee38240c58c9deef0ed1cf24b5962b43d1f01e1350c10397288bbcf01507; + polys[2] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x1b50b5eebf96664daa727b1fdce643c19a8ad5be951c801dcc4b8d2a1a6dc6bc; + poly[1] = 0x37f9e9889de00ca26e7ba98e3925addbb0eb8852b98850b37e2c265e1aa7e72c; + poly[2] = 0x20bb71ce71b550cf2626915fea263ac96885be0257182b16077011796a203e43; + polys[3] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x16e2cac1bdf829885d539ee5b7c410854a1c35efe8c5fea9d483e00d1874b956; + poly[1] = 0x22a97a6cfbbf12dd48bab46cdee27fe87e07f4183f02e395fce5409222573ed7; + poly[2] = 0x14649b4342de18b1ee87663b7e601914d70d353ba457269fa7b1c2f22a5683df; + polys[4] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x1eba988f3bae3989689183e5892e54c733d371512d7fa6e7ca96e234ae814703; + poly[1] = 0x23e415d03e9a88490016b2a8f1250284a761d4e23d725155644b78418d0ec480; + poly[2] = 0x037639dcfe26f8611d59fd35fbe2604144adeaaba1fd4ed20516dfc68f97e555; + polys[5] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x271845cc4a34c8239bca21878cadf6e153aea6e6613c9417544e965c77e68b2f; + poly[1] = 0x2b1b2b85d76899a09c94065fd905a04e24bb5846b571ce8e84025228c652cd3c; + poly[2] = 0x3158a16fc57057376152300765a25bd8e57031756127e08d8cb6eb8345d2e496; + polys[6] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x3a6bd6ff394ba34080fadeccc2b1fca8f54662bf9e616f8c3f222032d043183f; + poly[1] = 0x17154c665912ea4a65aefd6df3e0f1e28234dabef5c94a6339914b3a21da3a57; + poly[2] = 0x0f3dd782a603a7d3c0432bd22393ec7c7b86a7c11e08c75f5eb0d97481c54c93; + polys[7] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x3120fafb0faab0e46f3f5f83489c661a4207ce1377486df1556f354f2621f202; + poly[1] = 0x21b67bbd9fb8209d726a88a27771ae7c18231d6639b83fa8af37347c5e713b21; + poly[2] = 0x19a4e9c0bfa88d55cfcc01f808fc63447e9640572ef5ff226c25bc45f82f0281; + polys[8] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x098ec732bd60824332e143497ce89c98794f5ee0efe42c09e7efc0251ce98705; + poly[1] = 0x35212dea247fd17641453c5e0996e6acf1263f34849774ff174771423610c025; + poly[2] = 0x146d3ba8bf33ab2f1a768a0e095b125c5d8ca050eb37574a851188700c3439b1; + polys[9] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x0ad02dc3c28e324dc03290cd6ecf9b6d068b59a2b22ceb142061f2635bb25e58; + poly[1] = 0x2795a023718a873e6513a5ce61f39378f3910f91a11ebf562cb997bdf274e131; + poly[2] = 0x3e27eaa8738a4336c7ef065781fdb5acf4cfc11b4fd879c242b11b07c960b177; + polys[10] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x2a524aae155898eb2727162b2a32a4899da0ff4f73d90fc43483833f542c2057; + poly[1] = 0x2eb52b0303083a56157096d56fb694c3164903c3eb599fd5d096d6a7411e3ba0; + poly[2] = 0x3e47d63ec4a2647074ba2b4a1b5f4199d9c43bd574870b4f6065bebf5779381b; + polys[11] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x0f6946ab4a194d9c3d8d6aea0cba48a2a1f1ae6063bc0ebdceba7cfd845b0f9d; + poly[1] = 0x3a021fc94ca304273d013734de6ccc85ab92deb5019fa3670d9f04afd295be38; + poly[2] = 0x07a9dcb4437386edbe51d3d46938f41a76a92d5b32882b7c4d336f4891d53ed8; + polys[12] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x3d8db47f52a2e88071c1c24125da7587c39a5d9d6d637e97363c7f81578538c7; + poly[1] = 0x03f5d7a7d937ba08f73525dfce3498001ba290ead911118f57063a3c8062ad3a; + poly[2] = 0x1209e1b3ad1e0f5c89f8f0c083c43a69c16b744e33989452a37dba23b941883a; + polys[13] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x16b3a3cc6d6e4a9118e3d7b92b355c31a9fb38ddde523896768d05f241515a4b; + poly[1] = 0x39a60e31decb6c9a26ceb94bcf0c3f0183788f8167c81942068210cac4d4f950; + poly[2] = 0x26ceba6ece7073de90a7b4cf62d2c718660717c23994de9451fa6f2c4b22b311; + polys[14] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x2393f4eaf35f6f4190668c5b8bdc5cf8dddb7ebbeab412e6b272e7a321467467; + poly[1] = 0x2b2c1f6a766658407b8f15bcfe07ef58d5075a7fba71e5e1eb7d8dc0b288df79; + poly[2] = 0x1ecc8482d85547321b692cb95758c612b39a546846b1080fb1bda673c32a7bd7; + polys[15] = PolyLib.CompressedUniPoly(poly); + + poly = new uint256[](3); + poly[0] = 0x05b85218299b596f07f3180e2b30f8474d03d5113a7912c9659ca40fcb1513d9; + poly[1] = 0x2da66462c5600636192a2a101a089c925c48fce45f9572d453d87c0671fc6ee9; + poly[2] = 0x2a960d6cb4bafe2d63ad279d1d6e8d19c9aece078af4af0aea28cf200fb043c4; + polys[16] = PolyLib.CompressedUniPoly(poly); + + return PolyLib.SumcheckProof(polys); + } + + function check_tau_computation(uint256[] memory tau_expected) + private + returns (KeccakTranscriptLib.KeccakTranscript memory) + { + // secondary + ( + uint256 vk_digest, + Abstractions.RelaxedR1CSInstance memory U, + Vesta.VestaAffinePoint memory comm_Az, + Vesta.VestaAffinePoint memory comm_Bz, + Vesta.VestaAffinePoint memory comm_Cz + ) = loadInputForTau(); + + KeccakTranscriptLib.KeccakTranscript memory transcript = loadTranscript(); + + uint8[] memory label = new uint8[](2); // Rust's b"vk" + label[0] = 0x76; + label[1] = 0x6b; + + transcript = KeccakTranscriptLib.absorb(transcript, label, vk_digest); + + label = new uint8[](1); // Rust's b"U" + label[0] = 0x55; + transcript = KeccakTranscriptLib.absorb( + transcript, label, Vesta.decompress(U.comm_W), Vesta.decompress(U.comm_E), U.X, U.u + ); + + label = new uint8[](1); // Rust's b"c" + label[0] = 0x63; + + Vesta.VestaAffinePoint[] memory commitments = new Vesta.VestaAffinePoint[](3); + commitments[0] = comm_Az; + commitments[1] = comm_Bz; + commitments[2] = comm_Cz; + + transcript = KeccakTranscriptLib.absorb(transcript, label, commitments); + + label = new uint8[](1); // Rust's b"t" + label[0] = 0x74; + + uint256[] memory tau = new uint256[](17); + + assertEq(tau_expected.length, tau.length); + + for (uint256 index = 0; index < tau.length; index++) { + (transcript, tau[index]) = + KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + assertEq(tau[index], tau_expected[index]); + } + + return transcript; + } + + function check_u_computation( + KeccakTranscriptLib.KeccakTranscript memory transcript, + uint256[] memory tau, + PolyEvalInstanceLib.PolyEvalInstance memory expected + ) private returns (KeccakTranscriptLib.KeccakTranscript memory, uint256) { + (Vesta.VestaAffinePoint[] memory comm_vec, Vesta.VestaAffinePoint[] memory comms_E, uint256[] memory evals) = + loadInputForU(); + + uint8[] memory label = new uint8[](1); + label[0] = 0x65; // Rust's b"e" + + transcript = KeccakTranscriptLib.absorb(transcript, label, evals); + transcript = KeccakTranscriptLib.absorb(transcript, label, comms_E); + + // Question to reference implemnetation: Do we need this absorbing, that duplicates one above? + transcript = KeccakTranscriptLib.absorb(transcript, label, evals); + + label[0] = 0x63; // Rust's b"c" + uint256 c; + (transcript, c) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + + PolyEvalInstanceLib.PolyEvalInstance memory u = PolyEvalInstanceLib.batchSecondary(comm_vec, tau, evals, c); + + assertEq(expected.c_x, u.c_x); + assertEq(expected.c_y, u.c_y); + assertEq(expected.e, u.e); + assertEq(expected.x.length, u.x.length); + for (uint256 index = 0; index < u.x.length; index++) { + assertEq(expected.x[index], u.x[index]); + } + return (transcript, c); + } + + function check_gamma1_computation(KeccakTranscriptLib.KeccakTranscript memory transcript, uint256 gamma1_expected) + public + returns (KeccakTranscriptLib.KeccakTranscript memory) + { + uint8[] memory label = new uint8[](2); + label[0] = 0x67; // Rust's b"g1" + label[1] = 0x31; + + uint256 gamma_1; + (transcript, gamma_1) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + + assertEq(gamma1_expected, gamma_1); + + return transcript; + } + + function check_gamma2_computation(KeccakTranscriptLib.KeccakTranscript memory transcript, uint256 gamma2_expected) + public + returns (KeccakTranscriptLib.KeccakTranscript memory) + { + uint8[] memory label = new uint8[](2); + label[0] = 0x67; // Rust's b"g2" + label[1] = 0x32; + + uint256 gamma_2; + (transcript, gamma_2) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + + assertEq(gamma2_expected, gamma_2); + + return transcript; + } + + function check_coeffs_computation( + KeccakTranscriptLib.KeccakTranscript memory transcript, + uint256[] memory expected_coeffs + ) public returns (KeccakTranscriptLib.KeccakTranscript memory, uint256[] memory, uint256[] memory, uint256) { + (Vesta.VestaAffinePoint[] memory comm_output_vec, uint256[] memory claims_product_arr, uint256 vk_S_comm_N) = + loadInputForCoeffsComputation(); + + uint8[] memory label = new uint8[](1); + label[0] = 0x6f; // Rust's b"o" + + transcript = KeccakTranscriptLib.absorb(transcript, label, comm_output_vec); + + label[0] = 0x63; // Rust's b"c" + + transcript = KeccakTranscriptLib.absorb(transcript, label, claims_product_arr); + + uint256 num_rounds = log2(vk_S_comm_N); + + label[0] = 0x65; // Rust's b"e" + uint256[] memory rand_eq = new uint256[](num_rounds); + uint256 index = 0; + for (index = 0; index < num_rounds; index++) { + (transcript, rand_eq[index]) = + KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + } + + label[0] = 0x72; // Rust's b"r" + + // in Rust length of coeffs is 10 + uint256[] memory coeffs = new uint256[](10); + (transcript, coeffs[0]) = KeccakTranscriptLib.squeeze(transcript, ScalarFromUniformLib.curvePallas(), label); + assertEq(coeffs[0], expected_coeffs[0]); + + for (index = 1; index < coeffs.length; index++) { + coeffs[index] = mulmod(coeffs[index - 1], coeffs[0], Pallas.P_MOD); + assertEq(coeffs[index], expected_coeffs[index]); + } + + return (transcript, rand_eq, coeffs, num_rounds); + } + + function compute_tau_claim_sat_final_r_sat_c_inner() + public + returns ( + KeccakTranscriptLib.KeccakTranscript memory, + uint256[] memory, + uint256[] memory, + uint256, + uint256[] memory, + uint256, + PolyEvalInstanceLib.PolyEvalInstance memory + ) + { + // secondary + uint256[] memory tau_expected = new uint256[](17); + tau_expected[0] = 0x17c03663671666409d2e5656c3ee877145c7e32e3494e16dbbec709afd0709e6; + tau_expected[1] = 0x38b515b8596f09d0f1c56b3da33dc7c7dd3b1fe25d0d04b87cd716dc23f2cc31; + tau_expected[2] = 0x23ae00416f6e0bd1e292f12ba6cbd2c498509027b8a2d92f287314235f2b2a6d; + tau_expected[3] = 0x35281c3c99450dd3bdb0fccdafdf3028ea4e5b11a59fd8d485191cf79344f9e4; + tau_expected[4] = 0x3110a4ef81e06dd527736a4fa519e2dd25453adb5355b08e9c83bd6341274585; + tau_expected[5] = 0x02f5cd90a9bb245b75139967f5e033ccdaa0a5c03aa8eb349ec36eed1a4ee8fc; + tau_expected[6] = 0x3f7bbbc64bcd58d08a504d873192746a9f568042907f926b174b59a0247f6e8e; + tau_expected[7] = 0x2a3cb49129f6437fc4fc78ea272a653b610569f37a21757078fa74b39340f832; + tau_expected[8] = 0x246eaeb45c2eaa49fe0490501a77cea8f18497c2b7a35b9d86f0930e0e082b7f; + tau_expected[9] = 0x2f401cf8151d3eb918d15212f026ebd4930794107e7cd915c789a4b1c7e5eadd; + tau_expected[10] = 0x133bd93c31e8b783f39e71c9b40c96591649115e90b0bafbffa1823fffb10ba0; + tau_expected[11] = 0x14605eada47c70ab4c51563dc9fbb4953df05924deef56cbf8189840774a3828; + tau_expected[12] = 0x3a09b34278f95c71529c3374c6567cec43f5dd65c76f863469249d5c2ef43e9e; + tau_expected[13] = 0x0d88b3a19bf13be9c4c868dcff22a6790cc07736b9ed457be5782809bb55e0e4; + tau_expected[14] = 0x19430f84eabe5885bd7fcdb9630c471c8c6002ad54302818962e3f63293935f0; + tau_expected[15] = 0x3c43f9fc4e8571b3b15190551fe246bc25d190cff304e99253123126baf888ef; + tau_expected[16] = 0x0bde99a49b09b102f23fe24cf9790380c734acc82063014a243edbbe4b8ba3ed; + + KeccakTranscriptLib.KeccakTranscript memory transcript = check_tau_computation(tau_expected); + + PolyEvalInstanceLib.PolyEvalInstance memory u_expected = PolyEvalInstanceLib.PolyEvalInstance( + 0x15353461b0478bc4adc71d396fdb3d98aef58ac5184a56985b145ff8a72056cd, + 0x2042fe5212f18f19e509506eb626870011bfd54556493e761833a88dc40cadc0, + tau_expected, + 0x2144bc0d13b5cfc99beab8db542dd270bd2a8af3911e754ca0ca0818a5b9a5ba + ); + uint256 c_inner; + (transcript, c_inner) = check_u_computation(transcript, tau_expected, u_expected); + + // not a Step3, but we should have correct transcript + transcript = + check_gamma1_computation(transcript, 0x0d6f59a9222edc2cf19800be1beafc321d236892a73b2225f6ea491583a82bbd); + transcript = + check_gamma2_computation(transcript, 0x0cd442b1adc9853e45a036cc2613ee673ececcb54021a0980d51212176690d01); + + uint256[] memory coeffs = new uint256[](10); + coeffs[0] = 0x24abec2a07d73e7f6aa8c47c41c545063724e664fc177870725a479a48296c45; + coeffs[1] = 0x252a854862eb46096810a4a4a9f35c0e40a12ea0ec1960d95626f2657a6a0422; + coeffs[2] = 0x03d733614e8f8b22b7a014ddbaf7108a8b99575a73543fb38850fd59e5d26b65; + coeffs[3] = 0x26a82b7b3206cd44937ae80cb33d69f9e5ca95c456b92d0b4865d24a3850de3f; + coeffs[4] = 0x2722c59f6520030025c43aa9e486b5f0fee7e190f6751674328b28828227957a; + coeffs[5] = 0x3cdff180a4b073740aeacc97898517c3cfa3b750827902d4b28bd583d1eeb77d; + coeffs[6] = 0x12dada10e0a1bd16bb48b32c39f644188987784e0ca26dbf0e1a5db5721357e6; + coeffs[7] = 0x0ae9211366b88ba710f1b05e0b5d961eebbf59c205e5dbc9384b93c195dd357c; + coeffs[8] = 0x0f93dbcda1deaf626a43adb3c60580f16d6b319032efe5d9bcc56227b04db6a5; + coeffs[9] = 0x0082b3fee7e08d0875839ed964a59b3d8890f3cc8c99951135bab451e481de45; + + uint256 num_rounds; + uint256[] memory rand_eq; + (transcript, rand_eq, coeffs, num_rounds) = check_coeffs_computation(transcript, coeffs); + + uint256 claim_sat_final; + uint256[] memory r_sat; + (claim_sat_final, r_sat, transcript) = SecondarySumcheck.verify( + loadSumcheckProof(), mulmod(coeffs[9], u_expected.e, Pallas.P_MOD), num_rounds, 3, transcript + ); + + return (transcript, rand_eq, tau_expected, claim_sat_final, r_sat, c_inner, u_expected); + } + + function test_taus_bound_r_sat_rand_eq_bound_r_sat_computation() public { + KeccakTranscriptLib.KeccakTranscript memory transcript; + uint256[] memory rand_eq; + uint256[] memory tau; + uint256 claim_sat_final; + uint256[] memory r_sat; + uint256 c_inner; + PolyEvalInstanceLib.PolyEvalInstance memory u; + + (transcript, rand_eq, tau, claim_sat_final, r_sat, c_inner, u) = compute_tau_claim_sat_final_r_sat_c_inner(); + + uint256 claim_sat_final_expected = 0x1fd5c723b6f0663878bc5c4b30e71a4f6f4e94be969d8948579055fe7cfa1d1e; + uint256[] memory r_sat_expected = new uint256[](17); + r_sat_expected[0] = 0x0c6d2bf540a735934ae40e93560708b56f4452a1b9c6ad435bcc5a3d718d636c; + r_sat_expected[1] = 0x12356e9d5716fbc87d57127bf033d6c944a469d3594be6690ebea874852df9a2; + r_sat_expected[2] = 0x11920f58b99610ea1e7df2b95803ac51e568be3261d8c57e53c5e7232b6a8100; + r_sat_expected[3] = 0x07669895060aa6d19a26a3ca15b66c653f057411e3e249ad032bd4c3d454dd2c; + r_sat_expected[4] = 0x1529ed49bcf02d198015331aaceda91523d4cb6480bf88ece2b9fdcb7455318d; + r_sat_expected[5] = 0x1a143c3ea3b03de4235858e759e5a5f145becbe09e73034bc5deae7b448dafcd; + r_sat_expected[6] = 0x33b78932e8c0a8560c559f8c6ffb88f47355f01af8d4db106cbfd0bb6813b48f; + r_sat_expected[7] = 0x28137caa1e6c94ba725683445a2fda31dde080460f1194927ea3d705e4a2b4cc; + r_sat_expected[8] = 0x2a1dc1db6e9d737c435c9c5f1e99a82ef22909045565c1d3d4a70e7f3476ddd0; + r_sat_expected[9] = 0x1980c374b3934f56f94174320f07a2086f723271f06ec0341619e804fe0af261; + r_sat_expected[10] = 0x3c13da89c92bed75f7441764335289c8688dbaad7592ffa27fc4af6c76234b9a; + r_sat_expected[11] = 0x0821d484a68f72a551207bf5a27a57dddbe4f6c1352fce1210ac8139c5b4b423; + r_sat_expected[12] = 0x1d70c72ceb8af51ff89f5b520643d1dcc35393e1255e9476b7ad4987324c467a; + r_sat_expected[13] = 0x1cbcf9e4c122e494679ad733c241d0e908d2a3c9fdb65cafea3a8c6ff72e2517; + r_sat_expected[14] = 0x0ef3b3e72135c28d158b117f3733d291c4789c2ac9c754bfe1e90a8fc5fbb208; + r_sat_expected[15] = 0x17e5a84f6bbdd8e53f5ec117374d39b6a23fe37a58571e95da5b4c1820608245; + r_sat_expected[16] = 0x3492aaf8252e21df8a00c0febe0c2c2476008b7210edc742afd161f7439adb4f; + + assertEq(claim_sat_final_expected, claim_sat_final); + assertEq(r_sat_expected.length, r_sat.length); + for (uint256 index = 0; index < r_sat.length; index++) { + assertEq(r_sat[index], r_sat_expected[index]); + } + + uint256 taus_bound_r_sat = EqPolinomialLib.evaluate(tau, r_sat, Pallas.P_MOD, Pallas.negateBase); + uint256 rand_eq_bound_r_sat = EqPolinomialLib.evaluate(rand_eq, r_sat, Pallas.P_MOD, Pallas.negateBase); + + assertEq(0x22f427ab378ad36181e799afb461c7959e81ead14d9cbb1cf817c3799fbdeaf1, taus_bound_r_sat); + assertEq(0x08fa71bd727e1f0539be7441ee184c610e4012207be66fc1fc948b009aa7cb84, rand_eq_bound_r_sat); + } +} diff --git a/test/sumcheck-tests.t.sol b/test/sumcheck-tests.t.sol index 547ca22..026d3f8 100644 --- a/test/sumcheck-tests.t.sol +++ b/test/sumcheck-tests.t.sol @@ -2,41 +2,11 @@ pragma solidity ^0.8.16; import "@std/Test.sol"; -import "src/verifier/step4/KeccakTranscript.sol"; -import "src/verifier/step4/SumcheckLogic.sol"; +import "src/blocks/KeccakTranscript.sol"; +import "src/Utilities.sol"; +import "src/blocks/Sumcheck.sol"; contract SumcheckTest is Test { - function log2(uint256 x) public pure returns (uint256 y) { - assembly { - let arg := x - x := sub(x, 1) - x := or(x, div(x, 0x02)) - x := or(x, div(x, 0x04)) - x := or(x, div(x, 0x10)) - x := or(x, div(x, 0x100)) - x := or(x, div(x, 0x10000)) - x := or(x, div(x, 0x100000000)) - x := or(x, div(x, 0x10000000000000000)) - x := or(x, div(x, 0x100000000000000000000000000000000)) - x := add(x, 1) - let m := mload(0x40) - mstore(m, 0xf8f9cbfae6cc78fbefe7cdc3a1793dfcf4f0e8bbd8cec470b6a28a7a5a3e1efd) - mstore(add(m, 0x20), 0xf5ecf1b3e9debc68e1d9cfabc5997135bfb7a7a3938b7b606b5b4b3f2f1f0ffe) - mstore(add(m, 0x40), 0xf6e4ed9ff2d6b458eadcdf97bd91692de2d4da8fd2d0ac50c6ae9a8272523616) - mstore(add(m, 0x60), 0xc8c0b887b0a8a4489c948c7f847c6125746c645c544c444038302820181008ff) - mstore(add(m, 0x80), 0xf7cae577eec2a03cf3bad76fb589591debb2dd67e0aa9834bea6925f6a4a2e0e) - mstore(add(m, 0xa0), 0xe39ed557db96902cd38ed14fad815115c786af479b7e83247363534337271707) - mstore(add(m, 0xc0), 0xc976c13bb96e881cb166a933a55e490d9d56952b8d4e801485467d2362422606) - mstore(add(m, 0xe0), 0x753a6d1b65325d0c552a4d1345224105391a310b29122104190a110309020100) - mstore(0x40, add(m, 0x100)) - let magic := 0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff - let shift := 0x100000000000000000000000000000000000000000000000000000000000000 - let a := div(mul(x, magic), shift) - y := div(mload(add(m, sub(255, a))), shift) - y := add(y, mul(256, gt(arg, 0x8000000000000000000000000000000000000000000000000000000000000000))) - } - } - function testComputeTauPrimary() public { uint8[] memory input = new uint8[](16); // b"RelaxedR1CSSNARK" in Rust input[0] = 0x52; @@ -329,7 +299,7 @@ contract SumcheckTest is Test { transcript = KeccakTranscriptLib.absorb(transcript, vk_comm_label, vk_comm); transcript = KeccakTranscriptLib.absorb(transcript, U_label, U); - uint256 num_rounds_x = log2(16384); + uint256 num_rounds_x = CommonUtilities.log2(16384); //uint256 num_rounds_y = log2(16384) + 1; uint8[] memory squeezeLabel = new uint8[](1); // b"t" in Rust @@ -343,20 +313,20 @@ contract SumcheckTest is Test { tau[index] = keccakOutput; } - assertEq(tau[0], 0x327f4af4db96711d3192cee19b1946d5b9d3c61e78d6f352261e11af7cbed55a); - assertEq(tau[1], 0x2640290b59a25f849e020cb1b0063861e35a95a8c42a9cdd63928a4ea856adbf); - assertEq(tau[2], 0x11b72e2a69592c5545a794428674fd998d4e3fbd52f156eca4a66d54f09f775e); - assertEq(tau[3], 0x09b0dcdd3ebe153fea39180a0f6bf9546778ffd7e288088489529aa95097fcea); - assertEq(tau[4], 0x3757c49e53ce7f58203159e411db2fe38854df4fc7a93833f28e63960576202e); - assertEq(tau[5], 0x362681bac77a734c4b893a2a2ff2f3cfbff469319b1a1e851c139349f1f62232); - assertEq(tau[6], 0x3036e71d56b2ed7027b5e305dddbc94d3bae6c6afdfaec8bdcd7d05cd89fc4ef); - assertEq(tau[7], 0x33ebf2408bbe683a2516b6e3904d95f6a99da08c27843d425bb3e781b407f812); - assertEq(tau[8], 0x03b2369449d816527fe9f0ec97e4971a65a35f89762ae71610f06096337ea9f2); - assertEq(tau[9], 0x38ca25021f2193df59c755dcebe90a5efb52e97c0440597915d022e9a59357bd); - assertEq(tau[10], 0x240032a20ecb27257f7334b3f538d836f40783e9709b879bd5523f789aad0a63); - assertEq(tau[11], 0x364f7a4b101385305529e5d5237cb71e69950f2b4ed7b4f0b160b1aa3ac71c9a); - assertEq(tau[12], 0x3ffacadcc0e723b1fa45c1ad1b30612dc31924e6027171f0a5da6d8963671c5a); - assertEq(tau[13], 0x25ad865935043775d676da736cc400404b1060585df1386dd4f560de4c4680bc); + assertEq(tau[0], Field.reverse256(0xec15c1b59e4d0132159f6f523d6ea12c8cbdbd2c0f02ec9f47cab551a3eba530)); + assertEq(tau[1], Field.reverse256(0x6dc76eb849302b3eb0dacf4f0954fac6c62825621a49a5aa3189d8266711dd0c)); + assertEq(tau[2], Field.reverse256(0xf14fd95e50e62c669756afb51ae048ad61a67146f535a1180239104f71d10310)); + assertEq(tau[3], Field.reverse256(0xe1435c8ac491329906db14b063647f4829819636933e1eba745970e65bcd6408)); + assertEq(tau[4], Field.reverse256(0xe7f81e72eb554cc2d7586759ea3eeaf0c6adb12f8ed7412e8942716006b41625)); + assertEq(tau[5], Field.reverse256(0x352704eceb46a3b8d90d8898d1ed7867e606f791ce5566df6d3954a15fff1e0a)); + assertEq(tau[6], Field.reverse256(0xcfec1aa7ed04102c30cde1449bf855e062782e24e0c3d17d633840f0b5c27224)); + assertEq(tau[7], Field.reverse256(0xdd73e72d775abf5812f25bcd4fe88e7c9960c9486a8e0d0a7c5a1702af406c3e)); + assertEq(tau[8], Field.reverse256(0x1f21b52aae284e7cbe4f10adc93f6da159567295f7009cc0a970f5ebf62c893a)); + assertEq(tau[9], Field.reverse256(0x62c359fb38367fea51324c44f9bf747736ef1f57be5147d2cb2a4e0845309415)); + assertEq(tau[10], Field.reverse256(0xe7610dfab97ee9bf7bbe8c54048e6d33d344e4552f462780943c704c8ef5163b)); + assertEq(tau[11], Field.reverse256(0xa80224715966a0dbd9ef37fc32447c9522988208aec37435f14e2de9c1f82e06)); + assertEq(tau[12], Field.reverse256(0x2232489c8dacb3de64ddf91fa640a6dcffcf8e70c39fde06f374993226190529)); + assertEq(tau[13], Field.reverse256(0x60a7c22598a889a01f92683f05715b048b204a42a0af90a4e2c4ddfb68a66814)); } function testPolyUncompress() public {