use crate::error::{Error, Result};
use crate::transcript::DuplexSponge;
pub struct FiatShamirTransform {
sponge: DuplexSponge,
}
impl FiatShamirTransform {
pub fn new(domain_separator: &[u8], protocol_id: &[u8], session_id: &[u8]) -> Self {
let mut iv = [0u8; 32];
let mut offset = 0;
let ds_len = domain_separator.len().min(10);
iv[offset..offset + ds_len].copy_from_slice(&domain_separator[..ds_len]);
offset += ds_len;
let proto_len = protocol_id.len().min(10);
iv[offset..offset + proto_len].copy_from_slice(&protocol_id[..proto_len]);
offset += proto_len;
let session_len = session_id.len().min(32 - offset);
iv[offset..offset + session_len].copy_from_slice(&session_id[..session_len]);
Self {
sponge: DuplexSponge::new(&iv),
}
}
pub fn absorb_commitment(&mut self, commitment: &[u8]) {
self.sponge.prover_message(commitment);
}
pub fn generate_challenge(&mut self, challenge_len: usize) -> Vec<u8> {
self.sponge.verifier_challenge(challenge_len)
}
pub fn absorb_response(&mut self, response: &[u8]) {
self.sponge.absorb(response);
}
pub fn verify_transcript(
&mut self,
commitment: &[u8],
challenge: &[u8],
response: &[u8],
) -> Result<()> {
self.absorb_commitment(commitment);
let generated_challenge = self.generate_challenge(challenge.len());
if generated_challenge != challenge {
return Err(Error::InvalidChallenge);
}
self.absorb_response(response);
Ok(())
}
}