agree is a CLI tool for easily applying multi-key-turn security via Shamirs Secret Sharing.
agree is unstable.
Version semantics: ^([0-9]+\.[0-9]+\.[0-9]+)(-(alpha|beta)\.[0-9]+)?$.
To split a secret (file) into shares, execute one of the following examples:
- Data is in a file (
Cargo.toml):
agree split -i -s Cargo.toml - Data is generated by an inline shell script and written to
STDOUT(this approach uses process substitution):
agree split -i -s <(printf "secret")
This command is interactive and asks the user to provide data like share name, file path and optional password to encrypt the share data.
In the following example, the secret was split into 2 shares. We need to provide exactly two shares in order to restore the secret and write it to STDOUT.
This command is interactive as it might prompt for the password of the share if its share data is encrypted.
agree restore -i -s ./share1.file -s ./share2.file
Note that if any password is encrypted and the -i flag is not provided, the command execution will fail since no password can be prompted from the user when in non-interactive mode.
The example below will split the secret into three shares with a restore threshold of two. Assuming the file is called blueprint.conf, we can use the following command:
agree split -s Cargo.toml -b blueprint.confExisting share files are not overwritten unless --force is supplied. A failed split does not leave a partial share set behind.
Generated shares include threshold/total-share metadata by default so restore can report missing shares clearly. Set
info = false on a share only if you intentionally want to omit that metadata.
threshold = 2
generate = [
{ path = "./test/alice.share" },
{
path = "./test/bob.share"
encrypt = { plain = "example-bob" }
info = true
comment = "example for bob"
},
{
path = "./test/charlie.share"
encrypt = { shell = "printf example-charlie" }
}
]The same result can be achieved using the interactive mode:
agree split -i -s Cargo.tomlIf you use this software to generate archives that are mission critical or contain anything you really want to be able to restore, you should not solely rely on the persistence of GitHub or crates.io. It is highly recommended to either fork the version of this software or store its binaries with the shares at some point. This way, even if the ecosystem is compromised, the software is no longer maintained or distributed or in similar cases, you will still be able to access your data assuming the shares can be used (/ decrypted with the correct password).
For mission critical information, you should always have contingency plans and never rely on single point of failures.
Archives are versioned JSON documents with the following fields:
$.version: CLI version ($major.$minorformat) that was used to create the archive$.uid: Unique ID of this archive.$.pid: Process ID of this archive (used to make sure only archives that were created together can be used together)$.data:base64encoded archive data containing the share payload and metadata
New archives verify restoration with an HMAC-SHA512 tag. The HMAC key is embedded inside the Shamir payload before splitting, so fewer-than-threshold readers see only a public tag, not a reusable hash of the original secret.
Secret files are limited to 64 MiB, blueprint files to 1 MiB, and share archive files to 256 MiB. This keeps accidental huge reads out of a tool that must hold split/restore material in memory.
Empty share passwords are rejected. Encrypted share payloads derive a 32-byte key with Argon2id (m=65536 KiB, t=3, p=1) and encrypt with
ChaCha20-Poly1305. The encrypted byte layout before base64 encoding is:
/// |index |usage|
/// |-------|-----|
/// |0 - 31 |salt |
/// |32 - 43|nonce |
/// |44 - |ciphertext |
Wrong passwords fail through AEAD authentication. The info command redacts share material, encrypted payloads, and
authentication tags.
