Skip to content

Commit

Permalink
Merge pull request filecoin-project#130 from filecoin-project/gadget-…
Browse files Browse the repository at this point in the history
…pack-bits
  • Loading branch information
dignifiedquire authored Nov 9, 2020
2 parents a96c9a1 + 417b846 commit f352584
Showing 1 changed file with 31 additions and 1 deletion.
32 changes: 31 additions & 1 deletion src/gadgets/multipack.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Helpers for packing vectors of bits into scalar field elements.
use super::boolean::Boolean;
use super::num::Num;
use super::num::{AllocatedNum, Num};
use super::Assignment;
use crate::{ConstraintSystem, SynthesisError};
use ff::{Field, PrimeField, ScalarEngine};
Expand Down Expand Up @@ -71,6 +71,36 @@ pub fn compute_multipacking<E: ScalarEngine>(bits: &[bool]) -> Vec<E::Fr> {
result
}

/// Takes a sequence of booleans and exposes them as a single compact Num.
pub fn pack_bits<E, CS>(mut cs: CS, bits: &[Boolean]) -> Result<AllocatedNum<E>, SynthesisError>
where
E: ScalarEngine,
CS: ConstraintSystem<E>,
{
let mut num = Num::<E>::zero();
let mut coeff = E::Fr::one();
for bit in bits.iter().take(E::Fr::CAPACITY as usize) {
num = num.add_bool_with_coeff(CS::one(), &bit, coeff);

coeff.double();
}

let alloc_num = AllocatedNum::alloc(cs.namespace(|| "input"), || {
num.get_value()
.ok_or_else(|| SynthesisError::AssignmentMissing)
})?;

// num * 1 = input
cs.enforce(
|| "packing constraint",
|_| num.lc(E::Fr::one()),
|lc| lc + CS::one(),
|lc| lc + alloc_num.get_variable(),
);

Ok(alloc_num)
}

#[test]
fn test_multipacking() {
use crate::bls::Bls12;
Expand Down

0 comments on commit f352584

Please sign in to comment.