use ark_ff::Field;
use ark_relations::r1cs::SynthesisError;
use ark_std::vec::Vec;
use crate::{boolean::Boolean, uint8::UInt8};
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, 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_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
self.to_bytes_le()
}
}
impl<'a, F: Field, T: 'a + ToBytesGadget<F>> ToBytesGadget<F> for &'a T {
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
(*self).to_bytes_le()
}
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
(*self).to_non_unique_bytes_le()
}
}
impl<T: ToBytesGadget<F>, F: Field> ToBytesGadget<F> for [T] {
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
let mut bytes = Vec::new();
for elem in self {
let elem = elem.to_bytes_le()?;
bytes.extend_from_slice(&elem);
bytes.reserve(elem.len() * (self.len() - 1));
}
Ok(bytes)
}
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
let mut bytes = Vec::new();
for elem in self {
let elem = elem.to_non_unique_bytes_le()?;
bytes.extend_from_slice(&elem);
bytes.reserve(elem.len() * (self.len() - 1));
}
Ok(bytes)
}
}
impl<T: ToBytesGadget<F>, F: Field> ToBytesGadget<F> for Vec<T> {
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
self.as_slice().to_bytes_le()
}
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
self.as_slice().to_non_unique_bytes_le()
}
}
impl<T: ToBytesGadget<F>, F: Field, const N: usize> ToBytesGadget<F> for [T; N] {
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
self.as_slice().to_bytes_le()
}
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
self.as_slice().to_non_unique_bytes_le()
}
}
impl<F: Field> ToBytesGadget<F> for () {
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
Ok(Vec::new())
}
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
Ok(Vec::new())
}
}
pub trait ToConstraintFieldGadget<ConstraintF: ark_ff::PrimeField> {
fn to_constraint_field(
&self,
) -> Result<Vec<crate::fields::fp::FpVar<ConstraintF>>, ark_relations::r1cs::SynthesisError>;
}