Skip to content

Commit 9a80008

Browse files
vezenovmkevaundray
andauthored
chore!: Remove aggregation objects from RecursionConstraint (AztecProtocol#3885)
This removes the aggregation objects which are currently unused in the RecursionConstraint implementation. Next we will update the ACVM opcode to no longer use the aggregation object fields and update the serialization. # Checklist: Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge. - [ ] If the pull request requires a cryptography review (e.g. cryptographic algorithm implementations) I have added the 'crypto' tag. - [ ] I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code. - [ ] Every change is related to the PR description. - [ ] I have [linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this pull request to relevant issues (if any exist). --------- Co-authored-by: kevaundray <kevtheappdev@gmail.com>
1 parent 0dfc32f commit 9a80008

File tree

13 files changed

+12
-120
lines changed

13 files changed

+12
-120
lines changed

barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp

-11
Original file line numberDiff line numberDiff line change
@@ -203,18 +203,7 @@ void handle_blackbox_func_call(Circuit::Opcode::BlackBoxFuncCall const& arg, aci
203203
.proof = map(arg.proof, [](auto& e) { return e.witness.value; }),
204204
.public_inputs = map(arg.public_inputs, [](auto& e) { return e.witness.value; }),
205205
.key_hash = arg.key_hash.witness.value,
206-
.input_aggregation_object = {},
207-
.output_aggregation_object = {},
208-
.nested_aggregation_object = {},
209206
};
210-
if (arg.input_aggregation_object.has_value()) {
211-
for (size_t i = 0; i < RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) {
212-
c.input_aggregation_object[i] = (*arg.input_aggregation_object)[i].witness.value;
213-
}
214-
}
215-
for (size_t i = 0; i < RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) {
216-
c.output_aggregation_object[i] = arg.output_aggregation_object[i].value;
217-
}
218207
af.recursion_constraints.push_back(c);
219208
}
220209
},

barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.hpp

-15
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,6 @@ struct RecursionConstraint {
5353
std::vector<uint32_t> proof;
5454
std::vector<uint32_t> public_inputs;
5555
uint32_t key_hash;
56-
// TODO(maxim):This is now unused, but we keep it here for backwards compatibility
57-
std::array<uint32_t, AGGREGATION_OBJECT_SIZE> input_aggregation_object;
58-
// TODO(maxim): This is now unused, but we keep it here for backwards compatibility
59-
std::array<uint32_t, AGGREGATION_OBJECT_SIZE> output_aggregation_object;
60-
// TODO(maxim): This is currently not being used on the Noir level at all,
61-
// TODO(maxim): but we keep it here for backwards compatibility
62-
// TODO(maxim): The object is now currently contained by the `proof` field
63-
// TODO(maxim): and is handled when serializing ACIR to a barretenberg circuit
64-
std::array<uint32_t, AGGREGATION_OBJECT_SIZE> nested_aggregation_object;
6556

6657
friend bool operator==(RecursionConstraint const& lhs, RecursionConstraint const& rhs) = default;
6758
};
@@ -100,9 +91,6 @@ template <typename B> inline void read(B& buf, RecursionConstraint& constraint)
10091
read(buf, constraint.proof);
10192
read(buf, constraint.public_inputs);
10293
read(buf, constraint.key_hash);
103-
read(buf, constraint.input_aggregation_object);
104-
read(buf, constraint.output_aggregation_object);
105-
read(buf, constraint.nested_aggregation_object);
10694
}
10795

10896
template <typename B> inline void write(B& buf, RecursionConstraint const& constraint)
@@ -112,9 +100,6 @@ template <typename B> inline void write(B& buf, RecursionConstraint const& const
112100
write(buf, constraint.proof);
113101
write(buf, constraint.public_inputs);
114102
write(buf, constraint.key_hash);
115-
write(buf, constraint.input_aggregation_object);
116-
write(buf, constraint.output_aggregation_object);
117-
write(buf, constraint.nested_aggregation_object);
118103
}
119104

120105
} // namespace acir_format

barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,6 @@ Builder create_outer_circuit(std::vector<Builder>& inner_circuits)
207207
.proof = proof_indices,
208208
.public_inputs = inner_public_inputs,
209209
.key_hash = key_hash_start_idx,
210-
.input_aggregation_object = input_aggregation_object,
211-
.output_aggregation_object = output_aggregation_object,
212-
.nested_aggregation_object = nested_aggregation_object,
213210
};
214211
recursion_constraints.push_back(recursion_constraint);
215212

barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp

-14
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,6 @@ struct BlackBoxFuncCall {
178178
std::vector<Circuit::FunctionInput> proof;
179179
std::vector<Circuit::FunctionInput> public_inputs;
180180
Circuit::FunctionInput key_hash;
181-
std::optional<std::vector<Circuit::FunctionInput>> input_aggregation_object;
182-
std::vector<Circuit::Witness> output_aggregation_object;
183181

184182
friend bool operator==(const RecursiveAggregation&, const RecursiveAggregation&);
185183
std::vector<uint8_t> bincodeSerialize() const;
@@ -2659,12 +2657,6 @@ inline bool operator==(const BlackBoxFuncCall::RecursiveAggregation& lhs,
26592657
if (!(lhs.key_hash == rhs.key_hash)) {
26602658
return false;
26612659
}
2662-
if (!(lhs.input_aggregation_object == rhs.input_aggregation_object)) {
2663-
return false;
2664-
}
2665-
if (!(lhs.output_aggregation_object == rhs.output_aggregation_object)) {
2666-
return false;
2667-
}
26682660
return true;
26692661
}
26702662

@@ -2697,8 +2689,6 @@ void serde::Serializable<Circuit::BlackBoxFuncCall::RecursiveAggregation>::seria
26972689
serde::Serializable<decltype(obj.proof)>::serialize(obj.proof, serializer);
26982690
serde::Serializable<decltype(obj.public_inputs)>::serialize(obj.public_inputs, serializer);
26992691
serde::Serializable<decltype(obj.key_hash)>::serialize(obj.key_hash, serializer);
2700-
serde::Serializable<decltype(obj.input_aggregation_object)>::serialize(obj.input_aggregation_object, serializer);
2701-
serde::Serializable<decltype(obj.output_aggregation_object)>::serialize(obj.output_aggregation_object, serializer);
27022692
}
27032693

27042694
template <>
@@ -2711,10 +2701,6 @@ Circuit::BlackBoxFuncCall::RecursiveAggregation serde::Deserializable<
27112701
obj.proof = serde::Deserializable<decltype(obj.proof)>::deserialize(deserializer);
27122702
obj.public_inputs = serde::Deserializable<decltype(obj.public_inputs)>::deserialize(deserializer);
27132703
obj.key_hash = serde::Deserializable<decltype(obj.key_hash)>::deserialize(deserializer);
2714-
obj.input_aggregation_object =
2715-
serde::Deserializable<decltype(obj.input_aggregation_object)>::deserialize(deserializer);
2716-
obj.output_aggregation_object =
2717-
serde::Deserializable<decltype(obj.output_aggregation_object)>::deserialize(deserializer);
27182704
return obj;
27192705
}
27202706

noir/Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

noir/acvm-repo/acir/codegen/acir.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,6 @@ namespace Circuit {
178178
std::vector<Circuit::FunctionInput> proof;
179179
std::vector<Circuit::FunctionInput> public_inputs;
180180
Circuit::FunctionInput key_hash;
181-
std::optional<std::vector<Circuit::FunctionInput>> input_aggregation_object;
182-
std::vector<Circuit::Witness> output_aggregation_object;
183181

184182
friend bool operator==(const RecursiveAggregation&, const RecursiveAggregation&);
185183
std::vector<uint8_t> bincodeSerialize() const;
@@ -2295,8 +2293,6 @@ namespace Circuit {
22952293
if (!(lhs.proof == rhs.proof)) { return false; }
22962294
if (!(lhs.public_inputs == rhs.public_inputs)) { return false; }
22972295
if (!(lhs.key_hash == rhs.key_hash)) { return false; }
2298-
if (!(lhs.input_aggregation_object == rhs.input_aggregation_object)) { return false; }
2299-
if (!(lhs.output_aggregation_object == rhs.output_aggregation_object)) { return false; }
23002296
return true;
23012297
}
23022298

@@ -2324,8 +2320,6 @@ void serde::Serializable<Circuit::BlackBoxFuncCall::RecursiveAggregation>::seria
23242320
serde::Serializable<decltype(obj.proof)>::serialize(obj.proof, serializer);
23252321
serde::Serializable<decltype(obj.public_inputs)>::serialize(obj.public_inputs, serializer);
23262322
serde::Serializable<decltype(obj.key_hash)>::serialize(obj.key_hash, serializer);
2327-
serde::Serializable<decltype(obj.input_aggregation_object)>::serialize(obj.input_aggregation_object, serializer);
2328-
serde::Serializable<decltype(obj.output_aggregation_object)>::serialize(obj.output_aggregation_object, serializer);
23292323
}
23302324

23312325
template <>
@@ -2336,8 +2330,6 @@ Circuit::BlackBoxFuncCall::RecursiveAggregation serde::Deserializable<Circuit::B
23362330
obj.proof = serde::Deserializable<decltype(obj.proof)>::deserialize(deserializer);
23372331
obj.public_inputs = serde::Deserializable<decltype(obj.public_inputs)>::deserialize(deserializer);
23382332
obj.key_hash = serde::Deserializable<decltype(obj.key_hash)>::deserialize(deserializer);
2339-
obj.input_aggregation_object = serde::Deserializable<decltype(obj.input_aggregation_object)>::deserialize(deserializer);
2340-
obj.output_aggregation_object = serde::Deserializable<decltype(obj.output_aggregation_object)>::deserialize(deserializer);
23412333
return obj;
23422334
}
23432335

noir/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs

+2-19
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,6 @@ pub enum BlackBoxFuncCall {
107107
/// The circuit implementing this opcode can use this hash to ensure that the
108108
/// key provided to the circuit matches the key produced by the circuit creator
109109
key_hash: FunctionInput,
110-
/// An aggregation object is blob of data that the top-level verifier must run some proof system specific
111-
/// algorithm on to complete verification. The size is proof system specific and will be set by the backend integrating this opcode.
112-
/// The input aggregation object is only not `None` when we are verifying a previous recursive aggregation in
113-
/// the current circuit. If this is the first recursive aggregation there is no input aggregation object.
114-
/// It is left to the backend to determine how to handle when there is no input aggregation object.
115-
input_aggregation_object: Option<Vec<FunctionInput>>,
116-
/// This is the result of a recursive aggregation and is what will be fed into the next verifier.
117-
/// The next verifier can either perform a final verification (returning true or false)
118-
/// or perform another recursive aggregation where this output aggregation object
119-
/// will be the input aggregation object of the next recursive aggregation.
120-
output_aggregation_object: Vec<Witness>,
121110
},
122111
}
123112

@@ -223,16 +212,12 @@ impl BlackBoxFuncCall {
223212
proof,
224213
public_inputs,
225214
key_hash,
226-
..
227215
} => {
228216
let mut inputs = Vec::new();
229217
inputs.extend(key.iter().copied());
230218
inputs.extend(proof.iter().copied());
231219
inputs.extend(public_inputs.iter().copied());
232220
inputs.push(*key_hash);
233-
// NOTE: we do not return an input aggregation object as it will either be non-existent for the first recursive aggregation
234-
// or the output aggregation object of a previous recursive aggregation. We do not simulate recursive aggregation
235-
// thus the input aggregation object will always be unassigned until proving
236221
inputs
237222
}
238223
}
@@ -245,9 +230,7 @@ impl BlackBoxFuncCall {
245230
| BlackBoxFuncCall::Blake3 { outputs, .. }
246231
| BlackBoxFuncCall::Keccak256 { outputs, .. }
247232
| BlackBoxFuncCall::Keccakf1600 { outputs, .. }
248-
| BlackBoxFuncCall::RecursiveAggregation {
249-
output_aggregation_object: outputs, ..
250-
} => outputs.to_vec(),
233+
=> outputs.to_vec(),
251234
BlackBoxFuncCall::AND { output, .. }
252235
| BlackBoxFuncCall::XOR { output, .. }
253236
| BlackBoxFuncCall::SchnorrVerify { output, .. }
@@ -256,7 +239,7 @@ impl BlackBoxFuncCall {
256239
| BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output],
257240
BlackBoxFuncCall::FixedBaseScalarMul { outputs, .. }
258241
| BlackBoxFuncCall::PedersenCommitment { outputs, .. } => vec![outputs.0, outputs.1],
259-
BlackBoxFuncCall::RANGE { .. } => vec![],
242+
BlackBoxFuncCall::RANGE { .. } | BlackBoxFuncCall::RecursiveAggregation { .. } => vec![],
260243
BlackBoxFuncCall::Keccak256VariableLength { outputs, .. } => outputs.to_vec(),
261244
}
262245
}

noir/acvm-repo/acvm/src/compiler/transformers/mod.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -104,18 +104,14 @@ pub(super) fn transform_internal(
104104
| acir::circuit::opcodes::BlackBoxFuncCall::XOR { output, .. } => {
105105
transformer.mark_solvable(*output);
106106
}
107-
acir::circuit::opcodes::BlackBoxFuncCall::RANGE { .. } => (),
107+
acir::circuit::opcodes::BlackBoxFuncCall::RANGE { .. } | acir::circuit::opcodes::BlackBoxFuncCall::RecursiveAggregation { .. } => (),
108108
acir::circuit::opcodes::BlackBoxFuncCall::SHA256 { outputs, .. }
109109
| acir::circuit::opcodes::BlackBoxFuncCall::Keccak256 { outputs, .. }
110110
| acir::circuit::opcodes::BlackBoxFuncCall::Keccak256VariableLength {
111111
outputs,
112112
..
113113
}
114114
| acir::circuit::opcodes::BlackBoxFuncCall::Keccakf1600 { outputs, .. }
115-
| acir::circuit::opcodes::BlackBoxFuncCall::RecursiveAggregation {
116-
output_aggregation_object: outputs,
117-
..
118-
}
119115
| acir::circuit::opcodes::BlackBoxFuncCall::Blake2s { outputs, .. }
120116
| acir::circuit::opcodes::BlackBoxFuncCall::Blake3 { outputs, .. } => {
121117
for witness in outputs {

noir/acvm-repo/acvm/src/pwg/blackbox/mod.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,7 @@ pub(crate) fn solve(
177177
BlackBoxFuncCall::FixedBaseScalarMul { low, high, outputs } => {
178178
fixed_base_scalar_mul(backend, initial_witness, *low, *high, *outputs)
179179
}
180-
BlackBoxFuncCall::RecursiveAggregation { output_aggregation_object, .. } => {
181-
// Solve the output of the recursive aggregation to zero to prevent missing assignment errors
182-
// The correct value will be computed by the backend
183-
for witness in output_aggregation_object {
184-
insert_value(witness, FieldElement::zero(), initial_witness)?;
185-
}
186-
Ok(())
187-
}
180+
// Recursive aggregation will be entirely handled by the backend and is not solved by the ACVM
181+
BlackBoxFuncCall::RecursiveAggregation { .. } => Ok(()),
188182
}
189183
}

noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs

-12
Original file line numberDiff line numberDiff line change
@@ -227,23 +227,11 @@ impl GeneratedAcir {
227227
BlackBoxFuncCall::Keccakf1600 { inputs: inputs[0].clone(), outputs }
228228
}
229229
BlackBoxFunc::RecursiveAggregation => {
230-
let has_previous_aggregation = self.opcodes.iter().any(|op| {
231-
matches!(
232-
op,
233-
AcirOpcode::BlackBoxFuncCall(BlackBoxFuncCall::RecursiveAggregation { .. })
234-
)
235-
});
236-
237-
let input_aggregation_object =
238-
if !has_previous_aggregation { None } else { Some(inputs[4].clone()) };
239-
240230
BlackBoxFuncCall::RecursiveAggregation {
241231
verification_key: inputs[0].clone(),
242232
proof: inputs[1].clone(),
243233
public_inputs: inputs[2].clone(),
244234
key_hash: inputs[3][0],
245-
input_aggregation_object,
246-
output_aggregation_object: outputs,
247235
}
248236
}
249237
};

noir/noir_stdlib/src/lib.nr

+2-7
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,8 @@ unconstrained pub fn println<T>(input: T) {
3838
}
3939

4040
#[foreign(recursive_aggregation)]
41-
pub fn verify_proof<N>(
42-
_verification_key: [Field],
43-
_proof: [Field],
44-
_public_inputs: [Field],
45-
_key_hash: Field,
46-
_input_aggregation_object: [Field; N]
47-
) -> [Field; N] {}
41+
pub fn verify_proof<N>(_verification_key: [Field], _proof: [Field], _public_inputs: [Field], _key_hash: Field) {}
42+
4843
// Asserts that the given value is known at compile-time.
4944
// Useful for debugging for-loop bounds.
5045
#[builtin(assert_constant)]

0 commit comments

Comments
 (0)