func (msg *authMsgV4) sealPlain(h *encHandshake) ([]byte, error) { buf := make([]byte, authMsgLen) n := copy(buf, msg.Signature[:]) n += copy(buf[n:], crypto.Keccak256(exportPubkey(&h.randomPrivKey.PublicKey))) n += copy(buf[n:], msg.InitiatorPubkey[:]) n += copy(buf[n:], msg.Nonce[:]) buf[n] = 0 // token-flag return ecies.Encrypt(rand.Reader, h.remotePub, buf, nil, nil) }
// authResp generates the encrypted authentication response message. func (h *encHandshake) authResp(prv *ecdsa.PrivateKey, token []byte) ([]byte, error) { // responder auth message // E(remote-pubk, ecdhe-random-pubk || nonce || 0x0) resp := make([]byte, authRespLen) n := copy(resp, exportPubkey(&h.randomPrivKey.PublicKey)) n += copy(resp[n:], h.respNonce) if token == nil { resp[n] = 0 } else { resp[n] = 1 } // encrypt using remote-pubk return ecies.Encrypt(rand.Reader, h.remotePub, resp, nil, nil) }
func sealEIP8(msg interface{}, h *encHandshake) ([]byte, error) { buf := new(bytes.Buffer) if err := rlp.Encode(buf, msg); err != nil { return nil, err } // pad with random amount of data. the amount needs to be at least 100 bytes to make // the message distinguishable from pre-EIP-8 handshakes. pad := padSpace[:mrand.Intn(len(padSpace)-100)+100] buf.Write(pad) prefix := make([]byte, 2) binary.BigEndian.PutUint16(prefix, uint16(buf.Len()+eciesOverhead)) enc, err := ecies.Encrypt(rand.Reader, h.remotePub, buf.Bytes(), nil, prefix) return append(prefix, enc...), err }
// authMsg creates an encrypted initiator handshake message. func (h *encHandshake) authMsg(prv *ecdsa.PrivateKey, token []byte) ([]byte, error) { var tokenFlag byte if token == nil { // no session token found means we need to generate shared secret. // ecies shared secret is used as initial session token for new peers // generate shared key from prv and remote pubkey var err error if token, err = h.ecdhShared(prv); err != nil { return nil, err } } else { // for known peers, we use stored token from the previous session tokenFlag = 0x01 } // sign known message: // ecdh-shared-secret^nonce for new peers // token^nonce for old peers signed := xor(token, h.initNonce) signature, err := crypto.Sign(signed, h.randomPrivKey.ExportECDSA()) if err != nil { return nil, err } // encode auth message // signature || sha3(ecdhe-random-pubk) || pubk || nonce || token-flag msg := make([]byte, authMsgLen) n := copy(msg, signature) n += copy(msg[n:], crypto.Sha3(exportPubkey(&h.randomPrivKey.PublicKey))) n += copy(msg[n:], crypto.FromECDSAPub(&prv.PublicKey)[1:]) n += copy(msg[n:], h.initNonce) msg[n] = tokenFlag // encrypt auth message using remote-pubk return ecies.Encrypt(rand.Reader, h.remotePub, msg, nil, nil) }
func (msg *authRespV4) sealPlain(hs *encHandshake) ([]byte, error) { buf := make([]byte, authRespLen) n := copy(buf, msg.RandomPubkey[:]) n += copy(buf[n:], msg.Nonce[:]) return ecies.Encrypt(rand.Reader, hs.remotePub, buf, nil, nil) }
func Encrypt(pub *ecdsa.PublicKey, message []byte) ([]byte, error) { return ecies.Encrypt(rand.Reader, ecies.ImportECDSAPublic(pub), message, nil, nil) }