diff --git a/src/cyclefold/circuit.rs b/src/cyclefold/circuit.rs index 122b5b1e8..d5ff2ae85 100644 --- a/src/cyclefold/circuit.rs +++ b/src/cyclefold/circuit.rs @@ -9,10 +9,11 @@ use neptune::{circuit2::poseidon_hash_allocated, poseidon::PoseidonConstants}; use crate::{ constants::NUM_CHALLENGE_BITS, - gadgets::{alloc_zero, conditionally_select, le_bits_to_num, AllocatedPoint}, + gadgets::{alloc_zero, le_bits_to_num, AllocatedPoint}, traits::{commitment::CommitmentTrait, Engine}, Commitment, }; +use bellpepper::gadgets::boolean_utils::conditionally_select; /// A structure containing the CycleFold circuit inputs and implementing the synthesize function pub struct CyclefoldCircuit { diff --git a/src/cyclefold/gadgets.rs b/src/cyclefold/gadgets.rs index ab0577b37..b1b8c1880 100644 --- a/src/cyclefold/gadgets.rs +++ b/src/cyclefold/gadgets.rs @@ -220,7 +220,7 @@ impl AllocatedCycleFoldData { } pub mod emulated { - use bellpepper::gadgets::Assignment; + use bellpepper::gadgets::{boolean_utils::conditionally_select, Assignment}; use bellpepper_core::{ boolean::{AllocatedBit, Boolean}, num::AllocatedNum, @@ -230,8 +230,8 @@ pub mod emulated { use crate::{ constants::{NUM_CHALLENGE_BITS, NUM_FE_IN_EMULATED_POINT}, gadgets::{ - alloc_zero, conditionally_select, conditionally_select_allocated_bit, - conditionally_select_bignat, f_to_nat, le_bits_to_num, BigNat, + alloc_zero, conditionally_select_allocated_bit, conditionally_select_bignat, f_to_nat, + le_bits_to_num, BigNat, }, traits::{commitment::CommitmentTrait, Engine, Group, ROCircuitTrait, ROConstantsCircuit}, RelaxedR1CSInstance, diff --git a/src/cyclefold/nova_circuit.rs b/src/cyclefold/nova_circuit.rs index c595902d6..a917420d7 100644 --- a/src/cyclefold/nova_circuit.rs +++ b/src/cyclefold/nova_circuit.rs @@ -3,7 +3,7 @@ use crate::{ constants::{BN_N_LIMBS, NIO_CYCLE_FOLD, NUM_FE_IN_EMULATED_POINT, NUM_HASH_BITS}, gadgets::{ - alloc_num_equals, alloc_scalar_as_base, alloc_zero, conditionally_select_vec, le_bits_to_num, + alloc_num_equals, alloc_scalar_as_base, alloc_zero, le_bits_to_num, AllocatedRelaxedR1CSInstance, }, traits::{ @@ -13,7 +13,9 @@ use crate::{ }; use abomonation_derive::Abomonation; -use bellpepper::gadgets::{boolean::Boolean, num::AllocatedNum, Assignment}; +use bellpepper::gadgets::{ + boolean::Boolean, boolean_utils::conditionally_select_slice, num::AllocatedNum, Assignment, +}; use bellpepper_core::{boolean::AllocatedBit, ConstraintSystem, SynthesisError}; use ff::Field; use serde::{Deserialize, Serialize}; @@ -460,7 +462,7 @@ where ); // Compute z_{i+1} - let z_input = conditionally_select_vec( + let z_input = conditionally_select_slice( cs.namespace(|| "select input to F"), &z_0, &z_i, diff --git a/src/gadgets/mod.rs b/src/gadgets/mod.rs index e5f31dae0..5841f6ec2 100644 --- a/src/gadgets/mod.rs +++ b/src/gadgets/mod.rs @@ -15,5 +15,6 @@ mod utils; #[cfg(test)] pub(crate) use utils::alloc_one; pub(crate) use utils::{ - alloc_num_equals, alloc_scalar_as_base, alloc_zero, le_bits_to_num, scalar_as_base, + alloc_bignat_constant, alloc_num_equals, alloc_scalar_as_base, alloc_zero, + conditionally_select_allocated_bit, conditionally_select_bignat, le_bits_to_num, scalar_as_base, }; diff --git a/src/gadgets/utils.rs b/src/gadgets/utils.rs index 4474c4ece..411dfc348 100644 --- a/src/gadgets/utils.rs +++ b/src/gadgets/utils.rs @@ -185,6 +185,33 @@ pub fn alloc_num_equals>( Ok(r) } +// TODO: Figure out if this can be done better +pub fn conditionally_select_allocated_bit>( + mut cs: CS, + a: &AllocatedBit, + b: &AllocatedBit, + condition: &Boolean, +) -> Result { + let c = AllocatedBit::alloc( + cs.namespace(|| "conditionally select result"), + if condition.get_value().unwrap_or(false) { + a.get_value() + } else { + b.get_value() + }, + )?; + + // a * condition + b*(1-condition) = c -> + // a * condition - b*condition = c - b + cs.enforce( + || "conditional select constraint", + |lc| lc + a.get_variable() - b.get_variable(), + |_| condition.lc(CS::one(), F::ONE), + |lc| lc + c.get_variable() - b.get_variable(), + ); + + Ok(c) +} /// If condition return a otherwise b where a and b are `BigNats` pub fn conditionally_select_bignat>( mut cs: CS,