near_api_types/crypto/
mod.rs1use std::{
2 fmt::{Display, Formatter},
3 str::FromStr,
4};
5
6use crate::errors::{DataConversionError, KeyTypeError};
7
8pub mod public_key;
9pub mod secret_key;
10pub mod signature;
11
12pub const ED25519_PUBLIC_KEY_LENGTH: usize = 32;
13pub const SECP256K1_PUBLIC_KEY_LENGTH: usize = 64;
14pub const COMPONENT_SIZE: usize = 32;
15pub const SECP256K1_SIGNATURE_LENGTH: usize = 65;
16
17#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
18#[cfg_attr(test, derive(bolero::TypeGenerator))]
19pub enum KeyType {
20 ED25519 = 0,
21 SECP256K1 = 1,
22}
23
24impl Display for KeyType {
25 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
26 f.write_str(match self {
27 Self::ED25519 => "ed25519",
28 Self::SECP256K1 => "secp256k1",
29 })
30 }
31}
32
33impl FromStr for KeyType {
34 type Err = KeyTypeError;
35
36 fn from_str(value: &str) -> Result<Self, Self::Err> {
37 let lowercase_key_type = value.to_ascii_lowercase();
38 match lowercase_key_type.as_str() {
39 "ed25519" => Ok(Self::ED25519),
40 "secp256k1" => Ok(Self::SECP256K1),
41 _ => Err(KeyTypeError::InvalidKeyFormat(
42 lowercase_key_type.to_string(),
43 )),
44 }
45 }
46}
47
48impl TryFrom<u8> for KeyType {
49 type Error = KeyTypeError;
50
51 fn try_from(value: u8) -> Result<Self, Self::Error> {
52 match value {
53 0 => Ok(Self::ED25519),
54 1 => Ok(Self::SECP256K1),
55 unknown_key_type => Err(KeyTypeError::InvalidKeyTypeByteIndex(unknown_key_type)),
56 }
57 }
58}
59
60fn split_key_type_data(value: &str) -> Result<(KeyType, &str), DataConversionError> {
61 if let Some((prefix, key_data)) = value.split_once(':') {
62 Ok((KeyType::from_str(prefix)?, key_data))
63 } else {
64 Ok((KeyType::ED25519, value))
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use crate::CryptoHash;
72
73 use super::{public_key::PublicKey, secret_key::SecretKey, signature::Signature, KeyType};
74
75 #[test]
76 fn signature_verify_fuzzer() {
77 bolero::check!().with_type().for_each(
78 |(key_type, sign, data, public_key): &(KeyType, [u8; 65], [u8; 32], PublicKey)| {
79 let signature = match key_type {
80 KeyType::ED25519 => {
81 Signature::from_parts(KeyType::ED25519, &sign[..64]).unwrap()
82 }
83 KeyType::SECP256K1 => {
84 Signature::from_parts(KeyType::SECP256K1, &sign[..65]).unwrap()
85 }
86 };
87 let _ = signature.verify(CryptoHash(*data), *public_key);
88 },
89 );
90 }
91
92 #[test]
93 fn regression_signature_verification_originally_failed() {
94 let signature = Signature::from_parts(KeyType::SECP256K1, &[4; 65]).unwrap();
95 let _ = signature.verify(CryptoHash([0; 32]), PublicKey::empty(KeyType::SECP256K1));
96 }
97
98 #[test]
99 fn test_invalid_data() {
100 let invalid = "\"secp256k1:2xVqteU8PWhadHTv99TGh3bSf\"";
102 assert!(serde_json::from_str::<PublicKey>(invalid).is_err());
103 assert!(serde_json::from_str::<SecretKey>(invalid).is_err());
104 assert!(serde_json::from_str::<Signature>(invalid).is_err());
105 }
106}