github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/merkle/types.go (about)

     1  package merkle
     2  
     3  import (
     4  	"crypto/sha512"
     5  
     6  	"github.com/keybase/client/go/msgpack"
     7  	"github.com/keybase/client/go/protocol/keybase1"
     8  	"github.com/keybase/client/go/sig3"
     9  	merkletree "github.com/keybase/go-merkle-tree"
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  type TreeSeqno int64
    14  
    15  type EncodingType byte
    16  
    17  const (
    18  	EncodingTypeBlindedSHA512_256v1 EncodingType = 1 // p = HMAC-SHA512-256; (k, v) -> (k, p(p(k, s), v)) where s is a secret unique per Merkle seqno
    19  )
    20  
    21  const CurrentEncodingType = EncodingTypeBlindedSHA512_256v1
    22  
    23  func GetTreeConfig(encodingType EncodingType) (merkletree.Config, error) {
    24  	if encodingType == EncodingTypeBlindedSHA512_256v1 {
    25  		return merkletree.NewConfig(SHA512_256Hasher{}, 32, 64, EncodedLeaf{}), nil
    26  	}
    27  	return merkletree.Config{}, errors.Errorf("unknown encoding type %q", encodingType)
    28  }
    29  
    30  type EncodedLeaf []byte
    31  
    32  var _ merkletree.ValueConstructor = (*EncodedLeaf)(nil)
    33  
    34  func (l EncodedLeaf) Construct() interface{} {
    35  	return &[]byte{}
    36  }
    37  
    38  type LeafType uint16
    39  
    40  const (
    41  	LeafTypeTeamv1 = 1
    42  )
    43  
    44  type LeafBytes []byte
    45  type LeafContainer struct {
    46  	_struct   bool      `codec:",toarray"` //nolint
    47  	LeafType  LeafType  // specifies structure of leafBytes
    48  	LeafBytes LeafBytes // msgpack deserialization implements Leaf
    49  }
    50  
    51  func NewLeafContainer(leafType LeafType, leafBytes LeafBytes) LeafContainer {
    52  	return LeafContainer{LeafType: leafType, LeafBytes: leafBytes}
    53  }
    54  
    55  func (c LeafContainer) Serialize() ([]byte, error) {
    56  	return msgpack.EncodeCanonical(c)
    57  }
    58  
    59  type ID []byte
    60  type Revelations map[keybase1.SeqType]keybase1.Seqno
    61  
    62  type Leaf interface {
    63  	Serialize() ([]byte, error)
    64  	Type() LeafType
    65  	ID() ID
    66  	GetRevelations() Revelations
    67  }
    68  
    69  type SigID []byte
    70  type Teamv1HiddenTail struct {
    71  	_struct bool `codec:",toarray"` //nolint
    72  	SigID   SigID
    73  	LinkID  sig3.LinkID
    74  	Seqno   keybase1.Seqno
    75  }
    76  
    77  type Teamv1Leaf struct {
    78  	_struct bool `codec:",toarray"` //nolint
    79  	// do not encode teamID; it's redundant in the tree
    80  	TeamID sig3.TeamID `codec:"-"`
    81  	Tails  map[keybase1.SeqType]Teamv1HiddenTail
    82  }
    83  
    84  var _ Leaf = (*Teamv1Leaf)(nil)
    85  
    86  func (l Teamv1Leaf) Serialize() ([]byte, error) {
    87  	return msgpack.EncodeCanonical(l)
    88  }
    89  
    90  func (l Teamv1Leaf) Type() LeafType {
    91  	return LeafTypeTeamv1
    92  }
    93  
    94  func (l Teamv1Leaf) ID() ID {
    95  	return ID(l.TeamID[:])
    96  }
    97  
    98  func (l Teamv1Leaf) GetRevelations() Revelations {
    99  	m := make(map[keybase1.SeqType]keybase1.Seqno)
   100  	for chainType, tail := range l.Tails {
   101  		m[chainType] = tail.Seqno
   102  	}
   103  	return m
   104  }
   105  
   106  func ExportLeaf(l Leaf) (LeafContainer, error) {
   107  	b, err := l.Serialize()
   108  	if err != nil {
   109  		return LeafContainer{}, errors.Wrap(err, "failed to serialize leaf")
   110  	}
   111  	return NewLeafContainer(l.Type(), b), nil
   112  }
   113  
   114  type HashMeta []byte
   115  type Skips map[TreeSeqno]HashMeta
   116  type RootHash []byte
   117  
   118  type RootMetadata struct {
   119  	_struct      bool         `codec:",toarray"` //nolint
   120  	EncodingType EncodingType `codec:"e"`
   121  	Seqno        TreeSeqno    `codec:"s"`
   122  	Skips        Skips        `codec:"t"` // includes prev
   123  	Hash         RootHash     `codec:"r"`
   124  }
   125  
   126  func (r RootMetadata) EncodingAndHashMeta() (encoding []byte, hashMeta HashMeta, err error) {
   127  	b, err := msgpack.EncodeCanonical(r)
   128  	if err != nil {
   129  		return nil, nil, err
   130  	}
   131  	h := sha512.Sum512_256(b)
   132  	return b, h[:], nil
   133  }
   134  
   135  func (r RootMetadata) HashMeta() (HashMeta, error) {
   136  	_, hashMeta, err := r.EncodingAndHashMeta()
   137  	return hashMeta, err
   138  }
   139  
   140  type BlindedEntropy []byte
   141  
   142  type BlindedPreimage struct {
   143  	LeafContainer  LeafContainer
   144  	BlindedEntropy BlindedEntropy
   145  }
   146  
   147  func NewBlindedPreimage(leaf Leaf, blindedEntropy BlindedEntropy) (BlindedPreimage, error) {
   148  	container, err := ExportLeaf(leaf)
   149  	if err != nil {
   150  		return BlindedPreimage{}, err
   151  	}
   152  	return BlindedPreimage{LeafContainer: container, BlindedEntropy: blindedEntropy}, nil
   153  }
   154  
   155  type Skiplist = []RootMetadata
   156  type Path = []merkletree.Node
   157  type QueryResponse struct {
   158  	RootMetadata    RootMetadata    `codec:"r,omitempty"`
   159  	Path            Path            `codec:"p,omitempty"`
   160  	BlindedPreimage BlindedPreimage `codec:"v,omitempty"`
   161  	Skiplists       []Skiplist      `codec:"s,omitempty"`
   162  }
   163  type HistoricalQueryResponse struct {
   164  	RootMetadata     RootMetadata      `codec:"r,omitempty"`
   165  	Paths            []Path            `codec:"p,omitempty"`
   166  	BlindedPreimages []BlindedPreimage `codec:"v,omitempty"`
   167  	Skiplists        []Skiplist        `codec:"s,omitempty"`
   168  }
   169  
   170  type Key struct {
   171  	Key []byte
   172  }
   173  
   174  func NewKey(key []byte) Key {
   175  	return Key{Key: key}
   176  }
   177  
   178  type Secret struct {
   179  	Secret []byte
   180  }
   181  
   182  func NewSecret(secret []byte) Secret {
   183  	return Secret{Secret: secret}
   184  }