Skip to content

Commit

Permalink
Move func VerifySig() to the crypto package
Browse files Browse the repository at this point in the history
see #1325
  • Loading branch information
mkrufky authored and mk-livepeer committed Feb 12, 2020
1 parent 70691f5 commit 77327a1
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 60 deletions.
3 changes: 2 additions & 1 deletion core/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/livepeer/go-livepeer/net"
"github.com/livepeer/go-livepeer/pm"

lpcrypto "github.com/livepeer/go-livepeer/crypto"
lpmon "github.com/livepeer/go-livepeer/monitor"
ffmpeg "github.com/livepeer/lpms/ffmpeg"
"github.com/livepeer/lpms/stream"
Expand Down Expand Up @@ -67,7 +68,7 @@ func (orch *orchestrator) VerifySig(addr ethcommon.Address, msg string, sig []by
if orch.node == nil || orch.node.Eth == nil {
return true
}
return pm.VerifySig(addr, crypto.Keccak256([]byte(msg)), sig)
return lpcrypto.VerifySig(addr, crypto.Keccak256([]byte(msg)), sig)
}

func (orch *orchestrator) Address() ethcommon.Address {
Expand Down
56 changes: 56 additions & 0 deletions crypto/verify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package crypto

import (
"errors"
"math/big"

"github.com/ethereum/go-ethereum/accounts"
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)

var (
secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
)

// Verify verifies that a ETH ECDSA signature over a given message
// is produced by a given ETH address
func VerifySig(addr ethcommon.Address, msg, sig []byte) bool {
recovered, err := ecrecover(msg, sig)
if err != nil {
return false
}

return recovered == addr
}

func ecrecover(msg, sig []byte) (ethcommon.Address, error) {
if len(sig) != 65 {
return ethcommon.Address{}, errors.New("invalid signature length")
}

s := new(big.Int).SetBytes(sig[32:64])
if s.Cmp(secp256k1halfN) > 0 {
return ethcommon.Address{}, errors.New("signature s value too high")
}

v := sig[64]
if v != byte(27) && v != byte(28) {
return ethcommon.Address{}, errors.New("signature v value must be 27 or 28")
}

// crypto.SigToPub() expects signature v value = 0/1
// Copy the signature and convert its value to 0/1
ethSig := make([]byte, 65)
copy(ethSig[:], sig[:])
ethSig[64] -= 27

ethMsg := accounts.TextHash(msg)
pubkey, err := crypto.SigToPub(ethMsg, ethSig)
if err != nil {
return ethcommon.Address{}, err
}

return crypto.PubkeyToAddress(*pubkey), nil
}
2 changes: 1 addition & 1 deletion pm/helpers_test.go → crypto/verify_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package pm
package crypto

import (
"testing"
Expand Down
4 changes: 2 additions & 2 deletions eth/accountmanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/core/types"
"github.com/livepeer/go-livepeer/pm"
"github.com/livepeer/go-livepeer/crypto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -93,7 +93,7 @@ func TestSign(t *testing.T) {

sig, err := am.Sign([]byte("foo"))
assert.Nil(err)
assert.True(pm.VerifySig(a.Address, []byte("foo"), sig))
assert.True(crypto.VerifySig(a.Address, []byte("foo"), sig))
}

func tmpKeyStore(t *testing.T, encrypted bool) (string, *keystore.KeyStore) {
Expand Down
52 changes: 0 additions & 52 deletions pm/helpers.go
Original file line number Diff line number Diff line change
@@ -1,63 +1,11 @@
package pm

import (
"math/big"
"math/rand"

"github.com/ethereum/go-ethereum/accounts"
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/pkg/errors"
)

var (
secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
)

// VerifySig verifies that a ETH ECDSA signature over a given message
// is produced by a given ETH address
//
// TODO refactor to a package that both eth and pm can import
func VerifySig(addr ethcommon.Address, msg, sig []byte) bool {
recovered, err := ecrecover(msg, sig)
if err != nil {
return false
}

return recovered == addr
}

func ecrecover(msg, sig []byte) (ethcommon.Address, error) {
if len(sig) != 65 {
return ethcommon.Address{}, errors.New("invalid signature length")
}

s := new(big.Int).SetBytes(sig[32:64])
if s.Cmp(secp256k1halfN) > 0 {
return ethcommon.Address{}, errors.New("signature s value too high")
}

v := sig[64]
if v != byte(27) && v != byte(28) {
return ethcommon.Address{}, errors.New("signature v value must be 27 or 28")
}

// crypto.SigToPub() expects signature v value = 0/1
// Copy the signature and convert its value to 0/1
ethSig := make([]byte, 65)
copy(ethSig[:], sig[:])
ethSig[64] -= 27

ethMsg := accounts.TextHash(msg)
pubkey, err := crypto.SigToPub(ethMsg, ethSig)
if err != nil {
return ethcommon.Address{}, err
}

return crypto.PubkeyToAddress(*pubkey), nil
}

// RandHash returns a random keccak256 hash
func RandHash() ethcommon.Hash {
return ethcommon.BytesToHash(RandBytes(32))
Expand Down
3 changes: 2 additions & 1 deletion pm/sigverifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pm

import (
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/livepeer/go-livepeer/crypto"
)

// SigVerifier is an interface which describes an object capable
Expand All @@ -20,7 +21,7 @@ type DefaultSigVerifier struct {
// Verify checks if a provided signature over a message
// is valid for a given ETH address
func (sv *DefaultSigVerifier) Verify(addr ethcommon.Address, msg, sig []byte) bool {
return VerifySig(addr, msg, sig)
return crypto.VerifySig(addr, msg, sig)
}

// ApprovedSigVerifier is an implementation of the SigVerifier interface
Expand Down
4 changes: 2 additions & 2 deletions server/broadcast.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import (

"github.com/livepeer/go-livepeer/common"
"github.com/livepeer/go-livepeer/core"
lpcrypto "github.com/livepeer/go-livepeer/crypto"
"github.com/livepeer/go-livepeer/drivers"
"github.com/livepeer/go-livepeer/monitor"
"github.com/livepeer/go-livepeer/net"
"github.com/livepeer/go-livepeer/pm"
"github.com/livepeer/go-livepeer/verification"

"github.com/livepeer/lpms/ffmpeg"
Expand Down Expand Up @@ -491,7 +491,7 @@ func transcodeSegment(cxn *rtmpConnection, seg *stream.HLSSegment, name string,
// Might not have seg hashes if results are directly uploaded to the broadcaster's OS
// TODO: Consider downloading the results to generate seg hashes if results are directly uploaded to the broadcaster's OS
len(segHashes) != len(res.Segments) &&
!pm.VerifySig(ethcommon.BytesToAddress(ticketParams.Recipient), crypto.Keccak256(segHashes...), res.Sig) {
!lpcrypto.VerifySig(ethcommon.BytesToAddress(ticketParams.Recipient), crypto.Keccak256(segHashes...), res.Sig) {
glog.Errorf("Sig check failed for segment nonce=%d seqNo=%d", nonce, seg.SeqNo)
cxn.sessManager.removeSession(sess)
return nil, errPMCheckFailed
Expand Down
3 changes: 2 additions & 1 deletion server/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/livepeer/go-livepeer/common"
"github.com/livepeer/go-livepeer/core"
"github.com/livepeer/go-livepeer/crypto"
"github.com/livepeer/go-livepeer/drivers"
"github.com/livepeer/go-livepeer/net"
"github.com/livepeer/go-livepeer/pm"
Expand Down Expand Up @@ -96,7 +97,7 @@ func (r *stubOrchestrator) Sign(msg []byte) ([]byte, error) {
}

func (r *stubOrchestrator) VerifySig(addr ethcommon.Address, msg string, sig []byte) bool {
return pm.VerifySig(addr, ethcrypto.Keccak256([]byte(msg)), sig)
return crypto.VerifySig(addr, ethcrypto.Keccak256([]byte(msg)), sig)
}

func (r *stubOrchestrator) Address() ethcommon.Address {
Expand Down

0 comments on commit 77327a1

Please sign in to comment.