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.

215 lines
5.1 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. secp256k1 "github.com/btcsuite/btcd/btcec"
  6. "github.com/tendermint/ed25519"
  7. "github.com/tendermint/ed25519/extra25519"
  8. . "github.com/tendermint/go-common"
  9. data "github.com/tendermint/go-data"
  10. "github.com/tendermint/go-wire"
  11. "golang.org/x/crypto/ripemd160"
  12. )
  13. // PubKey is part of Account and Validator.
  14. type PubKey interface {
  15. Address() []byte
  16. Bytes() []byte
  17. KeyString() string
  18. VerifyBytes(msg []byte, sig Signature) bool
  19. Equals(PubKey) bool
  20. }
  21. var pubKeyMapper data.Mapper
  22. // register both public key types with go-data (and thus go-wire)
  23. func init() {
  24. pubKeyMapper = data.NewMapper(PubKeyS{}).
  25. RegisterInterface(PubKeyEd25519{}, NameEd25519, TypeEd25519).
  26. RegisterInterface(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1)
  27. }
  28. // PubKeyS add json serialization to PubKey
  29. type PubKeyS struct {
  30. PubKey
  31. }
  32. func WrapPubKey(pk PubKey) PubKeyS {
  33. for ppk, ok := pk.(PubKeyS); ok; ppk, ok = pk.(PubKeyS) {
  34. pk = ppk.PubKey
  35. }
  36. return PubKeyS{pk}
  37. }
  38. func (p PubKeyS) MarshalJSON() ([]byte, error) {
  39. return pubKeyMapper.ToJSON(p.PubKey)
  40. }
  41. func (p *PubKeyS) UnmarshalJSON(data []byte) (err error) {
  42. parsed, err := pubKeyMapper.FromJSON(data)
  43. if err == nil && parsed != nil {
  44. p.PubKey = parsed.(PubKey)
  45. }
  46. return
  47. }
  48. func (p PubKeyS) Empty() bool {
  49. return p.PubKey == nil
  50. }
  51. func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) {
  52. err = wire.ReadBinaryBytes(pubKeyBytes, &pubKey)
  53. return
  54. }
  55. //-------------------------------------
  56. // Implements PubKey
  57. type PubKeyEd25519 [32]byte
  58. func (pubKey PubKeyEd25519) Address() []byte {
  59. w, n, err := new(bytes.Buffer), new(int), new(error)
  60. wire.WriteBinary(pubKey[:], w, n, err)
  61. if *err != nil {
  62. PanicCrisis(*err)
  63. }
  64. // append type byte
  65. encodedPubkey := append([]byte{TypeEd25519}, w.Bytes()...)
  66. hasher := ripemd160.New()
  67. hasher.Write(encodedPubkey) // does not error
  68. return hasher.Sum(nil)
  69. }
  70. func (pubKey PubKeyEd25519) Bytes() []byte {
  71. return wire.BinaryBytes(struct{ PubKey }{pubKey})
  72. }
  73. func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
  74. // unwrap if needed
  75. if wrap, ok := sig_.(SignatureS); ok {
  76. sig_ = wrap.Signature
  77. }
  78. // make sure we use the same algorithm to sign
  79. sig, ok := sig_.(SignatureEd25519)
  80. if !ok {
  81. return false
  82. }
  83. pubKeyBytes := [32]byte(pubKey)
  84. sigBytes := [64]byte(sig)
  85. return ed25519.Verify(&pubKeyBytes, msg, &sigBytes)
  86. }
  87. func (p PubKeyEd25519) MarshalJSON() ([]byte, error) {
  88. return data.Encoder.Marshal(p[:])
  89. }
  90. func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error {
  91. var ref []byte
  92. err := data.Encoder.Unmarshal(&ref, enc)
  93. copy(p[:], ref)
  94. return err
  95. }
  96. // For use with golang/crypto/nacl/box
  97. // If error, returns nil.
  98. func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte {
  99. keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey)
  100. ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes)
  101. if !ok {
  102. return nil
  103. }
  104. return keyCurve25519
  105. }
  106. func (pubKey PubKeyEd25519) String() string {
  107. return Fmt("PubKeyEd25519{%X}", pubKey[:])
  108. }
  109. // Must return the full bytes in hex.
  110. // Used for map keying, etc.
  111. func (pubKey PubKeyEd25519) KeyString() string {
  112. return Fmt("%X", pubKey[:])
  113. }
  114. func (pubKey PubKeyEd25519) Equals(other PubKey) bool {
  115. if otherEd, ok := other.(PubKeyEd25519); ok {
  116. return bytes.Equal(pubKey[:], otherEd[:])
  117. } else {
  118. return false
  119. }
  120. }
  121. //-------------------------------------
  122. // Implements PubKey.
  123. // Compressed pubkey (just the x-cord),
  124. // prefixed with 0x02 or 0x03, depending on the y-cord.
  125. type PubKeySecp256k1 [33]byte
  126. // Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
  127. func (pubKey PubKeySecp256k1) Address() []byte {
  128. hasherSHA256 := sha256.New()
  129. hasherSHA256.Write(pubKey[:]) // does not error
  130. sha := hasherSHA256.Sum(nil)
  131. hasherRIPEMD160 := ripemd160.New()
  132. hasherRIPEMD160.Write(sha) // does not error
  133. return hasherRIPEMD160.Sum(nil)
  134. }
  135. func (pubKey PubKeySecp256k1) Bytes() []byte {
  136. return wire.BinaryBytes(struct{ PubKey }{pubKey})
  137. }
  138. func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool {
  139. // unwrap if needed
  140. if wrap, ok := sig_.(SignatureS); ok {
  141. sig_ = wrap.Signature
  142. }
  143. // and assert same algorithm to sign and verify
  144. sig, ok := sig_.(SignatureSecp256k1)
  145. if !ok {
  146. return false
  147. }
  148. pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256())
  149. if err != nil {
  150. return false
  151. }
  152. sig__, err := secp256k1.ParseDERSignature(sig[:], secp256k1.S256())
  153. if err != nil {
  154. return false
  155. }
  156. return sig__.Verify(Sha256(msg), pub__)
  157. }
  158. func (p PubKeySecp256k1) MarshalJSON() ([]byte, error) {
  159. return data.Encoder.Marshal(p[:])
  160. }
  161. func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error {
  162. var ref []byte
  163. err := data.Encoder.Unmarshal(&ref, enc)
  164. copy(p[:], ref)
  165. return err
  166. }
  167. func (pubKey PubKeySecp256k1) String() string {
  168. return Fmt("PubKeySecp256k1{%X}", pubKey[:])
  169. }
  170. // Must return the full bytes in hex.
  171. // Used for map keying, etc.
  172. func (pubKey PubKeySecp256k1) KeyString() string {
  173. return Fmt("%X", pubKey[:])
  174. }
  175. func (pubKey PubKeySecp256k1) Equals(other PubKey) bool {
  176. if otherSecp, ok := other.(PubKeySecp256k1); ok {
  177. return bytes.Equal(pubKey[:], otherSecp[:])
  178. } else {
  179. return false
  180. }
  181. }