73 lines
2.4 KiB
Rust
73 lines
2.4 KiB
Rust
|
use crate::parties::SimulatedParties;
|
||
|
use crate::server::SimulatedServer;
|
||
|
use rand_distr::Pareto;
|
||
|
use std::io::Write;
|
||
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||
|
mod parties;
|
||
|
mod server;
|
||
|
|
||
|
use clap::Clap;
|
||
|
|
||
|
#[derive(Clap)]
|
||
|
#[clap(version = "1.0", author = "Sarah Jamie Lewis <sarah@opneprivacy.ca>")]
|
||
|
struct Opts {
|
||
|
/// Sets a custom config file. Could have been an Option<T> with no default too
|
||
|
#[clap(short, long, default_value = "24")]
|
||
|
gamma: usize,
|
||
|
/// the number of parties to simulate
|
||
|
#[clap(short, long, default_value = "10")]
|
||
|
num_parties: usize,
|
||
|
|
||
|
/// samples per round
|
||
|
#[clap(short, long, default_value = "10")]
|
||
|
samples_per_round: usize,
|
||
|
|
||
|
/// minimum false positive rate
|
||
|
#[clap(short, long, default_value = "1")]
|
||
|
min_p: usize,
|
||
|
|
||
|
/// maximum false positive rate
|
||
|
#[clap(short, long, default_value = "8")]
|
||
|
max_p: usize,
|
||
|
}
|
||
|
|
||
|
fn main() {
|
||
|
let opts: Opts = Opts::parse();
|
||
|
let mut rng = rand::thread_rng();
|
||
|
let mut server = SimulatedServer::new();
|
||
|
|
||
|
println!("Generating {} Parties...", opts.num_parties);
|
||
|
let simulated_parties = SimulatedParties::new_simulation(opts.num_parties, opts.gamma);
|
||
|
simulated_parties.register_with_server(&mut server, &mut rng, opts.min_p, opts.max_p);
|
||
|
|
||
|
let pareto = Pareto::new(1.0, 1.0).unwrap();
|
||
|
|
||
|
println!("Simulating message sends using {} samples from a pareto distribution...", opts.samples_per_round);
|
||
|
(0..opts.samples_per_round).for_each(|_i| simulated_parties.sample_traffic(&mut server, &mut rng, pareto));
|
||
|
|
||
|
println!("Simulating Adversarial Server Processing Messages..");
|
||
|
server.test_messages();
|
||
|
|
||
|
let round_statistics = server.statistics();
|
||
|
let mut stdout = StandardStream::stdout(ColorChoice::Always);
|
||
|
for (party, stats) in round_statistics.iter() {
|
||
|
if stats.trivial_breaks > 0 {
|
||
|
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red))).unwrap();
|
||
|
} else {
|
||
|
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green))).unwrap();
|
||
|
}
|
||
|
writeln!(
|
||
|
&mut stdout,
|
||
|
"Party {} | Ideal: {} | Observed: {} ({:.2}) | Skew: {} ({:.2}) | Trivial Attributions this Round: {}",
|
||
|
party,
|
||
|
stats.ideal_rate,
|
||
|
stats.observed_messages,
|
||
|
100.0 * stats.observed_rate,
|
||
|
stats.observed_skew_messages,
|
||
|
stats.observed_skew,
|
||
|
stats.trivial_breaks
|
||
|
)
|
||
|
.unwrap();
|
||
|
}
|
||
|
}
|