github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/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 }