aead: avoid double allocation/copy in AES-GCM(-SIV) encrypt - #874
Open
vmaheshw wants to merge 1 commit into
Open
aead: avoid double allocation/copy in AES-GCM(-SIV) encrypt#874vmaheshw wants to merge 1 commit into
vmaheshw wants to merge 1 commit into
Conversation
AesGcm::encrypt (and AesGcmSiv::encrypt) previously called the RustCrypto aead crate's allocating encrypt(), which allocates a new Vec for the ciphertext+tag, then copied that whole buffer a second time into a freshly allocated iv||ciphertext Vec. Switch to AeadInPlace::encrypt_in_place_detached: allocate the final output buffer once (iv || pt, sized for iv + pt + tag), encrypt the plaintext portion of that same buffer in place, and append the 16-byte tag. This drops one heap allocation and one full-size copy of the ciphertext per encrypt call, while leaving decrypt and the wire format unchanged. Verified with cargo test -p tink-tests --test aead_test (all AES-GCM and AES-GCM-SIV unit + Wycheproof vector tests pass). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
daviddrysdale
approved these changes
Aug 26, 2026
| let ct_buf = &mut ret[iv.len()..]; | ||
| let tag = match &self.key { | ||
| AesGcmVariant::Aes128(key) => key.encrypt_in_place_detached(&iv, aad, ct_buf), | ||
| AesGcmVariant::Aes256(key) => key.encrypt_in_place_detached(&iv, aad, ct_buf), |
Contributor
There was a problem hiding this comment.
(Aside: this method gets deprecated in favour of AeadInOut::encrypt_inout_detached as of aes-gcm version 0.11; however, the replacement method isn't available in the 0.10 version used here.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
AesGcm::encrypt(andAesGcmSiv::encrypt) currently go through the RustCryptoaeadcrate's allocatingAead::encrypt, which allocates a newVecforciphertext || tag, and then that whole buffer gets copied a second time into a freshly allocatediv || ciphertextVec.This switches both to
AeadInPlace::encrypt_in_place_detached:iv + pt + tag.ivthenptinto it.ptportion of that same buffer in place (no extra buffer), getting the tag back detached.Net effect: one heap allocation and one full-size copy of the ciphertext removed per
encrypt()call.decrypt(), the wire format (iv || ciphertext || tag), and public API are unchanged.Testing
All AES-GCM and AES-GCM-SIV unit tests and Wycheproof vector tests pass (33 passed; 0 failed, after
git submodule update --initfor wycheproof vectors).cargo clippy -p tink-aead --all-targetsreports no new warnings from this change.