cita_tool/crypto/
crypto_trait.rs

1use crate::crypto::Encryption;
2use crate::Signature;
3use blake2b_simd::Params;
4use libsm::sm3;
5use std::{fmt, marker};
6use tiny_keccak::Hasher;
7use types::{Address, H256};
8
9const BLAKE2BKEY: &str = "CryptapeCryptape";
10
11/// Create secret Key
12pub trait CreateKey
13where
14    Self: marker::Sized,
15{
16    /// Private key
17    type PrivKey;
18    /// Public key
19    type PubKey;
20    /// Error
21    type Error;
22
23    /// Create a pair from secret key
24    fn from_privkey(privkey: Self::PrivKey) -> Result<Self, Self::Error>;
25    /// Generate a pair of public and private keys
26    fn gen_keypair() -> Self;
27    /// Get private key
28    fn privkey(&self) -> &Self::PrivKey;
29    /// Get public key
30    fn pubkey(&self) -> &Self::PubKey;
31    /// Get address of the public key
32    fn address(&self) -> Address;
33    /// Sign raw data
34    fn sign_raw(&self, data: &[u8]) -> Result<Signature, Self::Error>;
35}
36
37/// Hashable for some type
38pub trait Hashable {
39    /// Calculate crypt HASH of this object.
40    fn crypt_hash(&self, encryption: Encryption) -> H256 {
41        let mut result = [0u8; 32];
42        match encryption {
43            Encryption::Secp256k1 => self.sha3_crypt_hash_into(&mut result),
44            Encryption::Sm2 => self.sm3_crypt_hash_into(&mut result),
45        }
46        H256(result)
47    }
48
49    /// Calculate crypt HASH of this object and place result into dest, use sha3
50    fn sha3_crypt_hash_into(&self, dest: &mut [u8]);
51
52    /// Calculate crypt HASH of this object and place result into dest, use blake2b
53    fn blake2b_crypt_hash_into(&self, dest: &mut [u8]);
54
55    /// Calculate crypt HASH of this object and place result into dest, use sm3
56    fn sm3_crypt_hash_into(&self, dest: &mut [u8]);
57}
58
59impl<T> Hashable for T
60where
61    T: AsRef<[u8]>,
62{
63    fn sha3_crypt_hash_into(&self, dest: &mut [u8]) {
64        let input: &[u8] = self.as_ref();
65        let mut hasher = tiny_keccak::Keccak::v256();
66        hasher.update(input);
67        hasher.finalize(dest);
68    }
69
70    fn blake2b_crypt_hash_into(&self, dest: &mut [u8]) {
71        let input: &[u8] = self.as_ref();
72
73        dest.copy_from_slice(
74            Params::new()
75                .hash_length(dest.len())
76                .key(BLAKE2BKEY.as_bytes())
77                .to_state()
78                .update(input)
79                .finalize()
80                .as_ref(),
81        );
82    }
83
84    fn sm3_crypt_hash_into(&self, dest: &mut [u8]) {
85        let input: &[u8] = self.as_ref();
86        dest.copy_from_slice(sm3::hash::Sm3Hash::new(input).get_hash().as_ref());
87    }
88}
89
90/// Error of create secret key
91#[derive(Debug)]
92pub enum Error {
93    /// Invalid private key
94    InvalidPrivKey,
95    /// Invalid public key
96    InvalidPubKey,
97    /// Invalid signature
98    InvalidSignature,
99    /// Invalid message
100    InvalidMessage,
101    /// Recover error
102    RecoverError,
103    /// Io error
104    Io(::std::io::Error),
105    /// null
106    Null,
107}
108
109impl fmt::Display for Error {
110    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111        let msg = match *self {
112            Error::InvalidPrivKey => "Invalid secret".into(),
113            Error::InvalidPubKey => "Invalid public".into(),
114            Error::InvalidSignature => "Invalid EC signature".into(),
115            Error::InvalidMessage => "Invalid AES message".into(),
116            Error::RecoverError => "Recover Error".into(),
117            Error::Io(ref err) => format!("I/O error: {err}"),
118            Error::Null => "Null crypto".into(),
119        };
120        f.write_fmt(format_args!("Crypto error ({msg})"))
121    }
122}
123
124impl From<::secp256k1::Error> for Error {
125    fn from(e: ::secp256k1::Error) -> Error {
126        match e {
127            ::secp256k1::Error::InvalidMessage => Error::InvalidMessage,
128            ::secp256k1::Error::InvalidPublicKey => Error::InvalidPubKey,
129            ::secp256k1::Error::InvalidSecretKey => Error::InvalidPrivKey,
130            _ => Error::InvalidSignature,
131        }
132    }
133}
134
135impl From<::std::io::Error> for Error {
136    fn from(err: ::std::io::Error) -> Error {
137        Error::Io(err)
138    }
139}