1const IP: [u8; 64] = [
22 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6,
23 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61,
24 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7,
25];
26
27const FP: [u8; 64] = [
29 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30,
30 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
31 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25,
32];
33
34const E: [u8; 48] = [
37 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18,
38 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1,
39];
40
41const P: [u8; 32] = [
44 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19,
45 13, 30, 6, 22, 11, 4, 25,
46];
47
48const PC1: [u8; 56] = [
52 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60,
53 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29,
54 21, 13, 5, 28, 20, 12, 4,
55];
56
57const PC2: [u8; 48] = [
60 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52,
61 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32,
62];
63
64const SHIFTS: [u8; 16] = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1];
67
68const SBOXES: [[u8; 64]; 8] = [
74 [
76 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12,
77 11, 9, 5, 3, 8, 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9,
78 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
79 ],
80 [
82 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1,
83 10, 6, 9, 11, 5, 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15,
84 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
85 ],
86 [
88 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5,
89 14, 12, 11, 15, 1, 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6,
90 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
91 ],
92 [
94 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2,
95 12, 1, 10, 14, 9, 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1,
96 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
97 ],
98 [
100 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15,
101 10, 3, 9, 8, 6, 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14,
102 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
103 ],
104 [
106 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13,
107 14, 0, 11, 3, 8, 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5,
108 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
109 ],
110 [
112 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5,
113 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4,
114 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
115 ],
116 [
118 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6,
119 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10,
120 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
121 ],
122];
123
124const fn build_sbox_anf() -> [[u64; 4]; 8] {
128 let mut out = [[0u64; 4]; 8];
129 let mut sbox_idx = 0usize;
130 while sbox_idx < 8 {
131 let mut bit_idx = 0usize;
132 while bit_idx < 4 {
133 let mut coeffs = [0u8; 64];
134 let mut x = 0usize;
135 while x < 64 {
136 let row = ((x & 0x20) >> 4) | (x & 0x01);
137 let col = (x >> 1) & 0x0f;
138 coeffs[x] = (SBOXES[sbox_idx][row * 16 + col] >> bit_idx) & 1;
139 x += 1;
140 }
141
142 let mut var = 0usize;
143 while var < 6 {
144 let stride = 1usize << var;
145 let mut mask = 0usize;
146 while mask < 64 {
147 if mask & stride != 0 {
148 coeffs[mask] ^= coeffs[mask ^ stride];
149 }
150 mask += 1;
151 }
152 var += 1;
153 }
154
155 let mut packed = 0u64;
156 let mut monomial = 0usize;
157 while monomial < 64 {
158 packed |= (coeffs[monomial] as u64) << monomial;
159 monomial += 1;
160 }
161 out[sbox_idx][bit_idx] = packed;
162 bit_idx += 1;
163 }
164 sbox_idx += 1;
165 }
166 out
167}
168
169const SBOX_ANF: [[u64; 4]; 8] = build_sbox_anf();
170
171const fn build_perm64(perm: &[u8; 64]) -> [[u64; 256]; 8] {
179 let mut table = [[0u64; 256]; 8];
180 let mut i = 0usize;
181 while i < 64 {
182 let src = (perm[i] - 1) as usize; let src_byte = src / 8;
184 let src_bit = src % 8; let out_bit = 63 - i;
186 let mut v = 0usize;
187 while v < 256 {
188 if (v >> (7 - src_bit)) & 1 == 1 {
189 table[src_byte][v] |= 1u64 << out_bit;
190 }
191 v += 1;
192 }
193 i += 1;
194 }
195 table
196}
197
198const fn build_perm_e(perm: &[u8; 48]) -> [[u64; 256]; 4] {
199 let mut table = [[0u64; 256]; 4];
200 let mut i = 0usize;
201 while i < 48 {
202 let src = (perm[i] - 1) as usize; let src_byte = src / 8;
204 let src_bit = src % 8;
205 let out_bit = 47 - i;
206 let mut v = 0usize;
207 while v < 256 {
208 if (v >> (7 - src_bit)) & 1 == 1 {
209 table[src_byte][v] |= 1u64 << out_bit;
210 }
211 v += 1;
212 }
213 i += 1;
214 }
215 table
216}
217
218const fn apply_p_to_partial(s: u32) -> u32 {
221 let mut out = 0u32;
222 let mut i = 0u32;
223 while i < 32 {
224 let src_bit = 32u32 - P[i as usize] as u32; let dst_bit = 31u32 - i;
228 if (s >> src_bit) & 1 == 1 {
229 out |= 1u32 << dst_bit;
230 }
231 i += 1;
232 }
233 out
234}
235
236const fn build_sp() -> [[u32; 64]; 8] {
243 let mut sp = [[0u32; 64]; 8];
244 let mut i = 0u32;
245 while i < 8 {
246 let mut j = 0usize; while j < 64 {
248 let row = ((j & 0x20) >> 4) | (j & 0x01); let col = (j >> 1) & 0x0F; let sval = SBOXES[i as usize][row * 16 + col] as u32;
251 let partial = sval << (28u32 - 4 * i);
253 sp[i as usize][j] = apply_p_to_partial(partial);
254 j += 1;
255 }
256 i += 1;
257 }
258 sp
259}
260
261static IP_TABLE: [[u64; 256]; 8] = build_perm64(&IP);
262static FP_TABLE: [[u64; 256]; 8] = build_perm64(&FP);
263static E_TABLE: [[u64; 256]; 4] = build_perm_e(&E);
264static SP_TABLE: [[u32; 64]; 8] = build_sp();
265
266#[inline]
267fn fast_perm64(x: u64, t: &[[u64; 256]; 8]) -> u64 {
268 t[0][(x >> 56) as usize]
269 | t[1][((x >> 48) & 0xff) as usize]
270 | t[2][((x >> 40) & 0xff) as usize]
271 | t[3][((x >> 32) & 0xff) as usize]
272 | t[4][((x >> 24) & 0xff) as usize]
273 | t[5][((x >> 16) & 0xff) as usize]
274 | t[6][((x >> 8) & 0xff) as usize]
275 | t[7][(x & 0xff) as usize]
276}
277
278#[inline]
279fn fast_expand(r: u32, t: &[[u64; 256]; 4]) -> u64 {
280 t[0][(r >> 24) as usize]
281 | t[1][((r >> 16) & 0xff) as usize]
282 | t[2][((r >> 8) & 0xff) as usize]
283 | t[3][(r & 0xff) as usize]
284}
285
286#[inline]
292fn bit64(block: u64, pos: u8) -> u64 {
293 (block >> (64 - pos)) & 1
294}
295
296fn permute64(input: u64, table: &[u8]) -> u64 {
299 let mut out = 0u64;
300 for (i, &src) in table.iter().enumerate() {
301 out |= bit64(input, src) << (table.len() - 1 - i);
302 }
303 out
304}
305
306fn permute64_to48(input: u64, table: &[u8; 48]) -> u64 {
309 let mut out = 0u64;
310 for (i, &src) in table.iter().enumerate() {
311 out |= bit64(input, src) << (47 - i);
312 }
313 out
314}
315
316#[inline]
317fn rotate_left(val: u32, n: u8, bits: u8) -> u32 {
318 let mask = (1u32 << bits) - 1;
319 ((val << n) | (val >> (bits - n))) & mask
320}
321
322pub type KeySchedule = [u64; 16];
328
329#[must_use]
334pub fn key_schedule(key: u64) -> KeySchedule {
335 let pc1_out = permute64(key, &PC1);
338
339 let c_bytes = ((pc1_out >> 28) & 0x0FFF_FFFF).to_be_bytes();
340 let d_bytes = (pc1_out & 0x0FFF_FFFF).to_be_bytes();
341 let mut c = u32::from_be_bytes([c_bytes[4], c_bytes[5], c_bytes[6], c_bytes[7]]); let mut d = u32::from_be_bytes([d_bytes[4], d_bytes[5], d_bytes[6], d_bytes[7]]); let mut schedule = [0u64; 16];
345 for i in 0..16 {
346 c = rotate_left(c, SHIFTS[i], 28);
347 d = rotate_left(d, SHIFTS[i], 28);
348
349 let cd: u64 = (u64::from(c) << 28) | u64::from(d);
352
353 let cd_shifted = cd << 8; schedule[i] = permute64_to48(cd_shifted, &PC2);
359 }
360 schedule
361}
362
363fn f(r: u32, subkey: u64) -> u32 {
369 let xored = fast_expand(r, &E_TABLE) ^ subkey;
370
371 let mut result = 0u32;
372 for (i, sp_row) in SP_TABLE.iter().enumerate() {
373 let shift = 42 - 6 * i;
374 let b6 = ((xored >> shift) & 0x3F) as usize;
375 result |= sp_row[b6];
376 }
377 result
378}
379
380#[inline]
381fn subset_mask6(x: u8) -> u64 {
382 let mut mask = 1u64;
387
388 let bit0 = 0u64.wrapping_sub(u64::from(x & 1));
389 mask |= (mask << 1) & bit0;
390
391 let bit1 = 0u64.wrapping_sub(u64::from((x >> 1) & 1));
392 mask |= (mask << 2) & bit1;
393
394 let bit2 = 0u64.wrapping_sub(u64::from((x >> 2) & 1));
395 mask |= (mask << 4) & bit2;
396
397 let bit3 = 0u64.wrapping_sub(u64::from((x >> 3) & 1));
398 mask |= (mask << 8) & bit3;
399
400 let bit4 = 0u64.wrapping_sub(u64::from((x >> 4) & 1));
401 mask |= (mask << 16) & bit4;
402
403 let bit5 = 0u64.wrapping_sub(u64::from((x >> 5) & 1));
404 mask |= (mask << 32) & bit5;
405
406 mask
407}
408
409#[inline]
410fn parity64(mut x: u64) -> u8 {
411 x ^= x >> 32;
412 x ^= x >> 16;
413 x ^= x >> 8;
414 x ^= x >> 4;
415 x &= 0x0f;
416 let nibble = u16::try_from(x).expect("masked parity nibble fits in u16");
417 u8::try_from((0x6996u16 >> nibble) & 1).expect("parity bit fits in u8")
418}
419
420#[inline]
427fn sbox_ct(sbox_idx: usize, input: u8) -> u8 {
428 let active = subset_mask6(input);
429 let coeffs = &SBOX_ANF[sbox_idx];
430 parity64(active & coeffs[0])
431 | (parity64(active & coeffs[1]) << 1)
432 | (parity64(active & coeffs[2]) << 2)
433 | (parity64(active & coeffs[3]) << 3)
434}
435
436fn f_ct(r: u32, subkey: u64) -> u32 {
440 let mut expanded = 0u64;
441 for (i, &src) in E.iter().enumerate() {
442 let bit = u64::from((r >> (32 - src)) & 1);
443 expanded |= bit << (47 - i);
444 }
445 let xored = expanded ^ subkey;
446
447 let mut pre_p = 0u32;
448 for i in 0..8usize {
449 let shift = 42 - 6 * i;
450 let b6 = ((xored >> shift) & 0x3f) as u8;
451 let sval = u32::from(sbox_ct(i, b6));
452 pre_p |= sval << (28 - 4 * i);
453 }
454
455 apply_p_to_partial(pre_p)
456}
457
458fn des_block(block: u64, schedule: &KeySchedule) -> u64 {
467 let permuted = fast_perm64(block, &IP_TABLE);
468
469 let mut l = u32::try_from((permuted >> 32) & 0xFFFF_FFFF).expect("upper DES half fits in u32");
470 let mut r = u32::try_from(permuted & 0xFFFF_FFFF).expect("lower DES half fits in u32");
471
472 for &subkey in schedule {
473 let tmp = r;
474 r = l ^ f(r, subkey);
475 l = tmp;
476 }
477
478 let pre_output = (u64::from(r) << 32) | u64::from(l);
480 fast_perm64(pre_output, &FP_TABLE)
481}
482
483fn des_block_ct(block: u64, schedule: &KeySchedule) -> u64 {
484 let permuted = permute64(block, &IP);
485
486 let mut l = u32::try_from((permuted >> 32) & 0xFFFF_FFFF).expect("upper DES half fits in u32");
487 let mut r = u32::try_from(permuted & 0xFFFF_FFFF).expect("lower DES half fits in u32");
488
489 for &subkey in schedule {
490 let tmp = r;
491 r = l ^ f_ct(r, subkey);
492 l = tmp;
493 }
494
495 let pre_output = (u64::from(r) << 32) | u64::from(l);
496 permute64(pre_output, &FP)
497}
498
499pub struct Des {
505 enc_schedule: KeySchedule,
506 dec_schedule: KeySchedule,
507}
508
509pub struct DesCt {
515 enc_schedule: KeySchedule,
516 dec_schedule: KeySchedule,
517}
518
519#[derive(Debug, Clone, Copy, PartialEq, Eq)]
521pub enum DesKeyError {
522 WeakOrSemiWeakKey,
524}
525
526const WEAK_KEYS: [[u8; 8]; 4] = [
528 [0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01],
529 [0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE],
530 [0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1],
531 [0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E],
532];
533
534const SEMI_WEAK_KEY_PAIRS: [([u8; 8], [u8; 8]); 6] = [
536 (
537 [0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE],
538 [0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01],
539 ),
540 (
541 [0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1],
542 [0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E],
543 ),
544 (
545 [0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1],
546 [0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01],
547 ),
548 (
549 [0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE],
550 [0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E],
551 ),
552 (
553 [0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E],
554 [0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01],
555 ),
556 (
557 [0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE],
558 [0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1],
559 ),
560];
561
562#[inline]
563fn strip_parity_bits(key: &[u8; 8]) -> [u8; 8] {
564 let mut out = [0u8; 8];
565 for i in 0..8 {
566 out[i] = key[i] & 0xFE;
567 }
568 out
569}
570
571#[must_use]
573pub fn is_weak_or_semi_weak_key(key: &[u8; 8]) -> bool {
574 let normalized = strip_parity_bits(key);
575 WEAK_KEYS
576 .iter()
577 .any(|wk| strip_parity_bits(wk) == normalized)
578 || SEMI_WEAK_KEY_PAIRS.iter().any(|(a, b)| {
579 let a_norm = strip_parity_bits(a);
580 let b_norm = strip_parity_bits(b);
581 normalized == a_norm || normalized == b_norm
582 })
583}
584
585impl Des {
586 pub fn new(key: &[u8; 8]) -> Result<Self, DesKeyError> {
588 if is_weak_or_semi_weak_key(key) {
589 return Err(DesKeyError::WeakOrSemiWeakKey);
590 }
591 Ok(Self::new_unchecked(key))
592 }
593
594 #[must_use]
599 pub fn new_unchecked(key: &[u8; 8]) -> Self {
600 let k = u64::from_be_bytes(*key);
601 let enc_schedule = key_schedule(k);
602 let mut dec_schedule = enc_schedule;
603 dec_schedule.reverse();
604 Des {
605 enc_schedule,
606 dec_schedule,
607 }
608 }
609
610 pub fn new_wiping(key: &mut [u8; 8]) -> Result<Self, DesKeyError> {
612 let out = Self::new(key);
613 crate::ct::zeroize_slice(key.as_mut_slice());
614 out
615 }
616
617 #[must_use]
619 pub fn encrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
620 let b = u64::from_be_bytes(*block);
621 des_block(b, &self.enc_schedule).to_be_bytes()
622 }
623
624 #[must_use]
626 pub fn decrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
627 let b = u64::from_be_bytes(*block);
628 des_block(b, &self.dec_schedule).to_be_bytes()
629 }
630}
631
632impl DesCt {
633 pub fn new(key: &[u8; 8]) -> Result<Self, DesKeyError> {
635 if is_weak_or_semi_weak_key(key) {
636 return Err(DesKeyError::WeakOrSemiWeakKey);
637 }
638 Ok(Self::new_unchecked(key))
639 }
640
641 #[must_use]
643 pub fn new_unchecked(key: &[u8; 8]) -> Self {
644 let k = u64::from_be_bytes(*key);
645 let enc_schedule = key_schedule(k);
646 let mut dec_schedule = enc_schedule;
647 dec_schedule.reverse();
648 DesCt {
649 enc_schedule,
650 dec_schedule,
651 }
652 }
653
654 pub fn new_wiping(key: &mut [u8; 8]) -> Result<Self, DesKeyError> {
656 let out = Self::new(key);
657 crate::ct::zeroize_slice(key.as_mut_slice());
658 out
659 }
660
661 #[must_use]
663 pub fn encrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
664 let b = u64::from_be_bytes(*block);
665 des_block_ct(b, &self.enc_schedule).to_be_bytes()
666 }
667
668 #[must_use]
670 pub fn decrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
671 let b = u64::from_be_bytes(*block);
672 des_block_ct(b, &self.dec_schedule).to_be_bytes()
673 }
674}
675
676#[derive(Debug, Clone, Copy, PartialEq, Eq)]
698pub enum TDesMode {
699 ThreeKey,
701 TwoKey,
703}
704
705pub struct TripleDes {
707 k1_enc: KeySchedule,
708 k1_dec: KeySchedule,
709 k2_enc: KeySchedule,
710 k2_dec: KeySchedule,
711 k3_enc: KeySchedule,
712 k3_dec: KeySchedule,
713}
714
715impl TripleDes {
716 pub fn new_3key(key: &[u8; 24]) -> Result<Self, DesKeyError> {
723 let k1: &[u8; 8] = key[0..8].try_into().expect("first DES key split");
724 let k2: &[u8; 8] = key[8..16].try_into().expect("second DES key split");
725 let k3: &[u8; 8] = key[16..24].try_into().expect("third DES key split");
726 if is_weak_or_semi_weak_key(k1)
727 || is_weak_or_semi_weak_key(k2)
728 || is_weak_or_semi_weak_key(k3)
729 {
730 return Err(DesKeyError::WeakOrSemiWeakKey);
731 }
732 Ok(Self::from_keys(
733 u64::from_be_bytes(*k1),
734 u64::from_be_bytes(*k2),
735 u64::from_be_bytes(*k3),
736 ))
737 }
738
739 pub fn new_3key_wiping(key: &mut [u8; 24]) -> Result<Self, DesKeyError> {
741 let out = Self::new_3key(key);
742 crate::ct::zeroize_slice(key.as_mut_slice());
743 out
744 }
745
746 pub fn new_2key(key: &[u8; 16]) -> Result<Self, DesKeyError> {
753 let k1: &[u8; 8] = key[0..8].try_into().expect("first DES key split");
754 let k2: &[u8; 8] = key[8..16].try_into().expect("second DES key split");
755 if is_weak_or_semi_weak_key(k1) || is_weak_or_semi_weak_key(k2) {
756 return Err(DesKeyError::WeakOrSemiWeakKey);
757 }
758 Ok(Self::from_keys(
759 u64::from_be_bytes(*k1),
760 u64::from_be_bytes(*k2),
761 u64::from_be_bytes(*k1),
762 ))
763 }
764
765 pub fn new_2key_wiping(key: &mut [u8; 16]) -> Result<Self, DesKeyError> {
767 let out = Self::new_2key(key);
768 crate::ct::zeroize_slice(key.as_mut_slice());
769 out
770 }
771
772 pub fn new_single_key(key: &[u8; 8]) -> Result<Self, DesKeyError> {
775 if is_weak_or_semi_weak_key(key) {
776 return Err(DesKeyError::WeakOrSemiWeakKey);
777 }
778 Ok(Self::new_single_key_unchecked(key))
779 }
780
781 #[must_use]
783 pub fn new_single_key_unchecked(key: &[u8; 8]) -> Self {
784 let k = u64::from_be_bytes(*key);
785 Self::from_keys(k, k, k)
786 }
787
788 pub fn new_single_key_wiping(key: &mut [u8; 8]) -> Result<Self, DesKeyError> {
790 let out = Self::new_single_key(key);
791 crate::ct::zeroize_slice(key.as_mut_slice());
792 out
793 }
794
795 fn from_keys(k1: u64, k2: u64, k3: u64) -> Self {
796 let k1_enc = key_schedule(k1);
797 let k2_enc = key_schedule(k2);
798 let k3_enc = key_schedule(k3);
799 let mut k1_dec = k1_enc;
800 let mut k2_dec = k2_enc;
801 let mut k3_dec = k3_enc;
802 k1_dec.reverse();
803 k2_dec.reverse();
804 k3_dec.reverse();
805 TripleDes {
806 k1_enc,
807 k1_dec,
808 k2_enc,
809 k2_dec,
810 k3_enc,
811 k3_dec,
812 }
813 }
814
815 #[must_use]
817 pub fn encrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
818 let p = u64::from_be_bytes(*block);
819 let t1 = des_block(p, &self.k1_enc); let t2 = des_block(t1, &self.k2_dec); let c = des_block(t2, &self.k3_enc); c.to_be_bytes()
823 }
824
825 #[must_use]
827 pub fn decrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
828 let c = u64::from_be_bytes(*block);
829 let t1 = des_block(c, &self.k3_dec); let t2 = des_block(t1, &self.k2_enc); let p = des_block(t2, &self.k1_dec); p.to_be_bytes()
833 }
834}
835
836impl crate::BlockCipher for Des {
841 const BLOCK_LEN: usize = 8;
842 fn encrypt(&self, block: &mut [u8]) {
843 let arr: &[u8; 8] = (&*block).try_into().expect("wrong block length");
844 block.copy_from_slice(&self.encrypt_block(arr));
845 }
846 fn decrypt(&self, block: &mut [u8]) {
847 let arr: &[u8; 8] = (&*block).try_into().expect("wrong block length");
848 block.copy_from_slice(&self.decrypt_block(arr));
849 }
850}
851
852impl crate::BlockCipher for DesCt {
853 const BLOCK_LEN: usize = 8;
854 fn encrypt(&self, block: &mut [u8]) {
855 let arr: &[u8; 8] = (&*block).try_into().expect("wrong block length");
856 block.copy_from_slice(&self.encrypt_block(arr));
857 }
858 fn decrypt(&self, block: &mut [u8]) {
859 let arr: &[u8; 8] = (&*block).try_into().expect("wrong block length");
860 block.copy_from_slice(&self.decrypt_block(arr));
861 }
862}
863
864impl crate::BlockCipher for TripleDes {
865 const BLOCK_LEN: usize = 8;
866 fn encrypt(&self, block: &mut [u8]) {
867 let arr: &[u8; 8] = (&*block).try_into().expect("wrong block length");
868 block.copy_from_slice(&self.encrypt_block(arr));
869 }
870 fn decrypt(&self, block: &mut [u8]) {
871 let arr: &[u8; 8] = (&*block).try_into().expect("wrong block length");
872 block.copy_from_slice(&self.decrypt_block(arr));
873 }
874}
875
876impl Drop for Des {
877 fn drop(&mut self) {
878 crate::ct::zeroize_slice(self.enc_schedule.as_mut_slice());
880 crate::ct::zeroize_slice(self.dec_schedule.as_mut_slice());
881 }
882}
883
884impl Drop for DesCt {
885 fn drop(&mut self) {
886 crate::ct::zeroize_slice(self.enc_schedule.as_mut_slice());
887 crate::ct::zeroize_slice(self.dec_schedule.as_mut_slice());
888 }
889}
890
891impl Drop for TripleDes {
892 fn drop(&mut self) {
893 crate::ct::zeroize_slice(self.k1_enc.as_mut_slice());
895 crate::ct::zeroize_slice(self.k1_dec.as_mut_slice());
896 crate::ct::zeroize_slice(self.k2_enc.as_mut_slice());
897 crate::ct::zeroize_slice(self.k2_dec.as_mut_slice());
898 crate::ct::zeroize_slice(self.k3_enc.as_mut_slice());
899 crate::ct::zeroize_slice(self.k3_dec.as_mut_slice());
900 }
901}
902
903#[cfg(test)]
908mod tests {
909 use super::*;
910
911 fn from_hex(s: &str) -> u64 {
914 u64::from_str_radix(s, 16).unwrap()
915 }
916
917 fn hex_to_bytes8(s: &str) -> [u8; 8] {
918 from_hex(s).to_be_bytes()
919 }
920
921 fn hex_to_bytes24(s: &str) -> [u8; 24] {
922 let mut out = [0u8; 24];
923 for (idx, chunk) in s.as_bytes().chunks_exact(2).enumerate() {
924 let hi = (chunk[0] as char).to_digit(16).unwrap();
925 let lo = (chunk[1] as char).to_digit(16).unwrap();
926 out[idx] = u8::try_from((hi << 4) | lo).expect("decoded hex byte fits in u8");
927 }
928 out
929 }
930
931 fn tdes_kat(key_hex: &str, pt_hex: &str, ct_hex: &str) {
934 let key = hex_to_bytes8(key_hex);
935 let pt = hex_to_bytes8(pt_hex);
936 let ct = hex_to_bytes8(ct_hex);
937 let cipher = TripleDes::new_single_key_unchecked(&key);
938 assert_eq!(
939 cipher.encrypt_block(&pt),
940 ct,
941 "encrypt mismatch: key={key_hex} pt={pt_hex}"
942 );
943 assert_eq!(
944 cipher.decrypt_block(&ct),
945 pt,
946 "decrypt mismatch: key={key_hex} ct={ct_hex}"
947 );
948 }
949
950 fn des_kat(key_hex: &str, pt_hex: &str, ct_hex: &str) {
952 let key = hex_to_bytes8(key_hex);
953 let pt = hex_to_bytes8(pt_hex);
954 let ct = hex_to_bytes8(ct_hex);
955 let cipher = Des::new_unchecked(&key);
956 assert_eq!(
957 cipher.encrypt_block(&pt),
958 ct,
959 "encrypt mismatch: key={key_hex} pt={pt_hex}"
960 );
961 assert_eq!(
962 cipher.decrypt_block(&ct),
963 pt,
964 "decrypt mismatch: key={key_hex} ct={ct_hex}"
965 );
966 }
967
968 fn des_ct_kat(key_hex: &str, pt_hex: &str, ct_hex: &str) {
969 let key = hex_to_bytes8(key_hex);
970 let pt = hex_to_bytes8(pt_hex);
971 let ct = hex_to_bytes8(ct_hex);
972 let fast = Des::new_unchecked(&key);
973 let slow = DesCt::new_unchecked(&key);
974 assert_eq!(
975 slow.encrypt_block(&pt),
976 ct,
977 "encrypt mismatch: key={key_hex} pt={pt_hex}"
978 );
979 assert_eq!(
980 slow.decrypt_block(&ct),
981 pt,
982 "decrypt mismatch: key={key_hex} ct={ct_hex}"
983 );
984 assert_eq!(
985 slow.encrypt_block(&pt),
986 fast.encrypt_block(&pt),
987 "DesCt must match Des for key={key_hex} pt={pt_hex}"
988 );
989 }
990
991 #[test]
996 fn vartext_all_64() {
997 let cases: &[(&str, &str, &str)] = &[
999 ("0101010101010101", "8000000000000000", "95f8a5e5dd31d900"),
1000 ("0101010101010101", "4000000000000000", "dd7f121ca5015619"),
1001 ("0101010101010101", "2000000000000000", "2e8653104f3834ea"),
1002 ("0101010101010101", "1000000000000000", "4bd388ff6cd81d4f"),
1003 ("0101010101010101", "0800000000000000", "20b9e767b2fb1456"),
1004 ("0101010101010101", "0400000000000000", "55579380d77138ef"),
1005 ("0101010101010101", "0200000000000000", "6cc5defaaf04512f"),
1006 ("0101010101010101", "0100000000000000", "0d9f279ba5d87260"),
1007 ("0101010101010101", "0080000000000000", "d9031b0271bd5a0a"),
1008 ("0101010101010101", "0040000000000000", "424250b37c3dd951"),
1009 ("0101010101010101", "0020000000000000", "b8061b7ecd9a21e5"),
1010 ("0101010101010101", "0010000000000000", "f15d0f286b65bd28"),
1011 ("0101010101010101", "0008000000000000", "add0cc8d6e5deba1"),
1012 ("0101010101010101", "0004000000000000", "e6d5f82752ad63d1"),
1013 ("0101010101010101", "0002000000000000", "ecbfe3bd3f591a5e"),
1014 ("0101010101010101", "0001000000000000", "f356834379d165cd"),
1015 ("0101010101010101", "0000800000000000", "2b9f982f20037fa9"),
1016 ("0101010101010101", "0000400000000000", "889de068a16f0be6"),
1017 ("0101010101010101", "0000200000000000", "e19e275d846a1298"),
1018 ("0101010101010101", "0000100000000000", "329a8ed523d71aec"),
1019 ("0101010101010101", "0000080000000000", "e7fce22557d23c97"),
1020 ("0101010101010101", "0000040000000000", "12a9f5817ff2d65d"),
1021 ("0101010101010101", "0000020000000000", "a484c3ad38dc9c19"),
1022 ("0101010101010101", "0000010000000000", "fbe00a8a1ef8ad72"),
1023 ("0101010101010101", "0000008000000000", "750d079407521363"),
1024 ("0101010101010101", "0000004000000000", "64feed9c724c2faf"),
1025 ("0101010101010101", "0000002000000000", "f02b263b328e2b60"),
1026 ("0101010101010101", "0000001000000000", "9d64555a9a10b852"),
1027 ("0101010101010101", "0000000800000000", "d106ff0bed5255d7"),
1028 ("0101010101010101", "0000000400000000", "e1652c6b138c64a5"),
1029 ("0101010101010101", "0000000200000000", "e428581186ec8f46"),
1030 ("0101010101010101", "0000000100000000", "aeb5f5ede22d1a36"),
1031 ("0101010101010101", "0000000080000000", "e943d7568aec0c5c"),
1032 ("0101010101010101", "0000000040000000", "df98c8276f54b04b"),
1033 ("0101010101010101", "0000000020000000", "b160e4680f6c696f"),
1034 ("0101010101010101", "0000000010000000", "fa0752b07d9c4ab8"),
1035 ("0101010101010101", "0000000008000000", "ca3a2b036dbc8502"),
1036 ("0101010101010101", "0000000004000000", "5e0905517bb59bcf"),
1037 ("0101010101010101", "0000000002000000", "814eeb3b91d90726"),
1038 ("0101010101010101", "0000000001000000", "4d49db1532919c9f"),
1039 ("0101010101010101", "0000000000800000", "25eb5fc3f8cf0621"),
1040 ("0101010101010101", "0000000000400000", "ab6a20c0620d1c6f"),
1041 ("0101010101010101", "0000000000200000", "79e90dbc98f92cca"),
1042 ("0101010101010101", "0000000000100000", "866ecedd8072bb0e"),
1043 ("0101010101010101", "0000000000080000", "8b54536f2f3e64a8"),
1044 ("0101010101010101", "0000000000040000", "ea51d3975595b86b"),
1045 ("0101010101010101", "0000000000020000", "caffc6ac4542de31"),
1046 ("0101010101010101", "0000000000010000", "8dd45a2ddf90796c"),
1047 ("0101010101010101", "0000000000008000", "1029d55e880ec2d0"),
1048 ("0101010101010101", "0000000000004000", "5d86cb23639dbea9"),
1049 ("0101010101010101", "0000000000002000", "1d1ca853ae7c0c5f"),
1050 ("0101010101010101", "0000000000001000", "ce332329248f3228"),
1051 ("0101010101010101", "0000000000000800", "8405d1abe24fb942"),
1052 ("0101010101010101", "0000000000000400", "e643d78090ca4207"),
1053 ("0101010101010101", "0000000000000200", "48221b9937748a23"),
1054 ("0101010101010101", "0000000000000100", "dd7c0bbd61fafd54"),
1055 ("0101010101010101", "0000000000000080", "2fbc291a570db5c4"),
1056 ("0101010101010101", "0000000000000040", "e07c30d7e4e26e12"),
1057 ("0101010101010101", "0000000000000020", "0953e2258e8e90a1"),
1058 ("0101010101010101", "0000000000000010", "5b711bc4ceebf2ee"),
1059 ("0101010101010101", "0000000000000008", "cc083f1e6d9e85f6"),
1060 ("0101010101010101", "0000000000000004", "d2fd8867d50d2dfe"),
1061 ("0101010101010101", "0000000000000002", "06e7ea22ce92708f"),
1062 ("0101010101010101", "0000000000000001", "166b40b44aba4bd6"),
1063 ];
1064 for (k, pt, ct) in cases {
1065 tdes_kat(k, pt, ct);
1066 }
1067 }
1068
1069 #[test]
1074 fn invperm_sample() {
1075 let cases = [
1076 ("0101010101010101", "95f8a5e5dd31d900", "8000000000000000"),
1077 ("0101010101010101", "dd7f121ca5015619", "4000000000000000"),
1078 ("0101010101010101", "166b40b44aba4bd6", "0000000000000001"),
1079 ];
1080 for (k, pt, ct) in cases {
1081 tdes_kat(k, pt, ct);
1082 }
1083 }
1084
1085 #[test]
1089 fn varkey_all_56() {
1090 let cases: &[(&str, &str, &str)] = &[
1091 ("8001010101010101", "0000000000000000", "95a8d72813daa94d"),
1092 ("4001010101010101", "0000000000000000", "0eec1487dd8c26d5"),
1093 ("2001010101010101", "0000000000000000", "7ad16ffb79c45926"),
1094 ("1001010101010101", "0000000000000000", "d3746294ca6a6cf3"),
1095 ("0801010101010101", "0000000000000000", "809f5f873c1fd761"),
1096 ("0401010101010101", "0000000000000000", "c02faffec989d1fc"),
1097 ("0201010101010101", "0000000000000000", "4615aa1d33e72f10"),
1098 ("0180010101010101", "0000000000000000", "2055123350c00858"),
1099 ("0140010101010101", "0000000000000000", "df3b99d6577397c8"),
1100 ("0120010101010101", "0000000000000000", "31fe17369b5288c9"),
1101 ("0110010101010101", "0000000000000000", "dfdd3cc64dae1642"),
1102 ("0108010101010101", "0000000000000000", "178c83ce2b399d94"),
1103 ("0104010101010101", "0000000000000000", "50f636324a9b7f80"),
1104 ("0102010101010101", "0000000000000000", "a8468ee3bc18f06d"),
1105 ("0101800101010101", "0000000000000000", "a2dc9e92fd3cde92"),
1106 ("0101400101010101", "0000000000000000", "cac09f797d031287"),
1107 ("0101200101010101", "0000000000000000", "90ba680b22aeb525"),
1108 ("0101100101010101", "0000000000000000", "ce7a24f350e280b6"),
1109 ("0101080101010101", "0000000000000000", "882bff0aa01a0b87"),
1110 ("0101040101010101", "0000000000000000", "25610288924511c2"),
1111 ("0101020101010101", "0000000000000000", "c71516c29c75d170"),
1112 ("0101018001010101", "0000000000000000", "5199c29a52c9f059"),
1113 ("0101014001010101", "0000000000000000", "c22f0a294a71f29f"),
1114 ("0101012001010101", "0000000000000000", "ee371483714c02ea"),
1115 ("0101011001010101", "0000000000000000", "a81fbd448f9e522f"),
1116 ("0101010801010101", "0000000000000000", "4f644c92e192dfed"),
1117 ("0101010401010101", "0000000000000000", "1afa9a66a6df92ae"),
1118 ("0101010201010101", "0000000000000000", "b3c1cc715cb879d8"),
1119 ("0101010180010101", "0000000000000000", "19d032e64ab0bd8b"),
1120 ("0101010140010101", "0000000000000000", "3cfaa7a7dc8720dc"),
1121 ("0101010120010101", "0000000000000000", "b7265f7f447ac6f3"),
1122 ("0101010110010101", "0000000000000000", "9db73b3c0d163f54"),
1123 ("0101010108010101", "0000000000000000", "8181b65babf4a975"),
1124 ("0101010104010101", "0000000000000000", "93c9b64042eaa240"),
1125 ("0101010102010101", "0000000000000000", "5570530829705592"),
1126 ("0101010101800101", "0000000000000000", "8638809e878787a0"),
1127 ("0101010101400101", "0000000000000000", "41b9a79af79ac208"),
1128 ("0101010101200101", "0000000000000000", "7a9be42f2009a892"),
1129 ("0101010101100101", "0000000000000000", "29038d56ba6d2745"),
1130 ("0101010101080101", "0000000000000000", "5495c6abf1e5df51"),
1131 ("0101010101040101", "0000000000000000", "ae13dbd561488933"),
1132 ("0101010101020101", "0000000000000000", "024d1ffa8904e389"),
1133 ("0101010101018001", "0000000000000000", "d1399712f99bf02e"),
1134 ("0101010101014001", "0000000000000000", "14c1d7c1cffec79e"),
1135 ("0101010101012001", "0000000000000000", "1de5279dae3bed6f"),
1136 ("0101010101011001", "0000000000000000", "e941a33f85501303"),
1137 ("0101010101010801", "0000000000000000", "da99dbbc9a03f379"),
1138 ("0101010101010401", "0000000000000000", "b7fc92f91d8e92e9"),
1139 ("0101010101010201", "0000000000000000", "ae8e5caa3ca04e85"),
1140 ("0101010101010180", "0000000000000000", "9cc62df43b6eed74"),
1141 ("0101010101010140", "0000000000000000", "d863dbb5c59a91a0"),
1142 ("0101010101010120", "0000000000000000", "a1ab2190545b91d7"),
1143 ("0101010101010110", "0000000000000000", "0875041e64c570f7"),
1144 ("0101010101010108", "0000000000000000", "5a594528bebef1cc"),
1145 ("0101010101010104", "0000000000000000", "fcdb3291de21f0c0"),
1146 ("0101010101010102", "0000000000000000", "869efd7f9f265a09"),
1147 ];
1148 for (k, pt, ct) in cases {
1149 tdes_kat(k, pt, ct);
1150 }
1151 }
1152
1153 #[test]
1157 fn permop_all_32() {
1158 let cases: &[(&str, &str, &str)] = &[
1159 ("1046913489980131", "0000000000000000", "88d55e54f54c97b4"),
1160 ("1007103489988020", "0000000000000000", "0c0cc00c83ea48fd"),
1161 ("10071034c8980120", "0000000000000000", "83bc8ef3a6570183"),
1162 ("1046103489988020", "0000000000000000", "df725dcad94ea2e9"),
1163 ("1086911519190101", "0000000000000000", "e652b53b550be8b0"),
1164 ("1086911519580101", "0000000000000000", "af527120c485cbb0"),
1165 ("5107b01519580101", "0000000000000000", "0f04ce393db926d5"),
1166 ("1007b01519190101", "0000000000000000", "c9f00ffc74079067"),
1167 ("3107915498080101", "0000000000000000", "7cfd82a593252b4e"),
1168 ("3107919498080101", "0000000000000000", "cb49a2f9e91363e3"),
1169 ("10079115b9080140", "0000000000000000", "00b588be70d23f56"),
1170 ("3107911598080140", "0000000000000000", "406a9a6ab43399ae"),
1171 ("1007d01589980101", "0000000000000000", "6cb773611dca9ada"),
1172 ("9107911589980101", "0000000000000000", "67fd21c17dbb5d70"),
1173 ("9107d01589190101", "0000000000000000", "9592cb4110430787"),
1174 ("1007d01598980120", "0000000000000000", "a6b7ff68a318ddd3"),
1175 ("1007940498190101", "0000000000000000", "4d102196c914ca16"),
1176 ("0107910491190401", "0000000000000000", "2dfa9f4573594965"),
1177 ("0107910491190101", "0000000000000000", "b46604816c0e0774"),
1178 ("0107940491190401", "0000000000000000", "6e7e6221a4f34e87"),
1179 ("19079210981a0101", "0000000000000000", "aa85e74643233199"),
1180 ("1007911998190801", "0000000000000000", "2e5a19db4d1962d6"),
1181 ("10079119981a0801", "0000000000000000", "23a866a809d30894"),
1182 ("1007921098190101", "0000000000000000", "d812d961f017d320"),
1183 ("100791159819010b", "0000000000000000", "055605816e58608f"),
1184 ("1004801598190101", "0000000000000000", "abd88e8b1b7716f1"),
1185 ("1004801598190102", "0000000000000000", "537ac95be69da1e1"),
1186 ("1004801598190108", "0000000000000000", "aed0f6ae3c25cdd8"),
1187 ("1002911498100104", "0000000000000000", "b3e35a5ee53e7b8d"),
1188 ("1002911598190104", "0000000000000000", "61c79c71921a2ef8"),
1189 ("1002911598100201", "0000000000000000", "e2f5728f0995013c"),
1190 ("1002911698100101", "0000000000000000", "1aeac39a61f0a464"),
1191 ];
1192 for (k, pt, ct) in cases {
1193 tdes_kat(k, pt, ct);
1194 }
1195 }
1196
1197 #[test]
1201 fn subtab_all_19() {
1202 let cases: &[(&str, &str, &str)] = &[
1203 ("7ca110454a1a6e57", "01a1d6d039776742", "690f5b0d9a26939b"),
1204 ("0131d9619dc1376e", "5cd54ca83def57da", "7a389d10354bd271"),
1205 ("07a1133e4a0b2686", "0248d43806f67172", "868ebb51cab4599a"),
1206 ("3849674c2602319e", "51454b582ddf440a", "7178876e01f19b2a"),
1207 ("04b915ba43feb5b6", "42fd443059577fa2", "af37fb421f8c4095"),
1208 ("0113b970fd34f2ce", "059b5e0851cf143a", "86a560f10ec6d85b"),
1209 ("0170f175468fb5e6", "0756d8e0774761d2", "0cd3da020021dc09"),
1210 ("43297fad38e373fe", "762514b829bf486a", "ea676b2cb7db2b7a"),
1211 ("07a7137045da2a16", "3bdd119049372802", "dfd64a815caf1a0f"),
1212 ("04689104c2fd3b2f", "26955f6835af609a", "5c513c9c4886c088"),
1213 ("37d06bb516cb7546", "164d5e404f275232", "0a2aeeae3ff4ab77"),
1214 ("1f08260d1ac2465e", "6b056e18759f5cca", "ef1bf03e5dfa575a"),
1215 ("584023641aba6176", "004bd6ef09176062", "88bf0db6d70dee56"),
1216 ("025816164629b007", "480d39006ee762f2", "a1f9915541020b56"),
1217 ("49793ebc79b3258f", "437540c8698f3cfa", "6fbf1cafcffd0556"),
1218 ("4fb05e1515ab73a7", "072d43a077075292", "2f22e49bab7ca1ac"),
1219 ("49e95d6d4ca229bf", "02fe55778117f12a", "5a6b612cc26cce4a"),
1220 ("018310dc409b26d6", "1d9d5c5018f728c2", "5f4c038ed12b2e41"),
1221 ("1c587f1c13924fef", "305532286d6f295a", "63fac0d034d9f793"),
1222 ];
1223 for (k, pt, ct) in cases {
1224 tdes_kat(k, pt, ct);
1225 }
1226 }
1227
1228 #[test]
1233 fn des_direct_subtab() {
1234 let cases: &[(&str, &str, &str)] = &[
1235 ("7ca110454a1a6e57", "01a1d6d039776742", "690f5b0d9a26939b"),
1236 ("0131d9619dc1376e", "5cd54ca83def57da", "7a389d10354bd271"),
1237 ("07a1133e4a0b2686", "0248d43806f67172", "868ebb51cab4599a"),
1238 ];
1239 for (k, pt, ct) in cases {
1240 des_kat(k, pt, ct);
1241 }
1242 }
1243
1244 #[test]
1245 fn des_ct_direct_subtab() {
1246 let cases: &[(&str, &str, &str)] = &[
1247 ("7ca110454a1a6e57", "01a1d6d039776742", "690f5b0d9a26939b"),
1248 ("0131d9619dc1376e", "5cd54ca83def57da", "7a389d10354bd271"),
1249 ("07a1133e4a0b2686", "0248d43806f67172", "868ebb51cab4599a"),
1250 ];
1251 for (k, pt, ct) in cases {
1252 des_ct_kat(k, pt, ct);
1253 }
1254 }
1255
1256 #[test]
1264 fn tdes_3key_roundtrip() {
1265 let key: [u8; 24] = [
1267 0x01, 0x33, 0x45, 0x77, 0x99, 0xBB, 0xCD, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
1268 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
1269 ];
1270 let pt: [u8; 8] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF];
1271 let cipher = TripleDes::new_3key(&key).expect("non-weak TDES keys");
1272 let ct = cipher.encrypt_block(&pt);
1273 assert_eq!(cipher.decrypt_block(&ct), pt);
1274 }
1275
1276 #[test]
1279 fn tdes_2key_roundtrip() {
1280 let key: [u8; 16] = [
1281 0x01, 0x33, 0x45, 0x77, 0x99, 0xBB, 0xCD, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
1282 0x66, 0x77,
1283 ];
1284 let pt: [u8; 8] = [0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE];
1285 let cipher = TripleDes::new_2key(&key).expect("non-weak TDES keys");
1286 let ct = cipher.encrypt_block(&pt);
1287 assert_eq!(cipher.decrypt_block(&ct), pt);
1288 }
1289
1290 #[test]
1293 fn tdes_single_key_equals_des() {
1294 let key: [u8; 8] = [0x13, 0x34, 0x57, 0x79, 0x9B, 0xBC, 0xDF, 0xF1];
1295 let pt: [u8; 8] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF];
1296 let des = Des::new(&key).expect("non-weak DES key");
1297 let tdes = TripleDes::new_single_key(&key).expect("non-weak DES key");
1298 assert_eq!(
1299 des.encrypt_block(&pt),
1300 tdes.encrypt_block(&pt),
1301 "TDES(K,K,K) must equal DES(K) for same key and plaintext"
1302 );
1303 }
1304
1305 #[test]
1306 fn des_matches_openssl_ecb() {
1307 let key_hex = "133457799bbcdff1";
1308 let pt_hex = "0123456789abcdef";
1309 let Some(expected) =
1310 crate::test_utils::run_openssl_enc("-des-ecb", key_hex, None, &hex_to_bytes8(pt_hex))
1311 else {
1312 return;
1313 };
1314
1315 let cipher = Des::new(&hex_to_bytes8(key_hex)).expect("non-weak DES key");
1316 assert_eq!(
1317 cipher.encrypt_block(&hex_to_bytes8(pt_hex)).as_slice(),
1318 expected.as_slice()
1319 );
1320 }
1321
1322 #[test]
1323 fn tdes_matches_openssl_ecb() {
1324 let key_hex = "133457799bbcdff100112233445566778899aabbccddeeff";
1325 let pt_hex = "0123456789abcdef";
1326 let Some(expected) =
1327 crate::test_utils::run_openssl_enc("-des-ede3-ecb", key_hex, None, &hex_to_bytes8(pt_hex))
1328 else {
1329 return;
1330 };
1331
1332 let cipher = TripleDes::new_3key(&hex_to_bytes24(key_hex)).expect("non-weak TDES keys");
1333 assert_eq!(
1334 cipher.encrypt_block(&hex_to_bytes8(pt_hex)).as_slice(),
1335 expected.as_slice()
1336 );
1337 }
1338
1339 #[test]
1340 fn des_weak_keys_are_rejected_by_checked_constructor() {
1341 let weak_keys: [[u8; 8]; 4] = [
1343 hex_to_bytes8("0101010101010101"),
1344 hex_to_bytes8("FEFEFEFEFEFEFEFE"),
1345 hex_to_bytes8("E0E0E0E0F1F1F1F1"),
1346 hex_to_bytes8("1F1F1F1F0E0E0E0E"),
1347 ];
1348 for key in weak_keys {
1349 assert!(matches!(
1350 Des::new(&key),
1351 Err(DesKeyError::WeakOrSemiWeakKey)
1352 ));
1353 assert!(matches!(
1354 DesCt::new(&key),
1355 Err(DesKeyError::WeakOrSemiWeakKey)
1356 ));
1357 assert!(matches!(
1358 TripleDes::new_single_key(&key),
1359 Err(DesKeyError::WeakOrSemiWeakKey)
1360 ));
1361 }
1362 }
1363
1364 #[test]
1365 fn des_semi_weak_keys_are_rejected_by_checked_constructor() {
1366 let pairs: [([u8; 8], [u8; 8]); 6] = [
1368 (
1369 hex_to_bytes8("01FE01FE01FE01FE"),
1370 hex_to_bytes8("FE01FE01FE01FE01"),
1371 ),
1372 (
1373 hex_to_bytes8("1FE01FE00EF10EF1"),
1374 hex_to_bytes8("E01FE01FF10EF10E"),
1375 ),
1376 (
1377 hex_to_bytes8("01E001E001F101F1"),
1378 hex_to_bytes8("E001E001F101F101"),
1379 ),
1380 (
1381 hex_to_bytes8("1FFE1FFE0EFE0EFE"),
1382 hex_to_bytes8("FE1FFE1FFE0EFE0E"),
1383 ),
1384 (
1385 hex_to_bytes8("011F011F010E010E"),
1386 hex_to_bytes8("1F011F010E010E01"),
1387 ),
1388 (
1389 hex_to_bytes8("E0FEE0FEF1FEF1FE"),
1390 hex_to_bytes8("FEE0FEE0FEF1FEF1"),
1391 ),
1392 ];
1393 for (k1, k2) in pairs {
1394 assert!(matches!(Des::new(&k1), Err(DesKeyError::WeakOrSemiWeakKey)));
1395 assert!(matches!(Des::new(&k2), Err(DesKeyError::WeakOrSemiWeakKey)));
1396 assert!(matches!(
1397 DesCt::new(&k1),
1398 Err(DesKeyError::WeakOrSemiWeakKey)
1399 ));
1400 assert!(matches!(
1401 DesCt::new(&k2),
1402 Err(DesKeyError::WeakOrSemiWeakKey)
1403 ));
1404 }
1405 }
1406
1407 #[test]
1408 fn weak_key_math_still_holds_in_unchecked_path() {
1409 let key = hex_to_bytes8("0101010101010101");
1410 let pt = hex_to_bytes8("0123456789ABCDEF");
1411 let des = Des::new_unchecked(&key);
1412 let ct = des.encrypt_block(&pt);
1413 assert_eq!(des.encrypt_block(&ct), pt);
1414 }
1415}