From 45a9602232237b827209929926c99b45c2e1054d Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 21 Jun 2024 17:19:10 +0100 Subject: [PATCH] Clearer assertion failure on duplicate elements given to member() (#196) Before this commit, when `member()` function got a `set` with duplicate elements, the program would panic with ``` assertion failed: cs.is_sat() ``` with debugging informaiton about failing constraints. After this commit, the program still panics when encounting duplicates, but now with a clearer message ``` assertion failed: unique_values(set) ``` --- vm/src/circuit/r1cs.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/vm/src/circuit/r1cs.rs b/vm/src/circuit/r1cs.rs index d37f52c9..3f666ac5 100644 --- a/vm/src/circuit/r1cs.rs +++ b/vm/src/circuit/r1cs.rs @@ -7,7 +7,8 @@ //! These matrices are meant to be used at compile-time as a //! source for generating constraints over a target field. -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; +use std::hash::Hash; use std::ops::Range; use ark_bn254::FrConfig; @@ -324,9 +325,20 @@ impl R1CS { } } +fn unique_values(set: &[Elm]) -> bool { + let mut seen = HashSet::new(); + for v in set.iter() { + if !seen.insert(v) { + return false; + } + } + true +} + pub fn member(cs: &mut R1CS, name: &str, k: u32, set: &[u32]) { debug_assert!(set.len() > 1); debug_assert!(set.contains(&k)); + debug_assert!(unique_values(set)); // Compute constant that comes from evaulating // (x - s0)(x - s1)...(x - s{n - 1}) / (x - sk) @@ -613,6 +625,13 @@ mod test { test_mem(&[57, 67, 77, 107, 117, 119]); } + #[test] + #[cfg(debug_assertions)] + #[should_panic(expected = "assertion failed: unique_values(set)")] + fn test_member_dup() { + test_mem(&[2, 2]); + } + fn test_sel(n: u32) { for k in 0..n { let mut cs = R1CS::default();