1use crate::polyfill::ArrayFlatten;
16use core::ops::{BitXor, BitXorAssign};
17
18#[repr(transparent)]
19#[derive(Copy, Clone)]
20pub struct Block([u8; 16]);
21
22pub const BLOCK_LEN: usize = 16;
23
24impl Block {
25 #[inline]
26 pub fn zero() -> Self {
27 Self([0; 16])
28 }
29
30 #[inline]
31 pub fn overwrite_part_at(&mut self, index: usize, a: &[u8]) {
32 let mut tmp: [u8; BLOCK_LEN] = *self.as_ref();
33 tmp[index..][..a.len()].copy_from_slice(a);
34 *self = Self::from(&tmp)
35 }
36
37 #[inline]
38 pub fn zero_from(&mut self, index: usize) {
39 let mut tmp: [u8; BLOCK_LEN] = *self.as_ref();
40 tmp[index..].fill(0);
41 *self = Self::from(&tmp)
42 }
43}
44
45impl BitXorAssign for Block {
46 #[inline]
47 fn bitxor_assign(&mut self, a: Self) {
48 for (r, a) in self.0.iter_mut().zip(a.0.iter()) {
51 *r ^= *a;
52 }
53 }
54}
55
56impl BitXor for Block {
57 type Output = Self;
58
59 #[inline]
60 fn bitxor(self, a: Self) -> Self {
61 let mut r = self;
62 r.bitxor_assign(a);
63 r
64 }
65}
66
67impl<T> From<T> for Block
68where
69 T: ArrayFlatten<Output = [u8; 16]>,
70{
71 #[inline]
72 fn from(bytes: T) -> Self {
73 Self(bytes.array_flatten())
74 }
75}
76
77impl From<&'_ [u8; BLOCK_LEN]> for Block {
78 #[inline]
79 fn from(bytes: &[u8; BLOCK_LEN]) -> Self {
80 Self(*bytes)
81 }
82}
83
84impl AsRef<[u8; BLOCK_LEN]> for Block {
85 #[inline]
86 fn as_ref(&self) -> &[u8; BLOCK_LEN] {
87 &self.0
88 }
89}