ark-r1cs-std/r1cs-std/src/lib.rs
r1cs-std/src/lib.rsRaw
1#![deny(
2 unused_import_braces,
3 unused_qualifications,
4 trivial_casts,
5 trivial_numeric_casts
6)]
7#![deny(
8 unused_qualifications,
9 variant_size_differences,
10 stable_features,
11 unreachable_pub
12)]
13#![deny(
14 non_shorthand_field_patterns,
15 unused_attributes,
16 unused_imports,
17 unused_extern_crates
18)]
19#![deny(
20 renamed_and_removed_lints,
21 stable_features,
22 unused_allocation,
23 unused_comparisons,
24 bare_trait_objects
25)]
26#![deny(
27 const_err,
28 unused_must_use,
29 unused_mut,
30 unused_unsafe,
31 private_in_public,
32 unsafe_code
33)]
34#![forbid(unsafe_code)]
35
36#[macro_use]
37extern crate algebra;
38#[macro_use]
39extern crate derivative;
40
41use crate::ConstraintVar::*;
42use algebra::Field;
43use r1cs_core::{LinearCombination, SynthesisError, Variable};
44use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub};
45
46pub mod test_constraint_system;
47
48pub mod bits;
49pub use self::bits::*;
50
51pub mod fields;
52
53pub mod groups;
54
55pub mod pairing;
56
57pub mod eq;
58pub mod select;
59pub mod alloc;
60
61pub mod prelude {
62 pub use crate::eq::*;
63 pub use crate::select::*;
64 pub use crate::alloc::*;
65 pub use crate::fields::FieldGadget;
66 pub use crate::groups::GroupGadget;
67 pub use crate::bits::{ToBitsGadget, ToBytesGadget, boolean::Boolean, uint8::UInt8, uint32::UInt32};
68}
69
70pub trait Assignment<T> {
71 fn get(self) -> Result<T, SynthesisError>;
72}
73
74impl<T> Assignment<T> for Option<T> {
75 fn get(self) -> Result<T, SynthesisError> {
76 match self {
77 Some(v) => Ok(v),
78 None => Err(SynthesisError::AssignmentMissing),
79 }
80 }
81}
82
83#[derive(Clone, Debug)]
84pub enum ConstraintVar<F: Field> {
85 LC(LinearCombination<F>),
86 Var(Variable),
87}
88
89impl<F: Field> From<Variable> for ConstraintVar<F> {
90 #[inline]
91 fn from(var: Variable) -> Self {
92 Var(var)
93 }
94}
95
96impl<F: Field> From<(F, Variable)> for ConstraintVar<F> {
97 #[inline]
98 fn from(coeff_var: (F, Variable)) -> Self {
99 LC(coeff_var.into())
100 }
101}
102
103impl<F: Field> From<(F, LinearCombination<F>)> for ConstraintVar<F> {
104 #[inline]
105 fn from((coeff, mut lc): (F, LinearCombination<F>)) -> Self {
106 lc *= coeff;
107 LC(lc)
108 }
109}
110
111impl<F: Field> From<(F, ConstraintVar<F>)> for ConstraintVar<F> {
112 #[inline]
113 fn from((coeff, var): (F, ConstraintVar<F>)) -> Self {
114 match var {
115 LC(lc) => (coeff, lc).into(),
116 Var(var) => (coeff, var).into(),
117 }
118 }
119}
120
121impl<F: Field> ConstraintVar<F> {
122 #[inline]
123 pub fn zero() -> Self {
124 LC(LinearCombination::zero())
125 }
126
127 pub fn negate_in_place(&mut self) {
128 match self {
129 LC(ref mut lc) => lc.negate_in_place(),
130 Var(var) => *self = (-F::one(), *var).into(),
131 }
132 }
133
134 pub fn double_in_place(&mut self) {
135 match self {
136 LC(lc) => lc.double_in_place(),
137 Var(var) => *self = (F::one().double(), *var).into(),
138 }
139 }
140}
141
142impl<F: Field> Add<LinearCombination<F>> for ConstraintVar<F> {
143 type Output = LinearCombination<F>;
144
145 #[inline]
146 fn add(self, other_lc: LinearCombination<F>) -> LinearCombination<F> {
147 match self {
148 LC(lc) => other_lc + lc,
149 Var(var) => other_lc + var,
150 }
151 }
152}
153
154impl<F: Field> Sub<LinearCombination<F>> for ConstraintVar<F> {
155 type Output = LinearCombination<F>;
156
157 #[inline]
158 fn sub(self, other_lc: LinearCombination<F>) -> LinearCombination<F> {
159 let result = match self {
160 LC(lc) => other_lc - lc,
161 Var(var) => other_lc - var,
162 };
163 -result
164 }
165}
166
167impl<F: Field> Add<LinearCombination<F>> for &ConstraintVar<F> {
168 type Output = LinearCombination<F>;
169
170 #[inline]
171 fn add(self, other_lc: LinearCombination<F>) -> LinearCombination<F> {
172 match self {
173 LC(lc) => other_lc + lc,
174 Var(var) => other_lc + *var,
175 }
176 }
177}
178
179impl<F: Field> Sub<LinearCombination<F>> for &ConstraintVar<F> {
180 type Output = LinearCombination<F>;
181
182 #[inline]
183 fn sub(self, other_lc: LinearCombination<F>) -> LinearCombination<F> {
184 let result = match self {
185 LC(lc) => other_lc - lc,
186 Var(var) => other_lc - *var,
187 };
188 -result
189 }
190}
191
192impl<F: Field> Add<(F, Variable)> for ConstraintVar<F> {
193 type Output = Self;
194
195 #[inline]
196 fn add(self, var: (F, Variable)) -> Self {
197 let lc = match self {
198 LC(lc) => lc + var,
199 Var(var2) => LinearCombination::from(var2) + var,
200 };
201 LC(lc)
202 }
203}
204
205impl<F: Field> AddAssign<(F, Variable)> for ConstraintVar<F> {
206 #[inline]
207 fn add_assign(&mut self, var: (F, Variable)) {
208 match self {
209 LC(ref mut lc) => *lc += var,
210 Var(var2) => *self = LC(LinearCombination::from(*var2) + var),
211 };
212 }
213}
214
215impl<F: Field> Neg for ConstraintVar<F> {
216 type Output = Self;
217
218 #[inline]
219 fn neg(mut self) -> Self {
220 self.negate_in_place();
221 self
222 }
223}
224
225impl<F: Field> Mul<F> for ConstraintVar<F> {
226 type Output = Self;
227
228 #[inline]
229 fn mul(self, scalar: F) -> Self {
230 match self {
231 LC(lc) => LC(lc * scalar),
232 Var(var) => (scalar, var).into(),
233 }
234 }
235}
236
237impl<F: Field> MulAssign<F> for ConstraintVar<F> {
238 #[inline]
239 fn mul_assign(&mut self, scalar: F) {
240 match self {
241 LC(lc) => *lc *= scalar,
242 Var(var) => *self = (scalar, *var).into(),
243 }
244 }
245}
246
247impl<F: Field> Sub<(F, Variable)> for ConstraintVar<F> {
248 type Output = Self;
249
250 #[inline]
251 fn sub(self, (coeff, var): (F, Variable)) -> Self {
252 self + (-coeff, var)
253 }
254}
255
256impl<F: Field> Add<Variable> for ConstraintVar<F> {
257 type Output = Self;
258
259 fn add(self, other: Variable) -> Self {
260 self + (F::one(), other)
261 }
262}
263
264impl<F: Field> Sub<Variable> for ConstraintVar<F> {
265 type Output = Self;
266
267 #[inline]
268 fn sub(self, other: Variable) -> Self {
269 self - (F::one(), other)
270 }
271}
272
273impl<'a, F: Field> Add<&'a Self> for ConstraintVar<F> {
274 type Output = Self;
275
276 #[inline]
277 fn add(self, other: &'a Self) -> Self {
278 let lc = match self {
279 LC(lc2) => lc2,
280 Var(var) => var.into(),
281 };
282 let lc2 = match other {
283 LC(lc2) => lc + lc2,
284 Var(var) => lc + *var,
285 };
286 LC(lc2)
287 }
288}
289
290impl<'a, F: Field> Sub<&'a Self> for ConstraintVar<F> {
291 type Output = Self;
292
293 #[inline]
294 fn sub(self, other: &'a Self) -> Self {
295 let lc = match self {
296 LC(lc2) => lc2,
297 Var(var) => var.into(),
298 };
299 let lc2 = match other {
300 LC(lc2) => lc - lc2,
301 Var(var) => lc - *var,
302 };
303 LC(lc2)
304 }
305}
306
307impl<F: Field> Add<&ConstraintVar<F>> for &ConstraintVar<F> {
308 type Output = ConstraintVar<F>;
309
310 #[inline]
311 fn add(self, other: &ConstraintVar<F>) -> Self::Output {
312 (ConstraintVar::zero() + self) + other
313 }
314}
315
316impl<F: Field> Sub<&ConstraintVar<F>> for &ConstraintVar<F> {
317 type Output = ConstraintVar<F>;
318
319 #[inline]
320 fn sub(self, other: &ConstraintVar<F>) -> Self::Output {
321 (ConstraintVar::zero() + self) - other
322 }
323}
324
325impl<'a, F: Field> Add<(F, &'a Self)> for ConstraintVar<F> {
326 type Output = Self;
327
328 #[inline]
329 fn add(self, (coeff, other): (F, &'a Self)) -> Self {
330 let mut lc = match self {
331 LC(lc2) => lc2,
332 Var(var) => LinearCombination::zero() + var,
333 };
334
335 lc = match other {
336 LC(lc2) => lc + (coeff, lc2),
337 Var(var) => lc + (coeff, *var),
338 };
339 LC(lc)
340 }
341}
342
343impl<'a, F: Field> Sub<(F, &'a Self)> for ConstraintVar<F> {
344 type Output = Self;
345
346 #[inline]
347 fn sub(self, (coeff, other): (F, &'a Self)) -> Self {
348 let mut lc = match self {
349 LC(lc2) => lc2,
350 Var(var) => LinearCombination::zero() + var,
351 };
352 lc = match other {
353 LC(lc2) => lc - (coeff, lc2),
354 Var(var) => lc - (coeff, *var),
355 };
356 LC(lc)
357 }
358}