Skip to content

Commit

Permalink
chore: Recursive verifier updates (#3452)
Browse files Browse the repository at this point in the history
This work contains the following updates:

1. Previously we used only `check_circuit()` to ensure correctness of
the Honk recursive verifier circuits. This is somewhat incomplete if the
arithmetization of the circuit is Goblin Ultra Honk since
`check_circuit()` is only complete for the conventional Ultra
arithmetization and does not cover Goblin style ecc op gates or the
DataBus functionality. This PR swaps out `check_circuit` for genuine
proof construction/verification which is more time consuming but also
more robust.
2. Updates constructor of recursive verifier to take a native
verification key directly rather than requiring prior external
construction of the stdlib verification key.
3. Adds a debug only method for ensuring all selectors have the same
length.

Note: Currently the two recursive verifier test suites share a lot of
code. A follow on should potentially combine the two suites.
  • Loading branch information
ledwards2225 authored and AztecBot committed Dec 5, 2023
1 parent ead0570 commit 7afca0e
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 66 deletions.
3 changes: 2 additions & 1 deletion cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ template <typename BuilderType> class GoblinUltraRecursive_ {
using Commitment = typename Curve::Element;
using CommitmentHandle = typename Curve::Element;
using FF = typename Curve::ScalarField;
using NativeVerificationKey = flavor::GoblinUltra::VerificationKey;

// Note(luke): Eventually this may not be needed at all
using VerifierCommitmentKey = pcs::VerifierCommitmentKey<Curve>;
Expand Down Expand Up @@ -106,7 +107,7 @@ template <typename BuilderType> class GoblinUltraRecursive_ {
* @param builder
* @param native_key Native verification key from which to extract the precomputed commitments
*/
VerificationKey(CircuitBuilder* builder, const auto& native_key)
VerificationKey(CircuitBuilder* builder, std::shared_ptr<NativeVerificationKey> native_key)
: VerificationKey_<GoblinUltra::PrecomputedEntities<Commitment>>(native_key->circuit_size,
native_key->num_public_inputs)
{
Expand Down
3 changes: 2 additions & 1 deletion cpp/src/barretenberg/flavor/ultra_recursive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ template <typename BuilderType> class UltraRecursive_ {
using Commitment = typename Curve::Element;
using CommitmentHandle = typename Curve::Element;
using FF = typename Curve::ScalarField;
using NativeVerificationKey = flavor::Ultra::VerificationKey;

// Note(luke): Eventually this may not be needed at all
using VerifierCommitmentKey = pcs::VerifierCommitmentKey<Curve>;
Expand Down Expand Up @@ -250,7 +251,7 @@ template <typename BuilderType> class UltraRecursive_ {
* @param builder
* @param native_key Native verification key from which to extract the precomputed commitments
*/
VerificationKey(CircuitBuilder* builder, auto native_key)
VerificationKey(CircuitBuilder* builder, std::shared_ptr<NativeVerificationKey> native_key)
: VerificationKey_<PrecomputedEntities<Commitment>>(native_key->circuit_size, native_key->num_public_inputs)
{
this->q_m = Commitment::from_witness(builder, native_key->q_m);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ template <typename FF_> class UltraHonk {
SelectorType& q_elliptic() { return selectors[8]; };
SelectorType& q_aux() { return selectors[9]; };
SelectorType& q_lookup_type() { return selectors[10]; };
SelectorType& q_busread() { return this->selectors[11]; };
SelectorType& q_busread() { return selectors[11]; };
SelectorType& q_poseidon2_external() { return this->selectors[12]; };
SelectorType& q_poseidon2_internal() { return this->selectors[13]; };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ template <typename FF> void GoblinUltraCircuitBuilder_<FF>::add_gates_to_ensure_
this->w_l.emplace_back(public_calldata[read_idx]); // populate with value of calldata at read index
this->w_r.emplace_back(this->add_variable(FF(read_idx))); // populate with read index as witness
calldata_read_counts[read_idx]++; // increment read count at read index
q_busread.emplace_back(1); // read selector on
q_busread().emplace_back(1); // read selector on

// populate all other components with zero
this->w_o.emplace_back(this->zero_idx);
Expand Down Expand Up @@ -84,7 +84,7 @@ template <typename FF> void GoblinUltraCircuitBuilder_<FF>::add_gates_to_ensure_
this->q_lookup_type.emplace_back(0);
this->q_elliptic.emplace_back(0);
this->q_aux.emplace_back(0);
this->q_busread.emplace_back(0);
this->q_busread().emplace_back(0);
this->q_poseidon2_external.emplace_back(1);
this->q_poseidon2_internal.emplace_back(1);

Expand All @@ -106,7 +106,7 @@ template <typename FF> void GoblinUltraCircuitBuilder_<FF>::add_gates_to_ensure_
this->q_lookup_type.emplace_back(0);
this->q_elliptic.emplace_back(0);
this->q_aux.emplace_back(0);
this->q_busread.emplace_back(0);
this->q_busread().emplace_back(0);
this->q_poseidon2_external.emplace_back(0);
this->q_poseidon2_internal.emplace_back(0);

Expand Down Expand Up @@ -264,7 +264,7 @@ void GoblinUltraCircuitBuilder_<FF>::create_poseidon2_external_gate(const poseid
this->q_lookup_type.emplace_back(0);
this->q_elliptic.emplace_back(0);
this->q_aux.emplace_back(0);
this->q_busread.emplace_back(0);
this->q_busread().emplace_back(0);
this->q_poseidon2_external.emplace_back(1);
this->q_poseidon2_internal.emplace_back(0);
++this->num_gates;
Expand All @@ -288,7 +288,7 @@ void GoblinUltraCircuitBuilder_<FF>::create_poseidon2_internal_gate(const poseid
this->q_lookup_type.emplace_back(0);
this->q_elliptic.emplace_back(0);
this->q_aux.emplace_back(0);
this->q_busread.emplace_back(0);
this->q_busread().emplace_back(0);
this->q_poseidon2_external.emplace_back(0);
this->q_poseidon2_internal.emplace_back(1);
++this->num_gates;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ template <typename FF> class GoblinUltraCircuitBuilder_ : public UltraCircuitBui
WireVector& ecc_op_wire_3 = std::get<2>(ecc_op_wires);
WireVector& ecc_op_wire_4 = std::get<3>(ecc_op_wires);

SelectorVector& q_busread = this->selectors.q_busread();
SelectorVector& q_busread() { return this->selectors.q_busread(); };
SelectorVector& q_poseidon2_external = this->selectors.q_poseidon2_external();
SelectorVector& q_poseidon2_internal = this->selectors.q_poseidon2_internal();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ void UltraCircuitBuilder_<Arithmetization>::add_gates_to_ensure_all_polys_are_no
q_elliptic.emplace_back(1);
q_aux.emplace_back(1);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;

// Some relations depend on wire shifts so we add another gate with
Expand Down Expand Up @@ -140,6 +141,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_add_gate(const add_triple_<FF
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}

Expand Down Expand Up @@ -172,6 +174,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_big_add_gate(const add_quad_<
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}

Expand Down Expand Up @@ -266,6 +269,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_big_mul_gate(const mul_quad_<
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}

Expand All @@ -292,6 +296,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_balanced_add_gate(const add_q
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
// Why 3? TODO: return to this
// The purpose of this gate is to do enable lazy 32-bit addition.
Expand Down Expand Up @@ -334,6 +339,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_mul_gate(const mul_triple_<FF
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}
/**
Expand Down Expand Up @@ -363,6 +369,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_bool_gate(const uint32_t vari
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}

Expand Down Expand Up @@ -394,6 +401,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_poly_gate(const poly_triple_<
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}

Expand Down Expand Up @@ -448,6 +456,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_ecc_add_gate(const ecc_add_ga
q_elliptic.emplace_back(1);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}
w_l.emplace_back(in.x2);
Expand All @@ -466,6 +475,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_ecc_add_gate(const ecc_add_ga
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}

Expand Down Expand Up @@ -512,6 +522,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_ecc_dbl_gate(const ecc_dbl_ga
q_lookup_type.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}

Expand All @@ -531,6 +542,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_ecc_dbl_gate(const ecc_dbl_ga
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}

Expand Down Expand Up @@ -561,6 +573,7 @@ void UltraCircuitBuilder_<Arithmetization>::fix_witness(const uint32_t witness_i
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}

Expand Down Expand Up @@ -636,6 +649,7 @@ plookup::ReadData<uint32_t> UltraCircuitBuilder_<Arithmetization>::create_gates_
q_elliptic.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
++this->num_gates;
}
return read_data;
Expand Down Expand Up @@ -945,6 +959,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_sort_constraint(const std::ve
q_lookup_type.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
}
// dummy gate needed because of sort widget's check of next row
w_l.emplace_back(variable_index[variable_index.size() - 1]);
Expand All @@ -964,6 +979,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_sort_constraint(const std::ve
q_lookup_type.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
}

// useful to put variables in the witness that aren't already used - e.g. the dummy variables of the range constraint in
Expand Down Expand Up @@ -998,6 +1014,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_dummy_constraints(const std::
q_lookup_type.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
}
}

Expand Down Expand Up @@ -1029,6 +1046,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_sort_constraint_with_edges(
q_lookup_type.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
// enforce range check for middle rows
for (size_t i = gate_width; i < variable_index.size() - gate_width; i += gate_width) {

Expand All @@ -1049,6 +1067,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_sort_constraint_with_edges(
q_lookup_type.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
}
// enforce range checks of last row and ending at end
if (variable_index.size() > gate_width) {
Expand All @@ -1069,6 +1088,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_sort_constraint_with_edges(
q_lookup_type.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
}

// dummy gate needed because of sort widget's check of next row
Expand All @@ -1090,6 +1110,7 @@ void UltraCircuitBuilder_<Arithmetization>::create_sort_constraint_with_edges(
q_lookup_type.emplace_back(0);
q_aux.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
}

// range constraint a value by decomposing it into limbs whose size should be the default range constraint size
Expand Down Expand Up @@ -1206,6 +1227,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0);
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::LIMB_ACCUMULATE_2: {
Expand All @@ -1217,6 +1239,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0);
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::NON_NATIVE_FIELD_1: {
Expand All @@ -1228,6 +1251,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0);
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::NON_NATIVE_FIELD_2: {
Expand All @@ -1239,6 +1263,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0);
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::NON_NATIVE_FIELD_3: {
Expand All @@ -1250,6 +1275,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0);
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::ROM_CONSISTENCY_CHECK: {
Expand All @@ -1265,6 +1291,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0);
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::RAM_CONSISTENCY_CHECK: {
Expand All @@ -1281,6 +1308,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0);
q_arith.emplace_back(1);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::RAM_TIMESTAMP_CHECK: {
Expand All @@ -1294,6 +1322,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0);
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::ROM_READ: {
Expand All @@ -1308,6 +1337,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0); // read/write flag stored in q_c
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::RAM_READ: {
Expand All @@ -1322,6 +1352,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0); // read/write flag stored in q_c
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
case AUX_SELECTORS::RAM_WRITE: {
Expand All @@ -1336,6 +1367,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(1); // read/write flag stored in q_c
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
default: {
Expand All @@ -1347,6 +1379,7 @@ void UltraCircuitBuilder_<Arithmetization>::apply_aux_selectors(const AUX_SELECT
q_c.emplace_back(0);
q_arith.emplace_back(0);
selectors.pad_additional();
check_selector_length_consistency();
break;
}
}
Expand Down Expand Up @@ -1869,6 +1902,7 @@ std::array<uint32_t, 5> UltraCircuitBuilder_<Arithmetization>::evaluate_non_nati
q_aux.emplace_back(0);
selectors.pad_additional();
}
check_selector_length_consistency();

this->num_gates += 4;
return std::array<uint32_t, 5>{
Expand Down Expand Up @@ -1991,6 +2025,7 @@ std::array<uint32_t, 5> UltraCircuitBuilder_<Arithmetization>::evaluate_non_nati
q_aux.emplace_back(0);
selectors.pad_additional();
}
check_selector_length_consistency();

this->num_gates += 4;
return std::array<uint32_t, 5>{
Expand Down
Loading

0 comments on commit 7afca0e

Please sign in to comment.