1use crate::errors::InvalidLength;
13use core::convert::TryInto;
14use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
15
16pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
18
19pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;
21
22pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;
24
25pub trait NewBlockCipher: Sized {
27 type KeySize: ArrayLength<u8>;
29
30 fn new(key: &BlockCipherKey<Self>) -> Self;
32
33 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
38 if key.len() != Self::KeySize::to_usize() {
39 Err(InvalidLength)
40 } else {
41 Ok(Self::new(GenericArray::from_slice(key)))
42 }
43 }
44}
45
46pub trait BlockCipher {
48 type BlockSize: ArrayLength<u8>;
50
51 type ParBlocks: ArrayLength<Block<Self>>;
54}
55
56pub trait BlockEncrypt: BlockCipher {
58 fn encrypt_block(&self, block: &mut Block<Self>);
60
61 #[inline]
66 fn encrypt_par_blocks(&self, blocks: &mut ParBlocks<Self>) {
67 for block in blocks.iter_mut() {
68 self.encrypt_block(block);
69 }
70 }
71
72 #[inline]
74 fn encrypt_blocks(&self, mut blocks: &mut [Block<Self>]) {
75 let pb = Self::ParBlocks::to_usize();
76
77 if pb > 1 {
78 let mut iter = blocks.chunks_exact_mut(pb);
79
80 for chunk in &mut iter {
81 self.encrypt_par_blocks(chunk.try_into().unwrap())
82 }
83
84 blocks = iter.into_remainder();
85 }
86
87 for block in blocks {
88 self.encrypt_block(block);
89 }
90 }
91}
92
93pub trait BlockDecrypt: BlockCipher {
95 fn decrypt_block(&self, block: &mut Block<Self>);
97
98 #[inline]
103 fn decrypt_par_blocks(&self, blocks: &mut ParBlocks<Self>) {
104 for block in blocks.iter_mut() {
105 self.decrypt_block(block);
106 }
107 }
108
109 #[inline]
111 fn decrypt_blocks(&self, mut blocks: &mut [Block<Self>]) {
112 let pb = Self::ParBlocks::to_usize();
113
114 if pb > 1 {
115 let mut iter = blocks.chunks_exact_mut(pb);
116
117 for chunk in &mut iter {
118 self.decrypt_par_blocks(chunk.try_into().unwrap())
119 }
120
121 blocks = iter.into_remainder();
122 }
123
124 for block in blocks {
125 self.decrypt_block(block);
126 }
127 }
128}
129
130pub trait BlockEncryptMut: BlockCipher {
135 fn encrypt_block_mut(&mut self, block: &mut Block<Self>);
137}
138
139pub trait BlockDecryptMut: BlockCipher {
144 fn decrypt_block_mut(&mut self, block: &mut Block<Self>);
146}
147
148impl<Alg: BlockEncrypt> BlockEncryptMut for Alg {
149 fn encrypt_block_mut(&mut self, block: &mut Block<Self>) {
150 self.encrypt_block(block);
151 }
152}
153
154impl<Alg: BlockDecrypt> BlockDecryptMut for Alg {
155 fn decrypt_block_mut(&mut self, block: &mut Block<Self>) {
156 self.decrypt_block(block);
157 }
158}
159
160impl<Alg: BlockCipher> BlockCipher for &Alg {
163 type BlockSize = Alg::BlockSize;
164 type ParBlocks = Alg::ParBlocks;
165}
166
167impl<Alg: BlockEncrypt> BlockEncrypt for &Alg {
168 #[inline]
169 fn encrypt_block(&self, block: &mut Block<Self>) {
170 Alg::encrypt_block(self, block);
171 }
172
173 #[inline]
174 fn encrypt_par_blocks(&self, blocks: &mut ParBlocks<Self>) {
175 Alg::encrypt_par_blocks(self, blocks);
176 }
177
178 #[inline]
179 fn encrypt_blocks(&self, blocks: &mut [Block<Self>]) {
180 Alg::encrypt_blocks(self, blocks);
181 }
182}
183
184impl<Alg: BlockDecrypt> BlockDecrypt for &Alg {
185 #[inline]
186 fn decrypt_block(&self, block: &mut Block<Self>) {
187 Alg::decrypt_block(self, block);
188 }
189
190 #[inline]
191 fn decrypt_par_blocks(&self, blocks: &mut ParBlocks<Self>) {
192 Alg::decrypt_par_blocks(self, blocks);
193 }
194
195 #[inline]
196 fn decrypt_blocks(&self, blocks: &mut [Block<Self>]) {
197 Alg::decrypt_blocks(self, blocks);
198 }
199}