Skip to main content

cryptocol/symmetric/
des.rs

1// Copyright 2024, 2025 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
16
17use crate::number::{ SmallUInt, IntUnion, LongUnion };
18
19// Converts bit number into 0-based bit number in Little Endianness.
20macro_rules! convert {
21    ($p:expr) => {
22        ((($p - 1) >> 3) << 3) + (7 - (($p - 1) & 0b111))
23    };
24}
25
26macro_rules! make_FP {
27    () => {
28        {
29            let mut out = [0_u8; 64];
30            let mut i = 0_u8;
31            while i < 64
32            {
33                out[Self::IP[i as usize] as usize] = i;
34                i += 1;
35            }
36            out
37        }
38    }
39}
40
41macro_rules! permutate_data {
42    ($me:expr, $permut:expr) => {
43        let data = $me.block.get();
44        let mut permuted = 0_u64;
45        let mut idx = 0_usize;
46        // $permut and pos are already changed to be 0-based in little endianness.
47        for pos in $permut
48        {
49            if data.is_bit_set_(pos as u32)
50                { permuted |= 1_u64 << idx; } // ((7 - idx % 8) + (idx / 8) * 8); }
51            idx += 1;
52        }
53        $me.block.set(permuted);
54    };
55    // permutate_data!(Self::IP);
56    //
57    // let data = self.block.get();
58    // let mut permuted = 0_u64;
59    // let mut idx = 0_usize;
60    // // IP and pos are already changed to be 0-based in little endianness.
61    // for pos in Self::IP
62    // {
63    //     if data.is_bit_set_(pos as usize)
64    //         { permuted |= 1_u64 << idx; } // ((7 - idx % 8) + (idx / 8) * 8); }
65    //     idx += 1;
66    // }
67    // self.block.set(permuted);
68
69    ($permut:expr, $type:ty, $right:expr) => {
70        {
71            let mut permuted = 0 as $type;
72            let mut idx = 0_usize;
73            // $permut and pos are already changed to be 0-based in little endianness.
74            for pos in $permut
75            {
76                if $right.is_bit_set_(pos as u32)
77                    { permuted |= 1 as $type << idx; } // ((7 - idx % 8) + (idx / 8) * 8); }
78                idx += 1;
79            }
80            permuted
81        }
82    };
83    // permutate_data!(Self::TP, u32, right);
84    //
85    // let mut permuted = 0_u32;
86    // let mut idx = 0_usize;
87    // // TP and pos are already changed to be 0-based in little endianness.
88    // for pos in Self::TP
89    // {
90    //     if right.is_bit_set_(pos as usize)
91    //         { permuted |= 1 << idx; }
92    //     idx += 1;
93    // }
94    // permuted
95}
96
97macro_rules! shift_right_union {
98    ($u:expr, $n:expr) => {
99        let mut carry = 0_u8;
100        for i in 0..4
101        {
102            let tmp = $u.get_ubyte_(i) << (8 - $n);
103            $u.set_ubyte_(i, ($u.get_ubyte_(i) >> $n) | carry);
104            carry = tmp;
105        }
106    };
107}
108
109macro_rules! shift_left_union {
110    ($u:expr, $n:expr) => {
111        let mut carry = 0_u8;
112        for i in 0..4
113        {
114            let tmp = $u.get_ubyte_(3 - i) >> (8 - $n);
115            $u.set_ubyte_(3 - i, ($u.get_ubyte_(3 - i) << $n) | carry);
116            carry = tmp;
117        }
118    };
119    ($u:expr, $n:expr, $size:expr) => {
120        let mut carry = 0_u8;
121        for i in 0..$size
122        {
123            let tmp = $u.get_ubyte_($size - 1 - i) >> (8 - $n);
124            $u.set_ubyte_($size - 1 - i, ($u.get_ubyte_($size - 1 - i) << $n) | carry);
125            carry = tmp;
126        }
127    };
128}
129
130macro_rules! rotate_halfkey {
131    ($u:expr, $even:expr) => {
132        let n = if $even {2} else {1};
133        let mut carry = ($u.get_ubyte_(0) >> (4 - n)) & 0b11110000;
134        for i in 0..4
135        {
136            let tmp = $u.get_ubyte_(3 - i) >> (8 - n);
137            $u.set_ubyte_(3 - i, ($u.get_ubyte_(3 - i) << n) | carry);
138            carry = tmp;
139        }
140    };
141}
142
143macro_rules! slice_index {
144    ($indices:expr, $array:expr) => {
145        let mut idx = LongUnion::new_with($indices);
146        for i in 0..8_usize
147        {
148            $array[i] = ((idx.get_ubyte_(0) & 0b_111_111_00_u8) >> 2) as usize;
149            shift_left_union!(idx, 6, 6);
150        }
151    };
152}
153
154macro_rules! combine_pieces {
155    ($body:expr, $piece:expr) => {
156        $body >>= 8;
157        $body |= ($piece << 24);
158    };
159}
160
161// macro_rules! des_pre_encrypt_into_vec {
162//     ($to:expr, $length_in_bytes:expr, $type:ty) => {
163//         let len = ($length_in_bytes + 1).next_multiple_of(8_u64) as usize / <$type>::size_in_bytes() as usize;
164//         $to.truncate(len);
165//         $to.resize(len + 1, <$type>::zero());
166//     };
167//     // des_pre_encrypt_into_vec!(cipher, length_in_bytes, T);
168//     //
169//     // let mut len = if T::size_in_bytes() == 16 {16_usize} else {8};
170//     // len = (length_in_bytes + 1).next_multiple_of(len as u64) as usize / T::size_in_bytes();
171//     // cipher.truncate(len - 1);
172//     // cipher.resize(len, T::zero());
173// }
174// pub(super) use des_pre_encrypt_into_vec;
175
176// macro_rules! des_pre_decrypt_into_vec {
177//     ($to:expr, $length_in_bytes:expr, $type:ty) => {
178//         let len = $length_in_bytes as usize / <$type>::size_in_bytes() as usize;
179//         $to.truncate(len - 1);
180//         $to.resize(len, <$type>::zero());
181//     };
182// }
183// pub(super) use des_pre_decrypt_into_vec;
184
185// macro_rules! des_pre_decrypt_into_vec_no_padding {
186//     ($to:expr, $length_in_bytes:expr, $type:ty) => {
187//         let len = $length_in_bytes as usize / <$type>::size_in_bytes() as usize;
188//         $to.truncate(len);
189//         $to.resize(len, <$type>::zero());
190//     };
191// }
192// pub(super) use des_pre_decrypt_into_vec_no_padding;
193
194// macro_rules! des_pre_encrypt_into_array {
195//     ($to:expr, $length_in_bytes:expr, $type:ty) => {
196//         let mut len = if <$type>::size_in_bytes() == 16 {16_usize} else {8};
197//         len = ($length_in_bytes + 1).next_multiple_of(len as u64) as usize / <$type>::size_in_bytes() as usize;
198//         for i in len - 1..$to.len()
199//             { $to[i] = <$type>::zero(); }
200//     };
201//     // des_pre_encrypt_into_array!(cipher, length_in_bytes, T);
202//     //
203//     // let mut len = if T::size_in_bytes() == 16 {16_usize} else {8};
204//     // len = (length_in_bytes + 1).next_multiple_of(len as u64) as usize / T::size_in_bytes();
205//     // for i in len..M
206//     //     { cipher[i] = T::zero(); }
207// }
208// pub(super) use des_pre_encrypt_into_array;
209
210// macro_rules! des_pre_decrypt_into_array {
211//     ($to:expr, $length_in_bytes:expr, $type:ty) => {
212//         let len = $length_in_bytes as usize / <$type>::size_in_bytes() as usize;
213//         for i in len - 1..$to.len()
214//             { $to[i] = <$type>::zero(); }
215//     };
216// }
217// pub(super) use des_pre_decrypt_into_array;
218
219// macro_rules! des_pre_decrypt_into_array_no_padding {
220//     ($to:expr, $length_in_bytes:expr, $type:ty) => {
221//         let len = $length_in_bytes as usize / <$type>::size_in_bytes() as usize;
222//         for i in len..$to.len()
223//             { $to[i] = <$type>::zero(); }
224//     };
225// }
226// pub(super) use des_pre_decrypt_into_array_no_padding;
227
228
229
230/// You have freedom of changing EP01 ~ EP48, TP01 ~ TP32, and S000 ~ S763.
231/// You can change the DES algorithm by simply changing the generic parameters
232/// - EP01 ~ EP48: Expansion permutation constants. They are 1-based. For
233///   example, `EP01 = 28` means that the 28th bit of data is moved to the first
234///   bit of the data which is MSB at expansion permutation. They expand the
235///   32-bit right-half data from the Feistel structure of the corresponding
236///   round into 48 bits in order to perform XOR (exclusive OR) with the
237///   corresponding 48-bit round key. When you change these constants, you have
238///   to remember that you should included all the bits. You cannot drop any
239///   bit. Your dropping any bit will surely kill the whole DES
240///   encryption/decryption algorithm.
241/// - TP01 ~ TP32: Translation permutation constans.  They are 1-based. For
242///   example, `TP01 = 16` means that the 16th bit of data is moved to the
243///   first bit of the data which is MSB at translation permutation. You can
244///   change translation permutation wire by changing these constants. The
245///   change of these constants does not change the security strength. However,
246///   when you change these constants, you have to remember that you should
247///   included all the bits. You cannot drop any bit. Your dropping any bit will
248///   surely kill the whole DES encryption/decryption algorithm.
249/// - S000 ~ S763: S-Box constants. Its index such as 000, 212, etc. is
250///   0-based. S0XX means S-Box 0, S1XX means S-Box 1, and so on. S000 is the
251///   first element of S-Box 0.
252///   According to [the document](https://page.math.tu-berlin.de/~kant/teaching/hess/krypto-ws2006/des.htm),
253///   the input six bits determines the output of S-Box. The first and the last
254///   bit of the six bits represent in base 2 a number in the decimal range 0 to
255///   3 (or binary 00 to 11) which is row number. The rest middle four bits
256///   represent in base 2 a number in the decimal range 0 to 15 (binary 0000 to
257///   1111) which is column number. It is considered that the DES designers
258///   explained the S-box structure _unnecessarily too complicated_. The
259///   above-described S-box indexing way looks two dimensional, but actually is
260///   one dimensional. So, in this crate, S-boxes are implemented to be
261///   two-dimensional array which is an array of S-boxes. Each S-box is an array
262///   of 64 four-bit numbers. The input six-bit number is used as the index of
263///   the one-dimensional array of these 64 four-bit numbers. So, the S-box
264///   tables have been rearranged to be the one-dimensional array. You can cange
265///   S-Box by changing these constants. However, you have know that *the change
266///   of these constants may hurt the security a lot*. And the principle of
267///   S-box has been unknown so far.
268#[allow(non_camel_case_types)]
269pub type DES_F<
270    const EP01: u8 = 32, const EP02: u8 = 01, const EP03: u8 = 02, const EP04: u8 = 03,
271    const EP05: u8 = 04, const EP06: u8 = 05, const EP07: u8 = 04, const EP08: u8 = 05,
272    const EP09: u8 = 06, const EP10: u8 = 07, const EP11: u8 = 08, const EP12: u8 = 09,
273    const EP13: u8 = 08, const EP14: u8 = 09, const EP15: u8 = 10, const EP16: u8 = 11,
274    const EP17: u8 = 12, const EP18: u8 = 13, const EP19: u8 = 12, const EP20: u8 = 13,
275    const EP21: u8 = 14, const EP22: u8 = 15, const EP23: u8 = 16, const EP24: u8 = 17,
276    const EP25: u8 = 16, const EP26: u8 = 17, const EP27: u8 = 18, const EP28: u8 = 19,
277    const EP29: u8 = 20, const EP30: u8 = 21, const EP31: u8 = 20, const EP32: u8 = 21,
278    const EP33: u8 = 22, const EP34: u8 = 23, const EP35: u8 = 24, const EP36: u8 = 25,
279    const EP37: u8 = 24, const EP38: u8 = 25, const EP39: u8 = 26, const EP40: u8 = 27,
280    const EP41: u8 = 28, const EP42: u8 = 29, const EP43: u8 = 28, const EP44: u8 = 29,
281    const EP45: u8 = 30, const EP46: u8 = 31, const EP47: u8 = 32, const EP48: u8 = 01,
282    const TP01: u8 = 16, const TP02: u8 = 07, const TP03: u8 = 20, const TP04: u8 = 21,
283    const TP05: u8 = 29, const TP06: u8 = 12, const TP07: u8 = 28, const TP08: u8 = 17,
284    const TP09: u8 = 01, const TP10: u8 = 15, const TP11: u8 = 23, const TP12: u8 = 26,
285    const TP13: u8 = 05, const TP14: u8 = 18, const TP15: u8 = 31, const TP16: u8 = 10,
286    const TP17: u8 = 02, const TP18: u8 = 08, const TP19: u8 = 24, const TP20: u8 = 14,
287    const TP21: u8 = 32, const TP22: u8 = 27, const TP23: u8 = 03, const TP24: u8 = 09,
288    const TP25: u8 = 19, const TP26: u8 = 13, const TP27: u8 = 30, const TP28: u8 = 06,
289    const TP29: u8 = 22, const TP30: u8 = 11, const TP31: u8 = 04, const TP32: u8 = 25,
290    const S000: u8 = 0xe, const S001: u8 = 0x0, const S002: u8 = 0x4, const S003: u8 = 0xf,
291    const S004: u8 = 0xd, const S005: u8 = 0x7, const S006: u8 = 0x1, const S007: u8 = 0x4,
292    const S008: u8 = 0x2, const S009: u8 = 0xe, const S010: u8 = 0xf, const S011: u8 = 0x2,
293    const S012: u8 = 0xb, const S013: u8 = 0xd, const S014: u8 = 0x8, const S015: u8 = 0x1,
294    const S016: u8 = 0x3, const S017: u8 = 0xa, const S018: u8 = 0xa, const S019: u8 = 0x6,
295    const S020: u8 = 0x6, const S021: u8 = 0xc, const S022: u8 = 0xc, const S023: u8 = 0xb,
296    const S024: u8 = 0x5, const S025: u8 = 0x9, const S026: u8 = 0x9, const S027: u8 = 0x5,
297    const S028: u8 = 0x0, const S029: u8 = 0x3, const S030: u8 = 0x7, const S031: u8 = 0x8,
298    const S032: u8 = 0x4, const S033: u8 = 0xf, const S034: u8 = 0x1, const S035: u8 = 0xc,
299    const S036: u8 = 0xe, const S037: u8 = 0x8, const S038: u8 = 0x8, const S039: u8 = 0x2,
300    const S040: u8 = 0xd, const S041: u8 = 0x4, const S042: u8 = 0x6, const S043: u8 = 0x9,
301    const S044: u8 = 0x2, const S045: u8 = 0x1, const S046: u8 = 0xb, const S047: u8 = 0x7,
302    const S048: u8 = 0xf, const S049: u8 = 0x5, const S050: u8 = 0xc, const S051: u8 = 0xb,
303    const S052: u8 = 0x9, const S053: u8 = 0x3, const S054: u8 = 0x7, const S055: u8 = 0xe,
304    const S056: u8 = 0x3, const S057: u8 = 0xa, const S058: u8 = 0xa, const S059: u8 = 0x0,
305    const S060: u8 = 0x5, const S061: u8 = 0x6, const S062: u8 = 0x0, const S063: u8 = 0xd,
306    const S100: u8 = 0xf, const S101: u8 = 0x3, const S102: u8 = 0x1, const S103: u8 = 0xd,
307    const S104: u8 = 0x8, const S105: u8 = 0x4, const S106: u8 = 0xe, const S107: u8 = 0x7,
308    const S108: u8 = 0x6, const S109: u8 = 0xf, const S110: u8 = 0xb, const S111: u8 = 0x2,
309    const S112: u8 = 0x3, const S113: u8 = 0x8, const S114: u8 = 0x4, const S115: u8 = 0xe,
310    const S116: u8 = 0x9, const S117: u8 = 0xc, const S118: u8 = 0x7, const S119: u8 = 0x0,
311    const S120: u8 = 0x2, const S121: u8 = 0x1, const S122: u8 = 0xd, const S123: u8 = 0xa,
312    const S124: u8 = 0xc, const S125: u8 = 0x6, const S126: u8 = 0x0, const S127: u8 = 0x9,
313    const S128: u8 = 0x5, const S129: u8 = 0xb, const S130: u8 = 0xa, const S131: u8 = 0x5,
314    const S132: u8 = 0x0, const S133: u8 = 0xd, const S134: u8 = 0xe, const S135: u8 = 0x8,
315    const S136: u8 = 0x7, const S137: u8 = 0xa, const S138: u8 = 0xb, const S139: u8 = 0x1,
316    const S140: u8 = 0xa, const S141: u8 = 0x3, const S142: u8 = 0x4, const S143: u8 = 0xf,
317    const S144: u8 = 0xd, const S145: u8 = 0x4, const S146: u8 = 0x1, const S147: u8 = 0x2,
318    const S148: u8 = 0x5, const S149: u8 = 0xb, const S150: u8 = 0x8, const S151: u8 = 0x6,
319    const S152: u8 = 0xc, const S153: u8 = 0x7, const S154: u8 = 0x6, const S155: u8 = 0xc,
320    const S156: u8 = 0x9, const S157: u8 = 0x0, const S158: u8 = 0x3, const S159: u8 = 0x5,
321    const S160: u8 = 0x2, const S161: u8 = 0xe, const S162: u8 = 0xf, const S163: u8 = 0x9,
322    const S200: u8 = 0xa, const S201: u8 = 0xd, const S202: u8 = 0x0, const S203: u8 = 0x7,
323    const S204: u8 = 0x9, const S205: u8 = 0x0, const S206: u8 = 0xe, const S207: u8 = 0x9,
324    const S208: u8 = 0x6, const S209: u8 = 0x3, const S210: u8 = 0x3, const S211: u8 = 0x4,
325    const S212: u8 = 0xf, const S213: u8 = 0x6, const S214: u8 = 0x5, const S215: u8 = 0xa,
326    const S216: u8 = 0x1, const S217: u8 = 0x2, const S218: u8 = 0xd, const S219: u8 = 0x8,
327    const S220: u8 = 0xc, const S221: u8 = 0x5, const S222: u8 = 0x7, const S223: u8 = 0xe,
328    const S224: u8 = 0xb, const S225: u8 = 0xc, const S226: u8 = 0x4, const S227: u8 = 0xb,
329    const S228: u8 = 0x2, const S229: u8 = 0xf, const S230: u8 = 0x8, const S231: u8 = 0x1,
330    const S232: u8 = 0xd, const S233: u8 = 0x1, const S234: u8 = 0x6, const S235: u8 = 0xa,
331    const S236: u8 = 0x4, const S237: u8 = 0xd, const S238: u8 = 0x9, const S239: u8 = 0x0,
332    const S240: u8 = 0x8, const S241: u8 = 0x6, const S242: u8 = 0xf, const S243: u8 = 0x9,
333    const S244: u8 = 0x3, const S245: u8 = 0x8, const S246: u8 = 0x0, const S247: u8 = 0x7,
334    const S248: u8 = 0xb, const S249: u8 = 0x4, const S250: u8 = 0x1, const S251: u8 = 0xf,
335    const S252: u8 = 0x2, const S253: u8 = 0xe, const S254: u8 = 0xc, const S255: u8 = 0x3,
336    const S256: u8 = 0x5, const S257: u8 = 0xb, const S258: u8 = 0xa, const S259: u8 = 0x5,
337    const S260: u8 = 0xe, const S261: u8 = 0x2, const S262: u8 = 0x7, const S263: u8 = 0xc,
338    const S300: u8 = 0x7, const S301: u8 = 0xd, const S302: u8 = 0xd, const S303: u8 = 0x8,
339    const S304: u8 = 0xe, const S305: u8 = 0xb, const S306: u8 = 0x3, const S307: u8 = 0x5,
340    const S308: u8 = 0x0, const S309: u8 = 0x6, const S310: u8 = 0x6, const S311: u8 = 0xf,
341    const S312: u8 = 0x9, const S313: u8 = 0x0, const S314: u8 = 0xa, const S315: u8 = 0x3,
342    const S316: u8 = 0x1, const S317: u8 = 0x4, const S318: u8 = 0x2, const S319: u8 = 0x7,
343    const S320: u8 = 0x8, const S321: u8 = 0x2, const S322: u8 = 0x5, const S323: u8 = 0xc,
344    const S324: u8 = 0xb, const S325: u8 = 0x1, const S326: u8 = 0xc, const S327: u8 = 0xa,
345    const S328: u8 = 0x4, const S329: u8 = 0xe, const S330: u8 = 0xf, const S331: u8 = 0x9,
346    const S332: u8 = 0xa, const S333: u8 = 0x3, const S334: u8 = 0x6, const S335: u8 = 0xf,
347    const S336: u8 = 0x9, const S337: u8 = 0x0, const S338: u8 = 0x0, const S339: u8 = 0x6,
348    const S340: u8 = 0xc, const S341: u8 = 0xa, const S342: u8 = 0xb, const S343: u8 = 0x1,
349    const S344: u8 = 0x7, const S345: u8 = 0xd, const S346: u8 = 0xd, const S347: u8 = 0x8,
350    const S348: u8 = 0xf, const S349: u8 = 0x9, const S350: u8 = 0x1, const S351: u8 = 0x4,
351    const S352: u8 = 0x3, const S353: u8 = 0x5, const S354: u8 = 0xe, const S355: u8 = 0xb,
352    const S356: u8 = 0x5, const S357: u8 = 0xc, const S358: u8 = 0x2, const S359: u8 = 0x7,
353    const S360: u8 = 0x8, const S361: u8 = 0x2, const S362: u8 = 0x4, const S363: u8 = 0xe,
354    const S400: u8 = 0x2, const S401: u8 = 0xe, const S402: u8 = 0xc, const S403: u8 = 0xb,
355    const S404: u8 = 0x4, const S405: u8 = 0x2, const S406: u8 = 0x1, const S407: u8 = 0xc,
356    const S408: u8 = 0x7, const S409: u8 = 0x4, const S410: u8 = 0xa, const S411: u8 = 0x7,
357    const S412: u8 = 0xb, const S413: u8 = 0xd, const S414: u8 = 0x6, const S415: u8 = 0x1,
358    const S416: u8 = 0x8, const S417: u8 = 0x5, const S418: u8 = 0x5, const S419: u8 = 0x0,
359    const S420: u8 = 0x3, const S421: u8 = 0xf, const S422: u8 = 0xf, const S423: u8 = 0xa,
360    const S424: u8 = 0xd, const S425: u8 = 0x3, const S426: u8 = 0x0, const S427: u8 = 0x9,
361    const S428: u8 = 0xe, const S429: u8 = 0x8, const S430: u8 = 0x9, const S431: u8 = 0x6,
362    const S432: u8 = 0x4, const S433: u8 = 0xb, const S434: u8 = 0x2, const S435: u8 = 0x8,
363    const S436: u8 = 0x1, const S437: u8 = 0xc, const S438: u8 = 0xb, const S439: u8 = 0x7,
364    const S440: u8 = 0xa, const S441: u8 = 0x1, const S442: u8 = 0xd, const S443: u8 = 0xe,
365    const S444: u8 = 0x7, const S445: u8 = 0x2, const S446: u8 = 0x8, const S447: u8 = 0xd,
366    const S448: u8 = 0xf, const S449: u8 = 0x6, const S450: u8 = 0x9, const S451: u8 = 0xf,
367    const S452: u8 = 0xc, const S453: u8 = 0x0, const S454: u8 = 0x5, const S455: u8 = 0x9,
368    const S456: u8 = 0x6, const S457: u8 = 0xa, const S458: u8 = 0x3, const S459: u8 = 0x4,
369    const S460: u8 = 0x0, const S461: u8 = 0x5, const S462: u8 = 0xe, const S463: u8 = 0x3,
370    const S500: u8 = 0xc, const S501: u8 = 0xa, const S502: u8 = 0x1, const S503: u8 = 0xf,
371    const S504: u8 = 0xa, const S505: u8 = 0x4, const S506: u8 = 0xf, const S507: u8 = 0x2,
372    const S508: u8 = 0x9, const S509: u8 = 0x7, const S510: u8 = 0x2, const S511: u8 = 0xc,
373    const S512: u8 = 0x6, const S513: u8 = 0x9, const S514: u8 = 0x8, const S515: u8 = 0x5,
374    const S516: u8 = 0x0, const S517: u8 = 0x6, const S518: u8 = 0xd, const S519: u8 = 0x1,
375    const S520: u8 = 0x3, const S521: u8 = 0xd, const S522: u8 = 0x4, const S523: u8 = 0xe,
376    const S524: u8 = 0xe, const S525: u8 = 0x0, const S526: u8 = 0x7, const S527: u8 = 0xb,
377    const S528: u8 = 0x5, const S529: u8 = 0x3, const S530: u8 = 0xb, const S531: u8 = 0x8,
378    const S532: u8 = 0x9, const S533: u8 = 0x4, const S534: u8 = 0xe, const S535: u8 = 0x3,
379    const S536: u8 = 0xf, const S537: u8 = 0x2, const S538: u8 = 0x5, const S539: u8 = 0xc,
380    const S540: u8 = 0x2, const S541: u8 = 0x9, const S542: u8 = 0x8, const S543: u8 = 0x5,
381    const S544: u8 = 0xc, const S545: u8 = 0xf, const S546: u8 = 0x3, const S547: u8 = 0xa,
382    const S548: u8 = 0x7, const S549: u8 = 0xb, const S550: u8 = 0x0, const S551: u8 = 0xe,
383    const S552: u8 = 0x4, const S553: u8 = 0x1, const S554: u8 = 0xa, const S555: u8 = 0x7,
384    const S556: u8 = 0x1, const S557: u8 = 0x6, const S558: u8 = 0xd, const S559: u8 = 0x0,
385    const S560: u8 = 0xb, const S561: u8 = 0x8, const S562: u8 = 0x6, const S563: u8 = 0xd,
386    const S600: u8 = 0x4, const S601: u8 = 0xd, const S602: u8 = 0xb, const S603: u8 = 0x0,
387    const S604: u8 = 0x2, const S605: u8 = 0xb, const S606: u8 = 0xe, const S607: u8 = 0x7,
388    const S608: u8 = 0xf, const S609: u8 = 0x4, const S610: u8 = 0x0, const S611: u8 = 0x9,
389    const S612: u8 = 0x8, const S613: u8 = 0x1, const S614: u8 = 0xd, const S615: u8 = 0xa,
390    const S616: u8 = 0x3, const S617: u8 = 0xe, const S618: u8 = 0xc, const S619: u8 = 0x3,
391    const S620: u8 = 0x9, const S621: u8 = 0x5, const S622: u8 = 0x7, const S623: u8 = 0xc,
392    const S624: u8 = 0x5, const S625: u8 = 0x2, const S626: u8 = 0xa, const S627: u8 = 0xf,
393    const S628: u8 = 0x6, const S629: u8 = 0x8, const S630: u8 = 0x1, const S631: u8 = 0x6,
394    const S632: u8 = 0x1, const S633: u8 = 0x6, const S634: u8 = 0x4, const S635: u8 = 0xb,
395    const S636: u8 = 0xb, const S637: u8 = 0xd, const S638: u8 = 0xd, const S639: u8 = 0x8,
396    const S640: u8 = 0xc, const S641: u8 = 0x1, const S642: u8 = 0x3, const S643: u8 = 0x4,
397    const S644: u8 = 0x7, const S645: u8 = 0xa, const S646: u8 = 0xe, const S647: u8 = 0x7,
398    const S648: u8 = 0xa, const S649: u8 = 0x9, const S650: u8 = 0xf, const S651: u8 = 0x5,
399    const S652: u8 = 0x6, const S653: u8 = 0x0, const S654: u8 = 0x8, const S655: u8 = 0xf,
400    const S656: u8 = 0x0, const S657: u8 = 0xe, const S658: u8 = 0x5, const S659: u8 = 0x2,
401    const S660: u8 = 0x9, const S661: u8 = 0x3, const S662: u8 = 0x2, const S663: u8 = 0xc,
402    const S700: u8 = 0xd, const S701: u8 = 0x1, const S702: u8 = 0x2, const S703: u8 = 0xf,
403    const S704: u8 = 0x8, const S705: u8 = 0xd, const S706: u8 = 0x4, const S707: u8 = 0x8,
404    const S708: u8 = 0x6, const S709: u8 = 0xa, const S710: u8 = 0xf, const S711: u8 = 0x3,
405    const S712: u8 = 0xb, const S713: u8 = 0x7, const S714: u8 = 0x1, const S715: u8 = 0x4,
406    const S716: u8 = 0xa, const S717: u8 = 0xc, const S718: u8 = 0x9, const S719: u8 = 0x5,
407    const S720: u8 = 0x3, const S721: u8 = 0x6, const S722: u8 = 0xe, const S723: u8 = 0xb,
408    const S724: u8 = 0x5, const S725: u8 = 0x0, const S726: u8 = 0x0, const S727: u8 = 0xe,
409    const S728: u8 = 0xc, const S729: u8 = 0x9, const S730: u8 = 0x7, const S731: u8 = 0x2,
410    const S732: u8 = 0x7, const S733: u8 = 0x2, const S734: u8 = 0xb, const S735: u8 = 0x1,
411    const S736: u8 = 0x4, const S737: u8 = 0xe, const S738: u8 = 0x1, const S739: u8 = 0x7,
412    const S740: u8 = 0x9, const S741: u8 = 0x4, const S742: u8 = 0xc, const S743: u8 = 0xa,
413    const S744: u8 = 0xe, const S745: u8 = 0x8, const S746: u8 = 0x2, const S747: u8 = 0xd,
414    const S748: u8 = 0x0, const S749: u8 = 0xf, const S750: u8 = 0x6, const S751: u8 = 0xc,
415    const S752: u8 = 0xa, const S753: u8 = 0x9, const S754: u8 = 0xd, const S755: u8 = 0x0,
416    const S756: u8 = 0xf, const S757: u8 = 0x3, const S758: u8 = 0x3, const S759: u8 = 0x5,
417    const S760: u8 = 0x5, const S761: u8 = 0x6, const S762: u8 = 0x8, const S763: u8 = 0xb>
418            = DES_Generic<16, 0b_1000000100000011,
419                    57, 49, 41, 33, 25, 17, 09, 01,
420                    58, 50, 42, 34, 26, 18, 10, 02,
421                    59, 51, 43, 35, 27, 19, 11, 03,
422                    60, 52, 44, 36, 63, 55, 47, 39,
423                    31, 23, 15, 07, 62, 54, 46, 38,
424                    30, 22, 14, 06, 61, 53, 45, 37,
425                    29, 21, 13, 05, 28, 20, 12, 04,
426                    14, 17, 11, 24, 01, 05, 03, 28,
427                    15, 06, 21, 10, 23, 19, 12, 04,
428                    26, 08, 16, 07, 27, 20, 13, 02,
429                    41, 52, 31, 37, 47, 55, 30, 40,
430                    51, 45, 33, 48, 44, 49, 39, 56,
431                    34, 53, 46, 42, 50, 36, 29, 32,
432                    58, 50, 42, 34, 26, 18, 10, 02,
433                    60, 52, 44, 36, 28, 20, 12, 04,
434                    62, 54, 46, 38, 30, 22, 14, 06,
435                    64, 56, 48, 40, 32, 24, 16, 08,
436                    57, 49, 41, 33, 25, 17, 09, 01,
437                    59, 51, 43, 35, 27, 19, 11, 03,
438                    61, 53, 45, 37, 29, 21, 13, 05,
439                    63, 55, 47, 39, 31, 23, 15, 07,
440                    EP01, EP02, EP03, EP04, EP05, EP06, EP07, EP08, EP09, EP10, EP11, EP12,
441                    EP13, EP14, EP15, EP16, EP17, EP18, EP19, EP20, EP21, EP22, EP23, EP24,
442                    EP25, EP26, EP27, EP28, EP29, EP30, EP31, EP32, EP33, EP34, EP35, EP36,
443                    EP37, EP38, EP39, EP40, EP41, EP42, EP43, EP44, EP45, EP46, EP47, EP48,
444                    TP01, TP02, TP03, TP04, TP05, TP06, TP07, TP08, TP09, TP10, TP11, TP12,
445                    TP13, TP14, TP15, TP16, TP17, TP18, TP19, TP20, TP21, TP22, TP23, TP24,
446                    TP25, TP26, TP27, TP28, TP29, TP30, TP31, TP32,
447                    S000, S001, S002, S003, S004, S005, S006, S007, S008, S009, S010, S011,
448                    S012, S013, S014, S015, S016, S017, S018, S019, S020, S021, S022, S023,
449                    S024, S025, S026, S027, S028, S029, S030, S031, S032, S033, S034, S035,
450                    S036, S037, S038, S039, S040, S041, S042, S043, S044, S045, S046, S047,
451                    S048, S049, S050, S051, S052, S053, S054, S055, S056, S057, S058, S059,
452                    S060, S061, S062, S063,
453                    S100, S101, S102, S103, S104, S105, S106, S107, S108, S109, S110, S111,
454                    S112, S113, S114, S115, S116, S117, S118, S119, S120, S121, S122, S123,
455                    S124, S125, S126, S127, S128, S129, S130, S131, S132, S133, S134, S135,
456                    S136, S137, S138, S139, S140, S141, S142, S143, S144, S145, S146, S147,
457                    S148, S149, S150, S151, S152, S153, S154, S155, S156, S157, S158, S159,
458                    S160, S161, S162, S163,
459                    S200, S201, S202, S203, S204, S205, S206, S207, S208, S209, S210, S211,
460                    S212, S213, S214, S215, S216, S217, S218, S219, S220, S221, S222, S223,
461                    S224, S225, S226, S227, S228, S229, S230, S231, S232, S233, S234, S235,
462                    S236, S237, S238, S239, S240, S241, S242, S243, S244, S245, S246, S247,
463                    S248, S249, S250, S251, S252, S253, S254, S255, S256, S257, S258, S259,
464                    S260, S261, S262, S263,
465                    S300, S301, S302, S303, S304, S305, S306, S307, S308, S309, S310, S311,
466                    S312, S313, S314, S315, S316, S317, S318, S319, S320, S321, S322, S323,
467                    S324, S325, S326, S327, S328, S329, S330, S331, S332, S333, S334, S335,
468                    S336, S337, S338, S339, S340, S341, S342, S343, S344, S345, S346, S347,
469                    S348, S349, S350, S351, S352, S353, S354, S355, S356, S357, S358, S359,
470                    S360, S361, S362, S363,
471                    S400, S401, S402, S403, S404, S405, S406, S407, S408, S409, S410, S411,
472                    S412, S413, S414, S415, S416, S417, S418, S419, S420, S421, S422, S423,
473                    S424, S425, S426, S427, S428, S429, S430, S431, S432, S433, S434, S435,
474                    S436, S437, S438, S439, S440, S441, S442, S443, S444, S445, S446, S447,
475                    S448, S449, S450, S451, S452, S453, S454, S455, S456, S457, S458, S459,
476                    S460, S461, S462, S463,
477                    S500, S501, S502, S503, S504, S505, S506, S507, S508, S509, S510, S511,
478                    S512, S513, S514, S515, S516, S517, S518, S519, S520, S521, S522, S523,
479                    S524, S525, S526, S527, S528, S529, S530, S531, S532, S533, S534, S535,
480                    S536, S537, S538, S539, S540, S541, S542, S543, S544, S545, S546, S547,
481                    S548, S549, S550, S551, S552, S553, S554, S555, S556, S557, S558, S559,
482                    S560, S561, S562, S563,
483                    S600, S601, S602, S603, S604, S605, S606, S607, S608, S609, S610, S611,
484                    S612, S613, S614, S615, S616, S617, S618, S619, S620, S621, S622, S623,
485                    S624, S625, S626, S627, S628, S629, S630, S631, S632, S633, S634, S635,
486                    S636, S637, S638, S639, S640, S641, S642, S643, S644, S645, S646, S647,
487                    S648, S649, S650, S651, S652, S653, S654, S655, S656, S657, S658, S659,
488                    S660, S661, S662, S663,
489                    S700, S701, S702, S703, S704, S705, S706, S707, S708, S709, S710, S711,
490                    S712, S713, S714, S715, S716, S717, S718, S719, S720, S721, S722, S723,
491                    S724, S725, S726, S727, S728, S729, S730, S731, S732, S733, S734, S735,
492                    S736, S737, S738, S739, S740, S741, S742, S743, S744, S745, S746, S747,
493                    S748, S749, S750, S751, S752, S753, S754, S755, S756, S757, S758, S759,
494                    S760, S761, S762, S763>;
495
496
497
498
499/// You have freedom of changing SHIFT, and PC101 ~ PC248.
500/// You can change the DES algorithm by simply changing the generic parameters
501/// `SHIFT`, and PC101 ~ PC248 without touching the source code itself.
502/// - SHIFT: According to the number of rounds, you have to determine `SHIFT`
503///   which is used for generating round keys. You can determine how many bits
504///   the half keys will be rotated left for the corresponding round in the key
505///   generator. If `SHIFT` is '0b10011001', the half keys will be rotated left
506///   by one bit for the first round, and will be rotated left by two bits for
507///   the second round, and will be rotated left by two bits for  the third round,
508///   and so on. The LSB (Least Significant Bit) is for the first round and the
509///   MSB (Most Significant Bit) is for the 128th round. `0` means that the half
510///   keys will be rotated left by two bits and `1` means that the half keys
511///   will be rotated left by one bit. Up to only `ROUND` bits from the LSB of
512///   `SHIFT` will be meaningful. For example, if `ROUND` is 5 and `SHIFT` is
513///   '0b10011001', only '0b11001' out of '0b10011001' is meaningful.
514///   If `ROUND` is 16 and `SHIFT` is '0b10011001', `SHIFT` will be understood
515///   to be '0b0000000010011001'.
516/// - PC101 ~ PC248: Permutation compression. In key generator, the 64-bit key
517///   which includes parity bits is compressed into 56-bit key by dropping all
518///   the parity bits (8th, 16th, 24th, 32th, 40th, 48th, 56th, and 64th bits)
519///   and permutating (or transposing or shuffling) all bits.  They are 1-based.
520///   For this operation, PC101 ~ PC156 are used. You can change the permutation
521///   compression algorithm by changing these parameters. Note that PC101 ~
522///   PC248 should not include 8, 16, 24, 32, 40, 48, 56, and 64 because they
523///   are all parity bits. If you include any of those numbers, the whole DES
524///   encryption/decryption algorithm is broken or unstable or collapses. Also,
525///   in key generator, 56-bit key is compressed into 48-bit key by dropping all
526///   the bits (9th, 18th, 22nd, 25th, 35th, 43rd, and 54th bits) and
527///   permutating (or transposing or shuffling) all bits. For this operation,
528///   PC201 ~ PC248 are used. You can change the permutation compression
529///   algorithm by changing these parameters. In this case, you can drop other
530///   bits intead of dropping 9th, 18th, 22nd, 25th, 35th, 43rd, and 54th bits.
531///   Dropping other bits does not kill the whole DES encryption/decryption
532///   algorithm.
533#[allow(non_camel_case_types)]
534pub type DES_RoundKey<const SHIFT: u128 = 0b_1000000100000011,
535const PC101: u8 = 57, const PC102: u8 = 49, const PC103: u8 = 41, const PC104: u8 = 33,
536const PC105: u8 = 25, const PC106: u8 = 17, const PC107: u8 = 09, const PC108: u8 = 01,
537const PC109: u8 = 58, const PC110: u8 = 50, const PC111: u8 = 42, const PC112: u8 = 34,
538const PC113: u8 = 26, const PC114: u8 = 18, const PC115: u8 = 10, const PC116: u8 = 02,
539const PC117: u8 = 59, const PC118: u8 = 51, const PC119: u8 = 43, const PC120: u8 = 35,
540const PC121: u8 = 27, const PC122: u8 = 19, const PC123: u8 = 11, const PC124: u8 = 03,
541const PC125: u8 = 60, const PC126: u8 = 52, const PC127: u8 = 44, const PC128: u8 = 36,
542const PC129: u8 = 63, const PC130: u8 = 55, const PC131: u8 = 47, const PC132: u8 = 39,
543const PC133: u8 = 31, const PC134: u8 = 23, const PC135: u8 = 15, const PC136: u8 = 07,
544const PC137: u8 = 62, const PC138: u8 = 54, const PC139: u8 = 46, const PC140: u8 = 38,
545const PC141: u8 = 30, const PC142: u8 = 22, const PC143: u8 = 14, const PC144: u8 = 06,
546const PC145: u8 = 61, const PC146: u8 = 53, const PC147: u8 = 45, const PC148: u8 = 37,
547const PC149: u8 = 29, const PC150: u8 = 21, const PC151: u8 = 13, const PC152: u8 = 05,
548const PC153: u8 = 28, const PC154: u8 = 20, const PC155: u8 = 12, const PC156: u8 = 04,
549const PC201: u8 = 14, const PC202: u8 = 17, const PC203: u8 = 11, const PC204: u8 = 24,
550const PC205: u8 = 01, const PC206: u8 = 05, const PC207: u8 = 03, const PC208: u8 = 28,
551const PC209: u8 = 15, const PC210: u8 = 06, const PC211: u8 = 21, const PC212: u8 = 10,
552const PC213: u8 = 23, const PC214: u8 = 19, const PC215: u8 = 12, const PC216: u8 = 04,
553const PC217: u8 = 26, const PC218: u8 = 08, const PC219: u8 = 16, const PC220: u8 = 07,
554const PC221: u8 = 27, const PC222: u8 = 20, const PC223: u8 = 13, const PC224: u8 = 02,
555const PC225: u8 = 41, const PC226: u8 = 52, const PC227: u8 = 31, const PC228: u8 = 37,
556const PC229: u8 = 47, const PC230: u8 = 55, const PC231: u8 = 30, const PC232: u8 = 40,
557const PC233: u8 = 51, const PC234: u8 = 45, const PC235: u8 = 33, const PC236: u8 = 48,
558const PC237: u8 = 44, const PC238: u8 = 49, const PC239: u8 = 39, const PC240: u8 = 56,
559const PC241: u8 = 34, const PC242: u8 = 53, const PC243: u8 = 46, const PC244: u8 = 42,
560const PC245: u8 = 50, const PC246: u8 = 36, const PC247: u8 = 29, const PC248: u8 = 32>
561            = DES_Generic<16, SHIFT,
562                            PC101, PC102, PC103, PC104, PC105, PC106, PC107, PC108,
563                            PC109, PC110, PC111, PC112, PC113, PC114, PC115, PC116,
564                            PC117, PC118, PC119, PC120, PC121, PC122, PC123, PC124,
565                            PC125, PC126, PC127, PC128, PC129, PC130, PC131, PC132,
566                            PC133, PC134, PC135, PC136, PC137, PC138, PC139, PC140,
567                            PC141, PC142, PC143, PC144, PC145, PC146, PC147, PC148,
568                            PC149, PC150, PC151, PC152, PC153, PC154, PC155, PC156,
569                            PC201, PC202, PC203, PC204, PC205, PC206, PC207, PC208,
570                            PC209, PC210, PC211, PC212, PC213, PC214, PC215, PC216,
571                            PC217, PC218, PC219, PC220, PC221, PC222, PC223, PC224,
572                            PC225, PC226, PC227, PC228, PC229, PC230, PC231, PC232,
573                            PC233, PC234, PC235, PC236, PC237, PC238, PC239, PC240,
574                            PC241, PC242, PC243, PC244, PC245, PC246, PC247, PC248>;
575
576
577
578/// You have freedom of changing ROUND and SHIFT. You can change the DES
579/// algorithm by simply changing the generic parameters `ROUND` and `SHIFT`
580/// without touching the source code itself.
581/// - ROUND: You can determine how many times the Fiestel network will be
582///   repeated. Its maximum value is 128 and its minimum value is 0.
583///   Original DES has 16 rounds for its Feistel structure but you can increase
584///   the number of rounds up to 128 rounds, and decrease it down to 0.
585/// - SHIFT: According to the number of rounds, you have to determine `SHIFT`
586///   which is used for generating round keys. You can determine how many bits
587///   the half keys will be rotated left for the corresponding round in the key
588///   generator. If `SHIFT` is '0b10011001', the half keys will be rotated left
589///   by one bit for the first round, and will be rotated left by two bits for
590///   the second round, and will be rotated left by two bits for  the third round,
591///   and so on. The LSB (Least Significant Bit) is for the first round and the
592///   MSB (Most Significant Bit) is for the 128th round. `0` means that the half
593///   keys will be rotated left by two bits and `1` means that the half keys
594///   will be rotated left by one bit. Up to only `ROUND` bits from the LSB of
595///   `SHIFT` will be meaningful. For example, if `ROUND` is 5 and `SHIFT` is
596///   '0b10011001', only '0b11001' out of '0b10011001' is meaningful.
597///   If `ROUND` is 16 and `SHIFT` is '0b10011001', `SHIFT` will be understood
598///   to be '0b0000000010011001'.
599#[allow(non_camel_case_types)]
600pub type DES_Expanded<const ROUND: usize = 16, const SHIFT: u128 = 0b_1000000100000011> = DES_Generic<ROUND, SHIFT>;
601
602/// The official DES symmetric-key algorithm for the encryption of digital data
603/// If you want to use the official DES algorithm, the type DES is for you.
604#[allow(non_camel_case_types)]
605pub type DES = DES_Generic;    // equivalent to `pub type DES = DES_Expanded;`
606
607/// A DES symmetric-key algorithm for the encryption of digital data
608/// 
609/// # Note
610/// **This descryption about DES is according to big endianness.**
611/// MSB (Most Significant Bit) is the first bit and LSB (Least Significant Bit)
612/// is the 64th bit in this descryption unless otherwise mentioned.
613/// 
614/// # Introduction
615/// DES is the acronym of Data Encryption Standard. It is the symmetric key
616/// encryption/decryption algorithm. It was originally developed based on
617/// Lucifer encryption/decryption algorithm made by IBM. DES was approved as a 
618/// federal standard in November 1976.
619/// 
620/// # Vulnerability
621/// - Its key length is only 56-bit. It is considered to be too short against
622///   modern computing power. Actually, in July, 1998, the DES key was broken by
623///   brute-force attack within 56 hours with a machine DES cracker (Deep Crack)
624///   made by EEF (Electronic Frontier Foundation). And, in January, 1999, Deep
625///   Crack and distributed.net broke a DES key together within 22 hours and
626///   15 minutes.
627/// - Weak keys: 0x0000000000000000, 0x0101010101010101, 0xFFFFFFFFFFFFFFFF,
628///   0xFEFEFEFEFEFEFEFE, 0xF1F1F1F1E0E0E0E0, 0xF0F0F0F0E1E1E1E1,
629///   0x0E0E0E0E1F1F1F1F, 0x0F0F0F0F1E1E1E1E in little-endianness.
630///   Actually, if the parity bits in keys are ignored,
631///   the keys 0x0000000000000000 and 0x0101010101010101 are the same key.
632///   In fact, not only 0x0101010101010101 is the same key as
633///   0x0000000000000000. 0x0100000000000000 is also the same key. All the 256
634///   keys that have only different parity bits and all other bits same are the
635///   same key as 0x0000000000000000, too. Though only representative keys will
636///   be mentioned in this description, please keep in mind that all the 256
637///   keys that have only different parity bits and all other bits same are the
638///   same key.
639///   And, the keys 0xFFFFFFFFFFFFFFFF and 0xFEFEFEFEFEFEFEFE are also the same key.
640///   And, The keys 0xF1F1F1F1E0E0E0E0 and 0xF0F0F0F0E1E1E1E1 are also the same key.
641///   And, the keys 0x0E0E0E0E1F1F1F1F and 0x0F0F0F0F1E1E1E1E are the same key, too.
642///   For instance, if you encrypt your data with the key 0x0000000000000000 and
643///   encrypt the output ciphertext again with the same key 0x0000000000000000,
644///   you will get the original plaintext! So, the ciphertext is only
645///   secure-looking. 
646/// - Semi-week keys: The pairs (0x0E010E011F011F01, 0x010E010E011F011F),
647///   (0xF101F101E001E001, 0x01F101F101E001E0),
648///   (0xFE01FE01FE01FE01, 0x01FE01FE01FE01FE),
649///   (0xF10EF10EE01FE01F, 0x0EF10EF11FE01FE0),
650///   (0xFE0EFE0EFE1FFE1F, 0x0EFE0EFE1FFE1FFE), and 
651///   (0xFEF1FEF1FEE0FEE0, 0xF1FEF1FEE0FEE0FE) in little-endianness are
652///   considered to be week.
653///   For example, if you encrypt your data with the key 0x0E010E011F011F01 and
654///   encrypt the output ciphertext again with its counterpart key
655///   0x010E010E011F011F, you will get the original plaintext!
656///   So, the ciphertext is only secure-looking.
657/// 
658/// # Examples for Weak keys
659/// ```
660/// use cryptocol::symmetric::DES;
661/// let message = 0x1234567890ABCDEF_u64;
662/// let mut cipher: u64;
663/// let weak_key = [ 0x0000000000000000_u64, 0x0101010101010101, 0xFFFFFFFFFFFFFFFF, 0xFEFEFEFEFEFEFEFE, 0xF1F1F1F1E0E0E0E0, 0xF0F0F0F0E1E1E1E1, 0x0E0E0E0E1F1F1F1F, 0x0F0F0F0F1E1E1E1E];
664/// let mut des = DES::new();
665/// for key in weak_key
666/// {
667///     println!("Weak Key:\t{:#018X}", key);
668///     des.set_key_u64(key);
669///     cipher = des.encrypt_u64(message);
670///     cipher = des.encrypt_u64(cipher);
671/// 
672///     println!("Message =\t{:#018X}", message);
673///     println!("Cipher =\t{:#018X}", cipher);
674///     assert_eq!(message, cipher);
675///     println!();
676/// }
677/// ```
678/// 
679/// # Examples for Semi-Weak keys
680/// ```
681/// use cryptocol::symmetric::DES;
682/// let message = 0x1234567890ABCDEF_u64;
683/// let mut cipher: u64;
684/// let semi_weak_key: [(u64, u64); 6] = [  (0x0E010E011F011F01, 0x010E010E011F011F),
685///                                         (0xF101F101E001E001, 0x01F101F101E001E0),
686///                                         (0xFE01FE01FE01FE01, 0x01FE01FE01FE01FE),
687///                                         (0xF10EF10EE01FE01F, 0x0EF10EF11FE01FE0),
688///                                         (0xFE0EFE0EFE1FFE1F, 0x0EFE0EFE1FFE1FFE),
689///                                         (0xFEF1FEF1FEE0FEE0, 0xF1FEF1FEE0FEE0FE)];
690/// let mut des = DES::new();
691/// for key in semi_weak_key
692/// {
693///     println!("Semi-weak Key pair: {:#018X}, {:#018X}", key.0, key.1);
694///     des.set_key_u64(key.0);
695///     cipher = des.encrypt_u64(message);
696///     des.set_key_u64(key.1);
697///     cipher = des.encrypt_u64(cipher);
698/// 
699///     println!("Message =\t{:#018X}", message);
700///     println!("Cipher =\t{:#018X}", cipher);
701///     assert_eq!(message, cipher);
702///     println!();
703/// }
704/// ```
705/// 
706/// # Use of DES and its variants
707/// This algorithm is implemented generic way. Most of the constants are
708/// implemented as generic constants. So, without changing any line of code, you
709/// can change the algorithm by changing the generic parameter. You can design
710/// and implement your own algorithm based on DES which uses Feistel structure.
711/// 
712/// # Generic Parameters
713/// - ROUND: You can determine how many times the Fiestel network will be
714///   repeated. Its maximum value is 128 and its minimum value is 0.
715///   Original DES has 16 rounds for its Feistel structure but you can increase
716///   the number of rounds up to 128 rounds, and decrease it down to 0.
717/// - SHIFT: According to the number of rounds, you have to determine `SHIFT`
718///   which is used for generating round keys. You can determine how many bits
719///   the half keys will be rotated left for the corresponding round in the key
720///   generator. If `SHIFT` is '0b10011001', the half keys will be rotated left
721///   by one bit for the first round, and will be rotated left by two bits for
722///   the second round, and will be rotated left by two bits for  the third round,
723///   and so on. The LSB (Least Significant Bit) is for the first round and the
724///   MSB (Most Significant Bit) is for the 128th round. `0` means that the half
725///   keys will be rotated left by two bits and `1` means that the half keys
726///   will be rotated left by one bit. Up to only `ROUND` bits from the LSB of
727///   `SHIFT` will be meaningful. For example, if `ROUND` is 5 and `SHIFT` is
728///   '0b10011001', only '0b11001' out of '0b10011001' is meaningful.
729///   If `ROUND` is 16 and `SHIFT` is '0b10011001', `SHIFT` will be understood
730///   to be '0b0000000010011001'.
731/// - PC101 ~ PC248: Permutation compression. In key generator, the 64-bit key
732///   which includes parity bits is compressed into 56-bit key by dropping all
733///   the parity bits (8th, 16th, 24th, 32th, 40th, 48th, 56th, and 64th bits)
734///   and permutating (or transposing or shuffling) all bits. They are 1-based.
735///   For this operation, PC101 ~ PC156 are used. You can change the permutation
736///   compression algorithm by changing these parameters. Note that PC101 ~
737///   PC248 should not include 8, 16, 24, 32, 40, 48, 56, and 64 because they
738///   are all parity bits. If you include any of those numbers, the whole DES
739///   encryption/decryption algorithm is broken or unstable or collapses. Also,
740///   in key generator, 56-bit key is compressed into 48-bit key by dropping all
741///   the bits (9th, 18th, 22nd, 25th, 35th, 43rd, and 54th bits) and
742///   permutating (or transposing or shuffling) all bits. For this operation,
743///   PC201 ~ PC248 are used. You can change the permutation compression
744///   algorithm by changing these parameters. In this case, you can drop other
745///   bits intead of dropping 9th, 18th, 22nd, 25th, 35th, 43rd, and 54th bits.
746///   Dropping other bits does not kill the whole DES encryption/decryption
747///   algorithm.
748/// - IP01 ~ IP64: Inital permutation constants. They are 1-based. For example,
749///   `IP01 = 58` means that the 58th bit of data is moved to the first bit of
750///   the data which is MSB at initial permutation. You can change inital
751///   permutation wire by changing these constants. However, when you change
752///   these constants, you have to remember that you should included all the
753///   bits. You cannot drop any bit. Your dropping any bit will surely kill the
754///   whole DES encryption/decryption algorithm. Final permutation constants is
755///   automatically calculated from Inital permutation constants. FP01 ~ FP64
756///   is inverse version of IP01 ~ IP64. So, FP01 ~ FP64 will be automagically
757///   determined. You don't have to determine them.
758/// - S000 ~ S763: S-Box constants. Its index such as 000, 212, etc. is
759///   0-based. S0XX means S-Box 0, S1XX means S-Box 1, and so on. S000 is the
760///   first element of S-Box 0.
761///   According to [the document](https://page.math.tu-berlin.de/~kant/teaching/hess/krypto-ws2006/des.htm),
762///   the input six bits determines the output of S-Box. The first and the last
763///   bit of the six bits represent in base 2 a number in the decimal range 0 to
764///   3 (or binary 00 to 11) which is row number. The rest middle four bits
765///   represent in base 2 a number in the decimal range 0 to 15 (binary 0000 to
766///   1111) which is column number. It is considered that the DES designers
767///   explained the S-box structure _unnecessarily too complicated_. The
768///   above-described S-box indexing way looks two dimensional, but actually is
769///   one dimensional. So, in this crate, S-boxes are implemented to be
770///   two-dimensional array which is an array of S-boxes. Each S-box is an array
771///   of 64 four-bit numbers. The input six-bit number is used as the index of
772///   the one-dimensional array of these 64 four-bit numbers. So, the S-box
773///   tables have been rearranged to be the one-dimensional array. You can cange
774///   S-Box by changing these constants. However, you have know that *the change
775///   of these constants may hurt the security a lot*. And the principle of
776///   S-box has been unknown so far.
777/// - EP01 ~ EP48: Expansion permutation constants. They are 1-based. For
778///   example, `EP01 = 28` means that the 28th bit of data is moved to the first
779///   bit of the data which is MSB at expansion permutation. They expand the
780///   32-bit right-half data from the Feistel structure of the corresponding
781///   round into 48 bits in order to perform XOR (exclusive OR) with the
782///   corresponding 48-bit round key. When you change these constants, you have
783///   to remember that you should included all the bits. You cannot drop any
784///   bit. Your dropping any bit will surely kill the whole DES
785///   encryption/decryption algorithm.
786/// - TP01 ~ TP32: Translation permutation constans.  They are 1-based. For
787///   example, `TP01 = 16` means that the 16th bit of data is moved to the
788///   first bit of the data which is MSB at translation permutation. You can
789///   change translation permutation wire by changing these constants. However,
790///   when you change these constants, you have to remember that you should
791///   included all the bits. You cannot drop any bit. Your dropping any bit will
792///   surely kill the whole DES encryption/decryption algorithm.
793/// 
794/// # Caution
795/// DES is not considered to be secure anymore. So, it is wise not to use DES
796/// for serious purpose. Instead, use TDES or AES or any other equivalents.
797/// In this crate, NDES which is generalized version of TDES is provided, and
798/// AES is also provided.
799/// 
800/// # Reference
801/// [Read more](https://en.wikipedia.org/wiki/Data_Encryption_Standard)
802/// about DES in brief.
803/// Watch [this video](https://www.youtube.com/watch?v=kPBJIhpcZgE) and then
804/// [this video](https://www.youtube.com/watch?v=l-7YW06BFNs) in series
805/// for more (or deeper or full) understanding of DES.
806/// 
807/// # Quick Start
808/// You have to import (use) the module `DES` in order to use official DES
809/// as shown in Example 1.
810/// 
811/// # Example 1
812/// ```
813/// use cryptocol::symmetric::DES;
814/// ```
815/// 
816/// You can instantiate the DES object with `u64` key as Example 2.
817/// In this case, you have to take endianness into account.
818/// In little-endianness, 0x_1234567890ABCDEF_u64 is [0xEFu8, 0xCDu8, 0xABu8,
819/// 0x90u8, 0x78u8, 0x56u8, 0x34u8, 0x12u8] while the same 
820/// 0x_1234567890ABCDEF_u64 is [0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x90u8, 0xABu8,
821/// 0xCDu8, 0xEF_u64] in big-endianness.
822/// The instantiated object should be mutable.
823/// 
824/// # Example 2
825/// ```
826/// use cryptocol::symmetric::DES;
827/// let key = 0x_1234567890ABCDEF_u64;
828/// let mut _a_des = DES::new_with_key_u64(key);
829/// ```
830/// 
831/// Also, you can instantiate the DES object with `[u8; 8]` key as shown in
832/// Example 3. In this case, you don't have to take endianness into account.
833/// The instantiated object should be mutable.
834/// 
835/// # Example 3
836/// ```
837/// use cryptocol::symmetric::DES;
838/// let key = [0xEFu8, 0xCDu8, 0xABu8, 0x90u8, 0x78u8, 0x56u8, 0x34u8, 0x12u8];
839/// let mut _a_des = DES::new_with_key(key);
840/// ```
841/// 
842/// You can instantiate the DES object without key and set a `u64` key later as
843/// shown in Example 4 or a `[u8; 8]` key later as shown in Example 5.
844/// 
845/// # Example 4
846/// ```
847/// use cryptocol::symmetric::DES;
848/// let mut a_des = DES::new();
849/// let key = 0x_1234567890ABCDEF_u64;
850/// a_des.set_key_u64(key);
851/// ```
852/// 
853/// # Example 5
854/// ```
855/// use cryptocol::symmetric::DES;
856/// let mut a_des = DES::new();
857/// let key = [0xEFu8, 0xCDu8, 0xABu8, 0x90u8, 0x78u8, 0x56u8, 0x34u8, 0x12u8];
858/// a_des.set_key(key);
859/// ```
860/// 
861/// Now, you can freely use any operation mode. This crate provide
862/// ECB (Electronic CodeBook), CBC(Cipher Block Chaining), PCBC (Propagation
863/// Cipher Block Chaining), CFB (Cipher FeedBack) OFB (Output FeedBack), and
864/// CTR (CounTeR). You can choose the way of padding bits according to either
865/// [PKCS #7](https://node-security.com/posts/cryptography-pkcs-7-padding/) or
866/// [ISO 7816-4](https://en.wikipedia.org/wiki/Padding_(cryptography)#ISO/IEC_7816-4).
867/// So, you can import (use) one of the following traits: ECB_PKCS7, ECB_ISO,
868/// CBC_PKCS7, CBC_ISO, PCBC_PKCS7, PCBC_ISO, CFB, OFB, and CTR. The following
869/// example 6 shows the case that you choose CBC operation mode and padding bits
870/// according to PKCS #7.
871/// 
872/// # Example 6
873/// ```
874/// use std::io::Write;
875/// use std::fmt::Write as _;
876/// use cryptocol::symmetric::{ DES, CBC_PKCS7 };
877/// 
878/// let mut a_des = DES::new_with_key([0xEFu8, 0xCDu8, 0xABu8, 0x90u8, 0x78u8, 0x56u8, 0x34u8, 0x12u8]);
879/// let message = "In the beginning God created the heavens and the earth.";
880/// println!("M =\t{}", message);
881/// let iv = 0x_FEDCBA0987654321_u64;
882/// println!("IV =\t{}", iv);
883/// let mut cipher = Vec::<u8>::new();
884/// a_des.encrypt_str_into_vec(iv, message, &mut cipher);
885/// print!("C =\t");
886/// for c in cipher.clone()
887///     { print!("{:02X} ", c); }
888/// println!();
889/// let mut txt = String::new();
890/// for c in cipher.clone()
891///     { write!(txt, "{:02X} ", c); }
892/// assert_eq!(txt, "4B B5 ED DC A0 58 7E 6D 6C 3B A2 00 38 C3 D4 29 42 B1 CF 0D E9 FA EA 11 11 6B C8 30 73 39 DD B7 3F 96 9B A3 76 05 34 7E 64 2F D4 CC B2 68 33 64 C5 9E EF 01 A9 4A FD 5B ");
893/// 
894/// let mut recovered = String::new();
895/// a_des.decrypt_vec_into_string(iv, &cipher, &mut recovered);
896/// println!("B (16 rounds) =\t{}", recovered);
897/// assert_eq!(recovered, "In the beginning God created the heavens and the earth.");
898/// assert_eq!(recovered, message);
899/// println!();
900/// ```
901/// 
902/// You can modify the DES encryption/decryption algorithm as you want. All
903/// the constants are implemented as generic parameters. For instance, you can
904/// change S-box, the number of rounds of Feistel network, the number of
905/// shift-left in round key generators, etc. The following Example 7 shows the
906/// variation of DES which has 128 rounds instead of 16 rounds.
907/// 
908/// # Example 7
909/// ```
910/// use std::io::Write;
911/// use std::fmt::Write as _;
912/// use cryptocol::symmetric::{ DES_Expanded, CBC_PKCS7 };
913/// 
914/// let mut a_des = DES_Expanded::<128, 0x_8103_8103_8103_8103_8103_8103_8103_8103_u128>::new_with_key_u64([0xEFu8, 0xCDu8, 0xABu8, 0x90u8, 0x78u8, 0x56u8, 0x34u8, 0x12u8]);
915/// let message = "In the beginning God created the heavens and the earth.";
916/// println!("M =\t{}", message);
917/// let iv = 0x_FEDCBA0987654321_u64;
918/// println!("IV =\t{}", iv);
919/// let mut cipher = Vec::<u8>::new();
920/// a_des.encrypt_str_into_vec(iv, message.as_ptr(), message.len() as u64, &mut cipher);
921/// print!("C =\t");
922/// for c in cipher.clone()
923///     { print!("{:02X} ", c); }
924/// println!();
925/// let mut txt = String::new();
926/// for c in cipher.clone()
927///     { write!(txt, "{:02X} ", c); }
928/// assert_eq!(txt, "0B EA 6B BC 68 F9 B0 3E 7D AF DE 71 9C 08 AA 16 42 40 1C C8 DC 40 51 C6 8D D4 E7 D2 0B A4 F2 09 02 02 C2 6E 99 BC 9E 2A F4 11 7E 48 A7 ED 76 70 C6 9D C6 BD A6 9B 58 8B ");
929/// 
930/// let mut recovered = String::new();
931/// a_des.decrypt_vec_into_string(iv, &cipher, &mut recovered);
932/// println!("B =\t{}", recovered);
933/// assert_eq!(recovered, "In the beginning God created the heavens and the earth.");
934/// assert_eq!(recovered, message);
935/// ```
936/// 
937/// # Notice for Practical Use
938/// Now, you can freely use any methods with any paddings
939/// in any operation modes.
940/// - This crate provides six operation modes:
941///   ECB, CBC, PCBC, CFB, OFB, and CTR.
942/// - This crate provides two padding ways: ISO 7816-4 and PKCS #7.
943/// - The operation modes ECB, CBC and PCBC requires padding bytes.
944/// - You can combine three operation modes and two padding ways.
945/// - The operation modes
946///   [`CFB`](./trait.CFB.html#trait.CFB),
947///   [`OFB`](./trait.OFB.html#trait.OFB), and
948///   [`CTR`](./trait.CTR.html#trait.CTR)
949///   does not require padding bytes.
950/// - The traits that implements combination of operation modes and padding
951///   ways are provided such as
952///   [`ECB_PKCS7`](./trait.ECB_PKCS7.html#trait.ECB_PKCS7),
953///   [`ECB_ISO`](./trait.ECB_ISO.html#trait.ECB_ISO),
954///   [`CBC_PKCS7`](./trait.CBC_PKCS7.html#trait.ECB_PKCS7),
955///   [`CBC_ISO`](./trait.CBC_ISO.html#trait.CBC_ISO),
956///   [`PCBC_PKCS7`](./trait.PCBC_PKCS7.html#trait.PCBC_PKCS7), and
957///   [`PCBC_ISO`](./trait.PCBC_ISO.html#trait.PCBC_ISO).
958/// - You can find detaild instructions and their helpful examples
959///   if you go through those links.
960///
961/// In summary,
962///
963/// |      | padding PKCS7                                          | padding ISO                                      | no padding                        |
964/// |------|--------------------------------------------------------|--------------------------------------------------|-----------------------------------|
965/// | ECB  | [ECB_PKCS7](./trait.ECB_PKCS7.html#trait.ECB_PKCS7)    | [ECB_ISO](./trait.ECB_ISO.html#trait.ECB_ISO)    |                                   |
966/// | CBC  | [CBC_PKCS7](./trait.CBC_PKCS7.html#trait.ECB_PKCS7)    | [CBC_ISO](./trait.CBC_ISO.html#trait.CBC_ISO)    |                                   |
967/// | PCBC | [PCBC_PKCS7](./trait.PCBC_PKCS7.html#trait.PCBC_PKCS7) | [PCBC_ISO](./trait.PCBC_ISO.html#trait.PCBC_ISO) |                                   |
968/// | CFB  |                                                        |                                                  | [CFB](./trait.CFB.html#trait.CFB) |
969/// | OFB  |                                                        |                                                  | [OFB](./trait.OFB.html#trait.OFB) |
970/// | CTR  |                                                        |                                                  | [CTR](./trait.CTR.html#trait.CTR) |
971///
972#[allow(non_camel_case_types)]
973#[derive(Clone)]
974pub struct DES_Generic<const ROUND: usize = 16, const SHIFT: u128 = 0b_1000000100000011,
975                const PC101: u8 = 57, const PC102: u8 = 49, const PC103: u8 = 41, const PC104: u8 = 33,
976                const PC105: u8 = 25, const PC106: u8 = 17, const PC107: u8 = 09, const PC108: u8 = 01,
977                const PC109: u8 = 58, const PC110: u8 = 50, const PC111: u8 = 42, const PC112: u8 = 34,
978                const PC113: u8 = 26, const PC114: u8 = 18, const PC115: u8 = 10, const PC116: u8 = 02,
979                const PC117: u8 = 59, const PC118: u8 = 51, const PC119: u8 = 43, const PC120: u8 = 35,
980                const PC121: u8 = 27, const PC122: u8 = 19, const PC123: u8 = 11, const PC124: u8 = 03,
981                const PC125: u8 = 60, const PC126: u8 = 52, const PC127: u8 = 44, const PC128: u8 = 36,
982                const PC129: u8 = 63, const PC130: u8 = 55, const PC131: u8 = 47, const PC132: u8 = 39,
983                const PC133: u8 = 31, const PC134: u8 = 23, const PC135: u8 = 15, const PC136: u8 = 07,
984                const PC137: u8 = 62, const PC138: u8 = 54, const PC139: u8 = 46, const PC140: u8 = 38,
985                const PC141: u8 = 30, const PC142: u8 = 22, const PC143: u8 = 14, const PC144: u8 = 06,
986                const PC145: u8 = 61, const PC146: u8 = 53, const PC147: u8 = 45, const PC148: u8 = 37,
987                const PC149: u8 = 29, const PC150: u8 = 21, const PC151: u8 = 13, const PC152: u8 = 05,
988                const PC153: u8 = 28, const PC154: u8 = 20, const PC155: u8 = 12, const PC156: u8 = 04,
989                const PC201: u8 = 14, const PC202: u8 = 17, const PC203: u8 = 11, const PC204: u8 = 24,
990                const PC205: u8 = 01, const PC206: u8 = 05, const PC207: u8 = 03, const PC208: u8 = 28,
991                const PC209: u8 = 15, const PC210: u8 = 06, const PC211: u8 = 21, const PC212: u8 = 10,
992                const PC213: u8 = 23, const PC214: u8 = 19, const PC215: u8 = 12, const PC216: u8 = 04,
993                const PC217: u8 = 26, const PC218: u8 = 08, const PC219: u8 = 16, const PC220: u8 = 07,
994                const PC221: u8 = 27, const PC222: u8 = 20, const PC223: u8 = 13, const PC224: u8 = 02,
995                const PC225: u8 = 41, const PC226: u8 = 52, const PC227: u8 = 31, const PC228: u8 = 37,
996                const PC229: u8 = 47, const PC230: u8 = 55, const PC231: u8 = 30, const PC232: u8 = 40,
997                const PC233: u8 = 51, const PC234: u8 = 45, const PC235: u8 = 33, const PC236: u8 = 48,
998                const PC237: u8 = 44, const PC238: u8 = 49, const PC239: u8 = 39, const PC240: u8 = 56,
999                const PC241: u8 = 34, const PC242: u8 = 53, const PC243: u8 = 46, const PC244: u8 = 42,
1000                const PC245: u8 = 50, const PC246: u8 = 36, const PC247: u8 = 29, const PC248: u8 = 32,
1001                const IP01: u8 = 58, const IP02: u8 = 50, const IP03: u8 = 42, const IP04: u8 = 34,
1002                const IP05: u8 = 26, const IP06: u8 = 18, const IP07: u8 = 10, const IP08: u8 = 02,
1003                const IP09: u8 = 60, const IP10: u8 = 52, const IP11: u8 = 44, const IP12: u8 = 36,
1004                const IP13: u8 = 28, const IP14: u8 = 20, const IP15: u8 = 12, const IP16: u8 = 04,
1005                const IP17: u8 = 62, const IP18: u8 = 54, const IP19: u8 = 46, const IP20: u8 = 38,
1006                const IP21: u8 = 30, const IP22: u8 = 22, const IP23: u8 = 14, const IP24: u8 = 06,
1007                const IP25: u8 = 64, const IP26: u8 = 56, const IP27: u8 = 48, const IP28: u8 = 40,
1008                const IP29: u8 = 32, const IP30: u8 = 24, const IP31: u8 = 16, const IP32: u8 = 08,
1009                const IP33: u8 = 57, const IP34: u8 = 49, const IP35: u8 = 41, const IP36: u8 = 33,
1010                const IP37: u8 = 25, const IP38: u8 = 17, const IP39: u8 = 09, const IP40: u8 = 01,
1011                const IP41: u8 = 59, const IP42: u8 = 51, const IP43: u8 = 43, const IP44: u8 = 35,
1012                const IP45: u8 = 27, const IP46: u8 = 19, const IP47: u8 = 11, const IP48: u8 = 03,
1013                const IP49: u8 = 61, const IP50: u8 = 53, const IP51: u8 = 45, const IP52: u8 = 37,
1014                const IP53: u8 = 29, const IP54: u8 = 21, const IP55: u8 = 13, const IP56: u8 = 05,
1015                const IP57: u8 = 63, const IP58: u8 = 55, const IP59: u8 = 47, const IP60: u8 = 39,
1016                const IP61: u8 = 31, const IP62: u8 = 23, const IP63: u8 = 15, const IP64: u8 = 07,
1017                const EP01: u8 = 32, const EP02: u8 = 01, const EP03: u8 = 02, const EP04: u8 = 03,
1018                const EP05: u8 = 04, const EP06: u8 = 05, const EP07: u8 = 04, const EP08: u8 = 05,
1019                const EP09: u8 = 06, const EP10: u8 = 07, const EP11: u8 = 08, const EP12: u8 = 09,
1020                const EP13: u8 = 08, const EP14: u8 = 09, const EP15: u8 = 10, const EP16: u8 = 11,
1021                const EP17: u8 = 12, const EP18: u8 = 13, const EP19: u8 = 12, const EP20: u8 = 13,
1022                const EP21: u8 = 14, const EP22: u8 = 15, const EP23: u8 = 16, const EP24: u8 = 17,
1023                const EP25: u8 = 16, const EP26: u8 = 17, const EP27: u8 = 18, const EP28: u8 = 19,
1024                const EP29: u8 = 20, const EP30: u8 = 21, const EP31: u8 = 20, const EP32: u8 = 21,
1025                const EP33: u8 = 22, const EP34: u8 = 23, const EP35: u8 = 24, const EP36: u8 = 25,
1026                const EP37: u8 = 24, const EP38: u8 = 25, const EP39: u8 = 26, const EP40: u8 = 27,
1027                const EP41: u8 = 28, const EP42: u8 = 29, const EP43: u8 = 28, const EP44: u8 = 29,
1028                const EP45: u8 = 30, const EP46: u8 = 31, const EP47: u8 = 32, const EP48: u8 = 01,
1029                const TP01: u8 = 16, const TP02: u8 = 07, const TP03: u8 = 20, const TP04: u8 = 21,
1030                const TP05: u8 = 29, const TP06: u8 = 12, const TP07: u8 = 28, const TP08: u8 = 17,
1031                const TP09: u8 = 01, const TP10: u8 = 15, const TP11: u8 = 23, const TP12: u8 = 26,
1032                const TP13: u8 = 05, const TP14: u8 = 18, const TP15: u8 = 31, const TP16: u8 = 10,
1033                const TP17: u8 = 02, const TP18: u8 = 08, const TP19: u8 = 24, const TP20: u8 = 14,
1034                const TP21: u8 = 32, const TP22: u8 = 27, const TP23: u8 = 03, const TP24: u8 = 09,
1035                const TP25: u8 = 19, const TP26: u8 = 13, const TP27: u8 = 30, const TP28: u8 = 06,
1036                const TP29: u8 = 22, const TP30: u8 = 11, const TP31: u8 = 04, const TP32: u8 = 25,
1037                const S000: u8 = 0xe, const S001: u8 = 0x0, const S002: u8 = 0x4, const S003: u8 = 0xf,
1038                const S004: u8 = 0xd, const S005: u8 = 0x7, const S006: u8 = 0x1, const S007: u8 = 0x4,
1039                const S008: u8 = 0x2, const S009: u8 = 0xe, const S010: u8 = 0xf, const S011: u8 = 0x2,
1040                const S012: u8 = 0xb, const S013: u8 = 0xd, const S014: u8 = 0x8, const S015: u8 = 0x1,
1041                const S016: u8 = 0x3, const S017: u8 = 0xa, const S018: u8 = 0xa, const S019: u8 = 0x6,
1042                const S020: u8 = 0x6, const S021: u8 = 0xc, const S022: u8 = 0xc, const S023: u8 = 0xb,
1043                const S024: u8 = 0x5, const S025: u8 = 0x9, const S026: u8 = 0x9, const S027: u8 = 0x5,
1044                const S028: u8 = 0x0, const S029: u8 = 0x3, const S030: u8 = 0x7, const S031: u8 = 0x8,
1045                const S032: u8 = 0x4, const S033: u8 = 0xf, const S034: u8 = 0x1, const S035: u8 = 0xc,
1046                const S036: u8 = 0xe, const S037: u8 = 0x8, const S038: u8 = 0x8, const S039: u8 = 0x2,
1047                const S040: u8 = 0xd, const S041: u8 = 0x4, const S042: u8 = 0x6, const S043: u8 = 0x9,
1048                const S044: u8 = 0x2, const S045: u8 = 0x1, const S046: u8 = 0xb, const S047: u8 = 0x7,
1049                const S048: u8 = 0xf, const S049: u8 = 0x5, const S050: u8 = 0xc, const S051: u8 = 0xb,
1050                const S052: u8 = 0x9, const S053: u8 = 0x3, const S054: u8 = 0x7, const S055: u8 = 0xe,
1051                const S056: u8 = 0x3, const S057: u8 = 0xa, const S058: u8 = 0xa, const S059: u8 = 0x0,
1052                const S060: u8 = 0x5, const S061: u8 = 0x6, const S062: u8 = 0x0, const S063: u8 = 0xd,
1053                const S100: u8 = 0xf, const S101: u8 = 0x3, const S102: u8 = 0x1, const S103: u8 = 0xd,
1054                const S104: u8 = 0x8, const S105: u8 = 0x4, const S106: u8 = 0xe, const S107: u8 = 0x7,
1055                const S108: u8 = 0x6, const S109: u8 = 0xf, const S110: u8 = 0xb, const S111: u8 = 0x2,
1056                const S112: u8 = 0x3, const S113: u8 = 0x8, const S114: u8 = 0x4, const S115: u8 = 0xe,
1057                const S116: u8 = 0x9, const S117: u8 = 0xc, const S118: u8 = 0x7, const S119: u8 = 0x0,
1058                const S120: u8 = 0x2, const S121: u8 = 0x1, const S122: u8 = 0xd, const S123: u8 = 0xa,
1059                const S124: u8 = 0xc, const S125: u8 = 0x6, const S126: u8 = 0x0, const S127: u8 = 0x9,
1060                const S128: u8 = 0x5, const S129: u8 = 0xb, const S130: u8 = 0xa, const S131: u8 = 0x5,
1061                const S132: u8 = 0x0, const S133: u8 = 0xd, const S134: u8 = 0xe, const S135: u8 = 0x8,
1062                const S136: u8 = 0x7, const S137: u8 = 0xa, const S138: u8 = 0xb, const S139: u8 = 0x1,
1063                const S140: u8 = 0xa, const S141: u8 = 0x3, const S142: u8 = 0x4, const S143: u8 = 0xf,
1064                const S144: u8 = 0xd, const S145: u8 = 0x4, const S146: u8 = 0x1, const S147: u8 = 0x2,
1065                const S148: u8 = 0x5, const S149: u8 = 0xb, const S150: u8 = 0x8, const S151: u8 = 0x6,
1066                const S152: u8 = 0xc, const S153: u8 = 0x7, const S154: u8 = 0x6, const S155: u8 = 0xc,
1067                const S156: u8 = 0x9, const S157: u8 = 0x0, const S158: u8 = 0x3, const S159: u8 = 0x5,
1068                const S160: u8 = 0x2, const S161: u8 = 0xe, const S162: u8 = 0xf, const S163: u8 = 0x9,
1069                const S200: u8 = 0xa, const S201: u8 = 0xd, const S202: u8 = 0x0, const S203: u8 = 0x7,
1070                const S204: u8 = 0x9, const S205: u8 = 0x0, const S206: u8 = 0xe, const S207: u8 = 0x9,
1071                const S208: u8 = 0x6, const S209: u8 = 0x3, const S210: u8 = 0x3, const S211: u8 = 0x4,
1072                const S212: u8 = 0xf, const S213: u8 = 0x6, const S214: u8 = 0x5, const S215: u8 = 0xa,
1073                const S216: u8 = 0x1, const S217: u8 = 0x2, const S218: u8 = 0xd, const S219: u8 = 0x8,
1074                const S220: u8 = 0xc, const S221: u8 = 0x5, const S222: u8 = 0x7, const S223: u8 = 0xe,
1075                const S224: u8 = 0xb, const S225: u8 = 0xc, const S226: u8 = 0x4, const S227: u8 = 0xb,
1076                const S228: u8 = 0x2, const S229: u8 = 0xf, const S230: u8 = 0x8, const S231: u8 = 0x1,
1077                const S232: u8 = 0xd, const S233: u8 = 0x1, const S234: u8 = 0x6, const S235: u8 = 0xa,
1078                const S236: u8 = 0x4, const S237: u8 = 0xd, const S238: u8 = 0x9, const S239: u8 = 0x0,
1079                const S240: u8 = 0x8, const S241: u8 = 0x6, const S242: u8 = 0xf, const S243: u8 = 0x9,
1080                const S244: u8 = 0x3, const S245: u8 = 0x8, const S246: u8 = 0x0, const S247: u8 = 0x7,
1081                const S248: u8 = 0xb, const S249: u8 = 0x4, const S250: u8 = 0x1, const S251: u8 = 0xf,
1082                const S252: u8 = 0x2, const S253: u8 = 0xe, const S254: u8 = 0xc, const S255: u8 = 0x3,
1083                const S256: u8 = 0x5, const S257: u8 = 0xb, const S258: u8 = 0xa, const S259: u8 = 0x5,
1084                const S260: u8 = 0xe, const S261: u8 = 0x2, const S262: u8 = 0x7, const S263: u8 = 0xc,
1085                const S300: u8 = 0x7, const S301: u8 = 0xd, const S302: u8 = 0xd, const S303: u8 = 0x8,
1086                const S304: u8 = 0xe, const S305: u8 = 0xb, const S306: u8 = 0x3, const S307: u8 = 0x5,
1087                const S308: u8 = 0x0, const S309: u8 = 0x6, const S310: u8 = 0x6, const S311: u8 = 0xf,
1088                const S312: u8 = 0x9, const S313: u8 = 0x0, const S314: u8 = 0xa, const S315: u8 = 0x3,
1089                const S316: u8 = 0x1, const S317: u8 = 0x4, const S318: u8 = 0x2, const S319: u8 = 0x7,
1090                const S320: u8 = 0x8, const S321: u8 = 0x2, const S322: u8 = 0x5, const S323: u8 = 0xc,
1091                const S324: u8 = 0xb, const S325: u8 = 0x1, const S326: u8 = 0xc, const S327: u8 = 0xa,
1092                const S328: u8 = 0x4, const S329: u8 = 0xe, const S330: u8 = 0xf, const S331: u8 = 0x9,
1093                const S332: u8 = 0xa, const S333: u8 = 0x3, const S334: u8 = 0x6, const S335: u8 = 0xf,
1094                const S336: u8 = 0x9, const S337: u8 = 0x0, const S338: u8 = 0x0, const S339: u8 = 0x6,
1095                const S340: u8 = 0xc, const S341: u8 = 0xa, const S342: u8 = 0xb, const S343: u8 = 0x1,
1096                const S344: u8 = 0x7, const S345: u8 = 0xd, const S346: u8 = 0xd, const S347: u8 = 0x8,
1097                const S348: u8 = 0xf, const S349: u8 = 0x9, const S350: u8 = 0x1, const S351: u8 = 0x4,
1098                const S352: u8 = 0x3, const S353: u8 = 0x5, const S354: u8 = 0xe, const S355: u8 = 0xb,
1099                const S356: u8 = 0x5, const S357: u8 = 0xc, const S358: u8 = 0x2, const S359: u8 = 0x7,
1100                const S360: u8 = 0x8, const S361: u8 = 0x2, const S362: u8 = 0x4, const S363: u8 = 0xe,
1101                const S400: u8 = 0x2, const S401: u8 = 0xe, const S402: u8 = 0xc, const S403: u8 = 0xb,
1102                const S404: u8 = 0x4, const S405: u8 = 0x2, const S406: u8 = 0x1, const S407: u8 = 0xc,
1103                const S408: u8 = 0x7, const S409: u8 = 0x4, const S410: u8 = 0xa, const S411: u8 = 0x7,
1104                const S412: u8 = 0xb, const S413: u8 = 0xd, const S414: u8 = 0x6, const S415: u8 = 0x1,
1105                const S416: u8 = 0x8, const S417: u8 = 0x5, const S418: u8 = 0x5, const S419: u8 = 0x0,
1106                const S420: u8 = 0x3, const S421: u8 = 0xf, const S422: u8 = 0xf, const S423: u8 = 0xa,
1107                const S424: u8 = 0xd, const S425: u8 = 0x3, const S426: u8 = 0x0, const S427: u8 = 0x9,
1108                const S428: u8 = 0xe, const S429: u8 = 0x8, const S430: u8 = 0x9, const S431: u8 = 0x6,
1109                const S432: u8 = 0x4, const S433: u8 = 0xb, const S434: u8 = 0x2, const S435: u8 = 0x8,
1110                const S436: u8 = 0x1, const S437: u8 = 0xc, const S438: u8 = 0xb, const S439: u8 = 0x7,
1111                const S440: u8 = 0xa, const S441: u8 = 0x1, const S442: u8 = 0xd, const S443: u8 = 0xe,
1112                const S444: u8 = 0x7, const S445: u8 = 0x2, const S446: u8 = 0x8, const S447: u8 = 0xd,
1113                const S448: u8 = 0xf, const S449: u8 = 0x6, const S450: u8 = 0x9, const S451: u8 = 0xf,
1114                const S452: u8 = 0xc, const S453: u8 = 0x0, const S454: u8 = 0x5, const S455: u8 = 0x9,
1115                const S456: u8 = 0x6, const S457: u8 = 0xa, const S458: u8 = 0x3, const S459: u8 = 0x4,
1116                const S460: u8 = 0x0, const S461: u8 = 0x5, const S462: u8 = 0xe, const S463: u8 = 0x3,
1117                const S500: u8 = 0xc, const S501: u8 = 0xa, const S502: u8 = 0x1, const S503: u8 = 0xf,
1118                const S504: u8 = 0xa, const S505: u8 = 0x4, const S506: u8 = 0xf, const S507: u8 = 0x2,
1119                const S508: u8 = 0x9, const S509: u8 = 0x7, const S510: u8 = 0x2, const S511: u8 = 0xc,
1120                const S512: u8 = 0x6, const S513: u8 = 0x9, const S514: u8 = 0x8, const S515: u8 = 0x5,
1121                const S516: u8 = 0x0, const S517: u8 = 0x6, const S518: u8 = 0xd, const S519: u8 = 0x1,
1122                const S520: u8 = 0x3, const S521: u8 = 0xd, const S522: u8 = 0x4, const S523: u8 = 0xe,
1123                const S524: u8 = 0xe, const S525: u8 = 0x0, const S526: u8 = 0x7, const S527: u8 = 0xb,
1124                const S528: u8 = 0x5, const S529: u8 = 0x3, const S530: u8 = 0xb, const S531: u8 = 0x8,
1125                const S532: u8 = 0x9, const S533: u8 = 0x4, const S534: u8 = 0xe, const S535: u8 = 0x3,
1126                const S536: u8 = 0xf, const S537: u8 = 0x2, const S538: u8 = 0x5, const S539: u8 = 0xc,
1127                const S540: u8 = 0x2, const S541: u8 = 0x9, const S542: u8 = 0x8, const S543: u8 = 0x5,
1128                const S544: u8 = 0xc, const S545: u8 = 0xf, const S546: u8 = 0x3, const S547: u8 = 0xa,
1129                const S548: u8 = 0x7, const S549: u8 = 0xb, const S550: u8 = 0x0, const S551: u8 = 0xe,
1130                const S552: u8 = 0x4, const S553: u8 = 0x1, const S554: u8 = 0xa, const S555: u8 = 0x7,
1131                const S556: u8 = 0x1, const S557: u8 = 0x6, const S558: u8 = 0xd, const S559: u8 = 0x0,
1132                const S560: u8 = 0xb, const S561: u8 = 0x8, const S562: u8 = 0x6, const S563: u8 = 0xd,
1133                const S600: u8 = 0x4, const S601: u8 = 0xd, const S602: u8 = 0xb, const S603: u8 = 0x0,
1134                const S604: u8 = 0x2, const S605: u8 = 0xb, const S606: u8 = 0xe, const S607: u8 = 0x7,
1135                const S608: u8 = 0xf, const S609: u8 = 0x4, const S610: u8 = 0x0, const S611: u8 = 0x9,
1136                const S612: u8 = 0x8, const S613: u8 = 0x1, const S614: u8 = 0xd, const S615: u8 = 0xa,
1137                const S616: u8 = 0x3, const S617: u8 = 0xe, const S618: u8 = 0xc, const S619: u8 = 0x3,
1138                const S620: u8 = 0x9, const S621: u8 = 0x5, const S622: u8 = 0x7, const S623: u8 = 0xc,
1139                const S624: u8 = 0x5, const S625: u8 = 0x2, const S626: u8 = 0xa, const S627: u8 = 0xf,
1140                const S628: u8 = 0x6, const S629: u8 = 0x8, const S630: u8 = 0x1, const S631: u8 = 0x6,
1141                const S632: u8 = 0x1, const S633: u8 = 0x6, const S634: u8 = 0x4, const S635: u8 = 0xb,
1142                const S636: u8 = 0xb, const S637: u8 = 0xd, const S638: u8 = 0xd, const S639: u8 = 0x8,
1143                const S640: u8 = 0xc, const S641: u8 = 0x1, const S642: u8 = 0x3, const S643: u8 = 0x4,
1144                const S644: u8 = 0x7, const S645: u8 = 0xa, const S646: u8 = 0xe, const S647: u8 = 0x7,
1145                const S648: u8 = 0xa, const S649: u8 = 0x9, const S650: u8 = 0xf, const S651: u8 = 0x5,
1146                const S652: u8 = 0x6, const S653: u8 = 0x0, const S654: u8 = 0x8, const S655: u8 = 0xf,
1147                const S656: u8 = 0x0, const S657: u8 = 0xe, const S658: u8 = 0x5, const S659: u8 = 0x2,
1148                const S660: u8 = 0x9, const S661: u8 = 0x3, const S662: u8 = 0x2, const S663: u8 = 0xc,
1149                const S700: u8 = 0xd, const S701: u8 = 0x1, const S702: u8 = 0x2, const S703: u8 = 0xf,
1150                const S704: u8 = 0x8, const S705: u8 = 0xd, const S706: u8 = 0x4, const S707: u8 = 0x8,
1151                const S708: u8 = 0x6, const S709: u8 = 0xa, const S710: u8 = 0xf, const S711: u8 = 0x3,
1152                const S712: u8 = 0xb, const S713: u8 = 0x7, const S714: u8 = 0x1, const S715: u8 = 0x4,
1153                const S716: u8 = 0xa, const S717: u8 = 0xc, const S718: u8 = 0x9, const S719: u8 = 0x5,
1154                const S720: u8 = 0x3, const S721: u8 = 0x6, const S722: u8 = 0xe, const S723: u8 = 0xb,
1155                const S724: u8 = 0x5, const S725: u8 = 0x0, const S726: u8 = 0x0, const S727: u8 = 0xe,
1156                const S728: u8 = 0xc, const S729: u8 = 0x9, const S730: u8 = 0x7, const S731: u8 = 0x2,
1157                const S732: u8 = 0x7, const S733: u8 = 0x2, const S734: u8 = 0xb, const S735: u8 = 0x1,
1158                const S736: u8 = 0x4, const S737: u8 = 0xe, const S738: u8 = 0x1, const S739: u8 = 0x7,
1159                const S740: u8 = 0x9, const S741: u8 = 0x4, const S742: u8 = 0xc, const S743: u8 = 0xa,
1160                const S744: u8 = 0xe, const S745: u8 = 0x8, const S746: u8 = 0x2, const S747: u8 = 0xd,
1161                const S748: u8 = 0x0, const S749: u8 = 0xf, const S750: u8 = 0x6, const S751: u8 = 0xc,
1162                const S752: u8 = 0xa, const S753: u8 = 0x9, const S754: u8 = 0xd, const S755: u8 = 0x0,
1163                const S756: u8 = 0xf, const S757: u8 = 0x3, const S758: u8 = 0x3, const S759: u8 = 0x5,
1164                const S760: u8 = 0x5, const S761: u8 = 0x6, const S762: u8 = 0x8, const S763: u8 = 0xb>
1165{
1166    key: LongUnion,
1167    block: LongUnion,
1168    round_key: [u64; ROUND],
1169    enc: fn (s: &mut Self, message: u64) -> u64,
1170    dec: fn (s: &mut Self, cipher: u64) -> u64,
1171}
1172
1173impl <const ROUND: usize, const SHIFT: u128,
1174        const PC101: u8, const PC102: u8, const PC103: u8, const PC104: u8,
1175        const PC105: u8, const PC106: u8, const PC107: u8, const PC108: u8,
1176        const PC109: u8, const PC110: u8, const PC111: u8, const PC112: u8,
1177        const PC113: u8, const PC114: u8, const PC115: u8, const PC116: u8,
1178        const PC117: u8, const PC118: u8, const PC119: u8, const PC120: u8,
1179        const PC121: u8, const PC122: u8, const PC123: u8, const PC124: u8,
1180        const PC125: u8, const PC126: u8, const PC127: u8, const PC128: u8,
1181        const PC129: u8, const PC130: u8, const PC131: u8, const PC132: u8,
1182        const PC133: u8, const PC134: u8, const PC135: u8, const PC136: u8,
1183        const PC137: u8, const PC138: u8, const PC139: u8, const PC140: u8,
1184        const PC141: u8, const PC142: u8, const PC143: u8, const PC144: u8,
1185        const PC145: u8, const PC146: u8, const PC147: u8, const PC148: u8,
1186        const PC149: u8, const PC150: u8, const PC151: u8, const PC152: u8,
1187        const PC153: u8, const PC154: u8, const PC155: u8, const PC156: u8,
1188        const PC201: u8, const PC202: u8, const PC203: u8, const PC204: u8,
1189        const PC205: u8, const PC206: u8, const PC207: u8, const PC208: u8,
1190        const PC209: u8, const PC210: u8, const PC211: u8, const PC212: u8,
1191        const PC213: u8, const PC214: u8, const PC215: u8, const PC216: u8,
1192        const PC217: u8, const PC218: u8, const PC219: u8, const PC220: u8,
1193        const PC221: u8, const PC222: u8, const PC223: u8, const PC224: u8,
1194        const PC225: u8, const PC226: u8, const PC227: u8, const PC228: u8,
1195        const PC229: u8, const PC230: u8, const PC231: u8, const PC232: u8,
1196        const PC233: u8, const PC234: u8, const PC235: u8, const PC236: u8,
1197        const PC237: u8, const PC238: u8, const PC239: u8, const PC240: u8,
1198        const PC241: u8, const PC242: u8, const PC243: u8, const PC244: u8,
1199        const PC245: u8, const PC246: u8, const PC247: u8, const PC248: u8,
1200        const IP01: u8, const IP02: u8, const IP03: u8, const IP04: u8,
1201        const IP05: u8, const IP06: u8, const IP07: u8, const IP08: u8,
1202        const IP09: u8, const IP10: u8, const IP11: u8, const IP12: u8,
1203        const IP13: u8, const IP14: u8, const IP15: u8, const IP16: u8,
1204        const IP17: u8, const IP18: u8, const IP19: u8, const IP20: u8,
1205        const IP21: u8, const IP22: u8, const IP23: u8, const IP24: u8,
1206        const IP25: u8, const IP26: u8, const IP27: u8, const IP28: u8,
1207        const IP29: u8, const IP30: u8, const IP31: u8, const IP32: u8,
1208        const IP33: u8, const IP34: u8, const IP35: u8, const IP36: u8,
1209        const IP37: u8, const IP38: u8, const IP39: u8, const IP40: u8,
1210        const IP41: u8, const IP42: u8, const IP43: u8, const IP44: u8,
1211        const IP45: u8, const IP46: u8, const IP47: u8, const IP48: u8,
1212        const IP49: u8, const IP50: u8, const IP51: u8, const IP52: u8,
1213        const IP53: u8, const IP54: u8, const IP55: u8, const IP56: u8,
1214        const IP57: u8, const IP58: u8, const IP59: u8, const IP60: u8,
1215        const IP61: u8, const IP62: u8, const IP63: u8, const IP64: u8,
1216        const EP01: u8, const EP02: u8, const EP03: u8, const EP04: u8,
1217        const EP05: u8, const EP06: u8, const EP07: u8, const EP08: u8,
1218        const EP09: u8, const EP10: u8, const EP11: u8, const EP12: u8,
1219        const EP13: u8, const EP14: u8, const EP15: u8, const EP16: u8,
1220        const EP17: u8, const EP18: u8, const EP19: u8, const EP20: u8,
1221        const EP21: u8, const EP22: u8, const EP23: u8, const EP24: u8,
1222        const EP25: u8, const EP26: u8, const EP27: u8, const EP28: u8,
1223        const EP29: u8, const EP30: u8, const EP31: u8, const EP32: u8,
1224        const EP33: u8, const EP34: u8, const EP35: u8, const EP36: u8,
1225        const EP37: u8, const EP38: u8, const EP39: u8, const EP40: u8,
1226        const EP41: u8, const EP42: u8, const EP43: u8, const EP44: u8,
1227        const EP45: u8, const EP46: u8, const EP47: u8, const EP48: u8,
1228        const TP01: u8, const TP02: u8, const TP03: u8, const TP04: u8,
1229        const TP05: u8, const TP06: u8, const TP07: u8, const TP08: u8,
1230        const TP09: u8, const TP10: u8, const TP11: u8, const TP12: u8,
1231        const TP13: u8, const TP14: u8, const TP15: u8, const TP16: u8,
1232        const TP17: u8, const TP18: u8, const TP19: u8, const TP20: u8,
1233        const TP21: u8, const TP22: u8, const TP23: u8, const TP24: u8,
1234        const TP25: u8, const TP26: u8, const TP27: u8, const TP28: u8,
1235        const TP29: u8, const TP30: u8, const TP31: u8, const TP32: u8,
1236        const S000: u8, const S001: u8, const S002: u8, const S003: u8,
1237        const S004: u8, const S005: u8, const S006: u8, const S007: u8,
1238        const S008: u8, const S009: u8, const S010: u8, const S011: u8,
1239        const S012: u8, const S013: u8, const S014: u8, const S015: u8,
1240        const S016: u8, const S017: u8, const S018: u8, const S019: u8,
1241        const S020: u8, const S021: u8, const S022: u8, const S023: u8,
1242        const S024: u8, const S025: u8, const S026: u8, const S027: u8,
1243        const S028: u8, const S029: u8, const S030: u8, const S031: u8,
1244        const S032: u8, const S033: u8, const S034: u8, const S035: u8,
1245        const S036: u8, const S037: u8, const S038: u8, const S039: u8,
1246        const S040: u8, const S041: u8, const S042: u8, const S043: u8,
1247        const S044: u8, const S045: u8, const S046: u8, const S047: u8,
1248        const S048: u8, const S049: u8, const S050: u8, const S051: u8,
1249        const S052: u8, const S053: u8, const S054: u8, const S055: u8,
1250        const S056: u8, const S057: u8, const S058: u8, const S059: u8,
1251        const S060: u8, const S061: u8, const S062: u8, const S063: u8,
1252        const S100: u8, const S101: u8, const S102: u8, const S103: u8,
1253        const S104: u8, const S105: u8, const S106: u8, const S107: u8,
1254        const S108: u8, const S109: u8, const S110: u8, const S111: u8,
1255        const S112: u8, const S113: u8, const S114: u8, const S115: u8,
1256        const S116: u8, const S117: u8, const S118: u8, const S119: u8,
1257        const S120: u8, const S121: u8, const S122: u8, const S123: u8,
1258        const S124: u8, const S125: u8, const S126: u8, const S127: u8,
1259        const S128: u8, const S129: u8, const S130: u8, const S131: u8,
1260        const S132: u8, const S133: u8, const S134: u8, const S135: u8,
1261        const S136: u8, const S137: u8, const S138: u8, const S139: u8,
1262        const S140: u8, const S141: u8, const S142: u8, const S143: u8,
1263        const S144: u8, const S145: u8, const S146: u8, const S147: u8,
1264        const S148: u8, const S149: u8, const S150: u8, const S151: u8,
1265        const S152: u8, const S153: u8, const S154: u8, const S155: u8,
1266        const S156: u8, const S157: u8, const S158: u8, const S159: u8,
1267        const S160: u8, const S161: u8, const S162: u8, const S163: u8,
1268        const S200: u8, const S201: u8, const S202: u8, const S203: u8,
1269        const S204: u8, const S205: u8, const S206: u8, const S207: u8,
1270        const S208: u8, const S209: u8, const S210: u8, const S211: u8,
1271        const S212: u8, const S213: u8, const S214: u8, const S215: u8,
1272        const S216: u8, const S217: u8, const S218: u8, const S219: u8,
1273        const S220: u8, const S221: u8, const S222: u8, const S223: u8,
1274        const S224: u8, const S225: u8, const S226: u8, const S227: u8,
1275        const S228: u8, const S229: u8, const S230: u8, const S231: u8,
1276        const S232: u8, const S233: u8, const S234: u8, const S235: u8,
1277        const S236: u8, const S237: u8, const S238: u8, const S239: u8,
1278        const S240: u8, const S241: u8, const S242: u8, const S243: u8,
1279        const S244: u8, const S245: u8, const S246: u8, const S247: u8,
1280        const S248: u8, const S249: u8, const S250: u8, const S251: u8,
1281        const S252: u8, const S253: u8, const S254: u8, const S255: u8,
1282        const S256: u8, const S257: u8, const S258: u8, const S259: u8,
1283        const S260: u8, const S261: u8, const S262: u8, const S263: u8,
1284        const S300: u8, const S301: u8, const S302: u8, const S303: u8,
1285        const S304: u8, const S305: u8, const S306: u8, const S307: u8,
1286        const S308: u8, const S309: u8, const S310: u8, const S311: u8,
1287        const S312: u8, const S313: u8, const S314: u8, const S315: u8,
1288        const S316: u8, const S317: u8, const S318: u8, const S319: u8,
1289        const S320: u8, const S321: u8, const S322: u8, const S323: u8,
1290        const S324: u8, const S325: u8, const S326: u8, const S327: u8,
1291        const S328: u8, const S329: u8, const S330: u8, const S331: u8,
1292        const S332: u8, const S333: u8, const S334: u8, const S335: u8,
1293        const S336: u8, const S337: u8, const S338: u8, const S339: u8,
1294        const S340: u8, const S341: u8, const S342: u8, const S343: u8,
1295        const S344: u8, const S345: u8, const S346: u8, const S347: u8,
1296        const S348: u8, const S349: u8, const S350: u8, const S351: u8,
1297        const S352: u8, const S353: u8, const S354: u8, const S355: u8,
1298        const S356: u8, const S357: u8, const S358: u8, const S359: u8,
1299        const S360: u8, const S361: u8, const S362: u8, const S363: u8,
1300        const S400: u8, const S401: u8, const S402: u8, const S403: u8,
1301        const S404: u8, const S405: u8, const S406: u8, const S407: u8,
1302        const S408: u8, const S409: u8, const S410: u8, const S411: u8,
1303        const S412: u8, const S413: u8, const S414: u8, const S415: u8,
1304        const S416: u8, const S417: u8, const S418: u8, const S419: u8,
1305        const S420: u8, const S421: u8, const S422: u8, const S423: u8,
1306        const S424: u8, const S425: u8, const S426: u8, const S427: u8,
1307        const S428: u8, const S429: u8, const S430: u8, const S431: u8,
1308        const S432: u8, const S433: u8, const S434: u8, const S435: u8,
1309        const S436: u8, const S437: u8, const S438: u8, const S439: u8,
1310        const S440: u8, const S441: u8, const S442: u8, const S443: u8,
1311        const S444: u8, const S445: u8, const S446: u8, const S447: u8,
1312        const S448: u8, const S449: u8, const S450: u8, const S451: u8,
1313        const S452: u8, const S453: u8, const S454: u8, const S455: u8,
1314        const S456: u8, const S457: u8, const S458: u8, const S459: u8,
1315        const S460: u8, const S461: u8, const S462: u8, const S463: u8,
1316        const S500: u8, const S501: u8, const S502: u8, const S503: u8,
1317        const S504: u8, const S505: u8, const S506: u8, const S507: u8,
1318        const S508: u8, const S509: u8, const S510: u8, const S511: u8,
1319        const S512: u8, const S513: u8, const S514: u8, const S515: u8,
1320        const S516: u8, const S517: u8, const S518: u8, const S519: u8,
1321        const S520: u8, const S521: u8, const S522: u8, const S523: u8,
1322        const S524: u8, const S525: u8, const S526: u8, const S527: u8,
1323        const S528: u8, const S529: u8, const S530: u8, const S531: u8,
1324        const S532: u8, const S533: u8, const S534: u8, const S535: u8,
1325        const S536: u8, const S537: u8, const S538: u8, const S539: u8,
1326        const S540: u8, const S541: u8, const S542: u8, const S543: u8,
1327        const S544: u8, const S545: u8, const S546: u8, const S547: u8,
1328        const S548: u8, const S549: u8, const S550: u8, const S551: u8,
1329        const S552: u8, const S553: u8, const S554: u8, const S555: u8,
1330        const S556: u8, const S557: u8, const S558: u8, const S559: u8,
1331        const S560: u8, const S561: u8, const S562: u8, const S563: u8,
1332        const S600: u8, const S601: u8, const S602: u8, const S603: u8,
1333        const S604: u8, const S605: u8, const S606: u8, const S607: u8,
1334        const S608: u8, const S609: u8, const S610: u8, const S611: u8,
1335        const S612: u8, const S613: u8, const S614: u8, const S615: u8,
1336        const S616: u8, const S617: u8, const S618: u8, const S619: u8,
1337        const S620: u8, const S621: u8, const S622: u8, const S623: u8,
1338        const S624: u8, const S625: u8, const S626: u8, const S627: u8,
1339        const S628: u8, const S629: u8, const S630: u8, const S631: u8,
1340        const S632: u8, const S633: u8, const S634: u8, const S635: u8,
1341        const S636: u8, const S637: u8, const S638: u8, const S639: u8,
1342        const S640: u8, const S641: u8, const S642: u8, const S643: u8,
1343        const S644: u8, const S645: u8, const S646: u8, const S647: u8,
1344        const S648: u8, const S649: u8, const S650: u8, const S651: u8,
1345        const S652: u8, const S653: u8, const S654: u8, const S655: u8,
1346        const S656: u8, const S657: u8, const S658: u8, const S659: u8,
1347        const S660: u8, const S661: u8, const S662: u8, const S663: u8,
1348        const S700: u8, const S701: u8, const S702: u8, const S703: u8,
1349        const S704: u8, const S705: u8, const S706: u8, const S707: u8,
1350        const S708: u8, const S709: u8, const S710: u8, const S711: u8,
1351        const S712: u8, const S713: u8, const S714: u8, const S715: u8,
1352        const S716: u8, const S717: u8, const S718: u8, const S719: u8,
1353        const S720: u8, const S721: u8, const S722: u8, const S723: u8,
1354        const S724: u8, const S725: u8, const S726: u8, const S727: u8,
1355        const S728: u8, const S729: u8, const S730: u8, const S731: u8,
1356        const S732: u8, const S733: u8, const S734: u8, const S735: u8,
1357        const S736: u8, const S737: u8, const S738: u8, const S739: u8,
1358        const S740: u8, const S741: u8, const S742: u8, const S743: u8,
1359        const S744: u8, const S745: u8, const S746: u8, const S747: u8,
1360        const S748: u8, const S749: u8, const S750: u8, const S751: u8,
1361        const S752: u8, const S753: u8, const S754: u8, const S755: u8,
1362        const S756: u8, const S757: u8, const S758: u8, const S759: u8,
1363        const S760: u8, const S761: u8, const S762: u8, const S763: u8>
1364            DES_Generic<ROUND, SHIFT,
1365                        PC101, PC102, PC103, PC104, PC105, PC106, PC107, PC108,
1366                        PC109, PC110, PC111, PC112, PC113, PC114, PC115, PC116,
1367                        PC117, PC118, PC119, PC120, PC121, PC122, PC123, PC124,
1368                        PC125, PC126, PC127, PC128, PC129, PC130, PC131, PC132,
1369                        PC133, PC134, PC135, PC136, PC137, PC138, PC139, PC140,
1370                        PC141, PC142, PC143, PC144, PC145, PC146, PC147, PC148,
1371                        PC149, PC150, PC151, PC152, PC153, PC154, PC155, PC156,
1372                        PC201, PC202, PC203, PC204, PC205, PC206, PC207, PC208,
1373                        PC209, PC210, PC211, PC212, PC213, PC214, PC215, PC216,
1374                        PC217, PC218, PC219, PC220, PC221, PC222, PC223, PC224,
1375                        PC225, PC226, PC227, PC228, PC229, PC230, PC231, PC232,
1376                        PC233, PC234, PC235, PC236, PC237, PC238, PC239, PC240,
1377                        PC241, PC242, PC243, PC244, PC245, PC246, PC247, PC248,
1378                        IP01, IP02, IP03, IP04, IP05, IP06, IP07, IP08,
1379                        IP09, IP10, IP11, IP12, IP13, IP14, IP15, IP16,
1380                        IP17, IP18, IP19, IP20, IP21, IP22, IP23, IP24,
1381                        IP25, IP26, IP27, IP28, IP29, IP30, IP31, IP32,
1382                        IP33, IP34, IP35, IP36, IP37, IP38, IP39, IP40,
1383                        IP41, IP42, IP43, IP44, IP45, IP46, IP47, IP48,
1384                        IP49, IP50, IP51, IP52, IP53, IP54, IP55, IP56,
1385                        IP57, IP58, IP59, IP60, IP61, IP62, IP63, IP64,
1386                        EP01, EP02, EP03, EP04, EP05, EP06, EP07, EP08,
1387                        EP09, EP10, EP11, EP12, EP13, EP14, EP15, EP16,
1388                        EP17, EP18, EP19, EP20, EP21, EP22, EP23, EP24,
1389                        EP25, EP26, EP27, EP28, EP29, EP30, EP31, EP32,
1390                        EP33, EP34, EP35, EP36, EP37, EP38, EP39, EP40,
1391                        EP41, EP42, EP43, EP44, EP45, EP46, EP47, EP48,
1392                        TP01, TP02, TP03, TP04, TP05, TP06, TP07, TP08,
1393                        TP09, TP10, TP11, TP12, TP13, TP14, TP15, TP16,
1394                        TP17, TP18, TP19, TP20, TP21, TP22, TP23, TP24,
1395                        TP25, TP26, TP27, TP28, TP29, TP30, TP31, TP32,
1396                        S000, S001, S002, S003, S004, S005, S006, S007,
1397                        S008, S009, S010, S011, S012, S013, S014, S015,
1398                        S016, S017, S018, S019, S020, S021, S022, S023,
1399                        S024, S025, S026, S027, S028, S029, S030, S031,
1400                        S032, S033, S034, S035, S036, S037, S038, S039,
1401                        S040, S041, S042, S043, S044, S045, S046, S047,
1402                        S048, S049, S050, S051, S052, S053, S054, S055,
1403                        S056, S057, S058, S059, S060, S061, S062, S063,
1404                        S100, S101, S102, S103, S104, S105, S106, S107,
1405                        S108, S109, S110, S111, S112, S113, S114, S115,
1406                        S116, S117, S118, S119, S120, S121, S122, S123,
1407                        S124, S125, S126, S127, S128, S129, S130, S131,
1408                        S132, S133, S134, S135, S136, S137, S138, S139,
1409                        S140, S141, S142, S143, S144, S145, S146, S147,
1410                        S148, S149, S150, S151, S152, S153, S154, S155,
1411                        S156, S157, S158, S159, S160, S161, S162, S163,
1412                        S200, S201, S202, S203, S204, S205, S206, S207,
1413                        S208, S209, S210, S211, S212, S213, S214, S215,
1414                        S216, S217, S218, S219, S220, S221, S222, S223,
1415                        S224, S225, S226, S227, S228, S229, S230, S231,
1416                        S232, S233, S234, S235, S236, S237, S238, S239,
1417                        S240, S241, S242, S243, S244, S245, S246, S247,
1418                        S248, S249, S250, S251, S252, S253, S254, S255,
1419                        S256, S257, S258, S259, S260, S261, S262, S263,
1420                        S300, S301, S302, S303, S304, S305, S306, S307,
1421                        S308, S309, S310, S311, S312, S313, S314, S315,
1422                        S316, S317, S318, S319, S320, S321, S322, S323,
1423                        S324, S325, S326, S327, S328, S329, S330, S331,
1424                        S332, S333, S334, S335, S336, S337, S338, S339,
1425                        S340, S341, S342, S343, S344, S345, S346, S347,
1426                        S348, S349, S350, S351, S352, S353, S354, S355,
1427                        S356, S357, S358, S359, S360, S361, S362, S363,
1428                        S400, S401, S402, S403, S404, S405, S406, S407,
1429                        S408, S409, S410, S411, S412, S413, S414, S415,
1430                        S416, S417, S418, S419, S420, S421, S422, S423,
1431                        S424, S425, S426, S427, S428, S429, S430, S431,
1432                        S432, S433, S434, S435, S436, S437, S438, S439,
1433                        S440, S441, S442, S443, S444, S445, S446, S447,
1434                        S448, S449, S450, S451, S452, S453, S454, S455,
1435                        S456, S457, S458, S459, S460, S461, S462, S463,
1436                        S500, S501, S502, S503, S504, S505, S506, S507,
1437                        S508, S509, S510, S511, S512, S513, S514, S515,
1438                        S516, S517, S518, S519, S520, S521, S522, S523,
1439                        S524, S525, S526, S527, S528, S529, S530, S531,
1440                        S532, S533, S534, S535, S536, S537, S538, S539,
1441                        S540, S541, S542, S543, S544, S545, S546, S547,
1442                        S548, S549, S550, S551, S552, S553, S554, S555,
1443                        S556, S557, S558, S559, S560, S561, S562, S563,
1444                        S600, S601, S602, S603, S604, S605, S606, S607,
1445                        S608, S609, S610, S611, S612, S613, S614, S615,
1446                        S616, S617, S618, S619, S620, S621, S622, S623,
1447                        S624, S625, S626, S627, S628, S629, S630, S631,
1448                        S632, S633, S634, S635, S636, S637, S638, S639,
1449                        S640, S641, S642, S643, S644, S645, S646, S647,
1450                        S648, S649, S650, S651, S652, S653, S654, S655,
1451                        S656, S657, S658, S659, S660, S661, S662, S663,
1452                        S700, S701, S702, S703, S704, S705, S706, S707,
1453                        S708, S709, S710, S711, S712, S713, S714, S715,
1454                        S716, S717, S718, S719, S720, S721, S722, S723,
1455                        S724, S725, S726, S727, S728, S729, S730, S731,
1456                        S732, S733, S734, S735, S736, S737, S738, S739,
1457                        S740, S741, S742, S743, S744, S745, S746, S747,
1458                        S748, S749, S750, S751, S752, S753, S754, S755,
1459                        S756, S757, S758, S759, S760, S761, S762, S763>
1460{
1461    pub(super) const BLOCK_SIZE: usize = 8;
1462
1463    const SBOX: [[u8; 64]; 8] = [
1464              [ S000, S001, S002, S003, S004, S005, S006, S007,
1465                S008, S009, S010, S011, S012, S013, S014, S015,
1466                S016, S017, S018, S019, S020, S021, S022, S023,
1467                S024, S025, S026, S027, S028, S029, S030, S031,
1468                S032, S033, S034, S035, S036, S037, S038, S039,
1469                S040, S041, S042, S043, S044, S045, S046, S047,
1470                S048, S049, S050, S051, S052, S053, S054, S055,
1471                S056, S057, S058, S059, S060, S061, S062, S063 ],
1472              [ S100, S101, S102, S103, S104, S105, S106, S107,
1473                S108, S109, S110, S111, S112, S113, S114, S115,
1474                S116, S117, S118, S119, S120, S121, S122, S123,
1475                S124, S125, S126, S127, S128, S129, S130, S131,
1476                S132, S133, S134, S135, S136, S137, S138, S139,
1477                S140, S141, S142, S143, S144, S145, S146, S147,
1478                S148, S149, S150, S151, S152, S153, S154, S155,
1479                S156, S157, S158, S159, S160, S161, S162, S163 ],
1480              [ S200, S201, S202, S203, S204, S205, S206, S207,
1481                S208, S209, S210, S211, S212, S213, S214, S215,
1482                S216, S217, S218, S219, S220, S221, S222, S223,
1483                S224, S225, S226, S227, S228, S229, S230, S231,
1484                S232, S233, S234, S235, S236, S237, S238, S239,
1485                S240, S241, S242, S243, S244, S245, S246, S247,
1486                S248, S249, S250, S251, S252, S253, S254, S255,
1487                S256, S257, S258, S259, S260, S261, S262, S263 ],
1488              [ S300, S301, S302, S303, S304, S305, S306, S307,
1489                S308, S309, S310, S311, S312, S313, S314, S315,
1490                S316, S317, S318, S319, S320, S321, S322, S323,
1491                S324, S325, S326, S327, S328, S329, S330, S331,
1492                S332, S333, S334, S335, S336, S337, S338, S339,
1493                S340, S341, S342, S343, S344, S345, S346, S347,
1494                S348, S349, S350, S351, S352, S353, S354, S355,
1495                S356, S357, S358, S359, S360, S361, S362, S363 ],
1496              [ S400, S401, S402, S403, S404, S405, S406, S407,
1497                S408, S409, S410, S411, S412, S413, S414, S415,
1498                S416, S417, S418, S419, S420, S421, S422, S423,
1499                S424, S425, S426, S427, S428, S429, S430, S431,
1500                S432, S433, S434, S435, S436, S437, S438, S439,
1501                S440, S441, S442, S443, S444, S445, S446, S447,
1502                S448, S449, S450, S451, S452, S453, S454, S455,
1503                S456, S457, S458, S459, S460, S461, S462, S463 ],
1504              [ S500, S501, S502, S503, S504, S505, S506, S507,
1505                S508, S509, S510, S511, S512, S513, S514, S515,
1506                S516, S517, S518, S519, S520, S521, S522, S523,
1507                S524, S525, S526, S527, S528, S529, S530, S531,
1508                S532, S533, S534, S535, S536, S537, S538, S539,
1509                S540, S541, S542, S543, S544, S545, S546, S547,
1510                S548, S549, S550, S551, S552, S553, S554, S555,
1511                S556, S557, S558, S559, S560, S561, S562, S563 ],
1512              [ S600, S601, S602, S603, S604, S605, S606, S607,
1513                S608, S609, S610, S611, S612, S613, S614, S615,
1514                S616, S617, S618, S619, S620, S621, S622, S623,
1515                S624, S625, S626, S627, S628, S629, S630, S631,
1516                S632, S633, S634, S635, S636, S637, S638, S639,
1517                S640, S641, S642, S643, S644, S645, S646, S647,
1518                S648, S649, S650, S651, S652, S653, S654, S655,
1519                S656, S657, S658, S659, S660, S661, S662, S663 ],
1520              [ S700, S701, S702, S703, S704, S705, S706, S707,
1521                S708, S709, S710, S711, S712, S713, S714, S715,
1522                S716, S717, S718, S719, S720, S721, S722, S723,
1523                S724, S725, S726, S727, S728, S729, S730, S731,
1524                S732, S733, S734, S735, S736, S737, S738, S739,
1525                S740, S741, S742, S743, S744, S745, S746, S747,
1526                S748, S749, S750, S751, S752, S753, S754, S755,
1527                S756, S757, S758, S759, S760, S761, S762, S763 ]
1528    ];
1529
1530    // Initial Permutation Table changed to be 0-based in little endianness
1531    // So, LSB is 0-th bit and MSB is 63-rd bit in u64.
1532    const IP: [u8; 64] = [
1533            convert!(IP08), convert!(IP07), convert!(IP06), convert!(IP05),
1534            convert!(IP04), convert!(IP03), convert!(IP02), convert!(IP01),
1535            convert!(IP16), convert!(IP15), convert!(IP14), convert!(IP13),
1536            convert!(IP12), convert!(IP11), convert!(IP10), convert!(IP09),
1537            convert!(IP24), convert!(IP23), convert!(IP22), convert!(IP21),
1538            convert!(IP20), convert!(IP19), convert!(IP18), convert!(IP17),
1539            convert!(IP32), convert!(IP31), convert!(IP30), convert!(IP29),
1540            convert!(IP28), convert!(IP27), convert!(IP26), convert!(IP25),
1541            convert!(IP40), convert!(IP39), convert!(IP38), convert!(IP37),
1542            convert!(IP36), convert!(IP35), convert!(IP34), convert!(IP33),
1543            convert!(IP48), convert!(IP47), convert!(IP46), convert!(IP45),
1544            convert!(IP44), convert!(IP43), convert!(IP42), convert!(IP41),
1545            convert!(IP56), convert!(IP55), convert!(IP54), convert!(IP53),
1546            convert!(IP52), convert!(IP51), convert!(IP50), convert!(IP49),
1547            convert!(IP64), convert!(IP63), convert!(IP62), convert!(IP61),
1548            convert!(IP60), convert!(IP59), convert!(IP58), convert!(IP57)
1549    ];
1550
1551    // Final Permutation Table changed to be 0-based in little endianness
1552    // So, LSB is 0-th bit and MSB is 63-rd bit in u64.
1553    const FP: [u8; 64] = make_FP!();
1554
1555    // Expansion Permutation Table changed to be 0-based in little endianness
1556    // So, LSB is 0-th bit and MSB is 48-th bit in u48.
1557    const EP: [u8; 48] = [
1558        convert!(EP08), convert!(EP07), convert!(EP06), convert!(EP05),
1559        convert!(EP04), convert!(EP03), convert!(EP02), convert!(EP01),
1560        convert!(EP16), convert!(EP15), convert!(EP14), convert!(EP13),
1561        convert!(EP12), convert!(EP11), convert!(EP10), convert!(EP09),
1562        convert!(EP24), convert!(EP23), convert!(EP22), convert!(EP21),
1563        convert!(EP20), convert!(EP19), convert!(EP18), convert!(EP17),
1564        convert!(EP32), convert!(EP31), convert!(EP30), convert!(EP29),
1565        convert!(EP28), convert!(EP27), convert!(EP26), convert!(EP25),
1566        convert!(EP40), convert!(EP39), convert!(EP38), convert!(EP37),
1567        convert!(EP36), convert!(EP35), convert!(EP34), convert!(EP33),
1568        convert!(EP48), convert!(EP47), convert!(EP46), convert!(EP45),
1569        convert!(EP44), convert!(EP43), convert!(EP42), convert!(EP41)
1570    ];
1571
1572    // Initial Permutation Table changed to be 0-based in little endianness
1573    // So, LSB is 0-th bit and MSB is 63-rd bit in u64.
1574    const TP: [u8; 32] = [
1575        convert!(TP08), convert!(TP07), convert!(TP06), convert!(TP05),
1576        convert!(TP04), convert!(TP03), convert!(TP02), convert!(TP01),
1577        convert!(TP16), convert!(TP15), convert!(TP14), convert!(TP13),
1578        convert!(TP12), convert!(TP11), convert!(TP10), convert!(TP09),
1579        convert!(TP24), convert!(TP23), convert!(TP22), convert!(TP21),
1580        convert!(TP20), convert!(TP19), convert!(TP18), convert!(TP17),
1581        convert!(TP32), convert!(TP31), convert!(TP30), convert!(TP29),
1582        convert!(TP28), convert!(TP27), convert!(TP26), convert!(TP25)
1583    ];
1584
1585    const PC1: [u8; 56] = [
1586        convert!(PC108), convert!(PC107), convert!(PC106), convert!(PC105),
1587        convert!(PC104), convert!(PC103), convert!(PC102), convert!(PC101),
1588        convert!(PC116), convert!(PC115), convert!(PC114), convert!(PC113),
1589        convert!(PC112), convert!(PC111), convert!(PC110), convert!(PC109),
1590        convert!(PC124), convert!(PC123), convert!(PC122), convert!(PC121),
1591        convert!(PC120), convert!(PC119), convert!(PC118), convert!(PC117),
1592        convert!(PC132), convert!(PC131), convert!(PC130), convert!(PC129),
1593        convert!(PC128), convert!(PC127), convert!(PC126), convert!(PC125),
1594        convert!(PC140), convert!(PC139), convert!(PC138), convert!(PC137),
1595        convert!(PC136), convert!(PC135), convert!(PC134), convert!(PC133),
1596        convert!(PC148), convert!(PC147), convert!(PC146), convert!(PC145),
1597        convert!(PC144), convert!(PC143), convert!(PC142), convert!(PC141),
1598        convert!(PC156), convert!(PC155), convert!(PC154), convert!(PC153),
1599        convert!(PC152), convert!(PC151), convert!(PC150), convert!(PC149)
1600    ];
1601
1602    const PC2: [u8; 48] = [
1603        convert!(PC208), convert!(PC207), convert!(PC206), convert!(PC205),
1604        convert!(PC204), convert!(PC203), convert!(PC202), convert!(PC201),
1605        convert!(PC216), convert!(PC215), convert!(PC214), convert!(PC213),
1606        convert!(PC212), convert!(PC211), convert!(PC210), convert!(PC209),
1607        convert!(PC224), convert!(PC223), convert!(PC222), convert!(PC221),
1608        convert!(PC220), convert!(PC219), convert!(PC218), convert!(PC217),
1609        convert!(PC232), convert!(PC231), convert!(PC230), convert!(PC229),
1610        convert!(PC228), convert!(PC227), convert!(PC226), convert!(PC225),
1611        convert!(PC240), convert!(PC239), convert!(PC238), convert!(PC237),
1612        convert!(PC236), convert!(PC235), convert!(PC234), convert!(PC233),
1613        convert!(PC248), convert!(PC247), convert!(PC246), convert!(PC245),
1614        convert!(PC244), convert!(PC243), convert!(PC242), convert!(PC241)
1615    ];
1616
1617    const SUCCESS: u64 = !0;
1618    const FAILURE: u64 = 0;
1619    const MASK: u64 = 0xFEFEFEFEFEFEFEFE;
1620
1621    // pub fn new() -> Self
1622    /// Constructs a new object DES_Generic.
1623    ///
1624    /// # Features
1625    /// - In order to encrypt data, object should be instantiated mutable.
1626    /// - This method sets the key to be [0_u8, 0, 0, 0, 0, 0, 0, 0].
1627    /// - Do not use this default key [0_u8, 0, 0, 0, 0, 0, 0, 0]
1628    ///   because it is known as one of the weak keys.
1629    ///
1630    /// # Example 1
1631    /// ```
1632    /// use cryptocol::symmetric::DES;
1633    ///
1634    /// let mut des = DES::new();   // The default key is 0x0000000000000000 which is a weak key.
1635    /// let plaintext = 0x1234567890ABCDEF_u64;
1636    /// let ciphertext = des.encrypt_u64(plaintext);
1637    ///
1638    /// println!("Plaintext:\t\t{:#018X}", plaintext);
1639    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
1640    /// assert_eq!(ciphertext, 0x1E32B46B44C69201_u64);
1641    ///
1642    /// let cipher_cipher_text = des.encrypt_u64(ciphertext);
1643    /// println!("Cipher-ciphertext:\t{:#018X}", cipher_cipher_text);
1644    /// assert_eq!(cipher_cipher_text, 0x1234567890ABCDEF_u64);
1645    /// assert_eq!(cipher_cipher_text, plaintext);  // So, you can't use the default key!!!
1646    /// ```
1647    ///
1648    /// # For more examples,
1649    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.new)
1650    #[inline]
1651    pub fn new() -> Self
1652    {
1653        Self::new_with_key([0_u8; 8])
1654    }
1655
1656    // pub fn new_with_key(key: [u8; 8]) -> Self
1657    /// Constructs a new object DES_Generic.
1658    ///
1659    /// # Arguments
1660    /// - The argument `key` is the array of u8 that has 8 elements.
1661    /// - Remember that inverted parity bits do not affect the 56-bit real key.
1662    ///   So, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
1663    ///   [0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01],
1664    ///   [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01],
1665    ///   [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00],
1666    ///   [0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01], etc.
1667    ///   are all the same keys. Each key has 255 different equivalent keys
1668    ///   in DES.
1669    ///
1670    /// # Features
1671    /// This method sets the key to be the given argument `key`.
1672    ///
1673    /// # Example 1 for normal case
1674    /// ```
1675    /// use cryptocol::symmetric::DES;
1676    /// let mut des = DES::new_with_key([0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1677    /// let plaintext = 0x1234567890ABCDEF_u64;
1678    /// let ciphertext = des.encrypt_u64(plaintext);
1679    ///
1680    /// println!("Plaintext:\t\t{:#018X}", plaintext);
1681    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
1682    /// assert_eq!(ciphertext, 0x3B6041D76AF28F23_u64);
1683    ///
1684    /// let cipher_cipher_text = des.encrypt_u64(ciphertext);
1685    /// println!("Cipher-ciphertext:\t{:#018X}\n", cipher_cipher_text);
1686    /// assert_eq!(cipher_cipher_text, 0x7C5AAE491DC1310D_u64);
1687    /// assert_ne!(cipher_cipher_text, plaintext);
1688    /// ```
1689    ///
1690    /// # For more examples,
1691    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.new_with_key)
1692    pub fn new_with_key(key: [u8; 8]) -> Self
1693    {
1694        let mut des = Self
1695        {
1696            key:        LongUnion::new_with_ubytes(key),
1697            block:      LongUnion::new(),
1698            round_key:  [0_u64; ROUND],
1699            enc:        Self::encrypt_u64,
1700            dec:        Self::decrypt_u64,
1701        };
1702        des.make_round_keys();
1703        des
1704    }
1705
1706    // pub fn new_with_key_u64(key: u64) -> Self
1707    /// Constructs a new object DES_Generic.
1708    ///
1709    /// # Arguments
1710    /// - The argument `key` is of `u64`.
1711    /// - It should be in the same endianness of machine. For example,
1712    ///   if the intended key is [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD,
1713    ///   0xEF], the key in `u64` for this argument is 0x_1234567890ABCDEF_u64
1714    ///   for big-endian machine, and the key in `u64` for this argument is
1715    ///   0x_EFCDAB9078563412_u64 for little-endian machine.
1716    /// - Remember that inverted parity bits do not affect the 56-bit real key.
1717    ///   So, 0x_0000_0000_0000_0000_u4, 0x_0101_0101_0101_0101_u64,
1718    ///   0x_0000_0000_0000_0001_u64, 0x_0000_0000_0000_0100_u64,
1719    ///   0x_0100_0010_0000_0001_u64, etc. are all the same keys.
1720    ///   Each key has 255 different equivalent keys in DES.
1721    ///
1722    /// # Features
1723    /// This method sets the key to be the given argument `key`.
1724    ///
1725    /// # Example 1 for normal case
1726    /// ```
1727    /// use cryptocol::symmetric::DES;
1728    ///
1729    /// let mut des = DES::new_with_key_u64(0xEFCDAB9078563412);
1730    /// let plaintext = 0x1234567890ABCDEF_u64;
1731    /// let ciphertext = des.encrypt_u64(plaintext);
1732    ///
1733    /// println!("Plaintext:\t\t{:#018X}", plaintext);
1734    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
1735    /// assert_eq!(ciphertext, 0x3B6041D76AF28F23_u64);
1736    ///
1737    /// let cipher_cipher_text = des.encrypt_u64(ciphertext);
1738    /// println!("Cipher-ciphertext:\t{:#018X}\n", cipher_cipher_text);
1739    /// assert_eq!(cipher_cipher_text, 0x7C5AAE491DC1310D_u64);
1740    /// assert_ne!(cipher_cipher_text, plaintext);
1741    /// ```
1742    ///
1743    /// # For more examples,
1744    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.new_with_key_u64)
1745    pub fn new_with_key_u64(key: u64) -> Self
1746    {
1747        let mut des = Self
1748        {
1749            key:        LongUnion::new_with(key),
1750            block:      LongUnion::new(),
1751            round_key:  [0_u64; ROUND],
1752            enc:        Self::encrypt_u64,
1753            dec:        Self::decrypt_u64,
1754        };
1755        des.make_round_keys();
1756        des
1757    }
1758
1759    // pub fn encryptor_with_key(key: [u8; 8]) -> Self
1760    /// Constructs a new object DES_Generic as a positive encryptor (or
1761    /// an encryptor) for the component of BigCryptor64 incluing NDES.
1762    ///
1763    /// # Arguments
1764    /// - The argument `key` is the array of u8 that has 8 elements.
1765    /// - Remember that inverted parity bits do not affect the 56-bit real key.
1766    ///   So, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
1767    ///   [0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01],
1768    ///   [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01],
1769    ///   [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00],
1770    ///   [0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01], etc.
1771    ///   are all the same keys. Each key has 255 different equivalent keys
1772    ///   in DES.
1773    ///
1774    /// # Features
1775    /// - You won't use this method unless you use NDES for such as Triple DES.
1776    /// - This method sets the key to be the given argument `key`.
1777    /// - This method constructs the encryptor component of NDES.
1778    ///
1779    /// # Example 1
1780    /// ```
1781    /// use cryptocol::symmetric::{ DES, BigCryptor64, SmallCryptor };
1782    /// 
1783    /// let keys: [Box<dyn SmallCryptor<u64, 8>>; 3]
1784    ///         = [ Box::new(DES::encryptor_with_key([0xEF_u8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12])),
1785    ///             Box::new(DES::decryptor_with_key([0x21_u8, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE])),
1786    ///             Box::new(DES::encryptor_with_key([0xEF_u8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12])) ];
1787    /// let mut tdes = BigCryptor64::new_with_small_cryptor_array(keys);
1788    /// let plaintext = 0x_1234567890ABCDEF_u64;
1789    /// let ciphertext = tdes.encrypt_u64(plaintext);
1790    /// 
1791    /// println!("Plaintext:\t\t{:#018X}", plaintext);
1792    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
1793    /// assert_eq!(ciphertext, 0x272A2AC7B4E66748_u64);
1794    /// 
1795    /// let cipher_cipher_text = tdes.decrypt_u64(ciphertext);
1796    /// println!("Cipher-ciphertext:\t{:#018X}", cipher_cipher_text);
1797    /// assert_eq!(cipher_cipher_text, 0x1234567890ABCDEF_u64);
1798    /// assert_eq!(cipher_cipher_text, plaintext);
1799    /// ```
1800    ///
1801    /// # For more examples,
1802    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.encryptor_with_key)
1803    #[inline]
1804    pub fn encryptor_with_key(key: [u8; 8]) -> Self
1805    {
1806        Self::new_with_key(key)
1807    }
1808
1809    // pub fn encryptor_with_key_u64(key: u64) -> Self
1810    /// Constructs a new object DES_Generic as a positive encryptor (or
1811    /// an encryptor) for the component of BigCryptor64 incluing NDES.
1812    ///
1813    /// # Arguments
1814    /// - The argument `key` is an unsigned integer that is of `u64`-type.
1815    /// - Remember that inverted parity bits do not affect the 56-bit real key.
1816    ///   So, 0x0000000000000000_u64, 0x0101010101010101_u64,
1817    ///   0x0000000000000001_u64, 0x0000000000000100_u64, 0x0100001000000001,
1818    ///   etc. are all the same keys. Each key has 255 different equivalent keys
1819    ///   in DES.
1820    ///
1821    /// # Features
1822    /// - You won't use this method unless you use NDES for such as Triple DES.
1823    /// - This method sets the key to be the given argument `key`.
1824    /// - This method constructs the encryptor component of NDES.
1825    ///
1826    /// # Example 1
1827    /// ```
1828    /// use cryptocol::symmetric::{ BigCryptor64, DES };
1829    /// 
1830    /// let mut tdes = BigCryptor64::new_with_small_cryptor_array(
1831    ///             [Box::new(DES::encryptor_with_key_u64(0x_1234567890ABCDEF_u64)),
1832    ///             Box::new(DES::decryptor_with_key_u64(0x_FEDCBA0987654321_u64)),
1833    ///             Box::new(DES::encryptor_with_key_u64(0x_1234567890ABCDEF_u64))]
1834    /// );
1835    /// let plaintext = 0x_1234567890ABCDEF_u64;
1836    /// let ciphertext = tdes.encrypt_u64(plaintext);
1837    /// 
1838    /// println!("Plaintext:\t\t{:#018X}", plaintext);
1839    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
1840    /// assert_eq!(ciphertext, 0x_272A2AC7B4E66748_u64);
1841    /// 
1842    /// let cipher_cipher_text = tdes.decrypt_u64(ciphertext);
1843    /// println!("Cipher-ciphertext:\t{:#018X}", cipher_cipher_text);
1844    /// assert_eq!(cipher_cipher_text, 0x1234567890ABCDEF_u64);
1845    /// assert_eq!(cipher_cipher_text, plaintext);
1846    /// ```
1847    ///
1848    /// # For more examples,
1849    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.encryptor_with_key_u64)
1850    #[inline]
1851    pub fn encryptor_with_key_u64(key: u64) -> Self
1852    {
1853        Self::new_with_key_u64(key)
1854    }
1855
1856    // pub fn decryptor_with_key(key: [u8; 8]) -> Self
1857    /// Constructs a new object DES_Generic as a negative encryptor (or
1858    /// a decryptor) for the component of BigCryptor64 incluing NDES.
1859    ///
1860    /// # Arguments
1861    /// - The argument `key` is the array of u8 that has 8 elements.
1862    /// - Remember that inverted parity bits do not affect the 56-bit real key.
1863    ///   So, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
1864    ///   [0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01],
1865    ///   [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01],
1866    ///   [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00],
1867    ///   [0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01], etc.
1868    ///   are all the same keys. Each key has 255 different equivalent keys
1869    ///   in DES.
1870    ///
1871    /// # Features
1872    /// - You won't use this method unless you use NDES for such as Triple DES.
1873    /// - This method sets the key to be the given argument `key`.
1874    /// - This method constructs the decryptor component of NDES.
1875    ///
1876    /// # Example 1
1877    /// ```
1878    /// use cryptocol::symmetric::{ DES, BigCryptor64, SmallCryptor };
1879    /// 
1880    /// let keys: [Box<dyn SmallCryptor<u64, 8>>; 3]
1881    ///         = [ Box::new(DES::encryptor_with_key([0xEF_u8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12])),
1882    ///             Box::new(DES::decryptor_with_key([0x21_u8, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE])),
1883    ///             Box::new(DES::encryptor_with_key([0xEF_u8, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12])) ];
1884    /// let mut tdes = BigCryptor64::new_with_small_cryptor_array(keys);
1885    /// let plaintext = 0x_1234567890ABCDEF_u64;
1886    /// let ciphertext = tdes.encrypt_u64(plaintext);
1887    /// 
1888    /// println!("Plaintext:\t\t{:#018X}", plaintext);
1889    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
1890    /// assert_eq!(ciphertext, 0x272A2AC7B4E66748_u64);
1891    /// 
1892    /// let cipher_cipher_text = tdes.decrypt_u64(ciphertext);
1893    /// println!("Cipher-ciphertext:\t{:#018X}", cipher_cipher_text);
1894    /// assert_eq!(cipher_cipher_text, 0x1234567890ABCDEF_u64);
1895    /// assert_eq!(cipher_cipher_text, plaintext);
1896    /// ```
1897    ///
1898    /// # For more examples,
1899    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.decryptor_with_key)
1900    pub fn decryptor_with_key(key: [u8; 8]) -> Self
1901    {
1902        let mut des = Self
1903        {
1904            key:        LongUnion::new_with_ubytes(key),
1905            block:      LongUnion::new(),
1906            round_key:  [0_u64; ROUND],
1907            enc:        Self::decrypt_u64,
1908            dec:        Self::encrypt_u64,
1909        };
1910        des.make_round_keys();
1911        des
1912    }
1913
1914    // pub fn decryptor_with_key_u64(key: u64) -> Self
1915    /// Constructs a new object DES_Generic as a negative encryptor (or
1916    /// a decryptor) for the component of BigCryptor64 incluing NDES.
1917    ///
1918    /// # Arguments
1919    /// - The argument `key` is an unsigned integer that is of `u64`-type.
1920    /// - Remember that inverted parity bits do not affect the 56-bit real key.
1921    ///   So, 0x0000000000000000_u64, 0x0101010101010101_u64,
1922    ///   0x0000000000000001_u64, 0x0000000000000100_u64, 0x0100001000000001,
1923    ///   etc. are all the same keys. Each key has 255 different equivalent keys
1924    ///   in DES.
1925    ///
1926    /// # Features
1927    /// - You won't use this method unless you use NDES for such as Triple DES.
1928    /// - This method sets the key to be the given argument `key`.
1929    /// - This method constructs the decryptor component of NDES.
1930    ///
1931    /// # Example 1
1932    /// ```
1933    /// use cryptocol::symmetric::{ BigCryptor64, DES };
1934    /// 
1935    /// let mut tdes = BigCryptor64::new_with_small_cryptor_array(
1936    ///                 [ Box::new(DES::encryptor_with_key_u64(0x_1234567890ABCDEF_u64)),
1937    ///                                 Box::new(DES::decryptor_with_key_u64(0x_FEDCBA0987654321_u64)),
1938    ///                                 Box::new(DES::encryptor_with_key_u64(0x_1234567890ABCDEF_u64)) ] );
1939    /// let plaintext = 0x_1234567890ABCDEF_u64;
1940    /// let ciphertext = tdes.encrypt_u64(plaintext);
1941    /// 
1942    /// println!("Plaintext:\t\t{:#018X}", plaintext);
1943    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
1944    /// assert_eq!(ciphertext, 0x272A2AC7B4E66748_u64);
1945    /// 
1946    /// let cipher_cipher_text = tdes.decrypt_u64(ciphertext);
1947    /// println!("Cipher-ciphertext:\t{:#018X}", cipher_cipher_text);
1948    /// assert_eq!(cipher_cipher_text, 0x1234567890ABCDEF_u64);
1949    /// assert_eq!(cipher_cipher_text, plaintext);
1950    /// ```
1951    ///
1952    /// # For more examples,
1953    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.decryptor_with_key_u64)
1954    pub fn decryptor_with_key_u64(key: u64) -> Self
1955    {
1956        let mut des = Self
1957        {
1958            key:        LongUnion::new_with(key),
1959            block:      LongUnion::new(),
1960            round_key:  [0_u64; ROUND],
1961            enc:        Self::decrypt_u64,
1962            dec:        Self::encrypt_u64,
1963        };
1964        des.make_round_keys();
1965        des
1966    }
1967
1968    // pub fn get_key(&mut self) -> [u8; 8]
1969    /// Gets the key.
1970    ///
1971    /// # Output
1972    /// This method returns the key in the form of array of `u8`.
1973    ///
1974    /// # Example
1975    /// ```
1976    /// use cryptocol::symmetric::DES;
1977    ///
1978    /// let mut des = DES::new();
1979    /// des.set_key([0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1980    /// let key = des.get_key();
1981    /// print!("K = ");
1982    /// for k in key
1983    ///     { print!("{:X02#} ", k); }
1984    /// assert_eq!(key, [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
1985    /// ```
1986    pub fn get_key(&mut self) -> [u8; 8]
1987    {
1988        let mut key = [0u8; 8];
1989        for i in 0..8
1990            { key[i] = self.key.get_ubyte_(i); }
1991        key
1992    }
1993
1994    // pub fn get_key_u64(&self) -> u64
1995    /// Gets the key.
1996    ///
1997    /// # Output
1998    /// This method returns the key in the form of `u64`.
1999    ///
2000    /// # Example
2001    /// ```
2002    /// use cryptocol::symmetric::DES;
2003    ///
2004    /// let mut des = DES::new();
2005    /// des.set_key_u64(0xEFCDAB9078563412);
2006    /// let key = des.get_key_u64();
2007    /// println!("Key = {}", key);
2008    /// assert_eq!(key, 0xEFCDAB9078563412_u64);
2009    /// ```
2010    #[inline]
2011    pub fn get_key_u64(&self) -> u64
2012    {
2013        self.key.get_ulong()
2014    }
2015
2016    // pub fn set_key(&mut self, key: [u8; 8])
2017    /// Sets the key.
2018    ///
2019    /// # Arguments
2020    /// - The argument `key` is the array of `u8` that has 8 elements.
2021    /// - Remember that inverted parity bits do not affect the 56-bit real key.
2022    ///   So, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2023    ///   [0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01],
2024    ///   [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01],
2025    ///   [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00],
2026    ///   [0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01], etc.
2027    ///   are all the same keys. Each key has 255 different equivalent keys
2028    ///   in DES.
2029    ///
2030    /// # Features
2031    /// This method sets the key to be the given argument `key`.
2032    ///
2033    /// # Example 1 for normal case
2034    /// ```
2035    /// use cryptocol::symmetric::DES;
2036    ///
2037    /// let mut des = DES::new();
2038    /// des.set_key([0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]);
2039    /// let plaintext = 0x1234567890ABCDEF_u64;
2040    /// let ciphertext = des.encrypt_u64(plaintext);
2041    ///
2042    /// println!("Plaintext:\t\t{:#018X}", plaintext);
2043    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
2044    /// assert_eq!(ciphertext, 0x3B6041D76AF28F23_u64);
2045    ///
2046    /// let cipher_cipher_text = des.encrypt_u64(ciphertext);
2047    /// println!("Cipher-ciphertext:\t{:#018X}\n", cipher_cipher_text);
2048    /// assert_eq!(cipher_cipher_text, 0x7C5AAE491DC1310D_u64);
2049    /// assert_ne!(cipher_cipher_text, plaintext);
2050    /// ```
2051    ///
2052    /// # For more examples,
2053    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.set_key)
2054    pub fn set_key(&mut self, key: [u8; 8])
2055    {
2056        let mut i = 0_usize;
2057        for val in key
2058        {
2059            self.key.set_ubyte_(i, val);
2060            i += 1;
2061        }
2062        self.make_round_keys();
2063    }
2064
2065    // pub fn set_key_u64(&mut self, key: u64)
2066    /// Sets the key.
2067    ///
2068    /// # Arguments
2069    /// - The argument `key` is of `u64`.
2070    /// - It should be in the same endianness of machine. For example,
2071    ///   if a key is [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF],
2072    ///   the key in `u64` is 0x_1234567890ABCDEF_u64 for big-endian machine,
2073    ///   and the key in `u64` is 0x_EFCDAB9078563412_u64 for little-endian
2074    ///   machine.
2075    /// - Remember that inverted parity bits do not affect the 56-bit real key.
2076    ///   So, 0x_0000_0000_0000_0000_u4, 0x_0101_0101_0101_0101_u64,
2077    ///   0x_0000_0000_0000_0001_u64, 0x_0000_0000_0000_0100_u64,
2078    ///   0x_0100_0010_0000_0001_u64, etc. are all the same keys.
2079    ///   Each key has 255 different equivalent keys in DES.
2080    ///
2081    /// # Features
2082    /// This method sets the key to be the given argument `key`.
2083    ///
2084    /// # Example 1 for normal case
2085    /// ```
2086    /// use cryptocol::symmetric::DES;
2087    ///
2088    /// let mut des = DES::new();
2089    /// des.set_key_u64(0xEFCDAB9078563412);
2090    /// let plaintext = 0x1234567890ABCDEF_u64;
2091    /// let ciphertext = des.encrypt_u64(plaintext);
2092    ///
2093    /// println!("Plaintext:\t\t{:#018X}", plaintext);
2094    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
2095    /// assert_eq!(ciphertext, 0x3B6041D76AF28F23_u64);
2096    ///
2097    /// let cipher_cipher_text = des.encrypt_u64(ciphertext);
2098    /// println!("Cipher-ciphertext:\t{:#018X}\n", cipher_cipher_text);
2099    /// assert_eq!(cipher_cipher_text, 0x7C5AAE491DC1310D_u64);
2100    /// assert_ne!(cipher_cipher_text, plaintext);
2101    /// ```
2102    ///
2103    /// # For more examples,
2104    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.set_key_u64)
2105    pub fn set_key_u64(&mut self, key: u64)
2106    {
2107        self.key.set(key);
2108        self.make_round_keys();
2109    }
2110
2111    pub(crate) fn move_to_next_key(&mut self)
2112    {
2113        let mut key = self.get_key();
2114        let mut carry = 2;
2115        let mut old: u8;
2116        for i in 0..8
2117        {
2118            old = key[i];
2119            key[i] = key[i].wrapping_add(carry);
2120            carry = if key[i] < old {2} else {0};
2121        }
2122        self.set_key(key);
2123        self.avoid_undesirable_key();
2124    }
2125
2126    pub(crate) fn avoid_undesirable_key(&mut self)
2127    {
2128        while self.has_weak_key()
2129            { self.move_to_next_key(); }
2130    }
2131
2132    // pub fn turn_inverse(&mut self)
2133    /// Flips its role in BigCryptor64.
2134    ///
2135    /// # Features
2136    /// - You won't use this method unless you use BigCryptor64 or NDES
2137    ///   for such as Triple DES.
2138    /// - Even if you are writing codes in the context of using BigCryptor64
2139    ///   or NDES, you will hardly use this method because it is high chance
2140    ///   that you will have constructed components with the methods,
2141    ///   [encryptor_with_key](struct@DES_Generic#method.encryptor_with_key),
2142    ///   [encryptor_with_key_u64](struct@DES_Generic#method.encryptor_with_key_u64),
2143    ///   [decryptor_with_key](struct@DES_Generic#method.decryptor_with_key), and
2144    ///   [decryptor_with_key_u64](struct@DES_Generic#method.decryptor_with_key_u64).
2145    /// - If it is constructed as encryptor for BigCryptor64 or NDES,
2146    ///   it will be changed into decryptor.
2147    /// - If it is constructed as decryptor for BigCryptor64 or NDES,
2148    ///   it will be changed into encryptor.
2149    ///
2150    /// # Example 1
2151    /// ```
2152    /// use cryptocol::symmetric::{ BigCryptor64, DES, SmallCryptor };
2153    /// 
2154    /// let mut keys: [Box<dyn SmallCryptor<u64, 8>>; 3]
2155    ///             = [ Box::new(DES::new_with_key_u64(0x_1234567890ABCDEF_u64)),
2156    ///                 Box::new(DES::new_with_key_u64(0x_FEDCBA0987654321_u64)),
2157    ///                 Box::new(DES::new_with_key_u64(0x_1234567890ABCDEF_u64)) ];
2158    /// keys[1].turn_inverse();
2159    /// 
2160    /// let mut tdes = BigCryptor64::new_with_small_cryptor_array(keys);
2161    /// let plaintext = 0x_1234567890ABCDEF_u64;
2162    /// let ciphertext = tdes.encrypt_u64(plaintext);
2163    /// 
2164    /// println!("Plaintext:\t\t{:#018X}", plaintext);
2165    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
2166    /// assert_eq!(ciphertext, 0x_272A2AC7B4E66748_u64);
2167    /// 
2168    /// let cipher_cipher_text = tdes.decrypt_u64(ciphertext);
2169    /// println!("Cipher-ciphertext:\t{:#018X}", cipher_cipher_text);
2170    /// assert_eq!(cipher_cipher_text, 0x1234567890ABCDEF_u64);
2171    /// assert_eq!(cipher_cipher_text, plaintext);
2172    /// ```
2173    ///
2174    /// # For more examples,
2175    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.turn_inverse)
2176    #[inline]
2177    pub fn turn_inverse(&mut self)
2178    {
2179        (self.enc, self.dec) = (self.dec, self.enc);
2180    }
2181
2182    // pub fn turn_encryptor(&mut self)
2183    /// Changes its role in BigCryptor64 or NDES to encryptor.
2184    ///
2185    /// # Features
2186    /// - You won't use this method unless you use BigCryptor64 or NDES
2187    ///   for such as Triple DES.
2188    /// - Even if you are writing codes in the context of using BigCryptor64
2189    ///   or NDES, you will hardly use this method because it is high chance
2190    ///   that you will have constructed components with the methods,
2191    ///   [encryptor_with_key](struct@DES_Generic#method.encryptor_with_key),
2192    ///   [encryptor_with_key_u64](struct@DES_Generic#method.encryptor_with_key_u64),
2193    ///   [decryptor_with_key](struct@DES_Generic#method.decryptor_with_key), and
2194    ///   [decryptor_with_key_u64](struct@DES_Generic#method.decryptor_with_key_u64).
2195    /// - If it is constructed as encryptor for BigCryptor64 or NDES,
2196    ///   it will not be changed at all.
2197    /// - If it is constructed as decryptor for BigCryptor64 or NDES,
2198    ///   it will be changed into encryptor.
2199    ///
2200    /// # Example 1
2201    /// ```
2202    /// use cryptocol::symmetric::{ BigCryptor64, DES, SmallCryptor };
2203    /// 
2204    /// let mut keys: [Box<dyn SmallCryptor<u64, 8>>; 3]
2205    ///         = [ Box::new(DES::new_with_key_u64(0x_1234567890ABCDEF_u64)),
2206    ///             Box::new(DES::new_with_key_u64(0x_FEDCBA0987654321_u64)),
2207    ///             Box::new(DES::new_with_key_u64(0x_1234567890ABCDEF_u64)) ];
2208    /// keys[0].turn_encryptor();
2209    /// 
2210    /// let mut tdes = BigCryptor64::new_with_small_cryptor_array(keys);
2211    /// let plaintext = 0x_1234567890ABCDEF_u64;
2212    /// let ciphertext = tdes.encrypt_u64(plaintext);
2213    /// 
2214    /// println!("Plaintext:\t\t{:#018X}", plaintext);
2215    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
2216    /// assert_eq!(ciphertext, 0x_CDAC175F3B7EAA2B_u64);
2217    /// 
2218    /// let cipher_cipher_text = tdes.decrypt_u64(ciphertext);
2219    /// println!("Cipher-ciphertext:\t{:#018X}", cipher_cipher_text);
2220    /// assert_eq!(cipher_cipher_text, 0x1234567890ABCDEF_u64);
2221    /// assert_eq!(cipher_cipher_text, plaintext);
2222    /// ```
2223    ///
2224    /// # For more examples,
2225    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.turn_encryptor)
2226    pub fn turn_encryptor(&mut self)
2227    {
2228        self.enc = Self::encrypt_u64;
2229        self.dec = Self::decrypt_u64;
2230    }
2231
2232    // pub fn turn_decryptor(&mut self)
2233    /// Changes its role in BigCryptor64 or NDES to decryptor.
2234    ///
2235    /// # Features
2236    /// - You won't use this method unless you use BigCryptor64 or NDES
2237    ///   for such as Triple DES.
2238    /// - Even if you are writing codes in the context of using BigCryptor64
2239    ///   or NDES, you will hardly use this method because it is high chance
2240    ///   that you will have constructed components with the methods,
2241    ///   [encryptor_with_key](struct@DES_Generic#method.encryptor_with_key),
2242    ///   [encryptor_with_key_u64](struct@DES_Generic#method.encryptor_with_key_u64),
2243    ///   [decryptor_with_key](struct@DES_Generic#method.decryptor_with_key), and
2244    ///   [decryptor_with_key_u64](struct@DES_Generic#method.decryptor_with_key_u64).
2245    /// - If it is constructed as encryptor for BigCryptor64 or NDES,
2246    ///   it will be changed into decryptor.
2247    /// - If it is constructed as decryptor for BigCryptor64 or NDES,
2248    ///   it will not be changed at all.
2249    ///
2250    /// # Example 1
2251    /// ```
2252    /// use cryptocol::symmetric::{ BigCryptor64, DES, SmallCryptor };
2253    /// 
2254    /// let mut keys: [Box<dyn SmallCryptor<u64, 8>>; 3]
2255    ///             = [ Box::new(DES::new_with_key_u64(0x_1234567890ABCDEF_u64)),
2256    ///                 Box::new(DES::new_with_key_u64(0x_FEDCBA0987654321_u64)),
2257    ///                 Box::new(DES::new_with_key_u64(0x_1234567890ABCDEF_u64)) ];
2258    /// keys[1].turn_decryptor();
2259    /// 
2260    /// let mut tdes = BigCryptor64::new_with_small_cryptor_array(keys);
2261    /// let plaintext = 0x_1234567890ABCDEF_u64;
2262    /// let ciphertext = tdes.encrypt_u64(plaintext);
2263    /// 
2264    /// println!("Plaintext:\t\t{:#018X}", plaintext);
2265    /// println!("Ciphertext:\t\t{:#018X}", ciphertext);
2266    /// assert_eq!(ciphertext, 0x_272A2AC7B4E66748_u64);
2267    /// 
2268    /// let cipher_cipher_text = tdes.decrypt_u64(ciphertext);
2269    /// println!("Cipher-ciphertext:\t{:#018X}", cipher_cipher_text);
2270    /// assert_eq!(cipher_cipher_text, 0x1234567890ABCDEF_u64);
2271    /// assert_eq!(cipher_cipher_text, plaintext);
2272    /// ```
2273    ///
2274    /// # For more examples,
2275    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.turn_decryptor)
2276    pub fn turn_decryptor(&mut self)
2277    {
2278        self.enc = Self::decrypt_u64;
2279        self.dec = Self::encrypt_u64;
2280    }
2281
2282    // pub fn encrypt_u64(&mut self, message: u64) -> u64
2283    /// Encrypts a 64-bit data.
2284    ///
2285    /// # Arguments
2286    /// `message` is of `u64`-type and the plaintext to be encrypted.
2287    ///
2288    /// # Output
2289    /// This method returns the encrypted data of `u64`-type from `message`.
2290    /// 
2291    /// # Counterpart Methods
2292    /// For each trait
2293    /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2294    /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2295    /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2296    /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2297    /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2298    /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2299    /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2300    /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2301    /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2302    /// there are provided useful counterpart methods:
2303    /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
2304    /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
2305    /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
2306    /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
2307    /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array().
2308    ///
2309    /// # Example 1 for Normal case
2310    /// ```
2311    /// use cryptocol::symmetric::DES;
2312    ///
2313    /// let key = 0x_1234567890ABCDEF_u64;
2314    /// println!("K =\t{:#018X}", key);
2315    ///
2316    /// let message = 0x_1234567890ABCDEF_u64;
2317    /// println!("M_u64 =\t{:#018X}", message);
2318    ///
2319    /// let mut a_des = DES::new_with_key_u64(key);
2320    /// let cipher = a_des.encrypt_u64(message);
2321    /// println!("C_u64 (16 rounds) =\t{:#018X}", cipher);
2322    /// assert_eq!(cipher, 0x_1BC4896735BBE206_u64);
2323    /// ```
2324    ///
2325    /// # For more examples,
2326    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.encrypt_u64)
2327    pub fn encrypt_u64(&mut self, message: u64) -> u64
2328    {
2329        self.set_block(message);
2330        self.encrypt_block();
2331        self.get_block()
2332    }
2333
2334    // pub fn decrypt_u64(&mut self, cipher: u64) -> u64
2335    /// Decrypts a 64-bit data.
2336    ///
2337    /// # Arguments
2338    /// `cioher` is of `u64`-type and the ciphertext to be decrypted.
2339    ///
2340    /// # Output
2341    /// This method returns the decrypted data of `u64`-type from `cipher`.
2342    /// 
2343    /// # Counterpart Methods
2344    /// For each trait
2345    /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2346    /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2347    /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2348    /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2349    /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2350    /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2351    /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2352    /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2353    /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2354    /// there are provided useful counterpart methods:
2355    /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
2356    /// decrypt_into_string(),
2357    /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
2358    /// decrypt_vec_into_string(),
2359    /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
2360    /// and decrypt_array_into_string().
2361    /// 
2362    /// # Example 1 for Normal case
2363    /// ```
2364    /// use cryptocol::symmetric::DES;
2365    ///
2366    /// let key = 0x_1234567890ABCDEF_u64;
2367    /// println!("K =\t{:#018X}", key);
2368    ///
2369    /// let message = 0x_1234567890ABCDEF_u64;
2370    /// println!("M_u64 =\t{:#018X}", message);
2371    ///
2372    /// let mut a_des = DES::new_with_key_u64(key);
2373    /// let cipher = a_des.encrypt_u64(message);
2374    /// println!("C_u64 (16 rounds) =\t{:#018X}", cipher);
2375    /// assert_eq!(cipher, 0x_1BC4896735BBE206_u64);
2376    ///
2377    /// let recovered = a_des.decrypt_u64(cipher);
2378    /// println!("B_u64 (16 rounds) =\t{:#018X}", recovered);
2379    /// assert_eq!(recovered, 0x_1234567890ABCDEF_u64);
2380    /// assert_eq!(recovered, message);
2381    /// ```
2382    ///
2383    /// # For more examples,
2384    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.decrypt_u64)
2385    pub fn decrypt_u64(&mut self, cipher: u64) -> u64
2386    {
2387        self.set_block(cipher);
2388        self.decrypt_block();
2389        self.get_block()
2390    }
2391
2392    // pub(super) fn _encrypt(&mut self, message: u64) -> u64
2393    /// Encrypts a 64-bit data when NDES encrypting if the object was
2394    /// constructed as encryptor for NDES such as Triple DES, and decrypts a
2395    /// 64-bit data when NDES encrypting if the object was constructed as
2396    /// decryptor for NDES such as Triple DES.
2397    ///
2398    /// # Arguments
2399    /// `message` is of `u64`-type and the plaintext to be encrypted.
2400    ///
2401    /// # Output
2402    /// This method returns the encrypted data of `u64`-type from `message`.
2403    ///
2404    /// # Example 1 for Normal case
2405    /// ```
2406    /// use cryptocol::symmetric::DES;
2407    ///
2408    /// let key = 0x_1234567890ABCDEF_u64;
2409    /// println!("K =\t{:#018X}", key);
2410    ///
2411    /// let message = 0x_1234567890ABCDEF_u64;
2412    /// println!("M_u64 =\t{:#018X}", message);
2413    ///
2414    /// let mut a_des = DES::new_with_key_u64(key);
2415    /// let cipher = a_des._encrypt(message);
2416    /// println!("C_u64 (16 rounds) =\t{:#018X}", cipher);
2417    /// assert_eq!(cipher, 0x_1BC4896735BBE206_u64);
2418    /// ```
2419    ///
2420    /// # For more examples,
2421    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method._encrypt)
2422    #[inline]
2423    pub(super) fn _encrypt(&mut self, message: u64) -> u64
2424    {
2425        (self.enc)(self, message)
2426    }
2427
2428    // pub(super) fn _decrypt(&mut self, cipher: u64) -> u64
2429    /// Decrypts a 64-bit data when NDES decrypting if the object was
2430    /// constructed as encryptor for NDES such as Triple DES, and encrypts a
2431    /// 64-bit data when NDES decrypting if the object was constructed as
2432    /// decryptor for NDES such as Triple DES.
2433    ///
2434    /// # Arguments
2435    /// `cipher` is of `u64`-type and the ciphertext to be decrypted.
2436    ///
2437    /// # Output
2438    /// This method returns the decrypted data of `u64`-type from `cipher`.
2439    ///
2440    /// # Example 1 for Normal case
2441    /// ```
2442    /// use cryptocol::symmetric::DES;
2443    ///
2444    /// let key = 0x_1234567890ABCDEF_u64;
2445    /// println!("K =\t{:#018X}", key);
2446    ///
2447    /// let message = 0x_1234567890ABCDEF_u64;
2448    /// println!("M_u64 =\t{:#018X}", message);
2449    ///
2450    /// let mut a_des = DES::new_with_key_u64(key);
2451    /// let cipher = a_des._encrypt(message);
2452    /// println!("C_u64 (16 rounds) =\t{:#018X}", cipher);
2453    /// assert_eq!(cipher, 0x_1BC4896735BBE206_u64);
2454    ///
2455    /// let recovered = a_des._decrypt(cipher);
2456    /// println!("B_u64 (16 rounds) =\t{:#018X}", recovered);
2457    /// assert_eq!(recovered, 0x_1234567890ABCDEF_u64);
2458    /// assert_eq!(recovered, message);
2459    /// ```
2460    ///
2461    /// # For more examples,
2462    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method._decrypt)
2463    #[inline]
2464    pub(super) fn _decrypt(&mut self, cipher: u64) -> u64
2465    {
2466        (self.dec)(self, cipher)
2467    }
2468
2469    // pub fn encrypt_array_u64<const N: usize>(&mut self, message: &[u64; N], cipher: &mut [u64; N])
2470    /// Encrypts an array of 64-bit data.
2471    ///
2472    /// # Arguments
2473    /// - `message` is of an array of `u64`-type and the plaintext to be
2474    ///   encrypted.
2475    /// - `cipher` is of an array of `u64`-type and the ciphertext to be stored.
2476    ///
2477    /// # Features
2478    /// This method encrypts multiple of 64-bit data without padding anything
2479    /// in ECB (Electronic CodeBook) mode.
2480    ///
2481    /// # Counterpart methods
2482    /// For each trait
2483    /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2484    /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2485    /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2486    /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2487    /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2488    /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2489    /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2490    /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2491    /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2492    /// there are provided useful counterpart methods:
2493    /// encrypt(), encrypt_into_vec(), encrypt_into_array(),
2494    /// encrypt_str(), encrypt_str_into_vec(), encrypt_str_into_array(),
2495    /// encrypt_string(), encrypt_string_into_vec(), encrypt_string_into_array(),
2496    /// encrypt_vec(), encrypt_vec_into_vec(), encrypt_vec_into_array(),
2497    /// encrypt_array(), encrypt_array_into_vec(), and encrypt_array_into_array(),.
2498    /// 
2499    /// # Example 1 for Normal case
2500    /// ```
2501    /// use cryptocol::symmetric::DES;
2502    ///
2503    /// let key = 0x_1234567890ABCDEF_u64;
2504    /// println!("K =\t{:#018X}", key);
2505    ///
2506    /// let message = [0x_1234567890ABCDEF_u64, 0xEFCDAB9078563412, 0xFEDCBA0987654321 ];
2507    /// print!("M =\t");
2508    /// for m in message
2509    ///     { print!("{:#018X} ", m); }
2510    /// println!();
2511    /// let mut a_des = DES::new_with_key_u64(key);
2512    ///
2513    /// let mut cipher = [0; 3];
2514    /// a_des.encrypt_array_u64(&message, &mut cipher);
2515    /// print!("C (16 rounds) =\t");
2516    /// for c in cipher
2517    ///     { print!("{:#018X} ", c); }
2518    /// println!();
2519    /// assert_eq!(cipher[0], 0x_1BC4896735BBE206_u64);
2520    /// assert_eq!(cipher[1], 0x_1D8A61E5E62226A4_u64);
2521    /// assert_eq!(cipher[2], 0x_2990D69525C17067_u64);
2522    /// ```
2523    ///
2524    /// # For more examples,
2525    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.encrypt_array_u64)
2526    pub fn encrypt_array_u64<const N: usize>(&mut self, message: &[u64; N], cipher: &mut [u64; N])
2527    {
2528        for i in 0..N
2529        {
2530            self.set_block(message[i]);
2531            self.encrypt_block();
2532            cipher[i] = self.get_block();
2533        }
2534    }
2535
2536    // pub fn decrypt_array_u64<const N: usize>(&mut self, cipher: &[u64; N], message: &mut [u64; N])
2537    /// Decrypts an array of 64-bit data.
2538    ///
2539    /// # Arguments
2540    /// - `cipher` is of an array of `u64`-type and the ciphertext to be
2541    ///   decrypted.
2542    /// - `message` is of an array of `u64`-type and the plaintext to be stored.
2543    ///
2544    /// # Features
2545    /// This method decrypts multiple of 64-bit data without padding anything
2546    /// in ECB (Electronic CodeBook) mode.
2547    /// 
2548    /// # Counterpart Methods
2549    /// For each trait
2550    /// [`ECB_PKCS7`](symmetric/trait.ECB_PKCS7.html#trait.ECB_PKCS7),
2551    /// [`ECB_ISO`](symmetric/trait.ECB_ISO.html#trait.ECB_ISO),
2552    /// [`CBC_PKCS7`](symmetric/trait.CBC_PKCS7.html#trait.ECB_PKCS7),
2553    /// [`CBC_ISO`](symmetric/trait.CBC_ISO.html#trait.CBC_ISO),
2554    /// [`PCBC_PKCS7`](symmetric/trait.PCBC_PKCS7.html#trait.PCBC_PKCS7),
2555    /// [`PCBC_ISO`](symmetric/trait.PCBC_ISO.html#trait.PCBC_ISO).
2556    /// [`CFB`](symmetric/trait.CFB.html#trait.CFB),
2557    /// [`OFB`](symmetric/trait.OFB.html#trait.OFB), and
2558    /// [`CTR`](symmetric/trait.CTR.html#trait.CTR),
2559    /// there are provided useful counterpart methods:
2560    /// decrypt(), decrypt_into_vec(), decrypt_into_array(),
2561    /// decrypt_into_string(),
2562    /// decrypt_vec(), decrypt_vec_into_vec(), decrypt_vec_into_array(),
2563    /// decrypt_vec_into_string(),
2564    /// decrypt_array(), decrypt_array_into_vec(), decrypt_array_into_array(),
2565    /// and decrypt_array_into_string().
2566    /// 
2567    /// # Example 1 for Normal case
2568    /// ```
2569    /// use cryptocol::symmetric::DES;
2570    ///
2571    /// let key = 0x_1234567890ABCDEF_u64;
2572    /// println!("K =\t{:#018X}", key);
2573    ///
2574    /// let message = [0x_1234567890ABCDEF_u64, 0xEFCDAB9078563412, 0xFEDCBA0987654321 ];
2575    /// print!("M =\t");
2576    /// for m in message
2577    ///     { print!("{:#018X} ", m); }
2578    /// println!();
2579    /// let mut a_des = DES::new_with_key_u64(key);
2580    ///
2581    /// let mut cipher = [0; 3];
2582    /// a_des.encrypt_array_u64(&message, &mut cipher);
2583    /// print!("C (16 rounds) =\t");
2584    /// for c in cipher
2585    ///     { print!("{:#018X} ", c); }
2586    /// println!();
2587    /// assert_eq!(cipher[0], 0x_1BC4896735BBE206_u64);
2588    /// assert_eq!(cipher[1], 0x_1D8A61E5E62226A4_u64);
2589    /// assert_eq!(cipher[2], 0x_2990D69525C17067_u64);
2590    ///
2591    /// let mut recovered = [0; 3];
2592    /// a_des.decrypt_array_u64(&cipher, &mut recovered);
2593    /// print!("B (16 rounds) =\t");
2594    /// for r in recovered
2595    ///     { print!("{:#018X} ", r); }
2596    /// println!();
2597    /// assert_eq!(recovered[0], 0x_1234567890ABCDEF_u64);
2598    /// assert_eq!(recovered[1], 0x_EFCDAB9078563412_u64);
2599    /// assert_eq!(recovered[2], 0x_FEDCBA0987654321_u64);
2600    /// ```
2601    ///
2602    /// # For more examples,
2603    /// click [here](./documentation/des_basic/struct.DES_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(cipher[i]);
2609            self.decrypt_block();
2610            message[i] = self.get_block();
2611        }
2612    }
2613
2614    // pub fn is_succeful(&self) -> bool
2615    /// Checks whether the previous encryption or decryption was successful.
2616    ///
2617    /// # Output
2618    /// If the previous encryption or decryption was successful, this method
2619    /// returns true. Otherwise, it returns false.
2620    ///
2621    /// # Features
2622    /// - Usually, you don't have to use this method because the encryption
2623    ///   methods returns the length of ciphertext and the decryption methods
2624    ///   returns the length of plaintext but they returns `0` when they failed.
2625    /// - If the ciphertext is 8 bytes for decryption with the padding either
2626    ///   pkcs7 or iso, the return value `0` of the decryption methods is not
2627    ///   discriminatory. You don't know whether the previous decryption was
2628    ///   failed or the original plaintext was just null string or "". In this
2629    ///   case you can check its success with this method.
2630    ///
2631    /// # Example 1 for Normal case for the message of 0 bytes
2632    /// ```
2633    /// use std::io::Write;
2634    /// use std::fmt::Write as _;
2635    /// use cryptocol::symmetric::{ DES, ECB_PKCS7 };
2636    /// 
2637    /// let key = 0x_1234567890ABCDEF_u64;
2638    /// println!("K =\t{:#018X}", key);
2639    /// let mut a_des = DES::new_with_key_u64(key);
2640    /// let message = "";
2641    /// println!("M =\t{}", message);
2642    /// let mut cipher = [0_u8; 8];
2643    /// let len = a_des.encrypt_into_array(message.as_ptr(), message.len() as u64, &mut cipher);
2644    /// println!("The length of ciphertext = {}", len);
2645    /// assert_eq!(len, 8);
2646    /// let success = a_des.is_successful();
2647    /// assert_eq!(success, true);
2648    /// print!("C =\t");
2649    /// for c in cipher.clone()
2650    ///     { print!("{:02X} ", c); }
2651    /// println!();
2652    /// let mut txt = String::new();
2653    /// for c in cipher.clone()
2654    ///     { write!(txt, "{:02X} ", c); }
2655    /// assert_eq!(txt, "41 7F 89 79 08 CD A1 4C ");
2656    /// ```
2657    ///
2658    /// # For more examples,
2659    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.is_successful)
2660    #[inline]
2661    pub fn is_successful(&self) -> bool
2662    {
2663        self.block.get() == Self::SUCCESS
2664    }
2665
2666    // pub fn is_failed(&self) -> bool
2667    /// Checks whether the previous encryption or decryption was failed.
2668    ///
2669    /// # Output
2670    /// If the previous encryption or decryption was failed, this method
2671    /// returns true. Otherwise, it returns false.
2672    ///
2673    /// # Features
2674    /// - Usually, you don't have to use this method because the encryption
2675    ///   methods returns the length of ciphertext and the decryption methods
2676    ///   returns the length of plaintext but they returns `0` when they failed.
2677    /// - If the ciphertext is 8 bytes for decryption with the padding either
2678    ///   pkcs7 or iso, the return value `0` of the decryption methods is not
2679    ///   discriminatory. You don't know whether the previous decryption was
2680    ///   failed or the original plaintext was just null string or "". In this
2681    ///   case you can check its success with this method.
2682    ///
2683    /// # Example 1 for Normal case for the message of 0 bytes
2684    /// ```
2685    /// use std::io::Write;
2686    /// use std::fmt::Write as _;
2687    /// use cryptocol::symmetric::{ DES, ECB_PKCS7 };
2688    ///
2689    /// let key = 0x_1234567890ABCDEF_u64;
2690    /// println!("K =\t{:#018X}", key);
2691    /// let mut a_des = DES::new_with_key_u64(key);
2692    ///
2693    /// let message = "";
2694    /// println!("M =\t{}", message);
2695    /// let mut cipher = [0_u8; 8];
2696    /// let len = a_des.encrypt_str_into_array(message.as_ptr(), message.len() as u64, &mut cipher);
2697    /// println!("The length of ciphertext = {}", len);
2698    /// assert_eq!(len, 8);
2699    /// let failure = a_des.is_failed();
2700    /// assert_eq!(failure, false);
2701    /// print!("C =\t");
2702    /// for c in cipher.clone()
2703    ///     { print!("{:02X} ", c); }
2704    /// println!();
2705    /// let mut txt = String::new();
2706    /// for c in cipher.clone()
2707    ///     { write!(txt, "{:02X} ", c); }
2708    /// assert_eq!(txt, "41 7F 89 79 08 CD A1 4C ");
2709    /// ```
2710    ///
2711    /// # For more examples,
2712    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.is_failed)
2713    #[inline]
2714    pub fn is_failed(&self) -> bool
2715    {
2716        self.block.get() == Self::FAILURE
2717    }
2718
2719    // pub(super) fn set_successful(&mut self)
2720    /// Sets the flag to mean that the previous encryption or decryption
2721    /// was successful.
2722    ///
2723    /// # Features
2724    /// You won't use this method unless you write codes for implementation
2725    /// of a trait for BigCryptor64 or NDES.
2726    ///
2727    /// # Example
2728    /// ```
2729    /// use cryptocol::symmetric::DES;
2730    /// let mut a_des = DES::new_with_key_u64(0x_1234567890ABCDEF_u64);
2731    /// assert_eq!(a_des.is_successful(), false);
2732    ///
2733    /// a_des.set_successful();
2734    /// assert_eq!(a_des.is_successful(), true);
2735    /// ```
2736    #[inline]
2737    pub(super) fn set_successful(&mut self)
2738    {
2739        self.block.set(Self::SUCCESS);
2740    }
2741
2742    // pub(super) fn set_failed(&mut self)
2743    /// Sets the flag to mean that the previous encryption or decryption
2744    /// was failed.
2745    ///
2746    /// # Features
2747    /// You won't use this method unless you write codes for implementation
2748    /// of a trait for BigCryptor64 or NDES.
2749    ///
2750    /// # Example
2751    /// ```
2752    /// use cryptocol::symmetric::DES;
2753    /// let mut a_des = DES::new_with_key_u64(0x_1234567890ABCDEF_u64);
2754    /// a_des.encrypt_u64(0x1234567890ABCDEF_u64);
2755    /// assert_eq!(a_des.is_failed(), false);
2756    ///
2757    /// a_des.set_failed();
2758    /// assert_eq!(a_des.is_failed(), true);
2759    /// ```
2760    #[inline]
2761    pub(super) fn set_failed(&mut self)
2762    {
2763        self.block.set(Self::FAILURE);
2764    }
2765
2766    // pub fn has_weak_key(&self) -> bool
2767    /// Checks wether or not it has a weak key.
2768    ///
2769    /// # Output
2770    /// This method returns `true` if it has a weak key.
2771    /// Otherwise, it returns `false`.
2772    ///
2773    /// # Example 1 for not weak key
2774    /// ```
2775    /// use cryptocol::symmetric::DES;
2776    ///
2777    /// let key = 0x_1234567890ABCDEF_u64;
2778    /// let mut a_des = DES::new_with_key_u64(key);
2779    /// let weak_key = a_des.has_weak_key();
2780    /// println!("{:016X} is {}a weak key.", key.to_be(), if weak_key {""} else {"not "});
2781    /// assert_eq!(weak_key, false);
2782    /// ```
2783    ///
2784    /// # Example 2 for weak key
2785    /// ```
2786    /// use cryptocol::symmetric::DES;
2787    ///
2788    /// let key = 0x_0000000000000000_u64;
2789    /// a_des.set_key_u64(key);
2790    /// let weak_key = a_des.has_weak_key();
2791    /// println!("{:016X} is {}a weak key.", key.to_be(), if weak_key {""} else {"not "});
2792    /// assert_eq!(weak_key, true);
2793    /// ```
2794    ///
2795    /// # For more examples,
2796    /// click [here](./documentation/des_basic/struct.DES_Generic.html#method.has_weak_key)
2797    #[inline]
2798    pub fn has_weak_key(&mut self) -> bool
2799    {
2800        let cipher = self.encrypt_u64(0);
2801        self.encrypt_u64(cipher) == 0
2802    }
2803
2804    // pub fn is_equivalent_key_u64(&mut self, key: u64) -> bool
2805    /// Checks wether or not it `key` is equivalent to its key.
2806    ///
2807    /// # Output
2808    /// This method returns `true` if it is equivalent to its key.
2809    /// Otherwise, it returns `false`.
2810    #[inline]
2811    pub fn is_equivalent_key_u64(&mut self, key: u64) -> bool
2812    {
2813        key & Self::MASK == self.key.get() & Self::MASK
2814    }
2815
2816    // pub fn is_equivalent_key(&mut self, key: &[u8; 8]) -> bool
2817    /// Checks wether or not it `key` is equivalent to its key.
2818    ///
2819    /// # Output
2820    /// This method returns `true` if it is equivalent to its key.
2821    /// Otherwise, it returns `false`.
2822    #[inline]
2823    pub fn is_equivalent_key(&mut self, key: &[u8; 8]) -> bool
2824    {
2825        LongUnion::new_with_ubytes(*key).get() & Self::MASK == self.key.get() & Self::MASK
2826    }
2827
2828
2829    fn encrypt_block(&mut self)
2830    {
2831        self.permutate_initially();
2832        for round in 0..ROUND
2833            { self.feistel(round); }
2834        let left = self.block.get_uint_(0);
2835        let right = self.block.get_uint_(1);
2836        self.block.set_uint_(0, right);
2837        self.block.set_uint_(1, left);
2838        self.permutate_finally();
2839    }
2840
2841    fn decrypt_block(&mut self)
2842    {
2843        self.permutate_initially();
2844        for round in 0..ROUND
2845            { self.feistel(ROUND - 1 - round); }
2846        let left = self.block.get_uint_(0);
2847        let right = self.block.get_uint_(1);
2848        self.block.set_uint_(0, right);
2849        self.block.set_uint_(1, left);
2850        self.permutate_finally();
2851    }
2852
2853    #[allow(dead_code)]
2854    fn feistel(&mut self, round: usize)
2855    {
2856        const LEFT: usize = 0;
2857        const RIGHT: usize = 1;
2858        let right = self.block.get_uint_(RIGHT);
2859        let left = self.block.get_uint_(LEFT) ^ self.f(round, right);
2860        self.block.set_uint_(LEFT, right);
2861        self.block.set_uint_(RIGHT, left);
2862    }
2863
2864    #[allow(dead_code)]
2865    fn f(&mut self, round: usize, right: u32) -> u32
2866    {
2867        let expanded = self.expand(right);
2868        let indices = expanded ^ self.round_key[round];
2869        let mut idx = [0_usize; 8];
2870        slice_index!(indices, idx);
2871        let mut out = 0_u32;
2872        for i in 0..4
2873        {
2874            let left = i * 2;
2875            let right = left + 1;
2876            combine_pieces!(out, ((Self::SBOX[left][idx[left]] << 4) | Self::SBOX[right][idx[right]]) as u32);
2877        }
2878        self.translate(out)
2879    }
2880
2881    fn make_round_keys(&mut self)
2882    {
2883        let (mut left, mut right) = self.split();
2884        let mut shift = SHIFT;
2885        for i in 0..ROUND
2886        {
2887            rotate_halfkey!(left, shift.is_even());
2888            rotate_halfkey!(right, shift.is_even());
2889            self.make_a_round_key(i, left, right);
2890            shift >>= 1;
2891        }
2892    }
2893
2894    fn make_a_round_key(&mut self, round: usize, left: IntUnion, mut right: IntUnion)
2895    {
2896        let tail = right.get_ubyte_(0) >> 4;
2897        shift_left_union!(right, 4);
2898        let mut whole = LongUnion::new_with_uints([left.get(), right.get()]);
2899        whole.set_ubyte_(3, whole.get_ubyte_(3) | tail);
2900        self.round_key[round] = self.compress_into_48bits(whole.get());
2901    }
2902
2903    fn split(&self) -> (IntUnion, IntUnion)
2904    {
2905        let key_56bit = self.compress_into_56bits();
2906        let key = LongUnion::new_with(key_56bit);
2907        let mut left = IntUnion::new_with(key.get_uint_(0));
2908        left.set_ubyte_(3, left.get_ubyte_(3) & 0b_1111_0000);
2909        let mut right = IntUnion::new_with(key.get_uint_(1));
2910        shift_right_union!(right, 4);
2911        right.set_ubyte_(0, (key.get_ubyte_(3) << 4) | right.get_ubyte_(0));
2912        (left, right)
2913    }
2914
2915    fn permutate_initially(&mut self)   { permutate_data!(self, Self::IP); }
2916    fn permutate_finally(&mut self)     { permutate_data!(self, Self::FP); }
2917    fn compress_into_56bits(&self) -> u64   { return permutate_data!(Self::PC1, u64, self.key.get()); }
2918    fn compress_into_48bits(&self, whole: u64) -> u64   { return permutate_data!(Self::PC2, u64, whole); }
2919    fn expand(&self, right: u32) -> u64     { return permutate_data!(Self::EP, u64, right);}
2920    fn translate(&self, right: u32) -> u32  { return permutate_data!(Self::TP, u32, right); }
2921
2922    #[inline] fn get_block(&self) -> u64            { self.block.get() }
2923    #[inline] fn set_block(&mut self, block: u64)   { self.block.set(block); }
2924
2925
2926
2927
2928    ////// for unit test /////
2929    // #[inline] pub fn test_get_block(&self) -> u64           { self.block.get() }
2930    // #[inline] pub fn test_set_block(&mut self, block: u64)  { self.block.set(block); }
2931    //
2932    // pub fn test_set_key(&mut self, key: [u8; 8])
2933    // {
2934    //     for i in 0..8
2935    //         { self.key.set_ubyte_(i, key[i]); }
2936    // }
2937    //
2938    // pub fn test_permutate_initially(&mut self)    { permutate_data!(self, Self::IP); }
2939    // pub fn test_permutate_finally(&mut self)      { permutate_data!(self, Self::FP); }
2940    // #[inline] pub fn test_expand(&self, right: u32) -> u64  { self.expand(right) }
2941    // #[inline] pub fn test_compress_into_56bits(&self) -> u64    { self.compress_into_56bits() }
2942    // #[inline] pub fn test_split(&self) -> (IntUnion, IntUnion)  { self.split() }
2943    // #[inline] pub fn test_make_round_keys(&mut self)    { self.make_round_keys(); }
2944    // #[inline] pub fn test_get_round_key(&self, round: usize) -> u64  { self.round_key[round] }
2945    // pub fn test_slice_indices(&self, indices: u64, array: &mut [usize; 8])   { slice_index!(indices, array); }
2946    // pub fn test_combine(&self, collector: &mut u32, piece: u32) { combine_pieces!(*collector, piece); }
2947    // pub fn test_f(&mut self, round: usize, right: u32) -> u32   { self.f(round, right) }
2948}