Add create_labeled_silent_payment_address function
This commit is contained in:
parent
fcb11d0208
commit
2d55f9fa49
|
@ -2,6 +2,12 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bech32"
|
||||
version = "0.9.1"
|
||||
|
@ -41,6 +47,36 @@ version = "1.0.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.63"
|
||||
|
@ -121,6 +157,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"bech32",
|
||||
"hex",
|
||||
"num-bigint",
|
||||
"secp256k1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
|
@ -15,3 +15,4 @@ serde_json = "1.0"
|
|||
hex = "0.4"
|
||||
bech32 = "0.9"
|
||||
# bip32 = { version = "0.5", features = ["alloc"] }
|
||||
num-bigint = "0.4.0"
|
||||
|
|
22
src/input.rs
22
src/input.rs
|
@ -1,3 +1,4 @@
|
|||
use num_bigint::BigUint;
|
||||
use serde::Deserialize;
|
||||
use serde_json::{from_str, Value};
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
@ -22,11 +23,11 @@ pub struct ReceivingDataGiven {
|
|||
pub input_pub_keys: Vec<String>,
|
||||
pub bip32_seed: String,
|
||||
#[serde(deserialize_with = "empty_array_as_map")]
|
||||
pub labels: HashMap<String, u32>,
|
||||
pub labels: HashMap<String, BigUint>,
|
||||
pub outputs: Vec<String>,
|
||||
}
|
||||
|
||||
fn empty_array_as_map<'de, D>(deserializer: D) -> Result<HashMap<String, u32>, D::Error>
|
||||
fn empty_array_as_map<'de, D>(deserializer: D) -> Result<HashMap<String, BigUint>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
|
@ -41,22 +42,25 @@ where
|
|||
}
|
||||
}
|
||||
Value::Object(map) => {
|
||||
let result: HashMap<String, u32> = map
|
||||
// let len = map.len();
|
||||
let result: HashMap<String, BigUint> = map
|
||||
.into_iter()
|
||||
.map(|(k, v)| {
|
||||
.filter_map(|(k, v)| {
|
||||
if let Value::Number(num) = v {
|
||||
num.as_i64()
|
||||
.and_then(|n| u32::from_str(&n.to_string()).ok())
|
||||
.and_then(|n| BigUint::from_str(&n.to_string()).ok())
|
||||
.map(|n| (k, n))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Option<_>>()
|
||||
.ok_or(serde::de::Error::custom(
|
||||
"Failed to parse map values as u32",
|
||||
))?;
|
||||
.collect();
|
||||
|
||||
// if result.len() != len {
|
||||
// return Err(serde::de::Error::custom(
|
||||
// "Failed to parse map values as BigUint",
|
||||
// ));
|
||||
// }
|
||||
Ok(result)
|
||||
}
|
||||
_ => Err(serde::de::Error::custom("Expected map or empty array")),
|
||||
|
|
18
src/main.rs
18
src/main.rs
|
@ -14,8 +14,9 @@ use std::{collections::HashSet, io::Write};
|
|||
use crate::{
|
||||
input::ComparableHashMap,
|
||||
receiving::{
|
||||
derive_silent_payment_key_pair, encode_silent_payment_address, get_A_sum_public_keys,
|
||||
scanning, verify_and_calculate_signatures,
|
||||
create_labeled_silent_payment_address, derive_silent_payment_key_pair,
|
||||
encode_silent_payment_address, get_A_sum_public_keys, scanning,
|
||||
verify_and_calculate_signatures,
|
||||
},
|
||||
sending::create_outputs,
|
||||
};
|
||||
|
@ -70,6 +71,7 @@ fn main() {
|
|||
} else {
|
||||
eprintln!("sending expected = {:#?}", expected_comparable);
|
||||
eprintln!("sending outputs = {:#?}", outputs_comparable);
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,8 +90,15 @@ fn main() {
|
|||
let mut receiving_addresses: Vec<String> = vec![];
|
||||
receiving_addresses.push(encode_silent_payment_address(B_scan, B_spend, None, None));
|
||||
|
||||
// todo label support
|
||||
if !receiving_addresses.eq(&expected.addresses) {
|
||||
for (_, label) in &given.labels {
|
||||
receiving_addresses.push(create_labeled_silent_payment_address(
|
||||
B_scan, B_spend, label, None, None,
|
||||
));
|
||||
}
|
||||
|
||||
let set1: HashSet<_> = receiving_addresses.iter().collect();
|
||||
let set2: HashSet<_> = expected.addresses.iter().collect();
|
||||
if !set1.eq(&set2) {
|
||||
println!("receiving addressess failed");
|
||||
eprintln!("receiving_addresses = {:#?}", receiving_addresses);
|
||||
eprintln!("expected.addresses = {:#?}", expected.addresses);
|
||||
|
@ -105,7 +114,6 @@ fn main() {
|
|||
let outpoints_hash = hash_outpoints(&given.outpoints);
|
||||
let A_sum = get_A_sum_public_keys(&given.input_pub_keys);
|
||||
let labels = &given.labels;
|
||||
|
||||
let mut add_to_wallet = scanning(
|
||||
b_scan,
|
||||
B_spend,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use bech32::ToBase32;
|
||||
|
||||
use num_bigint::BigUint;
|
||||
use secp256k1::{hashes::Hash, Message, PublicKey, Scalar, Secp256k1, SecretKey, XOnlyPublicKey};
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
|
@ -50,7 +51,7 @@ pub fn get_A_sum_public_keys(input: &Vec<String>) -> PublicKey {
|
|||
.map(|x| match PublicKey::from_str(&x) {
|
||||
Ok(key) => key,
|
||||
Err(_) => {
|
||||
println!("using x only public key with even pairing");
|
||||
// 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)
|
||||
}
|
||||
|
@ -80,6 +81,31 @@ pub fn encode_silent_payment_address(
|
|||
bech32::encode(hrp, data, bech32::Variant::Bech32m).unwrap()
|
||||
}
|
||||
|
||||
pub fn create_labeled_silent_payment_address(
|
||||
B_scan: PublicKey,
|
||||
B_spend: PublicKey,
|
||||
m: &BigUint,
|
||||
hrp: Option<&str>,
|
||||
version: Option<u8>,
|
||||
) -> String {
|
||||
let bytes = m.to_bytes_be();
|
||||
|
||||
let mut array = [0u8; 32];
|
||||
let start = array.len() - bytes.len();
|
||||
|
||||
array[start..].copy_from_slice(&bytes);
|
||||
|
||||
let scalar = Scalar::from_be_bytes(array).unwrap();
|
||||
let secp = Secp256k1::new();
|
||||
let G: PublicKey = SecretKey::from_slice(&Scalar::ONE.to_be_bytes())
|
||||
.unwrap()
|
||||
.public_key(&secp);
|
||||
let intermediate = G.mul_tweak(&secp, &scalar).unwrap();
|
||||
let B_m = intermediate.combine(&B_spend).unwrap();
|
||||
|
||||
encode_silent_payment_address(B_scan, B_m, hrp, version)
|
||||
}
|
||||
|
||||
fn calculate_P_n(B_spend: &PublicKey, t_n: [u8; 32]) -> XOnlyPublicKey {
|
||||
let secp = Secp256k1::new();
|
||||
|
||||
|
@ -128,7 +154,7 @@ pub fn scanning(
|
|||
A_sum: PublicKey,
|
||||
outpoints_hash: [u8; 32],
|
||||
outputs_to_check: Vec<XOnlyPublicKey>,
|
||||
_labels: &HashMap<String, u32>,
|
||||
_labels: &HashMap<String, BigUint>,
|
||||
) -> Vec<WalletItem> {
|
||||
let ecdh_shared_secret = calculate_ecdh_secret(&A_sum, b_scan, outpoints_hash);
|
||||
let mut n = 0;
|
||||
|
|
Loading…
Reference in New Issue