github.com/dusk-network/dusk-crypto@v0.1.3/hash/hash.go (about)

     1  package hash
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/binary"
     6  	"errors"
     7  	"hash"
     8  	"strconv"
     9  
    10  	"github.com/OneOfOne/xxhash"
    11  	"golang.org/x/crypto/blake2b"
    12  	"golang.org/x/crypto/sha3"
    13  )
    14  
    15  // Hash is a convenient alias of hash.Hash
    16  type Hash = hash.Hash
    17  
    18  // Blake2b256 performs a Blake2 hashing of a binary payload
    19  func Blake2b256(bs []byte) ([]byte, error) {
    20  	h, err := blake2b.New256(nil)
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  	return PerformHash(h, bs)
    25  }
    26  
    27  // Blake2b512 performs a Blake2 hashing of a binary payload
    28  func Blake2b512(bs []byte) ([]byte, error) {
    29  	h, err := blake2b.New512(nil)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	return PerformHash(h, bs)
    34  }
    35  
    36  // Sha3256 takes a byte slice
    37  // and returns the SHA3-256 hash
    38  func Sha3256(bs []byte) ([]byte, error) {
    39  	return PerformHash(sha3.New256(), bs)
    40  }
    41  
    42  // PerformHash takes a generic hash.Hash and returns the hashed payload
    43  func PerformHash(H Hash, bs []byte) ([]byte, error) {
    44  	_, err := H.Write(bs)
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  	return H.Sum(nil), err
    49  }
    50  
    51  // Sha3512 takes a byte slice
    52  // and returns the SHA3-512 hash
    53  func Sha3512(bs []byte) ([]byte, error) {
    54  	return PerformHash(sha3.New512(), bs)
    55  }
    56  
    57  // Xxhash uses 64 bit xxhashing. It is not meant as a trapdoor, but as a fast collision resistant hashing for performant equal check and store retrieval
    58  func Xxhash(bs []byte) ([]byte, error) {
    59  	return PerformHash(xxhash.New64(), bs)
    60  }
    61  
    62  // RandEntropy takes a uint32 argument n and populates a byte slice of
    63  // size n with random input.
    64  func RandEntropy(n uint32) ([]byte, error) {
    65  
    66  	b := make([]byte, n)
    67  	a, err := rand.Read(b)
    68  
    69  	if err != nil {
    70  		return nil, errors.New("Error generating entropy " + err.Error())
    71  	}
    72  	if uint32(a) != n {
    73  		return nil, errors.New("Error expected to read" + strconv.Itoa(int(n)) + " bytes instead read " + strconv.Itoa(a) + " bytes")
    74  	}
    75  	return b, nil
    76  }
    77  
    78  //CompareChecksum takes data and an expected checksum
    79  // Returns true if the checksum of the given data is
    80  // equal to the expected checksum
    81  func CompareChecksum(data []byte, want uint32) bool {
    82  	got, err := Checksum(data)
    83  	if err != nil {
    84  		return false
    85  	}
    86  	if got != want {
    87  		return false
    88  	}
    89  	return true
    90  }
    91  
    92  // Checksum hashes the data with Xxhash
    93  // and returns the first four bytes
    94  func Checksum(data []byte) (uint32, error) {
    95  	hash, err := Xxhash(data)
    96  	if err != nil {
    97  		return 0, err
    98  	}
    99  	checksum := binary.BigEndian.Uint32(hash[:4])
   100  	return checksum, err
   101  }