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 data_encoding::Encoding;
14use data_encoding_macro::new_encoding;
15use ed25519_dalek::{SigningKey, VerifyingKey};
16use n0_error::{e, ensure, stack_error};
17use serde::{Deserialize, Serialize, de, ser};
18
19const Z_BASE_32: Encoding = new_encoding! {
21 symbols: "ybndrfg8ejkmcpqxot1uwisza345h769",
22};
23
24#[derive(Clone, Copy, PartialEq, Eq)]
29#[repr(transparent)]
30pub struct PublicKey(CompressedEdwardsY);
31
32impl Borrow<[u8; 32]> for PublicKey {
33 fn borrow(&self) -> &[u8; 32] {
34 self.as_bytes()
35 }
36}
37
38impl Deref for PublicKey {
39 type Target = [u8; 32];
40
41 fn deref(&self) -> &Self::Target {
42 self.as_bytes()
43 }
44}
45
46impl PartialOrd for PublicKey {
47 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
48 Some(self.cmp(other))
49 }
50}
51
52impl Ord for PublicKey {
53 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
54 self.0.as_bytes().cmp(other.0.as_bytes())
55 }
56}
57
58pub type EndpointId = PublicKey;
71
72impl Hash for PublicKey {
73 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
74 self.0.hash(state);
75 }
76}
77
78impl Serialize for PublicKey {
79 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
80 where
81 S: serde::Serializer,
82 {
83 if serializer.is_human_readable() {
84 serializer.serialize_str(&self.to_string())
85 } else {
86 self.0.as_bytes().serialize(serializer)
87 }
88 }
89}
90
91impl<'de> Deserialize<'de> for PublicKey {
92 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
93 where
94 D: serde::Deserializer<'de>,
95 {
96 if deserializer.is_human_readable() {
97 let s = String::deserialize(deserializer)?;
98 Self::from_str(&s).map_err(serde::de::Error::custom)
99 } else {
100 let data: [u8; 32] = serde::Deserialize::deserialize(deserializer)?;
101 Self::try_from(data.as_ref()).map_err(serde::de::Error::custom)
102 }
103 }
104}
105
106impl PublicKey {
107 pub const LENGTH: usize = ed25519_dalek::PUBLIC_KEY_LENGTH;
109
110 pub fn as_bytes(&self) -> &[u8; 32] {
112 self.0.as_bytes()
113 }
114
115 pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self, KeyParsingError> {
123 let key =
124 VerifyingKey::from_bytes(bytes).map_err(|_| e!(KeyParsingError::InvalidKeyData))?;
125 let y = CompressedEdwardsY(key.to_bytes());
126 Ok(Self(y))
127 }
128
129 pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), SignatureError> {
135 self.as_verifying_key()
136 .verify_strict(message, &signature.0)
137 .map_err(|_| SignatureError::new())
138 }
139
140 pub fn fmt_short(&self) -> impl Display + Copy + 'static {
143 PublicKeyShort(
144 self.0.as_bytes()[0..5]
145 .try_into()
146 .expect("slice with incorrect length"),
147 )
148 }
149
150 #[doc(hidden)]
152 pub fn as_verifying_key(&self) -> VerifyingKey {
153 VerifyingKey::from_bytes(self.0.as_bytes()).expect("already verified")
154 }
155
156 #[doc(hidden)]
158 pub fn from_verifying_key(key: VerifyingKey) -> Self {
159 Self(CompressedEdwardsY(key.to_bytes()))
160 }
161
162 pub fn to_z32(&self) -> String {
165 Z_BASE_32.encode(self.as_bytes())
166 }
167
168 pub fn from_z32(s: &str) -> Result<Self, KeyParsingError> {
170 let bytes = Z_BASE_32
171 .decode(s.as_bytes())
172 .map_err(|_| e!(KeyParsingError::FailedToDecodeBase32))?;
173 Self::try_from(bytes.as_slice())
174 }
175}
176
177#[derive(Copy, Clone)]
178struct PublicKeyShort([u8; 5]);
179
180impl Display for PublicKeyShort {
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182 data_encoding::HEXLOWER.encode_write(&self.0, f)
183 }
184}
185
186impl TryFrom<&[u8]> for PublicKey {
187 type Error = KeyParsingError;
188
189 #[inline]
190 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
191 let vk = VerifyingKey::try_from(bytes).map_err(|_| e!(KeyParsingError::InvalidKeyData))?;
192 Ok(Self(CompressedEdwardsY(vk.to_bytes())))
193 }
194}
195
196impl TryFrom<&[u8; 32]> for PublicKey {
197 type Error = KeyParsingError;
198
199 #[inline]
200 fn try_from(bytes: &[u8; 32]) -> Result<Self, Self::Error> {
201 Self::from_bytes(bytes)
202 }
203}
204
205impl AsRef<[u8]> for PublicKey {
206 fn as_ref(&self) -> &[u8] {
207 self.as_bytes()
208 }
209}
210
211impl Debug for PublicKey {
212 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
213 write!(
214 f,
215 "PublicKey({})",
216 data_encoding::HEXLOWER.encode(self.as_bytes())
217 )
218 }
219}
220
221impl Display for PublicKey {
222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223 write!(f, "{}", data_encoding::HEXLOWER.encode(self.as_bytes()))
224 }
225}
226
227#[stack_error(derive, add_meta, from_sources, std_sources)]
229#[allow(missing_docs)]
230#[non_exhaustive]
231pub enum KeyParsingError {
232 #[error("failed to decode hex string")]
234 FailedToDecodeHex,
235 #[error("failed to decode base32 string")]
237 FailedToDecodeBase32,
238 #[error("invalid length")]
240 InvalidLength,
241 #[error("data is not a valid public key")]
243 InvalidKeyData,
244}
245
246impl FromStr for PublicKey {
250 type Err = KeyParsingError;
251
252 fn from_str(s: &str) -> Result<Self, Self::Err> {
253 let bytes = decode_base32_hex(s)?;
254
255 Self::from_bytes(&bytes)
256 }
257}
258
259#[derive(Clone, zeroize::ZeroizeOnDrop)]
261pub struct SecretKey(SigningKey);
262
263impl Debug for SecretKey {
264 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
265 write!(f, "SecretKey(..)")
266 }
267}
268
269impl FromStr for SecretKey {
270 type Err = KeyParsingError;
271
272 fn from_str(s: &str) -> Result<Self, Self::Err> {
273 let bytes = decode_base32_hex(s)?;
274 Ok(SecretKey::from(bytes))
275 }
276}
277
278impl Serialize for SecretKey {
279 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
280 where
281 S: serde::Serializer,
282 {
283 self.0.serialize(serializer)
284 }
285}
286
287impl<'de> Deserialize<'de> for SecretKey {
288 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
289 where
290 D: serde::Deserializer<'de>,
291 {
292 let secret = SigningKey::deserialize(deserializer)?;
293 Ok(Self(secret))
294 }
295}
296
297impl SecretKey {
298 pub fn public(&self) -> PublicKey {
300 let key = self.0.verifying_key().to_bytes();
301 PublicKey(CompressedEdwardsY(key))
302 }
303
304 pub fn generate() -> Self {
319 Self::from_bytes(&rand::random())
320 }
321
322 pub fn sign(&self, msg: &[u8]) -> Signature {
324 use ed25519_dalek::Signer;
325
326 let sig = self.0.sign(msg);
327 Signature(sig)
328 }
329
330 pub fn to_bytes(&self) -> [u8; 32] {
333 self.0.to_bytes()
334 }
335
336 pub fn from_bytes(bytes: &[u8; 32]) -> Self {
338 let secret = SigningKey::from_bytes(bytes);
339 Self(secret)
340 }
341
342 #[doc(hidden)]
344 pub fn as_signing_key(&self) -> &SigningKey {
345 &self.0
346 }
347}
348
349impl From<[u8; 32]> for SecretKey {
350 fn from(value: [u8; 32]) -> Self {
351 Self::from_bytes(&value)
352 }
353}
354
355impl From<&[u8; 32]> for SecretKey {
356 fn from(value: &[u8; 32]) -> Self {
357 Self::from_bytes(value)
358 }
359}
360
361impl TryFrom<&[u8]> for SecretKey {
362 type Error = KeyParsingError;
363
364 #[inline]
365 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
366 let bytes: [u8; 32] = bytes
367 .try_into()
368 .map_err(|_| e!(KeyParsingError::InvalidLength))?;
369 let secret = SigningKey::from_bytes(&bytes);
370 Ok(Self(secret))
371 }
372}
373
374#[derive(Copy, Clone, Eq, PartialEq)]
376pub struct Signature(ed25519_dalek::Signature);
377
378impl Serialize for Signature {
379 fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
380 use ser::SerializeTuple;
381
382 let mut seq = serializer.serialize_tuple(Signature::LENGTH)?;
383
384 for byte in self.to_bytes() {
385 seq.serialize_element(&byte)?;
386 }
387
388 seq.end()
389 }
390}
391
392impl<'de> Deserialize<'de> for Signature {
395 fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
396 struct ByteArrayVisitor;
397
398 impl<'de> de::Visitor<'de> for ByteArrayVisitor {
399 type Value = [u8; Signature::LENGTH];
400
401 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
402 formatter.write_str("bytestring of length 64")
403 }
404
405 fn visit_seq<A>(self, mut seq: A) -> Result<[u8; Signature::LENGTH], A::Error>
406 where
407 A: de::SeqAccess<'de>,
408 {
409 use de::Error;
410 let mut arr = [0u8; Signature::LENGTH];
411
412 for (i, byte) in arr.iter_mut().enumerate() {
413 *byte = seq
414 .next_element()?
415 .ok_or_else(|| Error::invalid_length(i, &self))?;
416 }
417
418 Ok(arr)
419 }
420 }
421
422 deserializer
423 .deserialize_tuple(Signature::LENGTH, ByteArrayVisitor)
424 .map(|b| Signature::from_bytes(&b))
425 }
426}
427
428impl Debug for Signature {
429 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
430 write!(f, "{:?}", self.0)
431 }
432}
433
434impl Display for Signature {
435 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
436 write!(f, "{}", self.0)
437 }
438}
439
440#[stack_error(derive, add_meta)]
442#[error("Could not parse ed25519 signature")]
443pub struct SignatureParsingError;
444
445impl TryFrom<&[u8]> for Signature {
446 type Error = SignatureParsingError;
447
448 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
449 let signature =
450 ed25519_dalek::Signature::from_slice(bytes).map_err(|_| e!(SignatureParsingError))?;
451 Ok(Self(signature))
452 }
453}
454
455impl Signature {
456 pub const LENGTH: usize = ed25519_dalek::Signature::BYTE_SIZE;
458
459 pub fn to_bytes(&self) -> [u8; Self::LENGTH] {
461 self.0.to_bytes()
462 }
463
464 pub fn from_bytes(bytes: &[u8; Self::LENGTH]) -> Self {
466 Self(ed25519_dalek::Signature::from_bytes(bytes))
467 }
468}
469
470#[stack_error(derive, add_meta)]
472#[error("Invalid signature")]
473pub struct SignatureError {}
474
475fn decode_base32_hex(s: &str) -> Result<[u8; 32], KeyParsingError> {
476 let mut bytes = [0u8; 32];
477
478 let len = if s.len() == PublicKey::LENGTH * 2 {
479 data_encoding::HEXLOWER
481 .decode_mut(s.as_bytes(), &mut bytes)
482 .map_err(|_| e!(KeyParsingError::FailedToDecodeHex))?
483 } else {
484 let input = s.to_ascii_uppercase();
485 let input = input.as_bytes();
486 ensure!(
487 data_encoding::BASE32_NOPAD.decode_len(input.len()) == Ok(bytes.len()),
488 KeyParsingError::InvalidLength
489 );
490 data_encoding::BASE32_NOPAD
491 .decode_mut(input, &mut bytes)
492 .map_err(|_| e!(KeyParsingError::FailedToDecodeBase32))?
493 };
494 ensure!(len == PublicKey::LENGTH, KeyParsingError::InvalidLength);
495 Ok(bytes)
496}
497
498#[cfg(test)]
499mod tests {
500 use data_encoding::HEXLOWER;
501 use rand::{RngExt, SeedableRng};
502
503 use super::*;
504
505 #[test]
506 fn test_public_key_postcard() {
507 let public_key =
508 PublicKey::from_str("ae58ff8833241ac82d6ff7611046ed67b5072d142c588d0063e942d9a75502b6")
509 .unwrap();
510 let bytes = postcard::to_stdvec(&public_key).unwrap();
511 let expected = HEXLOWER
512 .decode(b"ae58ff8833241ac82d6ff7611046ed67b5072d142c588d0063e942d9a75502b6")
513 .unwrap();
514 assert_eq!(bytes, expected);
515 }
516
517 #[test]
518 fn public_key_postcard() {
519 let key = PublicKey::from_bytes(&[0; 32]).unwrap();
520 let bytes = postcard::to_stdvec(&key).unwrap();
521 let key2: PublicKey = postcard::from_bytes(&bytes).unwrap();
522 assert_eq!(key, key2);
523 }
524
525 #[test]
526 fn public_key_json() {
527 let key = PublicKey::from_bytes(&[0; 32]).unwrap();
528 let bytes = serde_json::to_string(&key).unwrap();
529 let key2: PublicKey = serde_json::from_str(&bytes).unwrap();
530 assert_eq!(key, key2);
531 }
532
533 #[test]
534 fn test_from_str() {
535 let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0u64);
536 let key = SecretKey::from_bytes(&rng.random());
537 assert_eq!(
538 SecretKey::from_str(&HEXLOWER.encode(&key.to_bytes()))
539 .unwrap()
540 .to_bytes(),
541 key.to_bytes()
542 );
543
544 assert_eq!(
545 PublicKey::from_str(&key.public().to_string()).unwrap(),
546 key.public()
547 );
548 }
549
550 #[test]
551 fn test_regression_parse_endpoint_id_panic() {
552 let not_a_endpoint_id = "foobarbaz";
553 assert!(PublicKey::from_str(not_a_endpoint_id).is_err());
554 }
555
556 #[test]
557 fn signature_postcard() {
558 let key = SecretKey::generate();
559 let signature = key.sign(b"hello world");
560 let bytes = postcard::to_stdvec(&signature).unwrap();
561 let signature2: Signature = postcard::from_bytes(&bytes).unwrap();
562 assert_eq!(signature, signature2);
563 }
564}