use crate::bits::Boolean;
use snarkvm_fields::Field;
use snarkvm_r1cs::{errors::SynthesisError, ConstraintSystem};
pub trait CondSelectGadget<F: Field>
where
Self: Sized,
{
fn conditionally_select<CS: ConstraintSystem<F>>(
cs: CS,
cond: &Boolean,
first: &Self,
second: &Self,
) -> Result<Self, SynthesisError>;
fn cost() -> usize;
}
impl<F: Field, T: CondSelectGadget<F>> CondSelectGadget<F> for Vec<T> {
fn conditionally_select<CS: ConstraintSystem<F>>(
mut cs: CS,
cond: &Boolean,
first: &Self,
second: &Self,
) -> Result<Self, SynthesisError> {
assert_eq!(first.len(), second.len());
let mut res = Vec::<T>::with_capacity(first.len());
for (i, (left, right)) in first.iter().zip(second.iter()).enumerate() {
res.push(T::conditionally_select(
cs.ns(|| format!("conditional_select_{}", i)),
cond,
left,
right,
)?)
}
Ok(res)
}
fn cost() -> usize {
unimplemented!()
}
}
pub trait TwoBitLookupGadget<F: Field>
where
Self: Sized,
{
type TableConstant;
fn two_bit_lookup<CS: ConstraintSystem<F>>(
cs: CS,
bits: &[Boolean],
constants: &[Self::TableConstant],
) -> Result<Self, SynthesisError>;
fn cost() -> usize;
}
pub trait ThreeBitCondNegLookupGadget<F: Field>
where
Self: Sized,
{
type TableConstant;
fn three_bit_cond_neg_lookup<CS: ConstraintSystem<F>>(
cs: CS,
bits: &[Boolean],
b0b1: &Boolean,
constants: &[Self::TableConstant],
) -> Result<Self, SynthesisError>;
fn cost() -> usize;
}