github.com/pokt-network/tendermint@v0.32.11-0.20230426215212-59310158d3e9/docs/architecture/adr-013-symmetric-crypto.md (about) 1 # ADR 013: Need for symmetric cryptography 2 3 ## Context 4 5 We require symmetric ciphers to handle how we encrypt keys in the sdk, 6 and to potentially encrypt `priv_validator.json` in tendermint. 7 8 Currently we use AEAD's to support symmetric encryption, 9 which is great since we want data integrity in addition to privacy and authenticity. 10 We don't currently have a scenario where we want to encrypt without data integrity, 11 so it is fine to optimize our code to just use AEAD's. 12 Currently there is not a way to switch out AEAD's easily, this ADR outlines a way 13 to easily swap these out. 14 15 ### How do we encrypt with AEAD's 16 17 AEAD's typically require a nonce in addition to the key. 18 For the purposes we require symmetric cryptography for, 19 we need encryption to be stateless. 20 Because of this we use random nonces. 21 (Thus the AEAD must support random nonces) 22 23 We currently construct a random nonce, and encrypt the data with it. 24 The returned value is `nonce || encrypted data`. 25 The limitation of this is that does not provide a way to identify 26 which algorithm was used in encryption. 27 Consequently decryption with multiple algoritms is sub-optimal. 28 (You have to try them all) 29 30 ## Decision 31 32 We should create the following two methods in a new `crypto/encoding/symmetric` package: 33 34 ```golang 35 func Encrypt(aead cipher.AEAD, plaintext []byte) (ciphertext []byte, err error) 36 func Decrypt(key []byte, ciphertext []byte) (plaintext []byte, err error) 37 func Register(aead cipher.AEAD, algo_name string, NewAead func(key []byte) (cipher.Aead, error)) error 38 ``` 39 40 This allows you to specify the algorithm in encryption, but not have to specify 41 it in decryption. 42 This is intended for ease of use in downstream applications, in addition to people 43 looking at the file directly. 44 One downside is that for the encrypt function you must have already initialized an AEAD, 45 but I don't really see this as an issue. 46 47 If there is no error in encryption, Encrypt will return `algo_name || nonce || aead_ciphertext`. 48 `algo_name` should be length prefixed, using standard varuint encoding. 49 This will be binary data, but thats not a problem considering the nonce and ciphertext are also binary. 50 51 This solution requires a mapping from aead type to name. 52 We can achieve this via reflection. 53 54 ```golang 55 func getType(myvar interface{}) string { 56 if t := reflect.TypeOf(myvar); t.Kind() == reflect.Ptr { 57 return "*" + t.Elem().Name() 58 } else { 59 return t.Name() 60 } 61 } 62 ``` 63 64 Then we maintain a map from the name returned from `getType(aead)` to `algo_name`. 65 66 In decryption, we read the `algo_name`, and then instantiate a new AEAD with the key. 67 Then we call the AEAD's decrypt method on the provided nonce/ciphertext. 68 69 `Register` allows a downstream user to add their own desired AEAD to the symmetric package. 70 It will error if the AEAD name is already registered. 71 This prevents a malicious import from modifying / nullifying an AEAD at runtime. 72 73 ## Implementation strategy 74 75 The golang implementation of what is proposed is rather straight forward. 76 The concern is that we will break existing private keys if we just switch to this. 77 If this is concerning, we can make a simple script which doesn't require decoding privkeys, 78 for converting from the old format to the new one. 79 80 ## Status 81 82 Proposed. 83 84 ## Consequences 85 86 ### Positive 87 88 - Allows us to support new AEAD's, in a way that makes decryption easier 89 - Allows downstream users to add their own AEAD 90 91 ### Negative 92 93 - We will have to break all private keys stored on disk. 94 They can be recovered using seed words, and upgrade scripts are simple. 95 96 ### Neutral 97 98 - Caller has to instantiate the AEAD with the private key. 99 However it forces them to be aware of what signing algorithm they are using, which is a positive.