code: func encryptBody(plaintext []byte) ([]byte, []*xcpb.Chunk, error) {
  	// generate session / encryption key
  	var sessionKey [32]byte
  	if _, err := crypto_rand.Read(sessionKey[:]); err != nil {
  		return nil, nil, err
  	}
  
  	chunks := make([]*xcpb.Chunk, 0, (len(plaintext)/chunkSizeMax)+1)
  	offset := 0
  
  	for offset < len(plaintext) {
  		// use a sequential nonce to prevent chunk reordering.
  		// since the pair of key and nonce has to be unique and we're
  		// generating a new random key for each message, this is OK
  		var nonce [24]byte
  		binary.BigEndian.PutUint64(nonce[:], uint64(len(chunks)))
  
  		// encrypt the plaintext using the random nonce
  		chunks = append(chunks, &xcpb.Chunk{
  			Body: secretbox.Seal(nil, plaintext[offset:min(len(plaintext), offset+chunkSizeMax)], &nonce, &sessionKey),
  		})
  		offset += chunkSizeMax
  	}
  
  	return sessionKey[:], chunks, nil
  }
docs: // encryptBody generates a random session key and a nonce and encrypts the given
  // plaintext with those. it returns all three