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

     1  package merkletree2
     2  
     3  import (
     4  	"crypto/hmac"
     5  	cryptorand "crypto/rand"
     6  	"crypto/sha512"
     7  	"hash"
     8  
     9  	"github.com/keybase/go-codec/codec"
    10  )
    11  
    12  type EncodingType uint8
    13  
    14  const (
    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  
    28  func (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.
    39  func (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.
    50  type UnsafeBlindedSHA512_256v1Encoder struct {
    51  	BlindedSHA512_256v1Inner
    52  	enc    *codec.Encoder
    53  	dec    *codec.Decoder
    54  	sha    hash.Hash
    55  	encBuf []byte
    56  }
    57  
    58  var _ Encoder = (*UnsafeBlindedSHA512_256v1Encoder)(nil)
    59  
    60  func 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  
    68  func (e *UnsafeBlindedSHA512_256v1Encoder) EncodeTo(o interface{}, out *[]byte) (err error) {
    69  	e.enc.ResetBytes(out)
    70  	return e.enc.Encode(o)
    71  }
    72  
    73  func (e *UnsafeBlindedSHA512_256v1Encoder) Encode(o interface{}) (out []byte, err error) {
    74  	return out, e.EncodeTo(o, &out)
    75  }
    76  
    77  func (e *UnsafeBlindedSHA512_256v1Encoder) Decode(dest interface{}, src []byte) error {
    78  	e.dec.ResetBytes(src)
    79  	return e.dec.Decode(dest)
    80  }
    81  
    82  func (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  
    93  func (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  
   104  func (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  
   112  type BlindedSHA512_256v1Encoder struct {
   113  	BlindedSHA512_256v1Inner
   114  	mh codec.MsgpackHandle
   115  }
   116  
   117  var _ Encoder = &BlindedSHA512_256v1Encoder{}
   118  
   119  func 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  
   127  func (e *BlindedSHA512_256v1Encoder) EncodeTo(o interface{}, out *[]byte) (err error) {
   128  	return codec.NewEncoderBytes(out, &e.mh).Encode(o)
   129  }
   130  
   131  func (e *BlindedSHA512_256v1Encoder) Encode(o interface{}) (out []byte, err error) {
   132  	return out, e.EncodeTo(o, &out)
   133  }
   134  
   135  func (e *BlindedSHA512_256v1Encoder) Decode(dest interface{}, src []byte) error {
   136  	return codec.NewDecoderBytes(src, &e.mh).Decode(dest)
   137  }
   138  
   139  func (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  
   150  func (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  
   162  func (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  
   170  type BlindedSHA512_256v1Inner struct{}
   171  
   172  func (e BlindedSHA512_256v1Inner) HashKeyEncodedValuePairWithKeySpecificSecret(kevp KeyEncodedValuePair, kss KeySpecificSecret) (h Hash, err error) {
   173  	return h, e.HashKeyEncodedValuePairWithKeySpecificSecretTo(kevp, kss, &h)
   174  }
   175  
   176  func (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  
   184  func (e BlindedSHA512_256v1Inner) GenerateMasterSecret(Seqno) (MasterSecret, error) {
   185  	secret := make([]byte, 32)
   186  	_, err := cryptorand.Read(secret)
   187  	return MasterSecret(secret), err
   188  }
   189  
   190  func (e BlindedSHA512_256v1Inner) ComputeKeySpecificSecret(ms MasterSecret, k Key) (kss KeySpecificSecret) {
   191  	e.ComputeKeySpecificSecretTo(ms, k, &kss)
   192  	return kss
   193  }
   194  
   195  func (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  
   202  func (e BlindedSHA512_256v1Inner) GetEncodingType() EncodingType {
   203  	return EncodingTypeBlindedSHA512_256v1
   204  }