summaryrefslogtreecommitdiffstats
path: root/src/crack.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/crack.rs')
-rw-r--r--src/crack.rs402
1 files changed, 234 insertions, 168 deletions
diff --git a/src/crack.rs b/src/crack.rs
index acc059b..9d56980 100644
--- a/src/crack.rs
+++ b/src/crack.rs
@@ -1,20 +1,19 @@
-use std::ascii::AsciiExt;
+use rand::Rng;
use std::borrow::ToOwned;
use std::collections::{HashMap, HashSet};
-use rand::{Rng, SeedableRng};
-use aes::encrypt_aes_128_cbc;
-use data::ENGLISH_FREQUENCIES;
-use primitives::{fixed_xor, unpad_pkcs7, hamming, repeating_key_xor};
-use random::MersenneTwister;
+use crate::aes::encrypt_aes_128_cbc;
+use crate::data::ENGLISH_FREQUENCIES;
+use crate::primitives::{fixed_xor, hamming, repeating_key_xor, unpad_pkcs7};
+use crate::random::MersenneTwister;
-#[derive(PartialEq,Eq,Debug)]
+#[derive(PartialEq, Eq, Debug)]
pub enum BlockCipherMode {
ECB,
CBC,
}
-pub fn find_single_byte_xor_encrypted_string (inputs: &[Vec<u8>]) -> Vec<u8> {
+pub fn find_single_byte_xor_encrypted_string(inputs: &[Vec<u8>]) -> Vec<u8> {
let mut min_diff = 100.0;
let mut best_decrypted = vec![];
for input in inputs {
@@ -27,44 +26,40 @@ pub fn find_single_byte_xor_encrypted_string (inputs: &[Vec<u8>]) -> Vec<u8> {
return best_decrypted;
}
-pub fn crack_single_byte_xor (input: &[u8]) -> Vec<u8> {
+pub fn crack_single_byte_xor(input: &[u8]) -> Vec<u8> {
let (key, _) = crack_single_byte_xor_with_confidence(input);
return repeating_key_xor(input, &[key]);
}
-pub fn crack_repeating_key_xor (input: &[u8]) -> Vec<u8> {
+pub fn crack_repeating_key_xor(input: &[u8]) -> Vec<u8> {
let mut keysizes = vec![];
for keysize in 2..40 {
let distance1 = hamming(
&input[(keysize * 0)..(keysize * 1)],
- &input[(keysize * 1)..(keysize * 2)]
+ &input[(keysize * 1)..(keysize * 2)],
) as f64;
let distance2 = hamming(
&input[(keysize * 1)..(keysize * 2)],
- &input[(keysize * 2)..(keysize * 3)]
+ &input[(keysize * 2)..(keysize * 3)],
) as f64;
let distance3 = hamming(
&input[(keysize * 2)..(keysize * 3)],
- &input[(keysize * 3)..(keysize * 4)]
+ &input[(keysize * 3)..(keysize * 4)],
) as f64;
let distance = distance1 + distance2 + distance3 / 3.0;
let normal_distance = distance / (keysize as f64);
keysizes.push((keysize, normal_distance));
if keysizes.len() > 5 {
- let (idx, _) = keysizes
- .iter()
- .enumerate()
- .fold(
- (0, (0, 0.0)),
- |(accidx, (accsize, accdist)), (idx, &(size, dist))| {
- if dist > accdist {
- (idx, (size, dist))
- }
- else {
- (accidx, (accsize, accdist))
- }
+ let (idx, _) = keysizes.iter().enumerate().fold(
+ (0, (0, 0.0)),
+ |(accidx, (accsize, accdist)), (idx, &(size, dist))| {
+ if dist > accdist {
+ (idx, (size, dist))
+ } else {
+ (accidx, (accsize, accdist))
}
- );
+ },
+ );
keysizes.swap_remove(idx);
}
}
@@ -72,7 +67,8 @@ pub fn crack_repeating_key_xor (input: &[u8]) -> Vec<u8> {
let mut min_diff = 100.0;
let mut best_key = vec![];
for (keysize, _) in keysizes {
- let (key, diff) = crack_repeating_key_xor_with_keysize(input, keysize);
+ let (key, diff) =
+ crack_repeating_key_xor_with_keysize(input, keysize);
if diff < min_diff {
min_diff = diff;
best_key = key;
@@ -82,7 +78,7 @@ pub fn crack_repeating_key_xor (input: &[u8]) -> Vec<u8> {
return best_key;
}
-pub fn find_aes_128_ecb_encrypted_string (inputs: &[Vec<u8>]) -> Vec<u8> {
+pub fn find_aes_128_ecb_encrypted_string(inputs: &[Vec<u8>]) -> Vec<u8> {
let mut max_dups = 0;
let mut found = vec![];
for input in inputs {
@@ -95,27 +91,32 @@ pub fn find_aes_128_ecb_encrypted_string (inputs: &[Vec<u8>]) -> Vec<u8> {
return found;
}
-pub fn detect_ecb_cbc<F> (f: &F, block_size: usize) -> BlockCipherMode where F: Fn(&[u8]) -> Vec<u8> {
- if block_size >= ::std::u8::MAX as usize {
+pub fn detect_ecb_cbc<F>(f: &F, block_size: usize) -> BlockCipherMode
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
+ if block_size >= std::u8::MAX as usize {
panic!("invalid block size: {}", block_size);
}
let block_size_byte = block_size as u8;
let plaintext: Vec<u8> = (0..block_size_byte)
.cycle()
.take(block_size * 2)
- .flat_map(|n| ::std::iter::repeat(n).take(block_size + 1))
+ .flat_map(|n| std::iter::repeat(n).take(block_size + 1))
.collect();
let ciphertext = f(&plaintext[..]);
if count_duplicate_blocks(&ciphertext[..], block_size) >= block_size {
return BlockCipherMode::ECB;
- }
- else {
+ } else {
return BlockCipherMode::CBC;
}
}
-pub fn crack_padded_aes_128_ecb<F> (f: &F) -> Vec<u8> where F: Fn(&[u8]) -> Vec<u8> {
+pub fn crack_padded_aes_128_ecb<F>(f: &F) -> Vec<u8>
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let block_size = find_block_size(f);
if detect_ecb_cbc(f, block_size) != BlockCipherMode::ECB {
panic!("Can only crack ECB-encrypted data");
@@ -135,7 +136,7 @@ pub fn crack_padded_aes_128_ecb<F> (f: &F) -> Vec<u8> where F: Fn(&[u8]) -> Vec<
loop {
let mut map = HashMap::new();
- let prefix: Vec<u8> = ::std::iter::repeat(b'A')
+ let prefix: Vec<u8> = std::iter::repeat(b'A')
.take(block_size - ((i % block_size) + 1))
.collect();
for c in 0..256 {
@@ -150,22 +151,26 @@ pub fn crack_padded_aes_128_ecb<F> (f: &F) -> Vec<u8> where F: Fn(&[u8]) -> Vec<
let next_char = map.get(&get_block(&prefix[..], i));
if next_char.is_some() {
plaintext.push(*next_char.unwrap());
- }
- else {
+ } else {
break;
}
i += 1;
}
- return unpad_pkcs7(&plaintext[..]).expect("invalid padding").to_vec();
+ return unpad_pkcs7(&plaintext[..])
+ .expect("invalid padding")
+ .to_vec();
}
-pub fn crack_padded_aes_128_ecb_with_prefix<F> (f: &F) -> Vec<u8> where F: Fn(&[u8]) -> Vec<u8> {
+pub fn crack_padded_aes_128_ecb_with_prefix<F>(f: &F) -> Vec<u8>
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let (block_size, prefix_len) = find_block_size_and_fixed_prefix_len(f);
let wrapped_f = |input: &[u8]| {
let alignment_padding = block_size - (prefix_len % block_size);
- let padded_input: Vec<u8> = ::std::iter::repeat(b'A')
+ let padded_input: Vec<u8> = std::iter::repeat(b'A')
.take(alignment_padding)
.chain(input.iter().map(|x| *x))
.collect();
@@ -178,8 +183,13 @@ pub fn crack_padded_aes_128_ecb_with_prefix<F> (f: &F) -> Vec<u8> where F: Fn(&[
return crack_padded_aes_128_ecb(&wrapped_f);
}
-pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>) where F: Fn(&str) -> Vec<u8> {
- fn incr_map_element (map: &mut HashMap<Vec<u8>, usize>, key: Vec<u8>) {
+pub fn crack_querystring_aes_128_ecb<F>(
+ encrypter: &F,
+) -> (String, Vec<Vec<u8>>)
+where
+ F: Fn(&str) -> Vec<u8>,
+{
+ fn incr_map_element(map: &mut HashMap<Vec<u8>, usize>, key: Vec<u8>) {
if let Some(val) = map.get_mut(&key) {
*val += 1;
return;
@@ -191,8 +201,8 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
let find_uid_role_blocks = || {
let mut map = HashMap::new();
for c in 32..127 {
- let email_bytes: Vec<u8> = ::std::iter::repeat(c).take(9).collect();
- let email = ::std::str::from_utf8(&email_bytes[..]).unwrap();
+ let email_bytes: Vec<u8> = std::iter::repeat(c).take(9).collect();
+ let email = std::str::from_utf8(&email_bytes[..]).unwrap();
let ciphertext = encrypter(email);
incr_map_element(&mut map, ciphertext[..16].to_vec());
incr_map_element(&mut map, ciphertext[16..32].to_vec());
@@ -202,20 +212,16 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
for (k, v) in map {
most_common_blocks.push((k, v));
if most_common_blocks.len() > 2 {
- let (idx, _) = most_common_blocks
- .iter()
- .enumerate()
- .fold(
- (0, (vec![], 10000)),
- |(aidx, (ablock, acount)), (idx, &(ref block, count))| {
- if count < acount {
- (idx, (block.clone(), count))
- }
- else {
- (aidx, (ablock.clone(), acount))
- }
+ let (idx, _) = most_common_blocks.iter().enumerate().fold(
+ (0, (vec![], 10000)),
+ |(aidx, (ablock, acount)), (idx, &(ref block, count))| {
+ if count < acount {
+ (idx, (block.clone(), count))
+ } else {
+ (aidx, (ablock.clone(), acount))
}
- );
+ },
+ );
most_common_blocks.swap_remove(idx);
}
}
@@ -224,8 +230,7 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
let (ref block1, _) = most_common_blocks[0];
let (ref block2, _) = most_common_blocks[1];
return (block1.clone(), block2.clone());
- }
- else {
+ } else {
panic!("couldn't find most common blocks");
}
};
@@ -234,9 +239,12 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
// email=..........admin<pcks7 padding>...............&uid=10&role=user
let calculate_admin_block = |block1: Vec<u8>, block2: Vec<u8>| {
for _ in 0..1000 {
- let email = "blorg@bar.admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b...............";
+ let email =
+ "blorg@bar.admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b...............";
let ciphertext = encrypter(email);
- if &ciphertext[48..64] == &block1[..] || &ciphertext[48..64] == &block2[..] {
+ if &ciphertext[48..64] == &block1[..]
+ || &ciphertext[48..64] == &block2[..]
+ {
return ciphertext[16..32].to_vec();
}
}
@@ -256,7 +264,10 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
.chain(admin_block.iter())
.map(|x| *x)
.collect();
- if !possibles.iter().any(|possible| possible == &modified_ciphertext) {
+ if !possibles
+ .iter()
+ .any(|possible| possible == &modified_ciphertext)
+ {
possibles.push(modified_ciphertext);
}
}
@@ -268,7 +279,10 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
return calculate_possible_admin_ciphertexts(admin_block);
}
-pub fn crack_cbc_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8> {
+pub fn crack_cbc_bitflipping<F>(f: &F) -> Vec<u8>
+where
+ F: Fn(&str) -> Vec<u8>,
+{
let mut ciphertext = f("AAAAAAAAAAAAAAAA:admin<true:AAAA");
ciphertext[32] = ciphertext[32] ^ 0x01;
ciphertext[38] = ciphertext[38] ^ 0x01;
@@ -276,7 +290,14 @@ pub fn crack_cbc_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8>
return ciphertext;
}
-pub fn crack_cbc_padding_oracle<F> (iv: &[u8], ciphertext: &[u8], f: &F) -> Vec<u8> where F: Fn(&[u8], &[u8]) -> bool {
+pub fn crack_cbc_padding_oracle<F>(
+ iv: &[u8],
+ ciphertext: &[u8],
+ f: &F,
+) -> Vec<u8>
+where
+ F: Fn(&[u8], &[u8]) -> bool,
+{
let mut prev = iv;
let mut plaintext = vec![];
for block in ciphertext.chunks(16) {
@@ -285,14 +306,15 @@ pub fn crack_cbc_padding_oracle<F> (iv: &[u8], ciphertext: &[u8], f: &F) -> Vec<
for c_int in 0..256 {
let c = (255 - c_int) as u8;
let offset = (16 - byte - 1) as usize;
- let mut iv: Vec<u8> = prev
- .iter()
- .take(offset)
- .map(|x| *x)
- .collect();
+ let mut iv: Vec<u8> =
+ prev.iter().take(offset).map(|x| *x).collect();
iv.push(prev[offset] ^ c ^ (byte + 1));
for i in 0..(byte as usize) {
- iv.push(prev[offset + i + 1] ^ plaintext_block[i] ^ (byte + 1));
+ iv.push(
+ prev[offset + i + 1]
+ ^ plaintext_block[i]
+ ^ (byte + 1),
+ );
}
if f(&iv[..], block) {
plaintext_block.insert(0, c);
@@ -309,7 +331,9 @@ pub fn crack_cbc_padding_oracle<F> (iv: &[u8], ciphertext: &[u8], f: &F) -> Vec<
return unpad_pkcs7(&plaintext[..]).unwrap().to_vec();
}
-pub fn crack_fixed_nonce_ctr_statistically (input: Vec<Vec<u8>>) -> Vec<Vec<u8>> {
+pub fn crack_fixed_nonce_ctr_statistically(
+ input: Vec<Vec<u8>>,
+) -> Vec<Vec<u8>> {
let min_len = input.iter().map(|line| line.len()).min().unwrap();
let max_len = input.iter().map(|line| line.len()).max().unwrap();
@@ -328,8 +352,7 @@ pub fn crack_fixed_nonce_ctr_statistically (input: Vec<Vec<u8>>) -> Vec<Vec<u8>>
if line.len() >= len {
idxs.push(idx);
true
- }
- else {
+ } else {
false
}
})
@@ -337,10 +360,8 @@ pub fn crack_fixed_nonce_ctr_statistically (input: Vec<Vec<u8>>) -> Vec<Vec<u8>>
.map(|x| *x)
.collect();
- let (key, _) = crack_repeating_key_xor_with_keysize(
- &ciphertext[..],
- len
- );
+ let (key, _) =
+ crack_repeating_key_xor_with_keysize(&ciphertext[..], len);
for i in full_key.len()..key.len() {
full_key.push(key[i])
}
@@ -358,11 +379,11 @@ pub fn crack_fixed_nonce_ctr_statistically (input: Vec<Vec<u8>>) -> Vec<Vec<u8>>
return plaintext_lines;
}
-pub fn recover_mersenne_twister_seed_from_time (output: u32) -> Option<u32> {
- let now = ::time::now().to_timespec().sec as u32;
+pub fn recover_mersenne_twister_seed_from_time(output: u32) -> Option<u32> {
+ let now = time::now().to_timespec().sec as u32;
for i in -10000..10000i32 {
let seed = (now as i32).wrapping_add(i) as u32;
- let mut mt = MersenneTwister::from_seed(seed);
+ let mut mt = MersenneTwister::from_u32(seed);
let test_output: u32 = mt.gen();
if test_output == output {
return Some(seed);
@@ -371,9 +392,14 @@ pub fn recover_mersenne_twister_seed_from_time (output: u32) -> Option<u32> {
return None;
}
-pub fn clone_mersenne_twister_from_output (outputs: &[u32]) -> MersenneTwister {
- fn untemper (val: u32) -> u32 {
- fn unxorshift<F> (f: F, mut y: u32, n: usize, mask: u32) -> u32 where F: Fn(u32, usize) -> u32 {
+pub fn clone_mersenne_twister_from_output(
+ outputs: &[u32],
+) -> MersenneTwister {
+ fn untemper(val: u32) -> u32 {
+ fn unxorshift<F>(f: F, mut y: u32, n: usize, mask: u32) -> u32
+ where
+ F: Fn(u32, usize) -> u32,
+ {
let mut a = y;
for _ in 0..(32 / n) {
y = f(y, n) & mask;
@@ -384,10 +410,10 @@ pub fn clone_mersenne_twister_from_output (outputs: &[u32]) -> MersenneTwister {
let mut y = val;
- y = unxorshift(|a, n| {a >> n}, y, 18, 0xffffffff);
- y = unxorshift(|a, n| {a << n}, y, 15, 0xefc60000);
- y = unxorshift(|a, n| {a << n}, y, 7, 0x9d2c5680);
- y = unxorshift(|a, n| {a >> n}, y, 11, 0xffffffff);
+ y = unxorshift(|a, n| a >> n, y, 18, 0xffffffff);
+ y = unxorshift(|a, n| a << n, y, 15, 0xefc60000);
+ y = unxorshift(|a, n| a << n, y, 7, 0x9d2c5680);
+ y = unxorshift(|a, n| a >> n, y, 11, 0xffffffff);
y
}
@@ -397,16 +423,17 @@ pub fn clone_mersenne_twister_from_output (outputs: &[u32]) -> MersenneTwister {
state[i] = untemper(output);
}
- return MersenneTwister::from_seed((state, 0));
+ return MersenneTwister::from_state(state, 0);
}
-pub fn recover_16_bit_mt19937_key (ciphertext: &[u8], suffix: &[u8]) -> Option<u16> {
+pub fn recover_16_bit_mt19937_key(
+ ciphertext: &[u8],
+ suffix: &[u8],
+) -> Option<u16> {
for _key in 0..65536u32 {
let key = _key as u16;
- let plaintext = ::random::mt19937_stream_cipher(
- ciphertext,
- key as u32
- );
+ let plaintext =
+ crate::random::mt19937_stream_cipher(ciphertext, key as u32);
if &plaintext[(ciphertext.len() - suffix.len())..] == suffix {
return Some(key);
}
@@ -415,12 +442,15 @@ pub fn recover_16_bit_mt19937_key (ciphertext: &[u8], suffix: &[u8]) -> Option<u
return None;
}
-pub fn recover_mt19937_key_from_time (token: &[u8]) -> Option<u32> {
- let now = ::time::now().to_timespec().sec as u32;
+pub fn recover_mt19937_key_from_time(token: &[u8]) -> Option<u32> {
+ let now = time::now().to_timespec().sec as u32;
for i in -500..500i32 {
let seed = (now as i32).wrapping_add(i) as u32;
- let mut mt = MersenneTwister::from_seed(seed);
- let test_token: Vec<u8> = mt.gen_iter().take(16).collect();
+ let mut mt = MersenneTwister::from_u32(seed);
+ let test_token: Vec<u8> = mt
+ .sample_iter(&rand::distributions::Standard)
+ .take(16)
+ .collect();
if &test_token[..] == token {
return Some(seed);
}
@@ -428,15 +458,23 @@ pub fn recover_mt19937_key_from_time (token: &[u8]) -> Option<u32> {
return None;
}
-pub fn crack_aes_128_ctr_random_access<F> (ciphertext: &[u8], edit: F) -> Vec<u8> where F: Fn(&[u8], usize, &[u8]) -> Vec<u8> {
- let empty_plaintext: Vec<u8> = ::std::iter::repeat(b'\x00')
- .take(ciphertext.len())
- .collect();
+pub fn crack_aes_128_ctr_random_access<F>(
+ ciphertext: &[u8],
+ edit: F,
+) -> Vec<u8>
+where
+ F: Fn(&[u8], usize, &[u8]) -> Vec<u8>,
+{
+ let empty_plaintext: Vec<u8> =
+ std::iter::repeat(b'\x00').take(ciphertext.len()).collect();
let keystream = edit(ciphertext, 0, &empty_plaintext[..]);
return fixed_xor(&keystream[..], ciphertext);
}
-pub fn crack_ctr_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8> {
+pub fn crack_ctr_bitflipping<F>(f: &F) -> Vec<u8>
+where
+ F: Fn(&str) -> Vec<u8>,
+{
let ciphertext = f("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
let replacement = fixed_xor(&ciphertext[32..44], b";admin=true;");
return ciphertext[..32]
@@ -447,14 +485,18 @@ pub fn crack_ctr_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8>
.collect();
}
-pub fn crack_cbc_iv_key<F1, F2> (encrypt: &F1, verify: &F2) -> Vec<u8> where F1: Fn(&str) -> Vec<u8>, F2: Fn(&[u8]) -> Result<bool, Vec<u8>> {
+pub fn crack_cbc_iv_key<F1, F2>(encrypt: &F1, verify: &F2) -> Vec<u8>
+where
+ F1: Fn(&str) -> Vec<u8>,
+ F2: Fn(&[u8]) -> Result<bool, Vec<u8>>,
+{
loop {
- let plaintext_bytes: Vec<u8> = ::rand::thread_rng()
- .gen_iter()
+ let plaintext_bytes: Vec<u8> = rand::thread_rng()
+ .sample_iter(&rand::distributions::Standard)
.filter(|&c| c >= 32 && c < 127)
- .take(16*5)
+ .take(16 * 5)
.collect();
- let plaintext = ::std::str::from_utf8(&plaintext_bytes).unwrap();
+ let plaintext = std::str::from_utf8(&plaintext_bytes).unwrap();
let ciphertext = encrypt(plaintext);
let modified_ciphertext: Vec<u8> = ciphertext[..16]
.iter()
@@ -466,7 +508,7 @@ pub fn crack_cbc_iv_key<F1, F2> (encrypt: &F1, verify: &F2) -> Vec<u8> where F1:
if let Err(modified_plaintext) = verify(&modified_ciphertext[..]) {
let key = fixed_xor(
&modified_plaintext[..16],
- &modified_plaintext[32..48]
+ &modified_plaintext[32..48],
);
let desired_plaintext = b"comment1=cooking%20MCs;userdata=;admin=true;comment2=%20like%20a%20pound%20of%20bacon";
return encrypt_aes_128_cbc(desired_plaintext, &key[..], &key[..]);
@@ -474,51 +516,65 @@ pub fn crack_cbc_iv_key<F1, F2> (encrypt: &F1, verify: &F2) -> Vec<u8> where F1:
}
}
-pub fn crack_sha1_mac_length_extension (input: &[u8], mac: [u8; 20], extension: &[u8]) -> Vec<(Vec<u8>, [u8; 20])> {
- let mut sha1_state: [u32; 5] = unsafe { ::std::mem::transmute(mac) };
+pub fn crack_sha1_mac_length_extension(
+ input: &[u8],
+ mac: [u8; 20],
+ extension: &[u8],
+) -> Vec<(Vec<u8>, [u8; 20])> {
+ let mut sha1_state: [u32; 5] = unsafe { std::mem::transmute(mac) };
for word in sha1_state.iter_mut() {
*word = u32::from_be(*word);
}
- (0..100).map(|i| {
- let new_input: Vec<u8> = input
- .iter()
- .chain(::sha1::sha1_padding(i + input.len() as u64).iter())
- .chain(extension.iter())
- .map(|x| *x)
- .collect();
- let new_hash = ::sha1::sha1_with_state(
- extension,
- sha1_state,
- i + new_input.len() as u64
- );
- (new_input, new_hash)
- }).collect()
+ (0..100)
+ .map(|i| {
+ let new_input: Vec<u8> = input
+ .iter()
+ .chain(
+ crate::sha1::sha1_padding(i + input.len() as u64).iter(),
+ )
+ .chain(extension.iter())
+ .map(|x| *x)
+ .collect();
+ let new_hash = crate::sha1::sha1_with_state(
+ extension,
+ sha1_state,
+ i + new_input.len() as u64,
+ );
+ (new_input, new_hash)
+ })
+ .collect()
}
-pub fn crack_md4_mac_length_extension (input: &[u8], mac: [u8; 16], extension: &[u8]) -> Vec<(Vec<u8>, [u8; 16])> {
- let mut md4_state: [u32; 4] = unsafe { ::std::mem::transmute(mac) };
+pub fn crack_md4_mac_length_extension(
+ input: &[u8],
+ mac: [u8; 16],
+ extension: &[u8],
+) -> Vec<(Vec<u8>, [u8; 16])> {
+ let mut md4_state: [u32; 4] = unsafe { std::mem::transmute(mac) };
for word in md4_state.iter_mut() {
*word = u32::from_le(*word);
}
- (0..100).map(|i| {
- let new_input: Vec<u8> = input
- .iter()
- .chain(::md4::md4_padding(i + input.len() as u64).iter())
- .chain(extension.iter())
- .map(|x| *x)
- .collect();
- let new_hash = ::md4::md4_with_state(
- extension,
- md4_state,
- i + new_input.len() as u64
- );
- (new_input, new_hash)
- }).collect()
+ (0..100)
+ .map(|i| {
+ let new_input: Vec<u8> = input
+ .iter()
+ .chain(crate::md4::md4_padding(i + input.len() as u64).iter())
+ .chain(extension.iter())
+ .map(|x| *x)
+ .collect();
+ let new_hash = crate::md4::md4_with_state(
+ extension,
+ md4_state,
+ i + new_input.len() as u64,
+ );
+ (new_input, new_hash)
+ })
+ .collect()
}
-fn crack_single_byte_xor_with_confidence (input: &[u8]) -> (u8, f64) {
+fn crack_single_byte_xor_with_confidence(input: &[u8]) -> (u8, f64) {
let mut min_diff = 100.0;
let mut best_key = 0;
for a in 0..256u16 {
@@ -526,12 +582,15 @@ fn crack_single_byte_xor_with_confidence (input: &[u8]) -> (u8, f64) {
input,
&::std::iter::repeat(a as u8)
.take(input.len())
- .collect::<Vec<u8>>()[..]
+ .collect::<Vec<u8>>()[..],
);
if !decrypted.is_ascii() {
continue;
}
- if decrypted.iter().any(|&c| c != b'\n' && (c < 0x20 || c > 0x7E)) {
+ if decrypted
+ .iter()
+ .any(|&c| c != b'\n' && (c < 0x20 || c > 0x7E))
+ {
continue;
}
let lowercase = decrypted.to_ascii_lowercase();
@@ -542,15 +601,17 @@ fn crack_single_byte_xor_with_confidence (input: &[u8]) -> (u8, f64) {
total_frequency += 1;
if c >= 0x61 && c <= 0x7A {
frequencies[(c - 0x61) as usize] += 1;
- }
- else {
+ } else {
extra_frequencies += 1;
}
}
let mut total_diff = 0.0;
- for (&english, &crypt) in ENGLISH_FREQUENCIES.iter().zip(frequencies.iter()) {
- let relative_frequency = (crypt as f64) / (total_frequency as f64);
+ for (&english, &crypt) in
+ ENGLISH_FREQUENCIES.iter().zip(frequencies.iter())
+ {
+ let relative_frequency =
+ (crypt as f64) / (total_frequency as f64);
total_diff += (english - relative_frequency).abs();
}
total_diff += (extra_frequencies as f64) / (total_frequency as f64);
@@ -564,7 +625,10 @@ fn crack_single_byte_xor_with_confidence (input: &[u8]) -> (u8, f64) {
return (best_key, min_diff);
}
-fn crack_repeating_key_xor_with_keysize (input: &[u8], keysize: usize) -> (Vec<u8>, f64) {
+fn crack_repeating_key_xor_with_keysize(
+ input: &[u8],
+ keysize: usize,
+) -> (Vec<u8>, f64) {
let strides: Vec<Vec<u8>> = (0..keysize)
.map(|n| {
// XXX sigh ):
@@ -585,14 +649,11 @@ fn crack_repeating_key_xor_with_keysize (input: &[u8], keysize: usize) -> (Vec<u
.iter()
.map(|&(_, diff)| diff)
.fold(0.0, |acc, x| acc + x);
- let key = cracked
- .iter()
- .map(|&(c, _)| c)
- .collect();
+ let key = cracked.iter().map(|&(c, _)| c).collect();
return (key, diff / (keysize as f64));
}
-fn count_duplicate_blocks (input: &[u8], block_size: usize) -> usize {
+fn count_duplicate_blocks(input: &[u8], block_size: usize) -> usize {
let mut set = HashSet::new();
let mut dups = 0;
for block in input.chunks(block_size) {
@@ -603,26 +664,27 @@ fn count_duplicate_blocks (input: &[u8], block_size: usize) -> usize {
return dups;
}
-fn find_block_size<F> (f: &F) -> usize where F: Fn(&[u8]) -> Vec<u8> {
+fn find_block_size<F>(f: &F) -> usize
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let (block_size, _) = find_block_size_and_fixed_prefix_len(f);
return block_size;
}
-fn find_block_size_and_fixed_prefix_len<F> (f: &F) -> (usize, usize) where F: Fn(&[u8]) -> Vec<u8> {
+fn find_block_size_and_fixed_prefix_len<F>(f: &F) -> (usize, usize)
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let fixed_prefix_len = find_fixed_block_prefix_len(f);
let byte = b'A';
let mut prev = f(&[b'f']);
let mut len = 0;
loop {
- let prefix: Vec<u8> = ::std::iter::repeat(byte)
- .take(len)
- .collect();
+ let prefix: Vec<u8> = std::iter::repeat(byte).take(len).collect();
let next = f(&prefix[..]);
- let prefix_len = shared_prefix_len(
- prev.iter(),
- next.iter()
- );
+ let prefix_len = shared_prefix_len(prev.iter(), next.iter());
if prefix_len > fixed_prefix_len {
let block_size = prefix_len - fixed_prefix_len;
return (block_size, fixed_prefix_len + block_size - (len - 1));
@@ -633,15 +695,19 @@ fn find_block_size_and_fixed_prefix_len<F> (f: &F) -> (usize, usize) where F: Fn
}
}
-fn find_fixed_block_prefix_len<F> (f: &F) -> usize where F: Fn(&[u8]) -> Vec<u8> {
+fn find_fixed_block_prefix_len<F>(f: &F) -> usize
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let ciphertext1 = f(b"");
let ciphertext2 = f(b"A");
return shared_prefix_len(ciphertext1.iter(), ciphertext2.iter());
}
-fn shared_prefix_len<I> (i1: I, i2: I) -> usize where I: Iterator, <I as Iterator>::Item: PartialEq {
- return i1
- .zip(i2)
- .take_while(|&(ref c1, ref c2)| { c1 == c2 })
- .count();
+fn shared_prefix_len<I>(i1: I, i2: I) -> usize
+where
+ I: Iterator,
+ <I as Iterator>::Item: PartialEq,
+{
+ return i1.zip(i2).take_while(|&(ref c1, ref c2)| c1 == c2).count();
}