hashchain

package module
v0.0.0-...-31f9f54 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2023 License: MIT Imports: 6 Imported by: 4

README

go-hashchain: Verify a file changed the same way over generations

hashchain is not blockchain or a merkle tree, it is something much simpler. I needed to track whether a file changed over a time the same way over many generations. The verifiability of the "chain" is not as important as the changes that the chain consists of.

Thus, this library was born. It's crypto built on somewhat solid foundations but it's still my crypto and I am not a cryptographer. I don't suggest you use it without evaluating what you need it for with a very critical eye.

Usage

// let's make two chains so we can show some things.
c1 := &Chain{}
c2 := &Chain{}

// the sum is yielded for the current provided buffer as a convenience for
// third-party tracking. Any hash.Hash interface works as a digest algorithm.

// we'll sum the same thing twice at first
sum, err := c1.Add(bytes.NewBuffer([]byte("buffer")), sha512.New())
if err != nil {
  log.Fatal(err)
}

sum, err = c2.Add(bytes.NewBuffer([]byte("buffer")), sha512.New())
if err != nil {
  log.Fatal(err)
}

// and one more time, for posterity's sake
sum, err = c1.Add(bytes.NewBuffer([]byte("buffer2")), sha512.New())
if err != nil {
  log.Fatal(err)
}

sum, err = c2.Add(bytes.NewBuffer([]byte("buffer2")), sha512.New())
if err != nil {
  log.Fatal(err)
}

// and now, we'll generate a mismatch
sum, err = c1.Add(bytes.NewBuffer([]byte("buffer1-1")), sha512.New())
if err != nil {
  log.Fatal(err)
}

sum, err = c2.Add(bytes.NewBuffer([]byte("buffer1-2")), sha512.New())
if err != nil {
  log.Fatal(err)
}

// difference functions. if the chains don't match at all, you'll get an error

// will return a chain containing c2's hashes, starting right after the first hash
chain, err := c1.FirstMatch(c2)

// will return a chain containing c2's hashes, starting right after the last hash
chain, err = c1.LastMatch(c2)

// we can tell the chains are different by comparing the sum of the entire chain:

fmt.Println(c1.Sum(sha512.New()) == c2.Sum(sha512.New()))

Author

Erik Hollensbe erik+github@hollensbe.org

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoMatch = errors.New("Chains do not match")
)

Functions

This section is empty.

Types

type Chain

type Chain struct {
	// contains filtered or unexported fields
}

Chain is a chain of sums iconifying generational changes to a single file, so that you can trace the origin of divergence later. Add to the Chain with the Add() function.

func (*Chain) Add

func (c *Chain) Add(r io.Reader, h hash.Hash) (string, error)

Add a file's sum to the chain. Returns the hex encoded sum for convenience. Always use the same hash.Hash type, but never the same object, with this function.

func (*Chain) AddInline

func (c *Chain) AddInline(w io.Writer, r io.Reader, h hash.Hash) (string, error)

Same as Add(), but also write it to the writer in the process. The sum is returned along with any error.

func (*Chain) AllSums

func (c *Chain) AllSums() []string

Obtain the list of sums this chain possesses. Useful for marshaling.

func (*Chain) FirstMatch

func (c *Chain) FirstMatch(c2 *Chain) (*Chain, error)

Find the first match in the provided chain; returns the passed chain that follows the match.

func (*Chain) LastMatch

func (c *Chain) LastMatch(c2 *Chain) (*Chain, error)

Find the last match in the provided chain; returns the passed chain that follows the match, which may be empty.

func (*Chain) Sum

func (c *Chain) Sum(h hash.Hash) (string, error)

Sum the entire chain's sums. Useful for quickly determining a mismatch.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL