Commit ed07dc0f authored by lash's avatar lash Committed by GitHub

Ethereum address creation faulty (#345)

* Fix faulty hashing of ethereum address
parent 050f8f21
...@@ -59,7 +59,10 @@ func ParseAddress(underlay, overlay, signature []byte, networkID uint64) (*Addre ...@@ -59,7 +59,10 @@ func ParseAddress(underlay, overlay, signature []byte, networkID uint64) (*Addre
return nil, ErrInvalidAddress return nil, ErrInvalidAddress
} }
recoveredOverlay := crypto.NewOverlayAddress(*recoveredPK, networkID) recoveredOverlay, err := crypto.NewOverlayAddress(*recoveredPK, networkID)
if err != nil {
return nil, ErrInvalidAddress
}
if !bytes.Equal(recoveredOverlay.Bytes(), overlay) { if !bytes.Equal(recoveredOverlay.Bytes(), overlay) {
return nil, ErrInvalidAddress return nil, ErrInvalidAddress
} }
......
...@@ -24,7 +24,10 @@ func TestBzzAddress(t *testing.T) { ...@@ -24,7 +24,10 @@ func TestBzzAddress(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
overlay := crypto.NewOverlayAddress(privateKey1.PublicKey, 3) overlay, err := crypto.NewOverlayAddress(privateKey1.PublicKey, 3)
if err != nil {
t.Fatal(err)
}
signer1 := crypto.NewDefaultSigner(privateKey1) signer1 := crypto.NewDefaultSigner(privateKey1)
bzzAddress, err := bzz.NewAddress(signer1, node1ma, overlay, 3) bzzAddress, err := bzz.NewAddress(signer1, node1ma, overlay, 3)
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"crypto/elliptic" "crypto/elliptic"
"crypto/rand" "crypto/rand"
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
...@@ -17,12 +18,15 @@ import ( ...@@ -17,12 +18,15 @@ import (
) )
// NewOverlayAddress constructs a Swarm Address from ECDSA private key. // NewOverlayAddress constructs a Swarm Address from ECDSA private key.
func NewOverlayAddress(p ecdsa.PublicKey, networkID uint64) swarm.Address { func NewOverlayAddress(p ecdsa.PublicKey, networkID uint64) (swarm.Address, error) {
ethAddr := NewEthereumAddress(p) ethAddr, err := NewEthereumAddress(p)
if err != nil {
return swarm.ZeroAddress, err
}
netIDBytes := make([]byte, 8) netIDBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(netIDBytes, networkID) binary.LittleEndian.PutUint64(netIDBytes, networkID)
h := sha3.Sum256(append(ethAddr, netIDBytes...)) h := sha3.Sum256(append(ethAddr, netIDBytes...))
return swarm.NewAddress(h[:]) return swarm.NewAddress(h[:]), nil
} }
// GenerateSecp256k1Key generates an ECDSA private key using // GenerateSecp256k1Key generates an ECDSA private key using
...@@ -47,14 +51,24 @@ func DecodeSecp256k1PrivateKey(data []byte) (*ecdsa.PrivateKey, error) { ...@@ -47,14 +51,24 @@ func DecodeSecp256k1PrivateKey(data []byte) (*ecdsa.PrivateKey, error) {
// NewEthereumAddress returns a binary representation of ethereum blockchain address. // NewEthereumAddress returns a binary representation of ethereum blockchain address.
// This function is based on github.com/ethereum/go-ethereum/crypto.PubkeyToAddress. // This function is based on github.com/ethereum/go-ethereum/crypto.PubkeyToAddress.
func NewEthereumAddress(p ecdsa.PublicKey) []byte { func NewEthereumAddress(p ecdsa.PublicKey) ([]byte, error) {
if p.X == nil || p.Y == nil { if p.X == nil || p.Y == nil {
return nil return nil, errors.New("invalid public key")
} }
pubBytes := elliptic.Marshal(btcec.S256(), p.X, p.Y) pubBytes := elliptic.Marshal(btcec.S256(), p.X, p.Y)
return legacyKeccak256(pubBytes[1:])[12:] pubHash, err := legacyKeccak256(pubBytes[1:])
if err != nil {
return nil, err
}
return pubHash[12:], err
} }
func legacyKeccak256(data []byte) []byte { func legacyKeccak256(data []byte) ([]byte, error) {
return sha3.NewLegacyKeccak256().Sum(data) var err error
hasher := sha3.NewLegacyKeccak256()
_, err = hasher.Write(data)
if err != nil {
return nil, err
}
return hasher.Sum(nil), err
} }
...@@ -6,6 +6,7 @@ package crypto_test ...@@ -6,6 +6,7 @@ package crypto_test
import ( import (
"bytes" "bytes"
"encoding/hex"
"testing" "testing"
"github.com/ethersphere/bee/pkg/crypto" "github.com/ethersphere/bee/pkg/crypto"
...@@ -37,7 +38,10 @@ func TestNewAddress(t *testing.T) { ...@@ -37,7 +38,10 @@ func TestNewAddress(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
a := crypto.NewOverlayAddress(k.PublicKey, 1) a, err := crypto.NewOverlayAddress(k.PublicKey, 1)
if err != nil {
t.Fatal(err)
}
if l := len(a.Bytes()); l != 32 { if l := len(a.Bytes()); l != 32 {
t.Errorf("got address length %v, want %v", l, 32) t.Errorf("got address length %v, want %v", l, 32)
} }
...@@ -57,3 +61,27 @@ func TestEncodeSecp256k1PrivateKey(t *testing.T) { ...@@ -57,3 +61,27 @@ func TestEncodeSecp256k1PrivateKey(t *testing.T) {
t.Fatal("encoded and decoded keys are not equal") t.Fatal("encoded and decoded keys are not equal")
} }
} }
func TestNewEthereumAddress(t *testing.T) {
privKeyHex := "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
privKeyBytes, err := hex.DecodeString(privKeyHex)
if err != nil {
t.Fatal(err)
}
privKey, err := crypto.DecodeSecp256k1PrivateKey(privKeyBytes)
if err != nil {
t.Fatal(err)
}
expectAddressHex := "2f63cbeb054ce76050827e42dd75268f6b9d87c5"
expectAddress, err := hex.DecodeString(expectAddressHex)
if err != nil {
t.Fatal(err)
}
address, err := crypto.NewEthereumAddress(privKey.PublicKey)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(address, expectAddress) {
t.Fatalf("address mismatch %x %x", address, expectAddress)
}
}
...@@ -32,7 +32,10 @@ func TestConnect(t *testing.T) { ...@@ -32,7 +32,10 @@ func TestConnect(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
overlay := crypto.NewOverlayAddress(privateKey.PublicKey, 0) overlay, err := crypto.NewOverlayAddress(privateKey.PublicKey, 0)
if err != nil {
t.Fatal(err)
}
underlama, err := ma.NewMultiaddr(underlay) underlama, err := ma.NewMultiaddr(underlay)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
......
...@@ -57,7 +57,10 @@ func TestBroadcastPeers(t *testing.T) { ...@@ -57,7 +57,10 @@ func TestBroadcastPeers(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
signer := crypto.NewDefaultSigner(pk) signer := crypto.NewDefaultSigner(pk)
overlay := crypto.NewOverlayAddress(pk.PublicKey, networkID) overlay, err := crypto.NewOverlayAddress(pk.PublicKey, networkID)
if err != nil {
t.Fatal(err)
}
bzzAddr, err := bzz.NewAddress(signer, underlay, overlay, networkID) bzzAddr, err := bzz.NewAddress(signer, underlay, overlay, networkID)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
......
...@@ -67,8 +67,12 @@ func encryptKey(k *ecdsa.PrivateKey, password string) ([]byte, error) { ...@@ -67,8 +67,12 @@ func encryptKey(k *ecdsa.PrivateKey, password string) ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
addr, err := crypto.NewEthereumAddress(k.PublicKey)
if err != nil {
return nil, err
}
return json.Marshal(encryptedKey{ return json.Marshal(encryptedKey{
Address: hex.EncodeToString(crypto.NewEthereumAddress(k.PublicKey)), Address: hex.EncodeToString(addr),
Crypto: *kc, Crypto: *kc,
Version: keyVersion, Version: keyVersion,
}) })
......
...@@ -116,7 +116,10 @@ func NewBee(o Options) (*Bee, error) { ...@@ -116,7 +116,10 @@ func NewBee(o Options) (*Bee, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("swarm key: %w", err) return nil, fmt.Errorf("swarm key: %w", err)
} }
address := crypto.NewOverlayAddress(swarmPrivateKey.PublicKey, o.NetworkID) address, err := crypto.NewOverlayAddress(swarmPrivateKey.PublicKey, o.NetworkID)
if err != nil {
return nil, err
}
if created { if created {
logger.Infof("new swarm network address created: %s", address) logger.Infof("new swarm network address created: %s", address)
} else { } else {
......
...@@ -59,11 +59,19 @@ func TestHandshake(t *testing.T) { ...@@ -59,11 +59,19 @@ func TestHandshake(t *testing.T) {
signer1 := crypto.NewDefaultSigner(privateKey1) signer1 := crypto.NewDefaultSigner(privateKey1)
signer2 := crypto.NewDefaultSigner(privateKey2) signer2 := crypto.NewDefaultSigner(privateKey2)
node1BzzAddress, err := bzz.NewAddress(signer1, node1ma, crypto.NewOverlayAddress(privateKey1.PublicKey, networkID), networkID) addr, err := crypto.NewOverlayAddress(privateKey1.PublicKey, networkID)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
node2BzzAddress, err := bzz.NewAddress(signer2, node2ma, crypto.NewOverlayAddress(privateKey2.PublicKey, networkID), networkID) node1BzzAddress, err := bzz.NewAddress(signer1, node1ma, addr, networkID)
if err != nil {
t.Fatal(err)
}
addr2, err := crypto.NewOverlayAddress(privateKey2.PublicKey, networkID)
if err != nil {
t.Fatal(err)
}
node2BzzAddress, err := bzz.NewAddress(signer2, node2ma, addr2, networkID)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -580,7 +588,7 @@ func TestHandshake(t *testing.T) { ...@@ -580,7 +588,7 @@ func TestHandshake(t *testing.T) {
_, err = handshakeService.Handle(stream1, node2AddrInfo.Addrs[0], node2AddrInfo.ID) _, err = handshakeService.Handle(stream1, node2AddrInfo.Addrs[0], node2AddrInfo.ID)
if err != handshake.ErrInvalidAck { if err != handshake.ErrInvalidAck {
t.Fatalf("expected %s, got %s", handshake.ErrInvalidAck, err) t.Fatalf("expected %s, got %v", handshake.ErrInvalidAck, err)
} }
}) })
......
...@@ -31,7 +31,10 @@ func newService(t *testing.T, networkID uint64, o libp2p.Options) (s *libp2p.Ser ...@@ -31,7 +31,10 @@ func newService(t *testing.T, networkID uint64, o libp2p.Options) (s *libp2p.Ser
t.Fatal(err) t.Fatal(err)
} }
overlay = crypto.NewOverlayAddress(swarmKey.PublicKey, networkID) overlay, err = crypto.NewOverlayAddress(swarmKey.PublicKey, networkID)
if err != nil {
t.Fatal(err)
}
addr := ":0" addr := ":0"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment