-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathtests.rs
145 lines (110 loc) · 3.71 KB
/
tests.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use des::{
cipher::{generic_array::GenericArray, BlockDecrypt, BlockEncrypt, KeyInit},
Des as Des_fuzz,
};
use rand::{thread_rng, Rng};
use super::{left_shift, *};
fn exhaustive_key_search(
ciphertext: &[u8; 8],
plaintext: &[u8; 8],
ciphertext2: &[u8; 8],
plaintext2: &[u8; 8],
) -> Option<[u8; 8]> {
for k in 0..(1u64 << 56) {
let key = k.to_be_bytes();
let subkeys = DES::setup(key);
let decrypted = DES::decrypt(&subkeys, ciphertext);
let decrypted2 = DES::decrypt(&subkeys, ciphertext2);
if decrypted == *plaintext && decrypted2 == *plaintext2 {
return Some(key);
}
}
None
}
#[test]
/// use multiple keys for more confidence
fn known_plaintext_attack() {
let mut rng = thread_rng();
let plaintext1 = rng.gen();
let plaintext2 = rng.gen();
let key = 100000_u64.to_be_bytes();
let subkeys = DES::setup(key);
let ciphertext = DES::encrypt(&subkeys, &plaintext1);
let ciphertext2 = DES::encrypt(&subkeys, &plaintext2);
let attack_key = exhaustive_key_search(&ciphertext, &plaintext1, &ciphertext2, &plaintext2);
assert!(attack_key.is_some());
}
#[test]
fn des() {
for _ in 0..100 {
let mut rng = thread_rng();
let secret_key = rng.gen();
let subkeys = DES::setup(secret_key);
let message = rng.gen();
let encrypted = DES::encrypt(&subkeys, &message);
let decrypted = DES::decrypt(&subkeys, &encrypted);
assert_eq!(message, decrypted);
}
}
#[test]
fn des_fuzz() {
let mut rng = thread_rng();
let key: [u8; 8] = rng.gen();
let subkeys = DES::setup(key);
let des_fuzz = Des_fuzz::new_from_slice(&key).unwrap();
let mut data: [u8; 8] = rng.gen();
let encrypted = DES::encrypt(&subkeys, &data);
des_fuzz.encrypt_block(GenericArray::from_mut_slice(&mut data));
let decrypted = DES::decrypt(&subkeys, &encrypted);
des_fuzz.decrypt_block(GenericArray::from_mut_slice(&mut data));
assert_eq!(decrypted, data);
}
#[test]
/// DES has four weak keys where encryption and decryption are same.
/// This is only possible when all round keys are same.
fn weak_keys() {
const WEAK_KEYS: [[u8; 8]; 4] = [
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
[0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E],
[0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1],
];
for key in WEAK_KEYS.into_iter() {
let subkeys = DES::setup(key);
let message = b"weaktest";
let encrypted = DES::encrypt(&subkeys, message);
let decrypted = DES::decrypt(&subkeys, message);
assert_eq!(encrypted, decrypted);
}
}
#[test]
/// DES has a nice property where $y=ENC_k(x)$ and $y'=ENC_{k'}(x')$
fn bit_complement() {
let mut rng = thread_rng();
let secret_key: u64 = rng.gen();
let subkeys = DES::setup(secret_key.to_be_bytes());
let message: u64 = rng.gen();
let encrypted = DES::encrypt(&subkeys, &message.to_be_bytes());
let key_complement = u64::MAX ^ secret_key;
let message_complement = u64::MAX ^ message;
let subkeys_complement = DES::setup(key_complement.to_be_bytes());
let encrypted_complement = DES::encrypt(&subkeys_complement, &message_complement.to_be_bytes());
assert_eq!(u64::MAX ^ u64::from_be_bytes(encrypted), u64::from_be_bytes(encrypted_complement));
}
#[test]
fn test_left_shift() {
// data = 00000101 11110101 11100001 00011001
let data = 100000025_u32.to_be_bytes();
// shift = 00000111 11010111 10000100 01100101
let shifts = left_shift(&data, 2);
assert_eq!(shifts[0], 0b00000111);
assert_eq!(shifts[1], 0b11010111);
assert_eq!(shifts[2], 0b10000100);
assert_eq!(shifts[3], 0b01100101);
}
#[test]
fn test_get_byte_from_bits() {
let data = [1, 0, 1, 1, 0, 1, 0, 0];
let res = 0b10110100_u8;
assert_eq!(get_byte_from_bits(&data), res);
}