summaryrefslogtreecommitdiffstats
path: root/challenge
diff options
context:
space:
mode:
Diffstat (limited to 'challenge')
-rw-r--r--challenge/c32.go173
1 files changed, 173 insertions, 0 deletions
diff --git a/challenge/c32.go b/challenge/c32.go
new file mode 100644
index 0000000..5cfc3b9
--- /dev/null
+++ b/challenge/c32.go
@@ -0,0 +1,173 @@
+// Copyright © 2021 rsiddharth <s@ricketyspace.net>
+// SPDX-License-Identifier: ISC
+
+package challenge
+
+import (
+ "fmt"
+ "net/http"
+ "net/url"
+ "time"
+
+ "ricketyspace.net/cryptopals/lib"
+)
+
+func C32(serve bool) {
+ // In-Secure Byte Compare.
+ inSecureCompare := func(a, b []byte) bool {
+ for i := 0; i < len(a); i++ {
+ if len(b) <= i {
+ return false
+ }
+ if a[i] != b[i] {
+ return false
+ }
+ lib.Sleep(500000) // Sleep 0.5ms
+ }
+ return true
+ }
+
+ // HMAC HTTP Server.
+ httpServer := func() {
+ // Secret for HMAC
+ sec := lib.StrToBytes("Rae Street")
+
+ // Signature checkker.
+ sigCheck := func(f, s string) bool {
+ // Check signature.
+ h := lib.HmacSha1(sec, lib.StrToBytes(f))
+
+ if inSecureCompare(h, lib.HexStrToBytes(s)) {
+ return true
+ }
+ return false
+ }
+
+ // HTTP Handler.
+ http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
+ // Read query.
+ var f, s []string
+ var ok bool
+ q := r.URL.Query()
+ if f, ok = q["file"]; !ok {
+ w.WriteHeader(400)
+ fmt.Fprintf(w, "file not specified\n")
+ return
+ }
+ if len(f) > 1 {
+ w.WriteHeader(400)
+ fmt.Fprintf(w, "Cannot specify more than one file\n")
+ return
+ }
+ if s, ok = q["signature"]; !ok {
+ w.WriteHeader(400)
+ fmt.Fprintf(w, "signature not specified\n")
+ return
+ }
+ if len(s) > 1 {
+ w.WriteHeader(400)
+ fmt.Fprintf(w,
+ "Cannot specify more than one signature\n")
+ return
+ }
+ if !sigCheck(f[0], s[0]) {
+ w.WriteHeader(500) // Signature check failed.
+ }
+ })
+
+ // Start HTTP Server
+ http.ListenAndServe(":9000", nil)
+ }
+
+ // Makes HTTP POST request to the server.
+ makeRequest := func(f, s string) int {
+ // Make HTTP request.
+ q := fmt.Sprintf("file=%s&signature=%s", f, s)
+ u, err := url.Parse("http://localhost:9000/test?" + q)
+ if err != nil {
+ fmt.Printf("url parse failed: %v\n", err)
+ return 0
+ }
+ res, err := http.Post(u.String(), "text/plain", nil)
+ if err != nil {
+ fmt.Printf("http post failed: %v\n", err)
+ return res.StatusCode
+ }
+ return res.StatusCode
+ }
+
+ // Crack signature for file "foo".
+ crack := func() {
+ stc := time.Now() // Start time of crack
+
+ f := "foo" // File
+ s := make([]byte, 20) // Signature
+
+ i := 0
+ g := byte(0) // Guess byte.
+ tl := int64(50 + 1000) // Time limit.
+ tries := 0
+ for {
+ st := time.Now()
+ sc := makeRequest(f, lib.BytesToHexStr(s))
+ et := time.Now().Sub(st) // Elapsed time.
+
+ if sc == 200 {
+ fmt.Printf("Signature Cracked: %x"+
+ " [tot. elapsed time: %v]\n",
+ s, time.Now().Sub(stc))
+ break
+ }
+ if et.Microseconds() >= tl {
+ if tries < 5 { // Try guess at least 5 times.
+ tries += 1
+ continue
+ }
+ fmt.Printf("Signature Cracked Status: %x"+
+ " [tot. elapsed time: %v]\n",
+ s, time.Now().Sub(stc))
+ tl = et.Microseconds() + 50 + 200
+ g = 0
+ i += 1
+ tries = 0
+ } else {
+ g += 1 // Change guess.
+ s[i] = g // Set guess.
+ tries = 0
+ }
+ }
+ }
+
+ if serve {
+ httpServer()
+ } else {
+ crack()
+ }
+}
+
+// Output:
+//
+// # Server:
+// $ ./cryptopals -c 32 -s
+// # Client:
+// $ ./cryptopals -c 32
+// Signature Cracked Status: 4400000000000000000000000000000000000000 [tot. elapsed time: 126.869763ms]
+// Signature Cracked Status: 44ee000000000000000000000000000000000000 [tot. elapsed time: 5.146844063s]
+// Signature Cracked Status: 44ee570000000000000000000000000000000000 [tot. elapsed time: 9.026893144s]
+// Signature Cracked Status: 44ee574500000000000000000000000000000000 [tot. elapsed time: 13.646937167s]
+// Signature Cracked Status: 44ee5745d3000000000000000000000000000000 [tot. elapsed time: 31.367079778s]
+// Signature Cracked Status: 44ee5745d3240000000000000000000000000000 [tot. elapsed time: 35.807108716s]
+// Signature Cracked Status: 44ee5745d324fd00000000000000000000000000 [tot. elapsed time: 1m8.247369106s]
+// Signature Cracked Status: 44ee5745d324fda7000000000000000000000000 [tot. elapsed time: 1m32.867563308s]
+// Signature Cracked Status: 44ee5745d324fda71e0000000000000000000000 [tot. elapsed time: 1m38.747613348s]
+// Signature Cracked Status: 44ee5745d324fda71ec000000000000000000000 [tot. elapsed time: 2m15.067906592s]
+// Signature Cracked Status: 44ee5745d324fda71ec0cb000000000000000000 [tot. elapsed time: 2m57.588228069s]
+// Signature Cracked Status: 44ee5745d324fda71ec0cbdd0000000000000000 [tot. elapsed time: 3m49.198625184s]
+// Signature Cracked Status: 44ee5745d324fda71ec0cbdd7e00000000000000 [tot. elapsed time: 4m20.99889498s]
+// Signature Cracked Status: 44ee5745d324fda71ec0cbdd7e0c000000000000 [tot. elapsed time: 4m25.798911645s]
+// Signature Cracked Status: 44ee5745d324fda71ec0cbdd7e0c620000000000 [tot. elapsed time: 4m55.039159294s]
+// Signature Cracked Status: 44ee5745d324fda71ec0cbdd7e0c621c00000000 [tot. elapsed time: 5m5.359239694s]
+// Signature Cracked Status: 44ee5745d324fda71ec0cbdd7e0c621c70000000 [tot. elapsed time: 5m43.219684819s]
+// Signature Cracked Status: 44ee5745d324fda71ec0cbdd7e0c621c70ba0000 [tot. elapsed time: 6m49.610083935s]
+// Signature Cracked Status: 44ee5745d324fda71ec0cbdd7e0c621c70bae700 [tot. elapsed time: 8m15.280753257s]
+// Signature Cracked: 44ee5745d324fda71ec0cbdd7e0c621c70bae785 [tot. elapsed time: 9m6.221153561s]