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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use ed25519_compact::{KeyPair, PublicKey, SecretKey, Seed, Signature};
use rand_core::{CryptoRng, RngCore};
use std::{borrow::Cow, fmt};
use crate::{Algorithm, AlgorithmSignature, Renamed};
impl AlgorithmSignature for Signature {
fn try_from_slice(bytes: &[u8]) -> anyhow::Result<Self> {
let mut signature = [0u8; Signature::BYTES];
if bytes.len() != signature.len() {
return Err(ed25519_compact::Error::SignatureMismatch.into());
}
signature.copy_from_slice(bytes);
Ok(Self::new(signature))
}
fn as_bytes(&self) -> Cow<[u8]> {
Cow::Borrowed(self.as_ref())
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct Ed25519VerifyingKey(PublicKey);
impl AsRef<PublicKey> for Ed25519VerifyingKey {
fn as_ref(&self) -> &PublicKey {
&self.0
}
}
impl Ed25519VerifyingKey {
pub fn from_slice(raw: &[u8]) -> anyhow::Result<Ed25519VerifyingKey> {
Ok(Ed25519VerifyingKey(PublicKey::from_slice(raw)?))
}
pub fn as_bytes(&self) -> Cow<[u8]> {
Cow::Borrowed(self.0.as_ref())
}
}
pub struct Ed25519SigningKey(SecretKey);
impl fmt::Debug for Ed25519SigningKey {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_tuple("Ed25519SigningKey")
.field(&self.0.as_ref())
.finish()
}
}
impl AsRef<SecretKey> for Ed25519SigningKey {
fn as_ref(&self) -> &SecretKey {
&self.0
}
}
impl Ed25519SigningKey {
pub fn from_slice(raw: &[u8]) -> anyhow::Result<Ed25519SigningKey> {
Ok(Ed25519SigningKey(SecretKey::from_slice(raw)?))
}
pub fn to_verifying_key(&self) -> PublicKey {
self.as_ref().public_key()
}
pub fn as_bytes(&self) -> Cow<[u8]> {
Cow::Borrowed(self.0.as_ref())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Ed25519;
impl Ed25519 {
pub fn with_specific_name() -> Renamed<Self> {
Renamed::new(Self, "Ed25519")
}
pub fn generate<R: CryptoRng + RngCore>(
&self,
rng: &mut R,
) -> (Ed25519SigningKey, Ed25519VerifyingKey) {
let mut seed = [0u8; Seed::BYTES];
rng.fill_bytes(&mut seed);
let keypair = KeyPair::from_seed(Seed::new(seed));
(
Ed25519SigningKey(keypair.sk),
Ed25519VerifyingKey(keypair.pk),
)
}
}
impl Algorithm for Ed25519 {
type SigningKey = Ed25519SigningKey;
type VerifyingKey = Ed25519VerifyingKey;
type Signature = Signature;
fn name(&self) -> Cow<'static, str> {
Cow::Borrowed("EdDSA")
}
fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
signing_key.as_ref().sign(message, Some(Default::default()))
}
fn verify_signature(
&self,
signature: &Self::Signature,
verifying_key: &Self::VerifyingKey,
message: &[u8],
) -> bool {
verifying_key.as_ref().verify(message, signature).is_ok()
}
}