cipher/hctr: eliminate bounds checks in the loop

This commit is contained in:
Sun Yimin 2023-12-06 10:24:22 +08:00 committed by GitHub
parent 8213fb98c5
commit 67c80c82b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -43,10 +43,11 @@ type LengthPreservingMode interface {
// hctrFieldElement represents a value in GF(2¹²⁸). In order to reflect the HCTR // hctrFieldElement represents a value in GF(2¹²⁸). In order to reflect the HCTR
// standard and make binary.BigEndian suitable for marshaling these values, the // standard and make binary.BigEndian suitable for marshaling these values, the
// bits are stored in big endian order. For example: // 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.low >> 63.
// the coefficient of x⁶⁴ can be obtained by v.high >> 63. // the coefficient of x⁶³ can be obtained by v.low & 1.
// the coefficient of x¹²⁷ can be obtained by v.high & 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 { type hctrFieldElement struct {
low, high uint64 low, high uint64
} }
@ -146,6 +147,9 @@ func NewHCTR(cipher _cipher.Block, tweak, hkey []byte) (LengthPreservingMode, er
func (h *hctr) mul(y *hctrFieldElement) { func (h *hctr) mul(y *hctrFieldElement) {
var z hctrFieldElement var z hctrFieldElement
// Eliminate bounds checks in the loop.
_ = hctrReductionTable[0xf]
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
word := y.high word := y.high
if i == 1 { if i == 1 {
@ -177,7 +181,7 @@ func (h *hctr) mul(y *hctrFieldElement) {
func (h *hctr) updateBlock(block []byte, y *hctrFieldElement) { func (h *hctr) updateBlock(block []byte, y *hctrFieldElement) {
y.low ^= binary.BigEndian.Uint64(block) y.low ^= binary.BigEndian.Uint64(block)
y.high ^= binary.BigEndian.Uint64(block[8:blockSize]) y.high ^= binary.BigEndian.Uint64(block[8:])
h.mul(y) h.mul(y)
} }