Skip to content

Commit

Permalink
minor optimizations to fast generate, split, readme
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Hamilton <m@tthamilton.com>
  • Loading branch information
Eriner committed Jul 22, 2023
1 parent 4faa9be commit 82097c2
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 34 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ Namely, `sync.Pool`s are used to reduce memory allocations and [frand](https://g
The benchmarks below show an approximate 2x speed increase while maintaining the cryptographic security of key generation.

```
% go test -bench=.
% go test -bench=. -benchtime=3s
goos: linux
goarch: amd64
pkg: github.com/eriner/vanity-npub
cpu: AMD Ryzen 7 2700X Eight-Core Processor
BenchmarkGeneratePrivateKey-16 499538 2073 ns/op
BenchmarkGenerateFastPrivateKey-16 1085912 1146 ns/op
BenchmarkGeneratePrivateKey-16 1671508 2076 ns/op
BenchmarkGenerateFastPrivateKey-16 3191943 1107 ns/op
PASS
ok github.com/eriner/vanity-npub 3.240s
ok github.com/eriner/vanity-npub 10.318s
```
31 changes: 31 additions & 0 deletions fast_generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
"encoding/hex"
"io"
"math/big"
"sync"

"github.com/btcsuite/btcd/btcec/v2"
"lukechampine.com/frand"
)

var params = btcec.S256().Params()
var one = new(big.Int).SetInt64(1)
var poolBytes = sync.Pool{New: func() any { return [256/8 + 8]byte{} }}
var poolBigInt = sync.Pool{New: func() any { return new(big.Int) }}

func GenerateFastPrivateKey() string {
b := poolBytes.Get().([256/8 + 8]byte)
if _, err := io.ReadFull(frand.Reader, b[:]); err != nil {
return ""
}
k := poolBigInt.Get().(*big.Int).SetBytes(b[:])
n := poolBigInt.Get().(*big.Int).Sub(params.N, one)
k.Mod(k, n)
k.Add(k, one)
poolBytes.Put(b)
poolBigInt.Put(k)
poolBigInt.Put(n)
return hex.EncodeToString(k.Bytes())
}
File renamed without changes.
32 changes: 2 additions & 30 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,15 @@ package main

import (
"context"
"encoding/hex"
"fmt"
"io"
"log"
"math/big"
"os"
"runtime"
"strings"
"sync"
"time"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip19"
"lukechampine.com/frand"
)

func main() {
Expand Down Expand Up @@ -49,8 +43,8 @@ func main() {
case <-ctx.Done():
return
default:
i++ // race, but no big deal
sk := GenerateFastPrivateKey()
i++ // race, but no big deal
sk := GenerateFastPrivateKey() // custom implementation (with CSPRNG) w/ ~+100% performance
pk, _ := nostr.GetPublicKey(sk)
npub, _ := nip19.EncodePublicKey(pk)
if strings.HasPrefix(npub, desiredPrefix) {
Expand All @@ -76,25 +70,3 @@ func main() {
fmt.Println(nsec)
fmt.Println(npub)
}

var params = btcec.S256().Params()
var one = new(big.Int).SetInt64(1)
var poolBytes = sync.Pool{New: func() any { return [256/8 + 8]byte{} }}
var poolBigInt = sync.Pool{New: func() any { return new(big.Int) }}

func GenerateFastPrivateKey() string {
b := poolBytes.Get().([256/8 + 8]byte)
defer poolBytes.Put(b)
if _, err := io.ReadFull(frand.Reader, b[:]); err != nil {
return ""
}
//k := new(big.Int).SetBytes(b[:])
//n := new(big.Int).Sub(params.N, one)
k := poolBigInt.Get().(*big.Int).SetBytes(b[:])
n := poolBigInt.Get().(*big.Int).Sub(params.N, one)
defer poolBigInt.Put(k)
defer poolBigInt.Put(n)
k.Mod(k, n)
k.Add(k, one)
return hex.EncodeToString(k.Bytes())
}

0 comments on commit 82097c2

Please sign in to comment.