yggdrasil-go/cmd/genkeys/main.go

129 lines
3.0 KiB
Go
Raw Normal View History

2017-12-29 04:16:20 +00:00
/*
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).
2019-11-29 09:45:02 +00:00
This is because the IP address format can compress leading 1s in the address, to increase the number of ID bits in the address.
2017-12-29 04:16:20 +00:00
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"
)
2017-12-29 04:16:20 +00:00
var doSig = flag.Bool("sig", false, "generate new signing keys instead")
2018-02-21 15:57:03 +00:00
type keySet struct {
priv []byte
pub []byte
id []byte
ip string
}
2017-12-29 04:16:20 +00:00
func main() {
2018-02-21 15:57:03 +00:00
threads := runtime.GOMAXPROCS(0)
var threadChannels []chan []byte
var currentBest []byte
newKeys := make(chan keySet, threads)
2018-01-04 22:37:51 +00:00
flag.Parse()
2018-02-21 15:57:03 +00:00
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 {
2018-02-21 15:57:03 +00:00
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))
2018-02-21 15:57:03 +00:00
default:
fmt.Println("boxPriv:", hex.EncodeToString(newKey.priv))
fmt.Println("boxPub:", hex.EncodeToString(newKey.pub))
fmt.Println("NodeID:", hex.EncodeToString(newKey.id))
2018-02-21 15:57:03 +00:00
fmt.Println("IP:", newKey.ip)
}
}
2018-01-04 22:37:51 +00:00
}
2017-12-29 04:16:20 +00:00
}
func isBetter(oldID, newID []byte) bool {
2018-01-04 22:37:51 +00:00
for idx := range oldID {
if newID[idx] != oldID[idx] {
return newID[idx] > oldID[idx]
2018-01-04 22:37:51 +00:00
}
}
return false
2017-12-29 04:16:20 +00:00
}
2018-02-21 15:57:03 +00:00
func doBoxKeys(out chan<- keySet, in <-chan []byte) {
var bestID crypto.NodeID
2018-01-04 22:37:51 +00:00
for {
2018-02-21 15:57:03 +00:00
select {
case newBestID := <-in:
if isBetter(bestID[:], newBestID) {
copy(bestID[:], newBestID)
}
default:
pub, priv := crypto.NewBoxKeys()
id := crypto.GetNodeID(pub)
2018-02-21 15:57:03 +00:00
if !isBetter(bestID[:], id[:]) {
continue
}
bestID = *id
ip := net.IP(address.AddrForNodeID(id)[:]).String()
2018-02-21 15:57:03 +00:00
out <- keySet{priv[:], pub[:], id[:], ip}
2018-01-04 22:37:51 +00:00
}
}
2017-12-29 04:16:20 +00:00
}
2018-02-21 15:57:03 +00:00
func doSigKeys(out chan<- keySet, in <-chan []byte) {
var bestID crypto.TreeID
2018-01-04 22:37:51 +00:00
for idx := range bestID {
bestID[idx] = 0
}
for {
2018-02-21 15:57:03 +00:00
select {
case newBestID := <-in:
if isBetter(bestID[:], newBestID) {
copy(bestID[:], newBestID)
}
default:
}
pub, priv := crypto.NewSigKeys()
id := crypto.GetTreeID(pub)
2018-01-04 22:37:51 +00:00
if !isBetter(bestID[:], id[:]) {
continue
}
bestID = *id
2018-02-21 15:57:03 +00:00
out <- keySet{priv[:], pub[:], id[:], ""}
2018-01-04 22:37:51 +00:00
}
2017-12-29 04:16:20 +00:00
}