You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
4.5 KiB

lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
  1. package ed25519
  2. import (
  3. "bytes"
  4. "crypto/ed25519"
  5. "crypto/subtle"
  6. "fmt"
  7. "io"
  8. "github.com/hdevalence/ed25519consensus"
  9. "github.com/tendermint/tendermint/crypto"
  10. "github.com/tendermint/tendermint/crypto/tmhash"
  11. tmjson "github.com/tendermint/tendermint/libs/json"
  12. )
  13. //-------------------------------------
  14. var _ crypto.PrivKey = PrivKey{}
  15. const (
  16. PrivKeyName = "tendermint/PrivKeyEd25519"
  17. PubKeyName = "tendermint/PubKeyEd25519"
  18. // PubKeySize is is the size, in bytes, of public keys as used in this package.
  19. PubKeySize = 32
  20. // PrivateKeySize is the size, in bytes, of private keys as used in this package.
  21. PrivateKeySize = 64
  22. // Size of an Edwards25519 signature. Namely the size of a compressed
  23. // Edwards25519 point, and a field element. Both of which are 32 bytes.
  24. SignatureSize = 64
  25. // SeedSize is the size, in bytes, of private key seeds. These are the
  26. // private key representations used by RFC 8032.
  27. SeedSize = 32
  28. KeyType = "ed25519"
  29. )
  30. func init() {
  31. tmjson.RegisterType(PubKey{}, PubKeyName)
  32. tmjson.RegisterType(PrivKey{}, PrivKeyName)
  33. }
  34. // PrivKey implements crypto.PrivKey.
  35. type PrivKey []byte
  36. // Bytes returns the privkey byte format.
  37. func (privKey PrivKey) Bytes() []byte {
  38. return []byte(privKey)
  39. }
  40. // Sign produces a signature on the provided message.
  41. // This assumes the privkey is wellformed in the golang format.
  42. // The first 32 bytes should be random,
  43. // corresponding to the normal ed25519 private key.
  44. // The latter 32 bytes should be the compressed public key.
  45. // If these conditions aren't met, Sign will panic or produce an
  46. // incorrect signature.
  47. func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
  48. signatureBytes := ed25519.Sign(ed25519.PrivateKey(privKey), msg)
  49. return signatureBytes, nil
  50. }
  51. // PubKey gets the corresponding public key from the private key.
  52. //
  53. // Panics if the private key is not initialized.
  54. func (privKey PrivKey) PubKey() crypto.PubKey {
  55. // If the latter 32 bytes of the privkey are all zero, privkey is not
  56. // initialized.
  57. initialized := false
  58. for _, v := range privKey[32:] {
  59. if v != 0 {
  60. initialized = true
  61. break
  62. }
  63. }
  64. if !initialized {
  65. panic("Expected ed25519 PrivKey to include concatenated pubkey bytes")
  66. }
  67. pubkeyBytes := make([]byte, PubKeySize)
  68. copy(pubkeyBytes, privKey[32:])
  69. return PubKey(pubkeyBytes)
  70. }
  71. // Equals - you probably don't need to use this.
  72. // Runs in constant time based on length of the keys.
  73. func (privKey PrivKey) Equals(other crypto.PrivKey) bool {
  74. if otherEd, ok := other.(PrivKey); ok {
  75. return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 1
  76. }
  77. return false
  78. }
  79. func (privKey PrivKey) Type() string {
  80. return KeyType
  81. }
  82. // GenPrivKey generates a new ed25519 private key.
  83. // It uses OS randomness in conjunction with the current global random seed
  84. // in tendermint/libs/common to generate the private key.
  85. func GenPrivKey() PrivKey {
  86. return genPrivKey(crypto.CReader())
  87. }
  88. // genPrivKey generates a new ed25519 private key using the provided reader.
  89. func genPrivKey(rand io.Reader) PrivKey {
  90. seed := make([]byte, SeedSize)
  91. _, err := io.ReadFull(rand, seed)
  92. if err != nil {
  93. panic(err)
  94. }
  95. return PrivKey(ed25519.NewKeyFromSeed(seed))
  96. }
  97. // GenPrivKeyFromSecret hashes the secret with SHA2, and uses
  98. // that 32 byte output to create the private key.
  99. // NOTE: secret should be the output of a KDF like bcrypt,
  100. // if it's derived from user input.
  101. func GenPrivKeyFromSecret(secret []byte) PrivKey {
  102. seed := crypto.Sha256(secret) // Not Ripemd160 because we want 32 bytes.
  103. return PrivKey(ed25519.NewKeyFromSeed(seed))
  104. }
  105. //-------------------------------------
  106. var _ crypto.PubKey = PubKey{}
  107. // PubKeyEd25519 implements crypto.PubKey for the Ed25519 signature scheme.
  108. type PubKey []byte
  109. // Address is the SHA256-20 of the raw pubkey bytes.
  110. func (pubKey PubKey) Address() crypto.Address {
  111. if len(pubKey) != PubKeySize {
  112. panic("pubkey is incorrect size")
  113. }
  114. return crypto.Address(tmhash.SumTruncated(pubKey))
  115. }
  116. // Bytes returns the PubKey byte format.
  117. func (pubKey PubKey) Bytes() []byte {
  118. return []byte(pubKey)
  119. }
  120. func (pubKey PubKey) VerifySignature(msg []byte, sig []byte) bool {
  121. // make sure we use the same algorithm to sign
  122. if len(sig) != SignatureSize {
  123. return false
  124. }
  125. return ed25519consensus.Verify(ed25519.PublicKey(pubKey), msg, sig)
  126. }
  127. func (pubKey PubKey) String() string {
  128. return fmt.Sprintf("PubKeyEd25519{%X}", []byte(pubKey))
  129. }
  130. func (pubKey PubKey) Type() string {
  131. return KeyType
  132. }
  133. func (pubKey PubKey) Equals(other crypto.PubKey) bool {
  134. if otherEd, ok := other.(PubKey); ok {
  135. return bytes.Equal(pubKey[:], otherEd[:])
  136. }
  137. return false
  138. }