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.

146 lines
3.5 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package crypto
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "fmt"
  6. secp256k1 "github.com/btcsuite/btcd/btcec"
  7. "github.com/tendermint/ed25519"
  8. "github.com/tendermint/ed25519/extra25519"
  9. cmn "github.com/tendermint/tmlibs/common"
  10. "golang.org/x/crypto/ripemd160"
  11. )
  12. // An address is a []byte, but hex-encoded even in JSON.
  13. // []byte leaves us the option to change the address length.
  14. // Use an alias so Unmarshal methods (with ptr receivers) are available too.
  15. type Address = cmn.HexBytes
  16. func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) {
  17. err = cdc.UnmarshalBinary(pubKeyBytes, &pubKey)
  18. return
  19. }
  20. //----------------------------------------
  21. type PubKey interface {
  22. Address() Address
  23. Bytes() []byte
  24. VerifyBytes(msg []byte, sig Signature) bool
  25. Equals(PubKey) bool
  26. }
  27. //-------------------------------------
  28. var _ PubKey = PubKeyEd25519{}
  29. // Implements PubKeyInner
  30. type PubKeyEd25519 [32]byte
  31. func (pubKey PubKeyEd25519) Address() Address {
  32. // append type byte
  33. hasher := ripemd160.New()
  34. hasher.Write(pubKey.Bytes()) // does not error
  35. return Address(hasher.Sum(nil))
  36. }
  37. func (pubKey PubKeyEd25519) Bytes() []byte {
  38. bz, err := cdc.MarshalBinary(pubKey)
  39. if err != nil {
  40. panic(err)
  41. }
  42. return bz
  43. }
  44. func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
  45. // make sure we use the same algorithm to sign
  46. sig, ok := sig_.(SignatureEd25519)
  47. if !ok {
  48. return false
  49. }
  50. pubKeyBytes := [32]byte(pubKey)
  51. sigBytes := [64]byte(sig)
  52. return ed25519.Verify(&pubKeyBytes, msg, &sigBytes)
  53. }
  54. // For use with golang/crypto/nacl/box
  55. // If error, returns nil.
  56. func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte {
  57. keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey)
  58. ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes)
  59. if !ok {
  60. return nil
  61. }
  62. return keyCurve25519
  63. }
  64. func (pubKey PubKeyEd25519) String() string {
  65. return fmt.Sprintf("PubKeyEd25519{%X}", pubKey[:])
  66. }
  67. func (pubKey PubKeyEd25519) Equals(other PubKey) bool {
  68. if otherEd, ok := other.(PubKeyEd25519); ok {
  69. return bytes.Equal(pubKey[:], otherEd[:])
  70. } else {
  71. return false
  72. }
  73. }
  74. //-------------------------------------
  75. var _ PubKey = PubKeySecp256k1{}
  76. // Implements PubKey.
  77. // Compressed pubkey (just the x-cord),
  78. // prefixed with 0x02 or 0x03, depending on the y-cord.
  79. type PubKeySecp256k1 [33]byte
  80. // Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
  81. func (pubKey PubKeySecp256k1) Address() Address {
  82. hasherSHA256 := sha256.New()
  83. hasherSHA256.Write(pubKey[:]) // does not error
  84. sha := hasherSHA256.Sum(nil)
  85. hasherRIPEMD160 := ripemd160.New()
  86. hasherRIPEMD160.Write(sha) // does not error
  87. return Address(hasherRIPEMD160.Sum(nil))
  88. }
  89. func (pubKey PubKeySecp256k1) Bytes() []byte {
  90. bz, err := cdc.MarshalBinary(pubKey)
  91. if err != nil {
  92. panic(err)
  93. }
  94. return bz
  95. }
  96. func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool {
  97. // and assert same algorithm to sign and verify
  98. sig, ok := sig_.(SignatureSecp256k1)
  99. if !ok {
  100. return false
  101. }
  102. pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256())
  103. if err != nil {
  104. return false
  105. }
  106. sig__, err := secp256k1.ParseDERSignature(sig[:], secp256k1.S256())
  107. if err != nil {
  108. return false
  109. }
  110. return sig__.Verify(Sha256(msg), pub__)
  111. }
  112. func (pubKey PubKeySecp256k1) String() string {
  113. return fmt.Sprintf("PubKeySecp256k1{%X}", pubKey[:])
  114. }
  115. func (pubKey PubKeySecp256k1) Equals(other PubKey) bool {
  116. if otherSecp, ok := other.(PubKeySecp256k1); ok {
  117. return bytes.Equal(pubKey[:], otherSecp[:])
  118. } else {
  119. return false
  120. }
  121. }