3#include "barretenberg/common/serialize.hpp"
4#include "barretenberg/crypto/blake3s/blake3s.hpp"
5#include "barretenberg/crypto/pedersen_hash/pedersen.hpp"
12template <
typename T,
typename... U>
13concept Loggable = (std::same_as<T, barretenberg::fr> || std::same_as<T, grumpkin::fr> ||
14 std::same_as<T, barretenberg::g1::affine_element> ||
15 std::same_as<T, grumpkin::g1::affine_element> || std::same_as<T, uint32_t>);
20 std::vector<std::string> challenge_label;
21 std::vector<std::pair<std::string, size_t>> entries;
23 bool operator==(
const RoundData& other)
const =
default;
26 std::map<size_t, RoundData> manifest;
31 for (
auto& round : manifest) {
32 info(
"Round: ", round.first);
33 for (
auto& label : round.second.challenge_label) {
34 info(
"\tchallenge: ", label);
36 for (
auto& entry : round.second.entries) {
37 info(
"\telement (", entry.second,
"): ", entry.first);
42 template <
typename... Strings>
void add_challenge(
size_t round, Strings&... labels)
44 manifest[round].challenge_label = { labels... };
46 void add_entry(
size_t round,
const std::string& element_label,
size_t element_size)
48 manifest[round].entries.emplace_back(element_label, element_size);
51 [[nodiscard]]
size_t size()
const {
return manifest.size(); }
53 RoundData operator[](
const size_t& round) {
return manifest[round]; };
64 using Proof = std::vector<uint8_t>;
74 : proof_data(proof_data.begin(), proof_data.end())
76 static constexpr size_t HASH_OUTPUT_SIZE = 32;
78 std::ptrdiff_t proof_start = 0;
79 size_t num_bytes_written = 0;
80 size_t num_bytes_read = 0;
81 size_t round_number = 0;
84 static constexpr size_t MIN_BYTES_PER_CHALLENGE = 128 / 8;
85 bool is_first_challenge =
true;
86 std::array<uint8_t, HASH_OUTPUT_SIZE> previous_challenge_buffer{};
87 std::vector<uint8_t> current_round_data;
90 TranscriptManifest manifest;
100 [[nodiscard]] std::array<uint8_t, HASH_OUTPUT_SIZE> get_next_challenge_buffer()
104 if (is_first_challenge) {
105 ASSERT(!current_round_data.empty());
112 std::vector<uint8_t> full_buffer;
113 if (!is_first_challenge) {
115 full_buffer.insert(full_buffer.end(), previous_challenge_buffer.begin(), previous_challenge_buffer.end());
118 is_first_challenge =
false;
120 if (!current_round_data.empty()) {
121 full_buffer.insert(full_buffer.end(), current_round_data.begin(), current_round_data.end());
122 current_round_data.clear();
132 auto base_hash = blake3::blake3s(compressed_buffer);
134 std::array<uint8_t, HASH_OUTPUT_SIZE> new_challenge_buffer;
135 std::copy_n(base_hash.begin(), HASH_OUTPUT_SIZE, new_challenge_buffer.begin());
137 previous_challenge_buffer = new_challenge_buffer;
138 return new_challenge_buffer;
151 manifest.add_entry(round_number, label, element_bytes.size());
153 current_round_data.insert(current_round_data.end(), element_bytes.begin(), element_bytes.end());
155 num_bytes_written += element_bytes.size();
168 auto element_bytes = to_buffer(element);
169 proof_data.insert(proof_data.end(), element_bytes.begin(), element_bytes.end());
182 constexpr size_t element_size =
sizeof(T);
183 ASSERT(offset + element_size <= proof_data.size());
185 auto element_bytes = std::span{ proof_data }.subspan(offset, element_size);
186 offset += element_size;
188 T element = from_buffer<T>(element_bytes);
203 std::vector<uint8_t> result(num_bytes_written);
204 std::copy_n(proof_data.begin() + proof_start, num_bytes_written, result.begin());
205 proof_start +=
static_cast<std::ptrdiff_t
>(num_bytes_written);
206 num_bytes_written = 0;
210 void load_proof(
const std::vector<uint8_t>& proof)
212 std::copy(proof.begin(), proof.end(), std::back_inserter(proof_data));
228 constexpr size_t num_challenges =
sizeof...(Strings);
231 manifest.add_challenge(round_number, labels...);
236 std::array<uint256_t, num_challenges> challenges{};
239 for (
size_t i = 0; i < num_challenges; i++) {
240 auto next_challenge_buffer = get_next_challenge_buffer();
241 std::array<uint8_t,
sizeof(
uint256_t)> field_element_buffer{};
245 std::copy_n(next_challenge_buffer.begin(),
246 HASH_OUTPUT_SIZE / 2,
247 field_element_buffer.begin() + HASH_OUTPUT_SIZE / 2);
248 challenges[i] = from_buffer<uint256_t>(field_element_buffer);
272 using serialize::write;
276 auto element_bytes = to_buffer(element);
277 proof_data.insert(proof_data.end(), element_bytes.begin(), element_bytes.end());
279#ifdef LOG_INTERACTIONS
281 info(
"sent: ", label,
": ", element);
295 constexpr size_t element_size =
sizeof(T);
296 ASSERT(num_bytes_read + element_size <= proof_data.size());
298 auto element_bytes = std::span{ proof_data }.subspan(num_bytes_read, element_size);
299 num_bytes_read += element_size;
303 T element = from_buffer<T>(element_bytes);
305#ifdef LOG_INTERACTIONS
307 info(
"received: ", label,
": ", element);
321 auto transcript = std::make_shared<BaseTranscript>();
322 constexpr uint32_t init{ 42 };
323 transcript->send_to_verifier(
"Init", init);
334 static std::shared_ptr<BaseTranscript>
verifier_init_empty(
const std::shared_ptr<BaseTranscript>& transcript)
336 auto verifier_transcript = std::make_shared<BaseTranscript>(transcript->proof_data);
337 [[maybe_unused]]
auto _ = verifier_transcript->template receive_from_prover<uint32_t>(
"Init");
338 return verifier_transcript;
341 uint256_t get_challenge(
const std::string& label)
344#if defined LOG_CHALLENGES || defined LOG_INTERACTIONS
345 info(
"challenge: ", label,
": ", result);
350 [[nodiscard]] TranscriptManifest get_manifest()
const {
return manifest; };
352 void print() { manifest.print(); }
362 std::array<FF, N> result;
363 std::move(arr.begin(), arr.end(), result.begin());
static Fq hash_buffer(const std::vector< uint8_t > &input, GeneratorContext context={})
Given an arbitrary length of bytes, convert them to fields and hash the result using the default gene...
Definition: pedersen.cpp:69
Definition: uint256.hpp:25
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
Definition: transcript.hpp:62
T deserialize_from_buffer(const Proof &proof_data, size_t &offset) const
Deserializes the bytes starting at offset into the typed element and returns that element.
Definition: transcript.hpp:180
void consume_prover_element_bytes(const std::string &label, std::span< const uint8_t > element_bytes)
Adds challenge elements to the current_round_buffer and updates the manifest.
Definition: transcript.hpp:148
void serialize_to_buffer(const T &element, Proof &proof_data)
Serializes object and appends it to proof_data.
Definition: transcript.hpp:166
std::array< uint256_t, sizeof...(Strings)> get_challenges(const Strings &... labels)
After all the prover messages have been sent, finalize the round by hashing all the data and then cre...
Definition: transcript.hpp:226
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.
Definition: transcript.hpp:270
static std::shared_ptr< BaseTranscript > prover_init_empty()
For testing: initializes transcript with some arbitrary data so that a challenge can be generated aft...
Definition: transcript.hpp:319
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.
Definition: transcript.hpp:293
static std::shared_ptr< BaseTranscript > verifier_init_empty(const std::shared_ptr< BaseTranscript > &transcript)
For testing: initializes transcript based on proof data then receives junk data produced by BaseTrans...
Definition: transcript.hpp:334
BaseTranscript(const Proof &proof_data)
Construct a new Base Transcript object for Verifier using proof_data.
Definition: transcript.hpp:73
std::vector< uint8_t > export_proof()
Return the proof data starting at proof_start.
Definition: transcript.hpp:201
Definition: transcript.hpp:18
Definition: transcript.hpp:13
Defines particular circuit builder types expected to be used for circuit construction in stdlib and c...
Definition: claim.hpp:6
std::array< FF, N > challenges_to_field_elements(std::array< T, N > &&arr)
Convert an array of uint256_t's to an array of field elements.
Definition: transcript.hpp:360