github.com/emmansun/gmsm@v0.29.1/sm3/sm3blocks_avx2_test.go (about)

     1  // Copyright 2024 Sun Yimin. All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build amd64 && !purego
     6  
     7  package sm3
     8  
     9  import (
    10  	"fmt"
    11  	"testing"
    12  )
    13  
    14  func initState8() [8]*[8]uint32 {
    15  	d := new(digest)
    16  	d.Reset()
    17  	var dig1 = d.h
    18  	var dig2 = d.h
    19  	var dig3 = d.h
    20  	var dig4 = d.h
    21  	var dig5 = d.h
    22  	var dig6 = d.h
    23  	var dig7 = d.h
    24  	return [8]*[8]uint32{&d.h, &dig1, &dig2, &dig3, &dig4, &dig5, &dig6, &dig7}
    25  }
    26  
    27  func createOneBlockBy8() [8]*byte {
    28  	var p1 [64]byte
    29  	p1[0] = 0x61
    30  	p1[1] = 0x62
    31  	p1[2] = 0x63
    32  	p1[3] = 0x80
    33  	p1[63] = 0x18
    34  	var p2 = p1
    35  	var p3 = p1
    36  	var p4 = p1
    37  	var p5 = p1
    38  	var p6 = p1
    39  	var p7 = p1
    40  	var p8 = p1
    41  	return [8]*byte{&p1[0], &p2[0], &p3[0], &p4[0], &p5[0], &p6[0], &p7[0], &p8[0]}
    42  }
    43  
    44  func createTwoBlocksBy8() [8]*byte {
    45  	var p1 [128]byte
    46  	p1[0] = 0x61
    47  	p1[1] = 0x62
    48  	p1[2] = 0x63
    49  	p1[3] = 0x64
    50  	copy(p1[4:], p1[:4])
    51  	copy(p1[8:], p1[:8])
    52  	copy(p1[16:], p1[:16])
    53  	copy(p1[32:], p1[:32])
    54  	p1[64] = 0x80
    55  	p1[126] = 0x02
    56  	var p2 = p1
    57  	var p3 = p1
    58  	var p4 = p1
    59  	var p5 = p1
    60  	var p6 = p1
    61  	var p7 = p1
    62  	var p8 = p1
    63  	return [8]*byte{&p1[0], &p2[0], &p3[0], &p4[0], &p5[0], &p6[0], &p7[0], &p8[0]}
    64  }
    65  
    66  func TestTransposeMatrix8x8(t *testing.T) {
    67  	if !useAVX2 {
    68  		t.Skip("AVX2 is not supported")
    69  	}
    70  	var m [8][8]uint32
    71  	for i := 0; i < 8; i++ {
    72  		for j := 0; j < 8; j++ {
    73  			m[i][j] = uint32(i*8 + j)
    74  		}
    75  	}
    76  	input := [8]*[8]uint32{&m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6], &m[7]}
    77  	transposeMatrix8x8(&input[0])
    78  	for i := 0; i < 8; i++ {
    79  		for j := 0; j < 8; j++ {
    80  			if m[j][i] != uint32(i*8+j) {
    81  				t.Errorf("m[%d][%d] got %d", i, j, m[j][i])
    82  			}
    83  		}
    84  	}
    85  	transposeMatrix8x8(&input[0])
    86  	for i := 0; i < 8; i++ {
    87  		for j := 0; j < 8; j++ {
    88  			if m[i][j] != uint32(i*8+j) {
    89  				t.Errorf("m[%d][%d] got %d", i, j, m[i][j])
    90  			}
    91  		}
    92  	}
    93  }
    94  
    95  func TestBlockMultBy8(t *testing.T) {
    96  	if !useAVX2 {
    97  		t.Skip("AVX2 is not supported")
    98  	}
    99  	digs := initState8()
   100  	p := createOneBlockBy8()
   101  	buffer := make([]byte, preallocSizeBy8)
   102  	blockMultBy8(&digs[0], &p[0], &buffer[0], 1)
   103  	expected := "[66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0]"
   104  	for i := 0; i < 8; i++ {
   105  		s := fmt.Sprintf("%x", digs[i][:])
   106  		if s != expected {
   107  			t.Errorf("digs[%d] got %s", i, s)
   108  		}
   109  	}
   110  
   111  	digs = initState8()
   112  	p = createTwoBlocksBy8()
   113  	blockMultBy8(&digs[0], &p[0], &buffer[0], 2)
   114  	expected = "[debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732]"
   115  	for i := 0; i < 8; i++ {
   116  		s := fmt.Sprintf("%x", digs[i][:])
   117  		if s != expected {
   118  			t.Errorf("digs[%d] got %s", i, s)
   119  		}
   120  	}
   121  }
   122  
   123  func BenchmarkOneBlockBy8(b *testing.B) {
   124  	if !useAVX2 {
   125  		b.Skip("AVX2 is not supported")
   126  	}
   127  	digs := initState8()
   128  	p := createOneBlockBy8()
   129  	buffer := make([]byte, preallocSizeBy8)
   130  	b.SetBytes(64 * 8)
   131  	b.ReportAllocs()
   132  	b.ResetTimer()
   133  	for i := 0; i < b.N; i++ {
   134  		blockMultBy8(&digs[0], &p[0], &buffer[0], 1)
   135  	}
   136  }
   137  
   138  func BenchmarkTwoBlocksBy8(b *testing.B) {
   139  	if !useAVX2 {
   140  		b.Skip("AVX2 is not supported")
   141  	}
   142  	digs := initState8()
   143  	p := createTwoBlocksBy8()
   144  	buffer := make([]byte, preallocSizeBy8)
   145  	b.SetBytes(64 * 2 * 8)
   146  	b.ReportAllocs()
   147  	b.ResetTimer()
   148  	for i := 0; i < b.N; i++ {
   149  		blockMultBy8(&digs[0], &p[0], &buffer[0], 2)
   150  	}
   151  }