github.com/pokt-network/tendermint@v0.32.11-0.20230426215212-59310158d3e9/docs/architecture/adr-015-crypto-encoding.md (about)

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