Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
aes128.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#include "aes128.hpp"
8
9#include "memory.h"
10#include <array>
11#include <cstddef>
12#include <cstdint>
13
14#include <iostream>
15
16namespace {
17
18static constexpr uint8_t round_constants[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
19
20inline void add_round_key(uint8_t* state, const uint8_t* round_key, const size_t round)
21{
22 for (size_t i = 0; i < 16; i += 4) {
23 for (size_t j = 0; j < 4; ++j) {
24 state[i + j] ^= round_key[(round * 16U) + i + j];
25 }
26 }
27}
28
29inline void xor_with_iv(uint8_t* state, const uint8_t* iv)
30{
31 for (size_t i = 0; i < 16; ++i) {
32 state[i] ^= iv[i];
33 }
34}
35
36void sub_bytes(uint8_t* input)
37{
38 uint8_t i, j;
39 for (i = 0; i < 4; ++i) {
40 for (j = 0; j < 4; ++j) {
41 input[j * 4 + i] = bb::crypto::aes128_sbox[input[j * 4 + i]];
42 }
43 }
44}
45
46void inverse_sub_bytes(uint8_t* input)
47{
48 for (size_t i = 0; i < 4; ++i) {
49 for (size_t j = 0; j < 4; ++j) {
50 input[j * 4 + i] = bb::crypto::aes128_sbox_inverse[input[j * 4 + i]];
51 }
52 }
53}
54
55void shift_rows(uint8_t* input)
56{
57 uint8_t temp;
58
59 temp = input[0 * 4 + 1];
60 input[0 * 4 + 1] = input[1 * 4 + 1];
61 input[1 * 4 + 1] = input[2 * 4 + 1];
62 input[2 * 4 + 1] = input[3 * 4 + 1];
63 input[3 * 4 + 1] = temp;
64
65 temp = input[0 * 4 + 2];
66 input[0 * 4 + 2] = input[2 * 4 + 2];
67 input[2 * 4 + 2] = temp;
68
69 temp = input[1 * 4 + 2];
70 input[1 * 4 + 2] = input[3 * 4 + 2];
71 input[3 * 4 + 2] = temp;
72
73 temp = input[0 * 4 + 3];
74 input[0 * 4 + 3] = input[3 * 4 + 3];
75 input[3 * 4 + 3] = input[2 * 4 + 3];
76 input[2 * 4 + 3] = input[1 * 4 + 3];
77 input[1 * 4 + 3] = temp;
78}
79
80static void inverse_shift_rows(uint8_t* input)
81{
82 uint8_t temp;
83
84 temp = input[3 * 4 + 1];
85 input[3 * 4 + 1] = input[2 * 4 + 1];
86 input[2 * 4 + 1] = input[1 * 4 + 1];
87 input[1 * 4 + 1] = input[0 * 4 + 1];
88 input[0 * 4 + 1] = temp;
89
90 temp = input[0 * 4 + 2];
91 input[0 * 4 + 2] = input[2 * 4 + 2];
92 input[2 * 4 + 2] = temp;
93
94 temp = input[1 * 4 + 2];
95 input[1 * 4 + 2] = input[3 * 4 + 2];
96 input[3 * 4 + 2] = temp;
97
98 temp = input[0 * 4 + 3];
99 input[0 * 4 + 3] = input[1 * 4 + 3];
100 input[1 * 4 + 3] = input[2 * 4 + 3];
101 input[2 * 4 + 3] = input[3 * 4 + 3];
102 input[3 * 4 + 3] = temp;
103}
104
105uint8_t xtime(const uint8_t x)
106{
107 return static_cast<uint8_t>((x << 1) ^ (((x >> 7) & 1) * 0x1b));
108}
109
110uint8_t gf2_8_mul(const uint8_t x, const uint8_t y)
111{
112 const uint8_t t0 = (uint8_t)((y & (uint8_t)1) * x);
113 const uint8_t t1 = (uint8_t)(((y >> (uint8_t)1) & (uint8_t)1) * xtime(x));
114 const uint8_t t2 = (uint8_t)(((y >> (uint8_t)2) & (uint8_t)1) * xtime(xtime(x)));
115 const uint8_t t3 = (uint8_t)(((y >> (uint8_t)3) & (uint8_t)1) * xtime(xtime(xtime(x))));
116 const uint8_t t4 = (uint8_t)(((y >> (uint8_t)4) & (uint8_t)1) * xtime(xtime(xtime(xtime(x)))));
117
118 uint8_t out = t0 ^ t1 ^ t2 ^ t3 ^ t4;
119 return out;
120}
121
122void mix_columns(uint8_t* input)
123{
124 for (uint8_t i = 0; i < 4; ++i) {
125 uint8_t t = input[i * 4 + 0];
126 uint8_t Tmp = input[i * 4 + 0] ^ input[i * 4 + 1] ^ input[i * 4 + 2] ^ input[i * 4 + 3];
127 uint8_t Tm = input[i * 4 + 0] ^ input[i * 4 + 1];
128 Tm = xtime(Tm);
129 input[i * 4 + 0] ^= Tm ^ Tmp;
130 Tm = input[i * 4 + 1] ^ input[i * 4 + 2];
131 Tm = xtime(Tm);
132 input[i * 4 + 1] ^= Tm ^ Tmp;
133 Tm = input[i * 4 + 2] ^ input[i * 4 + 3];
134 Tm = xtime(Tm);
135 input[i * 4 + 2] ^= Tm ^ Tmp;
136 Tm = input[i * 4 + 3] ^ t;
137 Tm = xtime(Tm);
138 input[i * 4 + 3] ^= Tm ^ Tmp;
139 }
140}
141
142void inverse_mix_columns(uint8_t* input)
143{
144 for (uint8_t i = 0; i < 4; ++i) {
145 uint8_t a = input[i * 4 + 0];
146 uint8_t b = input[i * 4 + 1];
147 uint8_t c = input[i * 4 + 2];
148 uint8_t d = input[i * 4 + 3];
149
150 input[i * 4 + 0] = gf2_8_mul(a, 0x0e) ^ gf2_8_mul(b, 0x0b) ^ gf2_8_mul(c, 0x0d) ^ gf2_8_mul(d, 0x09);
151 input[i * 4 + 1] = gf2_8_mul(a, 0x09) ^ gf2_8_mul(b, 0x0e) ^ gf2_8_mul(c, 0x0b) ^ gf2_8_mul(d, 0x0d);
152 input[i * 4 + 2] = gf2_8_mul(a, 0x0d) ^ gf2_8_mul(b, 0x09) ^ gf2_8_mul(c, 0x0e) ^ gf2_8_mul(d, 0x0b);
153 input[i * 4 + 3] = gf2_8_mul(a, 0x0b) ^ gf2_8_mul(b, 0x0d) ^ gf2_8_mul(c, 0x09) ^ gf2_8_mul(d, 0x0e);
154 }
155}
156} // namespace
157
158namespace bb::crypto {
159
160void aes128_expand_key(const uint8_t* key, uint8_t* round_key)
161{
162 uint8_t temp[4]{};
163
164 for (size_t i = 0; i < 16; i += 4) {
165 round_key[i] = key[i];
166 round_key[i + 1] = key[i + 1];
167 round_key[i + 2] = key[i + 2];
168 round_key[i + 3] = key[i + 3];
169 }
170
171 for (size_t i = 4; i < 44; ++i) {
172 size_t k = (i - 1) * 4;
173 temp[0] = round_key[k];
174 temp[1] = round_key[k + 1];
175 temp[2] = round_key[k + 2];
176 temp[3] = round_key[k + 3];
177
178 if ((i & 0x03) == 0) {
179 const uint8_t t = temp[0];
180 temp[0] = temp[1];
181 temp[1] = temp[2];
182 temp[2] = temp[3];
183 temp[3] = t;
184
185 temp[0] = aes128_sbox[temp[0]];
186 temp[1] = aes128_sbox[temp[1]];
187 temp[2] = aes128_sbox[temp[2]];
188 temp[3] = aes128_sbox[temp[3]];
189
190 temp[0] = temp[0] ^ round_constants[i >> 2];
191 }
192 size_t j = i * 4;
193 k = (i - 4) * 4;
194 round_key[j] = round_key[k] ^ temp[0];
195 round_key[j + 1] = round_key[k + 1] ^ temp[1];
196 round_key[j + 2] = round_key[k + 2] ^ temp[2];
197 round_key[j + 3] = round_key[k + 3] ^ temp[3];
198 }
199}
200
201void aes128_inverse_cipher(uint8_t* input, const uint8_t* round_key)
202{
203
204 add_round_key(input, round_key, 10);
205
206 for (size_t round = 9; round > 0; --round) {
207 inverse_shift_rows(input);
208 inverse_sub_bytes(input);
209 add_round_key(input, round_key, round);
210 inverse_mix_columns(input);
211 }
212 inverse_shift_rows(input);
213 inverse_sub_bytes(input);
214 add_round_key(input, round_key, 0);
215}
216
217void aes128_cipher(uint8_t* state, const uint8_t* round_key)
218{
219 add_round_key(state, round_key, 0);
220
221 for (uint8_t round = 1; round < 10; ++round) {
222 sub_bytes(state);
223 shift_rows(state);
224 mix_columns(state);
225 add_round_key(state, round_key, round);
226 }
227
228 sub_bytes(state);
229 shift_rows(state);
230 add_round_key(state, round_key, 10);
231}
232
233void aes128_encrypt_buffer_cbc(uint8_t* buffer, uint8_t* iv, const uint8_t* key, const size_t length)
234{
235 uint8_t round_key[176];
236 aes128_expand_key(key, round_key);
237
238 uint8_t block_state[16]{};
239
240 const size_t num_blocks = (length / 16);
241
242 for (size_t i = 0; i < num_blocks; ++i) {
243 memcpy((void*)block_state, (void*)(buffer + (i * 16)), 16);
244 xor_with_iv(block_state, iv);
245
246 aes128_cipher(block_state, round_key);
247
248 memcpy((void*)(buffer + (i * 16)), (void*)block_state, 16);
249 memcpy((void*)iv, (void*)block_state, 16);
250 }
251}
252
253void aes128_decrypt_buffer_cbc(uint8_t* buffer, uint8_t* iv, const uint8_t* key, const size_t length)
254{
255 uint8_t round_key[176];
256 aes128_expand_key(key, round_key);
257 uint8_t block_state[16]{};
258 const size_t num_blocks = (length / 16);
259
260 uint8_t next_iv[16]{};
261 for (size_t i = 0; i < num_blocks; ++i) {
262 memcpy((void*)block_state, (void*)(buffer + (i * 16)), 16);
263 memcpy((void*)next_iv, (void*)block_state, 16);
264 aes128_inverse_cipher(block_state, round_key);
265 xor_with_iv(block_state, iv);
266 memcpy((void*)(buffer + (i * 16)), (void*)block_state, 16);
267 memcpy((void*)iv, (void*)next_iv, 16);
268 }
269}
270
271} // namespace bb::crypto
FF a
FF b
uint8_t const size_t length
Definition data_store.hpp:9
uint8_t buffer[RANDOM_BUFFER_SIZE]
Definition engine.cpp:34
constexpr uint32_t round_constants[64]
void aes128_inverse_cipher(uint8_t *input, const uint8_t *round_key)
Definition aes128.cpp:201
void aes128_decrypt_buffer_cbc(uint8_t *buffer, uint8_t *iv, const uint8_t *key, const size_t length)
Definition aes128.cpp:253
void aes128_expand_key(const uint8_t *key, uint8_t *round_key)
Definition aes128.cpp:160
void aes128_cipher(uint8_t *state, const uint8_t *round_key)
Definition aes128.cpp:217
void aes128_encrypt_buffer_cbc(uint8_t *buffer, uint8_t *iv, const uint8_t *key, const size_t length)
Definition aes128.cpp:233
void xor_with_iv(byte_pair< Builder > *state, field_t< Builder > *iv)
Definition aes128.cpp:235
void sub_bytes(Builder *ctx, byte_pair< Builder > *state_pairs)
Definition aes128.cpp:218
void add_round_key(byte_pair< Builder > *sparse_state, field_t< Builder > *sparse_round_key, uint64_t round)
Definition aes128.cpp:226
void shift_rows(byte_pair< Builder > *state)
Definition aes128.cpp:169