Skip to content

Commit

Permalink
Add labeled hash helper functions for hashing data
Browse files Browse the repository at this point in the history
  • Loading branch information
dhaavi committed Jul 8, 2022
1 parent 6889bbd commit 62077ee
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
16 changes: 16 additions & 0 deletions lhash/algs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package lhash
import (
"crypto"
"hash"
"io"

// Register SHA2 in Go's internal registry.
_ "crypto/sha256"
Expand Down Expand Up @@ -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)
}
45 changes: 43 additions & 2 deletions lhash/labeledhash.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package lhash

import (
"bufio"
"crypto/subtle"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"io"
"os"

"github.com/mr-tron/base58"

Expand All @@ -21,15 +24,43 @@ 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,
digest: hasher.Sum(nil),
}
}

// 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)
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit 62077ee

Please sign in to comment.