[][src]Struct secret_tree::SecretTree

pub struct SecretTree { /* fields omitted */ }

Seeded structure that can be used to produce secrets and child SecretTrees.

Usage

During the program lifecycle, a root SecretTree should be restored from a secure persistent form (e.g., a passphrase-encrypted file) and then used to derive child trees and secrets. On the first use, the root should be initialized from a CSPRNG, such as rand::thread_rng(). The tree is not needed during the program execution and can be safely dropped after deriving necessary secrets (which zeroes out the tree seed).

It is possible to modify the derivation hierarchy over the course of program evolution by adding new secrets or abandoning the existing ones. However, the purpose of any given tree path should be fixed; that is, if some version of a program used path foo/bar to derive an Ed25519 keypair, a newer version shouldn’t use foo/bar to derive an AES-128 key. Violating this rule may lead to leaking the secret.

Examples

use secret_tree::{SecretTree, Name};
use rand::{Rng, thread_rng};

let tree = SecretTree::new(&mut thread_rng());
let mut first_secret = [0_u8; 32];
tree.child(Name::new("first")).fill(&mut first_secret);

// We can derive hierarchical secrets. The secrets below
// follow logical paths `sequence/0`, `sequence/1`, .., `sequence/4`
// relative to the `tree`.
let child_store = tree.child(Name::new("sequence"));
let more_secrets: Vec<[u64; 4]> = (0..5)
    .map(|i| child_store.index(i).rng().gen())
    .collect();

// The tree is compactly stored as a single 32-byte seed.
let seed = *tree.seed();
drop(tree);

// If we restore the tree from the seed, we can restore all derived secrets.
let tree = SecretTree::from_seed(&seed).unwrap();
let mut restored_secret = [0_u8; 32];
tree.child(Name::new("first")).fill(&mut restored_secret);
assert_eq!(first_secret, restored_secret);

Methods

impl SecretTree[src]

pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self[src]

Generates a tree by sampling its seed from the supplied RNG.

pub fn from_seed(bytes: &[u8]) -> Option<Self>[src]

Restores a tree from the seed.

pub fn seed(&self) -> &Seed[src]

Returns the tree seed.

pub fn rng(self) -> ChaChaRng[src]

Converts this tree into a cryptographically secure pseudo-random number generator (CSPRNG). This RNG can then be used to reproducibly create secrets (e.g., secret keys).

Security

fill() should be preferred if the secret allows it. While using a CSPRNG to generate secrets is theoretically sound, it introduces a new entity that may leak information. fill() is especially useful if the filled buffer implements zeroing on drop; the state of a CSPRNG generator returned by rng() is not zeroed on drop and thus creates a potential attack vector. (However theoretical it may be; ChaChaRng has a notably small state size - ~160 bytes, so it may be better localized and have lower risk to be accessed by the adversary than other CSPRNG implementations.)

pub fn fill<T: AsByteSliceMut + ?Sized>(self, dest: &mut T)[src]

Fills the specified buffer with a key derived from the seed of this tree.

The buffer must be equivalent to 16..=64 bytes; the method panics otherwise. Use rng() if the buffer size may be outside these bounds, or if the secret must be derived in a more complex way.

pub fn child(&self, name: Name) -> Self[src]

Produces a child with the specified string identifier.

pub fn index(&self, index: u64) -> Self[src]

Produces a child with the specified integer index.

Trait Implementations

impl Drop for SecretTree[src]

impl Debug for SecretTree[src]

Auto Trait Implementations

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<V, T> VZip<V> for T where
    V: MultiLane<T>,