cryptopals

Matasano's cryptopals challenges (cryptopals.com).
Log | Files | Refs | README | LICENSE

commit c02b362176501c3b0af17045c93f6aabdd85c66a
parent 55683ed479361e05ea312b3d9e126c810fdace97
Author: Jared Tobin <jared@jtobin.ca>
Date:   Wed, 30 Aug 2017 21:06:54 +1200

Updates.

Diffstat:
Msrc/main.rs | 3+++
Msrc/s1c2.rs | 3---
Msrc/s1c7.rs | 6+++---
Asrc/s2c10.rs | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 108 insertions(+), 6 deletions(-)

diff --git a/src/main.rs b/src/main.rs @@ -4,9 +4,12 @@ mod s1c2; mod s1c3; mod s1c7; +mod s2c10; + fn main() { println!("s1c1:\n{}\n", s1c1::s1c1()); println!("s1c2:\n{}\n", s1c2::s1c2()); println!("s1c3:\n{}\n", s1c3::s1c3()); println!("s1c7:\n{}\n", s1c7::s1c7()); + println!("s2c10:\n{}\n", s2c10::s2c10()); } diff --git a/src/s1c2.rs b/src/s1c2.rs @@ -7,9 +7,6 @@ const TARGET: &str = "1c0111001f010100061a024b53535009181c"; const PARTNER: &str = "686974207468652062756c6c277320657965"; fn fixed_xor(target: &str, partner: &str) -> String { - - assert_eq!(target.len(), partner.len()); - let mut l: Vec<u8> = FromHex::from_hex(&target).unwrap(); let r: Vec<u8> = FromHex::from_hex(&partner).unwrap(); diff --git a/src/s1c7.rs b/src/s1c7.rs @@ -3,12 +3,12 @@ extern crate base64; extern crate openssl; use self::openssl::symm::{Cipher, Crypter, Mode}; -use std::io::prelude::Read; use std::fs::File; +use std::io::prelude::Read; use std::str; use std::string::String; -fn new_crypter_unpadded( +pub fn new_crypter_unpadded( cipher: Cipher, mode: Mode, key: &[u8], @@ -22,7 +22,7 @@ fn new_crypter_unpadded( crypter } -fn aes_128_ecb_crypt(mode: Mode, key: &[u8], content: &[u8]) -> Vec<u8> { +pub fn aes_128_ecb_crypt(mode: Mode, key: &[u8], content: &[u8]) -> Vec<u8> { let cipher = Cipher::aes_128_ecb(); let iv = None; let bsize = content.len() + cipher.key_len(); diff --git a/src/s2c10.rs b/src/s2c10.rs @@ -0,0 +1,102 @@ + +extern crate base64; +extern crate hex; +extern crate openssl; + +use s1c7::aes_128_ecb_crypt; +use std::fs::File; +use self::openssl::symm::Mode; +use std::io::Read; +use std::str; + +const BLOCK_SIZE: usize = 16; + +fn fixed_xor(target: &[u8], partner: &[u8]) -> Vec<u8> { + target.iter() + .zip(partner) + .map(|(l, r)| l ^ r) + .collect() +} + +pub fn aes_128_cbc_crypt( + mode: Mode + , key: &[u8] + , iv: &[u8] + , contents: &[u8] + ) -> Vec<u8> { + + let mut buffer = Vec::with_capacity(contents.len()); + + match mode { + Mode::Encrypt => { + contents.chunks(BLOCK_SIZE).fold(iv.to_vec(), + |i, block| { + let xored = fixed_xor(&i, block); + let encrypted = aes_128_ecb_crypt(mode, key, &xored); + + buffer.extend(&encrypted); + encrypted + }); + }, + Mode::Decrypt => { + contents.chunks(BLOCK_SIZE).fold(iv.to_vec(), + |i, block| { + let decrypted = aes_128_ecb_crypt(mode, key, block); + let xored = fixed_xor(&decrypted, &i); + + buffer.extend(&xored); + block.to_vec() + }); + } + } + + buffer +} + +pub fn aes_128_cbc_decrypt(key: &str, iv: &str, ciphertext: &str) -> String { + let key: Vec<u8> = base64::decode(&key).unwrap(); + let iv: Vec<u8> = base64::decode(&iv).unwrap(); + let ciphertext: Vec<u8> = base64::decode(&ciphertext).unwrap(); + + let message = + aes_128_cbc_crypt(Mode::Decrypt, &key[..], &iv[..], &ciphertext[..]); + + base64::encode(&message) +} + +pub fn aes_128_cbc_encrypt(key: &str, iv: &str, message: &str) -> String { + let key: Vec<u8> = base64::decode(&key).unwrap(); + let iv: Vec<u8> = base64::decode(&iv).unwrap(); + let message: Vec<u8> = base64::decode(&message).unwrap(); + + let ciphertext = + aes_128_cbc_crypt(Mode::Encrypt, &key[..], &iv[..], &message[..]); + + base64::encode(&ciphertext) +} + + +pub fn s2c10() -> String { + let key = base64::encode("YELLOW SUBMARINE"); + let mut handle = File::open("data/s2/q10_input.txt").unwrap(); + let mut buffer = String::new(); + + let bsize = handle.read_to_string(&mut buffer); + + if let Err(err) = bsize { + panic!("{}", err); + } + + let trimmed: String = buffer.chars() + .filter(|&char| char != '\n') + .collect(); + + let iv = vec![0u8; BLOCK_SIZE]; + let iv = base64::encode(&iv); + + let decrypted = aes_128_cbc_decrypt(&key, &iv, &trimmed); + let decrypted = base64::decode(&decrypted).unwrap(); + + String::from_utf8(decrypted).unwrap() +} +