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.

84 lines
2.9 KiB

  1. # ADR 015: Crypto encoding
  2. ## Context
  3. We must standardize our method for encoding public keys and signatures on chain.
  4. Currently we amino encode the public keys and signatures.
  5. The reason we are using amino here is primarily due to ease of support in
  6. parsing for other languages.
  7. We don't need its upgradability properties in cryptosystems, as a change in
  8. the crypto that requires adapting the encoding, likely warrants being deemed
  9. a new cryptosystem.
  10. (I.e. using new public parameters)
  11. ## Decision
  12. ### Public keys
  13. For public keys, we will continue to use amino encoding on the canonical
  14. representation of the pubkey.
  15. (Canonical as defined by the cryptosystem itself)
  16. This has two significant drawbacks.
  17. Amino encoding is less space-efficient, due to requiring support for upgradability.
  18. Amino encoding support requires forking protobuf and adding this new interface support
  19. option in the language of choice.
  20. The reason for continuing to use amino however is that people can create code
  21. more easily in languages that already have an up to date amino library.
  22. It is possible that this will change in the future, if it is deemed that
  23. requiring amino for interacting with Tendermint cryptography is unnecessary.
  24. The arguments for space efficiency here are refuted on the basis that there are
  25. far more egregious wastages of space in the SDK.
  26. The space requirement of the public keys doesn't cause many problems beyond
  27. increasing the space attached to each validator / account.
  28. The alternative to using amino here would be for us to create an enum type.
  29. Switching to just an enum type is worthy of investigation post-launch.
  30. For reference, part of amino encoding interfaces is basically a 4 byte enum
  31. type definition.
  32. Enum types would just change that 4 bytes to be a variant, and it would remove
  33. the protobuf overhead, but it would be hard to integrate into the existing API.
  34. ### Signatures
  35. Signatures should be switched to be `[]byte`.
  36. Spatial efficiency in the signatures is quite important,
  37. as it directly affects the gas cost of every transaction,
  38. and the throughput of the chain.
  39. Signatures don't need to encode what type they are for (unlike public keys)
  40. since public keys must already be known.
  41. Therefore we can validate the signature without needing to encode its type.
  42. When placed in state, signatures will still be amino encoded, but it will be the
  43. primitive type `[]byte` getting encoded.
  44. #### Ed25519
  45. Use the canonical representation for signatures.
  46. #### Secp256k1
  47. There isn't a clear canonical representation here.
  48. Signatures have two elements `r,s`.
  49. These bytes are encoded as `r || s`, where `r` and `s` are both exactly
  50. 32 bytes long, encoded big-endian.
  51. This is basically Ethereum's encoding, but without the leading recovery bit.
  52. ## Status
  53. Implemented
  54. ## Consequences
  55. ### Positive
  56. - More space efficient signatures
  57. ### Negative
  58. - We have an amino dependency for cryptography.
  59. ### Neutral
  60. - No change to public keys