Skip to content

Instantly share code, notes, and snippets.

@arik-so
Last active August 31, 2023 17:19
Show Gist options
  • Save arik-so/f23c710c42da0fe5d06a528c49fb1e58 to your computer and use it in GitHub Desktop.
Save arik-so/f23c710c42da0fe5d06a528c49fb1e58 to your computer and use it in GitHub Desktop.
#[test]
fn generate_rusty_shards() {
let participant_count = 5; // EDIT ME!
let threshold = 3; // EDIT ME!
/**
Example output:
Threshold: 3 / 4
total shares: 6
users per share: 2
shares per user: 3
Share 0 users: [0, 1]
Share 1 users: [0, 2]
Share 2 users: [1, 2]
Share 3 users: [0, 3]
Share 4 users: [1, 3]
Share 5 users: [2, 3]
User 0 shares: [0, 1, 3]
User 1 shares: [0, 2, 4]
User 2 shares: [1, 2, 5]
User 3 shares: [3, 4, 5]
*/
println!("Threshold: {} / {}\n", threshold, participant_count);
let users_per_share = participant_count - threshold + 1;
let shares_per_user = num_integer::binomial(participant_count - 1, threshold - 1);
let share_count = num_integer::binomial(participant_count, users_per_share);
println!("total shares: {}", share_count);
println!("users per share: {}", users_per_share);
println!("shares per user: {}\n", shares_per_user);
let mut share_users = Vec::with_capacity(share_count as usize);
for i in 1..(1u32 << participant_count) {
if i.count_ones() == users_per_share {
share_users.push(i);
if share_users.len() == share_count as usize {
break;
}
}
}
let mut share_indices_by_user = Vec::with_capacity(participant_count as usize);
for i in 0..participant_count {
share_indices_by_user.push(Vec::with_capacity(shares_per_user as usize));
}
for (current_share_index, current_user_indices) in share_users.iter().enumerate() {
let current_user_indices = get_share_user_indices(participant_count, *current_user_indices);
println!("Share {} users: {:?}", current_share_index, current_user_indices);
assert_eq!(current_user_indices.len(), users_per_share as usize);
for current_user_index in current_user_indices {
share_indices_by_user[current_user_index].push(current_share_index);
}
}
println!("");
for (current_user_index, current_shares_indices) in share_indices_by_user.iter().enumerate() {
println!("User {} shares: {:?}", current_user_index, current_shares_indices);
assert_eq!(current_shares_indices.len(), shares_per_user as usize);
}
}
// fn get_share_user_indices(participant_count: u32, share_users: u32) -> HashSet<usize> {
fn get_share_user_indices(participant_count: u32, share_users: u32) -> Vec<usize> {
let mut user_indices = Vec::new();
for i in 0..participant_count {
if (1 << i) & share_users > 0 {
// user_indices.insert(i as usize);
user_indices.push(i as usize);
}
}
user_indices
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment