commit 764abb1eac66fed75c70cd50bb98c976968c6c30
parent 0d1dcef0700764e8143ac6c8f7bd5eb0bd68d976
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 18 Nov 2018 20:12:36 +1300
Update.
Diffstat:
9 files changed, 147 insertions(+), 96 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -4,9 +4,9 @@ version = "0.1.0"
authors = ["Jared Tobin <jared@jtobin.ca>"]
[dependencies]
-base64 = "0.6"
+base64 = "0.10.0"
clap = "2.26"
-hex = "0.2"
+hex = "0.3.2"
openssl = "0.10"
rand = "0.3"
combine = "2.5"
diff --git a/docs/s1.md b/docs/s1.md
@@ -1,5 +1,8 @@
### Set 1
+I am constantly picking at these things. You can run most everything with
+a `cargo test`.
+
#### 1.1
We want to go from hex (i.e., base 16) to base64 (i.e., base.. uh, 64). So
@@ -25,10 +28,13 @@ equality:
$ diff <(xxd -r -p data/s1/q1_input.txt | base64) data/s1/q1_output.txt
+In Rust it's easy enough to just use the appropriate functionality from the
+`hex` and `base64` crates.
+
#### 1.2
Fixed-xor just encrypts by XOR'ing every bit with some corresponding bit.
-An example, using `xxd` to output bits this time:
+An example, using `xxd -b` to output bits this time:
$ parallel -k 'echo -n {} | xxd -b' ::: FAB ICE
00000000: 01000110 01000001 01000010 FAB
@@ -48,17 +54,27 @@ zero-padded:
$ echo 'obase=16; ibase=2; 000011110000001000000111' | bc
F0207
-The `fixed_xor` binary in `./bin` will perform the reverse task here:
+The `fixed_xor` binary in `./bin` will perform the reverse task on the
+zero-padded string here:
$ ./bin/fixed_xor '0f0207' $(echo -n ICE | xxd -p) | xxd -r -p
FAB
-Running `fixed_xor` on the question input:
+The Rust implementation is trivial:
+
+ fn fixed_xor(target: &[u8], partner: &[u8]) -> Vec<u8> {
+ target.iter()
+ .zip(partner)
+ .map(|(l, r)| l ^ r)
+ .collect()
+ }
+
+And running `fixed_xor` on the question input yields the following:
$ SOLUTION=$(./bin/fixed_xor $(< data/s1/q2_input.txt) $(< data/s1/q2_against.txt))
746865206b696420646f6e277420706c6179
-Note that the ASCII-encoded output is fun:
+The ASCII encoding is fun:
$ echo $SOLUTION | xxd -r -p
the kid don't play
diff --git a/docs/s2.md b/docs/s2.md
@@ -67,3 +67,9 @@ Check out [the Rust source][src] to see a sane version.
[src]: https://github.com/jtobin/cryptopals/blob/master/src/s2c11.rs
+#### 2.12
+
+I found the text to this question to be incredibly sloppy and hard to follow.
+Maybe my own shortcoming.
+
+
diff --git a/src/errors.rs b/src/errors.rs
@@ -3,57 +3,60 @@ extern crate hex;
use std::error;
use std::fmt;
-use std::process;
-use std::string;
+// use std::process;
+use std::result;
+// use std::string;
-pub enum CryptopalsError {
- HexConversionError(hex::FromHexError),
- Utf8ConversionError(string::FromUtf8Error)
+pub type Possibly<T> = result::Result<T, CPError>;
+
+pub enum CPError {
+ HexConversion(hex::FromHexError),
+// Utf8Conversion(string::FromUtf8Error)
}
-impl fmt::Display for CryptopalsError {
+impl fmt::Display for CPError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
- CryptopalsError::HexConversionError(ref err) =>
+ CPError::HexConversion(ref err) =>
fmt::Display::fmt(err, f),
- CryptopalsError::Utf8ConversionError(ref err) =>
- fmt::Display::fmt(err, f)
+// CPError::Utf8Conversion(ref err) =>
+// fmt::Display::fmt(err, f)
}
}
}
-impl error::Error for CryptopalsError {
+impl error::Error for CPError {
fn description(&self) -> &str {
match *self {
- CryptopalsError::HexConversionError(ref err) => err.description(),
- CryptopalsError::Utf8ConversionError(ref err) => err.description()
+ CPError::HexConversion(ref err) => err.description(),
+// CPError::Utf8Conversion(ref err) => err.description()
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
- CryptopalsError::HexConversionError(ref err) => Some(err),
- CryptopalsError::Utf8ConversionError(ref err) => Some(err)
+ CPError::HexConversion(ref err) => Some(err),
+// CPError::Utf8Conversion(ref err) => Some(err)
}
}
}
-impl fmt::Debug for CryptopalsError {
+impl fmt::Debug for CPError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
- CryptopalsError::HexConversionError(ref err) =>
+ CPError::HexConversion(ref err) =>
fmt::Debug::fmt(err, f),
- CryptopalsError::Utf8ConversionError(ref err) =>
- fmt::Debug::fmt(err, f)
+// CPError::Utf8Conversion(ref err) =>
+// fmt::Debug::fmt(err, f)
}
}
}
-pub fn handle<A>(input: Result<A, CryptopalsError>) -> A {
- input.unwrap_or_else(|err| {
- println!("error (cryptopals):\n {}", err);
- process::exit(1);
- })
-}
+// pub fn handle<A>(input: Result<A, CPError>) -> A {
+// input.unwrap_or_else(|err| {
+// println!("cryptopals (error):\n {}", err);
+// process::exit(1);
+// })
+// }
diff --git a/src/main.rs b/src/main.rs
@@ -2,22 +2,24 @@
mod s1c01;
mod s1c02;
mod s1c03;
-mod s1c07;
-
-mod s2c09;
-mod s2c10;
-mod s2c11;
-mod s2c12;
+// mod s1c07;
+//
+// mod s2c09;
+// mod s2c10;
+// mod s2c11;
+// mod s2c12;
+// mod s2c13;
mod errors;
-
-fn main() {
- println!("s1c01:\n{}\n", errors::handle(s1c01::s1c01()));
- println!("s1c02:\n{}\n", errors::handle(s1c02::s1c02()));
- println!("s1c03:\n{}\n", errors::handle(s1c03::s1c03()));
- println!("s1c07:\n{}\n", s1c07::s1c07());
- println!("s2c09:\n{}\n", s2c09::s2c09());
- println!("s2c10:\n{}\n", s2c10::s2c10());
- println!("s2c11:\n{}\n", s2c11::s2c11());
- println!("s2c12:\n{}\n", s2c12::s2c12());
-}
+//
+// fn main() {
+// println!("s1c01:\n{}\n", errors::handle(s1c01::s1c01()));
+// println!("s1c02:\n{}\n", errors::handle(s1c02::s1c02()));
+// // println!("s1c03:\n{}\n", errors::handle(s1c03::s1c03()));
+// // println!("s1c07:\n{}\n", s1c07::s1c07());
+// // println!("s2c09:\n{}\n", s2c09::s2c09());
+// // println!("s2c10:\n{}\n", s2c10::s2c10());
+// // println!("s2c11:\n{}\n", s2c11::s2c11());
+// // println!("s2c12:\n{}\n", s2c12::s2c12());
+// // println!("s2c13:\n{}\n", s2c13::s2c13());
+// }
diff --git a/src/s1c01.rs b/src/s1c01.rs
@@ -2,21 +2,24 @@
extern crate base64;
extern crate hex;
-use errors::CryptopalsError;
-use self::hex::FromHex;
+use errors::{Possibly, CPError};
-const INPUT: &str =
- "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6\
- f7573206d757368726f6f6d";
+pub fn hex_to_b64(hex: &str) -> Possibly<String> {
+ let bytes: Possibly<Vec<u8>> =
+ hex::decode(&hex)
+ .map_err(|err| CPError::HexConversion(err));
-pub fn hex_to_b64(input: &str) -> Result<String, CryptopalsError> {
- let raw: Result<Vec<u8>, _> = FromHex::from_hex(&input)
- .map_err(|err| CryptopalsError::HexConversionError(err));
-
- raw.map(|contents| base64::encode(&contents))
+ bytes.map(|bs| base64::encode(&bs))
}
-pub fn s1c01() -> Result<String, CryptopalsError> {
- hex_to_b64(INPUT)
+#[test]
+fn test_hex_to_b64() {
+ const INPUT: &str = "49276d206b696c6c696e6720796f757220627261696e206c696b6\
+ 5206120706f69736f6e6f7573206d757368726f6f6d";
+
+ const OUTPUT: &str = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3Vz\
+ IG11c2hyb29t";
+ let b64 = hex_to_b64(INPUT).unwrap();
+ assert_eq!(OUTPUT, b64);
}
diff --git a/src/s1c02.rs b/src/s1c02.rs
@@ -1,9 +1,6 @@
extern crate hex;
-use errors::CryptopalsError;
-use self::hex::{FromHex, ToHex};
-
const TARGET: &str = "1c0111001f010100061a024b53535009181c";
const PARTNER: &str = "686974207468652062756c6c277320657965";
@@ -14,22 +11,12 @@ pub fn fixed_xor(target: &[u8], partner: &[u8]) -> Vec<u8> {
.collect()
}
-pub fn s1c02() -> Result<String, CryptopalsError> {
- let target: Result<Vec<u8>, _> = FromHex::from_hex(&TARGET)
- .map_err(|err| CryptopalsError::HexConversionError(err));
-
- let target = match target {
- Ok(val) => val,
- Err(err) => return Err(err)
- };
-
- let partner: Result<Vec<u8>, _> = FromHex::from_hex(&PARTNER)
- .map_err(|err| CryptopalsError::HexConversionError(err));
-
- let partner = match partner {
- Ok(val) => val,
- Err(err) => return Err(err)
- };
-
- Ok(fixed_xor(&target, &partner).to_hex())
+#[test]
+fn test_fixed_xor() {
+ let hex0 = hex::decode(TARGET).unwrap();
+ let hex1 = hex::decode(PARTNER).unwrap();
+ let xor = fixed_xor(&hex0, &hex1);
+ let expected = "746865206b696420646f6e277420706c6179";
+ assert_eq!(hex::encode(xor), expected)
}
+
diff --git a/src/s1c03.rs b/src/s1c03.rs
@@ -1,14 +1,10 @@
extern crate hex;
-use errors::CryptopalsError;
use std::collections::HashMap;
use std::f32;
use std::u8;
-const INPUT: &'static str =
- "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736";
-
fn tally(vec: Vec<u8>) -> HashMap<u8, u8> {
let mut hashmap = HashMap::new();
@@ -185,19 +181,14 @@ pub fn break_single_byte_xor(bytes: &[u8]) -> (u8, Vec<u8>) {
(min.1, min.0)
}
-pub fn s1c03() -> Result<String, CryptopalsError> {
- let ciphertext: Result<Vec<u8>, CryptopalsError> =
- hex::FromHex::from_hex(INPUT)
- .map_err(|err| CryptopalsError::HexConversionError(err));
-
- let ciphertext = match ciphertext {
- Ok(val) => val,
- Err(err) => return Err(err)
- };
+#[test]
+fn test_break_single_byte_xor() {
+ const INPUT: &'static str =
+ "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736";
+ let ciphertext = hex::decode(INPUT).unwrap();
let message = break_single_byte_xor(&ciphertext).1;
-
- String::from_utf8(message)
- .map_err(|err| CryptopalsError::Utf8ConversionError(err))
+ let output = String::from_utf8(message).unwrap();
+ assert_eq!(output, "Cooking MC's like a pound of bacon");
}
diff --git a/src/s2c13.rs b/src/s2c13.rs
@@ -0,0 +1,43 @@
+
+extern crate combine;
+
+use self::combine::{many1, sep_by, token, none_of};
+// use self::combine::char::letter;
+
+pub fn foo(input: String) -> String {
+ let metachars = "&=".iter().cloned();
+ let word = many1(none_of(metachars));
+ let pair = sep_by(word, token('='));
+ let pairs = sep_by(pair, token('&'));
+
+ String::from("hello")
+}
+
+
+pub fn s2c13() -> String{
+ String::from("foo")
+}
+
+
+
+// pub fn s2c13() -> String {
+// // FIXME & is not right here - there shouldn't be a hanging &
+// let structured_cookie = Regex::new(r"([A-Za-z]+=[^&=]*&?)*").unwrap();
+//
+// let test = structured_cookie.captures("foo=bar&baz=quux").unwrap();
+//
+// println!("{} {}", test.get(0).unwrap().as_str(), test.get(1).unwrap().as_str());
+//
+// String::from("foo")
+// }
+
+//
+// foo=bar&baz=qux
+//
+// parse that into some kind of json
+//
+// {
+// 'foo': 'bar',
+// 'baz': 'qux'
+// }
+//