sonobe_fs/nova/algorithms/
verifier.rs1use ark_std::{borrow::Borrow, cfg_iter, ops::Mul};
4#[cfg(not(feature = "parallel"))]
5use itertools::Itertools;
6#[cfg(feature = "parallel")]
7use rayon::prelude::*;
8use sonobe_primitives::{
9 algebra::ops::bits::FromBits, commitments::GroupBasedCommitment, traits::SonobeField,
10 transcripts::Transcript,
11};
12
13use crate::{Error, FoldingSchemeVerifier, nova::AbstractNova};
14
15impl<CM: GroupBasedCommitment, TF: SonobeField, const B: usize> FoldingSchemeVerifier<1, 1>
16 for AbstractNova<CM, TF, B>
17{
18 #[allow(non_snake_case)]
19 fn verify(
20 _vk: &(),
21 transcript: &mut impl Transcript<TF>,
22 Us: &[impl Borrow<Self::RU>; 1],
23 us: &[impl Borrow<Self::IU>; 1],
24 cm_t: &Self::Proof<1, 1>,
25 ) -> Result<Self::RU, Error> {
26 let (U, u) = (Us[0].borrow(), us[0].borrow());
27
28 let rho_bits = transcript.add(&U).add(&u).add(cm_t).challenge_bits(B);
29 let rho = CM::Scalar::from_bits_le(&rho_bits);
30
31 Ok(Self::RU {
32 cm_e: U.cm_e + cm_t.mul(rho),
33 u: U.u + rho,
34 cm_w: U.cm_w + u.cm_w.mul(rho),
35 x: cfg_iter!(U.x)
36 .zip_eq(&u.x)
37 .map(|(a, b)| rho * b + a)
38 .collect(),
39 })
40 }
41}
42
43impl<CM: GroupBasedCommitment, TF: SonobeField, const B: usize> FoldingSchemeVerifier<2, 0>
44 for AbstractNova<CM, TF, B>
45{
46 #[allow(non_snake_case)]
47 fn verify(
48 _vk: &(),
49 transcript: &mut impl Transcript<TF>,
50 [U1, U2]: &[impl Borrow<Self::RU>; 2],
51 _: &[impl Borrow<Self::IU>; 0],
52 cm_t: &Self::Proof<2, 0>,
53 ) -> Result<Self::RU, Error> {
54 let (U1, U2) = (U1.borrow(), U2.borrow());
55
56 let rho_bits = transcript.add(&(U1, U2)).add(cm_t).challenge_bits(B);
57 let rho = CM::Scalar::from_bits_le(&rho_bits);
58 let rho_squared = rho * rho;
59
60 Ok(Self::RU {
61 cm_e: U1.cm_e + cm_t.mul(rho) + U2.cm_e.mul(rho_squared),
62 u: U1.u + rho * U2.u,
63 cm_w: U1.cm_w + U2.cm_w.mul(rho),
64 x: cfg_iter!(U1.x)
65 .zip_eq(&U2.x)
66 .map(|(a, b)| rho * b + a)
67 .collect(),
68 })
69 }
70}