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