From 4b11f50264c54a4d6b0e321ea6068ac1455a8009 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Fri, 21 Jun 2019 23:10:08 +0300 Subject: [PATCH] Fix error in AVX2 implementation --- tz/hash.go | 22 +++++++++++++++------- tz/hash_avx2.go | 10 +++++----- tz/hash_test.go | 6 +++++- tz/tzbits_amd64.s | 4 ++-- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/tz/hash.go b/tz/hash.go index 4d9b65f..018466f 100644 --- a/tz/hash.go +++ b/tz/hash.go @@ -47,11 +47,10 @@ func (d *digest) checkSum() [hashSize]byte { } func (d *digest) byteArray() (b [hashSize]byte) { - var t []byte - for i := 0; i < 4; i++ { - t = d.x[i].ByteArray() - copy(b[i*16:], t) - } + copy(b[:], d.x[0].ByteArray()) + copy(b[16:], d.x[1].ByteArray()) + copy(b[32:], d.x[2].ByteArray()) + copy(b[48:], d.x[3].ByteArray()) return } @@ -85,14 +84,23 @@ func (d *digest) BlockSize() int { return hashBlockSize } -// Sum returnz Tillich-Zémor checksum of data -func Sum(data []byte) [hashSize]byte { +// Sum returnz Tillich-Zémor checksum of data. +// It uses only AVX instructions (no AVX2). +func SumAVX(data []byte) [hashSize]byte { d := new(digest) d.Reset() _, _ = d.Write(data) // no errors return d.checkSum() } +// Sum returns Tillich-Zémor checksum of data. +func Sum(data []byte) [hashSize]byte { + d := new(digest2) + d.Reset() + _, _ = d.Write(data) // no errors + return d.checkSum() +} + // Concat performs combining of hashes based on homomorphic property. func Concat(hs [][]byte) ([]byte, error) { var b, c sl2 diff --git a/tz/hash_avx2.go b/tz/hash_avx2.go index 3acfb56..c64a682 100644 --- a/tz/hash_avx2.go +++ b/tz/hash_avx2.go @@ -35,7 +35,7 @@ func (d *digest2) Sum(in []byte) []byte { } func (d *digest2) Reset() { d.x[0] = gf127.GF127x2{1, 0, 0, 0} - d.x[1] = gf127.GF127x2{0, 0, 0, 1} + d.x[1] = gf127.GF127x2{0, 0, 1, 0} } func (d *digest2) Size() int { return hashSize } func (d *digest2) BlockSize() int { return hashBlockSize } @@ -43,12 +43,12 @@ func (d *digest2) checkSum() (b [hashSize]byte) { // Matrix is stored transposed, // but we need to use order consistent with digest. h := d.x[0].ByteArray() - copy(b[:], h[:8]) - copy(b[16:], h[8:]) + copy(b[:], h[:16]) + copy(b[32:], h[16:]) h = d.x[1].ByteArray() - copy(b[8:], h[:8]) - copy(b[24:], h[8:]) + copy(b[16:], h[:16]) + copy(b[48:], h[16:]) return } diff --git a/tz/hash_test.go b/tz/hash_test.go index 222f363..c79dcc5 100644 --- a/tz/hash_test.go +++ b/tz/hash_test.go @@ -15,6 +15,10 @@ var testCases = []struct { input []byte hash string }{ + { + []byte{}, + "00000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + }, { []byte{0, 1, 2, 3, 4, 5, 6, 7, 8}, "00000000000001e4a545e5b90fb6882b00000000000000c849cd88f79307f67100000000000000cd0c898cb68356e624000000000000007cbcdc7c5e89b16e4b", @@ -40,7 +44,7 @@ func TestHash(t *testing.T) { }) t.Run("test AVX2 digest", func(t *testing.T) { - d := new(digest) + d := new(digest2) for _, tc := range testCases { d.Reset() _, _ = d.Write(tc.input) diff --git a/tz/tzbits_amd64.s b/tz/tzbits_amd64.s index ecd170c..063a154 100644 --- a/tz/tzbits_amd64.s +++ b/tz/tzbits_amd64.s @@ -64,9 +64,9 @@ TEXT ·mulBitRight(SB),NOSPLIT,$0 // func mulBitRightx2(c00c10, c01c11 *[4]uint64, e *[2]uint64) TEXT ·mulBitRightx2(SB),NOSPLIT,$0 - MOVQ c00c01+0(FP), AX + MOVQ c00c10+0(FP), AX VMOVDQA (AX), Y0 - MOVQ c10c11+8(FP), BX + MOVQ c01c11+8(FP), BX VMOVDQA (BX), Y8 VPSLLQ $1, Y0, Y1