1package merkletree2
2
3import (
4	"crypto/hmac"
5	cryptorand "crypto/rand"
6	"crypto/sha512"
7	"hash"
8
9	"github.com/keybase/go-codec/codec"
10)
11
12type EncodingType uint8
13
14const (
15	// For KeyValuePairs, the hash of the pair (k, v) is p(p(k, s), v )) where p
16	// = HMAC-SHA512-256 and s is a secret unique per Merkle seqno. Note that
17	// users learn k, v and p(k,s) but not s itself, so the hash is a commitment
18	// to the value only and not the key. However, the key is written and hashed
19	// as part of the merkle tree leaf node, so keybase cannot equivocate that.
20	// For generic data structures, this encoder uses SHA512-256 to hash the
21	// msgpack canonical encoding.
22	EncodingTypeBlindedSHA512_256v1 EncodingType = 1
23
24	// Generic testing encoding.
25	EncodingTypeForTesting EncodingType = 127
26)
27
28func (e EncodingType) GetEncoder() Encoder {
29	switch e {
30	case EncodingTypeBlindedSHA512_256v1:
31		return NewBlindedSHA512_256v1Encoder()
32	default:
33		panic("Invalid EncodingType")
34	}
35}
36
37// This function returns an encoder which is potentially unsafe for concurrent
38// use.
39func (e EncodingType) GetUnsafeEncoder() Encoder {
40	switch e {
41	case EncodingTypeBlindedSHA512_256v1:
42		return NewUnsafeBlindedSHA512_256v1Encoder()
43	default:
44		panic("Invalid EncodingType")
45	}
46}
47
48// UnsafeBlindedSHA512_256v1Encoder is analogous to BlindedSHA512_256v1Encoder,
49// but sometimes faster and not safe for concurrent use.
50type UnsafeBlindedSHA512_256v1Encoder struct {
51	BlindedSHA512_256v1Inner
52	enc    *codec.Encoder
53	dec    *codec.Decoder
54	sha    hash.Hash
55	encBuf []byte
56}
57
58var _ Encoder = (*UnsafeBlindedSHA512_256v1Encoder)(nil)
59
60func NewUnsafeBlindedSHA512_256v1Encoder() *UnsafeBlindedSHA512_256v1Encoder {
61	var mh codec.MsgpackHandle
62	mh.WriteExt = true
63	mh.Canonical = true
64
65	return &UnsafeBlindedSHA512_256v1Encoder{enc: codec.NewEncoderBytes(nil, &mh), dec: codec.NewDecoderBytes(nil, &mh), sha: sha512.New512_256()}
66}
67
68func (e *UnsafeBlindedSHA512_256v1Encoder) EncodeTo(o interface{}, out *[]byte) (err error) {
69	e.enc.ResetBytes(out)
70	return e.enc.Encode(o)
71}
72
73func (e *UnsafeBlindedSHA512_256v1Encoder) Encode(o interface{}) (out []byte, err error) {
74	return out, e.EncodeTo(o, &out)
75}
76
77func (e *UnsafeBlindedSHA512_256v1Encoder) Decode(dest interface{}, src []byte) error {
78	e.dec.ResetBytes(src)
79	return e.dec.Decode(dest)
80}
81
82func (e *UnsafeBlindedSHA512_256v1Encoder) HashGeneric(o interface{}, ret *Hash) error {
83	err := e.EncodeTo(o, &e.encBuf)
84	if err != nil {
85		return err
86	}
87	e.sha.Reset()
88	_, _ = e.sha.Write(e.encBuf)
89	*ret = e.sha.Sum((*ret)[:0])
90	return nil
91}
92
93func (e *UnsafeBlindedSHA512_256v1Encoder) EncodeAndHashGeneric(o interface{}) ([]byte, Hash, error) {
94	enc, err := e.Encode(o)
95	if err != nil {
96		return nil, nil, err
97	}
98	e.sha.Reset()
99	// sha.Write never errors.
100	_, _ = e.sha.Write(enc)
101	return enc, e.sha.Sum(nil), nil
102}
103
104func (e *UnsafeBlindedSHA512_256v1Encoder) HashKeyValuePairWithKeySpecificSecret(kvp KeyValuePair, kss KeySpecificSecret) (Hash, error) {
105	err := e.EncodeTo(kvp.Value, &e.encBuf)
106	if err != nil {
107		return nil, err
108	}
109	return e.HashKeyEncodedValuePairWithKeySpecificSecret(KeyEncodedValuePair{Key: kvp.Key, Value: e.encBuf}, kss)
110}
111
112type BlindedSHA512_256v1Encoder struct {
113	BlindedSHA512_256v1Inner
114	mh codec.MsgpackHandle
115}
116
117var _ Encoder = &BlindedSHA512_256v1Encoder{}
118
119func NewBlindedSHA512_256v1Encoder() *BlindedSHA512_256v1Encoder {
120	var mh codec.MsgpackHandle
121	mh.WriteExt = true
122	mh.Canonical = true
123
124	return &BlindedSHA512_256v1Encoder{mh: mh}
125}
126
127func (e *BlindedSHA512_256v1Encoder) EncodeTo(o interface{}, out *[]byte) (err error) {
128	return codec.NewEncoderBytes(out, &e.mh).Encode(o)
129}
130
131func (e *BlindedSHA512_256v1Encoder) Encode(o interface{}) (out []byte, err error) {
132	return out, e.EncodeTo(o, &out)
133}
134
135func (e *BlindedSHA512_256v1Encoder) Decode(dest interface{}, src []byte) error {
136	return codec.NewDecoderBytes(src, &e.mh).Decode(dest)
137}
138
139func (e *BlindedSHA512_256v1Encoder) EncodeAndHashGeneric(o interface{}) ([]byte, Hash, error) {
140	enc, err := e.Encode(o)
141	if err != nil {
142		return nil, nil, err
143	}
144	hasher := sha512.New512_256()
145	// hasher.Write never errors.
146	_, _ = hasher.Write(enc)
147	return enc, hasher.Sum(nil), nil
148}
149
150func (e *BlindedSHA512_256v1Encoder) HashGeneric(o interface{}, ret *Hash) error {
151	enc, err := e.Encode(o)
152	if err != nil {
153		return err
154	}
155	hasher := sha512.New512_256()
156	// hasher.Write never errors.
157	_, _ = hasher.Write(enc)
158	*ret = hasher.Sum((*ret)[:0])
159	return nil
160}
161
162func (e *BlindedSHA512_256v1Encoder) HashKeyValuePairWithKeySpecificSecret(kvp KeyValuePair, kss KeySpecificSecret) (Hash, error) {
163	encVal, err := e.Encode(kvp.Value)
164	if err != nil {
165		return nil, err
166	}
167	return e.HashKeyEncodedValuePairWithKeySpecificSecret(KeyEncodedValuePair{Key: kvp.Key, Value: encVal}, kss)
168}
169
170type BlindedSHA512_256v1Inner struct{}
171
172func (e BlindedSHA512_256v1Inner) HashKeyEncodedValuePairWithKeySpecificSecret(kevp KeyEncodedValuePair, kss KeySpecificSecret) (h Hash, err error) {
173	return h, e.HashKeyEncodedValuePairWithKeySpecificSecretTo(kevp, kss, &h)
174}
175
176func (e BlindedSHA512_256v1Inner) HashKeyEncodedValuePairWithKeySpecificSecretTo(kevp KeyEncodedValuePair, kss KeySpecificSecret, ret *Hash) error {
177	hasher := hmac.New(sha512.New512_256, kss)
178	// hasher.Write never errors.
179	_, _ = hasher.Write(kevp.Value)
180	*ret = hasher.Sum((*ret)[:0])
181	return nil
182}
183
184func (e BlindedSHA512_256v1Inner) GenerateMasterSecret(Seqno) (MasterSecret, error) {
185	secret := make([]byte, 32)
186	_, err := cryptorand.Read(secret)
187	return MasterSecret(secret), err
188}
189
190func (e BlindedSHA512_256v1Inner) ComputeKeySpecificSecret(ms MasterSecret, k Key) (kss KeySpecificSecret) {
191	e.ComputeKeySpecificSecretTo(ms, k, &kss)
192	return kss
193}
194
195func (e BlindedSHA512_256v1Inner) ComputeKeySpecificSecretTo(ms MasterSecret, k Key, ret *KeySpecificSecret) {
196	hasher := hmac.New(sha512.New512_256, ms)
197	// hasher.Write never errors.
198	_, _ = hasher.Write(k)
199	*ret = hasher.Sum((*ret)[:0])
200}
201
202func (e BlindedSHA512_256v1Inner) GetEncodingType() EncodingType {
203	return EncodingTypeBlindedSHA512_256v1
204}
205