Refactor "booleanization" of objects.

This commit is contained in:
Sean Bowe 2018-02-19 18:56:53 -07:00
parent 8d633db82b
commit 1df7fbeeff
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
2 changed files with 75 additions and 36 deletions

View File

@ -234,6 +234,47 @@ impl AllocatedBit {
}
}
pub fn field_into_allocated_bits_be<E: Engine, CS: ConstraintSystem<E>, F: PrimeField>(
mut cs: CS,
value: Option<F>
) -> Result<Vec<AllocatedBit>, SynthesisError>
{
let values = match value {
Some(ref value) => {
let mut field_char = BitIterator::new(F::char());
let mut tmp = Vec::with_capacity(F::NUM_BITS as usize);
let mut found_one = false;
for b in BitIterator::new(value.into_repr()) {
// Skip leading bits
found_one |= field_char.next().unwrap();
if !found_one {
continue;
}
tmp.push(Some(b));
}
assert_eq!(tmp.len(), F::NUM_BITS as usize);
tmp
},
None => {
vec![None; F::NUM_BITS as usize]
}
};
let bits = values.into_iter().enumerate().map(|(i, b)| {
AllocatedBit::alloc(
cs.namespace(|| format!("bit {}", i)),
b
)
}).collect::<Result<Vec<_>, SynthesisError>>()?;
Ok(bits)
}
/// This is a boolean value which may be either a constant or
/// an interpretation of an `AllocatedBit`.
#[derive(Clone)]
@ -509,7 +550,11 @@ mod test {
use pairing::bls12_381::{Bls12, Fr};
use pairing::{Field, PrimeField, PrimeFieldRepr, BitIterator};
use ::circuit::test::*;
use super::{AllocatedBit, Boolean};
use super::{
AllocatedBit,
Boolean,
field_into_allocated_bits_be
};
#[test]
fn test_allocated_bit() {
@ -1129,4 +1174,26 @@ mod test {
}
}
}
#[test]
fn test_field_into_allocated_bits_be() {
let mut cs = TestConstraintSystem::<Bls12>::new();
let r = Fr::from_str("9147677615426976802526883532204139322118074541891858454835346926874644257775").unwrap();
let bits = field_into_allocated_bits_be(&mut cs, Some(r)).unwrap();
assert!(cs.is_satisfied());
assert_eq!(bits.len(), 255);
assert_eq!(bits[0].value.unwrap(), false);
assert_eq!(bits[1].value.unwrap(), false);
assert_eq!(bits[2].value.unwrap(), true);
assert_eq!(bits[3].value.unwrap(), false);
assert_eq!(bits[4].value.unwrap(), true);
assert_eq!(bits[5].value.unwrap(), false);
assert_eq!(bits[20].value.unwrap(), true);
assert_eq!(bits[23].value.unwrap(), true);
}
}

View File

@ -17,8 +17,9 @@ use super::{
};
use super::boolean::{
Boolean,
AllocatedBit
self,
Boolean,
AllocatedBit
};
pub struct AllocatedNum<E: Engine> {
@ -76,39 +77,10 @@ impl<E: Engine> AllocatedNum<E> {
) -> Result<Vec<Boolean>, SynthesisError>
where CS: ConstraintSystem<E>
{
let bit_values = match self.value {
Some(value) => {
let mut field_char = BitIterator::new(E::Fr::char());
let mut tmp = Vec::with_capacity(E::Fr::NUM_BITS as usize);
let mut found_one = false;
for b in BitIterator::new(value.into_repr()) {
// Skip leading bits
found_one |= field_char.next().unwrap();
if !found_one {
continue;
}
tmp.push(Some(b));
}
assert_eq!(tmp.len(), E::Fr::NUM_BITS as usize);
tmp
},
None => {
vec![None; E::Fr::NUM_BITS as usize]
}
};
let mut bits = vec![];
for (i, b) in bit_values.into_iter().enumerate() {
bits.push(AllocatedBit::alloc(
cs.namespace(|| format!("bit {}", i)),
b
)?);
}
let bits = boolean::field_into_allocated_bits_be(
&mut cs,
self.value
)?;
let mut lc = LinearCombination::zero();
let mut coeff = E::Fr::one();