gitee.com/lh-her-team/common@v1.5.1/helper/libp2pcrypto/ed25519.go (about)

     1  package libp2pcrypto
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/ed25519"
     6  	"crypto/subtle"
     7  	"errors"
     8  	"fmt"
     9  	"io"
    10  
    11  	"gitee.com/lh-her-team/common/helper/libp2pcrypto/pb"
    12  )
    13  
    14  // Ed25519PrivateKey is an ed25519 private key.
    15  type Ed25519PrivateKey struct {
    16  	k ed25519.PrivateKey
    17  }
    18  
    19  // Ed25519PublicKey is an ed25519 public key.
    20  type Ed25519PublicKey struct {
    21  	k ed25519.PublicKey
    22  }
    23  
    24  // GenerateEd25519Key generates a new ed25519 private and public key pair.
    25  func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) {
    26  	pub, priv, err := ed25519.GenerateKey(src)
    27  	if err != nil {
    28  		return nil, nil, err
    29  	}
    30  	return &Ed25519PrivateKey{
    31  			k: priv,
    32  		},
    33  		&Ed25519PublicKey{
    34  			k: pub,
    35  		},
    36  		nil
    37  }
    38  
    39  // Type of the private key (Ed25519).
    40  func (k *Ed25519PrivateKey) Type() pb.KeyType {
    41  	return pb.KeyType_Ed25519
    42  }
    43  
    44  // Bytes marshals an ed25519 private key to protobuf bytes.
    45  func (k *Ed25519PrivateKey) Bytes() ([]byte, error) {
    46  	return MarshalPrivateKey(k)
    47  }
    48  
    49  // Raw private key bytes.
    50  func (k *Ed25519PrivateKey) Raw() ([]byte, error) {
    51  	// The Ed25519 private key contains two 32-bytes curve points, the private
    52  	// key and the public key.
    53  	// It makes it more efficient to get the public key without re-computing an
    54  	// elliptic curve multiplication.
    55  	buf := make([]byte, len(k.k))
    56  	copy(buf, k.k)
    57  	return buf, nil
    58  }
    59  
    60  func (k *Ed25519PrivateKey) pubKeyBytes() []byte {
    61  	return k.k[ed25519.PrivateKeySize-ed25519.PublicKeySize:]
    62  }
    63  
    64  // Equals compares two ed25519 private keys.
    65  func (k *Ed25519PrivateKey) Equals(o Key) bool {
    66  	edk, ok := o.(*Ed25519PrivateKey)
    67  	if !ok {
    68  		return basicEquals(k, o)
    69  	}
    70  	return subtle.ConstantTimeCompare(k.k, edk.k) == 1
    71  }
    72  
    73  // GetPublic returns an ed25519 public key from a private key.
    74  func (k *Ed25519PrivateKey) GetPublic() PubKey {
    75  	return &Ed25519PublicKey{k: k.pubKeyBytes()}
    76  }
    77  
    78  // Sign returns a signature from an input message.
    79  func (k *Ed25519PrivateKey) Sign(msg []byte) ([]byte, error) {
    80  	return ed25519.Sign(k.k, msg), nil
    81  }
    82  
    83  // Type of the public key (Ed25519).
    84  func (k *Ed25519PublicKey) Type() pb.KeyType {
    85  	return pb.KeyType_Ed25519
    86  }
    87  
    88  // Bytes returns a ed25519 public key as protobuf bytes.
    89  func (k *Ed25519PublicKey) Bytes() ([]byte, error) {
    90  	return MarshalPublicKey(k)
    91  }
    92  
    93  // Raw public key bytes.
    94  func (k *Ed25519PublicKey) Raw() ([]byte, error) {
    95  	return k.k, nil
    96  }
    97  
    98  // Equals compares two ed25519 public keys.
    99  func (k *Ed25519PublicKey) Equals(o Key) bool {
   100  	edk, ok := o.(*Ed25519PublicKey)
   101  	if !ok {
   102  		return basicEquals(k, o)
   103  	}
   104  	return bytes.Equal(k.k, edk.k)
   105  }
   106  
   107  // Verify checks a signature against the input data.
   108  func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (bool, error) {
   109  	return ed25519.Verify(k.k, data, sig), nil
   110  }
   111  
   112  // UnmarshalEd25519PublicKey returns a public key from input bytes.
   113  func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) {
   114  	if len(data) != 32 {
   115  		return nil, errors.New("expect ed25519 public key data size to be 32")
   116  	}
   117  	return &Ed25519PublicKey{
   118  		k: ed25519.PublicKey(data),
   119  	}, nil
   120  }
   121  
   122  // UnmarshalEd25519PrivateKey returns a private key from input bytes.
   123  func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) {
   124  	switch len(data) {
   125  	case ed25519.PrivateKeySize + ed25519.PublicKeySize:
   126  		// Remove the redundant public key. See issue #36.
   127  		redundantPk := data[ed25519.PrivateKeySize:]
   128  		pk := data[ed25519.PrivateKeySize-ed25519.PublicKeySize : ed25519.PrivateKeySize]
   129  		if subtle.ConstantTimeCompare(pk, redundantPk) == 0 {
   130  			return nil, errors.New("expected redundant ed25519 public key to be redundant")
   131  		}
   132  		// No point in storing the extra data.
   133  		newKey := make([]byte, ed25519.PrivateKeySize)
   134  		copy(newKey, data[:ed25519.PrivateKeySize])
   135  		data = newKey
   136  	case ed25519.PrivateKeySize:
   137  	default:
   138  		return nil, fmt.Errorf(
   139  			"expected ed25519 data size to be %d or %d, got %d",
   140  			ed25519.PrivateKeySize,
   141  			ed25519.PrivateKeySize+ed25519.PublicKeySize,
   142  			len(data),
   143  		)
   144  	}
   145  	return &Ed25519PrivateKey{
   146  		k: ed25519.PrivateKey(data),
   147  	}, nil
   148  }