// Copyright 2024 Sun Yimin. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. //go:build amd64 && !purego package sm3 import ( "fmt" "testing" ) func initState8() [8]*[8]uint32 { d := new(digest) d.Reset() var dig1 = d.h var dig2 = d.h var dig3 = d.h var dig4 = d.h var dig5 = d.h var dig6 = d.h var dig7 = d.h return [8]*[8]uint32{&d.h, &dig1, &dig2, &dig3, &dig4, &dig5, &dig6, &dig7} } func createOneBlockBy8() [8]*byte { var p1 [64]byte p1[0] = 0x61 p1[1] = 0x62 p1[2] = 0x63 p1[3] = 0x80 p1[63] = 0x18 var p2 = p1 var p3 = p1 var p4 = p1 var p5 = p1 var p6 = p1 var p7 = p1 var p8 = p1 return [8]*byte{&p1[0], &p2[0], &p3[0], &p4[0], &p5[0], &p6[0], &p7[0], &p8[0]} } func createTwoBlocksBy8() [8]*byte { var p1 [128]byte p1[0] = 0x61 p1[1] = 0x62 p1[2] = 0x63 p1[3] = 0x64 copy(p1[4:], p1[:4]) copy(p1[8:], p1[:8]) copy(p1[16:], p1[:16]) copy(p1[32:], p1[:32]) p1[64] = 0x80 p1[126] = 0x02 var p2 = p1 var p3 = p1 var p4 = p1 var p5 = p1 var p6 = p1 var p7 = p1 var p8 = p1 return [8]*byte{&p1[0], &p2[0], &p3[0], &p4[0], &p5[0], &p6[0], &p7[0], &p8[0]} } func TestTransposeMatrix8x8(t *testing.T) { if !useAVX2 { t.Skip("AVX2 is not supported") } var m [8][8]uint32 for i := 0; i < 8; i++ { for j := 0; j < 8; j++ { m[i][j] = uint32(i*8 + j) } } input := [8]*[8]uint32{&m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6], &m[7]} transposeMatrix8x8(&input[0]) for i := 0; i < 8; i++ { for j := 0; j < 8; j++ { if m[j][i] != uint32(i*8+j) { t.Errorf("m[%d][%d] got %d", i, j, m[j][i]) } } } transposeMatrix8x8(&input[0]) for i := 0; i < 8; i++ { for j := 0; j < 8; j++ { if m[i][j] != uint32(i*8+j) { t.Errorf("m[%d][%d] got %d", i, j, m[i][j]) } } } } func TestBlockMultBy8(t *testing.T) { if !useAVX2 { t.Skip("AVX2 is not supported") } digs := initState8() p := createOneBlockBy8() buffer := make([]byte, preallocSizeBy8) blockMultBy8(&digs[0], &p[0], &buffer[0], 1) expected := "[66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0]" for i := 0; i < 8; i++ { s := fmt.Sprintf("%x", digs[i][:]) if s != expected { t.Errorf("digs[%d] got %s", i, s) } } digs = initState8() p = createTwoBlocksBy8() blockMultBy8(&digs[0], &p[0], &buffer[0], 2) expected = "[debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732]" for i := 0; i < 8; i++ { s := fmt.Sprintf("%x", digs[i][:]) if s != expected { t.Errorf("digs[%d] got %s", i, s) } } } func BenchmarkOneBlockBy8(b *testing.B) { if !useAVX2 { b.Skip("AVX2 is not supported") } digs := initState8() p := createOneBlockBy8() buffer := make([]byte, preallocSizeBy8) b.SetBytes(64 * 8) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { blockMultBy8(&digs[0], &p[0], &buffer[0], 1) } } func BenchmarkTwoBlocksBy8(b *testing.B) { if !useAVX2 { b.Skip("AVX2 is not supported") } digs := initState8() p := createTwoBlocksBy8() buffer := make([]byte, preallocSizeBy8) b.SetBytes(64 * 2 * 8) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { blockMultBy8(&digs[0], &p[0], &buffer[0], 2) } }