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 Dec 4, 2023
1 parent 3f56dd7 commit dbb4a12
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 66 deletions.
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 barretenberg/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 dbb4a12

Please sign in to comment.