cita_tool/crypto/
cita_sm2.rs

1use crate::crypto::{pubkey_to_address, CreateKey, Error, Message, PubKey, Sm2Privkey, Sm2Pubkey};
2use crate::{Signature, H256, H512};
3use efficient_sm2::{create_key_slice, KeyPair, PublicKey};
4use hex::encode;
5use std::fmt;
6use std::ops::{Deref, DerefMut};
7use types::Address;
8
9const SIGNATURE_BYTES_LEN: usize = 128;
10
11/// Sm2 key pair
12#[derive(Default, Clone)]
13pub struct Sm2KeyPair {
14    privkey: Sm2Privkey,
15    pubkey: Sm2Pubkey,
16}
17
18impl fmt::Display for Sm2KeyPair {
19    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
20        writeln!(f, "privkey:  {}", encode(self.privkey.0))?;
21        writeln!(f, "pubkey:  {}", encode(self.pubkey.0))?;
22        write!(f, "address:  {}", encode(self.address().0))
23    }
24}
25
26impl CreateKey for Sm2KeyPair {
27    type PrivKey = Sm2Privkey;
28    type PubKey = Sm2Pubkey;
29    type Error = Error;
30
31    fn from_privkey(privkey: Self::PrivKey) -> Result<Self, Self::Error> {
32        let key_pair = KeyPair::new(privkey.as_bytes()).map_err(|_| Error::InvalidPrivKey)?;
33        Ok(Sm2KeyPair {
34            privkey,
35            pubkey: H512::from_slice(&key_pair.public_key().bytes_less_safe()[1..]),
36        })
37    }
38
39    fn gen_keypair() -> Self {
40        let private = H256(create_key_slice());
41        Self::from_privkey(private).unwrap()
42    }
43
44    fn privkey(&self) -> &Self::PrivKey {
45        &self.privkey
46    }
47
48    fn pubkey(&self) -> &Self::PubKey {
49        &self.pubkey
50    }
51
52    fn address(&self) -> Address {
53        pubkey_to_address(&PubKey::Sm2(self.pubkey))
54    }
55
56    fn sign_raw(&self, data: &[u8]) -> Result<Signature, Error> {
57        let keypair = KeyPair::new(self.privkey.as_bytes()).map_err(|_| Error::InvalidPrivKey)?;
58        let sig = keypair.sign(data).map_err(|_| Error::InvalidMessage)?;
59
60        let mut sig_bytes = [0u8; SIGNATURE_BYTES_LEN];
61        sig_bytes[..32].copy_from_slice(&sig.r());
62        sig_bytes[32..64].copy_from_slice(&sig.s());
63        sig_bytes[64..].copy_from_slice(&keypair.public_key().bytes_less_safe()[1..]);
64        Ok(Signature::Sm2(Sm2Signature(sig_bytes)))
65    }
66}
67
68/// Sm2 signature
69pub struct Sm2Signature(pub [u8; 128]);
70
71impl Sm2Signature {
72    /// Get a slice into the 'r' portion of the data.
73    #[inline]
74    pub fn r(&self) -> &[u8] {
75        &self.0[0..32]
76    }
77    /// Get a slice into the 's' portion of the data.
78    #[inline]
79    pub fn s(&self) -> &[u8] {
80        &self.0[32..64]
81    }
82    /// Get a slice into the public key portion of the data.
83    #[inline]
84    pub fn pk(&self) -> &[u8] {
85        &self.0[64..]
86    }
87
88    /// Recover public key
89    pub fn recover(&self, message: &Message) -> Result<Sm2Pubkey, Error> {
90        let pub_key = Sm2Pubkey::from_slice(self.pk());
91        self.verify_public(&pub_key, message)?;
92
93        Ok(pub_key)
94    }
95
96    /// Verify public key
97    pub fn verify_public(&self, pubkey: &Sm2Pubkey, message: &Message) -> Result<bool, Error> {
98        let pub_key = PublicKey::from_slice(pubkey.as_bytes());
99        let sig = efficient_sm2::Signature::new(self.r(), self.s())
100            .map_err(|_| Error::InvalidSignature)?;
101        sig.verify(&pub_key, message.as_bytes())
102            .map_err(|_| Error::RecoverError)
103            .map(|_| true)
104    }
105}
106
107/// Sign data with sm2
108pub fn sm2_sign(privkey: &Sm2Privkey, message: &Message) -> Result<Sm2Signature, Error> {
109    let keypair = KeyPair::new(privkey.as_bytes()).map_err(|_| Error::InvalidPrivKey)?;
110    let sig = keypair
111        .sign(message.as_bytes())
112        .map_err(|_| Error::InvalidMessage)?;
113
114    let mut sig_bytes = [0u8; SIGNATURE_BYTES_LEN];
115    sig_bytes[..32].copy_from_slice(&sig.r());
116    sig_bytes[32..64].copy_from_slice(&sig.s());
117    sig_bytes[64..].copy_from_slice(&keypair.public_key().bytes_less_safe()[1..]);
118    Ok(Sm2Signature(sig_bytes))
119}
120
121impl fmt::Debug for Sm2Signature {
122    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
123        f.debug_struct("Signature")
124            .field("r", &encode(self.r()))
125            .field("s", &encode(self.s()))
126            .field("pk", &encode(self.pk()))
127            .finish()
128    }
129}
130
131impl fmt::Display for Sm2Signature {
132    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
133        write!(f, "{}", encode(&self.0[..]))
134    }
135}
136
137impl Default for Sm2Signature {
138    fn default() -> Self {
139        Sm2Signature([0; 128])
140    }
141}
142
143impl From<[u8; 128]> for Sm2Signature {
144    fn from(s: [u8; 128]) -> Self {
145        Sm2Signature(s)
146    }
147}
148
149impl<'a> From<&'a [u8]> for Sm2Signature {
150    fn from(slice: &'a [u8]) -> Sm2Signature {
151        assert_eq!(slice.len(), SIGNATURE_BYTES_LEN);
152        let mut bytes = [0u8; SIGNATURE_BYTES_LEN];
153        bytes.copy_from_slice(slice);
154        Sm2Signature(bytes)
155    }
156}
157
158impl fmt::LowerHex for Sm2Signature {
159    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160        for i in &self.0[..] {
161            write!(f, "{i:02x}")?;
162        }
163        Ok(())
164    }
165}
166
167impl Deref for Sm2Signature {
168    type Target = [u8; 128];
169
170    fn deref(&self) -> &Self::Target {
171        &self.0
172    }
173}
174
175impl DerefMut for Sm2Signature {
176    fn deref_mut(&mut self) -> &mut Self::Target {
177        &mut self.0
178    }
179}
180
181#[cfg(test)]
182mod tests {
183    use super::*;
184
185    #[test]
186    fn test_recover() {
187        let keypair = Sm2KeyPair::gen_keypair();
188        let msg = Message::default();
189        let sig = sm2_sign(keypair.privkey(), &msg).unwrap();
190        assert_eq!(keypair.pubkey(), &sig.recover(&msg).unwrap());
191    }
192}