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  }