Skip to content
File

Blob: spec/tun/session.go

go57 lines
1package tun
2 
3import (
4 "crypto/sha256"
5 "encoding/binary"
6 "encoding/hex"
7 "fmt"
8 "strings"
9 
10 "go.miragespace.co/specter/spec/chord"
11)
12 
13const SessionAliasPrefix = "session:"
14 
15const EphemeralLabelPrefix = "e1-"
16 
17func lowerHex(s string) bool {
18 for _, c := range s {
19 if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) {
20 return false
21 }
22 }
23 return true
24}
25 
26func IsSessionAlias(addr string) bool {
27 return len(addr) == 40 && strings.HasPrefix(addr, SessionAliasPrefix) && lowerHex(addr[len(SessionAliasPrefix):])
28}
29 
30func SessionAlias(inv [16]byte) string { return SessionAliasPrefix + hex.EncodeToString(inv[:]) }
31 
32func EphemeralLabel(home uint64, spki []byte) (label string, inv [16]byte, err error) {
33 if home >= chord.MaxIdentitifer {
34 return "", inv, fmt.Errorf("home ID exceeds 48 bits")
35 }
36 var encoded [8]byte
37 binary.BigEndian.PutUint64(encoded[:], home)
38 h := sha256.New()
39 h.Write([]byte("specter/ephemeral/v1\x00"))
40 h.Write(encoded[2:])
41 h.Write(spki)
42 copy(inv[:], h.Sum(nil))
43 return EphemeralLabelPrefix + hex.EncodeToString(encoded[2:]) + hex.EncodeToString(inv[:]), inv, nil
44}
45 
46func ParseEphemeralLabel(label string) (home uint64, inv [16]byte, ok bool) {
47 if len(label) != 47 || !strings.HasPrefix(label, EphemeralLabelPrefix) || !lowerHex(label[3:]) {
48 return
49 }
50 raw, _ := hex.DecodeString(label[3:])
51 for _, b := range raw[:6] {
52 home = home<<8 | uint64(b)
53 }
54 copy(inv[:], raw[6:])
55 return home, inv, true
56}