AesGcmSiv implements Aead { @Override public byte[] encrypt(final byte[] plaintext, final byte[] associatedData) throws GeneralSecurityException { if (plaintext.length > Integer.MAX_VALUE - IV_SIZE_IN_BYTES - TAG_SIZE_IN_BYTES) { throw new GeneralSecurityException("plaintext too long"); } byte[] ciphertext = new byte[IV_SIZE_IN_BYTES + plaintext.length + TAG_SIZE_IN_BYTES]; byte[] iv = Random.randBytes(IV_SIZE_IN_BYTES); System.arraycopy(iv, 0, ciphertext, 0, IV_SIZE_IN_BYTES); AlgorithmParameterSpec params = getParams(iv); localCipher.get().init(Cipher.ENCRYPT_MODE, keySpec, params); if (associatedData != null && associatedData.length != 0) { localCipher.get().updateAAD(associatedData); } int written = localCipher.get().doFinal(plaintext, 0, plaintext.length, ciphertext, IV_SIZE_IN_BYTES); if (written != plaintext.length + TAG_SIZE_IN_BYTES) { int actualTagSize = written - plaintext.length; throw new GeneralSecurityException( String.format( "encryption failed; GCM tag must be %s bytes, but got only %s bytes", TAG_SIZE_IN_BYTES, actualTagSize)); } return ciphertext; } AesGcmSiv(final byte[] key); @Override /** * On Android KitKat (API level 19) this method does not support non null or non empty {@code * associatedData}. It might not work at all in older versions. */ byte[] encrypt(final byte[] plaintext, final byte[] associatedData); @Override /** * On Android KitKat (API level 19) this method does not support non null or non empty {@code * associatedData}. It might not work at all in older versions. */ byte[] decrypt(final byte[] ciphertext, final byte[] associatedData);  }
@Test public void testRandomNonce() throws Exception { final int samples = 1 << 17; byte[] key = Random.randBytes(16); byte[] message = new byte[0]; byte[] aad = new byte[0]; AesGcmSiv gcm = new AesGcmSiv(key); HashSet<String> ciphertexts = new HashSet<String>(); for (int i = 0; i < samples; i++) { byte[] ct = gcm.encrypt(message, aad); String ctHex = TestUtil.hexEncode(ct); assertFalse(ciphertexts.contains(ctHex)); ciphertexts.add(ctHex); } }