vrf-pbft 0.1.0

A Rust implementation of VRF-enhanced PBFT consensus protocol
Documentation
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, &params).unwrap();
    assert!(client.verify(&pk, &proof, &params).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;
        }
    }
    // With weight=100, expected=10, total=1000: p=0.01
    // Expected selection rate: ~63% (1-(1-0.01)^100)
    assert!(
        selected > 300 && selected < 900,
        "selected {} out of {} -- outside expected range",
        selected,
        trials
    );
}