From: yahtoo Date: Tue, 4 Jun 2019 02:16:30 +0000 (+0800) Subject: Modify the p2p module encryption library (#125) X-Git-Tag: v1.0.5~208^2~72 X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=commitdiff_plain;h=50455dfe305a57ea9120d5563ebb34d5b8ed96ce Modify the p2p module encryption library (#125) --- diff --git a/netsync/consensusmgr/handle.go b/netsync/consensusmgr/handle.go index 2d380f30..5443e769 100644 --- a/netsync/consensusmgr/handle.go +++ b/netsync/consensusmgr/handle.go @@ -16,7 +16,6 @@ import ( type Switch interface { AddReactor(name string, reactor p2p.Reactor) p2p.Reactor AddBannedPeer(string) error - ID() [32]byte } // Chain is the interface for Bytom core. diff --git a/p2p/connection/secret_connection.go b/p2p/connection/secret_connection.go index 69d175ea..28cce510 100644 --- a/p2p/connection/secret_connection.go +++ b/p2p/connection/secret_connection.go @@ -11,13 +11,13 @@ import ( "time" log "github.com/sirupsen/logrus" + "github.com/tendermint/go-wire" + cmn "github.com/tendermint/tmlibs/common" "golang.org/x/crypto/nacl/box" "golang.org/x/crypto/nacl/secretbox" "golang.org/x/crypto/ripemd160" - "github.com/tendermint/go-crypto" - wire "github.com/tendermint/go-wire" - cmn "github.com/tendermint/tmlibs/common" + "github.com/vapor/p2p/signlib" ) const ( @@ -25,12 +25,11 @@ const ( dataMaxSize = 1024 totalFrameSize = dataMaxSize + dataLenSize sealedFrameSize = totalFrameSize + secretbox.Overhead - authSigMsgSize = (32 + 1) + (64 + 1) // fixed size (length prefixed) byte arrays ) type authSigMessage struct { - Key crypto.PubKey - Sig crypto.Signature + Key []byte + Sig []byte } // SecretConnection implements net.Conn @@ -39,14 +38,12 @@ type SecretConnection struct { recvBuffer []byte recvNonce *[24]byte sendNonce *[24]byte - remPubKey crypto.PubKeyEd25519 + remPubKey signlib.PubKey shrSecret *[32]byte // shared secret } // MakeSecretConnection performs handshake and returns a new authenticated SecretConnection. -func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKeyEd25519) (*SecretConnection, error) { - locPubKey := locPrivKey.PubKey().Unwrap().(crypto.PubKeyEd25519) - +func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey signlib.PrivKey) (*SecretConnection, error) { // Generate ephemeral keys for perfect forward secrecy. locEphPub, locEphPriv := genEphKeys() @@ -81,18 +78,22 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKeyEd25 // Sign the challenge bytes for authentication. locSignature := signChallenge(challenge, locPrivKey) - // Share (in secret) each other's pubkey & challenge signature - authSigMsg, err := shareAuthSignature(sc, locPubKey, locSignature) + authSigMsg, err := shareAuthSignature(sc, locPrivKey.XPub().Bytes(), locSignature) + if err != nil { + return nil, err + } + pubKey, remSignature := authSigMsg.Key, authSigMsg.Sig + remPubKey, err := signlib.NewPubKey(pubKey) if err != nil { return nil, err } - remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig - if !remPubKey.VerifyBytes(challenge[:], remSignature) { + + if !remPubKey.Verify(challenge[:], remSignature[:]) { return nil, errors.New("Challenge verification failed") } - sc.remPubKey = remPubKey.Unwrap().(crypto.PubKeyEd25519) + sc.remPubKey = remPubKey return sc, nil } @@ -128,7 +129,7 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) { } // RemotePubKey returns authenticated remote pubkey -func (sc *SecretConnection) RemotePubKey() crypto.PubKeyEd25519 { +func (sc *SecretConnection) RemotePubKey() signlib.PubKey { return sc.remPubKey } @@ -230,31 +231,29 @@ func genNonces(loPubKey, hiPubKey *[32]byte, locIsLo bool) (*[24]byte, *[24]byte return nonce2, nonce1 } -func signChallenge(challenge *[32]byte, locPrivKey crypto.PrivKeyEd25519) (signature crypto.SignatureEd25519) { - signature = locPrivKey.Sign(challenge[:]).Unwrap().(crypto.SignatureEd25519) - return +func signChallenge(challenge *[32]byte, locPrivKey signlib.PrivKey) []byte { + return locPrivKey.Sign(challenge[:]) } -func shareAuthSignature(sc *SecretConnection, pubKey crypto.PubKeyEd25519, signature crypto.SignatureEd25519) (*authSigMessage, error) { +func shareAuthSignature(sc *SecretConnection, pubKey []byte, signature []byte) (*authSigMessage, error) { var recvMsg authSigMessage var err1, err2 error cmn.Parallel( func() { - msgBytes := wire.BinaryBytes(authSigMessage{pubKey.Wrap(), signature.Wrap()}) + msgBytes := wire.BinaryBytes(authSigMessage{pubKey, signature}) _, err1 = sc.Write(msgBytes) }, func() { - readBuffer := make([]byte, authSigMsgSize) + readBuffer := make([]byte, signlib.AuthSigMsgSize) _, err2 = io.ReadFull(sc, readBuffer) if err2 != nil { return } n := int(0) // not used. - recvMsg = wire.ReadBinary(authSigMessage{}, bytes.NewBuffer(readBuffer), authSigMsgSize, &n, &err2).(authSigMessage) + recvMsg = wire.ReadBinary(authSigMessage{}, bytes.NewBuffer(readBuffer), signlib.AuthSigMsgSize, &n, &err2).(authSigMessage) }, ) - if err1 != nil { return nil, err1 } diff --git a/p2p/connection/secret_connection_test.go b/p2p/connection/secret_connection_test.go index 4785bbc6..b4542cfe 100644 --- a/p2p/connection/secret_connection_test.go +++ b/p2p/connection/secret_connection_test.go @@ -5,8 +5,9 @@ import ( "io" "testing" - "github.com/tendermint/go-crypto" cmn "github.com/tendermint/tmlibs/common" + + "github.com/vapor/crypto/ed25519/chainkd" ) type dummyConn struct { @@ -32,10 +33,10 @@ func makeDummyConnPair() (fooConn, barConn dummyConn) { func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection) { fooConn, barConn := makeDummyConnPair() - fooPrvKey := crypto.GenPrivKeyEd25519() - fooPubKey := fooPrvKey.PubKey().Unwrap().(crypto.PubKeyEd25519) - barPrvKey := crypto.GenPrivKeyEd25519() - barPubKey := barPrvKey.PubKey().Unwrap().(crypto.PubKeyEd25519) + fooPrvKey, _ := chainkd.NewXPrv(nil) + fooPubKey := fooPrvKey.XPub() + barPrvKey, _ := chainkd.NewXPrv(nil) + barPubKey := barPrvKey.XPub() cmn.Parallel( func() { @@ -46,7 +47,7 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection return } remotePubBytes := fooSecConn.RemotePubKey() - if !bytes.Equal(remotePubBytes[:], barPubKey[:]) { + if !bytes.Equal(remotePubBytes.Bytes()[:], barPubKey[:]) { tb.Errorf("Unexpected fooSecConn.RemotePubKey. Expected %v, got %v", barPubKey, fooSecConn.RemotePubKey()) } @@ -59,7 +60,7 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection return } remotePubBytes := barSecConn.RemotePubKey() - if !bytes.Equal(remotePubBytes[:], fooPubKey[:]) { + if !bytes.Equal(remotePubBytes.Bytes()[:], fooPubKey[:]) { tb.Errorf("Unexpected barSecConn.RemotePubKey. Expected %v, got %v", fooPubKey, barSecConn.RemotePubKey()) } @@ -89,7 +90,7 @@ func TestSecretConnectionReadWrite(t *testing.T) { genNodeRunner := func(nodeConn dummyConn, nodeWrites []string, nodeReads *[]string) func() { return func() { // Node handskae - nodePrvKey := crypto.GenPrivKeyEd25519() + nodePrvKey, _ := chainkd.NewXPrv(nil) nodeSecretConn, err := MakeSecretConnection(nodeConn, nodePrvKey) if err != nil { t.Errorf("Failed to establish SecretConnection for node: %v", err) diff --git a/p2p/discover/dht/net.go b/p2p/discover/dht/net.go index 5be1731c..c3f6a0ef 100644 --- a/p2p/discover/dht/net.go +++ b/p2p/discover/dht/net.go @@ -13,9 +13,9 @@ import ( "golang.org/x/crypto/sha3" "github.com/vapor/common" - "github.com/vapor/crypto/ed25519" "github.com/vapor/crypto/sha3pool" "github.com/vapor/p2p/netutil" + "github.com/vapor/p2p/signlib" ) var ( @@ -123,9 +123,9 @@ func hash(target []byte) common.Hash { return common.BytesToHash(h[:]) } -func newNetwork(conn transport, ourPubkey ed25519.PublicKey, dbPath string, netrestrict *netutil.Netlist) (*Network, error) { +func newNetwork(conn transport, ourPubkey signlib.PubKey, dbPath string, netrestrict *netutil.Netlist) (*Network, error) { var ourID NodeID - copy(ourID[:], ourPubkey[:nodeIDBits]) + copy(ourID[:], ourPubkey.Bytes()[:nodeIDBits]) var db *nodeDB if dbPath != "" { diff --git a/p2p/discover/dht/net_test.go b/p2p/discover/dht/net_test.go index eacdaa81..f83896d6 100644 --- a/p2p/discover/dht/net_test.go +++ b/p2p/discover/dht/net_test.go @@ -9,7 +9,7 @@ import ( "time" "github.com/vapor/common" - "github.com/vapor/crypto/ed25519" + "github.com/vapor/p2p/signlib" ) func TestNetwork_Lookup(t *testing.T) { @@ -19,8 +19,12 @@ func TestNetwork_Lookup(t *testing.T) { } defer os.RemoveAll(tmpDir) - pubKey, _, err := ed25519.GenerateKey(nil) - network, err := newNetwork(lookupTestnet, pubKey, tmpDir, nil) + privKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + + network, err := newNetwork(lookupTestnet, privKey.XPub(), tmpDir, nil) if err != nil { t.Fatal(err) } @@ -328,7 +332,8 @@ func mine(target NodeID) { var dists [hashBits + 1][]NodeID found := 0 for found < bucketSize*10 { - pubKey, _, _ := ed25519.GenerateKey(nil) + privKey, _ := signlib.NewPrivKey() + pubKey := privKey.XPub() sha := hash(pubKey[:]) ld := logdist(targetSha, sha) if len(dists[ld]) < bucketSize { diff --git a/p2p/discover/dht/udp.go b/p2p/discover/dht/udp.go index a3c11cec..c8d73b70 100644 --- a/p2p/discover/dht/udp.go +++ b/p2p/discover/dht/udp.go @@ -17,8 +17,8 @@ import ( "github.com/vapor/common" cfg "github.com/vapor/config" "github.com/vapor/crypto" - "github.com/vapor/crypto/ed25519" "github.com/vapor/p2p/netutil" + "github.com/vapor/p2p/signlib" "github.com/vapor/version" ) @@ -246,7 +246,7 @@ type netWork interface { // udp implements the RPC protocol. type udp struct { conn conn - priv ed25519.PrivateKey + priv signlib.PrivKey //netID used to isolate subnets netID uint64 ourEndpoint rpcEndpoint @@ -254,7 +254,7 @@ type udp struct { } //NewDiscover create new dht discover -func NewDiscover(config *cfg.Config, priv ed25519.PrivateKey, port uint16, netID uint64) (*Network, error) { +func NewDiscover(config *cfg.Config, privKey signlib.PrivKey, port uint16, netID uint64) (*Network, error) { addr, err := net.ResolveUDPAddr("udp", net.JoinHostPort("0.0.0.0", strconv.FormatUint(uint64(port), 10))) if err != nil { return nil, err @@ -266,7 +266,7 @@ func NewDiscover(config *cfg.Config, priv ed25519.PrivateKey, port uint16, netID } realaddr := conn.LocalAddr().(*net.UDPAddr) - ntab, err := ListenUDP(priv, conn, realaddr, path.Join(config.DBDir(), "discover"), nil, netID) + ntab, err := ListenUDP(privKey, conn, realaddr, path.Join(config.DBDir(), "discover"), nil, netID) if err != nil { return nil, err } @@ -295,13 +295,13 @@ func NewDiscover(config *cfg.Config, priv ed25519.PrivateKey, port uint16, netID } // ListenUDP returns a new table that listens for UDP packets on laddr. -func ListenUDP(priv ed25519.PrivateKey, conn conn, realaddr *net.UDPAddr, nodeDBPath string, netrestrict *netutil.Netlist, netID uint64) (*Network, error) { - transport, err := listenUDP(priv, conn, realaddr, netID) +func ListenUDP(privKey signlib.PrivKey, conn conn, realaddr *net.UDPAddr, nodeDBPath string, netrestrict *netutil.Netlist, netID uint64) (*Network, error) { + transport, err := listenUDP(privKey, conn, realaddr, netID) if err != nil { return nil, err } - net, err := newNetwork(transport, priv.Public(), nodeDBPath, netrestrict) + net, err := newNetwork(transport, privKey.XPub(), nodeDBPath, netrestrict) if err != nil { return nil, err } @@ -311,7 +311,7 @@ func ListenUDP(priv ed25519.PrivateKey, conn conn, realaddr *net.UDPAddr, nodeDB return net, nil } -func listenUDP(priv ed25519.PrivateKey, conn conn, realaddr *net.UDPAddr, netID uint64) (*udp, error) { +func listenUDP(priv signlib.PrivKey, conn conn, realaddr *net.UDPAddr, netID uint64) (*udp, error) { return &udp{conn: conn, priv: priv, netID: netID, ourEndpoint: makeEndpoint(realaddr, uint16(realaddr.Port))}, nil } @@ -407,7 +407,7 @@ func (t *udp) sendPacket(toid NodeID, toaddr *net.UDPAddr, ptype byte, req inter // zeroed padding space for encodePacket. var headSpace = make([]byte, headSize) -func encodePacket(priv ed25519.PrivateKey, ptype byte, req interface{}, netID uint64) (p, hash []byte, err error) { +func encodePacket(privKey signlib.PrivKey, ptype byte, req interface{}, netID uint64) (p, hash []byte, err error) { b := new(bytes.Buffer) b.Write(headSpace) b.WriteByte(ptype) @@ -418,11 +418,11 @@ func encodePacket(priv ed25519.PrivateKey, ptype byte, req interface{}, netID ui return nil, nil, err } packet := b.Bytes() - nodeID := priv.Public() - sig := ed25519.Sign(priv, common.BytesToHash(packet[headSize:]).Bytes()) + nodeID := privKey.XPub() + sig := privKey.Sign(common.BytesToHash(packet[headSize:]).Bytes()) id := []byte(strconv.FormatUint(netID, 16)) copy(packet[:], id[:]) - copy(packet[netIDSize:], nodeID[:]) + copy(packet[netIDSize:], nodeID[:nodeIDSize]) copy(packet[netIDSize+nodeIDSize:], sig) hash = common.BytesToHash(packet[:]).Bytes() diff --git a/p2p/discover/dht/udp_test.go b/p2p/discover/dht/udp_test.go index 3353b209..d6f442f5 100644 --- a/p2p/discover/dht/udp_test.go +++ b/p2p/discover/dht/udp_test.go @@ -9,8 +9,8 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/vapor/common" - "github.com/vapor/crypto/ed25519" "github.com/vapor/errors" + "github.com/vapor/p2p/signlib" ) func TestPacketCodec(t *testing.T) { @@ -175,7 +175,7 @@ func TestPacketCodec(t *testing.T) { }, } - _, privateKey, _ := ed25519.GenerateKey(nil) + privateKey, _ := signlib.NewPrivKey() netID := uint64(0x12345) for i, test := range testPackets { packet, h, err := encodePacket(privateKey, test.ptype, test.wantPacket, netID) @@ -240,8 +240,8 @@ func TestPacketTransport(t *testing.T) { inConn := &testConn{conn: c1} realaddr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 40000} toAddr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 40000} - _, inPrivKey, _ := ed25519.GenerateKey(nil) - _, outPrivKey, _ := ed25519.GenerateKey(nil) + inPrivKey, _ := signlib.NewPrivKey() + outPrivKey, _ := signlib.NewPrivKey() netID := uint64(0x12345) udpInput, err := listenUDP(inPrivKey, inConn, realaddr, netID) @@ -368,8 +368,8 @@ func TestSendTopicNodes(t *testing.T) { c1, c2 := net.Pipe() inConn := &testConn{conn: c1} realaddr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 40000} - _, inPrivKey, _ := ed25519.GenerateKey(nil) - _, outPrivKey, _ := ed25519.GenerateKey(nil) + inPrivKey, _ := signlib.NewPrivKey() + outPrivKey, _ := signlib.NewPrivKey() netID := uint64(0x12345) udpInput, err := listenUDP(inPrivKey, inConn, realaddr, netID) diff --git a/p2p/node_info.go b/p2p/node_info.go index 5caed49d..00f818dd 100644 --- a/p2p/node_info.go +++ b/p2p/node_info.go @@ -4,11 +4,10 @@ import ( "fmt" "net" - "github.com/tendermint/go-crypto" - cfg "github.com/vapor/config" "github.com/vapor/consensus" "github.com/vapor/errors" + "github.com/vapor/p2p/signlib" "github.com/vapor/version" ) @@ -22,9 +21,9 @@ var ( //NodeInfo peer node info type NodeInfo struct { - PubKey crypto.PubKeyEd25519 `json:"pub_key"` - Moniker string `json:"moniker"` - Network string `json:"network"` + PubKey string `json:"pub_key"` + Moniker string `json:"moniker"` + Network string `json:"network"` //NetworkID used to isolate subnets with same network name NetworkID uint64 `json:"network_id"` RemoteAddr string `json:"remote_addr"` @@ -35,9 +34,9 @@ type NodeInfo struct { Other []string `json:"other"` } -func NewNodeInfo(config *cfg.Config, pubkey crypto.PubKeyEd25519, listenAddr string, netID uint64) *NodeInfo { +func NewNodeInfo(config *cfg.Config, pubkey signlib.PubKey, listenAddr string, netID uint64) *NodeInfo { return &NodeInfo{ - PubKey: pubkey, + PubKey: pubkey.String(), Moniker: config.Moniker, Network: config.ChainID, NetworkID: netID, diff --git a/p2p/node_info_test.go b/p2p/node_info_test.go index f31aa9fb..6e1c4b79 100644 --- a/p2p/node_info_test.go +++ b/p2p/node_info_test.go @@ -6,10 +6,10 @@ import ( "testing" "github.com/davecgh/go-spew/spew" - "github.com/tendermint/go-crypto" "github.com/tendermint/go-wire" "github.com/vapor/errors" + "github.com/vapor/p2p/signlib" ) func mockCompatibleWithFalse(remoteVerStr string) (bool, error) { @@ -42,18 +42,23 @@ func TestCompatibleWith(t *testing.T) { } func TestNodeInfoWriteRead(t *testing.T) { - nodeInfo := &NodeInfo{PubKey: crypto.GenPrivKeyEd25519().PubKey().Unwrap().(crypto.PubKeyEd25519), Moniker: "bytomd", Network: "mainnet", NetworkID: 0x888, RemoteAddr: "127.0.0.2:0", ListenAddr: "127.0.0.1:0", Version: "1.1.0-test", ServiceFlag: 10, Other: []string{"abc", "bcd"}} - n, err, err1 := new(int), new(error), new(error) + key := [64]byte{0x01, 0x02} + pubKey, err := signlib.NewPubKey(key[:]) + if err != nil { + t.Fatal("create pubkey err.", err) + } + nodeInfo := &NodeInfo{PubKey: pubKey.String(), Moniker: "bytomd", Network: "mainnet", NetworkID: 0x888, RemoteAddr: "127.0.0.2:0", ListenAddr: "127.0.0.1:0", Version: "1.1.0-test", ServiceFlag: 10, Other: []string{"abc", "bcd"}} + n, err1, err2 := new(int), new(error), new(error) buf := new(bytes.Buffer) - wire.WriteBinary(nodeInfo, buf, n, err) - if *err != nil { - t.Fatal(*err) + wire.WriteBinary(nodeInfo, buf, n, err1) + if *err1 != nil { + t.Fatal(*err1) } peerNodeInfo := new(NodeInfo) - wire.ReadBinary(peerNodeInfo, buf, maxNodeInfoSize, new(int), err1) - if *err1 != nil { + wire.ReadBinary(peerNodeInfo, buf, maxNodeInfoSize, new(int), err2) + if *err2 != nil { t.Fatal(*err1) } diff --git a/p2p/peer.go b/p2p/peer.go index 11641b8c..e239e372 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -9,7 +9,6 @@ import ( "github.com/btcsuite/go-socks/socks" "github.com/pkg/errors" log "github.com/sirupsen/logrus" - "github.com/tendermint/go-crypto" "github.com/tendermint/go-wire" cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/flowrate" @@ -17,6 +16,7 @@ import ( cfg "github.com/vapor/config" "github.com/vapor/consensus" "github.com/vapor/p2p/connection" + "github.com/vapor/p2p/signlib" ) // peerConn contains the raw connection and its config. @@ -76,7 +76,7 @@ func newPeer(pc *peerConn, nodeInfo *NodeInfo, reactorsByCh map[byte]Reactor, ch p := &Peer{ peerConn: pc, NodeInfo: nodeInfo, - Key: nodeInfo.PubKey.KeyString(), + Key: nodeInfo.PubKey, isLAN: isLAN, } p.mconn = createMConnection(pc.conn, p, reactorsByCh, chDescs, onPeerError, pc.config.MConfig) @@ -84,7 +84,7 @@ func newPeer(pc *peerConn, nodeInfo *NodeInfo, reactorsByCh map[byte]Reactor, ch return p } -func newOutboundPeerConn(addr *NetAddress, ourNodePrivKey crypto.PrivKeyEd25519, config *PeerConfig) (*peerConn, error) { +func newOutboundPeerConn(addr *NetAddress, ourNodePrivKey signlib.PrivKey, config *PeerConfig) (*peerConn, error) { conn, err := dial(addr, config) if err != nil { return nil, errors.Wrap(err, "Error dial peer") @@ -98,11 +98,11 @@ func newOutboundPeerConn(addr *NetAddress, ourNodePrivKey crypto.PrivKeyEd25519, return pc, nil } -func newInboundPeerConn(conn net.Conn, ourNodePrivKey crypto.PrivKeyEd25519, config *cfg.P2PConfig) (*peerConn, error) { +func newInboundPeerConn(conn net.Conn, ourNodePrivKey signlib.PrivKey, config *cfg.P2PConfig) (*peerConn, error) { return newPeerConn(conn, false, ourNodePrivKey, DefaultPeerConfig(config)) } -func newPeerConn(rawConn net.Conn, outbound bool, ourNodePrivKey crypto.PrivKeyEd25519, config *PeerConfig) (*peerConn, error) { +func newPeerConn(rawConn net.Conn, outbound bool, ourNodePrivKey signlib.PrivKey, config *PeerConfig) (*peerConn, error) { rawConn.SetDeadline(time.Now().Add(config.HandshakeTimeout)) conn, err := connection.MakeSecretConnection(rawConn, ourNodePrivKey) if err != nil { @@ -195,8 +195,8 @@ func (p *Peer) IsLAN() bool { } // PubKey returns peer's public key. -func (p *Peer) PubKey() crypto.PubKeyEd25519 { - return p.conn.(*connection.SecretConnection).RemotePubKey() +func (p *Peer) PubKey() string { + return p.conn.(*connection.SecretConnection).RemotePubKey().String() } // Send msg to the channel identified by chID byte. Returns false if the send diff --git a/p2p/peer_test.go b/p2p/peer_test.go index 1fd8937f..8559f119 100644 --- a/p2p/peer_test.go +++ b/p2p/peer_test.go @@ -6,18 +6,22 @@ import ( "testing" "time" - "github.com/tendermint/go-crypto" - cfg "github.com/vapor/config" conn "github.com/vapor/p2p/connection" + "github.com/vapor/p2p/signlib" "github.com/vapor/version" ) const testCh = 0x01 func TestPeerBasic(t *testing.T) { + privKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + // simulate remote peer - rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: testCfg} + rp := &remotePeer{PrivKey: privKey, Config: testCfg} rp.Start() defer rp.Stop() @@ -34,9 +38,12 @@ func TestPeerBasic(t *testing.T) { func TestPeerSend(t *testing.T) { config := testCfg - + privKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } // simulate remote peer - rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: config} + rp := &remotePeer{PrivKey: privKey, Config: config} rp.Start() defer rp.Stop() @@ -68,9 +75,12 @@ func createOutboundPeerAndPerformHandshake( {ID: testCh, Priority: 1}, } reactorsByCh := map[byte]Reactor{testCh: NewTestReactor(chDescs, true)} - privkey := crypto.GenPrivKeyEd25519() + privKey, err := signlib.NewPrivKey() + if err != nil { + return nil, err + } peerConfig := DefaultPeerConfig(config) - pc, err := newOutboundPeerConn(addr, privkey, peerConfig) + pc, err := newOutboundPeerConn(addr, privKey, peerConfig) if err != nil { return nil, err } @@ -88,7 +98,7 @@ func createOutboundPeerAndPerformHandshake( } type remotePeer struct { - PrivKey crypto.PrivKeyEd25519 + PrivKey signlib.PrivKey Config *cfg.Config addr *NetAddress quit chan struct{} @@ -132,7 +142,7 @@ func (rp *remotePeer) accept(l net.Listener) { } _, err = pc.HandshakeTimeout(&NodeInfo{ - PubKey: rp.PrivKey.PubKey().Unwrap().(crypto.PubKeyEd25519), + PubKey: rp.PrivKey.XPub().String(), Moniker: "remote_peer", Network: rp.Config.ChainID, Version: version.Version, @@ -156,7 +166,7 @@ func (rp *remotePeer) accept(l net.Listener) { } type inboundPeer struct { - PrivKey crypto.PrivKeyEd25519 + PrivKey signlib.PrivKey config *cfg.Config } @@ -168,7 +178,7 @@ func (ip *inboundPeer) dial(addr *NetAddress) { } _, err = pc.HandshakeTimeout(&NodeInfo{ - PubKey: ip.PrivKey.PubKey().Unwrap().(crypto.PubKeyEd25519), + PubKey: ip.PrivKey.XPub().String(), Moniker: "remote_peer", Network: ip.config.ChainID, Version: version.Version, diff --git a/p2p/signlib/chainkd.go b/p2p/signlib/chainkd.go new file mode 100644 index 00000000..b15db257 --- /dev/null +++ b/p2p/signlib/chainkd.go @@ -0,0 +1,43 @@ +package signlib + +import ( + "errors" + + "github.com/vapor/crypto/ed25519/chainkd" +) + +const ( + PubkeySize = 64 + AuthSigMsgSize = 132 +) + +var ( + ErrPubkeyLength = errors.New("pubkey length error") +) + +type PubKey interface { + String() string + Bytes() []byte + Verify(msg []byte, sig []byte) bool + MarshalText() ([]byte, error) +} + +type PrivKey interface { + Bytes() []byte + Sign(msg []byte) []byte + XPub() chainkd.XPub +} + +func NewPrivKey() (PrivKey, error) { + return chainkd.NewXPrv(nil) +} + +func NewPubKey(pubkey []byte) (PubKey, error) { + if len(pubkey) != PubkeySize { + return nil, ErrPubkeyLength + } + + var pubKey chainkd.XPub + copy(pubKey[:], pubkey[:]) + return pubKey, nil +} diff --git a/p2p/switch.go b/p2p/switch.go index cfae5120..62d47f1c 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -2,7 +2,6 @@ package p2p import ( "encoding/binary" - "encoding/hex" "encoding/json" "fmt" "net" @@ -10,12 +9,10 @@ import ( "time" log "github.com/sirupsen/logrus" - crypto "github.com/tendermint/go-crypto" cmn "github.com/tendermint/tmlibs/common" cfg "github.com/vapor/config" "github.com/vapor/consensus" - "github.com/vapor/crypto/ed25519" "github.com/vapor/crypto/sha3pool" dbm "github.com/vapor/database/leveldb" "github.com/vapor/errors" @@ -24,6 +21,7 @@ import ( "github.com/vapor/p2p/discover/dht" "github.com/vapor/p2p/discover/mdns" "github.com/vapor/p2p/netutil" + "github.com/vapor/p2p/signlib" "github.com/vapor/p2p/trust" "github.com/vapor/version" ) @@ -71,8 +69,8 @@ type Switch struct { reactorsByCh map[byte]Reactor peers *PeerSet dialing *cmn.CMap - nodeInfo *NodeInfo // our node info - nodePrivKey crypto.PrivKeyEd25519 // our node privkey + nodeInfo *NodeInfo // our node info + nodePrivKey signlib.PrivKey // our node privkey discv discv lanDiscv lanDiscv bannedPeer map[string]time.Time @@ -99,21 +97,11 @@ func NewSwitch(config *cfg.Config) (*Switch, error) { netID := binary.BigEndian.Uint64(h[:8]) blacklistDB := dbm.NewDB("trusthistory", config.DBBackend, config.DBDir()) - - _, yyy, _ := ed25519.GenerateKey(nil) - zzz := yyy.String() - - bytes, err := hex.DecodeString(zzz) - if err != nil { - return nil, err - } - var newKey [64]byte - copy(newKey[:], bytes) - privKey := crypto.PrivKeyEd25519(newKey) + privateKey := config.PrivateKey() if !config.VaultMode { // Create listener l, listenAddr = GetListener(config.P2P) - discv, err = dht.NewDiscover(config, ed25519.PrivateKey(bytes), l.ExternalAddress().Port, netID) + discv, err = dht.NewDiscover(config, *privateKey, l.ExternalAddress().Port, netID) if err != nil { return nil, err } @@ -122,11 +110,11 @@ func NewSwitch(config *cfg.Config) (*Switch, error) { } } - return newSwitch(config, discv, lanDiscv, blacklistDB, l, privKey, listenAddr, netID) + return newSwitch(config, discv, lanDiscv, blacklistDB, l, *privateKey, listenAddr, netID) } // newSwitch creates a new Switch with the given config. -func newSwitch(config *cfg.Config, discv discv, lanDiscv lanDiscv, blacklistDB dbm.DB, l Listener, priv crypto.PrivKeyEd25519, listenAddr string, netID uint64) (*Switch, error) { +func newSwitch(config *cfg.Config, discv discv, lanDiscv lanDiscv, blacklistDB dbm.DB, l Listener, privKey signlib.PrivKey, listenAddr string, netID uint64) (*Switch, error) { sw := &Switch{ Config: config, peerConfig: DefaultPeerConfig(config.P2P), @@ -135,11 +123,11 @@ func newSwitch(config *cfg.Config, discv discv, lanDiscv lanDiscv, blacklistDB d reactorsByCh: make(map[byte]Reactor), peers: NewPeerSet(), dialing: cmn.NewCMap(), - nodePrivKey: priv, + nodePrivKey: privKey, discv: discv, lanDiscv: lanDiscv, db: blacklistDB, - nodeInfo: NewNodeInfo(config, priv.PubKey().Unwrap().(crypto.PubKeyEd25519), listenAddr, netID), + nodeInfo: NewNodeInfo(config, privKey.XPub(), listenAddr, netID), bannedPeer: make(map[string]time.Time), } if err := sw.loadBannedPeers(); err != nil { @@ -291,10 +279,6 @@ func (sw *Switch) DialPeerWithAddress(addr *NetAddress) error { return nil } -func (sw *Switch) ID() [32]byte { - return sw.nodeInfo.PubKey -} - //IsDialing prevent duplicate dialing func (sw *Switch) IsDialing(addr *NetAddress) bool { return sw.dialing.Has(addr.IP.String()) @@ -464,7 +448,7 @@ func (sw *Switch) filterConnByPeer(peer *Peer) error { return err } - if sw.nodeInfo.PubKey.Equals(peer.PubKey().Wrap()) { + if sw.nodeInfo.PubKey == peer.PubKey() { return ErrConnectSelf } diff --git a/p2p/switch_test.go b/p2p/switch_test.go index d8498612..6b2cdb8f 100644 --- a/p2p/switch_test.go +++ b/p2p/switch_test.go @@ -8,12 +8,11 @@ import ( "time" "github.com/davecgh/go-spew/spew" - "github.com/tendermint/go-crypto" - cfg "github.com/vapor/config" dbm "github.com/vapor/database/leveldb" "github.com/vapor/errors" conn "github.com/vapor/p2p/connection" + "github.com/vapor/p2p/signlib" ) var ( @@ -136,8 +135,11 @@ func TestFiltersOutItself(t *testing.T) { testDB := dbm.NewDB("testdb", "leveldb", dirPath) cfg := *testCfg cfg.P2P.ListenAddress = "127.0.1.1:0" - swPrivKey := crypto.GenPrivKeyEd25519() - //cfg.P2P.PrivateKey = swPrivKey.String() + swPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) s1.Start() defer s1.Stop() @@ -170,14 +172,21 @@ func TestDialBannedPeer(t *testing.T) { testDB := dbm.NewDB("testdb", "leveldb", dirPath) cfg := *testCfg cfg.P2P.ListenAddress = "127.0.1.1:0" - swPrivKey := crypto.GenPrivKeyEd25519() - //cfg.P2P.PrivateKey = swPrivKey.String() + swPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) s1.Start() defer s1.Stop() rpCfg := *testCfg - rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: &rpCfg} + remotePrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + + rp := &remotePeer{PrivKey: remotePrivKey, Config: &rpCfg} rp.Start() defer rp.Stop() s1.AddBannedPeer(rp.addr.IP.String()) @@ -202,14 +211,22 @@ func TestDuplicateOutBoundPeer(t *testing.T) { testDB := dbm.NewDB("testdb", "leveldb", dirPath) cfg := *testCfg cfg.P2P.ListenAddress = "127.0.1.1:0" - swPrivKey := crypto.GenPrivKeyEd25519() - //cfg.P2P.PrivateKey = swPrivKey.String() + swPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) s1.Start() defer s1.Stop() rpCfg := *testCfg - rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: &rpCfg} + remotePrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + + rp := &remotePeer{PrivKey: remotePrivKey, Config: &rpCfg} rp.Start() defer rp.Stop() @@ -233,14 +250,21 @@ func TestDuplicateInBoundPeer(t *testing.T) { testDB := dbm.NewDB("testdb", "leveldb", dirPath) cfg := *testCfg cfg.P2P.ListenAddress = "127.0.1.1:0" - swPrivKey := crypto.GenPrivKeyEd25519() - //cfg.P2P.PrivateKey = swPrivKey.String() + swPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) s1.Start() defer s1.Stop() inpCfg := *testCfg - inp := &inboundPeer{PrivKey: crypto.GenPrivKeyEd25519(), config: &inpCfg} + inpPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + + inp := &inboundPeer{PrivKey: inpPrivKey, config: &inpCfg} addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr()) if err != nil { t.Fatal(err) @@ -269,15 +293,20 @@ func TestAddInboundPeer(t *testing.T) { cfg := *testCfg cfg.P2P.MaxNumPeers = 2 cfg.P2P.ListenAddress = "127.0.1.1:0" - swPrivKey := crypto.GenPrivKeyEd25519() - //cfg.P2P.PrivateKey = swPrivKey.String() + swPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) s1.Start() defer s1.Stop() inpCfg := *testCfg - inpPrivKey := crypto.GenPrivKeyEd25519() - //inpCfg.P2P.PrivateKey = inpPrivKey.String() + inpPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + inp := &inboundPeer{PrivKey: inpPrivKey, config: &inpCfg} addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr()) if err != nil { @@ -286,8 +315,10 @@ func TestAddInboundPeer(t *testing.T) { go inp.dial(addr) rpCfg := *testCfg - rpPrivKey := crypto.GenPrivKeyEd25519() - //rpCfg.P2P.PrivateKey = rpPrivKey.String() + rpPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } rp := &remotePeer{PrivKey: rpPrivKey, Config: &rpCfg} rp.Start() defer rp.Stop() @@ -297,8 +328,11 @@ func TestAddInboundPeer(t *testing.T) { } inp2Cfg := *testCfg - inp2PrivKey := crypto.GenPrivKeyEd25519() - //inp2Cfg.P2P.PrivateKey = inp2PrivKey.String() + + inp2PrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } inp2 := &inboundPeer{PrivKey: inp2PrivKey, config: &inp2Cfg} go inp2.dial(addr) @@ -321,16 +355,20 @@ func TestStopPeer(t *testing.T) { cfg := *testCfg cfg.P2P.MaxNumPeers = 2 cfg.P2P.ListenAddress = "127.0.1.1:0" - swPrivKey := crypto.GenPrivKeyEd25519() - //cfg.P2P.PrivateKey = swPrivKey.String() + swPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) s1.Start() defer s1.Stop() inpCfg := *testCfg - inpPrivKey := crypto.GenPrivKeyEd25519() - //inpCfg.P2P.PrivateKey = inpPrivKey.String() - inp := &inboundPeer{PrivKey: inpPrivKey, config: &inpCfg} + inp2PrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + inp := &inboundPeer{PrivKey: inp2PrivKey, config: &inpCfg} addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr()) if err != nil { t.Fatal(err) @@ -338,8 +376,11 @@ func TestStopPeer(t *testing.T) { go inp.dial(addr) rpCfg := *testCfg - rpPrivKey := crypto.GenPrivKeyEd25519() - //rpCfg.P2P.PrivateKey = rpPrivKey.String() + rpPrivKey, err := signlib.NewPrivKey() + if err != nil { + t.Fatal(err) + } + rp := &remotePeer{PrivKey: rpPrivKey, Config: &rpCfg} rp.Start() defer rp.Stop() diff --git a/p2p/test_util.go b/p2p/test_util.go index 8af7dc56..76c52ad9 100644 --- a/p2p/test_util.go +++ b/p2p/test_util.go @@ -4,13 +4,13 @@ import ( "net" log "github.com/sirupsen/logrus" - "github.com/tendermint/go-crypto" cmn "github.com/tendermint/tmlibs/common" cfg "github.com/vapor/config" dbm "github.com/vapor/database/leveldb" "github.com/vapor/p2p/connection" "github.com/vapor/p2p/discover/dht" + "github.com/vapor/p2p/signlib" ) //PanicOnAddPeerErr add peer error @@ -88,7 +88,7 @@ func (m *mockDiscv) ReadRandomNodes(buf []*dht.Node) (n int) { return 0 } -func MakeSwitch(cfg *cfg.Config, testdb dbm.DB, privKey crypto.PrivKeyEd25519, initSwitch func(*Switch) *Switch) *Switch { +func MakeSwitch(cfg *cfg.Config, testdb dbm.DB, privKey signlib.PrivKey, initSwitch func(*Switch) *Switch) *Switch { // new switch, add reactors l, listenAddr := GetListener(cfg.P2P) cfg.P2P.LANDiscover = false