Browse Source

Return the internally recorded value in `Allocated{Bool, Fp}::value()` for performance

avoid_assigned_value
winderica 11 months ago
parent
commit
1737456304
2 changed files with 24 additions and 27 deletions
  1. +23
    -26
      src/boolean/allocated.rs
  2. +1
    -1
      src/fields/fp/mod.rs

+ 23
- 26
src/boolean/allocated.rs

@ -6,7 +6,6 @@ use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError, Variab
use crate::{ use crate::{
alloc::{AllocVar, AllocationMode}, alloc::{AllocVar, AllocationMode},
select::CondSelectGadget, select::CondSelectGadget,
Assignment,
}; };
use super::Boolean; use super::Boolean;
@ -22,23 +21,13 @@ use super::Boolean;
pub struct AllocatedBool<F: Field> { pub struct AllocatedBool<F: Field> {
pub(super) variable: Variable, pub(super) variable: Variable,
pub(super) cs: ConstraintSystemRef<F>, pub(super) cs: ConstraintSystemRef<F>,
}
pub(crate) fn bool_to_field<F: Field>(val: impl Borrow<bool>) -> F {
F::from(*val.borrow())
pub(super) value: Option<bool>,
} }
impl<F: Field> AllocatedBool<F> { impl<F: Field> AllocatedBool<F> {
/// Get the assigned value for `self`. /// Get the assigned value for `self`.
pub fn value(&self) -> Result<bool, SynthesisError> { pub fn value(&self) -> Result<bool, SynthesisError> {
let value = self.cs.assigned_value(self.variable).get()?;
if value.is_zero() {
Ok(false)
} else if value.is_one() {
Ok(true)
} else {
unreachable!("Incorrect value assigned: {:?}", value);
}
self.value.ok_or(SynthesisError::AssignmentMissing)
} }
/// Get the R1CS variable for `self`. /// Get the R1CS variable for `self`.
@ -52,8 +41,12 @@ impl AllocatedBool {
cs: ConstraintSystemRef<F>, cs: ConstraintSystemRef<F>,
f: impl FnOnce() -> Result<T, SynthesisError>, f: impl FnOnce() -> Result<T, SynthesisError>,
) -> Result<Self, SynthesisError> { ) -> Result<Self, SynthesisError> {
let variable = cs.new_witness_variable(|| f().map(bool_to_field))?;
Ok(Self { variable, cs })
let value = f().map(|b| *b.borrow());
Ok(Self {
variable: cs.new_witness_variable(|| value.map(F::from))?,
cs,
value: value.ok(),
})
} }
/// Performs an XOR operation over the two operands, returning /// Performs an XOR operation over the two operands, returning
@ -64,6 +57,7 @@ impl AllocatedBool {
Ok(Self { Ok(Self {
variable, variable,
cs: self.cs.clone(), cs: self.cs.clone(),
value: self.value.map(|v| !v),
}) })
} }
@ -189,25 +183,28 @@ impl AllocVar for AllocatedBool {
let ns = cs.into(); let ns = cs.into();
let cs = ns.cs(); let cs = ns.cs();
if mode == AllocationMode::Constant { if mode == AllocationMode::Constant {
let variable = if *f()?.borrow() {
Variable::One
} else {
Variable::Zero
};
Ok(Self { variable, cs })
let value = *f()?.borrow();
Ok(Self {
variable: if value { Variable::One } else { Variable::Zero },
cs,
value: Some(value),
})
} else { } else {
let value = f().map(|b| *b.borrow());
let variable = if mode == AllocationMode::Input { let variable = if mode == AllocationMode::Input {
cs.new_input_variable(|| f().map(bool_to_field))?
cs.new_input_variable(|| value.map(F::from))?
} else { } else {
cs.new_witness_variable(|| f().map(bool_to_field))?
cs.new_witness_variable(|| value.map(F::from))?
}; };
// Constrain: (1 - a) * a = 0 // Constrain: (1 - a) * a = 0
// This constrains a to be either 0 or 1. // This constrains a to be either 0 or 1.
cs.enforce_constraint(lc!() + Variable::One - variable, lc!() + variable, lc!())?; cs.enforce_constraint(lc!() + Variable::One - variable, lc!() + variable, lc!())?;
Ok(Self { variable, cs })
Ok(Self {
variable,
cs,
value: value.ok(),
})
} }
} }
} }

+ 1
- 1
src/fields/fp/mod.rs

@ -136,7 +136,7 @@ impl AllocatedFp {
/// Returns the value assigned to `self` in the underlying constraint system /// Returns the value assigned to `self` in the underlying constraint system
/// (if a value was assigned). /// (if a value was assigned).
pub fn value(&self) -> Result<F, SynthesisError> { pub fn value(&self) -> Result<F, SynthesisError> {
self.cs.assigned_value(self.variable).get()
self.value.ok_or(SynthesisError::AssignmentMissing)
} }
/// Outputs `self + other`. /// Outputs `self + other`.

Loading…
Cancel
Save