From 67c80c82b4a6927ea69538537161e2a0bf513804 Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Wed, 6 Dec 2023 10:24:22 +0800 Subject: [PATCH] cipher/hctr: eliminate bounds checks in the loop --- cipher/hctr.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/cipher/hctr.go b/cipher/hctr.go index bbdc212f..ea41de64 100644 --- a/cipher/hctr.go +++ b/cipher/hctr.go @@ -43,10 +43,11 @@ type LengthPreservingMode interface { // hctrFieldElement represents a value in GF(2¹²⁸). In order to reflect the HCTR // standard and make binary.BigEndian suitable for marshaling these values, the // bits are stored in big endian order. For example: -// the coefficient of x⁰ can be obtained by v.low >> 63. -// the coefficient of x⁶³ can be obtained by v.low & 1. -// the coefficient of x⁶⁴ can be obtained by v.high >> 63. -// the coefficient of x¹²⁷ can be obtained by v.high & 1. +// +// the coefficient of x⁰ can be obtained by v.low >> 63. +// the coefficient of x⁶³ can be obtained by v.low & 1. +// the coefficient of x⁶⁴ can be obtained by v.high >> 63. +// the coefficient of x¹²⁷ can be obtained by v.high & 1. type hctrFieldElement struct { low, high uint64 } @@ -146,6 +147,9 @@ func NewHCTR(cipher _cipher.Block, tweak, hkey []byte) (LengthPreservingMode, er func (h *hctr) mul(y *hctrFieldElement) { var z hctrFieldElement + // Eliminate bounds checks in the loop. + _ = hctrReductionTable[0xf] + for i := 0; i < 2; i++ { word := y.high if i == 1 { @@ -177,7 +181,7 @@ func (h *hctr) mul(y *hctrFieldElement) { func (h *hctr) updateBlock(block []byte, y *hctrFieldElement) { y.low ^= binary.BigEndian.Uint64(block) - y.high ^= binary.BigEndian.Uint64(block[8:blockSize]) + y.high ^= binary.BigEndian.Uint64(block[8:]) h.mul(y) }