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: clean up proof lengths and IPA #11020

Merged
merged 13 commits into from
Jan 6, 2025
24 changes: 11 additions & 13 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@ void prove_tube(const std::string& output_path)
// circuit
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1048): INSECURE - make this tube proof actually use
// these public inputs by turning proof into witnesses and calling set_public on each witness
auto num_public_inputs = static_cast<uint32_t>(static_cast<uint256_t>(proof.mega_proof[1]));
num_public_inputs -= bb::PAIRING_POINT_ACCUMULATOR_SIZE; // don't add the agg object
auto num_inner_public_inputs = static_cast<uint32_t>(static_cast<uint256_t>(proof.mega_proof[1]));
num_inner_public_inputs -= bb::PAIRING_POINT_ACCUMULATOR_SIZE; // don't add the agg object

for (size_t i = 0; i < num_public_inputs; i++) {
for (size_t i = 0; i < num_inner_public_inputs; i++) {
auto offset = bb::HONK_PROOF_PUBLIC_INPUT_OFFSET;
builder->add_public_variable(proof.mega_proof[i + offset]);
}
Expand Down Expand Up @@ -278,13 +278,13 @@ void prove_tube(const std::string& output_path)
Verifier tube_verifier(tube_verification_key, ipa_verification_key);

// Break up the tube proof into the honk portion and the ipa portion
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1168): Add formula to flavor
const size_t HONK_PROOF_LENGTH = 469;
const size_t HONK_PROOF_LENGTH_WITHOUT_INNER_PUB_INPUTS =
UltraRollupFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS + PAIRING_POINT_ACCUMULATOR_SIZE + IPA_CLAIM_SIZE;
// The extra calculation is for the IPA proof length.
ASSERT(tube_proof.size() == HONK_PROOF_LENGTH + 1 + 4 * (CONST_ECCVM_LOG_N) + 2 + 2 + num_public_inputs);
ASSERT(tube_proof.size() == HONK_PROOF_LENGTH_WITHOUT_INNER_PUB_INPUTS + num_inner_public_inputs);
// split out the ipa proof
const std::ptrdiff_t honk_proof_with_pub_inputs_length =
static_cast<std::ptrdiff_t>(HONK_PROOF_LENGTH + num_public_inputs);
const std::ptrdiff_t honk_proof_with_pub_inputs_length = static_cast<std::ptrdiff_t>(
HONK_PROOF_LENGTH_WITHOUT_INNER_PUB_INPUTS - IPA_PROOF_LENGTH + num_inner_public_inputs);
auto ipa_proof = HonkProof(tube_proof.begin() + honk_proof_with_pub_inputs_length, tube_proof.end());
auto tube_honk_proof = HonkProof(tube_proof.begin(), tube_proof.end() + honk_proof_with_pub_inputs_length);
bool verified = tube_verifier.verify_proof(tube_honk_proof, ipa_proof);
Expand Down Expand Up @@ -895,15 +895,13 @@ template <IsUltraFlavor Flavor> bool verify_honk(const std::string& proof_path,
bool verified;
if constexpr (HasIPAAccumulator<Flavor>) {
// Break up the tube proof into the honk portion and the ipa portion
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1168): Add formula to flavor
const size_t HONK_PROOF_LENGTH = 469;
const size_t num_public_inputs =
static_cast<size_t>(uint64_t(proof[1])) - PAIRING_POINT_ACCUMULATOR_SIZE - IPA_CLAIM_SIZE;
const size_t HONK_PROOF_LENGTH = Flavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS - IPA_PROOF_LENGTH;
const size_t num_public_inputs = static_cast<size_t>(uint64_t(proof[1]));
// The extra calculation is for the IPA proof length.
debug("proof size: ", proof.size());
debug("num public inputs: ", num_public_inputs);
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1182): Move to ProofSurgeon.
ASSERT(proof.size() == HONK_PROOF_LENGTH + 1 + 4 * (CONST_ECCVM_LOG_N) + 2 + 2 + num_public_inputs);
ASSERT(proof.size() == HONK_PROOF_LENGTH + IPA_PROOF_LENGTH + num_public_inputs);
// split out the ipa proof
const std::ptrdiff_t honk_proof_with_pub_inputs_length =
static_cast<std::ptrdiff_t>(HONK_PROOF_LENGTH + num_public_inputs);
Expand Down
30 changes: 30 additions & 0 deletions barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
#include "barretenberg/common/container.hpp"
#include "barretenberg/common/thread.hpp"
#include "barretenberg/common/throw_or_abort.hpp"
#include "barretenberg/constants.hpp"
#include "barretenberg/ecc/scalar_multiplication/scalar_multiplication.hpp"
#include "barretenberg/stdlib/hash/poseidon2/poseidon2.hpp"
#include "barretenberg/stdlib/honk_verifier/ipa_accumulator.hpp"
#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp"
#include "barretenberg/stdlib/transcript/transcript.hpp"
#include "barretenberg/transcript/transcript.hpp"
#include <cstddef>
Expand All @@ -20,6 +22,8 @@
namespace bb {
// clang-format off

constexpr size_t IPA_PROOF_LENGTH = 1 + 4 * CONST_ECCVM_LOG_N + 2 + 2;

/**
* @brief IPA (inner product argument) commitment scheme class.
*
Expand Down Expand Up @@ -949,6 +953,32 @@ template <typename Curve_> class IPA {
output_claim.opening_pair.evaluation.self_reduce();
return {output_claim, prover_transcript->proof_data};
}

static std::pair<OpeningClaim<Curve>, HonkProof> create_fake_ipa_claim_and_proof(UltraCircuitBuilder& builder)
requires Curve::is_stdlib_type {
using NativeCurve = curve::Grumpkin;
using Builder = typename Curve::Builder;
using Curve = stdlib::grumpkin<Builder>;
auto ipa_transcript = std::make_shared<NativeTranscript>();
auto ipa_commitment_key = std::make_shared<CommitmentKey<NativeCurve>>(1 << CONST_ECCVM_LOG_N);
size_t n = 4;
auto poly = Polynomial<fq>(n);
for (size_t i = 0; i < n; i++) {
poly.at(i) = fq::random_element();
}
fq x = fq::random_element();
fq eval = poly.evaluate(x);
auto commitment = ipa_commitment_key->commit(poly);
const OpeningPair<NativeCurve> opening_pair = { x, eval };
IPA<NativeCurve>::compute_opening_proof(ipa_commitment_key, { poly, opening_pair }, ipa_transcript);

auto stdlib_comm = Curve::Group::from_witness(&builder, commitment);
auto stdlib_x = Curve::ScalarField::from_witness(&builder, x);
auto stdlib_eval = Curve::ScalarField::from_witness(&builder, eval);
OpeningClaim<Curve> stdlib_opening_claim{ { stdlib_x, stdlib_eval }, stdlib_comm };

return {stdlib_opening_claim, ipa_transcript->export_proof()};
}
};

} // namespace bb
26 changes: 4 additions & 22 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,31 +439,13 @@ HonkRecursionConstraintsOutput<Builder> process_honk_recursion_constraints(
} else if (nested_ipa_claims.size() > 2) {
throw_or_abort("Too many nested IPA claims to accumulate");
} else {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1184): Move to IPA class.
if (honk_recursion == 2) {
info("Proving with UltraRollupHonk but no IPA claims exist.");
// just create some fake IPA claim and proof
using NativeCurve = curve::Grumpkin;
using Curve = stdlib::grumpkin<Builder>;
auto ipa_transcript = std::make_shared<NativeTranscript>();
auto ipa_commitment_key = std::make_shared<CommitmentKey<NativeCurve>>(1 << CONST_ECCVM_LOG_N);
size_t n = 4;
auto poly = Polynomial<fq>(n);
for (size_t i = 0; i < n; i++) {
poly.at(i) = fq::random_element();
}
fq x = fq::random_element();
fq eval = poly.evaluate(x);
auto commitment = ipa_commitment_key->commit(poly);
const OpeningPair<NativeCurve> opening_pair = { x, eval };
IPA<NativeCurve>::compute_opening_proof(ipa_commitment_key, { poly, opening_pair }, ipa_transcript);

auto stdlib_comm = Curve::Group::from_witness(&builder, commitment);
auto stdlib_x = Curve::ScalarField::from_witness(&builder, x);
auto stdlib_eval = Curve::ScalarField::from_witness(&builder, eval);
OpeningClaim<Curve> stdlib_opening_claim{ { stdlib_x, stdlib_eval }, stdlib_comm };
auto [stdlib_opening_claim, ipa_proof] =
IPA<stdlib::grumpkin<Builder>>::create_fake_ipa_claim_and_proof(builder);

output.ipa_claim = stdlib_opening_claim;
output.ipa_proof = ipa_transcript->export_proof();
output.ipa_proof = ipa_proof;
}
}
output.agg_obj_indices = current_aggregation_object;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,9 @@ void create_dummy_vkey_and_proof(Builder& builder,
const std::vector<field_ct>& proof_fields)
{
// Set vkey->circuit_size correctly based on the proof size
size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs<typename Flavor::Commitment>();
size_t num_frs_fr = bb::field_conversion::calc_num_bn254_frs<typename Flavor::FF>();
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1168): Add formula to flavor
assert((proof_size - bb::HONK_PROOF_PUBLIC_INPUT_OFFSET - Flavor::NUM_WITNESS_ENTITIES * num_frs_comm -
Flavor::NUM_ALL_ENTITIES * num_frs_fr - num_frs_comm) %
(num_frs_comm + num_frs_fr * (Flavor::BATCHED_RELATION_PARTIAL_LENGTH + 1)) ==
0);
ASSERT(proof_size == Flavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS);
// Note: this computation should always result in log_circuit_size = CONST_PROOF_SIZE_LOG_N
auto log_circuit_size =
(proof_size - bb::HONK_PROOF_PUBLIC_INPUT_OFFSET - Flavor::NUM_WITNESS_ENTITIES * num_frs_comm -
Flavor::NUM_ALL_ENTITIES * num_frs_fr - num_frs_comm) /
(num_frs_comm + num_frs_fr * (Flavor::BATCHED_RELATION_PARTIAL_LENGTH + 1));
auto log_circuit_size = CONST_PROOF_SIZE_LOG_N;
// First key field is circuit size
builder.assert_equal(builder.add_variable(1 << log_circuit_size), key_fields[0].witness_index);
// Second key field is number of public inputs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,14 @@ UltraRecursiveVerifier_<Flavor>::Output UltraRecursiveVerifier_<Flavor>::verify_
Output output;
StdlibProof<Builder> honk_proof;
if constexpr (HasIPAAccumulator<Flavor>) {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1168): Add formula to flavor
const size_t HONK_PROOF_LENGTH = 469;
const size_t HONK_PROOF_LENGTH = Flavor::NativeFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS - IPA_PROOF_LENGTH;
const size_t num_public_inputs = static_cast<uint32_t>(proof[1].get_value());
// The extra calculation is for the IPA proof length.
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1182): Handle in ProofSurgeon.
ASSERT(proof.size() == HONK_PROOF_LENGTH + (1 + 4 * (CONST_ECCVM_LOG_N) + 2 + 2) + num_public_inputs -
(PAIRING_POINT_ACCUMULATOR_SIZE + IPA_CLAIM_SIZE));
ASSERT(proof.size() == HONK_PROOF_LENGTH + IPA_PROOF_LENGTH + num_public_inputs);
// split out the ipa proof
const std::ptrdiff_t honk_proof_with_pub_inputs_length = static_cast<std::ptrdiff_t>(
HONK_PROOF_LENGTH + num_public_inputs - (PAIRING_POINT_ACCUMULATOR_SIZE + IPA_CLAIM_SIZE));
const std::ptrdiff_t honk_proof_with_pub_inputs_length =
static_cast<std::ptrdiff_t>(HONK_PROOF_LENGTH + num_public_inputs);
output.ipa_proof = StdlibProof<Builder>(proof.begin() + honk_proof_with_pub_inputs_length, proof.end());
honk_proof = StdlibProof<Builder>(proof.begin(), proof.end() + honk_proof_with_pub_inputs_length);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,29 +77,11 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing
PairingPointAccumulatorIndices agg_obj_indices = stdlib::recursion::init_default_agg_obj_indices(builder);
builder.add_pairing_point_accumulator(agg_obj_indices);

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1184): Move to IPA class.
if constexpr (HasIPAAccumulator<RecursiveFlavor>) {
using NativeCurve = curve::Grumpkin;
using Curve = stdlib::grumpkin<InnerBuilder>;
auto ipa_transcript = std::make_shared<NativeTranscript>();
auto ipa_commitment_key = std::make_shared<CommitmentKey<NativeCurve>>(1 << CONST_ECCVM_LOG_N);
size_t n = 4;
auto poly = Polynomial<fq>(n);
for (size_t i = 0; i < n; i++) {
poly.at(i) = fq::random_element();
}
fq x = fq::random_element();
fq eval = poly.evaluate(x);
auto commitment = ipa_commitment_key->commit(poly);
const OpeningPair<NativeCurve> opening_pair = { x, eval };
IPA<NativeCurve>::compute_opening_proof(ipa_commitment_key, { poly, opening_pair }, ipa_transcript);

auto stdlib_comm = Curve::Group::from_witness(&builder, commitment);
auto stdlib_x = Curve::ScalarField::from_witness(&builder, x);
auto stdlib_eval = Curve::ScalarField::from_witness(&builder, eval);
OpeningClaim<Curve> stdlib_opening_claim{ { stdlib_x, stdlib_eval }, stdlib_comm };
auto [stdlib_opening_claim, ipa_proof] =
IPA<grumpkin<InnerBuilder>>::create_fake_ipa_claim_and_proof(builder);
builder.add_ipa_claim(stdlib_opening_claim.get_witness_indices());
builder.ipa_proof = ipa_transcript->export_proof();
builder.ipa_proof = ipa_proof;
}
return builder;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ class UltraFlavor {
// Note: made generic for use in MegaRecursive.
template <typename FF>

// List of relations reflecting the Ultra arithmetisation. WARNING: As UltraKeccak flavor inherits from Ultra flavor
// any change of ordering in this tuple needs to be reflected in the smart contract, otherwise relation accumulation
// will not match.
// List of relations reflecting the Ultra arithmetisation. WARNING: As UltraKeccak flavor inherits from
// Ultra flavor any change of ordering in this tuple needs to be reflected in the smart contract, otherwise
// relation accumulation will not match.
using Relations_ = std::tuple<bb::UltraArithmeticRelation<FF>,
bb::UltraPermutationRelation<FF>,
bb::LogDerivLookupRelation<FF>,
Expand Down Expand Up @@ -97,6 +97,22 @@ class UltraFlavor {
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1;
static constexpr size_t NUM_RELATIONS = std::tuple_size_v<Relations>;

// Proof length formula:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update comment

// 1. HONK_PROOF_PUBLIC_INPUT_OFFSET are the circuit_size, num_public_inputs, pub_inputs_offset
// 2. PAIRING_POINT_ACCUMULATOR_SIZE public inputs for pairing point accumulator
// 3. NUM_WITNESS_ENTITIES commitments
// 4. CONST_PROOF_SIZE_LOG_N sumcheck univariates
// 5. NUM_ALL_ENTITIES sumcheck evaluations
// 6. CONST_PROOF_SIZE_LOG_N Gemini Fold commitments
// 7. CONST_PROOF_SIZE_LOG_N Gemini a evaluations
// 8. KZG W commitment
static constexpr size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs<Commitment>();
static constexpr size_t num_frs_fr = bb::field_conversion::calc_num_bn254_frs<FF>();
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS =
HONK_PROOF_PUBLIC_INPUT_OFFSET + NUM_WITNESS_ENTITIES * num_frs_comm +
CONST_PROOF_SIZE_LOG_N * BATCHED_RELATION_PARTIAL_LENGTH * num_frs_fr + NUM_ALL_ENTITIES * num_frs_fr +
CONST_PROOF_SIZE_LOG_N * num_frs_comm + CONST_PROOF_SIZE_LOG_N * num_frs_fr + num_frs_comm;

template <size_t NUM_KEYS>
using ProtogalaxyTupleOfTuplesOfUnivariatesNoOptimisticSkipping =
decltype(create_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_KEYS>());
Expand Down Expand Up @@ -537,7 +553,6 @@ class UltraFlavor {
* @brief A container for storing the partially evaluated multivariates produced by sumcheck.
*/
class PartiallyEvaluatedMultivariates : public AllEntities<Polynomial> {

public:
PartiallyEvaluatedMultivariates() = default;
PartiallyEvaluatedMultivariates(const size_t circuit_size)
Expand Down Expand Up @@ -675,7 +690,7 @@ class UltraFlavor {
this->z_perm = commitments.z_perm;
}
}
};
}; // namespace bb
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete

// Specialize for Ultra (general case used in UltraRecursive).
using VerifierCommitments = VerifierCommitments_<Commitment, VerificationKey>;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
#pragma once
#include "barretenberg/commitment_schemes/ipa/ipa.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp"

namespace bb {

class UltraRollupFlavor : public bb::UltraFlavor {
public:
// Proof length formula:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update comment

// 1. HONK_PROOF_PUBLIC_INPUT_OFFSET are the circuit_size, num_public_inputs, pub_inputs_offset
// 2. PAIRING_POINT_ACCUMULATOR_SIZE public inputs for pairing point accumulator
// 3. IPA_CLAIM_SIZE public inputs for IPA claim
// 4. NUM_WITNESS_ENTITIES commitments
// 5. CONST_PROOF_SIZE_LOG_N sumcheck univariates
// 6. NUM_ALL_ENTITIES sumcheck evaluations
// 7. CONST_PROOF_SIZE_LOG_N Gemini Fold commitments
// 8. CONST_PROOF_SIZE_LOG_N Gemini a evaluations
// 9. KZG W commitment
static constexpr size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs<Commitment>();
static constexpr size_t num_frs_fr = bb::field_conversion::calc_num_bn254_frs<FF>();
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS =
UltraFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS + IPA_PROOF_LENGTH;

using UltraFlavor::UltraFlavor;
class ProvingKey : public UltraFlavor::ProvingKey {
public:
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
barretenberg_module(ultra_honk sumcheck)
barretenberg_module(ultra_honk sumcheck stdlib_primitives)
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ template <IsUltraFlavor Flavor> HonkProof UltraProver_<Flavor>::export_proof()
// Add the IPA proof
if constexpr (HasIPAAccumulator<Flavor>) {
// The extra calculation is for the IPA proof length.
ASSERT(proving_key->proving_key.ipa_proof.size() == 1 + 4 * (CONST_ECCVM_LOG_N) + 2 + 2);
ASSERT(proving_key->proving_key.ipa_proof.size() == IPA_PROOF_LENGTH);
proof.insert(proof.end(), proving_key->proving_key.ipa_proof.begin(), proving_key->proving_key.ipa_proof.end());
}
return proof;
Expand Down
Loading
Loading