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.

192 lines
4.8 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
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. "github.com/tendermint/go-wire"
  10. data "github.com/tendermint/go-wire/data"
  11. cmn "github.com/tendermint/tmlibs/common"
  12. "golang.org/x/crypto/ripemd160"
  13. )
  14. // An address is a []byte, but hex-encoded even in JSON.
  15. // []byte leaves us the option to change the address length.
  16. // Use an alias so Unmarshal methods (with ptr receivers) are available too.
  17. type Address = cmn.HexBytes
  18. func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) {
  19. if err := wire.ReadBinaryBytes(pubKeyBytes, &pubKey); err != nil {
  20. return PubKey{}, err
  21. }
  22. return pubKey, nil
  23. }
  24. //----------------------------------------
  25. // DO NOT USE THIS INTERFACE.
  26. // You probably want to use PubKey
  27. // +gen wrapper:"PubKey,Impl[PubKeyEd25519,PubKeySecp256k1],ed25519,secp256k1"
  28. type PubKeyInner interface {
  29. AssertIsPubKeyInner()
  30. Address() Address
  31. Bytes() []byte
  32. KeyString() string
  33. VerifyBytes(msg []byte, sig Signature) bool
  34. Equals(PubKey) bool
  35. Wrap() PubKey
  36. }
  37. //-------------------------------------
  38. var _ PubKeyInner = PubKeyEd25519{}
  39. // Implements PubKeyInner
  40. type PubKeyEd25519 [32]byte
  41. func (pubKey PubKeyEd25519) AssertIsPubKeyInner() {}
  42. func (pubKey PubKeyEd25519) Address() Address {
  43. w, n, err := new(bytes.Buffer), new(int), new(error)
  44. wire.WriteBinary(pubKey[:], w, n, err)
  45. if *err != nil {
  46. panic(*err)
  47. }
  48. // append type byte
  49. encodedPubkey := append([]byte{TypeEd25519}, w.Bytes()...)
  50. hasher := ripemd160.New()
  51. hasher.Write(encodedPubkey) // does not error
  52. return Address(hasher.Sum(nil))
  53. }
  54. func (pubKey PubKeyEd25519) Bytes() []byte {
  55. return wire.BinaryBytes(PubKey{pubKey})
  56. }
  57. func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
  58. // make sure we use the same algorithm to sign
  59. sig, ok := sig_.Unwrap().(SignatureEd25519)
  60. if !ok {
  61. return false
  62. }
  63. pubKeyBytes := [32]byte(pubKey)
  64. sigBytes := [64]byte(sig)
  65. return ed25519.Verify(&pubKeyBytes, msg, &sigBytes)
  66. }
  67. func (p PubKeyEd25519) MarshalJSON() ([]byte, error) {
  68. return data.Encoder.Marshal(p[:])
  69. }
  70. func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error {
  71. var ref []byte
  72. err := data.Encoder.Unmarshal(&ref, enc)
  73. copy(p[:], ref)
  74. return err
  75. }
  76. // For use with golang/crypto/nacl/box
  77. // If error, returns nil.
  78. func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte {
  79. keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey)
  80. ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes)
  81. if !ok {
  82. return nil
  83. }
  84. return keyCurve25519
  85. }
  86. func (pubKey PubKeyEd25519) String() string {
  87. return fmt.Sprintf("PubKeyEd25519{%X}", pubKey[:])
  88. }
  89. // Must return the full bytes in hex.
  90. // Used for map keying, etc.
  91. func (pubKey PubKeyEd25519) KeyString() string {
  92. return fmt.Sprintf("%X", pubKey[:])
  93. }
  94. func (pubKey PubKeyEd25519) Equals(other PubKey) bool {
  95. if otherEd, ok := other.Unwrap().(PubKeyEd25519); ok {
  96. return bytes.Equal(pubKey[:], otherEd[:])
  97. } else {
  98. return false
  99. }
  100. }
  101. //-------------------------------------
  102. var _ PubKeyInner = PubKeySecp256k1{}
  103. // Implements PubKey.
  104. // Compressed pubkey (just the x-cord),
  105. // prefixed with 0x02 or 0x03, depending on the y-cord.
  106. type PubKeySecp256k1 [33]byte
  107. func (pubKey PubKeySecp256k1) AssertIsPubKeyInner() {}
  108. // Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
  109. func (pubKey PubKeySecp256k1) Address() Address {
  110. hasherSHA256 := sha256.New()
  111. hasherSHA256.Write(pubKey[:]) // does not error
  112. sha := hasherSHA256.Sum(nil)
  113. hasherRIPEMD160 := ripemd160.New()
  114. hasherRIPEMD160.Write(sha) // does not error
  115. return Address(hasherRIPEMD160.Sum(nil))
  116. }
  117. func (pubKey PubKeySecp256k1) Bytes() []byte {
  118. return wire.BinaryBytes(PubKey{pubKey})
  119. }
  120. func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool {
  121. // and assert same algorithm to sign and verify
  122. sig, ok := sig_.Unwrap().(SignatureSecp256k1)
  123. if !ok {
  124. return false
  125. }
  126. pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256())
  127. if err != nil {
  128. return false
  129. }
  130. sig__, err := secp256k1.ParseDERSignature(sig[:], secp256k1.S256())
  131. if err != nil {
  132. return false
  133. }
  134. return sig__.Verify(Sha256(msg), pub__)
  135. }
  136. func (p PubKeySecp256k1) MarshalJSON() ([]byte, error) {
  137. return data.Encoder.Marshal(p[:])
  138. }
  139. func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error {
  140. var ref []byte
  141. err := data.Encoder.Unmarshal(&ref, enc)
  142. copy(p[:], ref)
  143. return err
  144. }
  145. func (pubKey PubKeySecp256k1) String() string {
  146. return fmt.Sprintf("PubKeySecp256k1{%X}", pubKey[:])
  147. }
  148. // Must return the full bytes in hex.
  149. // Used for map keying, etc.
  150. func (pubKey PubKeySecp256k1) KeyString() string {
  151. return fmt.Sprintf("%X", pubKey[:])
  152. }
  153. func (pubKey PubKeySecp256k1) Equals(other PubKey) bool {
  154. if otherSecp, ok := other.Unwrap().(PubKeySecp256k1); ok {
  155. return bytes.Equal(pubKey[:], otherSecp[:])
  156. } else {
  157. return false
  158. }
  159. }