@@ -31,17 +31,18 @@ namespace {
31
31
* @param key_fields
32
32
* @param proof_fields
33
33
*/
34
+ template <typename Flavor>
34
35
void create_dummy_vkey_and_proof (Builder& builder,
35
36
size_t proof_size,
36
37
size_t public_inputs_size,
37
38
const std::vector<field_ct>& key_fields,
38
- const std::vector<field_ct>& proof_fields)
39
+ const std::vector<field_ct>& proof_fields,
40
+ bool is_rollup_honk_recursion_constraint)
39
41
{
40
- using Flavor = UltraFlavor;
41
-
42
42
// Set vkey->circuit_size correctly based on the proof size
43
- size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs<Flavor::Commitment>();
44
- size_t num_frs_fr = bb::field_conversion::calc_num_bn254_frs<Flavor::FF>();
43
+ size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs<typename Flavor::Commitment>();
44
+ size_t num_frs_fr = bb::field_conversion::calc_num_bn254_frs<typename Flavor::FF>();
45
+ // TODO(https://github.com/AztecProtocol/barretenberg/issues/1168): Add formula to flavor
45
46
assert ((proof_size - bb::HONK_PROOF_PUBLIC_INPUT_OFFSET - Flavor::NUM_WITNESS_ENTITIES * num_frs_comm -
46
47
Flavor::NUM_ALL_ENTITIES * num_frs_fr - num_frs_comm) %
47
48
(num_frs_comm + num_frs_fr * (Flavor::BATCHED_RELATION_PARTIAL_LENGTH + 1 )) ==
@@ -61,13 +62,26 @@ void create_dummy_vkey_and_proof(Builder& builder,
61
62
builder.assert_equal (builder.add_variable (1 ), key_fields[3 ].witness_index );
62
63
uint32_t offset = 4 ;
63
64
size_t num_inner_public_inputs = public_inputs_size - bb::PAIRING_POINT_ACCUMULATOR_SIZE;
65
+ if (is_rollup_honk_recursion_constraint) {
66
+ num_inner_public_inputs -= bb::IPA_CLAIM_SIZE;
67
+ }
64
68
65
- // We are making the assumption that the aggregation object are behind all the inner public inputs
69
+ // We are making the assumption that the pairing point object is behind all the inner public inputs
66
70
for (size_t i = 0 ; i < bb::PAIRING_POINT_ACCUMULATOR_SIZE; i++) {
67
71
builder.assert_equal (builder.add_variable (num_inner_public_inputs + i), key_fields[offset].witness_index );
68
72
offset++;
69
73
}
70
74
75
+ if (is_rollup_honk_recursion_constraint) {
76
+ // Key field is the whether the proof contains an aggregation object.
77
+ builder.assert_equal (builder.add_variable (1 ), key_fields[offset++].witness_index );
78
+ // We are making the assumption that the IPA claim is behind the inner public inputs and pairing point object
79
+ for (size_t i = 0 ; i < bb::IPA_CLAIM_SIZE; i++) {
80
+ builder.assert_equal (builder.add_variable (num_inner_public_inputs + i), key_fields[offset].witness_index );
81
+ offset++;
82
+ }
83
+ }
84
+
71
85
for (size_t i = 0 ; i < Flavor::NUM_PRECOMPUTED_ENTITIES; ++i) {
72
86
auto comm = curve::BN254::AffineElement::one () * fr::random_element ();
73
87
auto frs = field_conversion::convert_to_bn254_frs (comm);
@@ -96,6 +110,14 @@ void create_dummy_vkey_and_proof(Builder& builder,
96
110
offset++;
97
111
}
98
112
113
+ if (is_rollup_honk_recursion_constraint) {
114
+ IPAClaimIndices ipa_claim; // WORKTODO: initialize this to something?
115
+ for (auto idx : ipa_claim) {
116
+ builder.assert_equal (idx, proof_fields[offset].witness_index );
117
+ offset++;
118
+ }
119
+ }
120
+
99
121
// first 8 witness commitments
100
122
for (size_t i = 0 ; i < Flavor::NUM_WITNESS_ENTITIES; i++) {
101
123
auto comm = curve::BN254::AffineElement::one () * fr::random_element ();
@@ -107,7 +129,8 @@ void create_dummy_vkey_and_proof(Builder& builder,
107
129
offset += 4 ;
108
130
}
109
131
110
- // now the univariates, which can just be 0s (8*CONST_PROOF_SIZE_LOG_N Frs, where 8 is the maximum relation degree)
132
+ // now the univariates, which can just be 0s (8*CONST_PROOF_SIZE_LOG_N Frs, where 8 is the maximum relation
133
+ // degree)
111
134
for (size_t i = 0 ; i < CONST_PROOF_SIZE_LOG_N * Flavor::BATCHED_RELATION_PARTIAL_LENGTH; i++) {
112
135
builder.assert_equal (builder.add_variable (fr::random_element ()), proof_fields[offset].witness_index );
113
136
offset++;
@@ -162,17 +185,20 @@ void create_dummy_vkey_and_proof(Builder& builder,
162
185
* We would either need a separate ACIR opcode where inner_proof_contains_pairing_point_accumulator = true,
163
186
* or we need non-witness data to be provided as metadata in the ACIR opcode
164
187
*/
165
- PairingPointAccumulatorIndices create_honk_recursion_constraints (
188
+
189
+ template <typename Flavor>
190
+ HonkRecursionConstraintOutput create_honk_recursion_constraints (
166
191
Builder& builder,
167
192
const RecursionConstraint& input,
168
193
PairingPointAccumulatorIndices input_aggregation_object_indices,
169
194
bool has_valid_witness_assignments)
170
195
{
171
- using Flavor = UltraRecursiveFlavor_<Builder>;
172
196
using RecursiveVerificationKey = Flavor::VerificationKey;
173
197
using RecursiveVerifier = bb::stdlib::recursion::honk::UltraRecursiveVerifier_<Flavor>;
174
198
175
- ASSERT (input.proof_type == HONK);
199
+ bool is_rollup_honk_recursion_constraint =
200
+ (input.proof_type == ROLLUP_HONK || input.proof_type == ROLLUP_ROOT_HONK);
201
+ ASSERT (input.proof_type == HONK || is_rollup_honk_recursion_constraint);
176
202
177
203
// Construct an in-circuit representation of the verification key.
178
204
// For now, the v-key is a circuit constant and is fixed for the circuit.
@@ -200,21 +226,63 @@ PairingPointAccumulatorIndices create_honk_recursion_constraints(
200
226
// In the constraint, the agg object public inputs are still contained in the proof. To get the 'raw' size of
201
227
// the proof and public_inputs we subtract and add the corresponding amount from the respective sizes.
202
228
size_t size_of_proof_with_no_pub_inputs = input.proof .size () - bb::PAIRING_POINT_ACCUMULATOR_SIZE;
229
+ if (is_rollup_honk_recursion_constraint) {
230
+ size_of_proof_with_no_pub_inputs -= bb::IPA_CLAIM_SIZE;
231
+ }
203
232
size_t total_num_public_inputs = input.public_inputs .size () + bb::PAIRING_POINT_ACCUMULATOR_SIZE;
204
- create_dummy_vkey_and_proof (
205
- builder, size_of_proof_with_no_pub_inputs, total_num_public_inputs, key_fields, proof_fields);
233
+ if (is_rollup_honk_recursion_constraint) {
234
+ total_num_public_inputs += bb::IPA_CLAIM_SIZE;
235
+ }
236
+ create_dummy_vkey_and_proof<typename Flavor::NativeFlavor>(builder,
237
+ size_of_proof_with_no_pub_inputs,
238
+ total_num_public_inputs,
239
+ key_fields,
240
+ proof_fields,
241
+ is_rollup_honk_recursion_constraint);
206
242
}
207
243
208
244
// Recursively verify the proof
209
245
auto vkey = std::make_shared<RecursiveVerificationKey>(builder, key_fields);
210
246
RecursiveVerifier verifier (&builder, vkey);
211
247
aggregation_state_ct input_agg_obj = bb::stdlib::recursion::convert_witness_indices_to_agg_obj<Builder, bn254>(
212
248
builder, input_aggregation_object_indices);
213
- UltraRecursiveVerifierOutput<Flavor> output = verifier.verify_proof (proof_fields, input_agg_obj);
249
+ std::vector<field_ct> honk_proof = proof_fields;
250
+ HonkRecursionConstraintOutput output;
251
+ if (is_rollup_honk_recursion_constraint) {
252
+ // TODO(https://github.com/AztecProtocol/barretenberg/issues/1168): Add formula to flavor
253
+ const size_t HONK_PROOF_LENGTH = 473 ;
254
+ // The extra calculation is for the IPA proof length.
255
+ ASSERT (input.proof .size () == HONK_PROOF_LENGTH + 1 + 4 * (CONST_ECCVM_LOG_N) + 2 + 2 );
256
+ ASSERT (proof_fields.size () == HONK_PROOF_LENGTH + 65 + input.public_inputs .size ());
257
+ // split out the ipa proof
258
+ const std::ptrdiff_t honk_proof_with_pub_inputs_length =
259
+ static_cast <std::ptrdiff_t >(HONK_PROOF_LENGTH + input.public_inputs .size ());
260
+ output.ipa_proof =
261
+ StdlibProof<Builder>(honk_proof.begin () + honk_proof_with_pub_inputs_length, honk_proof.end ());
262
+ honk_proof = StdlibProof<Builder>(honk_proof.begin (), honk_proof.end () + honk_proof_with_pub_inputs_length);
263
+ }
264
+ UltraRecursiveVerifierOutput<Flavor> verifier_output = verifier.verify_proof (honk_proof, input_agg_obj);
214
265
// TODO(https://github.com/AztecProtocol/barretenberg/issues/996): investigate whether assert_equal on public inputs
215
266
// is important, like what the plonk recursion constraint does.
216
267
217
- return output.agg_obj .get_witness_indices ();
268
+ output.agg_obj_indices = verifier_output.agg_obj .get_witness_indices ();
269
+ if (is_rollup_honk_recursion_constraint) {
270
+ ASSERT (HasIPAAccumulator<Flavor>);
271
+ output.ipa_claim = verifier_output.ipa_opening_claim ;
272
+ }
273
+ return output;
218
274
}
219
275
276
+ template HonkRecursionConstraintOutput create_honk_recursion_constraints<UltraRecursiveFlavor_<Builder>>(
277
+ Builder& builder,
278
+ const RecursionConstraint& input,
279
+ PairingPointAccumulatorIndices input_aggregation_object_indices,
280
+ bool has_valid_witness_assignments);
281
+
282
+ template HonkRecursionConstraintOutput create_honk_recursion_constraints<UltraRollupRecursiveFlavor_<Builder>>(
283
+ Builder& builder,
284
+ const RecursionConstraint& input,
285
+ PairingPointAccumulatorIndices input_aggregation_object_indices,
286
+ bool has_valid_witness_assignments);
287
+
220
288
} // namespace acir_format
0 commit comments