// Copyright (C) 2022 Opsmate, Inc. // // This Source Code Form is subject to the terms of the Mozilla // Public License, v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // // This software is distributed WITHOUT A WARRANTY OF ANY KIND. // See the Mozilla Public License for details. package merkletree import ( "crypto/sha256" "encoding/base64" "encoding/json" "fmt" ) const HashLen = 32 type Hash [HashLen]byte func (h Hash) Base64String() string { return base64.StdEncoding.EncodeToString(h[:]) } func (h Hash) MarshalJSON() ([]byte, error) { return json.Marshal(h[:]) } func (h Hash) MarshalBinary() ([]byte, error) { return h[:], nil } func (h *Hash) UnmarshalJSON(b []byte) error { var hashBytes []byte if err := json.Unmarshal(b, &hashBytes); err != nil { return err } return h.UnmarshalBinary(hashBytes) } func (h *Hash) UnmarshalBinary(hashBytes []byte) error { if len(hashBytes) != HashLen { return fmt.Errorf("Merkle Tree hash has wrong length (should be %d bytes long, not %d)", HashLen, len(hashBytes)) } copy(h[:], hashBytes) return nil } func HashNothing() Hash { return sha256.Sum256(nil) } func HashLeaf(leafBytes []byte) Hash { var hash Hash hasher := sha256.New() hasher.Write([]byte{0x00}) hasher.Write(leafBytes) hasher.Sum(hash[:0]) return hash } func HashChildren(left Hash, right Hash) Hash { var hash Hash hasher := sha256.New() hasher.Write([]byte{0x01}) hasher.Write(left[:]) hasher.Write(right[:]) hasher.Sum(hash[:0]) return hash }