arnaucube
arnaucube/miden-cryptoPublic Self-hosted repository
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}