-
Notifications
You must be signed in to change notification settings - Fork 594
Expand file tree
/
Copy pathgraph_description_goblin.test.cpp
More file actions
136 lines (114 loc) · 6.34 KB
/
graph_description_goblin.test.cpp
File metadata and controls
136 lines (114 loc) · 6.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "barretenberg/boomerang_value_detection/graph.hpp"
#include "barretenberg/circuit_checker/circuit_checker.hpp"
#include "barretenberg/common/test.hpp"
#include "barretenberg/goblin/goblin.hpp"
#include "barretenberg/goblin/goblin_verifier.hpp"
#include "barretenberg/goblin/merge_prover.hpp"
#include "barretenberg/goblin/mock_circuits.hpp"
#include "barretenberg/srs/global_crs.hpp"
#include "barretenberg/stdlib/honk_verifier/ultra_verification_keys_comparator.hpp"
#include "barretenberg/ultra_honk/ultra_prover.hpp"
#include "barretenberg/ultra_honk/ultra_verifier.hpp"
namespace bb::stdlib::recursion::honk {
class BoomerangGoblinRecursiveVerifierTests : public testing::Test {
public:
using Builder = UltraCircuitBuilder;
using ECCVMVK = Goblin::ECCVMVerificationKey;
using TranslatorVK = Goblin::TranslatorVerificationKey;
using OuterFlavor = UltraFlavor;
using OuterProver = UltraProver_<OuterFlavor>;
using OuterVerifier = UltraRollupVerifier;
using OuterProverInstance = ProverInstance_<OuterFlavor>;
using Commitment = MergeVerifier::Commitment;
using MergeCommitments = MergeVerifier::InputCommitments;
using RecursiveCommitment = GoblinRecursiveVerifier::MergeVerifier::Commitment;
using RecursiveMergeCommitments = GoblinRecursiveVerifier::MergeVerifier::InputCommitments;
static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); }
struct ProverOutput {
GoblinProof proof;
Goblin::VerificationKey verifier_input;
MergeCommitments merge_commitments;
};
/**
* @brief Create a goblin proof and the VM verification keys needed by the goblin recursive verifier
*
* @return ProverOutput
*/
static ProverOutput create_goblin_prover_output()
{
Goblin goblin;
GoblinMockCircuits::construct_and_merge_mock_circuits(goblin, 5);
// Merge the ecc ops from the newly constructed circuit
auto goblin_proof = goblin.prove();
// Subtable values and commitments - needed for (Recursive)MergeVerifier
MergeCommitments merge_commitments;
auto t_current = goblin.op_queue->construct_current_ultra_ops_subtable_columns();
auto T_prev = goblin.op_queue->construct_previous_ultra_ops_table_columns();
MergeProver::shift_table_by_disabled_rows(t_current);
MergeProver::shift_table_by_disabled_rows(T_prev);
CommitmentKey<curve::BN254> pcs_commitment_key(goblin.op_queue->get_ultra_ops_table_num_rows() +
MergeProver::TRACE_OFFSET);
for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) {
merge_commitments.t_commitments[idx] = pcs_commitment_key.commit(t_current[idx]);
merge_commitments.T_prev_commitments[idx] = pcs_commitment_key.commit(T_prev[idx]);
}
// Output is a goblin proof plus ECCVM/Translator verification keys
return { goblin_proof, { std::make_shared<ECCVMVK>(), std::make_shared<TranslatorVK>() }, merge_commitments };
}
};
/**
* @brief Construct and check a goblin recursive verification circuit
*
*/
TEST_F(BoomerangGoblinRecursiveVerifierTests, graph_description_basic)
{
auto [proof, verifier_input, merge_commitments] = create_goblin_prover_output();
Builder builder;
// Merge commitments
RecursiveMergeCommitments recursive_merge_commitments;
for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) {
recursive_merge_commitments.t_commitments[idx] =
RecursiveCommitment::from_witness(&builder, merge_commitments.t_commitments[idx]);
recursive_merge_commitments.T_prev_commitments[idx] =
RecursiveCommitment::from_witness(&builder, merge_commitments.T_prev_commitments[idx]);
recursive_merge_commitments.t_commitments[idx].unset_free_witness_tag();
recursive_merge_commitments.T_prev_commitments[idx].unset_free_witness_tag();
}
auto transcript = std::make_shared<GoblinRecursiveVerifier::Transcript>();
GoblinStdlibProof stdlib_proof(builder, proof);
GoblinRecursiveVerifier verifier{ transcript, stdlib_proof, recursive_merge_commitments, MergeSettings::APPEND };
GoblinRecursiveVerifier::ReductionResult output = verifier.reduce_to_pairing_check_and_ipa_opening();
// Aggregate merge + translator pairing points
output.translator_pairing_points.aggregate(output.merge_pairing_points);
stdlib::recursion::honk::RollupIO inputs;
inputs.pairing_inputs = output.translator_pairing_points;
inputs.ipa_claim = output.ipa_claim;
inputs.set_public();
builder.ipa_proof = output.ipa_proof.get_value();
// Use the already aggregated pairing points (merge + translator)
auto translator_pairing_points = output.translator_pairing_points;
// The pairing points are public outputs from the recursive verifier that will be verified externally via a pairing
// check. While they are computed within the circuit (via batch_mul for P0 and negation for P1), their output
// coordinates may not appear in multiple constraint gates. Calling fix_witness() adds explicit constraints on these
// values. Without these constraints, the StaticAnalyzer detects 20 variables (the coordinate limbs) that appear in
// only one gate. This ensures the pairing point coordinates are properly constrained within the circuit itself,
// rather than relying solely on them being public outputs.
translator_pairing_points.fix_witness();
// Construct and verify a proof for the Goblin Recursive Verifier circuit
{
auto prover_instance = std::make_shared<OuterProverInstance>(builder);
auto verification_key =
std::make_shared<typename OuterFlavor::VerificationKey>(prover_instance->get_precomputed());
auto vk_and_hash = std::make_shared<typename OuterFlavor::VKAndHash>(verification_key);
OuterProver prover(prover_instance, verification_key);
OuterVerifier verifier(vk_and_hash);
auto proof = prover.construct_proof();
bool verified = verifier.verify_proof(proof).result;
ASSERT_TRUE(verified);
}
info("Recursive Verifier: num gates = ", builder.num_gates());
auto graph = cdg::StaticAnalyzer(builder, false);
auto variables_in_one_gate = graph.get_variables_in_one_gate();
EXPECT_EQ(variables_in_one_gate.size(), 0);
}
} // namespace bb::stdlib::recursion::honk