commit 6494621f70376ecb3feb2a234306dca3793709a4
parent 4b307a8b848020c4b29634f00ff97ccc8be2ab1f
Author: Jared Tobin <jared@jtobin.ca>
Date: Sat, 26 Aug 2017 19:39:39 +1200
Clean up old stuff.
Diffstat:
M | .gitignore | | | 1 | + |
M | docs/s2.md | | | 4 | ++-- |
D | src/s1c1.rs | | | 18 | ------------------ |
D | src/s1c2.rs | | | 24 | ------------------------ |
D | src/s1c3.hs | | | 48 | ------------------------------------------------ |
D | src/s1c3.rs | | | 54 | ------------------------------------------------------ |
D | src/s1c4.hs | | | 59 | ----------------------------------------------------------- |
D | src/s1c5.rs | | | 40 | ---------------------------------------- |
D | src/s1c6.hs | | | 123 | ------------------------------------------------------------------------------- |
9 files changed, 3 insertions(+), 368 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -6,3 +6,4 @@ target
*.o
*.hi
etc/working
+deprecated
diff --git a/docs/s2.md b/docs/s2.md
@@ -57,12 +57,12 @@ So you could do something crazy, like:
else ./bin/aes_cbc --encrypt -k $AES_KEY --iv $IV; fi
zcE4rONdRk04w8v4Sm8HYQ==
-and then:
+and then make the guess:
$ echo "zcE4rONdRk04w8v4Sm8HYQ==" | ./bin/ecb_detector
likely cbc
-which is actually the wrong guess here.
+which is actually the wrong one here.
But, uh, let's not use bash for this.
diff --git a/src/s1c1.rs b/src/s1c1.rs
@@ -1,18 +0,0 @@
-extern crate rustc_serialize as serialize;
-
-// tips:
-//
-// always operate on raw bytes, never encoded strings
-// only use hex and base64 for pretty printing
-
-use serialize::base64::{self, ToBase64};
-use serialize::hex::FromHex;
-
-fn main() {
- let input = "49276d206b696c6c696e6720796f757220627261696e206c696b652061207\
- 06f69736f6e6f7573206d757368726f6f6d";
-
- let result = input.from_hex().unwrap().to_base64(base64::STANDARD);
-
- println!("{}", result);
-}
diff --git a/src/s1c2.rs b/src/s1c2.rs
@@ -1,24 +0,0 @@
-extern crate rustc_serialize;
-
-use rustc_serialize::hex::{ToHex, FromHex};
-
-fn fixed_xor(target: &str, partner: &str) -> String {
- assert_eq!(target.len(), partner.len());
-
- let mut l = target.from_hex().unwrap();
- let r = partner.from_hex().unwrap();
-
- for (lb, rb) in l.iter_mut().zip(r) { *lb ^= rb }
-
- l.to_hex()
-}
-
-fn main() {
- let left = "1c0111001f010100061a024b53535009181c";
- let right = "686974207468652062756c6c277320657965";
-
- let result = fixed_xor(left, right);
-
- println!("{}", result);
-}
-
diff --git a/src/s1c3.hs b/src/s1c3.hs
@@ -1,48 +0,0 @@
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE OverloadedStrings #-}
-
-import Data.Bits
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Char8 as B8
-import qualified Data.ByteString.Base16 as B16
-import qualified Data.Map.Strict as MS
-import GHC.Word
-
-hash :: B.ByteString
-hash = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"
-
-fromHex :: B.ByteString -> [Word8]
-fromHex = B.unpack . fst . B16.decode
-
-tally :: Ord a => [a] -> MS.Map a Int
-tally = loop MS.empty where
- loop !acc [] = acc
- loop !acc (x:xs) =
- let nacc = case MS.lookup x acc of
- Nothing -> MS.insert x 1 acc
- Just _ -> MS.update (Just . succ) x acc
- in loop nacc xs
-
-mostFrequent :: MS.Map a Int -> Maybe a
-mostFrequent ms = case MS.toList ms of
- [] -> Nothing
- ((k, v):xs) -> Just (loop k v xs)
- where
- loop mk _ [] = mk
- loop mk mv ((k, v):xs) = case compare v mv of
- GT -> loop k v xs
- _ -> loop mk mv xs
-
-decrypt :: B8.ByteString -> B8.ByteString
-decrypt bs = case mostFrequent (tally bytes) of
- Nothing -> bs
- Just c ->
- let xored = fmap (`xor` c) bytes
- in B.pack xored
- where
- bytes = fromHex bs
-
-main :: IO ()
-main = do
- B8.putStrLn hash
- B8.putStrLn (decrypt hash)
diff --git a/src/s1c3.rs b/src/s1c3.rs
@@ -1,54 +0,0 @@
-extern crate rustc_serialize as serialize;
-
-use serialize::hex::FromHex;
-use std::collections::HashMap;
-use std::string::String;
-use std::vec::Vec;
-
-const HASH: &'static str =
- "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736";
-
-fn decode(s: &str) -> Vec<u8> {
- s.from_hex().unwrap()
-}
-
-fn tally(vec: Vec<u8>) -> HashMap<u8, u8> {
- let mut hashmap = HashMap::new();
-
- for byte in vec {
- let count = hashmap.entry(byte).or_insert(0);
- *count += 1;
- }
-
- hashmap
-}
-
-fn max_elem(hashmap: HashMap<u8, u8>) -> u8 {
- let mut max = 0;
- let mut max_index = 0;
-
- for (byte, count) in hashmap.iter() {
- if count > &max {
- max = *count;
- max_index = *byte;
- }
- }
-
- max_index
-}
-
-fn main() {
- let decoded = decode(HASH);
- let tallied = tally(decoded);
- let max = max_elem(tallied);
-
- let mut i_am_a_rust_noob = decode(HASH);
-
- for byte in i_am_a_rust_noob.iter_mut() { *byte ^= max; }
-
- let decrypted = String::from_utf8(i_am_a_rust_noob).unwrap();
- println!("{}", HASH);
- println!("{}", decrypted);
-}
-
-
diff --git a/src/s1c4.hs b/src/s1c4.hs
@@ -1,59 +0,0 @@
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE OverloadedStrings #-}
-
-import Data.Bits
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Char8 as B8
-import qualified Data.ByteString.Base16 as B16
-import qualified Data.Map.Strict as MS
-import GHC.Word
-
-fromHex :: B.ByteString -> [Word8]
-fromHex = B.unpack . fst . B16.decode
-
-tally :: Ord a => [a] -> MS.Map a Int
-tally = loop MS.empty where
- loop !acc [] = acc
- loop !acc (x:xs) =
- let nacc = case MS.lookup x acc of
- Nothing -> MS.insert x 1 acc
- Just _ -> MS.update (Just . succ) x acc
- in loop nacc xs
-
-mostFrequent :: MS.Map a Int -> Maybe (a, Int)
-mostFrequent ms = case MS.toList ms of
- [] -> Nothing
- ((k, v):xs) -> Just (loop k v xs)
- where
- loop mk mv [] = (mk, mv)
- loop mk mv ((k, v):xs) = case compare v mv of
- GT -> loop k v xs
- _ -> loop mk mv xs
-
-decrypt :: B8.ByteString -> B8.ByteString
-decrypt bs = case mostFrequent (tally bytes) of
- Nothing -> bs
- Just (c, _) ->
- let xored = filter printable $ fmap (`xor` c) bytes
- in B.pack xored
- where
- bytes = fromHex bs
- printable c = elem c [33..126]
-
-prune :: [B8.ByteString] -> [B8.ByteString]
-prune = filter highscoring where
- highscoring string = case mostFrequent (tally (fromHex string)) of
- Nothing -> False
- Just (c, v) -> v > 4
-
-display :: B8.ByteString -> IO ()
-display string = do
- B8.putStrLn string
- B8.putStrLn (decrypt string)
- B8.putStrLn mempty
-
-batchDecrypt :: FilePath -> IO ()
-batchDecrypt file = do
- strings <- fmap B8.lines $ B.readFile file
- mapM_ display (prune strings)
-
diff --git a/src/s1c5.rs b/src/s1c5.rs
@@ -1,40 +0,0 @@
-extern crate rustc_serialize as serialize;
-
-use serialize::hex::{ToHex};
-use std::vec::Vec;
-
-const STRING: &'static str =
- "Burning 'em, if you ain't quick and nimble\n\
- I go crazy when I hear a cymbal";
-
-fn repeating_key_xor(text: &str, key: &str) -> String {
- let text_bytes = text.as_bytes();
- let key_bytes = key.as_bytes();
-
- let mut xored: Vec<u8> = vec![0; text_bytes.len()];
-
- for (idx, val) in text_bytes.iter().enumerate() {
- let byte_idx = idx % key_bytes.len();
- xored[idx] = val ^ key_bytes[byte_idx];
- }
-
- xored.to_hex()
-}
-
-fn main() {
- println!("{}", STRING);
- println!("{}", repeating_key_xor(STRING, "ICE"));
-}
-
-// to read from stdin:
-//
-// use std::io::{self, Read};
-//
-// let mut buffer = String::new();
-//
-// io::stdin().read_to_string(&mut buffer)
-// .expect("Couldn't read.");
-//
-// println!("{}", &buffer);
-// println!("{}", repeating_key_xor(&buffer, "ICE"));
-
diff --git a/src/s1c6.hs b/src/s1c6.hs
@@ -1,123 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TypeOperators #-}
-
-import Control.Error
-import Data.Bits
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Char8 as B8
-import qualified Data.ByteString.Base16 as B16
-import qualified Data.ByteString.Base64 as B64
-import qualified Data.IntPSQ as PSQ
-import qualified Data.Map.Strict as MS
-import GHC.Word
-import System.IO
-
--- | Hamming distance between bytestrings.
---
--- Returns Nothing if bytestrings are of unequal length.
-distance :: B.ByteString -> B.ByteString -> Maybe Int
-distance s0 s1
- | B.length s0 /= B.length s1 = Nothing
- | otherwise = Just (foldr alg 0 (B.zip s0 s1))
- where
- hamming a b = popCount (xor a b)
- alg = (+) . uncurry hamming
-
--- | Score a keysize applied to a bytestring.
-score :: Fractional a => B.ByteString -> Int -> Maybe a
-score text size = do
- let (chunk0, rest) = B.splitAt size text
- chunk1 = B.take size rest
- hamming <- distance chunk0 chunk1
- return $ fromIntegral hamming / fromIntegral size
-
--- | More meticulously score a keysize applied to a bytestring.
-altScore :: Fractional a => B.ByteString -> Int -> Maybe a
-altScore text size = do
- let chunked = chunks size text
- leading = take 4 chunked
-
- chunk0 <- atMay leading 0
- chunk1 <- atMay leading 1
- chunk2 <- atMay leading 2
- chunk3 <- atMay leading 3
-
- hamming0 <- distance chunk0 chunk1
- hamming1 <- distance chunk0 chunk2
- hamming2 <- distance chunk0 chunk3
-
- let dsum = hamming0 + hamming1 + hamming2
-
- return $ fromIntegral dsum / (3 * fromIntegral size)
-
--- | Score keysizes 2-40 over a given bytestring.
-scoreKeysizes
- :: (B.ByteString -> Int -> Maybe Double)
- -> B.ByteString
- -> PSQ.IntPSQ Double ()
-scoreKeysizes scorer text = loop PSQ.empty 2 where
- plain = B64.decodeLenient text
- loop !acc size
- | size == 40 = acc
- | otherwise = case score plain size of
- Nothing -> acc
- Just prio ->
- let nacc = PSQ.insert size prio () acc
- in loop nacc (succ size)
-
--- | Return the best (smallest) n keys from a queue, by key..
-best :: Ord p => Int -> PSQ.IntPSQ p v -> [(Int, p)]
-best = loop mempty where
- loop !acc idx queue
- | idx <= 0 = reverse acc
- | otherwise = case PSQ.minView queue of
- Nothing -> reverse acc
- Just (key, prio, _, rest) ->
- let nacc = (key, prio) : acc
- in loop nacc (pred idx) rest
-
--- | Split a bytestring into chunks.
-chunks :: Int -> B.ByteString -> [B.ByteString]
-chunks size = loop mempty where
- loop !acc bs
- | B.null bs = reverse acc
- | otherwise = case B.splitAt size bs of
- (chunk, rest) -> loop (chunk : acc) rest
-
-tally :: Ord a => [a] -> MS.Map a Int
-tally = loop MS.empty where
- loop !acc [] = acc
- loop !acc (x:xs) =
- let nacc = case MS.lookup x acc of
- Nothing -> MS.insert x 1 acc
- Just count -> MS.update (Just . succ) x acc
- in loop nacc xs
-
-mostFrequent :: MS.Map a Int -> Maybe a
-mostFrequent ms = case MS.toList ms of
- [] -> Nothing
- ((k, v):xs) -> Just (loop k v xs)
- where
- loop mk _ [] = mk
- loop mk mv ((k, v):xs) = case compare v mv of
- GT -> loop k v xs
- _ -> loop mk mv xs
-
-main :: IO ()
-main = do
- raw <- B.readFile "etc/data/6.txt"
- let mdecoded = B64.decode (B8.filter (/= '\n') raw)
-
- case mdecoded of
- Left msg -> hPutStrLn stderr msg
- Right decoded -> do
- let hexed = B16.encode decoded
- chunked = chunks 3 hexed
- rotated = B.transpose chunked
- unpacked = fmap B.unpack rotated
-
- return ()
-
- return ()