use crypto::Hasher;
use utils::{
collections::Vec, ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
SliceReader,
};
#[derive(Debug, Clone, Default, Eq, PartialEq)]
pub struct Commitments(Vec<u8>);
impl Commitments {
pub fn new<H: Hasher>(
trace_roots: Vec<H::Digest>,
constraint_root: H::Digest,
fri_roots: Vec<H::Digest>,
) -> Self {
let mut bytes = Vec::new();
bytes.write(trace_roots);
bytes.write(constraint_root);
bytes.write(fri_roots);
Commitments(bytes)
}
pub fn add<H: Hasher>(&mut self, commitment: &H::Digest) {
commitment.write_into(&mut self.0);
}
#[allow(clippy::type_complexity)]
pub fn parse<H: Hasher>(
self,
num_trace_segments: usize,
num_fri_layers: usize,
) -> Result<(Vec<H::Digest>, H::Digest, Vec<H::Digest>), DeserializationError> {
let mut reader = SliceReader::new(&self.0);
let trace_commitments = H::Digest::read_batch_from(&mut reader, num_trace_segments)?;
let constraint_commitment = H::Digest::read_from(&mut reader)?;
let fri_commitments = H::Digest::read_batch_from(&mut reader, num_fri_layers + 1)?;
if reader.has_more_bytes() {
return Err(DeserializationError::UnconsumedBytes);
}
Ok((trace_commitments, constraint_commitment, fri_commitments))
}
}
impl Serializable for Commitments {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
assert!(self.0.len() < u16::MAX as usize);
target.write_u16(self.0.len() as u16);
target.write_u8_slice(&self.0);
}
}
impl Deserializable for Commitments {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let num_bytes = source.read_u16()? as usize;
let result = source.read_u8_vec(num_bytes)?;
Ok(Commitments(result))
}
}