literate_crypto/cipher/block/modes/
ecb.rs1use {
2 crate::{
3 BlockCipher,
4 BlockDecrypt,
5 BlockEncrypt,
6 BlockMode,
7 Cipher,
8 CipherDecrypt,
9 CipherEncrypt,
10 Padding,
11 },
12 std::{convert::Infallible, fmt},
13};
14
15#[derive(Debug)]
30pub struct Ecb<Cip, Pad> {
31 cip: Cip,
32 pad: Pad,
33}
34
35impl<Cip: BlockCipher, Pad: Padding> Ecb<Cip, Pad> {
36 pub fn new(cip: Cip, pad: Pad) -> Self {
37 Self { cip, pad }
38 }
39}
40
41impl<Cip: BlockCipher, Pad: Padding> Cipher for Ecb<Cip, Pad>
42where
43 Cip::Block: for<'a> TryFrom<&'a mut [u8], Error: fmt::Debug> + AsRef<[u8]>,
44 Cip::Key: Clone,
45{
46 type Key = Cip::Key;
47}
48
49impl<Cip: BlockCipher, Pad: Padding> BlockMode for Ecb<Cip, Pad>
50where
51 Cip::Block: for<'a> TryFrom<&'a mut [u8], Error: fmt::Debug> + AsRef<[u8]>,
52 Cip::Key: Clone,
53{
54}
55
56impl<Enc: BlockEncrypt, Pad: Padding> CipherEncrypt for Ecb<Enc, Pad>
57where
58 Enc::EncryptionBlock: for<'a> TryFrom<&'a mut [u8], Error: fmt::Debug> + AsRef<[u8]>,
59 Enc::EncryptionKey: Clone,
60{
61 type EncryptionErr = Infallible;
62 type EncryptionKey = Enc::EncryptionKey;
63
64 fn encrypt(
65 &self,
66 data: Vec<u8>,
67 key: Self::EncryptionKey,
68 ) -> Result<Vec<u8>, Self::EncryptionErr> {
69 let block_size = std::mem::size_of::<Enc::EncryptionBlock>();
71 let mut data = self.pad.pad(data, block_size);
72 for chunk in data.chunks_mut(block_size) {
73 let block = chunk.try_into().unwrap();
74 chunk.copy_from_slice(self.cip.encrypt(block, key.clone()).as_ref());
75 }
76 Ok(data)
77 }
78}
79
80impl<Dec: BlockDecrypt, Pad: Padding> CipherDecrypt for Ecb<Dec, Pad>
81where
82 Dec::DecryptionBlock: for<'a> TryFrom<&'a mut [u8], Error: fmt::Debug> + AsRef<[u8]>,
83 Dec::DecryptionKey: Clone,
84{
85 type DecryptionErr = Pad::Err;
86 type DecryptionKey = Dec::DecryptionKey;
87
88 fn decrypt(
89 &self,
90 mut data: Vec<u8>,
91 key: Self::DecryptionKey,
92 ) -> Result<Vec<u8>, Self::DecryptionErr> {
93 let block_size = std::mem::size_of::<Dec::DecryptionBlock>();
95 for chunk in data.chunks_mut(block_size) {
96 let block = chunk.try_into().unwrap();
97 chunk.copy_from_slice(self.cip.decrypt(block, key.clone()).as_ref());
98 }
99 self.pad.unpad(data, block_size)
100 }
101}