zcash-sync/src/key.rs

85 lines
3.0 KiB
Rust
Raw Normal View History

2022-02-28 07:35:29 -08:00
use bech32::{ToBase32, Variant};
2021-06-21 17:33:13 -07:00
use crate::NETWORK;
2021-06-26 02:52:03 -07:00
use bip39::{Language, Mnemonic, Seed};
2022-02-28 07:35:29 -08:00
use rand::RngCore;
use rand::rngs::OsRng;
2021-06-26 02:52:03 -07:00
use zcash_client_backend::encoding::{
decode_extended_full_viewing_key, decode_extended_spending_key,
encode_extended_full_viewing_key, encode_extended_spending_key, encode_payment_address,
};
use zcash_primitives::consensus::Parameters;
use zcash_primitives::zip32::{ChildIndex, ExtendedFullViewingKey, ExtendedSpendingKey};
2021-06-21 17:33:13 -07:00
2021-06-29 00:04:12 -07:00
pub fn decode_key(key: &str) -> anyhow::Result<(Option<String>, Option<String>, String, String)> {
2021-07-16 01:42:29 -07:00
let res = if let Ok(mnemonic) = Mnemonic::from_phrase(&key, Language::English) {
let (sk, ivk, pa) = derive_secret_key(&mnemonic)?;
Ok((Some(key.to_string()), Some(sk), ivk, pa))
} else if let Ok(Some(sk)) =
decode_extended_spending_key(NETWORK.hrp_sapling_extended_spending_key(), &key)
{
let (ivk, pa) = derive_viewing_key(&sk)?;
Ok((None, Some(key.to_string()), ivk, pa))
} else if let Ok(Some(fvk)) =
decode_extended_full_viewing_key(NETWORK.hrp_sapling_extended_full_viewing_key(), &key)
{
let pa = derive_address(&fvk)?;
Ok((None, None, key.to_string(), pa))
} else {
Err(anyhow::anyhow!("Not a valid key"))
};
2021-06-29 00:04:12 -07:00
res
}
2021-11-11 17:39:50 -08:00
pub fn is_valid_key(key: &str) -> i8 {
2021-06-29 00:04:12 -07:00
if Mnemonic::from_phrase(&key, Language::English).is_ok() {
2021-11-11 17:39:50 -08:00
return 0;
2021-06-29 00:04:12 -07:00
}
2021-07-16 01:42:29 -07:00
if let Ok(Some(_)) =
decode_extended_spending_key(NETWORK.hrp_sapling_extended_spending_key(), &key)
{
2021-11-11 17:39:50 -08:00
return 1;
2021-06-29 00:04:12 -07:00
}
2021-07-16 01:42:29 -07:00
if let Ok(Some(_)) =
decode_extended_full_viewing_key(NETWORK.hrp_sapling_extended_full_viewing_key(), &key)
{
2021-11-11 17:39:50 -08:00
return 2;
2021-06-29 00:04:12 -07:00
}
2021-11-11 17:39:50 -08:00
-1
2021-06-29 00:04:12 -07:00
}
pub fn derive_secret_key(mnemonic: &Mnemonic) -> anyhow::Result<(String, String, String)> {
2021-06-21 17:33:13 -07:00
let seed = Seed::new(&mnemonic, "");
let master = ExtendedSpendingKey::master(seed.as_bytes());
let path = [
ChildIndex::Hardened(32),
ChildIndex::Hardened(NETWORK.coin_type()),
ChildIndex::Hardened(0),
];
let extsk = ExtendedSpendingKey::from_path(&master, &path);
2021-07-16 01:42:29 -07:00
let sk = encode_extended_spending_key(NETWORK.hrp_sapling_extended_spending_key(), &extsk);
2021-06-21 17:33:13 -07:00
2021-06-29 00:04:12 -07:00
let (fvk, pa) = derive_viewing_key(&extsk)?;
Ok((sk, fvk, pa))
2021-06-21 17:33:13 -07:00
}
2021-06-29 00:04:12 -07:00
pub fn derive_viewing_key(extsk: &ExtendedSpendingKey) -> anyhow::Result<(String, String)> {
let fvk = ExtendedFullViewingKey::from(extsk);
let pa = derive_address(&fvk)?;
2021-07-16 01:42:29 -07:00
let fvk =
encode_extended_full_viewing_key(NETWORK.hrp_sapling_extended_full_viewing_key(), &fvk);
2021-06-29 00:04:12 -07:00
Ok((fvk, pa))
2021-06-21 17:33:13 -07:00
}
2021-06-29 00:04:12 -07:00
pub fn derive_address(fvk: &ExtendedFullViewingKey) -> anyhow::Result<String> {
2021-06-21 17:33:13 -07:00
let (_, payment_address) = fvk.default_address().unwrap();
let address = encode_payment_address(NETWORK.hrp_sapling_payment_address(), &payment_address);
Ok(address)
}
2022-02-28 07:35:29 -08:00
pub fn generate_random_enc_key() -> anyhow::Result<String> {
let mut key = [0u8; 32];
OsRng.fill_bytes(&mut key);
let key = bech32::encode("zwk", key.to_base32(), Variant::Bech32)?;
Ok(key)
}