cryptocol/symmetric/rijndael.rs
1// Copyright 2025, 2026 PARK Youngho.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6// This file may not be copied, modified, or distributed
7// except according to those terms.
8
9
10// #![allow(missing_docs)]
11// #![allow(unused_must_use)]
12// #![allow(dead_code)]
13// #![allow(unused_variables)]
14// #![warn(rustdoc::missing_doc_code_examples)]
15
16use std::ptr::{ copy_nonoverlapping, copy };
17use crate::number::{ IntUnion, LongUnion, LongerUnion };
18
19
20// macro_rules! rijndael_pre_encrypt_into_vec {
21// ($to:expr, $length_in_bytes:expr, $type:ty) => {
22// let len = ($length_in_bytes + 1).next_multiple_of(4 * NB as u64) as usize / <$type>::size_in_bytes() as usize;
23// $to.truncate(len);
24// $to.resize(len + 1, <$type>::zero());
25// };
26// }
27// pub(super) use rijndael_pre_encrypt_into_vec;
28
29
30// macro_rules! GF_rot_left {
31// ($r:expr, $n:expr) => {
32// $r.rotate_left_assign($n);
33// };
34// }
35
36macro_rules! GF_mul {
37 ($a:expr, $b:expr) => {
38 {
39 let mut a = $a;
40 let mut b = $b;
41 let mut ret = 0_u8;
42 while b != 0
43 {
44 if (b & 1 == 1)
45 { ret ^= a; }
46 if (a & 0b1000_0000 != 0)
47 { a = (a << 1) ^ (IRREDUCIBLE as u8); }
48 else
49 { a <<= 1; }
50 b >>= 1;
51 }
52 ret
53 }
54 };
55}
56
57macro_rules! GF_is_candidate {
58 ($a:expr) => {
59 {
60 let a_1 = $a;
61 let a_2 = GF_mul!(a_1, a_1);
62 let a_4 = GF_mul!(a_2, a_2);
63 let a_8 = GF_mul!(a_4, a_4);
64 let a_16 = GF_mul!(a_8, a_8);
65 let a_32 = GF_mul!(a_16, a_16);
66 // let a_64 = GF_mul!(a_32, a_32);
67
68 let a_3 = GF_mul!(a_1, a_2);
69 let mut ret = GF_mul!(a_3, a_4);
70 ret = GF_mul!(ret, a_8);
71 if ret == 1
72 {
73 false
74 }
75 else
76 {
77 ret = GF_mul!(a_3, a_16);
78 ret = GF_mul!(ret, a_32);
79 if ret == 1
80 {
81 false
82 }
83 else
84 {
85 ret = GF_mul!(a_1, a_4);
86 ret = GF_mul!(ret, a_16);
87 ret = GF_mul!(ret, a_32);
88 ret != 1
89 }
90 }
91 }
92 };
93}
94
95macro_rules! GF_generator {
96 () => {
97 {
98 let mut ret = 0_u8;
99 let mut j = 2_u16;
100 while j < 256
101 {
102 if GF_is_candidate!(j as u8)
103 {
104 ret = j as u8;
105 break;
106 }
107 j += 1;
108 }
109 ret
110 }
111 };
112}
113
114macro_rules! GF_inverse_of {
115 ($a:expr) => {
116 {
117 let mut ret = 0_u8;
118 let mut inv = 255_u8;
119 while inv > 1
120 {
121 if GF_mul!($a, inv) == 1
122 {
123 ret = inv;
124 break;
125 }
126 inv -= 1;
127 }
128 ret
129 }
130 }
131}
132
133macro_rules! make_SBOX {
134 () => {
135 {
136 let mut out = [0_u8; 256];
137 let mut p = 1_u8;
138 let mut q = 1_u8;
139 let generator = GF_generator!();
140 let inverse = GF_inverse_of!(generator);
141 let mut j = 255_u16;
142 while j > 0
143 {
144 p = GF_mul!(p, generator);
145 q = GF_mul!(q, inverse);
146 let mut transformed = 0_u8;
147 let mut i = 0_u8;
148 while i < 8
149 {
150 let affine_u8 = (AFFINE_MUL >> (i << 3)) as u8;
151 let bits = affine_u8 & q;
152 if bits.count_ones() & 1 == 1
153 { transformed |= 1 << i; }
154 i += 1;
155 }
156 out[p as usize] = transformed ^ AFFINE_ADD;
157 if p == 1
158 { break; }
159 j -= 1;
160 }
161 out[0] = AFFINE_ADD;
162 out
163 }
164 };
165}
166
167macro_rules! make_INV_SBOX {
168 () => {
169 {
170 let mut out = [0_u8; 256];
171 let mut i = 0_u16;
172 while i < 256
173 {
174 out[Self::SBOX[i as usize] as usize] = i as u8;
175 i += 1;
176 }
177 out
178 }
179 }
180}
181
182macro_rules! make_INV_MC {
183 () => {
184 {
185 let mut aug = [[0_u8; 4]; 4];
186 let mut inv = [[0_u8; 4]; 4];
187 let mut i = 0_usize;
188 let mut j: usize;
189 while i < 4
190 {
191 j = 0;
192 while j < 4
193 {
194 aug[i][j] = Self::MC[i][j];
195 j += 1;
196 }
197 inv[i][i] = 1;
198 i += 1;
199 }
200
201 let generator = GF_generator!();
202 let inverse = GF_inverse_of!(generator);
203 let mut row = 0_usize;
204 while row < 4
205 {
206 let mut pivot = aug[row][row];
207 if pivot == 0
208 {
209 i = row + 1;
210 while i < 4
211 {
212 if aug[i][row] != 0
213 {
214 j = 0;
215 while j < 4
216 {
217 (aug[row][j], aug[i][j]) = (aug[i][j], aug[row][j]);
218 (inv[row][j], inv[i][j]) = (inv[i][j], inv[row][j]);
219 j += 1;
220 }
221 pivot = aug[row][row];
222 break;
223 }
224 i += 1;
225 }
226 if pivot == 0
227 { panic!("Singular Matrix"); }
228 }
229
230 let mut p = 1_u8;
231 let mut q = 1_u8;
232 while p != pivot
233 {
234 p = GF_mul!(p, generator);
235 q = GF_mul!(q, inverse);
236 }
237 j = 0;
238 while j < 4
239 {
240 aug[row][j] = GF_mul!(aug[row][j], q);
241 inv[row][j] = GF_mul!(inv[row][j], q);
242 j += 1;
243 }
244 let mut r = 0;
245 while r < 4
246 {
247 if r != row
248 {
249 let factor = aug[r][row];
250 j = 0;
251 while j < 4
252 {
253 inv[r][j] ^= GF_mul!(inv[row][j], factor);
254 aug[r][j] ^= GF_mul!(aug[row][j], factor);
255 j += 1;
256 }
257 }
258 r += 1;
259 }
260 row += 1;
261 }
262 inv
263 }
264 }
265}
266
267macro_rules! make_RC_ARRAY {
268 () => {
269 {
270 let mut out = [0u32; ROUND];
271 let round = [ RC0.to_le(), RC1.to_le(), RC2.to_le(), RC3.to_le(), RC4.to_le(),
272 RC5.to_le(), RC6.to_le(), RC7.to_le(), RC8.to_le(), RC9.to_le() ];
273 let nr = if ROUND <= 10 { ROUND } else { 10 };
274 let mut i = 0;
275 while i < nr
276 {
277 out[i] = round[i];
278 i += 1;
279 }
280 while i < ROUND
281 {
282 out[i] = (GF_mul!(out[i-1].to_le() as u8, 2) as u32).to_le();
283 i += 1;
284 }
285 out
286 }
287 }
288}
289
290
291/// Rijndael_32_32 is not really practical but only educational to understand
292/// AES or Rijndael cryptographic algorithm. Its key is 32-bit and its
293/// encryption block is 32-bit.
294#[allow(non_camel_case_types)]
295pub type Rijndael_32_32 = Rijndael_Generic<7, 1, 1>;
296
297/// Rijndael_64_64 is not really practical too, but it can be used with DES
298/// cryptographic algorithm along or as random number generator engine.
299/// Its key is 64-bit and its encryption block is 64-bit.
300/// So, it can work with DES.
301#[allow(non_camel_case_types)]
302pub type Rijndael_64_64 = Rijndael_Generic<8, 2, 2>;
303
304/// Rijndael_512_512 can be used as one of post-Quantum algorithms for a
305/// while because even Grover algorithm takes long enough to break
306/// Rijndael_512_512. Its key is 512-bit and its encryption block is 512-bit.
307#[allow(non_camel_case_types)]
308pub type Rijndael_512_512 = Rijndael_Generic<22, 16, 16>;
309
310/// Rijndael_512_384 is one of Rijndael series. Its key is 384-bit and its
311/// encryption block is 512-bit.
312#[allow(non_camel_case_types)]
313pub type Rijndael_512_384 = Rijndael_Generic<18, 16, 12>;
314
315/// Rijndael_384_256 is one of Rijndael series. Its key is 256-bit and its
316/// encryption block is 512-bit.
317#[allow(non_camel_case_types)]
318pub type Rijndael_512_256 = Rijndael_Generic<14, 16, 8>;
319
320/// Rijndael_384_192 is one of Rijndael series. Its key is 192-bit and its
321/// encryption block is 512-bit.
322#[allow(non_camel_case_types)]
323pub type Rijndael_512_192 = Rijndael_Generic<14, 16, 6>;
324
325/// Rijndael_512_128 is one of Rijndael series. Its key is 128-bit and its
326/// encryption block is 512-bit.
327#[allow(non_camel_case_types)]
328pub type Rijndael_512_128 = Rijndael_Generic<14, 16, 4>;
329
330/// Rijndael_384_512 can be used as one of post-Quantum algorithms for a
331/// while because even Grover algorithm takes long enough to break
332/// Rijndael_384_512. Its key is 512-bit and its encryption block is 384-bit.
333#[allow(non_camel_case_types)]
334pub type Rijndael_384_512 = Rijndael_Generic<22, 12, 16>;
335
336/// Rijndael_384_384 is one of Rijndael series. Its key is 384-bit and its
337/// encryption block is 384-bit.
338#[allow(non_camel_case_types)]
339pub type Rijndael_384_384 = Rijndael_Generic<18, 12, 12>;
340
341/// Rijndael_384_256 is one of Rijndael series. Its key is 256-bit and its
342/// encryption block is 384-bit.
343#[allow(non_camel_case_types)]
344pub type Rijndael_384_256 = Rijndael_Generic<14, 12, 8>;
345
346/// Rijndael_384_192 is one of Rijndael series. Its key is 192-bit and its
347/// encryption block is 384-bit.
348#[allow(non_camel_case_types)]
349pub type Rijndael_384_192 = Rijndael_Generic<14, 12, 6>;
350
351/// Rijndael_384_128 is one of Rijndael series. Its key is 128-bit and its
352/// encryption block is 384-bit.
353#[allow(non_camel_case_types)]
354pub type Rijndael_384_128 = Rijndael_Generic<14, 12, 4>;
355
356/// Rijndael_256_512 can be used as one of post-Quantum algorithms for a
357/// while because even Grover algorithm takes long enough to break
358/// Rijndael_256_512. Its key is 512-bit and its encryption block is 256-bit.
359#[allow(non_camel_case_types)]
360pub type Rijndael_256_512 = Rijndael_Generic<22, 8, 16>;
361
362/// Rijndael_256_384 is one of Rijndael series. Its key is 384-bit and its
363/// encryption block is 256-bit.
364#[allow(non_camel_case_types)]
365pub type Rijndael_256_384 = Rijndael_Generic<18, 8, 12>;
366
367/// Rijndael_256_256 is one of Rijndael series. Its key is 256-bit and its
368/// encryption block is 256-bit.
369#[allow(non_camel_case_types)]
370pub type Rijndael_256_256 = Rijndael_Generic<14, 8, 8>;
371
372/// Rijndael_256_192 is one of Rijndael series. Its key is 192-bit and its
373/// encryption block is 256-bit.
374#[allow(non_camel_case_types)]
375pub type Rijndael_256_192 = Rijndael_Generic<14, 8, 6>;
376
377/// Rijndael_256_128 is one of Rijndael series. Its key is 128-bit and its
378/// encryption block is 256-bit.
379#[allow(non_camel_case_types)]
380pub type Rijndael_256_128 = Rijndael_Generic<14, 8, 4>;
381
382/// Rijndael_192_512 can be used as one of post-Quantum algorithms for a
383/// while because even Grover algorithm takes long enough to break
384/// Rijndael_192_512. Its key is 512-bit and its encryption block is 192-bit.
385#[allow(non_camel_case_types)]
386pub type Rijndael_192_512 = Rijndael_Generic<22, 6, 16>;
387
388/// Rijndael_192_384 is one of Rijndael series. Its key is 384-bit and its
389/// encryption block is 192-bit.
390#[allow(non_camel_case_types)]
391pub type Rijndael_192_384 = Rijndael_Generic<18, 6, 12>;
392
393/// Rijndael_192_256 is one of Rijndael series. Its key is 256-bit and its
394/// encryption block is 192-bit.
395#[allow(non_camel_case_types)]
396pub type Rijndael_192_256 = Rijndael_Generic<14, 6, 8>;
397
398/// Rijndael_192_192 is one of Rijndael series. Its key is 192-bit and its
399/// encryption block is 192-bit.
400#[allow(non_camel_case_types)]
401pub type Rijndael_192_192 = Rijndael_Generic<12, 6, 6>;
402
403/// Rijndael_256_128 is one of Rijndael series. Its key is 128-bit and its
404/// encryption block is 192-bit.
405#[allow(non_camel_case_types)]
406pub type Rijndael_192_128 = Rijndael_Generic<12, 6, 4>;
407
408/// Rijndael_128_512 can be used as one of post-Quantum algorithms for a
409/// while because even Grover algorithm takes long enough to break
410/// Rijndael_128_512. Its key is 512-bit and its encryption block is 128-bit.
411#[allow(non_camel_case_types)]
412pub type Rijndael_128_512 = Rijndael_Generic<22, 4, 16>;
413
414/// Rijndael_128_384 is one of Rijndael series. Its key is 384-bit and its
415/// encryption block is 128-bit.
416#[allow(non_camel_case_types)]
417pub type Rijndael_128_384 = Rijndael_Generic<18, 4, 12>;
418
419/// Rijndael_128_256 is one of Rijndael series. Its key is 256-bit and its
420/// encryption block is 128-bit. It is the same as the AES_256.
421#[allow(non_camel_case_types)]
422pub type Rijndael_128_256 = Rijndael_Generic<14, 4, 8>;
423
424/// Rijndael_128_192 is one of Rijndael series. Its key is 192-bit and its
425/// encryption block is 128-bit. It is the same as the AES_192.
426#[allow(non_camel_case_types)]
427pub type Rijndael_128_192 = Rijndael_Generic<12, 4, 6>;
428
429/// Rijndael_128_128 is one of Rijndael series. Its key is 128-bit and its
430/// encryption block is 128-bit. It is the same as the AES_128.
431#[allow(non_camel_case_types)]
432pub type Rijndael_128_128 = Rijndael_Generic;
433
434/// AES_256 is one of AES series. Its key is 256-bit and its encryption
435/// block is 128-bit. It is the same as the Rijndael_128_256.
436#[allow(non_camel_case_types)]
437pub type AES_256 = Rijndael_Generic<14, 4, 8>;
438
439/// AES_192 is one of AES series. Its key is 192-bit and its encryption
440/// block is 128-bit. It is the same as the Rijndael_128_192.
441#[allow(non_camel_case_types)]
442pub type AES_192 = Rijndael_Generic<12, 4, 6>;
443
444/// AES_128 is one of AES series. Its key is 128-bit and its encryption
445/// block is 128-bit. It is the same as the Rijndael_128_128.
446#[allow(non_camel_case_types)]
447pub type AES_128 = Rijndael_Generic;
448
449
450/// A Rijndael or AES (Advanced Encryption Standard) symmetric-key algorithm
451/// for the encryption of digital data
452///
453/// # Note
454/// __This descryption about Rijndael is according to little endianness.__
455/// MSB (Most Significant Bit) is the 64th bit and LSB (Least Significant Bit)
456/// is the first bit in this descryption unless otherwise mentioned.
457///
458/// # Introduction
459/// The name, AES, is the acronym of Advanced Encryption Standard. The name,
460/// Rijndael, is created out of the names of the Belgian cryptographers, Joan
461/// Daemen and Vincent Rijmen. Rijndael means Rhine valley in Dutch though it is
462/// not known whether the name Rijndael was made with that intention. AES is the
463/// subset of Rijndael. AES has three versions: AES-128, AES-192 and AES-256.
464/// All of them have the 128-bit data block. AES-128 has the 128-bit key length.
465/// AES-192 has the 192-bit key length. AES-256 has the 256-bit key length.
466/// On the other hand, Rijndael has nine versions: Rijndael-128-128,
467/// Rijndael-128-192, Rijndael-128-256, Rijndael-192-128, Rijndael-192-192,
468/// Rijndael-192-256, Rijndael-256-128, Rijndael-256-192, and Rijndael-256-256.
469/// Rijndael-128-*, Rijndael-192-*, and Rijndael-256-* have 128-bit data block,
470/// 192-bit data block, and 256-bit data block, respectively. Rijndael-*-128,
471/// Rijndael-*-192, and Rijndael-*-256 have 128-bit key length, 192-bit key
472/// length, and 256-bit key length, respectively. However, this module,
473/// Rijndael_Generic provides more expanded versions such as 32-bit and 64-bit
474/// data blocks and key lengths and more than 256-bit data blocks and key
475/// lengths.
476///
477/// # Short History of birth of AES
478/// On 2nd, January, 1997, NIST announced that they wished to choose the
479/// encryption algorithm standard in replacement of DES, which is called AES.
480/// The contest held three rounds. At the first round, fifteen were submitted:
481/// CAST-256, CRYPTON, DEAL, DFC, E2, FROG, HPC, LOKI97, MAGENTA, MARS, RC6,
482/// Rijndael, SAFER+, Serpent, and Twofish. At the second round, five remained:
483/// MARS, RC6, Rijndael, Serpent, and Twofish. At the third round, Rijndael was
484/// chosen out of the remained five. However, all the five algorithms are
485/// commonly referred to as "AES finalists", and they are also considered
486/// well-known and respected in the community. So, the other four algorithms
487/// are also being actively used as well as Rijndael, today.
488///
489/// # Use of AES or Rijndael and its variants
490/// This algorithm is implemented generic way. Most of the constants are
491/// implemented as generic constants. So, without changing any line of code, you
492/// can change the algorithm by changing the generic parameter. You can design
493/// and implement your own algorithm based on Rijndael which uses SPN
494/// (Substitution–Permutation Network). You can also use the the source code of
495/// Rijndael_Generic in order to find the weakness of SPN.
496///
497/// # Generic Parameters
498/// You can change the generic parameters if you want to make your own
499/// encryption/decryption algorithm based on Rijndael. However, your own
500/// algorithm may or may not be securer than AES. It is a high chance that
501/// your own algorithm is less secure than AES unless you have performed the
502/// security test for your own algorithm and proved that your algorithm is
503/// at least as secure as AES.
504/// - ROUND: Indicates the number of rounds. You can change how many times the
505/// Substitution-Permutation Network will be repeated. Its minimum value is 0.
506/// Original Rijndael has the number of rounds as follows:
507/// | data \ key | 128-bit key | 192-bit key | 256-bit key |
508/// |--------------|-------------|-------------|-------------|
509/// | 128-bit data | 10 rounds | 12 rounds | 14 rounds |
510/// | 192-bit data | 12 rounds | 12 rounds | 14 rounds |
511/// | 256-bit data | 14 rounds | 14 rounds | 14 rounds |
512///
513/// The default of `ROUND` is 10. The default value `10` is for AES-128
514/// which is most frequently used.
515/// - NB: Indicates the size of block. The block size is (`NB` * 4) bytes.
516/// You can change the size of block by changing the value `NB`.
517/// The default value of `NB` is `4`. The default value `4` is for AES
518/// which is most frequently used.
519/// If `NB` is `0`, the behavior is not defined.
520/// - NK: Indicates the size of key. The key size is (`NK` * 4) bytes.
521/// You can change the size of Key by changing the value `NK`.
522/// The default value of `NK` is `4`. The default value `4` is for AES-128
523/// which is most frequently used.
524/// If `NK` is `0`, the behavior is not defined.
525/// - IRREDUCIBLE: Indicates the irreducible polynomial. You can change the
526/// irreducible polynomial by changing `IRREDUCIBLE`. The default value of
527/// `IRREDUCIBLE` is `0b_0001_1011` which means x^8 + x^4 + x^3 + x + 1. In
528/// `IRREDUCIBLE`, the term `x^8` is always omitted. The default value
529/// `0b_0001_1011` is for Rijndael or AES.
530/// - AFFINE_MUL: Indicates the two-dimensional matrix that is used to make
531/// S-Box. `AFFINE_MUL` is the linear part of the affine transformation.
532/// You can change the S-Box by changing `AFFINE_MUL` with `AFFINE_ADD`
533/// along. The default value of `AFFINE_MUL` is
534/// `0b_11111000_01111100_00111110_00011111_10001111_11000111_11100011_11110001`
535/// which means the matrix as follows.
536/// | Matrix |
537/// |-----------------|
538/// | 1 1 1 1 1 0 0 0 |
539/// | 0 1 1 1 1 1 0 0 |
540/// | 0 0 1 1 1 1 1 0 |
541/// | 0 0 0 1 1 1 1 1 |
542/// | 1 0 0 0 1 1 1 1 |
543/// | 1 1 0 0 0 1 1 1 |
544/// | 1 1 1 0 0 0 1 1 |
545/// | 1 1 1 1 0 0 0 1 |
546///
547/// The default value of `AFFINE_MUL` is for Rijndael or AES.
548/// - AFFINE_ADD: Indicates the one-dimensional matrix that is used to make
549/// S-Box. `AFFINE_ADD` is the non-linear part of the affine transformation.
550/// You can change the S-Box by changing `AFFINE_ADD` with `AFFINE_MUL` along.
551/// The default value of `AFFINE_ADD` is `0b_01100011` which means the matrix
552/// as follows.
553/// | Matrix |
554/// |--------|
555/// | 0 |
556/// | 1 |
557/// | 1 |
558/// | 0 |
559/// | 0 |
560/// | 0 |
561/// | 1 |
562/// | 1 |
563///
564/// The default value of `AFFINE_ADD` is for Rijndael or AES.
565/// - SR0 ~ SR3: Indicates how many bytes to shift (rotate) in each row in
566/// ShiftRows step. You can change the amounts of shifting (rotating) in each
567/// row by changing `SR0`, `SR1`, `SR2`, and `SR3`. The default values of
568/// `SR0`, `SR1`, `SR2`, and `SR3` are `0`, `1`, `2`, and `3`, respectively.
569/// The default values `0`, `1`, `2`, and `3` are for Rijndael or AES.
570/// - MC00 ~ MC33: Indicates the two-dimensional matrix that is used as
571/// MixColumns matrix in MixColumn step. `MC00`, `MC01`, `MC02`, `MC03`,
572/// `MC10`, `MC11`, `MC12`, `MC13`, `MC20`, `MC21`, `MC22`, `MC23`, `MC30`,
573/// `MC31`, `MC32`, and `MC33` are the elements of the two-dimensional
574/// MixColumns matrix. You can change the MixColumns matrix to change the
575/// MixColumn step by changing `MC00` ~ `MC33`. The default values of `MC00`,
576/// `MC01`, `MC02`, `MC03`, `MC10`, `MC11`, `MC12`, `MC13`, `MC20`, `MC21`,
577/// `MC22`, `MC23`, `MC30`, `MC31`, `MC32`, and `MC33` are `2`, `3`, `1`,
578/// `1`, `1`, `2`, `3`, `1`, `1`, `1`, `2`, `3`, `3`, `1`, `1`, and `2`,
579/// respectively, which means the matrix as follows.
580/// | Matrix |
581/// |---------|
582/// | 2 3 1 1 |
583/// | 1 2 3 1 |
584/// | 1 1 2 3 |
585/// | 3 1 1 2 |
586///
587/// The default values of `MC00` ~ `MC33` are for Rijndael or AES.
588/// - RC0 ~ RC9: Indicates Round Constants that are used to make round keys.
589/// The round keys are used in the AddRoundKey step. You can change the
590/// round keys by changing `RC0` ~ `RC9`. The default values of `RC0`, `RC1`,
591/// `RC2`, `RC3`, `RC4`, `RC5`, `RC6`, `RC7`, `RC8`, and `RC9` are
592/// `0b_0000_0001`, `0b_0000_0010`, `0b_0000_0100`, `0b_0000_1000`,
593/// `0b_0001_0000`, `0b_0010_0000`,`0b_0100_0000`, `0b_1000_0000`,
594/// `0b_0001_1011`, and `0b_001_10110`, respectively. The default values are
595/// for Rijndael or AES. If `Round` is greater than 10, the round constants
596/// after RC9 will be determined by multiplying previous round constant by `2`
597/// on Galois Field. So, So-called RC10 is double of `RC9` on Galois Field and
598/// RC11 is double of `RC10` on Galois Field, and so on.
599/// - ROT: Indicates how may bytes to shift (rotate) in making round keys. You
600/// can change round keys by changing `ROT`. The default value of `ROT` is
601/// `1`. The default value `1` is for for Rijndael or AES.
602///
603/// # Reference
604/// [Read more](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
605/// about AES in brief.
606/// Watch [this video](https://www.youtube.com/watch?v=x1v2tX4_dkQ) and then
607/// [this video](https://www.youtube.com/watch?v=NHuibtoL_qk) in series
608/// for more (or deeper or full) understanding of AES.
609///
610/// # Quick Start
611/// You have to import (use) one of the modules: `AES_128`, `AES_192`, and
612/// `AES_256` in order to use official AES as shown in Example 1. And, in the
613/// same way you can import (use) the modules:
614/// `Rijndael_128_128`, `Rijndael_128_192`, `Rijndael_128_256`,
615/// `Rijndael_128_384`, `Rijndael_128_512`,
616/// `Rijndael_192_128`, `Rijndael_192_192`, `Rijndael_192_256`,
617/// `Rijndael_192_384`, `Rijndael_192_512`,
618/// `Rijndael_256_128`, `Rijndael_256_192`, `Rijndael_256_256`,
619/// `Rijndael_256_384`, `Rijndael_256_512`,
620/// `Rijndael_384_128`, `Rijndael_384_192`, `Rijndael_384_256`,
621/// `Rijndael_384_384`, `Rijndael_384_512`,
622/// `Rijndael_512_128`, `Rijndael_512_192`, `Rijndael_512_256`,
623/// `Rijndael_512_384`, and `Rijndael_512_512`.
624/// Of course, you can also expand Rijndael by changing the generic parameters.
625/// Also, there are some predefined modules:
626/// `Rijndael_32_32` for 32 bit key and 32-bit encryption data, and
627/// `Rijndael_64_64` for 64 bit key and 64-bit encryption data for educational
628/// purpose, though they are not very practical.
629///
630/// # Example 1
631/// ```
632/// use cryptocol::symmetric::AES_128;
633/// use cryptocol::symmetric::AES_192;
634/// use cryptocol::symmetric::AES_256;
635///
636/// use cryptocol::symmetric::Rijndael_128_128;
637/// use cryptocol::symmetric::Rijndael_128_192;
638/// use cryptocol::symmetric::Rijndael_128_256;
639/// use cryptocol::symmetric::Rijndael_128_384;
640/// use cryptocol::symmetric::Rijndael_128_512;
641///
642/// use cryptocol::symmetric::Rijndael_192_128;
643/// use cryptocol::symmetric::Rijndael_192_192;
644/// use cryptocol::symmetric::Rijndael_192_256;
645/// use cryptocol::symmetric::Rijndael_192_384;
646/// use cryptocol::symmetric::Rijndael_192_512;
647///
648/// use cryptocol::symmetric::Rijndael_256_128;
649/// use cryptocol::symmetric::Rijndael_256_192;
650/// use cryptocol::symmetric::Rijndael_256_256;
651/// use cryptocol::symmetric::Rijndael_256_384;
652/// use cryptocol::symmetric::Rijndael_256_512;
653///
654/// use cryptocol::symmetric::Rijndael_384_128;
655/// use cryptocol::symmetric::Rijndael_384_192;
656/// use cryptocol::symmetric::Rijndael_384_256;
657/// use cryptocol::symmetric::Rijndael_384_384;
658/// use cryptocol::symmetric::Rijndael_384_512;
659///
660/// use cryptocol::symmetric::Rijndael_512_128;
661/// use cryptocol::symmetric::Rijndael_512_192;
662/// use cryptocol::symmetric::Rijndael_512_256;
663/// use cryptocol::symmetric::Rijndael_512_384;
664/// use cryptocol::symmetric::Rijndael_512_512;
665///
666/// use cryptocol::symmetric::Rijndael_64_64;
667/// use cryptocol::symmetric::Rijndael_32_32;
668/// ```
669///
670/// You can instantiate the AES object with `u128` key as Example 2.
671/// In this case, you have to take endianness into account.
672/// In little-endianness, 0x_1234567890ABCDEF1234567890ABCDEF_u128 is [0xEFu8,
673/// 0xCDu8, 0xABu8, 0x90u8, 0x78u8, 0x56u8, 0x34u8, 0x12u8, 0xEFu8, 0xCDu8,
674/// 0xABu8, 0x90u8, 0x78u8, 0x56u8, 0x34u8, 0x12u8] while the same
675/// 0x_1234567890ABCDEF1234567890ABCDEF_u128 is [0x12u8, 0x34u8, 0x56u8, 0x78u8,
676/// 0x90u8, 0xABu8, 0xCDu8, 0xEF_u64, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x90u8,
677/// 0xABu8, 0xCDu8, 0xEF_u64] in big-endianness.
678/// The instantiated object should be mutable.
679///
680/// # Example 2
681/// ```
682/// use cryptocol::symmetric::AES_128;
683/// let key = 0x_1234567890ABCDEF1234567890ABCDEF_u128;
684/// let mut _a_aes = AES_128::new_with_key_u128(key);
685/// ```
686///
687/// Note that the object should be intantiated as mutable object.
688/// Also, you can instantiate the AES object with `[u8; 16]` key as shown in
689/// Example 3. In this case, you don't have to take endianness into account.
690/// The instantiated object should be mutable.
691///
692/// # Example 3
693/// ```
694/// use cryptocol::symmetric::AES_128;
695/// let key = [0xEFu8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12];
696/// let mut _a_aes = AES_128::new_with_key(&key);
697/// ```
698///
699/// You can instantiate the AES object without key and set a `u128` key later as
700/// shown in Example 4 or a `[u8; 16]` key later as shown in Example 5.
701///
702/// # Example 4
703/// ```
704/// use cryptocol::symmetric::AES_128;
705/// let mut a_aes = AES_128::new();
706/// let key = 0x_1234567890ABCDEF1234567890ABCDEF_u128;
707/// a_aes.set_key_u128(key);
708/// ```
709///
710/// # Example 5
711/// ```
712/// use cryptocol::symmetric::AES_128;
713/// let mut a_aes = AES_128::new();
714/// let key = [0xEFu8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12];
715/// a_aes.set_key(&key);
716/// ```
717///
718/// Now, you can freely use any operation mode. This crate provide
719/// ECB (Electronic CodeBook), CBC(Cipher Block Chaining), PCBC (Propagation
720/// Cipher Block Chaining), CFB (Cipher FeedBack) OFB (Output FeedBack), and
721/// CTR (CounTeR). You can choose the way of padding bits according to either
722/// [PKCS #7](https://node-security.com/posts/cryptography-pkcs-7-padding/) or
723/// [ISO 7816-4](https://en.wikipedia.org/wiki/Padding_(cryptography)#ISO/IEC_7816-4).
724/// So, you can import (use) one of the following traits: ECB_PKCS7, ECB_ISO,
725/// CBC_PKCS7, CBC_ISO, PCBC_PKCS7, PCBC_ISO, CFB, OFB, and CTR. The following
726/// example 6 shows the case that you choose CBC operation mode and padding bits
727/// according to PKCS #7.
728///
729/// # Example 6
730/// ```
731/// use std::io::Write;
732/// use std::fmt::Write as _;
733/// use cryptocol::symmetric::{ AES_128, CBC_PKCS7 };
734///
735/// let mut a_aes = AES_128::new_with_key(&[0xEFu8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
736/// let message = "In the beginning God created the heavens and the earth.";
737/// println!("M =\t{}", message);
738/// let iv = [0x87654321_u32, 0xFEDCBA09_u32, 0x87654321_u32, 0xFEDCBA09_u32];
739/// println!("IV =\t{:08X}{:08X}{:08X}{:08X}", iv[0].to_be(), iv[1].to_be(), iv[2].to_be(), iv[3].to_be());
740/// let mut cipher = Vec::<u8>::new();
741/// a_aes.encrypt_str_into_vec(iv, message, &mut cipher);
742/// print!("C =\t");
743/// for c in cipher.clone()
744/// { print!("{:02X} ", c); }
745/// println!();
746/// let mut txt = String::new();
747/// for c in cipher.clone()
748/// { write!(txt, "{:02X} ", c); }
749/// assert_eq!(txt, "C9 1C 27 CE 83 92 A1 CF 7D A4 64 35 16 48 01 72 CC E3 6D CD BB 19 FC D0 80 22 09 9F 23 32 73 27 58 37 F9 9B 3C 44 7B 03 B3 80 7E 99 DF 97 4E E9 A3 89 67 0C 21 29 3E 4D DC AD B6 44 09 D4 3B 02 ");
750///
751/// let mut recovered = String::new();
752/// a_aes.decrypt_vec_into_string(iv, &cipher, &mut recovered);
753/// println!("B =\t{}", recovered);
754/// assert_eq!(recovered, "In the beginning God created the heavens and the earth.");
755/// assert_eq!(recovered, message);
756/// println!();
757/// ```
758///
759/// You can modify the Rijndael encryption/decryption algorithm as you want. All
760/// the constants are implemented as generic parameters. For instance, you can
761/// change S-box, the number of rounds of Substitution - Permutation network,
762/// the irreducible polynormial, key length, etc. The following Example 7 shows
763/// the variation of Rijndael which has 512-bit data block and 512-bit key.
764///
765/// # Example 7
766/// ```
767/// use std::io::Write;
768/// use std::fmt::Write as _;
769/// use cryptocol::symmetric::{ Rijndael_Generic, CBC_PKCS7 };
770///
771/// let mut a_rijndael = Rijndael_Generic::<22, 16, 16>::new_with_key(&[0xEFu8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
772/// let message = "In the beginning God created the heavens and the earth.";
773/// println!("M =\t{}", message);
774/// let iv = [0x_FEDCBA09_u32, 87654321_u32, 0x_FEDCBA09_u32, 87654321_u32, 0x_FEDCBA09_u32, 87654321_u32, 0x_FEDCBA09_u32, 87654321_u32, 0x_FEDCBA09_u32, 87654321_u32, 0x_FEDCBA09_u32, 87654321_u32, 0x_FEDCBA09_u32, 87654321_u32, 0x_FEDCBA09_u32, 87654321_u32];
775/// println!("IV =\t{:08X}{:08X}{:08X}{:08X}", iv[0].to_be(), iv[1].to_be(), iv[2].to_be(), iv[3].to_be());
776///
777/// let mut cipher = Vec::<u8>::new();
778/// a_rijndael.encrypt_str_into_vec(iv, message, &mut cipher);
779/// print!("C =\t");
780/// for c in cipher.clone()
781/// { print!("{:02X} ", c); }
782/// println!();
783/// let mut txt = String::new();
784/// for c in cipher.clone()
785/// { write!(txt, "{:02X} ", c); }
786/// assert_eq!(txt, "B1 C0 1F 84 17 46 35 12 D9 16 52 44 5F 40 A1 7F 3B 55 F7 E6 42 E5 1F 42 57 43 AD E4 00 19 54 1D B6 F3 1B 20 C8 D3 08 92 B7 C4 0C E2 77 73 A5 E4 0D E7 0F F4 B0 38 FE 78 30 56 E4 A7 9E CE 0E 50 ");
787///
788/// let mut recovered = String::new();
789/// a_rijndael.decrypt_vec_into_string(iv, &cipher, &mut recovered);
790/// println!("B =\t{}", recovered);
791/// assert_eq!(recovered, "In the beginning God created the heavens and the earth.");
792/// assert_eq!(recovered, message);
793/// ```
794///
795/// You can use Rijndael_512_512 as one of post-Quantum algorithms for a
796/// while because even Grover algorithm takes long enough to break
797/// Rijndael_512_512. Its key is 512-bit and its encryption block is 512-bit.
798///
799/// # Example 8 for Post-Quantum
800/// ```
801/// use std::io::Write;
802/// use std::fmt::Write as _;
803/// use cryptocol::number::SharedArrays;
804/// use cryptocol::hash::SHA3_512;
805/// use cryptocol::symmetric::{ Rijndael_512_512, CBC_ISO };
806///
807/// let mut sha3 = SHA3_512::new();
808/// sha3.absorb_str("Post-Quantum");
809/// let key: [u8; 64] = sha3.get_hash_value_in_array();
810/// print!("K =\t");
811/// for i in 0..64
812/// { print!("{:02X}", key[i]); }
813/// println!();
814/// let mut a_rijndael = Rijndael_512_512::new_with_key(&key);
815/// sha3.absorb_str("Initialize");
816/// let mut iv = SharedArrays::<u32, 16, u8, 64>::new();
817/// iv.src = sha3.get_hash_value_in_array();
818/// let iv = unsafe { iv.des };
819/// print!("IV =\t");
820/// for i in 0..16
821/// { print!("{:08X}", iv[i].to_be()); }
822/// println!();
823/// let message = "In the beginning God created the heavens and the earth.";
824/// println!("M =\t{}", message);
825/// let mut cipher = [0_u8; 64];
826/// a_rijndael.encrypt(iv.clone(), message.as_ptr(), message.len() as u64, cipher.as_mut_ptr());
827/// print!("C =\t");
828/// for c in cipher.clone()
829/// { print!("{:02X} ", c); }
830/// println!();
831/// let mut txt = String::new();
832/// for c in cipher.clone()
833/// { write!(txt, "{:02X} ", c); }
834/// assert_eq!(txt, "C2 C4 1C 91 EE 50 F0 04 B6 73 00 B2 81 05 01 25 C1 87 24 27 7E CE 01 65 C5 CB 87 38 99 9F 5B 0C D1 DF 8D 52 C4 C4 C8 D8 F5 D5 AD F3 FD DA 35 C2 33 F6 5D 83 02 85 F1 20 8C 56 0B 72 9C 91 84 42 ");
835///
836/// let mut recovered = vec![0; 55];
837/// a_rijndael.decrypt(iv, cipher.as_ptr(), cipher.len() as u64, recovered.as_mut_ptr());
838/// print!("Ba =\t");
839/// for b in recovered.clone()
840/// { print!("{:02X} ", b); }
841/// println!();
842/// let mut txt = String::new();
843/// for c in recovered.clone()
844/// { write!(txt, "{:02X} ", c); }
845/// assert_eq!(txt, "49 6E 20 74 68 65 20 62 65 67 69 6E 6E 69 6E 67 20 47 6F 64 20 63 72 65 61 74 65 64 20 74 68 65 20 68 65 61 76 65 6E 73 20 61 6E 64 20 74 68 65 20 65 61 72 74 68 2E ");
846///
847/// let mut converted = String::new();
848/// unsafe { converted.as_mut_vec() }.append(&mut recovered);
849///
850/// println!("Bb =\t{}", converted);
851/// assert_eq!(converted, "In the beginning God created the heavens and the earth.");
852/// assert_eq!(converted, message);
853/// ```
854///
855/// # Notice for Practical Use
856/// Now, you can freely use any methods with any paddings
857/// in any operation modes.
858/// - This crate provides six operation modes:
859/// ECB, CBC, PCBC, CFB, OFB, and CTR.
860/// - This crate provides two padding ways: ISO 7816-4 and PKCS #7.
861/// - The operation modes ECB, CBC and PCBC requires padding bytes.
862/// - You can combine three operation modes and two padding ways.
863/// - The operation modes
864/// [`CFB`](./trait.CFB.html#trait.CFB),
865/// [`OFB`](./trait.OFB.html#trait.OFB), and
866/// [`CTR`](./trait.CTR.html#trait.CTR)
867/// does not require padding bytes.
868/// - The traits that implements combination of operation modes and padding
869/// ways are provided such as
870/// [`ECB_PKCS7`](./trait.ECB_PKCS7.html#trait.ECB_PKCS7),
871/// [`ECB_ISO`](./trait.ECB_ISO.html#trait.ECB_ISO),
872/// [`CBC_PKCS7`](./trait.CBC_PKCS7.html#trait.ECB_PKCS7),
873/// [`CBC_ISO`](./trait.CBC_ISO.html#trait.CBC_ISO),
874/// [`PCBC_PKCS7`](./trait.PCBC_PKCS7.html#trait.PCBC_PKCS7), and
875/// [`PCBC_ISO`](./trait.PCBC_ISO.html#trait.PCBC_ISO).
876/// - You can find detaild instructions and their helpful examples
877/// if you go through those links.
878///
879/// In summary,
880///
881/// | | padding PKCS7 | padding ISO | no padding |
882/// |------|--------------------------------------------------------|--------------------------------------------------|-----------------------------------|
883/// | ECB | [ECB_PKCS7](./trait.ECB_PKCS7.html#trait.ECB_PKCS7) | [ECB_ISO](./trait.ECB_ISO.html#trait.ECB_ISO) | |
884/// | CBC | [CBC_PKCS7](./trait.CBC_PKCS7.html#trait.ECB_PKCS7) | [CBC_ISO](./trait.CBC_ISO.html#trait.CBC_ISO) | |
885/// | PCBC | [PCBC_PKCS7](./trait.PCBC_PKCS7.html#trait.PCBC_PKCS7) | [PCBC_ISO](./trait.PCBC_ISO.html#trait.PCBC_ISO) | |
886/// | CFB | | | [CFB](./trait.CFB.html#trait.CFB) |
887/// | OFB | | | [OFB](./trait.OFB.html#trait.OFB) |
888/// | CTR | | | [CTR](./trait.CTR.html#trait.CTR) |
889///
890#[allow(non_camel_case_types)]
891#[derive(Debug, Clone)]
892pub struct Rijndael_Generic<const ROUND: usize = 10, const NB: usize = 4, const NK: usize = 4,
893 const IRREDUCIBLE: u8 = 0b_0001_1011,
894 const AFFINE_MUL: u64 = 0b_11111000_01111100_00111110_00011111_10001111_11000111_11100011_11110001,
895 const AFFINE_ADD: u8 = 0b_01100011,
896 const SR0: usize = 0, const SR1: usize = 1, const SR2: usize = 2, const SR3: usize = 3,
897 const MC00: u8 = 2, const MC01: u8 = 3, const MC02: u8 = 1, const MC03: u8 = 1,
898 const MC10: u8 = 1, const MC11: u8 = 2, const MC12: u8 = 3, const MC13: u8 = 1,
899 const MC20: u8 = 1, const MC21: u8 = 1, const MC22: u8 = 2, const MC23: u8 = 3,
900 const MC30: u8 = 3, const MC31: u8 = 1, const MC32: u8 = 1, const MC33: u8 = 2,
901 const RC0: u32 = 0b_0000_0001, const RC1: u32 = 0b_0000_0010, const RC2: u32 = 0b_0000_0100,
902 const RC3: u32 = 0b_0000_1000, const RC4: u32 = 0b_0001_0000, const RC5: u32 = 0b_0010_0000,
903 const RC6: u32 = 0b_0100_0000, const RC7: u32 = 0b_1000_0000, const RC8: u32 = 0b_0001_1011,
904 const RC9: u32 = 0b_001_10110, const ROT: u32 = 1>
905{
906 key: [IntUnion; NK],
907 block: [[u8; NB]; 4],
908 round_key: Vec<[IntUnion; NB]>,
909 enc: fn (s: &mut Self, message: &[IntUnion; NB]) -> [IntUnion; NB],
910 dec: fn (s: &mut Self, cipher: &[IntUnion; NB]) -> [IntUnion; NB],
911}
912
913impl <const ROUND: usize, const NB: usize, const NK: usize, const IRREDUCIBLE: u8, const AFFINE_MUL: u64,
914 const AFFINE_ADD: u8, const SR0: usize, const SR1: usize, const SR2: usize, const SR3: usize,
915 const MC00: u8, const MC01: u8, const MC02: u8, const MC03: u8,
916 const MC10: u8, const MC11: u8, const MC12: u8, const MC13: u8,
917 const MC20: u8, const MC21: u8, const MC22: u8, const MC23: u8,
918 const MC30: u8, const MC31: u8, const MC32: u8, const MC33: u8,
919 const RC0: u32, const RC1: u32, const RC2: u32, const RC3: u32, const RC4: u32,
920 const RC5: u32, const RC6: u32, const RC7: u32, const RC8: u32, const RC9: u32, const ROT: u32>
921Rijndael_Generic<ROUND, NB, NK, IRREDUCIBLE, AFFINE_MUL, AFFINE_ADD, SR0, SR1, SR2, SR3,
922 MC00, MC01, MC02, MC03, MC10, MC11, MC12, MC13, MC20, MC21, MC22, MC23, MC30, MC31, MC32, MC33,
923 RC0, RC1, RC2, RC3, RC4, RC5, RC6, RC7, RC8, RC9, ROT>
924{
925 pub(super) const BLOCK_SIZE: usize = 4 * NB;
926
927 const SUCCESS: u8 = !0;
928 const FAILURE: u8 = 0;
929 const SBOX: [u8; 256] = make_SBOX!();
930 const INV_SBOX: [u8; 256] = make_INV_SBOX!();
931 const SR: [usize; 4] = [SR0, SR1, SR2, SR3];
932 const MC: [[u8; 4]; 4] = [ [ MC00, MC01, MC02, MC03 ],
933 [ MC10, MC11, MC12, MC13 ],
934 [ MC20, MC21, MC22, MC23 ],
935 [ MC30, MC31, MC32, MC33 ] ];
936 const INV_MC: [[u8; 4]; 4] = make_INV_MC!();
937 const RC: [u32; ROUND] = make_RC_ARRAY!();
938
939 #[allow(non_upper_case_globals)]
940 const method_shift_rows: fn (&mut Self) = if (SR0 == 0) && (SR1 == 1) && (SR2 == 2) && (SR3 == 3)
941 { Self::optimal_shift_rows }
942 else
943 { Self::shift_rows };
944
945 #[allow(non_upper_case_globals)]
946 const method_inv_shift_rows: fn (&mut Self) = if (SR0 == 0) && (SR1 == 1) && (SR2 == 2) && (SR3 == 3)
947 { Self::optimal_inv_shift_rows }
948 else
949 { Self::inv_shift_rows };
950
951 #[allow(non_upper_case_globals)]
952 const method_make_round_keys: fn (&mut Self) = if NK > 6
953 {
954 if NK == NB
955 { Self::make_round_keys_nk_greater_than_6_and_nk_equal_to_nb }
956 else
957 { Self::make_round_keys_nk_greater_than_6_and_nk_diff_from_nb }
958 }
959 else
960 {
961 if NK == NB
962 { Self::make_round_keys_nk_up_to_6_and_nk_equal_to_nb }
963 else
964 { Self::make_round_keys_nk_up_to_6_and_nk_diff_from_nb }
965 };
966
967 #[allow(non_upper_case_globals)]
968 const method_mix_columns: fn (&mut Self) = if (MC00 == 2) && (MC01 == 3) && (MC02 == 1) && (MC03 == 1)
969 && (MC10 == 1) && (MC11 == 2) && (MC12 == 3) && (MC13 == 1)
970 && (MC20 == 1) && (MC21 == 1) && (MC22 == 2) && (MC23 == 3)
971 && (MC30 == 3) && (MC31 == 1) && (MC32 == 1) && (MC33 == 2)
972 { Self::optimal_mix_columns }
973 else
974 { Self::mix_columns };
975
976 // pub fn new() -> Self
977 /// Constructs a new object Rijndael_Generic.
978 ///
979 /// # Features
980 /// - In order to encrypt data, object should be instantiated mutable.
981 /// - This method sets the key to have all bits zeros.
982 /// - The default key which has all bits zeros is not a weak key unlike DES.
983 ///
984 /// # Example 1
985 /// ```
986 /// use cryptocol::symmetric::AES_128;
987 /// let mut _a_aes = AES_128::new();
988 /// let plaintext = 0x1234567890ABCDEF1234567890ABCDEF_u128;
989 /// let ciphertext = _a_aes.encrypt_u128(plaintext);
990 ///
991 /// println!("Plaintext:\t\t{:#032X}", plaintext);
992 /// println!("Ciphertext:\t\t{:#032X}", ciphertext);
993 /// assert_eq!(ciphertext, 0xE2C8CD3BFD4D72366A4806B100659867);
994 ///
995 /// let recovered_cipher_text = _a_aes.decrypt_u128(ciphertext);
996 /// println!("Recovered-ciphertext:\t{:#032X}", recovered_cipher_text);
997 /// assert_eq!(recovered_cipher_text, 0x1234567890ABCDEF1234567890ABCDEF_u128);
998 /// assert_eq!(recovered_cipher_text, plaintext);
999 /// ```
1000 ///
1001 /// # For more examples,
1002 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.new)
1003 pub fn new() -> Self
1004 {
1005 let mut rijndael = Self
1006 {
1007 key: [IntUnion::new(); NK],
1008 block: [[0_u8; NB]; 4],
1009 round_key: vec![[IntUnion::new(); NB]; ROUND + 1],
1010 enc: Self::encrypt_unit,
1011 dec: Self::decrypt_unit,
1012 };
1013 Self::method_make_round_keys(&mut rijndael);
1014 rijndael
1015 }
1016
1017 // pub fn box_new() -> Box<Self>
1018 /// Constructs a new object Rijndael_Generic wrapped by Box.
1019 ///
1020 /// # Features
1021 /// - In order to encrypt data, object should be instantiated mutable.
1022 /// - This method sets the key to have all bits zeros.
1023 /// - The default key which has all bits zeros is not a weak key unlike DES.
1024 ///
1025 /// # Example 1
1026 /// ```
1027 /// use cryptocol::symmetric::AES_128;
1028 /// let mut _a_aes = AES_128::box_new();
1029 /// let plaintext = 0x1234567890ABCDEF1234567890ABCDEF_u128;
1030 /// let ciphertext = _a_aes.encrypt_u128(plaintext);
1031 ///
1032 /// println!("Plaintext:\t\t{:#032X}", plaintext);
1033 /// println!("Ciphertext:\t\t{:#032X}", ciphertext);
1034 /// assert_eq!(ciphertext, 0xE2C8CD3BFD4D72366A4806B100659867);
1035 ///
1036 /// let recovered_cipher_text = _a_aes.decrypt_u128(ciphertext);
1037 /// println!("Recovered-ciphertext:\t{:#032X}", recovered_cipher_text);
1038 /// assert_eq!(recovered_cipher_text, 0x1234567890ABCDEF1234567890ABCDEF_u128);
1039 /// assert_eq!(recovered_cipher_text, plaintext);
1040 /// ```
1041 ///
1042 /// # For more examples,
1043 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.box_new)
1044 #[inline]
1045 pub fn box_new() -> Box<Self>
1046 {
1047 Box::new(Self::new())
1048 }
1049
1050 // pub fn new_with_key<const K: usize>(key: &[u8; K]) -> Self
1051 /// Constructs a new object Rijndael_Generic.
1052 ///
1053 /// # Arguments
1054 /// - The argument `key` is the array of u8 that has `K` elements.
1055 ///
1056 /// # Features
1057 /// - This method sets the key to be the given argument `key`.
1058 /// - If `K` is less than `4 * NK`, the rest bits of
1059 /// the key to be set after `K` bits will be set to be `zero`.
1060 /// - If `K` is greater than `4 * NK`, the rest bits after `4 * NK` bits
1061 /// of the key given as the argument will be ignored.
1062 ///
1063 /// # Example 1 for normal case
1064 /// ```
1065 /// use cryptocol::symmetric::AES_128;
1066 ///
1067 /// let mut aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1068 /// let plaintext = 0x1234567890ABCDEF1234567890ABCDEF_u128;
1069 /// let ciphertext = aes.encrypt_u128(plaintext);
1070 ///
1071 /// println!("Plaintext:\t\t{:#034X}", plaintext);
1072 /// println!("Ciphertext:\t\t{:#034X}", ciphertext);
1073 /// assert_eq!(ciphertext, 0x01CCF8264AECB5D644E2BAE927584D87_u128);
1074 ///
1075 /// let cipher_cipher_text = aes.encrypt_u128(ciphertext);
1076 /// println!("Recovered-ciphertext:\t{:#034X}", recovered_cipher_text);
1077 /// assert_eq!(recovered_cipher_text, 0x1234567890ABCDEF1234567890ABCDEF_u128);
1078 /// assert_eq!(recovered_cipher_text, plaintext);
1079 /// ```
1080 ///
1081 /// # For more examples,
1082 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.new_with_key)
1083 pub fn new_with_key<const K: usize>(key: &[u8; K]) -> Self
1084 {
1085 let mut rijndael = Self
1086 {
1087 key: [IntUnion::new(); NK],
1088 block: [[0_u8; NB]; 4],
1089 round_key: vec![[IntUnion::new(); NB]; ROUND + 1],
1090 enc: Self::encrypt_unit,
1091 dec: Self::decrypt_unit,
1092 };
1093 rijndael.set_key(key);
1094 rijndael
1095 }
1096
1097 // pub fn new_with_key_u128(key: u128) -> Self
1098 /// Constructs a new object Rijndael_Generic.
1099 ///
1100 /// # Arguments
1101 /// - The argument `key` is of `u128`.
1102 /// - It should be in the same endianness of machine. For example,
1103 /// if the intended key is [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD,
1104 /// 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF], the key in
1105 /// `u128` for this argument is 0x_1234567890ABCDEF1234567890ABCDEF_u128
1106 /// for big-endian machine, and the key in `u128` for this argument is
1107 /// 0x_EFCDAB9078563412EFCDAB9078563412_u128 for little-endian machine.
1108 ///
1109 /// # Features
1110 /// - This method sets the key to be the given argument `key`.
1111 /// - If `NK` is less than `4`, the rest bits at the address higher than
1112 /// `4 * NK * 8` bits of the key given as the argument will be ignored.
1113 /// - If `NK` is greater than `4`, the rest bits of the key to be set after
1114 /// 128 bits will be set to be `zero`.
1115 ///
1116 /// # Example 1 for normal case
1117 /// ```
1118 /// use cryptocol::symmetric::AES_128;
1119 ///
1120 /// let mut aes = AES_128::new_with_key_u128(0xEFCDAB9078563412EFCDAB9078563412);
1121 /// let plaintext = 0x1234567890ABCDEF1234567890ABCDEF_u128;
1122 /// let ciphertext = aes.encrypt_u128(plaintext);
1123 ///
1124 /// println!("Plaintext:\t\t{:#034X}", plaintext);
1125 /// println!("Ciphertext:\t\t{:#034X}", ciphertext);
1126 /// assert_eq!(ciphertext, 0x01CCF8264AECB5D644E2BAE927584D87_u128);
1127 ///
1128 /// let recovered_cipher_text = aes.decrypt_u128(ciphertext);
1129 /// println!("Recovered-ciphertext:\t{:#034X}\n", recovered_cipher_text);
1130 /// assert_eq!(recovered_cipher_text, 0x1234567890ABCDEF1234567890ABCDEF_u128);
1131 /// assert_eq!(recovered_cipher_text, plaintext);
1132 /// ```
1133 ///
1134 /// # For more examples,
1135 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.new_with_key_u128)
1136 pub fn new_with_key_u128(key: u128) -> Self
1137 {
1138 let mut rijndael = Self
1139 {
1140 key: [IntUnion::new(); NK],
1141 block: [[0_u8; NB]; 4],
1142 round_key: vec![[IntUnion::new(); NB]; ROUND + 1],
1143 enc: Self::encrypt_unit,
1144 dec: Self::decrypt_unit,
1145 };
1146 rijndael.set_key_u128(key);
1147 rijndael
1148 }
1149
1150 // pub fn encryptor_with_key<const K: usize>(key: &[u8; K]) -> Self
1151 /// Constructs a new object Rijndael_Generic as a positive encryptor (or
1152 /// an encryptor) for the component of BigCryptor128 and NAES.
1153 ///
1154 /// # Arguments
1155 /// - The argument `key` is the array of u8 that has `K` elements.
1156 ///
1157 /// # Features
1158 /// - You won't use this method unless you use BigCryptor128 and NAES
1159 /// for such as Triple AES.
1160 /// - This method constructs the encryptor component of BigCryptor128
1161 /// and NAES.
1162 /// - This method sets the key to be the given argument `key`.
1163 /// - If `K` is less than `4 * NK`, the rest bits of
1164 /// the key to be set after `K` bits will be set to be `zero`.
1165 /// - If `K` is greater than `4 * NK`, the rest bits after `4 * NB` bits
1166 /// of the key given as the argument will be ignored.
1167 ///
1168 /// # Example 1
1169 /// ```
1170 /// use cryptocol::symmetric::{ AES_128, BigCryptor128, SmallCryptor };
1171 ///
1172 /// let keys: [Box<dyn SmallCryptor<u128, 16>>; 3]
1173 /// = [ Box::new(AES_128::encryptor_with_key(&[0xEF_u8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0x21, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE])),
1174 /// Box::new(AES_128::decryptor_with_key(&[0x21_u8, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12])),
1175 /// Box::new(AES_128::encryptor_with_key(&[0xEF_u8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0x21, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE])) ];
1176 /// let mut taes = BigCryptor128::new_with_small_cryptor_array(keys);
1177 /// let plaintext = 0x_1234567890ABCDEFFEDCA0987654321_u128;
1178 /// let ciphertext = taes.encrypt_u128(plaintext);
1179 ///
1180 /// println!("Plaintext:\t\t{:#034X}", plaintext);
1181 /// println!("Ciphertext:\t\t{:#034X}", ciphertext);
1182 /// assert_eq!(ciphertext, 0x_E301940B5A5DE1600D78C375BF58F232_u128);
1183 ///
1184 /// let recovered_text = taes.decrypt_u128(ciphertext);
1185 /// println!("Recovered text:\t{:#034X}", recovered_text);
1186 /// assert_eq!(recovered_text, 0x_1234567890ABCDEFFEDCA0987654321_u128);
1187 /// assert_eq!(recovered_text, plaintext);
1188 /// ```
1189 ///
1190 /// # For more examples,
1191 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encryptor_with_key)
1192 #[inline]
1193 pub fn encryptor_with_key<const K: usize>(key: &[u8; K]) -> Self
1194 {
1195 Self::new_with_key(key)
1196 }
1197
1198 // pub fn encryptor_with_key_u128(key: u128) -> Self
1199 /// Constructs a new object Rijndael_Generic as a positive encryptor (or
1200 /// an encryptor) for the component of BigCryptor128 and NAES.
1201 ///
1202 /// # Arguments
1203 /// - The argument `key` is of `u128`.
1204 /// - It should be in the same endianness of machine. For example,
1205 /// if the intended key is [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD,
1206 /// 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF], the key in
1207 /// `u128` for this argument is 0x_1234567890ABCDEF1234567890ABCDEF_u128
1208 /// for big-endian machine, and the key in `u128` for this argument is
1209 /// 0x_EFCDAB9078563412EFCDAB9078563412_u128 for little-endian machine.
1210 ///
1211 /// # Features
1212 /// - You won't use this method unless you use BigCryptor128 and NAES
1213 /// for such as Triple AES.
1214 /// - This method constructs the encryptor component of BigCryptor128
1215 /// and NAES.
1216 /// - This method sets the key to be the given argument `key`.
1217 /// - If `NK` is less than `4`, the rest bits at the address higher than
1218 /// `4 * NK * 8` bits of the key given as the argument will be ignored.
1219 /// - If `NK` is greater than `4`, the rest bits of the key to be set after
1220 /// 128 bits will be set to be `zero`.
1221 ///
1222 /// # Example 1
1223 /// ```
1224 /// use cryptocol::symmetric::{ AES_128, BigCryptor128, SmallCryptor };
1225 ///
1226 /// let mut taes = BigCryptor128::new_with_small_cryptor_array(
1227 /// [Box::new(AES_128::encryptor_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128)),
1228 /// Box::new(AES_128::decryptor_with_key_u128(0x_FEDCBA09876543211234567890ABCDEF_u128)),
1229 /// Box::new(AES_128::encryptor_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128))]
1230 /// );
1231 /// let plaintext = 0x_11223344556677889900AABBCCDDEEFF_u128;
1232 /// let ciphertext = taes.encrypt_u128(plaintext);
1233 ///
1234 /// println!("Plaintext:\t\t{:#034X}", plaintext);
1235 /// println!("Ciphertext:\t\t{:#034X}", ciphertext);
1236 /// assert_eq!(ciphertext, 0x_DB56B1B7D320D7481BF40A1964E9C7C4_u128);
1237 ///
1238 /// let recovered_text = taes.decrypt_u128(ciphertext);
1239 /// println!("Recovered text:\t{:#034X}", recovered_text);
1240 /// assert_eq!(recovered_text, 0x_11223344556677889900AABBCCDDEEFF_u128);
1241 /// assert_eq!(recovered_text, plaintext);
1242 /// ```
1243 ///
1244 /// # For more examples,
1245 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encryptor_with_key_u128)
1246 #[inline]
1247 pub fn encryptor_with_key_u128(key: u128) -> Self
1248 {
1249 Self::new_with_key_u128(key)
1250 }
1251
1252 // pub fn decryptor_with_key<const K: usize>(key: &[u8; K]) -> Self
1253 /// Constructs a new object Rijndael_Generic as a negative encryptor (or
1254 /// a decryptor) for the component of BigCryptor128 and NAES.
1255 ///
1256 /// # Arguments
1257 /// - The argument `key` is the array of u8 that has `K` elements.
1258 ///
1259 /// # Features
1260 /// - You won't use this method unless you use BigCryptor128 and NAES
1261 /// for such as Triple AES.
1262 /// - This method constructs the encryptor component of BigCryptor128
1263 /// and NAES.
1264 /// - This method sets the key to be the given argument `key`.
1265 /// - If `K` is less than `4 * NK`, the rest bits of
1266 /// the key to be set after `K * 8` bits will be set to be `zero`.
1267 /// - If `K` is greater than `4 * NK`, the rest bits after `4 * NB * 8` bits
1268 /// of the key given as the argument will be ignored.
1269 ///
1270 /// # Example 1
1271 /// ```
1272 /// use cryptocol::symmetric::{ AES_128, BigCryptor128, SmallCryptor };
1273 ///
1274 /// let keys: [Box<dyn SmallCryptor<u128, 16>>; 3]
1275 /// = [ Box::new(AES_128::encryptor_with_key(&[0xEF_u8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0x21, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE])),
1276 /// Box::new(AES_128::decryptor_with_key(&[0x21_u8, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12])),
1277 /// Box::new(AES_128::encryptor_with_key(&[0xEF_u8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12, 0x21, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE])) ];
1278 /// let mut taes = BigCryptor128::new_with_small_cryptor_array(keys);
1279 /// let plaintext = 0x_1234567890ABCDEFFEDCA0987654321_u128;
1280 /// let ciphertext = taes.encrypt_u128(plaintext);
1281 ///
1282 /// println!("Plaintext:\t\t{:#034X}", plaintext);
1283 /// println!("Ciphertext:\t\t{:#034X}", ciphertext);
1284 /// assert_eq!(ciphertext, 0x_E301940B5A5DE1600D78C375BF58F232_u128);
1285 ///
1286 /// let recovered_text = taes.decrypt_u128(ciphertext);
1287 /// println!("Recovered text:\t{:#034X}", recovered_text);
1288 /// assert_eq!(recovered_text, 0x_1234567890ABCDEFFEDCA0987654321_u128);
1289 /// assert_eq!(recovered_text, plaintext);
1290 /// ```
1291 ///
1292 /// # For more examples,
1293 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decryptor_with_key)
1294 pub fn decryptor_with_key<const K: usize>(key: &[u8; K]) -> Self
1295 {
1296 let mut rijndael = Self::new_with_key(key);
1297 rijndael.turn_inverse();
1298 rijndael
1299 }
1300
1301 // pub fn decryptor_with_key_u128(key: u128) -> Self
1302 /// Constructs a new object Rijndael_Generic as a negative encryptor (or
1303 /// a decryptor) for the component of BigCryptor128 and NAES.
1304 ///
1305 /// # Arguments
1306 /// - The argument `key` is of `u128`.
1307 /// - It should be in the same endianness of machine. For example,
1308 /// if the intended key is [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD,
1309 /// 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF], the key in
1310 /// `u128` for this argument is 0x_1234567890ABCDEF1234567890ABCDEF_u128
1311 /// for big-endian machine, and the key in `u128` for this argument is
1312 /// 0x_EFCDAB9078563412EFCDAB9078563412_u128 for little-endian machine.
1313 ///
1314 /// # Features
1315 /// - You won't use this method unless you use BigCryptor128 and NAES
1316 /// for such as Triple AES.
1317 /// - This method constructs the encryptor component of BigCryptor128
1318 /// and NAES.
1319 /// - This method sets the key to be the given argument `key`.
1320 /// - If `NK` is less than `4`, the rest bits at the address higher than
1321 /// `4 * NK * 8` bits of the key given as the argument will be ignored.
1322 /// - If `NK` is greater than `4`, the rest bits of the key to be set after
1323 /// 128 bits will be set to be `zero`.
1324 ///
1325 /// # Example 1
1326 /// ```
1327 /// use cryptocol::symmetric::{ AES_128, BigCryptor128, SmallCryptor };
1328 ///
1329 /// let mut taes = BigCryptor128::new_with_small_cryptor_array(
1330 /// [Box::new(AES_128::encryptor_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128)),
1331 /// Box::new(AES_128::decryptor_with_key_u128(0x_FEDCBA09876543211234567890ABCDEF_u128)),
1332 /// Box::new(AES_128::encryptor_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128))]
1333 /// );
1334 /// let plaintext = 0x_11223344556677889900AABBCCDDEEFF_u128;
1335 /// let ciphertext = taes.encrypt_u128(plaintext);
1336 ///
1337 /// println!("Plaintext:\t\t{:#034X}", plaintext);
1338 /// println!("Ciphertext:\t\t{:#034X}", ciphertext);
1339 /// assert_eq!(ciphertext, 0x_DB56B1B7D320D7481BF40A1964E9C7C4_u128);
1340 ///
1341 /// let recovered_text = taes.decrypt_u128(ciphertext);
1342 /// println!("Recovered text:\t{:#034X}", recovered_text);
1343 /// assert_eq!(recovered_text, 0x_11223344556677889900AABBCCDDEEFF_u128);
1344 /// assert_eq!(recovered_text, plaintext);
1345 /// ```
1346 ///
1347 /// # For more examples,
1348 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decryptor_with_key_u128)
1349 pub fn decryptor_with_key_u128(key: u128) -> Self
1350 {
1351 let mut rijndael = Self::new_with_key_u128(key);
1352 rijndael.turn_inverse();
1353 rijndael
1354 }
1355
1356 // pub fn get_key(&mut self) -> [u32; NK]
1357 /// Gets the key.
1358 ///
1359 /// # Output
1360 /// This method returns the key in the form of array of `u32`.
1361 ///
1362 /// # Example 1 for AES_128
1363 /// ```
1364 /// use cryptocol::symmetric::AES_128;
1365 ///
1366 /// let mut _aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1367 /// let key = _aes.get_key();
1368 /// print!("K = ");
1369 /// for k in key
1370 /// { print!("{:#010X} ", k); }
1371 /// println!();
1372 /// assert_eq!(key, [0x78563412, 0xEFCDAB90, 0x78563412, 0xEFCDAB90]);
1373 /// ```
1374 ///
1375 /// # For more examples,
1376 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.get_key)
1377 pub fn get_key(&mut self) -> [u32; NK]
1378 {
1379 let mut key = [0_u32; NK];
1380 unsafe { copy_nonoverlapping(self.key.as_ptr() as *const u32,
1381 &mut key as *mut u32, NK); }
1382 key
1383 }
1384
1385 // pub fn get_key_u128(&self) -> u128
1386 /// Gets the key.
1387 ///
1388 /// # Output
1389 /// This method returns the key in the form of `u128`.
1390 ///
1391 /// # Features
1392 /// - If `NK` is less than `4`, the rest bits at the address higher than
1393 /// `4 * NK * 8` bits of the returned key will be set to be `zero`.
1394 /// - If `NK` is greater than `4`, the rest bits of the key to be returned
1395 /// after 128 bits will be ignored.
1396 ///
1397 /// # Example 1 for 128-bit key
1398 /// ```
1399 /// use cryptocol::symmetric::AES_128;
1400 ///
1401 /// let mut _aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1402 /// let key = _aes.get_key_u128();
1403 /// println!("Key = {:#034X}", key);
1404 /// assert_eq!(key, 0xEFCDAB9078563412EFCDAB9078563412_u128);
1405 /// ```
1406 ///
1407 /// # For more examples,
1408 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.get_key_u128)
1409 pub fn get_key_u128(&self) -> u128
1410 {
1411 let len = if 16 < NK * 4 { 16 } else { NK * 4 };
1412 let mut key = 0_u128;
1413 unsafe { copy_nonoverlapping(self.key.as_ptr() as *const u8,
1414 &mut key as *mut u128 as *mut u8, len); }
1415 key
1416 }
1417
1418 // pub fn set_key<const K: usize>(&mut self, key: &[u8; K])
1419 /// Sets the key.
1420 ///
1421 /// # Arguments
1422 /// - The argument `key` is the array of `u8` that has `K` elements.
1423 ///
1424 /// # Features
1425 /// - This method sets the key to be the given argument `key`.
1426 /// - If `K` is less than `4 * NK`, the rest bits of
1427 /// the key to be set after `K * 8` bits will be set to be `zero`.
1428 /// - If `K` is greater than `4 * NK`, the rest bits after `4 * NK * 8` bits
1429 /// of the key given as the argument will be ignored.
1430 ///
1431 /// # Example 1 for normal case
1432 /// ```
1433 /// use cryptocol::symmetric::AES_128;
1434 ///
1435 /// let mut aes = AES_128::new();
1436 /// aes.set_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1437 /// let key = aes.get_key();
1438 /// print!("K = ");
1439 /// for k in key
1440 /// { print!("{:#010X} ", k); }
1441 /// println!();
1442 /// assert_eq!(key, [0x78563412, 0xEFCDAB90, 0x78563412, 0xEFCDAB90]);
1443 /// ```
1444 ///
1445 /// # For more examples,
1446 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.set_key)
1447 pub fn set_key<const K: usize>(&mut self, key: &[u8; K])
1448 {
1449 let len = if K < NK * 4 { K } else { NK * 4 };
1450 unsafe {
1451 copy_nonoverlapping(key.as_ptr(), self.key.as_mut_ptr() as *mut u8, len);
1452 }
1453 Self::method_make_round_keys(self);
1454 }
1455
1456 // pub fn set_key_u128(&mut self, key: u128)
1457 /// Constructs a new object Rijndael_Generic.
1458 ///
1459 /// # Arguments
1460 /// - The argument `key` is of `u128`.
1461 /// - It should be in the same endianness of machine. For example,
1462 /// if the intended key is [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD,
1463 /// 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF], the key in
1464 /// `u128` for this argument is 0x_1234567890ABCDEF1234567890ABCDEF_u128
1465 /// for big-endian machine, and the key in `u128` for this argument is
1466 /// 0x_EFCDAB9078563412EFCDAB9078563412_u128 for little-endian machine.
1467 ///
1468 /// # Features
1469 /// - This method sets the key to be the given argument `key`.
1470 /// - If `NK` is less than `4`, the rest bits at the address higher than
1471 /// `4 * NK * 8` bits of the key given as the argument will be ignored.
1472 /// - If `NK` is greater than `4`, the rest bits of the key to be set after
1473 /// 128 bits will be set to be `zero`.
1474 ///
1475 /// # Example 1 for normal case
1476 /// ```
1477 /// use cryptocol::symmetric::AES_128;
1478 ///
1479 /// let mut aes = AES_128::new();
1480 /// aes.set_key_u128(0xEFCDAB9078563412EFCDAB9078563412);
1481 /// let key = aes.get_key();
1482 /// print!("K = ");
1483 /// for k in key
1484 /// { print!("{:#010X} ", k); }
1485 /// println!();
1486 /// assert_eq!(key, [0x78563412, 0xEFCDAB90, 0x78563412, 0xEFCDAB90]);
1487 /// ```
1488 ///
1489 /// # For more examples,
1490 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.set_key_u128)
1491 pub fn set_key_u128(&mut self, key: u128)
1492 {
1493 let len = if 16 < NK * 4 { 16 } else { NK * 4 };
1494 unsafe {
1495 copy_nonoverlapping(&key as *const u128 as *const u8,
1496 self.key.as_mut_ptr() as *mut u8, len);
1497 }
1498 Self::method_make_round_keys(self);
1499 }
1500
1501 pub(crate) fn set_original_key(&mut self, key: &[u32; NK])
1502 {
1503 for i in 0..NK
1504 { self.key[i].set(key[i]); }
1505 }
1506
1507 pub(crate) fn move_to_next_key(&mut self)
1508 {
1509 let mut key = self.get_key();
1510 let mut carry = 1;
1511 let mut old: u32;
1512 for i in 0..NK
1513 {
1514 old = key[i];
1515 key[i] = key[i].wrapping_add(carry);
1516 carry = if key[i] < old {1} else {0};
1517 }
1518 self.set_original_key(&key);
1519 }
1520
1521 // pub fn turn_inverse(&mut self)
1522 /// Flips its role in BigCryptor128 or NAES.
1523 ///
1524 /// # Features
1525 /// - You won't use this method unless you use BigCryptor128 or NAES
1526 /// for such as Triple DES.
1527 /// - Even if you are writing codes in the context of using BigCryptor128
1528 /// or NAES, you will hardly use this method because it is high chance
1529 /// that you will have constructed components with the methods,
1530 /// encryptor_with_key(struct@Rijndael_Generic#method.encryptor_with_key),
1531 /// encryptor_with_key_u64(struct@Rijndael_Generic#method.encryptor_with_key_u128),
1532 /// decryptor_with_key(struct@Rijndael_Generic#method.decryptor_with_key), and
1533 /// decryptor_with_key_u64(struct@Rijndael_Generic#method.decryptor_with_key_u128).
1534 /// - If it is constructed as encryptor for BigCryptor128 or NAES,
1535 /// it will be changed into decryptor.
1536 /// - If it is constructed as decryptor for BigCryptor128 or NAES,
1537 /// it will be changed into encryptor.
1538 ///
1539 /// # Example 1
1540 /// ```
1541 /// use cryptocol::symmetric::{ AES_128, BigCryptor128, SmallCryptor };
1542 ///
1543 /// let mut keys: [Box<dyn SmallCryptor<u128, 16>>; 3]
1544 /// = [ Box::new(AES_128::new_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128)),
1545 /// Box::new(AES_128::new_with_key_u128(0x_FEDCBA09876543211234567890ABCDEF_u128)),
1546 /// Box::new(AES_128::new_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128)) ];
1547 /// keys[1].turn_inverse();
1548 ///
1549 /// let mut taes = BigCryptor128::new_with_small_cryptor_array(keys);
1550 /// let plaintext = 0x_11223344556677889900AABBCCDDEEFF_u128;
1551 /// let ciphertext = taes.encrypt_u128(plaintext);
1552 ///
1553 /// println!("Plaintext:\t\t{:#034X}", plaintext);
1554 /// println!("Ciphertext:\t\t{:#034X}", ciphertext);
1555 /// assert_eq!(ciphertext, 0x_DB56B1B7D320D7481BF40A1964E9C7C4_u128);
1556 ///
1557 /// let recovered_text = taes.decrypt_u128(ciphertext);
1558 /// println!("Recovered text:\t{:#034X}", recovered_text);
1559 /// assert_eq!(recovered_text, 0x_11223344556677889900AABBCCDDEEFF_u128);
1560 /// assert_eq!(recovered_text, plaintext);
1561 /// ```
1562 ///
1563 /// # For more examples,
1564 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.turn_inverse)
1565 #[inline]
1566 pub fn turn_inverse(&mut self)
1567 {
1568 (self.enc, self.dec) = (self.dec, self.enc);
1569 }
1570
1571 // pub fn turn_encryptor(&mut self)
1572 /// Changes its role in BigCryptor128 or NAES to encryptor.
1573 ///
1574 /// # Features
1575 /// - You won't use this method unless you use BigCryptor128 or NAES
1576 /// for such as Triple AES.
1577 /// - Even if you are writing codes in the context of using BigCryptor128
1578 /// or NAES, you will hardly use this method because it is high chance
1579 /// that you will have constructed components with the methods,
1580 /// [encryptor_with_key](struct@Rijndael_Generic#method.encryptor_with_key),
1581 /// [encryptor_with_key_u128](struct@Rijndael_Generic#method.encryptor_with_key_u128),
1582 /// [decryptor_with_key](struct@Rijndael_Generic#method.decryptor_with_key), and
1583 /// [decryptor_with_key_u128](struct@Rijndael_Generic#method.decryptor_with_key_u128).
1584 /// - If it is constructed as encryptor for BigCryptor128 or NAES,
1585 /// it will not be changed at all.
1586 /// - If it is constructed as decryptor for BigCryptor128 or NAES,
1587 /// it will be changed into encryptor.
1588 ///
1589 /// # Example 1
1590 /// ```
1591 /// use cryptocol::symmetric::{ AES_128, BigCryptor128, SmallCryptor };
1592 ///
1593 /// let mut keys: [Box<dyn SmallCryptor<u128, 16>>; 3]
1594 /// = [ Box::new(AES_128::new_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128)),
1595 /// Box::new(AES_128::new_with_key_u128(0x_FEDCBA09876543211234567890ABCDEF_u128)),
1596 /// Box::new(AES_128::new_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128)) ];
1597 /// keys[0].turn_encryptor();
1598 ///
1599 /// let mut taes = BigCryptor128::new_with_small_cryptor_array(keys);
1600 /// let plaintext = 0x_11223344556677889900AABBCCDDEEFF_u128;
1601 /// let ciphertext = taes.encrypt_u128(plaintext);
1602 ///
1603 /// println!("Plaintext:\t\t{:#034X}", plaintext);
1604 /// println!("Ciphertext:\t\t{:#034X}", ciphertext);
1605 /// assert_eq!(ciphertext, 0x_5C842CA9ECB742B2F3164BC33E0BDCB6_u128);
1606 ///
1607 /// let recovered_text = taes.decrypt_u128(ciphertext);
1608 /// println!("Recovered text:\t{:#034X}", recovered_text);
1609 /// assert_eq!(recovered_text, 0x_11223344556677889900AABBCCDDEEFF_u128);
1610 /// assert_eq!(recovered_text, plaintext);
1611 /// ```
1612 ///
1613 /// # For more examples,
1614 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.turn_encryptor)
1615 pub fn turn_encryptor(&mut self)
1616 {
1617 self.enc = Self::encrypt_unit;
1618 self.dec = Self::decrypt_unit;
1619 }
1620
1621 // pub fn turn_decryptor(&mut self)
1622 /// Changes its role in BigCryptor128 or NAES to decryptor.
1623 ///
1624 /// # Features
1625 /// - You won't use this method unless you use BBigCryptor128 or NAES
1626 /// for such as Triple DES.
1627 /// - Even if you are writing codes in the context of using BigCryptor128
1628 /// or NAES, you will hardly use this method because it is high chance
1629 /// that you will have constructed components with the methods,
1630 /// [encryptor_with_key](struct@Rijndael_Generic#method.encryptor_with_key),
1631 /// [encryptor_with_key_u128](struct@Rijndael_Generic#method.encryptor_with_key_u128),
1632 /// [decryptor_with_key](struct@Rijndael_Generic#method.decryptor_with_key), and
1633 /// [decryptor_with_key_u128](struct@Rijndael_Generic#method.decryptor_with_key_u128).
1634 /// - If it is constructed as encryptor for BigCryptor128 or NAES,
1635 /// it will be changed into decryptor.
1636 /// - If it is constructed as decryptor for BigCryptor128 or NAES,
1637 /// it will not be changed at all.
1638 ///
1639 /// # Example 1
1640 /// ```
1641 /// use cryptocol::symmetric::{ AES_128, BigCryptor128, SmallCryptor };
1642 ///
1643 /// let mut keys: [Box<dyn SmallCryptor<u128, 16>>; 3]
1644 /// = [ Box::new(AES_128::new_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128)),
1645 /// Box::new(AES_128::new_with_key_u128(0x_FEDCBA09876543211234567890ABCDEF_u128)),
1646 /// Box::new(AES_128::new_with_key_u128(0x_1234567890ABCDEFFEDCA0987654321_u128)) ];
1647 /// keys[1].turn_decryptor();
1648 ///
1649 /// let mut taes = BigCryptor128::new_with_small_cryptor_array(keys);
1650 /// let plaintext = 0x_11223344556677889900AABBCCDDEEFF_u128;
1651 /// let ciphertext = taes.encrypt_u128(plaintext);
1652 ///
1653 /// println!("Plaintext:\t\t{:#034X}", plaintext);
1654 /// println!("Ciphertext:\t\t{:#034X}", ciphertext);
1655 /// assert_eq!(ciphertext, 0x_DB56B1B7D320D7481BF40A1964E9C7C4_u128);
1656 ///
1657 /// let recovered_text = taes.decrypt_u128(ciphertext);
1658 /// println!("Recovered text:\t{:#034X}", recovered_text);
1659 /// assert_eq!(recovered_text, 0x_11223344556677889900AABBCCDDEEFF_u128);
1660 /// assert_eq!(recovered_text, plaintext);
1661 /// ```
1662 ///
1663 /// # For more examples,
1664 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.turn_decryptor)
1665 pub fn turn_decryptor(&mut self)
1666 {
1667 self.enc = Self::decrypt_unit;
1668 self.dec = Self::encrypt_unit;
1669 }
1670
1671 // pub fn encrypt_unit(&mut self, message: &[IntUnion; NB]) -> [IntUnion; NB]
1672 /// Encrypts data in the form of an array of IntUnion with `NB` elements.
1673 ///
1674 /// # Arguments
1675 /// `message` is of the type `&[IntUnion; NB]`
1676 /// and the plaintext to be encrypted.
1677 ///
1678 /// # Output
1679 /// This method returns the encrypted data in the array of `IntUnion`
1680 /// with `NB` elements.
1681 ///
1682 /// # Counterpart methods
1683 /// For each trait
1684 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
1685 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
1686 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
1687 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
1688 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
1689 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
1690 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
1691 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
1692 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
1693 /// there are provided useful counterpart methods:
1694 /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
1695 /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
1696 /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
1697 /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
1698 /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array().
1699 ///
1700 /// # Example 1 for AES_128
1701 /// ```
1702 /// use cryptocol::number::IntUnion;
1703 /// use cryptocol::symmetric::AES_128;
1704 ///
1705 /// let mut aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1706 /// let plaintext = [IntUnion::new_with(0x90ABCDEF), IntUnion::new_with(0x12345678), IntUnion::new_with(0x90ABCDEF), IntUnion::new_with(0x12345678)];
1707 /// let ciphertext = aes.encrypt_unit(&plaintext);
1708 ///
1709 /// println!("Plaintext:\t{:08X}{:08X}{:08X}{:08X}", plaintext[0].get(), plaintext[1].get(), plaintext[2].get(), plaintext[3].get());
1710 /// println!("Ciphertext:\t{:08X}{:08X}{:08X}{:08X}", ciphertext[0].get(), ciphertext[1].get(), ciphertext[2].get(), ciphertext[3].get());
1711 /// assert_eq!(ciphertext[0].get(), 0x27584D87);
1712 /// assert_eq!(ciphertext[1].get(), 0x44E2BAE9);
1713 /// assert_eq!(ciphertext[2].get(), 0x4AECB5D6);
1714 /// assert_eq!(ciphertext[3].get(), 0x01CCF826);
1715 /// ```
1716 ///
1717 /// # For more examples,
1718 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encrypt_unit)
1719 pub fn encrypt_unit(&mut self, message: &[IntUnion; NB]) -> [IntUnion; NB]
1720 {
1721 self.set_block(message);
1722 self.encrypt_block();
1723 self.get_block()
1724 }
1725
1726 // pub fn encrypt_u128(&mut self, message: u128) -> u128
1727 /// Encrypts a 128-bit data.
1728 ///
1729 /// # Arguments
1730 /// `message` is of `u128`-type and the plaintext to be encrypted.
1731 ///
1732 /// # Output
1733 /// This method returns the encrypted data of `u128`-type from `message`.
1734 ///
1735 /// # Caution
1736 /// - This method is meaningful only when `NB` is `4`.
1737 /// - If `NB` is other than `4`, this method may panic.
1738 /// - Even if this method does not panic, its behaviour is not defined.
1739 ///
1740 /// # Counterpart Methods
1741 /// For each trait
1742 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
1743 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
1744 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
1745 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
1746 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
1747 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
1748 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
1749 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
1750 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
1751 /// there are provided useful counterpart methods:
1752 /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
1753 /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
1754 /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
1755 /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
1756 /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array().
1757 ///
1758 /// # Example 1 for AES_128
1759 /// ```
1760 /// use cryptocol::symmetric::AES_128;
1761 ///
1762 /// let mut aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1763 /// let plaintext = 0x1234567890ABCDEF1234567890ABCDEF;
1764 /// let ciphertext = aes.encrypt_u128(plaintext);
1765 ///
1766 /// println!("Plaintext:\t{:#034X}", plaintext);
1767 /// println!("Ciphertext:\t{:#034X}", ciphertext);
1768 /// assert_eq!(ciphertext, 0x01CCF8264AECB5D644E2BAE927584D87_u128);
1769 /// ```
1770 ///
1771 /// # For more examples,
1772 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encrypt_u128)
1773 pub fn encrypt_u128(&mut self, message: u128) -> u128
1774 {
1775 self.set_block_u128(message);
1776 self.encrypt_block();
1777 self.get_block_u128()
1778 }
1779
1780 // pub fn encrypt_u64(&mut self, message: u64) -> u64
1781 /// Encrypts a 64-bit data.
1782 ///
1783 /// # Arguments
1784 /// `message` is of `u64`-type and the plaintext to be encrypted.
1785 ///
1786 /// # Output
1787 /// This method returns the encrypted data of `u64`-type from `message`.
1788 ///
1789 /// # Caution
1790 /// - This method is meaningful only when `NB` is `2`.
1791 /// - If `NB` is other than `2`, this method may panic.
1792 /// - Even if this method does not panic, its behaviour is not defined.
1793 ///
1794 /// # Counterpart Methods
1795 /// For each trait
1796 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
1797 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
1798 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
1799 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
1800 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
1801 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
1802 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
1803 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
1804 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
1805 /// there are provided useful counterpart methods:
1806 /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
1807 /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
1808 /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
1809 /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
1810 /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array().
1811 ///
1812 /// # Example 1 for Rijndael_64_64
1813 /// ```
1814 /// use cryptocol::symmetric::Rijndael_64_64;
1815 ///
1816 /// let mut rijndael = Rijndael_64_64::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1817 /// let plaintext = 0x1234567890ABCDEF;
1818 /// println!("Plaintext:\t{:#018X}", plaintext);
1819 /// let ciphertext = rijndael.encrypt_u64(plaintext);
1820 /// println!("Ciphertext:\t{:#018X}", ciphertext);
1821 /// assert_eq!(ciphertext, 0x4FAA3F0E49CC4DCF_u64);
1822 /// ```
1823 ///
1824 /// # For more examples,
1825 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encrypt_u64)
1826 pub fn encrypt_u64(&mut self, message: u64) -> u64
1827 {
1828 self.set_block_u64(message);
1829 self.encrypt_block();
1830 self.get_block_u64()
1831 }
1832
1833 // pub fn encrypt_u32(&mut self, message: u32) -> u32
1834 /// Encrypts a 32-bit data.
1835 ///
1836 /// # Arguments
1837 /// `message` is of `u32`-type and the plaintext to be encrypted.
1838 ///
1839 /// # Output
1840 /// This method returns the encrypted data of `u32`-type from `message`.
1841 ///
1842 /// # Caution
1843 /// - This method is meaningful only when `NB` is `1`.
1844 /// - If `NB` is other than `1`, this method may panic.
1845 /// - Even if this method does not panic, its behaviour is not defined.
1846 ///
1847 /// # Counterpart Methods
1848 /// For each trait
1849 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
1850 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
1851 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
1852 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
1853 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
1854 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
1855 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
1856 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
1857 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
1858 /// there are provided useful counterpart methods:
1859 /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
1860 /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
1861 /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
1862 /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
1863 /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array().
1864 ///
1865 /// # Example 1 for Rijndael_32_32
1866 /// ```
1867 /// use cryptocol::symmetric::Rijndael_32_32;
1868 ///
1869 /// let mut rijndael = Rijndael_32_32::new_with_key(&[0x12, 0x34, 0x56, 0x78]);
1870 /// let plaintext = 0x1234567;
1871 /// println!("Plaintext:\t{:#010X}", plaintext);
1872 /// let ciphertext = rijndael.encrypt_u32(plaintext);
1873 /// println!("Ciphertext:\t{:#010X}", ciphertext);
1874 /// assert_eq!(ciphertext, 0xB25E4E09_u32);
1875 /// ```
1876 ///
1877 /// # For more examples,
1878 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encrypt_u32)
1879 pub fn encrypt_u32(&mut self, message: u32) -> u32
1880 {
1881 self.set_block_u32(message);
1882 self.encrypt_block();
1883 self.get_block_u32()
1884 }
1885
1886 // pub fn decrypt_unit(&mut self, cipher: &[IntUnion; NB]) -> [IntUnion; NB]
1887 /// Decrypts data in the form of an array of IntUnion with `NB` elements.
1888 ///
1889 /// # Arguments
1890 /// `cipher` is of the type `&[IntUnion; NB]`
1891 /// and the ciphertext to be decrypted.
1892 ///
1893 /// # Output
1894 /// This method returns the decrypted data in the array of `IntUnion`
1895 /// with `NB` elements.
1896 ///
1897 /// # Counterpart Methods
1898 /// For each trait
1899 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
1900 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
1901 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
1902 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
1903 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
1904 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
1905 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
1906 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
1907 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
1908 /// there are provided useful counterpart methods:
1909 /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
1910 /// decrypt_into_string(),
1911 /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
1912 /// decrypt_vec_into_string(),
1913 /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
1914 /// and decrypt_array_into_string().
1915 ///
1916 /// # Example 1 for AES_128
1917 /// ```
1918 /// use cryptocol::number::IntUnion;
1919 /// use cryptocol::symmetric::AES_128;
1920 ///
1921 /// let mut aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1922 /// let ciphertext = [IntUnion::new_with(0x27584D87), IntUnion::new_with(0x44E2BAE9), IntUnion::new_with(0x4AECB5D6), IntUnion::new_with(0x01CCF826)];
1923 /// let plaintext = aes.decrypt_unit(&ciphertext);
1924 ///
1925 /// println!("Ciphertext:\t{:08X}{:08X}{:08X}{:08X}", ciphertext[0].get(), ciphertext[1].get(), ciphertext[2].get(), ciphertext[3].get());
1926 /// println!("Plaintext:\t{:08X}{:08X}{:08X}{:08X}", plaintext[0].get(), plaintext[1].get(), plaintext[2].get(), plaintext[3].get());
1927 /// assert_eq!(plaintext[0].get(), 0x90ABCDEF);
1928 /// assert_eq!(plaintext[1].get(), 0x12345678);
1929 /// assert_eq!(plaintext[2].get(), 0x90ABCDEF);
1930 /// assert_eq!(plaintext[3].get(), 0x12345678);
1931 /// ```
1932 ///
1933 /// # For more examples,
1934 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decrypt_unit)
1935 pub fn decrypt_unit(&mut self, cipher: &[IntUnion; NB]) -> [IntUnion; NB]
1936 {
1937 self.set_block(cipher);
1938 self.decrypt_block();
1939 self.get_block()
1940 }
1941
1942 // pub fn decrypt_u128(&mut self, cipher: u128) -> u128
1943 /// Decrypts a 128-bit data.
1944 ///
1945 /// # Arguments
1946 /// `cioher` is of `u128`-type and the ciphertext to be decrypted.
1947 ///
1948 /// # Output
1949 /// This method returns the decrypted data of `u128`-type from `cipher`.
1950 ///
1951 /// # Caution
1952 /// - This method is meaningful only when `NB` is `4`.
1953 /// - If `NB` is other than `4`, this method may panic.
1954 /// - Even if this method does not panic, its behaviour is not defined.
1955 ///
1956 /// # Counterpart Methods
1957 /// For each trait
1958 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
1959 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
1960 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
1961 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
1962 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
1963 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
1964 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
1965 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
1966 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
1967 /// there are provided useful counterpart methods:
1968 /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
1969 /// decrypt_into_string(),
1970 /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
1971 /// decrypt_vec_into_string(),
1972 /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
1973 /// and decrypt_array_into_string().
1974 ///
1975 /// # Example 1 for AES_128
1976 /// ```
1977 /// use cryptocol::number::IntUnion;
1978 /// use cryptocol::symmetric::AES_128;
1979 ///
1980 /// let mut aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1981 /// let ciphertext = 0x01CCF8264AECB5D644E2BAE927584D87_u128;
1982 /// let plaintext = aes.decrypt_u128(ciphertext);
1983 ///
1984 /// println!("Ciphertext:\t{:#034X}", ciphertext);
1985 /// println!("Plaintext:\t{:#034X}", plaintext);
1986 /// assert_eq!(plaintext, 0x1234567890ABCDEF1234567890ABCDEF);
1987 /// ```
1988 ///
1989 /// # For more examples,
1990 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decrypt_u128)
1991 pub fn decrypt_u128(&mut self, cipher: u128) -> u128
1992 {
1993 self.set_block_u128(cipher);
1994 self.decrypt_block();
1995 self.get_block_u128()
1996 }
1997
1998 // pub fn decrypt_u64(&mut self, cipher: u64) -> u64
1999 /// Decrypts a 64-bit data.
2000 ///
2001 /// # Arguments
2002 /// `cioher` is of `u64`-type and the ciphertext to be decrypted.
2003 ///
2004 /// # Output
2005 /// This method returns the decrypted data of `u64`-type from `cipher`.
2006 ///
2007 /// # Caution
2008 /// - This method is meaningful only when `NB` is `2`.
2009 /// - If `NB` is other than `2`, this method may panic.
2010 /// - Even if this method does not panic, its behaviour is not defined.
2011 ///
2012 /// # Counterpart Methods
2013 /// For each trait
2014 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2015 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2016 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2017 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2018 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2019 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2020 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2021 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2022 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2023 /// there are provided useful counterpart methods:
2024 /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
2025 /// decrypt_into_string(),
2026 /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
2027 /// decrypt_vec_into_string(),
2028 /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
2029 /// and decrypt_array_into_string().
2030 ///
2031 /// # Example 1 for Rijndael_64_64
2032 /// ```
2033 /// use cryptocol::symmetric::Rijndael_64_64;
2034 ///
2035 /// let mut rijndael = Rijndael_64_64::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2036 /// let ciphertext = 0x4FAA3F0E49CC4DCF_u64;
2037 /// println!("Ciphertext:\t{:#018X}", ciphertext);
2038 /// let plaintext = rijndael.decrypt_u64(ciphertext);
2039 /// println!("Plaintext:\t{:#018X}", plaintext);
2040 /// assert_eq!(plaintext, 0x1234567890ABCDEF_u64);
2041 /// ```
2042 ///
2043 /// # For more examples,
2044 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decrypt_u64)
2045 pub fn decrypt_u64(&mut self, cipher: u64) -> u64
2046 {
2047 self.set_block_u64(cipher);
2048 self.decrypt_block();
2049 self.get_block_u64()
2050 }
2051
2052 // pub fn decrypt_u32(&mut self, cipher: u32) -> u32
2053 /// Decrypts a 32-bit data.
2054 ///
2055 /// # Arguments
2056 /// `cioher` is of `u32`-type and the ciphertext to be decrypted.
2057 ///
2058 /// # Output
2059 /// This method returns the decrypted data of `u32`-type from `cipher`.
2060 ///
2061 /// # Caution
2062 /// - This method is meaningful only when `NB` is `1`.
2063 /// - If `NB` is other than `1`, this method may panic.
2064 /// - Even if this method does not panic, its behaviour is not defined.
2065 ///
2066 /// # Counterpart Methods
2067 /// For each trait
2068 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2069 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2070 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2071 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2072 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2073 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2074 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2075 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2076 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2077 /// there are provided useful counterpart methods:
2078 /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
2079 /// decrypt_into_string(),
2080 /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
2081 /// decrypt_vec_into_string(),
2082 /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
2083 /// and decrypt_array_into_string().
2084 ///
2085 /// # Example 1 for Rijndael_32_32
2086 /// ```
2087 /// use cryptocol::symmetric::Rijndael_32_32;
2088 ///
2089 /// let mut rijndael = Rijndael_32_32::new_with_key(&[0x12, 0x34, 0x56, 0x78]);
2090 /// let ciphertext = 0xB25E4E09_u32;
2091 /// println!("Ciphertext:\t{:#010X}", ciphertext);
2092 /// let plaintext = rijndael.decrypt_u32(ciphertext);
2093 /// println!("Plaintext:\t{:#010X}", plaintext);
2094 /// assert_eq!(plaintext, 0x1234567_u32);
2095 /// ```
2096 ///
2097 /// # For more examples,
2098 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decrypt_u32)
2099 pub fn decrypt_u32(&mut self, cipher: u32) -> u32
2100 {
2101 self.set_block_u32(cipher);
2102 self.decrypt_block();
2103 self.get_block_u32()
2104 }
2105
2106 #[inline]
2107 pub(super) fn _encrypt(&mut self, message: &[IntUnion; NB]) -> [IntUnion; NB]
2108 {
2109 (self.enc)(self, message)
2110 }
2111
2112 #[inline]
2113 pub(super) fn _decrypt(&mut self, cipher: &[IntUnion; NB]) -> [IntUnion; NB]
2114 {
2115 (self.dec)(self, cipher)
2116 }
2117
2118 // pub fn encrypt_array_unit<const N: usize>(&mut self, message: &[[IntUnion; NB]; N], cipher: &mut [[IntUnion; NB]; N])
2119 /// Encrypts an array of unit data, `[[IntUnion; NB]; N]`.
2120 ///
2121 /// # Arguments
2122 /// - `message` is of an array of `[IntUnion; NB]`-type and the plaintext
2123 /// to be encrypted.
2124 /// - `cipher` is of an array of `[IntUnion; NB]`-type and the ciphertext
2125 /// to be stored.
2126 ///
2127 /// # Features
2128 /// This method encrypts multiple of 64-bit data without padding anything
2129 /// in ECB (Electronic CodeBook) mode.
2130 ///
2131 /// # Counterpart Methods
2132 /// For each trait
2133 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2134 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2135 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2136 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2137 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2138 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2139 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2140 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2141 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2142 /// there are provided useful counterpart methods:
2143 /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
2144 /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
2145 /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
2146 /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
2147 /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array().
2148 ///
2149 /// # Example 1 for AES_128
2150 /// ```
2151 /// use cryptocol::number::IntUnion;
2152 /// use cryptocol::symmetric::AES_128;
2153 ///
2154 /// let mut aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2155 /// let plaintext = [[IntUnion::new_with(0x90ABCDEF), IntUnion::new_with(0x12345678), IntUnion::new_with(0x90ABCDEF), IntUnion::new_with(0x12345678)]; 3];
2156 /// let mut ciphertext = [[IntUnion::new(); 4]; 3];
2157 /// aes.encrypt_array_unit(&plaintext, &mut ciphertext);
2158 ///
2159 /// println!("Plaintext:\t{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}",
2160 /// plaintext[0][0].get(), plaintext[0][1].get(), plaintext[0][2].get(), plaintext[0][3].get(),
2161 /// plaintext[1][0].get(), plaintext[1][1].get(), plaintext[1][2].get(), plaintext[1][3].get(),
2162 /// plaintext[2][0].get(), plaintext[2][1].get(), plaintext[2][2].get(), plaintext[2][3].get());
2163 /// println!("Ciphertext:\t{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}",
2164 /// ciphertext[0][0].get(), ciphertext[0][1].get(), ciphertext[0][2].get(), ciphertext[0][3].get(),
2165 /// ciphertext[1][0].get(), ciphertext[1][1].get(), ciphertext[1][2].get(), ciphertext[1][3].get(),
2166 /// ciphertext[2][0].get(), ciphertext[2][1].get(), ciphertext[2][2].get(), ciphertext[2][3].get());
2167 /// assert_eq!(ciphertext[0][0].get(), 0x27584D87);
2168 /// assert_eq!(ciphertext[0][1].get(), 0x44E2BAE9);
2169 /// assert_eq!(ciphertext[0][2].get(), 0x4AECB5D6);
2170 /// assert_eq!(ciphertext[0][3].get(), 0x01CCF826);
2171 /// assert_eq!(ciphertext[1][0].get(), 0x27584D87);
2172 /// assert_eq!(ciphertext[1][1].get(), 0x44E2BAE9);
2173 /// assert_eq!(ciphertext[1][2].get(), 0x4AECB5D6);
2174 /// assert_eq!(ciphertext[1][3].get(), 0x01CCF826);
2175 /// assert_eq!(ciphertext[2][0].get(), 0x27584D87);
2176 /// assert_eq!(ciphertext[2][1].get(), 0x44E2BAE9);
2177 /// assert_eq!(ciphertext[2][2].get(), 0x4AECB5D6);
2178 /// assert_eq!(ciphertext[2][3].get(), 0x01CCF826);
2179 /// ```
2180 ///
2181 /// # For more examples,
2182 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encrypt_array_unit)
2183 pub fn encrypt_array_unit<const N: usize>(&mut self, message: &[[IntUnion; NB]; N], cipher: &mut [[IntUnion; NB]; N])
2184 {
2185 for i in 0..N
2186 {
2187 self.set_block(&message[i]);
2188 self.encrypt_block();
2189 cipher[i] = self.get_block();
2190 }
2191 }
2192
2193 // pub fn encrypt_array_u128<const N: usize>(&mut self, message: &[u128; N], cipher: &mut [u128; N])
2194 /// Encrypts an array of 128-bit data.
2195 ///
2196 /// # Arguments
2197 /// - `message` is of an array of `u128`-type and the plaintext
2198 /// to be encrypted.
2199 /// - `cipher` is of an array of `u128`-type and the ciphertext
2200 /// to be stored.
2201 ///
2202 /// # Features
2203 /// This method encrypts multiple of 128-bit data without padding anything
2204 /// in ECB (Electronic CodeBook) mode.
2205 ///
2206 /// # Caution
2207 /// - This method is meaningful only when `NB` is `4`.
2208 /// - If `NB` is other than `4`, this method may panic.
2209 /// - Even if this method does not panic, its behaviour is not defined.
2210 ///
2211 /// # Counterpart Methods
2212 /// For each trait
2213 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2214 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2215 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2216 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2217 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2218 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2219 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2220 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2221 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2222 /// there are provided useful counterpart methods:
2223 /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
2224 /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
2225 /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
2226 /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
2227 /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array().
2228 ///
2229 /// # Example 1 for AES_128
2230 /// ```
2231 /// use cryptocol::symmetric::AES_128;
2232 ///
2233 /// let mut aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2234 /// let plaintext = [0x1234567890ABCDEF1234567890ABCDEF_u128, 0x11223344556677889900AABBCCDDEEFF, 0xFFEEDDCCBBAA00998877665544332211];
2235 /// let mut ciphertext = [0_u128; 3];
2236 /// aes.encrypt_array_u128(&plaintext, &mut ciphertext);
2237 ///
2238 /// println!("Plaintext:\t{:#034X} {:#034X} {:#034X}", plaintext[0], plaintext[1], plaintext[2]);
2239 /// println!("Ciphertext:\t{:#034X} {:#034X} {:#034X}", ciphertext[0], ciphertext[1], ciphertext[2]);
2240 /// assert_eq!(ciphertext[0], 0x01CCF8264AECB5D644E2BAE927584D87_u128);
2241 /// assert_eq!(ciphertext[1], 0x7601C1D6EA61791544C28D4004577BB9_u128);
2242 /// assert_eq!(ciphertext[2], 0xB7225E77C077541D5055FE9C8D3894B9_u128);
2243 /// ```
2244 ///
2245 /// # For more examples,
2246 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encrypt_array_u128)
2247 pub fn encrypt_array_u128<const N: usize>(&mut self, message: &[u128; N], cipher: &mut [u128; N])
2248 {
2249 for i in 0..N
2250 {
2251 self.set_block_u128(message[i]);
2252 self.encrypt_block();
2253 cipher[i] = self.get_block_u128();
2254 }
2255 }
2256
2257 // pub fn encrypt_array_u64<const N: usize>(&mut self, message: &[u64; N], cipher: &mut [u64; N])
2258 /// Encrypts an array of 64-bit data.
2259 ///
2260 /// # Arguments
2261 /// - `message` is of an array of `u64`-type and the plaintext
2262 /// to be encrypted.
2263 /// - `cipher` is of an array of `u64`-type and the ciphertext
2264 /// to be stored.
2265 ///
2266 /// # Features
2267 /// This method encrypts multiple of 64-bit data without padding anything
2268 /// in ECB (Electronic CodeBook) mode.
2269 ///
2270 /// # Caution
2271 /// - This method is meaningful only when `NB` is `2`.
2272 /// - If `NB` is other than `2`, this method may panic.
2273 /// - Even if this method does not panic, its behaviour is not defined.
2274 ///
2275 /// # Counterpart Methods
2276 /// For each trait
2277 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2278 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2279 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2280 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2281 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2282 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2283 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2284 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2285 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2286 /// there are provided useful counterpart methods:
2287 /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
2288 /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
2289 /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
2290 /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
2291 /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array().
2292 ///
2293 /// # Example 1 for Rijndael_64_64
2294 /// ```
2295 /// use cryptocol::symmetric::Rijndael_64_64;
2296 ///
2297 /// let mut rijndael = Rijndael_64_64::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2298 /// let plaintext = [0x1234567890ABCDEF_u64, 0x1122334455667788, 0xFFEEDDCCBBAA0099];
2299 /// let mut ciphertext = [0_u64; 3];
2300 /// rijndael.encrypt_array_u64(&plaintext, &mut ciphertext);
2301 ///
2302 /// println!("Plaintext:\t{:#018X} {:#018X} {:#018X}", plaintext[0], plaintext[1], plaintext[2]);
2303 /// println!("Ciphertext:\t{:#018X} {:#018X} {:#018X}", ciphertext[0], ciphertext[1], ciphertext[2]);
2304 /// assert_eq!(ciphertext[0], 0x4FAA3F0E49CC4DCF_u64);
2305 /// assert_eq!(ciphertext[1], 0x036AAEDC0F1A5BEC_u64);
2306 /// assert_eq!(ciphertext[2], 0x99B8209339BCC1EB_u64);
2307 /// ```
2308 ///
2309 /// # For more examples,
2310 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encrypt_array_u64)
2311 pub fn encrypt_array_u64<const N: usize>(&mut self, message: &[u64; N], cipher: &mut [u64; N])
2312 {
2313 for i in 0..N
2314 {
2315 self.set_block_u64(message[i]);
2316 self.encrypt_block();
2317 cipher[i] = self.get_block_u64();
2318 }
2319 }
2320
2321 // pub fn encrypt_array_u32<const N: usize>(&mut self, message: &[u32; N], cipher: &mut [u32; N])
2322 /// Encrypts an array of 32-bit data.
2323 ///
2324 /// # Arguments
2325 /// - `message` is of an array of `u32`-type and the plaintext
2326 /// to be encrypted.
2327 /// - `cipher` is of an array of `u32`-type and the ciphertext
2328 /// to be stored.
2329 ///
2330 /// # Features
2331 /// This method encrypts multiple of 32-bit data without padding anything
2332 /// in ECB (Electronic CodeBook) mode.
2333 ///
2334 /// # Caution
2335 /// - This method is meaningful only when `NB` is `1`.
2336 /// - If `NB` is other than `1`, this method may panic.
2337 /// - Even if this method does not panic, its behaviour is not defined.
2338 ///
2339 /// # Counterpart Methods
2340 /// For each trait
2341 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2342 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2343 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2344 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2345 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2346 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2347 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2348 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2349 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2350 /// there are provided useful counterpart methods:
2351 /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
2352 /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
2353 /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
2354 /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
2355 /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array().
2356 ///
2357 /// # Example 1 for Rijndael_32_32
2358 /// ```
2359 /// use cryptocol::symmetric::Rijndael_32_32;
2360 ///
2361 /// let mut rijndael = Rijndael_32_32::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2362 /// let plaintext = [0x12345678_u32, 0x90ABCDEF, 0xFFEEDDCC];
2363 /// let mut ciphertext = [0_u32; 3];
2364 /// rijndael.encrypt_array_u32(&plaintext, &mut ciphertext);
2365 ///
2366 /// println!("Plaintext:\t{:#010X} {:#010X} {:#010X}", plaintext[0], plaintext[1], plaintext[2]);
2367 /// println!("Ciphertext:\t{:#010X} {:#010X} {:#010X}", ciphertext[0], ciphertext[1], ciphertext[2]);
2368 /// assert_eq!(ciphertext[0], 0x335228F6_u32);
2369 /// assert_eq!(ciphertext[1], 0xBFB99AFB_u32);
2370 /// assert_eq!(ciphertext[2], 0x2D114838_u32);
2371 /// ```
2372 ///
2373 /// # For more examples,
2374 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.encrypt_array_u32)
2375 pub fn encrypt_array_u32<const N: usize>(&mut self, message: &[u32; N], cipher: &mut [u32; N])
2376 {
2377 for i in 0..N
2378 {
2379 self.set_block_u32(message[i]);
2380 self.encrypt_block();
2381 cipher[i] = self.get_block_u32();
2382 }
2383 }
2384
2385 // pub fn decrypt_array_unit<const N: usize>(&mut self, cipher: &[[IntUnion; NB]; N], message: &mut [[IntUnion; NB]; N])
2386 /// Decrypts an array of unit data, `[[IntUnion; NB]; N]`.
2387 ///
2388 /// # Arguments
2389 /// - `cipher` is of an array of `[IntUnion; NB]`-type and the ciphertext
2390 /// to be encrypted.
2391 /// - `message` is of an array of `[IntUnion; NB]`-type and the plaintext
2392 /// to be stored.
2393 ///
2394 /// # Features
2395 /// This method decrypts multiple of 64-bit data without padding anything
2396 /// in ECB (Electronic CodeBook) mode.
2397 ///
2398 /// # Counterpart Methods
2399 /// For each trait
2400 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2401 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2402 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2403 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2404 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2405 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2406 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2407 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2408 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2409 /// there are provided useful counterpart methods:
2410 /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
2411 /// decrypt_into_string(),
2412 /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
2413 /// decrypt_vec_into_string(),
2414 /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
2415 /// and decrypt_array_into_string().
2416 ///
2417 /// # Example 1 for AES_128
2418 /// ```
2419 /// use cryptocol::number::IntUnion;
2420 /// use cryptocol::symmetric::AES_128;
2421 ///
2422 /// let mut aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2423 /// let ciphertext = [[IntUnion::new_with(0x27584D87), IntUnion::new_with(0x44E2BAE9), IntUnion::new_with(0x4AECB5D6), IntUnion::new_with(0x01CCF826)]; 3];
2424 /// let mut plaintext = [[IntUnion::new(); 4]; 3];
2425 /// aes.decrypt_array_unit(&ciphertext, &mut plaintext);
2426 ///
2427 /// println!("Ciphertext:\t{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}",
2428 /// ciphertext[0][0].get(), ciphertext[0][1].get(), ciphertext[0][2].get(), ciphertext[0][3].get(),
2429 /// ciphertext[1][0].get(), ciphertext[1][1].get(), ciphertext[1][2].get(), ciphertext[1][3].get(),
2430 /// ciphertext[2][0].get(), ciphertext[2][1].get(), ciphertext[2][2].get(), ciphertext[2][3].get());
2431 /// println!("Plaintext:\t{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}{:08X}",
2432 /// plaintext[0][0].get(), plaintext[0][1].get(), plaintext[0][2].get(), plaintext[0][3].get(),
2433 /// plaintext[1][0].get(), plaintext[1][1].get(), plaintext[1][2].get(), plaintext[1][3].get(),
2434 /// plaintext[2][0].get(), plaintext[2][1].get(), plaintext[2][2].get(), plaintext[2][3].get());
2435 /// assert_eq!(plaintext[0][0].get(), 0x90ABCDEF);
2436 /// assert_eq!(plaintext[0][1].get(), 0x12345678);
2437 /// assert_eq!(plaintext[0][2].get(), 0x90ABCDEF);
2438 /// assert_eq!(plaintext[0][3].get(), 0x12345678);
2439 /// assert_eq!(plaintext[1][0].get(), 0x90ABCDEF);
2440 /// assert_eq!(plaintext[1][1].get(), 0x12345678);
2441 /// assert_eq!(plaintext[1][2].get(), 0x90ABCDEF);
2442 /// assert_eq!(plaintext[1][3].get(), 0x12345678);
2443 /// assert_eq!(plaintext[2][0].get(), 0x90ABCDEF);
2444 /// assert_eq!(plaintext[2][1].get(), 0x12345678);
2445 /// assert_eq!(plaintext[2][2].get(), 0x90ABCDEF);
2446 /// assert_eq!(plaintext[2][3].get(), 0x12345678);
2447 /// ```
2448 ///
2449 /// # For more examples,
2450 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decrypt_array_unit)
2451 pub fn decrypt_array_unit<const N: usize>(&mut self, cipher: &[[IntUnion; NB]; N], message: &mut [[IntUnion; NB]; N])
2452 {
2453 for i in 0..N
2454 {
2455 self.set_block(&cipher[i]);
2456 self.decrypt_block();
2457 message[i] = self.get_block();
2458 }
2459 }
2460
2461 // pub fn decrypt_array_u128<const N: usize>(&mut self, cipher: &[u128; N], message: &mut [u128; N])
2462 /// Decrypts an array of 128-bit data.
2463 ///
2464 /// # Arguments
2465 /// - `cipher` is of an array of `u128`-type and the ciphertext to be
2466 /// decrypted.
2467 /// - `message` is of an array of `u128`-type and the plaintext to be stored.
2468 ///
2469 /// # Features
2470 /// This method decrypts multiple of 64-bit data without padding anything
2471 /// in ECB (Electronic CodeBook) mode.
2472 ///
2473 /// # Caution
2474 /// - This method is meaningful only when `NB` is `4`.
2475 /// - If `NB` is other than `4`, this method may panic.
2476 /// - Even if this method does not panic, its behaviour is not defined.
2477 ///
2478 /// # Caution
2479 /// - This method is meaningful only when `NB` is `4`.
2480 /// - If `NB` is other than `4`, this method may panic.
2481 /// - Even if this method does not panic, its behaviour is not defined.
2482 ///
2483 /// # Counterpart Methods
2484 /// For each trait
2485 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2486 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2487 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2488 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2489 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2490 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2491 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2492 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2493 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2494 /// there are provided useful counterpart methods:
2495 /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
2496 /// decrypt_into_string(),
2497 /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
2498 /// decrypt_vec_into_string(),
2499 /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
2500 /// and decrypt_array_into_string().
2501 ///
2502 /// # Example 1 for AES_128
2503 /// ```
2504 /// use cryptocol::number::IntUnion;
2505 /// use cryptocol::symmetric::AES_128;
2506 ///
2507 /// let mut aes = AES_128::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2508 /// let plaintext = [0x1234567890ABCDEF1234567890ABCDEF_u128, 0x11223344556677889900AABBCCDDEEFF, 0xFFEEDDCCBBAA00998877665544332211];
2509 /// println!("Plaintext:\t{:#034X} {:#034X} {:#034X}", plaintext[0], plaintext[1], plaintext[2]);
2510 /// let mut ciphertext = [0_u128; 3];
2511 /// aes.encrypt_array_u128(&plaintext, &mut ciphertext);
2512 /// println!("Ciphertext:\t{:#034X} {:#034X} {:#034X}", ciphertext[0], ciphertext[1], ciphertext[2]);
2513 /// assert_eq!(ciphertext[0], 0x01CCF8264AECB5D644E2BAE927584D87_u128);
2514 /// assert_eq!(ciphertext[1], 0x7601C1D6EA61791544C28D4004577BB9_u128);
2515 /// assert_eq!(ciphertext[2], 0xB7225E77C077541D5055FE9C8D3894B9_u128);
2516 ///
2517 /// let mut recovered = [0_u128; 3];
2518 /// aes.decrypt_array_u128(&ciphertext, &mut recovered);
2519 /// println!("Recovered:\t{:#034X} {:#034X} {:#034X}", recovered[0], recovered[1], recovered[2]);
2520 /// assert_eq!(recovered[0], 0x1234567890ABCDEF1234567890ABCDEF_u128);
2521 /// assert_eq!(recovered[1], 0x11223344556677889900AABBCCDDEEFF_u128);
2522 /// assert_eq!(recovered[2], 0xFFEEDDCCBBAA00998877665544332211_u128);
2523 /// assert_eq!(recovered[0], plaintext[0]);
2524 /// assert_eq!(recovered[1], plaintext[1]);
2525 /// assert_eq!(recovered[2], plaintext[2]);
2526 /// ```
2527 ///
2528 /// # For more examples,
2529 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decrypt_array_u128)
2530 pub fn decrypt_array_u128<const N: usize>(&mut self, cipher: &[u128; N], message: &mut [u128; N])
2531 {
2532 for i in 0..N
2533 {
2534 self.set_block_u128(cipher[i]);
2535 self.decrypt_block();
2536 message[i] = self.get_block_u128();
2537 }
2538 }
2539
2540 // pub fn decrypt_array_u64<const N: usize>(&mut self, cipher: &[u64; N], message: &mut [u64; N])
2541 /// Decrypts an array of 64-bit data.
2542 ///
2543 /// # Arguments
2544 /// - `cipher` is of an array of `u64`-type and the ciphertext
2545 /// to be decrypted.
2546 /// - `message` is of an array of `u64`-type and the plaintext
2547 /// to be stored.
2548 ///
2549 /// # Features
2550 /// This method encrypts multiple of 64-bit data without padding anything
2551 /// in ECB (Electronic CodeBook) mode.
2552 ///
2553 /// # Caution
2554 /// - This method is meaningful only when `NB` is `2`.
2555 /// - If `NB` is other than `2`, this method may panic.
2556 /// - Even if this method does not panic, its behaviour is not defined.
2557 ///
2558 /// # Counterpart Methods
2559 /// For each trait
2560 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2561 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2562 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2563 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2564 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2565 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2566 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2567 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2568 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2569 /// there are provided useful counterpart methods:
2570 /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
2571 /// decrypt_into_string(),
2572 /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
2573 /// decrypt_vec_into_string(),
2574 /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
2575 /// and decrypt_array_into_string().
2576 ///
2577 /// # Example 1 for Rijndael_64_64
2578 /// ```
2579 /// use cryptocol::symmetric::Rijndael_64_64;
2580 ///
2581 /// let mut rijndael = Rijndael_64_64::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2582 /// let plaintext = [0x1234567890ABCDEF_u64, 0x1122334455667788, 0xFFEEDDCCBBAA0099];
2583 /// println!("Plaintext:\t{:#018X} {:#018X} {:#018X}", plaintext[0], plaintext[1], plaintext[2]);
2584 /// let mut ciphertext = [0_u64; 3];
2585 /// rijndael.encrypt_array_u64(&plaintext, &mut ciphertext);
2586 /// println!("Ciphertext:\t{:#018X} {:#018X} {:#018X}", ciphertext[0], ciphertext[1], ciphertext[2]);
2587 /// assert_eq!(ciphertext[0], 0x4FAA3F0E49CC4DCF_u64);
2588 /// assert_eq!(ciphertext[1], 0x036AAEDC0F1A5BEC_u64);
2589 /// assert_eq!(ciphertext[2], 0x99B8209339BCC1EB_u64);
2590 ///
2591 /// let mut recovered = [0_u64; 3];
2592 /// rijndael.decrypt_array_u64(&ciphertext, &mut recovered);
2593 /// println!("Recovered:\t{:#018X} {:#018X} {:#018X}", recovered[0], recovered[1], recovered[2]);
2594 /// assert_eq!(recovered[0], 0x1234567890ABCDEF_u64);
2595 /// assert_eq!(recovered[1], 0x1122334455667788_u64);
2596 /// assert_eq!(recovered[2], 0xFFEEDDCCBBAA0099_u64);
2597 /// assert_eq!(recovered[0], plaintext[0]);
2598 /// assert_eq!(recovered[1], plaintext[1]);
2599 /// assert_eq!(recovered[2], plaintext[2]);
2600 /// ```
2601 ///
2602 /// # For more examples,
2603 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decrypt_array_u64)
2604 pub fn decrypt_array_u64<const N: usize>(&mut self, cipher: &[u64; N], message: &mut [u64; N])
2605 {
2606 for i in 0..N
2607 {
2608 self.set_block_u64(cipher[i]);
2609 self.decrypt_block();
2610 message[i] = self.get_block_u64();
2611 }
2612 }
2613
2614 // pub fn decrypt_array_u32<const N: usize>(&mut self, cipher: &[u32; N], message: &mut [u32; N])
2615 /// Decrypts an array of 32-bit data.
2616 ///
2617 /// # Arguments
2618 /// - `cipher` is of an array of `u32`-type and the ciphertext
2619 /// to be decrypted.
2620 /// - `message` is of an array of `u32`-type and the plaintext
2621 /// to be stored.
2622 ///
2623 /// # Features
2624 /// This method encrypts multiple of 32-bit data without padding anything
2625 /// in ECB (Electronic CodeBook) mode.
2626 ///
2627 /// # Caution
2628 /// - This method is meaningful only when `NB` is `1`.
2629 /// - If `NB` is other than `1`, this method may panic.
2630 /// - Even if this method does not panic, its behaviour is not defined.
2631 ///
2632 /// # Counterpart Methods
2633 /// For each trait
2634 /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2635 /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2636 /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2637 /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2638 /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2639 /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2640 /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2641 /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2642 /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2643 /// there are provided useful counterpart methods:
2644 /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
2645 /// decrypt_into_string(),
2646 /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
2647 /// decrypt_vec_into_string(),
2648 /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
2649 /// and decrypt_array_into_string().
2650 ///
2651 /// # Example 1 for Rijndael_32_32
2652 /// ```
2653 /// use cryptocol::symmetric::Rijndael_32_32;
2654 ///
2655 /// let mut rijndael = Rijndael_32_32::new_with_key(&[0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2656 /// let plaintext = [0x12345678_u32, 0x90ABCDEF, 0xFFEEDDCC];
2657 /// println!("Plaintext:\t{:#010X} {:#010X} {:#010X}", plaintext[0], plaintext[1], plaintext[2]);
2658 /// let mut ciphertext = [0_u32; 3];
2659 /// rijndael.encrypt_array_u32(&plaintext, &mut ciphertext);
2660 /// println!("Ciphertext:\t{:#010X} {:#010X} {:#010X}", ciphertext[0], ciphertext[1], ciphertext[2]);
2661 /// assert_eq!(ciphertext[0], 0x335228F6_u32);
2662 /// assert_eq!(ciphertext[1], 0xBFB99AFB_u32);
2663 /// assert_eq!(ciphertext[2], 0x2D114838_u32);
2664 ///
2665 /// let mut recovered = [0_u32; 3];
2666 /// rijndael.decrypt_array_u32(&ciphertext, &mut recovered);
2667 /// println!("Recovered:\t{:#010X} {:#010X} {:#010X}", recovered[0], recovered[1], recovered[2]);
2668 /// assert_eq!(recovered[0], 0x12345678_u32);
2669 /// assert_eq!(recovered[1], 0x90ABCDEF_u32);
2670 /// assert_eq!(recovered[2], 0xFFEEDDCC_u32);
2671 /// assert_eq!(recovered[0], plaintext[0]);
2672 /// assert_eq!(recovered[1], plaintext[1]);
2673 /// assert_eq!(recovered[2], plaintext[2]);
2674 /// ```
2675 ///
2676 /// # For more examples,
2677 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.decrypt_array_u32)
2678 pub fn decrypt_array_u32<const N: usize>(&mut self, cipher: &[u32; N], message: &mut [u32; N])
2679 {
2680 for i in 0..N
2681 {
2682 self.set_block_u32(cipher[i]);
2683 self.decrypt_block();
2684 message[i] = self.get_block_u32();
2685 }
2686 }
2687
2688 // pub fn is_succeful(&self) -> bool
2689 /// Checks whether the previous encryption or decryption was successful.
2690 ///
2691 /// # Output
2692 /// If the previous encryption or decryption was successful, this method
2693 /// returns true. Otherwise, it returns false.
2694 ///
2695 /// # Features
2696 /// - Usually, you don't have to use this method because the encryption
2697 /// methods returns the length of ciphertext and the decryption methods
2698 /// returns the length of plaintext but they returns `0` when they failed.
2699 /// - If the ciphertext is 8 bytes for decryption with the padding either
2700 /// pkcs7 or iso, the return value `0` of the decryption methods is not
2701 /// discriminatory. You don't know whether the previous decryption was
2702 /// failed or the original plaintext was just null string or "". In this
2703 /// case you can check its success with this method.
2704 ///
2705 /// # Example 1 for the message of 0 bytes
2706 /// ```
2707 /// use std::io::Write;
2708 /// use std::fmt::Write as _;
2709 /// use cryptocol::symmetric::{ AES_128, ECB_PKCS7 };
2710 ///
2711 /// let key = 0xEFCDAB9078563412EFCDAB9078563412_u128;
2712 /// println!("K =\t{:#034X}", key);
2713 /// let mut a_aes = AES_128::new_with_key_u128(key);
2714 /// let message = "";
2715 /// println!("M =\t{}", message);
2716 /// let mut cipher = [0_u8; 16];
2717 /// let len = a_aes.encrypt_into_array(message.as_ptr(), message.len() as u64, &mut cipher);
2718 /// println!("The length of ciphertext = {}", len);
2719 /// assert_eq!(len, 16);
2720 /// let success = a_aes.is_successful();
2721 /// assert_eq!(success, true);
2722 /// print!("C =\t");
2723 /// for c in cipher.clone()
2724 /// { print!("{:02X} ", c); }
2725 /// println!();
2726 /// let mut txt = String::new();
2727 /// for c in cipher.clone()
2728 /// { write!(txt, "{:02X} ", c); }
2729 /// assert_eq!(txt, "26 F2 F8 B7 B7 FD 46 9A 97 97 F3 24 E7 51 99 47 ");
2730 /// ```
2731 ///
2732 /// # For more examples,
2733 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.is_successful)
2734 #[inline]
2735 pub fn is_successful(&self) -> bool
2736 {
2737 self.block[0][0] == Self::SUCCESS
2738 }
2739
2740 // pub fn is_failed(&self) -> bool
2741 /// Checks whether the previous encryption or decryption was failed.
2742 ///
2743 /// # Output
2744 /// If the previous encryption or decryption was failed, this method
2745 /// returns true. Otherwise, it returns false.
2746 ///
2747 /// # Features
2748 /// - Usually, you don't have to use this method because the encryption
2749 /// methods returns the length of ciphertext and the decryption methods
2750 /// returns the length of plaintext but they returns `0` when they failed.
2751 /// - If the ciphertext is 8 bytes for decryption with the padding either
2752 /// pkcs7 or iso, the return value `0` of the decryption methods is not
2753 /// discriminatory. You don't know whether the previous decryption was
2754 /// failed or the original plaintext was just null string or "". In this
2755 /// case you can check its success with this method.
2756 ///
2757 /// # Example 1 for the message of 0 bytes
2758 /// ```
2759 /// use std::io::Write;
2760 /// use std::fmt::Write as _;
2761 /// use cryptocol::symmetric::{ AES_128, ECB_PKCS7 };
2762 ///
2763 /// let key = 0xEFCDAB9078563412EFCDAB9078563412_u128;
2764 /// println!("K =\t{:#034X}", key);
2765 /// let mut a_aes = AES_128::new_with_key_u128(key);
2766 /// let message = "";
2767 /// println!("M =\t{}", message);
2768 /// let mut cipher = [0_u8; 16];
2769 /// let len = a_aes.encrypt_into_array(message.as_ptr(), message.len() as u64, &mut cipher);
2770 /// println!("The length of ciphertext = {}", len);
2771 /// assert_eq!(len, 16);
2772 /// let failure = a_aes.is_failed();
2773 /// assert_eq!(failure, false);
2774 /// print!("C =\t");
2775 /// for c in cipher.clone()
2776 /// { print!("{:02X} ", c); }
2777 /// println!();
2778 /// let mut txt = String::new();
2779 /// for c in cipher.clone()
2780 /// { write!(txt, "{:02X} ", c); }
2781 /// assert_eq!(txt, "26 F2 F8 B7 B7 FD 46 9A 97 97 F3 24 E7 51 99 47 ");
2782 /// ```
2783 ///
2784 /// # For more examples,
2785 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.is_failed)
2786 #[inline]
2787 pub fn is_failed(&self) -> bool
2788 {
2789 self.block[0][0] == Self::FAILURE
2790 }
2791
2792 // pub(super) fn set_successful(&mut self)
2793 /// Sets the flag to mean that the previous encryption or decryption
2794 /// was successful.
2795 ///
2796 /// # Features
2797 /// You won't use this method unless you write codes for implementation
2798 /// of a trait for BigCryptor128.
2799 #[inline]
2800 pub(super) fn set_successful(&mut self)
2801 {
2802 self.block[0][0] = Self::SUCCESS;
2803 }
2804
2805 // pub(super) fn set_failed(&mut self)
2806 /// Sets the flag to mean that the previous encryption or decryption
2807 /// was failed.
2808 ///
2809 /// # Features
2810 /// You won't use this method unless you write codes for implementation
2811 /// of a trait for BigCryptor64 or NDES.
2812 #[inline]
2813 pub(super) fn set_failed(&mut self)
2814 {
2815 self.block[0][0] = Self::FAILURE;
2816 }
2817
2818 // pub fn get_desirable_round() -> usize
2819 /// Returns the desirable number of rounds
2820 /// according to the Rijndael documents
2821 ///
2822 /// # Example 1 for AES_128
2823 /// ```
2824 /// use cryptocol::symmetric::AES_128;
2825 /// let rounds = AES_128::get_desirable_round();
2826 /// println!("The desirable number of rounds of AES_128 is {}", rounds);
2827 /// assert_eq!(rounds, 10);
2828 /// ```
2829 ///
2830 /// # For more examples,
2831 /// click [here](./documentation/rijndael_basic/struct.Rijndael_Generic.html#method.get_desirable_round)
2832 #[inline]
2833 pub fn get_desirable_round() -> usize
2834 {
2835 6 + if NB > NK { NB } else { NK }
2836 }
2837
2838 fn encrypt_block(&mut self)
2839 {
2840 self.add_round_key(0);
2841 for round in 1..ROUND
2842 {
2843 self.sub_bytes();
2844 Self::method_shift_rows(self);
2845 Self::method_mix_columns(self);
2846 self.add_round_key(round);
2847 }
2848 self.sub_bytes();
2849 Self::method_shift_rows(self);
2850 self.add_round_key(ROUND);
2851 }
2852
2853 fn sub_bytes(&mut self)
2854 {
2855 for i in 0..4
2856 {
2857 for j in 0..NB
2858 {
2859 self.block[i][j] = Self::SBOX[self.block[i][j] as usize];
2860 }
2861 }
2862 }
2863
2864 fn optimal_shift_rows(&mut self)
2865 {
2866 let mut tmp = [0_u8; 3];
2867 let tmp_ptr = tmp.as_mut_ptr();
2868 for i in 1..4
2869 {
2870 unsafe {
2871 let j = i % NB;
2872 let ptr_block_0 = self.block[i].as_mut_ptr();
2873 let ptr_block_i = self.block[i].as_ptr().add(j);
2874 let ptr_block_nb_i = self.block[i].as_mut_ptr().add(NB - j);
2875 copy_nonoverlapping(ptr_block_0, tmp_ptr, j);
2876 copy(ptr_block_i, ptr_block_0, NB - j);
2877 copy_nonoverlapping(tmp_ptr, ptr_block_nb_i, j);
2878 }
2879 }
2880 }
2881
2882 fn shift_rows(&mut self)
2883 {
2884 let mut tmp = [0_u8; NB];
2885 let tmp_ptr = tmp.as_mut_ptr();
2886 for i in 0..4
2887 {
2888 unsafe {
2889 let j = Self::SR[i] % NB;
2890 let ptr_block_0 = self.block[i].as_mut_ptr();
2891 let ptr_block_i = self.block[i].as_ptr().add(j);
2892 let ptr_block_nb_i = self.block[i].as_mut_ptr().add(NB - j);
2893 copy_nonoverlapping(ptr_block_0, tmp_ptr, j);
2894 copy(ptr_block_i, ptr_block_0, NB - j);
2895 copy_nonoverlapping(tmp_ptr, ptr_block_nb_i, j);
2896 }
2897 }
2898 }
2899
2900 fn optimal_mix_columns(&mut self)
2901 {
2902 let mut new_block = [[0_u8; NB]; 4];
2903 for col in 0..NB
2904 {
2905 new_block[0][col] = GF_mul!(2, self.block[0][col]) ^ GF_mul!(3, self.block[1][col])
2906 ^ self.block[2][col] ^ self.block[3][col];
2907 new_block[1][col] = self.block[0][col] ^ GF_mul!(2, self.block[1][col])
2908 ^ GF_mul!(3, self.block[2][col]) ^ self.block[3][col];
2909 new_block[2][col] = self.block[0][col] ^ self.block[1][col]
2910 ^ GF_mul!(2, self.block[2][col]) ^ GF_mul!(3, self.block[3][col]);
2911 new_block[3][col] = GF_mul!(3, self.block[0][col]) ^ self.block[1][col]
2912 ^ self.block[2][col] ^ GF_mul!(2, self.block[3][col]);
2913 }
2914 self.block = new_block;
2915 }
2916
2917 fn mix_columns(&mut self)
2918 {
2919 let mut new_block = [[0_u8; NB]; 4];
2920 for row in 0..4
2921 {
2922 for col in 0..NB
2923 {
2924 for i in 0..4
2925 {
2926 new_block[row][col] ^= GF_mul!(Self::MC[row][i], self.block[i][col]);
2927 }
2928 }
2929 }
2930 self.block = new_block;
2931 }
2932
2933 fn add_round_key(&mut self, round: usize)
2934 {
2935 for i in 0..4
2936 {
2937 for j in 0..NB
2938 {
2939 self.block[i][j] ^= self.round_key[round][j].get_ubyte_(i);
2940 }
2941 }
2942 }
2943
2944 fn decrypt_block(&mut self)
2945 {
2946 self.add_round_key(ROUND);
2947 let mut round = ROUND-1;
2948 while round > 0
2949 {
2950 Self::method_inv_shift_rows(self);
2951 self.inv_sub_bytes();
2952 self.add_round_key(round);
2953 self.inv_mix_columns();
2954 round -= 1;
2955 }
2956 Self::method_inv_shift_rows(self);
2957 self.inv_sub_bytes();
2958 self.add_round_key(round);
2959 }
2960
2961 fn inv_sub_bytes(&mut self)
2962 {
2963 for i in 0..4
2964 {
2965 for j in 0..NB
2966 {
2967 self.block[i][j] = Self::INV_SBOX[self.block[i][j] as usize];
2968 }
2969 }
2970 }
2971
2972 fn optimal_inv_shift_rows(&mut self)
2973 {
2974 let mut tmp = [0_u8; 3];
2975 let tmp_ptr = tmp.as_mut_ptr();
2976 for i in 1..4
2977 {
2978 unsafe {
2979 let j = i % NB;
2980 let ptr_block_0 = self.block[i].as_mut_ptr();
2981 let ptr_block_i = self.block[i].as_mut_ptr().add(j);
2982 let ptr_block_nb_i = self.block[i].as_ptr().add(NB - j);
2983 copy_nonoverlapping(ptr_block_nb_i, tmp_ptr, j);
2984 copy(ptr_block_0, ptr_block_i, NB - j);
2985 copy_nonoverlapping(tmp_ptr, ptr_block_0, j);
2986 }
2987 }
2988 }
2989
2990 fn inv_shift_rows(&mut self)
2991 {
2992 let mut tmp = [0_u8; NB];
2993 let tmp_ptr = tmp.as_mut_ptr();
2994 for i in 0..4
2995 {
2996 unsafe {
2997 let j = Self::SR[i] % NB;
2998 let ptr_block_0 = self.block[i].as_mut_ptr();
2999 let ptr_block_i = self.block[i].as_mut_ptr().add(j);
3000 let ptr_block_nb_i = self.block[i].as_ptr().add(NB - j);
3001 copy_nonoverlapping(ptr_block_nb_i, tmp_ptr, j);
3002 copy(ptr_block_0, ptr_block_i, NB - j);
3003 copy_nonoverlapping(tmp_ptr, ptr_block_0, j);
3004 }
3005 }
3006 }
3007
3008 fn inv_mix_columns(&mut self)
3009 {
3010 let mut new_block = [[0_u8; NB]; 4];
3011 for row in 0..4
3012 {
3013 for col in 0..NB
3014 {
3015 for i in 0..4
3016 {
3017 new_block[row][col] ^= GF_mul!(Self::INV_MC[row][i], self.block[i][col]);
3018 }
3019 }
3020 }
3021 self.block = new_block;
3022 }
3023
3024 fn make_round_keys_nk_up_to_6_and_nk_equal_to_nb(&mut self)
3025 {
3026 self.set_zeroth_round_key();
3027 for round in 1..=ROUND
3028 {
3029 let mut tmp = self.round_key[round-1][NB-1];
3030 #[cfg(target_endian = "little")] { tmp = tmp.rotate_right(8 * ROT); }
3031 #[cfg(target_endian = "big")] { tmp = tmp.rotate_left(8 * ROT); }
3032 for j in 0..4
3033 { tmp.set_ubyte_(j, Self::SBOX[tmp.get_ubyte_(j) as usize]); }
3034 tmp.set(tmp.get() ^ Self::RC[round-1]);
3035 self.round_key[round][0] = tmp ^ self.round_key[round-1][0];
3036 for i in 1..NB
3037 { self.round_key[round][i] = self.round_key[round][i-1] ^ self.round_key[round-1][i]; }
3038 }
3039 }
3040
3041 fn make_round_keys_nk_greater_than_6_and_nk_equal_to_nb(&mut self)
3042 {
3043 self.set_zeroth_round_key();
3044 for round in 1..=ROUND
3045 {
3046 let mut tmp = self.round_key[round-1][NB-1];
3047 #[cfg(target_endian = "little")] { tmp = tmp.rotate_right(8 * ROT); }
3048 #[cfg(target_endian = "big")] { tmp = tmp.rotate_left(8 * ROT); }
3049 for j in 0..4
3050 { tmp.set_ubyte_(j, Self::SBOX[tmp.get_ubyte_(j) as usize]); }
3051 tmp.set(tmp.get() ^ Self::RC[round-1]);
3052 self.round_key[round][0] = tmp ^ self.round_key[round-1][0];
3053 for i in 1..3
3054 { self.round_key[round][0] = self.round_key[round][i-1] ^ self.round_key[round-1][i]; }
3055 tmp = self.round_key[round][3];
3056 for j in 0..4
3057 { tmp.set_ubyte_(j, Self::SBOX[tmp.get_ubyte_(j) as usize]); }
3058 self.round_key[round][4] = tmp ^ self.round_key[round-1][4];
3059 for i in 5..NB
3060 { self.round_key[round][i] = self.round_key[round][i-1] ^ self.round_key[round-1][i]; }
3061 }
3062 }
3063
3064 fn make_round_keys_nk_up_to_6_and_nk_diff_from_nb(&mut self)
3065 {
3066 self.set_zeroth_round_key();
3067 let mut round = NK / NB;
3068 let mut cc = NK % NB;
3069 let mut idx = NK;
3070 let mut rc_round = 0;
3071 while (round <= ROUND) && (rc_round < ROUND)
3072 {
3073 let mut tmp = if cc == 0 { self.round_key[round-1][NB-1] } else { self.round_key[round][cc-1] };
3074 if idx % NK == 0
3075 {
3076 #[cfg(target_endian = "little")] { tmp = tmp.rotate_right(8 * ROT); }
3077 #[cfg(target_endian = "big")] { tmp = tmp.rotate_left(8 * ROT); }
3078 for j in 0..4
3079 { tmp.set_ubyte_(j, Self::SBOX[tmp.get_ubyte_(j) as usize]); }
3080 tmp.set(tmp.get() ^ Self::RC[rc_round]);
3081 rc_round += 1;
3082 }
3083 if cc < NK
3084 {
3085 let rrr = (idx - NK) / NB;
3086 let ccc = (idx - NK) % NB;
3087 self.round_key[round][cc] = tmp ^ self.round_key[rrr][ccc];
3088 }
3089 else
3090 {
3091 self.round_key[round][cc] = tmp ^ self.round_key[round][cc-NK];
3092 }
3093 if cc == NB - 1
3094 {
3095 cc = 0;
3096 round += 1;
3097 }
3098 else
3099 {
3100 cc += 1;
3101 }
3102 idx += 1;
3103 }
3104 }
3105
3106 fn make_round_keys_nk_greater_than_6_and_nk_diff_from_nb(&mut self)
3107 {
3108 self.set_zeroth_round_key();
3109 let mut round = NK / NB;
3110 let mut cc = NK % NB;
3111 let mut idx = NK;
3112 let mut rc_round = 0;
3113 while (round <= ROUND) && (rc_round < ROUND)
3114 {
3115 let mut tmp = if cc == 0 { self.round_key[round-1][NB-1] } else { self.round_key[round][cc-1] };
3116 if idx % NK == 0
3117 {
3118 #[cfg(target_endian = "little")] { tmp = tmp.rotate_right(8 * ROT); }
3119 #[cfg(target_endian = "big")] { tmp = tmp.rotate_left(8 * ROT); }
3120 for j in 0..4
3121 { tmp.set_ubyte_(j, Self::SBOX[tmp.get_ubyte_(j) as usize]); }
3122 tmp.set(tmp.get() ^ Self::RC[rc_round]);
3123 rc_round += 1;
3124 }
3125 else if idx % NK == 4
3126 {
3127 let rrr = (idx - NK) / NB;
3128 let ccc = (idx - NK) % NB;
3129 for j in 0..4
3130 { tmp.set_ubyte_(j, Self::SBOX[tmp.get_ubyte_(j) as usize]); }
3131 self.round_key[round][cc] = tmp ^ self.round_key[rrr][ccc];
3132 }
3133 if cc < NK
3134 {
3135 let rrr = (idx - NK) / NB;
3136 let ccc = (idx - NK) % NB;
3137 self.round_key[round][cc] = tmp ^ self.round_key[rrr][ccc];
3138 }
3139 else
3140 {
3141 self.round_key[round][cc] = tmp ^ self.round_key[round][cc-NK];
3142 }
3143 if cc < NB - 1
3144 {
3145 cc += 1;
3146 }
3147 else
3148 {
3149 cc = 0;
3150 round += 1;
3151 }
3152 idx += 1;
3153 }
3154 }
3155
3156 #[inline]
3157 fn set_zeroth_round_key(&mut self)
3158 {
3159 unsafe {
3160 copy_nonoverlapping(self.key.as_ptr() as *const u8,
3161 self.round_key.as_mut_ptr() as *mut u8, NK * 4);
3162 }
3163 }
3164
3165 fn get_block(&self) -> [IntUnion; NB]
3166 {
3167 let mut block = [IntUnion::new(); NB];
3168 for j in 0..NB
3169 {
3170 for i in 0..4
3171 {
3172 block[j].set_ubyte_(i, self.block[i][j]);
3173 }
3174 }
3175 block
3176 }
3177
3178 fn get_block_u128(&self) -> u128
3179 {
3180 let nb = if 4 < NB {4} else {NB};
3181 let mut block = LongerUnion::new();
3182 let mut idx = 0;
3183 for j in 0..nb
3184 {
3185 for i in 0..4
3186 {
3187 block.set_ubyte_(idx, self.block[i][j]);
3188 idx += 1;
3189 }
3190 }
3191 block.get()
3192 }
3193
3194 fn get_block_u64(&self) -> u64
3195 {
3196 let nb = if 2 < NB {2} else {NB};
3197 let mut block = LongUnion::new();
3198 let mut idx = 0;
3199 for j in 0..nb
3200 {
3201 for i in 0..4
3202 {
3203 block.set_ubyte_(idx, self.block[i][j]);
3204 idx += 1;
3205 }
3206 }
3207 block.get()
3208 }
3209
3210 fn get_block_u32(&self) -> u32
3211 {
3212 let mut block = IntUnion::new();
3213 let mut idx = 0;
3214 for i in 0..4
3215 {
3216 block.set_ubyte_(idx, self.block[i][0]);
3217 idx += 1;
3218 }
3219 block.get()
3220 }
3221
3222 fn set_block(&mut self, block: &[IntUnion; NB])
3223 {
3224 for j in 0..NB
3225 {
3226 for i in 0..4
3227 {
3228 self.block[i][j] = block[j].get_ubyte_(i);
3229 }
3230 }
3231 }
3232
3233 fn set_block_u128(&mut self, block: u128)
3234 {
3235 let nb = if 4 < NB {4} else {NB};
3236 let block_union = LongerUnion::new_with(block);
3237 let mut idx = 0;
3238 for j in 0..nb
3239 {
3240 for i in 0..4
3241 {
3242 self.block[i][j] = block_union.get_ubyte_(idx);
3243 idx += 1;
3244 }
3245 }
3246 }
3247
3248 fn set_block_u64(&mut self, block: u64)
3249 {
3250 let nb = if 2 < NB {2} else {NB};
3251 let block_union = LongUnion::new_with(block);
3252 let mut idx = 0;
3253 for j in 0..nb
3254 {
3255 for i in 0..4
3256 {
3257 self.block[i][j] = block_union.get_ubyte_(idx);
3258 idx += 1;
3259 }
3260 }
3261 }
3262
3263 fn set_block_u32(&mut self, block: u32)
3264 {
3265 let block_union = IntUnion::new_with(block);
3266 let mut idx = 0;
3267 for i in 0..4
3268 {
3269 self.block[i][0] = block_union.get_ubyte_(idx);
3270 idx += 1;
3271 }
3272 }
3273
3274 // fn GF_mul(mut a: u8, mut b: u8, m: u8) -> u8
3275 // {
3276 // let mut ret = 0_u8;
3277 // while b != 0
3278 // {
3279 // if b & 1 == 1
3280 // { ret ^= a; }
3281 // if a & 0b1000_0000 != 0
3282 // { a = (a << 1) ^ m; }
3283 // else
3284 // { a <<= 1; }
3285 // b >>= 1;
3286 // }
3287 // ret
3288 // }
3289
3290
3291 /////// Testing Codes during Development //////
3292 // #[allow(non_snake_case)]
3293 // pub fn show_SBox()
3294 // {
3295 // for i in 0..256
3296 // { println!("{:02X} => {:02X}", i, Self::SBOX[i]); }
3297 // }
3298
3299 // #[allow(non_snake_case)]
3300 // pub fn show_InvSBox()
3301 // {
3302 // for i in 0..256
3303 // { println!("{:02X} => {:02X}", i, Self::INV_SBOX[i]); }
3304 // }
3305
3306 // #[allow(non_snake_case)]
3307 // pub fn show_MC()
3308 // {
3309 // println!("MC is as follows:");
3310 // for i in 0..4
3311 // {
3312 // for j in 0..4
3313 // { print!("{:02x} ", Self::MC[i][j]); }
3314 // println!();
3315 // }
3316 // }
3317
3318 // #[allow(non_snake_case)]
3319 // pub fn show_InvMC()
3320 // {
3321 // println!("Inverse MC is as follows:");
3322 // for i in 0..4
3323 // {
3324 // for j in 0..4
3325 // { print!("{:02x} ", Self::INV_MC[i][j]); }
3326 // println!();
3327 // }
3328 // }
3329
3330 // #[allow(non_snake_case)]
3331 // pub fn show_RC()
3332 // {
3333 // for i in 0..ROUND
3334 // { println!("{:02} => {:02X}", i, Self::RC[i]); }
3335 // }
3336}