use crate::prelude::*;
use ark_ff::Field;
use ark_relations::r1cs::SynthesisError;
use ark_std::vec::Vec;
pub trait CondSelectGadget<ConstraintF: Field>
where
Self: Sized,
Self: Clone,
{
fn conditionally_select(
cond: &Boolean<ConstraintF>,
true_value: &Self,
false_value: &Self,
) -> Result<Self, SynthesisError>;
fn conditionally_select_power_of_two_vector(
position: &[Boolean<ConstraintF>],
values: &[Self],
) -> Result<Self, SynthesisError> {
let m = values.len();
let n = position.len();
assert!(m.is_power_of_two());
assert_eq!(1 << n, m);
let mut cur_mux_values = values.to_vec();
for i in 0..n {
let cur_size = 1 << (n - i);
assert_eq!(cur_mux_values.len(), cur_size);
let mut next_mux_values = Vec::new();
for j in (0..cur_size).step_by(2) {
let cur = Self::conditionally_select(
&position[n - 1 - i],
&cur_mux_values[j + 1],
&cur_mux_values[j],
)?;
next_mux_values.push(cur);
}
cur_mux_values = next_mux_values;
}
Ok(cur_mux_values[0].clone())
}
}
pub trait TwoBitLookupGadget<ConstraintF: Field>
where
Self: Sized,
{
type TableConstant;
fn two_bit_lookup(
bits: &[Boolean<ConstraintF>],
constants: &[Self::TableConstant],
) -> Result<Self, SynthesisError>;
}
pub trait ThreeBitCondNegLookupGadget<ConstraintF: Field>
where
Self: Sized,
{
type TableConstant;
fn three_bit_cond_neg_lookup(
bits: &[Boolean<ConstraintF>],
b0b1: &Boolean<ConstraintF>,
constants: &[Self::TableConstant],
) -> Result<Self, SynthesisError>;
}