diff --git a/core/crypto/hash.go b/core/crypto/hash.go new file mode 100644 index 000000000..00abf93dd --- /dev/null +++ b/core/crypto/hash.go @@ -0,0 +1,5 @@ +package crypto + +import "github.com/NethermindEth/juno/core/felt" + +type HashFn func(*felt.Felt, *felt.Felt) *felt.Felt diff --git a/core/trie/node.go b/core/trie/node.go index 2ef176f92..172869cb1 100644 --- a/core/trie/node.go +++ b/core/trie/node.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" + "github.com/NethermindEth/juno/core/crypto" "github.com/NethermindEth/juno/core/felt" ) @@ -19,7 +20,7 @@ type Node struct { } // Hash calculates the hash of a [Node] -func (n *Node) Hash(path *Key, hashFunc hashFunc) *felt.Felt { +func (n *Node) Hash(path *Key, hashFn crypto.HashFn) *felt.Felt { if path.Len() == 0 { // we have to deference the Value, since the Node can released back // to the NodePool and be reused anytime @@ -28,15 +29,15 @@ func (n *Node) Hash(path *Key, hashFunc hashFunc) *felt.Felt { } pathFelt := path.Felt() - hash := hashFunc(n.Value, &pathFelt) + hash := hashFn(n.Value, &pathFelt) pathFelt.SetUint64(uint64(path.Len())) return hash.Add(hash, &pathFelt) } // Hash calculates the hash of a [Node] -func (n *Node) HashFromParent(parentKey, nodeKey *Key, hashFunc hashFunc) *felt.Felt { +func (n *Node) HashFromParent(parentKey, nodeKey *Key, hashFn crypto.HashFn) *felt.Felt { path := path(nodeKey, parentKey) - return n.Hash(&path, hashFunc) + return n.Hash(&path, hashFn) } func (n *Node) WriteTo(buf *bytes.Buffer) (int64, error) { diff --git a/core/trie/proof.go b/core/trie/proof.go index bc4b66d0d..9f1fd3ab1 100644 --- a/core/trie/proof.go +++ b/core/trie/proof.go @@ -16,7 +16,7 @@ func NewProofNodeSet() *ProofNodeSet { } type ProofNode interface { - Hash(hash hashFunc) *felt.Felt + Hash(hash crypto.HashFn) *felt.Felt Len() uint8 String() string } @@ -26,7 +26,7 @@ type Binary struct { RightHash *felt.Felt } -func (b *Binary) Hash(hash hashFunc) *felt.Felt { +func (b *Binary) Hash(hash crypto.HashFn) *felt.Felt { return hash(b.LeftHash, b.RightHash) } @@ -43,7 +43,7 @@ type Edge struct { Path *Key // path from parent to child } -func (e *Edge) Hash(hash hashFunc) *felt.Felt { +func (e *Edge) Hash(hash crypto.HashFn) *felt.Felt { length := make([]byte, len(e.Path.bitset)) length[len(e.Path.bitset)-1] = e.Path.len pathFelt := e.Path.Felt() @@ -137,7 +137,7 @@ func (t *Trie) GetRangeProof(leftKey, rightKey *felt.Felt, proofSet *ProofNodeSe // - Any node's computed hash doesn't match its expected hash // - The path bits don't match the key bits // - The proof ends before processing all key bits -func VerifyProof(root, keyFelt *felt.Felt, proof *ProofNodeSet, hash hashFunc) (*felt.Felt, error) { +func VerifyProof(root, keyFelt *felt.Felt, proof *ProofNodeSet, hash crypto.HashFn) (*felt.Felt, error) { key := FeltToKey(globalTrieHeight, keyFelt) expectedHash := root keyLen := key.Len() diff --git a/core/trie/trie.go b/core/trie/trie.go index c21168c50..5f8a51d9c 100644 --- a/core/trie/trie.go +++ b/core/trie/trie.go @@ -16,8 +16,6 @@ import ( const globalTrieHeight = 251 // TODO(weiihann): this is declared in core also, should be moved to a common place -type hashFunc func(*felt.Felt, *felt.Felt) *felt.Felt - // Trie is a dense Merkle Patricia Trie (i.e., all internal nodes have two children). // // This implementation allows for a "flat" storage by keying nodes on their path rather than @@ -40,7 +38,7 @@ type Trie struct { rootKey *Key maxKey *felt.Felt storage *Storage - hash hashFunc + hash crypto.HashFn dirtyNodes []*Key rootKeyIsDirty bool @@ -56,7 +54,7 @@ func NewTriePoseidon(storage *Storage, height uint8) (*Trie, error) { return newTrie(storage, height, crypto.Poseidon) } -func newTrie(storage *Storage, height uint8, hash hashFunc) (*Trie, error) { +func newTrie(storage *Storage, height uint8, hash crypto.HashFn) (*Trie, error) { if height > felt.Bits { return nil, fmt.Errorf("max trie height is %d, got: %d", felt.Bits, height) }