bucky_crypto/
signature.rs

1use generic_array::typenum::{marker_traits::Unsigned, U16, U32, U64, U96};
2use generic_array::GenericArray;
3use std::ptr::slice_from_raw_parts;
4use bucky_time::bucky_time_now;
5
6use crate::*;
7
8impl Default for Signature {
9    fn default() -> Self {
10        Self {
11            sign_time: bucky_time_now(),
12            sign: SignData::Rsa1024(GenericArray::default()),
13        }
14    }
15}
16
17#[derive(Clone, Eq, PartialEq, Debug)]
18pub enum SignData {
19    Rsa1024(GenericArray<u32, U32>),
20    Rsa2048(GenericArray<u32, U64>),
21    Rsa3072(GenericArray<u32, U96>),
22    Ecc(GenericArray<u32, U16>),
23}
24
25impl SignData {
26    pub fn sign_type(&self) -> &str {
27        match self {
28            Self::Rsa1024(_) => "rsa1024",
29            Self::Rsa2048(_) => "rsa2048",
30            Self::Rsa3072(_) => "rsa3072",
31            Self::Ecc(_) => "ecc",
32        }
33    }
34
35    pub fn as_slice<'a>(&self) -> &'a [u8] {
36        let sign_slice = match self {
37            SignData::Rsa1024(sign) => unsafe {
38                &*slice_from_raw_parts(
39                    sign.as_ptr() as *const u8,
40                    std::mem::size_of::<u32>() * U32::to_usize(),
41                )
42            },
43            SignData::Rsa2048(sign) => unsafe {
44                &*slice_from_raw_parts(
45                    sign.as_ptr() as *const u8,
46                    std::mem::size_of::<u32>() * U64::to_usize(),
47                )
48            },
49            SignData::Rsa3072(sign) => unsafe {
50                &*slice_from_raw_parts(
51                    sign.as_ptr() as *const u8,
52                    std::mem::size_of::<u32>() * U96::to_usize(),
53                )
54            },
55            SignData::Ecc(sign) => unsafe {
56                &*slice_from_raw_parts(
57                    sign.as_ptr() as *const u8,
58                    std::mem::size_of::<u32>() * U16::to_usize(),
59                )
60            },
61        };
62        sign_slice
63    }
64}
65
66#[derive(Clone, Eq, PartialEq, Debug)]
67pub struct Signature {
68    sign_time: u64,
69    sign: SignData,
70}
71
72impl Signature {
73    pub fn new(
74        sign_time: u64,
75        sign: SignData,
76    ) -> Self {
77        Self {
78            sign_time: sign_time,
79            sign: sign,
80        }
81    }
82
83    pub fn sign(&self) -> &SignData {
84        &self.sign
85    }
86
87    pub fn as_slice<'a>(&self) -> &'a [u8] {
88        self.sign.as_slice()
89    }
90
91    pub fn sign_time(&self) -> u64 {
92        self.sign_time
93    }
94}
95
96impl RawEncode for Signature {
97    fn raw_measure(&self, _purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
98        // sign_source_with_ref_index
99        let mut size = u64::raw_bytes().unwrap();
100
101        // sign_data: Vec<u8>
102        size = size
103            + u8::raw_bytes().unwrap()
104            + std::mem::size_of::<u32>()
105                * match self.sign {
106                    SignData::Rsa1024(_) => U32::to_usize(),
107                    SignData::Rsa2048(_) => U64::to_usize(),
108                    SignData::Rsa3072(_) => U96::to_usize(),
109                    SignData::Ecc(_) => U16::to_usize(),
110                };
111
112        Ok(size)
113    }
114
115    fn raw_encode<'a>(
116        &self,
117        buf: &'a mut [u8],
118        purpose: &Option<RawEncodePurpose>,
119    ) -> Result<&'a mut [u8], BuckyError> {
120        let bytes = self.raw_measure(purpose).unwrap();
121        if buf.len() < bytes {
122            let msg = format!(
123                "not enough buffer for encode Signature buf, except={}, got={}",
124                bytes,
125                buf.len()
126            );
127            error!("{}", msg);
128
129            return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
130        }
131
132        // sign_time
133        let buf = self.sign_time.raw_encode(buf, purpose)?;
134
135        // sign_data: Vec<u8>
136        let buf = match self.sign {
137            SignData::Rsa1024(sign) => {
138                let buf = KEY_TYPE_RSA.raw_encode(buf, purpose)?;
139                let bytes = std::mem::size_of::<u32>() * U32::to_usize();
140                unsafe {
141                    std::ptr::copy(
142                        sign.as_slice().as_ptr() as *const u8,
143                        buf.as_mut_ptr(),
144                        bytes,
145                    );
146                }
147                &mut buf[bytes..]
148            }
149            SignData::Rsa2048(sign) => {
150                let buf = KEY_TYPE_RSA2048.raw_encode(buf, purpose)?;
151                let bytes = std::mem::size_of::<u32>() * U64::to_usize();
152                unsafe {
153                    std::ptr::copy(
154                        sign.as_slice().as_ptr() as *const u8,
155                        buf.as_mut_ptr(),
156                        bytes,
157                    );
158                }
159                &mut buf[bytes..]
160            }
161            SignData::Rsa3072(sign) => {
162                let buf = KEY_TYPE_RSA3072.raw_encode(buf, purpose)?;
163                let bytes = std::mem::size_of::<u32>() * U96::to_usize();
164                unsafe {
165                    std::ptr::copy(
166                        sign.as_slice().as_ptr() as *const u8,
167                        buf.as_mut_ptr(),
168                        bytes,
169                    );
170                }
171                &mut buf[bytes..]
172            }
173            SignData::Ecc(sign) => {
174                let buf = KEY_TYPE_SECP256K1.raw_encode(buf, purpose)?;
175                let bytes = std::mem::size_of::<u32>() * U16::to_usize();
176                unsafe {
177                    std::ptr::copy(
178                        sign.as_slice().as_ptr() as *const u8,
179                        buf.as_mut_ptr(),
180                        bytes,
181                    );
182                }
183                &mut buf[bytes..]
184            }
185        };
186
187        Ok(buf)
188    }
189}
190
191impl<'de> RawDecode<'de> for Signature {
192    fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
193        let (sign_time, buf) = u64::raw_decode(buf)?;
194
195        let (key_type, buf) = u8::raw_decode(buf)?;
196
197        let (sign, buf) = match key_type {
198            KEY_TYPE_RSA => {
199                let bytes = std::mem::size_of::<u32>() * U32::to_usize();
200                if buf.len() < bytes {
201                    return Err(BuckyError::new(
202                        BuckyErrorCode::OutOfLimit,
203                        "not enough buffer for rsa1024 signature",
204                    ));
205                }
206
207                let mut sign = GenericArray::default();
208                unsafe {
209                    std::ptr::copy(
210                        buf.as_ptr(),
211                        sign.as_mut_slice().as_mut_ptr() as *mut u8,
212                        bytes,
213                    );
214                }
215
216                (SignData::Rsa1024(sign), &buf[bytes..])
217            }
218            KEY_TYPE_RSA2048 => {
219                let bytes = std::mem::size_of::<u32>() * U64::to_usize();
220                if buf.len() < bytes {
221                    return Err(BuckyError::new(
222                        BuckyErrorCode::OutOfLimit,
223                        "not enough buffer for rsa2048 signature",
224                    ));
225                }
226
227                let mut sign = GenericArray::default();
228                unsafe {
229                    std::ptr::copy(
230                        buf.as_ptr(),
231                        sign.as_mut_slice().as_mut_ptr() as *mut u8,
232                        bytes,
233                    );
234                }
235
236                (SignData::Rsa2048(sign), &buf[bytes..])
237            }
238            KEY_TYPE_RSA3072 => {
239                let bytes = std::mem::size_of::<u32>() * U96::to_usize();
240                if buf.len() < bytes {
241                    return Err(BuckyError::new(
242                        BuckyErrorCode::OutOfLimit,
243                        "not enough buffer for rsa3072 signature",
244                    ));
245                }
246
247                let mut sign = GenericArray::default();
248                unsafe {
249                    std::ptr::copy(
250                        buf.as_ptr(),
251                        sign.as_mut_slice().as_mut_ptr() as *mut u8,
252                        bytes,
253                    );
254                }
255
256                (SignData::Rsa3072(sign), &buf[bytes..])
257            }
258            KEY_TYPE_SECP256K1 => {
259                let bytes = std::mem::size_of::<u32>() * U16::to_usize();
260                if buf.len() < bytes {
261                    return Err(BuckyError::new(
262                        BuckyErrorCode::OutOfLimit,
263                        "not enough buffer for secp256k1 signature",
264                    ));
265                }
266
267                let mut sign = GenericArray::default();
268                unsafe {
269                    std::ptr::copy(
270                        buf.as_ptr(),
271                        sign.as_mut_slice().as_mut_ptr() as *mut u8,
272                        bytes,
273                    );
274                }
275
276                (SignData::Ecc(sign), &buf[bytes..])
277            }
278            _ => {
279                return Err(BuckyError::new(
280                    BuckyErrorCode::NotMatch,
281                    format!("Invalid Signature KeyType:{}", key_type),
282                ));
283            }
284        };
285
286        Ok((
287            Self {
288                sign_time,
289                sign: sign,
290            },
291            buf,
292        ))
293    }
294}
295
296#[cfg(test)]
297mod test {
298    use crate::{RawConvertTo, RawFrom, Signature};
299
300    #[test]
301    fn signature() {
302        let sig1 = Signature::default();
303        let buf = sig1.to_vec().unwrap();
304        let sig2 = Signature::clone_from_slice(&buf).unwrap();
305        assert_eq!(sig1, sig2)
306    }
307}