1use std::{
4 borrow::Borrow,
5 cmp::{Ord, PartialOrd},
6 fmt::{self, Debug, Display},
7 hash::Hash,
8 ops::Deref,
9 str::FromStr,
10};
11
12use curve25519_dalek::edwards::CompressedEdwardsY;
13use ed25519_dalek::{SigningKey, VerifyingKey};
14use n0_error::{ensure, stack_error};
15use rand_core::CryptoRng;
16use serde::{Deserialize, Serialize, de, ser};
17
18#[derive(Clone, Copy, PartialEq, Eq)]
23#[repr(transparent)]
24pub struct PublicKey(CompressedEdwardsY);
25
26impl Borrow<[u8; 32]> for PublicKey {
27 fn borrow(&self) -> &[u8; 32] {
28 self.as_bytes()
29 }
30}
31
32impl Deref for PublicKey {
33 type Target = [u8; 32];
34
35 fn deref(&self) -> &Self::Target {
36 self.as_bytes()
37 }
38}
39
40impl PartialOrd for PublicKey {
41 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
42 Some(self.cmp(other))
43 }
44}
45
46impl Ord for PublicKey {
47 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
48 self.0.as_bytes().cmp(other.0.as_bytes())
49 }
50}
51
52pub type EndpointId = PublicKey;
65
66impl Hash for PublicKey {
67 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
68 self.0.hash(state);
69 }
70}
71
72impl Serialize for PublicKey {
73 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74 where
75 S: serde::Serializer,
76 {
77 if serializer.is_human_readable() {
78 serializer.serialize_str(&self.to_string())
79 } else {
80 self.0.as_bytes().serialize(serializer)
81 }
82 }
83}
84
85impl<'de> Deserialize<'de> for PublicKey {
86 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
87 where
88 D: serde::Deserializer<'de>,
89 {
90 if deserializer.is_human_readable() {
91 let s = String::deserialize(deserializer)?;
92 Self::from_str(&s).map_err(serde::de::Error::custom)
93 } else {
94 let data: [u8; 32] = serde::Deserialize::deserialize(deserializer)?;
95 Self::try_from(data.as_ref()).map_err(serde::de::Error::custom)
96 }
97 }
98}
99
100impl PublicKey {
101 pub const LENGTH: usize = ed25519_dalek::PUBLIC_KEY_LENGTH;
103
104 pub fn as_bytes(&self) -> &[u8; 32] {
106 self.0.as_bytes()
107 }
108
109 pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self, KeyParsingError> {
117 let key = VerifyingKey::from_bytes(bytes)?;
118 let y = CompressedEdwardsY(key.to_bytes());
119 Ok(Self(y))
120 }
121
122 pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), SignatureError> {
128 self.as_verifying_key()
129 .verify_strict(message, &signature.0)
130 .map_err(|_| SignatureError::new())
131 }
132
133 pub fn fmt_short(&self) -> impl Display + Copy + 'static {
136 PublicKeyShort(
137 self.0.as_bytes()[0..5]
138 .try_into()
139 .expect("slice with incorrect length"),
140 )
141 }
142
143 #[doc(hidden)]
145 pub fn as_verifying_key(&self) -> VerifyingKey {
146 VerifyingKey::from_bytes(self.0.as_bytes()).expect("already verified")
147 }
148
149 #[doc(hidden)]
151 pub fn from_verifying_key(key: VerifyingKey) -> Self {
152 Self(CompressedEdwardsY(key.to_bytes()))
153 }
154}
155
156#[derive(Copy, Clone)]
157struct PublicKeyShort([u8; 5]);
158
159impl Display for PublicKeyShort {
160 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
161 data_encoding::HEXLOWER.encode_write(&self.0, f)
162 }
163}
164
165impl TryFrom<&[u8]> for PublicKey {
166 type Error = KeyParsingError;
167
168 #[inline]
169 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
170 let vk = VerifyingKey::try_from(bytes)?;
171 Ok(Self(CompressedEdwardsY(vk.to_bytes())))
172 }
173}
174
175impl TryFrom<&[u8; 32]> for PublicKey {
176 type Error = KeyParsingError;
177
178 #[inline]
179 fn try_from(bytes: &[u8; 32]) -> Result<Self, Self::Error> {
180 Self::from_bytes(bytes)
181 }
182}
183
184impl AsRef<[u8]> for PublicKey {
185 fn as_ref(&self) -> &[u8] {
186 self.as_bytes()
187 }
188}
189
190impl Debug for PublicKey {
191 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
192 write!(
193 f,
194 "PublicKey({})",
195 data_encoding::HEXLOWER.encode(self.as_bytes())
196 )
197 }
198}
199
200impl Display for PublicKey {
201 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
202 write!(f, "{}", data_encoding::HEXLOWER.encode(self.as_bytes()))
203 }
204}
205
206#[stack_error(derive, add_meta, from_sources, std_sources)]
208#[allow(missing_docs)]
209pub enum KeyParsingError {
210 #[error(transparent)]
212 Decode(data_encoding::DecodeError),
213 #[error(transparent)]
215 Key(ed25519_dalek::SignatureError),
216 #[error("invalid length")]
218 DecodeInvalidLength,
219}
220
221impl FromStr for PublicKey {
225 type Err = KeyParsingError;
226
227 fn from_str(s: &str) -> Result<Self, Self::Err> {
228 let bytes = decode_base32_hex(s)?;
229
230 Self::from_bytes(&bytes)
231 }
232}
233
234#[derive(Clone, zeroize::ZeroizeOnDrop)]
236pub struct SecretKey(SigningKey);
237
238impl Debug for SecretKey {
239 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240 write!(f, "SecretKey(..)")
241 }
242}
243
244impl FromStr for SecretKey {
245 type Err = KeyParsingError;
246
247 fn from_str(s: &str) -> Result<Self, Self::Err> {
248 let bytes = decode_base32_hex(s)?;
249 Ok(SecretKey::from(bytes))
250 }
251}
252
253impl Serialize for SecretKey {
254 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
255 where
256 S: serde::Serializer,
257 {
258 self.0.serialize(serializer)
259 }
260}
261
262impl<'de> Deserialize<'de> for SecretKey {
263 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
264 where
265 D: serde::Deserializer<'de>,
266 {
267 let secret = SigningKey::deserialize(deserializer)?;
268 Ok(Self(secret))
269 }
270}
271
272impl SecretKey {
273 pub fn public(&self) -> PublicKey {
275 let key = self.0.verifying_key().to_bytes();
276 PublicKey(CompressedEdwardsY(key))
277 }
278
279 pub fn generate<R: CryptoRng + ?Sized>(csprng: &mut R) -> Self {
286 let secret = SigningKey::generate(csprng);
287 Self(secret)
288 }
289
290 pub fn sign(&self, msg: &[u8]) -> Signature {
292 use ed25519_dalek::Signer;
293
294 let sig = self.0.sign(msg);
295 Signature(sig)
296 }
297
298 pub fn to_bytes(&self) -> [u8; 32] {
301 self.0.to_bytes()
302 }
303
304 pub fn from_bytes(bytes: &[u8; 32]) -> Self {
306 let secret = SigningKey::from_bytes(bytes);
307 Self(secret)
308 }
309
310 #[doc(hidden)]
312 pub fn as_signing_key(&self) -> &SigningKey {
313 &self.0
314 }
315}
316
317impl From<[u8; 32]> for SecretKey {
318 fn from(value: [u8; 32]) -> Self {
319 Self::from_bytes(&value)
320 }
321}
322
323impl TryFrom<&[u8]> for SecretKey {
324 type Error = KeyParsingError;
325
326 #[inline]
327 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
328 let secret = SigningKey::try_from(bytes)?;
329 Ok(Self(secret))
330 }
331}
332
333#[derive(Copy, Clone, Eq, PartialEq)]
335pub struct Signature(ed25519_dalek::Signature);
336
337impl Serialize for Signature {
338 fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
339 use ser::SerializeTuple;
340
341 let mut seq = serializer.serialize_tuple(Signature::LENGTH)?;
342
343 for byte in self.to_bytes() {
344 seq.serialize_element(&byte)?;
345 }
346
347 seq.end()
348 }
349}
350
351impl<'de> Deserialize<'de> for Signature {
354 fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
355 struct ByteArrayVisitor;
356
357 impl<'de> de::Visitor<'de> for ByteArrayVisitor {
358 type Value = [u8; Signature::LENGTH];
359
360 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
361 formatter.write_str("bytestring of length 64")
362 }
363
364 fn visit_seq<A>(self, mut seq: A) -> Result<[u8; Signature::LENGTH], A::Error>
365 where
366 A: de::SeqAccess<'de>,
367 {
368 use de::Error;
369 let mut arr = [0u8; Signature::LENGTH];
370
371 for (i, byte) in arr.iter_mut().enumerate() {
372 *byte = seq
373 .next_element()?
374 .ok_or_else(|| Error::invalid_length(i, &self))?;
375 }
376
377 Ok(arr)
378 }
379 }
380
381 deserializer
382 .deserialize_tuple(Signature::LENGTH, ByteArrayVisitor)
383 .map(|b| Signature::from_bytes(&b))
384 }
385}
386
387impl Debug for Signature {
388 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
389 write!(f, "{:?}", self.0)
390 }
391}
392
393impl Display for Signature {
394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395 write!(f, "{}", self.0)
396 }
397}
398
399impl Signature {
400 pub const LENGTH: usize = ed25519_dalek::Signature::BYTE_SIZE;
402
403 pub fn to_bytes(&self) -> [u8; Self::LENGTH] {
405 self.0.to_bytes()
406 }
407
408 pub fn from_bytes(bytes: &[u8; Self::LENGTH]) -> Self {
410 Self(ed25519_dalek::Signature::from_bytes(bytes))
411 }
412}
413
414#[stack_error(derive, add_meta)]
416#[error("Invalid signature")]
417pub struct SignatureError {}
418
419fn decode_base32_hex(s: &str) -> Result<[u8; 32], KeyParsingError> {
420 let mut bytes = [0u8; 32];
421
422 let res = if s.len() == PublicKey::LENGTH * 2 {
423 data_encoding::HEXLOWER.decode_mut(s.as_bytes(), &mut bytes)
425 } else {
426 let input = s.to_ascii_uppercase();
427 let input = input.as_bytes();
428 ensure!(
429 data_encoding::BASE32_NOPAD.decode_len(input.len())? == bytes.len(),
430 KeyParsingError::DecodeInvalidLength
431 );
432 data_encoding::BASE32_NOPAD.decode_mut(input, &mut bytes)
433 };
434 match res {
435 Ok(len) => {
436 ensure!(
437 len == PublicKey::LENGTH,
438 KeyParsingError::DecodeInvalidLength
439 );
440 }
441 Err(partial) => return Err(partial.error.into()),
442 }
443 Ok(bytes)
444}
445
446#[cfg(test)]
447mod tests {
448 use data_encoding::HEXLOWER;
449 use rand::SeedableRng;
450
451 use super::*;
452
453 #[test]
454 fn test_public_key_postcard() {
455 let public_key =
456 PublicKey::from_str("ae58ff8833241ac82d6ff7611046ed67b5072d142c588d0063e942d9a75502b6")
457 .unwrap();
458 let bytes = postcard::to_stdvec(&public_key).unwrap();
459 let expected = HEXLOWER
460 .decode(b"ae58ff8833241ac82d6ff7611046ed67b5072d142c588d0063e942d9a75502b6")
461 .unwrap();
462 assert_eq!(bytes, expected);
463 }
464
465 #[test]
466 fn public_key_postcard() {
467 let key = PublicKey::from_bytes(&[0; 32]).unwrap();
468 let bytes = postcard::to_stdvec(&key).unwrap();
469 let key2: PublicKey = postcard::from_bytes(&bytes).unwrap();
470 assert_eq!(key, key2);
471 }
472
473 #[test]
474 fn public_key_json() {
475 let key = PublicKey::from_bytes(&[0; 32]).unwrap();
476 let bytes = serde_json::to_string(&key).unwrap();
477 let key2: PublicKey = serde_json::from_str(&bytes).unwrap();
478 assert_eq!(key, key2);
479 }
480
481 #[test]
482 fn test_from_str() {
483 let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0u64);
484 let key = SecretKey::generate(&mut rng);
485 assert_eq!(
486 SecretKey::from_str(&HEXLOWER.encode(&key.to_bytes()))
487 .unwrap()
488 .to_bytes(),
489 key.to_bytes()
490 );
491
492 assert_eq!(
493 PublicKey::from_str(&key.public().to_string()).unwrap(),
494 key.public()
495 );
496 }
497
498 #[test]
499 fn test_regression_parse_endpoint_id_panic() {
500 let not_a_endpoint_id = "foobarbaz";
501 assert!(PublicKey::from_str(not_a_endpoint_id).is_err());
502 }
503
504 #[test]
505 fn signature_postcard() {
506 let key = SecretKey::generate(&mut rand::rng());
507 let signature = key.sign(b"hello world");
508 let bytes = postcard::to_stdvec(&signature).unwrap();
509 let signature2: Signature = postcard::from_bytes(&bytes).unwrap();
510 assert_eq!(signature, signature2);
511 }
512}