use franklin_crypto::bellman::{Engine, Field, PrimeField};
#[derive(Clone)]
pub enum DomainStrategy {
FixedLength,
VariableLength,
CustomFixedLength,
CustomVariableLength,
NoPadding,
}
impl DomainStrategy {
pub(crate) fn compute_capacity<E: Engine>(&self, input_len: usize, rate: usize) -> Option<E::Fr> {
let mut repr = <E::Fr as PrimeField>::Repr::default();
repr.as_mut()[1] = 1u64; let mut el = E::Fr::from_repr(repr).unwrap();
let mut out_repr = <E::Fr as PrimeField>::Repr::default();
out_repr.as_mut()[0] = (rate - 1) as u64;
let out_el = E::Fr::from_repr(out_repr).unwrap();
match &self {
Self::FixedLength => {
let length_as_fe = E::Fr::from_str(&input_len.to_string()).unwrap();
el.mul_assign(&length_as_fe);
el.add_assign(&out_el);
Some(el)
}
Self::VariableLength => {
el.add_assign(&out_el);
Some(el)
}
Self::CustomFixedLength => {
let mut repr = <E::Fr as PrimeField>::Repr::default();
repr.as_mut()[0] = input_len as u64;
E::Fr::from_repr(repr).ok()
}
Self::CustomVariableLength => None,
_ => unimplemented!("unknown domain strategy"),
}
}
pub(crate) fn generate_padding_values<E: Engine>(&self, input_len: usize, rate: usize) -> Vec<E::Fr> {
assert!(input_len != 0, "empty input");
if input_len % rate == 0 {
return vec![];
}
let mut values_for_padding = Vec::with_capacity(rate);
match self {
Self::FixedLength => {
values_for_padding.resize(rate - input_len, E::Fr::zero());
values_for_padding
}
Self::VariableLength => {
values_for_padding.push(E::Fr::one());
while (values_for_padding.len() + input_len) % rate != 0 {
values_for_padding.push(E::Fr::zero());
}
values_for_padding
}
Self::CustomFixedLength => {
let mut cycle = input_len / rate;
if input_len % rate != 0 {
cycle += 1;
}
let padding_len = cycle * rate - input_len;
for _ in 0..padding_len {
values_for_padding.push(E::Fr::one());
}
values_for_padding
}
Self::CustomVariableLength => {
values_for_padding.push(E::Fr::one());
while (values_for_padding.len() + input_len) % rate != 0 {
values_for_padding.push(E::Fr::one());
}
values_for_padding
}
_ => unimplemented!("unknown domain strategy"),
}
}
}