func TestHashTimelockSerialize(t *testing.T) {
	var err error
	tlSeed := [32]byte{}
	if _, err = rand.Read(tlSeed[:]); err != nil {
		t.Errorf("Error reading bytes to seed for hashtimelock serialize: %s", err)
		return
	}
	htl := &HashTimelock{
		TimelockSeed: tlSeed[:],
		TimeToRun:    uint64(10000),
	}
	htl.SetHashFunction(sha3.New256())
	var timelockBytes []byte
	if timelockBytes, err = htl.Serialize(); err != nil {
		t.Errorf("Error, this is a valid hashtimelock, serialize should not return an error: %s", err)
		return
	}
	finalHtlPtr := new(HashTimelock)
	if err = finalHtlPtr.Deserialize(timelockBytes); err != nil {
		t.Errorf("Error, deserialization should work for bytes that were just serialized: %s", err)
		return
	}
	if finalHtlPtr.TimeToRun != htl.TimeToRun {
		t.Errorf("TimeToRun for resulting struct is %d but should have been %d", finalHtlPtr.TimeToRun, htl.TimeToRun)
		return
	}
	if bytes.Compare(finalHtlPtr.TimelockSeed, htl.TimelockSeed) != 0 {
		t.Errorf("TimelockSeed for resulting struct is %8x but should be %8x", finalHtlPtr.TimelockSeed, htl.TimelockSeed)
		return
	}
	return
}
TestHashTimelockSerialize tests that a hash timelock, when
serialized and deserialized with gob, doesn't change
package hashtimelock
import (
	"bytes"
	"crypto/rand"
	"crypto/sha256"
	"testing"
	"github.com/btcsuite/fastsha256"
	"github.com/dchest/siphash"
	"github.com/minio/highwayhash"
	"golang.org/x/crypto/blake2b"
	"golang.org/x/crypto/sha3"
)
func TestZeroTimeSHA256(t *testing.T) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxzero"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(0)
	puzzle, _, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		t.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		t.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, seed) {
		t.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, seed, puzzleAns)
	}
}
func TestOneTimeSHA256(t *testing.T) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxone"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(1)
	puzzle, _, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		t.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		t.Fatalf("Error solving puzzle: %s\n", err)
	}
	testSHA := sha256.New()
	if _, err = testSHA.Write(seed); err != nil {
		t.Fatalf("Could not write to hash function: %s\n", err)
	}
	seedSum := testSHA.Sum(nil)
	if !bytes.Equal(puzzleAns, seedSum) {
		t.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, seedSum, puzzleAns)
	}
}
func TestTenTimeSHA256(t *testing.T) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxten"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(10)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		t.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		t.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		t.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func TestHundredTimeSHA256(t *testing.T) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxhundred"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(100)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		t.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		t.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		t.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func TestThousandTimeSHA256(t *testing.T) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxthousand"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(1000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		t.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		t.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		t.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func TestTenThousandTimeSHA256(t *testing.T) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxtenthousand"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(10000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		t.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		t.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		t.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func TestHundredThousandTimeSHA256(t *testing.T) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxhundredthousand"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(100000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		t.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		t.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		t.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func TestMillionTimeSHA256(t *testing.T) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxmillion"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(1000000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		t.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		t.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		t.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func TestTenMillionTimeSHA256(t *testing.T) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxtenmillion"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(10000000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		t.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		t.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		t.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func BenchmarkHundredMillionTimeSHA256(b *testing.B) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxhundredmillion"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(100000000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		b.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		b.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		b.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func BenchmarkHundredMillionTimeFastSHA256(b *testing.B) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxhundredmillion"))
	hashFunction := fastsha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(100000000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		b.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		b.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		b.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func BenchmarkHundredMillionTimeBlake2B(b *testing.B) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxhundredmillion"))
	hashFunction, err := blake2b.New256(nil)
	if err != nil {
		b.Fatalf("Could not set up blake2b: %s\n", err)
	}
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(100000000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		b.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		b.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		b.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func BenchmarkHundredMillionTimeSipHash(b *testing.B) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxhundredmillion"))
	hashFunction := siphash.New(seed)
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(100000000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		b.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		b.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		b.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func BenchmarkHundredMillionTimeHighwayHash(b *testing.B) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxhundredmillion"))
	hashFunction, err := highwayhash.New(seed)
	if err != nil {
		b.Fatalf("Could not create highwayhash: %s\n", err)
	}
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(100000000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		b.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		b.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		b.Fatalf("Answer did not equal puzzle for time = %d. Expected %x, got %x\n", time, expectedAns, puzzleAns)
	}
}
func BenchmarkBillionTimeSHA256(b *testing.B) {
	seed := make([]byte, 32)
	copy(seed[:], []byte("opencxbillion"))
	hashFunction := sha256.New()
	hashPuzzle, _ := New(seed, hashFunction)
	time := uint64(1000000000)
	puzzle, expectedAns, err := hashPuzzle.SetupTimelockPuzzle(time)
	if err != nil {
		b.Fatalf("There was an error setting up the timelock puzzle: %s\n", err)
	}
	puzzleAns, err := puzzle.Solve()
	if err != nil {
		b.Fatalf("Error solving puzzle: %s\n", err)
	}
	if !bytes.Equal(puzzleAns, expectedAns) {
		b.Fatalf("Answer did not equal puzzle for time = 0. Expected %x, got %x\n", expectedAns, puzzleAns)
	}
}