/* 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[:], ""} } }