@@ -19,6 +19,7 @@ package sha256
1919import (
2020 "crypto/sha256"
2121 "encoding/binary"
22+ "errors"
2223 "hash"
2324)
2425
@@ -386,3 +387,82 @@ var _K = []uint32{
386387 0xbef9a3f7 ,
387388 0xc67178f2 ,
388389}
390+
391+ const (
392+ magic256 = "sha\x03 "
393+ marshaledSize = len (magic256 ) + 8 * 4 + chunk + 8
394+ )
395+
396+ func (d * digest ) MarshalBinary () ([]byte , error ) {
397+ b := make ([]byte , 0 , marshaledSize )
398+ b = append (b , magic256 ... )
399+ b = appendUint32 (b , d .h [0 ])
400+ b = appendUint32 (b , d .h [1 ])
401+ b = appendUint32 (b , d .h [2 ])
402+ b = appendUint32 (b , d .h [3 ])
403+ b = appendUint32 (b , d .h [4 ])
404+ b = appendUint32 (b , d .h [5 ])
405+ b = appendUint32 (b , d .h [6 ])
406+ b = appendUint32 (b , d .h [7 ])
407+ b = append (b , d .x [:d .nx ]... )
408+ b = b [:len (b )+ len (d .x )- d .nx ] // already zero
409+ b = appendUint64 (b , d .len )
410+ return b , nil
411+ }
412+
413+ func (d * digest ) UnmarshalBinary (b []byte ) error {
414+ if len (b ) < len (magic256 ) || string (b [:len (magic256 )]) != magic256 {
415+ return errors .New ("crypto/sha256: invalid hash state identifier" )
416+ }
417+ if len (b ) != marshaledSize {
418+ return errors .New ("crypto/sha256: invalid hash state size" )
419+ }
420+ b = b [len (magic256 ):]
421+ b , d .h [0 ] = consumeUint32 (b )
422+ b , d .h [1 ] = consumeUint32 (b )
423+ b , d .h [2 ] = consumeUint32 (b )
424+ b , d .h [3 ] = consumeUint32 (b )
425+ b , d .h [4 ] = consumeUint32 (b )
426+ b , d .h [5 ] = consumeUint32 (b )
427+ b , d .h [6 ] = consumeUint32 (b )
428+ b , d .h [7 ] = consumeUint32 (b )
429+ b = b [copy (d .x [:], b ):]
430+ b , d .len = consumeUint64 (b )
431+ d .nx = int (d .len % chunk )
432+ return nil
433+ }
434+
435+ func appendUint32 (b []byte , v uint32 ) []byte {
436+ return append (b ,
437+ byte (v >> 24 ),
438+ byte (v >> 16 ),
439+ byte (v >> 8 ),
440+ byte (v ),
441+ )
442+ }
443+
444+ func appendUint64 (b []byte , v uint64 ) []byte {
445+ return append (b ,
446+ byte (v >> 56 ),
447+ byte (v >> 48 ),
448+ byte (v >> 40 ),
449+ byte (v >> 32 ),
450+ byte (v >> 24 ),
451+ byte (v >> 16 ),
452+ byte (v >> 8 ),
453+ byte (v ),
454+ )
455+ }
456+
457+ func consumeUint64 (b []byte ) ([]byte , uint64 ) {
458+ _ = b [7 ]
459+ x := uint64 (b [7 ]) | uint64 (b [6 ])<< 8 | uint64 (b [5 ])<< 16 | uint64 (b [4 ])<< 24 |
460+ uint64 (b [3 ])<< 32 | uint64 (b [2 ])<< 40 | uint64 (b [1 ])<< 48 | uint64 (b [0 ])<< 56
461+ return b [8 :], x
462+ }
463+
464+ func consumeUint32 (b []byte ) ([]byte , uint32 ) {
465+ _ = b [3 ]
466+ x := uint32 (b [3 ]) | uint32 (b [2 ])<< 8 | uint32 (b [1 ])<< 16 | uint32 (b [0 ])<< 24
467+ return b [4 :], x
468+ }
0 commit comments