Skip to main content

sonobe_fs/nova/algorithms/
verifier.rs

1//! Proof verification for Nova.
2
3use 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}