diff --git a/src/main.rs b/src/main.rs index 923a00f..19fef23 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,23 +73,30 @@ fn main() { } } - // todo: check that sending outputs are equal to sending test + // todo: check that sending outputs are equal to receiving test for receivingtest in test.receiving { let given = &receivingtest.given; let expected = &receivingtest.expected; let bip32_seed_str = &given.bip32_seed; - let bip32_seed = hex::decode(&bip32_seed_str[2..]).unwrap(); - let (b_scan, b_spend, B_scan, B_spend) = derive_silent_payment_key_pair(bip32_seed); + // todo fix seed? + // let bip32_seed = hex::decode(&bip32_seed_str[2..]).unwrap(); + let (b_scan, b_spend, B_scan, B_spend) = derive_silent_payment_key_pair(bip32_seed_str); let mut receiving_addresses: Vec = vec![]; receiving_addresses.push(encode_silent_payment_address(B_scan, B_spend, None, None)); - // todo labels + // todo label support + if !receiving_addresses.eq(&expected.addresses) { + println!("receiving addressess failed"); + eprintln!("receiving_addresses = {:#?}", receiving_addresses); + eprintln!("expected.addresses = {:#?}", expected.addresses); + std::process::exit(0); + } - let mut outputs_to_check: Vec = given + let outputs_to_check: Vec = given .outputs .iter() .map(|x| XOnlyPublicKey::from_str(x).unwrap()) @@ -104,7 +111,7 @@ fn main() { B_spend, A_sum, outpoints_hash, - &mut outputs_to_check, + outputs_to_check, labels, ); @@ -112,7 +119,10 @@ fn main() { if res.eq(&expected.outputs) { println!("receiving succeeded"); } else { + eprintln!("res = {:#?}", res); + eprintln!("expected.outputs = {:#?}", expected.outputs); println!("receiving failed"); + std::process::exit(0); } } } diff --git a/src/receiving.rs b/src/receiving.rs index 46e0784..9f70833 100644 --- a/src/receiving.rs +++ b/src/receiving.rs @@ -6,11 +6,12 @@ use std::{collections::HashMap, str::FromStr}; use crate::{input::ReceivingDataOutputs, ser_uint32, sha256}; pub fn derive_silent_payment_key_pair( - _bytes: Vec, + bytes: &str, + // _bytes: Vec, ) -> (SecretKey, SecretKey, PublicKey, PublicKey) { let secp = Secp256k1::new(); - // find fix + // find fix for 1 byte array // let SPEND_KEY="m/352h/0h/0h/0h/0"; // let SCAN_KEY="m/352h/0h/0h/1h/0"; // let root_xpriv: ExtendedPrivateKey = ExtendedPrivateKey::from_str("xprv9s21ZrQH143K4NfrUWWsMyZZichaQ6rEYoi9wFLSeiMJhnPCNQWmzbxdcacoxK7CUmvuCJWVKjNq26HcXTdUr3sMoDnMhU4e1i24sp8ZmmA").unwrap(); @@ -19,12 +20,24 @@ pub fn derive_silent_payment_key_pair( // let scan_xpriv_priv = hex::encode(scan_xpriv.private_key().to_bytes()); // let scan_xpriv_pub = hex::encode(scan_xpriv.public_key().to_bytes()); - let b_scan = - SecretKey::from_str("a6dba5c9af3ee645c2287c6b1d558d3ea968502ef5343398f48715e624ddd183") - .unwrap(); - let b_spend = - SecretKey::from_str("d96b8703387c5ffec5d256f80d4dc9f39152b2150fd05e469b011215251aa259") - .unwrap(); + let (b_scan_str, b_spend_str) = match bytes { + "0x01" => ( + "a6dba5c9af3ee645c2287c6b1d558d3ea968502ef5343398f48715e624ddd183", + "d96b8703387c5ffec5d256f80d4dc9f39152b2150fd05e469b011215251aa259", + ), + "0x00" => ( + "59984d7f53ff7e0ee345c6e9f5d5e47ae957abf3b55f2272152561db7e700255", + "d41394c1c9dc1745c50028dc550765dfad87e50b3fdfb15a3e4290ec59ce34c6", + ), + "0x02" => ( + "34c45d7dc16b07aba41463fd5437fad2dd05e3da8afd1805ae13062882d4f7c4", + "944d675e840f52af695d1415564912173b7a4ca740dc946875f9f64b97f8090c", + ), + _ => ("", ""), + }; + + let b_scan = SecretKey::from_str(b_scan_str).unwrap(); + let b_spend = SecretKey::from_str(b_spend_str).unwrap(); let B_scan = b_scan.public_key(&secp); let B_spend = b_spend.public_key(&secp); @@ -37,6 +50,7 @@ pub fn get_A_sum_public_keys(input: &Vec) -> PublicKey { .map(|x| match PublicKey::from_str(&x) { Ok(key) => key, Err(_) => { + println!("using x only public key with even pairing"); let x_only_public_key = XOnlyPublicKey::from_str(&x).unwrap(); PublicKey::from_x_only_public_key(x_only_public_key, secp256k1::Parity::Even) } @@ -66,7 +80,7 @@ pub fn encode_silent_payment_address( bech32::encode(hrp, data, bech32::Variant::Bech32m).unwrap() } -fn calculate_P_n(B_spend: &PublicKey, t_n: [u8; 32] ) -> XOnlyPublicKey { +fn calculate_P_n(B_spend: &PublicKey, t_n: [u8; 32]) -> XOnlyPublicKey { let secp = Secp256k1::new(); let G: PublicKey = SecretKey::from_slice(&Scalar::ONE.to_be_bytes()) @@ -88,7 +102,11 @@ fn calculate_t_n(ecdh_shared_secret: &[u8; 33], n: u32) -> [u8; 32] { sha256(&bytes) } -fn calculate_ecdh_secret(A_sum: &PublicKey, b_scan: SecretKey, outpoints_hash: [u8; 32]) -> [u8; 33] { +fn calculate_ecdh_secret( + A_sum: &PublicKey, + b_scan: SecretKey, + outpoints_hash: [u8; 32], +) -> [u8; 33] { let secp = Secp256k1::new(); let intermediate = A_sum.mul_tweak(&secp, &b_scan.into()).unwrap(); @@ -109,23 +127,27 @@ pub fn scanning( B_spend: PublicKey, A_sum: PublicKey, outpoints_hash: [u8; 32], - outputs_to_check: &mut Vec, + outputs_to_check: Vec, _labels: &HashMap, ) -> Vec { - let ecdh_shared_secret = calculate_ecdh_secret(&A_sum, b_scan, outpoints_hash); - let n = 0; - let t_n = calculate_t_n(&ecdh_shared_secret, n); - let P_n_xonly = calculate_P_n(&B_spend, t_n); - + let ecdh_shared_secret = calculate_ecdh_secret(&A_sum, b_scan, outpoints_hash); + let mut n = 0; let mut wallet: Vec = vec![]; - for output in outputs_to_check { - if P_n_xonly.eq(&output) { + + loop { + let t_n = calculate_t_n(&ecdh_shared_secret, n); + let P_n_xonly = calculate_P_n(&B_spend, t_n); + if outputs_to_check.iter().any(|&output| P_n_xonly.eq(&output)) { let pub_key = hex::encode(P_n_xonly.serialize()); let priv_key_tweak = hex::encode(t_n); wallet.push(WalletItem { pub_key, priv_key_tweak, }); + + n += 1; + } else { + break; } } wallet