mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
Refactor crypto.FromECDSAPub to MarshalPubkey/Std (#3797)
Most places that used this method were cutting off the 1st byte. Refactor this idea to a common place. * better naming: MarshalPubkey matches existing UnmarshalPubkey * "Std" suffix for the ANSI standard encoding without cut off * docs
This commit is contained in:
parent
4519e10e39
commit
930d662f21
@ -88,7 +88,7 @@ func main() {
|
||||
}
|
||||
|
||||
if *writeAddr {
|
||||
fmt.Printf("%x\n", crypto.FromECDSAPub(&nodeKey.PublicKey)[1:])
|
||||
fmt.Printf("%x\n", crypto.MarshalPubkey(&nodeKey.PublicKey))
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
|
@ -1491,7 +1491,7 @@ func (s *EmptyStep) author() (common.Address, error) {
|
||||
if err != nil {
|
||||
return common.Address{}, err
|
||||
}
|
||||
ecdsa, err := crypto.UnmarshalPubkey(public)
|
||||
ecdsa, err := crypto.UnmarshalPubkeyStd(public)
|
||||
if err != nil {
|
||||
return common.Address{}, err
|
||||
}
|
||||
|
@ -173,8 +173,10 @@ func FromECDSA(priv *ecdsa.PrivateKey) []byte {
|
||||
return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
|
||||
}
|
||||
|
||||
// UnmarshalPubkey converts bytes to a secp256k1 public key.
|
||||
func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
|
||||
// UnmarshalPubkeyStd parses a public key from the given bytes in the standard "uncompressed" format.
|
||||
// The input slice must be 65 bytes long and have this format: [4, X..., Y...]
|
||||
// See MarshalPubkeyStd.
|
||||
func UnmarshalPubkeyStd(pub []byte) (*ecdsa.PublicKey, error) {
|
||||
x, y := elliptic.Unmarshal(S256(), pub)
|
||||
if x == nil {
|
||||
return nil, errInvalidPubkey
|
||||
@ -182,13 +184,39 @@ func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
|
||||
return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
|
||||
}
|
||||
|
||||
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
|
||||
// MarshalPubkeyStd converts a public key into the standard "uncompressed" format.
|
||||
// It returns a 65 bytes long slice that contains: [4, X..., Y...]
|
||||
// Returns nil if the given public key is not initialized.
|
||||
// See UnmarshalPubkeyStd.
|
||||
func MarshalPubkeyStd(pub *ecdsa.PublicKey) []byte {
|
||||
if pub == nil || pub.X == nil || pub.Y == nil {
|
||||
return nil
|
||||
}
|
||||
return elliptic.Marshal(S256(), pub.X, pub.Y)
|
||||
}
|
||||
|
||||
// UnmarshalPubkey parses a public key from the given bytes in the 64 bytes "uncompressed" format.
|
||||
// The input slice must be 64 bytes long and have this format: [X..., Y...]
|
||||
// See MarshalPubkey.
|
||||
func UnmarshalPubkey(keyBytes []byte) (*ecdsa.PublicKey, error) {
|
||||
keyBytes = append([]byte{0x4}, keyBytes...)
|
||||
return UnmarshalPubkeyStd(keyBytes)
|
||||
}
|
||||
|
||||
// MarshalPubkey converts a public key into a 64 bytes "uncompressed" format.
|
||||
// It returns a 64 bytes long slice that contains: [X..., Y...]
|
||||
// In the standard 65 bytes format the first byte is always constant (equal to 4),
|
||||
// so it can be cut off and trivially recovered later.
|
||||
// Returns nil if the given public key is not initialized.
|
||||
// See UnmarshalPubkey.
|
||||
func MarshalPubkey(pubkey *ecdsa.PublicKey) []byte {
|
||||
keyBytes := MarshalPubkeyStd(pubkey)
|
||||
if keyBytes == nil {
|
||||
return nil
|
||||
}
|
||||
return keyBytes[1:]
|
||||
}
|
||||
|
||||
// HexToECDSA parses a secp256k1 private key.
|
||||
func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
|
||||
b, err := hex.DecodeString(hexkey)
|
||||
@ -284,8 +312,8 @@ func ValidateSignatureValues(v byte, r, s *uint256.Int, homestead bool) bool {
|
||||
|
||||
// DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
|
||||
func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
|
||||
pubBytes := FromECDSAPub(&p)
|
||||
return common.BytesToAddress(Keccak256(pubBytes[1:])[12:])
|
||||
pubBytes := MarshalPubkey(&p)
|
||||
return common.BytesToAddress(Keccak256(pubBytes)[12:])
|
||||
}
|
||||
|
||||
func zeroBytes(bytes []byte) {
|
||||
|
@ -78,7 +78,7 @@ func TestUnmarshalPubkey(t *testing.T) {
|
||||
}
|
||||
|
||||
var (
|
||||
enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d")
|
||||
enc, _ = hex.DecodeString("760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d")
|
||||
dec = &ecdsa.PublicKey{
|
||||
Curve: S256(),
|
||||
X: hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"),
|
||||
@ -107,7 +107,7 @@ func TestSign(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("ECRecover error: %s", err)
|
||||
}
|
||||
pubKey, _ := UnmarshalPubkey(recoveredPub)
|
||||
pubKey, _ := UnmarshalPubkeyStd(recoveredPub)
|
||||
recoveredAddr := PubkeyToAddress(*pubKey)
|
||||
if addr != recoveredAddr {
|
||||
t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
|
||||
|
@ -90,7 +90,7 @@ func TestDecompressPubkey(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if uncompressed := FromECDSAPub(key); !bytes.Equal(uncompressed, testpubkey) {
|
||||
if uncompressed := MarshalPubkeyStd(key); !bytes.Equal(uncompressed, testpubkey) {
|
||||
t.Errorf("wrong public key result: got %x, want %x", uncompressed, testpubkey)
|
||||
}
|
||||
if _, err := DecompressPubkey(nil); err == nil {
|
||||
|
@ -247,7 +247,7 @@ func (e *rootEntry) sigHash() []byte {
|
||||
|
||||
func (e *rootEntry) verifySignature(pubkey *ecdsa.PublicKey) bool {
|
||||
sig := e.sig[:crypto.RecoveryIDOffset] // remove recovery id
|
||||
enckey := crypto.FromECDSAPub(pubkey)
|
||||
enckey := crypto.MarshalPubkeyStd(pubkey)
|
||||
return crypto.VerifySignature(enckey, e.sigHash(), sig)
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,6 @@ func parsePubkey(in string) (*ecdsa.PublicKey, error) {
|
||||
} else if len(b) != 64 {
|
||||
return nil, fmt.Errorf("wrong length, want %d hex chars", 128)
|
||||
}
|
||||
b = append([]byte{0x4}, b...)
|
||||
return crypto.UnmarshalPubkey(b)
|
||||
}
|
||||
|
||||
@ -175,7 +174,7 @@ func (n *Node) URLv4() string {
|
||||
n.Load((*Secp256k1)(&key))
|
||||
switch {
|
||||
case scheme == "v4" || key != ecdsa.PublicKey{}:
|
||||
nodeid = fmt.Sprintf("%x", crypto.FromECDSAPub(&key)[1:])
|
||||
nodeid = fmt.Sprintf("%x", crypto.MarshalPubkey(&key))
|
||||
default:
|
||||
nodeid = fmt.Sprintf("%s.%x", scheme, n.id[:])
|
||||
}
|
||||
|
@ -567,7 +567,7 @@ func (h *handshakeState) makeAuthMsg(prv *ecdsa.PrivateKey) (*authMsgV4, error)
|
||||
|
||||
msg := new(authMsgV4)
|
||||
copy(msg.Signature[:], signature)
|
||||
copy(msg.InitiatorPubkey[:], crypto.FromECDSAPub(&prv.PublicKey)[1:])
|
||||
copy(msg.InitiatorPubkey[:], crypto.MarshalPubkey(&prv.PublicKey))
|
||||
copy(msg.Nonce[:], h.initNonce)
|
||||
msg.Version = 4
|
||||
return msg, nil
|
||||
@ -640,20 +640,18 @@ func (h *handshakeState) sealEIP8(msg interface{}) ([]byte, error) {
|
||||
return append(prefix, enc...), err
|
||||
}
|
||||
|
||||
// importPublicKey unmarshals 512 bit public keys.
|
||||
// importPublicKey unmarshals 64 or 65 bytes long public keys.
|
||||
func importPublicKey(pubKey []byte) (*ecies.PublicKey, error) {
|
||||
var pubKey65 []byte
|
||||
var pub *ecdsa.PublicKey
|
||||
var err error
|
||||
switch len(pubKey) {
|
||||
case 64:
|
||||
// add 'uncompressed key' flag
|
||||
pubKey65 = append([]byte{0x04}, pubKey...)
|
||||
pub, err = crypto.UnmarshalPubkey(pubKey)
|
||||
case 65:
|
||||
pubKey65 = pubKey
|
||||
pub, err = crypto.UnmarshalPubkeyStd(pubKey)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid public key length %v (expect 64/65)", len(pubKey))
|
||||
}
|
||||
// TODO: fewer pointless conversions
|
||||
pub, err := crypto.UnmarshalPubkey(pubKey65)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -268,12 +268,12 @@ var (
|
||||
|
||||
func TestHandshakeForwardCompatibility(t *testing.T) {
|
||||
var (
|
||||
pubA = crypto.FromECDSAPub(&keyA.PublicKey)[1:]
|
||||
pubB = crypto.FromECDSAPub(&keyB.PublicKey)[1:]
|
||||
pubA = crypto.MarshalPubkey(&keyA.PublicKey)
|
||||
pubB = crypto.MarshalPubkey(&keyB.PublicKey)
|
||||
ephA, _ = crypto.HexToECDSA("869d6ecf5211f1cc60418a13b9d870b22959d0c16f02bec714c960dd2298a32d")
|
||||
ephB, _ = crypto.HexToECDSA("e238eb8e04fee6511ab04c6dd3c89ce097b11f25d584863ac2b6d5b35b1847e4")
|
||||
ephPubA = crypto.FromECDSAPub(&ephA.PublicKey)[1:]
|
||||
ephPubB = crypto.FromECDSAPub(&ephB.PublicKey)[1:]
|
||||
ephPubA = crypto.MarshalPubkey(&ephA.PublicKey)
|
||||
ephPubB = crypto.MarshalPubkey(&ephB.PublicKey)
|
||||
nonceA = unhex("7e968bba13b6c50e2c4cd7f241cc0d64d1ac25c7f5952df231ac6a2bda8ee5d6")
|
||||
nonceB = unhex("559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd")
|
||||
_, _, _, _ = pubA, pubB, ephPubA, ephPubB
|
||||
|
@ -511,8 +511,8 @@ func (srv *Server) Start(ctx context.Context) error {
|
||||
|
||||
func (srv *Server) setupLocalNode() error {
|
||||
// Create the devp2p handshake.
|
||||
pubkey := crypto.FromECDSAPub(&srv.PrivateKey.PublicKey)
|
||||
srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, Pubkey: pubkey[1:]}
|
||||
pubkey := crypto.MarshalPubkey(&srv.PrivateKey.PublicKey)
|
||||
srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, Pubkey: pubkey}
|
||||
for _, p := range srv.Protocols {
|
||||
srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap())
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ func (c *testTransport) doEncHandshake(prv *ecdsa.PrivateKey) (*ecdsa.PublicKey,
|
||||
}
|
||||
|
||||
func (c *testTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) {
|
||||
pubkey := crypto.FromECDSAPub(c.rpub)[1:]
|
||||
pubkey := crypto.MarshalPubkey(c.rpub)
|
||||
return &protoHandshake{Pubkey: pubkey, Name: "test"}, nil
|
||||
}
|
||||
|
||||
@ -317,7 +317,7 @@ func TestServerPeerLimits(t *testing.T) {
|
||||
var tp = &setupTransport{
|
||||
pubkey: &clientkey.PublicKey,
|
||||
phs: protoHandshake{
|
||||
Pubkey: crypto.FromECDSAPub(&clientkey.PublicKey)[1:],
|
||||
Pubkey: crypto.MarshalPubkey(&clientkey.PublicKey),
|
||||
// Force "DiscUselessPeer" due to unmatching caps
|
||||
// Caps: []Cap{discard.cap()},
|
||||
},
|
||||
@ -416,13 +416,13 @@ func TestServerSetupConn(t *testing.T) {
|
||||
wantCloseErr: errors.New("foo"),
|
||||
},
|
||||
{
|
||||
tt: &setupTransport{pubkey: srvpub, phs: protoHandshake{Pubkey: crypto.FromECDSAPub(srvpub)[1:]}},
|
||||
tt: &setupTransport{pubkey: srvpub, phs: protoHandshake{Pubkey: crypto.MarshalPubkey(srvpub)}},
|
||||
flags: inboundConn,
|
||||
wantCalls: "doEncHandshake,close,",
|
||||
wantCloseErr: DiscSelf,
|
||||
},
|
||||
{
|
||||
tt: &setupTransport{pubkey: clientpub, phs: protoHandshake{Pubkey: crypto.FromECDSAPub(clientpub)[1:]}},
|
||||
tt: &setupTransport{pubkey: clientpub, phs: protoHandshake{Pubkey: crypto.MarshalPubkey(clientpub)}},
|
||||
flags: inboundConn,
|
||||
wantCalls: "doEncHandshake,doProtoHandshake,close,",
|
||||
wantCloseErr: DiscUselessPeer,
|
||||
|
@ -30,11 +30,11 @@ import (
|
||||
func TestProtocolHandshake(t *testing.T) {
|
||||
var (
|
||||
prv0, _ = crypto.GenerateKey()
|
||||
pub0 = crypto.FromECDSAPub(&prv0.PublicKey)[1:]
|
||||
pub0 = crypto.MarshalPubkey(&prv0.PublicKey)
|
||||
hs0 = &protoHandshake{Version: 3, Pubkey: pub0, Caps: []Cap{{"a", 0}, {"b", 2}}}
|
||||
|
||||
prv1, _ = crypto.GenerateKey()
|
||||
pub1 = crypto.FromECDSAPub(&prv1.PublicKey)[1:]
|
||||
pub1 = crypto.MarshalPubkey(&prv1.PublicKey)
|
||||
hs1 = &protoHandshake{Version: 3, Pubkey: pub1, Caps: []Cap{{"c", 1}, {"d", 3}}}
|
||||
|
||||
wg sync.WaitGroup
|
||||
|
Loading…
Reference in New Issue
Block a user