github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/merkletree2/config.go (about)

     1  package merkletree2
     2  
     3  import "fmt"
     4  
     5  // Config defines the shape of the MerkleTree.
     6  type Config struct {
     7  	// An encoder is used to compute hashes in this configuration, and also
     8  	// manages the blinding secrets (see UseBlindedValueHashes).
     9  	Encoder Encoder
    10  
    11  	// UseBlindedValueHashes controls whether this tree blinds hashes of
    12  	// KeyValuePairs with a per (Key,Seqno) specific secret (which is itself
    13  	// derived from a per Seqno specific secret which is stored together with
    14  	// the tree). This ensures values stored in the tree cannot are not leaked
    15  	// by the membership proofs (but keys can leak, as well as the rough tree
    16  	// size). If the tree is rebuilt at every Seqno, this also hides whether
    17  	// values are changing (but not when a value is first inserted).
    18  	UseBlindedValueHashes bool
    19  
    20  	// The number of children per node. Must be a power of two. Some children
    21  	// can be empty.
    22  	ChildrenPerNode int
    23  
    24  	// The maximum number of KeyValuePairs in a leaf node before we split
    25  	MaxValuesPerLeaf int
    26  
    27  	// The number of bits necessary to represent a ChildIndex, i.e.
    28  	// log2(childrenPerNode)
    29  	BitsPerIndex uint8
    30  
    31  	// The length of all the keys which will be stored in the tree. For
    32  	// simplicity, we enforce that all the keys have the same length and that
    33  	// bitsPerIndex divides keyByteLength*8
    34  	KeysByteLength int
    35  
    36  	// The maximum depth of the tree. Should always equal keysByteLength*8/bitsPerIndex
    37  	MaxDepth int
    38  
    39  	// ConstructValueContainer constructs a new empty value for the value in a KeyValuePair, so that the
    40  	// decoding routine has the correct type template.
    41  	ConstructValueContainer func() interface{}
    42  }
    43  
    44  // NewConfig makes a new config object. It takes a a Hasher, logChildrenPerNode
    45  // which is the base 2 logarithm of the number of children per interior node,
    46  // maxValuesPerLeaf the maximum number of entries in a leaf before the leaf is
    47  // split into multiple nodes (at a lower level in the tree), keyByteLength the
    48  // length of the Keys which the tree will store, and a ConstructValueContainer function (so that
    49  // typed values can be pulled out of the Merkle Tree).
    50  func NewConfig(e Encoder, useBlindedValueHashes bool, logChildrenPerNode uint8, maxValuesPerLeaf int, keysByteLength int, constructValueFunc func() interface{}) (Config, error) {
    51  	childrenPerNode := 1 << logChildrenPerNode
    52  	if (keysByteLength*8)%int(logChildrenPerNode) != 0 {
    53  		return Config{}, NewInvalidConfigError("The key bit length does not divide logChildrenPerNode")
    54  	}
    55  	if logChildrenPerNode > 63 {
    56  		return Config{}, NewInvalidConfigError("This package does not support more than 2^63 children per internal node")
    57  	}
    58  	if logChildrenPerNode < 1 {
    59  		return Config{}, NewInvalidConfigError(fmt.Sprintf("Need at least 2 children per node, but logChildrenPerNode = %v", logChildrenPerNode))
    60  	}
    61  	maxDepth := keysByteLength * 8 / int(logChildrenPerNode)
    62  	return Config{Encoder: e, UseBlindedValueHashes: useBlindedValueHashes, ChildrenPerNode: childrenPerNode, MaxValuesPerLeaf: maxValuesPerLeaf, BitsPerIndex: logChildrenPerNode, KeysByteLength: keysByteLength, MaxDepth: maxDepth, ConstructValueContainer: constructValueFunc}, nil
    63  }
    64  
    65  // MasterSecret is a secret used to hide wether a leaf value has changed between
    66  // different versions (Seqnos) in a blinded merkle tree. One MasterSecret per
    67  // tree is generated for each Seqno, and such secret is then used to generate a
    68  // KeySpecific secret per leaf.
    69  type MasterSecret []byte
    70  
    71  // MasterSecret is a secret used to hide wether a leaf value has changed between
    72  // different versions (Seqnos) in a blinded merkle tree. This is derived from a
    73  // per-Seqno MasterSecret as specified by the Encoder
    74  type KeySpecificSecret []byte
    75  
    76  // Encoder is an interface for cryptographically hashing MerkleTree data
    77  // structures. It also manages blinding secrets.
    78  type Encoder interface {
    79  	Decode(dest interface{}, src []byte) error
    80  	Encode(src interface{}) (dst []byte, err error)
    81  	// takes as input a []byte pointer dst to avoid creating new objects
    82  	EncodeTo(o interface{}, dst *[]byte) (err error)
    83  
    84  	EncodeAndHashGeneric(interface{}) (encoded []byte, hash Hash, err error)
    85  	// takes as input an hash pointer ret to avoid creating new objects
    86  	HashGeneric(o interface{}, ret *Hash) error
    87  
    88  	GenerateMasterSecret(Seqno) (MasterSecret, error)
    89  	ComputeKeySpecificSecret(MasterSecret, Key) KeySpecificSecret
    90  	// takes as input a KeySpecificSecret pointer to avoid creating new objects
    91  	ComputeKeySpecificSecretTo(MasterSecret, Key, *KeySpecificSecret)
    92  
    93  	HashKeyValuePairWithKeySpecificSecret(KeyValuePair, KeySpecificSecret) (Hash, error)
    94  	HashKeyEncodedValuePairWithKeySpecificSecret(KeyEncodedValuePair, KeySpecificSecret) (Hash, error)
    95  	// takes as input an hash pointer ret to avoid creating new objects
    96  	HashKeyEncodedValuePairWithKeySpecificSecretTo(KeyEncodedValuePair, KeySpecificSecret, *Hash) error
    97  
    98  	GetEncodingType() EncodingType
    99  }