arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
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}