mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
p2p/enr: avoid using btcec directly
This commit is contained in:
parent
dd97fb7bd5
commit
08cdd66304
3 changed files with 28 additions and 50 deletions
|
|
@ -33,11 +33,8 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
|
@ -206,25 +203,27 @@ func (r *Record) DecodeRLP(s *rlp.Stream) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type s256raw []byte
|
||||||
|
|
||||||
|
func (s256raw) ENRKey() string { return "secp256k1" }
|
||||||
|
|
||||||
// NodeAddr returns the node address. The return value will be nil if the record is
|
// NodeAddr returns the node address. The return value will be nil if the record is
|
||||||
// unsigned.
|
// unsigned.
|
||||||
func (r *Record) NodeAddr() []byte {
|
func (r *Record) NodeAddr() []byte {
|
||||||
var secp256k1 Secp256k1
|
var key s256raw
|
||||||
if r.Load(&secp256k1) != nil {
|
if r.Load(&key) != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
pk := btcec.PublicKey(secp256k1)
|
return crypto.Keccak256(key)
|
||||||
return crypto.Keccak256(pk.SerializeCompressed())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign signs the record with the given private key. It updates the record's identity
|
// Sign signs the record with the given private key. It updates the record's identity
|
||||||
// scheme, public key and increments the sequence number. Sign returns an error if the
|
// scheme, public key and increments the sequence number. Sign returns an error if the
|
||||||
// encoded record is larger than the size limit.
|
// encoded record is larger than the size limit.
|
||||||
func (r *Record) Sign(privkey *ecdsa.PrivateKey) error {
|
func (r *Record) Sign(privkey *ecdsa.PrivateKey) error {
|
||||||
pk := (*btcec.PublicKey)(&privkey.PublicKey)
|
|
||||||
r.seq = r.seq + 1
|
r.seq = r.seq + 1
|
||||||
r.Set(ID_SECP256k1_KECCAK)
|
r.Set(ID_SECP256k1_KECCAK)
|
||||||
r.Set(Secp256k1(*pk))
|
r.Set(Secp256k1(privkey.PublicKey))
|
||||||
return r.signAndEncode(privkey)
|
return r.signAndEncode(privkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,14 +243,14 @@ func (r *Record) signAndEncode(privkey *ecdsa.PrivateKey) error {
|
||||||
// Sign the tail of the list.
|
// Sign the tail of the list.
|
||||||
h := sha3.NewKeccak256()
|
h := sha3.NewKeccak256()
|
||||||
rlp.Encode(h, list[1:])
|
rlp.Encode(h, list[1:])
|
||||||
sig, err := (*btcec.PrivateKey)(privkey).Sign(h.Sum(nil))
|
sig, err := crypto.Sign(h.Sum(nil), privkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
sig = sig[:len(sig)-1] // remove v
|
||||||
|
|
||||||
// Put signature in front.
|
// Put signature in front.
|
||||||
r.signature = encodeCompactSignature(sig)
|
r.signature, list[0] = sig, sig
|
||||||
list[0] = r.signature
|
|
||||||
r.raw, err = rlp.EncodeToBytes(list)
|
r.raw, err = rlp.EncodeToBytes(list)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -265,18 +264,16 @@ func (r *Record) signAndEncode(privkey *ecdsa.PrivateKey) error {
|
||||||
func (r *Record) verifySignature() error {
|
func (r *Record) verifySignature() error {
|
||||||
// Get identity scheme, public key, signature.
|
// Get identity scheme, public key, signature.
|
||||||
var id ID
|
var id ID
|
||||||
var secp256k1 Secp256k1
|
var key s256raw
|
||||||
if err := r.Load(&id); err != nil {
|
if err := r.Load(&id); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if id != ID_SECP256k1_KECCAK {
|
} else if id != ID_SECP256k1_KECCAK {
|
||||||
return errNoID
|
return errNoID
|
||||||
}
|
}
|
||||||
if err := r.Load(&secp256k1); err != nil {
|
if err := r.Load(&key); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
sig, err := parseCompactSignature(r.signature)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
|
} else if len(key) != 33 {
|
||||||
|
return fmt.Errorf("invalid public key")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the signature.
|
// Verify the signature.
|
||||||
|
|
@ -284,22 +281,11 @@ func (r *Record) verifySignature() error {
|
||||||
list = r.appendPairs(list)
|
list = r.appendPairs(list)
|
||||||
h := sha3.NewKeccak256()
|
h := sha3.NewKeccak256()
|
||||||
rlp.Encode(h, list)
|
rlp.Encode(h, list)
|
||||||
if !sig.Verify(h.Sum(nil), (*btcec.PublicKey)(&secp256k1)) {
|
fmt.Printf("sig: %x\n", r.signature)
|
||||||
|
fmt.Printf("key: %x\n", key)
|
||||||
|
fmt.Printf("hash: %x\n", h.Sum(nil))
|
||||||
|
if !crypto.VerifySignature(key, h.Sum(nil), r.signature) {
|
||||||
return errInvalidSig
|
return errInvalidSig
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeCompactSignature(sig *btcec.Signature) []byte {
|
|
||||||
b := make([]byte, 64)
|
|
||||||
math.ReadBits(sig.R, b[:32])
|
|
||||||
math.ReadBits(sig.S, b[32:])
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseCompactSignature(sig []byte) (*btcec.Signature, error) {
|
|
||||||
if len(sig) != 64 {
|
|
||||||
return nil, errInvalidSigsize
|
|
||||||
}
|
|
||||||
return &btcec.Signature{R: new(big.Int).SetBytes(sig[:32]), S: new(big.Int).SetBytes(sig[32:])}, nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
@ -32,10 +31,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
privkeyHex = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
|
privkey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
privkey, _ = crypto.HexToECDSA(privkeyHex)
|
pubkey = &privkey.PublicKey
|
||||||
pubkeyBytes, _ = hex.DecodeString("03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138")
|
|
||||||
pubkey, _ = btcec.ParsePubKey(pubkeyBytes, btcec.S256())
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
|
var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -121,25 +121,20 @@ func (v Secp256k1) ENRKey() string { return "secp256k1" }
|
||||||
|
|
||||||
// EncodeRLP implements rlp.Encoder.
|
// EncodeRLP implements rlp.Encoder.
|
||||||
func (v Secp256k1) EncodeRLP(w io.Writer) error {
|
func (v Secp256k1) EncodeRLP(w io.Writer) error {
|
||||||
pk := btcec.PublicKey(v)
|
return rlp.Encode(w, crypto.CompressPubkey((*ecdsa.PublicKey)(&v)))
|
||||||
|
|
||||||
return rlp.Encode(w, pk.SerializeCompressed())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeRLP implements rlp.Decoder.
|
// DecodeRLP implements rlp.Decoder.
|
||||||
func (v *Secp256k1) DecodeRLP(s *rlp.Stream) error {
|
func (v *Secp256k1) DecodeRLP(s *rlp.Stream) error {
|
||||||
buf := make([]byte, 33)
|
buf, err := s.Bytes()
|
||||||
if err := s.Decode(&buf); err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
pk, err := crypto.DecompressPubkey(buf)
|
||||||
pk, err := btcec.ParsePubKey(buf, btcec.S256())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*v = (Secp256k1)(*pk)
|
*v = (Secp256k1)(*pk)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue