1use alloc::{
4 format,
5 string::{String, ToString},
6 vec::Vec,
7};
8use core::{
9 cmp::Ordering,
10 convert::TryFrom,
11 fmt::{self, Debug, Display, Formatter},
12 hash::{Hash, Hasher},
13 iter,
14 marker::Copy,
15};
16#[cfg(any(feature = "std", test))]
17use std::path::Path;
18
19#[cfg(feature = "datasize")]
20use datasize::DataSize;
21#[cfg(any(feature = "std", test))]
22use derp::{Der, Tag};
23use ed25519_dalek::{
24 Signature as Ed25519Signature, SigningKey as Ed25519SecretKey,
25 VerifyingKey as Ed25519PublicKey, PUBLIC_KEY_LENGTH as ED25519_PUBLIC_KEY_LENGTH,
26 SECRET_KEY_LENGTH as ED25519_SECRET_KEY_LENGTH, SIGNATURE_LENGTH as ED25519_SIGNATURE_LENGTH,
27};
28use hex_fmt::HexFmt;
29use k256::ecdsa::{
30 signature::{Signer, Verifier},
31 Signature as Secp256k1Signature, SigningKey as Secp256k1SecretKey,
32 VerifyingKey as Secp256k1PublicKey,
33};
34#[cfg(any(feature = "std", test))]
35use once_cell::sync::Lazy;
36#[cfg(any(feature = "std", test))]
37use pem::Pem;
38#[cfg(any(all(feature = "std", feature = "testing"), test))]
39use rand::{Rng, RngCore};
40#[cfg(feature = "json-schema")]
41use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema};
42use serde::{Deserialize, Deserializer, Serialize, Serializer};
43#[cfg(feature = "json-schema")]
44use serde_json::json;
45#[cfg(any(feature = "std", test))]
46use untrusted::Input;
47
48#[cfg(any(all(feature = "std", feature = "testing"), test))]
49use crate::testing::TestRng;
50use crate::{
51 account::AccountHash,
52 bytesrepr,
53 bytesrepr::{FromBytes, ToBytes, U8_SERIALIZED_LENGTH},
54 checksummed_hex,
55 crypto::Error,
56 CLType, CLTyped, Tagged,
57};
58#[cfg(any(feature = "std", test))]
59use crate::{
60 crypto::ErrorExt,
61 file_utils::{read_file, write_file, write_private_file},
62};
63
64#[cfg(any(feature = "testing", test))]
65pub mod gens;
66#[cfg(test)]
67mod tests;
68
69const TAG_LENGTH: usize = U8_SERIALIZED_LENGTH;
70
71pub const SYSTEM_TAG: u8 = 0;
73const SYSTEM: &str = "System";
74
75pub const ED25519_TAG: u8 = 1;
77const ED25519: &str = "Ed25519";
78
79pub const SECP256K1_TAG: u8 = 2;
81const SECP256K1: &str = "Secp256k1";
82
83const SECP256K1_SECRET_KEY_LENGTH: usize = 32;
84const SECP256K1_COMPRESSED_PUBLIC_KEY_LENGTH: usize = 33;
85const SECP256K1_SIGNATURE_LENGTH: usize = 64;
86
87pub const SYSTEM_ACCOUNT: PublicKey = PublicKey::System;
89
90#[cfg(any(feature = "std", test))]
92const EC_PUBLIC_KEY_OBJECT_IDENTIFIER: [u8; 7] = [42, 134, 72, 206, 61, 2, 1];
93
94#[cfg(any(feature = "std", test))]
96const ED25519_OBJECT_IDENTIFIER: [u8; 3] = [43, 101, 112];
97#[cfg(any(feature = "std", test))]
98const ED25519_PEM_SECRET_KEY_TAG: &str = "PRIVATE KEY";
99#[cfg(any(feature = "std", test))]
100const ED25519_PEM_PUBLIC_KEY_TAG: &str = "PUBLIC KEY";
101
102#[cfg(any(feature = "std", test))]
104const SECP256K1_OBJECT_IDENTIFIER: [u8; 5] = [43, 129, 4, 0, 10];
105#[cfg(any(feature = "std", test))]
106const SECP256K1_PEM_SECRET_KEY_TAG: &str = "EC PRIVATE KEY";
107#[cfg(any(feature = "std", test))]
108const SECP256K1_PEM_PUBLIC_KEY_TAG: &str = "PUBLIC KEY";
109
110#[cfg(any(feature = "std", test))]
111static ED25519_SECRET_KEY: Lazy<SecretKey> = Lazy::new(|| {
112 let bytes = [15u8; SecretKey::ED25519_LENGTH];
113 SecretKey::ed25519_from_bytes(bytes).unwrap()
114});
115
116#[cfg(any(feature = "std", test))]
117static ED25519_PUBLIC_KEY: Lazy<PublicKey> = Lazy::new(|| {
118 let bytes = [15u8; SecretKey::ED25519_LENGTH];
119 let secret_key = SecretKey::ed25519_from_bytes(bytes).unwrap();
120 PublicKey::from(&secret_key)
121});
122
123pub trait AsymmetricType<'a>
125where
126 Self: 'a + Sized + Tagged<u8>,
127 Vec<u8>: From<&'a Self>,
128{
129 fn to_hex(&'a self) -> String {
131 let bytes = iter::once(self.tag())
132 .chain(Vec::<u8>::from(self))
133 .collect::<Vec<u8>>();
134 base16::encode_lower(&bytes)
135 }
136
137 fn from_hex<A: AsRef<[u8]>>(input: A) -> Result<Self, Error> {
140 if input.as_ref().len() < 2 {
141 return Err(Error::AsymmetricKey(
142 "failed to decode from hex: too short".to_string(),
143 ));
144 }
145
146 let (tag_hex, key_hex) = input.as_ref().split_at(2);
147
148 let tag = checksummed_hex::decode(tag_hex)?;
149 let key_bytes = checksummed_hex::decode(key_hex)?;
150
151 match tag[0] {
152 SYSTEM_TAG => {
153 if key_bytes.is_empty() {
154 Ok(Self::system())
155 } else {
156 Err(Error::AsymmetricKey(
157 "failed to decode from hex: invalid system variant".to_string(),
158 ))
159 }
160 }
161 ED25519_TAG => Self::ed25519_from_bytes(&key_bytes),
162 SECP256K1_TAG => Self::secp256k1_from_bytes(&key_bytes),
163 _ => Err(Error::AsymmetricKey(format!(
164 "failed to decode from hex: invalid tag. Expected {}, {} or {}, got {}",
165 SYSTEM_TAG, ED25519_TAG, SECP256K1_TAG, tag[0]
166 ))),
167 }
168 }
169
170 fn system() -> Self;
172
173 fn ed25519_from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, Error>;
175
176 fn secp256k1_from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, Error>;
178}
179
180#[cfg_attr(feature = "datasize", derive(DataSize))]
182#[non_exhaustive]
183pub enum SecretKey {
184 System,
186 #[cfg_attr(feature = "datasize", data_size(skip))]
188 Ed25519(Ed25519SecretKey),
190 #[cfg_attr(feature = "datasize", data_size(skip))]
192 Secp256k1(Secp256k1SecretKey),
193}
194
195impl SecretKey {
196 pub const SYSTEM_LENGTH: usize = 0;
198
199 pub const ED25519_LENGTH: usize = ED25519_SECRET_KEY_LENGTH;
201
202 pub const SECP256K1_LENGTH: usize = SECP256K1_SECRET_KEY_LENGTH;
204
205 pub fn system() -> Self {
207 SecretKey::System
208 }
209
210 pub fn ed25519_from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, Error> {
212 Ok(SecretKey::Ed25519(Ed25519SecretKey::try_from(
213 bytes.as_ref(),
214 )?))
215 }
216
217 pub fn secp256k1_from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, Error> {
219 Ok(SecretKey::Secp256k1(
220 Secp256k1SecretKey::from_slice(bytes.as_ref()).map_err(|_| Error::SignatureError)?,
221 ))
222 }
223
224 fn variant_name(&self) -> &str {
225 match self {
226 SecretKey::System => SYSTEM,
227 SecretKey::Ed25519(_) => ED25519,
228 SecretKey::Secp256k1(_) => SECP256K1,
229 }
230 }
231}
232
233#[cfg(any(feature = "std", test))]
234impl SecretKey {
235 pub fn generate_ed25519() -> Result<Self, ErrorExt> {
237 let mut bytes = [0u8; Self::ED25519_LENGTH];
238 getrandom::getrandom(&mut bytes[..])?;
239 SecretKey::ed25519_from_bytes(bytes).map_err(Into::into)
240 }
241
242 pub fn generate_secp256k1() -> Result<Self, ErrorExt> {
244 let mut bytes = [0u8; Self::SECP256K1_LENGTH];
245 getrandom::getrandom(&mut bytes[..])?;
246 SecretKey::secp256k1_from_bytes(bytes).map_err(Into::into)
247 }
248
249 pub fn to_file<P: AsRef<Path>>(&self, file: P) -> Result<(), ErrorExt> {
251 write_private_file(file, self.to_pem()?).map_err(ErrorExt::SecretKeySave)
252 }
253
254 pub fn from_file<P: AsRef<Path>>(file: P) -> Result<Self, ErrorExt> {
256 let data = read_file(file).map_err(ErrorExt::SecretKeyLoad)?;
257 Self::from_pem(data)
258 }
259
260 pub fn to_der(&self) -> Result<Vec<u8>, ErrorExt> {
262 match self {
263 SecretKey::System => Err(Error::System(String::from("to_der")).into()),
264 SecretKey::Ed25519(secret_key) => {
265 let mut key_bytes = vec![];
267 let mut der = Der::new(&mut key_bytes);
268 der.octet_string(&secret_key.to_bytes())?;
269
270 let mut encoded = vec![];
271 der = Der::new(&mut encoded);
272 der.sequence(|der| {
273 der.integer(&[0])?;
274 der.sequence(|der| der.oid(&ED25519_OBJECT_IDENTIFIER))?;
275 der.octet_string(&key_bytes)
276 })?;
277 Ok(encoded)
278 }
279 SecretKey::Secp256k1(secret_key) => {
280 let mut oid_bytes = vec![];
282 let mut der = Der::new(&mut oid_bytes);
283 der.oid(&SECP256K1_OBJECT_IDENTIFIER)?;
284
285 let mut encoded = vec![];
286 der = Der::new(&mut encoded);
287 der.sequence(|der| {
288 der.integer(&[1])?;
289 der.octet_string(secret_key.to_bytes().as_slice())?;
290 der.element(Tag::ContextSpecificConstructed0, &oid_bytes)
291 })?;
292 Ok(encoded)
293 }
294 }
295 }
296
297 pub fn from_der<T: AsRef<[u8]>>(input: T) -> Result<Self, ErrorExt> {
299 let input = Input::from(input.as_ref());
300
301 let (key_type_tag, raw_bytes) = input.read_all(derp::Error::Read, |input| {
302 derp::nested(input, Tag::Sequence, |input| {
303 let version_slice =
305 derp::expect_tag_and_get_value(input, Tag::Integer)?.as_slice_less_safe();
306 if version_slice.len() != 1 {
307 return Err(derp::Error::NonZeroUnusedBits);
308 }
309 let version = version_slice[0];
310
311 let (tag, value) = derp::read_tag_and_get_value(input)?;
313 if tag == Tag::Sequence as u8 {
314 if version != 0 {
316 return Err(derp::Error::WrongValue);
317 }
318
319 let object_identifier = value.read_all(derp::Error::Read, |input| {
321 derp::expect_tag_and_get_value(input, Tag::Oid)
322 })?;
323 if object_identifier.as_slice_less_safe() != ED25519_OBJECT_IDENTIFIER {
324 return Err(derp::Error::WrongValue);
325 }
326
327 let raw_bytes = derp::nested(input, Tag::OctetString, |input| {
330 derp::expect_tag_and_get_value(input, Tag::OctetString)
331 })?
332 .as_slice_less_safe();
333
334 return Ok((ED25519_TAG, raw_bytes));
335 } else if tag == Tag::OctetString as u8 {
336 if version != 1 {
338 return Err(derp::Error::WrongValue);
339 }
340
341 let raw_bytes = value.as_slice_less_safe();
343
344 let parameter0 =
346 derp::expect_tag_and_get_value(input, Tag::ContextSpecificConstructed0)?;
347 let object_identifier = parameter0.read_all(derp::Error::Read, |input| {
348 derp::expect_tag_and_get_value(input, Tag::Oid)
349 })?;
350 if object_identifier.as_slice_less_safe() != SECP256K1_OBJECT_IDENTIFIER {
351 return Err(derp::Error::WrongValue);
352 }
353
354 let _ = derp::read_tag_and_get_value(input);
358
359 return Ok((SECP256K1_TAG, raw_bytes));
360 }
361
362 Err(derp::Error::WrongValue)
363 })
364 })?;
365
366 match key_type_tag {
367 SYSTEM_TAG => Err(Error::AsymmetricKey("cannot construct variant".to_string()).into()),
368 ED25519_TAG => SecretKey::ed25519_from_bytes(raw_bytes).map_err(Into::into),
369 SECP256K1_TAG => SecretKey::secp256k1_from_bytes(raw_bytes).map_err(Into::into),
370 _ => Err(Error::AsymmetricKey("unknown type tag".to_string()).into()),
371 }
372 }
373
374 pub fn to_pem(&self) -> Result<String, ErrorExt> {
376 let tag = match self {
377 SecretKey::System => return Err(Error::System(String::from("to_pem")).into()),
378 SecretKey::Ed25519(_) => ED25519_PEM_SECRET_KEY_TAG.to_string(),
379 SecretKey::Secp256k1(_) => SECP256K1_PEM_SECRET_KEY_TAG.to_string(),
380 };
381 let contents = self.to_der()?;
382 let pem = Pem { tag, contents };
383 Ok(pem::encode(&pem))
384 }
385
386 pub fn from_pem<T: AsRef<[u8]>>(input: T) -> Result<Self, ErrorExt> {
388 let pem = pem::parse(input)?;
389
390 let secret_key = Self::from_der(&pem.contents)?;
391
392 let bad_tag = |expected_tag: &str| {
393 ErrorExt::FromPem(format!(
394 "invalid tag: expected {}, got {}",
395 expected_tag, pem.tag
396 ))
397 };
398
399 match secret_key {
400 SecretKey::System => return Err(Error::System(String::from("from_pem")).into()),
401 SecretKey::Ed25519(_) => {
402 if pem.tag != ED25519_PEM_SECRET_KEY_TAG {
403 return Err(bad_tag(ED25519_PEM_SECRET_KEY_TAG));
404 }
405 }
406 SecretKey::Secp256k1(_) => {
407 if pem.tag != SECP256K1_PEM_SECRET_KEY_TAG {
408 return Err(bad_tag(SECP256K1_PEM_SECRET_KEY_TAG));
409 }
410 }
411 }
412
413 Ok(secret_key)
414 }
415
416 #[cfg(any(feature = "testing", test))]
418 pub fn random(rng: &mut TestRng) -> Self {
419 if rng.gen() {
420 Self::random_ed25519(rng)
421 } else {
422 Self::random_secp256k1(rng)
423 }
424 }
425
426 #[cfg(any(feature = "testing", test))]
428 pub fn random_ed25519(rng: &mut TestRng) -> Self {
429 let mut bytes = [0u8; Self::ED25519_LENGTH];
430 rng.fill_bytes(&mut bytes[..]);
431 SecretKey::ed25519_from_bytes(bytes).unwrap()
432 }
433
434 #[cfg(any(feature = "testing", test))]
436 pub fn random_secp256k1(rng: &mut TestRng) -> Self {
437 let mut bytes = [0u8; Self::SECP256K1_LENGTH];
438 rng.fill_bytes(&mut bytes[..]);
439 SecretKey::secp256k1_from_bytes(bytes).unwrap()
440 }
441
442 pub fn doc_example() -> &'static Self {
444 &ED25519_SECRET_KEY
445 }
446}
447
448impl Debug for SecretKey {
449 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
450 write!(formatter, "SecretKey::{}", self.variant_name())
451 }
452}
453
454impl Display for SecretKey {
455 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
456 <Self as Debug>::fmt(self, formatter)
457 }
458}
459
460impl Tagged<u8> for SecretKey {
461 fn tag(&self) -> u8 {
462 match self {
463 SecretKey::System => SYSTEM_TAG,
464 SecretKey::Ed25519(_) => ED25519_TAG,
465 SecretKey::Secp256k1(_) => SECP256K1_TAG,
466 }
467 }
468}
469
470#[derive(Clone, Eq, PartialEq)]
472#[cfg_attr(feature = "datasize", derive(DataSize))]
473#[non_exhaustive]
474pub enum PublicKey {
475 System,
477 #[cfg_attr(feature = "datasize", data_size(skip))]
479 Ed25519(Ed25519PublicKey),
480 #[cfg_attr(feature = "datasize", data_size(skip))]
482 Secp256k1(Secp256k1PublicKey),
483}
484
485impl PublicKey {
486 pub const SYSTEM_LENGTH: usize = 0;
488
489 pub const ED25519_LENGTH: usize = ED25519_PUBLIC_KEY_LENGTH;
491
492 pub const SECP256K1_LENGTH: usize = SECP256K1_COMPRESSED_PUBLIC_KEY_LENGTH;
494
495 pub fn to_account_hash(&self) -> AccountHash {
497 AccountHash::from(self)
498 }
499
500 pub fn is_system(&self) -> bool {
502 matches!(self, PublicKey::System)
503 }
504
505 fn variant_name(&self) -> &str {
506 match self {
507 PublicKey::System => SYSTEM,
508 PublicKey::Ed25519(_) => ED25519,
509 PublicKey::Secp256k1(_) => SECP256K1,
510 }
511 }
512}
513
514#[cfg(any(feature = "std", test))]
515impl PublicKey {
516 pub fn generate_ed25519() -> Result<Self, ErrorExt> {
518 let mut bytes = [0u8; Self::ED25519_LENGTH];
519 getrandom::getrandom(&mut bytes[..]).expect("RNG failure!");
520 PublicKey::ed25519_from_bytes(bytes).map_err(Into::into)
521 }
522
523 pub fn generate_secp256k1() -> Result<Self, ErrorExt> {
525 let mut bytes = [0u8; Self::SECP256K1_LENGTH];
526 getrandom::getrandom(&mut bytes[..]).expect("RNG failure!");
527 PublicKey::secp256k1_from_bytes(bytes).map_err(Into::into)
528 }
529
530 pub fn to_file<P: AsRef<Path>>(&self, file: P) -> Result<(), ErrorExt> {
532 write_file(file, self.to_pem()?).map_err(ErrorExt::PublicKeySave)
533 }
534
535 pub fn from_file<P: AsRef<Path>>(file: P) -> Result<Self, ErrorExt> {
537 let data = read_file(file).map_err(ErrorExt::PublicKeyLoad)?;
538 Self::from_pem(data)
539 }
540
541 pub fn to_der(&self) -> Result<Vec<u8>, ErrorExt> {
543 match self {
544 PublicKey::System => Err(Error::System(String::from("to_der")).into()),
545 PublicKey::Ed25519(public_key) => {
546 let mut encoded = vec![];
548 let mut der = Der::new(&mut encoded);
549 der.sequence(|der| {
550 der.sequence(|der| der.oid(&ED25519_OBJECT_IDENTIFIER))?;
551 der.bit_string(0, public_key.as_ref())
552 })?;
553 Ok(encoded)
554 }
555 PublicKey::Secp256k1(public_key) => {
556 let mut encoded = vec![];
558 let mut der = Der::new(&mut encoded);
559 der.sequence(|der| {
560 der.sequence(|der| {
561 der.oid(&EC_PUBLIC_KEY_OBJECT_IDENTIFIER)?;
562 der.oid(&SECP256K1_OBJECT_IDENTIFIER)
563 })?;
564 der.bit_string(0, public_key.to_encoded_point(true).as_ref())
565 })?;
566 Ok(encoded)
567 }
568 }
569 }
570
571 pub fn from_der<T: AsRef<[u8]>>(input: T) -> Result<Self, ErrorExt> {
573 let input = Input::from(input.as_ref());
574
575 let mut key_type_tag = ED25519_TAG;
576 let raw_bytes = input.read_all(derp::Error::Read, |input| {
577 derp::nested(input, Tag::Sequence, |input| {
578 derp::nested(input, Tag::Sequence, |input| {
579 let object_identifier =
581 derp::expect_tag_and_get_value(input, Tag::Oid)?.as_slice_less_safe();
582 if object_identifier == ED25519_OBJECT_IDENTIFIER {
583 key_type_tag = ED25519_TAG;
584 Ok(())
585 } else if object_identifier == EC_PUBLIC_KEY_OBJECT_IDENTIFIER {
586 let next_object_identifier =
588 derp::expect_tag_and_get_value(input, Tag::Oid)?.as_slice_less_safe();
589 if next_object_identifier != SECP256K1_OBJECT_IDENTIFIER {
590 return Err(derp::Error::WrongValue);
591 }
592
593 key_type_tag = SECP256K1_TAG;
594 Ok(())
595 } else {
596 Err(derp::Error::WrongValue)
597 }
598 })?;
599 Ok(derp::bit_string_with_no_unused_bits(input)?.as_slice_less_safe())
600 })
601 })?;
602
603 match key_type_tag {
604 ED25519_TAG => PublicKey::ed25519_from_bytes(raw_bytes).map_err(Into::into),
605 SECP256K1_TAG => PublicKey::secp256k1_from_bytes(raw_bytes).map_err(Into::into),
606 _ => unreachable!(),
607 }
608 }
609
610 pub fn to_pem(&self) -> Result<String, ErrorExt> {
612 let tag = match self {
613 PublicKey::System => return Err(Error::System(String::from("to_pem")).into()),
614 PublicKey::Ed25519(_) => ED25519_PEM_PUBLIC_KEY_TAG.to_string(),
615 PublicKey::Secp256k1(_) => SECP256K1_PEM_PUBLIC_KEY_TAG.to_string(),
616 };
617 let contents = self.to_der()?;
618 let pem = Pem { tag, contents };
619 Ok(pem::encode(&pem))
620 }
621
622 pub fn from_pem<T: AsRef<[u8]>>(input: T) -> Result<Self, ErrorExt> {
624 let pem = pem::parse(input)?;
625 let public_key = Self::from_der(&pem.contents)?;
626 let bad_tag = |expected_tag: &str| {
627 ErrorExt::FromPem(format!(
628 "invalid tag: expected {}, got {}",
629 expected_tag, pem.tag
630 ))
631 };
632 match public_key {
633 PublicKey::System => return Err(Error::System(String::from("from_pem")).into()),
634 PublicKey::Ed25519(_) => {
635 if pem.tag != ED25519_PEM_PUBLIC_KEY_TAG {
636 return Err(bad_tag(ED25519_PEM_PUBLIC_KEY_TAG));
637 }
638 }
639 PublicKey::Secp256k1(_) => {
640 if pem.tag != SECP256K1_PEM_PUBLIC_KEY_TAG {
641 return Err(bad_tag(SECP256K1_PEM_PUBLIC_KEY_TAG));
642 }
643 }
644 }
645 Ok(public_key)
646 }
647
648 #[cfg(any(feature = "testing", test))]
650 pub fn random(rng: &mut TestRng) -> Self {
651 let secret_key = SecretKey::random(rng);
652 PublicKey::from(&secret_key)
653 }
654
655 #[cfg(any(feature = "testing", test))]
657 pub fn random_ed25519(rng: &mut TestRng) -> Self {
658 let secret_key = SecretKey::random_ed25519(rng);
659 PublicKey::from(&secret_key)
660 }
661
662 #[cfg(any(feature = "testing", test))]
664 pub fn random_secp256k1(rng: &mut TestRng) -> Self {
665 let secret_key = SecretKey::random_secp256k1(rng);
666 PublicKey::from(&secret_key)
667 }
668
669 pub fn doc_example() -> &'static Self {
671 &ED25519_PUBLIC_KEY
672 }
673}
674
675impl AsymmetricType<'_> for PublicKey {
676 fn system() -> Self {
677 PublicKey::System
678 }
679
680 fn ed25519_from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, Error> {
681 Ok(PublicKey::Ed25519(Ed25519PublicKey::try_from(
682 bytes.as_ref(),
683 )?))
684 }
685
686 fn secp256k1_from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, Error> {
687 Ok(PublicKey::Secp256k1(
688 Secp256k1PublicKey::from_sec1_bytes(bytes.as_ref())
689 .map_err(|_| Error::SignatureError)?,
690 ))
691 }
692}
693
694impl From<&SecretKey> for PublicKey {
695 fn from(secret_key: &SecretKey) -> PublicKey {
696 match secret_key {
697 SecretKey::System => PublicKey::System,
698 SecretKey::Ed25519(secret_key) => PublicKey::Ed25519(secret_key.into()),
699 SecretKey::Secp256k1(secret_key) => PublicKey::Secp256k1(secret_key.into()),
700 }
701 }
702}
703
704impl From<&PublicKey> for Vec<u8> {
705 fn from(public_key: &PublicKey) -> Self {
706 match public_key {
707 PublicKey::System => Vec::new(),
708 PublicKey::Ed25519(key) => key.to_bytes().into(),
709 PublicKey::Secp256k1(key) => key.to_encoded_point(true).as_ref().into(),
710 }
711 }
712}
713
714impl From<PublicKey> for Vec<u8> {
715 fn from(public_key: PublicKey) -> Self {
716 Vec::<u8>::from(&public_key)
717 }
718}
719
720impl Debug for PublicKey {
721 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
722 write!(
723 formatter,
724 "PublicKey::{}({})",
725 self.variant_name(),
726 base16::encode_lower(&Into::<Vec<u8>>::into(self))
727 )
728 }
729}
730
731impl Display for PublicKey {
732 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
733 write!(
734 formatter,
735 "PubKey::{}({:10})",
736 self.variant_name(),
737 HexFmt(Into::<Vec<u8>>::into(self))
738 )
739 }
740}
741
742impl PartialOrd for PublicKey {
743 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
744 Some(self.cmp(other))
745 }
746}
747
748impl Ord for PublicKey {
749 fn cmp(&self, other: &Self) -> Ordering {
750 let self_tag = self.tag();
751 let other_tag = other.tag();
752 if self_tag == other_tag {
753 Into::<Vec<u8>>::into(self).cmp(&Into::<Vec<u8>>::into(other))
754 } else {
755 self_tag.cmp(&other_tag)
756 }
757 }
758}
759
760#[allow(clippy::derived_hash_with_manual_eq)]
763impl Hash for PublicKey {
764 fn hash<H: Hasher>(&self, state: &mut H) {
765 self.tag().hash(state);
766 Into::<Vec<u8>>::into(self).hash(state);
767 }
768}
769
770impl Tagged<u8> for PublicKey {
771 fn tag(&self) -> u8 {
772 match self {
773 PublicKey::System => SYSTEM_TAG,
774 PublicKey::Ed25519(_) => ED25519_TAG,
775 PublicKey::Secp256k1(_) => SECP256K1_TAG,
776 }
777 }
778}
779
780impl ToBytes for PublicKey {
781 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
782 let mut buffer = bytesrepr::allocate_buffer(self)?;
783 self.write_bytes(&mut buffer)?;
784 Ok(buffer)
785 }
786
787 fn serialized_length(&self) -> usize {
788 TAG_LENGTH
789 + match self {
790 PublicKey::System => Self::SYSTEM_LENGTH,
791 PublicKey::Ed25519(_) => Self::ED25519_LENGTH,
792 PublicKey::Secp256k1(_) => Self::SECP256K1_LENGTH,
793 }
794 }
795
796 fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
797 match self {
798 PublicKey::System => writer.push(SYSTEM_TAG),
799 PublicKey::Ed25519(public_key) => {
800 writer.push(ED25519_TAG);
801 writer.extend_from_slice(public_key.as_bytes());
802 }
803 PublicKey::Secp256k1(public_key) => {
804 writer.push(SECP256K1_TAG);
805 writer.extend_from_slice(public_key.to_encoded_point(true).as_ref());
806 }
807 }
808 Ok(())
809 }
810}
811
812impl FromBytes for PublicKey {
813 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
814 let (tag, remainder) = u8::from_bytes(bytes)?;
815 match tag {
816 SYSTEM_TAG => Ok((PublicKey::System, remainder)),
817 ED25519_TAG => {
818 let (raw_bytes, remainder): ([u8; Self::ED25519_LENGTH], _) =
819 FromBytes::from_bytes(remainder)?;
820 let public_key = Self::ed25519_from_bytes(raw_bytes)
821 .map_err(|_error| bytesrepr::Error::Formatting)?;
822 Ok((public_key, remainder))
823 }
824 SECP256K1_TAG => {
825 let (raw_bytes, remainder): ([u8; Self::SECP256K1_LENGTH], _) =
826 FromBytes::from_bytes(remainder)?;
827 let public_key = Self::secp256k1_from_bytes(raw_bytes)
828 .map_err(|_error| bytesrepr::Error::Formatting)?;
829 Ok((public_key, remainder))
830 }
831 _ => Err(bytesrepr::Error::Formatting),
832 }
833 }
834}
835
836impl Serialize for PublicKey {
837 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
838 detail::serialize(self, serializer)
839 }
840}
841
842impl<'de> Deserialize<'de> for PublicKey {
843 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
844 detail::deserialize(deserializer)
845 }
846}
847
848#[cfg(feature = "json-schema")]
849impl JsonSchema for PublicKey {
850 fn schema_name() -> String {
851 String::from("PublicKey")
852 }
853
854 fn json_schema(gen: &mut SchemaGenerator) -> Schema {
855 let schema = gen.subschema_for::<String>();
856 let mut schema_object = schema.into_object();
857 schema_object.metadata().description = Some(
858 "Hex-encoded cryptographic public key, including the algorithm tag prefix.".to_string(),
859 );
860 schema_object.metadata().examples = vec![
861 json!({
862 "name": "SystemPublicKey",
863 "description": "A pseudo public key, used for example when the system proposes an \
864 immediate switch block after a network upgrade rather than a specific validator. \
865 Its hex-encoded value is always '00', as is the corresponding pseudo signature's",
866 "value": "00"
867 }),
868 json!({
869 "name": "Ed25519PublicKey",
870 "description": "An Ed25519 public key. Its hex-encoded value begins '01' and is \
871 followed by 64 characters",
872 "value": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"
873 }),
874 json!({
875 "name": "Secp256k1PublicKey",
876 "description": "A secp256k1 public key. Its hex-encoded value begins '02' and is \
877 followed by 66 characters",
878 "value": "0203408e9526316fd1f8def480dd45b2cc72ffd732771c9ceb5d92ffa4051e6ee084"
879 }),
880 ];
881 schema_object.into()
882 }
883}
884
885impl CLTyped for PublicKey {
886 fn cl_type() -> CLType {
887 CLType::PublicKey
888 }
889}
890
891#[derive(Clone, Copy)]
893#[cfg_attr(feature = "datasize", derive(DataSize))]
894#[non_exhaustive]
895pub enum Signature {
896 System,
898 #[cfg_attr(feature = "datasize", data_size(skip))]
900 Ed25519(Ed25519Signature),
901 #[cfg_attr(feature = "datasize", data_size(skip))]
903 Secp256k1(Secp256k1Signature),
904}
905
906impl Signature {
907 pub const SYSTEM_LENGTH: usize = 0;
909
910 pub const ED25519_LENGTH: usize = ED25519_SIGNATURE_LENGTH;
912
913 pub const SECP256K1_LENGTH: usize = SECP256K1_SIGNATURE_LENGTH;
915
916 pub fn ed25519(bytes: [u8; Self::ED25519_LENGTH]) -> Result<Self, Error> {
918 let signature = Ed25519Signature::from_bytes(&bytes);
919 Ok(Signature::Ed25519(signature))
920 }
921
922 pub fn secp256k1(bytes: [u8; Self::SECP256K1_LENGTH]) -> Result<Self, Error> {
924 let signature = Secp256k1Signature::try_from(&bytes[..]).map_err(|_| {
925 Error::AsymmetricKey(format!(
926 "failed to construct secp256k1 signature from {:?}",
927 &bytes[..]
928 ))
929 })?;
930
931 Ok(Signature::Secp256k1(signature))
932 }
933
934 fn variant_name(&self) -> &str {
935 match self {
936 Signature::System => SYSTEM,
937 Signature::Ed25519(_) => ED25519,
938 Signature::Secp256k1(_) => SECP256K1,
939 }
940 }
941}
942
943impl AsymmetricType<'_> for Signature {
944 fn system() -> Self {
945 Signature::System
946 }
947
948 fn ed25519_from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, Error> {
949 let signature = Ed25519Signature::try_from(bytes.as_ref()).map_err(|_| {
950 Error::AsymmetricKey(format!(
951 "failed to construct Ed25519 signature from {:?}",
952 bytes.as_ref()
953 ))
954 })?;
955 Ok(Signature::Ed25519(signature))
956 }
957
958 fn secp256k1_from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, Error> {
959 let signature = Secp256k1Signature::try_from(bytes.as_ref()).map_err(|_| {
960 Error::AsymmetricKey(format!(
961 "failed to construct secp256k1 signature from {:?}",
962 bytes.as_ref()
963 ))
964 })?;
965 Ok(Signature::Secp256k1(signature))
966 }
967}
968
969impl Debug for Signature {
970 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
971 write!(
972 formatter,
973 "Signature::{}({})",
974 self.variant_name(),
975 base16::encode_lower(&Into::<Vec<u8>>::into(*self))
976 )
977 }
978}
979
980impl Display for Signature {
981 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
982 write!(
983 formatter,
984 "Sig::{}({:10})",
985 self.variant_name(),
986 HexFmt(Into::<Vec<u8>>::into(*self))
987 )
988 }
989}
990
991impl PartialOrd for Signature {
992 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
993 Some(self.cmp(other))
994 }
995}
996
997impl Ord for Signature {
998 fn cmp(&self, other: &Self) -> Ordering {
999 let self_tag = self.tag();
1000 let other_tag = other.tag();
1001 if self_tag == other_tag {
1002 Into::<Vec<u8>>::into(*self).cmp(&Into::<Vec<u8>>::into(*other))
1003 } else {
1004 self_tag.cmp(&other_tag)
1005 }
1006 }
1007}
1008
1009impl PartialEq for Signature {
1010 fn eq(&self, other: &Self) -> bool {
1011 self.tag() == other.tag() && Into::<Vec<u8>>::into(*self) == Into::<Vec<u8>>::into(*other)
1012 }
1013}
1014
1015impl Eq for Signature {}
1016
1017impl Hash for Signature {
1018 fn hash<H: Hasher>(&self, state: &mut H) {
1019 self.tag().hash(state);
1020 Into::<Vec<u8>>::into(*self).hash(state);
1021 }
1022}
1023
1024impl Tagged<u8> for Signature {
1025 fn tag(&self) -> u8 {
1026 match self {
1027 Signature::System => SYSTEM_TAG,
1028 Signature::Ed25519(_) => ED25519_TAG,
1029 Signature::Secp256k1(_) => SECP256K1_TAG,
1030 }
1031 }
1032}
1033
1034impl ToBytes for Signature {
1035 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
1036 let mut buffer = bytesrepr::allocate_buffer(self)?;
1037 self.write_bytes(&mut buffer)?;
1038 Ok(buffer)
1039 }
1040
1041 fn serialized_length(&self) -> usize {
1042 TAG_LENGTH
1043 + match self {
1044 Signature::System => Self::SYSTEM_LENGTH,
1045 Signature::Ed25519(_) => Self::ED25519_LENGTH,
1046 Signature::Secp256k1(_) => Self::SECP256K1_LENGTH,
1047 }
1048 }
1049
1050 fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
1051 match self {
1052 Signature::System => {
1053 writer.push(SYSTEM_TAG);
1054 }
1055 Signature::Ed25519(signature) => {
1056 writer.push(ED25519_TAG);
1057 writer.extend(signature.to_bytes());
1058 }
1059 Signature::Secp256k1(signature) => {
1060 writer.push(SECP256K1_TAG);
1061 writer.extend_from_slice(&signature.to_bytes());
1062 }
1063 }
1064 Ok(())
1065 }
1066}
1067
1068impl FromBytes for Signature {
1069 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
1070 let (tag, remainder) = u8::from_bytes(bytes)?;
1071 match tag {
1072 SYSTEM_TAG => Ok((Signature::System, remainder)),
1073 ED25519_TAG => {
1074 let (raw_bytes, remainder): ([u8; Self::ED25519_LENGTH], _) =
1075 FromBytes::from_bytes(remainder)?;
1076 let public_key =
1077 Self::ed25519(raw_bytes).map_err(|_error| bytesrepr::Error::Formatting)?;
1078 Ok((public_key, remainder))
1079 }
1080 SECP256K1_TAG => {
1081 let (raw_bytes, remainder): ([u8; Self::SECP256K1_LENGTH], _) =
1082 FromBytes::from_bytes(remainder)?;
1083 let public_key =
1084 Self::secp256k1(raw_bytes).map_err(|_error| bytesrepr::Error::Formatting)?;
1085 Ok((public_key, remainder))
1086 }
1087 _ => Err(bytesrepr::Error::Formatting),
1088 }
1089 }
1090}
1091
1092impl Serialize for Signature {
1093 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1094 detail::serialize(self, serializer)
1095 }
1096}
1097
1098impl<'de> Deserialize<'de> for Signature {
1099 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1100 detail::deserialize(deserializer)
1101 }
1102}
1103
1104impl From<&Signature> for Vec<u8> {
1105 fn from(signature: &Signature) -> Self {
1106 match signature {
1107 Signature::System => Vec::new(),
1108 Signature::Ed25519(signature) => signature.to_bytes().into(),
1109 Signature::Secp256k1(signature) => (*signature.to_bytes()).into(),
1110 }
1111 }
1112}
1113
1114impl From<Signature> for Vec<u8> {
1115 fn from(signature: Signature) -> Self {
1116 Vec::<u8>::from(&signature)
1117 }
1118}
1119
1120#[cfg(feature = "json-schema")]
1121impl JsonSchema for Signature {
1122 fn schema_name() -> String {
1123 String::from("Signature")
1124 }
1125
1126 fn json_schema(gen: &mut SchemaGenerator) -> Schema {
1127 let schema = gen.subschema_for::<String>();
1128 let mut schema_object = schema.into_object();
1129 schema_object.metadata().description = Some(
1130 "Hex-encoded cryptographic signature, including the algorithm tag prefix.".to_string(),
1131 );
1132 schema_object.into()
1133 }
1134}
1135
1136pub fn sign<T: AsRef<[u8]>>(
1138 message: T,
1139 secret_key: &SecretKey,
1140 public_key: &PublicKey,
1141) -> Signature {
1142 match (secret_key, public_key) {
1143 (SecretKey::System, PublicKey::System) => {
1144 panic!("cannot create signature with system keys",)
1145 }
1146 (SecretKey::Ed25519(secret_key), PublicKey::Ed25519(_public_key)) => {
1147 let signature = secret_key.sign(message.as_ref());
1148 Signature::Ed25519(signature)
1149 }
1150 (SecretKey::Secp256k1(secret_key), PublicKey::Secp256k1(_public_key)) => {
1151 let signer = secret_key;
1152 let signature: Secp256k1Signature = signer
1153 .try_sign(message.as_ref())
1154 .expect("should create signature");
1155 Signature::Secp256k1(signature)
1156 }
1157 _ => panic!("secret and public key types must match"),
1158 }
1159}
1160
1161pub fn verify<T: AsRef<[u8]>>(
1163 message: T,
1164 signature: &Signature,
1165 public_key: &PublicKey,
1166) -> Result<(), Error> {
1167 match (signature, public_key) {
1168 (Signature::System, _) => Err(Error::AsymmetricKey(String::from(
1169 "signatures based on the system key cannot be verified",
1170 ))),
1171 (Signature::Ed25519(signature), PublicKey::Ed25519(public_key)) => public_key
1172 .verify_strict(message.as_ref(), signature)
1173 .map_err(|_| Error::AsymmetricKey(String::from("failed to verify Ed25519 signature"))),
1174 (Signature::Secp256k1(signature), PublicKey::Secp256k1(public_key)) => {
1175 let verifier: &Secp256k1PublicKey = public_key;
1176 verifier
1177 .verify(message.as_ref(), signature)
1178 .map_err(|error| {
1179 Error::AsymmetricKey(format!("failed to verify secp256k1 signature: {}", error))
1180 })
1181 }
1182 _ => Err(Error::AsymmetricKey(format!(
1183 "type mismatch between {} and {}",
1184 signature, public_key
1185 ))),
1186 }
1187}
1188
1189#[cfg(any(feature = "std", test))]
1192pub fn generate_ed25519_keypair() -> (SecretKey, PublicKey) {
1193 let secret_key = SecretKey::generate_ed25519().unwrap();
1194 let public_key = PublicKey::from(&secret_key);
1195 (secret_key, public_key)
1196}
1197
1198mod detail {
1199 use alloc::{string::String, vec::Vec};
1200
1201 use serde::{de::Error as _deError, Deserialize, Deserializer, Serialize, Serializer};
1202
1203 use super::{PublicKey, Signature};
1204 use crate::AsymmetricType;
1205
1206 #[derive(Serialize, Deserialize)]
1211 pub(super) enum AsymmetricTypeAsBytes {
1212 System,
1213 Ed25519(Vec<u8>),
1214 Secp256k1(Vec<u8>),
1215 }
1216
1217 impl From<&PublicKey> for AsymmetricTypeAsBytes {
1218 fn from(public_key: &PublicKey) -> Self {
1219 match public_key {
1220 PublicKey::System => AsymmetricTypeAsBytes::System,
1221 key @ PublicKey::Ed25519(_) => AsymmetricTypeAsBytes::Ed25519(key.into()),
1222 key @ PublicKey::Secp256k1(_) => AsymmetricTypeAsBytes::Secp256k1(key.into()),
1223 }
1224 }
1225 }
1226
1227 impl From<&Signature> for AsymmetricTypeAsBytes {
1228 fn from(signature: &Signature) -> Self {
1229 match signature {
1230 Signature::System => AsymmetricTypeAsBytes::System,
1231 key @ Signature::Ed25519(_) => AsymmetricTypeAsBytes::Ed25519(key.into()),
1232 key @ Signature::Secp256k1(_) => AsymmetricTypeAsBytes::Secp256k1(key.into()),
1233 }
1234 }
1235 }
1236
1237 pub(super) fn serialize<'a, T, S>(value: &'a T, serializer: S) -> Result<S::Ok, S::Error>
1238 where
1239 T: AsymmetricType<'a>,
1240 Vec<u8>: From<&'a T>,
1241 S: Serializer,
1242 AsymmetricTypeAsBytes: From<&'a T>,
1243 {
1244 if serializer.is_human_readable() {
1245 return value.to_hex().serialize(serializer);
1246 }
1247
1248 AsymmetricTypeAsBytes::from(value).serialize(serializer)
1249 }
1250
1251 pub(super) fn deserialize<'a, 'de, T, D>(deserializer: D) -> Result<T, D::Error>
1252 where
1253 T: AsymmetricType<'a>,
1254 Vec<u8>: From<&'a T>,
1255 D: Deserializer<'de>,
1256 {
1257 if deserializer.is_human_readable() {
1258 let hex_string = String::deserialize(deserializer)?;
1259 let value = T::from_hex(hex_string.as_bytes()).map_err(D::Error::custom)?;
1260 return Ok(value);
1261 }
1262
1263 let as_bytes = AsymmetricTypeAsBytes::deserialize(deserializer)?;
1264 match as_bytes {
1265 AsymmetricTypeAsBytes::System => Ok(T::system()),
1266 AsymmetricTypeAsBytes::Ed25519(raw_bytes) => {
1267 T::ed25519_from_bytes(raw_bytes).map_err(D::Error::custom)
1268 }
1269 AsymmetricTypeAsBytes::Secp256k1(raw_bytes) => {
1270 T::secp256k1_from_bytes(raw_bytes).map_err(D::Error::custom)
1271 }
1272 }
1273 }
1274}