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
  8pub mod boolean;
  9pub mod uint8;
 10#[macro_use]
 11pub mod uint;
 12
 13make_uint!(UInt16, 16, u16, uint16);
 14make_uint!(UInt32, 32, u32, uint32);
 15make_uint!(UInt64, 64, u64, uint64);
 16
 17pub trait ToBitsGadget<F: Field> {
 18    /// Outputs the canonical little-endian bit-wise representation of `self`.
 19    ///
 20    /// This is the correct default for 99% of use cases.
 21    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError>;
 22
 23    /// Outputs a possibly non-unique bit-wise representation of `self`.
 24    ///
 25    /// If you're not absolutely certain that your usecase can get away with a
 26    /// non-canonical representation, please use `self.to_bits(cs)` instead.
 27    fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 28        self.to_bits_le()
 29    }
 30}
 31
 32impl<F: Field> ToBitsGadget<F> for Boolean<F> {
 33    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 34        Ok(vec![self.clone()])
 35    }
 36}
 37
 38impl<F: Field> ToBitsGadget<F> for [Boolean<F>] {
 39    /// Outputs `self`.
 40    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 41        Ok(self.to_vec())
 42    }
 43}
 44
 45impl<F: Field> ToBitsGadget<F> for UInt8<F> {
 46    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 47        Ok(self.bits.to_vec())
 48    }
 49}
 50
 51impl<F: Field> ToBitsGadget<F> for [UInt8<F>] {
 52    /// Interprets `self` as an integer, and outputs the little-endian
 53    /// bit-wise decomposition of that integer.
 54    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 55        let bits = self.iter().flat_map(|b| &b.bits).cloned().collect();
 56        Ok(bits)
 57    }
 58}
 59
 60impl<F: Field, T> ToBitsGadget<F> for Vec<T>
 61where
 62    [T]: ToBitsGadget<F>,
 63{
 64    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 65        self.as_slice().to_bits_le().map(|v| v.to_vec())
 66    }
 67
 68    fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 69        self.as_slice().to_non_unique_bits_le().map(|v| v.to_vec())
 70    }
 71}
 72
 73pub trait ToBytesGadget<F: Field> {
 74    /// Outputs a canonical, little-endian, byte decomposition of `self`.
 75    ///
 76    /// This is the correct default for 99% of use cases.
 77    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
 78
 79    /// Outputs a possibly non-unique byte decomposition of `self`.
 80    ///
 81    /// If you're not absolutely certain that your usecase can get away with a
 82    /// non-canonical representation, please use `self.to_bytes(cs)` instead.
 83    fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
 84        self.to_bytes()
 85    }
 86}
 87
 88impl<F: Field> ToBytesGadget<F> for [UInt8<F>] {
 89    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
 90        Ok(self.to_vec())
 91    }
 92}
 93
 94impl<'a, F: Field, T: 'a + ToBytesGadget<F>> ToBytesGadget<F> for &'a T {
 95    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
 96        (*self).to_bytes()
 97    }
 98}
 99
100impl<'a, F: Field> ToBytesGadget<F> for &'a [UInt8<F>] {
101    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
102        Ok(self.to_vec())
103    }
104}