diff --git a/.github/workflows/rust_ci.yml b/.github/workflows/rust_ci.yml index 95c6b3e..70f8445 100644 --- a/.github/workflows/rust_ci.yml +++ b/.github/workflows/rust_ci.yml @@ -254,4 +254,7 @@ jobs: run: ./run_werewolf.zsh night - name: Run werewolf vote - run: ./run_werewolf.zsh vote \ No newline at end of file + run: ./run_werewolf.zsh vote + + - name: Run werewolf role assignment + run: ./run_werewolf.zsh role_assignment \ No newline at end of file diff --git a/examples/bin_werewolf.rs b/examples/bin_werewolf.rs index ac63a49..bf8a737 100644 --- a/examples/bin_werewolf.rs +++ b/examples/bin_werewolf.rs @@ -385,6 +385,7 @@ fn role_assignment(opt: &Opt) -> Result<(), std::io::Error> { // prove let local_role_circuit = RoleAssignmentCircuit { num_players: n, + max_group_size: grouping_parameter.get_max_group_size(), pedersen_param: pedersen_param.clone(), tau_matrix: na::DMatrix::::zeros(n + m, n + m), shuffle_matrices: vec![na::DMatrix::::zeros(n + m, n + m); 2], @@ -420,6 +421,7 @@ fn role_assignment(opt: &Opt) -> Result<(), std::io::Error> { let mpc_role_circuit = RoleAssignmentCircuit { num_players: n, + max_group_size: grouping_parameter.get_max_group_size(), pedersen_param: mpc_pedersen_param, tau_matrix: grouping_parameter.generate_tau_matrix(), shuffle_matrices: shuffle_matrix, @@ -622,6 +624,14 @@ impl GroupingParameter { self.0.values().map(|x| x.0).sum() } + fn get_max_group_size(&self) -> usize { + self.0 + .values() + .map(|(count, is_not_alone)| if *is_not_alone { *count } else { 1 }) + .max() + .expect("Error: No max value found") + } + fn get_corresponding_role(&self, role_id: usize) -> Roles { let mut count = self.get_num_players(); for (role, (role_count, is_not_alone)) in self.0.iter() { diff --git a/src/circuits/werewolf.rs b/src/circuits/werewolf.rs index f2bc6e1..d080600 100644 --- a/src/circuits/werewolf.rs +++ b/src/circuits/werewolf.rs @@ -855,6 +855,7 @@ impl ConstraintSynthesizer> for WinningJudgeCircuit> { // parameter pub num_players: usize, + pub max_group_size: usize, pub pedersen_param: F::PedersenParam, // instance @@ -961,7 +962,7 @@ impl ConstraintSynthesizer for RoleAssignmentCircuit { let calced_role = calced_vec .iter() - .map(|val| test_max(val, false).unwrap()) + .map(|val| test_max(val, self.max_group_size + 1, true).unwrap()) .collect::>(); // commitment @@ -1077,7 +1078,7 @@ impl ConstraintSynthesizer> for RoleAssignmentCircuit>(); // commitment @@ -1328,8 +1329,10 @@ impl ElGamalLocalOrMPC> for mm::MpcField { } } +// return maximum value in the vector a, index runs from 0 to use_index_len fn test_max( a: &[FpVar], + use_index_len: usize, should_enforce: bool, ) -> Result, SynthesisError> { let cs = a[0].cs().clone(); @@ -1340,11 +1343,9 @@ fn test_max( if should_enforce { // each element must be less than half of the modulus - a.iter().for_each(|x| { - max_var - .enforce_cmp(x, core::cmp::Ordering::Greater, true) - .unwrap() - }); + for i in 0..use_index_len { + a[i].enforce_cmp(&max_var, core::cmp::Ordering::Less, true)?; + } } Ok(max_var) @@ -1352,6 +1353,7 @@ fn test_max( fn test_max_mpc( a: &[MpcFpVar], + use_index_len: usize, should_enforce: bool, ) -> Result, SynthesisError> { let cs = a[0].cs().clone(); @@ -1361,12 +1363,9 @@ fn test_max_mpc row sum and column sum is 1 let val = &matrix[(i, j)]; - ( as Zero>::zero() - val) - .is_zero() + val.is_zero() .unwrap() - .or(&( as One>::one() - val).is_zero().unwrap()) + .or(&(val - as One>::one()).is_zero().unwrap()) .unwrap() .enforce_equal(&MpcBoolean::TRUE)?;