11/* *
2+ * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
3+ *
4+ * This file is part of libbitcoin.
5+ *
6+ * This program is free software: you can redistribute it and/or modify
7+ * it under the terms of the GNU Affero General Public License as published by
8+ * the Free Software Foundation, either version 3 of the License, or
9+ * (at your option) any later version.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU Affero General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU Affero General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+ #include < bitcoin/system/crypto/aes256.hpp>
20+
21+ #include < bitcoin/system/data/data.hpp>
22+ #include < bitcoin/system/define.hpp>
23+ #include < bitcoin/system/math/math.hpp>
24+
25+ namespace libbitcoin {
26+ namespace system {
27+
28+ BC_PUSH_WARNING (NO_ARRAY_INDEXING)
29+ BC_PUSH_WARNING (NO_DYNAMIC_ARRAY_INDEXING)
30+
31+ // local
32+ // ----------------------------------------------------------------------------
33+ // Derived in part from:
34+ /* *
235 * Byte-oriented AES-256 implementation.
3- * All lookup tables replaced with 'on the fly' calculations.
36+ * All lookup tables replaced with 'on the fly' calculations.
437 *
538 * Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
639 * Other contributors: Hal Finney
1750 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1851 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1952 */
20- #include < bitcoin/system/crypto/aes256.hpp>
21-
22- #include < bitcoin/system/define.hpp>
23- #include < bitcoin/system/data/data.hpp>
24- #include < bitcoin/system/math/math.hpp>
25-
26- namespace libbitcoin {
27- namespace system {
28- namespace aes256 {
29-
30- struct context
31- {
32- secret key;
33- secret enckey;
34- secret deckey;
35- };
3653
3754constexpr size_t rounds = 14 ;
55+ constexpr auto block_size = array_count<aes256::block>;
56+ constexpr auto secret_size = array_count<aes256::secret>;
3857
3958constexpr data_array<to_bits(secret_size)> sbox
4059{
@@ -110,47 +129,48 @@ constexpr data_array<to_bits(secret_size)> sbox_inverse
110129
111130constexpr uint8_t f_enc_key (uint8_t byte) NOEXCEPT
112131{
113- return shift_left (byte) ^ (get_left (byte) ? 0b0001' 1011_u8 : zero);
132+ constexpr auto mask = 0b0001' 1011_u8;
133+ return shift_left (byte) ^ (get_left (byte) ? mask : 0_u8);
114134}
115135
116136constexpr uint8_t f_dec_key (uint8_t byte) NOEXCEPT
117137{
118- return shift_right (byte) ^ (get_right (byte) ? 0b1000' 1101_u8 : zero);
138+ constexpr auto mask = 0b1000' 1101_u8;
139+ return shift_right (byte) ^ (get_right (byte) ? mask : 0_u8);
119140}
120141
121- BC_PUSH_WARNING (NO_ARRAY_INDEXING)
122- BC_PUSH_WARNING (NO_DYNAMIC_ARRAY_INDEXING)
123-
124- constexpr void sub_bytes (block& bytes) NOEXCEPT
142+ constexpr void sub_bytes (aes256::block& bytes) NOEXCEPT
125143{
126144 auto i = block_size;
127145 while (to_bool (i--))
128146 bytes[i] = sbox[bytes[i]];
129147}
130148
131- constexpr void sub_bytes_inverse (block& bytes) NOEXCEPT
149+ constexpr void sub_bytes_inverse (aes256:: block& bytes) NOEXCEPT
132150{
133151 auto i = block_size;
134152 while (to_bool (i--))
135153 bytes[i] = sbox_inverse[bytes[i]];
136154}
137155
138- constexpr void add_round_key_lower (block& bytes, secret& key) NOEXCEPT
156+ constexpr void add_round_key_lower (aes256::block& bytes,
157+ aes256::secret& key) NOEXCEPT
139158{
140159 auto i = block_size;
141160 while (to_bool (i--))
142161 bytes[i] ^= key[i];
143162}
144163
145- constexpr void add_round_key_upper (block& bytes, secret& key) NOEXCEPT
164+ constexpr void add_round_key_upper (aes256::block& bytes,
165+ aes256::secret& key) NOEXCEPT
146166{
147167 auto i = block_size;
148168 while (to_bool (i--))
149169 bytes[i] ^= key[i + block_size];
150170}
151171
152- constexpr void add_round_key_copy (block& bytes, secret& key,
153- secret& copy) NOEXCEPT
172+ constexpr void add_round_key_copy (aes256:: block& bytes, aes256:: secret& key,
173+ aes256:: secret& copy) NOEXCEPT
154174{
155175 auto i = block_size;
156176 while (to_bool (i--))
@@ -162,11 +182,9 @@ constexpr void add_round_key_copy(block& bytes, secret& key,
162182 }
163183}
164184
165- constexpr void shift_rows (block& bytes) NOEXCEPT
185+ constexpr void shift_rows (aes256:: block& bytes) NOEXCEPT
166186{
167- uint8_t i, j;
168-
169- i = bytes[1 ];
187+ auto i = bytes[1 ];
170188 bytes[ 1 ] = bytes[5 ];
171189 bytes[ 5 ] = bytes[9 ];
172190 bytes[ 9 ] = bytes[13 ];
@@ -176,7 +194,7 @@ constexpr void shift_rows(block& bytes) NOEXCEPT
176194 bytes[10 ] = bytes[2 ];
177195 bytes[ 2 ] = i;
178196
179- j = bytes[3 ];
197+ auto j = bytes[3 ];
180198 bytes[ 3 ] = bytes[15 ];
181199 bytes[15 ] = bytes[11 ];
182200 bytes[11 ] = bytes[7 ];
@@ -187,11 +205,9 @@ constexpr void shift_rows(block& bytes) NOEXCEPT
187205 bytes[ 6 ] = j;
188206}
189207
190- constexpr void shift_rows_inverse (block& bytes) NOEXCEPT
208+ constexpr void shift_rows_inverse (aes256:: block& bytes) NOEXCEPT
191209{
192- uint8_t i, j;
193-
194- i = bytes[1 ];
210+ auto i = bytes[1 ];
195211 bytes[ 1 ] = bytes[13 ];
196212 bytes[13 ] = bytes[9 ];
197213 bytes[ 9 ] = bytes[5 ];
@@ -201,7 +217,7 @@ constexpr void shift_rows_inverse(block& bytes) NOEXCEPT
201217 bytes[ 2 ] = bytes[10 ];
202218 bytes[10 ] = i;
203219
204- j = bytes[3 ];
220+ auto j = bytes[3 ];
205221 bytes[ 3 ] = bytes[7 ];
206222 bytes[ 7 ] = bytes[11 ];
207223 bytes[11 ] = bytes[15 ];
@@ -212,40 +228,36 @@ constexpr void shift_rows_inverse(block& bytes) NOEXCEPT
212228 bytes[14 ] = j;
213229}
214230
215- constexpr void mix_columns (block& bytes) NOEXCEPT
231+ constexpr void mix_columns (aes256:: block& bytes) NOEXCEPT
216232{
217- uint8_t a, b, c, d, e;
218-
219233 for (size_t i = 0 ; i < block_size; i += 4_size)
220234 {
221- a = bytes[i + 0 ];
222- b = bytes[i + 1 ];
223- c = bytes[i + 2 ];
224- d = bytes[i + 3 ];
235+ const auto a = bytes[i + 0 ];
236+ const auto b = bytes[i + 1 ];
237+ const auto c = bytes[i + 2 ];
238+ const auto d = bytes[i + 3 ];
225239
226- e = a ^ b ^ c ^ d;
240+ const uint8_t e = a ^ b ^ c ^ d;
227241 bytes[i + 0 ] ^= e ^ f_enc_key (a ^ b);
228242 bytes[i + 1 ] ^= e ^ f_enc_key (b ^ c);
229243 bytes[i + 2 ] ^= e ^ f_enc_key (c ^ d);
230244 bytes[i + 3 ] ^= e ^ f_enc_key (d ^ a);
231245 }
232246}
233247
234- constexpr void mix_columns_inverse (block& bytes) NOEXCEPT
248+ constexpr void mix_columns_inverse (aes256:: block& bytes) NOEXCEPT
235249{
236- uint8_t a, b, c, d, e, x, y, z;
237-
238- for (size_t i = 0 ; i < block_size; i += 4_size)
250+ for (size_t i{}; i < block_size; i += 4_size)
239251 {
240- a = bytes[i + 0 ];
241- b = bytes[i + 1 ];
242- c = bytes[i + 2 ];
243- d = bytes[i + 3 ];
252+ const auto a = bytes[i + 0 ];
253+ const auto b = bytes[i + 1 ];
254+ const auto c = bytes[i + 2 ];
255+ const auto d = bytes[i + 3 ];
244256
245- e = a ^ b ^ c ^ d;
246- z = f_enc_key (e);
247- x = e ^ f_enc_key (f_enc_key (z ^ a ^ c));
248- y = e ^ f_enc_key (f_enc_key (z ^ b ^ d));
257+ const uint8_t e = a ^ b ^ c ^ d;
258+ const uint8_t z = f_enc_key (e);
259+ const uint8_t x = e ^ f_enc_key (f_enc_key (z ^ a ^ c));
260+ const uint8_t y = e ^ f_enc_key (f_enc_key (z ^ b ^ d));
249261
250262 bytes[i + 0 ] ^= x ^ f_enc_key (a ^ b);
251263 bytes[i + 1 ] ^= y ^ f_enc_key (b ^ c);
@@ -254,7 +266,7 @@ constexpr void mix_columns_inverse(block& bytes) NOEXCEPT
254266 }
255267}
256268
257- constexpr void expand_key (secret& key, uint8_t & round) NOEXCEPT
269+ constexpr void expand_key (aes256:: secret& key, uint8_t & round) NOEXCEPT
258270{
259271 key[0 ] ^= sbox[key[29 ]] ^ round;
260272 key[1 ] ^= sbox[key[30 ]];
@@ -284,7 +296,7 @@ constexpr void expand_key(secret& key, uint8_t& round) NOEXCEPT
284296 }
285297}
286298
287- constexpr void expand_key_inverse (secret& key, uint8_t & round) NOEXCEPT
299+ constexpr void expand_key_inverse (aes256:: secret& key, uint8_t & round) NOEXCEPT
288300{
289301 for (size_t i = 28 ; i > 16_size; i -= 4_size)
290302 {
@@ -314,25 +326,25 @@ constexpr void expand_key_inverse(secret& key, uint8_t& round) NOEXCEPT
314326 key[3 ] ^= sbox[key[28 ]];
315327}
316328
317- BC_POP_WARNING ()
318- BC_POP_WARNING ()
329+ // private/static
330+ // ----------------------------------------------------------------------------
319331
320- constexpr void initialize ( aes256::context& context, const secret& key) NOEXCEPT
332+ void aes256::initialize ( context& context, const secret& key) NOEXCEPT
321333{
322334 context.deckey = key;
323335 context.enckey = key;
324336
325337 auto round = bit_lo<uint8_t >;
326- for (size_t i = 0 ; i < sub1 (bits<uint8_t >); ++i)
338+ for (size_t i{} ; i < sub1 (bits<uint8_t >); ++i)
327339 expand_key (context.deckey , round);
328340}
329341
330- constexpr void encrypt_block ( aes256::context& context, block& bytes) NOEXCEPT
342+ void aes256::encrypt_ecb ( context& context, block& bytes) NOEXCEPT
331343{
332344 add_round_key_copy (bytes, context.enckey , context.key );
333345
334346 auto round = bit_lo<uint8_t >;
335- for (size_t i = 0 ; i < sub1 (rounds); ++i)
347+ for (size_t i{} ; i < sub1 (rounds); ++i)
336348 {
337349 sub_bytes (bytes);
338350 shift_rows (bytes);
@@ -355,15 +367,14 @@ constexpr void encrypt_block(aes256::context& context, block& bytes) NOEXCEPT
355367 add_round_key_lower (bytes, context.key );
356368}
357369
358- constexpr void decrypt_block ( aes256::context& context, block& bytes) NOEXCEPT
370+ void aes256::decrypt_ecb ( context& context, block& bytes) NOEXCEPT
359371{
360372 add_round_key_copy (bytes, context.deckey , context.key );
361-
362373 shift_rows_inverse (bytes);
363374 sub_bytes_inverse (bytes);
364375
365376 auto round = bit_hi<uint8_t >;
366- for (size_t i = 0 ; i < sub1 (rounds); ++i)
377+ for (size_t i{} ; i < sub1 (rounds); ++i)
367378 {
368379 if (is_even (i))
369380 {
@@ -383,32 +394,25 @@ constexpr void decrypt_block(aes256::context& context, block& bytes) NOEXCEPT
383394 add_round_key_lower (bytes, context.key );
384395}
385396
386- // //constexpr void zeroize(aes256::context& context) NOEXCEPT
387- // //{
388- // // context.key.fill(0);
389- // // context.enckey.fill(0);
390- // // context.deckey.fill(0);
391- // //}
392-
393- // published
397+ // public/static
394398// ----------------------------------------------------------------------------
395399
396- void encrypt (block& bytes, const secret& key) NOEXCEPT
400+ void aes256::encrypt_ecb (block& bytes, const secret& key) NOEXCEPT
397401{
398- aes256:: context context;
402+ context context{} ;
399403 initialize (context, key);
400- encrypt_block (context, bytes);
401- // //zeroize(context);
404+ encrypt_ecb (context, bytes);
402405}
403406
404- void decrypt (block& bytes, const secret& key) NOEXCEPT
407+ void aes256::decrypt_ecb (block& bytes, const secret& key) NOEXCEPT
405408{
406- aes256:: context context;
409+ context context;
407410 initialize (context, key);
408- decrypt_block (context, bytes);
409- // //zeroize(context);
411+ decrypt_ecb (context, bytes);
410412}
411413
412- } // namespace aes256
414+ BC_POP_WARNING ()
415+ BC_POP_WARNING ()
416+
413417} // namespace system
414418} // namespace libbitcoin
0 commit comments