Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
transcript.test.cpp
Go to the documentation of this file.
2#include <gtest/gtest.h>
3
4using namespace bb;
5
6using FF = bb::fr;
7using Fr = bb::fr;
8using Fq = bb::fq;
9
11 public:
13 {
14 // Modify the integer value in the proof data.
15 proof_data.back() += 1;
16 }
17};
18
23TEST(NativeTranscript, TwoProversTwoFields)
24{
25 const auto EXPECT_PROVER_STATE = [](const TestTranscript& transcript, size_t start, size_t written) {
26 EXPECT_EQ(transcript.proof_start, static_cast<std::ptrdiff_t>(start));
27 EXPECT_EQ(transcript.num_frs_written, written);
28 };
29 const auto EXPECT_VERIFIER_STATE =
30 [](const TestTranscript& verifier_transcript, size_t read, size_t proof_size = 0) {
31 EXPECT_EQ(verifier_transcript.num_frs_read, read);
32 if (proof_size != 0) {
33 EXPECT_EQ(verifier_transcript.num_frs_read, proof_size);
34 }
35 };
36
37 TestTranscript prover_transcript;
38 // state initializes to zero
39
40 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 0, /*written*/ 0);
41 Fr elt_a = 1377;
42 prover_transcript.send_to_verifier("a", elt_a);
43 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 0, /*written*/ 1);
44 TestTranscript verifier_transcript;
45 verifier_transcript.load_proof(prover_transcript.export_proof());
46 // export resets read/write state and sets start in prep for next export
47 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 1, /*written*/ 0);
48 // state initializes to zero
49 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 0);
50 Fr received_a = verifier_transcript.receive_from_prover<Fr>("a");
51 // receiving is reading frs input and writing them to an internal proof_data buffer
52 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 1, prover_transcript.size_proof_data());
53 EXPECT_EQ(received_a, elt_a);
54
55 { // send grumpkin::fr
56 Fq elt_b = 773;
57 prover_transcript.send_to_verifier("b", elt_b);
58 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 1, /*written*/ 2);
59 verifier_transcript.load_proof(prover_transcript.export_proof());
60 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 3, /*written*/ 0);
61 // load proof is not an action by a prover or verifier, so it does not change read/write counts
62 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 1);
63 Fq received_b = verifier_transcript.receive_from_prover<Fq>("b");
64 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 3, prover_transcript.size_proof_data());
65 EXPECT_EQ(received_b, elt_b);
66 }
67 { // send uint32_t
68 uint32_t elt_c = 43;
69 prover_transcript.send_to_verifier("c", elt_c);
70 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 3, /*written*/ 1);
71 verifier_transcript.load_proof(prover_transcript.export_proof());
72 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 4, /*written*/ 0);
73 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 3);
74 auto received_c = verifier_transcript.receive_from_prover<uint32_t>("c");
75 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 4, prover_transcript.size_proof_data());
76 EXPECT_EQ(received_c, elt_c);
77 }
78 { // send curve::BN254::AffineElement
80 prover_transcript.send_to_verifier("d", elt_d);
81 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 4, /*written*/ 4);
82 verifier_transcript.load_proof(prover_transcript.export_proof());
83 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 8, /*written*/ 0);
84 auto received_d = verifier_transcript.receive_from_prover<curve::BN254::AffineElement>("d");
85 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 8, prover_transcript.size_proof_data());
86 EXPECT_EQ(received_d, elt_d);
87 }
88 { // send std::array<bb::fr, 4>
89 std::array<bb::fr, 5> elt_e = { 1, 2, 3, 4, 5 };
90 prover_transcript.send_to_verifier("e", elt_e);
91 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 8, /*written*/ 5);
92 verifier_transcript.load_proof(prover_transcript.export_proof());
93 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 13, /*written*/ 0);
94 auto received_e = verifier_transcript.receive_from_prover<std::array<bb::fr, 5>>("e");
95 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 13);
96 EXPECT_EQ(received_e, elt_e);
97 }
98 { // send std::array<grumpkin::fr>
99 std::array<grumpkin::fr, 7> elt_f = { 9, 12515, 1231, 745, 124, 6231, 957 };
100 prover_transcript.send_to_verifier("f", elt_f);
101 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 13, /*written*/ 14);
102 verifier_transcript.load_proof(prover_transcript.export_proof());
103 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 27, /*written*/ 0);
104 auto received_f = verifier_transcript.receive_from_prover<std::array<grumpkin::fr, 7>>("f");
105 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 27);
106 EXPECT_EQ(received_f, elt_f);
107 }
108 { // send Univariate<bb::fr>
109 bb::Univariate<bb::fr, 4> elt_g{ std::array<bb::fr, 4>({ 5, 6, 7, 8 }) };
110 prover_transcript.send_to_verifier("g", elt_g);
111 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 27, /*written*/ 4);
112 verifier_transcript.load_proof(prover_transcript.export_proof());
113 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 31, /*written*/ 0);
114 auto received_g = verifier_transcript.receive_from_prover<bb::Univariate<bb::fr, 4>>("g");
115 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 31);
116 EXPECT_EQ(received_g, elt_g);
117 }
118 { // send Univariate<grumpkin::fr>
120 prover_transcript.send_to_verifier("h", elt_h);
121 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 31, /*written*/ 6);
122 verifier_transcript.load_proof(prover_transcript.export_proof());
123 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 37, /*written*/ 0);
124 auto received_h = verifier_transcript.receive_from_prover<bb::Univariate<grumpkin::fr, 3>>("h");
125 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 37);
126 EXPECT_EQ(received_h, elt_h);
127 }
128 { // send curve::Grumpkin::AffineElement
130 prover_transcript.send_to_verifier("i", elt_i);
131 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 37, /*written*/ 2);
132 verifier_transcript.load_proof(prover_transcript.export_proof());
133 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 39, /*written*/ 0);
134 auto received_i = verifier_transcript.receive_from_prover<curve::Grumpkin::AffineElement>("i");
135 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 39);
136 EXPECT_EQ(received_i, elt_i);
137 }
138 { // send curve::Grumpkin::AffineElement point at infinity
140 elt_j.self_set_infinity();
141 prover_transcript.send_to_verifier("j", elt_j);
142 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 39, /*written*/ 2);
143 verifier_transcript.load_proof(prover_transcript.export_proof());
144 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 41, /*written*/ 0);
145 auto received_j = verifier_transcript.receive_from_prover<curve::Grumpkin::AffineElement>("j");
146 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 41);
147 EXPECT_TRUE(received_j.is_point_at_infinity());
148 EXPECT_EQ(received_j, elt_j);
149 }
150 { // send curve::BN254::AffineElement point at infinity
152 elt_k.self_set_infinity();
153 prover_transcript.send_to_verifier("k", elt_k);
154 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 41, /*written*/ 4);
155 verifier_transcript.load_proof(prover_transcript.export_proof());
156 EXPECT_PROVER_STATE(prover_transcript, /*start*/ 45, /*written*/ 0);
157 auto received_k = verifier_transcript.receive_from_prover<curve::BN254::AffineElement>("k");
158 EXPECT_VERIFIER_STATE(verifier_transcript, /*read*/ 45);
159 EXPECT_TRUE(received_k.is_point_at_infinity());
160 EXPECT_EQ(received_k, elt_k);
161 }
162}
163
168TEST(NativeTranscript, ConsumeElement)
169{
170 TestTranscript prover_transcript, verifier_transcript;
171 prover_transcript.add_to_hash_buffer("a", Fr(1));
172 verifier_transcript.add_to_hash_buffer("a", Fr(1));
173 auto prover_chal = prover_transcript.get_challenge<Fr>("alpha");
174 auto verifier_chal = verifier_transcript.get_challenge<Fr>("alpha");
175 EXPECT_EQ(prover_chal, verifier_chal);
176}
177
182TEST(NativeTranscript, MultipleProversWithAddToHashBuffer)
183{
184
185 // Populate prover and verifier transcripts. Make sure that some elements are hashed without being placed into the
186 // proof data, i.e. use `add_to_hash_buffer()` method.
187 auto simulate_transcript_interaction_with_multiple_provers = [](const size_t num_proof_exports,
188 TestTranscript& prover_transcript,
189 TestTranscript& verifier_transcript,
190 bool tampered_transcript = false) {
191 for (size_t idx = 0; idx < num_proof_exports; idx++) {
192
193 // Mock current prover transcript actions.
194 prover_transcript.add_to_hash_buffer("vk_field", Fr(1));
195 prover_transcript.send_to_verifier<uint32_t>("integer", 5);
196
197 if (tampered_transcript) {
198 // Modify the integer value in the proof data.
199 prover_transcript.tamper_proof_data();
200 }
201
202 prover_transcript.send_to_verifier("random_field_element", Fr::random_element());
203 prover_transcript.send_to_verifier("random_Grumpkin_point",
204 curve::Grumpkin::AffineElement::random_element());
205 prover_transcript.send_to_verifier("random_bn254_point", curve::BN254::AffineElement::random_element());
206
207 const Fr prover_challenge = prover_transcript.get_challenge<Fr>("alpha");
208
209 // Mock the verifier logic.
210 verifier_transcript.load_proof(prover_transcript.export_proof());
211 verifier_transcript.add_to_hash_buffer("vk_field", Fr(1));
212 verifier_transcript.receive_from_prover<Fr>("random_field_element");
213 verifier_transcript.receive_from_prover<uint32_t>("integer");
214 const Fr verifier_challenge = verifier_transcript.get_challenge<Fr>("alpha");
215
216 verifier_transcript.receive_from_prover<curve::Grumpkin::AffineElement>("random_Grumpkin_point");
217 verifier_transcript.receive_from_prover<curve::BN254::AffineElement>("random_bn254_point");
218
219 EXPECT_FALSE(prover_challenge == verifier_challenge);
220 };
221 };
222
223 // Test valid transcript data
224 for (size_t num_proof_exports = 2; num_proof_exports < 5; num_proof_exports++) {
225 TestTranscript prover_transcript;
226 TestTranscript verifier_transcript;
227 simulate_transcript_interaction_with_multiple_provers(
228 num_proof_exports, prover_transcript, verifier_transcript);
229 }
230
231 // Test tampered transcript data
232 TestTranscript prover_transcript;
233 TestTranscript verifier_transcript;
234 simulate_transcript_interaction_with_multiple_provers(
235 /*num_proof_exports=*/2, prover_transcript, verifier_transcript, true);
236}
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
T receive_from_prover(const std::string &label)
Reads the next element of type T from the transcript, with a predefined label, only used by verifier.
void load_proof(const std::vector< DataType > &proof)
void add_to_hash_buffer(const std::string &label, const T &element)
Adds an element to the transcript.
std::vector< DataType > export_proof()
Return the proof data starting at proof_start.
void send_to_verifier(const std::string &label, const T &element)
Adds a prover message to the transcript, only intended to be used by the prover.
std::ptrdiff_t proof_start
size_t size_proof_data()
Return the size of proof_data.
ChallengeType get_challenge(const std::string &label)
A univariate polynomial represented by its values on {domain_start, domain_start + 1,...
typename Group::affine_element AffineElement
Definition bn254.hpp:22
typename Group::affine_element AffineElement
Definition grumpkin.hpp:56
constexpr void self_set_infinity() noexcept
static constexpr affine_element affine_one
Definition group.hpp:48
Entry point for Barretenberg command-line interface.
void read(B &it, field2< base_field, Params > &value)
field< Bn254FqParams > fq
Definition fq.hpp:169
TEST(MegaCircuitBuilder, CopyConstructor)
typename Flavor::FF FF
field< Bn254FrParams > fr
Definition fr.hpp:174
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static field random_element(numeric::RNG *engine=nullptr) noexcept
bb::fr Fr