arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/src/bits/mod.rs
src/bits/mod.rsRaw
  1use crate::{
  2    bits::{boolean::Boolean, uint8::UInt8},
  3    Vec,
  4};
  5use ark_ff::Field;
  6use ark_relations::r1cs::SynthesisError;
  7
  8/// This module contains `Boolean`, a R1CS equivalent of the `bool` type.
  9pub mod boolean;
 10/// This module contains `UInt8`, a R1CS equivalent of the `u8` type.
 11pub mod uint8;
 12/// This module contains a macro for generating `UIntN` types, which are R1CS
 13/// equivalents of `N`-bit unsigned integers.
 14#[macro_use]
 15pub mod uint;
 16
 17make_uint!(UInt16, 16, u16, uint16, "16");
 18make_uint!(UInt32, 32, u32, uint32, "32");
 19make_uint!(UInt64, 64, u64, uint64, "64");
 20
 21/// Specifies constraints for conversion to a little-endian bit representation
 22/// of `self`.
 23pub trait ToBitsGadget<F: Field> {
 24    /// Outputs the canonical little-endian bit-wise representation of `self`.
 25    ///
 26    /// This is the correct default for 99% of use cases.
 27    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError>;
 28
 29    /// Outputs a possibly non-unique little-endian bit-wise representation of
 30    /// `self`.
 31    ///
 32    /// If you're not absolutely certain that your usecase can get away with a
 33    /// non-canonical representation, please use `self.to_bits()` instead.
 34    fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 35        self.to_bits_le()
 36    }
 37
 38    /// Outputs the canonical big-endian bit-wise representation of `self`.
 39    fn to_bits_be(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 40        let mut res = self.to_bits_le()?;
 41        res.reverse();
 42        Ok(res)
 43    }
 44
 45    /// Outputs a possibly non-unique big-endian bit-wise representation of
 46    /// `self`.
 47    fn to_non_unique_bits_be(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 48        let mut res = self.to_non_unique_bits_le()?;
 49        res.reverse();
 50        Ok(res)
 51    }
 52}
 53
 54impl<F: Field> ToBitsGadget<F> for Boolean<F> {
 55    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 56        Ok(vec![self.clone()])
 57    }
 58}
 59
 60impl<F: Field> ToBitsGadget<F> for [Boolean<F>] {
 61    /// Outputs `self`.
 62    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 63        Ok(self.to_vec())
 64    }
 65}
 66
 67impl<F: Field> ToBitsGadget<F> for UInt8<F> {
 68    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 69        Ok(self.bits.to_vec())
 70    }
 71}
 72
 73impl<F: Field> ToBitsGadget<F> for [UInt8<F>] {
 74    /// Interprets `self` as an integer, and outputs the little-endian
 75    /// bit-wise decomposition of that integer.
 76    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 77        let bits = self.iter().flat_map(|b| &b.bits).cloned().collect();
 78        Ok(bits)
 79    }
 80}
 81
 82impl<F: Field, T> ToBitsGadget<F> for Vec<T>
 83where
 84    [T]: ToBitsGadget<F>,
 85{
 86    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 87        self.as_slice().to_bits_le().map(|v| v.to_vec())
 88    }
 89
 90    fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 91        self.as_slice().to_non_unique_bits_le().map(|v| v.to_vec())
 92    }
 93}
 94
 95/// Specifies constraints for conversion to a little-endian byte representation
 96/// of `self`.
 97pub trait ToBytesGadget<F: Field> {
 98    /// Outputs a canonical, little-endian, byte decomposition of `self`.
 99    ///
100    /// This is the correct default for 99% of use cases.
101    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
102
103    /// Outputs a possibly non-unique byte decomposition of `self`.
104    ///
105    /// If you're not absolutely certain that your usecase can get away with a
106    /// non-canonical representation, please use `self.to_bytes(cs)` instead.
107    fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
108        self.to_bytes()
109    }
110}
111
112impl<F: Field> ToBytesGadget<F> for [UInt8<F>] {
113    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
114        Ok(self.to_vec())
115    }
116}
117
118impl<'a, F: Field, T: 'a + ToBytesGadget<F>> ToBytesGadget<F> for &'a T {
119    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
120        (*self).to_bytes()
121    }
122}
123
124impl<'a, F: Field> ToBytesGadget<F> for &'a [UInt8<F>] {
125    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
126        Ok(self.to_vec())
127    }
128}