diff --git a/src/gadgets/biguint.rs b/src/gadgets/biguint.rs index e5075f5b..9fe47bf9 100644 --- a/src/gadgets/biguint.rs +++ b/src/gadgets/biguint.rs @@ -93,14 +93,23 @@ impl, const D: usize> CircuitBuilder { // Add two `BigUintTarget`s. pub fn add_biguint(&mut self, a: BigUintTarget, b: BigUintTarget) -> BigUintTarget { - let num_limbs = a.limbs.len(); - debug_assert!(b.limbs.len() == num_limbs); + let num_limbs = a.num_limbs().max(b.num_limbs()); let mut combined_limbs = vec![]; let mut carry = self.zero_u32(); for i in 0..num_limbs { - let (new_limb, new_carry) = - self.add_three_u32(carry.clone(), a.limbs[i].clone(), b.limbs[i].clone()); + let a_limb = if i < a.num_limbs() { + a.limbs[i].clone() + } else { + self.zero_u32() + }; + let b_limb = if i < b.num_limbs() { + b.limbs[i].clone() + } else { + self.zero_u32() + }; + + let (new_limb, new_carry) = self.add_three_u32(carry.clone(), a_limb, b_limb); carry = new_carry; combined_limbs.push(new_limb); } @@ -221,7 +230,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { use anyhow::Result; - use num::{BigUint, FromPrimitive}; + use num::{BigUint, FromPrimitive, Integer}; use crate::{ field::crandall_field::CrandallField, @@ -300,4 +309,54 @@ mod tests { verify(proof, &data.verifier_only, &data.common) } + + #[test] + fn test_biguint_cmp() -> Result<()> { + let x_value = BigUint::from_u128(33333333333333333333333333333333333333).unwrap(); + let y_value = BigUint::from_u128(22222222222222222222222222222222222222).unwrap(); + + type F = CrandallField; + let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + let x = builder.constant_biguint(x_value); + let y = builder.constant_biguint(y_value); + let cmp = builder.cmp_biguint(x, y); + let expected_cmp = builder.constant_bool(true); + + builder.connect(cmp.target, expected_cmp.target); + + let data = builder.build(); + let proof = data.prove(pw).unwrap(); + + verify(proof, &data.verifier_only, &data.common) + } + + #[test] + fn test_biguint_div_rem() -> Result<()> { + let x_value = BigUint::from_u128(456456456456456456456456456456456456).unwrap(); + let y_value = BigUint::from_u128(123123123123123123123123123123123123).unwrap(); + let (expected_div_value, expected_rem_value) = x_value.div_rem(&y_value); + + type F = CrandallField; + let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + let x = builder.constant_biguint(x_value); + let y = builder.constant_biguint(y_value); + let (div, rem) = builder.div_rem_biguint(x, y); + + let expected_div = builder.constant_biguint(expected_div_value); + let expected_rem = builder.constant_biguint(expected_rem_value); + + //builder.connect_biguint(div, expected_div); + //builder.connect_biguint(rem, expected_rem); + + let data = builder.build(); + let proof = data.prove(pw).unwrap(); + + verify(proof, &data.verifier_only, &data.common) + } } diff --git a/src/gadgets/multiple_comparison.rs b/src/gadgets/multiple_comparison.rs index 3c2ac0f5..bfeaa098 100644 --- a/src/gadgets/multiple_comparison.rs +++ b/src/gadgets/multiple_comparison.rs @@ -15,8 +15,8 @@ impl, const D: usize> CircuitBuilder { ); let n = a.len(); - let chunk_size = 4; - let num_chunks = ceil_div_usize(num_bits, chunk_size); + let chunk_bits = 2; + let num_chunks = ceil_div_usize(num_bits, chunk_bits); let one = self.one(); let mut result = self.one(); diff --git a/src/iop/generator.rs b/src/iop/generator.rs index c395ad73..c5c67bcb 100644 --- a/src/iop/generator.rs +++ b/src/iop/generator.rs @@ -159,7 +159,8 @@ impl GeneratedValues { } pub fn set_biguint_target(&mut self, target: BigUintTarget, value: BigUint) { - let limbs = value.to_u32_digits(); + let mut limbs = value.to_u32_digits(); + limbs.resize(target.num_limbs(), 0); for i in 0..target.num_limbs() { self.set_u32_target(target.get_limb(i), limbs[i]); }