Browse Source

Rename AllocatedBit to AllocatedBool (#60)

* Rename AllocatedBit to AllocatedBool

* Update Changelog

* Fix independent fmt issues
master
Dev Ojha 3 years ago
committed by GitHub
parent
commit
5debc6f8f1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 49 deletions
  1. +14
    -0
      CHANGELOG.md
  2. +30
    -30
      src/bits/boolean.rs
  3. +23
    -19
      src/bits/uint.rs

+ 14
- 0
CHANGELOG.md

@ -1,3 +1,17 @@
## Pending
### Breaking changes
- #60 Rename `AllocatedBit` to `AllocatedBool` for consistency with the `Boolean` variable.
You can update downstream usage with `grep -rl 'AllocatedBit' . | xargs env LANG=C env LC_CTYPE=C sed -i '' 's/AllocatedBit/AllocatedBool/g'`.
### Features
### Improvements
### Bug Fixes
## v0.2.0
### Breaking changes

+ 30
- 30
src/bits/boolean.rs

@ -9,12 +9,12 @@ use core::borrow::Borrow;
/// Represents a variable in the constraint system which is guaranteed
/// to be either zero or one.
///
/// In general, one should prefer using `Boolean` instead of `AllocatedBit`,
/// In general, one should prefer using `Boolean` instead of `AllocatedBool`,
/// as `Boolean` offers better support for constant values, and implements
/// more traits.
#[derive(Clone, Debug, Eq, PartialEq)]
#[must_use]
pub struct AllocatedBit<F: Field> {
pub struct AllocatedBool<F: Field> {
variable: Variable,
cs: ConstraintSystemRef<F>,
}
@ -27,7 +27,7 @@ pub(crate) fn bool_to_field(val: impl Borrow) -> F {
}
}
impl<F: Field> AllocatedBit<F> {
impl<F: Field> AllocatedBool<F> {
/// Get the assigned value for `self`.
pub fn value(&self) -> Result<bool, SynthesisError> {
let value = self.cs.assigned_value(self.variable).get()?;
@ -55,7 +55,7 @@ impl AllocatedBit {
}
/// Performs an XOR operation over the two operands, returning
/// an `AllocatedBit`.
/// an `AllocatedBool`.
#[tracing::instrument(target = "r1cs")]
pub fn xor(&self, b: &Self) -> Result<Self, SynthesisError> {
let result = Self::new_witness_without_booleanity_check(self.cs.clone(), || {
@ -87,7 +87,7 @@ impl AllocatedBit {
}
/// Performs an AND operation over the two operands, returning
/// an `AllocatedBit`.
/// an `AllocatedBool`.
#[tracing::instrument(target = "r1cs")]
pub fn and(&self, b: &Self) -> Result<Self, SynthesisError> {
let result = Self::new_witness_without_booleanity_check(self.cs.clone(), || {
@ -106,7 +106,7 @@ impl AllocatedBit {
}
/// Performs an OR operation over the two operands, returning
/// an `AllocatedBit`.
/// an `AllocatedBool`.
#[tracing::instrument(target = "r1cs")]
pub fn or(&self, b: &Self) -> Result<Self, SynthesisError> {
let result = Self::new_witness_without_booleanity_check(self.cs.clone(), || {
@ -161,7 +161,7 @@ impl AllocatedBit {
}
}
impl<F: Field> AllocVar<bool, F> for AllocatedBit<F> {
impl<F: Field> AllocVar<bool, F> for AllocatedBool<F> {
/// Produces a new variable of the appropriate kind
/// (instance or witness), with a booleanity check.
///
@ -199,7 +199,7 @@ impl AllocVar for AllocatedBit {
}
}
impl<F: Field> CondSelectGadget<F> for AllocatedBit<F> {
impl<F: Field> CondSelectGadget<F> for AllocatedBool<F> {
#[tracing::instrument(target = "r1cs")]
fn conditionally_select(
cond: &Boolean<F>,
@ -224,9 +224,9 @@ impl CondSelectGadget for AllocatedBit {
#[must_use]
pub enum Boolean<F: Field> {
/// Existential view of the boolean variable.
Is(AllocatedBit<F>),
Is(AllocatedBool<F>),
/// Negated view of the boolean variable.
Not(AllocatedBit<F>),
Not(AllocatedBool<F>),
/// Constant (not an allocated variable).
Constant(bool),
}
@ -772,8 +772,8 @@ impl Boolean {
}
}
impl<F: Field> From<AllocatedBit<F>> for Boolean<F> {
fn from(b: AllocatedBit<F>) -> Self {
impl<F: Field> From<AllocatedBool<F>> for Boolean<F> {
fn from(b: AllocatedBool<F>) -> Self {
Boolean::Is(b)
}
}
@ -787,7 +787,7 @@ impl AllocVar for Boolean {
if mode == AllocationMode::Constant {
Ok(Boolean::Constant(*f()?.borrow()))
} else {
AllocatedBit::new_variable(cs, f, mode).map(Boolean::from)
AllocatedBool::new_variable(cs, f, mode).map(Boolean::from)
}
}
}
@ -916,7 +916,7 @@ impl CondSelectGadget for Boolean {
(a, b) => {
let cs = cond.cs();
let result: Boolean<F> =
AllocatedBit::new_witness_without_booleanity_check(cs.clone(), || {
AllocatedBool::new_witness_without_booleanity_check(cs.clone(), || {
let cond = cond.value()?;
Ok(if cond { a.value()? } else { b.value()? })
})?
@ -954,7 +954,7 @@ impl CondSelectGadget for Boolean {
#[cfg(test)]
mod test {
use super::{AllocatedBit, Boolean};
use super::{AllocatedBool, Boolean};
use crate::prelude::*;
use ark_ff::{BitIteratorBE, BitIteratorLE, Field, One, PrimeField, UniformRand, Zero};
use ark_relations::r1cs::{ConstraintSystem, Namespace, SynthesisError};
@ -982,9 +982,9 @@ mod test {
for a_val in [false, true].iter().copied() {
for b_val in [false, true].iter().copied() {
let cs = ConstraintSystem::<Fr>::new_ref();
let a = AllocatedBit::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBit::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBit::xor(&a, &b)?;
let a = AllocatedBool::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBool::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBool::xor(&a, &b)?;
assert_eq!(c.value()?, a_val ^ b_val);
assert!(cs.is_satisfied().unwrap());
@ -1001,9 +1001,9 @@ mod test {
for a_val in [false, true].iter().copied() {
for b_val in [false, true].iter().copied() {
let cs = ConstraintSystem::<Fr>::new_ref();
let a = AllocatedBit::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBit::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBit::or(&a, &b)?;
let a = AllocatedBool::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBool::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBool::or(&a, &b)?;
assert_eq!(c.value()?, a_val | b_val);
assert!(cs.is_satisfied().unwrap());
@ -1020,9 +1020,9 @@ mod test {
for a_val in [false, true].iter().copied() {
for b_val in [false, true].iter().copied() {
let cs = ConstraintSystem::<Fr>::new_ref();
let a = AllocatedBit::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBit::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBit::and(&a, &b)?;
let a = AllocatedBool::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBool::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBool::and(&a, &b)?;
assert_eq!(c.value()?, a_val & b_val);
assert!(cs.is_satisfied().unwrap());
@ -1039,9 +1039,9 @@ mod test {
for a_val in [false, true].iter().copied() {
for b_val in [false, true].iter().copied() {
let cs = ConstraintSystem::<Fr>::new_ref();
let a = AllocatedBit::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBit::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBit::and_not(&a, &b)?;
let a = AllocatedBool::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBool::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBool::and_not(&a, &b)?;
assert_eq!(c.value()?, a_val & !b_val);
assert!(cs.is_satisfied().unwrap());
@ -1058,9 +1058,9 @@ mod test {
for a_val in [false, true].iter().copied() {
for b_val in [false, true].iter().copied() {
let cs = ConstraintSystem::<Fr>::new_ref();
let a = AllocatedBit::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBit::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBit::nor(&a, &b)?;
let a = AllocatedBool::new_witness(cs.clone(), || Ok(a_val))?;
let b = AllocatedBool::new_witness(cs.clone(), || Ok(b_val))?;
let c = AllocatedBool::nor(&a, &b)?;
assert_eq!(c.value()?, !a_val & !b_val);
assert!(cs.is_satisfied().unwrap());

+ 23
- 19
src/bits/uint.rs

@ -17,7 +17,7 @@ macro_rules! make_uint {
};
use crate::{
boolean::{AllocatedBit, Boolean},
boolean::{AllocatedBool, Boolean},
prelude::*,
Assignment, Vec,
};
@ -128,18 +128,15 @@ macro_rules! make_uint {
let mut result = self.clone();
let by = by % $size;
let new_bits = self
.bits
.iter()
.skip(by)
.chain(&self.bits)
.take($size);
let new_bits = self.bits.iter().skip(by).chain(&self.bits).take($size);
for (res, new) in result.bits.iter_mut().zip(new_bits) {
*res = new.clone();
}
result.value = self.value.map(|v| v.rotate_right(u32::try_from(by).unwrap()));
result.value = self
.value
.map(|v| v.rotate_right(u32::try_from(by).unwrap()));
result
}
@ -188,7 +185,8 @@ macro_rules! make_uint {
// Compute the maximum value of the sum so we allocate enough bits for
// the result
let mut max_value = BigUint::from($native::max_value()) * BigUint::from(operands.len());
let mut max_value =
BigUint::from($native::max_value()) * BigUint::from(operands.len());
// Keep track of the resulting value
let mut result_value = Some(BigUint::zero());
@ -242,12 +240,10 @@ macro_rules! make_uint {
}
// The value of the actual result is modulo 2^$size
let modular_value = result_value.clone().map(|v|
{
let modulus = BigUint::from(1u64) << ($size as u32);
(v % modulus).to_u128().unwrap() as $native
}
);
let modular_value = result_value.clone().map(|v| {
let modulus = BigUint::from(1u64) << ($size as u32);
(v % modulus).to_u128().unwrap() as $native
});
if all_constants && modular_value.is_some() {
// We can just return a constant, rather than
@ -265,7 +261,12 @@ macro_rules! make_uint {
let mut i = 0;
while max_value != BigUint::zero() {
// Allocate the bit_gadget
let b = AllocatedBit::new_witness(cs.clone(), || result_value.clone().map(|v| (v >> i) & BigUint::one() == BigUint::one()).get())?;
let b = AllocatedBool::new_witness(cs.clone(), || {
result_value
.clone()
.map(|v| (v >> i) & BigUint::one() == BigUint::one())
.get()
})?;
// Subtract this bit_gadget from the linear combination to ensure the sums
// balance out
@ -369,11 +370,14 @@ macro_rules! make_uint {
let mut values = [None; $size];
if let Some(val) = value {
values.iter_mut().enumerate().for_each(|(i, v)| *v = Some((val >> i) & 1 == 1));
values
.iter_mut()
.enumerate()
.for_each(|(i, v)| *v = Some((val >> i) & 1 == 1));
}
let mut bits = [Boolean::FALSE; $size];
for (b, v) in bits.iter_mut().zip(&values) {
for (b, v) in bits.iter_mut().zip(&values) {
*b = Boolean::new_variable(cs.clone(), || v.get(), mode)?;
}
Ok(Self { bits, value })
@ -384,9 +388,9 @@ macro_rules! make_uint {
mod test {
use super::$name;
use crate::{bits::boolean::Boolean, prelude::*, Vec};
use ark_test_curves::mnt4_753::Fr;
use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
use ark_std::rand::Rng;
use ark_test_curves::mnt4_753::Fr;
#[test]
fn test_from_bits() -> Result<(), SynthesisError> {

Loading…
Cancel
Save