1 // Copyright 2018 Brian Smith.
2 //
3 // Permission to use, copy, modify, and/or distribute this software for any
4 // purpose with or without fee is hereby granted, provided that the above
5 // copyright notice and this permission notice appear in all copies.
6 //
7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10 // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 
15 use crate::endian::*;
16 use core::ops::{BitXor, BitXorAssign};
17 
18 #[repr(transparent)]
19 #[derive(Copy, Clone)]
20 pub struct Block([BigEndian<u64>; 2]);
21 
22 pub const BLOCK_LEN: usize = 16;
23 
24 impl Block {
25     #[inline]
zero() -> Self26     pub fn zero() -> Self {
27         Self([Encoding::ZERO; 2])
28     }
29 
30     #[inline]
overwrite_part_at(&mut self, index: usize, a: &[u8])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]
zero_from(&mut self, index: usize)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 
45 impl From<[u64; 2]> for Block {
46     #[inline]
from(other: [u64; 2]) -> Self47     fn from(other: [u64; 2]) -> Self {
48         Self([other[0].into(), other[1].into()])
49     }
50 }
51 
52 impl From<Block> for [u64; 2] {
53     #[inline]
from(Block(components): Block) -> Self54     fn from(Block(components): Block) -> Self {
55         components.map(Into::into)
56     }
57 }
58 
59 impl BitXorAssign for Block {
60     #[inline]
bitxor_assign(&mut self, a: Self)61     fn bitxor_assign(&mut self, a: Self) {
62         for (r, a) in self.0.iter_mut().zip(a.0.iter()) {
63             *r ^= *a;
64         }
65     }
66 }
67 
68 impl BitXor for Block {
69     type Output = Self;
70 
71     #[inline]
bitxor(self, a: Self) -> Self72     fn bitxor(self, a: Self) -> Self {
73         let mut r = self;
74         r.bitxor_assign(a);
75         r
76     }
77 }
78 
79 impl From<&'_ [u8; BLOCK_LEN]> for Block {
80     #[inline]
from(bytes: &[u8; BLOCK_LEN]) -> Self81     fn from(bytes: &[u8; BLOCK_LEN]) -> Self {
82         Self(FromByteArray::from_byte_array(bytes))
83     }
84 }
85 
86 impl AsRef<[u8; BLOCK_LEN]> for Block {
87     #[inline]
as_ref(&self) -> &[u8; BLOCK_LEN]88     fn as_ref(&self) -> &[u8; BLOCK_LEN] {
89         self.0.as_byte_array()
90     }
91 }
92