cita_tool/crypto/
crypto_trait.rs1use 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
11pub trait CreateKey
13where
14 Self: marker::Sized,
15{
16 type PrivKey;
18 type PubKey;
20 type Error;
22
23 fn from_privkey(privkey: Self::PrivKey) -> Result<Self, Self::Error>;
25 fn gen_keypair() -> Self;
27 fn privkey(&self) -> &Self::PrivKey;
29 fn pubkey(&self) -> &Self::PubKey;
31 fn address(&self) -> Address;
33 fn sign_raw(&self, data: &[u8]) -> Result<Signature, Self::Error>;
35}
36
37pub trait Hashable {
39 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 fn sha3_crypt_hash_into(&self, dest: &mut [u8]);
51
52 fn blake2b_crypt_hash_into(&self, dest: &mut [u8]);
54
55 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#[derive(Debug)]
92pub enum Error {
93 InvalidPrivKey,
95 InvalidPubKey,
97 InvalidSignature,
99 InvalidMessage,
101 RecoverError,
103 Io(::std::io::Error),
105 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}