mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
80 lines
3.0 KiB
Markdown
80 lines
3.0 KiB
Markdown
|
# 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
|