Skip to content

Commit

Permalink
feat: add sign lightning network algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
vincenzopalazzo committed Aug 29, 2022
1 parent 7751893 commit 57a423c
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 2 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/LNOpenMetrics/lnmetrics.utils
go 1.15

require (
github.com/btcsuite/btcd/btcec/v2 v2.2.1
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.2.2
github.com/syndtr/goleveldb v1.0.0
Expand Down
13 changes: 12 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E=
github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
Expand All @@ -21,13 +31,14 @@ github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFd
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
Expand Down
15 changes: 15 additions & 0 deletions goutils/common_error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package goutils

import "fmt"

func Todo(message string, args ...interface{}) error {
return fmt.Errorf(message, args...)
}

func Errf(message string, args ...interface{}) error {
return fmt.Errorf(message, args...)
}

func NotImplementYet() error {
return Todo("not implemented yet")
}
17 changes: 16 additions & 1 deletion hash/sha256/sha256_algo.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,25 @@ import (
"github.com/LNOpenMetrics/lnmetrics.utils/hash"
)

//Calculate the sha256 of the content, and return back the
// SHA256 Calculate the sha256 of the content, and return back the
// string in bach54
func SHA256(content *string) string {
strBytes := hash.ToBytes(content)
hashStr := go_sha256.Sum256(strBytes)
return hash.ToString(hashStr[:])
}

// DoubleSHA256 Double hash is the algorithm used in Bitcoin protocol
func DoubleSHA256(content *string) string {
strBytes := hash.ToBytes(content)
oneHash := go_sha256.Sum256(strBytes)
hashStr := go_sha256.Sum256(oneHash[:])
return hash.ToString(hashStr[:])
}

// DoubleSHA256FromByte Double hash is the algorithm used in Bitcoin protocol
func DoubleSHA256FromByte(content []byte) []byte {
oneHash := go_sha256.Sum256(content)
hashStr := go_sha256.Sum256(oneHash[:])
return hashStr[:]
}
56 changes: 56 additions & 0 deletions sign/ln/ln_signer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Package ln is a package that implement a signature proposed in the
// lightning network protocol, but not yet specified.
package ln

import (
"encoding/base32"
"encoding/hex"
"github.com/LNOpenMetrics/lnmetrics.utils/goutils"
"github.com/LNOpenMetrics/lnmetrics.utils/hash/sha256"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
)

// LNSigner is a struct that implement th Signer interface
type LNSigner struct {
encoder *base32.Encoding
signedMsgPrefix string
}

func NewLNSigner() *LNSigner {
return &LNSigner{
// Copied from https://github.com/ElementsProject/lightning/blob/master/lightningd/signmessage.c#L11
encoder: base32.NewEncoding("ybndrfg8ejkmcpqxot1uwisza345h769"),
signedMsgPrefix: "Lightning Signed Message:",
}
}

// SignMsg sign the message by following the lightning network rules, but it is not implemented
// because required to import the keys to sign the message.
func (self *LNSigner) SignMsg(msg *string) (*string, error) {
return nil, goutils.NotImplementYet()
}

// VerifyMsg sign the message with the lightning network logics implemented in the most popular implementation
func (self *LNSigner) VerifyMsg(key *string, signature *string, msg *string) (bool, error) {
u8sing, err := self.encoder.DecodeString(*signature)
if err != nil {
return false, nil
}

// https://github.com/ElementsProject/lightning/blob/master/lightningd/signmessage.c#L177
if len(u8sing) != 65 {
return false, goutils.Errf("zbase is too is wrong size %d, need to be exactly 65", len(u8sing))
}

// The signature is over the double-sha256 hash of the message.
toVerify := append([]byte(self.signedMsgPrefix), []byte(*msg)...)
digest := sha256.DoubleSHA256FromByte(toVerify)

// RecoverCompact both recovers the pubkey and validates the signature.
pubKey, _, err := ecdsa.RecoverCompact(u8sing, digest)
if err != nil {
return false, nil
}
pubKeyHex := hex.EncodeToString(pubKey.SerializeCompressed())
return pubKeyHex == *key, goutils.NotImplementYet()
}
30 changes: 30 additions & 0 deletions sign/ln/ln_signer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ln

import (
"github.com/stretchr/testify/assert"
"testing"
)

// Test the following command in core lightning
// clightning --testnet signmessage "Testing go utils"
// pub key: 03b39d1ddf13ce486de74e9e44e0538f960401a9ec75534ba9cfe4100d65426880
// zbase32 encoding: d7m5xma1tia1hw6mjkeixqoocexiyoyn1jgm53mncszdeut5j9r1k1nq7wsrh3pkk3c3xp7mkuuxmbneitu3us36cqfn9a6sdu3wa45j
// signature: 57b7af128d712e53cb4a9157ba10621f504002924cbde56265ae344e3b4fc925484eed2c4e65aa565997b7ab54e6f58448ac6799db3e638a2fe3d61cf34c6b69
// message: "Testing go utils"
func TestLNSignerVerifyMsgTrue(t *testing.T) {
pubKey := "03b39d1ddf13ce486de74e9e44e0538f960401a9ec75534ba9cfe4100d65426880"
zbase32 := "d7m5xma1tia1hw6mjkeixqoocexiyoyn1jgm53mncszdeut5j9r1k1nq7wsrh3pkk3c3xp7mkuuxmbneitu3us36cqfn9a6sdu3wa45j"
msg := "Testing go utils"
signer := NewLNSigner()
verified, _ := signer.VerifyMsg(&pubKey, &zbase32, &msg)
assert.Equal(t, true, verified, "Return level returned it is diffirent")
}

func TestLNSignerVerifyMsgFalse(t *testing.T) {
pubKey := "03b39d1ddf13ce486de74e9e44e0538f960401a9ec75534ba9cfe4100d65426880"
zbase32 := "d7m5xma1tia1hw6mjkeixqoocexiyoyn1jgm53mncszdeut5j9r1k1nq7wsrh3pkk3c3xp7mkuuxmbneitu3us36cqfn9a6sdu3wa45j"
msg := "Invalid message"
signer := NewLNSigner()
verified, _ := signer.VerifyMsg(&pubKey, &zbase32, &msg)
assert.Equal(t, false, verified, "Return level returned it is diffirent")
}
19 changes: 19 additions & 0 deletions sign/sign.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Package sign give the API to implement a custom signer
// that is able to sign and verify a sequence of bytes or
// a string.
package sign

// Signer is a common interface that give the possibility to implement
// a signer and verify algorithm in pure go
type Signer interface {
// SignMsg sign a string and return the result or an error
SignMsg(msg *string) (*string, error)

// VerifyMsg a signature with optional public key specified as parameter
// or use some key stored inside the struct.
VerifyMsg(signature *string) (bool, error)
}

// Keys tagger interface to store the information about the
// key (if any) that are used to sign a message.
type Keys interface{}

0 comments on commit 57a423c

Please sign in to comment.