ark-r1cs-std/r1cs-std/src/eq.rs
r1cs-std/src/eq.rsRaw
1use crate::prelude::*;
2use algebra::Field;
3use r1cs_core::{ConstraintSystem, SynthesisError};
4
5/// If `condition == 1`, then enforces that `self` and `other` are equal;
6/// otherwise, it doesn't enforce anything.
7pub trait ConditionalEqGadget<ConstraintF: Field>: Eq {
8 fn conditional_enforce_equal<CS: ConstraintSystem<ConstraintF>>(
9 &self,
10 cs: CS,
11 other: &Self,
12 condition: &Boolean,
13 ) -> Result<(), SynthesisError>;
14
15 fn cost() -> usize;
16}
17impl<T: ConditionalEqGadget<ConstraintF>, ConstraintF: Field> ConditionalEqGadget<ConstraintF>
18 for [T]
19{
20 fn conditional_enforce_equal<CS: ConstraintSystem<ConstraintF>>(
21 &self,
22 mut cs: CS,
23 other: &Self,
24 condition: &Boolean,
25 ) -> Result<(), SynthesisError> {
26 for (i, (a, b)) in self.iter().zip(other.iter()).enumerate() {
27 let mut cs = cs.ns(|| format!("Iteration {}", i));
28 a.conditional_enforce_equal(&mut cs, b, condition)?;
29 }
30 Ok(())
31 }
32
33 fn cost() -> usize {
34 unimplemented!()
35 }
36}
37
38pub trait EqGadget<ConstraintF: Field>: Eq
39where
40 Self: ConditionalEqGadget<ConstraintF>,
41{
42 fn enforce_equal<CS: ConstraintSystem<ConstraintF>>(
43 &self,
44 cs: CS,
45 other: &Self,
46 ) -> Result<(), SynthesisError> {
47 self.conditional_enforce_equal(cs, other, &Boolean::constant(true))
48 }
49
50 fn cost() -> usize {
51 <Self as ConditionalEqGadget<ConstraintF>>::cost()
52 }
53}
54
55impl<T: EqGadget<ConstraintF>, ConstraintF: Field> EqGadget<ConstraintF> for [T] {}
56
57pub trait NEqGadget<ConstraintF: Field>: Eq {
58 fn enforce_not_equal<CS: ConstraintSystem<ConstraintF>>(
59 &self,
60 cs: CS,
61 other: &Self,
62 ) -> Result<(), SynthesisError>;
63
64 fn cost() -> usize;
65}
66
67pub trait OrEqualsGadget<ConstraintF: Field>
68where
69 Self: Sized,
70{
71 fn enforce_equal_or<CS: ConstraintSystem<ConstraintF>>(
72 cs: CS,
73 cond: &Boolean,
74 var: &Self,
75 first: &Self,
76 second: &Self,
77 ) -> Result<(), SynthesisError>;
78
79 fn cost() -> usize;
80}
81
82impl<ConstraintF: Field, T: Sized + ConditionalOrEqualsGadget<ConstraintF>>
83 OrEqualsGadget<ConstraintF> for T
84{
85 fn enforce_equal_or<CS: ConstraintSystem<ConstraintF>>(
86 cs: CS,
87 cond: &Boolean,
88 var: &Self,
89 first: &Self,
90 second: &Self,
91 ) -> Result<(), SynthesisError> {
92 Self::conditional_enforce_equal_or(cs, cond, var, first, second, &Boolean::Constant(true))
93 }
94
95 fn cost() -> usize {
96 <Self as ConditionalOrEqualsGadget<ConstraintF>>::cost()
97 }
98}
99
100pub trait ConditionalOrEqualsGadget<ConstraintF: Field>
101where
102 Self: Sized,
103{
104 fn conditional_enforce_equal_or<CS: ConstraintSystem<ConstraintF>>(
105 cs: CS,
106 cond: &Boolean,
107 var: &Self,
108 first: &Self,
109 second: &Self,
110 should_enforce: &Boolean,
111 ) -> Result<(), SynthesisError>;
112
113 fn cost() -> usize;
114}
115
116impl<
117 ConstraintF: Field,
118 T: Sized + ConditionalEqGadget<ConstraintF> + CondSelectGadget<ConstraintF>,
119 > ConditionalOrEqualsGadget<ConstraintF> for T
120{
121 fn conditional_enforce_equal_or<CS: ConstraintSystem<ConstraintF>>(
122 mut cs: CS,
123 cond: &Boolean,
124 var: &Self,
125 first: &Self,
126 second: &Self,
127 should_enforce: &Boolean,
128 ) -> Result<(), SynthesisError> {
129 let match_opt = Self::conditionally_select(
130 &mut cs.ns(|| "conditional_select_in_or"),
131 cond,
132 first,
133 second,
134 )?;
135 var.conditional_enforce_equal(&mut cs.ns(|| "equals_in_or"), &match_opt, should_enforce)
136 }
137
138 fn cost() -> usize {
139 <Self as ConditionalEqGadget<ConstraintF>>::cost()
140 + <Self as CondSelectGadget<ConstraintF>>::cost()
141 }
142}