use spongefish::{ProverState, VerificationError, VerificationResult, VerifierState};
use super::vc::{MerkleVc, Opening};
use crate::field::Goldilocks4;
pub(crate) fn write_opening(transcript: &mut ProverState, opening: &Opening<MerkleVc>) {
let n_vals = opening.openings.len() as u32;
transcript.prover_message(&n_vals.to_le_bytes());
let n_sym: u32 = if opening.openings.is_empty() {
0
} else {
opening.openings[0].len() as u32
};
transcript.prover_message(&n_sym.to_le_bytes());
for symbols in &opening.openings {
for sym in symbols {
transcript.prover_message(&sym.to_bytes());
}
}
let path_len = opening.vc_proof.len() as u32;
transcript.prover_message(&path_len.to_le_bytes());
for h in &opening.vc_proof {
transcript.prover_message(h);
}
}
pub(crate) fn read_opening(
transcript: &mut VerifierState,
expected_n_vals: usize,
expected_n_sym: usize,
expected_path_len: usize,
) -> VerificationResult<Opening<MerkleVc>> {
let n_vals_bytes: [u8; 4] = transcript.prover_message()?;
let n_vals = u32::from_le_bytes(n_vals_bytes) as usize;
if n_vals != expected_n_vals {
return Err(VerificationError);
}
let n_sym_bytes: [u8; 4] = transcript.prover_message()?;
let n_sym = u32::from_le_bytes(n_sym_bytes) as usize;
if n_sym != expected_n_sym {
return Err(VerificationError);
}
let mut openings: Vec<Vec<Goldilocks4>> = Vec::with_capacity(n_vals);
for _ in 0..n_vals {
let mut symbols: Vec<Goldilocks4> = Vec::with_capacity(n_sym);
for _ in 0..n_sym {
let bytes: [u8; 32] = transcript.prover_message()?;
let sym = Goldilocks4::from_bytes(&bytes).ok_or(VerificationError)?;
symbols.push(sym);
}
openings.push(symbols);
}
let path_len_bytes: [u8; 4] = transcript.prover_message()?;
let path_len = u32::from_le_bytes(path_len_bytes) as usize;
if path_len != expected_path_len {
return Err(VerificationError);
}
let mut vc_proof: Vec<[u8; 32]> = Vec::with_capacity(path_len);
for _ in 0..path_len {
let h: [u8; 32] = transcript.prover_message()?;
vc_proof.push(h);
}
Ok(Opening { openings, vc_proof })
}
pub(crate) fn sample_positions_prover(
transcript: &mut ProverState,
count: usize,
domain_size: usize,
) -> Vec<usize> {
transcript
.verifier_messages_vec(count)
.into_iter()
.map(|i: u64| (i % domain_size as u64) as usize)
.collect()
}
pub(crate) fn sample_positions_verifier(
transcript: &mut VerifierState,
count: usize,
domain_size: usize,
) -> Vec<usize> {
(0..count)
.map(|_| {
let position: u64 = transcript.verifier_message();
(position % domain_size as u64) as usize
})
.collect()
}