Skip to content

Commit

Permalink
feat: derive transcript structure between non-zk and zk flavors and b…
Browse files Browse the repository at this point in the history
…etween Ultra and UltraKeccak (#11086)

The Transcript Classes were duplicated between base and derived flavors
which resulted at times in inconsistencies. This PR addresses the issue:
* ZK flavors' Transcript is now a derived class of the corresponding
non-ZK Transcript class
* `UltraFlavor` Transcript is now templated so in UltraKeccak we can
just instantiate it with different parameters corresponding to Keccak
rather than duplicate it.
 * the transcript tests are run for all flavor variations.
  • Loading branch information
maramihali authored Jan 7, 2025
1 parent fed44a5 commit 48286c6
Show file tree
Hide file tree
Showing 19 changed files with 581 additions and 331 deletions.
10 changes: 6 additions & 4 deletions barretenberg/cpp/src/barretenberg/flavor/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 +322,11 @@ template <typename Tuple> constexpr auto create_tuple_of_arrays_of_values()
// Forward declare honk flavors
namespace bb {
class UltraFlavor;
class UltraFlavorWithZK;
class UltraZKFlavor;
class UltraRollupFlavor;
class ECCVMFlavor;
class UltraKeccakFlavor;
class UltraKeccakZKFlavor;
class MegaFlavor;
class MegaZKFlavor;
class TranslatorFlavor;
Expand Down Expand Up @@ -361,10 +362,10 @@ template <typename T>
concept IsPlonkFlavor = IsAnyOf<T, plonk::flavor::Standard, plonk::flavor::Ultra>;

template <typename T>
concept IsUltraPlonkOrHonk = IsAnyOf<T, plonk::flavor::Ultra, UltraFlavor, UltraKeccakFlavor, UltraFlavorWithZK, UltraRollupFlavor, MegaFlavor, MegaZKFlavor>;
concept IsUltraPlonkOrHonk = IsAnyOf<T, plonk::flavor::Ultra, UltraFlavor, UltraKeccakFlavor,UltraKeccakZKFlavor, UltraZKFlavor, UltraRollupFlavor, MegaFlavor, MegaZKFlavor>;

template <typename T>
concept IsUltraFlavor = IsAnyOf<T, UltraFlavor, UltraKeccakFlavor, UltraFlavorWithZK, UltraRollupFlavor, MegaFlavor, MegaZKFlavor>;
concept IsUltraFlavor = IsAnyOf<T, UltraFlavor, UltraKeccakFlavor,UltraKeccakZKFlavor, UltraZKFlavor, UltraRollupFlavor, MegaFlavor, MegaZKFlavor>;

template <typename T>
concept IsMegaFlavor = IsAnyOf<T, MegaFlavor, MegaZKFlavor,
Expand Down Expand Up @@ -403,8 +404,9 @@ template <typename T> concept IsECCVMRecursiveFlavor = IsAnyOf<T, ECCVMRecursive
template <typename T> concept IsFoldingFlavor = IsAnyOf<T, UltraFlavor,
// Note(md): must be here to use oink prover
UltraKeccakFlavor,
UltraKeccakZKFlavor,
UltraRollupFlavor,
UltraFlavorWithZK,
UltraZKFlavor,
MegaFlavor,
MegaZKFlavor,
UltraRecursiveFlavor_<UltraCircuitBuilder>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,7 @@ class MegaFlavor {
* Note: Made generic for use in MegaRecursive.
* TODO(https://github.com/AztecProtocol/barretenberg/issues/877): Remove this Commitment template parameter
*/
template <typename Commitment> class Transcript_ : public NativeTranscript {
class Transcript : public NativeTranscript {
public:
uint32_t circuit_size;
uint32_t public_input_size;
Expand Down Expand Up @@ -887,23 +887,23 @@ class MegaFlavor {
Commitment shplonk_q_comm;
Commitment kzg_w_comm;

Transcript_() = default;
Transcript() = default;

Transcript_(const HonkProof& proof)
Transcript(const HonkProof& proof)
: NativeTranscript(proof)
{}

static std::shared_ptr<Transcript_> prover_init_empty()
static std::shared_ptr<Transcript> prover_init_empty()
{
auto transcript = std::make_shared<Transcript_>();
auto transcript = std::make_shared<Transcript>();
constexpr uint32_t init{ 42 }; // arbitrary
transcript->send_to_verifier("Init", init);
return transcript;
};

static std::shared_ptr<Transcript_> verifier_init_empty(const std::shared_ptr<Transcript_>& transcript)
static std::shared_ptr<Transcript> verifier_init_empty(const std::shared_ptr<Transcript>& transcript)
{
auto verifier_transcript = std::make_shared<Transcript_>(transcript->proof_data);
auto verifier_transcript = std::make_shared<Transcript>(transcript->proof_data);
[[maybe_unused]] auto _ = verifier_transcript->template receive_from_prover<uint32_t>("Init");
return verifier_transcript;
};
Expand Down Expand Up @@ -1010,8 +1010,6 @@ class MegaFlavor {
ASSERT(proof_data.size() == old_proof_length);
}
};
// Specialize for Mega (general case used in MegaRecursive).
using Transcript = Transcript_<Commitment>;
};

} // namespace bb

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,10 @@ class UltraFlavor {
* @brief Derived class that defines proof structure for Ultra proofs, as well as supporting functions.
*
*/
class Transcript : public NativeTranscript {
template <typename Params> class Transcript_ : public BaseTranscript<Params> {
public:
using Base = BaseTranscript<Params>;

// Transcript objects defined as public member variables for easy access and modification
uint32_t circuit_size;
uint32_t public_input_size;
Expand All @@ -719,24 +721,24 @@ class UltraFlavor {
std::vector<FF> gemini_fold_evals;
Commitment shplonk_q_comm;
Commitment kzg_w_comm;
Transcript() = default;
Transcript_() = default;

// Used by verifier to initialize the transcript
Transcript(const std::vector<FF>& proof)
: NativeTranscript(proof)
Transcript_(const std::vector<FF>& proof)
: Base(proof)
{}

static std::shared_ptr<Transcript> prover_init_empty()
static std::shared_ptr<Transcript_> prover_init_empty()
{
auto transcript = std::make_shared<Transcript>();
auto transcript = std::make_shared<Transcript_>();
constexpr uint32_t init{ 42 }; // arbitrary
transcript->send_to_verifier("Init", init);
return transcript;
};

static std::shared_ptr<Transcript> verifier_init_empty(const std::shared_ptr<Transcript>& transcript)
static std::shared_ptr<Transcript_> verifier_init_empty(const std::shared_ptr<Transcript_>& transcript)
{
auto verifier_transcript = std::make_shared<Transcript>(transcript->proof_data);
auto verifier_transcript = std::make_shared<Transcript_>(transcript->proof_data);
[[maybe_unused]] auto _ = verifier_transcript->template receive_from_prover<FF>("Init");
return verifier_transcript;
};
Expand All @@ -750,37 +752,40 @@ class UltraFlavor {
void deserialize_full_transcript()
{
// take current proof and put them into the struct
auto& proof_data = this->proof_data;
size_t num_frs_read = 0;
circuit_size = deserialize_from_buffer<uint32_t>(proof_data, num_frs_read);
circuit_size = Base::template deserialize_from_buffer<uint32_t>(proof_data, num_frs_read);

public_input_size = deserialize_from_buffer<uint32_t>(proof_data, num_frs_read);
pub_inputs_offset = deserialize_from_buffer<uint32_t>(proof_data, num_frs_read);
public_input_size = Base::template deserialize_from_buffer<uint32_t>(proof_data, num_frs_read);
pub_inputs_offset = Base::template deserialize_from_buffer<uint32_t>(proof_data, num_frs_read);
for (size_t i = 0; i < public_input_size; ++i) {
public_inputs.push_back(deserialize_from_buffer<FF>(proof_data, num_frs_read));
public_inputs.push_back(Base::template deserialize_from_buffer<FF>(proof_data, num_frs_read));
}
w_l_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
w_r_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
w_o_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
lookup_read_counts_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
lookup_read_tags_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
w_4_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
lookup_inverses_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
z_perm_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
w_l_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
w_r_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
w_o_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
lookup_read_counts_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
lookup_read_tags_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
w_4_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
lookup_inverses_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
z_perm_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) {
sumcheck_univariates.push_back(
deserialize_from_buffer<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(proof_data,
num_frs_read));
Base::template deserialize_from_buffer<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(
proof_data, num_frs_read));
}
sumcheck_evaluations = deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(proof_data, num_frs_read);
sumcheck_evaluations =
Base::template deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(proof_data, num_frs_read);
for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N - 1; ++i) {
gemini_fold_comms.push_back(deserialize_from_buffer<Commitment>(proof_data, num_frs_read));
gemini_fold_comms.push_back(
Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read));
}
for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) {
gemini_fold_evals.push_back(deserialize_from_buffer<FF>(proof_data, num_frs_read));
gemini_fold_evals.push_back(Base::template deserialize_from_buffer<FF>(proof_data, num_frs_read));
}
shplonk_q_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
shplonk_q_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);

kzg_w_comm = deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
kzg_w_comm = Base::template deserialize_from_buffer<Commitment>(proof_data, num_frs_read);
}

/**
Expand All @@ -791,39 +796,42 @@ class UltraFlavor {
*/
void serialize_full_transcript()
{
auto& proof_data = this->proof_data;
size_t old_proof_length = proof_data.size();
proof_data.clear(); // clear proof_data so the rest of the function can replace it
serialize_to_buffer(circuit_size, proof_data);
serialize_to_buffer(public_input_size, proof_data);
serialize_to_buffer(pub_inputs_offset, proof_data);
Base::template serialize_to_buffer(circuit_size, proof_data);
Base::template serialize_to_buffer(public_input_size, proof_data);
Base::template serialize_to_buffer(pub_inputs_offset, proof_data);
for (size_t i = 0; i < public_input_size; ++i) {
serialize_to_buffer(public_inputs[i], proof_data);
Base::template serialize_to_buffer(public_inputs[i], proof_data);
}
serialize_to_buffer(w_l_comm, proof_data);
serialize_to_buffer(w_r_comm, proof_data);
serialize_to_buffer(w_o_comm, proof_data);
serialize_to_buffer(lookup_read_counts_comm, proof_data);
serialize_to_buffer(lookup_read_tags_comm, proof_data);
serialize_to_buffer(w_4_comm, proof_data);
serialize_to_buffer(lookup_inverses_comm, proof_data);
serialize_to_buffer(z_perm_comm, proof_data);
Base::template serialize_to_buffer(w_l_comm, proof_data);
Base::template serialize_to_buffer(w_r_comm, proof_data);
Base::template serialize_to_buffer(w_o_comm, proof_data);
Base::template serialize_to_buffer(lookup_read_counts_comm, proof_data);
Base::template serialize_to_buffer(lookup_read_tags_comm, proof_data);
Base::template serialize_to_buffer(w_4_comm, proof_data);
Base::template serialize_to_buffer(lookup_inverses_comm, proof_data);
Base::template serialize_to_buffer(z_perm_comm, proof_data);
for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) {
serialize_to_buffer(sumcheck_univariates[i], proof_data);
Base::template serialize_to_buffer(sumcheck_univariates[i], proof_data);
}
serialize_to_buffer(sumcheck_evaluations, proof_data);
Base::template serialize_to_buffer(sumcheck_evaluations, proof_data);
for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N - 1; ++i) {
serialize_to_buffer(gemini_fold_comms[i], proof_data);
Base::template serialize_to_buffer(gemini_fold_comms[i], proof_data);
}
for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) {
serialize_to_buffer(gemini_fold_evals[i], proof_data);
Base::template serialize_to_buffer(gemini_fold_evals[i], proof_data);
}
serialize_to_buffer(shplonk_q_comm, proof_data);
serialize_to_buffer(kzg_w_comm, proof_data);
Base::template serialize_to_buffer(shplonk_q_comm, proof_data);
Base::template serialize_to_buffer(kzg_w_comm, proof_data);

// sanity check to make sure we generate the same length of proof as before.
ASSERT(proof_data.size() == old_proof_length);
}
};

using Transcript = Transcript_<NativeTranscriptParams>;
};

} // namespace bb
Loading

0 comments on commit 48286c6

Please sign in to comment.