mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
p2p/enr: use compact signature encoding
This commit is contained in:
parent
e490233414
commit
12ac6cd58b
2 changed files with 37 additions and 33 deletions
|
|
@ -22,19 +22,18 @@ import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"errors"
|
"errors"
|
||||||
"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/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ()
|
var (
|
||||||
|
errNoID = errors.New("unknown or unspecified identity scheme")
|
||||||
// The maximum encoded size of a node record is 300 bytes. Implementations should reject records larger than this size.
|
errInvalidSigsize = errors.New("invalid signature size")
|
||||||
const (
|
|
||||||
ID_SECP256k1_KECCAK = "secp256k1-keccak" // "secp256k1-keccak" identity scheme identifier
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Key is implemented by known node record key types.
|
// Key is implemented by known node record key types.
|
||||||
|
|
@ -249,14 +248,11 @@ func (r *Record) signAndEncode(privkey *ecdsa.PrivateKey) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
digest := crypto.Keccak256Hash(sigcontent)
|
sig, err := (*btcec.PrivateKey)(privkey).Sign(crypto.Keccak256(sigcontent))
|
||||||
|
|
||||||
key := btcec.PrivateKey(*privkey)
|
|
||||||
signature, err := key.Sign(digest.Bytes())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r.signature = signature.Serialize()
|
r.signature = encodeCompactSignature(sig)
|
||||||
|
|
||||||
blob, err := rlp.EncodeToBytes(r.signature)
|
blob, err := rlp.EncodeToBytes(r.signature)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -271,35 +267,41 @@ func (r *Record) signAndEncode(privkey *ecdsa.PrivateKey) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Record) verifySignature(sigcontent []byte) error {
|
func (r *Record) verifySignature(sigcontent []byte) error {
|
||||||
|
// Get identity scheme, public key.
|
||||||
var id ID
|
var id ID
|
||||||
_, err := r.Load(&id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// currently "secp256k1-keccak" is the only known identity scheme
|
|
||||||
if id != ID_SECP256k1_KECCAK {
|
|
||||||
return errors.New("unknown identity scheme")
|
|
||||||
}
|
|
||||||
|
|
||||||
// get publickey from record
|
|
||||||
var secp256k1 Secp256k1
|
var secp256k1 Secp256k1
|
||||||
_, err = r.Load(&secp256k1)
|
if _, err := r.Load(&id); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
|
}
|
||||||
|
if id != ID_SECP256k1_KECCAK {
|
||||||
|
return errNoID
|
||||||
|
}
|
||||||
|
if _, err := r.Load(&secp256k1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
digest := crypto.Keccak256Hash(sigcontent)
|
// Verify the signature.
|
||||||
|
sig, err := parseCompactSignature(r.signature)
|
||||||
sign, err := btcec.ParseSignature(r.signature, btcec.S256())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if !sig.Verify(crypto.Keccak256(sigcontent), (*btcec.PublicKey)(&secp256k1)) {
|
||||||
if !sign.Verify(digest.Bytes(), (*btcec.PublicKey)(&secp256k1)) {
|
|
||||||
return errors.New("signature is not valid")
|
return errors.New("signature is not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,9 @@ func (DiscPort) ENRKey() string {
|
||||||
return "discv5"
|
return "discv5"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID is the name of identity scheme, e.g. "secp256k1-keccak".
|
const ID_SECP256k1_KECCAK = "secp256k1-keccak" // identity scheme identifier
|
||||||
|
|
||||||
|
// ID is the name of the identity scheme, e.g. "secp256k1-keccak".
|
||||||
type ID string
|
type ID string
|
||||||
|
|
||||||
func (ID) ENRKey() string {
|
func (ID) ENRKey() string {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue