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.

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