use alloc::vec::Vec;
use crypto::{Hasher, MerkleTree};
use fri::FriProof;
use math::FieldElement;
use security::{ConjecturedSecurity, ProvenSecurity};
use utils::{ByteReader, Deserializable, DeserializationError, Serializable, SliceReader};
use crate::{options::BatchingMethod, ProofOptions, TraceInfo};
mod context;
pub use context::Context;
mod commitments;
pub use commitments::Commitments;
mod queries;
pub use queries::Queries;
mod ood_frame;
pub use ood_frame::{merge_ood_evaluations, OodFrame, QuotientOodFrame, TraceOodFrame};
mod security;
mod table;
pub use table::Table;
#[cfg(test)]
mod tests;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Proof {
pub context: Context,
pub num_unique_queries: u8,
pub commitments: Commitments,
pub trace_queries: Vec<Queries>,
pub constraint_queries: Queries,
pub ood_frame: OodFrame,
pub fri_proof: FriProof,
pub pow_nonce: u64,
}
impl Proof {
pub fn options(&self) -> &ProofOptions {
self.context.options()
}
pub fn trace_info(&self) -> &TraceInfo {
self.context.trace_info()
}
pub fn lde_domain_size(&self) -> usize {
self.context.lde_domain_size()
}
pub fn conjectured_security<H: Hasher>(&self) -> ConjecturedSecurity {
ConjecturedSecurity::compute(
self.context.options(),
self.context.num_modulus_bits(),
H::COLLISION_RESISTANCE,
)
}
pub fn proven_security<H: Hasher>(&self) -> ProvenSecurity {
let num_constraints = self.context.num_constraints();
let num_trace_polys = self.context.trace_info().width();
let num_constraint_composition_polys = self.options().blowup_factor();
let num_committed_polys = num_trace_polys + num_constraint_composition_polys;
ProvenSecurity::compute(
self.context.options(),
self.context.num_modulus_bits(),
self.trace_info().length(),
H::COLLISION_RESISTANCE,
num_constraints,
num_committed_polys,
)
}
pub fn to_bytes(&self) -> Vec<u8> {
Serializable::to_bytes(self)
}
pub fn from_bytes(source: &[u8]) -> Result<Self, DeserializationError> {
Deserializable::read_from_bytes(source)
}
pub fn new_dummy() -> Self {
use crypto::{hashers::Blake3_192 as DummyHasher, BatchMerkleProof};
use math::fields::f64::BaseElement as DummyField;
use crate::FieldExtension;
Self {
context: Context::new::<DummyField>(
TraceInfo::new(1, 8),
ProofOptions::new(
1,
2,
2,
FieldExtension::None,
8,
1,
BatchingMethod::Linear,
BatchingMethod::Linear,
),
100,
),
num_unique_queries: 1,
commitments: Commitments::default(),
trace_queries: vec![
Queries::new::<DummyHasher<DummyField>, DummyField, MerkleTree<_>>(
BatchMerkleProof::<DummyHasher<DummyField>> { nodes: Vec::new(), depth: 0 },
vec![vec![DummyField::ONE]],
),
],
constraint_queries: Queries::new::<DummyHasher<DummyField>, DummyField, MerkleTree<_>>(
BatchMerkleProof::<DummyHasher<DummyField>> { nodes: Vec::new(), depth: 0 },
vec![vec![DummyField::ONE]],
),
ood_frame: OodFrame::default(),
fri_proof: FriProof::new_dummy(),
pow_nonce: 0,
}
}
}
impl Serializable for Proof {
fn write_into<W: utils::ByteWriter>(&self, target: &mut W) {
self.context.write_into(target);
target.write_u8(self.num_unique_queries);
self.commitments.write_into(target);
target.write_many(&self.trace_queries);
self.constraint_queries.write_into(target);
self.ood_frame.write_into(target);
self.fri_proof.write_into(target);
self.pow_nonce.write_into(target);
}
}
impl Deserializable for Proof {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let context = Context::read_from(source)?;
let num_unique_queries = source.read_u8()?;
let commitments = Commitments::read_from(source)?;
let num_trace_segments = context.trace_info().num_segments();
let mut trace_queries = Vec::with_capacity(num_trace_segments);
for _ in 0..num_trace_segments {
trace_queries.push(Queries::read_from(source)?);
}
let proof = Proof {
context,
num_unique_queries,
commitments,
trace_queries,
constraint_queries: Queries::read_from(source)?,
ood_frame: OodFrame::read_from(source)?,
fri_proof: FriProof::read_from(source)?,
pow_nonce: source.read_u64()?,
};
Ok(proof)
}
}