Add labeled hash helper functions for hashing data

This commit is contained in:
Daniel 2022-07-08 22:32:13 +02:00
parent 6889bbd62e
commit 62077eefb5
2 changed files with 59 additions and 2 deletions

View file

@ -6,6 +6,7 @@ package lhash
import (
"crypto"
"hash"
"io"
// Register SHA2 in Go's internal registry.
_ "crypto/sha256"
@ -83,3 +84,18 @@ func (a Algorithm) new() hash.Hash {
return nil
}
}
// Digest creates a new labeled hash and digests the given data.
func (a Algorithm) Digest(data []byte) *LabeledHash {
return Digest(a, data)
}
// DigestFile creates a new labeled hash and digests the given file.
func (a Algorithm) DigestFile(pathToFile string) (*LabeledHash, error) {
return DigestFile(a, pathToFile)
}
// DigestFromReader creates a new labeled hash and digests from the given reader.
func (a Algorithm) DigestFromReader(alg Algorithm, reader io.Reader) (*LabeledHash, error) {
return DigestFromReader(a, reader)
}

View file

@ -1,11 +1,14 @@
package lhash
import (
"bufio"
"crypto/subtle"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
"github.com/mr-tron/base58"
@ -21,8 +24,8 @@ type LabeledHash struct {
// Digest creates a new labeled hash and digests the given data.
func Digest(alg Algorithm, data []byte) *LabeledHash {
hasher := alg.new()
_, _ = hasher.Write(data) // never returns an error
defer hasher.Reset() // internal state may leak data if kept in memory
_, _ = hasher.Write(data) // Never returns an error.
defer hasher.Reset() // Internal state may leak data if kept in memory.
return &LabeledHash{
alg: alg,
@ -30,6 +33,34 @@ func Digest(alg Algorithm, data []byte) *LabeledHash {
}
}
// DigestFile creates a new labeled hash and digests the given file.
func DigestFile(alg Algorithm, pathToFile string) (*LabeledHash, error) {
// Open file that should be hashed.
file, err := os.OpenFile(pathToFile, os.O_RDONLY, 0)
if err != nil {
return nil, fmt.Errorf("failed to open file: %w", err)
}
return DigestFromReader(alg, file)
}
// DigestFromReader creates a new labeled hash and digests from the given reader.
func DigestFromReader(alg Algorithm, reader io.Reader) (*LabeledHash, error) {
hasher := alg.new()
defer hasher.Reset() // Internal state may leak data if kept in memory.
// Pipe all data directly to the hashing algorithm.
_, err := bufio.NewReader(reader).WriteTo(hasher)
if err != nil {
return nil, fmt.Errorf("failed to read: %w", err)
}
return &LabeledHash{
alg: alg,
digest: hasher.Sum(nil),
}, nil
}
// Load loads a labeled hash from the given []byte slice.
func Load(labeledHash []byte) (*LabeledHash, error) {
c := container.New(labeledHash)
@ -95,6 +126,16 @@ func FromBase58(base58Encoded string) (*LabeledHash, error) {
return Load(raw)
}
// Algorithm returns the algorithm of the labeled hash.
func (lh *LabeledHash) Algorithm() Algorithm {
return lh.alg
}
// Sum returns the raw calculated hash digest.
func (lh *LabeledHash) Sum() []byte {
return lh.digest
}
// Bytes return the []byte representation of the labeled hash.
func (lh *LabeledHash) Bytes() []byte {
c := container.New()