Last active
December 14, 2015 16:59
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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