1use core::fmt;
56use std::{
57 cmp::Ordering,
58 fmt::Debug,
59 hash::{Hash, Hasher},
60};
61
62use crate::{
64 codec::{Decoder, Encoder, NeoSerializable},
65 config::NeoConstants,
66 crypto::CryptoError,
67 neo_crypto::utils::{FromHexString, ToHexString},
68};
69use elliptic_curve::zeroize::Zeroize;
70use p256::{
71 ecdsa::{signature::Signer, Signature, SigningKey, VerifyingKey},
72 elliptic_curve::{
73 sec1::{FromEncodedPoint, ToEncodedPoint},
74 Field,
75 },
76 EncodedPoint, FieldBytes, PublicKey, SecretKey,
77};
78use primitive_types::U256;
79use rand_core::OsRng;
80use serde::{Deserialize, Deserializer, Serialize, Serializer};
81use signature::{hazmat::PrehashSigner, SignerMut, Verifier};
82
83#[cfg_attr(feature = "substrate", serde(crate = "serde_substrate"))]
84#[derive(Debug, Clone)]
85pub struct Secp256r1PublicKey {
86 inner: PublicKey,
87}
88
89#[derive(Debug, Clone)]
90pub struct Secp256r1PrivateKey {
91 inner: SecretKey,
92}
93
94#[derive(Clone)]
95pub struct Secp256r1Signature {
96 inner: Signature,
97}
98
99impl Debug for Secp256r1Signature {
100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101 write!(f, "Secp256r1Signature")
102 }
103}
104
105#[derive(Debug, PartialEq, Clone)]
106pub struct Secp256r1SignedMsg<T: Serialize> {
107 pub msg: T,
108 pub signature: Secp256r1Signature,
109}
110
111impl Secp256r1PublicKey {
112 pub fn new(gx: [u8; 32], gy: [u8; 32]) -> Option<Self> {
123 let mut uncompressed_point = Vec::with_capacity(65);
124 uncompressed_point.push(0x04);
125 uncompressed_point.extend_from_slice(&gx);
126 uncompressed_point.extend_from_slice(&gy);
127
128 let encoded_point = EncodedPoint::from_bytes(&uncompressed_point).ok()?;
129 let public_key_option = PublicKey::from_encoded_point(&encoded_point);
130
131 if public_key_option.is_some().into() {
132 let public_key = public_key_option.unwrap();
134 Some(Secp256r1PublicKey { inner: public_key })
135 } else {
136 None
137 }
138 }
139
140 pub fn from_public_key(public_key: PublicKey) -> Self {
148 Secp256r1PublicKey { inner: public_key }
149 }
150
151 pub fn from_bytes(bytes: &[u8]) -> Result<Self, CryptoError> {
160 if bytes.len() != 33 && bytes.len() != 65 {
161 return Err(CryptoError::InvalidPublicKey);
162 }
163
164 let point = if bytes.len() == 33 {
165 EncodedPoint::from_bytes(bytes).map_err(|_| CryptoError::InvalidPublicKey)?
167 } else {
168 EncodedPoint::from_bytes(bytes).map_err(|_| CryptoError::InvalidPublicKey)?
170 };
171
172 let public_key = PublicKey::from_encoded_point(&point);
173 if public_key.is_some().into() {
174 Ok(Self { inner: public_key.unwrap() })
175 } else {
176 Err(CryptoError::InvalidPublicKey)
177 }
178 }
179
180 pub fn verify(
191 &self,
192 message: &[u8],
193 signature: &Secp256r1Signature,
194 ) -> Result<(), CryptoError> {
195 let verifying_key = VerifyingKey::from(&self.inner);
196
197 verifying_key
198 .verify(message, &signature.inner)
199 .map_err(|_| CryptoError::SignatureVerificationError)
200 }
201
202 pub fn get_encoded(&self, compressed: bool) -> Vec<u8> {
208 self.inner.to_encoded_point(compressed).as_bytes().to_vec()
209 }
210
211 pub fn get_encoded_point(&self, compressed: bool) -> EncodedPoint {
212 self.inner.to_encoded_point(compressed)
213 }
214
215 pub fn get_encoded_compressed_hex(&self) -> String {
220 let encoded = self.get_encoded(true);
221 encoded.to_hex_string()
222 }
223
224 pub fn from_encoded(encoded: &str) -> Option<Self> {
233 let encoded = &encoded.replace("0x", "");
234 let encoded = encoded.from_hex_string().ok()?;
235
236 Secp256r1PublicKey::from_bytes(encoded.as_slice()).ok()
237 }
238
239 fn get_size(&self) -> usize {
240 if self.inner.to_encoded_point(false).is_identity() {
241 1
242 } else {
243 NeoConstants::PUBLIC_KEY_SIZE_COMPRESSED as usize
244 }
245 }
246}
247
248impl Secp256r1PrivateKey {
249 pub fn new_random() -> Self {
255 let mut rng = OsRng;
256 Self::random(&mut rng)
257 }
258
259 pub fn random(rng: &mut OsRng) -> Self {
265 Self { inner: SecretKey::random(rng) }
266 }
267
268 pub fn from_bytes(bytes: &[u8]) -> Result<Self, CryptoError> {
277 if bytes.len() != 32 {
278 return Err(CryptoError::InvalidPrivateKey);
279 }
280 SecretKey::from_slice(bytes)
281 .map(|inner| Self { inner })
282 .map_err(|_| CryptoError::InvalidPrivateKey)
283 }
284
285 pub fn to_raw_bytes(&self) -> [u8; 32] {
289 self.inner
290 .clone()
291 .to_bytes()
292 .as_slice()
293 .try_into()
294 .expect("Private key should always be 32 bytes")
295 }
296
297 pub fn to_public_key(&self) -> Secp256r1PublicKey {
301 Secp256r1PublicKey::from_public_key(self.inner.public_key())
302 }
303
304 pub fn erase(&mut self) {
305 let bytes = [1u8; 32];
308 self.inner = SecretKey::from_bytes(&bytes.into())
310 .expect("Creating SecretKey from fixed bytes should never fail");
311 }
312
313 pub fn sign_tx(&self, message: &[u8]) -> Result<Secp256r1Signature, CryptoError> {
322 let signing_key = SigningKey::from_slice(&self.inner.to_bytes().as_slice())
323 .map_err(|_| CryptoError::InvalidPrivateKey)?;
324 let (signature, _) =
325 signing_key.try_sign(message).map_err(|_| CryptoError::SigningError)?;
326
327 Ok(Secp256r1Signature { inner: signature })
328 }
329
330 pub fn sign_prehash(&self, message: &[u8]) -> Result<Secp256r1Signature, CryptoError> {
338 let signing_key = SigningKey::from_slice(&self.inner.to_bytes().as_slice())
339 .map_err(|_| CryptoError::InvalidPrivateKey)?;
340 let (signature, _) =
341 signing_key.sign_prehash(message).map_err(|_| CryptoError::SigningError)?;
342
343 Ok(Secp256r1Signature { inner: signature })
344 }
345}
346
347impl Secp256r1Signature {
348 pub fn from_scalars(r: &[u8; 32], s: &[u8; 32]) -> Result<Self, CryptoError> {
360 let r_field: FieldBytes = (*r).into();
361 let s_field: FieldBytes = (*s).into();
362
363 let signature = Signature::from_scalars(r_field, s_field)
364 .map_err(|_| CryptoError::SignatureVerificationError)?;
365
366 Ok(Self { inner: signature })
367 }
368
369 pub fn from_u256(r: U256, s: U256) -> Result<Self, CryptoError> {
380 let x = r.to_big_endian();
381 let y = s.to_big_endian();
382 Secp256r1Signature::from_scalars(&x, &y)
383 }
384
385 pub fn from_bytes(bytes: &[u8]) -> Result<Self, CryptoError> {
396 if bytes.len() != 64 {
397 return Err(CryptoError::InvalidFormat("Invalid signature length".to_string()));
398 }
399
400 Signature::from_slice(bytes)
401 .map(|inner| Secp256r1Signature { inner })
402 .map_err(|_| CryptoError::InvalidFormat("Invalid signature format".to_string()))
403 }
404
405 pub fn to_bytes(&self) -> [u8; 64] {
412 let r_bytes: FieldBytes = self.inner.r().into();
413 let s_bytes: FieldBytes = self.inner.s().into();
414
415 let mut bytes = [0u8; 64];
416 bytes[..32].copy_from_slice(r_bytes.as_ref());
417 bytes[32..].copy_from_slice(s_bytes.as_ref());
418
419 bytes
420 }
421}
422
423impl fmt::Display for Secp256r1PrivateKey {
424 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
425 write!(f, "Secp256r1PrivateKey: {}\n", hex::encode(self.inner.to_bytes().as_slice()))
426 }
427}
428
429impl fmt::Display for Secp256r1PublicKey {
430 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
431 write!(
432 f,
433 "Secp256r1PublicKey: {}\n",
434 hex::encode(self.inner.to_encoded_point(false).as_bytes())
435 )
436 }
437}
438
439impl fmt::Display for Secp256r1Signature {
440 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
441 write!(f, "Secp256r1Signature\n")?;
442 write!(f, "x: {}\n", hex::encode(&self.to_bytes()))
443 }
444}
445
446impl Serialize for Secp256r1PublicKey {
447 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
448 where
449 S: Serializer,
450 {
451 serializer.serialize_bytes(&self.get_encoded(true))
452 }
453}
454
455impl Serialize for Secp256r1PrivateKey {
456 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
457 where
458 S: Serializer,
459 {
460 serializer.serialize_bytes(&self.to_raw_bytes())
461 }
462}
463
464impl Serialize for Secp256r1Signature {
465 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
466 where
467 S: Serializer,
468 {
469 serializer.serialize_bytes(&self.to_bytes())
470 }
471}
472
473impl<'de> Deserialize<'de> for Secp256r1PublicKey {
474 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
475 where
476 D: Deserializer<'de>,
477 {
478 let bytes = <Vec<u8>>::deserialize(deserializer)?;
479 Secp256r1PublicKey::from_bytes(&bytes)
480 .map_err(|_| serde::de::Error::custom("Invalid public key"))
481 }
482}
483
484impl<'de> Deserialize<'de> for Secp256r1PrivateKey {
485 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
486 where
487 D: Deserializer<'de>,
488 {
489 let bytes = <Vec<u8>>::deserialize(deserializer)?;
490 Secp256r1PrivateKey::from_bytes(&bytes)
491 .map_err(|_| serde::de::Error::custom("Invalid private key"))
492 }
493}
494
495impl<'de> Deserialize<'de> for Secp256r1Signature {
496 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
497 where
498 D: Deserializer<'de>,
499 {
500 let bytes = <Vec<u8>>::deserialize(deserializer)?;
501 Secp256r1Signature::from_bytes(&bytes)
502 .map_err(|_| serde::de::Error::custom("Invalid signature"))
503 }
504}
505
506impl PartialEq for Secp256r1PublicKey {
507 fn eq(&self, other: &Secp256r1PublicKey) -> bool {
508 self.get_encoded(true) == other.get_encoded(true)
509 }
510}
511
512impl PartialOrd for Secp256r1PublicKey {
513 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
514 let self_bytes = self.get_encoded(true);
515 let other_bytes = other.get_encoded(true);
516 self_bytes.partial_cmp(&other_bytes)
517 }
518}
519
520impl Eq for Secp256r1PublicKey {}
521
522impl Ord for Secp256r1PublicKey {
523 fn cmp(&self, other: &Self) -> Ordering {
524 let self_bytes = self.get_encoded(true);
525 let other_bytes = other.get_encoded(true);
526 self_bytes.cmp(&other_bytes)
527 }
528}
529
530impl Hash for Secp256r1PublicKey {
531 fn hash<H: Hasher>(&self, state: &mut H) {
532 self.get_encoded(false).hash(state);
533 }
534}
535
536impl Hash for Secp256r1PrivateKey {
537 fn hash<H: Hasher>(&self, state: &mut H) {
538 self.to_raw_bytes().hash(state);
539 }
540}
541
542impl Hash for Secp256r1Signature {
543 fn hash<H: Hasher>(&self, state: &mut H) {
544 self.to_bytes().hash(state);
545 }
546}
547
548impl PartialEq for Secp256r1PrivateKey {
549 fn eq(&self, other: &Self) -> bool {
550 self.to_raw_bytes() == other.to_raw_bytes()
551 }
552}
553
554impl PartialEq for Secp256r1Signature {
555 fn eq(&self, other: &Self) -> bool {
556 self.to_bytes() == other.to_bytes()
557 }
558}
559
560impl From<Vec<u8>> for Secp256r1PublicKey {
561 fn from(bytes: Vec<u8>) -> Self {
562 Secp256r1PublicKey::from_bytes(&bytes).unwrap_or_else(|e| {
563 eprintln!("Warning: Failed to create public key from bytes: {}", e);
564 Secp256r1PublicKey::from_encoded(
567 "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
568 )
569 .expect("Generator point should always be valid")
570 })
571 }
572}
573
574pub trait PrivateKeyExtension
575where
576 Self: Sized,
577{
578 fn to_vec(&self) -> Vec<u8>;
579
580 fn from_slice(slice: &[u8]) -> Result<Self, CryptoError>;
581}
582
583impl PrivateKeyExtension for Secp256r1PrivateKey {
584 fn to_vec(&self) -> Vec<u8> {
585 self.to_raw_bytes().to_vec()
586 }
587
588 fn from_slice(slice: &[u8]) -> Result<Self, CryptoError> {
589 if slice.len() != 32 {
590 return Err(CryptoError::InvalidPublicKey);
591 }
592
593 let mut arr = [0u8; 32];
594 arr.copy_from_slice(slice);
595 Self::from_bytes(&arr).map_err(|_| CryptoError::InvalidPublicKey)
596 }
597}
598
599pub trait PublicKeyExtension
600where
601 Self: Sized,
602{
603 fn to_vec(&self) -> Vec<u8>;
604 fn from_slice(slice: &[u8]) -> Result<Self, CryptoError>;
605}
606
607impl PublicKeyExtension for Secp256r1PublicKey {
608 fn to_vec(&self) -> Vec<u8> {
609 self.get_encoded(true)
610 }
611
612 fn from_slice(slice: &[u8]) -> Result<Self, CryptoError> {
613 if slice.len() != 64 && slice.len() != 33 {
614 return Err(CryptoError::InvalidPublicKey);
615 }
616 Self::from_slice(slice).map_err(|_| CryptoError::InvalidPublicKey)
617 }
618}
619
620impl NeoSerializable for Secp256r1PublicKey {
621 type Error = CryptoError;
622
623 fn size(&self) -> usize {
624 NeoConstants::PUBLIC_KEY_SIZE_COMPRESSED as usize
625 }
626
627 fn encode(&self, writer: &mut Encoder) {
628 writer.write_bytes(&self.get_encoded(true));
629 }
630
631 fn decode(reader: &mut Decoder) -> Result<Self, Self::Error> {
632 let bytes = reader
633 .read_bytes(NeoConstants::PUBLIC_KEY_SIZE_COMPRESSED as usize)
634 .map_err(|_| CryptoError::InvalidPublicKey)?;
635 Secp256r1PublicKey::from_bytes(&bytes).map_err(|_| CryptoError::InvalidPublicKey)
636 }
637
638 fn to_array(&self) -> Vec<u8> {
639 let mut writer = Encoder::new();
641 self.encode(&mut writer);
642 writer.to_bytes()
643 }
644}
645
646#[cfg(test)]
647mod tests {
648 use hex_literal::hex;
649 use p256::EncodedPoint;
650
651 use crate::{
652 codec::{Decoder, NeoSerializable},
653 crypto::{
654 HashableForVec, Secp256r1PrivateKey, Secp256r1PublicKey, Secp256r1Signature, ToArray32,
655 },
656 neo_crypto::utils::{FromHexString, ToHexString},
657 };
658
659 const ENCODED_POINT: &str =
660 "03b4af8d061b6b320cce6c63bc4ec7894dce107bfc5f5ef5c68a93b4ad1e136816";
661
662 #[test]
663 fn test_new_public_key_from_point() {
664 let expected_x = hex!("b4af8d061b6b320cce6c63bc4ec7894dce107bfc5f5ef5c68a93b4ad1e136816");
665 let expected_y = hex!("5f4f7fb1c5862465543c06dd5a2aa414f6583f92a5cc3e1d4259df79bf6839c9");
666
667 let expected_ec_point =
668 EncodedPoint::from_affine_coordinates(&expected_x.into(), &expected_y.into(), false);
669
670 let enc_ec_point = "03b4af8d061b6b320cce6c63bc4ec7894dce107bfc5f5ef5c68a93b4ad1e136816";
671 let enc_ec_point_bytes = hex::decode(enc_ec_point).unwrap();
672
673 let pub_key = Secp256r1PublicKey::from_encoded(&enc_ec_point).unwrap();
674
675 assert_eq!(pub_key.get_encoded_point(false), expected_ec_point);
676 assert_eq!(pub_key.get_encoded(true), enc_ec_point_bytes);
677 assert_eq!(pub_key.get_encoded_compressed_hex(), enc_ec_point);
678 }
679
680 #[test]
681 fn test_new_public_key_from_uncompressed_point() {
682 let uncompressed = "04b4af8d061b6b320cce6c63bc4ec7894dce107bfc5f5ef5c68a93b4ad1e1368165f4f7fb1c5862465543c06dd5a2aa414f6583f92a5cc3e1d4259df79bf6839c9";
683 assert_eq!(
684 Secp256r1PublicKey::from_encoded(uncompressed)
685 .unwrap()
686 .get_encoded_compressed_hex(),
687 ENCODED_POINT
688 );
689 }
690
691 #[test]
692 fn test_new_public_key_from_string_with_invalid_size() {
693 let too_small = "03b4af8d061b6b320cce6c63bc4ec7894dce107bfc5f5ef5c68a93b4ad1e1368"; assert!(Secp256r1PublicKey::from_encoded(too_small).is_none());
695 }
696
697 #[test]
698 fn test_new_public_key_from_point_with_hex_prefix() {
699 let prefixed = format!("0x{ENCODED_POINT}");
700 let a = Secp256r1PublicKey::from_encoded(&prefixed).unwrap();
701 assert_eq!(a.get_encoded_compressed_hex(), ENCODED_POINT);
702 }
703
704 #[test]
705 fn test_serialize_public_key() {
706 let enc_point = "03b4af8d061b6b320cce6c63bc4ec7894dce107bfc5f5ef5c68a93b4ad1e136816";
707 let pub_key = Secp256r1PublicKey::from_encoded(&enc_point).unwrap();
708
709 assert_eq!(pub_key.to_array(), hex::decode(enc_point).unwrap());
710 }
711
712 #[test]
713 fn test_deserialize_public_key() {
714 let data = hex!("036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296");
715 let mut decoder = Decoder::new(&data);
716 let public_key = Secp256r1PublicKey::decode(&mut decoder).unwrap();
717 assert_eq!(public_key.get_encoded(true).to_hex_string(), hex::encode(data));
718 }
719
720 #[test]
721 fn test_public_key_size() {
722 let mut key = Secp256r1PublicKey::from_encoded(
723 "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
724 )
725 .unwrap();
726 assert_eq!(key.get_size(), 33);
727 }
728
729 #[test]
730 fn test_private_key_should_be_zero_after_erasing() {
731 let mut key = Secp256r1PrivateKey::from_bytes(&hex!(
732 "a7038726c5a127989d78593c423e3dad93b2d74db90a16c0a58468c9e6617a87"
733 ))
734 .unwrap();
735 key.erase();
736 assert_eq!(key.to_raw_bytes(), [1u8; 32]);
737 }
738
739 #[test]
740 fn test_public_key_comparable() {
741 let encoded_key2 = "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296";
742 let encoded_key1_uncompressed = "04b4af8d061b6b320cce6c63bc4ec7894dce107bfc5f5ef5c68a93b4ad1e1368165f4f7fb1c5862465543c06dd5a2aa414f6583f92a5cc3e1d4259df79bf6839c9";
743
744 let key1 = Secp256r1PublicKey::from_encoded(ENCODED_POINT).unwrap();
745 let key2 = Secp256r1PublicKey::from_encoded(encoded_key2).unwrap();
746 let key1_uncompressed =
747 Secp256r1PublicKey::from_encoded(encoded_key1_uncompressed).unwrap();
748
749 assert!(key1 > key2);
750 assert!(key1 == key1_uncompressed);
751 assert!(!(key1 < key1_uncompressed));
752 assert!(!(key1 > key1_uncompressed));
753 }
754
755 #[test]
756 fn test_sign_message() {
757 let private_key_hex = "9117f4bf9be717c9a90994326897f4243503accd06712162267e77f18b49c3a3";
758 let public_key_hex = "0265bf906bf385fbf3f777832e55a87991bcfbe19b097fb7c5ca2e4025a4d5e5d6";
759 let test_message = "A test message";
760
761 let private_key =
762 Secp256r1PrivateKey::from_bytes(&hex::decode(private_key_hex).unwrap()).unwrap();
763 let public_key =
764 Secp256r1PublicKey::from_bytes(&hex::decode(public_key_hex).unwrap()).unwrap();
765
766 assert_eq!(public_key.clone(), private_key.clone().to_public_key());
767
768 let hashed_msg = test_message.as_bytes().hash256();
770
771 let signature: Secp256r1Signature = private_key.clone().sign_tx(&hashed_msg).unwrap();
773
774 assert!(public_key.verify(&hashed_msg, &signature).is_ok());
777 }
778}