Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: unify honk verifier contracts #11067

Merged
merged 5 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 25 additions & 22 deletions barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// Source code for the Ultrahonk Solidity verifier.
// It's expected that the AcirComposer will inject a library which will load the verification key into memory.
const std::string HONK_CONTRACT_SOURCE = R"(
static const char HONK_CONTRACT_SOURCE[] = R"(
pragma solidity ^0.8.27;

type Fr is uint256;
Expand Down Expand Up @@ -1407,11 +1407,22 @@ interface IVerifier {
function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool);
}

// Smart contract verifier of honk proofs
contract HonkVerifier is IVerifier
{

abstract contract BaseHonkVerifier is IVerifier {
using FrLib for Fr;

uint256 N;
uint256 logN;
uint256 numPublicInputs;

constructor(uint256 _N, uint256 _logN, uint256 _numPublicInputs) {
N = _N;
logN = _logN;
numPublicInputs = _numPublicInputs;
}

function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);

function verify(bytes calldata proof, bytes32[] calldata publicInputs) public view override returns (bool) {
Honk.VerificationKey memory vk = loadVerificationKey();
Honk.Proof memory p = TranscriptLib.loadProof(proof);
Expand All @@ -1437,10 +1448,6 @@ contract HonkVerifier is IVerifier
return sumcheckVerified && shpleminiVerified; // Boolean condition not required - nice for vanity :)
}

function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {
return HonkVerificationKey.loadVerificationKey();
}

function computePublicInputDelta(
bytes32[] memory publicInputs,
Fr beta,
Expand All @@ -1455,7 +1462,7 @@ contract HonkVerifier is IVerifier
Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));

{
for (uint256 i = 0; i < NUMBER_OF_PUBLIC_INPUTS; i++) {
for (uint256 i = 0; i < numPublicInputs; i++) {
Fr pubInput = FrLib.fromBytes32(publicInputs[i]);

numerator = numerator * (numeratorAcc + pubInput);
Expand All @@ -1477,7 +1484,7 @@ contract HonkVerifier is IVerifier
Fr powPartialEvaluation = Fr.wrap(1);

// We perform sumcheck reductions over log n rounds ( the multivariate degree )
for (uint256 round; round < LOG_N; ++round) {
for (uint256 round; round < logN; ++round) {
Fr[BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];
bool valid = checkSum(roundUnivariate, roundTarget);
if (!valid) revert SumcheckFailed();
Expand Down Expand Up @@ -1509,6 +1516,7 @@ contract HonkVerifier is IVerifier
view
returns (Fr targetSum)
{
// TODO: inline
Fr[BATCHED_RELATION_PARTIAL_LENGTH] memory BARYCENTRIC_LAGRANGE_DENOMINATORS = [
Fr.wrap(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec51),
Fr.wrap(0x00000000000000000000000000000000000000000000000000000000000002d0),
Expand Down Expand Up @@ -1589,7 +1597,7 @@ contract HonkVerifier is IVerifier
{
ShpleminiIntermediates memory mem; // stack

// - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size, I think this should be CONST_PROOF_SIZE
// - Compute vector (r, r², ... , r²⁽ⁿ⁻¹⁾), where n = log_circuit_size
Fr[CONST_PROOF_SIZE_LOG_N] memory powers_of_evaluation_challenge = computeSquares(tp.geminiR);

// Arrays hold values that will be linearly combined for the gemini and shplonk batch openings
Expand Down Expand Up @@ -1719,7 +1727,7 @@ contract HonkVerifier is IVerifier
mem.batchingChallenge = tp.shplonkNu.sqr();

for (uint256 i; i < CONST_PROOF_SIZE_LOG_N - 1; ++i) {
bool dummy_round = i >= (LOG_N - 1);
bool dummy_round = i >= (logN - 1);

Fr scalingFactor = Fr.wrap(0);
if (!dummy_round) {
Expand Down Expand Up @@ -1775,7 +1783,7 @@ contract HonkVerifier is IVerifier

for (uint256 i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) {
Fr round_inverted_denominator = Fr.wrap(0);
if (i <= LOG_N + 1) {
if (i <= logN + 1) {
round_inverted_denominator = (eval_challenge + eval_challenge_powers[i]).invert();
}
inverse_vanishing_evals[i + 1] = round_inverted_denominator;
Expand All @@ -1800,7 +1808,7 @@ contract HonkVerifier is IVerifier
// Divide by the denominator
batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (Fr.wrap(1) - u) + u).invert();

bool is_dummy_round = (i > LOG_N);
bool is_dummy_round = (i > logN);
if (!is_dummy_round) {
batchedEvalAccumulator = batchedEvalRoundAcc;
}
Expand Down Expand Up @@ -1874,16 +1882,11 @@ contract HonkVerifier is IVerifier
}
}

// Conversion util - Duplicated as we cannot template LOG_N
function convertPoints(Honk.G1ProofPoint[LOG_N + 1] memory commitments)
pure
returns (Honk.G1Point[LOG_N + 1] memory converted)
{
for (uint256 i; i < LOG_N + 1; ++i) {
converted[i] = convertProofPoint(commitments[i]);
contract HonkVerifier is BaseHonkVerifier(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) {
function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {
return HonkVerificationKey.loadVerificationKey();
}
}

)";

inline std::string get_honk_solidity_verifier(auto const& verification_key)
Expand Down
Loading
Loading