1use 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#[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}