From e8ef3d40dd1bacd23cc5ba083e2c05aad7156db0 Mon Sep 17 00:00:00 2001 From: Jonathan Rudenberg Date: Thu, 3 Jul 2014 21:54:44 -0700 Subject: [PATCH] Remove an alloc by pre-allocating the dest slice --- box/box.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/box/box.go b/box/box.go index 6b09bf1..04e3938 100644 --- a/box/box.go +++ b/box/box.go @@ -90,6 +90,13 @@ func (c *Crypter) Encrypt(dst []byte, ephKey *Key, plaintext []byte, padLen int) } ephKey = &k } + dstPrefixLen := len(dst) + // Allocate a new slice that can fit the full encrypted box if the current dst doesn't fit + if encLen := c.EncryptedLen(len(plaintext) + padLen); cap(dst)-len(dst) < encLen { + newDst := make([]byte, len(dst), len(dst)+encLen) + copy(newDst, dst) + dst = newDst + } dh1 := c.Cipher.DH(ephKey.Private, c.ReceiverKey.Public) dh2 := c.Cipher.DH(c.SenderKey.Private, c.ReceiverKey.Public) @@ -100,8 +107,13 @@ func (c *Crypter) Encrypt(dst []byte, ephKey *Key, plaintext []byte, padLen int) cc1 := c.Cipher.NewCipher(cv1) cc2 := c.Cipher.NewCipher(c.ChainVar) - header := cc1.Encrypt(ephKey.Public, ephKey.Public, c.SenderKey.Public) - return noiseBody(cc2, header, padLen, plaintext, header), nil + dst = append(dst, ephKey.Public...) + dst = cc1.Encrypt(dst, ephKey.Public, c.SenderKey.Public) + return noiseBody(cc2, dst, padLen, plaintext, dst[dstPrefixLen:]), nil +} + +func (c *Crypter) EncryptedLen(n int) int { + return n + (2 * c.Cipher.DHLen()) + (2 * c.Cipher.MACLen()) + 4 } func (c *Crypter) Decrypt(ciphertext []byte) ([]byte, error) {