Skip to content

Commit

Permalink
Split ST and public key logic RIVM-106
Browse files Browse the repository at this point in the history
  • Loading branch information
vikulin committed Aug 6, 2023
1 parent 3ec7952 commit 42a1e35
Show file tree
Hide file tree
Showing 17 changed files with 133 additions and 102 deletions.
5 changes: 2 additions & 3 deletions cmd/genkeys/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/*
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).
Expand All @@ -8,7 +7,6 @@ This is because the IP address format can compress leading 1s in the address, to
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

Expand All @@ -22,6 +20,7 @@ import (

"github.com/gologme/log"

iwt "github.com/Arceliar/ironwood/types"
c "github.com/RiV-chain/RiV-mesh/src/core"
)

Expand All @@ -46,7 +45,7 @@ func main() {
fmt.Println("Pub:", hex.EncodeToString(newKey.pub))
logger := log.New(os.Stdout, "", log.Flags())
core, _ := c.New(newKey.priv, logger, nil)
addr := core.AddrForKey(newKey.pub)
addr := core.AddrForDomain(iwt.Domain("example"))
fmt.Println("IP:", net.IP(addr[:]).String())
}
}
Expand Down
19 changes: 10 additions & 9 deletions cmd/mesh/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"crypto/ed25519"
"encoding/hex"
"encoding/json"
"flag"
Expand Down Expand Up @@ -31,6 +30,8 @@ import (
"github.com/RiV-chain/RiV-mesh/src/restapi"
"github.com/RiV-chain/RiV-mesh/src/tun"
"github.com/RiV-chain/RiV-mesh/src/version"

iwt "github.com/Arceliar/ironwood/types"
)

type node struct {
Expand Down Expand Up @@ -203,23 +204,23 @@ func run(args rivArgs, sigCh chan os.Signal) {
}
n := &node{}
// Have we been asked for the node address yet? If so, print it and then stop.
getNodeKey := func() ed25519.PublicKey {
if pubkey, err := hex.DecodeString(cfg.PrivateKey); err == nil {
return ed25519.PrivateKey(pubkey).Public().(ed25519.PublicKey)
getDomain := func() iwt.Domain {
if d, err := hex.DecodeString(cfg.Domain); err == nil {
return d
}
return nil
}
switch {
case args.getaddr:
if key := getNodeKey(); key != nil {
addr := n.core.AddrForKey(key)
if domain := getDomain(); domain != nil {
addr := n.core.AddrForDomain(domain)
ip := net.IP(addr[:])
fmt.Println(ip.String())
}
return
case args.getsnet:
if key := getNodeKey(); key != nil {
snet := n.core.SubnetForKey(key)
if domain := getDomain(); domain != nil {
snet := n.core.SubnetForDomain(domain)
ipnet := net.IPNet{
IP: append(snet[:], 0, 0, 0, 0, 0, 0, 0, 0),
Mask: net.CIDRMask(len(snet)*8, 128),
Expand Down Expand Up @@ -324,7 +325,7 @@ func run(args rivArgs, sigCh chan os.Signal) {
// This is just logged to stdout for the user.
address := n.core.Address()
subnet := n.core.Subnet()
public := n.core.GetSelf().Key
public := n.core.GetSelf().Domain
logger.Infof("Your public key is %s", hex.EncodeToString(public[:]))
logger.Infof("Your IPv6 address is %s", address.String())
logger.Infof("Your IPv6 subnet is %s", subnet.String())
Expand Down
4 changes: 2 additions & 2 deletions contrib/mobile/mobile.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ func (m *Mesh) GetSubnetString() string {

// GetPublicKeyString gets the node's public key in hex form
func (m *Mesh) GetPublicKeyString() string {
return hex.EncodeToString(m.core.GetSelf().Key)
return hex.EncodeToString(m.core.GetSelf().Domain)
}

// GetCoordsString gets the node's coordinates
Expand All @@ -230,7 +230,7 @@ func (m *Mesh) GetPeersJSON() (result string) {
IP string
}{}
for _, v := range m.core.GetPeers() {
a := m.core.AddrForKey(v.Key)
a := m.core.AddrForDomain(v.Domain)
ip := net.IP(a[:]).String()
peers = append(peers, struct {
core.PeerInfo
Expand Down
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ module github.com/RiV-chain/RiV-mesh

go 1.18

replace github.com/Arceliar/ironwood => github.com/RiV-chain/ironwood v0.0.0-20230806102314-bd0750e3fe00

require (
github.com/Arceliar/ironwood v0.0.0-20221115123222-ec61cea2f439
github.com/Arceliar/ironwood v0.0.0-20230805085300-86206813435f
github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979
github.com/getlantern/multipath v0.0.0-20220920195041-55195f38df73
github.com/gologme/log v1.2.0
Expand Down Expand Up @@ -41,7 +43,7 @@ require (
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 // indirect
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/google/uuid v1.1.2 // indirect
github.com/google/uuid v1.3.0
github.com/libp2p/go-buffer-pool v0.0.2 // indirect
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
github.com/rivo/uniseg v0.3.4 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
gerace.dev/zipfs v0.2.0 h1:3U1GsasLdxGVhf7lCYbccsH4mpuSpMpLOy37GmfT+KY=
gerace.dev/zipfs v0.2.0/go.mod h1:L6cxA6m8uVfWDawsBHnki/J6Gos5uSlu/6RJZhafrfQ=
github.com/Arceliar/ironwood v0.0.0-20221115123222-ec61cea2f439 h1:eOW6/XIs06TnUn9GPCnfv71CQZw8edP3u3mH3lZt6iM=
github.com/Arceliar/ironwood v0.0.0-20221115123222-ec61cea2f439/go.mod h1:RP72rucOFm5udrnEzTmIWLRVGQiV/fSUAQXJ0RST/nk=
github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979 h1:WndgpSW13S32VLQ3ugUxx2EnnWmgba1kCqPkd4Gk1yQ=
github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979/go.mod h1:6Lkn+/zJilRMsKmbmG1RPoamiArC6HS73xbwRyp3UyI=
github.com/RiV-chain/ironwood v0.0.0-20230806102314-bd0750e3fe00 h1:XeRRkIRhDN0zITv6yx9GkqZ0PQ9WXIfL2dINlhgk+UQ=
github.com/RiV-chain/ironwood v0.0.0-20230806102314-bd0750e3fe00/go.mod h1:RP72rucOFm5udrnEzTmIWLRVGQiV/fSUAQXJ0RST/nk=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -33,6 +33,8 @@ github.com/gologme/log v1.2.0 h1:Ya5Ip/KD6FX7uH0S31QO87nCCSucKtF44TLbTtO7V4c=
github.com/gologme/log v1.2.0/go.mod h1:gq31gQ8wEHkR+WekdWsqDuf8pXTUZA9BnnzTuPz1Y9U=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hjson/hjson-go v3.1.0+incompatible h1:DY/9yE8ey8Zv22bY+mHV1uk2yRy0h8tKhZ77hEdi0Aw=
Expand Down
1 change: 1 addition & 0 deletions src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type NodeConfig struct {
AllowedPublicKeys []string `comment:"List of peer public keys to allow incoming peering connections\nfrom. If left empty/undefined then all connections will be allowed\nby default. This does not affect outgoing peerings, nor does it\naffect link-local peers discovered via multicast."`
PublicKey string `comment:"Your public key. Your peers may ask you for this to put\ninto their AllowedPublicKeys configuration."`
PrivateKey string `comment:"Your private key. DO NOT share this with anyone!"`
Domain string `comment:"Your domain. Should be registered with consensus algo."`
IfName string `comment:"Local network interface name for TUN adapter, or \"auto\" to select\nan interface automatically, or \"none\" to run without TUN."`
IfMTU uint64 `comment:"Maximum Transmission Unit (MTU) size for your local TUN interface.\nDefault is the largest supported size for your platform. The lowest\npossible value is 1280."`
NodeInfoPrivacy bool `comment:"By default, nodeinfo contains some defaults including the platform,\narchitecture and RiV-mesh version. These can help when surveying\nthe network and diagnosing network routing problems. Enabling\nnodeinfo privacy prevents this, so that only items specified in\n\"NodeInfo\" are sent back if specified."`
Expand Down
33 changes: 17 additions & 16 deletions src/core/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package core
import (
"crypto/ed25519"
"encoding/hex"

iwt "github.com/Arceliar/ironwood/types"
)

// Address represents an IPv6 address in the mesh address range.
Expand Down Expand Up @@ -50,23 +52,23 @@ func (c *Core) IsValidSubnet(s Subnet) bool {
return s[l-1] == prefix[l-1]|0x01
}

// AddrForKey takes an ed25519.PublicKey as an argument and returns an *Address.
// This function returns nil if the key length is not ed25519.PublicKeySize.
// AddrForDomain takes a Domain as an argument and returns an *Address.
// This function returns nil if the Domain length is greater ed25519.PublicKeySize.
// This address begins with the contents of GetPrefix(), with the last bit set to 0 to indicate an address.
// The following 8 bits are set to the number of leading 1 bits in the bitwise inverse of the public key.
// The bitwise inverse of the key, excluding the leading 1 bits and the first leading 0 bit, is truncated to the appropriate length and makes up the remainder of the address.
func (c *Core) AddrForKey(publicKey ed25519.PublicKey) *Address {
func (c *Core) AddrForDomain(domain iwt.Domain) *Address {
// 128 bit address
// Begins with prefix
// Next bit is a 0
// Next 7 bits, interpreted as a uint, are # of leading 1s in the NodeID
// Leading 1s and first leading 0 of the NodeID are truncated off
// The rest is appended to the IPv6 address (truncated to 128 bits total)
if len(publicKey) != ed25519.PublicKeySize {
if len(domain) > ed25519.PublicKeySize {
return nil
}
var buf [ed25519.PublicKeySize]byte
copy(buf[:], publicKey)
copy(buf[:], domain)
for idx := range buf {
buf[idx] = ^buf[idx]
}
Expand Down Expand Up @@ -100,29 +102,28 @@ func (c *Core) AddrForKey(publicKey ed25519.PublicKey) *Address {
return &addr
}

// SubnetForKey takes an ed25519.PublicKey as an argument and returns a *Subnet.
// This function returns nil if the key length is not ed25519.PublicKeySize.
// SubnetForDomain takes a Domain as an argument and returns a *Subnet.
// This function returns nil if the Domain length is greater ed25519.PublicKeySize.
// The subnet begins with the address prefix, with the last bit set to 1 to indicate a prefix.
// The following 8 bits are set to the number of leading 1 bits in the bitwise inverse of the key.
// The bitwise inverse of the key, excluding the leading 1 bits and the first leading 0 bit, is truncated to the appropriate length and makes up the remainder of the subnet.
func (c *Core) SubnetForKey(publicKey ed25519.PublicKey) *Subnet {
func (c *Core) SubnetForDomain(domain iwt.Domain) *Subnet {
// Exactly as the address version, with two exceptions:
// 1) The first bit after the fixed prefix is a 1 instead of a 0
// 2) It's truncated to a subnet prefix length instead of 128 bits
addr := c.AddrForKey(publicKey)
addr := c.AddrForDomain(domain)
if addr == nil {
return nil
}
var snet Subnet
copy(snet[:], addr[:])
prefix := c.GetPrefix() // nolint:staticcheck
snet[len(prefix)-1] |= 0x01
snet[len(c.GetPrefix())-1] |= 0x01
return &snet
}

// GetKet returns the partial ed25519.PublicKey for the Address.
// GetKet returns the partial Domain for the Address.
// This is used for key lookup.
func (c *Core) GetAddressKey(a Address) ed25519.PublicKey {
func (c *Core) GetAddressKey(a Address) iwt.Domain {
var key [ed25519.PublicKeySize]byte
prefix := c.GetPrefix() // nolint:staticcheck
ones := int(a[len(prefix)])
Expand All @@ -145,12 +146,12 @@ func (c *Core) GetAddressKey(a Address) ed25519.PublicKey {
for idx := range key {
key[idx] = ^key[idx]
}
return ed25519.PublicKey(key[:])
return iwt.Domain(key[:])
}

// GetKet returns the partial ed25519.PublicKey for the Subnet.
// GetKet returns the partial Domain for the Subnet.
// This is used for key lookup.
func (c *Core) GetSubnetKey(s Subnet) ed25519.PublicKey {
func (c *Core) GetSubnetKey(s Subnet) iwt.Domain {
var addr Address
copy(addr[:], s[:])
return c.GetAddressKey(addr)
Expand Down
10 changes: 6 additions & 4 deletions src/core/address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"crypto/ed25519"
"math/rand"
"testing"

iwt "github.com/Arceliar/ironwood/types"
)

func (c *Core) TestAddress_Address_IsValid(t *testing.T) {
Expand Down Expand Up @@ -54,7 +56,7 @@ func (c *Core) TestAddress_Subnet_IsValid(t *testing.T) {
}

func (c *Core) TestAddress_AddrForKey(t *testing.T) {
publicKey := ed25519.PublicKey{
publicKey := iwt.Domain{
189, 186, 207, 216, 34, 64, 222, 61, 205, 18, 57, 36, 203, 181, 82, 86,
251, 141, 171, 8, 170, 152, 227, 5, 82, 138, 184, 79, 65, 158, 110, 251,
}
Expand All @@ -63,20 +65,20 @@ func (c *Core) TestAddress_AddrForKey(t *testing.T) {
0xfc, 0, 132, 138, 96, 79, 187, 126, 67, 132, 101, 219, 141, 182, 104, 149,
}

if *c.AddrForKey(publicKey) != expectedAddress {
if *c.AddrForDomain(publicKey) != expectedAddress {
t.Fatal("invalid address returned")
}
}

func (c *Core) TestAddress_SubnetForKey(t *testing.T) {
publicKey := ed25519.PublicKey{
publicKey := iwt.Domain{
189, 186, 207, 216, 34, 64, 222, 61, 205, 18, 57, 36, 203, 181, 82, 86,
251, 141, 171, 8, 170, 152, 227, 5, 82, 138, 184, 79, 65, 158, 110, 251,
}

expectedSubnet := Subnet{0xfd, 0, 132, 138, 96, 79, 187, 126}

if *c.SubnetForKey(publicKey) != expectedSubnet {
if *c.SubnetForDomain(publicKey) != expectedSubnet {
t.Fatal("invalid subnet returned")
}
}
Expand Down
Loading

0 comments on commit 42a1e35

Please sign in to comment.