summaryrefslogtreecommitdiffstats
path: root/challenge/c12.go
diff options
context:
space:
mode:
Diffstat (limited to 'challenge/c12.go')
-rw-r--r--challenge/c12.go121
1 files changed, 121 insertions, 0 deletions
diff --git a/challenge/c12.go b/challenge/c12.go
new file mode 100644
index 0000000..fbb9fbb
--- /dev/null
+++ b/challenge/c12.go
@@ -0,0 +1,121 @@
+// Copyright © 2020 rsiddharth <s@ricketyspace.net>
+// SPDX-License-Identifier: ISC
+
+package challenge
+
+import (
+ "fmt"
+ "ricketyspace.net/cryptopals/lib"
+)
+
+var sheep byte = 65
+
+func C12() {
+ if !isOracleUsingECB() {
+ panic("oracle not using ecb mode")
+ }
+
+ blocksize := findBlockSize()
+ nbl, us_sz := findUnknownStringCharacteristics(blocksize)
+ in := freshSheepBlock(blocksize)
+ ds := make([]byte, 0) // deciphered unknown string in bytes
+ for i := 0; i < nbl; i++ {
+ nby := blocksize
+ if i == nbl-1 {
+ nby = us_sz % blocksize
+ }
+ for j := 0; j < nby; j++ {
+ in, ds = decipherUnknownStringIter(blocksize, i+1, j+1,
+ in, ds)
+ }
+ s := 16 * i
+ e := s + 16
+ copy(in, ds[s:e])
+ }
+ fmt.Printf("Unknown String:\n%v", lib.BytesToStr(ds))
+}
+
+func freshSheepBlock(blocksize int) []byte {
+ in := make([]byte, blocksize)
+ for i := 0; i < blocksize; i++ {
+ in[i] = sheep
+ }
+ return in
+}
+
+func findBlockSize() int {
+ in := make([]byte, 0)
+
+ in = append(in, sheep)
+ is := len(lib.OracleAESEncryptECB(in)) // initial size
+ bs := 0 // block size
+ for {
+ in = append(in, sheep)
+ bs = len(lib.OracleAESEncryptECB(in))
+ if bs != is {
+ return (bs - is)
+ }
+ }
+}
+
+func findUnknownStringCharacteristics(blocksize int) (int, int) {
+ in := make([]byte, 0)
+ c_sz := len(lib.OracleAESEncryptECB(in)) // Cipher size
+ nblocks := c_sz / 16 // number of blocks
+
+ // Figure out ize of unknown string.
+ for {
+ in = append(in, sheep)
+ bs := len(lib.OracleAESEncryptECB(in))
+ if bs != c_sz {
+ return nblocks, (c_sz - len(in))
+ }
+ }
+
+}
+
+func isOracleUsingECB() bool {
+ in := lib.StrToBytes("OliverMkTukudzi OliverMkTukudzi OliverMkTukudzi")
+ oo := lib.OracleAESEncryptECB(in)
+ if lib.CipherUsesECB(oo) != nil {
+ return true
+ }
+ return false
+}
+
+// `blocksize` is the size of a block
+// `block` is the nth block that is being deciphered
+// `n` is the nth byte of the block `block` that is going to be deciphered.
+// `in` (n-1)th block that is known
+// `ds` deciphered unknown string
+func decipherUnknownStringIter(blocksize, block, n int, in, ds []byte) ([]byte, []byte) {
+ oo := lib.OracleAESEncryptECB(in[0:(blocksize - n)])
+
+ s := 16 * (block - 1)
+ e := s + 16
+ nbl := oo[s:e] // nth block of the cipher
+
+ // Shift `in` to the left by one place.
+ for i := 0; i < blocksize-1; i++ {
+ in[i] = in[i+1]
+ }
+
+ // Try all combinations.
+ for i := 0; i < 256; i++ {
+ in[15] = byte(i)
+ oo = lib.OracleAESEncryptECB(in)
+
+ if lib.BlocksEqual(nbl, oo[0:16]) {
+ ds = append(ds, in[15])
+ return in, ds
+ }
+ }
+ panic("not found!")
+}
+
+// Output:
+// Unknown String:
+// Rollin' in my 5.0
+// With my rag-top down so my hair can blow
+// The girlies on standby waving just to say hi
+// Did you stop? No, I just drove by