From a9d87b8048b2ed5ad297b143c7e1f4fe56f3178b Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 8 Apr 2018 08:16:45 -0700 Subject: [PATCH] Move cryptopals tests to a module in tests/ --- src/b64.rs | 9 ------- src/xor.rs | 58 ++++++++------------------------------------- tests/cryptopals.rs | 53 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 57 deletions(-) create mode 100644 tests/cryptopals.rs diff --git a/src/b64.rs b/src/b64.rs index 0d2544d..0d0ffae 100644 --- a/src/b64.rs +++ b/src/b64.rs @@ -119,13 +119,4 @@ mod tests { let output: String = input.chars().hex_decoded().base64_encoded().collect(); assert_eq!(output, ex_output); } - - #[test] - fn cryptopals() { - println!(""); - let input = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"; - let ex_output = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t"; - let output: String = input.chars().hex_decoded().base64_encoded().collect(); - assert_eq!(output, ex_output); - } } diff --git a/src/xor.rs b/src/xor.rs index 36ac23f..6831223 100644 --- a/src/xor.rs +++ b/src/xor.rs @@ -1,30 +1,28 @@ use std::iter; -pub type FixedXOR = iter::Map, fn((u8, u8)) -> u8>; -pub type SingleByteXOR = FixedXOR>; +pub type FixedByteXOR = iter::Map, fn((u8, u8)) -> u8>; +pub type SingleByteXOR = FixedByteXOR>; -pub trait FixedXORable { - fn fixed_xor(self, other: U) -> FixedXOR; +pub trait FixedXOR { + fn fixed_xor(self, other: U) -> FixedByteXOR; } -impl<'a, 'b, T, U> FixedXORable for T +impl<'a, 'b, T, U> FixedXOR for T where T: iter::Iterator + 'a, U: iter::Iterator + 'b { - fn fixed_xor(self, other: U) -> FixedXOR { + fn fixed_xor(self, other: U) -> FixedByteXOR { fn xor(tup: (u8, u8)) -> u8 { tup.0 ^ tup.1 } self.zip(other).map(xor) } } -pub trait SingleByteXORable { - fn single_byte_xor(self, byte: u8) -> SingleByteXOR; +pub trait ByteXOR { + fn byte_xor(self, byte: u8) -> SingleByteXOR; } -impl<'a, T> SingleByteXORable for T - where T: FixedXORable> -{ - fn single_byte_xor(self, byte: u8) -> SingleByteXOR { +impl<'a, T> ByteXOR for T where T: iter::Iterator + 'a { + fn byte_xor(self, byte: u8) -> SingleByteXOR { self.fixed_xor(iter::repeat(byte)) } } @@ -35,41 +33,5 @@ mod tests { use letter_frequency::LetterFreq; use hex::{HexDecodable, HexEncodable}; use std::f32; - use std::ascii::AsciiExt; - #[test] - fn cryptopals() { - println!(); - let a = "1c0111001f010100061a024b53535009181c"; - let b = "686974207468652062756c6c277320657965"; - let ex_output = "746865206b696420646f6e277420706c6179"; - let output: String = a.chars().hex_decoded() - .fixed_xor(b.chars().hex_decoded()) - .hex_encoded().collect(); - assert_eq!(output, ex_output); - } - - #[test] - fn cryptopals13() { - let input = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"; - let mut best_key = 0u8; - let mut best_score = f32::INFINITY; - let mut best_output: Option = None; - for key in 32u8..127 { - let possible_output = input.chars().hex_decoded() - .single_byte_xor(key) - .map(char::from) - .collect::(); - let score = possible_output.chi2_freqs("en"); - println!("{}: {:?} -> {}", key, possible_output, score); - if !score.is_nan() && score < best_score { - best_score = score; - best_output = Some(possible_output); - best_key = key; - } - } - let best_output = best_output.expect("expected output"); - println!("{}: {:?} -> {}", best_key, best_output, best_score); - assert!(best_output.to_lowercase().contains("bacon")); - } } diff --git a/tests/cryptopals.rs b/tests/cryptopals.rs new file mode 100644 index 0000000..9960cfc --- /dev/null +++ b/tests/cryptopals.rs @@ -0,0 +1,53 @@ +// cryptopals.rs +// Eryn Wells + +extern crate cryptopals; + +use std::f32; +use cryptopals::b64::Base64Encodable; +use cryptopals::hex::{HexDecodable, HexEncodable}; +use cryptopals::letter_frequency::LetterFreq; +use cryptopals::xor::{FixedXOR, ByteXOR}; + +#[test] +fn s1c1() { + let input = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"; + let ex_output = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t"; + let output: String = input.chars().hex_decoded().base64_encoded().collect(); + assert_eq!(output, ex_output); +} + +#[test] +fn s1c2() { + let a = "1c0111001f010100061a024b53535009181c"; + let b = "686974207468652062756c6c277320657965"; + let ex_output = "746865206b696420646f6e277420706c6179"; + let output: String = a.chars().hex_decoded() + .fixed_xor(b.chars().hex_decoded()) + .hex_encoded().collect(); + assert_eq!(output, ex_output); +} + +#[test] +fn s1c3() { + let input = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"; + let mut best_key = 0u8; + let mut best_score = f32::INFINITY; + let mut best_output: Option = None; + for key in 32u8..127 { + let possible_output = input.chars().hex_decoded() + .byte_xor(key) + .map(char::from) + .collect::(); + let score = possible_output.chi2_freqs("en"); + println!("{}: {:?} -> {}", key, possible_output, score); + if !score.is_nan() && score < best_score { + best_score = score; + best_output = Some(possible_output); + best_key = key; + } + } + let best_output = best_output.expect("expected output"); + println!("{}: {:?} -> {}", best_key, best_output, best_score); + assert!(best_output.to_lowercase().contains("bacon")); +}