code: func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error {
  	if config.ClientVersion != "" {
  		c.clientVersion = []byte(config.ClientVersion)
  	} else {
  		c.clientVersion = []byte(packageVersion)
  	}
  	var err error
  	c.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion)
  	if err != nil {
  		return err
  	}
  
  	c.transport = newClientTransport(
  		newTransport(c.sshConn.conn, config.Rand, true /* is client */),
  		c.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr())
  	if err := c.transport.requestKeyChange(); err != nil {
  		return err
  	}
  
  	if packet, err := c.transport.readPacket(); err != nil {
  		return err
  	} else if packet[0] != msgNewKeys {
  		return unexpectedMessageError(msgNewKeys, packet[0])
  	}
  
  	// We just did the key change, so the session ID is established.
  	c.sessionID = c.transport.getSessionID()
  
  	return c.clientAuthenticate(config)
  }
docs: // clientHandshake performs the client side key exchange. See RFC 4253 Section
  // 7.