-
Notifications
You must be signed in to change notification settings - Fork 22
/
main.go
110 lines (92 loc) · 2.24 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"bytes"
"flag"
"fmt"
"log"
"os"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)
var (
signature = flag.String("selector", "", "selector given")
mustBeZeros = flag.Bool("all_zeros", false, "force search for zeros")
found bool = false
)
// Perm calls f with each permutation of a.
func Perm(a []rune, f func([]rune)) {
perm(a, f, 0)
}
// Permute the values at index i to len(a)-1.
func perm(a []rune, f func([]rune), i int) {
if i > len(a) {
f(a)
return
}
if found {
return
}
perm(a, f, i+1)
for j := i + 1; j < len(a); j++ {
a[i], a[j] = a[j], a[i]
perm(a, f, i+1)
a[i], a[j] = a[j], a[i]
}
}
func permutate(input string, parent string) []string {
if len(input) == 1 {
return []string{parent + input}
}
var permutations []string
for i := 0; i < len(input); i++ {
restOfInput := input[0:i] + input[i+1:]
curChar := input[i : i+1]
permutations = append(permutations, permutate(restOfInput, parent+curChar)...)
}
return permutations
}
func main() {
flag.Parse()
if *signature == "" {
log.Fatal("no selector given")
}
sig := *signature
atMost := []byte{0x00, 0x00, 0x00, 0xff}
wanted := []byte{0x00, 0x00, 0x00, 0x00}
started := time.Now()
p := *mustBeZeros
t0 := time.Now()
fmt.Println("generating all the permutations ")
all := permutate("abcdefghijk", "")
fmt.Println("took", time.Since(t0), "to generate all permutations")
length := len(all)
chopped := length / 4
fmt.Println("kicking off 4 threads")
for i := 0; i < 4; i++ {
fmt.Println("range", i*chopped, i*chopped+chopped)
subrange := all[i*chopped : i*chopped+chopped]
go func() {
for _, a := range subrange {
combined := string(a) + "(" + sig + ")"
b := crypto.Keccak256([]byte(combined))[:4]
if bytes.Equal(wanted, b) {
fmt.Println("FOUND exactly all zeros after",
time.Since(started), "signature should be", combined,
)
os.Exit(0)
return
}
if p == false && bytes.Compare(b, atMost) == -1 {
fmt.Println("this is good enough - can do ctrl-c now",
"use this as your signature",
combined, "found after",
time.Since(started),
hexutil.Encode(b),
)
}
}
}()
}
select {}
}