1use super::{State, Word};
2
3macro_rules! define_mix_columns {
8 (
9 $name:ident,
10 $name_inv:ident,
11 $first_rotate:path,
12 $second_rotate:path
13 ) => {
14 #[rustfmt::skip]
15 pub(super) fn $name<W: Word>(state: &mut State<W>) {
16 let (a0, a1, a2, a3, a4, a5, a6, a7) = (
17 state[0], state[1], state[2], state[3], state[4], state[5], state[6], state[7]
18 );
19 let (b0, b1, b2, b3, b4, b5, b6, b7) = (
20 $first_rotate(a0),
21 $first_rotate(a1),
22 $first_rotate(a2),
23 $first_rotate(a3),
24 $first_rotate(a4),
25 $first_rotate(a5),
26 $first_rotate(a6),
27 $first_rotate(a7),
28 );
29 let (c0, c1, c2, c3, c4, c5, c6, c7) = (
30 a0 ^ b0,
31 a1 ^ b1,
32 a2 ^ b2,
33 a3 ^ b3,
34 a4 ^ b4,
35 a5 ^ b5,
36 a6 ^ b6,
37 a7 ^ b7,
38 );
39 state[0] = b0 ^ c7 ^ $second_rotate(c0);
40 state[1] = b1 ^ c0 ^ c7 ^ $second_rotate(c1);
41 state[2] = b2 ^ c1 ^ $second_rotate(c2);
42 state[3] = b3 ^ c2 ^ c7 ^ $second_rotate(c3);
43 state[4] = b4 ^ c3 ^ c7 ^ $second_rotate(c4);
44 state[5] = b5 ^ c4 ^ $second_rotate(c5);
45 state[6] = b6 ^ c5 ^ $second_rotate(c6);
46 state[7] = b7 ^ c6 ^ $second_rotate(c7);
47 }
48
49 #[rustfmt::skip]
50 pub(super) fn $name_inv<W: Word>(state: &mut State<W>) {
51 let (a0, a1, a2, a3, a4, a5, a6, a7) = (
52 state[0], state[1], state[2], state[3], state[4], state[5], state[6], state[7]
53 );
54 let (b0, b1, b2, b3, b4, b5, b6, b7) = (
55 $first_rotate(a0),
56 $first_rotate(a1),
57 $first_rotate(a2),
58 $first_rotate(a3),
59 $first_rotate(a4),
60 $first_rotate(a5),
61 $first_rotate(a6),
62 $first_rotate(a7),
63 );
64 let (c0, c1, c2, c3, c4, c5, c6, c7) = (
65 a0 ^ b0,
66 a1 ^ b1,
67 a2 ^ b2,
68 a3 ^ b3,
69 a4 ^ b4,
70 a5 ^ b5,
71 a6 ^ b6,
72 a7 ^ b7,
73 );
74 let (d0, d1, d2, d3, d4, d5, d6, d7) = (
75 a0 ^ c7,
76 a1 ^ c0 ^ c7,
77 a2 ^ c1,
78 a3 ^ c2 ^ c7,
79 a4 ^ c3 ^ c7,
80 a5 ^ c4,
81 a6 ^ c5,
82 a7 ^ c6,
83 );
84 let (e0, e1, e2, e3, e4, e5, e6, e7) = (
85 c0 ^ d6,
86 c1 ^ d6 ^ d7,
87 c2 ^ d0 ^ d7,
88 c3 ^ d1 ^ d6,
89 c4 ^ d2 ^ d6 ^ d7,
90 c5 ^ d3 ^ d7,
91 c6 ^ d4,
92 c7 ^ d5,
93 );
94 state[0] = d0 ^ e0 ^ $second_rotate(e0);
95 state[1] = d1 ^ e1 ^ $second_rotate(e1);
96 state[2] = d2 ^ e2 ^ $second_rotate(e2);
97 state[3] = d3 ^ e3 ^ $second_rotate(e3);
98 state[4] = d4 ^ e4 ^ $second_rotate(e4);
99 state[5] = d5 ^ e5 ^ $second_rotate(e5);
100 state[6] = d6 ^ e6 ^ $second_rotate(e6);
101 state[7] = d7 ^ e7 ^ $second_rotate(e7);
102 }
103 };
104}
105
106define_mix_columns!(
107 mix_columns_0,
108 inv_mix_columns_0,
109 rotate_rows_1,
110 rotate_rows_2
111);
112
113define_mix_columns!(
114 mix_columns_1,
115 inv_mix_columns_1,
116 rotate_rows_and_columns_1_1,
117 rotate_rows_and_columns_2_2
118);
119
120#[cfg(not(aes_backend_soft = "compact"))]
121define_mix_columns!(
122 mix_columns_2,
123 inv_mix_columns_2,
124 rotate_rows_and_columns_1_2,
125 rotate_rows_2
126);
127
128#[cfg(not(aes_backend_soft = "compact"))]
129define_mix_columns!(
130 mix_columns_3,
131 inv_mix_columns_3,
132 rotate_rows_and_columns_1_3,
133 rotate_rows_and_columns_2_2
134);
135
136#[inline(always)]
137fn rotate_rows_1<W: Word>(x: W) -> W {
138 x.ror(W::ror_distance(1, 0))
139}
140
141#[inline(always)]
142fn rotate_rows_2<W: Word>(x: W) -> W {
143 x.ror(W::ror_distance(2, 0))
144}
145
146#[inline(always)]
147fn rotate_rows_and_columns_1_1<W: Word>(x: W) -> W {
148 let a = x.ror(W::ror_distance(1, 1)) & W::uniform_row(0x3f);
149 let b = x.ror(W::ror_distance(0, 1)) & W::uniform_row(0xc0);
150 a | b
151}
152
153#[cfg(not(aes_backend_soft = "compact"))]
154#[inline(always)]
155fn rotate_rows_and_columns_1_2<W: Word>(x: W) -> W {
156 let a = x.ror(W::ror_distance(1, 2)) & W::uniform_row(0x0f);
157 let b = x.ror(W::ror_distance(0, 2)) & W::uniform_row(0xf0);
158 a | b
159}
160
161#[cfg(not(aes_backend_soft = "compact"))]
162#[inline(always)]
163fn rotate_rows_and_columns_1_3<W: Word>(x: W) -> W {
164 let a = x.ror(W::ror_distance(1, 3)) & W::uniform_row(0x03);
165 let b = x.ror(W::ror_distance(0, 3)) & W::uniform_row(0xfc);
166 a | b
167}
168
169#[inline(always)]
170fn rotate_rows_and_columns_2_2<W: Word>(x: W) -> W {
171 let a = x.ror(W::ror_distance(2, 2)) & W::uniform_row(0x0f);
172 let b = x.ror(W::ror_distance(1, 2)) & W::uniform_row(0xf0);
173 a | b
174}