Remove duplicated code and make base64 error handling better
parent
fbf26efa44
commit
5158c16d56
|
@ -0,0 +1,64 @@
|
|||
CRIwqt4+szDbqkNY+I0qbDe3LQz0wiw0SuxBQtAM5TDdMbjCMD/venUDW9BL
|
||||
PEXODbk6a48oMbAY6DDZsuLbc0uR9cp9hQ0QQGATyyCESq2NSsvhx5zKlLtz
|
||||
dsnfK5ED5srKjK7Fz4Q38/ttd+stL/9WnDzlJvAo7WBsjI5YJc2gmAYayNfm
|
||||
CW2lhZE/ZLG0CBD2aPw0W417QYb4cAIOW92jYRiJ4PTsBBHDe8o4JwqaUac6
|
||||
rqdi833kbyAOV/Y2RMbN0oDb9Rq8uRHvbrqQJaJieaswEtMkgUt3P5Ttgeh7
|
||||
J+hE6TR0uHot8WzHyAKNbUWHoi/5zcRCUipvVOYLoBZXlNu4qnwoCZRSBgvC
|
||||
wTdz3Cbsp/P2wXB8tiz6l9rL2bLhBt13Qxyhhu0H0+JKj6soSeX5ZD1Rpilp
|
||||
9ncR1tHW8+uurQKyXN4xKeGjaKLOejr2xDIw+aWF7GszU4qJhXBnXTIUUNUf
|
||||
RlwEpS6FZcsMzemQF30ezSJHfpW7DVHzwiLyeiTJRKoVUwo43PXupnJXDmUy
|
||||
sCa2nQz/iEwyor6kPekLv1csm1Pa2LZmbA9Ujzz8zb/gFXtQqBAN4zA8/wt0
|
||||
VfoOsEZwcsaLOWUPtF/Ry3VhlKwXE7gGH/bbShAIKQqMqqUkEucZ3HPHAVp7
|
||||
ZCn3Ox6+c5QJ3Uv8V7L7SprofPFN6F+kfDM4zAc59do5twgDoClCbxxG0L19
|
||||
TBGHiYP3CygeY1HLMrX6KqypJfFJW5O9wNIF0qfOC2lWFgwayOwq41xdFSCW
|
||||
0/EBSc7cJw3N06WThrW5LimAOt5L9c7Ik4YIxu0K9JZwAxfcU4ShYu6euYmW
|
||||
LP98+qvRnIrXkePugS9TSOJOHzKUoOcb1/KYd9NZFHEcp58Df6rXFiz9DSq8
|
||||
0rR5Kfs+M+Vuq5Z6zY98/SP0A6URIr9NFu+Cs9/gf+q4TRwsOzRMjMQzJL8f
|
||||
7TXPEHH2+qEcpDKz/5pE0cvrgHr63XKu4XbzLCOBz0DoFAw3vkuxGwJq4Cpx
|
||||
kt+eCtxSKUzNtXMn/mbPqPl4NZNJ8yzMqTFSODS4bYTBaN/uQYcOAF3NBYFd
|
||||
5x9TzIAoW6ai13a8h/s9i5FlVRJDe2cetQhArrIVBquF0L0mUXMWNPFKkaQE
|
||||
BsxpMCYh7pp7YlyCNode12k5jY1/lc8jQLQJ+EJHdCdM5t3emRzkPgND4a7O
|
||||
NhoIkUUS2R1oEV1toDj9iDzGVFwOvWyt4GzA9XdxT333JU/n8m+N6hs23MBc
|
||||
Z086kp9rJGVxZ5f80jRz3ZcjU6zWjR9ucRyjbsuVn1t4EJEm6A7KaHm13m0v
|
||||
wN/O4KYTiiY3aO3siayjNrrNBpn1OeLv9UUneLSCdxcUqjRvOrdA5NYv25Hb
|
||||
4wkFCIhC/Y2ze/kNyis6FrXtStcjKC1w9Kg8O25VXB1Fmpu+4nzpbNdJ9LXa
|
||||
hF7wjOPXN6dixVKpzwTYjEFDSMaMhaTOTCaqJig97624wv79URbCgsyzwaC7
|
||||
YXRtbTstbFuEFBee3uW7B3xXw72mymM2BS2uPQ5NIwmacbhta8aCRQEGqIZ0
|
||||
78YrrOlZIjar3lbTCo5o6nbbDq9bvilirWG/SgWINuc3pWl5CscRcgQQNp7o
|
||||
LBgrSkQkv9AjZYcvisnr89TxjoxBO0Y93jgp4T14LnVwWQVx3l3d6S1wlsci
|
||||
dVeaM24E/JtS8k9XAvgSoKCjyiqsawBMzScXCIRCk6nqX8ZaJU3rZ0LeOMTU
|
||||
w6MC4dC+aY9SrCvNQub19mBdtJUwOBOqGdfd5IoqQkaL6DfOkmpnsCs5PuLb
|
||||
GZBVhah5L87IY7r6TB1V7KboXH8PZIYc1zlemMZGU0o7+etxZWHgpdeX6JbJ
|
||||
Is3ilAzYqw/Hz65no7eUxcDg1aOaxemuPqnYRGhW6PvjZbwAtfQPlofhB0jT
|
||||
Ht5bRlzF17rn9q/6wzlc1ssp2xmeFzXoxffpELABV6+yj3gfQ/bxIB9NWjdZ
|
||||
K08RX9rjm9CcBlRQeTZrD67SYQWqRpT5t7zcVDnx1s7ZffLBWm/vXLfPzMaQ
|
||||
YEJ4EfoduSutjshXvR+VQRPs2TWcF7OsaE4csedKUGFuo9DYfFIHFDNg+1Py
|
||||
rlWJ0J/X0PduAuCZ+uQSsM/ex/vfXp6Z39ngq4exUXoPtAIqafrDMd8SuAty
|
||||
EZhyY9V9Lp2qNQDbl6JI39bDz+6pDmjJ2jlnpMCezRK89cG11IqiUWvIPxHj
|
||||
oiT1guH1uk4sQ2Pc1J4zjJNsZgoJDcPBbfss4kAqUJvQyFbzWshhtVeAv3dm
|
||||
gwUENIhNK/erjpgw2BIRayzYw001jAIF5c7rYg38o6x3YdAtU3d3QpuwG5xD
|
||||
fODxzfL3yEKQr48C/KqxI87uGwyg6H5gc2AcLU9JYt5QoDFoC7PFxcE3RVqc
|
||||
7/Um9Js9X9UyriEjftWt86/tEyG7F9tWGxGNEZo3MOydwX/7jtwoxQE5ybFj
|
||||
WndqLp8DV3naLQsh/Fz8JnTYHvOR72vuiw/x5D5PFuXV0aSVvmw5Wnb09q/B
|
||||
owS14WzoHH6ekaWbh78xlypn/L/M+nIIEX1Ol3TaVOqIxvXZ2sjm86xRz0Ed
|
||||
oHFfupSekdBULCqptxpFpBshZFvauUH8Ez7wA7wjL65GVlZ0f74U7MJVu9Sw
|
||||
sZdgsLmnsQvr5n2ojNNBEv+qKG2wpUYTmWRaRc5EClUNfhzh8iDdHIsl6edO
|
||||
ewORRrNiBay1NCzlfz1cj6VlYYQUM9bDEyqrwO400XQNpoFOxo4fxUdd+AHm
|
||||
CBhHbyCR81/C6LQTG2JQBvjykG4pmoqnYPxDyeiCEG+JFHmP1IL+jggdjWhL
|
||||
WQatslrWxuESEl3PEsrAkMF7gt0dBLgnWsc1cmzntG1rlXVi/Hs2TAU3RxEm
|
||||
MSWDFubSivLWSqZj/XfGWwVpP6fsnsfxpY3d3h/fTxDu7U8GddaFRQhJ+0ZO
|
||||
dx6nRJUW3u6xnhH3mYVRk88EMtpEpKrSIWfXphgDUPZ0f4agRzehkn9vtzCm
|
||||
NjFnQb0/shnqTh4Mo/8oommbsBTUKPYS7/1oQCi12QABjJDt+LyUan+4iwvC
|
||||
i0k0IUIHvk21381vC0ixYDZxzY64+xx/RNID+iplgzq9PDZgjc8L7jMg+2+m
|
||||
rxPS56e71m5E2zufZ4d+nFjIg+dHD/ShNPzVpXizRVUERztLuak8Asah3/yv
|
||||
wOrH1mKEMMGC1/6qfvZUgFLJH5V0Ep0n2K/Fbs0VljENIN8cjkCKdG8aBnef
|
||||
EhITdV7CVjXcivQ6efkbOQCfkfcwWpaBFC8tD/zebXFE+JshW16D4EWXMnSm
|
||||
/9HcGwHvtlAj04rwrZ5tRvAgf1IR83kqqiTvqfENcj7ddCFwtNZrQK7EJhgB
|
||||
5Tr1tBFcb9InPRtS3KYteYHl3HWR9t8E2YGE8IGrS1sQibxaK/C0kKbqIrKp
|
||||
npwtoOLsZPNbPw6K2jpko9NeZAx7PYFmamR4D50KtzgELQcaEsi5aCztMg7f
|
||||
p1mK6ijyMKIRKwNKIYHagRRVLNgQLg/WTKzGVbWwq6kQaQyArwQCUXo4uRty
|
||||
zGMaKbTG4dns1OFB1g7NCiPb6s1lv0/lHFAF6HwoYV/FPSL/pirxyDSBb/FR
|
||||
RA3PIfmvGfMUGFVWlyS7+O73l5oIJHxuaJrR4EenzAu4Avpa5d+VuiYbM10a
|
||||
LaVegVPvFn4pCP4U/Nbbw4OTCFX2HKmWEiVBB0O3J9xwXWpxN1Vr5CDi75Fq
|
||||
NhxYCjgSJzWOUD34Y1dAfcj57VINmQVEWyc8Tch8vg9MnHGCOfOjRqp0VGyA
|
||||
S15AVD2QS1V6fhRimJSVyT6QuGb8tKRsl2N+a2Xze36vgMhw7XK7zh//jC2H
|
|
@ -55,7 +55,7 @@ impl BytesBase64 {
|
|||
Bytes(v.chunks(4).map(|c| to_bytes(c)).flatten().collect())
|
||||
}
|
||||
|
||||
pub fn from_base64(s: &str) -> BytesBase64 {
|
||||
pub fn from_base64(s: &str) -> Result<BytesBase64, String> {
|
||||
let mut r: Vec<u8> = Vec::with_capacity(s.len());
|
||||
for c in s.chars() {
|
||||
match c {
|
||||
|
@ -64,10 +64,15 @@ impl BytesBase64 {
|
|||
'0'..='9' => r.push((c as u8) - ('0' as u8) + 52),
|
||||
'+' => r.push(62),
|
||||
'/' => r.push(63),
|
||||
_ => (),
|
||||
'\n' => (),
|
||||
'=' => (),
|
||||
' ' => (),
|
||||
_ => {
|
||||
return Err(format!("Unexpected character '{}'", c));
|
||||
}
|
||||
}
|
||||
}
|
||||
BytesBase64(r)
|
||||
Ok(BytesBase64(r))
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
|
|
|
@ -13,7 +13,7 @@ mod set4;
|
|||
mod utils;
|
||||
|
||||
fn main() {
|
||||
const RUN_ALL: bool = false;
|
||||
const RUN_ALL: bool = true;
|
||||
if RUN_ALL {
|
||||
set1::challenge1();
|
||||
set1::challenge2();
|
||||
|
|
41
src/set1.rs
41
src/set1.rs
|
@ -1,8 +1,8 @@
|
|||
#![allow(dead_code)]
|
||||
use crate::bytes::Bytes;
|
||||
use crate::bytes_base64::BytesBase64;
|
||||
use crate::ecb;
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use crate::{ecb, utils};
|
||||
use std::io::Write;
|
||||
use std::str;
|
||||
|
||||
pub fn challenge1() {
|
||||
|
@ -38,15 +38,7 @@ pub fn challenge3() {
|
|||
}
|
||||
|
||||
pub fn challenge4() {
|
||||
fn read(path: &str) -> Vec<Bytes> {
|
||||
let file = std::fs::File::open(path).unwrap();
|
||||
let br = BufReader::new(file);
|
||||
br.lines()
|
||||
.map(|line| Bytes::from_hex(&line.unwrap()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
let bytes_vector = read("data/4.txt");
|
||||
let bytes_vector = utils::read_hex_lines("data/4.txt");
|
||||
let mut xored_bytes_vector: Vec<Bytes> = vec![];
|
||||
for i in 32..=127 {
|
||||
for bytes in bytes_vector.iter() {
|
||||
|
@ -73,11 +65,6 @@ pub fn challenge5() {
|
|||
}
|
||||
|
||||
pub fn challenge6() {
|
||||
fn read(path: &str) -> Bytes {
|
||||
let s = std::fs::read_to_string(path).unwrap();
|
||||
BytesBase64::from_base64(&s).to_bytes()
|
||||
}
|
||||
|
||||
fn _write(path: &str, bytes_base64: &BytesBase64) {
|
||||
let width = 60;
|
||||
let bytes = bytes_base64.to_string();
|
||||
|
@ -96,7 +83,7 @@ pub fn challenge6() {
|
|||
|
||||
fn _test_roundtrip() {
|
||||
// Test that conversion from to bytes and back works
|
||||
let bytes = read("data/6.txt");
|
||||
let bytes = utils::read_base64("data/6.txt");
|
||||
let bytes_base64 = BytesBase64::from_bytes(bytes);
|
||||
_write("data/6.txt", &bytes_base64);
|
||||
}
|
||||
|
@ -139,7 +126,7 @@ pub fn challenge6() {
|
|||
}
|
||||
|
||||
_test_roundtrip();
|
||||
let bytes = read("data/6.txt");
|
||||
let bytes = utils::read_base64("data/6.txt");
|
||||
let key_size = guess_key_size(&bytes);
|
||||
let bytes_tranposed = transpose(&bytes, key_size);
|
||||
let key = Bytes(
|
||||
|
@ -155,10 +142,6 @@ pub fn challenge6() {
|
|||
}
|
||||
|
||||
pub fn challenge7() {
|
||||
fn read(path: &str) -> Bytes {
|
||||
let s = std::fs::read_to_string(path).unwrap();
|
||||
BytesBase64::from_base64(&s).to_bytes()
|
||||
}
|
||||
let text = Bytes::from_utf8("We meet at burger king!");
|
||||
let key = Bytes::from_utf8("YELLOW SUBMARINE");
|
||||
let ciphertext = ecb::encrypt(&key, &text);
|
||||
|
@ -166,21 +149,13 @@ pub fn challenge7() {
|
|||
if text != roundtrip {
|
||||
panic!("ECB roundtrip not working.");
|
||||
}
|
||||
let ciphertext = read("data/7.txt");
|
||||
let ciphertext = utils::read_base64("data/7.txt");
|
||||
let data = ecb::decrypt(&key, &ciphertext);
|
||||
let partial_msg = data.to_utf8()[..20].to_string();
|
||||
println!("[okay] Challenge 7: {}...", partial_msg);
|
||||
}
|
||||
|
||||
pub fn challenge8() {
|
||||
fn read(path: &str) -> Vec<Bytes> {
|
||||
let file = std::fs::File::open(path).unwrap();
|
||||
let br = BufReader::new(file);
|
||||
br.lines()
|
||||
.map(|line| Bytes::from_hex(&line.unwrap()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn rate(Bytes(v): &Bytes, size: usize) -> u32 {
|
||||
let mut rating = 0;
|
||||
let chunks: Vec<&[u8]> = v.chunks(size).collect();
|
||||
|
@ -193,7 +168,7 @@ pub fn challenge8() {
|
|||
}
|
||||
|
||||
let expected_index: usize = 132;
|
||||
let bytes_vector = read("data/8.txt");
|
||||
let bytes_vector = utils::read_hex_lines("data/8.txt");
|
||||
let ratings: Vec<u32> = bytes_vector.iter().map(|b| rate(&b, 16)).collect();
|
||||
let min_rating = ratings.iter().min().unwrap();
|
||||
let index = ratings.iter().position(|e| e == min_rating).unwrap();
|
||||
|
@ -208,7 +183,7 @@ pub fn challenge8() {
|
|||
);
|
||||
|
||||
// More elegant solution.
|
||||
let bytes_vector = read("data/8.txt");
|
||||
let bytes_vector = utils::read_hex_lines("data/8.txt");
|
||||
let ix: Vec<usize> = bytes_vector
|
||||
.iter()
|
||||
.enumerate()
|
||||
|
|
26
src/set2.rs
26
src/set2.rs
|
@ -1,8 +1,8 @@
|
|||
use crate::bytes::Bytes;
|
||||
use crate::bytes_base64::BytesBase64;
|
||||
use crate::cbc;
|
||||
use crate::ecb;
|
||||
use crate::parser;
|
||||
use crate::utils;
|
||||
use rand::Rng;
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
@ -13,10 +13,6 @@ pub fn challenge9() {
|
|||
}
|
||||
|
||||
pub fn challenge10() {
|
||||
fn read(path: &str) -> Bytes {
|
||||
let s = std::fs::read_to_string(path).unwrap();
|
||||
BytesBase64::from_base64(&s).to_bytes()
|
||||
}
|
||||
let iv = Bytes(vec![0; 16]);
|
||||
let key = Bytes::from_utf8("YELLOW SUBMARINE");
|
||||
|
||||
|
@ -24,7 +20,7 @@ pub fn challenge10() {
|
|||
let ciphertext = cbc::encrypt(&key, &iv, &text);
|
||||
let roundtrip = cbc::decrypt(&key, &iv, &ciphertext);
|
||||
if text == roundtrip {
|
||||
let ciphertext = read("data/10.txt");
|
||||
let ciphertext = utils::read_base64("data/10.txt");
|
||||
let cleartext = cbc::decrypt(&key, &iv, &ciphertext);
|
||||
let output = cleartext.to_utf8()[..16].to_string();
|
||||
println!("[okay] Challenge 10: {}", output);
|
||||
|
@ -104,16 +100,11 @@ pub fn challenge11() {
|
|||
}
|
||||
|
||||
pub fn challenge12() {
|
||||
fn read(path: &str) -> Bytes {
|
||||
let s = std::fs::read_to_string(path).unwrap();
|
||||
BytesBase64::from_base64(&s).to_bytes()
|
||||
}
|
||||
|
||||
fn encryption_oracle(key: &Bytes, Bytes(data): &Bytes) -> Bytes {
|
||||
// Copy your oracle function to a new function that encrypts buffers under ECB mode using a consistent but unknown key
|
||||
// Now take that same function and have it append to the plaintext, BEFORE ENCRYPTING, the following string (from 12.txt):
|
||||
let mut data = data.to_vec();
|
||||
let mut string = read("data/12.txt");
|
||||
let mut string = utils::read_base64("data/12.txt");
|
||||
data.append(&mut string.0);
|
||||
let cipher = ecb::encrypt(&key, &Bytes(data));
|
||||
cipher
|
||||
|
@ -184,7 +175,7 @@ pub fn challenge12() {
|
|||
assert_eq!(get_block_size(&key), 16); // 1. discover block size
|
||||
assert_eq!(is_encryption_ecb(&key), true); // 2. confirm oracle uses ecb
|
||||
let roundtrip_text = decode(&key); // 3.-6.
|
||||
let cleartext = read("data/12.txt");
|
||||
let cleartext = utils::read_base64("data/12.txt");
|
||||
|
||||
// 138 (instead of 139); I think we get one additional byte because we guess
|
||||
// the first padding byte. The right approach would be to remove the last
|
||||
|
@ -254,11 +245,6 @@ pub fn challenge13() {
|
|||
}
|
||||
|
||||
pub fn challenge14() {
|
||||
fn read(path: &str) -> Bytes {
|
||||
let s = std::fs::read_to_string(path).unwrap();
|
||||
BytesBase64::from_base64(&s).to_bytes()
|
||||
}
|
||||
|
||||
fn encryption_oracle(
|
||||
Bytes(random_prefix): &Bytes,
|
||||
random_key: &Bytes,
|
||||
|
@ -271,7 +257,7 @@ pub fn challenge14() {
|
|||
// long it is and then adjust the decoding routine.
|
||||
let mut plaintext = random_prefix.to_vec();
|
||||
plaintext.append(&mut attacker_controlled.to_vec());
|
||||
let mut target_bytes = read("data/12.txt").0;
|
||||
let mut target_bytes = utils::read_base64("data/12.txt").0;
|
||||
plaintext.append(&mut target_bytes);
|
||||
let cipher = ecb::encrypt(&random_key, &Bytes(plaintext));
|
||||
cipher
|
||||
|
@ -383,7 +369,7 @@ pub fn challenge14() {
|
|||
let prefix_len = get_prefix_size(&prefix, &key);
|
||||
assert_eq!(prefix.len(), prefix_len);
|
||||
let roundtrip_text = decode(&prefix, &key);
|
||||
let cleartext = read("data/12.txt");
|
||||
let cleartext = utils::read_base64("data/12.txt");
|
||||
assert_eq!(roundtrip_text, cleartext);
|
||||
println!(
|
||||
"[okay] Challenge 14: {}",
|
||||
|
|
34
src/set3.rs
34
src/set3.rs
|
@ -9,21 +9,12 @@ use rand::Rng;
|
|||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::io::{BufRead, BufReader};
|
||||
|
||||
pub fn challenge17() {
|
||||
fn read(path: &str) -> Vec<Bytes> {
|
||||
let file = std::fs::File::open(path).unwrap();
|
||||
let br = BufReader::new(file);
|
||||
br.lines()
|
||||
.map(|line| BytesBase64::from_base64(&line.unwrap()).to_bytes())
|
||||
.collect()
|
||||
}
|
||||
|
||||
let key = Bytes::random(16);
|
||||
let encrypt = || -> (Bytes, Bytes, usize) {
|
||||
// The first function should select at random one of the ten strings
|
||||
let cleartexts = read("data/17.txt");
|
||||
let cleartexts = utils::read_base64_lines("data/17.txt");
|
||||
let index: usize = rand::thread_rng().gen_range(0..cleartexts.len());
|
||||
let mut cleartext = Bytes(cleartexts[index].0.to_vec());
|
||||
|
||||
|
@ -95,7 +86,7 @@ pub fn challenge17() {
|
|||
roundtrip.0.append(&mut clear_block.0);
|
||||
}
|
||||
roundtrip.remove_pkcs7(16);
|
||||
let cleartexts = read("data/17.txt");
|
||||
let cleartexts = utils::read_base64_lines("data/17.txt");
|
||||
let cleartext = Bytes(cleartexts[cleartext_index].0.to_vec());
|
||||
assert_eq!(roundtrip, cleartext);
|
||||
println!("[okay] Challenge 17: {}", roundtrip.to_utf8());
|
||||
|
@ -112,20 +103,13 @@ pub fn challenge18() {
|
|||
let cipher = BytesBase64::from_base64(
|
||||
"L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ==",
|
||||
)
|
||||
.unwrap()
|
||||
.to_bytes();
|
||||
let cleartext = ctr::decrypt(&key, 0, &cipher).to_utf8();
|
||||
println!("[okay] Challenge 18: {cleartext}");
|
||||
}
|
||||
|
||||
pub fn challenge19() {
|
||||
fn read(path: &str) -> Vec<Bytes> {
|
||||
let file = std::fs::File::open(path).unwrap();
|
||||
let br = BufReader::new(file);
|
||||
br.lines()
|
||||
.map(|line| BytesBase64::from_base64(&line.unwrap()).to_bytes())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn xor_to_char_set(letters: &Vec<u8>) -> HashMap<u8, RefCell<HashSet<u8>>> {
|
||||
let mut h = HashMap::new();
|
||||
for i in 0..255_u8 {
|
||||
|
@ -255,7 +239,7 @@ pub fn challenge19() {
|
|||
decrypts[37].borrow_mut()[30] = b'i';
|
||||
}
|
||||
|
||||
let plaintexts = read("data/19.txt");
|
||||
let plaintexts = utils::read_base64_lines("data/19.txt");
|
||||
let key = Bytes::from_utf8("YELLOW SUBMARINE");
|
||||
let encrypt = |plaintext: &Bytes| -> Bytes { ctr::encrypt(&key, 0, plaintext) };
|
||||
let ciphers: Vec<Bytes> = plaintexts.iter().map(|ct| encrypt(&ct)).collect();
|
||||
|
@ -271,14 +255,6 @@ pub fn challenge19() {
|
|||
}
|
||||
|
||||
pub fn challenge20() {
|
||||
fn read(path: &str) -> Vec<Bytes> {
|
||||
let file = std::fs::File::open(path).unwrap();
|
||||
let br = BufReader::new(file);
|
||||
br.lines()
|
||||
.map(|line| BytesBase64::from_base64(&line.unwrap()).to_bytes())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn attack(ciphers: Vec<Bytes>) -> Vec<Bytes> {
|
||||
let min_cipher_len = ciphers.iter().map(|c| c.len()).min().unwrap_or(0);
|
||||
let mut key: Vec<u8> = vec![];
|
||||
|
@ -294,7 +270,7 @@ pub fn challenge20() {
|
|||
.collect()
|
||||
}
|
||||
|
||||
let plaintexts = read("data/20.txt");
|
||||
let plaintexts = utils::read_base64_lines("data/20.txt");
|
||||
let key = Bytes::from_utf8("YELLOW SUBMARINE");
|
||||
let encrypt = |plaintext: &Bytes| -> Bytes { ctr::encrypt(&key, 0, plaintext) };
|
||||
let ciphers: Vec<Bytes> = plaintexts.iter().map(|ct| encrypt(&ct)).collect();
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
use crate::{bytes::Bytes, utils};
|
||||
|
||||
pub fn challenge25() {
|
||||
println!("[xxxx] Challenge 25: TBD");
|
||||
let cipher = utils::read_base64("data/25.txt");
|
||||
let key = Bytes::from_utf8("YELLOW SUBMARINE");
|
||||
let _cleartext = crate::ecb::decrypt(&key, &cipher);
|
||||
|
||||
println!("[xxxx] Challenge 25: wip");
|
||||
}
|
||||
|
|
34
src/utils.rs
34
src/utils.rs
|
@ -1,4 +1,8 @@
|
|||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use crate::{bytes::Bytes, bytes_base64::BytesBase64};
|
||||
use std::{
|
||||
io::{BufRead, BufReader},
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
pub fn unix_timestamp() -> u32 {
|
||||
let start = SystemTime::now();
|
||||
|
@ -7,3 +11,31 @@ pub fn unix_timestamp() -> u32 {
|
|||
.expect("Time went backwards");
|
||||
since_the_epoch.as_secs() as u32
|
||||
}
|
||||
|
||||
pub fn read_base64(path: &str) -> Bytes {
|
||||
let s = std::fs::read_to_string(path).unwrap();
|
||||
match BytesBase64::from_base64(&s) {
|
||||
Ok(bytes) => bytes.to_bytes(),
|
||||
Err(msg) => panic!("Failed to read_base64 {}: {}", path, msg),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_base64_lines(path: &str) -> Vec<Bytes> {
|
||||
let file = std::fs::File::open(path).unwrap();
|
||||
let br = BufReader::new(file);
|
||||
br.lines()
|
||||
.map(|line| {
|
||||
BytesBase64::from_base64(&line.expect(&format!("Failed to read line in {}", path)))
|
||||
.expect(&format!("Invalid base64 in {}", path))
|
||||
.to_bytes()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn read_hex_lines(path: &str) -> Vec<Bytes> {
|
||||
let file = std::fs::File::open(path).unwrap();
|
||||
let br = BufReader::new(file);
|
||||
br.lines()
|
||||
.map(|line| Bytes::from_hex(&line.unwrap()))
|
||||
.collect()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue