1use std::cmp::Ordering;
25use std::ops::Deref;
26
27use crate::display::{Encoding, MultiDisplay};
28use crate::{EcPk, EcPkInvalid, EcSig, EcSigInvalid, EcSign, EcSk, EcSkInvalid, EcVerifyError};
29
30impl MultiDisplay<Encoding> for ec25519::PublicKey {
34 type Display = String;
35 fn display_fmt(&self, f: &Encoding) -> Self::Display { f.encode(self.as_slice()) }
36}
37
38impl EcPk for ec25519::PublicKey {
39 const COMPRESSED_LEN: usize = 32;
40 const CURVE_NAME: &'static str = "Edwards25519";
41 type Compressed = [u8; 32];
42
43 fn base_point() -> Self {
44 ec25519::PublicKey::from_slice(
45 &[
46 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
47 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
48 0x66, 0x66, 0x66, 0x66,
49 ][..],
50 )
51 .expect("hardcoded basepoint value")
52 }
53
54 fn to_pk_compressed(&self) -> Self::Compressed { *self.deref() }
55
56 fn from_pk_compressed(pk: Self::Compressed) -> Result<Self, EcPkInvalid> {
57 Ok(ec25519::PublicKey::new(pk))
58 }
59
60 fn from_pk_compressed_slice(slice: &[u8]) -> Result<Self, EcPkInvalid> {
61 if slice.len() != Self::COMPRESSED_LEN {
62 return Err(EcPkInvalid {});
63 }
64 let mut buf = [0u8; 32];
65 buf.copy_from_slice(slice);
66 Self::from_pk_compressed(buf)
67 }
68}
69
70impl EcSk for ec25519::SecretKey {
71 type Pk = ec25519::PublicKey;
72
73 fn generate_keypair() -> (Self, Self::Pk)
74 where Self: Sized {
75 let pair = ec25519::KeyPair::generate();
76 (pair.sk, pair.pk)
77 }
78
79 fn to_pk(&self) -> Result<Self::Pk, EcSkInvalid> { Ok(self.public_key()) }
80}
81
82#[derive(Wrapper, Copy, Clone, PartialEq, Eq, Hash, Debug, From)]
86#[wrapper(Deref)]
87#[cfg_attr(
88 feature = "serde",
89 derive(Serialize, Deserialize),
90 serde(into = "String", try_from = "String")
91)]
92pub struct PublicKey(#[from] ec25519::PublicKey);
93
94impl PartialOrd for PublicKey {
95 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
96 self.0.as_ref().partial_cmp(other.0.as_ref())
97 }
98}
99
100impl Ord for PublicKey {
101 fn cmp(&self, other: &Self) -> Ordering { self.0.as_ref().cmp(other.0.as_ref()) }
102}
103
104impl EcPk for PublicKey {
105 const COMPRESSED_LEN: usize = 32;
106 const CURVE_NAME: &'static str = "Edwards25519";
107 type Compressed = [u8; 32];
108
109 fn base_point() -> Self { Self(ec25519::PublicKey::base_point()) }
110
111 fn to_pk_compressed(&self) -> Self::Compressed { self.0.to_pk_compressed() }
112
113 fn from_pk_compressed(pk: Self::Compressed) -> Result<Self, EcPkInvalid> {
114 ec25519::PublicKey::from_pk_compressed(pk).map(Self)
115 }
116
117 fn from_pk_compressed_slice(slice: &[u8]) -> Result<Self, EcPkInvalid> {
118 ec25519::PublicKey::from_pk_compressed_slice(slice).map(Self)
119 }
120}
121
122impl MultiDisplay<Encoding> for PublicKey {
123 type Display = String;
124 fn display_fmt(&self, f: &Encoding) -> Self::Display { self.0.display_fmt(f) }
125}
126
127#[derive(Wrapper, Clone, PartialEq, Eq, Hash, Debug, From)]
128#[wrapper(Deref)]
129pub struct PrivateKey(#[from] ec25519::SecretKey);
130
131impl PartialOrd for PrivateKey {
132 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
133}
134
135impl Ord for PrivateKey {
136 fn cmp(&self, other: &Self) -> Ordering { self.0.cmp(&other.0) }
137}
138
139impl EcSk for PrivateKey {
140 type Pk = PublicKey;
141
142 fn generate_keypair() -> (Self, Self::Pk)
143 where Self: Sized {
144 let (sk, pk) = ec25519::SecretKey::generate_keypair();
145 (sk.into(), pk.into())
146 }
147
148 fn to_pk(&self) -> Result<PublicKey, EcSkInvalid> { self.0.to_pk().map(PublicKey::from) }
149}
150
151impl EcSign for ec25519::SecretKey {
155 type Sig = ec25519::Signature;
156
157 fn sign(&self, msg: impl AsRef<[u8]>) -> ec25519::Signature { self.sign(msg, None) }
158}
159
160impl MultiDisplay<Encoding> for ec25519::Signature {
161 type Display = String;
162 fn display_fmt(&self, f: &Encoding) -> Self::Display { f.encode(self.as_slice()) }
163}
164
165impl EcSig for ec25519::Signature {
166 const COMPRESSED_LEN: usize = 64;
167
168 type Pk = ec25519::PublicKey;
169 type Compressed = [u8; 64];
170
171 fn to_sig_compressed(&self) -> Self::Compressed { *self.deref() }
172
173 fn from_sig_compressed(sig: Self::Compressed) -> Result<Self, EcSigInvalid> {
174 Ok(Self::from_slice(&sig).expect("fixed length"))
175 }
176
177 fn from_sig_compressed_slice(slice: &[u8]) -> Result<Self, EcSigInvalid> {
178 Self::from_slice(slice).map_err(|_| EcSigInvalid {})
179 }
180
181 fn verify(&self, pk: &Self::Pk, msg: impl AsRef<[u8]>) -> Result<(), EcVerifyError> {
182 pk.verify(msg, self).map_err(EcVerifyError::from)
183 }
184}
185
186#[derive(Wrapper, Copy, Clone, PartialEq, Eq, Hash, Debug)]
188#[wrapper(Deref)]
189pub struct Signature(ec25519::Signature);
190
191impl AsRef<[u8]> for Signature {
192 fn as_ref(&self) -> &[u8] { self.0.as_ref() }
193}
194
195impl From<ec25519::Signature> for Signature {
196 fn from(other: ec25519::Signature) -> Self { Self(other) }
197}
198
199impl MultiDisplay<Encoding> for Signature {
200 type Display = String;
201 fn display_fmt(&self, f: &Encoding) -> Self::Display { self.0.display_fmt(f) }
202}
203
204impl EcSig for Signature {
205 const COMPRESSED_LEN: usize = 64;
206 type Pk = PublicKey;
207 type Compressed = [u8; 64];
208
209 fn to_sig_compressed(&self) -> Self::Compressed { self.0.to_sig_compressed() }
210
211 fn from_sig_compressed(sig: Self::Compressed) -> Result<Self, EcSigInvalid> {
212 ec25519::Signature::from_sig_compressed(sig).map(Self)
213 }
214
215 fn from_sig_compressed_slice(slice: &[u8]) -> Result<Self, EcSigInvalid> {
216 ec25519::Signature::from_sig_compressed_slice(slice).map(Self)
217 }
218
219 fn verify(&self, pk: &Self::Pk, msg: impl AsRef<[u8]>) -> Result<(), EcVerifyError> {
220 self.0.verify(pk, msg)
221 }
222}
223
224impl EcSign for PrivateKey {
225 type Sig = Signature;
226
227 fn sign(&self, msg: impl AsRef<[u8]>) -> Signature { Signature(self.0.sign(msg, None)) }
228}
229
230#[cfg(feature = "multibase")]
234mod human_readable {
235 use std::fmt::{self, Display, Formatter};
236 use std::str::FromStr;
237
238 use super::*;
239 use crate::EcSerError;
240
241 impl PublicKey {
242 pub const MULTICODEC_TYPE: [u8; 2] = [0xED, 0x1];
244
245 pub fn to_human_readable(&self) -> String {
251 let mut buf = [0; 2 + ec25519::PublicKey::BYTES];
252 buf[..2].copy_from_slice(&Self::MULTICODEC_TYPE);
253 buf[2..].copy_from_slice(self.0.deref());
254
255 multibase::encode(multibase::Base::Base58Btc, buf)
256 }
257 }
258
259 impl Display for PublicKey {
260 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
261 f.write_str(&self.to_human_readable())
262 }
263 }
264
265 impl FromStr for PublicKey {
266 type Err = EcSerError;
267
268 fn from_str(s: &str) -> Result<Self, Self::Err> {
269 let (_, bytes) = multibase::decode(s)?;
270
271 if let Some(bytes) = bytes.strip_prefix(&Self::MULTICODEC_TYPE) {
272 let key = ec25519::PublicKey::from_slice(bytes)?;
273
274 Ok(Self(key))
275 } else {
276 Err(EcSerError::DataEncoding(s!("unrecognized multicode type")))
277 }
278 }
279 }
280
281 impl From<PublicKey> for String {
282 fn from(other: PublicKey) -> Self { other.to_human_readable() }
283 }
284
285 impl TryFrom<String> for PublicKey {
286 type Error = EcSerError;
287
288 fn try_from(value: String) -> Result<Self, Self::Error> { Self::from_str(&value) }
289 }
290
291 impl Display for Signature {
292 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
293 let base = multibase::Base::Base58Btc;
294 write!(f, "{}", multibase::encode(base, self.0))
295 }
296 }
297
298 impl FromStr for Signature {
299 type Err = EcSerError;
300
301 fn from_str(s: &str) -> Result<Self, Self::Err> {
302 let (_, bytes) = multibase::decode(s)?;
303 let sig = ec25519::Signature::from_slice(bytes.as_slice())?;
304
305 Ok(Self(sig))
306 }
307 }
308}
309
310#[cfg(feature = "pem")]
311mod pem_der {
312 use super::*;
313
314 impl PublicKey {
315 pub fn from_pem(pem: &str) -> Result<Self, ec25519::Error> {
316 ec25519::PublicKey::from_pem(pem).map(Self)
317 }
318
319 pub fn from_der(der: &[u8]) -> Result<Self, ec25519::Error> {
320 ec25519::PublicKey::from_der(der).map(Self::from)
321 }
322
323 pub fn to_pem(&self) -> String { self.0.to_pem() }
324 }
325
326 impl PrivateKey {
327 pub fn from_pem(pem: &str) -> Result<Self, ec25519::Error> {
328 ec25519::SecretKey::from_pem(pem).map(Self::from)
329 }
330
331 pub fn from_der(der: &[u8]) -> Result<Self, ec25519::Error> {
332 ec25519::SecretKey::from_der(der).map(Self::from)
333 }
334
335 pub fn to_pem(&self) -> String { self.0.to_pem() }
336 }
337}