Skip to content

Commit

Permalink
pass regex by argv
Browse files Browse the repository at this point in the history
  • Loading branch information
milahu committed Aug 31, 2021
1 parent d166e9a commit e8070b0
Showing 1 changed file with 75 additions and 26 deletions.
101 changes: 75 additions & 26 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,112 @@ package main
import (
"crypto/rand"
"fmt"
"io/ioutil"
//"io/ioutil"
"log"
"os"
"regexp"
"runtime"
"strings"
//"strings"
"encoding/base64"

"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
)

var (
alphabet = regexp.MustCompile("^[123456789abcdefghijklmnopqrstuvwxyz]+$")
numWorkers = runtime.NumCPU()
)

// Key stores PrettyID containing desired substring at Index
type Key struct {
PrettyID string
Index int
Index int
Part string
PrivateKey string
}

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.
This tool can generate IPFS public and private keypairs
and filter the public keys by regex, to find vanity IPFS public keys
Keypairs are printed to stdout and to output.txt
To use a key, edit your ~/.ipfs/config file, which is generated by ipfs init
Identity.PeerID is your public key
Identity.PrivKey is your private key in base64 encoding
Usage:
%s {part}
For fast results suggested length of public key part is 4-5 characters
%s {regex}
For fast results, use a short substring of 4-5 characters
Alphabet of public key:
[1-9a-zA-Z]
Regex samples:
hello$
(?i)hello
(foo|bar)$
Regex basics:
(?i) add this prefix to make the regex case-insensitive
(a|b) a or b
$ end of string
^ start of string. not needed here, the start is mostly constant
Regex docs:
https://duckduckgo.com/?q=golang+regexp
https://yourbasic.org/golang/regexp-cheat-sheet/
https://golangdocs.com/regex-in-golang-regexp-package
`, 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)

partRegex := regexp.MustCompile(os.Args[1])
// TODO? validate regex with alphabet
//alphabet = regexp.MustCompile("^[123456789abcdefghijklmnopqrstuvwxyz]+$")

outputFile, err := os.OpenFile("output.txt", os.O_APPEND | os.O_CREATE | os.O_WRONLY, 0644)
if err != nil {
log.Println(err)
}
defer outputFile.Close()

runtime.GOMAXPROCS(numWorkers)
keyChan := make(chan Key)
for i := 0; i < numWorkers; i++ {
go func() {
err := generateKey(part, keyChan)
err := generateKey(partRegex, keyChan)
if err != nil {
log.Fatal(err)
}
}()
}
for key := range keyChan {
fmt.Printf(
"%s\u001b[32m%s\u001b[0m%s\n",
// TODO allow to disable color
"%s %s\u001b[32m%s\u001b[0m%s %s\n",
//"%s %s%s%s %s\n",
key.Part,
key.PrettyID[:key.Index],
key.PrettyID[key.Index:len(part)+key.Index],
key.PrettyID[len(part)+key.Index:])
key.PrettyID[key.Index:len(key.Part)+key.Index],
key.PrettyID[len(key.Part)+key.Index:],
key.PrivateKey,
)

// TODO allow to disable
_, err := outputFile.WriteString(
fmt.Sprintf("%s %s %s\n", key.Part, key.PrettyID, key.PrivateKey),
)
if err != nil {
log.Println(err)
}
}
}

func generateKey(part string, keyChan chan Key) error {
func generateKey(partRegex *regexp.Regexp, keyChan chan Key) error {
for {
privateKey, publicKey, err := crypto.GenerateEd25519Key(rand.Reader)
if err != nil {
Expand All @@ -74,23 +119,27 @@ func generateKey(part string, keyChan chan Key) error {
return err
}
prettyID := peerID.Pretty()
lowerID := strings.ToLower(prettyID)
idx := strings.Index(lowerID, part)
if idx == -1 {

if !partRegex.MatchString(prettyID) {
continue
}

part := partRegex.FindString(prettyID)
idx := partRegex.FindStringIndex(prettyID)[0]

privateKeyBytes, err := privateKey.Raw()
if err != nil {
return err
}
err = ioutil.WriteFile(prettyID, privateKeyBytes, 0600)
// TODO print privateKey in base64, as in ~/.ipfs/config .Identity.PrivKey
if err != nil {
return err
}

privateKey64 := make([]byte, base64.StdEncoding.EncodedLen(len(privateKeyBytes)))
base64.StdEncoding.Encode(privateKey64, privateKeyBytes)

keyChan <- Key{
PrettyID: prettyID,
Index: idx,
Part: part,
PrivateKey: string(privateKey64),
}
}
}

0 comments on commit e8070b0

Please sign in to comment.