Skip to content

Instantly share code, notes, and snippets.

@inhies
Last active December 14, 2015 16:59
Show Gist options
  • Save inhies/5119199 to your computer and use it in GitHub Desktop.
Save inhies/5119199 to your computer and use it in GitHub Desktop.
Generates cjdns key pairs and stores the private key along with the IPv6 address in a database. Then use MySQL to search through the IPs for some with nice patterns.
package main
import (
"code.google.com/p/go.crypto/curve25519"
"crypto/rand"
"crypto/sha512"
"database/sql"
"fmt"
_ "github.com/Go-SQL-Driver/MySQL"
"os"
"os/signal"
"runtime"
"sync"
"syscall"
"time"
)
/* MySQL Table setup:
CREATE TABLE `cjdns_keys` (
`addr` varchar(39) DEFAULT NULL,
`privkey` varchar(64) DEFAULT NULL,
UNIQUE KEY `addr` (`addr`)
)
*/
var pass string = "" // Database password
var user string = "" // Database username
var db string = "" // Database name
var table string = "" // Database table
var mysqlSock string = "/var/run/mysqld/mysqld.sock" // MySQL socket
const version = "2012.03.09.1"
type KeyPair struct {
Private [32]byte
Public [32]byte
IP string
}
type Stats struct {
Interval time.Duration
Counter int64
LastTime time.Time
LastCount int64
StartTime time.Time
}
type Config struct {
MaxGoroutines int
UpdateInterval int
}
var SystemStats *Stats
var SystemConfig Config
func init() {
runtime.GOMAXPROCS(runtime.NumCPU()) // This will max out your CPU
SystemConfig.MaxGoroutines = 500 // Base setting
SystemConfig.UpdateInterval = 5 // Seconds between updates
SystemStats = &Stats{time.Duration(SystemConfig.UpdateInterval) * time.Second,
0, time.Now(), 0, time.Now()}
// Signal handling
c := make(chan os.Signal, 1)
signal.Notify(c)
go func() {
for sig := range c {
switch sig {
case syscall.SIGUSR1: // Increase MaxGoroutines by 10%
increaseBy := SystemConfig.MaxGoroutines * 10 / 100
newValue := SystemConfig.MaxGoroutines + increaseBy
fmt.Println("\nIncreasing go routines from", SystemConfig.MaxGoroutines,
"to", newValue)
SystemConfig.MaxGoroutines += increaseBy
case syscall.SIGUSR2: // Decrease MaxGoroutines by 10%
decreaseBy := SystemConfig.MaxGoroutines * 10 / 100
newValue := SystemConfig.MaxGoroutines - decreaseBy
fmt.Println("\nDecreasing go routines from", SystemConfig.MaxGoroutines,
"to", newValue)
SystemConfig.MaxGoroutines -= decreaseBy
case syscall.SIGTERM:
os.Exit(1) // Error becuase we were killed
case syscall.SIGQUIT, syscall.SIGINT: // ctrl-c
total := SystemStats.LastCount + SystemStats.Counter
timeNow := time.Now()
duration := timeNow.Sub(SystemStats.StartTime)
speed := total / (duration.Nanoseconds() / 1e9)
fmt.Printf("\nCreated %v new keys in %v (%v keys/second average)\n",
total, duration, speed)
os.Exit(0)
}
}
}()
}
func main() {
db, err := sql.Open("mysql", user+":"+pass+"@unix("+mysqlSock+")/"+db)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer db.Close()
var wg sync.WaitGroup
initialGoroutines := runtime.NumGoroutine()
stmt, err := db.Prepare("insert into " + table + " values (?, ?)")
for {
if runtime.NumGoroutine() < initialGoroutines+SystemConfig.MaxGoroutines+1 {
wg.Add(1)
go func() {
data := MakeKeyPair()
private := data.Private[:]
pString := fmt.Sprintf("%x", private)
_, err = stmt.Exec(data.IP, pString)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
KeyDone(SystemStats)
wg.Done()
}()
}
runtime.Gosched()
}
wg.Wait()
stmt.Close()
}
// Will loop until a valid keypair is found
func MakeKeyPair() (key KeyPair) {
random := key.Private[:]
Start:
rand.Read(random)
key.Private[0] &= 248
key.Private[31] &= 127
key.Private[31] |= 64
curve25519.ScalarBaseMult(&key.Public, &key.Private)
slicedPriv := key.Private[:]
// Do the hashing that generates the IP
out := sha512hash(sha512hash(slicedPriv))
if out[0] != 0xfc {
goto Start
}
// Assemble the IP
out = out[0:16]
for i := 0; i < 16; i++ {
if i > 0 && i < 16 && i%2 == 0 {
key.IP += ":"
}
key.IP += fmt.Sprintf("%02x", out[i])
}
return
}
// Called when we have a valid key to update stats
func KeyDone(Stats *Stats) {
Stats.Counter++
timeNow := time.Now()
timeDiff := timeNow.Sub(Stats.LastTime)
if timeDiff >= Stats.Interval {
speed := Stats.Counter / (timeDiff.Nanoseconds() / 1e9)
fmt.Printf("\r%v keys/second.", speed)
Stats.LastTime = time.Now()
Stats.LastCount += Stats.Counter
Stats.Counter = 0
}
}
func sha512hash(input []byte) []byte {
h := sha512.New()
h.Write(input)
return []byte(h.Sum(nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment