nova_snark/frontend/util_cs/
witness_cs.rs1use ff::PrimeField;
4
5use crate::frontend::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable};
6
7pub trait SizedWitness<Scalar: PrimeField> {
9 fn num_constraints(&self) -> usize;
11 fn num_inputs(&self) -> usize;
13 fn num_aux(&self) -> usize;
15
16 fn generate_witness_into(&mut self, aux: &mut [Scalar], inputs: &mut [Scalar]) -> Scalar;
18
19 fn generate_witness_into_cs<CS: ConstraintSystem<Scalar>>(&mut self, cs: &mut CS) -> Scalar {
21 assert!(cs.is_witness_generator());
22
23 let aux_count = self.num_aux();
24 let inputs_count = self.num_inputs();
25
26 let (aux, inputs) = cs.allocate_empty(aux_count, inputs_count);
27
28 assert_eq!(aux.len(), aux_count);
29 assert_eq!(inputs.len(), inputs_count);
30
31 self.generate_witness_into(aux, inputs)
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq)]
36pub struct WitnessCS<Scalar>
38where
39 Scalar: PrimeField,
40{
41 pub(crate) input_assignment: Vec<Scalar>,
43 pub(crate) aux_assignment: Vec<Scalar>,
44}
45
46impl<Scalar> WitnessCS<Scalar>
47where
48 Scalar: PrimeField,
49{
50 pub fn input_assignment(&self) -> &[Scalar] {
52 &self.input_assignment
53 }
54
55 pub fn aux_assignment(&self) -> &[Scalar] {
57 &self.aux_assignment
58 }
59}
60
61impl<Scalar> ConstraintSystem<Scalar> for WitnessCS<Scalar>
62where
63 Scalar: PrimeField,
64{
65 type Root = Self;
66
67 fn new() -> Self {
68 let input_assignment = vec![Scalar::ONE];
69
70 Self {
71 input_assignment,
72 aux_assignment: vec![],
73 }
74 }
75
76 fn alloc<F, A, AR>(&mut self, _: A, f: F) -> Result<Variable, SynthesisError>
77 where
78 F: FnOnce() -> Result<Scalar, SynthesisError>,
79 A: FnOnce() -> AR,
80 AR: Into<String>,
81 {
82 self.aux_assignment.push(f()?);
83
84 Ok(Variable(Index::Aux(self.aux_assignment.len() - 1)))
85 }
86
87 fn alloc_input<F, A, AR>(&mut self, _: A, f: F) -> Result<Variable, SynthesisError>
88 where
89 F: FnOnce() -> Result<Scalar, SynthesisError>,
90 A: FnOnce() -> AR,
91 AR: Into<String>,
92 {
93 self.input_assignment.push(f()?);
94
95 Ok(Variable(Index::Input(self.input_assignment.len() - 1)))
96 }
97
98 fn enforce<A, AR, LA, LB, LC>(&mut self, _: A, _a: LA, _b: LB, _c: LC)
99 where
100 A: FnOnce() -> AR,
101 AR: Into<String>,
102 LA: FnOnce(LinearCombination<Scalar>) -> LinearCombination<Scalar>,
103 LB: FnOnce(LinearCombination<Scalar>) -> LinearCombination<Scalar>,
104 LC: FnOnce(LinearCombination<Scalar>) -> LinearCombination<Scalar>,
105 {
106 }
108
109 fn push_namespace<NR, N>(&mut self, _: N)
110 where
111 NR: Into<String>,
112 N: FnOnce() -> NR,
113 {
114 }
116
117 fn pop_namespace(&mut self) {
118 }
120
121 fn get_root(&mut self) -> &mut Self::Root {
122 self
123 }
124
125 fn is_extensible() -> bool {
128 true
129 }
130
131 fn extend(&mut self, other: &Self) {
132 self.input_assignment
133 .extend(&other.input_assignment[1..]);
135 self.aux_assignment.extend(&other.aux_assignment);
136 }
137
138 fn is_witness_generator(&self) -> bool {
141 true
142 }
143
144 fn extend_inputs(&mut self, new_inputs: &[Scalar]) {
145 self.input_assignment.extend(new_inputs);
146 }
147
148 fn extend_aux(&mut self, new_aux: &[Scalar]) {
149 self.aux_assignment.extend(new_aux);
150 }
151
152 fn allocate_empty(&mut self, aux_n: usize, inputs_n: usize) -> (&mut [Scalar], &mut [Scalar]) {
153 let allocated_aux = {
154 let i = self.aux_assignment.len();
155 self.aux_assignment.resize(aux_n + i, Scalar::ZERO);
156 &mut self.aux_assignment[i..]
157 };
158
159 let allocated_inputs = {
160 let i = self.input_assignment.len();
161 self.input_assignment.resize(inputs_n + i, Scalar::ZERO);
162 &mut self.input_assignment[i..]
163 };
164
165 (allocated_aux, allocated_inputs)
166 }
167
168 fn inputs_slice(&self) -> &[Scalar] {
169 &self.input_assignment
170 }
171
172 fn aux_slice(&self) -> &[Scalar] {
173 &self.aux_assignment
174 }
175}