github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/p2p/rlpx/rlpx.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package rlpx implements the RLPx transport protocol.
    18  package rlpx
    19  
    20  import (
    21  	"bytes"
    22  	"crypto/aes"
    23  	"crypto/cipher"
    24  	"crypto/ecdsa"
    25  	"crypto/elliptic"
    26  	"crypto/hmac"
    27  	"crypto/rand"
    28  	"encoding/binary"
    29  	"errors"
    30  	"fmt"
    31  	"hash"
    32  	"io"
    33  	mrand "math/rand"
    34  	"net"
    35  	"time"
    36  
    37  	"github.com/golang/snappy"
    38  	"golang.org/x/crypto/sha3"
    39  
    40  	"github.com/scroll-tech/go-ethereum/crypto"
    41  	"github.com/scroll-tech/go-ethereum/crypto/ecies"
    42  	"github.com/scroll-tech/go-ethereum/rlp"
    43  )
    44  
    45  // Conn is an RLPx network connection. It wraps a low-level network connection. The
    46  // underlying connection should not be used for other activity when it is wrapped by Conn.
    47  //
    48  // Before sending messages, a handshake must be performed by calling the Handshake method.
    49  // This type is not generally safe for concurrent use, but reading and writing of messages
    50  // may happen concurrently after the handshake.
    51  type Conn struct {
    52  	dialDest *ecdsa.PublicKey
    53  	conn     net.Conn
    54  	session  *sessionState
    55  
    56  	// These are the buffers for snappy compression.
    57  	// Compression is enabled if they are non-nil.
    58  	snappyReadBuffer  []byte
    59  	snappyWriteBuffer []byte
    60  }
    61  
    62  // sessionState contains the session keys.
    63  type sessionState struct {
    64  	enc cipher.Stream
    65  	dec cipher.Stream
    66  
    67  	egressMAC  hashMAC
    68  	ingressMAC hashMAC
    69  	rbuf       readBuffer
    70  	wbuf       writeBuffer
    71  }
    72  
    73  // hashMAC holds the state of the RLPx v4 MAC contraption.
    74  type hashMAC struct {
    75  	cipher     cipher.Block
    76  	hash       hash.Hash
    77  	aesBuffer  [16]byte
    78  	hashBuffer [32]byte
    79  	seedBuffer [32]byte
    80  }
    81  
    82  func newHashMAC(cipher cipher.Block, h hash.Hash) hashMAC {
    83  	m := hashMAC{cipher: cipher, hash: h}
    84  	if cipher.BlockSize() != len(m.aesBuffer) {
    85  		panic(fmt.Errorf("invalid MAC cipher block size %d", cipher.BlockSize()))
    86  	}
    87  	if h.Size() != len(m.hashBuffer) {
    88  		panic(fmt.Errorf("invalid MAC digest size %d", h.Size()))
    89  	}
    90  	return m
    91  }
    92  
    93  // NewConn wraps the given network connection. If dialDest is non-nil, the connection
    94  // behaves as the initiator during the handshake.
    95  func NewConn(conn net.Conn, dialDest *ecdsa.PublicKey) *Conn {
    96  	return &Conn{
    97  		dialDest: dialDest,
    98  		conn:     conn,
    99  	}
   100  }
   101  
   102  // SetSnappy enables or disables snappy compression of messages. This is usually called
   103  // after the devp2p Hello message exchange when the negotiated version indicates that
   104  // compression is available on both ends of the connection.
   105  func (c *Conn) SetSnappy(snappy bool) {
   106  	if snappy {
   107  		c.snappyReadBuffer = []byte{}
   108  		c.snappyWriteBuffer = []byte{}
   109  	} else {
   110  		c.snappyReadBuffer = nil
   111  		c.snappyWriteBuffer = nil
   112  	}
   113  }
   114  
   115  // SetReadDeadline sets the deadline for all future read operations.
   116  func (c *Conn) SetReadDeadline(time time.Time) error {
   117  	return c.conn.SetReadDeadline(time)
   118  }
   119  
   120  // SetWriteDeadline sets the deadline for all future write operations.
   121  func (c *Conn) SetWriteDeadline(time time.Time) error {
   122  	return c.conn.SetWriteDeadline(time)
   123  }
   124  
   125  // SetDeadline sets the deadline for all future read and write operations.
   126  func (c *Conn) SetDeadline(time time.Time) error {
   127  	return c.conn.SetDeadline(time)
   128  }
   129  
   130  // Read reads a message from the connection.
   131  // The returned data buffer is valid until the next call to Read.
   132  func (c *Conn) Read() (code uint64, data []byte, wireSize int, err error) {
   133  	if c.session == nil {
   134  		panic("can't ReadMsg before handshake")
   135  	}
   136  
   137  	frame, err := c.session.readFrame(c.conn)
   138  	if err != nil {
   139  		return 0, nil, 0, err
   140  	}
   141  	code, data, err = rlp.SplitUint64(frame)
   142  	if err != nil {
   143  		return 0, nil, 0, fmt.Errorf("invalid message code: %v", err)
   144  	}
   145  	wireSize = len(data)
   146  
   147  	// If snappy is enabled, verify and decompress message.
   148  	if c.snappyReadBuffer != nil {
   149  		var actualSize int
   150  		actualSize, err = snappy.DecodedLen(data)
   151  		if err != nil {
   152  			return code, nil, 0, err
   153  		}
   154  		if actualSize > maxUint24 {
   155  			return code, nil, 0, errPlainMessageTooLarge
   156  		}
   157  		c.snappyReadBuffer = growslice(c.snappyReadBuffer, actualSize)
   158  		data, err = snappy.Decode(c.snappyReadBuffer, data)
   159  	}
   160  	return code, data, wireSize, err
   161  }
   162  
   163  func (h *sessionState) readFrame(conn io.Reader) ([]byte, error) {
   164  	h.rbuf.reset()
   165  
   166  	// Read the frame header.
   167  	header, err := h.rbuf.read(conn, 32)
   168  	if err != nil {
   169  		return nil, err
   170  	}
   171  
   172  	// Verify header MAC.
   173  	wantHeaderMAC := h.ingressMAC.computeHeader(header[:16])
   174  	if !hmac.Equal(wantHeaderMAC, header[16:]) {
   175  		return nil, errors.New("bad header MAC")
   176  	}
   177  
   178  	// Decrypt the frame header to get the frame size.
   179  	h.dec.XORKeyStream(header[:16], header[:16])
   180  	fsize := readUint24(header[:16])
   181  	// Frame size rounded up to 16 byte boundary for padding.
   182  	rsize := fsize
   183  	if padding := fsize % 16; padding > 0 {
   184  		rsize += 16 - padding
   185  	}
   186  
   187  	// Read the frame content.
   188  	frame, err := h.rbuf.read(conn, int(rsize))
   189  	if err != nil {
   190  		return nil, err
   191  	}
   192  
   193  	// Validate frame MAC.
   194  	frameMAC, err := h.rbuf.read(conn, 16)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  	wantFrameMAC := h.ingressMAC.computeFrame(frame)
   199  	if !hmac.Equal(wantFrameMAC, frameMAC) {
   200  		return nil, errors.New("bad frame MAC")
   201  	}
   202  
   203  	// Decrypt the frame data.
   204  	h.dec.XORKeyStream(frame, frame)
   205  	return frame[:fsize], nil
   206  }
   207  
   208  // Write writes a message to the connection.
   209  //
   210  // Write returns the written size of the message data. This may be less than or equal to
   211  // len(data) depending on whether snappy compression is enabled.
   212  func (c *Conn) Write(code uint64, data []byte) (uint32, error) {
   213  	if c.session == nil {
   214  		panic("can't WriteMsg before handshake")
   215  	}
   216  	if len(data) > maxUint24 {
   217  		return 0, errPlainMessageTooLarge
   218  	}
   219  	if c.snappyWriteBuffer != nil {
   220  		// Ensure the buffer has sufficient size.
   221  		// Package snappy will allocate its own buffer if the provided
   222  		// one is smaller than MaxEncodedLen.
   223  		c.snappyWriteBuffer = growslice(c.snappyWriteBuffer, snappy.MaxEncodedLen(len(data)))
   224  		data = snappy.Encode(c.snappyWriteBuffer, data)
   225  	}
   226  
   227  	wireSize := uint32(len(data))
   228  	err := c.session.writeFrame(c.conn, code, data)
   229  	return wireSize, err
   230  }
   231  
   232  func (h *sessionState) writeFrame(conn io.Writer, code uint64, data []byte) error {
   233  	h.wbuf.reset()
   234  
   235  	// Write header.
   236  	fsize := rlp.IntSize(code) + len(data)
   237  	if fsize > maxUint24 {
   238  		return errPlainMessageTooLarge
   239  	}
   240  	header := h.wbuf.appendZero(16)
   241  	putUint24(uint32(fsize), header)
   242  	copy(header[3:], zeroHeader)
   243  	h.enc.XORKeyStream(header, header)
   244  
   245  	// Write header MAC.
   246  	h.wbuf.Write(h.egressMAC.computeHeader(header))
   247  
   248  	// Encode and encrypt the frame data.
   249  	offset := len(h.wbuf.data)
   250  	h.wbuf.data = rlp.AppendUint64(h.wbuf.data, code)
   251  	h.wbuf.Write(data)
   252  	if padding := fsize % 16; padding > 0 {
   253  		h.wbuf.appendZero(16 - padding)
   254  	}
   255  	framedata := h.wbuf.data[offset:]
   256  	h.enc.XORKeyStream(framedata, framedata)
   257  
   258  	// Write frame MAC.
   259  	h.wbuf.Write(h.egressMAC.computeFrame(framedata))
   260  
   261  	_, err := conn.Write(h.wbuf.data)
   262  	return err
   263  }
   264  
   265  // computeHeader computes the MAC of a frame header.
   266  func (m *hashMAC) computeHeader(header []byte) []byte {
   267  	sum1 := m.hash.Sum(m.hashBuffer[:0])
   268  	return m.compute(sum1, header)
   269  }
   270  
   271  // computeFrame computes the MAC of framedata.
   272  func (m *hashMAC) computeFrame(framedata []byte) []byte {
   273  	m.hash.Write(framedata)
   274  	seed := m.hash.Sum(m.seedBuffer[:0])
   275  	return m.compute(seed, seed[:16])
   276  }
   277  
   278  // compute computes the MAC of a 16-byte 'seed'.
   279  //
   280  // To do this, it encrypts the current value of the hash state, then XORs the ciphertext
   281  // with seed. The obtained value is written back into the hash state and hash output is
   282  // taken again. The first 16 bytes of the resulting sum are the MAC value.
   283  //
   284  // This MAC construction is a horrible, legacy thing.
   285  func (m *hashMAC) compute(sum1, seed []byte) []byte {
   286  	if len(seed) != len(m.aesBuffer) {
   287  		panic("invalid MAC seed")
   288  	}
   289  
   290  	m.cipher.Encrypt(m.aesBuffer[:], sum1)
   291  	for i := range m.aesBuffer {
   292  		m.aesBuffer[i] ^= seed[i]
   293  	}
   294  	m.hash.Write(m.aesBuffer[:])
   295  	sum2 := m.hash.Sum(m.hashBuffer[:0])
   296  	return sum2[:16]
   297  }
   298  
   299  // Handshake performs the handshake. This must be called before any data is written
   300  // or read from the connection.
   301  func (c *Conn) Handshake(prv *ecdsa.PrivateKey) (*ecdsa.PublicKey, error) {
   302  	var (
   303  		sec Secrets
   304  		err error
   305  		h   handshakeState
   306  	)
   307  	if c.dialDest != nil {
   308  		sec, err = h.runInitiator(c.conn, prv, c.dialDest)
   309  	} else {
   310  		sec, err = h.runRecipient(c.conn, prv)
   311  	}
   312  	if err != nil {
   313  		return nil, err
   314  	}
   315  	c.InitWithSecrets(sec)
   316  	c.session.rbuf = h.rbuf
   317  	c.session.wbuf = h.wbuf
   318  	return sec.remote, err
   319  }
   320  
   321  // InitWithSecrets injects connection secrets as if a handshake had
   322  // been performed. This cannot be called after the handshake.
   323  func (c *Conn) InitWithSecrets(sec Secrets) {
   324  	if c.session != nil {
   325  		panic("can't handshake twice")
   326  	}
   327  	macc, err := aes.NewCipher(sec.MAC)
   328  	if err != nil {
   329  		panic("invalid MAC secret: " + err.Error())
   330  	}
   331  	encc, err := aes.NewCipher(sec.AES)
   332  	if err != nil {
   333  		panic("invalid AES secret: " + err.Error())
   334  	}
   335  	// we use an all-zeroes IV for AES because the key used
   336  	// for encryption is ephemeral.
   337  	iv := make([]byte, encc.BlockSize())
   338  	c.session = &sessionState{
   339  		enc:        cipher.NewCTR(encc, iv),
   340  		dec:        cipher.NewCTR(encc, iv),
   341  		egressMAC:  newHashMAC(macc, sec.EgressMAC),
   342  		ingressMAC: newHashMAC(macc, sec.IngressMAC),
   343  	}
   344  }
   345  
   346  // Close closes the underlying network connection.
   347  func (c *Conn) Close() error {
   348  	return c.conn.Close()
   349  }
   350  
   351  // Constants for the handshake.
   352  const (
   353  	sskLen = 16                     // ecies.MaxSharedKeyLength(pubKey) / 2
   354  	sigLen = crypto.SignatureLength // elliptic S256
   355  	pubLen = 64                     // 512 bit pubkey in uncompressed representation without format byte
   356  	shaLen = 32                     // hash length (for nonce etc)
   357  
   358  	eciesOverhead = 65 /* pubkey */ + 16 /* IV */ + 32 /* MAC */
   359  )
   360  
   361  var (
   362  	// this is used in place of actual frame header data.
   363  	// TODO: replace this when Msg contains the protocol type code.
   364  	zeroHeader = []byte{0xC2, 0x80, 0x80}
   365  
   366  	// errPlainMessageTooLarge is returned if a decompressed message length exceeds
   367  	// the allowed 24 bits (i.e. length >= 16MB).
   368  	errPlainMessageTooLarge = errors.New("message length >= 16MB")
   369  )
   370  
   371  // Secrets represents the connection secrets which are negotiated during the handshake.
   372  type Secrets struct {
   373  	AES, MAC              []byte
   374  	EgressMAC, IngressMAC hash.Hash
   375  	remote                *ecdsa.PublicKey
   376  }
   377  
   378  // handshakeState contains the state of the encryption handshake.
   379  type handshakeState struct {
   380  	initiator            bool
   381  	remote               *ecies.PublicKey  // remote-pubk
   382  	initNonce, respNonce []byte            // nonce
   383  	randomPrivKey        *ecies.PrivateKey // ecdhe-random
   384  	remoteRandomPub      *ecies.PublicKey  // ecdhe-random-pubk
   385  
   386  	rbuf readBuffer
   387  	wbuf writeBuffer
   388  }
   389  
   390  // RLPx v4 handshake auth (defined in EIP-8).
   391  type authMsgV4 struct {
   392  	Signature       [sigLen]byte
   393  	InitiatorPubkey [pubLen]byte
   394  	Nonce           [shaLen]byte
   395  	Version         uint
   396  
   397  	// Ignore additional fields (forward-compatibility)
   398  	Rest []rlp.RawValue `rlp:"tail"`
   399  }
   400  
   401  // RLPx v4 handshake response (defined in EIP-8).
   402  type authRespV4 struct {
   403  	RandomPubkey [pubLen]byte
   404  	Nonce        [shaLen]byte
   405  	Version      uint
   406  
   407  	// Ignore additional fields (forward-compatibility)
   408  	Rest []rlp.RawValue `rlp:"tail"`
   409  }
   410  
   411  // runRecipient negotiates a session token on conn.
   412  // it should be called on the listening side of the connection.
   413  //
   414  // prv is the local client's private key.
   415  func (h *handshakeState) runRecipient(conn io.ReadWriter, prv *ecdsa.PrivateKey) (s Secrets, err error) {
   416  	authMsg := new(authMsgV4)
   417  	authPacket, err := h.readMsg(authMsg, prv, conn)
   418  	if err != nil {
   419  		return s, err
   420  	}
   421  	if err := h.handleAuthMsg(authMsg, prv); err != nil {
   422  		return s, err
   423  	}
   424  
   425  	authRespMsg, err := h.makeAuthResp()
   426  	if err != nil {
   427  		return s, err
   428  	}
   429  	authRespPacket, err := h.sealEIP8(authRespMsg)
   430  	if err != nil {
   431  		return s, err
   432  	}
   433  	if _, err = conn.Write(authRespPacket); err != nil {
   434  		return s, err
   435  	}
   436  
   437  	return h.secrets(authPacket, authRespPacket)
   438  }
   439  
   440  func (h *handshakeState) handleAuthMsg(msg *authMsgV4, prv *ecdsa.PrivateKey) error {
   441  	// Import the remote identity.
   442  	rpub, err := importPublicKey(msg.InitiatorPubkey[:])
   443  	if err != nil {
   444  		return err
   445  	}
   446  	h.initNonce = msg.Nonce[:]
   447  	h.remote = rpub
   448  
   449  	// Generate random keypair for ECDH.
   450  	// If a private key is already set, use it instead of generating one (for testing).
   451  	if h.randomPrivKey == nil {
   452  		h.randomPrivKey, err = ecies.GenerateKey(rand.Reader, crypto.S256(), nil)
   453  		if err != nil {
   454  			return err
   455  		}
   456  	}
   457  
   458  	// Check the signature.
   459  	token, err := h.staticSharedSecret(prv)
   460  	if err != nil {
   461  		return err
   462  	}
   463  	signedMsg := xor(token, h.initNonce)
   464  	remoteRandomPub, err := crypto.Ecrecover(signedMsg, msg.Signature[:])
   465  	if err != nil {
   466  		return err
   467  	}
   468  	h.remoteRandomPub, _ = importPublicKey(remoteRandomPub)
   469  	return nil
   470  }
   471  
   472  // secrets is called after the handshake is completed.
   473  // It extracts the connection secrets from the handshake values.
   474  func (h *handshakeState) secrets(auth, authResp []byte) (Secrets, error) {
   475  	ecdheSecret, err := h.randomPrivKey.GenerateShared(h.remoteRandomPub, sskLen, sskLen)
   476  	if err != nil {
   477  		return Secrets{}, err
   478  	}
   479  
   480  	// derive base secrets from ephemeral key agreement
   481  	sharedSecret := crypto.Keccak256(ecdheSecret, crypto.Keccak256(h.respNonce, h.initNonce))
   482  	aesSecret := crypto.Keccak256(ecdheSecret, sharedSecret)
   483  	s := Secrets{
   484  		remote: h.remote.ExportECDSA(),
   485  		AES:    aesSecret,
   486  		MAC:    crypto.Keccak256(ecdheSecret, aesSecret),
   487  	}
   488  
   489  	// setup sha3 instances for the MACs
   490  	mac1 := sha3.NewLegacyKeccak256()
   491  	mac1.Write(xor(s.MAC, h.respNonce))
   492  	mac1.Write(auth)
   493  	mac2 := sha3.NewLegacyKeccak256()
   494  	mac2.Write(xor(s.MAC, h.initNonce))
   495  	mac2.Write(authResp)
   496  	if h.initiator {
   497  		s.EgressMAC, s.IngressMAC = mac1, mac2
   498  	} else {
   499  		s.EgressMAC, s.IngressMAC = mac2, mac1
   500  	}
   501  
   502  	return s, nil
   503  }
   504  
   505  // staticSharedSecret returns the static shared secret, the result
   506  // of key agreement between the local and remote static node key.
   507  func (h *handshakeState) staticSharedSecret(prv *ecdsa.PrivateKey) ([]byte, error) {
   508  	return ecies.ImportECDSA(prv).GenerateShared(h.remote, sskLen, sskLen)
   509  }
   510  
   511  // runInitiator negotiates a session token on conn.
   512  // it should be called on the dialing side of the connection.
   513  //
   514  // prv is the local client's private key.
   515  func (h *handshakeState) runInitiator(conn io.ReadWriter, prv *ecdsa.PrivateKey, remote *ecdsa.PublicKey) (s Secrets, err error) {
   516  	h.initiator = true
   517  	h.remote = ecies.ImportECDSAPublic(remote)
   518  
   519  	authMsg, err := h.makeAuthMsg(prv)
   520  	if err != nil {
   521  		return s, err
   522  	}
   523  	authPacket, err := h.sealEIP8(authMsg)
   524  	if err != nil {
   525  		return s, err
   526  	}
   527  
   528  	if _, err = conn.Write(authPacket); err != nil {
   529  		return s, err
   530  	}
   531  
   532  	authRespMsg := new(authRespV4)
   533  	authRespPacket, err := h.readMsg(authRespMsg, prv, conn)
   534  	if err != nil {
   535  		return s, err
   536  	}
   537  	if err := h.handleAuthResp(authRespMsg); err != nil {
   538  		return s, err
   539  	}
   540  
   541  	return h.secrets(authPacket, authRespPacket)
   542  }
   543  
   544  // makeAuthMsg creates the initiator handshake message.
   545  func (h *handshakeState) makeAuthMsg(prv *ecdsa.PrivateKey) (*authMsgV4, error) {
   546  	// Generate random initiator nonce.
   547  	h.initNonce = make([]byte, shaLen)
   548  	_, err := rand.Read(h.initNonce)
   549  	if err != nil {
   550  		return nil, err
   551  	}
   552  	// Generate random keypair to for ECDH.
   553  	h.randomPrivKey, err = ecies.GenerateKey(rand.Reader, crypto.S256(), nil)
   554  	if err != nil {
   555  		return nil, err
   556  	}
   557  
   558  	// Sign known message: static-shared-secret ^ nonce
   559  	token, err := h.staticSharedSecret(prv)
   560  	if err != nil {
   561  		return nil, err
   562  	}
   563  	signed := xor(token, h.initNonce)
   564  	signature, err := crypto.Sign(signed, h.randomPrivKey.ExportECDSA())
   565  	if err != nil {
   566  		return nil, err
   567  	}
   568  
   569  	msg := new(authMsgV4)
   570  	copy(msg.Signature[:], signature)
   571  	copy(msg.InitiatorPubkey[:], crypto.FromECDSAPub(&prv.PublicKey)[1:])
   572  	copy(msg.Nonce[:], h.initNonce)
   573  	msg.Version = 4
   574  	return msg, nil
   575  }
   576  
   577  func (h *handshakeState) handleAuthResp(msg *authRespV4) (err error) {
   578  	h.respNonce = msg.Nonce[:]
   579  	h.remoteRandomPub, err = importPublicKey(msg.RandomPubkey[:])
   580  	return err
   581  }
   582  
   583  func (h *handshakeState) makeAuthResp() (msg *authRespV4, err error) {
   584  	// Generate random nonce.
   585  	h.respNonce = make([]byte, shaLen)
   586  	if _, err = rand.Read(h.respNonce); err != nil {
   587  		return nil, err
   588  	}
   589  
   590  	msg = new(authRespV4)
   591  	copy(msg.Nonce[:], h.respNonce)
   592  	copy(msg.RandomPubkey[:], exportPubkey(&h.randomPrivKey.PublicKey))
   593  	msg.Version = 4
   594  	return msg, nil
   595  }
   596  
   597  // readMsg reads an encrypted handshake message, decoding it into msg.
   598  func (h *handshakeState) readMsg(msg interface{}, prv *ecdsa.PrivateKey, r io.Reader) ([]byte, error) {
   599  	h.rbuf.reset()
   600  	h.rbuf.grow(512)
   601  
   602  	// Read the size prefix.
   603  	prefix, err := h.rbuf.read(r, 2)
   604  	if err != nil {
   605  		return nil, err
   606  	}
   607  	size := binary.BigEndian.Uint16(prefix)
   608  
   609  	// Read the handshake packet.
   610  	packet, err := h.rbuf.read(r, int(size))
   611  	if err != nil {
   612  		return nil, err
   613  	}
   614  	dec, err := ecies.ImportECDSA(prv).Decrypt(packet, nil, prefix)
   615  	if err != nil {
   616  		return nil, err
   617  	}
   618  	// Can't use rlp.DecodeBytes here because it rejects
   619  	// trailing data (forward-compatibility).
   620  	s := rlp.NewStream(bytes.NewReader(dec), 0)
   621  	err = s.Decode(msg)
   622  	return h.rbuf.data[:len(prefix)+len(packet)], err
   623  }
   624  
   625  // sealEIP8 encrypts a handshake message.
   626  func (h *handshakeState) sealEIP8(msg interface{}) ([]byte, error) {
   627  	h.wbuf.reset()
   628  
   629  	// Write the message plaintext.
   630  	if err := rlp.Encode(&h.wbuf, msg); err != nil {
   631  		return nil, err
   632  	}
   633  	// Pad with random amount of data. the amount needs to be at least 100 bytes to make
   634  	// the message distinguishable from pre-EIP-8 handshakes.
   635  	h.wbuf.appendZero(mrand.Intn(100) + 100)
   636  
   637  	prefix := make([]byte, 2)
   638  	binary.BigEndian.PutUint16(prefix, uint16(len(h.wbuf.data)+eciesOverhead))
   639  
   640  	enc, err := ecies.Encrypt(rand.Reader, h.remote, h.wbuf.data, nil, prefix)
   641  	return append(prefix, enc...), err
   642  }
   643  
   644  // importPublicKey unmarshals 512 bit public keys.
   645  func importPublicKey(pubKey []byte) (*ecies.PublicKey, error) {
   646  	var pubKey65 []byte
   647  	switch len(pubKey) {
   648  	case 64:
   649  		// add 'uncompressed key' flag
   650  		pubKey65 = append([]byte{0x04}, pubKey...)
   651  	case 65:
   652  		pubKey65 = pubKey
   653  	default:
   654  		return nil, fmt.Errorf("invalid public key length %v (expect 64/65)", len(pubKey))
   655  	}
   656  	// TODO: fewer pointless conversions
   657  	pub, err := crypto.UnmarshalPubkey(pubKey65)
   658  	if err != nil {
   659  		return nil, err
   660  	}
   661  	return ecies.ImportECDSAPublic(pub), nil
   662  }
   663  
   664  func exportPubkey(pub *ecies.PublicKey) []byte {
   665  	if pub == nil {
   666  		panic("nil pubkey")
   667  	}
   668  	return elliptic.Marshal(pub.Curve, pub.X, pub.Y)[1:]
   669  }
   670  
   671  func xor(one, other []byte) (xor []byte) {
   672  	xor = make([]byte, len(one))
   673  	for i := 0; i < len(one); i++ {
   674  		xor[i] = one[i] ^ other[i]
   675  	}
   676  	return xor
   677  }