1use lazy_static::__Deref;
2use zeroize::{Zeroize, ZeroizeOnDrop};
3
4use crate::rng::copy_randombytes;
5
6#[derive(Zeroize, ZeroizeOnDrop, Debug, PartialEq, Eq, Clone)]
9pub struct StackByteArray<const LENGTH: usize>([u8; LENGTH]);
10
11pub trait ByteArray<const LENGTH: usize>: Bytes {
13 fn as_array(&self) -> &[u8; LENGTH];
15}
16
17pub trait Bytes {
19 fn as_slice(&self) -> &[u8];
21 fn len(&self) -> usize;
23 fn is_empty(&self) -> bool;
25}
26
27pub trait MutByteArray<const LENGTH: usize>: ByteArray<LENGTH> + MutBytes {
29 fn as_mut_array(&mut self) -> &mut [u8; LENGTH];
31}
32
33pub trait NewByteArray<const LENGTH: usize>: MutByteArray<LENGTH> + NewBytes {
35 fn new_byte_array() -> Self;
37 fn gen() -> Self;
39}
40
41pub trait MutBytes: Bytes {
43 fn as_mut_slice(&mut self) -> &mut [u8];
45 fn copy_from_slice(&mut self, other: &[u8]);
48}
49
50pub trait NewBytes: MutBytes {
52 fn new_bytes() -> Self;
54}
55
56pub trait ResizableBytes {
58 fn resize(&mut self, new_len: usize, value: u8);
61}
62
63impl<const LENGTH: usize> ByteArray<LENGTH> for StackByteArray<LENGTH> {
64 #[inline]
65 fn as_array(&self) -> &[u8; LENGTH] {
66 &self.0
67 }
68}
69
70impl<const LENGTH: usize> Bytes for StackByteArray<LENGTH> {
71 #[inline]
72 fn as_slice(&self) -> &[u8] {
73 &self.0
74 }
75
76 #[inline]
77 fn len(&self) -> usize {
78 self.0.len()
79 }
80
81 #[inline]
82 fn is_empty(&self) -> bool {
83 self.0.is_empty()
84 }
85}
86
87impl<const LENGTH: usize> NewBytes for StackByteArray<LENGTH> {
88 fn new_bytes() -> Self {
89 Self::default()
90 }
91}
92
93impl<const LENGTH: usize> NewByteArray<LENGTH> for StackByteArray<LENGTH> {
94 fn new_byte_array() -> Self {
95 Self::default()
96 }
97
98 fn gen() -> Self {
100 let mut res = Self::default();
101 copy_randombytes(&mut res.0);
102 res
103 }
104}
105
106impl<const LENGTH: usize> MutByteArray<LENGTH> for StackByteArray<LENGTH> {
107 #[inline]
108 fn as_mut_array(&mut self) -> &mut [u8; LENGTH] {
109 &mut self.0
110 }
111}
112
113impl<const LENGTH: usize> MutBytes for StackByteArray<LENGTH> {
114 #[inline]
115 fn as_mut_slice(&mut self) -> &mut [u8] {
116 &mut self.0
117 }
118
119 fn copy_from_slice(&mut self, other: &[u8]) {
120 self.0.copy_from_slice(other)
121 }
122}
123
124impl<const LENGTH: usize> NewByteArray<LENGTH> for Vec<u8> {
125 fn new_byte_array() -> Self {
126 vec![0u8; LENGTH]
127 }
128
129 fn gen() -> Self {
131 let mut res = vec![0u8; LENGTH];
132 copy_randombytes(&mut res);
133 res
134 }
135}
136
137impl<const LENGTH: usize> MutByteArray<LENGTH> for Vec<u8> {
138 #[inline]
139 fn as_mut_array(&mut self) -> &mut [u8; LENGTH] {
140 assert!(
141 self.len() >= LENGTH,
142 "invalid vec length {}, expecting at least {}",
143 self.len(),
144 LENGTH
145 );
146 let arr = self.as_ptr() as *mut [u8; LENGTH];
147 unsafe { &mut *arr }
148 }
149}
150
151impl<const LENGTH: usize> ByteArray<LENGTH> for Vec<u8> {
152 #[inline]
153 fn as_array(&self) -> &[u8; LENGTH] {
154 assert!(
155 self.len() >= LENGTH,
156 "invalid vec length {}, expecting at least {}",
157 self.len(),
158 LENGTH
159 );
160 let arr = self.as_ptr() as *const [u8; LENGTH];
161 unsafe { &*arr }
162 }
163}
164
165impl<const LENGTH: usize> NewBytes for [u8; LENGTH] {
166 fn new_bytes() -> Self {
167 [0u8; LENGTH]
168 }
169}
170
171impl<const LENGTH: usize> NewByteArray<LENGTH> for [u8; LENGTH] {
172 fn new_byte_array() -> Self {
173 [0u8; LENGTH]
174 }
175
176 fn gen() -> Self {
178 let mut res = Self::new_byte_array();
179 copy_randombytes(&mut res);
180 res
181 }
182}
183
184impl<const LENGTH: usize> MutByteArray<LENGTH> for [u8; LENGTH] {
185 #[inline]
186 fn as_mut_array(&mut self) -> &mut [u8; LENGTH] {
187 self
188 }
189}
190
191impl<const LENGTH: usize> MutBytes for [u8; LENGTH] {
192 #[inline]
193 fn as_mut_slice(&mut self) -> &mut [u8] {
194 self
195 }
196
197 fn copy_from_slice(&mut self, other: &[u8]) {
198 <[u8]>::copy_from_slice(self, other)
199 }
200}
201
202impl Bytes for Vec<u8> {
203 #[inline]
204 fn as_slice(&self) -> &[u8] {
205 self.as_slice()
206 }
207
208 #[inline]
209 fn len(&self) -> usize {
210 <[u8]>::len(self)
211 }
212
213 #[inline]
214 fn is_empty(&self) -> bool {
215 <[u8]>::is_empty(self)
216 }
217}
218
219impl NewBytes for Vec<u8> {
220 fn new_bytes() -> Self {
221 vec![]
222 }
223}
224
225impl MutBytes for Vec<u8> {
226 #[inline]
227 fn as_mut_slice(&mut self) -> &mut [u8] {
228 self.as_mut_slice()
229 }
230
231 fn copy_from_slice(&mut self, other: &[u8]) {
232 <[u8]>::copy_from_slice(self, other)
233 }
234}
235
236impl ResizableBytes for Vec<u8> {
237 fn resize(&mut self, new_len: usize, value: u8) {
238 self.resize(new_len, value);
239 }
240}
241
242impl Bytes for [u8] {
243 #[inline]
244 fn as_slice(&self) -> &[u8] {
245 self
246 }
247
248 #[inline]
249 fn len(&self) -> usize {
250 <[u8]>::len(self)
251 }
252
253 #[inline]
254 fn is_empty(&self) -> bool {
255 <[u8]>::is_empty(self)
256 }
257}
258
259impl Bytes for &[u8] {
260 #[inline]
261 fn as_slice(&self) -> &[u8] {
262 self
263 }
264
265 #[inline]
266 fn len(&self) -> usize {
267 <[u8]>::len(self)
268 }
269
270 #[inline]
271 fn is_empty(&self) -> bool {
272 <[u8]>::is_empty(self)
273 }
274}
275
276impl Bytes for &mut [u8] {
277 #[inline]
278 fn as_slice(&self) -> &[u8] {
279 self
280 }
281
282 #[inline]
283 fn len(&self) -> usize {
284 <[u8]>::len(self)
285 }
286
287 #[inline]
288 fn is_empty(&self) -> bool {
289 <[u8]>::is_empty(self)
290 }
291}
292
293impl<const LENGTH: usize> Bytes for [u8; LENGTH] {
294 #[inline]
295 fn as_slice(&self) -> &[u8] {
296 self
297 }
298
299 #[inline]
300 fn len(&self) -> usize {
301 <[u8]>::len(self)
302 }
303
304 #[inline]
305 fn is_empty(&self) -> bool {
306 <[u8]>::is_empty(self)
307 }
308}
309
310#[allow(suspicious_double_ref_op)]
311impl<const LENGTH: usize> Bytes for &[u8; LENGTH] {
312 #[inline]
313 fn as_slice(&self) -> &[u8] {
314 self.deref()
315 }
316
317 #[inline]
318 fn len(&self) -> usize {
319 <[u8]>::len(self.deref())
320 }
321
322 #[inline]
323 fn is_empty(&self) -> bool {
324 <[u8]>::is_empty(self.deref())
325 }
326}
327
328impl<const LENGTH: usize> ByteArray<LENGTH> for [u8; LENGTH] {
329 #[inline]
330 fn as_array(&self) -> &[u8; LENGTH] {
331 self
332 }
333}
334
335impl<const LENGTH: usize> ByteArray<LENGTH> for &[u8] {
338 #[inline]
339 fn as_array(&self) -> &[u8; LENGTH] {
340 assert!(
341 self.len() >= LENGTH,
342 "invalid slice length {}, expecting at least {}",
343 self.len(),
344 LENGTH
345 );
346 let arr = self.as_ptr() as *const [u8; LENGTH];
347 unsafe { &*arr }
348 }
349}
350
351impl<const LENGTH: usize> ByteArray<LENGTH> for [u8] {
352 #[inline]
353 fn as_array(&self) -> &[u8; LENGTH] {
354 assert!(
355 self.len() >= LENGTH,
356 "invalid slice length {}, expecting at least {}",
357 self.len(),
358 LENGTH
359 );
360 let arr = self.as_ptr() as *const [u8; LENGTH];
361 unsafe { &*arr }
362 }
363}
364
365impl<const LENGTH: usize> MutByteArray<LENGTH> for [u8] {
366 fn as_mut_array(&mut self) -> &mut [u8; LENGTH] {
367 assert!(
368 self.len() >= LENGTH,
369 "invalid slice length {}, expecting at least {}",
370 self.len(),
371 LENGTH
372 );
373 let arr = self.as_mut_ptr() as *mut [u8; LENGTH];
374 unsafe { &mut *arr }
375 }
376}
377
378impl MutBytes for [u8] {
379 #[inline]
380 fn as_mut_slice(&mut self) -> &mut [u8] {
381 self
382 }
383
384 fn copy_from_slice(&mut self, other: &[u8]) {
385 self.copy_from_slice(other)
386 }
387}
388
389impl<const LENGTH: usize> StackByteArray<LENGTH> {
390 pub fn new() -> Self {
392 Self::default()
393 }
394}
395
396impl<const LENGTH: usize> std::convert::AsRef<[u8; LENGTH]> for StackByteArray<LENGTH> {
397 fn as_ref(&self) -> &[u8; LENGTH] {
398 let arr = self.0.as_ptr() as *const [u8; LENGTH];
399 unsafe { &*arr }
400 }
401}
402
403impl<const LENGTH: usize> std::convert::AsMut<[u8; LENGTH]> for StackByteArray<LENGTH> {
404 fn as_mut(&mut self) -> &mut [u8; LENGTH] {
405 let arr = self.0.as_mut_ptr() as *mut [u8; LENGTH];
406 unsafe { &mut *arr }
407 }
408}
409
410impl<const LENGTH: usize> std::convert::AsRef<[u8]> for StackByteArray<LENGTH> {
411 fn as_ref(&self) -> &[u8] {
412 self.0.as_ref()
413 }
414}
415
416impl<const LENGTH: usize> std::convert::AsMut<[u8]> for StackByteArray<LENGTH> {
417 fn as_mut(&mut self) -> &mut [u8] {
418 self.0.as_mut()
419 }
420}
421
422impl<const LENGTH: usize> std::ops::Deref for StackByteArray<LENGTH> {
423 type Target = [u8];
424
425 fn deref(&self) -> &Self::Target {
426 &self.0
427 }
428}
429
430impl<const LENGTH: usize> std::ops::DerefMut for StackByteArray<LENGTH> {
431 fn deref_mut(&mut self) -> &mut Self::Target {
432 &mut self.0
433 }
434}
435
436impl<const LENGTH: usize> std::ops::Index<usize> for StackByteArray<LENGTH> {
437 type Output = u8;
438
439 #[inline]
440 fn index(&self, index: usize) -> &Self::Output {
441 &self.0[index]
442 }
443}
444impl<const LENGTH: usize> std::ops::IndexMut<usize> for StackByteArray<LENGTH> {
445 #[inline]
446 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
447 &mut self.0[index]
448 }
449}
450
451macro_rules! impl_index {
452 ($range:ty) => {
453 impl<const LENGTH: usize> std::ops::Index<$range> for StackByteArray<LENGTH> {
454 type Output = [u8];
455
456 #[inline]
457 fn index(&self, index: $range) -> &Self::Output {
458 &self.0[index]
459 }
460 }
461 impl<const LENGTH: usize> std::ops::IndexMut<$range> for StackByteArray<LENGTH> {
462 #[inline]
463 fn index_mut(&mut self, index: $range) -> &mut Self::Output {
464 &mut self.0[index]
465 }
466 }
467 };
468}
469
470impl_index!(std::ops::Range<usize>);
471impl_index!(std::ops::RangeFull);
472impl_index!(std::ops::RangeFrom<usize>);
473impl_index!(std::ops::RangeInclusive<usize>);
474impl_index!(std::ops::RangeTo<usize>);
475impl_index!(std::ops::RangeToInclusive<usize>);
476
477impl<const LENGTH: usize> Default for StackByteArray<LENGTH> {
478 fn default() -> Self {
479 Self([0u8; LENGTH])
480 }
481}
482
483impl<const LENGTH: usize> From<&[u8; LENGTH]> for StackByteArray<LENGTH> {
484 fn from(src: &[u8; LENGTH]) -> Self {
485 let mut arr = Self::default();
486 arr.0.copy_from_slice(src);
487 arr
488 }
489}
490
491impl<const LENGTH: usize> From<[u8; LENGTH]> for StackByteArray<LENGTH> {
492 fn from(src: [u8; LENGTH]) -> Self {
493 Self::from(&src)
494 }
495}
496
497impl<const LENGTH: usize> TryFrom<&[u8]> for StackByteArray<LENGTH> {
498 type Error = crate::error::Error;
499
500 fn try_from(src: &[u8]) -> Result<Self, Self::Error> {
501 if src.len() != LENGTH {
502 Err(dryoc_error!(format!(
503 "Invalid size: expected {} found {}",
504 LENGTH,
505 src.len()
506 )))
507 } else {
508 let mut arr = Self::default();
509 arr.0.copy_from_slice(src);
510 Ok(arr)
511 }
512 }
513}
514
515#[cfg(test)]
516mod tests {
517 use super::*;
518
519 #[test]
520 #[should_panic(expected = "invalid vec length 2, expecting at least 3")]
521 fn test_vec_as_array_out_of_bounds_panic() {
522 let vec = vec![1, 2];
523 let _ = <Vec<u8> as ByteArray<3>>::as_array(&vec)[2];
524 }
525
526 #[test]
527 fn test_vec_as_array_out_of_bounds_ok() {
528 let vec = vec![1, 2];
529 let _ = <Vec<u8> as ByteArray<2>>::as_array(&vec)[1];
530 }
531
532 #[test]
533 #[should_panic(expected = "invalid vec length 2, expecting at least 3")]
534 fn test_vec_as_mut_array_out_of_bounds_panic() {
535 let mut vec = vec![1, 2];
536 let _ = <Vec<u8> as MutByteArray<3>>::as_mut_array(&mut vec)[2];
537 }
538
539 #[test]
540 fn test_vec_as_mut_array_out_of_bounds_ok() {
541 let mut vec = vec![1, 2];
542 let _ = <Vec<u8> as MutByteArray<2>>::as_mut_array(&mut vec)[1];
543 }
544}