type digest struct {
h [8 ]uint32
x [chunk ]byte
nx int
len uint64
is224 bool
}
const (
magic224 = "sha\x02"
magic256 = "sha\x03"
marshaledSize = len (magic256 ) + 8 *4 + chunk + 8
)
func (d *digest ) MarshalBinary () ([]byte , error ) {
b := make ([]byte , 0 , marshaledSize )
if d .is224 {
b = append (b , magic224 ...)
} else {
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 )]
b = appendUint64 (b , d .len )
return b , nil
}
func (d *digest ) UnmarshalBinary (b []byte ) error {
if len (b ) < len (magic224 ) || (d .is224 && string (b [:len (magic224 )]) != magic224 ) || (!d .is224 && string (b [:len (magic256 )]) != magic256 ) {
return errors .New ("crypto/sha256: invalid hash state identifier" )
}
if len (b ) != marshaledSize {
return errors .New ("crypto/sha256: invalid hash state size" )
}
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 , d .len = consumeUint64 (b )
d .nx = int (d .len % chunk )
return nil
}
func appendUint64 (b []byte , x uint64 ) []byte {
var a [8 ]byte
binary .BigEndian .PutUint64 (a [:], x )
return append (b , a [:]...)
}
func appendUint32 (b []byte , x uint32 ) []byte {
var a [4 ]byte
binary .BigEndian .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 (d *digest ) Reset () {
if !d .is224 {
d .h [0 ] = init0
d .h [1 ] = init1
d .h [2 ] = init2
d .h [3 ] = init3
d .h [4 ] = init4
d .h [5 ] = init5
d .h [6 ] = init6
d .h [7 ] = init7
} else {
d .h [0 ] = init0_224
d .h [1 ] = init1_224
d .h [2 ] = init2_224
d .h [3 ] = init3_224
d .h [4 ] = init4_224
d .h [5 ] = init5_224
d .h [6 ] = init6_224
d .h [7 ] = init7_224
}
d .nx = 0
d .len = 0
}