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
100
101
102
103
104
105
106
107
108
109
110
111
112
use ed25519_dalek::{
    Signature as CryptoSignature, Signer, SigningKey as CryptoSigningKey,
    VerifyingKey as CryptoVerifyingKey,
};
use getter_methods::GetterMethods;
use ppppp_bytes::{
    impl_as_bytes_outputs, impl_from_bytes_inputs, impl_to_bytes_outputs, AsBytes,
    DeserializeBytesError, FromBytes, ToBytes,
};
use std::convert::Infallible;

pub use ed25519_dalek::SignatureError;

pub type SignDeserializeBytesError = DeserializeBytesError<SignatureError>;

/// A secret key to sign messages
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SigningKey(CryptoSigningKey);

impl FromBytes<32> for SigningKey {
    type Error = Infallible;

    fn from_bytes(bytes: &[u8; 32]) -> Result<Self, Self::Error> {
        Ok(SigningKey(CryptoSigningKey::from_bytes(bytes)))
    }
}

impl AsBytes<32> for SigningKey {
    fn as_bytes(&self) -> &[u8; 32] {
        self.0.as_bytes()
    }
}

impl_from_bytes_inputs!(SigningKey, 32_usize);
impl_as_bytes_outputs!(SigningKey, 32_usize);

impl SigningKey {
    pub fn sign(&self, message: &[u8]) -> Signature {
        Signature(self.0.sign(message))
    }

    pub fn try_sign(&self, message: &[u8]) -> Result<Signature, SignatureError> {
        Ok(Signature(self.0.try_sign(message)?))
    }
}

/// A public key to verify signatures
#[derive(Clone, Debug, Eq)]
pub struct VerifyingKey(CryptoVerifyingKey);

impl FromBytes<32> for VerifyingKey {
    type Error = SignatureError;

    fn from_bytes(bytes: &[u8; 32]) -> Result<Self, Self::Error> {
        // TODO check if key is weak
        Ok(VerifyingKey(CryptoVerifyingKey::from_bytes(bytes)?))
    }
}

impl AsBytes<32> for VerifyingKey {
    fn as_bytes(&self) -> &[u8; 32] {
        self.0.as_bytes()
    }
}

impl_from_bytes_inputs!(VerifyingKey, 32_usize);
impl_as_bytes_outputs!(VerifyingKey, 32_usize);

impl VerifyingKey {
    // https://github.com/dalek-cryptography/curve25519-dalek/tree/main/ed25519-dalek#weak-key-forgery-and-verify_strict
    pub fn is_weak(&self) -> bool {
        self.0.is_weak()
    }

    pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), SignatureError> {
        self.0.verify_strict(message, &signature.0)
    }
}

impl PartialEq for VerifyingKey {
    fn eq(&self, other: &Self) -> bool {
        self.as_bytes() == other.as_bytes()
    }
}

/// A private and public key pair to sign and verify signatures
#[derive(Clone, Debug, GetterMethods)]
pub struct SignKeypair {
    signing_key: SigningKey,
    verifying_key: VerifyingKey,
}

/// An Ed25519 signature
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Signature(CryptoSignature);

impl FromBytes<64> for Signature {
    type Error = Infallible;

    fn from_bytes(bytes: &[u8; 64]) -> Result<Self, Self::Error> {
        Ok(Signature(CryptoSignature::from_bytes(bytes)))
    }
}

impl ToBytes<64> for Signature {
    fn to_bytes(&self) -> [u8; 64] {
        self.0.to_bytes()
    }
}

impl_from_bytes_inputs!(Signature, 64_usize);
impl_to_bytes_outputs!(Signature, 64_usize);