diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b400946 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module charon + +go 1.26 diff --git a/main.go b/main.go new file mode 100644 index 0000000..794ab4e --- /dev/null +++ b/main.go @@ -0,0 +1,107 @@ +package main + +import ( + "crypto" + _ "crypto/sha1" + "encoding/hex" + "fmt" + "math/rand" + "time" +) + +func main() { + g := Generator{ + Difficulty: 26, + } + c := g.RandomChallenge() + fmt.Println(c.String()) + fmt.Println(c.Solve().String()) +} + +type Challenge struct { + Input [48]byte + Date [20]byte + Difficulty byte + Solution int64 +} +type Generator struct { + Difficulty byte +} + +func (g *Generator) RandomChallenge() Challenge { + bytes := make([]byte, 48) + for i, _ := range bytes { + bytes[i] = byte(rand.Int()) + } + today := time.Now().UTC() + date := today.Format("2006-01-02") + hash := crypto.SHA1.New().Sum([]byte(date)) + return Challenge{ + Input: [48]byte(bytes), + Date: [20]byte(hash), + Difficulty: g.Difficulty, + } +} + +// using a lookup table for this is super goofy but i'm lazy and it's 6am +var prefixLookup = []int{ + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +} + +func (c Challenge) Solve() Challenge { + bytes := make([]byte, 76) + bytes = append(bytes, c.Input[:]...) + bytes = append(bytes, c.Date[:]...) + for { + for i := range 8 { + bytes[75-i] = byte(c.Solution >> (i * 8)) + } + sum := make([]byte, 20) + hash := crypto.SHA1.New() + hash.Write(bytes) + sum = hash.Sum(nil) + count := 0 + for _, c := range sum { + p := prefixLookup[c] + count += p + if p != 8 { + break + } + } + if c.Solution%20000000 == 0 { + println(c.Solution) + } + if count >= int(c.Difficulty) { + println(c.Solution) + break + } + c.Solution++ + } + return c +} +func (c Challenge) String() string { + bytes := make([]byte, 0) + bytes = append(bytes, c.Input[:]...) + bytes = append(bytes, c.Date[:]...) + bytes = append(bytes, make([]byte, 8)...) + bytes[68] = c.Difficulty + for i := range 7 { + bytes[75-i] = byte(c.Solution >> (i * 8)) + } + return hex.EncodeToString(bytes) +}