From d5178771ca1afcde69b6cca42eca610c409e61eb Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:12:09 +0000 Subject: [PATCH 1/3] feat: add shplemini transcript --- barretenberg/sol/src/honk/HonkTypes.sol | 4 + barretenberg/sol/src/honk/Transcript.sol | 118 +++++++++++++++++++++-- barretenberg/sol/src/honk/utils.sol | 5 + 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/barretenberg/sol/src/honk/HonkTypes.sol b/barretenberg/sol/src/honk/HonkTypes.sol index 180b163271f..1d96f8c478e 100644 --- a/barretenberg/sol/src/honk/HonkTypes.sol +++ b/barretenberg/sol/src/honk/HonkTypes.sol @@ -136,5 +136,9 @@ library Honk { // Sumcheck Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates; Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations; + // Gemini + Honk.G1ProofPoint[CONST_PROOF_SIZE_LOG_N] geminiFoldUnivariates; + Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations; + Honk.G1ProofPoint shplonkQ; } } diff --git a/barretenberg/sol/src/honk/Transcript.sol b/barretenberg/sol/src/honk/Transcript.sol index 70ac6234158..39e49accce6 100644 --- a/barretenberg/sol/src/honk/Transcript.sol +++ b/barretenberg/sol/src/honk/Transcript.sol @@ -19,7 +19,11 @@ struct Transcript { Fr[NUMBER_OF_ALPHAS] alphas; Fr[CONST_PROOF_SIZE_LOG_N] gateChallenges; Fr[CONST_PROOF_SIZE_LOG_N] sumCheckUChallenges; - // Fr rho; + // Gemini + Fr rho; + Fr geminiR; + Fr shplonkNu; + Fr shplonkZ; // Derived Fr publicInputsDelta; } @@ -40,7 +44,14 @@ library TranscriptLib { (t.gateChallenges, previousChallenge) = generateGateChallenges(previousChallenge); (t.sumCheckUChallenges, previousChallenge) = generateSumcheckChallenges(proof, previousChallenge); - // (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge); + + (t.rho, previousChallenge) = generateRhoChallenge(proof, previousChallenge); + + (t.geminiR, previousChallenge) = generateGeminiRChallenge(proof, previousChallenge); + + (t.shplonkNu, previousChallenge) = generateShplonkNuChallenge(proof, previousChallenge); + + (t.shplonkZ, previousChallenge) = generateShplonkZChallenge(proof, previousChallenge); return t; } @@ -196,6 +207,62 @@ library TranscriptLib { (rho, unused) = splitChallenge(nextPreviousChallenge); } + function generateGeminiRChallenge(Honk.Proof memory proof, Fr prevChallenge) + internal + view + returns (Fr geminiR, Fr nextPreviousChallenge) + { + uint256[(CONST_PROOF_SIZE_LOG_N - 1) * 4 + 1] memory gR; + gR[0] = Fr.unwrap(prevChallenge); + + for (uint256 i = 0; i < CONST_PROOF_SIZE_LOG_N - 1; i++) { + gR[1 + i * 4] = proof.geminiFoldUnivariates[i].x_0; + gR[2 + i * 4] = proof.geminiFoldUnivariates[i].x_1; + gR[3 + i * 4] = proof.geminiFoldUnivariates[i].y_0; + gR[4 + i * 4] = proof.geminiFoldUnivariates[i].y_1; + } + + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR))); + Fr unused; + (geminiR, unused) = splitChallenge(nextPreviousChallenge); + } + + function generateShplonkNuChallenge(Honk.Proof memory proof, Fr prevChallenge) + internal + view + returns (Fr shplonkNu, Fr nextPreviousChallenge) + { + uint256[(CONST_PROOF_SIZE_LOG_N) + 1] memory shplonkNuChallengeElements; + shplonkNuChallengeElements[0] = Fr.unwrap(prevChallenge); + + for (uint256 i = 0; i < CONST_PROOF_SIZE_LOG_N; i++) { + shplonkNuChallengeElements[i + 1] = Fr.unwrap(proof.geminiAEvaluations[i]); + } + + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements))); + Fr unused; + (shplonkNu, unused) = splitChallenge(nextPreviousChallenge); + logFr("shplonkNu", shplonkNu); + } + + function generateShplonkZChallenge(Honk.Proof memory proof, Fr prevChallenge) + internal + view + returns (Fr shplonkZ, Fr nextPreviousChallenge) + { + uint256[5] memory shplonkZChallengeElements; + shplonkZChallengeElements[0] = Fr.unwrap(prevChallenge); + + shplonkZChallengeElements[1] = proof.shplonkQ.x_0; + shplonkZChallengeElements[2] = proof.shplonkQ.x_1; + shplonkZChallengeElements[3] = proof.shplonkQ.y_0; + shplonkZChallengeElements[4] = proof.shplonkQ.y_1; + + nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkZChallengeElements))); + Fr unused; + (shplonkZ, unused) = splitChallenge(nextPreviousChallenge); + } + // TODO: mod q proof points // TODO: Preprocess all of the memory locations // TODO: Adjust proof point serde away from poseidon forced field elements @@ -287,12 +354,47 @@ library TranscriptLib { } boundary = boundary + (NUMBER_OF_ENTITIES * 0x20); - // p.zmPi = Honk.G1ProofPoint({ - // x_0: uint256(bytes32(proof[boundary + 0x80:boundary + 0xa0])), - // x_1: uint256(bytes32(proof[boundary + 0xa0:boundary + 0xc0])), - // y_0: uint256(bytes32(proof[boundary + 0xc0:boundary + 0xe0])), - // y_1: uint256(bytes32(proof[boundary + 0xe0:boundary + 0x100])) - // }); + + // Gemini + // Read gemini fold univariates + for (uint256 i = 0; i < CONST_PROOF_SIZE_LOG_N - 1; i++) { + uint256 xStart = boundary + (i * 0x80); + uint256 xEnd = xStart + 0x20; + + uint256 x1Start = xEnd; + uint256 x1End = x1Start + 0x20; + + uint256 yStart = x1End; + uint256 yEnd = yStart + 0x20; + + uint256 y1Start = yEnd; + uint256 y1End = y1Start + 0x20; + p.geminiFoldUnivariates[i] = Honk.G1ProofPoint({ + x_0: uint256(bytes32(proof[xStart:xEnd])), + x_1: uint256(bytes32(proof[x1Start:x1End])), + y_0: uint256(bytes32(proof[yStart:yEnd])), + y_1: uint256(bytes32(proof[y1Start:y1End])) + }); + } + + boundary = boundary + ((CONST_PROOF_SIZE_LOG_N - 1) * 0x80); + + // Read gemini a evaluations + for (uint256 i = 0; i < CONST_PROOF_SIZE_LOG_N; i++) { + uint256 start = boundary + (i * 0x20); + uint256 end = start + 0x20; + p.geminiAEvaluations[i] = FrLib.fromBytes32(bytes32(proof[start:end])); + } + + boundary = boundary + (CONST_PROOF_SIZE_LOG_N * 0x20); + + // Shplonk + p.shplonkQ = Honk.G1ProofPoint({ + x_0: uint256(bytes32(proof[boundary:boundary + 0x20])), + x_1: uint256(bytes32(proof[boundary + 0x20:boundary + 0x40])), + y_0: uint256(bytes32(proof[boundary + 0x40:boundary + 0x60])), + y_1: uint256(bytes32(proof[boundary + 0x60:boundary + 0x80])) + }); return p; } diff --git a/barretenberg/sol/src/honk/utils.sol b/barretenberg/sol/src/honk/utils.sol index 15d5e9b7b67..dc70597d1b6 100644 --- a/barretenberg/sol/src/honk/utils.sol +++ b/barretenberg/sol/src/honk/utils.sol @@ -55,6 +55,11 @@ function logUint(string memory name, uint256 value) pure { console2.log(name, as_hex); } +function logUint(string memory name, uint256 i, uint256 value) pure { + string memory as_hex = bytes32ToString(bytes32(value)); + console2.log(name, i, as_hex); +} + function logFr(string memory name, Fr value) pure { string memory as_hex = bytes32ToString(bytes32(Fr.unwrap(value))); console2.log(name, as_hex); From 993c70a900f8068c55ba7362554716f0f272e753 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Sat, 28 Sep 2024 13:07:44 +0000 Subject: [PATCH 2/3] fix: remove log --- barretenberg/sol/src/honk/Transcript.sol | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/barretenberg/sol/src/honk/Transcript.sol b/barretenberg/sol/src/honk/Transcript.sol index 39e49accce6..2a5fa1f0be5 100644 --- a/barretenberg/sol/src/honk/Transcript.sol +++ b/barretenberg/sol/src/honk/Transcript.sol @@ -66,7 +66,7 @@ library TranscriptLib { function generateEtaChallenge(Honk.Proof memory proof, bytes32[] calldata publicInputs, uint256 publicInputsSize) internal - view + pure returns (Fr eta, Fr etaTwo, Fr etaThree, Fr previousChallenge) { bytes32[] memory round0 = new bytes32[](3 + publicInputsSize + 12); @@ -101,7 +101,7 @@ library TranscriptLib { function generateBetaAndGammaChallenges(Fr previousChallenge, Honk.Proof memory proof) internal - view + pure returns (Fr beta, Fr gamma, Fr nextPreviousChallenge) { bytes32[13] memory round1; @@ -126,7 +126,7 @@ library TranscriptLib { // Alpha challenges non-linearise the gate contributions function generateAlphaChallenges(Fr previousChallenge, Honk.Proof memory proof) internal - view + pure returns (Fr[NUMBER_OF_ALPHAS] memory alphas, Fr nextPreviousChallenge) { // Generate the original sumcheck alpha 0 by hashing zPerm and zLookup @@ -157,7 +157,7 @@ library TranscriptLib { function generateGateChallenges(Fr previousChallenge) internal - view + pure returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge) { for (uint256 i = 0; i < CONST_PROOF_SIZE_LOG_N; i++) { @@ -170,7 +170,7 @@ library TranscriptLib { function generateSumcheckChallenges(Honk.Proof memory proof, Fr prevChallenge) internal - view + pure returns (Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckChallenges, Fr nextPreviousChallenge) { for (uint256 i = 0; i < CONST_PROOF_SIZE_LOG_N; i++) { @@ -188,10 +188,9 @@ library TranscriptLib { nextPreviousChallenge = prevChallenge; } - // TODO: reuse this for Shplemini function generateRhoChallenge(Honk.Proof memory proof, Fr prevChallenge) internal - view + pure returns (Fr rho, Fr nextPreviousChallenge) { Fr[NUMBER_OF_ENTITIES + 1] memory rhoChallengeElements; @@ -209,7 +208,7 @@ library TranscriptLib { function generateGeminiRChallenge(Honk.Proof memory proof, Fr prevChallenge) internal - view + pure returns (Fr geminiR, Fr nextPreviousChallenge) { uint256[(CONST_PROOF_SIZE_LOG_N - 1) * 4 + 1] memory gR; @@ -229,7 +228,7 @@ library TranscriptLib { function generateShplonkNuChallenge(Honk.Proof memory proof, Fr prevChallenge) internal - view + pure returns (Fr shplonkNu, Fr nextPreviousChallenge) { uint256[(CONST_PROOF_SIZE_LOG_N) + 1] memory shplonkNuChallengeElements; @@ -242,12 +241,11 @@ library TranscriptLib { nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(shplonkNuChallengeElements))); Fr unused; (shplonkNu, unused) = splitChallenge(nextPreviousChallenge); - logFr("shplonkNu", shplonkNu); } function generateShplonkZChallenge(Honk.Proof memory proof, Fr prevChallenge) internal - view + pure returns (Fr shplonkZ, Fr nextPreviousChallenge) { uint256[5] memory shplonkZChallengeElements; @@ -267,7 +265,7 @@ library TranscriptLib { // TODO: Preprocess all of the memory locations // TODO: Adjust proof point serde away from poseidon forced field elements // TODO: move this back to probably each instance to avoid dynamic init of arrays in the Transcript Lib - function loadProof(bytes calldata proof) internal view returns (Honk.Proof memory) { + function loadProof(bytes calldata proof) internal pure returns (Honk.Proof memory) { Honk.Proof memory p; // Metadata From d03d0342a1bd0c0df7c14a1f6622b792187b34c6 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Tue, 1 Oct 2024 12:30:14 +0000 Subject: [PATCH 3/3] fix: rename geminiComms --- barretenberg/sol/src/honk/HonkTypes.sol | 2 +- barretenberg/sol/src/honk/Transcript.sol | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/barretenberg/sol/src/honk/HonkTypes.sol b/barretenberg/sol/src/honk/HonkTypes.sol index 1d96f8c478e..0e8890e8c2c 100644 --- a/barretenberg/sol/src/honk/HonkTypes.sol +++ b/barretenberg/sol/src/honk/HonkTypes.sol @@ -137,7 +137,7 @@ library Honk { Fr[BATCHED_RELATION_PARTIAL_LENGTH][CONST_PROOF_SIZE_LOG_N] sumcheckUnivariates; Fr[NUMBER_OF_ENTITIES] sumcheckEvaluations; // Gemini - Honk.G1ProofPoint[CONST_PROOF_SIZE_LOG_N] geminiFoldUnivariates; + Honk.G1ProofPoint[CONST_PROOF_SIZE_LOG_N - 1] geminiFoldComms; Fr[CONST_PROOF_SIZE_LOG_N] geminiAEvaluations; Honk.G1ProofPoint shplonkQ; } diff --git a/barretenberg/sol/src/honk/Transcript.sol b/barretenberg/sol/src/honk/Transcript.sol index 2a5fa1f0be5..f7c1f8df677 100644 --- a/barretenberg/sol/src/honk/Transcript.sol +++ b/barretenberg/sol/src/honk/Transcript.sol @@ -215,10 +215,10 @@ library TranscriptLib { gR[0] = Fr.unwrap(prevChallenge); for (uint256 i = 0; i < CONST_PROOF_SIZE_LOG_N - 1; i++) { - gR[1 + i * 4] = proof.geminiFoldUnivariates[i].x_0; - gR[2 + i * 4] = proof.geminiFoldUnivariates[i].x_1; - gR[3 + i * 4] = proof.geminiFoldUnivariates[i].y_0; - gR[4 + i * 4] = proof.geminiFoldUnivariates[i].y_1; + gR[1 + i * 4] = proof.geminiFoldComms[i].x_0; + gR[2 + i * 4] = proof.geminiFoldComms[i].x_1; + gR[3 + i * 4] = proof.geminiFoldComms[i].y_0; + gR[4 + i * 4] = proof.geminiFoldComms[i].y_1; } nextPreviousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(gR))); @@ -367,7 +367,7 @@ library TranscriptLib { uint256 y1Start = yEnd; uint256 y1End = y1Start + 0x20; - p.geminiFoldUnivariates[i] = Honk.G1ProofPoint({ + p.geminiFoldComms[i] = Honk.G1ProofPoint({ x_0: uint256(bytes32(proof[xStart:xEnd])), x_1: uint256(bytes32(proof[x1Start:x1End])), y_0: uint256(bytes32(proof[yStart:yEnd])),