arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/r1cs-std/src/bits/mod.rs
r1cs-std/src/bits/mod.rsRaw
  1use crate::{
  2    bits::{boolean::Boolean, uint8::UInt8},
  3    Vec,
  4};
  5use algebra::Field;
  6use r1cs_core::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 equivalents of
 13/// `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 of `self`.
 22pub trait ToBitsGadget<F: Field> {
 23    /// Outputs the canonical little-endian bit-wise representation of `self`.
 24    ///
 25    /// This is the correct default for 99% of use cases.
 26    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError>;
 27
 28    /// Outputs a possibly non-unique bit-wise representation of `self`.
 29    ///
 30    /// If you're not absolutely certain that your usecase can get away with a
 31    /// non-canonical representation, please use `self.to_bits(cs)` instead.
 32    fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 33        self.to_bits_le()
 34    }
 35}
 36
 37impl<F: Field> ToBitsGadget<F> for Boolean<F> {
 38    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 39        Ok(vec![self.clone()])
 40    }
 41}
 42
 43impl<F: Field> ToBitsGadget<F> for [Boolean<F>] {
 44    /// Outputs `self`.
 45    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 46        Ok(self.to_vec())
 47    }
 48}
 49
 50impl<F: Field> ToBitsGadget<F> for UInt8<F> {
 51    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 52        Ok(self.bits.to_vec())
 53    }
 54}
 55
 56impl<F: Field> ToBitsGadget<F> for [UInt8<F>] {
 57    /// Interprets `self` as an integer, and outputs the little-endian
 58    /// bit-wise decomposition of that integer.
 59    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 60        let bits = self.iter().flat_map(|b| &b.bits).cloned().collect();
 61        Ok(bits)
 62    }
 63}
 64
 65impl<F: Field, T> ToBitsGadget<F> for Vec<T>
 66where
 67    [T]: ToBitsGadget<F>,
 68{
 69    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 70        self.as_slice().to_bits_le().map(|v| v.to_vec())
 71    }
 72
 73    fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 74        self.as_slice().to_non_unique_bits_le().map(|v| v.to_vec())
 75    }
 76}
 77
 78/// Specifies constraints for conversion to a little-endian byte representation of `self`.
 79pub trait ToBytesGadget<F: Field> {
 80    /// Outputs a canonical, little-endian, byte decomposition of `self`.
 81    ///
 82    /// This is the correct default for 99% of use cases.
 83    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
 84
 85    /// Outputs a possibly non-unique byte decomposition of `self`.
 86    ///
 87    /// If you're not absolutely certain that your usecase can get away with a
 88    /// non-canonical representation, please use `self.to_bytes(cs)` instead.
 89    fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
 90        self.to_bytes()
 91    }
 92}
 93
 94impl<F: Field> ToBytesGadget<F> for [UInt8<F>] {
 95    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
 96        Ok(self.to_vec())
 97    }
 98}
 99
100impl<'a, F: Field, T: 'a + ToBytesGadget<F>> ToBytesGadget<F> for &'a T {
101    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
102        (*self).to_bytes()
103    }
104}
105
106impl<'a, F: Field> ToBytesGadget<F> for &'a [UInt8<F>] {
107    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
108        Ok(self.to_vec())
109    }
110}