Skip to content

Commit

Permalink
Merge e4319de into e9e2318
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasxia01 authored Jul 29, 2024
2 parents e9e2318 + e4319de commit 6e0d675
Show file tree
Hide file tree
Showing 38 changed files with 212 additions and 152 deletions.
8 changes: 2 additions & 6 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,7 @@ void prove_tube(const std::string& output_path)

// 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.
std::array<uint32_t, acir_format::HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> current_aggregation_object = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
AggregationObjectIndices current_aggregation_object = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
fq x0("0x031e97a575e9d05a107acb64952ecab75c020998797da7842ab5d6d1986846cf");
fq y0("0x178cbf4206471d722669117f9758a4c410db10a01750aebb5666547acf8bd5a4");
fq x1("0x0f94656a2ca489889939f81e9c74027fd51009034b3357f0e91b8a11e7842c38");
Expand All @@ -609,9 +607,7 @@ void prove_tube(const std::string& output_path)
}
// 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);
builder->set_recursive_proof(current_aggregation_object);

info("num gates in tube circuit: ", builder->get_num_gates());
using Prover = UltraProver_<UltraFlavor>;
Expand Down
50 changes: 18 additions & 32 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,8 @@ void build_constraints(Builder& builder,
// TODO(maxim): input_aggregation_object to be non-zero.
// TODO(maxim): if not, we can add input_aggregation_object to the proof too for all recursive proofs
// TODO(maxim): This might be the case for proof trees where the proofs are created on different machines
std::array<uint32_t, RecursionConstraint::AGGREGATION_OBJECT_SIZE> current_input_aggregation_object = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
std::array<uint32_t, RecursionConstraint::AGGREGATION_OBJECT_SIZE> current_output_aggregation_object = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
AggregationObjectIndices current_input_aggregation_object = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
AggregationObjectIndices current_output_aggregation_object = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

// Get the size of proof with no public inputs prepended to it
// This is used while processing recursion constraints to determine whether
Expand All @@ -263,20 +259,19 @@ void build_constraints(Builder& builder,
// The user tells us they how they want these constants set by keeping the nested aggregation object
// attached to the proof as public inputs. As this is the only object that can prepended to the proof if the
// proof is above the expected size (with public inputs stripped)
std::array<uint32_t, RecursionConstraint::AGGREGATION_OBJECT_SIZE> nested_aggregation_object = {};
AggregationObjectPubInputIndices nested_aggregation_object = {};
// If the proof has public inputs attached to it, we should handle setting the nested aggregation object
if (constraint.proof.size() > proof_size_no_pub_inputs) {
// The public inputs attached to a proof should match the aggregation object in size
if (constraint.proof.size() - proof_size_no_pub_inputs !=
RecursionConstraint::AGGREGATION_OBJECT_SIZE) {
if (constraint.proof.size() - proof_size_no_pub_inputs != bb::AGGREGATION_OBJECT_SIZE) {
auto error_string = format(
"Public inputs are always stripped from proofs unless we have a recursive proof.\n"
"Thus, public inputs attached to a proof must match the recursive aggregation object in size "
"which is ",
RecursionConstraint::AGGREGATION_OBJECT_SIZE);
bb::AGGREGATION_OBJECT_SIZE);
throw_or_abort(error_string);
}
for (size_t i = 0; i < RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) {
for (size_t i = 0; i < bb::AGGREGATION_OBJECT_SIZE; ++i) {
// Set the nested aggregation object indices to the current size of the public inputs
// This way we know that the nested aggregation object indices will always be the last
// indices of the public inputs
Expand All @@ -289,7 +284,7 @@ void build_constraints(Builder& builder,
// in they way taht the recursion constraint expects
constraint.proof.erase(constraint.proof.begin(),
constraint.proof.begin() +
static_cast<std::ptrdiff_t>(RecursionConstraint::AGGREGATION_OBJECT_SIZE));
static_cast<std::ptrdiff_t>(bb::AGGREGATION_OBJECT_SIZE));
}

current_output_aggregation_object = create_recursion_constraints(builder,
Expand All @@ -315,9 +310,7 @@ void build_constraints(Builder& builder,

// Make sure the verification key records the public input indices of the
// final recursion output.
std::vector<uint32_t> proof_output_witness_indices(current_output_aggregation_object.begin(),
current_output_aggregation_object.end());
builder.set_recursive_proof(proof_output_witness_indices);
builder.set_recursive_proof(current_output_aggregation_object);
}
}

Expand All @@ -334,20 +327,17 @@ void build_constraints(Builder& builder,
// These should not be set by the caller
// TODO(https://github.com/AztecProtocol/barretenberg/issues/996): this usage of all zeros is a hack and could
// use types or enums to properly fix.
std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> current_aggregation_object = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
AggregationObjectIndices current_aggregation_object = {};

// Add recursion constraints

for (size_t i = 0; i < constraint_system.honk_recursion_constraints.size(); ++i) {
auto& constraint = constraint_system.honk_recursion_constraints.at(i);
// A proof passed into the constraint should be stripped of its inner public inputs, but not the
// nested aggregation object itself. The verifier circuit requires that the indices to a nested
// proof aggregation state are a circuit constant. The user tells us they how they want these
// 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 = {};
for (size_t i = 0; i < HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) {
// A proof passed into the constraint should be stripped of its inner public inputs, but not the nested
// aggregation object itself. The verifier circuit requires that the indices to a nested proof aggregation
// state are a circuit constant. The user tells us they how they want these constants set by keeping the
// nested aggregation object attached to the proof as public inputs.
AggregationObjectIndices nested_aggregation_object = {};
for (size_t i = 0; i < bb::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]);
Expand All @@ -359,7 +349,7 @@ void build_constraints(Builder& builder,
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));
bb::AGGREGATION_OBJECT_SIZE));
current_aggregation_object = create_honk_recursion_constraints(builder,
constraint,
current_aggregation_object,
Expand All @@ -382,9 +372,7 @@ void build_constraints(Builder& builder,

// 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);
builder.set_recursive_proof(current_aggregation_object);
} 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
Expand Down Expand Up @@ -414,9 +402,7 @@ void build_constraints(Builder& builder,
}
// 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);
builder.set_recursive_proof(current_aggregation_object);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "honk_recursion_constraint.hpp"
#include "barretenberg/flavor/flavor.hpp"
#include "barretenberg/plonk_honk_shared/types/aggregation_object_type.hpp"
#include "barretenberg/stdlib/honk_recursion/verifier/ultra_recursive_verifier.hpp"
#include "barretenberg/stdlib/plonk_recursion/aggregation_state/aggregation_state.hpp"
#include "barretenberg/stdlib/primitives/bigfield/constants.hpp"
Expand All @@ -14,8 +15,8 @@ using field_ct = stdlib::field_t<Builder>;
using bn254 = stdlib::bn254<Builder>;
using aggregation_state_ct = bb::stdlib::recursion::aggregation_state<bn254>;

std::array<bn254::Group, 2> agg_points_from_witness_indicies(
Builder& builder, const std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE>& obj_witness_indices)
std::array<bn254::Group, 2> agg_points_from_witness_indicies(Builder& builder,
const AggregationObjectIndices& obj_witness_indices)
{
std::array<bn254::BaseField, 4> aggregation_elements;
for (size_t i = 0; i < 4; ++i) {
Expand Down Expand Up @@ -44,12 +45,11 @@ std::array<bn254::Group, 2> agg_points_from_witness_indicies(
* We would either need a separate ACIR opcode where inner_proof_contains_recursive_proof = true,
* or we need non-witness data to be provided as metadata in the ACIR opcode
*/
std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> create_honk_recursion_constraints(
Builder& builder,
const HonkRecursionConstraint& input,
std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> input_aggregation_object,
std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> nested_aggregation_object,
bool has_valid_witness_assignments)
AggregationObjectIndices create_honk_recursion_constraints(Builder& builder,
const HonkRecursionConstraint& input,
AggregationObjectIndices input_aggregation_object,
AggregationObjectIndices nested_aggregation_object,
bool has_valid_witness_assignments)
{
using Flavor = UltraRecursiveFlavor_<Builder>;
using RecursiveVerificationKey = Flavor::VerificationKey;
Expand Down Expand Up @@ -139,7 +139,13 @@ std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> create_ho
builder.assert_equal(builder.add_variable(1 << log_circuit_size), key_fields[0].witness_index);
builder.assert_equal(builder.add_variable(input.public_inputs.size()), key_fields[1].witness_index);
builder.assert_equal(builder.add_variable(UltraFlavor::has_zero_row ? 1 : 0), key_fields[2].witness_index);
uint32_t offset = 3;
builder.assert_equal(builder.add_variable(0), key_fields[4].witness_index);
uint32_t offset = 4;
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1059): Properly set this to a default agg obj.
for (size_t i = 0; i < bb::AGGREGATION_OBJECT_SIZE; i++) {
builder.assert_equal(builder.add_variable(0), key_fields[offset].witness_index);
offset++;
}

for (size_t i = 0; i < Flavor::NUM_PRECOMPUTED_ENTITIES; ++i) {
auto comm = curve::BN254::AffineElement::one() * fr::random_element();
Expand Down Expand Up @@ -220,7 +226,7 @@ std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> create_ho
cur_aggregation_object.P0 = pairing_points[0]; // * recursion_separator;
cur_aggregation_object.P1 = pairing_points[1]; // * recursion_separator;

std::vector<uint32_t> proof_witness_indices = {
AggregationObjectIndices proof_witness_indices = {
cur_aggregation_object.P0.x.binary_basis_limbs[0].element.normalize().witness_index,
cur_aggregation_object.P0.x.binary_basis_limbs[1].element.normalize().witness_index,
cur_aggregation_object.P0.x.binary_basis_limbs[2].element.normalize().witness_index,
Expand All @@ -244,14 +250,8 @@ std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> create_ho
// TODO(https://github.com/AztecProtocol/barretenberg/issues/996): investigate whether assert_equal on public inputs
// is important, like what the plonk recursion constraint does.

// We want to return an array, so just copy the vector into the array
ASSERT(result.proof_witness_indices.size() == HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE);
std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> resulting_output_aggregation_object;
std::copy(result.proof_witness_indices.begin(),
result.proof_witness_indices.begin() + HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE,
resulting_output_aggregation_object.begin());

return resulting_output_aggregation_object;
ASSERT(result.proof_witness_indices.size() == bb::AGGREGATION_OBJECT_SIZE);
return result.proof_witness_indices;
}

} // namespace acir_format
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,17 @@ struct HonkRecursionConstraint {
// In Honk, the proof starts with circuit_size, num_public_inputs, and pub_input_offset. We use this offset to keep
// track of where the public inputs start.
static constexpr size_t inner_public_input_offset = 3;
// An aggregation state is represented by two G1 affine elements. Each G1 point has
// two field element coordinates (x, y). Thus, four field elements
static constexpr size_t NUM_AGGREGATION_ELEMENTS = 4;
// Four limbs are used when simulating a non-native field using the bigfield class
static constexpr size_t AGGREGATION_OBJECT_SIZE = NUM_AGGREGATION_ELEMENTS * fq_ct::NUM_LIMBS; // 16 field elements
std::vector<uint32_t> key;
std::vector<uint32_t> proof;
std::vector<uint32_t> public_inputs;

friend bool operator==(HonkRecursionConstraint const& lhs, HonkRecursionConstraint const& rhs) = default;
};

std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> create_honk_recursion_constraints(
Builder& builder,
const HonkRecursionConstraint& input,
std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> input_aggregation_object,
std::array<uint32_t, HonkRecursionConstraint::AGGREGATION_OBJECT_SIZE> nested_aggregation_object,
bool has_valid_witness_assignments = false);
AggregationObjectIndices create_honk_recursion_constraints(Builder& builder,
const HonkRecursionConstraint& input,
AggregationObjectIndices input_aggregation_object,
AggregationObjectIndices nested_aggregation_object,
bool has_valid_witness_assignments = false);

} // namespace acir_format
Loading

0 comments on commit 6e0d675

Please sign in to comment.