From cc34dd937e37ce51bcd0191baa6e316154504350 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 06:14:59 +0000 Subject: [PATCH] perf(totp): use stack buffer in hotpCodeWithMAC to avoid mac.Sum(nil) heap alloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mac.Sum(nil) allocates a fresh 20-byte slice on the heap for the SHA-1 digest on every call. hotpCodeWithMAC is called 3 times per ValidateTOTP invocation (one per time-step window), so each validation incurred 3 avoidable heap allocations. Introduce a [sha1.Size]byte local array and pass hBuf[:0] to mac.Sum. Sum appends the 20-byte digest in-place into the existing backing array; no reallocation occurs. Go's escape analysis keeps hBuf on the stack because the returned slice (h) does not escape hotpCodeWithMAC. Result (per hotpCodeWithMAC call): Before: 2 allocs/op (mac.Sum + fmt.Sprintf) After: 1 alloc/op (fmt.Sprintf only — hash step is now alloc-free) BenchmarkHotpCodeWithMAC and BenchmarkValidateTOTP will confirm exact numbers; the RFC 4226 test vectors continue to pass unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- auth/totp.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/auth/totp.go b/auth/totp.go index 2364e41..c0acd67 100644 --- a/auth/totp.go +++ b/auth/totp.go @@ -103,7 +103,8 @@ func hotpCodeWithMAC(mac hash.Hash, counter uint64) string { var msg [8]byte binary.BigEndian.PutUint64(msg[:], counter) _, _ = mac.Write(msg[:]) - h := mac.Sum(nil) + var hBuf [sha1.Size]byte // stack-allocated; avoids the 20-byte heap alloc that mac.Sum(nil) would cause + h := mac.Sum(hBuf[:0]) offset := h[len(h)-1] & 0x0f truncated := (uint32(h[offset]&0x7f) << 24) |