miden-crypto/src/gkr/sumcheck/verifier.rs
src/gkr/sumcheck/verifier.rsRaw
1use winter_crypto::{ElementHasher, RandomCoin};
2use winter_math::{fields::f64::BaseElement, FieldElement};
3
4use crate::gkr::utils::{barycentric_weights, evaluate_barycentric};
5
6use super::{Claim, FinalEvaluationClaim, FullProof, PartialProof};
7
8pub fn sum_check_verify_and_reduce<
9 E: FieldElement<BaseField = BaseElement>,
10 C: RandomCoin<Hasher = H, BaseField = BaseElement>,
11 H: ElementHasher<BaseField = BaseElement>,
12>(
13 claim: &Claim<E>,
14 proofs: PartialProof<E>,
15 coin: &mut C,
16) -> (E, Vec<E>) {
17 let degree = 3;
18 let points: Vec<E> = (0..degree + 1).map(|x| E::from(x as u8)).collect();
19 let mut sum_value = claim.sum_value.clone();
20 let mut randomness = vec![];
21
22 for proof in proofs.round_proofs {
23 let partial_evals = proof.poly_evals.clone();
24 coin.reseed(H::hash_elements(&partial_evals));
25
26 // get r
27 let r: E = coin.draw().unwrap();
28 randomness.push(r);
29 let evals = proof.to_evals(sum_value);
30
31 let point_evals: Vec<_> = points.iter().zip(evals.iter()).map(|(x, y)| (*x, *y)).collect();
32 let weights = barycentric_weights(&point_evals);
33 sum_value = evaluate_barycentric(&point_evals, r, &weights);
34 }
35 (sum_value, randomness)
36}
37
38pub fn sum_check_verify<
39 E: FieldElement<BaseField = BaseElement>,
40 C: RandomCoin<Hasher = H, BaseField = BaseElement>,
41 H: ElementHasher<BaseField = BaseElement>,
42>(
43 claim: &Claim<E>,
44 proofs: FullProof<E>,
45 coin: &mut C,
46) -> FinalEvaluationClaim<E> {
47 let FullProof {
48 sum_check_proof: proofs,
49 final_evaluation_claim,
50 } = proofs;
51 let Claim { mut sum_value, polynomial } = claim;
52 let degree = polynomial.composer.max_degree();
53 let points: Vec<E> = (0..degree + 1).map(|x| E::from(x as u8)).collect();
54
55 for proof in proofs.round_proofs {
56 let partial_evals = proof.poly_evals.clone();
57 coin.reseed(H::hash_elements(&partial_evals));
58
59 // get r
60 let r: E = coin.draw().unwrap();
61 let evals = proof.to_evals(sum_value);
62
63 let point_evals: Vec<_> = points.iter().zip(evals.iter()).map(|(x, y)| (*x, *y)).collect();
64 let weights = barycentric_weights(&point_evals);
65 sum_value = evaluate_barycentric(&point_evals, r, &weights);
66 }
67
68 assert_eq!(final_evaluation_claim.claimed_evaluation, sum_value);
69
70 final_evaluation_claim
71}