@Override
  public byte[] encrypt(final byte[] plaintext, final byte[] associatedData)
      throws GeneralSecurityException {
    byte[] ciphertext = cipher.encrypt(plaintext);
    byte[] ad = associatedData;
    if (ad == null) {
      ad = new byte[0];
    }
    byte[] adLengthInBits =
        Arrays.copyOf(ByteBuffer.allocate(8).putLong(8L * ad.length).array(), 8);
    byte[] macValue = mac.computeMac(Bytes.concat(ad, ciphertext, adLengthInBits));
    return Bytes.concat(outputPrefix, ciphertext, macValue);
  }
Encrypts {@code plaintext} with {@code associatedData}. The resulting ciphertext allows
for checking authenticity and integrity of associated data (ad), but does not guarantee its
secrecy.

<p>The plaintext is encrypted with an {@code IndCpaCipher}, then MAC is computed over (ad ||
ciphertext || t) where t is ad's length in bits represented as 64-bit bigendian unsigned
integer. The final ciphertext format is (output prefix || ind-cpa ciphertext || mac).

@return resulting ciphertext.
java_src/src/main/java/com/google/crypto/tink/subtle/EncryptThenAuthenticate.java