1use alloc::{boxed::Box, string::String, vec::Vec};
2use bs58;
3use core::{pin::Pin, result::Result};
4
5use crate::error::*;
6
7pub type AsyncCryptoResult<'a, T, E> =
8 Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;
9
10pub trait Crypto: Send + Sync {
11 fn create_uuid() -> String;
13
14 fn random_bytes(length: usize) -> Vec<u8>;
16
17 type Sha256Error: core::fmt::Debug + Send + Sync + 'static =
19 crate::error::Sha256Error;
20
21 fn hash_sha256<'a>(
23 to_digest: &'a [u8],
24 ) -> AsyncCryptoResult<'a, [u8; 32], Self::Sha256Error>;
25
26 fn dec_b58_32(data: &str) -> Result<[u8; 32], B58DecodeError> {
29 let bytes = bs58::decode(data)
30 .into_vec()
31 .map_err(|_| B58DecodeError::InvalidBase58)?;
32
33 if bytes.len() != 32 {
34 return Err(B58DecodeError::WrongLength {
35 expected: 32,
36 got: bytes.len(),
37 });
38 }
39
40 let mut out = [0u8; 32];
41 out.copy_from_slice(&bytes);
42 Ok(out)
43 }
44
45 type HkdfError: core::fmt::Debug + Send + Sync + 'static =
47 crate::error::HkdfError;
48
49 fn hkdf_sha256<'a>(
51 ikm: &'a [u8],
52 salt: &'a [u8],
53 ) -> AsyncCryptoResult<'a, [u8; 32], Self::HkdfError>;
54
55 type Ed25519GenError: core::fmt::Debug + Send + Sync + 'static =
57 crate::error::Ed25519GenError;
58
59 fn gen_ed25519<'a>()
61 -> AsyncCryptoResult<'a, (Vec<u8>, Vec<u8>), Self::Ed25519GenError>;
62
63 type Ed25519SignError: core::fmt::Debug + Send + Sync + 'static =
64 crate::error::Ed25519SignError;
65
66 fn sig_ed25519<'a>(
68 pri_key: &'a [u8],
69 data: &'a [u8],
70 ) -> AsyncCryptoResult<'a, [u8; 64], Self::Ed25519SignError>;
71
72 type Ed25519VerifyError: core::fmt::Debug + Send + Sync + 'static =
74 crate::error::Ed25519VerifyError;
75
76 fn ver_ed25519<'a>(
79 pub_key: &'a [u8],
80 sig: &'a [u8],
81 data: &'a [u8],
82 ) -> AsyncCryptoResult<'a, bool, Self::Ed25519VerifyError>;
83
84 type AesCtrError: core::fmt::Debug + Send + Sync + 'static =
86 crate::error::AesCtrError;
87
88 fn aes_ctr_encrypt<'a>(
90 key: &'a [u8; 32],
91 iv: &'a [u8; 16],
92 plaintext: &'a [u8],
93 ) -> AsyncCryptoResult<'a, Vec<u8>, Self::AesCtrError>;
94
95 fn aes_ctr_decrypt<'a>(
97 key: &'a [u8; 32],
98 iv: &'a [u8; 16],
99 cipher: &'a [u8],
100 ) -> AsyncCryptoResult<'a, Vec<u8>, Self::AesCtrError>;
101
102 type KeyWrapError: core::fmt::Debug + Send + Sync + 'static =
104 crate::error::KeyWrapError;
105
106 fn key_wrap_rfc3394<'a>(
108 kek: &'a [u8; 32],
109 key_to_wrap: &'a [u8; 32],
110 ) -> AsyncCryptoResult<'a, [u8; 40], Self::KeyWrapError>;
111
112 type KeyUnwrapError: core::fmt::Debug + Send + Sync + 'static =
113 crate::error::KeyUnwrapError;
114
115 fn key_unwrap_rfc3394<'a>(
118 kek: &'a [u8; 32],
119 wrapped: &'a [u8; 40],
120 ) -> AsyncCryptoResult<'a, [u8; 32], Self::KeyUnwrapError>;
121
122 type X25519GenError: core::fmt::Debug + Send + Sync + 'static =
124 crate::error::X25519GenError;
125
126 fn gen_x25519<'a>()
128 -> AsyncCryptoResult<'a, ([u8; 44], [u8; 48]), Self::X25519GenError>;
129
130 type X25519DeriveError: core::fmt::Debug + Send + Sync + 'static =
131 crate::error::X25519DeriveError;
132
133 fn derive_x25519<'a>(
136 pri_key: &'a [u8; 48],
137 peer_pub: &'a [u8; 44],
138 ) -> AsyncCryptoResult<'a, [u8; 32], Self::X25519DeriveError>;
139
140 fn enc_b58(data: &[u8]) -> String {
143 bs58::encode(data).into_string()
144 }
145
146 fn dec_b58(data: &str) -> Result<Vec<u8>, B58DecodeError> {
148 bs58::decode(data)
149 .into_vec()
150 .map_err(|_| B58DecodeError::InvalidBase58)
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157
158 struct T;
160
161 impl Crypto for T {
162 fn create_uuid() -> String {
163 String::new()
165 }
166
167 fn random_bytes(length: usize) -> Vec<u8> {
168 unimplemented!()
169 }
170
171 fn hash_sha256<'a>(
172 _to_digest: &'a [u8],
173 ) -> AsyncCryptoResult<'a, [u8; 32], Self::Sha256Error> {
174 unimplemented!()
175 }
176
177 fn hkdf_sha256<'a>(
178 _ikm: &'a [u8],
179 _salt: &'a [u8],
180 ) -> AsyncCryptoResult<'a, [u8; 32], Self::HkdfError> {
181 unimplemented!()
182 }
183
184 fn gen_ed25519<'a>()
185 -> AsyncCryptoResult<'a, (Vec<u8>, Vec<u8>), Self::Ed25519GenError>
186 {
187 unimplemented!()
188 }
189
190 fn sig_ed25519<'a>(
191 _pri_key: &'a [u8],
192 _data: &'a [u8],
193 ) -> AsyncCryptoResult<'a, [u8; 64], Self::Ed25519SignError> {
194 unimplemented!()
195 }
196
197 fn ver_ed25519<'a>(
198 _pub_key: &'a [u8],
199 _sig: &'a [u8],
200 _data: &'a [u8],
201 ) -> AsyncCryptoResult<'a, bool, Self::Ed25519VerifyError> {
202 unimplemented!()
203 }
204
205 fn aes_ctr_encrypt<'a>(
206 _key: &'a [u8; 32],
207 _iv: &'a [u8; 16],
208 _plaintext: &'a [u8],
209 ) -> AsyncCryptoResult<'a, Vec<u8>, Self::AesCtrError> {
210 unimplemented!()
211 }
212
213 fn aes_ctr_decrypt<'a>(
214 _key: &'a [u8; 32],
215 _iv: &'a [u8; 16],
216 _cipher: &'a [u8],
217 ) -> AsyncCryptoResult<'a, Vec<u8>, Self::AesCtrError> {
218 unimplemented!()
219 }
220
221 fn key_wrap_rfc3394<'a>(
222 _kek: &'a [u8; 32],
223 _key_to_wrap: &'a [u8; 32],
224 ) -> AsyncCryptoResult<'a, [u8; 40], Self::KeyWrapError> {
225 unimplemented!()
226 }
227
228 fn key_unwrap_rfc3394<'a>(
229 _kek: &'a [u8; 32],
230 _wrapped: &'a [u8; 40],
231 ) -> AsyncCryptoResult<'a, [u8; 32], Self::KeyUnwrapError> {
232 unimplemented!()
233 }
234
235 fn gen_x25519<'a>()
236 -> AsyncCryptoResult<'a, ([u8; 44], [u8; 48]), Self::X25519GenError>
237 {
238 unimplemented!()
239 }
240
241 fn derive_x25519<'a>(
242 _pri_key: &'a [u8; 48],
243 _peer_pub: &'a [u8; 44],
244 ) -> AsyncCryptoResult<'a, [u8; 32], Self::X25519DeriveError> {
245 unimplemented!()
246 }
247 }
248
249 #[test]
250 fn b58_roundtrip_arbitrary_bytes() {
251 let input = b"hello DATEX";
252 let encoded = T::enc_b58(input);
253 let decoded = T::dec_b58(&encoded).unwrap();
254 assert_eq!(input, &decoded[..]);
255 }
256
257 #[test]
258 fn b58_roundtrip_empty() {
259 let input: &[u8] = b"";
260 let encoded = T::enc_b58(input);
261 let decoded = T::dec_b58(&encoded).unwrap();
262 assert_eq!(input, &decoded[..]);
263 }
264
265 #[test]
266 fn b58_roundtrip_32_bytes() {
267 let mut input = [0u8; 32];
268 for (i, b) in input.iter_mut().enumerate() {
269 *b = (i as u8).wrapping_mul(7).wrapping_add(3);
270 }
271
272 let encoded = T::enc_b58(&input);
273 let decoded = T::dec_b58_32(&encoded).unwrap();
274 assert_eq!(input, decoded);
275 }
276
277 #[test]
278 fn b58_dec_invalid_base58_errors() {
279 let bad = "0OIl";
281 let err = T::dec_b58(bad).unwrap_err();
282 assert_eq!(err, B58DecodeError::InvalidBase58);
283 }
284
285 #[test]
286 fn b58_dec32_wrong_length_errors() {
287 let s = "2g";
289 let err = T::dec_b58_32(s).unwrap_err();
290 assert_eq!(
291 err,
292 B58DecodeError::WrongLength {
293 expected: 32,
294 got: 1
295 }
296 );
297 }
298}