use crate::{
folding::{utils::FieldFolder, SumFold, SumFoldInstance, SumFoldProof},
message::Message,
sumcheck::{DegreeParam, Sum, SumcheckFunction},
SumcheckError,
};
use ark_ff::Field;
use transcript::{
params::ParamResolver, protocols::Reduction, MessageGuard, TranscriptBuilder, TranscriptGuard,
};
impl<F: Field, SF: SumcheckFunction<F>> Reduction<F> for SumFold<F, SF> {
type A = SumFoldInstance<F, 2>;
type B = (Sum<F>, FieldFolder<F>);
type Key = Self;
type Proof = SumFoldProof<F>;
type Error = SumcheckError;
fn transcript_pattern(key: &Self::Key, builder: TranscriptBuilder) -> TranscriptBuilder {
let params = ParamResolver::new().set::<DegreeParam>(key.degree + 1);
builder
.round::<F, SumFoldInstance<F, 2>, 1>()
.with_params(params, |builder| builder.round::<F, Message<F>, 1>())
}
fn verify_reduction<S: sponge::sponge::Duplex<F>>(
key: &Self::Key,
instance: MessageGuard<Self::A>,
mut transcript: TranscriptGuard<F, S, Self::Proof>,
) -> Result<Self::B, Self::Error> {
let (instance, [beta]) = transcript
.unwrap_guard(instance)
.map_err(SumcheckError::TranscriptError)?;
let sum = (F::one() - beta) * instance.sums[0].0 + beta * instance.sums[1].0;
let (msg, [r]) = transcript
.receive_message(|proof| proof.message.clone())
.map_err(SumcheckError::TranscriptError)?;
if sum != msg.eval_at_0() + msg.eval_at_1() {
return Err(SumcheckError::RoundSum);
}
let eqr = r * beta + (F::one() - r) * (F::one() - beta);
let new_sum = msg.eval_at_x(r, &key.extended_weights);
let new_sum = Sum(new_sum / eqr);
let folder = FieldFolder::new(r);
Ok((new_sum, folder))
}
}