#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use binary_fields::BinaryFieldElement;
use merkle_tree::{BatchedMerkleProof, CompleteMerkleTree, MerkleRoot};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "prover")]
use reed_solomon::ReedSolomon;
#[cfg(feature = "prover")]
pub struct ProverConfig<T: BinaryFieldElement, U: BinaryFieldElement> {
pub recursive_steps: usize,
pub initial_dims: (usize, usize),
pub dims: Vec<(usize, usize)>,
pub initial_k: usize,
pub ks: Vec<usize>,
pub initial_reed_solomon: ReedSolomon<T>,
pub reed_solomon_codes: Vec<ReedSolomon<U>>,
pub num_queries: usize,
}
#[cfg(feature = "prover")]
impl<T: BinaryFieldElement, U: BinaryFieldElement> ProverConfig<T, U> {
pub fn validate(&self) -> crate::Result<()> {
if self.num_queries < 148 {
#[cfg(feature = "std")]
return Err(crate::LigeritoError::InvalidConfig(format!(
"num_queries must be >= 148 for 100-bit security, got {}",
self.num_queries
)));
#[cfg(not(feature = "std"))]
return Err(crate::LigeritoError::InvalidConfig);
}
Ok(())
}
}
#[derive(Clone, Debug)]
pub struct VerifierConfig {
pub recursive_steps: usize,
pub initial_dim: usize,
pub log_dims: Vec<usize>,
pub initial_k: usize,
pub ks: Vec<usize>,
pub num_queries: usize,
}
impl VerifierConfig {
pub fn poly_log_size(&self) -> usize {
self.initial_dim + self.initial_k
}
}
#[cfg(feature = "prover")]
pub struct RecursiveLigeroWitness<T: BinaryFieldElement> {
pub mat: Vec<Vec<T>>, pub tree: CompleteMerkleTree,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "scale",
derive(codec::Encode, codec::Decode, scale_info::TypeInfo)
)]
pub struct RecursiveLigeroCommitment {
pub root: MerkleRoot,
}
impl RecursiveLigeroCommitment {
pub fn size_of(&self) -> usize {
self.root.size_of()
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "scale",
derive(codec::Encode, codec::Decode, scale_info::TypeInfo)
)]
pub struct RecursiveLigeroProof<T: BinaryFieldElement> {
pub opened_rows: Vec<Vec<T>>,
pub merkle_proof: BatchedMerkleProof,
}
impl<T: BinaryFieldElement> RecursiveLigeroProof<T> {
pub fn size_of(&self) -> usize {
self.opened_rows
.iter()
.map(|row| row.len() * core::mem::size_of::<T>())
.sum::<usize>()
+ self.merkle_proof.size_of()
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "scale",
derive(codec::Encode, codec::Decode, scale_info::TypeInfo)
)]
pub struct FinalLigeroProof<T: BinaryFieldElement> {
pub yr: Vec<T>,
pub opened_rows: Vec<Vec<T>>,
pub merkle_proof: BatchedMerkleProof,
}
impl<T: BinaryFieldElement> FinalLigeroProof<T> {
pub fn size_of(&self) -> usize {
self.yr.len() * core::mem::size_of::<T>()
+ self
.opened_rows
.iter()
.map(|row| row.len() * core::mem::size_of::<T>())
.sum::<usize>()
+ self.merkle_proof.size_of()
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "scale",
derive(codec::Encode, codec::Decode, scale_info::TypeInfo)
)]
pub struct SumcheckTranscript<T: BinaryFieldElement> {
pub transcript: Vec<(T, T, T)>, }
impl<T: BinaryFieldElement> SumcheckTranscript<T> {
pub fn size_of(&self) -> usize {
self.transcript.len() * 3 * core::mem::size_of::<T>()
}
}
pub struct LigeritoProof<T: BinaryFieldElement, U: BinaryFieldElement> {
pub initial_ligero_cm: Option<RecursiveLigeroCommitment>,
pub initial_ligero_proof: Option<RecursiveLigeroProof<T>>,
pub recursive_commitments: Vec<RecursiveLigeroCommitment>,
pub recursive_proofs: Vec<RecursiveLigeroProof<U>>,
pub final_ligero_proof: Option<FinalLigeroProof<U>>,
pub sumcheck_transcript: Option<SumcheckTranscript<U>>,
}
impl<T: BinaryFieldElement, U: BinaryFieldElement> Default for LigeritoProof<T, U> {
fn default() -> Self {
Self::new()
}
}
impl<T: BinaryFieldElement, U: BinaryFieldElement> LigeritoProof<T, U> {
pub fn new() -> Self {
Self {
initial_ligero_cm: None,
initial_ligero_proof: None,
recursive_commitments: Vec::new(),
recursive_proofs: Vec::new(),
final_ligero_proof: None,
sumcheck_transcript: None,
}
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "scale",
derive(codec::Encode, codec::Decode, scale_info::TypeInfo)
)]
pub struct FinalizedLigeritoProof<T: BinaryFieldElement, U: BinaryFieldElement> {
pub initial_ligero_cm: RecursiveLigeroCommitment,
pub initial_ligero_proof: RecursiveLigeroProof<T>,
pub recursive_commitments: Vec<RecursiveLigeroCommitment>,
pub recursive_proofs: Vec<RecursiveLigeroProof<U>>,
pub final_ligero_proof: FinalLigeroProof<U>,
pub sumcheck_transcript: SumcheckTranscript<U>,
#[cfg_attr(feature = "serde", serde(default))]
pub eval_rounds: Vec<crate::eval_proof::EvalSumcheckRound<U>>,
}
impl<T: BinaryFieldElement, U: BinaryFieldElement> FinalizedLigeritoProof<T, U> {
pub fn size_of(&self) -> usize {
self.initial_ligero_cm.size_of()
+ self.initial_ligero_proof.size_of()
+ self
.recursive_commitments
.iter()
.map(|c| c.size_of())
.sum::<usize>()
+ self
.recursive_proofs
.iter()
.map(|p| p.size_of())
.sum::<usize>()
+ self.final_ligero_proof.size_of()
+ self.sumcheck_transcript.size_of()
+ self.eval_rounds.len() * 3 * core::mem::size_of::<U>()
}
}
pub fn finalize<T: BinaryFieldElement, U: BinaryFieldElement>(
proof: LigeritoProof<T, U>,
) -> crate::Result<FinalizedLigeritoProof<T, U>> {
Ok(FinalizedLigeritoProof {
initial_ligero_cm: proof
.initial_ligero_cm
.ok_or(crate::LigeritoError::InvalidProof)?,
initial_ligero_proof: proof
.initial_ligero_proof
.ok_or(crate::LigeritoError::InvalidProof)?,
recursive_commitments: proof.recursive_commitments,
recursive_proofs: proof.recursive_proofs,
final_ligero_proof: proof
.final_ligero_proof
.ok_or(crate::LigeritoError::InvalidProof)?,
sumcheck_transcript: proof
.sumcheck_transcript
.ok_or(crate::LigeritoError::InvalidProof)?,
eval_rounds: Vec::new(),
})
}