func (hash *Hash) Clone() *Hash {
	return &Hash{h: hash.h.Clone()}
}
Clone returns a copy of the Hash in its current state.
package hash
import (
	"encoding"
	"errors"
	"fmt"
	"io"
	"math/big"
	"reflect"
	"github.com/taurusgroup/multi-party-sig/internal/params"
	"github.com/zeebo/blake3"
)
const DigestLengthBytes = params.SecBytes * 2  
type Hash struct {
	h *blake3.Hasher
}
func New(initialData ...WriterToWithDomain) *Hash {
	hash := &Hash{h: blake3.New()}
	_, _ = hash.h.WriteString("CMP-BLAKE")
	for _, d := range initialData {
		_ = hash.WriteAny(d)
	}
	return hash
}
func (hash *Hash) Digest() io.Reader {
	return hash.h.Digest()
}
func (hash *Hash) Sum() []byte {
	out := make([]byte, DigestLengthBytes)
	if _, err := io.ReadFull(hash.Digest(), out); err != nil {
		panic(fmt.Sprintf("hash.ReadBytes: internal hash failure: %v", err))
	}
	return out
}
func (hash *Hash) WriteAny(data ...interface{}) error {
	var toBeWritten WriterToWithDomain
	for _, d := range data {
		switch t := d.(type) {
		case []byte:
			if t == nil {
				return errors.New("hash.WriteAny: nil []byte")
			}
			toBeWritten = &BytesWithDomain{"[]byte", t}
		case *big.Int:
			if t == nil {
				return fmt.Errorf("hash.Hash: write *big.Int: nil")
			}
			bytes, _ := t.GobEncode()
			toBeWritten = &BytesWithDomain{"big.Int", bytes}
		case WriterToWithDomain:
			toBeWritten = t
		case encoding.BinaryMarshaler:
			name := reflect.TypeOf(t)
			bytes, err := t.MarshalBinary()
			if err != nil {
				return fmt.Errorf("hash.WriteAny: %s: %w", name.String(), err)
			}
			toBeWritten = &BytesWithDomain{
				TheDomain: name.String(),
				Bytes:     bytes,
			}
		default:
			fmt.Println(t)
		}
		_, _ = hash.h.WriteString("(")
		_, _ = hash.h.WriteString(toBeWritten.Domain())
		_, err := toBeWritten.WriteTo(hash.h)
		_, _ = hash.h.WriteString(")")
		if err != nil {
			return fmt.Errorf("hash.WriteAny: %s: %w", toBeWritten.Domain(), err)
		}
	}
	return nil
}