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
/Source
that 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
Processor
that 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
/Sink
that 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,
};