|
|
@ -0,0 +1,80 @@ |
|
|
|
# ADR 015: Crypto encoding |
|
|
|
|
|
|
|
## Context |
|
|
|
|
|
|
|
We must standardize our method for encoding public keys and signatures on chain. |
|
|
|
Currently we amino encode the public keys and signatures. |
|
|
|
The reason we are using amino here is primarily due to ease of support in |
|
|
|
parsing for other languages. |
|
|
|
We don't need its upgradability properties in cryptosystems, as a change in |
|
|
|
the crypto that requires adapting the encoding, likely warrants being deemed |
|
|
|
a new cryptosystem. |
|
|
|
(I.e. using new public parameters) |
|
|
|
|
|
|
|
## Decision |
|
|
|
|
|
|
|
### Public keys |
|
|
|
|
|
|
|
For public keys, we will continue to use amino encoding on the canonical |
|
|
|
representation of the pubkey. |
|
|
|
(Canonical as defined by the cryptosystem itself) |
|
|
|
This has two significant drawbacks. |
|
|
|
Amino encoding is less space-efficient, due to requiring support for upgradability. |
|
|
|
Amino encoding support requires forking protobuf and adding this new interface support |
|
|
|
option in the langauge of choice. |
|
|
|
|
|
|
|
The reason for continuing to use amino however is that people can create code |
|
|
|
more easily in languages that already have an up to date amino library. |
|
|
|
It is possible that this will change in the future, if it is deemed that |
|
|
|
requiring amino for interacting with tendermint cryptography is unneccessary. |
|
|
|
|
|
|
|
The arguments for space efficiency here are refuted on the basis that there are |
|
|
|
far more egregious wastages of space in the SDK. |
|
|
|
The space requirement of the public keys doesn't cause many problems beyond |
|
|
|
increasing the space attached to each validator / account. |
|
|
|
|
|
|
|
The alternative to using amino here would be for us to create an enum type. |
|
|
|
Switching to just an enum type is worthy of investigation post-launch. |
|
|
|
For referrence, part of amino encoding interfaces is basically a 4 byte enum |
|
|
|
type definition. |
|
|
|
Enum types would just change that 4 bytes to be a varuint, and it would remove |
|
|
|
the protobuf overhead, but it would be hard to integrate into the existing API. |
|
|
|
|
|
|
|
### Signatures |
|
|
|
|
|
|
|
Signatures should be switched to be `[]byte`. |
|
|
|
Spatial efficiency in the signatures is quite important, |
|
|
|
as it directly affects the gas cost of every transaction, |
|
|
|
and the throughput of the chain. |
|
|
|
Signatures don't need to encode what type they are for (unlike public keys) |
|
|
|
since public keys must already be known. |
|
|
|
Therefore we can validate the signature without needing to encode its type. |
|
|
|
|
|
|
|
When placed in state, signatures will still be amino encoded, but it will be the |
|
|
|
primitive type `[]byte` getting encoded. |
|
|
|
|
|
|
|
#### Ed25519 |
|
|
|
Use the canonical representation for signatures. |
|
|
|
|
|
|
|
#### Secp256k1 |
|
|
|
There isn't a clear canonical representation here. |
|
|
|
Signatures have two elements `r,s`. |
|
|
|
We should encode these bytes as `r || s`, where `r` and `s` are both exactly |
|
|
|
32 bytes long. |
|
|
|
This is basically Ethereum's encoding, but without the leading recovery bit. |
|
|
|
|
|
|
|
## Status |
|
|
|
|
|
|
|
Proposed. The signature section seems to be agreed upon for the most part. |
|
|
|
Needs decision on Enum types. |
|
|
|
|
|
|
|
## Consequences |
|
|
|
|
|
|
|
### Positive |
|
|
|
* More space efficient signatures |
|
|
|
|
|
|
|
### Negative |
|
|
|
* We have an amino dependency for cryptography. |
|
|
|
|
|
|
|
### Neutral |
|
|
|
* No change to public keys |