github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/merkle/util.go (about) 1 package merkle 2 3 import ( 4 "crypto/sha512" 5 6 merkletree "github.com/keybase/go-merkle-tree" 7 ) 8 9 func ComputeSkipPointers(s TreeSeqno) []TreeSeqno { 10 if s <= 1 { 11 return nil 12 } 13 var skips []TreeSeqno 14 r := TreeSeqno(1) 15 s -= r 16 for s > 0 { 17 skips = append(skips, s) 18 s -= r 19 r *= 2 20 } 21 return skips 22 } 23 24 // computeSkipPath computes a log pattern skip path in reverse 25 // e.g., start=100, end=2033 -> ret = {1009, 497, 241, 113, 105, 101} 26 // such that ret[i+1] \in computeSkipPointers(ret[i]) 27 func ComputeSkipPath(start TreeSeqno, end TreeSeqno) []TreeSeqno { 28 if end <= start { 29 return []TreeSeqno{} 30 } 31 jumps := []TreeSeqno{} 32 diff := end - start 33 z := TreeSeqno(1) 34 for diff > 0 { 35 if diff&1 == 1 { 36 start += z 37 jumps = append(jumps, start) 38 } 39 diff >>= 1 40 z *= 2 41 } 42 43 // array reversal 44 for i := len(jumps)/2 - 1; i >= 0; i-- { 45 opp := len(jumps) - 1 - i 46 jumps[i], jumps[opp] = jumps[opp], jumps[i] 47 } 48 49 return jumps[1:] // ignore end 50 } 51 52 type SHA512_256Hasher struct{} 53 54 var _ merkletree.Hasher = (*SHA512_256Hasher)(nil) 55 56 func (h SHA512_256Hasher) Hash(x []byte) merkletree.Hash { 57 y := sha512.Sum512_256(x) 58 return merkletree.Hash(y[:]) 59 }