gmsm/pkcs/internal/md2/md2_test.go

145 lines
4.9 KiB
Go

package md2
import (
"bytes"
"encoding"
"fmt"
"io"
"testing"
"github.com/emmansun/gmsm/internal/cryptotest"
)
type md2Test struct {
out string
in string
halfState string // marshaled hash state after first half of in written, used by TestGoldenMarshal
}
var golden = []md2Test{
{"8350e5a3e24c153df2275c9f80692773", "", "md2\x01\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"},
{"32ec01ec4a6dac72c0ab96fb34c0b5d1", "a", "md2\x01\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"},
{"da853b0d3f88d99b30283a69e6ded6bb", "abc", "md2\x01\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
{"ab4f496bfb2a530b219ff33031fe06b0", "message digest", "md2\x01\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\x00message\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a"},
{"4e8ddff3650292ab5a4108c3aa47940b", "abcdefghijklmnopqrstuvwxyz", "md2\x01\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\x00abcdefghijklm\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r"},
{"da33def2a42df13975352846c30338cd", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "md2\x01\xa3k\x01X\x1a\xe6\x01\xfc\xe9\x8eH\xb5>\x8b:\xf9ho\x8a\xb1\x8f\xe1\xaf\xe4\xc5\x02¨Xs\xbb\xf8QRSTUVWXYZabcde\x00\x00\x00\x00\x00\x00\x00\x00\x1f"},
{"d5976f79d83d3a0dc9806c3c66f3efd8", "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "md2\x01\x8d\xd7h\x84\x8b1\x19E\x92\xcfA\xd3\x00k\x83\xfa\xd1\xeb\xb3\\\xe8S\xac6:$j\x93\xe8=\x03\x8534567890\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00("},
}
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
s := fmt.Sprintf("%x", Sum([]byte(g.in)))
if s != g.out {
t.Fatalf("Sum function: md2(%s) = %s want %s", g.in, s, g.out)
}
c := New()
buf := make([]byte, len(g.in)+4)
for j := 0; j < 3+4; j++ {
if j < 2 {
io.WriteString(c, g.in)
} else if j == 2 {
io.WriteString(c, g.in[0:len(g.in)/2])
c.Sum(nil)
io.WriteString(c, g.in[len(g.in)/2:])
} else if j > 2 {
// test unaligned write
buf = buf[1:]
copy(buf, g.in)
c.Write(buf[:len(g.in)])
}
s := fmt.Sprintf("%x", c.Sum(nil))
if s != g.out {
t.Fatalf("md2[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
}
}
type binaryAppender interface {
// AppendBinary appends the binary representation of itself to the end of b
// (allocating a larger slice if necessary) and returns the updated slice.
//
// Implementations must not retain b, nor mutate any bytes within b[:len(b)].
AppendBinary(b []byte) ([]byte, error)
}
func TestGoldenMarshal(t *testing.T) {
for _, g := range golden {
h := New()
h2 := New()
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
}
stateAppend, err := h.(binaryAppender).AppendBinary(make([]byte, 4, 32))
if err != nil {
t.Errorf("could not marshal: %v", err)
continue
}
stateAppend = stateAppend[4:]
if string(state) != g.halfState {
t.Errorf("md2(%q) state = %q, want %q", g.in, state, g.halfState)
continue
}
if string(stateAppend) != g.halfState {
t.Errorf("md2(%q) stateAppend = %q, want %q", g.in, stateAppend, 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("md2(%q) = 0x%x != marshaled 0x%x", 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)
}
}
func TestMD2Hash(t *testing.T) {
t.Run("MD2", func(t *testing.T) {
cryptotest.TestHash(t, New)
})
}
func TestAllocations(t *testing.T) {
in := []byte("hello, world!")
out := make([]byte, 0, Size)
h := New()
n := int(testing.AllocsPerRun(10, func() {
h.Reset()
h.Write(in)
out = h.Sum(out[:0])
}))
if n > 0 {
t.Errorf("allocs = %d, want 0", n)
}
}