-
Notifications
You must be signed in to change notification settings - Fork 11
/
main.go
95 lines (87 loc) · 1.96 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
package main
import (
"crypto/rand"
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
"runtime"
"strings"
"github.com/libp2p/go-libp2p-crypto"
"github.com/libp2p/go-libp2p-peer"
)
var (
alphabet = regexp.MustCompile("^[123456789abcdefghijklmnopqrstuvwxyz]+$")
numWorkers = runtime.NumCPU()
)
// Key stores PrettyID containing desired substring at Index
type Key struct {
PrettyID string
Index int
}
func main() {
if len(os.Args) != 2 {
fmt.Printf(`
This tool generates IPFS public and private keypair until it finds public key
which contains required substring. Keys are stored in local directory. If you
like one of them, you can move it to ~/.ipfs/keystore/ to use it with IPFS.
Usage:
%s {part}
For fast results suggested length of public key part is 4-5 characters
`, os.Args[0])
os.Exit(1)
}
part := strings.ToLower(os.Args[1])
if !alphabet.MatchString(part) {
fmt.Println("{part} must match the alphabet:", alphabet.String())
os.Exit(2)
}
runtime.GOMAXPROCS(numWorkers)
keyChan := make(chan Key)
for i := 0; i < numWorkers; i++ {
go func() {
err := generateKey(part, keyChan)
if err != nil {
log.Fatal(err)
}
}()
}
for key := range keyChan {
fmt.Printf(
"%s\u001b[32m%s\u001b[0m%s\n",
key.PrettyID[:key.Index],
key.PrettyID[key.Index:len(part)+key.Index],
key.PrettyID[len(part)+key.Index:])
}
}
func generateKey(part string, keyChan chan Key) error {
for {
privateKey, publicKey, err := crypto.GenerateEd25519Key(rand.Reader)
if err != nil {
return err
}
peerID, err := peer.IDFromPublicKey(publicKey)
if err != nil {
return err
}
prettyID := peerID.Pretty()
lowerID := strings.ToLower(prettyID)
idx := strings.Index(lowerID, part)
if idx == -1 {
continue
}
privateKeyBytes, err := privateKey.Bytes()
if err != nil {
return err
}
err = ioutil.WriteFile(prettyID, privateKeyBytes, 0600)
if err != nil {
return err
}
keyChan <- Key{
PrettyID: prettyID,
Index: idx,
}
}
}