1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use crate::key;
use rand_core::{CryptoRng, RngCore};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VrfVerification {
    Success,
    Failed,
}

pub trait VerifiableRandomFunction: key::AsymmetricPublicKey + key::AsymmetricKey {
    type VerifiedRandomOutput;
    type RandomOutput;
    type Input: ?Sized;

    const VERIFIED_RANDOM_SIZE: usize;

    fn evaluate_and_prove<T: RngCore + CryptoRng>(
        secret: &Self::Secret,
        input: &Self::Input,
        rng: T,
    ) -> Self::VerifiedRandomOutput;

    fn verify(
        public: &Self::Public,
        input: &Self::Input,
        vrand: &Self::VerifiedRandomOutput,
    ) -> VrfVerification;

    fn strip_verification_output(vr: &Self::VerifiedRandomOutput) -> Self::RandomOutput;
}

/// Evaluate the VRF for a specific input and return a verified output
pub fn vrf_evaluate_and_prove<VRF: VerifiableRandomFunction, T: RngCore + CryptoRng>(
    secret: &key::SecretKey<VRF>,
    input: &<VRF as VerifiableRandomFunction>::Input,
    rng: T,
) -> <VRF as VerifiableRandomFunction>::VerifiedRandomOutput {
    VRF::evaluate_and_prove(&secret.0, input, rng)
}

/// Verify the VRF output for a specific input is correct
pub fn vrf_verify<VRF: VerifiableRandomFunction>(
    public: &key::PublicKey<VRF>,
    input: &<VRF as VerifiableRandomFunction>::Input,
    vrand: &<VRF as VerifiableRandomFunction>::VerifiedRandomOutput,
) -> VrfVerification {
    VRF::verify(&public.0, input, vrand)
}

pub fn vrf_verified_get_output<VRF: VerifiableRandomFunction>(
    vr: &<VRF as VerifiableRandomFunction>::VerifiedRandomOutput,
) -> <VRF as VerifiableRandomFunction>::RandomOutput {
    VRF::strip_verification_output(vr)
}