// NOTE: The default hash function is Ripemd160.
func BinaryRipemd160(o interface{}) []byte {
	hasher, n, err := ripemd160.New(), new(int64), new(error)
	WriteBinary(o, hasher, n, err)
	if *err != nil {
		PanicSanity(*err)
	}
	return hasher.Sum(nil)
}
// General Convenience
func SimpleHashFromBinary(item interface{}) []byte {
	hasher, n, err := ripemd160.New(), new(int64), new(error)
	wire.WriteBinary(item, hasher, n, err)
	if *err != nil {
		PanicCrisis(err)
	}
	return hasher.Sum(nil)
}
func (part *Part) Hash() []byte {
	if part.hash != nil {
		return part.hash
	} else {
		hasher := ripemd160.New()
		hasher.Write(part.Bytes) // doesn't err
		part.hash = hasher.Sum(nil)
		return part.hash
	}
}
func SimpleHashFromTwoHashes(left []byte, right []byte) []byte {
	var n int64
	var err error
	var hasher = ripemd160.New()
	wire.WriteByteSlice(left, hasher, &n, &err)
	wire.WriteByteSlice(right, hasher, &n, &err)
	if err != nil {
		PanicCrisis(err)
	}
	return hasher.Sum(nil)
}
func (kv KVPair) Hash() []byte {
	hasher, n, err := ripemd160.New(), new(int64), new(error)
	wire.WriteString(kv.Key, hasher, n, err)
	if kvH, ok := kv.Value.(Hashable); ok {
		wire.WriteByteSlice(kvH.Hash(), hasher, n, err)
	} else {
		wire.WriteBinary(kv.Value, hasher, n, err)
	}
	if *err != nil {
		PanicSanity(*err)
	}
	return hasher.Sum(nil)
}
func (leaf IAVLProofLeafNode) Hash() []byte {
	hasher := ripemd160.New()
	buf := new(bytes.Buffer)
	n, err := int64(0), error(nil)
	wire.WriteInt8(0, buf, &n, &err)
	wire.WriteVarint(1, buf, &n, &err)
	wire.WriteByteSlice(leaf.KeyBytes, buf, &n, &err)
	wire.WriteByteSlice(leaf.ValueBytes, buf, &n, &err)
	if err != nil {
		PanicCrisis(Fmt("Failed to hash IAVLProofLeafNode: %v", err))
	}
	// fmt.Printf("LeafNode hash bytes:   %X\n", buf.Bytes())
	hasher.Write(buf.Bytes())
	return hasher.Sum(nil)
}
// NOTE: sets hashes recursively
func (node *IAVLNode) hashWithCount(t *IAVLTree) ([]byte, int) {
	if node.hash != nil {
		return node.hash, 0
	}

	hasher := ripemd160.New()
	buf := new(bytes.Buffer)
	_, hashCount, err := node.writeHashBytes(t, buf)
	if err != nil {
		PanicCrisis(err)
	}
	// fmt.Printf("Wrote IAVL hash bytes: %X\n", buf.Bytes())
	hasher.Write(buf.Bytes())
	node.hash = hasher.Sum(nil)
	// fmt.Printf("Write IAVL hash: %X\n", node.hash)

	return node.hash, hashCount + 1
}
func (branch IAVLProofInnerNode) Hash(childHash []byte) []byte {
	hasher := ripemd160.New()
	buf := new(bytes.Buffer)
	n, err := int64(0), error(nil)
	wire.WriteInt8(branch.Height, buf, &n, &err)
	wire.WriteVarint(branch.Size, buf, &n, &err)
	if len(branch.Left) == 0 {
		wire.WriteByteSlice(childHash, buf, &n, &err)
		wire.WriteByteSlice(branch.Right, buf, &n, &err)
	} else {
		wire.WriteByteSlice(branch.Left, buf, &n, &err)
		wire.WriteByteSlice(childHash, buf, &n, &err)
	}
	if err != nil {
		PanicCrisis(Fmt("Failed to hash IAVLProofInnerNode: %v", err))
	}
	// fmt.Printf("InnerNode hash bytes: %X\n", buf.Bytes())
	hasher.Write(buf.Bytes())
	return hasher.Sum(nil)
}