-
Notifications
You must be signed in to change notification settings - Fork 15
/
warpwallet_cracker.go
109 lines (92 loc) · 2.67 KB
/
warpwallet_cracker.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
package main
import (
pbkdf2 "github.com/ctz/go-fastpbkdf2"
"golang.org/x/crypto/scrypt"
"unsafe"
"crypto/sha256"
"fmt"
"time"
"os"
"math/rand"
"github.com/vsergeev/btckeygenie/btckey"
)
const wordSize = int(unsafe.Sizeof(uintptr(0)))
var c chan []byte // goroutine channel
const letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func random(r *rand.Rand, n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[r.Intn(62)]
}
return string(b)
}
func main () {
r := rand.New(rand.NewSource(time.Now().Unix()))
c = make(chan []byte)
var address string
saltValue := ""
if len(os.Args) >= 2 {
address = os.Args[1]
if len(os.Args) == 3 {
saltValue = os.Args[2]
} else {
saltValue = "";
}
} else {
fmt.Printf("Usage: %s [Address] [Salt - optional]\n\n", os.Args[0])
os.Exit(0)
}
fmt.Printf("Using address \"%s\" and salt \"%s\"\n", address, saltValue)
tries := 0
start := time.Now()
for {
passphraseValue := random(r, 8)
result := bruteforce(passphraseValue, saltValue, address);
if result != "" {
fmt.Printf("Found! Passphrase %s\n", passphraseValue)
os.Exit(0)
} else {
tries += 1
timeElapsed := time.Since(start)
hashRate := float64(tries) / (timeElapsed.Seconds())
fmt.Printf("\rspeed=%.2fh/s, last=%s, tries=%d, elapsed=%s", hashRate, passphraseValue, tries, timeElapsed)
}
}
}
func bruteforce(passphraseValue string, saltValue string, address string) string {
var priv btckey.PrivateKey
var err error
go doScrypt(fmt.Sprint(passphraseValue, "\x01"), fmt.Sprint(saltValue, "\x01"), c)
go doPbkdf2(fmt.Sprint(passphraseValue, "\x02"), fmt.Sprint(saltValue, "\x02"), c)
key1, key2 := <-c, <-c
result := make([]byte, 32)
fastXORWords(result, key1, key2)
err = priv.FromBytes(result)
if err != nil {
fmt.Printf("Error importing private key: %s [%s]\n", err, passphraseValue)
return ""
}
if (priv.ToAddressUncompressed() == address) {
return passphraseValue
}
return ""
}
func doScrypt(pass string, salt string, c chan []byte) {
scryptKey, _ := scrypt.Key([]byte(pass), []byte(salt), 262144, 8, 1, 32)
c <- scryptKey
}
func doPbkdf2(pass string, salt string, c chan []byte) {
pbkdf2Key := pbkdf2.Key([]byte(pass), []byte(salt), 65536, 32, sha256.New)
c <- pbkdf2Key
}
// fastXORWords XORs multiples of 4 or 8 bytes (depending on architecture.)
// The arguments are assumed to be of equal length.
func fastXORWords(dst, a, b []byte) {
dw := *(*[]uintptr)(unsafe.Pointer(&dst))
aw := *(*[]uintptr)(unsafe.Pointer(&a))
bw := *(*[]uintptr)(unsafe.Pointer(&b))
n := len(b) / wordSize
for i := 0; i < n; i++ {
dw[i] = aw[i] ^ bw[i]
}
}