use group::ff::FromUniformBytes;
use std::io::{self, Read};
use crate::arithmetic::CurveAffine;
use crate::transcript::{Blake2bRead, Challenge255, EncodedChallenge, Transcript, TranscriptRead};
#[derive(Debug, Clone)]
pub enum TranscriptEvent<C: CurveAffine> {
CommonPoint(C),
CommonScalar(C::Scalar),
ReadPoint(C),
ReadScalar(C::Scalar),
Squeeze(C::Scalar),
}
#[derive(Debug, Clone)]
pub struct ChallengeRecorder<R: Read, C: CurveAffine, E: EncodedChallenge<C>> {
inner: Blake2bRead<R, C, E>,
pub challenges: Vec<C::Scalar>,
pub points: Vec<C>,
pub scalars: Vec<C::Scalar>,
pub common_points: Vec<C>,
pub events: Vec<TranscriptEvent<C>>,
}
impl<R: Read, C: CurveAffine, E: EncodedChallenge<C>> ChallengeRecorder<R, C, E> {
pub fn init(reader: R) -> Self {
ChallengeRecorder {
inner: Blake2bRead::init(reader),
challenges: Vec::new(),
points: Vec::new(),
scalars: Vec::new(),
common_points: Vec::new(),
events: Vec::new(),
}
}
}
impl<R: Read, C: CurveAffine> Transcript<C, Challenge255<C>>
for ChallengeRecorder<R, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn squeeze_challenge(&mut self) -> Challenge255<C> {
let challenge = self.inner.squeeze_challenge();
let scalar = challenge.get_scalar();
self.challenges.push(scalar);
self.events.push(TranscriptEvent::Squeeze(scalar));
challenge
}
fn common_point(&mut self, point: C) -> io::Result<()> {
self.common_points.push(point);
self.events.push(TranscriptEvent::CommonPoint(point));
self.inner.common_point(point)
}
fn common_scalar(&mut self, scalar: C::Scalar) -> io::Result<()> {
self.events.push(TranscriptEvent::CommonScalar(scalar));
self.inner.common_scalar(scalar)
}
}
impl<R: Read, C: CurveAffine> TranscriptRead<C, Challenge255<C>>
for ChallengeRecorder<R, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn read_point(&mut self) -> io::Result<C> {
let point = self.inner.read_point()?;
self.points.push(point);
self.events.push(TranscriptEvent::ReadPoint(point));
Ok(point)
}
fn read_scalar(&mut self) -> io::Result<C::Scalar> {
let scalar = self.inner.read_scalar()?;
self.scalars.push(scalar);
self.events.push(TranscriptEvent::ReadScalar(scalar));
Ok(scalar)
}
}