Skip to main content

sonobe_fs/nova/keys/
mod.rs

1//! Definitions of Nova keys and trait implementations for relation checks and
2//! witness-instance sampling using Nova keys.
3
4use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
5use ark_std::{UniformRand, rand::RngCore, sync::Arc};
6use sonobe_primitives::{
7    arithmetizations::{
8        Arith, ArithConfig, ArithRelation,
9        r1cs::{RelaxedInstance, RelaxedWitness},
10    },
11    circuits::AssignmentsOwned,
12    commitments::{CommitmentDef, CommitmentOps},
13    relations::{Relation, WitnessInstanceSampler},
14};
15
16use super::{
17    instances::{IncomingInstance as IU, RunningInstance as RU},
18    witnesses::{IncomingWitness as IW, RunningWitness as RW},
19};
20use crate::{DeciderKey, Error, PlainInstance as PU, PlainWitness as PW};
21
22/// [`NovaKey`] is Nova's decider key.
23#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)]
24pub struct NovaKey<A: Arith, CM: CommitmentDef> {
25    pub(super) arith: Arc<A>,
26    pub(super) ck: Arc<CM::Key>,
27}
28
29impl<A: Arith, CM: CommitmentDef> DeciderKey for NovaKey<A, CM> {
30    type ProverKey = Self;
31    type VerifierKey = ();
32
33    fn to_pk(&self) -> &Self::ProverKey {
34        self
35    }
36
37    fn to_vk(&self) -> &Self::VerifierKey {
38        &()
39    }
40
41    fn to_arith_config(&self) -> ArithConfig {
42        self.arith.config()
43    }
44}
45
46impl<A, CM> Relation<RW<CM>, RU<CM>> for NovaKey<A, CM>
47where
48    A: for<'a> ArithRelation<RelaxedWitness<&'a [CM::Scalar]>, RelaxedInstance<&'a [CM::Scalar]>>,
49    CM: CommitmentOps,
50{
51    type Error = Error;
52
53    fn check_relation(&self, w: &RW<CM>, u: &RU<CM>) -> Result<(), Self::Error> {
54        self.arith.check_relation(
55            &RelaxedWitness { w: &w.w, e: &w.e },
56            &RelaxedInstance { x: &u.x, u: &u.u },
57        )?;
58        CM::open(&self.ck, &w.w, &w.r_w, &u.cm_w)?;
59        CM::open(&self.ck, &w.e, &w.r_e, &u.cm_e)?;
60        Ok(())
61    }
62}
63
64impl<A, CM> Relation<IW<CM>, IU<CM>> for NovaKey<A, CM>
65where
66    A: ArithRelation<Vec<CM::Scalar>, Vec<CM::Scalar>>,
67    CM: CommitmentOps,
68{
69    type Error = Error;
70
71    fn check_relation(&self, w: &IW<CM>, u: &IU<CM>) -> Result<(), Self::Error> {
72        self.arith.check_relation(&w.w, &u.x)?;
73        CM::open(&self.ck, &w.w, &w.r_w, &u.cm_w)?;
74        Ok(())
75    }
76}
77
78impl<A, CM> Relation<PW<CM::Scalar>, PU<CM::Scalar>> for NovaKey<A, CM>
79where
80    A: ArithRelation<Vec<CM::Scalar>, Vec<CM::Scalar>>,
81    CM: CommitmentDef,
82{
83    type Error = Error;
84
85    fn check_relation(&self, w: &PW<CM::Scalar>, u: &PU<CM::Scalar>) -> Result<(), Self::Error> {
86        self.arith.check_relation(w, u)?;
87        Ok(())
88    }
89}
90
91impl<A: Arith, CM: CommitmentOps> WitnessInstanceSampler<IW<CM>, IU<CM>> for NovaKey<A, CM> {
92    type Source = AssignmentsOwned<CM::Scalar>;
93    type Error = Error;
94
95    fn sample(&self, z: Self::Source, rng: impl RngCore) -> Result<(IW<CM>, IU<CM>), Error> {
96        let (w, x) = (z.private, z.public);
97        let (cm_w, r_w) = CM::commit(&self.ck, &w, rng)?;
98        Ok((IW { w, r_w }, IU { cm_w, x }))
99    }
100}
101
102impl<A: Arith, CM: CommitmentDef> WitnessInstanceSampler<PW<CM::Scalar>, PU<CM::Scalar>>
103    for NovaKey<A, CM>
104{
105    type Source = AssignmentsOwned<CM::Scalar>;
106    type Error = Error;
107
108    fn sample(
109        &self,
110        z: Self::Source,
111        _rng: impl RngCore,
112    ) -> Result<(PW<CM::Scalar>, PU<CM::Scalar>), Error> {
113        Ok((z.private.into(), z.public.into()))
114    }
115}
116
117impl<A, CM> WitnessInstanceSampler<RW<CM>, RU<CM>> for NovaKey<A, CM>
118where
119    A: for<'a> ArithRelation<
120            RelaxedWitness<&'a [CM::Scalar]>,
121            RelaxedInstance<&'a [CM::Scalar]>,
122            Evaluation = Vec<CM::Scalar>,
123        >,
124    CM: CommitmentOps,
125{
126    type Source = ();
127    type Error = Error;
128
129    fn sample(&self, _: Self::Source, mut rng: impl RngCore) -> Result<(RW<CM>, RU<CM>), Error> {
130        let cfg = self.arith.config();
131
132        let u = CM::Scalar::rand(&mut rng);
133        let x = (0..cfg.n_public_inputs)
134            .map(|_| CM::Scalar::rand(&mut rng))
135            .collect::<Vec<_>>();
136        let w = (0..cfg.n_witnesses)
137            .map(|_| CM::Scalar::rand(&mut rng))
138            .collect::<Vec<_>>();
139        let e = self.arith.eval_relation(
140            &RelaxedWitness { w: &w, e: &[] },
141            &RelaxedInstance { x: &x, u: &u },
142        )?;
143
144        let (cm_w, r_w) = CM::commit(&self.ck, &w, &mut rng)?;
145        let (cm_e, r_e) = CM::commit(&self.ck, &e, &mut rng)?;
146        Ok((RW { w, r_w, e, r_e }, RU { cm_w, x, cm_e, u }))
147    }
148}