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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use paired::bls12_381::{Bls12, Fr};

use crate::crypto::sloth;
use crate::error::Result;
use crate::hasher::pedersen::PedersenDomain;
use crate::parameter_cache::ParameterSetMetadata;
use crate::vdf::Vdf;

/// VDF construction using sloth.
#[derive(Debug, Clone)]
pub struct Sloth {}

#[derive(Debug, Clone)]
pub struct SetupParams {
    pub key: PedersenDomain,
    pub rounds: usize,
}

#[derive(Debug, Clone)]
pub struct PublicParams {
    pub key: PedersenDomain,
    pub rounds: usize,
}

impl ParameterSetMetadata for PublicParams {
    fn identifier(&self) -> String {
        format!(
            "vdf_sloth::PublicParams{{key: {:?}; rounds: {}}}",
            self.key, self.rounds
        )
    }

    fn sector_size(&self) -> u64 {
        unimplemented!("required for parameter metadata file generation")
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Proof {
    y: PedersenDomain,
}

impl Vdf<PedersenDomain> for Sloth {
    type SetupParams = SetupParams;
    type PublicParams = PublicParams;
    type Proof = Proof;

    fn setup(sp: &Self::SetupParams) -> Result<Self::PublicParams> {
        Ok(PublicParams {
            key: sp.key,
            rounds: sp.rounds,
        })
    }

    fn eval(pp: &Self::PublicParams, x: &PedersenDomain) -> Result<(PedersenDomain, Self::Proof)> {
        let key: Fr = pp.key.into();
        let x: Fr = (*x).into();
        let y = sloth::encode::<Bls12>(&key, &x, pp.rounds);

        Ok((y.into(), Proof { y: y.into() }))
    }

    fn verify(pp: &Self::PublicParams, x: &PedersenDomain, proof: &Self::Proof) -> Result<bool> {
        let y: Fr = Self::extract_output(proof).into();
        let key: Fr = pp.key.into();
        let decoded: PedersenDomain = sloth::decode::<Bls12>(&key, &y, pp.rounds).into();

        Ok(&decoded == x)
    }

    fn key(pp: &self::PublicParams) -> PedersenDomain {
        pp.key
    }
    fn rounds(pp: &self::PublicParams) -> usize {
        pp.rounds
    }
    fn extract_output(proof: &Proof) -> PedersenDomain {
        proof.y
    }
}