arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/src/uint/or.rs
src/uint/or.rsRaw
  1use ark_ff::PrimeField;
  2use ark_relations::r1cs::SynthesisError;
  3use ark_std::{ops::BitOr, ops::BitOrAssign};
  4
  5use super::{PrimUInt, UInt};
  6
  7impl<const N: usize, T: PrimUInt, F: PrimeField> UInt<N, T, F> {
  8    fn _or(&self, other: &Self) -> Result<Self, SynthesisError> {
  9        let mut result = self.clone();
 10        for (a, b) in result.bits.iter_mut().zip(&other.bits) {
 11            *a |= b;
 12        }
 13        result.value = self.value.and_then(|a| Some(a | other.value?));
 14        Ok(result)
 15    }
 16}
 17
 18impl<'a, const N: usize, T: PrimUInt, F: PrimeField> BitOr<Self> for &'a UInt<N, T, F> {
 19    type Output = UInt<N, T, F>;
 20
 21    /// Output `self | other`.
 22    ///
 23    /// If at least one of `self` and `other` are constants, then this method
 24    /// *does not* create any constraints or variables.
 25    ///
 26    /// ```
 27    /// # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
 28    /// // We'll use the BLS12-381 scalar field for our constraints.
 29    /// use ark_test_curves::bls12_381::Fr;
 30    /// use ark_relations::r1cs::*;
 31    /// use ark_r1cs_std::prelude::*;
 32    ///
 33    /// let cs = ConstraintSystem::<Fr>::new_ref();
 34    /// let a = UInt8::new_witness(cs.clone(), || Ok(16))?;
 35    /// let b = UInt8::new_witness(cs.clone(), || Ok(17))?;
 36    /// let c = UInt8::new_witness(cs.clone(), || Ok(16 | 17))?;
 37    ///
 38    /// (a | b).enforce_equal(&c)?;
 39    /// assert!(cs.is_satisfied().unwrap());
 40    /// # Ok(())
 41    /// # }
 42    /// ```
 43    #[tracing::instrument(target = "r1cs", skip(self, other))]
 44    fn bitor(self, other: Self) -> Self::Output {
 45        self._or(other).unwrap()
 46    }
 47}
 48
 49impl<'a, const N: usize, T: PrimUInt, F: PrimeField> BitOr<&'a Self> for UInt<N, T, F> {
 50    type Output = UInt<N, T, F>;
 51
 52    #[tracing::instrument(target = "r1cs", skip(self, other))]
 53    fn bitor(self, other: &Self) -> Self::Output {
 54        self._or(&other).unwrap()
 55    }
 56}
 57
 58impl<'a, const N: usize, T: PrimUInt, F: PrimeField> BitOr<UInt<N, T, F>> for &'a UInt<N, T, F> {
 59    type Output = UInt<N, T, F>;
 60
 61    #[tracing::instrument(target = "r1cs", skip(self, other))]
 62    fn bitor(self, other: UInt<N, T, F>) -> Self::Output {
 63        self._or(&other).unwrap()
 64    }
 65}
 66
 67impl<const N: usize, T: PrimUInt, F: PrimeField> BitOr<Self> for UInt<N, T, F> {
 68    type Output = Self;
 69
 70    #[tracing::instrument(target = "r1cs", skip(self, other))]
 71    fn bitor(self, other: Self) -> Self::Output {
 72        self._or(&other).unwrap()
 73    }
 74}
 75
 76impl<const N: usize, T: PrimUInt, F: PrimeField> BitOrAssign<Self> for UInt<N, T, F> {
 77    /// Sets `self = self | other`.
 78    ///
 79    /// If at least one of `self` and `other` are constants, then this method
 80    /// *does not* create any constraints or variables.
 81    ///
 82    /// ```
 83    /// # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
 84    /// // We'll use the BLS12-381 scalar field for our constraints.
 85    /// use ark_test_curves::bls12_381::Fr;
 86    /// use ark_relations::r1cs::*;
 87    /// use ark_r1cs_std::prelude::*;
 88    ///
 89    /// let cs = ConstraintSystem::<Fr>::new_ref();
 90    /// let mut a = UInt8::new_witness(cs.clone(), || Ok(16))?;
 91    /// let b = UInt8::new_witness(cs.clone(), || Ok(17))?;
 92    /// let c = UInt8::new_witness(cs.clone(), || Ok(16 | 17))?;
 93    ///
 94    /// a |= b;
 95    /// a.enforce_equal(&c)?;
 96    /// assert!(cs.is_satisfied().unwrap());
 97    /// # Ok(())
 98    /// # }
 99    /// ```
100    #[tracing::instrument(target = "r1cs", skip(self, other))]
101    fn bitor_assign(&mut self, other: Self) {
102        let result = self._or(&other).unwrap();
103        *self = result;
104    }
105}
106
107impl<'a, const N: usize, T: PrimUInt, F: PrimeField> BitOrAssign<&'a Self> for UInt<N, T, F> {
108    #[tracing::instrument(target = "r1cs", skip(self, other))]
109    fn bitor_assign(&mut self, other: &'a Self) {
110        let result = self._or(other).unwrap();
111        *self = result;
112    }
113}
114
115#[cfg(test)]
116mod tests {
117    use super::*;
118    use crate::{
119        alloc::{AllocVar, AllocationMode},
120        prelude::EqGadget,
121        uint::test_utils::{run_binary_exhaustive, run_binary_random},
122        R1CSVar,
123    };
124    use ark_ff::PrimeField;
125    use ark_test_curves::bls12_381::Fr;
126
127    fn uint_or<T: PrimUInt, const N: usize, F: PrimeField>(
128        a: UInt<N, T, F>,
129        b: UInt<N, T, F>,
130    ) -> Result<(), SynthesisError> {
131        let cs = a.cs().or(b.cs());
132        let both_constant = a.is_constant() && b.is_constant();
133        let computed = &a | &b;
134        let expected_mode = if both_constant {
135            AllocationMode::Constant
136        } else {
137            AllocationMode::Witness
138        };
139        let expected = UInt::<N, T, F>::new_variable(
140            cs.clone(),
141            || Ok(a.value()? | b.value()?),
142            expected_mode,
143        )?;
144        assert_eq!(expected.value(), computed.value());
145        expected.enforce_equal(&computed)?;
146        if !both_constant {
147            assert!(cs.is_satisfied().unwrap());
148        }
149        Ok(())
150    }
151
152    #[test]
153    fn u8_or() {
154        run_binary_exhaustive(uint_or::<u8, 8, Fr>).unwrap()
155    }
156
157    #[test]
158    fn u16_or() {
159        run_binary_random::<1000, 16, _, _>(uint_or::<u16, 16, Fr>).unwrap()
160    }
161
162    #[test]
163    fn u32_or() {
164        run_binary_random::<1000, 32, _, _>(uint_or::<u32, 32, Fr>).unwrap()
165    }
166
167    #[test]
168    fn u64_or() {
169        run_binary_random::<1000, 64, _, _>(uint_or::<u64, 64, Fr>).unwrap()
170    }
171
172    #[test]
173    fn u128_or() {
174        run_binary_random::<1000, 128, _, _>(uint_or::<u128, 128, Fr>).unwrap()
175    }
176}