Cryptographic Procedures
Stronghold ensures that sensitive data cannot easily escape from memory. This requires a mechanism to work with secrets stored inside Stronghold's vault. While parts of Stronghold are primarily concerned with writing secrets, the question arises: "What can you do with a secret that is never exposed? Why even store it?”.
Cryptographic Procedures Pipeline
Stronghold features a framework to build pipelines of cryptographic operations. The pipeline pattern is an abstraction over chained function calls. Each stage of a pipeline can either:
- Produce a value. For example, generate a secret (BIP39 and Mnemonic, Ed25519)
- Process an existing value. For example, deriving a secret key from an existing key (SLIP10)
- Export a value from an existing secret. For example, export the public key of a key pair.
The framework is abstracted in a way that allows you to combine simple and complex cryptographic procedures. However, custom procedures are not possible within Stronghold. This is because a procedure can access secrets. Providing a custom procedure that exposes a secret and returns it would violate the Stronghold core principle.
The procedures framework is built upon a pipeline pattern. Each stage is only given the location inside the vault to access or work with secret data. The following schematic showcases the generation of a public / private keypair that gets stored in location1. The following step takes the previous location1 and derives a new keypair to store it in location2. Eventually, the last stage takes location2, extracts the public key and returns it to some publicly accessible data.
The pipeline pattern handles three kinds of primitives:
- A
Generator/Sourcethat produces secret keys or seeds and does not take any inputs. In most cases, it generates either a key pair (e.g. Ed25519) or a mnemonic (BIP39) to create a seed for a deterministic wallet - A
Processorthat takes in locations or data, and produces some new secret, stores it in a location. It is usually used to derive a new keypair (SLIP10). - A
Receiver/Sinkthat takes a location, produces a value and returns it. It does not store any product inside the vault.
All operations involving sensitive data make heavy use of the procedures framework.
Code Example
// .. we initialize `client` somewhere before the calls
// This constructs a `GenerateKey` procedure, that will generate a key at given
// output location in the vault
let generate_key_procedure = GenerateKey {
ty: keytype.clone(),
output: output_location.clone(),
};
// Even though this procedure does not create a useful output, the result can be
// used to check for errors
let procedure_result = client.execute_procedure(StrongholdProcedure::GenerateKey(generate_key_procedure));
// Front the previously generate key, we want to export the public key
let public_key_procedure = stronghold::procedures::PublicKey {
ty: keytype,
private_key: output_location,
};
