brontide: use a fixed size buffer for the nonce within the brontide machine

In this commit, we use a fixed sized buffer for the nonce when we
read/write messages. This was actually escaping to the heap. We can
avoid this by statically allocating it alongside the struct itself.

The benchmark state at this point:

```
goos: darwin
goarch: arm64
pkg: github.com/lightningnetwork/lnd/brontide
cpu: Apple M4 Max
BenchmarkWriteMessage-16    	   25264	     47012 ns/op	       4 B/op	       1 allocs/op
BenchmarkWriteMessage-16    	   23542	     46809 ns/op	       4 B/op	       1 allocs/op
BenchmarkWriteMessage-16    	   25989	     47256 ns/op	       4 B/op	       1 allocs/op
BenchmarkWriteMessage-16    	   25542	     46388 ns/op	       4 B/op	       1 allocs/op
BenchmarkWriteMessage-16    	   26083	     46612 ns/op	       4 B/op	       1 allocs/op
BenchmarkWriteMessage-16    	   25860	     46367 ns/op	       4 B/op	       1 allocs/op
BenchmarkWriteMessage-16    	   24967	     46748 ns/op	       4 B/op	       1 allocs/op
BenchmarkWriteMessage-16    	   26088	     46485 ns/op	       4 B/op	       1 allocs/op
BenchmarkWriteMessage-16    	   25561	     46425 ns/op	       4 B/op	       1 allocs/op
BenchmarkWriteMessage-16    	   25474	     47249 ns/op	       4 B/op	       1 allocs/op
PASS
ok  	github.com/lightningnetwork/lnd/brontide	16.911s
```

```
goos: darwin
goarch: arm64
pkg: github.com/lightningnetwork/lnd/brontide
cpu: Apple M4 Max
                │   old.txt   │              new2.txt              │
                │   sec/op    │   sec/op     vs base               │
WriteMessage-16   50.34µ ± 1%   46.68µ ± 1%  -7.28% (p=0.000 n=10)

                │    old.txt     │              new2.txt              │
                │      B/op      │    B/op     vs base                │
WriteMessage-16   73788.000 ± 0%   4.000 ± 0%  -99.99% (p=0.000 n=10)

                │  old.txt   │              new2.txt              │
                │ allocs/op  │ allocs/op   vs base                │
WriteMessage-16   5.000 ± 0%   1.000 ± 0%  -80.00% (p=0.000 n=10)
```
This commit is contained in:
Olaoluwa Osuntokun
2025-08-30 14:48:15 +01:00
parent 06826f85d8
commit 1fe156f2f4

View File

@@ -91,6 +91,9 @@ type cipherState struct {
// TODO(roasbeef): this should actually be 96 bit
nonce uint64
// nonceBuffer is a reusable buffer for the nonce to avoid allocations.
nonceBuffer [12]byte
// secretKey is the shared symmetric key which will be used to
// instantiate the cipher.
//
@@ -117,10 +120,12 @@ func (c *cipherState) Encrypt(associatedData, cipherText, plainText []byte) []by
}
}()
var nonce [12]byte
binary.LittleEndian.PutUint64(nonce[4:], c.nonce)
// Write the nonce counter to the buffer (bytes 4-11).
binary.LittleEndian.PutUint64(c.nonceBuffer[4:], c.nonce)
return c.cipher.Seal(cipherText, nonce[:], plainText, associatedData)
return c.cipher.Seal(
cipherText, c.nonceBuffer[:], plainText, associatedData,
)
}
// Decrypt attempts to decrypt the passed ciphertext observing the specified
@@ -135,10 +140,12 @@ func (c *cipherState) Decrypt(associatedData, plainText, cipherText []byte) ([]b
}
}()
var nonce [12]byte
binary.LittleEndian.PutUint64(nonce[4:], c.nonce)
// Write the nonce counter to the buffer (bytes 4-11).
binary.LittleEndian.PutUint64(c.nonceBuffer[4:], c.nonce)
return c.cipher.Open(plainText, nonce[:], cipherText, associatedData)
return c.cipher.Open(
plainText, c.nonceBuffer[:], cipherText, associatedData,
)
}
// InitializeKey initializes the secret key and AEAD cipher scheme based off of