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}