Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
e1eabc3
build: point to latest lnd w/ TLV package
Roasbeef Jul 24, 2019
d01f017
sphinx: Introduce HopPayload as opaque, variable length, byte-slice
cdecker Feb 4, 2019
0905948
multi-frame: Introduce frameSize constant to differentiate hops from …
cdecker Feb 5, 2019
5bd4035
multi-frame: Use HopPayload instead of HopData
cdecker Feb 4, 2019
dfdb189
multi-frame: Actually use multiple frames for a single payload
cdecker Feb 5, 2019
51659d9
multi-frame: Add a test for multi-frame onions
cdecker Feb 5, 2019
f4e4208
tool: Add an onion spec in JSON that can be passed in
cdecker Feb 12, 2019
f2ff78b
sphinx: move HopData to path.go re-add its Decode method
Roasbeef May 14, 2019
b175ee5
sphinx: add new NewHopPayload constructor
Roasbeef May 14, 2019
d70c20f
sphinx: get rid of mutating CalculateRealm method in favor of packRealm
Roasbeef May 14, 2019
1ce3fd7
sphinx: remove HopData from OnionHop, expose left over EOB from payload
Roasbeef May 14, 2019
60a2703
sphinx: convert to variable sized EOB payloads
Roasbeef Jul 4, 2019
7f17f54
sphinx: replace prior EOB test with TestSphinxHopVariableSizedPayloads
Roasbeef Jul 4, 2019
41ff4a6
sphinx: add variable sized EOB spec JSON tests
Roasbeef Jul 4, 2019
3b4e296
cmd: update CLI tool with latest API changes
Roasbeef Jul 4, 2019
7302ea4
sphinx: switch to using BigSize for varints
Roasbeef Jul 24, 2019
0779eb2
testdata: update to latest variable payload onion using BigSize
Roasbeef Jul 24, 2019
a94cd91
build: tidy go modules
Roasbeef Aug 7, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@ func BenchmarkPathPacketConstruction(b *testing.B) {
}

hopData := HopData{
Realm: [1]byte{0x00},
ForwardAmount: uint64(i),
OutgoingCltv: uint32(i),
}
copy(hopData.NextAddress[:], bytes.Repeat([]byte{byte(i)}, 8))

hopPayload, err := NewHopPayload(&hopData, nil)
if err != nil {
b.Fatalf("unable to create new hop payload: %v", err)
}

route[i] = OnionHop{
NodePub: *privKey.PubKey(),
HopData: hopData,
NodePub: *privKey.PubKey(),
HopPayload: hopPayload,
}
}

Expand Down
121 changes: 88 additions & 33 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
Expand All @@ -14,6 +15,68 @@ import (
sphinx "github.com/lightningnetwork/lightning-onion"
)

type OnionHopSpec struct {
Realm int `json:"realm"`
PublicKey string `json:"pubkey"`
Payload string `json:"payload"`
}

type OnionSpec struct {
SessionKey string `json:"session_key,omitempty"`
Hops []OnionHopSpec `json:"hops"`
}

func parseOnionSpec(spec OnionSpec) (*sphinx.PaymentPath, *btcec.PrivateKey, error) {
var path sphinx.PaymentPath
var binSessionKey []byte
var err error

if spec.SessionKey != "" {
binSessionKey, err = hex.DecodeString(spec.SessionKey)
if err != nil {
log.Fatalf("Unable to decode the sessionKey %v: %v\n", spec.SessionKey, err)
}

if len(binSessionKey) != 32 {
log.Fatalf("Session key must be a 32 byte hex string: %v\n", spec.SessionKey)
}
} else {
binSessionKey = bytes.Repeat([]byte{'A'}, 32)
}

sessionKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), binSessionKey)

for i, hop := range spec.Hops {
binKey, err := hex.DecodeString(hop.PublicKey)
if err != nil || len(binKey) != 33 {
log.Fatalf("%s is not a valid hex pubkey %s", hop.PublicKey, err)
}

pubkey, err := btcec.ParsePubKey(binKey, btcec.S256())
if err != nil {
log.Fatalf("%s is not a valid hex pubkey %s", hop.PublicKey, err)
}

path[i].NodePub = *pubkey

payload, err := hex.DecodeString(hop.Payload)
if err != nil {
log.Fatalf("%s is not a valid hex payload %s",
hop.Payload, err)
}

hopPayload, err := sphinx.NewHopPayload(nil, payload)
if err != nil {
log.Fatalf("unable to make payload: %v", err)
}

path[i].HopPayload = hopPayload

fmt.Fprintf(os.Stderr, "Node %d pubkey %x\n", i, pubkey.SerializeCompressed())
}
return &path, sessionKey, nil
}

// main implements a simple command line utility that can be used in order to
// either generate a fresh mix-header or decode and fully process an existing
// one given a private key.
Expand All @@ -22,44 +85,33 @@ func main() {

assocData := bytes.Repeat([]byte{'B'}, 32)

if len(args) == 1 {
fmt.Printf("Usage: %s (generate|decode) <private-keys>\n", args[0])
if len(args) < 3 {
fmt.Printf("Usage: %s (generate|decode) <input-file>\n", args[0])
return
} else if args[1] == "generate" {
var path sphinx.PaymentPath
for i, hexKey := range args[2:] {
binKey, err := hex.DecodeString(hexKey)
if err != nil || len(binKey) != 33 {
log.Fatalf("%s is not a valid hex pubkey %s", hexKey, err)
}

pubkey, err := btcec.ParsePubKey(binKey, btcec.S256())
if err != nil {
panic(err)
}

path[i] = sphinx.OnionHop{
NodePub: *pubkey,
HopData: sphinx.HopData{
Realm: [1]byte{0x00},
ForwardAmount: uint64(i),
OutgoingCltv: uint32(i),
},
}
copy(path[i].HopData.NextAddress[:], bytes.Repeat([]byte{byte(i)}, 8))

fmt.Fprintf(os.Stderr, "Node %d pubkey %x\n", i, pubkey.SerializeCompressed())
}

sessionKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), bytes.Repeat([]byte{'A'}, 32))

msg, err := sphinx.NewOnionPacket(&path, sessionKey, assocData)
var spec OnionSpec

jsonSpec, err := ioutil.ReadFile(args[2])
if err != nil {
log.Fatalf("Unable to read JSON onion spec from file %v: %v", args[2], err)
}

if err := json.Unmarshal(jsonSpec, &spec); err != nil {
log.Fatalf("Unable to parse JSON onion spec: %v", err)
}

path, sessionKey, err := parseOnionSpec(spec)
if err != nil {
log.Fatalf("could not parse onion spec: %v", err)
}

msg, err := sphinx.NewOnionPacket(path, sessionKey, assocData)
if err != nil {
log.Fatalf("Error creating message: %v", err)
}

w := bytes.NewBuffer([]byte{})
err = msg.Encode(w)

if err != nil {
log.Fatalf("Error serializing message: %v", err)
}
Expand All @@ -78,8 +130,11 @@ func main() {
}

privkey, _ := btcec.PrivKeyFromBytes(btcec.S256(), binKey)
s := sphinx.NewRouter(privkey, &chaincfg.TestNet3Params,
sphinx.NewMemoryReplayLog())
replayLog := sphinx.NewMemoryReplayLog()
s := sphinx.NewRouter(privkey, &chaincfg.TestNet3Params, replayLog)

replayLog.Start()
defer replayLog.Stop()

var packet sphinx.OnionPacket
err = packet.Decode(bytes.NewBuffer(binMsg))
Expand Down
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ module github.com/lightningnetwork/lightning-onion

require (
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da
github.com/btcsuite/btcd v0.0.0-20181130015935-7d2daa5bfef2
github.com/btcsuite/btcd v0.0.0-20190629003639-c26ffa870fd8
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc
golang.org/x/sys v0.0.0-20190102155601-82a175fd1598 // indirect
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/davecgh/go-spew v1.1.1
github.com/lightningnetwork/lnd v0.7.1-beta.0.20190807225126-ea77ff91c221
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67
)
Loading