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/subtle"
  5. "fmt"
  6. "io"
  7. "golang.org/x/crypto/ed25519"
  8. "github.com/tendermint/tendermint/crypto"
  9. "github.com/tendermint/tendermint/crypto/tmhash"
  10. tmjson "github.com/tendermint/tendermint/libs/json"
  11. )
  12. //-------------------------------------
  13. var _ crypto.PrivKey = PrivKey{}
  14. const (
  15. PrivKeyAminoName = "tendermint/PrivKeyEd25519"
  16. PubKeyAminoName = "tendermint/PubKeyEd25519"
  17. // PubKeySize is is the size, in bytes, of public keys as used in this package.
  18. PubKeySize = 32
  19. // PrivateKeySize is the size, in bytes, of private keys as used in this package.
  20. PrivateKeySize = 64
  21. // Size of an Edwards25519 signature. Namely the size of a compressed
  22. // Edwards25519 point, and a field element. Both of which are 32 bytes.
  23. SignatureSize = 64
  24. // SeedSize is the size, in bytes, of private key seeds. These are the
  25. // private key representations used by RFC 8032.
  26. SeedSize = 32
  27. keyType = "ed25519"
  28. )
  29. func init() {
  30. tmjson.RegisterType(PubKey{}, PubKeyAminoName)
  31. tmjson.RegisterType(PrivKey{}, PrivKeyAminoName)
  32. }
  33. // PrivKey implements crypto.PrivKey.
  34. type PrivKey []byte
  35. // Bytes returns the privkey byte format.
  36. func (privKey PrivKey) Bytes() []byte {
  37. return []byte(privKey)
  38. }
  39. // Sign produces a signature on the provided message.
  40. // This assumes the privkey is wellformed in the golang format.
  41. // The first 32 bytes should be random,
  42. // corresponding to the normal ed25519 private key.
  43. // The latter 32 bytes should be the compressed public key.
  44. // If these conditions aren't met, Sign will panic or produce an
  45. // incorrect signature.
  46. func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
  47. signatureBytes := ed25519.Sign(ed25519.PrivateKey(privKey), msg)
  48. return signatureBytes, nil
  49. }
  50. // PubKey gets the corresponding public key from the private key.
  51. //
  52. // Panics if the private key is not initialized.
  53. func (privKey PrivKey) PubKey() crypto.PubKey {
  54. // If the latter 32 bytes of the privkey are all zero, privkey is not
  55. // initialized.
  56. initialized := false
  57. for _, v := range privKey[32:] {
  58. if v != 0 {
  59. initialized = true
  60. break
  61. }
  62. }
  63. if !initialized {
  64. panic("Expected ed25519 PrivKey to include concatenated pubkey bytes")
  65. }
  66. pubkeyBytes := make([]byte, PubKeySize)
  67. copy(pubkeyBytes, privKey[32:])
  68. return PubKey(pubkeyBytes)
  69. }
  70. // Equals - you probably don't need to use this.
  71. // Runs in constant time based on length of the keys.
  72. func (privKey PrivKey) Equals(other crypto.PrivKey) bool {
  73. if otherEd, ok := other.(PrivKey); ok {
  74. return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 1
  75. }
  76. return false
  77. }
  78. func (privKey PrivKey) Type() string {
  79. return keyType
  80. }
  81. // GenPrivKey generates a new ed25519 private key.
  82. // It uses OS randomness in conjunction with the current global random seed
  83. // in tendermint/libs/common to generate the private key.
  84. func GenPrivKey() PrivKey {
  85. return genPrivKey(crypto.CReader())
  86. }
  87. // genPrivKey generates a new ed25519 private key using the provided reader.
  88. func genPrivKey(rand io.Reader) PrivKey {
  89. seed := make([]byte, SeedSize)
  90. _, err := io.ReadFull(rand, seed)
  91. if err != nil {
  92. panic(err)
  93. }
  94. return PrivKey(ed25519.NewKeyFromSeed(seed))
  95. }
  96. // GenPrivKeyFromSecret hashes the secret with SHA2, and uses
  97. // that 32 byte output to create the private key.
  98. // NOTE: secret should be the output of a KDF like bcrypt,
  99. // if it's derived from user input.
  100. func GenPrivKeyFromSecret(secret []byte) PrivKey {
  101. seed := crypto.Sha256(secret) // Not Ripemd160 because we want 32 bytes.
  102. return PrivKey(ed25519.NewKeyFromSeed(seed))
  103. }
  104. //-------------------------------------
  105. var _ crypto.PubKey = PubKey{}
  106. // PubKeyEd25519 implements crypto.PubKey for the Ed25519 signature scheme.
  107. type PubKey []byte
  108. // Address is the SHA256-20 of the raw pubkey bytes.
  109. func (pubKey PubKey) Address() crypto.Address {
  110. if len(pubKey) != PubKeySize {
  111. panic("pubkey is incorrect size")
  112. }
  113. return crypto.Address(tmhash.SumTruncated(pubKey))
  114. }
  115. // Bytes returns the PubKey byte format.
  116. func (pubKey PubKey) Bytes() []byte {
  117. return []byte(pubKey)
  118. }
  119. func (pubKey PubKey) VerifyBytes(msg []byte, sig []byte) bool {
  120. // make sure we use the same algorithm to sign
  121. if len(sig) != SignatureSize {
  122. return false
  123. }
  124. return ed25519.Verify(ed25519.PublicKey(pubKey), msg, sig)
  125. }
  126. func (pubKey PubKey) String() string {
  127. return fmt.Sprintf("PubKeyEd25519{%X}", []byte(pubKey))
  128. }
  129. func (pubKey PubKey) Type() string {
  130. return keyType
  131. }
  132. func (pubKey PubKey) Equals(other crypto.PubKey) bool {
  133. if otherEd, ok := other.(PubKey); ok {
  134. return bytes.Equal(pubKey[:], otherEd[:])
  135. }
  136. return false
  137. }