package gost34112012
import (
+ "bytes"
"encoding/binary"
+ "errors"
)
const (
BlockSize = 64
+
+ MarshaledName = "STREEBOG"
)
var (
}
return r
}
+
+func (h *Hash) MarshalBinary() (data []byte, err error) {
+ data = make([]byte, len(MarshaledName)+1+8+3*BlockSize+len(h.buf))
+ copy(data, []byte(MarshaledName))
+ idx := len(MarshaledName)
+ data[idx] = byte(h.size)
+ idx += 1
+ binary.BigEndian.PutUint64(data[idx:idx+8], h.n)
+ idx += 8
+ copy(data[idx:], h.hsh[:])
+ idx += BlockSize
+ copy(data[idx:], h.chk[:])
+ idx += BlockSize
+ copy(data[idx:], h.tmp[:])
+ idx += BlockSize
+ copy(data[idx:], h.buf)
+ return
+}
+
+func (h *Hash) UnmarshalBinary(data []byte) error {
+ if len(data) < len(MarshaledName)+1+8+3*BlockSize {
+ return errors.New("too short data")
+ }
+ if !bytes.HasPrefix(data, []byte(MarshaledName)) {
+ return errors.New("no hash name prefix")
+ }
+ idx := len(MarshaledName)
+ h.size = int(data[idx])
+ idx += 1
+ h.n = binary.BigEndian.Uint64(data[idx : idx+8])
+ idx += 8
+ copy(h.hsh[:], data[idx:])
+ idx += BlockSize
+ copy(h.chk[:], data[idx:])
+ idx += BlockSize
+ copy(h.tmp[:], data[idx:])
+ idx += BlockSize
+ h.buf = data[idx:]
+ return nil
+}
import (
"bytes"
"crypto/rand"
+ "encoding"
"hash"
"testing"
"testing/quick"
func TestHashInterface(t *testing.T) {
h := New(64)
var _ hash.Hash = h
+ var _ encoding.BinaryMarshaler = h
+ var _ encoding.BinaryUnmarshaler = h
}
func TestVectors(t *testing.T) {
h.Reset()
h.Write(data)
d1 := h.Sum(nil)
+ h1Raw, err := h.MarshalBinary()
+ if err != nil {
+ return false
+ }
h.Reset()
for _, c := range data {
h.Write([]byte{c})
}
d2 := h.Sum(nil)
- return bytes.Compare(d1, d2) == 0
+ if bytes.Compare(d1, d2) != 0 {
+ return false
+ }
+ h2Raw, err := h.MarshalBinary()
+ if err != nil {
+ return false
+ }
+ if bytes.Compare(h1Raw, h2Raw) != 0 {
+ return false
+ }
+ hNew := New(64)
+ if err = hNew.UnmarshalBinary(h1Raw); err != nil {
+ return false
+ }
+ return bytes.Compare(hNew.Sum(nil), d1) == 0
}
if err := quick.Check(f, nil); err != nil {
t.Error(err)