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 little-endian 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()` instead.
 32    fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 33        self.to_bits_le()
 34    }
 35
 36    /// Outputs the canonical big-endian bit-wise representation of `self`.
 37    fn to_bits_be(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 38        let mut res = self.to_bits_le()?;
 39        res.reverse();
 40        Ok(res)
 41    }
 42
 43    /// Outputs a possibly non-unique big-endian bit-wise representation of `self`.
 44    fn to_non_unique_bits_be(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 45        let mut res = self.to_non_unique_bits_le()?;
 46        res.reverse();
 47        Ok(res)
 48    }
 49}
 50
 51impl<F: Field> ToBitsGadget<F> for Boolean<F> {
 52    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 53        Ok(vec![self.clone()])
 54    }
 55}
 56
 57impl<F: Field> ToBitsGadget<F> for [Boolean<F>] {
 58    /// Outputs `self`.
 59    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 60        Ok(self.to_vec())
 61    }
 62}
 63
 64impl<F: Field> ToBitsGadget<F> for UInt8<F> {
 65    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 66        Ok(self.bits.to_vec())
 67    }
 68}
 69
 70impl<F: Field> ToBitsGadget<F> for [UInt8<F>] {
 71    /// Interprets `self` as an integer, and outputs the little-endian
 72    /// bit-wise decomposition of that integer.
 73    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 74        let bits = self.iter().flat_map(|b| &b.bits).cloned().collect();
 75        Ok(bits)
 76    }
 77}
 78
 79impl<F: Field, T> ToBitsGadget<F> for Vec<T>
 80where
 81    [T]: ToBitsGadget<F>,
 82{
 83    fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 84        self.as_slice().to_bits_le().map(|v| v.to_vec())
 85    }
 86
 87    fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
 88        self.as_slice().to_non_unique_bits_le().map(|v| v.to_vec())
 89    }
 90}
 91
 92/// Specifies constraints for conversion to a little-endian byte representation of `self`.
 93pub trait ToBytesGadget<F: Field> {
 94    /// Outputs a canonical, little-endian, byte decomposition of `self`.
 95    ///
 96    /// This is the correct default for 99% of use cases.
 97    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
 98
 99    /// Outputs a possibly non-unique byte decomposition of `self`.
100    ///
101    /// If you're not absolutely certain that your usecase can get away with a
102    /// non-canonical representation, please use `self.to_bytes(cs)` instead.
103    fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
104        self.to_bytes()
105    }
106}
107
108impl<F: Field> ToBytesGadget<F> for [UInt8<F>] {
109    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
110        Ok(self.to_vec())
111    }
112}
113
114impl<'a, F: Field, T: 'a + ToBytesGadget<F>> ToBytesGadget<F> for &'a T {
115    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
116        (*self).to_bytes()
117    }
118}
119
120impl<'a, F: Field> ToBytesGadget<F> for &'a [UInt8<F>] {
121    fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
122        Ok(self.to_vec())
123    }
124}