package  sha256 
 
import  ( 
	"crypto/internal/fips140"  
	"crypto/internal/fips140deps/byteorder"  
	"errors"  
	"hash"  
) 
 
 
const  size = 32  
 
 
const  size224 = 28  
 
 
const  blockSize = 64  
 
 
 
const  maxAsmIters = 1024  
const  maxAsmSize = blockSize  * maxAsmIters   
 
const  ( 
	chunk     = 64  
	init0     = 0x6A09E667  
	init1     = 0xBB67AE85  
	init2     = 0x3C6EF372  
	init3     = 0xA54FF53A  
	init4     = 0x510E527F  
	init5     = 0x9B05688C  
	init6     = 0x1F83D9AB  
	init7     = 0x5BE0CD19  
	init0_224 = 0xC1059ED8  
	init1_224 = 0x367CD507  
	init2_224 = 0x3070DD17  
	init3_224 = 0xF70E5939  
	init4_224 = 0xFFC00B31  
	init5_224 = 0x68581511  
	init6_224 = 0x64F98FA7  
	init7_224 = 0xBEFA4FA4  
) 
 
 
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 ) { 
	return  d .AppendBinary (make ([]byte , 0 , marshaledSize )) 
} 
 
func  (d  *Digest ) AppendBinary (b  []byte ) ([]byte , error ) { 
	if  d .is224  { 
		b  = append (b , magic224 ...) 
	} else  { 
		b  = append (b , magic256 ...) 
	} 
	b  = byteorder .BEAppendUint32 (b , d .h [0 ]) 
	b  = byteorder .BEAppendUint32 (b , d .h [1 ]) 
	b  = byteorder .BEAppendUint32 (b , d .h [2 ]) 
	b  = byteorder .BEAppendUint32 (b , d .h [3 ]) 
	b  = byteorder .BEAppendUint32 (b , d .h [4 ]) 
	b  = byteorder .BEAppendUint32 (b , d .h [5 ]) 
	b  = byteorder .BEAppendUint32 (b , d .h [6 ]) 
	b  = byteorder .BEAppendUint32 (b , d .h [7 ]) 
	b  = append (b , d .x [:d .nx ]...) 
	b  = append (b , make ([]byte , len (d .x )-d .nx )...) 
	b  = byteorder .BEAppendUint64 (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  consumeUint64(b  []byte ) ([]byte , uint64 ) { 
	return  b [8 :], byteorder .BEUint64 (b ) 
} 
 
func  consumeUint32(b  []byte ) ([]byte , uint32 ) { 
	return  b [4 :], byteorder .BEUint32 (b ) 
} 
 
func  (d  *Digest ) Clone () (hash .Cloner , error ) { 
	r  := *d  
	return  &r , nil  
} 
 
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  
} 
 
 
func  New  () *Digest  { 
	d  := new (Digest ) 
	d .Reset () 
	return  d  
} 
 
 
func  New224  () *Digest  { 
	d  := new (Digest ) 
	d .is224  = true  
	d .Reset () 
	return  d  
} 
 
func  (d  *Digest ) Size () int  { 
	if  !d .is224  { 
		return  size  
	} 
	return  size224  
} 
 
func  (d  *Digest ) BlockSize () int  { return  blockSize  } 
 
func  (d  *Digest ) Write (p  []byte ) (nn  int , err  error ) { 
	nn  = len (p ) 
	d .len  += uint64 (nn ) 
	if  d .nx  > 0  { 
		n  := copy (d .x [d .nx :], p ) 
		d .nx  += n  
		if  d .nx  == chunk  { 
			block (d , d .x [:]) 
			d .nx  = 0  
		} 
		p  = p [n :] 
	} 
	if  len (p ) >= chunk  { 
		n  := len (p ) &^ (chunk  - 1 ) 
		for  n  > maxAsmSize  { 
			block (d , p [:maxAsmSize ]) 
			p  = p [maxAsmSize :] 
			n  -= maxAsmSize  
		} 
		block (d , p [:n ]) 
		p  = p [n :] 
	} 
	if  len (p ) > 0  { 
		d .nx  = copy (d .x [:], p ) 
	} 
	return  
} 
 
func  (d  *Digest ) Sum (in  []byte ) []byte  { 
	fips140 .RecordApproved () 
	 
	d0  := *d  
	hash  := d0 .checkSum () 
	if  d0 .is224  { 
		return  append (in , hash [:size224 ]...) 
	} 
	return  append (in , hash [:]...) 
} 
 
func  (d  *Digest ) checkSum () [size ]byte  { 
	len  := d .len  
	 
	var  tmp  [64  + 8 ]byte   
	tmp [0 ] = 0x80  
	var  t  uint64  
	if  len %64  < 56  { 
		t  = 56  - len %64  
	} else  { 
		t  = 64  + 56  - len %64  
	} 
 
	 
	len  <<= 3  
	padlen  := tmp [:t +8 ] 
	byteorder .BEPutUint64 (padlen [t +0 :], len ) 
	d .Write (padlen ) 
 
	if  d .nx  != 0  { 
		panic ("d.nx != 0" ) 
	} 
 
	var  digest  [size ]byte  
 
	byteorder .BEPutUint32 (digest [0 :], d .h [0 ]) 
	byteorder .BEPutUint32 (digest [4 :], d .h [1 ]) 
	byteorder .BEPutUint32 (digest [8 :], d .h [2 ]) 
	byteorder .BEPutUint32 (digest [12 :], d .h [3 ]) 
	byteorder .BEPutUint32 (digest [16 :], d .h [4 ]) 
	byteorder .BEPutUint32 (digest [20 :], d .h [5 ]) 
	byteorder .BEPutUint32 (digest [24 :], d .h [6 ]) 
	if  !d .is224  { 
		byteorder .BEPutUint32 (digest [28 :], d .h [7 ]) 
	} 
 
	return  digest  
} 
  
The pages are generated with Golds   v0.7.9-preview . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .