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
// 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)
}