diff --git a/CHANGELOG.md b/CHANGELOG.md index 31c4fe2..0cb7f6e 100644 --- a/CHANGELOG.md +++ b/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 diff --git a/src/bits/boolean.rs b/src/bits/boolean.rs index b68e511..3e25b3f 100644 --- a/src/bits/boolean.rs +++ b/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 { +pub struct AllocatedBool { variable: Variable, cs: ConstraintSystemRef, } @@ -27,7 +27,7 @@ pub(crate) fn bool_to_field(val: impl Borrow) -> F { } } -impl AllocatedBit { +impl AllocatedBool { /// Get the assigned value for `self`. pub fn value(&self) -> Result { 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 { 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 { 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 { let result = Self::new_witness_without_booleanity_check(self.cs.clone(), || { @@ -161,7 +161,7 @@ impl AllocatedBit { } } -impl AllocVar for AllocatedBit { +impl AllocVar for AllocatedBool { /// Produces a new variable of the appropriate kind /// (instance or witness), with a booleanity check. /// @@ -199,7 +199,7 @@ impl AllocVar for AllocatedBit { } } -impl CondSelectGadget for AllocatedBit { +impl CondSelectGadget for AllocatedBool { #[tracing::instrument(target = "r1cs")] fn conditionally_select( cond: &Boolean, @@ -224,9 +224,9 @@ impl CondSelectGadget for AllocatedBit { #[must_use] pub enum Boolean { /// Existential view of the boolean variable. - Is(AllocatedBit), + Is(AllocatedBool), /// Negated view of the boolean variable. - Not(AllocatedBit), + Not(AllocatedBool), /// Constant (not an allocated variable). Constant(bool), } @@ -772,8 +772,8 @@ impl Boolean { } } -impl From> for Boolean { - fn from(b: AllocatedBit) -> Self { +impl From> for Boolean { + fn from(b: AllocatedBool) -> 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 = - 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::::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::::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::::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::::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::::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()); diff --git a/src/bits/uint.rs b/src/bits/uint.rs index 11b45d2..cc5053e 100644 --- a/src/bits/uint.rs +++ b/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> {