-
Notifications
You must be signed in to change notification settings - Fork 21
/
r1cs_utils.rs
53 lines (43 loc) · 1.68 KB
/
r1cs_utils.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use bulletproofs::r1cs::{ConstraintSystem, R1CSError, Variable};
use curve25519_dalek::scalar::Scalar;
use bulletproofs::{BulletproofGens, PedersenGens};
use bulletproofs::r1cs::LinearCombination;
/// Represents a variable for quantity, along with its assignment.
#[derive(Copy, Clone, Debug)]
pub struct AllocatedQuantity {
pub variable: Variable,
pub assignment: Option<u64>
}
#[derive(Copy, Clone, Debug)]
pub struct AllocatedScalar {
pub variable: Variable,
pub assignment: Option<Scalar>
}
/// Enforces that the quantity of v is in the range [0, 2^n).
pub fn positive_no_gadget<CS: ConstraintSystem>(
cs: &mut CS,
v: AllocatedQuantity,
bit_size: usize) -> Result<(), R1CSError> {
let mut constraint_v = vec![(v.variable, -Scalar::one())];
let mut exp_2 = Scalar::one();
for i in 0..bit_size {
// Create low-level variables and add them to constraints
let (a, b, o) = cs.allocate_multiplier(v.assignment.map(|q| {
let bit: u64 = (q >> i) & 1;
((1 - bit).into(), bit.into())
}))?;
// Enforce a * b = 0, so one of (a,b) is zero
cs.constrain(o.into());
// Enforce that a = 1 - b, so they both are 1 or 0.
cs.constrain(a + (b - 1u64));
constraint_v.push((b, exp_2) );
exp_2 = exp_2 + exp_2;
}
// Enforce that -v + Sum(b_i * 2^i, i = 0..n-1) = 0 => Sum(b_i * 2^i, i = 0..n-1) = v
cs.constrain(constraint_v.iter().collect());
Ok(())
}
/// Constrain a linear combination to be equal to a scalar
pub fn constrain_lc_with_scalar<CS: ConstraintSystem>(cs: &mut CS, lc: LinearCombination, scalar: &Scalar) {
cs.constrain(lc - LinearCombination::from(*scalar));
}