use ark_ff::Field; use ark_relations::r1cs::SynthesisError; use ark_std::vec::Vec; use crate::{boolean::Boolean, uint8::UInt8}; /// Specifies constraints for conversion to a little-endian bit representation /// of `self`. pub trait ToBitsGadget { /// Outputs the canonical little-endian bit-wise representation of `self`. /// /// This is the correct default for 99% of use cases. fn to_bits_le(&self) -> Result>, SynthesisError>; /// Outputs a possibly non-unique little-endian bit-wise representation of /// `self`. /// /// If you're not absolutely certain that your usecase can get away with a /// non-canonical representation, please use `self.to_bits()` instead. fn to_non_unique_bits_le(&self) -> Result>, SynthesisError> { self.to_bits_le() } /// Outputs the canonical big-endian bit-wise representation of `self`. fn to_bits_be(&self) -> Result>, SynthesisError> { let mut res = self.to_bits_le()?; res.reverse(); Ok(res) } /// Outputs a possibly non-unique big-endian bit-wise representation of /// `self`. fn to_non_unique_bits_be(&self) -> Result>, SynthesisError> { let mut res = self.to_non_unique_bits_le()?; res.reverse(); Ok(res) } } impl ToBitsGadget for Boolean { fn to_bits_le(&self) -> Result>, SynthesisError> { Ok(vec![self.clone()]) } } impl ToBitsGadget for [Boolean] { /// Outputs `self`. fn to_bits_le(&self) -> Result>, SynthesisError> { Ok(self.to_vec()) } } impl ToBitsGadget for Vec where [T]: ToBitsGadget, { fn to_bits_le(&self) -> Result>, SynthesisError> { self.as_slice().to_bits_le().map(|v| v.to_vec()) } fn to_non_unique_bits_le(&self) -> Result>, SynthesisError> { self.as_slice().to_non_unique_bits_le().map(|v| v.to_vec()) } } /// Specifies constraints for conversion to a little-endian byte representation /// of `self`. pub trait ToBytesGadget { /// Outputs a canonical, little-endian, byte decomposition of `self`. /// /// This is the correct default for 99% of use cases. fn to_bytes(&self) -> Result>, SynthesisError>; /// Outputs a possibly non-unique byte decomposition of `self`. /// /// If you're not absolutely certain that your usecase can get away with a /// non-canonical representation, please use `self.to_bytes(cs)` instead. fn to_non_unique_bytes(&self) -> Result>, SynthesisError> { self.to_bytes() } } impl<'a, F: Field, T: 'a + ToBytesGadget> ToBytesGadget for &'a T { fn to_bytes(&self) -> Result>, SynthesisError> { (*self).to_bytes() } } /// Specifies how to convert a variable of type `Self` to variables of /// type `FpVar` pub trait ToConstraintFieldGadget { /// Converts `self` to `FpVar` variables. fn to_constraint_field( &self, ) -> Result>, ark_relations::r1cs::SynthesisError>; }