banana_recovery/
lib.rs

1//! Secrets recovery from split chunks according to the
2//! [banana split protocol](https://github.com/paritytech/banana_split).
3//!
4//! This crate is `no_std` compatible in `default-features = false` mode.
5//!
6//! # Examples
7//!```
8//! # #[cfg(feature = "std")]
9//! # {
10//! use banana_recovery::{Share, ShareCollection};
11//!
12//! // Recovering Alice seed phrase, from 2 shares out of 3 existing.
13//!
14//! const ALICE_SEEDPHRASE: &str = "bottom drive obey lake curtain smoke basket hold race lonely fit walk";
15//! const SCAN_A1: &str = "7b2276223a312c2274223a22416c6963652074726965732042616e616e6153706c697420616761696e222c2272223a322c2264223a223841666c74524d465a42425930326b3675457262364e747a375855364957796747764649444c4247566167542f6e7a5365507a55304e7a436e7175795975363765666634675462674564445542787671594f4d32557048326c6758544c673667583437546c694958554d66317562322f7675726c7479727769516b564e5636505158673d3d222c226e223a226f39446270426939723755574a484f726975444172523456726330564f6f336c227d";
16//! const SCAN_A2: &str = "7b2276223a312c2274223a22416c6963652074726965732042616e616e6153706c697420616761696e222c2272223a322c2264223a223841752f61694a2b794343786f715a7843434d6e32312f426358675a4b4935316b55742b644a6d6f782f7255456c3434485149547a437055414a38516835635a302b7155717067554d76697161777238763671786d3959544f4e636e66667942774249693067634b576f776463776f31664270456b5176357757694358654f38486a773d3d222c226e223a226f39446270426939723755574a484f726975444172523456726330564f6f336c227d";
17//! const PASSPHRASE_A: &str = "blighted-comprised-bucktooth-disjoin";
18//!
19//! // Initiate share collector.
20//! let mut share_collection = ShareCollection::new();
21//!
22//! // Process share #1 QR code.
23//! let share1 = Share::new(hex::decode(SCAN_A1).unwrap()).unwrap();
24//!
25//! // Add share #1 to collector.
26//! share_collection.add_share(share1).unwrap();
27//!
28//! if let ShareCollection::InProgress(ref in_progress) = share_collection {
29//!     // 1 share collected so far
30//!     assert_eq!(in_progress.shares_now(), 1);
31//!
32//!     // minimim 2 shares are needed (info from share itself)
33//!     assert_eq!(in_progress.shares_required(), 2);
34//!
35//!     // set title, identical for all shares in set (info from share itself)
36//!     assert_eq!(in_progress.title(), "Alice tries BananaSplit again");
37//! } else {
38//!     panic!("Added 1 share out of required 2. Must be `InProgress` variant.")
39//! }
40//!
41//! // Try adding same share #1 again. This would result in an error.
42//! let share1_again = Share::new(hex::decode(SCAN_A1).unwrap()).unwrap();
43//! assert!(
44//!     share_collection.add_share(share1_again).is_err(),
45//!     "Can not add the same share second time."
46//! );
47//!
48//! // Process share #2 QR code.
49//! let share2 = Share::new(hex::decode(SCAN_A2).unwrap()).unwrap();
50//!
51//! // Add share #2 to collector.
52//! share_collection.add_share(share2).unwrap();
53//!
54//! if let ShareCollection::Ready(combined) = share_collection {
55//!     // `SetCombined` could be processed to recover the secret.
56//!     let alice_secret = combined.recover_with_passphrase(PASSPHRASE_A).unwrap();
57//!     assert_eq!(alice_secret, ALICE_SEEDPHRASE);
58//! } else {
59//!     panic!("Added 2 different shares out of required 2. Must be `Ready` variant.")
60//! }
61//! # }
62//! ```
63#![no_std]
64#![deny(missing_docs)]
65#![deny(unused_crate_dependencies)]
66#![deny(unused_results)]
67
68#[macro_use]
69extern crate alloc;
70
71extern crate core;
72
73#[cfg(feature = "std")]
74extern crate std;
75
76mod error;
77mod shares;
78
79#[cfg(test)]
80mod tests;
81
82pub use error::BananaError;
83pub use shares::{SetCombined, SetInProgress, Share, ShareCollection};