132 lines
3.0 KiB
Go

/*
This file generates crypto keys.
It prints out a new set of keys each time if finds a "better" one.
By default, "better" means a higher NodeID (-> higher IP address).
This is because the IP address format can compress leading 1s in the address, to incrase the number of ID bits in the address.
If run with the "-sig" flag, it generates signing keys instead.
A "better" signing key means one with a higher TreeID.
This only matters if it's high enough to make you the root of the tree.
*/
package main
import (
"encoding/hex"
"flag"
"fmt"
"net"
"runtime"
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
)
var doSig = flag.Bool("sig", false, "generate new signing keys instead")
type keySet struct {
priv []byte
pub []byte
id []byte
ip string
}
func main() {
threads := runtime.GOMAXPROCS(0)
var threadChannels []chan []byte
var currentBest []byte
newKeys := make(chan keySet, threads)
flag.Parse()
for i := 0; i < threads; i++ {
threadChannels = append(threadChannels, make(chan []byte, threads))
switch {
case *doSig:
go doSigKeys(newKeys, threadChannels[i])
default:
go doBoxKeys(newKeys, threadChannels[i])
}
}
for {
newKey := <-newKeys
if isBetter(currentBest[:], newKey.id[:]) || len(currentBest) == 0 {
currentBest = newKey.id
for _, channel := range threadChannels {
select {
case channel <- newKey.id:
}
}
fmt.Println("--------------------------------------------------------------------------------")
switch {
case *doSig:
fmt.Println("sigPriv:", hex.EncodeToString(newKey.priv[:]))
fmt.Println("sigPub:", hex.EncodeToString(newKey.pub[:]))
fmt.Println("TreeID:", hex.EncodeToString(newKey.id[:]))
default:
fmt.Println("boxPriv:", hex.EncodeToString(newKey.priv[:]))
fmt.Println("boxPub:", hex.EncodeToString(newKey.pub[:]))
fmt.Println("NodeID:", hex.EncodeToString(newKey.id[:]))
fmt.Println("IP:", newKey.ip)
}
}
}
}
func isBetter(oldID, newID []byte) bool {
for idx := range oldID {
if newID[idx] > oldID[idx] {
return true
}
if newID[idx] < oldID[idx] {
return false
}
}
return false
}
func doBoxKeys(out chan<- keySet, in <-chan []byte) {
var bestID crypto.NodeID
for {
select {
case newBestID := <-in:
if isBetter(bestID[:], newBestID) {
copy(bestID[:], newBestID)
}
default:
pub, priv := crypto.NewBoxKeys()
id := crypto.GetNodeID(pub)
if !isBetter(bestID[:], id[:]) {
continue
}
bestID = *id
ip := net.IP(address.AddrForNodeID(id)[:]).String()
out <- keySet{priv[:], pub[:], id[:], ip}
}
}
}
func doSigKeys(out chan<- keySet, in <-chan []byte) {
var bestID crypto.TreeID
for idx := range bestID {
bestID[idx] = 0
}
for {
select {
case newBestID := <-in:
if isBetter(bestID[:], newBestID) {
copy(bestID[:], newBestID)
}
default:
}
pub, priv := crypto.NewSigKeys()
id := crypto.GetTreeID(pub)
if !isBetter(bestID[:], id[:]) {
continue
}
bestID = *id
out <- keySet{priv[:], pub[:], id[:], ""}
}
}