Skip to content

Commit dada06f

Browse files
authored
fix: make vk metadata actual witnesses (#12459)
Closes AztecProtocol/barretenberg#983. Makes the vk metadata witnesses instead of native types. I think only circuit_size actually needs to be a witness, but its fine to make them all witnesses. Still a lot of security concerns around this area since there's missing constraints with these witnesses.
1 parent ab9e99b commit dada06f

31 files changed

+146
-124
lines changed

barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ class ECCVMFlavor {
108108
* @brief A base class labelling precomputed entities and (ordered) subsets of interest.
109109
* @details Used to build the proving key and verification key.
110110
*/
111-
template <typename DataType_> class PrecomputedEntities : public PrecomputedEntitiesBase {
111+
template <typename DataType_> class PrecomputedEntities {
112112
public:
113+
bool operator==(const PrecomputedEntities& other) const = default;
113114
using DataType = DataType_;
114115
DEFINE_FLAVOR_MEMBERS(DataType,
115116
lagrange_first, // column 0
@@ -746,8 +747,9 @@ class ECCVMFlavor {
746747
* resolve that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for
747748
* portability of our circuits.
748749
*/
749-
class VerificationKey : public VerificationKey_<PrecomputedEntities<Commitment>, VerifierCommitmentKey> {
750+
class VerificationKey : public VerificationKey_<uint64_t, PrecomputedEntities<Commitment>, VerifierCommitmentKey> {
750751
public:
752+
bool operator==(const VerificationKey&) const = default;
751753
VerificationKey() = default;
752754
VerificationKey(const size_t circuit_size, const size_t num_public_inputs)
753755
: VerificationKey_(circuit_size, num_public_inputs)

barretenberg/cpp/src/barretenberg/flavor/flavor.hpp

+7-13
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,6 @@
8787

8888
namespace bb {
8989

90-
/**
91-
* @brief Base class template containing circuit-specifying data.
92-
*
93-
*/
94-
class PrecomputedEntitiesBase {
95-
public:
96-
bool operator==(const PrecomputedEntitiesBase& other) const = default;
97-
uint64_t circuit_size;
98-
uint64_t log_circuit_size;
99-
uint64_t num_public_inputs;
100-
};
10190
// Specifies the regions of the execution trace containing non-trivial wire values
10291
struct ActiveRegionData {
10392
void add_range(const size_t start, const size_t end)
@@ -164,18 +153,23 @@ template <typename FF, typename CommitmentKey_> class ProvingKey_ {
164153
/**
165154
* @brief Base verification key class.
166155
*
156+
* @tparam FF_, the type that we will represent our VK metadata (circuit_size, log_circuit_size, num_public_inputs,
157+
* pub_inputs_offset). It will either be uint64_t or a stdlib field type.
167158
* @tparam PrecomputedEntities An instance of PrecomputedEntities_ with affine_element data type and handle type.
168159
* @tparam VerifierCommitmentKey The PCS verification key
169160
*/
170-
template <typename PrecomputedCommitments, typename VerifierCommitmentKey>
161+
template <typename FF_, typename PrecomputedCommitments, typename VerifierCommitmentKey>
171162
class VerificationKey_ : public PrecomputedCommitments {
172163
public:
173164
using FF = typename VerifierCommitmentKey::Curve::ScalarField;
174165
using Commitment = typename VerifierCommitmentKey::Commitment;
175166
std::shared_ptr<VerifierCommitmentKey> pcs_verification_key;
167+
FF_ circuit_size;
168+
FF_ log_circuit_size;
169+
FF_ num_public_inputs;
170+
FF_ pub_inputs_offset = 0;
176171
bool contains_pairing_point_accumulator = false;
177172
PairingPointAccumulatorPubInputIndices pairing_point_accumulator_public_input_indices = {};
178-
uint64_t pub_inputs_offset = 0;
179173

180174
bool operator==(const VerificationKey_&) const = default;
181175
VerificationKey_() = default;

barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_flavor.hpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ template <typename BuilderType> class ECCVMRecursiveFlavor_ {
8787
* portability of our circuits.
8888
*/
8989
class VerificationKey
90-
: public VerificationKey_<ECCVMFlavor::PrecomputedEntities<Commitment>, VerifierCommitmentKey> {
90+
: public VerificationKey_<FF, ECCVMFlavor::PrecomputedEntities<Commitment>, VerifierCommitmentKey> {
9191
public:
9292
VerificationKey(const size_t circuit_size, const size_t num_public_inputs)
9393
{
@@ -108,10 +108,11 @@ template <typename BuilderType> class ECCVMRecursiveFlavor_ {
108108
{
109109
this->pcs_verification_key = std::make_shared<VerifierCommitmentKey>(
110110
builder, native_key->circuit_size, native_key->pcs_verification_key);
111-
this->circuit_size = native_key->circuit_size;
112-
this->log_circuit_size = numeric::get_msb(this->circuit_size);
113-
this->num_public_inputs = native_key->num_public_inputs;
114-
this->pub_inputs_offset = native_key->pub_inputs_offset;
111+
this->circuit_size = FF::from_witness(builder, native_key->circuit_size);
112+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1283): Use stdlib get_msb.
113+
this->log_circuit_size = FF::from_witness(builder, numeric::get_msb(native_key->circuit_size));
114+
this->num_public_inputs = FF::from_witness(builder, native_key->num_public_inputs);
115+
this->pub_inputs_offset = FF::from_witness(builder, native_key->pub_inputs_offset);
115116

116117
for (auto [native_commitment, commitment] : zip_view(native_key->get_all(), this->get_all())) {
117118
commitment = Commitment::from_witness(builder, native_commitment);

barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ ECCVMRecursiveVerifier_<Flavor>::verify_proof(const ECCVMProof& proof)
6868
commitments.z_perm = transcript->template receive_from_prover<Commitment>(commitment_labels.z_perm);
6969

7070
// Execute Sumcheck Verifier
71+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1283): Suspicious get_value().
7172
const size_t log_circuit_size = numeric::get_msb(static_cast<uint32_t>(circuit_size.get_value()));
7273
auto sumcheck = SumcheckVerifier<Flavor>(log_circuit_size, transcript);
7374
const FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");

barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.test.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,11 @@ template <typename RecursiveFlavor> class ECCVMRecursiveTests : public ::testing
110110
}
111111

112112
// Ensure verification key is the same
113-
EXPECT_EQ(verifier.key->circuit_size, verification_key->circuit_size);
114-
EXPECT_EQ(verifier.key->log_circuit_size, verification_key->log_circuit_size);
115-
EXPECT_EQ(verifier.key->num_public_inputs, verification_key->num_public_inputs);
113+
EXPECT_EQ(static_cast<uint64_t>(verifier.key->circuit_size.get_value()), verification_key->circuit_size);
114+
EXPECT_EQ(static_cast<uint64_t>(verifier.key->log_circuit_size.get_value()),
115+
verification_key->log_circuit_size);
116+
EXPECT_EQ(static_cast<uint64_t>(verifier.key->num_public_inputs.get_value()),
117+
verification_key->num_public_inputs);
116118
for (auto [vk_poly, native_vk_poly] : zip_view(verifier.key->get_all(), verification_key->get_all())) {
117119
EXPECT_EQ(vk_poly.get_value(), native_vk_poly);
118120
}

barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ std::array<typename Flavor::GroupElement, 2> DeciderRecursiveVerifier_<Flavor>::
2626

2727
VerifierCommitments commitments{ accumulator->verification_key, accumulator->witness_commitments };
2828

29-
auto sumcheck = Sumcheck(
30-
static_cast<size_t>(accumulator->verification_key->log_circuit_size), transcript, accumulator->target_sum);
29+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1283): fix log_circuit_size usage in stdlib cases.
30+
auto sumcheck = Sumcheck(static_cast<uint32_t>(accumulator->verification_key->log_circuit_size.get_value()),
31+
transcript,
32+
accumulator->target_sum);
3133

3234
SumcheckOutput<Flavor> output =
3335
sumcheck.verify(accumulator->relation_parameters, accumulator->alphas, accumulator->gate_challenges);

barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/oink_recursive_verifier.cpp

+15-9
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,27 @@ template <typename Flavor> void OinkRecursiveVerifier_<Flavor>::verify()
4747
FF public_input_size = transcript->template receive_from_prover<FF>(domain_separator + "public_input_size");
4848
FF pub_inputs_offset = transcript->template receive_from_prover<FF>(domain_separator + "pub_inputs_offset");
4949

50-
if (static_cast<uint32_t>(circuit_size.get_value()) != verification_key->verification_key->circuit_size) {
50+
if (static_cast<uint32_t>(circuit_size.get_value()) !=
51+
static_cast<uint32_t>(verification_key->verification_key->circuit_size.get_value())) {
5152
throw_or_abort("OinkRecursiveVerifier::verify: proof circuit size does not match verification key");
5253
}
53-
if (static_cast<uint32_t>(public_input_size.get_value()) != verification_key->verification_key->num_public_inputs) {
54-
const std::string message = "OinkRecursiveVerifier::verify: proof public input size (" +
55-
std::to_string(static_cast<uint32_t>(public_input_size.get_value())) +
56-
") does not match verification key public input size (" +
57-
std::to_string(verification_key->verification_key->num_public_inputs) + ")";
54+
if (static_cast<uint32_t>(public_input_size.get_value()) !=
55+
static_cast<uint32_t>(verification_key->verification_key->num_public_inputs.get_value())) {
56+
const std::string message =
57+
"OinkRecursiveVerifier::verify: proof public input size (" +
58+
std::to_string(static_cast<uint32_t>(public_input_size.get_value())) +
59+
") does not match verification key public input size (" +
60+
std::to_string(static_cast<uint32_t>(verification_key->verification_key->num_public_inputs.get_value())) +
61+
")";
5862
throw_or_abort(message);
5963
}
60-
if (static_cast<uint32_t>(pub_inputs_offset.get_value()) != verification_key->verification_key->pub_inputs_offset) {
64+
if (static_cast<uint32_t>(pub_inputs_offset.get_value()) !=
65+
static_cast<uint32_t>(verification_key->verification_key->pub_inputs_offset.get_value())) {
6166
throw_or_abort("OinkRecursiveVerifier::verify: proof public input offset does not match verification key");
6267
}
6368

6469
std::vector<FF> public_inputs;
65-
for (size_t i = 0; i < verification_key->verification_key->num_public_inputs; ++i) {
70+
for (size_t i = 0; i < static_cast<size_t>(static_cast<uint32_t>(public_input_size.get_value())); ++i) {
6671
public_inputs.emplace_back(
6772
transcript->template receive_from_prover<FF>(domain_separator + "public_input_" + std::to_string(i)));
6873
}
@@ -109,12 +114,13 @@ template <typename Flavor> void OinkRecursiveVerifier_<Flavor>::verify()
109114
}
110115
}
111116

117+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1283): Suspicious get_value().
112118
const FF public_input_delta = compute_public_input_delta<Flavor>(
113119
public_inputs,
114120
beta,
115121
gamma,
116122
circuit_size,
117-
static_cast<uint32_t>(verification_key->verification_key->pub_inputs_offset));
123+
static_cast<uint32_t>(verification_key->verification_key->pub_inputs_offset.get_value()));
118124

119125
// Get commitment to permutation and lookup grand products
120126
commitments.z_perm = transcript->template receive_from_prover<Commitment>(domain_separator + labels.z_perm);

barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ UltraRecursiveVerifier_<Flavor>::Output UltraRecursiveVerifier_<Flavor>::verify_
104104

105105
// Execute Sumcheck Verifier and extract multivariate opening point u = (u_0, ..., u_{d-1}) and purported
106106
// multivariate evaluations at u
107-
const size_t log_circuit_size = numeric::get_msb(static_cast<uint32_t>(key->circuit_size));
107+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1283): Suspicious get_value().
108+
const size_t log_circuit_size = numeric::get_msb(static_cast<uint32_t>(key->circuit_size.get_value()));
108109
auto sumcheck = Sumcheck(log_circuit_size, transcript);
109110

110111
// Receive commitments to Libra masking polynomials

barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing
128128
RecursiveVerifier verifier{ &outer_circuit, honk_vk };
129129

130130
// Spot check some values in the recursive VK to ensure it was constructed correctly
131-
EXPECT_EQ(verifier.key->circuit_size, honk_vk->circuit_size);
132-
EXPECT_EQ(verifier.key->log_circuit_size, honk_vk->log_circuit_size);
133-
EXPECT_EQ(verifier.key->num_public_inputs, honk_vk->num_public_inputs);
131+
EXPECT_EQ(static_cast<uint64_t>(verifier.key->circuit_size.get_value()), honk_vk->circuit_size);
132+
EXPECT_EQ(static_cast<uint64_t>(verifier.key->log_circuit_size.get_value()), honk_vk->log_circuit_size);
133+
EXPECT_EQ(static_cast<uint64_t>(verifier.key->num_public_inputs.get_value()), honk_vk->num_public_inputs);
134134
for (auto [vk_poly, native_vk_poly] : zip_view(verifier.key->get_all(), honk_vk->get_all())) {
135135
EXPECT_EQ(vk_poly.get_value(), native_vk_poly);
136136
}

barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/recursive_decider_verification_key.hpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,13 @@ template <IsRecursiveFlavor Flavor> class RecursiveDeciderVerificationKey_ {
100100
*/
101101
DeciderVerificationKey get_value()
102102
{
103-
auto native_honk_vk = std::make_shared<NativeVerificationKey>(verification_key->circuit_size,
104-
verification_key->num_public_inputs);
103+
auto native_honk_vk = std::make_shared<NativeVerificationKey>(
104+
static_cast<uint64_t>(verification_key->circuit_size.get_value()),
105+
static_cast<uint64_t>(verification_key->num_public_inputs.get_value()));
105106
native_honk_vk->pcs_verification_key = verification_key->pcs_verification_key == nullptr
106107
? std::make_shared<VerifierCommitmentKey>()
107108
: verification_key->pcs_verification_key;
108-
native_honk_vk->pub_inputs_offset = verification_key->pub_inputs_offset;
109+
native_honk_vk->pub_inputs_offset = static_cast<uint64_t>(verification_key->pub_inputs_offset.get_value());
109110
native_honk_vk->contains_pairing_point_accumulator = verification_key->contains_pairing_point_accumulator;
110111
native_honk_vk->pairing_point_accumulator_public_input_indices =
111112
verification_key->pairing_point_accumulator_public_input_indices;
@@ -120,7 +121,8 @@ template <IsRecursiveFlavor Flavor> class RecursiveDeciderVerificationKey_ {
120121
DeciderVerificationKey decider_vk(native_honk_vk);
121122
decider_vk.is_accumulator = is_accumulator;
122123

123-
decider_vk.public_inputs = std::vector<NativeFF>(static_cast<size_t>(verification_key->num_public_inputs));
124+
decider_vk.public_inputs = std::vector<NativeFF>(
125+
static_cast<size_t>(static_cast<uint32_t>(verification_key->num_public_inputs.get_value())));
124126
for (auto [public_input, inst_public_input] : zip_view(public_inputs, decider_vk.public_inputs)) {
125127
inst_public_input = public_input.get_value();
126128
}

barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/recursive_decider_verification_keys.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ template <IsRecursiveFlavor Flavor_, size_t NUM_> struct RecursiveDeciderVerific
4545
{
4646
size_t max_log_circuit_size{ 0 };
4747
for (auto key : _data) {
48-
max_log_circuit_size =
49-
std::max(max_log_circuit_size, static_cast<size_t>(key->verification_key->log_circuit_size));
48+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1283): Suspicious get_value.
49+
max_log_circuit_size = std::max(
50+
max_log_circuit_size,
51+
static_cast<size_t>(static_cast<uint32_t>(key->verification_key->log_circuit_size.get_value())));
5052
}
5153
return max_log_circuit_size;
5254
}

barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_flavor.hpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ template <typename BuilderType> class TranslatorRecursiveFlavor_ {
9393
* portability of our circuits.
9494
*/
9595
class VerificationKey
96-
: public VerificationKey_<TranslatorFlavor::PrecomputedEntities<Commitment>, VerifierCommitmentKey> {
96+
: public VerificationKey_<FF, TranslatorFlavor::PrecomputedEntities<Commitment>, VerifierCommitmentKey> {
9797
public:
9898
VerificationKey(const size_t circuit_size, const size_t num_public_inputs)
9999
{
@@ -105,10 +105,11 @@ template <typename BuilderType> class TranslatorRecursiveFlavor_ {
105105
VerificationKey(CircuitBuilder* builder, const std::shared_ptr<NativeVerificationKey>& native_key)
106106
{
107107
this->pcs_verification_key = std::make_shared<VerifierCommitmentKey>(); // ?
108-
this->circuit_size = native_key->circuit_size;
109-
this->log_circuit_size = numeric::get_msb(this->circuit_size);
110-
this->num_public_inputs = native_key->num_public_inputs;
111-
this->pub_inputs_offset = native_key->pub_inputs_offset;
108+
this->circuit_size = FF::from_witness(builder, native_key->circuit_size);
109+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1283): Use stdlib get_msb.
110+
this->log_circuit_size = numeric::get_msb(native_key->circuit_size);
111+
this->num_public_inputs = FF::from_witness(builder, native_key->num_public_inputs);
112+
this->pub_inputs_offset = FF::from_witness(builder, native_key->pub_inputs_offset);
112113

113114
for (auto [native_comm, comm] : zip_view(native_key->get_all(), this->get_all())) {
114115
comm = Commitment::from_witness(builder, native_comm);

barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ std::array<typename Flavor::GroupElement, 2> TranslatorRecursiveVerifier_<Flavor
7777
CommitmentLabels commitment_labels;
7878

7979
const FF circuit_size = transcript->template receive_from_prover<FF>("circuit_size");
80-
if (static_cast<uint32_t>(circuit_size.get_value()) != key->circuit_size) {
80+
if (static_cast<uint32_t>(circuit_size.get_value()) != static_cast<uint32_t>(key->circuit_size.get_value())) {
8181
throw_or_abort(
8282
"TranslatorRecursiveVerifier::verify_proof: proof circuit size does not match verification key!");
8383
}
@@ -104,6 +104,7 @@ std::array<typename Flavor::GroupElement, 2> TranslatorRecursiveVerifier_<Flavor
104104
commitments.z_perm = transcript->template receive_from_prover<Commitment>(commitment_labels.z_perm);
105105

106106
// Execute Sumcheck Verifier
107+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1283): Suspicious get_value().
107108
const size_t log_circuit_size = numeric::get_msb(static_cast<uint32_t>(circuit_size.get_value()));
108109
auto sumcheck = Sumcheck(log_circuit_size, transcript);
109110
FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");

barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,11 @@ template <typename RecursiveFlavor> class TranslatorRecursiveTests : public ::te
108108
<< "Recursive Verifier/Verifier manifest discrepency in round " << i;
109109
}
110110

111-
EXPECT_EQ(verifier.key->circuit_size, verification_key->circuit_size);
112-
EXPECT_EQ(verifier.key->log_circuit_size, verification_key->log_circuit_size);
113-
EXPECT_EQ(verifier.key->num_public_inputs, verification_key->num_public_inputs);
111+
EXPECT_EQ(static_cast<uint64_t>(verifier.key->circuit_size.get_value()), verification_key->circuit_size);
112+
EXPECT_EQ(static_cast<uint64_t>(verifier.key->log_circuit_size.get_value()),
113+
verification_key->log_circuit_size);
114+
EXPECT_EQ(static_cast<uint64_t>(verifier.key->num_public_inputs.get_value()),
115+
verification_key->num_public_inputs);
114116
for (auto [vk_poly, native_vk_poly] : zip_view(verifier.key->get_all(), verification_key->get_all())) {
115117
EXPECT_EQ(vk_poly.get_value(), native_vk_poly);
116118
}

barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class MegaFlavor {
103103
* @brief A base class labelling precomputed entities and (ordered) subsets of interest.
104104
* @details Used to build the proving key and verification key.
105105
*/
106-
template <typename DataType_> class PrecomputedEntities : public PrecomputedEntitiesBase {
106+
template <typename DataType_> class PrecomputedEntities {
107107
public:
108108
bool operator==(const PrecomputedEntities&) const = default;
109109
using DataType = DataType_;
@@ -429,7 +429,7 @@ class MegaFlavor {
429429
* circuits.
430430
* @todo TODO(https://github.com/AztecProtocol/barretenberg/issues/876)
431431
*/
432-
class VerificationKey : public VerificationKey_<PrecomputedEntities<Commitment>, VerifierCommitmentKey> {
432+
class VerificationKey : public VerificationKey_<uint64_t, PrecomputedEntities<Commitment>, VerifierCommitmentKey> {
433433
public:
434434
// Data pertaining to transfer of databus return data via public inputs of the proof being recursively verified
435435
DatabusPropagationData databus_propagation_data;

0 commit comments

Comments
 (0)