summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrsiddharth <s@ricketyspace.net>2020-08-29 20:00:53 -0400
committerrsiddharth <s@ricketyspace.net>2020-08-29 20:00:53 -0400
commit3b0fb163cbac08a36b01f186b72e2a9cee4b7a2d (patch)
tree5c33a9744c675edb87e29e771b90ed2dfc9a2779
parented26b39e82cee901c785c13e3d1b669fbb502e14 (diff)
challenge: do challenge 3
* challenge/c03.go: Implement challenge 3 * cryptopals.go (main): Add handling to run challenge 3 * lib/brute.go (XORCrackSingleKey): New function. * lib/hex.go (HexStrToAsciiStr, ByteToHexStr): New functions. * lib/str.go (FillStr): New function.
-rw-r--r--challenge/c03.go17
-rw-r--r--cryptopals.go2
-rw-r--r--lib/brute.go56
-rw-r--r--lib/hex.go29
-rw-r--r--lib/str.go15
5 files changed, 119 insertions, 0 deletions
diff --git a/challenge/c03.go b/challenge/c03.go
new file mode 100644
index 0000000..019aaff
--- /dev/null
+++ b/challenge/c03.go
@@ -0,0 +1,17 @@
+// Copyright © 2020 rsiddharth <s@ricketyspace.net>
+// SPDX-License-Identifier: ISC
+
+package challenge
+
+import (
+ "fmt"
+ "ricketyspace.net/cryptopals/lib"
+)
+
+func C3() {
+ hs := "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"
+ k, ds, scr := lib.XORCrackSingleKey(hs)
+
+ fmt.Printf("Key is '%c' (Score: %v)\n", k, scr)
+ fmt.Printf("Decrypted string: %v\n", ds)
+}
diff --git a/cryptopals.go b/cryptopals.go
index 37580be..5faa363 100644
--- a/cryptopals.go
+++ b/cryptopals.go
@@ -22,5 +22,7 @@ func main() {
challenge.C1()
case 2:
challenge.C2()
+ case 3:
+ challenge.C3()
}
}
diff --git a/lib/brute.go b/lib/brute.go
new file mode 100644
index 0000000..54be06b
--- /dev/null
+++ b/lib/brute.go
@@ -0,0 +1,56 @@
+// Copyright © 2020 rsiddharth <s@ricketyspace.net>
+// SPDX-License-Identifier: ISC
+
+package lib
+
+// Average Word Length (English).
+const awl float64 = 4.7
+
+// 'hs' must be a hex encoded string.
+func XORCrackSingleKey(hs string) (byte, string, float64) {
+ l := len(hs) / 2
+
+ var k byte = 0
+ var ds string = ""
+ var scr float64 = 100.0
+
+ i := byte(0)
+ for i < 255 {
+ ks := FillStr(ByteToHexStr(i), l)
+ xs := FixedXOR(hs, ks)
+ as := HexStrToAsciiStr(xs)
+
+ s := phraseScore(as)
+ if s < scr {
+ k = i
+ ds = as
+ scr = s
+ }
+ i += 1
+ }
+ return k, ds, scr
+}
+
+func phraseScore(phrase string) float64 {
+ pl := len(phrase)
+
+ // Expected number of words.
+ ew := float64(pl) / awl
+
+ // Number of words in phrase.
+ ws := 0.0
+
+ for i := 0; i < pl; i++ {
+ if phrase[i] == ' ' {
+ ws += 1.0
+ }
+ }
+ ws += 1.0
+
+ // Compute score.
+ score := 1.0 - (ws / ew)
+ if score < 0 {
+ score *= -1
+ }
+ return score
+}
diff --git a/lib/hex.go b/lib/hex.go
index bf539bc..6fe7e6a 100644
--- a/lib/hex.go
+++ b/lib/hex.go
@@ -24,3 +24,32 @@ func DecToHexChar(i uint16) byte {
}
return 0
}
+
+// 'h' must be hex encoded string.
+func HexStrToAsciiStr(h string) string {
+ a := ""
+ lh := len(h)
+
+ if lh < 1 {
+ return a
+ }
+ if lh == 1 {
+ return string(HexCharToDec(h[0]))
+ }
+
+ for i := 0; i < lh; i += 2 {
+ b := HexCharToDec(h[i])<<4 | HexCharToDec(h[i+1])
+ a += string(b)
+ }
+ return a
+}
+
+func ByteToHexStr(b byte) string {
+ p := DecToHexChar(uint16(b >> 4))
+ q := DecToHexChar(uint16(b & 0xf))
+
+ s := string(p)
+ s += string(q)
+
+ return s
+}
diff --git a/lib/str.go b/lib/str.go
new file mode 100644
index 0000000..e0cb8ae
--- /dev/null
+++ b/lib/str.go
@@ -0,0 +1,15 @@
+// Copyright © 2020 rsiddharth <s@ricketyspace.net>
+// SPDX-License-Identifier: ISC
+
+package lib
+
+func FillStr(a string, l int) string {
+ b := ""
+ if l < 1 {
+ return b
+ }
+ for i := 0; i < l; i++ {
+ b += a
+ }
+ return b
+}