github.com/tunabay/go-bitarray@v1.3.1/bitarray_sha256.go (about) 1 // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved. 2 // Use of this source code is governed by the MIT license that can be found in 3 // the LICENSE file. 4 5 package bitarray 6 7 import ( 8 _ "crypto/sha256" // block() 9 "encoding/binary" 10 _ "unsafe" // linkname 11 ) 12 13 // SHA256 returns the SHA-256 checksum of the bit array. It treats the bit array 14 // as a bit-oriented message to compute the checksum as defined in FIPS 180-4. 15 func (ba *BitArray) SHA256() (d256 [32]byte) { 16 return ba.sha256CheckSum(false) 17 } 18 19 // SHA224 returns the SHA-224 checksum of the bit array. It treats the bit array 20 // as a bit-oriented message to compute the checksum as defined in FIPS 180-4. 21 func (ba *BitArray) SHA224() (d224 [28]byte) { 22 d256 := ba.sha256CheckSum(true) 23 copy(d224[:], d256[:]) 24 return 25 } 26 27 func (ba *BitArray) sha256CheckSum(is224 bool) [32]byte { 28 nBits := ba.Len() 29 buf := NewBuffer((nBits + 1 + 64 + 511) &^ 511) 30 buf.PutBitArrayAt(0, ba) 31 buf.PutBitAt(nBits, 1) 32 binary.BigEndian.PutUint64(buf.b[len(buf.b)-8:], uint64(nBits)) 33 34 d := &sha256Digest{is224: is224} 35 sha256Reset(d) 36 sha256Block(d, buf.b) 37 38 n := 8 39 if is224 { 40 n = 7 41 } 42 var d256 [32]byte 43 for i := 0; i < n; i++ { 44 binary.BigEndian.PutUint32(d256[i<<2:], d.h[i]) 45 } 46 47 return d256 48 } 49 50 // crypto/sha256.digest 51 // TODO: if possible, use crypto/sha256.digest directly 52 type sha256Digest struct { 53 h [8]uint32 54 x [64]byte //nolint:structcheck,unused // for Reset() 55 nx int //nolint:structcheck,unused // for Reset() 56 len uint64 //nolint:structcheck,unused // for Reset() 57 is224 bool 58 } 59 60 //go:linkname sha256Block crypto/sha256.block 61 func sha256Block(*sha256Digest, []byte) 62 63 //go:linkname sha256Reset crypto/sha256.(*digest).Reset 64 func sha256Reset(*sha256Digest)