From 5ee379fc6e97ebe5b625518acab39e2dbe6bbf08 Mon Sep 17 00:00:00 2001 From: deatil <2217957370@qq.com> Date: Tue, 26 Mar 2024 17:09:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20echo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- echo/digest.go | 302 ++++++++++++++++++++++++++++++++++++++++++++ echo/echo.go | 311 +++++----------------------------------------- echo/echo_test.go | 186 +++++++++++++++++++++++++-- 3 files changed, 509 insertions(+), 290 deletions(-) create mode 100644 echo/digest.go diff --git a/echo/digest.go b/echo/digest.go new file mode 100644 index 0000000..a1e0d21 --- /dev/null +++ b/echo/digest.go @@ -0,0 +1,302 @@ +package echo + +import ( + "hash" + "errors" +) + +const ( + // hash size + Size224 = 28 + Size256 = 32 + Size384 = 48 + Size512 = 64 +) + +// digest represents the partial evaluation of a checksum. +type digest struct { + s [32]uint64 + x []byte + nx int + len uint64 + + hs, bs int + salt [2]uint64 +} + +// New returns a new hash.Hash computing the echo checksum +func New(hs int) (hash.Hash, error) { + return NewWithSalt(hs, nil) +} + +// New returns a new hash.Hash computing the echo checksum +func NewWithSalt(hashsize int, salt []byte) (hash.Hash, error) { + if hashsize == 0 { + return nil, errors.New("go-hash/echo: hash size can't be zero") + } + if (hashsize % 8) > 0 { + return nil, errors.New("go-hash/echo: non-byte hash sizes are not supported") + } + if hashsize > 512 { + return nil, errors.New("go-hash/echo: invalid hash size") + } + + d := new(digest) + d.hs = hashsize + d.Reset() + + if len(salt) > 0 { + if len(salt) != 16 { + return nil, errors.New("go-hash/echo: invalid salt length") + } + + s := bytesToUint64s(salt) + copy(d.salt[:], s) + } else { + d.salt = [2]uint64{} + } + + return d, nil +} + +func (d *digest) Reset() { + if d.hs > 256 { + d.bs = 1024 + } else { + d.bs = 1536 + } + + // m + d.x = make([]byte, d.bs / 8) + + // h + d.s = [32]uint64{} + + var r int + if d.hs > 256 { + r = 8 + } else { + r = 4 + } + + var i int + for i = 0; i < r; i++ { + d.s[2 * i] = uint64(d.hs) + d.s[2 * i + 1] = 0 + } + + d.nx = 0 + d.len = 0 +} + +func (d *digest) Size() int { + return d.hs / 8 +} + +func (d *digest) BlockSize() int { + return d.bs / 8 +} + +func (d *digest) Write(p []byte) (nn int, err error) { + nn = len(p) + + plen := len(p) + + var limit = d.bs / 8 + for d.nx + plen >= limit { + xx := limit - d.nx + + copy(d.x[d.nx:], p) + + d.transform(true, uint64(xx) * 8) + + plen -= xx + d.len += uint64(xx) * 8 + + p = p[xx:] + d.nx = 0 + } + + copy(d.x[d.nx:], p) + d.nx += plen + d.len += uint64(plen) * 8 + + return +} + +func (d *digest) Sum(in []byte) []byte { + // Make a copy of d so that caller can keep writing and summing. + d0 := *d + hash := d0.checkSum() + return append(in, hash...) +} + +func (d *digest) checkSum() []byte { + d.x[d.nx] = 0x80 + d.nx++ + + var limit = d.bs / 8 + + zeros := make([]byte, limit) + + if d.nx > limit - 18 { + copy(d.x[d.nx:], zeros) + d.transform(true, 0) + d.nx = 0 + } + + copy(d.x[d.nx:], zeros) + + var hsize = uint16(d.hs) + + PUTU16(d.x[limit - 18:], hsize) + PUTU64(d.x[limit - 16:], d.len) + copy(d.x[limit - 8:], zeros) + + if d.nx > 1 { + d.transform(true, 0) + } else { + d.transform(false, 0) + } + + ss := uint64sToBytes(d.s[:]) + return ss[:d.hs / 8] +} + +func (d *digest) transform(addedbits bool, addtototal uint64) { + var counter uint64 = 0 + if addedbits { + counter = d.len + addtototal + } + + xx := bytesToUint64s(d.x) + copy(d.s[32-len(xx):], xx) + + var w [32]uint64 + copy(w[:], d.s[:]) + + var rounds int + if d.hs > 256 { + rounds = 10 + } else { + rounds = 8 + } + + const firstbits uint64 = 0xfefefefefefefefe + const lastbit uint64 = 0x0101010101010101 + + var l, r, i, j int + for l = 0; l < rounds; l++ { + for r = 0; r < 16; r++ { + var idx int = r * 2 + var idx1 int = r * 2 + 1 + + var t0 uint32 = uint32(counter) ^ + T[0][byte(w[idx])] ^ + T[1][byte(w[idx] >> 40)] ^ + T[2][byte(w[idx1] >> 16)] ^ + T[3][byte(w[idx1] >> 56)] + var t1 uint32 = uint32(counter >> 32) ^ + T[0][byte(w[idx] >> 32)] ^ + T[1][byte(w[idx1] >> 8)] ^ + T[2][byte(w[idx1] >> 48)] ^ + T[3][byte(w[idx] >> 24)] + var t2 uint32 = T[0][byte(w[idx1])] ^ + T[1][byte(w[idx1] >> 40)] ^ + T[2][byte(w[idx] >> 16)] ^ + T[3][byte(w[idx] >> 56)] + var t3 uint32 = T[0][byte(w[idx1] >> 32)] ^ + T[1][byte(w[idx] >> 8)] ^ + T[2][byte(w[idx] >> 48)] ^ + T[3][byte(w[idx1] >> 24)] + + counter++ + + w[idx] = uint64(T[0][byte(t0)] ^ + T[1][byte(t1 >> 8)] ^ + T[2][byte(t2 >> 16)] ^ + T[3][byte(t3 >> 24)]) ^ + (uint64(T[0][byte(t1)] ^ + T[1][byte(t2 >> 8)] ^ + T[2][byte(t3 >> 16)] ^ + T[3][byte(t0 >> 24)]) << 32) ^ + d.salt[0] + w[idx + 1] = uint64(T[0][byte(t2)] ^ + T[1][byte(t3 >> 8)] ^ + T[2][byte(t0 >> 16)] ^ + T[3][byte(t1 >> 24)]) ^ + (uint64(T[0][byte(t3)] ^ + T[1][byte(t0 >> 8)] ^ + T[2][byte(t1 >> 16)] ^ + T[3][byte(t2 >> 24)]) << 32) ^ + d.salt[1] + } + + w[2], w[10] = w[10], w[2] + w[3], w[11] = w[11], w[3] + w[4], w[20] = w[20], w[4] + w[5], w[21] = w[21], w[5] + w[6], w[30] = w[30], w[6] + w[7], w[31] = w[31], w[7] + w[12], w[28] = w[28], w[12] + w[13], w[29] = w[29], w[13] + w[22], w[14] = w[14], w[22] + w[23], w[15] = w[15], w[23] + w[30], w[14] = w[14], w[30] + w[31], w[15] = w[15], w[31] + w[26], w[18] = w[18], w[26] + w[27], w[19] = w[19], w[27] + w[26], w[10] = w[10], w[26] + w[27], w[11] = w[11], w[27] + + for i = 0; i < 4; i++ { + for j = 0; j < 2; j++ { + var idx int = i * 4 * 2 + j + var a uint64 = w[idx] + var b uint64 = w[idx + 2] + var c uint64 = w[idx + 4] + var d uint64 = w[idx + 6] + + var dblA uint64 = ((a << 1) & firstbits) ^ (((a >> 7) & lastbit) * 0x1b) + var dblB uint64 = ((b << 1) & firstbits) ^ (((b >> 7) & lastbit) * 0x1b) + var dblC uint64 = ((c << 1) & firstbits) ^ (((c >> 7) & lastbit) * 0x1b) + var dblD uint64 = ((d << 1) & firstbits) ^ (((d >> 7) & lastbit) * 0x1b) + + w[idx] = dblA ^ dblB ^ b ^ c ^ d + w[idx + 2] = dblB ^ dblC ^ c ^ d ^ a + w[idx + 4] = dblC ^ dblD ^ d ^ a ^ b + w[idx + 6] = dblD ^ dblA ^ a ^ b ^ c + } + } + } + + h := &d.s + + if d.hs <= 256 { + h[0] = h[0] ^ h[8] ^ h[16] ^ h[24] ^ w[0] ^ w[8] ^ w[16] ^ w[24] + h[1] = h[1] ^ h[9] ^ h[17] ^ h[25] ^ w[1] ^ w[9] ^ w[17] ^ w[25] + h[2] = h[2] ^ h[10] ^ h[18] ^ h[26] ^ w[2] ^ w[10] ^ w[18] ^ w[26] + h[3] = h[3] ^ h[11] ^ h[19] ^ h[27] ^ w[3] ^ w[11] ^ w[19] ^ w[27] + h[4] = h[4] ^ h[12] ^ h[20] ^ h[28] ^ w[4] ^ w[12] ^ w[20] ^ w[28] + h[5] = h[5] ^ h[13] ^ h[21] ^ h[29] ^ w[5] ^ w[13] ^ w[21] ^ w[29] + h[6] = h[6] ^ h[14] ^ h[22] ^ h[30] ^ w[6] ^ w[14] ^ w[22] ^ w[30] + h[7] = h[7] ^ h[15] ^ h[23] ^ h[31] ^ w[7] ^ w[15] ^ w[23] ^ w[31] + } else { + h[0] = h[0] ^ h[16] ^ w[0] ^ w[16] + h[1] = h[1] ^ h[17] ^ w[1] ^ w[17] + h[2] = h[2] ^ h[18] ^ w[2] ^ w[18] + h[3] = h[3] ^ h[19] ^ w[3] ^ w[19] + h[4] = h[4] ^ h[20] ^ w[4] ^ w[20] + h[5] = h[5] ^ h[21] ^ w[5] ^ w[21] + h[6] = h[6] ^ h[22] ^ w[6] ^ w[22] + h[7] = h[7] ^ h[23] ^ w[7] ^ w[23] + h[8] = h[8] ^ h[24] ^ w[8] ^ w[24] + h[9] = h[9] ^ h[25] ^ w[9] ^ w[25] + h[10] = h[10] ^ h[26] ^ w[10] ^ w[26] + h[11] = h[11] ^ h[27] ^ w[11] ^ w[27] + h[12] = h[12] ^ h[28] ^ w[12] ^ w[28] + h[13] = h[13] ^ h[29] ^ w[13] ^ w[29] + h[14] = h[14] ^ h[30] ^ w[14] ^ w[30] + h[15] = h[15] ^ h[31] ^ w[15] ^ w[31] + } +} diff --git a/echo/echo.go b/echo/echo.go index 8d939d7..891c82f 100644 --- a/echo/echo.go +++ b/echo/echo.go @@ -2,313 +2,64 @@ package echo import ( "hash" - "errors" ) // New224 returns a new hash.Hash computing the echo checksum func New224() (hash.Hash, error) { - return NewWithSalt(224, nil) + return New(224) } // New256 returns a new hash.Hash computing the echo checksum func New256() (hash.Hash, error) { - return NewWithSalt(256, nil) + return New(256) } // New384 returns a new hash.Hash computing the echo checksum func New384() (hash.Hash, error) { - return NewWithSalt(384, nil) + return New(384) } // New512 returns a new hash.Hash computing the echo checksum func New512() (hash.Hash, error) { - return NewWithSalt(512, nil) + return New(512) } -// digest represents the partial evaluation of a checksum. -type digest struct { - s [32]uint64 - x []byte - nx int - len uint64 +// Sum224 returns the ECHO-224 checksum of the data. +func Sum224(data []byte) (sum224 [Size224]byte) { + h, _ := New224() + h.Write(data) + sum := h.Sum(nil) - hs, bs int - salt [2]uint64 -} - -// New returns a new hash.Hash computing the echo checksum -func New(hs int) (hash.Hash, error) { - return NewWithSalt(hs, nil) -} - -// New returns a new hash.Hash computing the echo checksum -func NewWithSalt(hashsize int, salt []byte) (hash.Hash, error) { - if hashsize == 0 { - return nil, errors.New("go-hash/echo: hash size can't be zero") - } - if (hashsize % 8) > 0 { - return nil, errors.New("go-hash/echo: non-byte hash sizes are not supported") - } - if hashsize > 512 { - return nil, errors.New("go-hash/echo: invalid hash size") - } - - d := new(digest) - d.hs = hashsize - d.Reset() - - if len(salt) > 0 { - if len(salt) != 16 { - return nil, errors.New("go-hash/echo: invalid salt length") - } - - s := bytesToUint64s(salt) - copy(d.salt[:], s) - } else { - d.salt = [2]uint64{} - } - - return d, nil -} - -func (d *digest) Reset() { - if d.hs > 256 { - d.bs = 1024 - } else { - d.bs = 1536 - } - - // m - d.x = make([]byte, d.bs / 8) - - // h - d.s = [32]uint64{} - - var r int - if d.hs > 256 { - r = 8 - } else { - r = 4 - } - - var i int - for i = 0; i < r; i++ { - d.s[2 * i] = uint64(d.hs) - d.s[2 * i + 1] = 0 - } - - d.nx = 0 - d.len = 0 -} - -func (d *digest) Size() int { - return d.hs / 8 -} - -func (d *digest) BlockSize() int { - return d.bs / 8 + copy(sum224[:], sum[:Size224]) + return } -func (d *digest) Write(p []byte) (nn int, err error) { - nn = len(p) - - plen := len(p) - - var limit = d.bs / 8 - for d.nx + plen >= limit { - xx := limit - d.nx - - copy(d.x[d.nx:], p[:xx]) - - d.transform(true, uint64(xx) * 8) - - plen -= xx - d.len += uint64(xx) - - p = p[xx:] - d.nx = 0 - } - - copy(d.x[d.nx:], p[:plen]) - d.nx += plen - d.len += uint64(plen) +// Sum256 returns the ECHO-256 checksum of the data. +func Sum256(data []byte) (sum256 [Size256]byte) { + h, _ := New256() + h.Write(data) + sum := h.Sum(nil) + copy(sum256[:], sum[:Size256]) return } -func (d *digest) Sum(in []byte) []byte { - // Make a copy of d so that caller can keep writing and summing. - d0 := *d - hash := d0.checkSum() - return append(in, hash...) -} - -func (d *digest) checkSum() []byte { - d.x[d.nx] = 0x80 - d.nx++ - - var limit = d.bs / 8 - - zeros := make([]byte, limit) - - if d.nx > limit - 18 { - copy(d.x[d.nx:], zeros[:limit - d.nx]) - d.transform(true, 0) - d.nx = 0 - } - - copy(d.x[d.nx:], zeros[:limit - 18 - d.nx]) +// Sum384 returns the ECHO-384 checksum of the data. +func Sum384(data []byte) (sum384 [Size384]byte) { + h, _ := New384() + h.Write(data) + sum := h.Sum(nil) - var hsize = uint16(d.hs) - - PUTU16(d.x[limit - 18:], hsize) - PUTU64(d.x[limit - 16:], d.len * 8) - copy(d.x[limit - 8:], zeros) - - if d.nx > 1 { - d.transform(true, 0) - } else { - d.transform(false, 0) - } - - ss := uint64sToBytes(d.s[:]) - return ss[:d.hs / 8] + copy(sum384[:], sum[:Size384]) + return } -func (d *digest) transform(addedbits bool, addtototal uint64) { - var counter uint64 = 0 - if addedbits { - counter = d.len + addtototal - } - - xx := bytesToUint64s(d.x[:]) - copy(d.s[32-len(xx):], xx) - - var w [32]uint64 - copy(w[:], d.s[:]) +// Sum512 returns the ECHO-512 checksum of the data. +func Sum512(data []byte) (sum512 [Size512]byte) { + h, _ := New512() + h.Write(data) + sum := h.Sum(nil) - var rounds int - if d.hs > 256 { - rounds = 10 - } else { - rounds = 8 - } - - const firstbits uint64 = 0xfefefefefefefefe - const lastbit uint64 = 0x0101010101010101 - - var l, r, i, j int - for l = 0; l < rounds; l++ { - for r = 0; r < 16; r++ { - var idx int = r * 2 - var idx1 int = r * 2 + 1 - - var t0 uint32 = uint32(counter) ^ - T[0][byte(w[idx])] ^ - T[1][byte(w[idx] >> 40)] ^ - T[2][byte(w[idx1] >> 16)] ^ - T[3][byte(w[idx1] >> 56)] - var t1 uint32 = uint32(counter >> 32) ^ - T[0][byte(w[idx] >> 32)] ^ - T[1][byte(w[idx1] >> 8)] ^ - T[2][byte(w[idx1] >> 48)] ^ - T[3][byte(w[idx] >> 24)] - var t2 uint32 = T[0][byte(w[idx1])] ^ - T[1][byte(w[idx1] >> 40)] ^ - T[2][byte(w[idx] >> 16)] ^ - T[3][byte(w[idx] >> 56)] - var t3 uint32 = T[0][byte(w[idx1] >> 32)] ^ - T[1][byte(w[idx] >> 8)] ^ - T[2][byte(w[idx] >> 48)] ^ - T[3][byte(w[idx1] >> 24)] - - counter++ - - w[idx] = uint64(T[0][byte(t0)] ^ - T[1][byte(t1 >> 8)] ^ - T[2][byte(t2 >> 16)] ^ - T[3][byte(t3 >> 24)]) ^ - (uint64(T[0][byte(t1)] ^ - T[1][byte(t2 >> 8)] ^ - T[2][byte(t3 >> 16)] ^ - T[3][byte(t0 >> 24)]) << 32) ^ - d.salt[0] - w[idx + 1] = uint64(T[0][byte(t2)] ^ - T[1][byte(t3 >> 8)] ^ - T[2][byte(t0 >> 16)] ^ - T[3][byte(t1 >> 24)]) ^ - (uint64(T[0][byte(t3)] ^ - T[1][byte(t0 >> 8)] ^ - T[2][byte(t1 >> 16)] ^ - T[3][byte(t2 >> 24)]) << 32) ^ - d.salt[1] - } - - w[2], w[10] = w[10], w[2] - w[3], w[11] = w[11], w[3] - w[4], w[20] = w[20], w[4] - w[5], w[21] = w[21], w[5] - w[6], w[30] = w[30], w[6] - w[7], w[31] = w[31], w[7] - w[12], w[28] = w[28], w[12] - w[13], w[29] = w[29], w[13] - w[22], w[14] = w[14], w[22] - w[23], w[15] = w[15], w[23] - w[30], w[14] = w[14], w[30] - w[31], w[15] = w[15], w[31] - w[26], w[18] = w[18], w[26] - w[27], w[19] = w[19], w[27] - w[26], w[10] = w[10], w[26] - w[27], w[11] = w[11], w[27] - - for i = 0; i < 4; i++ { - for j = 0; j < 2; j++ { - var idx int = i * 4 * 2 + j - var a uint64 = w[idx] - var b uint64 = w[idx + 2] - var c uint64 = w[idx + 4] - var d uint64 = w[idx + 6] - - var dblA uint64 = ((a << 1) & firstbits) ^ (((a >> 7) & lastbit) * 0x1b) - var dblB uint64 = ((b << 1) & firstbits) ^ (((b >> 7) & lastbit) * 0x1b) - var dblC uint64 = ((c << 1) & firstbits) ^ (((c >> 7) & lastbit) * 0x1b) - var dblD uint64 = ((d << 1) & firstbits) ^ (((d >> 7) & lastbit) * 0x1b) - - w[idx] = dblA ^ dblB ^ b ^ c ^ d - w[idx + 2] = dblB ^ dblC ^ c ^ d ^ a - w[idx + 4] = dblC ^ dblD ^ d ^ a ^ b - w[idx + 6] = dblD ^ dblA ^ a ^ b ^ c - } - } - } - - h := &d.s - - if d.hs <= 256 { - h[0] = h[0] ^ h[8] ^ h[16] ^ h[24] ^ w[0] ^ w[8] ^ w[16] ^ w[24] - h[1] = h[1] ^ h[9] ^ h[17] ^ h[25] ^ w[1] ^ w[9] ^ w[17] ^ w[25] - h[2] = h[2] ^ h[10] ^ h[18] ^ h[26] ^ w[2] ^ w[10] ^ w[18] ^ w[26] - h[3] = h[3] ^ h[11] ^ h[19] ^ h[27] ^ w[3] ^ w[11] ^ w[19] ^ w[27] - h[4] = h[4] ^ h[12] ^ h[20] ^ h[28] ^ w[4] ^ w[12] ^ w[20] ^ w[28] - h[5] = h[5] ^ h[13] ^ h[21] ^ h[29] ^ w[5] ^ w[13] ^ w[21] ^ w[29] - h[6] = h[6] ^ h[14] ^ h[22] ^ h[30] ^ w[6] ^ w[14] ^ w[22] ^ w[30] - h[7] = h[7] ^ h[15] ^ h[23] ^ h[31] ^ w[7] ^ w[15] ^ w[23] ^ w[31] - } else { - h[0] = h[0] ^ h[16] ^ w[0] ^ w[16] - h[1] = h[1] ^ h[17] ^ w[1] ^ w[17] - h[2] = h[2] ^ h[18] ^ w[2] ^ w[18] - h[3] = h[3] ^ h[19] ^ w[3] ^ w[19] - h[4] = h[4] ^ h[20] ^ w[4] ^ w[20] - h[5] = h[5] ^ h[21] ^ w[5] ^ w[21] - h[6] = h[6] ^ h[22] ^ w[6] ^ w[22] - h[7] = h[7] ^ h[23] ^ w[7] ^ w[23] - h[8] = h[8] ^ h[24] ^ w[8] ^ w[24] - h[9] = h[9] ^ h[25] ^ w[9] ^ w[25] - h[10] = h[10] ^ h[26] ^ w[10] ^ w[26] - h[11] = h[11] ^ h[27] ^ w[11] ^ w[27] - h[12] = h[12] ^ h[28] ^ w[12] ^ w[28] - h[13] = h[13] ^ h[29] ^ w[13] ^ w[29] - h[14] = h[14] ^ h[30] ^ w[14] ^ w[30] - h[15] = h[15] ^ h[31] ^ w[15] ^ w[31] - } + copy(sum512[:], sum[:Size512]) + return } diff --git a/echo/echo_test.go b/echo/echo_test.go index 4ae6e85..111e0ce 100644 --- a/echo/echo_test.go +++ b/echo/echo_test.go @@ -1,7 +1,7 @@ package echo import ( - "fmt" + "bytes" "testing" "encoding/hex" ) @@ -14,7 +14,7 @@ func fromHex(s string) []byte { func Test_Hash224(t *testing.T) { msg := []byte("test-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-data") - h, _ := New(224) + h, _ := New224() h.Write(msg) dst := h.Sum(nil) @@ -23,18 +23,184 @@ func Test_Hash224(t *testing.T) { } } -// 28 bytes -// the hash has some wrong -func test_Hash224_Check(t *testing.T) { - msg := fromHex("DA5B2118CBD59F408CE56362489FDA69EF73172F46DEC16C0D4A66E3F3CCA373927CB6784CE62BBCB08A490D003A8F77391E82CDD87860909383B054DB95816720112E2F96DE9E0FFC8BABC1350ED46B9AEB5D46B66940EFA311F4853F3118063C550733E7679D871729001C12270E98439E375E0CD24769D318E03CBC97D643F1DC5F1B5EF59D12789F22449BD8FA43A13CE78A4186166523F3807B0B621079CC528F4E17C258D4F9BDD095A3E365614B94F2CD778CACABF26244891531EEDC24E1BF4598319EB8B7527736BB1E734429360F47F04B2E95D5AAE997763A467CC5303D1141C2C01F7AB9EDAB860D180697C906CE1558AEFF5ADCE603F8A4A10FC6C1699189E73B489F64CEFB89AC557C5BB8826C0317EAEF2302E855FBD96777898104365D96AE8A8ED8669C568C4DBEB0A70F6CF4C22FD933014473F91871C08D5A7B44A928295FB2AA56D5E2C39CA79D2837FB39B35C6810C378D749AACB543368A19C137B872229E0A6F469022AA93BCB2BE38B761C85AC09415CA7DEEB38FF2A2101507206FE322A89666D32750AF0F4D7B2E59571F02A048B8F94FE2D231072E301C8641D1CDB4F841AB165AF297495A348BCCD937712E68852A4ACA948C1294F8B733D06D67DE89F206498DD401E149FCC1EDCA92DEB92952EDE4EBDC7CD7992104769A04DE8705027A31337B88E8DE93F6624E8F10B9F9924E8CE5A9D841C9260753FA1492CDDFFE6B4400C5719D76FB5B01B234F32FFE64F04D0A00676FBFC58DBE17B4D552FDF0C5B802C0CADF723F73F86E8FFC493992D23E8C0B84F7220A983DDDA21170B1F730C736E75549AF6ECB8DC94FB25C26BCDDEE420C83E8A45AE4C345816B7163CFE016DCCFE47C66979D610A7F9B4A7B1BA5E230344C9F46BA076F2FCEA68AADA8FA09BF0B5CBB3850DDEDD80A30E1F7A639AC69E5595C6A4083AA959831EBBEB84C018068723192F58BAECDDD18C857E212D4C7E7215B6C954728183FBAA07720B97189AF6A7729C30D28DB33A889F225D027D164F254535770C504C506AEE4EC4676771F69F935BA08A1C6C85") +func Test_Hash256(t *testing.T) { + msg := []byte("test-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-data") + + h, _ := New256() + h.Write(msg) + dst := h.Sum(nil) + + if len(dst) == 0 { + t.Error("Hash make error") + } +} + +func Test_Hash384(t *testing.T) { + msg := []byte("test-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-data") - h, _ := New(224) + h, _ := New384() h.Write(msg) dst := h.Sum(nil) - check := "68CDEE826AB3808027F88E52CDAD3F1D436623BA64D4C33E94E6316E" + if len(dst) == 0 { + t.Error("Hash make error") + } +} + +func Test_Hash512(t *testing.T) { + msg := []byte("test-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-datatest-data") + + h, _ := New512() + h.Write(msg) + dst := h.Sum(nil) + + if len(dst) == 0 { + t.Error("Hash make error") + } +} + +type testData struct { + msg []byte + md []byte +} + +// 28 bytes +func Test_Hash224_Check(t *testing.T) { + tests := []testData{ + { + fromHex("1F877C"), + fromHex("ED7A2952CBC3068C58FF4C870AB850AFA0A499FE64FB2E943655AB88"), + }, + { + fromHex("FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD"), + fromHex("0BE012037ECC300262A12DD01A2298ECBB70620F22CD6B2F15443A89"), + }, + { + fromHex("A7ED84749CCC56BB1DFBA57119D279D412B8A986886D810F067AF349E8749E9EA746A60B03742636C464FC1EE233ACC52C1983914692B64309EDFDF29F1AB912EC3E8DA074D3F1D231511F5756F0B6EEAD3E89A6A88FE330A10FACE267BFFBFC3E3090C7FD9A850561F363AD75EA881E7244F80FF55802D5EF7A1A4E7B89FCFA80F16DF54D1B056EE637E6964B9E0FFD15B6196BDD7DB270C56B47251485348E49813B4EB9ED122A01B3EA45AD5E1A929DF61D5C0F3E77E1FDC356B63883A60E9CBB9FC3E00C2F32DBD469659883F690C6772E335F617BC33F161D6F6984252EE12E62B6000AC5231E0C9BC65BE223D8DFD94C5004A101AF9FD6C0FB"), + fromHex("D2B548165ADBA9CEC19EB47581E8A107DC49A604E6E8E63A3574ECAB"), + }, + { + fromHex("858EF34C28B8939BFB4644D1E458A67A034B9AF9F82DB786892D81C343D27B96EE49CFFBF2C3419EB11EFAEB9F8D0410B0EB688156654A8E32EE2A570C5A88007656A18380DF33F7756A6004766A6B96BB27A741057A7A0E22D732D797C488EB613F179DC3F1094B2B5C8E5A34BD57F26DE85E234FD894A2D276E8F31D0F7F23E570A0A4E13BDB635CC8897282A1AE00CB0C8F04124EDC6EDE1404272F1BFDF55AB2A0B3D5B3534A4C01CB0E1D5750EE71328FE3DACCE5420344108996B6DE1A443834B6BADFE616534EAAEA32681D57A2E41C77173D6DC0751DA26A17731B01833AD0B9C4D3B48BA23773AA6D2BB7029377F453484A44E6734A3ACB3725FFBA0547F1045F18BACB1E9C9C801759B9A16209F0158A4E8F21CCA9112FDE82388CF1FE58ADFA1F684C3158935EDF9388B42AC0E5B3B68E6E6A4D4476C4EAC78F166EC5FA464B565D481F57A9D263BAB7A1FED05D737974C4F7BDAF2CE5BA40B2A993E867E5844C7750014E66BCC5BBF5E500402529DDABF1EA2E395DB084C4BB85766FDA993B547788FCEF35381FB16AF0965A08EE5CBB4D68C934785594B37F78E76A6558AEE73E570E40CCC889B0D5269756BC40897EC0C2D6C33A33B1897AEF297F377CB58A7A1A389EA60F4B5F25D1305D046E48D5BFB1083A82C5AEED09208FF83076367156B9071BEAB5AA12D9DCA9F8AA093872C4C95B84CDBB0B84ABBB03F33B63A7C603D723DD9970524548E61F3804B7A914852AE55D377E25A8431B1E7CE78F1294664925D62B7D8CA3C880C4AC80E92F8E86554BCAFCD39CA44CAC017F4C4550BE119EBDEC7AEECCD527EFB478348425FC3668141607D14DFAC90451B2996DD46B23683210916B90E63EA2A4A006BF72C4DBB6ABF3D0505379C5B360966A25471E658EE24CABCEBB5C6ED5F8DCCC84614D64BCA54F35189F579C170F2A2B773AADFCF3C1C435885D0ADE7121A4D2FCC96AFA88DF6EA2C519A98AB279E9F75400AB053D457ED3FF957C20F282BD121EF67F53053FB4963D08F70EB287E011DFD015CFE492ADCB927BB80093545014736A12E236569ECC3453350A5E57D50B1BBCA5C8A01A946248370CDE6177D7B8C84F11EABAB0C3A5CE654FF85783EE8EEFEAB58451CE73E164A9DF47DCDC9ED24B0F7A87E0ECD1A3DD15E6D656B8945F096492EC72C0B51D13613B3134C3E31CD1A3093B8023649C1B3A3EE8A09E5A8D612A91B4B14646E22D575CC09348A5A58E0F9B641037D7B63D32B40EA5FC16C55A0875F3E64F25CA97F2A70DA0F4567C9626030B5B8463D8A55C34665481F2FC308D2B87111D23B1B6CA96013FF033B23216C27C9D2E1222DEE25B295E180CB6EB9BBF72F59AEC070AC809A79B3306E0BDB701521D4DE1D755F75EEAD5D79A72DCA55B6E25FD10C4EC68BC5C585AA1C392DA26BE5DCB75CF2FF4B31C3C578F9708191F59D04C2E00ABEABC6B217D89BA9BCD0CBE76E72E316A4C7F18AF642D9FAF3E76A6E4F4F5E80E1252E52F996DDEA279BAE6D88EF866AE6F3D77E0E105111D04D4145F09691925CEFC2A8DF96F0D340AC86C0B48EF5D18EC1DF59748BF5F261580ACDC4F58CDD2C2649E4B357872DD982D9FCB59916037A8247C6E374F0CEA924A25ED9A0B5DC15DA9AEECA8A9A9DE9811E1DCC4F05357867871B959AC9E1D3C4AA2633C9445AA2239D02E9E5C7D22FEBA47E7A0332F025E83DA06EAA82F30ADBFC8E1167391C6F3FA82B87857DEEC2F39D08D4AA3BA59E1598B54D665BA68438FC7493B351AB54B907A80945FEDA0ED5ABAC57584182E40CD4C8B48F61987A07AE6FF6196E5435324B3546F7712BF453A1F31CAC5778F94647B656DCB4FDD8B58AD3645FA1D54FA7D8EA1B627F65D68D40B9256778B46950CC2D1E4C3313D542105A3476A7AE2E51877254BD756E7FB55A55526A32B78C95ABD169DA1929CB3A1A098D246F029AF5DCD0BED4546B2559A6A4739396C2E222C77CC4D3AB47262CBE363465CCB3223452A35B91C15D4F2822FD75A91A191ED0B19EF0D4689A2F793D31607DDFAB5FE0292EB3126C6729B37BDF4EEF808A1A715982BEB2F9D6AD6571D2346AC4CC75374B4641A2BE62140DCEF6A105EB3AA593207DE595C439C8E94E8596F8D995690813B897F150670374DFD9BA0588C7AB7603958565BC31C274ED42DA1BA94372EBE0B4F08611DFE26127E7D05AFF7B9DE63B360B8C3E79B0057F92B40348C4A6CF8C238BDD33C204926C342170D9C15DC3D69C7E61F2A94807A4B84D04DF599411C11DEEBEAC243681FDEC8BE382EEEADEDF61F728646FDF9A421EA231FBBDE6613DE7A4F7BDA125AF5DF1149ACCAAABE2C2A01841D24E165AE76808CA9AF94EFFB1CF3B1E31C765559AEFEFDCCE122BDFE567E67C970E6B40B468DA0AD6B82BACCCDCB293722450AEAAE801A342ADC7F1F443D9935F5D438A16361A087228C2E26C12CB59BC98774CBDD9B49B2A065C8A767334CF16DD2717CF45A0C8EDE97B4F4FAF99ACB013B5E0079F2B3A6A2CB82B611DC7818221A679C007377EDBB9FD0A2000B32C6A17E1B0BE9B91208EDD3E417E631C2E6D23DFA763FD792972F9A9B1C8FA42F0AF5297EB49B0776BAB810B6856E0175EB1B87EC83CD2CD12E2C5C1610E1EEBE9E665A6C3467B870A1574E6F2CFC865687515D8A35F5E90D85138C3D2C9823696E25317B1BA5B0BE623FDC6CAA1041374D398578167F4352F315AE9DB4255A32EE4910F2742633D79D5B5F105ADB63B0A3D776350B8574477E572EFDCA09574445ECE8DD6382FC21D7B9D68B3A4BFCA158DF4A7AA4CC1C0DA1016C364C9FDC62ABC991A3504EABB590809B2D41E4D51CCBB0E92E8752A4C0F72E74CA7E45EB1968191D564D813131DB2B321279FE7A104ABC6E33FFACC553D0A62D69ED3CB67798BF8E927D4DB02A35334E9466052858E6828E0C28540880742ED54923BAAB85922E05E0B66EEB401453C82D5B4D7FF25297C1F9F1358BCFEB5D5294773DE203D7F2FF9FAD19FEDCE6C12896C1AE44ABE0905EA80D24BCAAD927AAFC6AFD48DDE526F3DDF4E6CF94EABB9E99CA6852360DF3DD2BFC7907E42A35744BA720FB0F366EEDAA8E86E44059F64B384E296F00ACFB469472AD01232E4A4833D11A2CF097C75492E2AA1FD7E425082195BF43F4CEF3B3477D16B606866F1AA62644F1A31119B9BC787ECF70686468A96AFCCE82625C860CEBE802C270605EA003B2B40124E8CA4EBC78A9CE226CBB3AE74A7FC829F53A51D925038CE9A3D3681CD50DC463AC3488C981DBB0ED6E4BE127CD3AEC473765C2AA762611A641848022E33AE6B5A1BD57D17221D172A1775AC54DAE58A1B0E21C54853BA59BA46CCE0C62399A547DE37557FF4B6694B86FEFE062AF6EFCC103C4A1A2BD06700E8769E4C70641011E5424C2A2F0A6A2C8EF989774FD59C0800EB0CB19EDB51B69E88BF4FAEA43F5C2C2818F9B95E27BC68F60BFBBBCDC778C6F6B116333DBC17DD352E2E97BFB5E33EBE9B3E518F93E86067E75F064A714DB634E37CE71D4BAD65FE2BBF326EA2793C87CB44572C965AD6598312BD9838DFA8E1B599CCB8701DCB397E8466A8524B568E77BE95CB96C79A64DC180A736A6D996EEB896DCD9D9AAA8B6A4A9AEEE6F213DF1A071F6F309C1ABAD52FD477F6F707F876F40EBFF3530195EC39887E3D764488EC4C7618FFBE79265EEE08CB809CDBD0F7D38A8A2D292822661C2273D8270D1E0B2BDA7DBF1362349A9206BA25C0DC1C668B39DB7724E29050618E43BBA05F50F202D9A026894EB20FEE7D6FCBB22D7DE3EB89EEFF428AAA1B3F18A9847FD5FCFE6AFB9EAD2C864E0DB5C0C7533E574CFCBD82F14DB20F851979722277AEB0EF579802336C90D3BE78B47DED5C829E83956FC9587ACD1B0157918C4A1DB3676E4001F068128CD4C4511385F4AC39EBC687AEEE6EC7D7535391062191F86B4A2F1818E6D1DDBB24E1E7CF743E399106AA1C39E52AD7EC2BE7BDFB32B54E923D50EF8AD4EBC6A80C65614EEA4AA5D07F48FC597A29EE20026DEF2F300C7D3CA727E8857A098A0FB22F2C6757268E390F839BE20D459830A9E3DAC71EF418215D9B89BA559A80341E1590DC964B8A6ABA07FAAE4A9AD8E5969E9471D53E4DA76889AF5F9923B18BB584D71E30231E0EBFD9FA4891AF34007C1235A9CFB2B0DB0EFC1A5417CBD53F694C6F3882E8553A0E01F7AE34C24439A97DEEACE8BDD2F59515DE0760589FF6230D602BE3893D27E34DCECCE7B8E310D87790FFF49AE5B530FDFDFF71E61BE2E1B90D4204194EFD263D1CCFF4584938C06666B0AB675A6CC5CA0C6578851730E281C107B58A27099647541CB2B9C46626662451137BE1B34438ED825C45628D7DD49303770BC3330E5E98E9ADA7A1CCB694EE5E00B27F7A5AA000D1D9D1F7614532BA4B8AB8A92367B6946247B5F69F870DE10775325C65ADE56A7D063757371739E053E971179D2BB6517C7D9F8EF37A78DD3B9D15C9D2F021D4B81FFE9437353A965D79B82177B6798A70EF8511D27FFF215B741B9"), + fromHex("CE5DEEC8F08241C637DC30A476F52C5519A6A32004C8776884A719D6"), + }, + { + fromHex("6964E2D650B19AA6D31B839C604A90AA3D105834F3854DF4A41D4787A387042CC413DE27503A1EFC366B87ED677EA63DCCD40D9C7F699FFF9B8A42B596173014B9E811D42D2DE574ED5C80FC6A5A86B772A3EEBE5640102527401C0E9BEF57E05BBF06986535D3163788C60C92EC7460B7FC685FB45FB8A18FA84EF5A37C94A2EC3A948DCAFC69B83E2434ABCFDAFCE948D8C76ED9BA780D39AC3DD098EBB3208538A666CED8ACF1B3031C5EF23592FC432AC25BE0552C1A6463E3CC778D456A520432A8C55436573219C49E6BC27474AA4BD9B1B3BC64917D016B6580AEF2A0BA41ACFB98EA869D3995012715D06D64E0AAEFB2627125F225E2EFEA21AF7EC49304B8E6399623FAC15D6CDF39C4177A12254E5D807B4AAECED6D591F4D0BF50C07F5B69E7D60055062654E7B1C8B96AF726BCB34B10C60B7FC3B10DBC69107C7D81043BCAA681EB354CF19AF26AE3C7CB321B892C33CD044A24A5249F2F2EA3F804944B5049CA887EAA6D4CD5E52D17CF01CB0FCECDA47425EC85F8362AE045ED0D109758C90134EA27C4CBF6E3ABE7F283F4C3FFC4455EAE4790329AE47658DB2850B09A79A89BDBF72A20DC887B6AD7ADECBD5A86C08479D446EF817E13A37819C227792E3E0FF80A2831B20760B879A489A4AE50AFF9FB1DFF39132DD84300EF7ABE05E98C5929683A2DDFEA99468996D652DCCC698183F9A3103F7C049A7227733D0C14ED1BB809B4EF750DF19094885961D327394D6CFA0A21B341681738B7E6FEEFCBF4DD474B7B45EA64A3A60B97BFF297E8A52CD4AA6E92D6DBB7FEF7F736D29CE3B041488A6DB68D28F3C0204CFFF82CE6EAD11E11D7B060A0FF550711BE33288ACC63B6DCF2062251771544AD41B35B1EA5F11C4B196C48F5FBFCB4B39C60044A70E1DBB2CFBF9D8FCC855DEC9A0B33F2021CC76B236ADEB5A1356CFB8590FC1DDF8A721D9331861DB604AD0C8C89871E960019A0DABA43202ADDD526C1706E782FAC5F98295F4C6036B8E2DF6D225B6335D1314143573AB8E66A7750BDB6420452FA060B24FBBC3618D951490534718D97E3AE994D5E770D103E1F405A5357A2521E9393ED2ED197E7AAC87E142205C69DBEE846034FE6F2168DC207D13022E11427E8F02087D2F4E850E7FD21237D56BE970781CD779F7B0D8E9F689E6CADA3386B5E779E382AE3DEB6CB20DBA16A94D147101FE594790A5B331D40551C8C1D81052CE00642F56E4048F6831D713E74E3F4C6ED2352854854E35C06313F0104FA47EEB282AFF9A3ED3D683FC88E9684AA0C460C3EC333080D5F557520A359803563A1D8BA7C716082CBEA808DFF6296947CEF7EA30CBAD458C0B90A07847E3E557CFC33B0E3893D32924934DA966F6D451FF8C6B28ECAD7480CC137327E5DB10D180D41E8088660297DFA99126F7E2AB290F206C02644B4F28A603E959077E13D65C650CC0513259C36324CB5223E829350EB0A567317FA176213EBEFD40B98C38055B24AD85171FF0724410926B38D8A06DE500775D39E472B0B3212122204136D0793ED28F6EA070ED50745745DF57079F7D4C63C6B5A862A031DA93F4E576873E6ED03EAABC2A59D4FDE5A670850A52B17DFB059AD5A0822FF68B9A3A11A26BDE519E86A2C7F743BC932BB29208383621D509DA438A56B56E1AAADC330A0CEADE51EA65ECA256E3DEE4495C3FB94F41C121B03B6996981033D5D9E5540719E29EB1AD9A10C2182811629BB5A7D2296842FCA6018E44B1B2B0EE56DB63EDACFFA837A0147D1FBEA737FD66B614FA097819422DAEB9E1F04B81D4B1E569AA84708AFAC7A9DD92F95D9CAC1137404F950C70D0E337C956BFD2C7B64A3B99F1499F9B297391B0996B42289E205B47900168F8BC3A30C84CDF00AF52EF14D8B4A87675F8859E9C3980524C2081D3A08DE576C1FD5B40459E299BA89FBD05C8ED01E3BEDD893F7EC17DD1BE1EEE0B19186E739DDE650566C395EB143451C09EB51C6E14EEF3FC3E20210CE62C49D0BB862CEC28872C0CD989050B56EEEB062AE2645C1510635E4085F5940EEC6274CA982E312AB21BA0930BE4D6B57AD8D36BBF58DC05D353E32A5CFCC4EB008610E24A8F2A1FCB57BF6E4ADCF80D3408997D6872A2EA5E94E74CC184ECCBBA15882745E03146045DBF6E94127581CEE20F2F408841D1982132E5B7F582B91784740761EFDC9346BD9EBB3C1FD341C3056F4DBB4B36EA9E4BF05C965B367346472D0EB55B840ED49EF245C6F86EC5394063305BA0DF45DB30F7658D28AA988CC9AD97F0A9C0B3E59FB623D55C61F2E202521714970C2285BDBF7C6119FA3097D82F6A1EBC33D42C85A93630AE18521A2F8AA785A17C2D9354033FE297B172EA1F06CCA686DE4E1A28836DA559E4405856411D58533CE33C6B573EC51F0F565499F6FCA8837FC80BC4925867EEB6BDCAB15EF1C70B17E02A535E2F423D36591A22CF527D118D5C540A6749E1C206058C0452BD9C8F5885EB5823BA8515C105F8D96FD5F4AF9337E66D35069D19EC041A7D979452E5743A6A22DA0DF662FD9D1A2AC3F8D431A61F4FB944089C52233167E0D53899B6D45C51393F3EF6894921486D2F9F4D5E6E95107FB975C8E856AFC76B06BF3648668EAFF6AA59FC9A3AA536E548880D4D79C9EB5CFEBA4D6D5D402197C0E1608500D69833C069BD1C45D766A7BC783C0194A2C813B223F141D8AE2868FD65D68DD67EF463E34E4FC20C7777BE17A3FCFA51A9D98FB23B341B12CDD2B430B0602CAB03A226C7CEE4F9488C8319DDBF4EFF1B614BA9C1FE0098E9CE1B57EA4D8D777EE89F4C2E3C729216B6B2EE2685DB9C1945B27986C748DCA51BB361824824FB2A31EF9D7244B734779B86354BC0DBA438D378193A84785B6B864306EB6E6A0A80FA2AF04985FC540477B911D7EA859D8F956DD1DF3E464D884A6355E8B24CA3F05F25EE53B23EBE43CE6C32774FB74BACE33A12E7C1798B7116BEE1245CBE323882464C49B647D61350ADEB84CAE9C61B02BD702E6D8DE849FAD57A57AD297150312198D89EF1366E45286F4BCC8217DB2EDD39B144D6BA1D6CB0D1C74BE396CB535E6FF9900AC371A6F9E8DAA45DD1B1842FC685D1FDEE0FC127A165B03B561002CA56F19143024C41520489BEFA82AF92FCE5BB220DCEC1AA047B299F7FAC2BCB489C99044AEFAF2920C324597DAACAB92F6347BC0EF95CA619DC19A7F28A1CBBACEFC85EA2BD7A769E6BE424F4AF08AF7F24F5475EE2434ACEECEC18BFBCFD3479226363B2BFA915DA76B839857A33641B4B9F64F15702ADB3964E5DB19FAF48489A7F6F9F56A2A258C54E0E5F97F382FA99274B2607D3D6A6B94CA075EB454080B01435C5ABA8B45AD6EDFD00DDC0270C7E54919A43DC715CB7B37E8423C7D2285D222AEC66E4DC4B55BC6EED3CED1B8D5B364F5FED35BA0312E46418192937792E865EBF5D5315F1E395194004B77F1D15E48203E3E5BD2C508E3CD8D1E2075B3D6DB0A5B28C10F155B13954297DB518A3E47DB5DA1C0ED8536FA7B5945E952BB5C4E24C40FCA0C344302A5202B92A351738225505209D810789F7A590672ECAAD866ACE771A3F9091A1695DA17B3576213A0DB5C4641E78045822AFD939B6272D12E05CDD1040681AAEE55523BE6371C53FCED13638A9448C0E9AF8AEF55ACAF723D513DAB5138F62E28FEB489E75BE072418051CDFDABC7CEB0C99F181C6AD95E7EFF5226BE5C4F4EDEE7A8C4A0500241EDBC363CB4C3AC12DD046EF0C840933740F48C63DE39C082FF4374C2D8453F2B813F397B822E90FD59B448262C00FDCAE73BCF90CAE164BAE33041CB809E7CAFCFDD658065B84B7C370CE3E08D505F7A2BA783A666EF74D8743336FA4DF4E20A1F8D58CD0B0EFF66FA77803F42169F51109A4CCFD008F36E23EDBAAA6ABF53B822C9EF356B79027CF28DF9E5D5D7CA360AEB407CF02CA2689F8131C78CE6DE7C5D8A2DC65A91DF7ACA7787ECD5145C5C791B7428F3F9CBB22F584EB564AF89263F5750CB37C8151F205B2FCA7DF746226D5AFE10177C8BC456452EA65D449E19B4253D6625D5C3349F3EC3BE554D4158DF219DE226AF379A422A8DAC91B97C64E19C120141D806767F7EE931D88E293EE8AE1EFD2766EE83174DE19BB645EE3455133B81E2270AC1C7CCEB037A50A5CCD540F00ABE27F05BBC29A2F10542CA0AE130D2B2A1464DB03C0B2510A9E7FB98AB24FD391CBAE0A112A66EAC05304127D1545BE6638B6D35606877719C3CD782FAE3FAAD1B89EB603750C7B5C3CE84F93FAC147346350C750CF2CA7EF9099D6725BD31172C37FAE60E07F33572CB843E67E8662D0DD55E424AFA9B1D57CBF9DDCDE447A3B8B604EFA253EBB2CEBE01521F0353C521F457F451CD93346D815D6BCBA87B3D2F96A22ED17C17B90BE3DDF7E04838C4F780BE2C96B781558B4A4999B3ADBAACA1229F22FF637CFC068CE8802F8684AAC32AE32BD09CD5C1D770900CC7C5FE8DF41E8110FAAD782C15C3CD637BA619A0037D7378C72CB0C95A35A9109BE11F8C4BF0D3BB80949A15C64A0D6F52A9B52A521D06DC749CD0E553418E127FB519BDA401F59E5AE517CBC2F538B6C32F9CE5C34088CFFFE03FDC7D36A7A912EDE8254B7EA46F1262973BE564089C44825437D8DBA98BE04CF7F6AB5D03C5C10AB51557F331D0B1B919B9643EFAD709080D2FF46BE83E081551F64ECD826DB09469179FF4B068CCA172D1E16750BD6D4C805146DC0221A555C81931A60206AF7CB485D2FB7FA9D7AACBC3E3729EB09979D2E683EA3ED8AD3B4BAAF4FE25F8B227568795563D3F2902A97375C521BA20F9C5E860DFAC83A0F0ED347588F250A44F01C93611405AEB04C6E75153F0A6E064E19D895DF7596C6A48A0BB3804A78937A45BCD05486314BAF72661349E8EB516FCFBAFFB31639716C5B88CAF4255E20EE90A6EF402E7A39C5CCDC5B196A99C5455639E9ECB788F94ABD7A711833B92DB9FD56B6412BF84C6BEE9505682EA300CEEDA496EF06CC477C272318F9883212794E9AD88177B65CECC1BA8474D3DE7656B61A3B832240578A4FF704CAA65E01A29F365C1ABB1DF23D61AD41C08B092CE870BA1103857DA37D8F5647A5D5ADA7BB1D9804C547C187BD1767258292514491CEC97BA41F48C6B581FE8E74520D0F0F6B0E44C9920290F68684D169253087540EBE733AE2465254BA04BEB703F3A309BE14B4F22EA63AA2DE8E674D2AD446F356D1CFE1207A5ED7C2D565CCD5CC1EF0EB1E7919C26E92B851F7478C83DE6CD21A3547CD4464A6B6B4DA6A8D8F736D16D818063D1FB95A8D6A46911FC564AA5CFB1CF76EF09D0C104648F92DB9B28816F560A24935923A945A1FB52AD9FAC6EA2E640A64F79F25693398B0A0E567518D950714A8AAF343A68A4EB1EE1F518ACBE99E05041CA505AD509F6EBCC68C84D85DC17E60F0240EC848A842F4A1ABF11371F46CE69D5B535FAB5634523E359AE14DD07749FBC6390EEB9E5330FC07926C971C719CD02AA565048CDA7E534365A3F39555F25BEC847C0FE5A76EF68F038FF552DA2722581CC14ECEDA1297942A1A67D0501815747C61517A9AC876DB662641F750A917EDFD8EA199D27E5D56855E5200791CD404D15B6EF6F5771234B0902C9DB5B033F260359F1A52E6646DBDE9E4F9876A7BF2C5FD7BA028BAA306FF9D4287DF88AA055C833ED8AC6A56D2C83AD69AD3FD6FFA96AB717444035D3B8DAE9D26D475767CAD452B607B3ECA6C573C38530DB071968B7E1DC26058827C57AD84A14B495FE082419255C495C5E13F5BC34D96CB498378CC16DBF6683D54836E12D44D76956A6B0CE788AF5282B9F06B5BAD30347A1D537EF864BB0C1496176B1B10118D02A56407609C0208E860B86A47C82B6FDE76CEC5AA70CF58B4B110D67E70E7B37DFE3A1D530183111E2AC6B30736BE4FFD6DBAEC5DCBB7194B9F0CC733F0A3A"), + fromHex("CE4096CAE9992BF9AA1A25D82842D3FD93A6F020DB36726E07148669"), + }, + } + + for i, test := range tests { + h, _ := New224() + h.Write(test.msg) + sum := h.Sum(nil) + + if !bytes.Equal(sum, test.md) { + t.Errorf("[%d] New224 fail, got %x, want %x", i, sum, test.md) + } + + // ===== + + sum2 := Sum224(test.msg) + + if !bytes.Equal(sum2[:], test.md) { + t.Errorf("[%d] Sum224 fail, got %x, want %x", i, sum2, test.md) + } + } +} + +func Test_Hash256_Check(t *testing.T) { + tests := []testData{ + { + fromHex("5BE43C90F22902E4FE8ED2D3"), + fromHex("E110E4884E77A1809817D975A30A531B65D5257404E7DE198DD1A2CF8B73B14C"), + }, + { + fromHex("FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD"), + fromHex("6B8CCFD83C2FC663C9C9ABBC45FABFF1E195D1D3AE96877940DA0E1115BD3AB4"), + }, + { + fromHex("D9257004993C7AE50D20F534B42B4EC39BF358393B9FB5C8E37F87AC7361354554BE596F40E67B2ED499887E26DC435C4331CDE3BF1A118F60FD821477FFA3B92F6469568CD2CDA6FC0A2B13906AE459CF5D5417DE2CE104D0B6499D3683BEB40715582CE70DED5C5F8461EDEAA38BFA31979661A2DC96D926307128F77700F2C7D38B8A9D6C6F70A3973005350F938B9B4A64E228CC3B3F9C4FD446FC650AA6377152D7F46903D8EC8E9340710E28475CF21E641737E7D7DA3CDF18D01C8F37131E727C7274B2DB759C5586FB84EC36A5CE2D820E553DE6426B8B96111295C19DBA8D17A2B7047FCDF662A59C2AF27A9ABEE37A7F8AFC06944346E343E779EBD895119D7460E7DA998962FB1100E950A8D7FE214360AD263B8D070F2B7DC91C9D77C6692DA0F472A0A4646A1EDB069CCD9CE4CA6FC24713D650153B9A253DB5136A3710198E60934DD2053315D313E27DD2C6FFD2ECF028625F0E937AFD8C2FFB1F646E51A768204D83A649798A51B8E87FCDDA7BDDF58ED943BB7E29C7D7C5DFF024545F6A689AA0E727FECD80B561011A731ACDD9B3F283123098BA66B6B9FCE6123B35B6F3A20EF1055BE9E257CDE97E5AF41EB796438727A62AA665CC9B771C4A2052EFAC61BC91BCDF573F7263107D44DFEB125E66D1F3DDED3BD63845AF3BF4185A9A24A7F4B777C32496A6107B7AC940AF24BE983F6A758E5064F8717EABBB86E6AADA7DA75F72ABED59A42DE82B1AA2642F5EF1B2E7304F642EB2AAFBF00C1183D9B5FB83893EDD48E9034DC7A7AB66F3F392F9666C00ECC9743AC4F777EDCF47B6818A34B7392B4AB8E38891FAB4018DFB99AF06369115D60C4FA073240D9C2605E020A42DB2E1E0AE4ADE3A04B825927A05D4FE3F50C1C7ADD7A496DA7E95825C064315196C2007524D1E1EF2C51303DD1203AB66D9FE89DE553CB4B95A6C5D629B89B7116463EE10AB3CF2C2615F95741CA226F9E9A20E99303888F725C77476533B4C393763170F18F292C89A22DF68EABDB81AEF11CC2AC329C174BDAE5D3CC0BDCEA6EB225E00C15021432264BA7C5EB49A49231D1F7A13AFC238BD4EFC04DA3C15AE0BB7D693A0150E6A5AD9B1E11A490B3CE90C027442501684C528FE260881162D9E5EF84D6E4F73F222E779E58B71D5176D9A27F65E49D83EFBB2D7810E5B06619D8CEF7E7B51CDFB6E8138E4CF5674242F947EAC13FAD08D68A8A11AAC9754A5316C93738BA7F3C3BD2E827A"), + fromHex("6C94544B2DCDE500E778ED4DA7B244A301169BB8723EF6999F640F7743B73A43"), + }, + } + + for i, test := range tests { + h, _ := New256() + h.Write(test.msg) + sum := h.Sum(nil) + + if !bytes.Equal(sum, test.md) { + t.Errorf("[%d] New256 fail, got %x, want %x", i, sum, test.md) + } + + // ===== + + sum2 := Sum256(test.msg) + + if !bytes.Equal(sum2[:], test.md) { + t.Errorf("[%d] Sum256 fail, got %x, want %x", i, sum2, test.md) + } + } +} + +func Test_Hash384_Check(t *testing.T) { + tests := []testData{ + { + fromHex("1f877c"), + fromHex("91f2a4a29cfee555751c388afb63317842e3ef02d7b02fb35acf3f1cc18366bd37f2b0aef1f329cf9658e03ccd8fb6c6"), + }, + { + fromHex("0dc45181337ca32a8222fe7a3bf42fc9f89744259cff653504d6051fe84b1a7ffd20cb47d4696ce212a686bb9be9a8ab1c697b6d6a33"), + fromHex("4608e7610eec6d3ee68514ca77791e346e187152663e5dd1ed1fa35cf6b4f8839a936fce428228170e240879d478c084"), + }, + } + + for i, test := range tests { + h, _ := New384() + h.Write(test.msg) + sum := h.Sum(nil) + + if !bytes.Equal(sum, test.md) { + t.Errorf("[%d] New384 fail, got %x, want %x", i, sum, test.md) + } + + // ===== + + sum2 := Sum384(test.msg) + + if !bytes.Equal(sum2[:], test.md) { + t.Errorf("[%d] Sum384 fail, got %x, want %x", i, sum2, test.md) + } + } +} + +func Test_Hash512_Check(t *testing.T) { + tests := []testData{ + { + fromHex("52a608ab21ccdd8a4457a57ede782176"), + fromHex("ea47150919586419aba6e67e4146fdf7ac285a53e98f9e1e2e949ad5907c2b73e9f36a5de3687987a85edcaec32af117cb4fd9650e358cc60a43eaaffc017528"), + }, + { + fromHex("aecbb02759f7433d6fcb06963c74061cd83b5b3ffa6f13c6"), + fromHex("2d7ec63594f700b2c6dc93069c987e0d85d24efddb938249bf084b2f111e979b923cb356efc2a58c53dc5608e4e26e751cdf00dd81f21d670ca00e05ced341c2"), + }, + } + + for i, test := range tests { + h, _ := New512() + h.Write(test.msg) + sum := h.Sum(nil) + + if !bytes.Equal(sum, test.md) { + t.Errorf("[%d] New512 fail, got %x, want %x", i, sum, test.md) + } + + // ===== + + sum2 := Sum512(test.msg) - if fmt.Sprintf("%X", dst) != check { - t.Errorf("fail, got %X, want %s", dst, check) + if !bytes.Equal(sum2[:], test.md) { + t.Errorf("[%d] Sum512 fail, got %x, want %x", i, sum2, test.md) + } } }