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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
pub use anyhow::Error;
pub use bytes::{Buf, BufMut, Bytes, BytesMut};
pub use ophelia_hasher::{HashValue, Hasher};
pub use rand::{CryptoRng, RngCore};

use std::convert::TryFrom;

pub trait PrivateKey: for<'a> TryFrom<&'a [u8], Error = Error> + Clone {
    type Signature;

    const LENGTH: usize;

    fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Self;

    fn sign_message(&self, msg: &HashValue) -> Self::Signature;

    fn to_bytes(&self) -> Bytes;
}

pub trait ToPublicKey {
    type PublicKey;

    fn pub_key(&self) -> Self::PublicKey;
}

pub trait ToBlsPublicKey {
    type PublicKey;
    type CommonReference;

    fn pub_key(&self, cr: &Self::CommonReference) -> Self::PublicKey;
}

// Todo: use const generics
pub trait PublicKey: for<'a> TryFrom<&'a [u8], Error = Error> + Clone {
    type Signature;

    const LENGTH: usize;

    fn to_bytes(&self) -> Bytes;
}

pub trait UncompressedPublicKey: for<'a> TryFrom<&'a [u8], Error = Error> + Clone {
    type Signature;

    const LENGTH: usize;

    fn to_uncompressed_bytes(&self) -> Bytes;
}

pub trait Signature: for<'a> TryFrom<&'a [u8], Error = Error> + Clone {
    fn to_bytes(&self) -> Bytes;
}

pub trait SignatureVerify {
    type PublicKey;

    fn verify(&self, msg: &HashValue, pub_key: &Self::PublicKey) -> Result<(), Error>;
}

pub trait BlsSignatureVerify {
    type PublicKey;
    type CommonReference;

    fn verify(
        &self,
        msg: &HashValue,
        pub_key: &Self::PublicKey,
        cr: &Self::CommonReference,
    ) -> Result<(), Error>;
}

pub trait Crypto {
    type PrivateKey: PrivateKey<Signature = Self::Signature>
        + ToPublicKey<PublicKey = Self::PublicKey>;
    type PublicKey: PublicKey<Signature = Self::Signature>;
    type Signature: Signature + SignatureVerify<PublicKey = Self::PublicKey>;

    fn pub_key(priv_key: &[u8]) -> Result<Self::PublicKey, Error> {
        let priv_key = Self::PrivateKey::try_from(priv_key)?;

        Ok(priv_key.pub_key())
    }

    fn sign_message(msg: &[u8], priv_key: &[u8]) -> Result<Self::Signature, Error> {
        let priv_key = Self::PrivateKey::try_from(priv_key)?;
        let msg = HashValue::try_from(msg)?;

        Ok(priv_key.sign_message(&msg))
    }

    fn verify_signature(msg: &[u8], sig: &[u8], pub_key: &[u8]) -> Result<(), Error> {
        let msg = HashValue::try_from(msg)?;
        let sig = Self::Signature::try_from(sig)?;
        let pub_key = Self::PublicKey::try_from(pub_key)?;

        sig.verify(&msg, &pub_key)?;
        Ok(())
    }
}