aes/backends/fixslice/
aes256.rs1use super::{BatchBlocks, State, Word, mix_columns::*, sbox::*, utils::*};
2
3pub(crate) type RoundKeys<W> = [W; 120];
5
6pub(crate) fn key_schedule<W: Word>(key: &[u8; 32]) -> RoundKeys<W> {
8 let mut rkeys = [W::default(); 120];
9
10 W::bitslice(&mut rkeys[..8], &broadcast::<W>(&key[..16]));
11 W::bitslice(&mut rkeys[8..16], &broadcast::<W>(&key[16..]));
12
13 let mut rk_off = 8;
14
15 let mut rcon = 0;
16 loop {
17 memshift32(&mut rkeys, rk_off);
18 rk_off += 8;
19
20 sub_bytes(&mut rkeys[rk_off..(rk_off + 8)]);
21 sub_bytes_nots(&mut rkeys[rk_off..(rk_off + 8)]);
22
23 add_round_constant_bit(&mut rkeys[rk_off..(rk_off + 8)], rcon);
24 xor_columns(&mut rkeys, rk_off, 16, W::ror_distance(1, 3));
25 rcon += 1;
26
27 if rcon == 7 {
28 break;
29 }
30
31 memshift32(&mut rkeys, rk_off);
32 rk_off += 8;
33
34 sub_bytes(&mut rkeys[rk_off..(rk_off + 8)]);
35 sub_bytes_nots(&mut rkeys[rk_off..(rk_off + 8)]);
36
37 xor_columns(&mut rkeys, rk_off, 16, W::ror_distance(0, 3));
38 }
39
40 #[cfg(aes_backend_soft = "compact")]
42 {
43 for i in (8..120).step_by(16) {
44 inv_shift_rows_1(&mut rkeys[i..(i + 8)]);
45 }
46 }
47 #[cfg(not(aes_backend_soft = "compact"))]
48 {
49 for i in (8..104).step_by(32) {
50 inv_shift_rows_1(&mut rkeys[i..(i + 8)]);
51 inv_shift_rows_2(&mut rkeys[(i + 8)..(i + 16)]);
52 inv_shift_rows_3(&mut rkeys[(i + 16)..(i + 24)]);
53 }
54 inv_shift_rows_1(&mut rkeys[104..112]);
55 }
56
57 for i in 1..15 {
59 sub_bytes_nots(&mut rkeys[(i * 8)..(i * 8 + 8)]);
60 }
61
62 rkeys
63}
64
65pub(crate) fn encrypt<W: Word>(rkeys: &RoundKeys<W>, blocks: &BatchBlocks<W>) -> BatchBlocks<W> {
69 let mut state = State::<W>::default();
70
71 W::bitslice(&mut state, blocks);
72
73 add_round_key(&mut state, &rkeys[..8]);
74
75 let mut rk_off = 8;
76 loop {
77 sub_bytes(&mut state);
78 mix_columns_1(&mut state);
79 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
80 rk_off += 8;
81
82 #[cfg(aes_backend_soft = "compact")]
83 {
84 shift_rows_2(&mut state);
85 }
86
87 if rk_off == 112 {
88 break;
89 }
90
91 #[cfg(not(aes_backend_soft = "compact"))]
92 {
93 sub_bytes(&mut state);
94 mix_columns_2(&mut state);
95 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
96 rk_off += 8;
97
98 sub_bytes(&mut state);
99 mix_columns_3(&mut state);
100 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
101 rk_off += 8;
102 }
103
104 sub_bytes(&mut state);
105 mix_columns_0(&mut state);
106 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
107 rk_off += 8;
108 }
109
110 #[cfg(not(aes_backend_soft = "compact"))]
111 {
112 shift_rows_2(&mut state);
113 }
114
115 sub_bytes(&mut state);
116 add_round_key(&mut state, &rkeys[112..]);
117
118 W::inv_bitslice(&state)
119}
120
121pub(crate) fn decrypt<W: Word>(rkeys: &RoundKeys<W>, blocks: &BatchBlocks<W>) -> BatchBlocks<W> {
125 let mut state = State::<W>::default();
126
127 W::bitslice(&mut state, blocks);
128
129 add_round_key(&mut state, &rkeys[112..]);
130 inv_sub_bytes(&mut state);
131
132 #[cfg(not(aes_backend_soft = "compact"))]
133 {
134 inv_shift_rows_2(&mut state);
135 }
136
137 let mut rk_off = 104;
138 loop {
139 #[cfg(aes_backend_soft = "compact")]
140 {
141 inv_shift_rows_2(&mut state);
142 }
143
144 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
145 inv_mix_columns_1(&mut state);
146 inv_sub_bytes(&mut state);
147 rk_off -= 8;
148
149 if rk_off == 0 {
150 break;
151 }
152
153 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
154 inv_mix_columns_0(&mut state);
155 inv_sub_bytes(&mut state);
156 rk_off -= 8;
157
158 #[cfg(not(aes_backend_soft = "compact"))]
159 {
160 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
161 inv_mix_columns_3(&mut state);
162 inv_sub_bytes(&mut state);
163 rk_off -= 8;
164
165 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
166 inv_mix_columns_2(&mut state);
167 inv_sub_bytes(&mut state);
168 rk_off -= 8;
169 }
170 }
171
172 add_round_key(&mut state, &rkeys[..8]);
173
174 W::inv_bitslice(&state)
175}