mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
* crypto/secp256k1: Fix signature malleability, adopt more efficient encoding This removes signature malleability per ADR 14, and makes secp match the encoding in ADR 15. * (squash this) add lock
85 lines
2.9 KiB
Markdown
85 lines
2.9 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`.
|
|
These bytes are encoded as `r || s`, where `r` and `s` are both exactly
|
|
32 bytes long, encoded big-endian.
|
|
This is basically Ethereum's encoding, but without the leading recovery bit.
|
|
|
|
## Status
|
|
|
|
Implemented
|
|
|
|
## Consequences
|
|
|
|
### Positive
|
|
|
|
- More space efficient signatures
|
|
|
|
### Negative
|
|
|
|
- We have an amino dependency for cryptography.
|
|
|
|
### Neutral
|
|
|
|
- No change to public keys
|