3
3
#include " barretenberg/plonk/transcript/transcript_wrappers.hpp"
4
4
#include " barretenberg/stdlib/recursion/aggregation_state/aggregation_state.hpp"
5
5
#include " barretenberg/stdlib/recursion/verifier/verifier.hpp"
6
+ #include < cstddef>
6
7
7
8
namespace acir_format {
8
9
@@ -28,12 +29,19 @@ void generate_dummy_proof() {}
28
29
* We would either need a separate ACIR opcode where inner_proof_contains_recursive_proof = true,
29
30
* or we need non-witness data to be provided as metadata in the ACIR opcode
30
31
*/
31
- template <typename Builder>
32
- void create_recursion_constraints (Builder& builder,
33
- const RecursionConstraint& input,
34
- bool has_valid_witness_assignments)
32
+ std::array<uint32_t , RecursionConstraint::AGGREGATION_OBJECT_SIZE> create_recursion_constraints (
33
+ Builder& builder,
34
+ const RecursionConstraint& input,
35
+ std::array<uint32_t , RecursionConstraint::AGGREGATION_OBJECT_SIZE> input_aggregation_object,
36
+ // TODO: does this need to be a part of the recursion opcode?
37
+ // TODO: or can we figure it out from the vk?
38
+ // TODO: either way we could probably have the user explicitly provide it
39
+ // TODO: in Noir.
40
+ // Note: this is not being used in Noir at the moment
41
+ std::array<uint32_t , RecursionConstraint::AGGREGATION_OBJECT_SIZE> nested_aggregation_object,
42
+ bool has_valid_witness_assignments)
35
43
{
36
- const auto & nested_aggregation_indices = input. nested_aggregation_object ;
44
+ const auto & nested_aggregation_indices = nested_aggregation_object;
37
45
bool nested_aggregation_indices_all_zero = true ;
38
46
for (const auto & idx : nested_aggregation_indices) {
39
47
nested_aggregation_indices_all_zero &= (idx == 0 );
@@ -47,8 +55,12 @@ void create_recursion_constraints(Builder& builder,
47
55
const std::vector<fr> dummy_key = export_dummy_key_in_recursion_format (
48
56
PolynomialManifest (Builder::CIRCUIT_TYPE), inner_proof_contains_recursive_proof);
49
57
const auto manifest = Composer::create_manifest (input.public_inputs .size ());
50
- const std::vector<barretenberg::fr> dummy_proof =
58
+ std::vector<barretenberg::fr> dummy_proof =
51
59
export_dummy_transcript_in_recursion_format (manifest, inner_proof_contains_recursive_proof);
60
+
61
+ // Remove the public inputs from the dummy proof
62
+ dummy_proof.erase (dummy_proof.begin (),
63
+ dummy_proof.begin () + static_cast <std::ptrdiff_t >(input.public_inputs .size ()));
52
64
for (size_t i = 0 ; i < input.proof .size (); ++i) {
53
65
const auto proof_field_idx = input.proof [i];
54
66
// if we do NOT have a witness assignment (i.e. are just building the proving/verification keys),
@@ -74,7 +86,7 @@ void create_recursion_constraints(Builder& builder,
74
86
// Construct an in-circuit representation of the verification key.
75
87
// For now, the v-key is a circuit constant and is fixed for the circuit.
76
88
// (We may need a separate recursion opcode for this to vary, or add more config witnesses to this opcode)
77
- const auto & aggregation_input = input. input_aggregation_object ;
89
+ const auto & aggregation_input = input_aggregation_object;
78
90
aggregation_state_ct previous_aggregation;
79
91
80
92
// If we have previously recursively verified proofs, `is_aggregation_object_nonzero = true`
@@ -113,7 +125,13 @@ void create_recursion_constraints(Builder& builder,
113
125
}
114
126
115
127
std::vector<field_ct> proof_fields;
116
- proof_fields.reserve (input.proof .size ());
128
+ // Prepend the public inputs to the proof fields because this is how the
129
+ // core barretenberg library processes proofs (with the public inputs first and not separated)
130
+ proof_fields.reserve (input.proof .size () + input.public_inputs .size ());
131
+ for (const auto & idx : input.public_inputs ) {
132
+ auto field = field_ct::from_witness_index (&builder, idx);
133
+ proof_fields.emplace_back (field);
134
+ }
117
135
for (const auto & idx : input.proof ) {
118
136
auto field = field_ct::from_witness_index (&builder, idx);
119
137
proof_fields.emplace_back (field);
@@ -137,12 +155,14 @@ void create_recursion_constraints(Builder& builder,
137
155
result.public_inputs [i].assert_equal (field_ct::from_witness_index (&builder, input.public_inputs [i]));
138
156
}
139
157
140
- // Assign the recursive proof outputs to `output_aggregation_object`
141
- for (size_t i = 0 ; i < result.proof_witness_indices .size (); ++i) {
142
- const auto lhs = field_ct::from_witness_index (&builder, result.proof_witness_indices [i]);
143
- const auto rhs = field_ct::from_witness_index (&builder, input.output_aggregation_object [i]);
144
- lhs.assert_equal (rhs);
145
- }
158
+ // We want to return an array, so just copy the vector into the array
159
+ ASSERT (result.proof_witness_indices .size () == RecursionConstraint::AGGREGATION_OBJECT_SIZE);
160
+ std::array<uint32_t , RecursionConstraint::AGGREGATION_OBJECT_SIZE> resulting_output_aggregation_object;
161
+ std::copy (result.proof_witness_indices .begin (),
162
+ result.proof_witness_indices .begin () + RecursionConstraint::AGGREGATION_OBJECT_SIZE,
163
+ resulting_output_aggregation_object.begin ());
164
+
165
+ return resulting_output_aggregation_object;
146
166
}
147
167
148
168
/* *
@@ -350,8 +370,4 @@ G1AsFields export_g1_affine_element_as_fields(const barretenberg::g1::affine_ele
350
370
return G1AsFields{ x_lo, x_hi, y_lo, y_hi };
351
371
}
352
372
353
- template void create_recursion_constraints<UltraCircuitBuilder>(UltraCircuitBuilder& builder,
354
- const RecursionConstraint& input,
355
- bool has_valid_witness_assignments);
356
-
357
373
} // namespace acir_format
0 commit comments