Skip to content

Commit

Permalink
wip: experiments
Browse files Browse the repository at this point in the history
  • Loading branch information
Beerosagos committed Dec 16, 2024
1 parent 10c4bd0 commit ecd8269
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 31 deletions.
103 changes: 103 additions & 0 deletions src/rust/bitbox02-rust/src/hww/api/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use alloc::vec::Vec;
use super::Error;
use crate::pb;

Expand Down Expand Up @@ -150,3 +151,105 @@ pub async fn from_mnemonic(
unlock::unlock_bip39().await;
Ok(Response::Success(pb::Success {}))
}

pub async fn from_shamir(
#[cfg_attr(not(feature = "app-u2f"), allow(unused_variables))]
&pb::RestoreFromMnemonicRequest {
timestamp,
timezone_offset,
}: &pb::RestoreFromMnemonicRequest,
) -> Result<Response, Error> {
#[cfg(feature = "app-u2f")]
{
let datetime_string = bitbox02::format_datetime(timestamp, timezone_offset, false)
.map_err(|_| Error::InvalidInput)?;
confirm::confirm(&confirm::Params {
title: "Is now?",
body: &datetime_string,
accept_is_nextarrow: true,
..Default::default()
})
.await?;
}

let mnemonic1 = "abuse erode slam exchange stereo scheme brush prepare sugar balcony soldier cup amazing auction frequent lemon medal catalog harvest view gift marble afraid assault";
// let mnemonic1 = mnemonic::get().await?;
let seed1 = match bitbox02::keystore::bip39_mnemonic_to_seed(&mnemonic1) {
Ok(seed) => seed,
Err(()) => {
status::status("Recovery words\ninvalid", false).await;
return Err(Error::Generic);
}
};
let s1 = sharks::Share::try_from(seed1.as_slice()).unwrap();
let share = Vec::from(&s1);
bitbox02::print_stdout(&format!("share: {}, len: {}\n", hex::encode(share.clone()), share.len()));

let mnemonic2 = "act situate gate quiz humor famous federal team glare pyramid harsh inhale size abandon final abuse hammer knee clip food coffee panda father lamp";
// let mnemonic2 = mnemonic::get().await?;
let seed2 = match bitbox02::keystore::bip39_mnemonic_to_seed(&mnemonic2) {
Ok(seed) => seed,
Err(()) => {
status::status("Recovery words\ninvalid", false).await;
return Err(Error::Generic);
}
};
let s2 = sharks::Share::try_from(seed2.as_slice()).unwrap();
let share2 = Vec::from(&s2);
bitbox02::print_stdout(&format!("share: {}, len: {}\n", hex::encode(share2.clone()), share2.len()));
let shares = vec![s1, s2];
let sharks = sharks::Sharks(2);
let seed = match sharks.recover(&shares) {
Ok(seed) => seed,
Err(err_str) => {
status::status("Recovery words\ninvalid", false).await;
bitbox02::print_stdout(format!("Err: {}", err_str).as_str());
return Err(Error::Generic);
}
};
// match secret {
// Err(e) => bitbox02::print_stdout(&format!("Error {}\n", e)),
// Ok(_) => bitbox02::print_stdout("***test ok\n"),

status::status("Recovery words\nvalid", true).await;

bitbox02::print_stdout(&format!("seed: {}, len: {}\n", hex::encode(seed.clone()), seed.len()));
let mnemonic_sentence = bitbox02::keystore::get_bip39_mnemonic_from_bytes(seed.as_ptr(), seed.len())?;
bitbox02::print_stdout(format!("mnemonic: {}\n", mnemonic_sentence.as_str()).as_str());

// If entering password fails (repeat password does not match the first), we don't want to abort
// the process immediately. We break out only if the user confirms.
let password = loop {
match password::enter_twice().await {
Err(password::EnterTwiceError::DoNotMatch) => {
confirm::confirm(&confirm::Params {
title: "",
body: "Passwords\ndo not match.\nTry again?",
..Default::default()
})
.await?;
}
Err(password::EnterTwiceError::Cancelled) => return Err(Error::UserAbort),
Ok(password) => break password,
}
};

if let Err(err) = bitbox02::keystore::encrypt_and_store_seed(&seed.as_slice(), &password) {
status::status(&format!("Could not\nrestore backup\n{:?}", err), false).await;
return Err(Error::Generic);
};

#[cfg(feature = "app-u2f")]
{
// Ignore error - the U2f counter not being set can lead to problems with U2F, but it should
// not fail the recovery, so the user can access their coins.
let _ = bitbox02::securechip::u2f_counter_set(timestamp);
}

bitbox02::memory::set_initialized().or(Err(Error::Memory))?;

// This should never fail.
bitbox02::keystore::unlock(&password).expect("restore_from_mnemonic: unlock failed");
unlock::unlock_bip39().await;
Ok(Response::Success(pb::Success {}))
}
79 changes: 48 additions & 31 deletions src/rust/bitbox02-rust/src/hww/api/show_shamir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,34 +33,18 @@ pub async fn process() -> Result<Response, Error> {
if bitbox02::memory::is_initialized() {
unlock::unlock_keystore("Unlock device", unlock::CanCancel::Yes).await?;
}
// Set a minimum threshold of 10 shares
let sharks = Sharks(3);
// Set a minimum threshold of 2 shares
let sharks = Sharks(2);

// // Obtain an iterator over the shares for secret [1, 2, 3, 4]
// // TODO: use RNG from SE?
let mut rng = rand_chacha::ChaCha8Rng::from_seed([0x90; 32]);

let seed = bitbox02::keystore::copy_seed()?;
// let seed = bitbox02::keystore::copy_seed()?;
let seed = [1,2,3];
let dealer = sharks.dealer_rng(&seed, &mut rng);
bitbox02::print_stdout(&format!("seed: {}, len: {}\n", hex::encode(seed.clone()), seed.len()));
// let dealer = sharks.dealer_rng(&[1,2,3,4], &mut rng);
// Get 3 shares
let mut shares: Vec<Share> = dealer.take(3).collect();
for s in shares {

// shares.remove(1);
// shares.remove(0);
// Recover the original secret!
// bitbox02::print_stdout("Recovering...\n");
// let secret = sharks.recover(shares.as_slice());
// match secret {
// Err(e) => bitbox02::print_stdout(&format!("Error {}\n", e)),
// Ok(_) => bitbox02::print_stdout("***test ok\n"),
// }
// assert_eq!(*secret.unwrap(), *seed);
let mnemonic_sentence = keystore::get_bip39_mnemonic_from_bytes(Vec::from(&s).as_ptr(), seed.len())?;

// let mnemonic_sentence = keystore::get_bip39_mnemonic()?;

confirm::confirm(&confirm::Params {
title: "Warning",
body: "DO NOT share your\nrecovery words with\nanyone!",
Expand All @@ -69,19 +53,52 @@ pub async fn process() -> Result<Response, Error> {
})
.await?;

confirm::confirm(&confirm::Params {
title: "Recovery\nwords",
body: "Please write down\nthe following words",
accept_is_nextarrow: true,
..Default::default()
})
.await?;
// Get 3 shares
let shares: Vec<Share> = dealer.take(3).collect();
let mut new_shares: Vec<Share> = Vec::new();
for s in shares {
let mut share_clean = Vec::from(&s);
share_clean[0] = (share_clean[0]+1)%3;
bitbox02::print_stdout(&format!("Share: {}\n", hex::encode(share_clean.clone())));
let share = sharks::Share::try_from(share_clean.as_slice()).unwrap();
new_shares.push(share);
}
let secret = sharks.recover(new_shares.as_slice());
match secret {
Err(e) => bitbox02::print_stdout(&format!("Error {}\n", e)),
Ok(secret) => bitbox02::print_stdout(&format!("Secret: {}\n", hex::encode(secret))),
};

let words: Vec<&str> = mnemonic_sentence.split(' ').collect();
// for s in dealer.take(3) {
// // let share = Vec::from(&s)[1..].to_vec();
// // bitbox02::print_stdout(&format!("share: {}, len: {}\n", hex::encode(share.clone()), share.len()));

mnemonic::show_and_confirm_mnemonic(&words).await?;
// // shares.remove(1);
// // shares.remove(0);
// // Recover the original secret!
// // bitbox02::print_stdout("Recovering...\n");
// // let secret = sharks.recover(shares.as_slice());
// // match secret {
// // Err(e) => bitbox02::print_stdout(&format!("Error {}\n", e)),
// // Ok(_) => bitbox02::print_stdout("***test ok\n"),
// // }
// // assert_eq!(*secret.unwrap(), *seed);
// // let mnemonic_sentence = keystore::get_bip39_mnemonic_from_bytes(share.as_ptr(), share.len())?;
// let mnemonic_sentence = "abuse erode slam exchange stereo scheme brush prepare sugar balcony soldier cup amazing auction frequent lemon medal catalog harvest view gift marble afraid assault";

// confirm::confirm(&confirm::Params {
// title: "Recovery\nwords #{s}", // FIXME
// body: "Please write down\nthe following words",
// accept_is_nextarrow: true,
// ..Default::default()
// })
// .await?;

}
// let words: Vec<&str> = mnemonic_sentence.split(' ').collect();

// mnemonic::show_and_confirm_mnemonic(&words).await?;

// }
bitbox02::memory::set_initialized().or(Err(Error::Memory))?;

status::status("Backup created", true).await;
Expand Down

0 comments on commit ecd8269

Please sign in to comment.