sonobe_fs/nova/instances/
circuits.rs1use ark_r1cs_std::{
4 GR1CSVar,
5 alloc::{AllocVar, AllocationMode},
6 fields::fp::FpVar,
7 prelude::Boolean,
8 select::CondSelectGadget,
9};
10use ark_relations::gr1cs::{ConstraintSystemRef, Namespace, SynthesisError};
11use ark_std::borrow::Borrow;
12use sonobe_primitives::{commitments::CommitmentDefGadget, transcripts::AbsorbableVar};
13
14use super::{IncomingInstance, RunningInstance};
15use crate::FoldingInstanceVar;
16
17#[derive(Clone, Debug, PartialEq)]
19pub struct RunningInstanceVar<CM: CommitmentDefGadget> {
20 pub cm_e: CM::CommitmentVar,
22 pub u: CM::ScalarVar,
24 pub cm_w: CM::CommitmentVar,
26 pub x: Vec<CM::ScalarVar>,
29}
30
31impl<CM: CommitmentDefGadget> AllocVar<RunningInstance<CM::Widget>, CM::ConstraintField>
32 for RunningInstanceVar<CM>
33{
34 fn new_variable<T: Borrow<RunningInstance<CM::Widget>>>(
35 cs: impl Into<Namespace<CM::ConstraintField>>,
36 f: impl FnOnce() -> Result<T, SynthesisError>,
37 mode: AllocationMode,
38 ) -> Result<Self, SynthesisError> {
39 let cs = cs.into().cs();
40 let v = f()?;
41 let RunningInstance { cm_e, u, cm_w, x } = v.borrow();
42 Ok(Self {
43 cm_e: AllocVar::new_variable(cs.clone(), || Ok(cm_e), mode)?,
44 u: AllocVar::new_variable(cs.clone(), || Ok(u), mode)?,
45 cm_w: AllocVar::new_variable(cs.clone(), || Ok(cm_w), mode)?,
46 x: AllocVar::new_variable(cs.clone(), || Ok(&x[..]), mode)?,
47 })
48 }
49}
50
51impl<CM: CommitmentDefGadget> GR1CSVar<CM::ConstraintField> for RunningInstanceVar<CM> {
52 type Value = RunningInstance<CM::Widget>;
53
54 fn cs(&self) -> ConstraintSystemRef<CM::ConstraintField> {
55 self.cm_e
56 .cs()
57 .or(self.u.cs())
58 .or(self.cm_w.cs())
59 .or(self.x.cs())
60 }
61
62 fn value(&self) -> Result<Self::Value, SynthesisError> {
63 Ok(RunningInstance {
64 cm_e: self.cm_e.value()?,
65 u: self.u.value()?,
66 cm_w: self.cm_w.value()?,
67 x: self.x.value()?,
68 })
69 }
70}
71
72impl<CM: CommitmentDefGadget> AbsorbableVar<CM::ConstraintField> for RunningInstanceVar<CM> {
73 fn absorb_into(
74 &self,
75 dest: &mut Vec<FpVar<CM::ConstraintField>>,
76 ) -> Result<(), SynthesisError> {
77 self.u.absorb_into(dest)?;
78 self.x.absorb_into(dest)?;
79 self.cm_e.absorb_into(dest)?;
80 self.cm_w.absorb_into(dest)
81 }
82}
83
84impl<CM: CommitmentDefGadget> CondSelectGadget<CM::ConstraintField> for RunningInstanceVar<CM> {
85 fn conditionally_select(
86 cond: &Boolean<CM::ConstraintField>,
87 true_value: &Self,
88 false_value: &Self,
89 ) -> Result<Self, SynthesisError> {
90 if true_value.x.len() != false_value.x.len() {
91 return Err(SynthesisError::Unsatisfiable);
92 }
93 Ok(Self {
94 cm_e: cond.select(&true_value.cm_e, &false_value.cm_e)?,
95 u: cond.select(&true_value.u, &false_value.u)?,
96 cm_w: cond.select(&true_value.cm_w, &false_value.cm_w)?,
97 x: true_value
98 .x
99 .iter()
100 .zip(&false_value.x)
101 .map(|(t, f)| cond.select(t, f))
102 .collect::<Result<_, _>>()?,
103 })
104 }
105}
106
107impl<CM: CommitmentDefGadget> FoldingInstanceVar<CM> for RunningInstanceVar<CM> {
108 fn commitments(&self) -> Vec<&CM::CommitmentVar> {
109 vec![&self.cm_w, &self.cm_e]
110 }
111
112 fn public_inputs(&self) -> &Vec<CM::ScalarVar> {
113 &self.x
114 }
115
116 fn new_witness_with_public_inputs(
117 cs: impl Into<Namespace<CM::ConstraintField>>,
118 u: &Self::Value,
119 x: Vec<CM::ScalarVar>,
120 ) -> Result<Self, SynthesisError> {
121 let cs = cs.into().cs();
122 Ok(Self {
123 cm_e: AllocVar::new_witness(cs.clone(), || Ok(&u.cm_e))?,
124 u: AllocVar::new_witness(cs.clone(), || Ok(&u.u))?,
125 cm_w: AllocVar::new_witness(cs.clone(), || Ok(&u.cm_w))?,
126 x,
127 })
128 }
129}
130
131#[derive(Clone, Debug, PartialEq)]
133pub struct IncomingInstanceVar<CM: CommitmentDefGadget> {
134 pub cm_w: CM::CommitmentVar,
136 pub x: Vec<CM::ScalarVar>,
139}
140
141impl<CM: CommitmentDefGadget> AllocVar<IncomingInstance<CM::Widget>, CM::ConstraintField>
142 for IncomingInstanceVar<CM>
143{
144 fn new_variable<T: Borrow<IncomingInstance<CM::Widget>>>(
145 cs: impl Into<Namespace<CM::ConstraintField>>,
146 f: impl FnOnce() -> Result<T, SynthesisError>,
147 mode: AllocationMode,
148 ) -> Result<Self, SynthesisError> {
149 let cs = cs.into().cs();
150 let v = f()?;
151 let IncomingInstance { cm_w, x } = v.borrow();
152 Ok(Self {
153 cm_w: AllocVar::new_variable(cs.clone(), || Ok(cm_w), mode)?,
154 x: AllocVar::new_variable(cs.clone(), || Ok(&x[..]), mode)?,
155 })
156 }
157}
158
159impl<CM: CommitmentDefGadget> GR1CSVar<CM::ConstraintField> for IncomingInstanceVar<CM> {
160 type Value = IncomingInstance<CM::Widget>;
161
162 fn cs(&self) -> ConstraintSystemRef<CM::ConstraintField> {
163 self.cm_w.cs().or(self.x.cs())
164 }
165
166 fn value(&self) -> Result<Self::Value, SynthesisError> {
167 Ok(IncomingInstance {
168 cm_w: self.cm_w.value()?,
169 x: self.x.value()?,
170 })
171 }
172}
173
174impl<CM: CommitmentDefGadget> AbsorbableVar<CM::ConstraintField> for IncomingInstanceVar<CM> {
175 fn absorb_into(
176 &self,
177 dest: &mut Vec<FpVar<CM::ConstraintField>>,
178 ) -> Result<(), SynthesisError> {
179 self.x.absorb_into(dest)?;
180 self.cm_w.absorb_into(dest)
181 }
182}
183
184impl<CM: CommitmentDefGadget> CondSelectGadget<CM::ConstraintField> for IncomingInstanceVar<CM> {
185 fn conditionally_select(
186 cond: &Boolean<CM::ConstraintField>,
187 true_value: &Self,
188 false_value: &Self,
189 ) -> Result<Self, SynthesisError> {
190 if true_value.x.len() != false_value.x.len() {
191 return Err(SynthesisError::Unsatisfiable);
192 }
193 Ok(Self {
194 cm_w: cond.select(&true_value.cm_w, &false_value.cm_w)?,
195 x: true_value
196 .x
197 .iter()
198 .zip(&false_value.x)
199 .map(|(t, f)| cond.select(t, f))
200 .collect::<Result<_, _>>()?,
201 })
202 }
203}
204
205impl<CM: CommitmentDefGadget> FoldingInstanceVar<CM> for IncomingInstanceVar<CM> {
206 fn commitments(&self) -> Vec<&CM::CommitmentVar> {
207 vec![&self.cm_w]
208 }
209
210 fn public_inputs(&self) -> &Vec<CM::ScalarVar> {
211 &self.x
212 }
213
214 fn new_witness_with_public_inputs(
215 cs: impl Into<Namespace<CM::ConstraintField>>,
216 u: &Self::Value,
217 x: Vec<CM::ScalarVar>,
218 ) -> Result<Self, SynthesisError> {
219 let cs = cs.into().cs();
220 Ok(Self {
221 cm_w: AllocVar::new_witness(cs.clone(), || Ok(&u.cm_w))?,
222 x,
223 })
224 }
225}