# Cryptography Toolkit

Cryptography is a critical component for any information or communication technology. It is also one of the most fragile, combinations of perfectly secure cryptographic components are often not secure. This led to the well-known advice of “don’t roll your own crypto”, which, predictably, has led to a widespread dearth of cryptography (outside TLS and cryptocurrencies). This fragility makes cryptography ill-suited for adaptability - adapting cryptographic primitives or protocols is very difficult!

However, there are various abstractions that can be described. The precise choice of Authenticated Encryption with Associated Data algorithm, which provides confidentiality of the plaintext and assurance that the ciphertext (and some associated data) has not been modified, can usually be abstracted, for example. Unless, of course, you don’t know what encryption key was used.

Initially as part of converge, we have been building a library of those abstractions, selecting a set of implementations that fit together nicely, have as few caveats as possible, and avoid leaving cryptographic decision-making to the application developer. This is a rough sketch of the abstractions we’re working with, though it may change as time goes on.

## Versions and Domains

Cryptographic agility is a great source of bugs and exploits, yet we need some way to transition from one implementation to another. This is where versions come in, each abstraction has different versioned implementations, and the same version of different abstractions are made work with each other. These versions are marked on the keys and other serializable data, along with their role in the abstraction they are used with.

Another source of bugs and exploits is using the same abstractions for different purposes. Therefore, every abstraction takes an additional static argument that describes the purpose to which it is being put. If a key from one area of a protocol is fed into the same algorithm in another area, the outputs from the second use of that algorithm will be incompatible with the first, as they take different domains.

## Salt and Passwords

We randomly generate passwords and assign them to the operator. This allows the use of memorable passwords (by using words in a language that the operator is fluent), with sufficient entropy (40 or more bits) to be difficult to brute force even given the salt.

Salt is some random data that is added to passwords during key derivation, to strengthen them against precomputation (rainbow tables). It is versioned, which determines which password key derivation function is used to derive the derivation key, which is also versioned.

## Derivation Keys

Derivation keys are fixed-size chunks of randomly-generated (or derived) bytes. They are used for deriving other keys, and are not used directly by any other abstractions.

## Non-Deterministic Authenticated Encryption with Associated Data and Key Commitment

These encryption schemes provide confidentiality of the plaintext, authenticity of the ciphertext and associated data, and commitment to the encryption key. They target indistinguishability under chosen plaintext attack (IND-CPA), existential unforgeability under chosen message attack (EUF-CMA), and indistinguishability from randomly generated data.

Encryption proceeds with a domain, a key, the plaintext, and the associated data, producing a ciphertext. Decryption proceeds with a domain, a key, the ciphertext, and the associated data, producing either the plaintext or failure. Nonces are generated from a secure random source, not supplied by the user, and provide the non-determinism (enabling IND-CPA).

## Deterministic Authenticated Encryption with Associated Data and Key Commitment

These encryption schemes provide confidentiality of the plaintext, authenticity of the ciphertext and associated data, and commitment to the encryption key. They target existential unforgeability under chosen message attack, and indistinguishability from randomly generated data, but do not satisfy indistinguishability under chosen plaintext attack. This is simply because they are deterministic - the same domain, key, plaintext, and associated data inputs will result in the same output.

Encryption proceeds with a domain, a key, the plaintext, and the associated data, producing a ciphertext. Decryption proceeds with a domain, a key, the ciphertext, and the associated data, producing either the plaintext or failure. Nonces are derived from the domain, key, plaintext and associated data, not supplied by the user.