1use crate::aes::{aes_128, aes_192, aes_256};
5use std::convert::TryInto;
6
7const BLOCKLEN: usize = 16; pub fn aes_ctr(key: &[u8], data: &mut [u8], nonce: u128) {
25 let mut counter = 0u128;
26 for block in data.chunks_mut(BLOCKLEN) {
27 let counter_block: [u8; BLOCKLEN] = (nonce.wrapping_add(counter)).to_be_bytes();
29
30 println!("Counter Block: {:x?}", counter_block);
32 let encrypted_counter_block = match key.len() {
33 16 => aes_128(key.try_into().unwrap(), counter_block, true),
34 24 => aes_192(key.try_into().unwrap(), counter_block, true),
35 32 => aes_256(key.try_into().unwrap(), counter_block, true),
36 _ => panic!("Invalid key length. Must be 128, 192, or 256 bits."),
37 };
38 println!("Encrypted Counter Block: {:x?}", encrypted_counter_block);
39
40 println!("Data Block Before XOR: {:x?}", block);
42 block.iter_mut().enumerate().for_each(|(i, byte)| {
43 *byte ^= encrypted_counter_block[i];
44 });
45 println!("Data Block After XOR: {:x?}", block);
46
47 counter += 1;
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
59 fn test_aes_128_ctr() {
60 let key: [u8; 16] = [
61 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
62 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
63 ];
64 let plaintext: [u8; 64] = [
65 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
66 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
67 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
68 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
69 ];
70 let nonce: u128 = 0xF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF;
71
72 let exp_ciphertext: [u8; 64] = [
73 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE,
74 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF,
75 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB,
76 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE
77 ];
78 test_aes_ctr_comm(&key, plaintext, exp_ciphertext, nonce);
79 }
80
81 #[test]
82 fn test_aes_192_ctr() {
83 let key: [u8; 24] = [
84 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, 0xC8, 0x10, 0xF3, 0x2B,
85 0x80, 0x90, 0x79, 0xE5, 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B
86 ];
87 let plaintext: [u8; 64] = [
88 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
89 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
90 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
91 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
92 ];
93 let nonce: u128 = 0xF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF;
94
95 let exp_ciphertext: [u8; 64] = [
96 0x1A, 0xBC, 0x93, 0x24, 0x17, 0x52, 0x1C, 0xA2, 0x4F, 0x2B, 0x04, 0x59, 0xFE, 0x7E, 0x6E, 0x0B,
97 0x09, 0x03, 0x39, 0xEC, 0x0A, 0xA6, 0xFA, 0xEF, 0xD5, 0xCC, 0xC2, 0xC6, 0xF4, 0xCE, 0x8E, 0x94,
98 0x1E, 0x36, 0xB2, 0x6B, 0xD1, 0xEB, 0xC6, 0x70, 0xD1, 0xBD, 0x1D, 0x66, 0x56, 0x20, 0xAB, 0xF7,
99 0x4F, 0x78, 0xA7, 0xF6, 0xD2, 0x98, 0x09, 0x58, 0x5A, 0x97, 0xDA, 0xEC, 0x58, 0xC6, 0xB0, 0x50
100 ];
101 test_aes_ctr_comm(&key, plaintext, exp_ciphertext, nonce);
102 }
103
104 #[test]
105 fn test_aes_256_ctr() {
106 let key: [u8; 32] = [
107 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
108 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4
109 ];
110 let plaintext: [u8; 64] = [
111 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
112 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
113 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
114 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
115 ];
116 let nonce: u128 = 0xF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF;
117
118 let exp_ciphertext: [u8; 64] = [
119 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28,
120 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5,
121 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D,
122 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6
123 ];
124 test_aes_ctr_comm(&key, plaintext, exp_ciphertext, nonce);
125 }
126
127 fn test_aes_ctr_comm(key: &[u8], plaintext: [u8; 64], exp_ciphertext: [u8; 64], nonce: u128) {
128 println!("---------------------Before Encryption:---------------------\n");
129 println!("plaintext: {:x?}", plaintext);
130 println!("key: {:x?}", key);
131 println!("nonce: {:x?}", nonce);
132
133 let mut act_ciphertext: [u8; 64] = plaintext;
134 aes_ctr(key, &mut act_ciphertext, nonce);
135
136 println!("---------------------After Encryption:---------------------\n");
137 println!("actual ciphertext: {:x?}", act_ciphertext);
138 println!("expected ciphertext: {:x?}\n", exp_ciphertext);
139 assert_eq!(exp_ciphertext, act_ciphertext);
140
141 let mut act_plaintext = act_ciphertext;
142 aes_ctr(key, &mut act_plaintext, nonce);
143
144 println!("---------------------After Decryption:---------------------\n");
145 println!("actual plaintext: {:x?}", act_plaintext);
146 println!("expected plaintext: {:x?}", plaintext);
147 assert_eq!(plaintext, act_plaintext);
148 }
149}