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