1use crate::CtrFlavor;
2use cipher::{
3 generic_array::ArrayLength, Block, BlockBackend, BlockClosure, BlockSizeUser, ParBlocks,
4 ParBlocksSizeUser, StreamBackend, StreamClosure,
5};
6
7struct Backend<'a, F, B>
8where
9 F: CtrFlavor<B::BlockSize>,
10 B: BlockBackend,
11{
12 ctr_nonce: &'a mut F::CtrNonce,
13 backend: &'a mut B,
14}
15
16impl<'a, F, B> BlockSizeUser for Backend<'a, F, B>
17where
18 F: CtrFlavor<B::BlockSize>,
19 B: BlockBackend,
20{
21 type BlockSize = B::BlockSize;
22}
23
24impl<'a, F, B> ParBlocksSizeUser for Backend<'a, F, B>
25where
26 F: CtrFlavor<B::BlockSize>,
27 B: BlockBackend,
28{
29 type ParBlocksSize = B::ParBlocksSize;
30}
31
32impl<'a, F, B> StreamBackend for Backend<'a, F, B>
33where
34 F: CtrFlavor<B::BlockSize>,
35 B: BlockBackend,
36{
37 #[inline(always)]
38 fn gen_ks_block(&mut self, block: &mut Block<Self>) {
39 let tmp = F::next_block(self.ctr_nonce);
40 self.backend.proc_block((&tmp, block).into());
41 }
42
43 #[inline(always)]
44 fn gen_par_ks_blocks(&mut self, blocks: &mut ParBlocks<Self>) {
45 let mut tmp = ParBlocks::<Self>::default();
46 for block in tmp.iter_mut() {
47 *block = F::next_block(self.ctr_nonce);
48 }
49 self.backend.proc_par_blocks((&tmp, blocks).into());
50 }
51}
52
53pub(crate) struct Closure<'a, F, BS, SC>
54where
55 F: CtrFlavor<BS>,
56 BS: ArrayLength<u8>,
57 SC: StreamClosure<BlockSize = BS>,
58{
59 pub(crate) ctr_nonce: &'a mut F::CtrNonce,
60 pub(crate) f: SC,
61}
62
63impl<'a, F, BS, SC> BlockSizeUser for Closure<'a, F, BS, SC>
64where
65 F: CtrFlavor<BS>,
66 BS: ArrayLength<u8>,
67 SC: StreamClosure<BlockSize = BS>,
68{
69 type BlockSize = BS;
70}
71
72impl<'a, F, BS, SC> BlockClosure for Closure<'a, F, BS, SC>
73where
74 F: CtrFlavor<BS>,
75 BS: ArrayLength<u8>,
76 SC: StreamClosure<BlockSize = BS>,
77{
78 #[inline(always)]
79 fn call<B: BlockBackend<BlockSize = BS>>(self, backend: &mut B) {
80 let Self { ctr_nonce, f } = self;
81 f.call(&mut Backend::<F, B> { ctr_nonce, backend })
82 }
83}