curve25519.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package ecdh
  2. import (
  3. "crypto"
  4. "io"
  5. "golang.org/x/crypto/curve25519"
  6. )
  7. type curve25519ECDH struct {
  8. ECDH
  9. }
  10. // NewCurve25519ECDH creates a new ECDH instance that uses djb's curve25519
  11. // elliptical curve.
  12. func NewCurve25519ECDH() ECDH {
  13. return &curve25519ECDH{}
  14. }
  15. func (e *curve25519ECDH) GenerateKey(rand io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) {
  16. var pub, priv [32]byte
  17. var err error
  18. _, err = io.ReadFull(rand, priv[:])
  19. if err != nil {
  20. return nil, nil, err
  21. }
  22. priv[0] &= 248
  23. priv[31] &= 127
  24. priv[31] |= 64
  25. curve25519.ScalarBaseMult(&pub, &priv)
  26. return &priv, &pub, nil
  27. }
  28. func (e *curve25519ECDH) Marshal(p crypto.PublicKey) []byte {
  29. pub := p.(*[32]byte)
  30. return pub[:]
  31. }
  32. func (e *curve25519ECDH) Unmarshal(data []byte) (crypto.PublicKey, bool) {
  33. var pub [32]byte
  34. if len(data) != 32 {
  35. return nil, false
  36. }
  37. copy(pub[:], data)
  38. return &pub, true
  39. }
  40. func (e *curve25519ECDH) GenerateSharedSecret(privKey crypto.PrivateKey, pubKey crypto.PublicKey) ([]byte, error) {
  41. var priv, pub, secret *[32]byte
  42. priv = privKey.(*[32]byte)
  43. pub = pubKey.(*[32]byte)
  44. secret = new([32]byte)
  45. curve25519.ScalarMult(secret, priv, pub)
  46. return secret[:], nil
  47. }