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.

85 lines
3.1 KiB

  1. package cryptoamino
  2. import (
  3. "reflect"
  4. amino "github.com/tendermint/go-amino"
  5. "github.com/tendermint/tendermint/crypto"
  6. "github.com/tendermint/tendermint/crypto/ed25519"
  7. "github.com/tendermint/tendermint/crypto/multisig"
  8. "github.com/tendermint/tendermint/crypto/secp256k1"
  9. "github.com/tendermint/tendermint/crypto/sr25519"
  10. )
  11. var cdc = amino.NewCodec()
  12. // nameTable is used to map public key concrete types back
  13. // to their registered amino names. This should eventually be handled
  14. // by amino. Example usage:
  15. // nameTable[reflect.TypeOf(ed25519.PubKeyEd25519{})] = ed25519.PubKeyAminoName
  16. var nameTable = make(map[reflect.Type]string, 3)
  17. func init() {
  18. // NOTE: It's important that there be no conflicts here,
  19. // as that would change the canonical representations,
  20. // and therefore change the address.
  21. // TODO: Remove above note when
  22. // https://github.com/tendermint/go-amino/issues/9
  23. // is resolved
  24. RegisterAmino(cdc)
  25. // TODO: Have amino provide a way to go from concrete struct to route directly.
  26. // Its currently a private API
  27. nameTable[reflect.TypeOf(ed25519.PubKeyEd25519{})] = ed25519.PubKeyAminoName
  28. nameTable[reflect.TypeOf(sr25519.PubKeySr25519{})] = sr25519.PubKeyAminoName
  29. nameTable[reflect.TypeOf(secp256k1.PubKeySecp256k1{})] = secp256k1.PubKeyAminoName
  30. nameTable[reflect.TypeOf(multisig.PubKeyMultisigThreshold{})] = multisig.PubKeyMultisigThresholdAminoRoute
  31. }
  32. // PubkeyAminoName returns the amino route of a pubkey
  33. // cdc is currently passed in, as eventually this will not be using
  34. // a package level codec.
  35. func PubkeyAminoName(cdc *amino.Codec, key crypto.PubKey) (string, bool) {
  36. route, found := nameTable[reflect.TypeOf(key)]
  37. return route, found
  38. }
  39. // RegisterAmino registers all crypto related types in the given (amino) codec.
  40. func RegisterAmino(cdc *amino.Codec) {
  41. // These are all written here instead of
  42. cdc.RegisterInterface((*crypto.PubKey)(nil), nil)
  43. cdc.RegisterConcrete(ed25519.PubKeyEd25519{},
  44. ed25519.PubKeyAminoName, nil)
  45. cdc.RegisterConcrete(sr25519.PubKeySr25519{},
  46. sr25519.PubKeyAminoName, nil)
  47. cdc.RegisterConcrete(secp256k1.PubKeySecp256k1{},
  48. secp256k1.PubKeyAminoName, nil)
  49. cdc.RegisterConcrete(multisig.PubKeyMultisigThreshold{},
  50. multisig.PubKeyMultisigThresholdAminoRoute, nil)
  51. cdc.RegisterInterface((*crypto.PrivKey)(nil), nil)
  52. cdc.RegisterConcrete(ed25519.PrivKeyEd25519{},
  53. ed25519.PrivKeyAminoName, nil)
  54. cdc.RegisterConcrete(sr25519.PrivKeySr25519{},
  55. sr25519.PrivKeyAminoName, nil)
  56. cdc.RegisterConcrete(secp256k1.PrivKeySecp256k1{},
  57. secp256k1.PrivKeyAminoName, nil)
  58. }
  59. // RegisterKeyType registers an external key type to allow decoding it from bytes
  60. func RegisterKeyType(o interface{}, name string) {
  61. cdc.RegisterConcrete(o, name, nil)
  62. nameTable[reflect.TypeOf(o)] = name
  63. }
  64. // PrivKeyFromBytes unmarshals private key bytes and returns a PrivKey
  65. func PrivKeyFromBytes(privKeyBytes []byte) (privKey crypto.PrivKey, err error) {
  66. err = cdc.UnmarshalBinaryBare(privKeyBytes, &privKey)
  67. return
  68. }
  69. // PubKeyFromBytes unmarshals public key bytes and returns a PubKey
  70. func PubKeyFromBytes(pubKeyBytes []byte) (pubKey crypto.PubKey, err error) {
  71. err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey)
  72. return
  73. }