From 3eaea833d440613abb02da06fe286f05254c8412 Mon Sep 17 00:00:00 2001 From: redshiftzero Date: Thu, 7 Dec 2023 13:27:07 -0500 Subject: [PATCH] test: add small circuit testing `U128x128Var::round_down_to_amount` --- crates/core/num/src/fixpoint.rs | 72 +++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/crates/core/num/src/fixpoint.rs b/crates/core/num/src/fixpoint.rs index bf58d06cec..8fc3d6d281 100644 --- a/crates/core/num/src/fixpoint.rs +++ b/crates/core/num/src/fixpoint.rs @@ -729,6 +729,8 @@ mod test { use proptest::prelude::*; use rand_core::OsRng; + use crate::Amount; + use super::*; proptest! { @@ -1313,4 +1315,74 @@ mod test { panic!("should not be able to verify proof"); } } + + proptest! { + #![proptest_config(ProptestConfig::with_cases(5))] + #[test] + fn round_down_to_amount( + a_int in any::(), + a_frac in any::(), + ) { + let a = U128x128( + U256([a_frac, a_int]) + ); + + let expected_c = a.round_down().try_into().expect("should be able to round down OOC"); + + let circuit = TestRoundDownCircuit { + a, + c: expected_c, + }; + + let (pk, vk) = TestRoundDownCircuit::generate_test_parameters(); + let mut rng = OsRng; + + let proof = Groth16::::prove(&pk, circuit, &mut rng) + .expect("should be able to form proof"); + + let proof_result = Groth16::::verify( + &vk, + &expected_c.to_field_elements().unwrap(), + &proof, + ); + assert!(proof_result.is_ok()); + } + } + + struct TestRoundDownCircuit { + a: U128x128, + + // `c` is expected to be `a` rounded down to an `Amount` + pub c: Amount, + } + + impl ConstraintSynthesizer for TestRoundDownCircuit { + fn generate_constraints( + self, + cs: ConstraintSystemRef, + ) -> ark_relations::r1cs::Result<()> { + let a_var = U128x128Var::new_witness(cs.clone(), || Ok(self.a))?; + let c_public_var = AmountVar::new_input(cs, || Ok(self.c))?; + let c_var = a_var.round_down_to_amount()?; + c_var.enforce_equal(&c_public_var)?; + Ok(()) + } + } + + impl TestRoundDownCircuit { + fn generate_test_parameters() -> (ProvingKey, VerifyingKey) { + let num: [u8; 32] = [0u8; 32]; + let a = U128x128::from_bytes(num); + let c: Amount = a + .round_down() + .try_into() + .expect("should be able to round down OOC"); + let circuit = TestRoundDownCircuit { a, c }; + let (pk, vk) = Groth16::::circuit_specific_setup( + circuit, &mut OsRng, + ) + .expect("can perform circuit specific setup"); + (pk, vk) + } + } }