On Thu, 15 Dec 2022 18:06:38 GMT, Daniel Jeliński <djelin...@openjdk.org> wrote:

>> This patch modifies `CipherOutputStream` to avoid pointless memory 
>> allocations when decrypting data using AEAD ciphers. This is related to 
>> #11597, which fixed a similar issue in `CipherInputStream`.
>> 
>> `Cipher.update` does not output any data when doing AEAD decryption; all 
>> data is buffered, and is later returned in one shot from `doFinal`. 
>> `Cipher.getOutputSize` returns the buffer size required by `doFinal`, which 
>> increases after every `update`, triggering new allocation in 
>> `ensureCapacity`.
>> 
>> This patch addresses the issue by calling the `update` overload that returns 
>> the output buffer until one of the update calls returns some data. When that 
>> happens, we know that the cipher does not buffer everything until `doFinal`, 
>> and revert to original behavior.
>> 
>> This PR adds a new benchmark for AES/GCM encryption and decryption using 
>> `CipherOutputStream`.
>> 
>> Benchmark results before:
>> 
>> Benchmark                         (dataSize)  (keyLength)  (provider)   Mode 
>>  Cnt       Score      Error  Units
>> AESGCMCipherOutputStream.decrypt       16384          128              thrpt 
>>   40   27949,624 ±  301,408  ops/s
>> AESGCMCipherOutputStream.decrypt     1048576          128              thrpt 
>>   40      20,730 ±    0,875  ops/s
>> AESGCMCipherOutputStream.encrypt       16384          128              thrpt 
>>   40  175358,641 ± 4235,808  ops/s
>> AESGCMCipherOutputStream.encrypt     1048576          128              thrpt 
>>   40    2588,111 ±   35,469  ops/s
>> 
>> 
>> after:
>> 
>> Benchmark                         (dataSize)  (keyLength)  (provider)   Mode 
>>  Cnt       Score      Error  Units
>> AESGCMCipherOutputStream.decrypt       16384          128              thrpt 
>>   40   69644,217 ± 1081,032  ops/s
>> AESGCMCipherOutputStream.decrypt     1048576          128              thrpt 
>>   40     949,667 ±    9,431  ops/s
>> AESGCMCipherOutputStream.encrypt       16384          128              thrpt 
>>   40  173144,038 ± 3279,149  ops/s
>> AESGCMCipherOutputStream.encrypt     1048576          128              thrpt 
>>   40    2514,840 ±   87,935  ops/s
>
> Daniel Jeliński has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Fix test failure

src/java.base/share/classes/javax/crypto/CipherOutputStream.java line 95:

> 93:      *
> 94:      * If obuffer is null/zero-sized, do not allocate a new buffer.
> 95:      * This reduces allocation for AEAD ciphers that never return data 
> from update

AEAD ciphers do return data for update() calls for encryption. Perhaps we 
should add "when used for decryption" or some other similar wordings to the 
above sentence? Same goes for the comment in CipherInputStream class.

-------------

PR: https://git.openjdk.org/jdk/pull/11693

Reply via email to