// #include "goboringcrypto.h"
import "C"
import (
+ "errors"
"hash"
"unsafe"
)
out [20]byte
}
+type sha1Ctx struct {
+ h [5]uint32
+ nl, nh uint32
+ x [64]byte
+ nx uint32
+}
+
func (h *sha1Hash) Reset() { C._goboringcrypto_SHA1_Init(&h.ctx) }
func (h *sha1Hash) Size() int { return 20 }
func (h *sha1Hash) BlockSize() int { return 64 }
return h.out[:]
}
+const (
+ sha1Magic = "sha\x01"
+ sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8
+)
+
+func (h *sha1Hash) MarshalBinary() ([]byte, error) {
+ d := (*sha1Ctx)(unsafe.Pointer(&h.ctx))
+ b := make([]byte, 0, sha1MarshaledSize)
+ b = append(b, sha1Magic...)
+ b = appendUint32(b, d.h[0])
+ b = appendUint32(b, d.h[1])
+ b = appendUint32(b, d.h[2])
+ b = appendUint32(b, d.h[3])
+ b = appendUint32(b, d.h[4])
+ b = append(b, d.x[:d.nx]...)
+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
+ return b, nil
+}
+
+func (h *sha1Hash) UnmarshalBinary(b []byte) error {
+ if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic {
+ return errors.New("crypto/sha1: invalid hash state identifier")
+ }
+ if len(b) != sha1MarshaledSize {
+ return errors.New("crypto/sha1: invalid hash state size")
+ }
+ d := (*sha1Ctx)(unsafe.Pointer(&h.ctx))
+ b = b[len(sha1Magic):]
+ b, d.h[0] = consumeUint32(b)
+ b, d.h[1] = consumeUint32(b)
+ b, d.h[2] = consumeUint32(b)
+ b, d.h[3] = consumeUint32(b)
+ b, d.h[4] = consumeUint32(b)
+ b = b[copy(d.x[:], b):]
+ b, n := consumeUint64(b)
+ d.nl = uint32(n << 3)
+ d.nh = uint32(n >> 29)
+ d.nx = uint32(n) % 64
+ return nil
+}
+
// NewSHA224 returns a new SHA224 hash.
func NewSHA224() hash.Hash {
h := new(sha224Hash)
return h.out[:]
}
+const (
+ magic224 = "sha\x02"
+ magic256 = "sha\x03"
+ marshaledSize256 = len(magic256) + 8*4 + 64 + 8
+)
+
+type sha256Ctx struct {
+ h [8]uint32
+ nl, nh uint32
+ x [64]byte
+ nx uint32
+}
+
+func (h *sha224Hash) MarshalBinary() ([]byte, error) {
+ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
+ b := make([]byte, 0, marshaledSize256)
+ b = append(b, magic224...)
+ b = appendUint32(b, d.h[0])
+ b = appendUint32(b, d.h[1])
+ b = appendUint32(b, d.h[2])
+ b = appendUint32(b, d.h[3])
+ b = appendUint32(b, d.h[4])
+ b = appendUint32(b, d.h[5])
+ b = appendUint32(b, d.h[6])
+ b = appendUint32(b, d.h[7])
+ b = append(b, d.x[:d.nx]...)
+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
+ return b, nil
+}
+
+func (h *sha256Hash) MarshalBinary() ([]byte, error) {
+ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
+ b := make([]byte, 0, marshaledSize256)
+ b = append(b, magic256...)
+ b = appendUint32(b, d.h[0])
+ b = appendUint32(b, d.h[1])
+ b = appendUint32(b, d.h[2])
+ b = appendUint32(b, d.h[3])
+ b = appendUint32(b, d.h[4])
+ b = appendUint32(b, d.h[5])
+ b = appendUint32(b, d.h[6])
+ b = appendUint32(b, d.h[7])
+ b = append(b, d.x[:d.nx]...)
+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
+ return b, nil
+}
+
+func (h *sha224Hash) UnmarshalBinary(b []byte) error {
+ if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 {
+ return errors.New("crypto/sha256: invalid hash state identifier")
+ }
+ if len(b) != marshaledSize256 {
+ return errors.New("crypto/sha256: invalid hash state size")
+ }
+ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
+ b = b[len(magic224):]
+ b, d.h[0] = consumeUint32(b)
+ b, d.h[1] = consumeUint32(b)
+ b, d.h[2] = consumeUint32(b)
+ b, d.h[3] = consumeUint32(b)
+ b, d.h[4] = consumeUint32(b)
+ b, d.h[5] = consumeUint32(b)
+ b, d.h[6] = consumeUint32(b)
+ b, d.h[7] = consumeUint32(b)
+ b = b[copy(d.x[:], b):]
+ b, n := consumeUint64(b)
+ d.nl = uint32(n << 3)
+ d.nh = uint32(n >> 29)
+ d.nx = uint32(n) % 64
+ return nil
+}
+
+func (h *sha256Hash) UnmarshalBinary(b []byte) error {
+ if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 {
+ return errors.New("crypto/sha256: invalid hash state identifier")
+ }
+ if len(b) != marshaledSize256 {
+ return errors.New("crypto/sha256: invalid hash state size")
+ }
+ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
+ b = b[len(magic256):]
+ b, d.h[0] = consumeUint32(b)
+ b, d.h[1] = consumeUint32(b)
+ b, d.h[2] = consumeUint32(b)
+ b, d.h[3] = consumeUint32(b)
+ b, d.h[4] = consumeUint32(b)
+ b, d.h[5] = consumeUint32(b)
+ b, d.h[6] = consumeUint32(b)
+ b, d.h[7] = consumeUint32(b)
+ b = b[copy(d.x[:], b):]
+ b, n := consumeUint64(b)
+ d.nl = uint32(n << 3)
+ d.nh = uint32(n >> 29)
+ d.nx = uint32(n) % 64
+ return nil
+}
+
// NewSHA384 returns a new SHA384 hash.
func NewSHA384() hash.Hash {
h := new(sha384Hash)
}
return h.out[:]
}
+
+type sha512Ctx struct {
+ h [8]uint64
+ nl, nh uint64
+ x [128]byte
+ nx uint32
+}
+
+const (
+ magic384 = "sha\x04"
+ magic512_224 = "sha\x05"
+ magic512_256 = "sha\x06"
+ magic512 = "sha\x07"
+ marshaledSize512 = len(magic512) + 8*8 + 128 + 8
+)
+
+var zero [128]byte
+
+func (h *sha384Hash) MarshalBinary() ([]byte, error) {
+ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
+ b := make([]byte, 0, marshaledSize512)
+ b = append(b, magic384...)
+ b = appendUint64(b, d.h[0])
+ b = appendUint64(b, d.h[1])
+ b = appendUint64(b, d.h[2])
+ b = appendUint64(b, d.h[3])
+ b = appendUint64(b, d.h[4])
+ b = appendUint64(b, d.h[5])
+ b = appendUint64(b, d.h[6])
+ b = appendUint64(b, d.h[7])
+ b = append(b, d.x[:d.nx]...)
+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+ b = appendUint64(b, d.nl>>3|d.nh<<61)
+ return b, nil
+}
+
+func (h *sha512Hash) MarshalBinary() ([]byte, error) {
+ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
+ b := make([]byte, 0, marshaledSize512)
+ b = append(b, magic512...)
+ b = appendUint64(b, d.h[0])
+ b = appendUint64(b, d.h[1])
+ b = appendUint64(b, d.h[2])
+ b = appendUint64(b, d.h[3])
+ b = appendUint64(b, d.h[4])
+ b = appendUint64(b, d.h[5])
+ b = appendUint64(b, d.h[6])
+ b = appendUint64(b, d.h[7])
+ b = append(b, d.x[:d.nx]...)
+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+ b = appendUint64(b, d.nl>>3|d.nh<<61)
+ return b, nil
+}
+
+func (h *sha384Hash) UnmarshalBinary(b []byte) error {
+ if len(b) < len(magic512) {
+ return errors.New("crypto/sha512: invalid hash state identifier")
+ }
+ if string(b[:len(magic384)]) != magic384 {
+ return errors.New("crypto/sha512: invalid hash state identifier")
+ }
+ if len(b) != marshaledSize512 {
+ return errors.New("crypto/sha512: invalid hash state size")
+ }
+ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
+ b = b[len(magic512):]
+ b, d.h[0] = consumeUint64(b)
+ b, d.h[1] = consumeUint64(b)
+ b, d.h[2] = consumeUint64(b)
+ b, d.h[3] = consumeUint64(b)
+ b, d.h[4] = consumeUint64(b)
+ b, d.h[5] = consumeUint64(b)
+ b, d.h[6] = consumeUint64(b)
+ b, d.h[7] = consumeUint64(b)
+ b = b[copy(d.x[:], b):]
+ b, n := consumeUint64(b)
+ d.nl = n << 3
+ d.nh = n >> 61
+ d.nx = uint32(n) % 128
+ return nil
+}
+
+func (h *sha512Hash) UnmarshalBinary(b []byte) error {
+ if len(b) < len(magic512) {
+ return errors.New("crypto/sha512: invalid hash state identifier")
+ }
+ if string(b[:len(magic512)]) != magic512 {
+ return errors.New("crypto/sha512: invalid hash state identifier")
+ }
+ if len(b) != marshaledSize512 {
+ return errors.New("crypto/sha512: invalid hash state size")
+ }
+ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
+ b = b[len(magic512):]
+ b, d.h[0] = consumeUint64(b)
+ b, d.h[1] = consumeUint64(b)
+ b, d.h[2] = consumeUint64(b)
+ b, d.h[3] = consumeUint64(b)
+ b, d.h[4] = consumeUint64(b)
+ b, d.h[5] = consumeUint64(b)
+ b, d.h[6] = consumeUint64(b)
+ b, d.h[7] = consumeUint64(b)
+ b = b[copy(d.x[:], b):]
+ b, n := consumeUint64(b)
+ d.nl = n << 3
+ d.nh = n >> 61
+ d.nx = uint32(n) % 128
+ return nil
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+ var a [8]byte
+ putUint64(a[:], x)
+ return append(b, a[:]...)
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+ var a [4]byte
+ putUint32(a[:], x)
+ return append(b, a[:]...)
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+ _ = b[7]
+ x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+ return b[8:], x
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+ _ = b[3]
+ x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+ return b[4:], x
+}
+
+func putUint64(x []byte, s uint64) {
+ _ = x[7]
+ x[0] = byte(s >> 56)
+ x[1] = byte(s >> 48)
+ x[2] = byte(s >> 40)
+ x[3] = byte(s >> 32)
+ x[4] = byte(s >> 24)
+ x[5] = byte(s >> 16)
+ x[6] = byte(s >> 8)
+ x[7] = byte(s)
+}
+
+func putUint32(x []byte, s uint32) {
+ _ = x[3]
+ x[0] = byte(s >> 24)
+ x[1] = byte(s >> 16)
+ x[2] = byte(s >> 8)
+ x[3] = byte(s)
+}