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

feat: adding aggregation to honk and rollup #7466

Merged
merged 10 commits into from
Jul 25, 2024
108 changes: 52 additions & 56 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,20 +348,19 @@ void build_constraints(Builder& builder,
// constants set by keeping the nested aggregation object attached to the proof as public inputs.
std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> nested_aggregation_object = {};
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1044): Reinstate aggregation
// for (size_t i = 0; i < HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) {
// // Set the nested aggregation object indices to witness indices from the proof
// nested_aggregation_object[i] =
// static_cast<uint32_t>(constraint.proof[HonkRecursionConstraint::inner_public_input_offset + i]);
// // Adding the nested aggregation object to the constraint's public inputs
// constraint.public_inputs.emplace_back(nested_aggregation_object[i]);
// }
for (size_t i = 0; i < HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) {
// Set the nested aggregation object indices to witness indices from the proof
nested_aggregation_object[i] =
static_cast<uint32_t>(constraint.proof[HonkRecursionConstraint::inner_public_input_offset + i]);
// Adding the nested aggregation object to the constraint's public inputs
constraint.public_inputs.emplace_back(nested_aggregation_object[i]);
}
// Remove the aggregation object so that they can be handled as normal public inputs
// in they way that the recursion constraint expects
// constraint.proof.erase(constraint.proof.begin() + HonkRecursionConstraint::inner_public_input_offset,
// constraint.proof.begin() +
// static_cast<std::ptrdiff_t>(HonkRecursionConstraint::inner_public_input_offset
// +
// HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE));
constraint.proof.erase(constraint.proof.begin() + HonkRecursionConstraint::inner_public_input_offset,
constraint.proof.begin() +
static_cast<std::ptrdiff_t>(HonkRecursionConstraint::inner_public_input_offset +
HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE));
current_aggregation_object = create_honk_recursion_constraints(builder,
constraint,
current_aggregation_object,
Expand All @@ -379,51 +378,48 @@ void build_constraints(Builder& builder,
// Set the indices as public inputs because they are no longer being
// created in ACIR
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1044): Reinstate aggregation
// for (const auto& idx : current_aggregation_object) {
// builder.set_public_input(idx);
// }

// // Make sure the verification key records the public input indices of the
// // final recursion output.
// std::vector<uint32_t> proof_output_witness_indices(current_aggregation_object.begin(),
// current_aggregation_object.end());
// builder.set_recursive_proof(proof_output_witness_indices);
for (const auto& idx : current_aggregation_object) {
builder.set_public_input(idx);
}

// Make sure the verification key records the public input indices of the
// final recursion output.
std::vector<uint32_t> proof_output_witness_indices(current_aggregation_object.begin(),
current_aggregation_object.end());
builder.set_recursive_proof(proof_output_witness_indices);
} else if (honk_recursion &&
builder.is_recursive_circuit) { // Set a default aggregation object if we don't have one.
// TODO(https://github.com/AztecProtocol/barretenberg/issues/911): These are pairing points extracted
// from a valid proof. This is a workaround because we can't represent the point at infinity in biggroup
// yet.
fq x0("0x031e97a575e9d05a107acb64952ecab75c020998797da7842ab5d6d1986846cf");
fq y0("0x178cbf4206471d722669117f9758a4c410db10a01750aebb5666547acf8bd5a4");

fq x1("0x0f94656a2ca489889939f81e9c74027fd51009034b3357f0e91b8a11e7842c38");
fq y1("0x1b52c2020d7464a0c80c0da527a08193fe27776f50224bd6fb128b46c1ddb67f");
std::vector<fq> aggregation_object_fq_values = { x0, y0, x1, y1 };
size_t agg_obj_indices_idx = 0;
for (fq val : aggregation_object_fq_values) {
const uint256_t x = val;
std::array<fr, fq_ct::NUM_LIMBS> val_limbs = {
x.slice(0, fq_ct::NUM_LIMB_BITS),
x.slice(fq_ct::NUM_LIMB_BITS, fq_ct::NUM_LIMB_BITS * 2),
x.slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 3),
x.slice(fq_ct::NUM_LIMB_BITS * 3, stdlib::field_conversion::TOTAL_BITS)
};
for (size_t i = 0; i < fq_ct::NUM_LIMBS; ++i) {
uint32_t idx = builder.add_variable(val_limbs[i]);
builder.set_public_input(idx);
current_aggregation_object[agg_obj_indices_idx] = idx;
agg_obj_indices_idx++;
}
}
// Make sure the verification key records the public input indices of the
// final recursion output.
std::vector<uint32_t> proof_output_witness_indices(current_aggregation_object.begin(),
current_aggregation_object.end());
builder.set_recursive_proof(proof_output_witness_indices);
}
static_cast<void>(honk_recursion);
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1044): Reinstate aggregation
// else if (honk_recursion &&
// builder.is_recursive_circuit) { // Set a default aggregation object if we don't have one.
// // TODO(https://github.com/AztecProtocol/barretenberg/issues/911): These are pairing points extracted
// from
// // a valid proof. This is a workaround because we can't represent the point at infinity in biggroup
// yet. fq x0("0x031e97a575e9d05a107acb64952ecab75c020998797da7842ab5d6d1986846cf"); fq
// y0("0x178cbf4206471d722669117f9758a4c410db10a01750aebb5666547acf8bd5a4");

// fq x1("0x0f94656a2ca489889939f81e9c74027fd51009034b3357f0e91b8a11e7842c38");
// fq y1("0x1b52c2020d7464a0c80c0da527a08193fe27776f50224bd6fb128b46c1ddb67f");
// std::vector<fq> aggregation_object_fq_values = { x0, y0, x1, y1 };
// size_t agg_obj_indices_idx = 0;
// for (fq val : aggregation_object_fq_values) {
// const uint256_t x = val;
// std::array<fr, fq_ct::NUM_LIMBS> val_limbs = {
// x.slice(0, fq_ct::NUM_LIMB_BITS),
// x.slice(fq_ct::NUM_LIMB_BITS, fq_ct::NUM_LIMB_BITS * 2),
// x.slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 3),
// x.slice(fq_ct::NUM_LIMB_BITS * 3, stdlib::field_conversion::TOTAL_BITS)
// };
// for (size_t i = 0; i < fq_ct::NUM_LIMBS; ++i) {
// uint32_t idx = builder.add_variable(val_limbs[i]);
// builder.set_public_input(idx);
// current_aggregation_object[agg_obj_indices_idx] = idx;
// agg_obj_indices_idx++;
// }
// }
// // Make sure the verification key records the public input indices of the
// // final recursion output.
// std::vector<uint32_t> proof_output_witness_indices(current_aggregation_object.begin(),
// current_aggregation_object.end());
// builder.set_recursive_proof(proof_output_witness_indices);
// }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,15 @@ class AcirHonkRecursionConstraint : public ::testing::Test {
std::vector<fr> inner_public_input_values(
proof_witnesses.begin() + static_cast<std::ptrdiff_t>(inner_public_input_offset),
proof_witnesses.begin() +
static_cast<std::ptrdiff_t>(inner_public_input_offset + num_inner_public_inputs));
static_cast<std::ptrdiff_t>(inner_public_input_offset + num_inner_public_inputs -
RecursionConstraint::AGGREGATION_OBJECT_SIZE));

// We want to make sure that we do not remove the nested aggregation object.
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1044): Reinstate aggregation
proof_witnesses.erase(proof_witnesses.begin() + static_cast<std::ptrdiff_t>(inner_public_input_offset),
proof_witnesses.begin() +
static_cast<std::ptrdiff_t>(inner_public_input_offset + num_inner_public_inputs));
static_cast<std::ptrdiff_t>(inner_public_input_offset + num_inner_public_inputs -
RecursionConstraint::AGGREGATION_OBJECT_SIZE));

std::vector<bb::fr> key_witnesses = verification_key->to_field_elements();

Expand All @@ -179,9 +181,9 @@ class AcirHonkRecursionConstraint : public ::testing::Test {
const uint32_t public_input_start_idx =
static_cast<uint32_t>(inner_public_input_offset + witness_offset); // points to public_input_0
const uint32_t proof_indices_start_idx =
static_cast<uint32_t>(public_input_start_idx + num_inner_public_inputs);
static_cast<uint32_t>(public_input_start_idx + num_inner_public_inputs -
RecursionConstraint::AGGREGATION_OBJECT_SIZE); // points to agg_obj_0
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1044): Reinstate aggregation
// - RecursionConstraint::AGGREGATION_OBJECT_SIZE); // points to agg_obj_0
const uint32_t key_indices_start_idx =
static_cast<uint32_t>(proof_indices_start_idx + proof_witnesses.size() -
inner_public_input_offset); // would point to vkey_3 without the -
Expand All @@ -205,7 +207,7 @@ class AcirHonkRecursionConstraint : public ::testing::Test {
// thus we do not explicitly have to keep the public inputs while setting up the initial recursion
// constraint. They will later be attached as public inputs when creating the circuit.
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1044): Reinstate aggregation
for (size_t i = 0; i < num_inner_public_inputs; ++i) {
for (size_t i = 0; i < num_inner_public_inputs - RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) {
inner_public_inputs.push_back(static_cast<uint32_t>(i + public_input_start_idx));
}

Expand Down Expand Up @@ -245,7 +247,7 @@ class AcirHonkRecursionConstraint : public ::testing::Test {
// We once again have to check whether we have a nested proof, because if we do have one
// then we could get a segmentation fault as `inner_public_inputs` was never filled with values.
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1044): Reinstate aggregation
for (size_t i = 0; i < num_inner_public_inputs; ++i) {
for (size_t i = 0; i < num_inner_public_inputs - RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) {
witness[inner_public_inputs[i]] = inner_public_input_values[i];
}

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

// This circuit aggregates a single Honk proof from `assert_statement_recursive`.
global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 393;
global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 409;
fn main(
verification_key: [Field; 103],
// This is the proof without public inputs attached.
Expand Down
2 changes: 1 addition & 1 deletion noir/verify_honk_proof/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

// This circuit aggregates a single Honk proof from `assert_statement_recursive`.
global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 393;
global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 409;
fn main(
verification_key: [Field; 103],
// This is the proof without public inputs attached.
Expand Down
Loading