mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2024-11-27 20:15:23 +00:00
132 lines
3.0 KiB
Go
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[:], ""}
|
|
}
|
|
}
|