keypair.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright 2018-2022 The NATS Authors
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the License.
  4. // You may obtain a copy of the License at
  5. //
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. package nkeys
  14. import (
  15. "bytes"
  16. "crypto/rand"
  17. "io"
  18. "golang.org/x/crypto/ed25519"
  19. )
  20. // kp is the internal struct for a kepypair using seed.
  21. type kp struct {
  22. seed []byte
  23. }
  24. // All seeds are 32 bytes long.
  25. const seedLen = 32
  26. // CreatePair will create a KeyPair based on the rand entropy and a type/prefix byte.
  27. func CreatePair(prefix PrefixByte) (KeyPair, error) {
  28. return CreatePairWithRand(prefix, rand.Reader)
  29. }
  30. // CreatePair will create a KeyPair based on the rand reader and a type/prefix byte. rand can be nil.
  31. func CreatePairWithRand(prefix PrefixByte, rr io.Reader) (KeyPair, error) {
  32. if prefix == PrefixByteCurve {
  33. return CreateCurveKeysWithRand(rr)
  34. }
  35. if rr == nil {
  36. rr = rand.Reader
  37. }
  38. var rawSeed [seedLen]byte
  39. _, err := io.ReadFull(rr, rawSeed[:])
  40. if err != nil {
  41. return nil, err
  42. }
  43. seed, err := EncodeSeed(prefix, rawSeed[:])
  44. if err != nil {
  45. return nil, err
  46. }
  47. return &kp{seed}, nil
  48. }
  49. // rawSeed will return the raw, decoded 64 byte seed.
  50. func (pair *kp) rawSeed() ([]byte, error) {
  51. _, raw, err := DecodeSeed(pair.seed)
  52. return raw, err
  53. }
  54. // keys will return a 32 byte public key and a 64 byte private key utilizing the seed.
  55. func (pair *kp) keys() (ed25519.PublicKey, ed25519.PrivateKey, error) {
  56. raw, err := pair.rawSeed()
  57. if err != nil {
  58. return nil, nil, err
  59. }
  60. return ed25519.GenerateKey(bytes.NewReader(raw))
  61. }
  62. // Wipe will randomize the contents of the seed key
  63. func (pair *kp) Wipe() {
  64. io.ReadFull(rand.Reader, pair.seed)
  65. pair.seed = nil
  66. }
  67. // Seed will return the encoded seed.
  68. func (pair *kp) Seed() ([]byte, error) {
  69. return pair.seed, nil
  70. }
  71. // PublicKey will return the encoded public key associated with the KeyPair.
  72. // All KeyPairs have a public key.
  73. func (pair *kp) PublicKey() (string, error) {
  74. public, raw, err := DecodeSeed(pair.seed)
  75. if err != nil {
  76. return "", err
  77. }
  78. pub, _, err := ed25519.GenerateKey(bytes.NewReader(raw))
  79. if err != nil {
  80. return "", err
  81. }
  82. pk, err := Encode(public, pub)
  83. if err != nil {
  84. return "", err
  85. }
  86. return string(pk), nil
  87. }
  88. // PrivateKey will return the encoded private key for KeyPair.
  89. func (pair *kp) PrivateKey() ([]byte, error) {
  90. _, priv, err := pair.keys()
  91. if err != nil {
  92. return nil, err
  93. }
  94. return Encode(PrefixBytePrivate, priv)
  95. }
  96. // Sign will sign the input with KeyPair's private key.
  97. func (pair *kp) Sign(input []byte) ([]byte, error) {
  98. _, priv, err := pair.keys()
  99. if err != nil {
  100. return nil, err
  101. }
  102. return ed25519.Sign(priv, input), nil
  103. }
  104. // Verify will verify the input against a signature utilizing the public key.
  105. func (pair *kp) Verify(input []byte, sig []byte) error {
  106. pub, _, err := pair.keys()
  107. if err != nil {
  108. return err
  109. }
  110. if !ed25519.Verify(pub, input, sig) {
  111. return ErrInvalidSignature
  112. }
  113. return nil
  114. }
  115. // Seal is only supported on CurveKeyPair
  116. func (pair *kp) Seal(input []byte, recipient string) ([]byte, error) {
  117. return nil, ErrInvalidNKeyOperation
  118. }
  119. // SealWithRand is only supported on CurveKeyPair
  120. func (pair *kp) SealWithRand(input []byte, recipient string, rr io.Reader) ([]byte, error) {
  121. return nil, ErrInvalidNKeyOperation
  122. }
  123. // Open is only supported on CurveKey
  124. func (pair *kp) Open(input []byte, sender string) ([]byte, error) {
  125. return nil, ErrInvalidNKeyOperation
  126. }