From 1737456304122678c1ef6902772e18b0d3701a2c Mon Sep 17 00:00:00 2001 From: winderica Date: Tue, 30 Apr 2024 02:29:16 +0800 Subject: [PATCH] Return the internally recorded value in `Allocated{Bool, Fp}::value()` for performance --- src/boolean/allocated.rs | 49 +++++++++++++++++++--------------------- src/fields/fp/mod.rs | 2 +- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/boolean/allocated.rs b/src/boolean/allocated.rs index 9397f12..add34c4 100644 --- a/src/boolean/allocated.rs +++ b/src/boolean/allocated.rs @@ -6,7 +6,6 @@ use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError, Variab use crate::{ alloc::{AllocVar, AllocationMode}, select::CondSelectGadget, - Assignment, }; use super::Boolean; @@ -22,23 +21,13 @@ use super::Boolean; pub struct AllocatedBool { pub(super) variable: Variable, pub(super) cs: ConstraintSystemRef, -} - -pub(crate) fn bool_to_field(val: impl Borrow) -> F { - F::from(*val.borrow()) + pub(super) value: Option, } impl AllocatedBool { /// Get the assigned value for `self`. pub fn value(&self) -> Result { - 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`. @@ -52,8 +41,12 @@ impl AllocatedBool { cs: ConstraintSystemRef, f: impl FnOnce() -> Result, ) -> Result { - 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 @@ -64,6 +57,7 @@ impl AllocatedBool { Ok(Self { variable, cs: self.cs.clone(), + value: self.value.map(|v| !v), }) } @@ -189,25 +183,28 @@ impl AllocVar for AllocatedBool { let ns = cs.into(); let cs = ns.cs(); 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 { + let value = f().map(|b| *b.borrow()); let variable = if mode == AllocationMode::Input { - cs.new_input_variable(|| f().map(bool_to_field))? + cs.new_input_variable(|| value.map(F::from))? } else { - cs.new_witness_variable(|| f().map(bool_to_field))? + cs.new_witness_variable(|| value.map(F::from))? }; // Constrain: (1 - a) * a = 0 // This constrains a to be either 0 or 1. - cs.enforce_constraint(lc!() + Variable::One - variable, lc!() + variable, lc!())?; - - Ok(Self { variable, cs }) + Ok(Self { + variable, + cs, + value: value.ok(), + }) } } } diff --git a/src/fields/fp/mod.rs b/src/fields/fp/mod.rs index bc35c81..3e8cdc1 100644 --- a/src/fields/fp/mod.rs +++ b/src/fields/fp/mod.rs @@ -136,7 +136,7 @@ impl AllocatedFp { /// Returns the value assigned to `self` in the underlying constraint system /// (if a value was assigned). pub fn value(&self) -> Result { - self.cs.assigned_value(self.variable).get() + self.value.ok_or(SynthesisError::AssignmentMissing) } /// Outputs `self + other`.