gmsm/sm3/sm3_test.go

275 lines
11 KiB
Go
Raw Normal View History

2022-01-21 11:24:10 +08:00
package sm3
import (
"bytes"
"crypto/sha256"
"encoding"
"encoding/base64"
"fmt"
"hash"
"io"
"testing"
"golang.org/x/sys/cpu"
)
type sm3Test struct {
out string
in string
halfState string // marshaled hash state after first half of in written, used by TestGoldenMarshal
}
var golden = []sm3Test{
{"66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", "abc", "sm3\x03s\x80\x16oI\x14\xb2\xb9\x17$B\xd7ڊ\x06\x00\xa9o0\xbc\x1618\xaa\xe3\x8d\xeeM\xb0\xfb\x0eNa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
{"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", "sm3\x03s\x80\x16oI\x14\xb2\xb9\x17$B\xd7ڊ\x06\x00\xa9o0\xbc\x1618\xaa\xe3\x8d\xeeM\xb0\xfb\x0eNabcdabcdabcdabcdabcdabcdabcdabcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 "},
{"952eb84cacee9c10bde4d6882d29d63140ba72af6fe485085095dccd5b872453", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabc", "sm3\x03s\x80\x16oI\x14\xb2\xb9\x17$B\xd7ڊ\x06\x00\xa9o0\xbc\x1618\xaa\xe3\x8d\xeeM\xb0\xfb\x0eNabcdabcdabcdabcdabcdabcdabcdabcda\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!"},
{"90d52a2e85631a8d6035262626941fa11b85ce570cec1e3e991e2dd7ed258148", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", "sm3\x03YPށF\x86d\xebB\xfdL\x86\x1e|\xa0\n\xc0\xa5\x91\v\xae\x9aU\xea\x1aۍ\x17v<\xa2\"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@"},
{"e1c53f367a9c5d19ab6ddd30248a7dafcc607e74e6bcfa52b00e0ba35e470421", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabc", "sm3\x03YPށF\x86d\xebB\xfdL\x86\x1e|\xa0\n\xc0\xa5\x91\v\xae\x9aU\xea\x1aۍ\x17v<\xa2\"a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A"},
}
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
h := Sum([]byte(g.in))
s := fmt.Sprintf("%x", h)
fmt.Printf("%s\n", base64.StdEncoding.EncodeToString(h[:]))
if s != g.out {
t.Fatalf("SM3 function: sm3(%s) = %s want %s", g.in, s, g.out)
}
c := New()
for j := 0; j < 3; j++ {
if j < 2 {
io.WriteString(c, g.in)
} else {
io.WriteString(c, g.in[0:len(g.in)/2])
c.Sum(nil)
io.WriteString(c, g.in[len(g.in)/2:])
}
s := fmt.Sprintf("%x", c.Sum(nil))
if s != g.out {
t.Fatalf("sm3[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
}
}
func TestGoldenMarshal(t *testing.T) {
tests := []struct {
name string
newHash func() hash.Hash
gold []sm3Test
}{
{"", New, golden},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for _, g := range tt.gold {
h := tt.newHash()
h2 := tt.newHash()
io.WriteString(h, g.in[:len(g.in)/2])
state, err := h.(encoding.BinaryMarshaler).MarshalBinary()
if err != nil {
t.Errorf("could not marshal: %v", err)
continue
}
if string(state) != g.halfState {
t.Errorf("sm3%s(%q) state = %q, want %q", tt.name, g.in, state, g.halfState)
continue
}
if err := h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(state); err != nil {
t.Errorf("could not unmarshal: %v", err)
continue
}
io.WriteString(h, g.in[len(g.in)/2:])
io.WriteString(h2, g.in[len(g.in)/2:])
if actual, actual2 := h.Sum(nil), h2.Sum(nil); !bytes.Equal(actual, actual2) {
t.Errorf("sm3%s(%q) = 0x%x != marshaled 0x%x", tt.name, g.in, actual, actual2)
}
}
})
}
}
func TestSize(t *testing.T) {
c := New()
if got := c.Size(); got != Size {
t.Errorf("Size = %d; want %d", got, Size)
}
}
func TestBlockSize(t *testing.T) {
c := New()
if got := c.BlockSize(); got != BlockSize {
t.Errorf("BlockSize = %d want %d", got, BlockSize)
}
fmt.Printf("ARM64 has sm3 %v, has sm4 %v, has aes %v\n", cpu.ARM64.HasSM3, cpu.ARM64.HasSM4, cpu.ARM64.HasAES)
}
var bench = New()
var benchSH256 = sha256.New()
var buf = make([]byte, 8192)
func benchmarkSize(hash hash.Hash, b *testing.B, size int) {
b.SetBytes(int64(size))
sum := make([]byte, bench.Size())
for i := 0; i < b.N; i++ {
hash.Reset()
hash.Write(buf[:size])
hash.Sum(sum[:0])
}
}
func BenchmarkHash8Bytes(b *testing.B) {
benchmarkSize(bench, b, 8)
}
func BenchmarkHash1K(b *testing.B) {
benchmarkSize(bench, b, 1024)
}
func BenchmarkHash8K(b *testing.B) {
benchmarkSize(bench, b, 8192)
}
func BenchmarkHash8K_SH256(b *testing.B) {
benchmarkSize(benchSH256, b, 8192)
}
2023-06-20 17:51:14 +08:00
/*
func round1(a, b, c, d, e, f, g, h string, i int) {
fmt.Printf("//Round %d\n", i+1)
fmt.Printf("tt2 = bits.RotateLeft32(%s, 12)\n", a)
fmt.Printf("ss1 = bits.RotateLeft32(tt2+%s+_K[%d], 7)\n", e, i)
fmt.Printf("%s = %s ^ %s ^ %s + %s + (ss1 ^ tt2) + (w[%d] ^ w[%d])\n", d, a, b, c, d, i, i+4)
fmt.Printf("tt2 = %s ^ %s ^ %s + %s + ss1 + w[%d]\n", e, f, g, h, i)
fmt.Printf("%s = bits.RotateLeft32(%s, 9)\n", b, b)
fmt.Printf("%s = bits.RotateLeft32(%s, 19)\n", f, f)
fmt.Printf("%s = tt2 ^ bits.RotateLeft32(tt2, 9) ^ bits.RotateLeft32(tt2, 17)\n\n", h)
}
func round2(a, b, c, d, e, f, g, h string, i int) {
fmt.Printf("//Round %d\n", i+1)
fmt.Printf("w[%d] = p1(w[%d]^w[%d]^bits.RotateLeft32(w[%d], 15)) ^ bits.RotateLeft32(w[%d], 7) ^ w[%d]\n", i+4, i-12, i-5, i+1, i-9, i-2)
fmt.Printf("tt2 = bits.RotateLeft32(%s, 12)\n", a)
fmt.Printf("ss1 = bits.RotateLeft32(tt2+%s+_K[%d], 7)\n", e, i)
fmt.Printf("%s = %s ^ %s ^ %s + %s + (ss1 ^ tt2) + (w[%d] ^ w[%d])\n", d, a, b, c, d, i, i+4)
fmt.Printf("tt2 = %s ^ %s ^ %s + %s + ss1 + w[%d]\n", e, f, g, h, i)
fmt.Printf("%s = bits.RotateLeft32(%s, 9)\n", b, b)
fmt.Printf("%s = bits.RotateLeft32(%s, 19)\n", f, f)
fmt.Printf("%s = tt2 ^ bits.RotateLeft32(tt2, 9) ^ bits.RotateLeft32(tt2, 17)\n\n", h)
}
func round3(a, b, c, d, e, f, g, h string, i int) {
fmt.Printf("//Round %d\n", i+1)
fmt.Printf("w[%d] = p1(w[%d]^w[%d]^bits.RotateLeft32(w[%d], 15)) ^ bits.RotateLeft32(w[%d], 7) ^ w[%d]\n", i+4, i-12, i-5, i+1, i-9, i-2)
fmt.Printf("tt2 = bits.RotateLeft32(%s, 12)\n", a)
fmt.Printf("ss1 = bits.RotateLeft32(tt2+%s+_K[%d], 7)\n", e, i)
fmt.Printf("%s = (%s & %s) | (%s & %s) | (%s & %s) + %s + (ss1 ^ tt2) + (w[%d] ^ w[%d])\n", d, a, b, a, c, b, c, d, i, i+4)
fmt.Printf("tt2 = (%s & %s) | (^%s & %s) + %s + ss1 + w[%d]\n", e, f, e, g, h, i)
fmt.Printf("%s = bits.RotateLeft32(%s, 9)\n", b, b)
fmt.Printf("%s = bits.RotateLeft32(%s, 19)\n", f, f)
fmt.Printf("%s = tt2 ^ bits.RotateLeft32(tt2, 9) ^ bits.RotateLeft32(tt2, 17)\n\n", h)
}
func TestGenerateBlock(t *testing.T) {
round1("a", "b", "c", "d", "e", "f", "g", "h", 0)
round1("d", "a", "b", "c", "h", "e", "f", "g", 1)
round1("c", "d", "a", "b", "g", "h", "e", "f", 2)
round1("b", "c", "d", "a", "f", "g", "h", "e", 3)
round1("a", "b", "c", "d", "e", "f", "g", "h", 4)
round1("d", "a", "b", "c", "h", "e", "f", "g", 5)
round1("c", "d", "a", "b", "g", "h", "e", "f", 6)
round1("b", "c", "d", "a", "f", "g", "h", "e", 7)
round1("a", "b", "c", "d", "e", "f", "g", "h", 8)
round1("d", "a", "b", "c", "h", "e", "f", "g", 9)
round1("c", "d", "a", "b", "g", "h", "e", "f", 10)
round1("b", "c", "d", "a", "f", "g", "h", "e", 11)
round2("a", "b", "c", "d", "e", "f", "g", "h", 12)
round2("d", "a", "b", "c", "h", "e", "f", "g", 13)
round2("c", "d", "a", "b", "g", "h", "e", "f", 14)
round2("b", "c", "d", "a", "f", "g", "h", "e", 15)
round3("a", "b", "c", "d", "e", "f", "g", "h", 16)
round3("d", "a", "b", "c", "h", "e", "f", "g", 17)
round3("c", "d", "a", "b", "g", "h", "e", "f", 18)
round3("b", "c", "d", "a", "f", "g", "h", "e", 19)
round3("a", "b", "c", "d", "e", "f", "g", "h", 20)
round3("d", "a", "b", "c", "h", "e", "f", "g", 21)
round3("c", "d", "a", "b", "g", "h", "e", "f", 22)
round3("b", "c", "d", "a", "f", "g", "h", "e", 23)
round3("a", "b", "c", "d", "e", "f", "g", "h", 24)
round3("d", "a", "b", "c", "h", "e", "f", "g", 25)
round3("c", "d", "a", "b", "g", "h", "e", "f", 26)
round3("b", "c", "d", "a", "f", "g", "h", "e", 27)
round3("a", "b", "c", "d", "e", "f", "g", "h", 28)
round3("d", "a", "b", "c", "h", "e", "f", "g", 29)
round3("c", "d", "a", "b", "g", "h", "e", "f", 30)
round3("b", "c", "d", "a", "f", "g", "h", "e", 31)
round3("a", "b", "c", "d", "e", "f", "g", "h", 32)
round3("d", "a", "b", "c", "h", "e", "f", "g", 33)
round3("c", "d", "a", "b", "g", "h", "e", "f", 34)
round3("b", "c", "d", "a", "f", "g", "h", "e", 35)
round3("a", "b", "c", "d", "e", "f", "g", "h", 36)
round3("d", "a", "b", "c", "h", "e", "f", "g", 37)
round3("c", "d", "a", "b", "g", "h", "e", "f", 38)
round3("b", "c", "d", "a", "f", "g", "h", "e", 39)
round3("a", "b", "c", "d", "e", "f", "g", "h", 40)
round3("d", "a", "b", "c", "h", "e", "f", "g", 41)
round3("c", "d", "a", "b", "g", "h", "e", "f", 42)
round3("b", "c", "d", "a", "f", "g", "h", "e", 43)
round3("a", "b", "c", "d", "e", "f", "g", "h", 44)
round3("d", "a", "b", "c", "h", "e", "f", "g", 45)
round3("c", "d", "a", "b", "g", "h", "e", "f", 46)
round3("b", "c", "d", "a", "f", "g", "h", "e", 47)
round3("a", "b", "c", "d", "e", "f", "g", "h", 48)
round3("d", "a", "b", "c", "h", "e", "f", "g", 49)
round3("c", "d", "a", "b", "g", "h", "e", "f", 50)
round3("b", "c", "d", "a", "f", "g", "h", "e", 51)
round3("a", "b", "c", "d", "e", "f", "g", "h", 52)
round3("d", "a", "b", "c", "h", "e", "f", "g", 53)
round3("c", "d", "a", "b", "g", "h", "e", "f", 54)
round3("b", "c", "d", "a", "f", "g", "h", "e", 55)
round3("a", "b", "c", "d", "e", "f", "g", "h", 56)
round3("d", "a", "b", "c", "h", "e", "f", "g", 57)
round3("c", "d", "a", "b", "g", "h", "e", "f", 58)
round3("b", "c", "d", "a", "f", "g", "h", "e", 59)
round3("a", "b", "c", "d", "e", "f", "g", "h", 60)
round3("d", "a", "b", "c", "h", "e", "f", "g", 61)
round3("c", "d", "a", "b", "g", "h", "e", "f", 62)
round3("b", "c", "d", "a", "f", "g", "h", "e", 63)
}
func TestGenerateT(t *testing.T) {
for i := 0; i < 16; i++ {
fmt.Printf("0x%x, ", bits.RotateLeft32(_T0, i))
}
fmt.Println()
for i := 16; i < 64; i++ {
fmt.Printf("0x%x, ", bits.RotateLeft32(_T1, i))
}
fmt.Println()
}
*/