Skip to content

Commit

Permalink
add Hasher api. saves on hash output buffer creation. also, re-use in…
Browse files Browse the repository at this point in the history
…terior node hash buffer in VerifyProof, where it's easiest to do. note: multiple calls to Hasher.Write (for a few 32-byte bufs) were actually slower than appending them and calling hash once. note: doesn't save to reset Hasher since reset clones hasher state.
  • Loading branch information
sanjit-bhat committed Feb 7, 2025
1 parent 33f8426 commit b85ea47
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 13 deletions.
24 changes: 22 additions & 2 deletions cryptoffi/cryptoffi.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/rand"
"crypto/sha256"
"github.com/mit-pdos/pav/cryptoffi/vrf"
"hash"
)

const (
Expand All @@ -14,8 +15,27 @@ const (
// # Hash

func Hash(data []byte) []byte {
hash := sha256.Sum256(data)
return hash[:]
h := sha256.Sum256(data)
return h[:]
}

type Hasher struct {
h hash.Hash
}

func NewHasher() *Hasher {
return &Hasher{sha256.New()}
}

func (hr *Hasher) Write(b []byte) {
_, err := hr.h.Write(b)
if err != nil {
panic("cryptoffi: Hasher.Write err")
}
}

func (hr *Hasher) Sum(b []byte) []byte {
return hr.h.Sum(b)
}

// # Signature
Expand Down
24 changes: 13 additions & 11 deletions merkle2/merkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,22 @@ func VerifyProof(inTree bool, label, val []byte, proof *Proof, dig []byte) bool

// compute hash up the tree.
var depth = maxDepth
var hashBuf = make([]byte, 0, 2*cryptoffi.HashLen+1)
// depth offset by one to prevent underflow.
for depth >= 1 {
begin := (depth - 1) * cryptoffi.HashLen
end := depth * cryptoffi.HashLen
sib := proof.siblings[begin:end]

if !getBit(label, depth-1) {
// TODO: could reuse and reset hasher state across these calls,
// along with in put calls.
// could also re-use output hash slice here.
currHash = compInteriorHash(currHash, sib)
hashBuf = setInteriorHashBuf(hashBuf, currHash, sib)
} else {
currHash = compInteriorHash(sib, currHash)
hashBuf = setInteriorHashBuf(hashBuf, sib, currHash)
}
hr := cryptoffi.NewHasher()
hr.Write(hashBuf)
hashBuf = hashBuf[:0]
currHash = hr.Sum(currHash)
depth--
}

Expand Down Expand Up @@ -239,17 +242,16 @@ func compLeafHash(label, val []byte) []byte {
func setInteriorHash(n *node, c *cache) {
child0 := getNodeHash(n.child0, c)
child1 := getNodeHash(n.child1, c)
n.hash = compInteriorHash(child0, child1)
var b = make([]byte, 0, 2*cryptoffi.HashLen+1)
b = setInteriorHashBuf(b, child0, child1)
n.hash = cryptoffi.Hash(b)
}

func compInteriorHash(child0, child1 []byte) []byte {
// TODO: compare this against using stateful hash api.
// should be no memcpy into b.
var b = make([]byte, 0, 2*cryptoffi.HashLen+1)
func setInteriorHashBuf(b []byte, child0, child1 []byte) []byte {
b = append(b, child0...)
b = append(b, child1...)
b = append(b, interiorNodeTag)
return cryptoffi.Hash(b)
return b
}

// getChild returns a child and its sibling child,
Expand Down

0 comments on commit b85ea47

Please sign in to comment.