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.

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