...

Source file src/github.com/theupdateframework/go-tuf/pkg/keys/ed25519.go

Documentation: github.com/theupdateframework/go-tuf/pkg/keys

     1  package keys
     2  
     3  import (
     4  	"bytes"
     5  	"crypto"
     6  	"crypto/ed25519"
     7  	"crypto/rand"
     8  	"crypto/subtle"
     9  	"encoding/json"
    10  	"errors"
    11  	"fmt"
    12  	"io"
    13  
    14  	"github.com/theupdateframework/go-tuf/data"
    15  )
    16  
    17  func init() {
    18  	SignerMap.Store(data.KeyTypeEd25519, NewEd25519Signer)
    19  	VerifierMap.Store(data.KeyTypeEd25519, NewEd25519Verifier)
    20  }
    21  
    22  func NewEd25519Signer() Signer {
    23  	return &ed25519Signer{}
    24  }
    25  
    26  func NewEd25519Verifier() Verifier {
    27  	return &ed25519Verifier{}
    28  }
    29  
    30  type ed25519Verifier struct {
    31  	PublicKey data.HexBytes `json:"public"`
    32  	key       *data.PublicKey
    33  }
    34  
    35  func (e *ed25519Verifier) Public() string {
    36  	return string(e.PublicKey)
    37  }
    38  
    39  func (e *ed25519Verifier) Verify(msg, sig []byte) error {
    40  	if !ed25519.Verify([]byte(e.PublicKey), msg, sig) {
    41  		return errors.New("tuf: ed25519 signature verification failed")
    42  	}
    43  	return nil
    44  }
    45  
    46  func (e *ed25519Verifier) MarshalPublicKey() *data.PublicKey {
    47  	return e.key
    48  }
    49  
    50  func (e *ed25519Verifier) UnmarshalPublicKey(key *data.PublicKey) error {
    51  	e.key = key
    52  
    53  	// Prepare decoder limited to 512Kb
    54  	dec := json.NewDecoder(io.LimitReader(bytes.NewReader(key.Value), MaxJSONKeySize))
    55  
    56  	// Unmarshal key value
    57  	if err := dec.Decode(e); err != nil {
    58  		if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
    59  			return fmt.Errorf("tuf: the public key is truncated or too large: %w", err)
    60  		}
    61  		return err
    62  	}
    63  	if n := len(e.PublicKey); n != ed25519.PublicKeySize {
    64  		return fmt.Errorf("tuf: unexpected public key length for ed25519 key, expected %d, got %d", ed25519.PublicKeySize, n)
    65  	}
    66  	return nil
    67  }
    68  
    69  type Ed25519PrivateKeyValue struct {
    70  	Public  data.HexBytes `json:"public"`
    71  	Private data.HexBytes `json:"private"`
    72  }
    73  
    74  type ed25519Signer struct {
    75  	ed25519.PrivateKey
    76  }
    77  
    78  func GenerateEd25519Key() (*ed25519Signer, error) {
    79  	_, private, err := ed25519.GenerateKey(rand.Reader)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  	return &ed25519Signer{
    87  		PrivateKey: ed25519.PrivateKey(data.HexBytes(private)),
    88  	}, nil
    89  }
    90  
    91  func NewEd25519SignerFromKey(keyValue Ed25519PrivateKeyValue) *ed25519Signer {
    92  	return &ed25519Signer{
    93  		PrivateKey: ed25519.PrivateKey(data.HexBytes(keyValue.Private)),
    94  	}
    95  }
    96  
    97  func (e *ed25519Signer) SignMessage(message []byte) ([]byte, error) {
    98  	return e.Sign(rand.Reader, message, crypto.Hash(0))
    99  }
   100  
   101  func (e *ed25519Signer) MarshalPrivateKey() (*data.PrivateKey, error) {
   102  	valueBytes, err := json.Marshal(Ed25519PrivateKeyValue{
   103  		Public:  data.HexBytes([]byte(e.PrivateKey.Public().(ed25519.PublicKey))),
   104  		Private: data.HexBytes(e.PrivateKey),
   105  	})
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  	return &data.PrivateKey{
   110  		Type:       data.KeyTypeEd25519,
   111  		Scheme:     data.KeySchemeEd25519,
   112  		Algorithms: data.HashAlgorithms,
   113  		Value:      valueBytes,
   114  	}, nil
   115  }
   116  
   117  func (e *ed25519Signer) UnmarshalPrivateKey(key *data.PrivateKey) error {
   118  	keyValue := &Ed25519PrivateKeyValue{}
   119  
   120  	// Prepare decoder limited to 512Kb
   121  	dec := json.NewDecoder(io.LimitReader(bytes.NewReader(key.Value), MaxJSONKeySize))
   122  
   123  	// Unmarshal key value
   124  	if err := dec.Decode(keyValue); err != nil {
   125  		if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
   126  			return fmt.Errorf("tuf: the private key is truncated or too large: %w", err)
   127  		}
   128  	}
   129  
   130  	// Check private key length
   131  	if n := len(keyValue.Private); n != ed25519.PrivateKeySize {
   132  		return fmt.Errorf("tuf: invalid ed25519 private key length, expected %d, got %d", ed25519.PrivateKeySize, n)
   133  	}
   134  
   135  	// Generate public key from private key
   136  	pub, _, err := ed25519.GenerateKey(bytes.NewReader(keyValue.Private))
   137  	if err != nil {
   138  		return fmt.Errorf("tuf: unable to derive public key from private key: %w", err)
   139  	}
   140  
   141  	// Compare keys
   142  	if subtle.ConstantTimeCompare(keyValue.Public, pub) != 1 {
   143  		return errors.New("tuf: public and private keys don't match")
   144  	}
   145  
   146  	// Prepare signer
   147  	*e = ed25519Signer{
   148  		PrivateKey: ed25519.PrivateKey(data.HexBytes(keyValue.Private)),
   149  	}
   150  	return nil
   151  }
   152  
   153  func (e *ed25519Signer) PublicData() *data.PublicKey {
   154  	keyValBytes, _ := json.Marshal(ed25519Verifier{PublicKey: []byte(e.PrivateKey.Public().(ed25519.PublicKey))})
   155  	return &data.PublicKey{
   156  		Type:       data.KeyTypeEd25519,
   157  		Scheme:     data.KeySchemeEd25519,
   158  		Algorithms: data.HashAlgorithms,
   159  		Value:      keyValBytes,
   160  	}
   161  }
   162  

View as plain text