Skip to content

Commit

Permalink
Avoid unnecessary copy of ciphertext in xchacha20poly1305.go
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 533984764
Change-Id: Ibf7f5b5df5eec86ac2e86f62d0147ec8d492f486
  • Loading branch information
juergw authored and copybara-github committed May 22, 2023
1 parent 7eb7c24 commit 8a78ca8
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
5 changes: 3 additions & 2 deletions aead/subtle/xchacha20poly1305.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ func (x *XChaCha20Poly1305) Encrypt(plaintext []byte, associatedData []byte) ([]
}

n := x.newNonce()
ct := c.Seal(nil, n, plaintext, associatedData)
return append(n, ct...), nil
dst := make([]byte, 0, chacha20poly1305.NonceSizeX+len(plaintext)+c.Overhead())
dst = append(dst, n...)
return c.Seal(dst, n, plaintext, associatedData), nil
}

// Decrypt decrypts ciphertext with associatedData.
Expand Down
22 changes: 22 additions & 0 deletions aead/subtle/xchacha20poly1305_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,25 @@ func runXChaCha20Poly1305WycheproofCase(t *testing.T, tc *AEADCase) {
}
}
}

func TestPreallocatedCiphertextMemoryInXChaCha20Poly1305IsExact(t *testing.T) {
key := random.GetRandomBytes(chacha20poly1305.KeySize)
a, err := subtle.NewXChaCha20Poly1305(key)
if err != nil {
t.Fatalf("aead.NewAESGCMInsecureIV() err = %v, want nil", err)
}
plaintext := random.GetRandomBytes(13)
associatedData := random.GetRandomBytes(17)

ciphertext, err := a.Encrypt(plaintext, associatedData)
if err != nil {
t.Fatalf("a.Encrypt() err = %v, want nil", err)
}
// Encrypt() uses cipher.Overhead() to pre-allocate the memory needed store the ciphertext.
// For ChaCha20Poly1305, the size of the allocated memory should always be exact. If this check
// fails, the pre-allocated memory was too large or too small. If it was too small, the system had
// to re-allocate more memory, which is expensive and should be avoided.
if len(ciphertext) != cap(ciphertext) {
t.Errorf("want len(ciphertext) == cap(ciphertext), got %d != %d", len(ciphertext), cap(ciphertext))
}
}

0 comments on commit 8a78ca8

Please sign in to comment.