code: func encryptPayload(vsn encryptionVersion, key []byte, msg []byte, data []byte, dst *bytes.Buffer) error {
  	// Get the AES block cipher
  	aesBlock, err := aes.NewCipher(key)
  	if err != nil {
  		return err
  	}
  
  	// Get the GCM cipher mode
  	gcm, err := cipher.NewGCM(aesBlock)
  	if err != nil {
  		return err
  	}
  
  	// Grow the buffer to make room for everything
  	offset := dst.Len()
  	dst.Grow(encryptedLength(vsn, len(msg)))
  
  	// Write the encryption version
  	dst.WriteByte(byte(vsn))
  
  	// Add a random nonce
  	io.CopyN(dst, rand.Reader, nonceSize)
  	afterNonce := dst.Len()
  
  	// Ensure we are correctly padded (only version 0)
  	if vsn == 0 {
  		io.Copy(dst, bytes.NewReader(msg))
  		pkcs7encode(dst, offset+versionSize+nonceSize, aes.BlockSize)
  	}
  
  	// Encrypt message using GCM
  	slice := dst.Bytes()[offset:]
  	nonce := slice[versionSize : versionSize+nonceSize]
  
  	// Message source depends on the encryption version.
  	// Version 0 uses padding, version 1 does not
  	var src []byte
  	if vsn == 0 {
  		src = slice[versionSize+nonceSize:]
  	} else {
  		src = msg
  	}
  	out := gcm.Seal(nil, nonce, src, data)
  
  	// Truncate the plaintext, and write the cipher text
  	dst.Truncate(afterNonce)
  	dst.Write(out)
  	return nil
  }
docs: // encryptPayload is used to encrypt a message with a given key.
  // We make use of AES-128 in GCM mode. New byte buffer is the version,
  // nonce, ciphertext and tag