Skip to content

Commit

Permalink
Creating structures for aggregated FRI.
Browse files Browse the repository at this point in the history
  • Loading branch information
martun committed Sep 13, 2024
1 parent 246955a commit 4f1cb82
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,55 @@ namespace nil {
std::vector<round_proof_type> round_proofs;
};

struct round_proofs_batch {
bool operator==(const round_proofs_batch &rhs) const {
return fri_roots == rhs.fri_roots &&
round_proofs == rhs.round_proofs &&
final_polynomial == rhs.final_polynomial;
}

bool operator!=(const round_proofs_batch &rhs) const {
return !(rhs == *this);
}

std::vector<commitment_type> fri_roots; // 0,..step_list.size()
std::vector<std::vector<round_proof_type>> round_proofs; // 0...lambda - 1
math::polynomial<typename field_type::value_type> final_polynomial;
};

struct initial_proofs_batch {
initial_proofs_batch() = default;

// Just pre-allocate the vector for a given size.
initial_proofs_batch(std::size_t lambda)
: initial_proofs(lambda) {
}

bool operator==(const initial_proofs_batch &rhs) const {
return initial_proofs == rhs.initial_proofs;
}

bool operator!=(const initial_proofs_batch &rhs) const {
return !(rhs == *this);
}

std::vector<std::map<std::size_t, initial_proof_type>> initial_proofs; // 0...lambda - 1
};

struct proof_type {
proof_type() = default;
proof_type(const proof_type&) = default;

proof_type(const round_proofs_batch& round_proofs,
const initial_proofs_batch& intial_proofs)
: fri_roots(round_proofs.fri_roots)
, final_polynomial(round_proofs.final_polynomial) {
for (std::size_t i = 0; i < intial_proofs.initial_proofs.size(); ++i) {
query_proofs.emplace_back(
{intial_proofs.initial_proofs[i], round_proofs.round_proofs[i]});
}
}

bool operator==(const proof_type &rhs) const {
// TODO(martun): check if the following comment can be deleted.
// if( FRI::use_grinding && proof_of_work != rhs.proof_of_work ){
Expand All @@ -288,6 +336,40 @@ namespace nil {
std::vector<query_proof_type> query_proofs; // 0...lambda - 1
typename GrindingType::output_type proof_of_work;
};

// This represents and aggregated proofs of N provers with shared initial proof.
struct aggregated_proof {
aggregated_proof() = default;
aggregated_proof(const aggregated_proof&) = default;

// Size of vector 'round_proofs_per_prover' is the number of provers.
aggregated_proof(
const std::vector<round_proofs_batch>& round_proofs_per_prover,
const initial_proofs_batch& intial_proofs)
: round_proofs_per_prover(round_proofs_per_prover)
, intial_proofs(intial_proofs) {
}

bool operator==(const aggregated_proof &rhs) const {
//if (FRI::use_grinding && proof_of_work != rhs.proof_of_work) {
// return false;
//}
return round_proofs_per_prover == rhs.round_proofs_per_prover &&
intial_proofs == rhs.intial_proofs;
}

bool operator!=(const aggregated_proof &rhs) const {
return !(rhs == *this);
}

// For each prover we have a rounds proof partial FRI proof for consistency checks.
std::vector<round_proofs_batch> round_proofs_per_prover;

// We have a single intial proof for checking that F(X) is a low degree polynomial.
initial_proofs_batch intial_proofs;

typename GrindingType::output_type proof_of_work;
};
};
} // namespace detail
} // namespace commitments
Expand Down Expand Up @@ -665,7 +747,6 @@ namespace nil {
>
commit_phase(
const PolynomialType& combined_Q,
const std::map<std::size_t, typename FRI::precommitment_type> &precommitments,
const typename FRI::precommitment_type &combined_Q_precommitment,
const typename FRI::params_type &fri_params,
typename FRI::transcript_type &transcript)
Expand Down Expand Up @@ -840,11 +921,6 @@ namespace nil {
static std::vector<typename FRI::round_proof_type>
build_round_proofs(
const typename FRI::params_type &fri_params,
const std::map<std::size_t, std::vector<PolynomialType>> &g,
const std::map<
std::size_t,
std::vector<math::polynomial<typename FRI::field_type::value_type>>
> &g_coeffs,
const std::vector<typename FRI::precommitment_type> &fri_trees,
const std::vector<PolynomialType> &fs,
const math::polynomial<typename FRI::field_type::value_type> &final_polynomial,
Expand Down Expand Up @@ -915,18 +991,44 @@ namespace nil {


template<typename FRI, typename PolynomialType>
static std::vector<typename FRI::query_proof_type>
query_phase(
const std::map<std::size_t, typename FRI::precommitment_type> &precommitments,
static typename FRI::round_proofs_batch query_phase_round_proofs_with_challenges(
const typename FRI::params_type &fri_params,
typename FRI::transcript_type &transcript,
const std::map<std::size_t, std::vector<PolynomialType>> &g,
const std::vector<typename FRI::precommitment_type> &fri_trees,
const std::vector<PolynomialType> &fs,
const math::polynomial<typename FRI::field_type::value_type> &final_polynomial)
const math::polynomial<typename FRI::field_type::value_type> &final_polynomial,
const std::vector<typename FRI::field_type::value_type>& challenges)
{
PROFILE_SCOPE("Basic FRI query phase");
std::vector<typename FRI::query_proof_type> query_proofs(fri_params.lambda);
typename FRI::round_proofs_batch proof;

for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) {
std::size_t domain_size = fri_params.D[0]->size();
typename FRI::field_type::value_type x = challenges[query_id];
x = x.pow((FRI::field_type::modulus - 1) / domain_size);

std::uint64_t x_index = 0;

while (fri_params.D[0]->get_domain_element(x_index) != x) {
++x_index;
}

// Fill round proofs
std::vector<typename FRI::round_proof_type> round_proofs =
build_round_proofs<FRI, PolynomialType>(
fri_params, fri_trees, fs, final_polynomial, x_index);

proof.round_proofs[query_id] = std::move(round_proofs);
}
return proof;
}

template<typename FRI, typename PolynomialType>
static typename FRI::initial_proofs_batch query_phase_initial_proofs_with_challenges(
const std::map<std::size_t, typename FRI::precommitment_type> &precommitments,
const typename FRI::params_type &fri_params,
const std::map<std::size_t, std::vector<PolynomialType>> &g,
const std::vector<typename FRI::field_type::value_type>& challenges)
{
typename FRI::initial_proofs_batch proof(fri_params.lambda);

// If we have DFS polynomials, and we are going to resize them, better convert them to coefficients form,
// and compute their values in those 2 * FRI::lambda points each, which is normally 2 * 20.
Expand All @@ -937,43 +1039,85 @@ namespace nil {

for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) {
std::size_t domain_size = fri_params.D[0]->size();
typename FRI::field_type::value_type x = transcript.template challenge<typename FRI::field_type>();
x = x.pow((FRI::field_type::modulus - 1)/domain_size);
typename FRI::field_type::value_type x = challenges[query_id];
x = x.pow((FRI::field_type::modulus - 1) / domain_size);

std::uint64_t x_index = 0;

while (fri_params.D[0]->get_domain_element(x_index) != x) {
++x_index;
}

// Initial proof
std::map<std::size_t, typename FRI::initial_proof_type>
initial_proof = build_initial_proof<FRI, PolynomialType>(
precommitments,
fri_params, g, g_coeffs, x_index);

// Fill round proofs
std::vector<typename FRI::round_proof_type>
round_proofs = build_round_proofs<FRI, PolynomialType>(
fri_params, g, g_coeffs, fri_trees, fs, final_polynomial, x_index);
proof.initial_proofs.emplace_back(std::move(initial_proof));
}
return proof;
}

typename FRI::query_proof_type query_proof = {std::move(initial_proof), std::move(round_proofs)};
query_proofs[query_id] = std::move(query_proof);
template<typename FRI, typename PolynomialType>
static std::vector<typename FRI::query_proof_type>
query_phase_with_challenges(
const std::map<std::size_t, typename FRI::precommitment_type> &precommitments,
const typename FRI::params_type &fri_params,
const std::vector<typename FRI::field_type::value_type>& challenges,
const std::map<std::size_t, std::vector<PolynomialType>> &g,
const std::vector<typename FRI::precommitment_type> &fri_trees,
const std::vector<PolynomialType> &fs,
const math::polynomial<typename FRI::field_type::value_type> &final_polynomial)
{
typename FRI::initial_proofs_batch initial_proofs =
query_phase_initial_proofs_with_challenges<FRI, PolynomialType>(
precommitments, fri_params, g, challenges);

typename FRI::round_proofs_batch round_proofs =
query_phase_round_proofs_with_challenges<FRI, PolynomialType>(
fri_params, fri_trees, fs, final_polynomial, challenges);

// Join intial proofs and round proofs into a structure of query proofs.
std::vector<typename FRI::query_proof_type> query_proofs(fri_params.lambda);

for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) {
query_proofs[query_id] = {std::move(initial_proofs.initial_proofs[query_id]),
std::move(round_proofs.round_proofs[query_id])};
}
return query_proofs;
}

return std::move(query_proofs);
template<typename FRI, typename PolynomialType>
static std::vector<typename FRI::query_proof_type>
query_phase(
const std::map<std::size_t, typename FRI::precommitment_type> &precommitments,
const typename FRI::params_type &fri_params,
typename FRI::transcript_type &transcript,
const std::map<std::size_t, std::vector<PolynomialType>> &g,
const std::vector<typename FRI::precommitment_type> &fri_trees,
const std::vector<PolynomialType> &fs,
const math::polynomial<typename FRI::field_type::value_type> &final_polynomial)
{
PROFILE_SCOPE("Basic FRI query phase");
std::vector<typename FRI::field_type::value_type> challenges;
for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) {
typename FRI::field_type::value_type x = transcript.template challenge<typename FRI::field_type>();
challenges.push_back(x);
}
return query_phase_with_challenges<FRI, PolynomialType>(
precommitments, fri_params, challenges, g, fri_trees, fs, final_polynomial);
}


template<typename FRI, typename PolynomialType,
typename std::enable_if<
std::is_base_of<
commitments::detail::basic_batched_fri<
typename FRI::field_type, typename FRI::merkle_tree_hash_type,
typename FRI::transcript_hash_type,
FRI::m, typename FRI::grinding_type>,
FRI>::value,
bool>::type = true>
std::is_base_of<
commitments::detail::basic_batched_fri<
typename FRI::field_type, typename FRI::merkle_tree_hash_type,
typename FRI::transcript_hash_type,
FRI::m, typename FRI::grinding_type>,
FRI>::value,
bool>::type = true>
static typename FRI::proof_type proof_eval(
const std::map<std::size_t, std::vector<PolynomialType>> &g,
const PolynomialType& combined_Q,
Expand All @@ -997,13 +1141,13 @@ namespace nil {
math::polynomial<typename FRI::field_type::value_type> final_polynomial;

std::tie(fs, fri_trees, fri_roots, final_polynomial) =
commit_phase<FRI, PolynomialType>(
combined_Q, precommitments,
commit_phase<FRI, PolynomialType>(
combined_Q,
combined_Q_precommitment,
fri_params, transcript);

// Grinding
if ( fri_params.use_grinding ) {
if (fri_params.use_grinding) {
PROFILE_SCOPE("Basic FRI grinding phase");
proof.proof_of_work = FRI::grinding_type::generate(transcript, fri_params.grinding_parameter);
}
Expand Down
Loading

0 comments on commit 4f1cb82

Please sign in to comment.