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

     1  package merkle
     2  
     3  import (
     4  	"crypto/hmac"
     5  	cryptorand "crypto/rand"
     6  	"crypto/sha512"
     7  
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  type Encoder struct {
    12  	encodingType EncodingType
    13  }
    14  
    15  func NewEncoder(encodingType EncodingType) *Encoder {
    16  	return &Encoder{encodingType: encodingType}
    17  }
    18  
    19  func (e *Encoder) EncodingType() EncodingType {
    20  	return e.encodingType
    21  }
    22  
    23  func (e *Encoder) BlindedPreimage(leaf Leaf, key Key, secret Secret) (BlindedPreimage, error) {
    24  	switch e.encodingType {
    25  	case EncodingTypeBlindedSHA512_256v1:
    26  		h := hmac.New(sha512.New, secret.Secret)
    27  		_, err := h.Write(key.Key)
    28  		if err != nil {
    29  			return BlindedPreimage{}, err
    30  		}
    31  		z := h.Sum(nil)
    32  		return NewBlindedPreimage(leaf, z[:32])
    33  	default:
    34  		return BlindedPreimage{}, errors.Errorf("unknown encoding type %q", e.encodingType)
    35  	}
    36  }
    37  
    38  func (e *Encoder) Hash(preimage BlindedPreimage) ([]byte, error) {
    39  	b, err := preimage.LeafContainer.Serialize()
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  	switch e.encodingType {
    44  	case EncodingTypeBlindedSHA512_256v1:
    45  		h := hmac.New(sha512.New, preimage.BlindedEntropy)
    46  		_, err := h.Write(b)
    47  		if err != nil {
    48  			return nil, err
    49  		}
    50  		z := h.Sum(nil)
    51  		return z[:32], nil
    52  	default:
    53  		return nil, errors.Errorf("unknown encoding type %q", e.encodingType)
    54  	}
    55  }
    56  
    57  func (e *Encoder) Encode(leaf Leaf, key Key, secret Secret) ([]byte, error) {
    58  	preimage, err := e.BlindedPreimage(leaf, key, secret)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	return e.Hash(preimage)
    63  }
    64  
    65  func (e *Encoder) GenerateSecret() (Secret, error) {
    66  	switch e.encodingType {
    67  	case EncodingTypeBlindedSHA512_256v1:
    68  		secret := make([]byte, 32)
    69  		_, err := cryptorand.Read(secret)
    70  		return NewSecret(secret), err
    71  	default:
    72  		return Secret{}, errors.Errorf("unknown encoding type %q", e.encodingType)
    73  	}
    74  }