commit 71400f97981bafcc157b7f9e3e1b1ca61701c3ba
parent 195bbec86afbc84ee3451e35a737eda795a9bb88
Author: Jared Tobin <jared@jtobin.io>
Date: Sat, 3 Jun 2023 09:46:26 +0400
Finish set 1.
Diffstat:
M | docs/s1.md | | | 42 | ++++++++++++++++++++++++++---------------- |
1 file changed, 26 insertions(+), 16 deletions(-)
diff --git a/docs/s1.md b/docs/s1.md
@@ -1,8 +1,5 @@
### 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
@@ -168,15 +165,20 @@ so if we want to decrypt the ciphertext we'll need to pipe it through
#### 1.6
First, determining a keysize for a suspected repeating-key XOR'd
-ciphertext; I use an average pairwise normalised Hamming distance:
+ciphertext. I use an average pairwise normalised Hamming distance; one
+breaks the ciphertext into chunks of a specific size, then calculates
+the number of differing bits for every pair of chunks, normalising by
+the chunk size, and then averages them all together.
$ detect-repeating-key-xor-keysize "$(< data/s1/q6_input.txt)"
cryptopals: keysize of 29 yields minimum score of 2.7856894063790736
Then to guess the key itself, one chunks the input into blocks of the
appropriate size and transposes the result, so that every byte in a
-transposed block has been XOR'd against a single byte. Doing that and
-breaking each block individually yields the key:
+transposed block has (if the ciphertext has indeed been produced by
+repeating-key XOR, and the keysize guess is correct) been XOR'd against
+a single byte. Doing that and breaking each block individually yields
+the key:
$ input_hex=$(cat data/s1/q6_input.txt | base64 -d | xxd -p | tr -d '\n')
$ key=$(rotate 29 $input_hex | \
@@ -184,7 +186,7 @@ breaking each block individually yields the key:
$ echo $key
Terminator X: Bring the noise
-then use `repeating-key-xor` with the key to recover the plaintext:
+Use `repeating-key-xor` with the key to recover the plaintext:
$ repeating-key-xor "$key" --hex "$input_hex" | xxd -r -p | head -2
I'm back and I'm ringin' the bell
@@ -192,9 +194,17 @@ then use `repeating-key-xor` with the key to recover the plaintext:
#### 1.7
-Here we're doing AES-128 decryption in ECB mode.
+Here we're doing AES-128 decryption in ECB mode. AES (Advanced
+Encryption Standard) is a substitution-permutation based block cipher
+with a fixed 128 bit (i.e. 16 byte) block size; AES-128 means the
+keysize is also 128 bits.
+
+ECB means "electronic codebook," the simplest block cipher encryption
+mode. One divides a message into 16-byte blocks and then encrypts each
+block independently.
-It's worth using the `openssl` tool just to get a feel for it:
+It's worth using the `openssl` command-line tool here just to get a feel
+for it:
$ key=$(echo -n 'YELLOW SUBMARINE' | xxd -p)
$ openssl enc -aes-128-ecb \
@@ -203,7 +213,8 @@ It's worth using the `openssl` tool just to get a feel for it:
I'm back and I'm ringin' the bell
A rockin' on the mike while the fly girls yell
-The `aes` binary will similarly do the trick:
+The `aes` binary I've cooked up (using `cryptonite` under the hood) will
+similarly do the trick:
$ key=$(echo -n "YELLOW SUBMARINE" | xxd -p)
$ ciphertext=$(cat data/s1/q7_input.txt | base64 -d | xxd -p | tr -d '\n')
@@ -213,14 +224,13 @@ The `aes` binary will similarly do the trick:
#### 1.8
-ECB means electronic codebook, the simplest block cipher encryption mode. One
-divides a message into 16-byte chunks and then encrypts each chunk separately.
-The same 16 bytes will thus encrypt to the same output.
+Under ECB mode, the same 16 bytes will always encrypt to the same
+output, so we can look for repeating bytes to detect ECB mode-encrypted
+ciphertext:
$ cat data/s1/q8_input.txt | parallel \
- 'echo -n {} | ./bin/chunks 8 | \
- printf "%s %u\n" {} $(datamash countunique 1)' | \
- awk '{ if ($2 < 20) { print $1 }; }' | fold -w 64
+ 'echo -n {} | fold -w 16 | printf "%s %u\n" {} $(datamash countunique 1)' | \
+ awk '{ if ($2 < 20) { print $1 }; }' | fold -w 64
d880619740a8a19b7840a8a31c810a3d08649af70dc06f4fd5d2d69c744cd283
e2dd052f6b641dbf9d11b0348542bb5708649af70dc06f4fd5d2d69c744cd283
9475c9dfdbc1d46597949d9c7e82bf5a08649af70dc06f4fd5d2d69c744cd283