github.com/theQRL/go-zond@v0.1.1/beacon/merkle/merkle.go (about) 1 // Copyright 2022 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package merkle implements proof verifications in binary merkle trees. 18 package merkle 19 20 import ( 21 "crypto/sha256" 22 "errors" 23 "reflect" 24 25 "github.com/theQRL/go-zond/common" 26 "github.com/theQRL/go-zond/common/hexutil" 27 ) 28 29 // Value represents either a 32 byte leaf value or hash node in a binary merkle tree/partial proof. 30 type Value [32]byte 31 32 // Values represent a series of merkle tree leaves/nodes. 33 type Values []Value 34 35 var valueT = reflect.TypeOf(Value{}) 36 37 // UnmarshalJSON parses a merkle value in hex syntax. 38 func (m *Value) UnmarshalJSON(input []byte) error { 39 return hexutil.UnmarshalFixedJSON(valueT, input, m[:]) 40 } 41 42 // VerifyProof verifies a Merkle proof branch for a single value in a 43 // binary Merkle tree (index is a generalized tree index). 44 func VerifyProof(root common.Hash, index uint64, branch Values, value Value) error { 45 hasher := sha256.New() 46 for _, sibling := range branch { 47 hasher.Reset() 48 if index&1 == 0 { 49 hasher.Write(value[:]) 50 hasher.Write(sibling[:]) 51 } else { 52 hasher.Write(sibling[:]) 53 hasher.Write(value[:]) 54 } 55 hasher.Sum(value[:0]) 56 if index >>= 1; index == 0 { 57 return errors.New("branch has extra items") 58 } 59 } 60 if index != 1 { 61 return errors.New("branch is missing items") 62 } 63 if common.Hash(value) != root { 64 return errors.New("root mismatch") 65 } 66 return nil 67 }