use crate::{
bits::{boolean::Boolean, uint8::UInt8},
Vec,
};
use ark_ff::Field;
use ark_relations::r1cs::SynthesisError;
pub mod boolean;
pub mod uint8;
#[macro_use]
pub mod uint;
make_uint!(UInt16, 16, u16, uint16, "`U16`", "`u16`", "16");
make_uint!(UInt32, 32, u32, uint32, "`U32`", "`u32`", "32");
make_uint!(UInt64, 64, u64, uint64, "`U64`", "`u64`", "64");
make_uint!(UInt128, 128, u128, uint128, "`U128`", "`u128`", "128");
pub trait ToBitsGadget<F: Field> {
fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError>;
fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
self.to_bits_le()
}
fn to_bits_be(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
let mut res = self.to_bits_le()?;
res.reverse();
Ok(res)
}
fn to_non_unique_bits_be(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
let mut res = self.to_non_unique_bits_le()?;
res.reverse();
Ok(res)
}
}
impl<F: Field> ToBitsGadget<F> for Boolean<F> {
fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
Ok(vec![self.clone()])
}
}
impl<F: Field> ToBitsGadget<F> for [Boolean<F>] {
fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
Ok(self.to_vec())
}
}
impl<F: Field> ToBitsGadget<F> for UInt8<F> {
fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
Ok(self.bits.to_vec())
}
}
impl<F: Field> ToBitsGadget<F> for [UInt8<F>] {
fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
let bits = self.iter().flat_map(|b| &b.bits).cloned().collect();
Ok(bits)
}
}
impl<F: Field, T> ToBitsGadget<F> for Vec<T>
where
[T]: ToBitsGadget<F>,
{
fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
self.as_slice().to_bits_le().map(|v| v.to_vec())
}
fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
self.as_slice().to_non_unique_bits_le().map(|v| v.to_vec())
}
}
pub trait ToBytesGadget<F: Field> {
fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
self.to_bytes()
}
}
impl<F: Field> ToBytesGadget<F> for [UInt8<F>] {
fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
Ok(self.to_vec())
}
}
impl<'a, F: Field, T: 'a + ToBytesGadget<F>> ToBytesGadget<F> for &'a T {
fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
(*self).to_bytes()
}
}
impl<'a, F: Field> ToBytesGadget<F> for &'a [UInt8<F>] {
fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
Ok(self.to_vec())
}
}