use vrf_pbft::vrf::{sortition, VrfClient, VrfParams};
use vrf_pbft::Role;
#[test]
fn key_generation() {
let mut client = VrfClient::new().unwrap();
let (sk, pk) = client.generate_keys(42).unwrap();
assert!(!sk.is_empty());
assert!(!pk.is_empty());
}
#[test]
fn prove_and_verify() {
let mut client = VrfClient::new().unwrap();
let (sk, pk) = client.generate_keys(42).unwrap();
let params = VrfParams {
weight: 100,
round: 1,
seed: 42,
role: Role::Validator,
};
let proof = client.prove(&sk, ¶ms).unwrap();
assert!(client.verify(&pk, &proof, ¶ms).unwrap());
}
#[test]
fn different_params_produce_different_hashes() {
let mut client = VrfClient::new().unwrap();
let (sk, _) = client.generate_keys(42).unwrap();
let proof1 = client
.prove(
&sk,
&VrfParams {
weight: 100,
round: 1,
seed: 42,
role: Role::Proposer,
},
)
.unwrap();
let proof2 = client
.prove(
&sk,
&VrfParams {
weight: 100,
round: 1,
seed: 42,
role: Role::Validator,
},
)
.unwrap();
assert_ne!(proof1.hash, proof2.hash);
}
#[test]
fn sortition_zero_weight() {
assert_eq!(sortition(&[0; 32], 0, 10, 100), 0);
}
#[test]
fn sortition_zero_expected() {
assert_eq!(sortition(&[0; 32], 100, 0, 1000), 0);
}
#[test]
fn sortition_produces_reasonable_distribution() {
let mut selected = 0;
let trials = 1000;
for i in 0u64..trials {
let hash: Vec<u8> = (0..32)
.map(|j| ((i.wrapping_mul(31).wrapping_add(j * 7)) % 256) as u8)
.collect();
if sortition(&hash, 100, 10, 1000) > 0 {
selected += 1;
}
}
assert!(
selected > 300 && selected < 900,
"selected {} out of {} -- outside expected range",
selected,
trials
);
}