keypair.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // Copyright (c) 2021 Tulir Asokan
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. // Package keys contains a utility struct for elliptic curve keypairs.
  7. package keys
  8. import (
  9. "go.mau.fi/libsignal/ecc"
  10. "go.mau.fi/util/random"
  11. "golang.org/x/crypto/curve25519"
  12. )
  13. type KeyPair struct {
  14. Pub *[32]byte
  15. Priv *[32]byte
  16. }
  17. var _ ecc.ECPublicKeyable
  18. func NewKeyPairFromPrivateKey(priv [32]byte) *KeyPair {
  19. var kp KeyPair
  20. kp.Priv = &priv
  21. var pub [32]byte
  22. curve25519.ScalarBaseMult(&pub, kp.Priv)
  23. kp.Pub = &pub
  24. return &kp
  25. }
  26. func NewKeyPair() *KeyPair {
  27. priv := *(*[32]byte)(random.Bytes(32))
  28. priv[0] &= 248
  29. priv[31] &= 127
  30. priv[31] |= 64
  31. return NewKeyPairFromPrivateKey(priv)
  32. }
  33. func (kp *KeyPair) CreateSignedPreKey(keyID uint32) *PreKey {
  34. newKey := NewPreKey(keyID)
  35. newKey.Signature = kp.Sign(&newKey.KeyPair)
  36. return newKey
  37. }
  38. func (kp *KeyPair) Sign(keyToSign *KeyPair) *[64]byte {
  39. pubKeyForSignature := make([]byte, 33)
  40. pubKeyForSignature[0] = ecc.DjbType
  41. copy(pubKeyForSignature[1:], keyToSign.Pub[:])
  42. signature := ecc.CalculateSignature(ecc.NewDjbECPrivateKey(*kp.Priv), pubKeyForSignature)
  43. return &signature
  44. }
  45. type PreKey struct {
  46. KeyPair
  47. KeyID uint32
  48. Signature *[64]byte
  49. }
  50. func NewPreKey(keyID uint32) *PreKey {
  51. return &PreKey{
  52. KeyPair: *NewKeyPair(),
  53. KeyID: keyID,
  54. }
  55. }