code: func (sc *SecretConnection) Read(data []byte) (n int, err error) {
  	if 0 < len(sc.recvBuffer) {
  		n_ := copy(data, sc.recvBuffer)
  		sc.recvBuffer = sc.recvBuffer[n_:]
  		return
  	}
  
  	sealedFrame := make([]byte, sealedFrameSize)
  	_, err = io.ReadFull(sc.conn, sealedFrame)
  	if err != nil {
  		return
  	}
  
  	// decrypt the frame
  	var frame = make([]byte, totalFrameSize)
  	// fmt.Printf("secretbox.Open(sealed:%X,recvNonce:%X,shrSecret:%X\n", sealedFrame, sc.recvNonce, sc.shrSecret)
  	_, ok := secretbox.Open(frame[:0], sealedFrame, sc.recvNonce, sc.shrSecret)
  	if !ok {
  		return n, errors.New("Failed to decrypt SecretConnection")
  	}
  	incr2Nonce(sc.recvNonce)
  	// end decryption
  
  	var chunkLength = binary.BigEndian.Uint16(frame) // read the first two bytes
  	if chunkLength > dataMaxSize {
  		return 0, errors.New("chunkLength is greater than dataMaxSize")
  	}
  	var chunk = frame[dataLenSize : dataLenSize+chunkLength]
  
  	n = copy(data, chunk)
  	sc.recvBuffer = chunk[n:]
  	return
  }
docs: // CONTRACT: data smaller than dataMaxSize is read atomically.