Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
05847c1
use one agg object in build_constraints
vezenovm Apr 25, 2024
b30c253
initial work to remove difference in proof sizes for non-nested proof…
vezenovm Apr 26, 2024
652c118
failed hacky fix -> we want a biggroup pt at infty to make this worm
lucasxia01 Apr 26, 2024
f988543
hardcode valid aggregation object
lucasxia01 May 2, 2024
1e11019
Merge remote-tracking branch 'origin/master' into mv/simplify-non-nes…
lucasxia01 May 2, 2024
259b2fb
fixed, negate the rhs element
lucasxia01 May 3, 2024
fe73f8b
Merge branch 'master' into mv/simplify-non-nested-proofs-dsl
lucasxia01 May 3, 2024
d3824bb
Merge branch 'master' into mv/simplify-non-nested-proofs-dsl
lucasxia01 May 8, 2024
0fae0ae
Merge remote-tracking branch 'origin/master' into mv/simplify-non-nes…
lucasxia01 May 9, 2024
50c749e
new recursion constraint hpp for honk
lucasxia01 May 9, 2024
6eae187
added check to make sure that proof always contains aggregation objec…
lucasxia01 May 9, 2024
cff0072
Merge branch 'master' into mv/simplify-non-nested-proofs-dsl
lucasxia01 May 9, 2024
13ce677
new function for converting verification key to bb::fr elements
lucasxia01 May 10, 2024
c0d5c76
minor update to conversions to allow uint64_t
lucasxia01 May 13, 2024
43503c7
added new verify function that takes in stdlib proof
lucasxia01 May 13, 2024
c86cbae
new deserialization from field_ct elements to VerificationKey
lucasxia01 May 13, 2024
4cf389b
Merge branch 'master' into mv/simplify-non-nested-proofs-dsl
lucasxia01 May 13, 2024
59e8ea6
build works
lucasxia01 May 14, 2024
86fef82
modified rebuild script to skip missing directories and print out fai…
lucasxia01 May 14, 2024
c317131
Merge branch 'mv/simplify-non-nested-proofs-dsl' into lx/honk-recursi…
lucasxia01 May 14, 2024
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
7 changes: 7 additions & 0 deletions barretenberg/acir_tests/reset_acir_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cd ~/aztec-packages/noir/noir-repo
cargo clean
noirup -p .
cd test_programs && ./rebuild.sh

cd ~/aztec-packages/barretenberg/acir_tests
rm -rf acir_tests
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ bool proveAndVerify(const std::string& bytecodePath, const std::string& witnessP
auto witness = get_witness(witnessPath);

acir_proofs::AcirComposer acir_composer{ 0, verbose };
// init_bn254_crs(acir_composer.get_dyadic_circuit_size());
acir_composer.create_circuit(constraint_system, witness);

init_bn254_crs(acir_composer.get_dyadic_circuit_size());

Timer pk_timer;
Expand Down
119 changes: 105 additions & 14 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "acir_format.hpp"
#include "barretenberg/common/log.hpp"
#include "barretenberg/ecc/fields/field_conversion.hpp"
#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp"
#include "barretenberg/stdlib/primitives/field/field_conversion.hpp"
#include "barretenberg/stdlib_circuit_builders/goblin_ultra_circuit_builder.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp"
#include <cstddef>
Expand Down Expand Up @@ -132,10 +135,7 @@ void build_constraints(Builder& builder, AcirFormat const& constraint_system, bo
// 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 = {
std::array<uint32_t, RecursionConstraint::AGGREGATION_OBJECT_SIZE> current_aggregation_object = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

Expand All @@ -155,14 +155,18 @@ void build_constraints(Builder& builder, AcirFormat const& constraint_system, bo
std::array<uint32_t, RecursionConstraint::AGGREGATION_OBJECT_SIZE> 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) {
info("constraint.proof.size(): ", constraint.proof.size());
info("proof_size_no_pub_inputs: ", 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) {
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 {}\n",
"which is ",
RecursionConstraint::AGGREGATION_OBJECT_SIZE);
info("constraint.proof.size(): ", constraint.proof.size());
info("proof_size_no_pub_inputs: ", proof_size_no_pub_inputs);
throw_or_abort(error_string);
}
for (size_t i = 0; i < RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) {
Expand All @@ -172,20 +176,23 @@ void build_constraints(Builder& builder, AcirFormat const& constraint_system, bo
nested_aggregation_object[i] = static_cast<uint32_t>(constraint.public_inputs.size());
// Attach the nested aggregation object to the end of the public inputs to fill in
// the slot where the nested aggregation object index will point into
// info("nested_aggregation_object[", i, "]: ", nested_aggregation_object[i]);
// info("constraint.proof[", i, "]: ", constraint.proof[i]);
constraint.public_inputs.emplace_back(constraint.proof[i]);
}
// Remove the aggregation object so that they can be handled as normal public inputs
// 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));
} else {
throw_or_abort("proof does not contain aggregation object!");
}
current_output_aggregation_object = create_recursion_constraints(builder,
constraint,
current_input_aggregation_object,
nested_aggregation_object,
has_valid_witness_assignments);
current_input_aggregation_object = current_output_aggregation_object;
current_aggregation_object = create_recursion_constraints(builder,
constraint,
current_aggregation_object,
nested_aggregation_object,
has_valid_witness_assignments);
}

// Now that the circuit has been completely built, we add the output aggregation as public
Expand All @@ -195,14 +202,98 @@ void build_constraints(Builder& builder, AcirFormat const& constraint_system, bo
// First add the output aggregation object as public inputs
// Set the indices as public inputs because they are no longer being
// created in ACIR
for (const auto& idx : current_output_aggregation_object) {
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 (builder.is_recursive_circuit) {
info("g1 infinity: ", bb::g1::affine_point_at_infinity);
// const auto zero = bb::fr::zero();
// const auto group_zero = bb::g1::affine_one * zero;
// info("group_zero: ", group_zero);
info("fq_ct::NUM_LAST_LIMB_BITS: ", fq_ct::NUM_LAST_LIMB_BITS);
info("bb::stdlib::field_conversion::TOTAL_BITS: ", bb::stdlib::field_conversion::TOTAL_BITS);
fq x0("0x031e97a575e9d05a107acb64952ecab75c020998797da7842ab5d6d1986846cf");
fq x1("0x0f94656a2ca489889939f81e9c74027fd51009034b3357f0e91b8a11e7842c38");
std::array<fq, 2> xs = { x0, x1 };

fq y0("0x178cbf4206471d722669117f9758a4c410db10a01750aebb5666547acf8bd5a4");
fq y1("0x1b52c2020d7464a0c80c0da527a08193fe27776f50224bd6fb128b46c1ddb67f");
std::array<fq, 2> ys = { y0, y1 };
for (size_t i = 0; i < RecursionConstraint::AGGREGATION_OBJECT_SIZE / 8; ++i) {
const auto group_element = g1::element(xs[i], ys[i], 1);
info("is group_element infinity: ", group_element.is_point_at_infinity());

// const auto x = bb::field_conversion::convert_to_bn254_frs(const T &val);
const uint256_t x = group_element.x;
const uint256_t y = group_element.y;
const bb::fr x_1 = x.slice(0, stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION);

const bb::fr x_2 =
x.slice(stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION, stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2);
const bb::fr x_3 = x.slice(stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2,
stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 3);
const bb::fr x_4 =
x.slice(stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 3, bb::stdlib::field_conversion::TOTAL_BITS);

const bb::fr y_1 = y.slice(0, stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION);
const bb::fr y_2 =
y.slice(stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION, stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2);
const bb::fr y_3 = y.slice(stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2,
stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 3);
const bb::fr y_4 =
y.slice(stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 3, bb::stdlib::field_conversion::TOTAL_BITS);

info("x_1: ", x_1);
info("x_2: ", x_2);
info("x_3: ", x_3);
info("x_4: ", x_4);

info("y_1: ", y_1);
info("y_2: ", y_2);
info("y_3: ", y_3);
info("y_4: ", y_4);

uint32_t idx = builder.add_variable(x_1);
builder.set_public_input(idx);
current_aggregation_object[i * 8] = idx;

idx = builder.add_variable(x_2);
builder.set_public_input(idx);
current_aggregation_object[i * 8 + 1] = idx;

idx = builder.add_variable(x_3);
builder.set_public_input(idx);
current_aggregation_object[i * 8 + 2] = idx;

idx = builder.add_variable(x_4);
builder.set_public_input(idx);
current_aggregation_object[i * 8 + 3] = idx;

idx = builder.add_variable(y_1);
builder.set_public_input(idx);
current_aggregation_object[i * 8 + 4] = idx;

idx = builder.add_variable(y_2);
builder.set_public_input(idx);
current_aggregation_object[i * 8 + 5] = idx;

idx = builder.add_variable(y_3);
builder.set_public_input(idx);
current_aggregation_object[i * 8 + 6] = idx;

idx = builder.add_variable(y_4);
builder.set_public_input(idx);
current_aggregation_object[i * 8 + 7] = 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_output_aggregation_object.begin(),
current_output_aggregation_object.end());
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 @@ -10,7 +10,7 @@ namespace acir_format {
using namespace bb::plonk;

// `NUM_LIMB_BITS_IN_FIELD_SIMULATION` is the limb size when simulating a non-native field using the bigfield class
// A aggregation object is two acir_format::g1_ct types where each coordinate in a point is a non-native field.
// An aggregation object is two acir_format::g1_ct types where each coordinate in a point is a non-native field.
// Each field is represented as four limbs. We split those limbs in half when serializing to/from buffer.
static constexpr uint64_t TWO_LIMBS_BITS_IN_FIELD_SIMULATION = stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2;
static constexpr uint64_t FOUR_LIMBS_BITS_IN_FIELD_SIMULATION = stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 4;
Expand Down Expand Up @@ -42,7 +42,7 @@ std::array<uint32_t, RecursionConstraint::AGGREGATION_OBJECT_SIZE> create_recurs
nested_aggregation_indices_all_zero &= (idx == 0);
}
const bool inner_proof_contains_recursive_proof = !nested_aggregation_indices_all_zero;

info("inner_proof_contains_recursive_proof: ", inner_proof_contains_recursive_proof);
// If we do not have a witness, we must ensure that our dummy witness will not trigger
// on-curve errors and inverting-zero errors
{
Expand Down Expand Up @@ -94,7 +94,7 @@ std::array<uint32_t, RecursionConstraint::AGGREGATION_OBJECT_SIZE> create_recurs
const auto& aggregation_input = input_aggregation_object;
aggregation_state_ct previous_aggregation;

// If we have previously recursively verified proofs, `is_aggregation_object_nonzero = true`
// If we have previously recursively verified proofs, `inner_aggregation_indices_all_zero = true`
// For now this is a complile-time constant i.e. whether this is true/false is fixed for the circuit!
bool inner_aggregation_indices_all_zero = true;
for (const auto& idx : aggregation_input) {
Expand Down Expand Up @@ -133,10 +133,12 @@ std::array<uint32_t, RecursionConstraint::AGGREGATION_OBJECT_SIZE> create_recurs
// Prepend the public inputs to the proof fields because this is how the
// core barretenberg library processes proofs (with the public inputs first and not separated)
proof_fields.reserve(input.proof.size() + input.public_inputs.size());
info("input.public_inputs.size(): ", input.public_inputs.size());
for (const auto& idx : input.public_inputs) {
auto field = field_ct::from_witness_index(&builder, idx);
proof_fields.emplace_back(field);
}

for (const auto& idx : input.proof) {
auto field = field_ct::from_witness_index(&builder, idx);
proof_fields.emplace_back(field);
Expand Down
Loading