rust-silentpayments/tests/vector_tests.rs

156 lines
5.5 KiB
Rust

#![allow(non_snake_case)]
mod common;
#[cfg(test)]
mod tests {
use std::{
collections::{HashMap, HashSet},
str::FromStr,
};
use secp256k1::{PublicKey, SecretKey};
#[cfg(feature = "receiving")]
use silentpayments::receiving::SilentPayment;
#[cfg(feature = "sending")]
use silentpayments::sending::{decode_scan_pubkey, generate_recipient_pubkeys};
use crate::common::{
structs::TestData,
utils::{
self, calculate_tweak_data_for_recipient, decode_input_pub_keys, decode_outpoints,
decode_outputs_to_check, decode_priv_keys, decode_recipients, get_a_sum_secret_keys,
hash_outpoints, sender_calculate_shared_secret, verify_and_calculate_signatures,
},
};
const IS_TESTNET: bool = false;
#[test]
fn test_with_test_vectors() {
let testdata = utils::read_file();
for test in testdata {
process_test_case(test);
}
}
fn process_test_case(test_case: TestData) {
let mut sending_outputs: HashSet<String> = HashSet::new();
eprintln!("test.comment = {:?}", test_case.comment);
#[cfg(feature = "sending")]
for sendingtest in test_case.sending {
let given = sendingtest.given;
let expected = sendingtest.expected.outputs;
let expected_output_addresses: HashSet<String> =
expected.iter().map(|(x, _)| x.into()).collect();
let input_priv_keys = decode_priv_keys(&given.input_priv_keys);
let outpoints = decode_outpoints(&given.outpoints);
let outpoints_hash = hash_outpoints(&outpoints);
let silent_addresses = decode_recipients(&given.recipients);
let a_sum = get_a_sum_secret_keys(&input_priv_keys);
let mut ecdh_shared_secrets: HashMap<PublicKey, PublicKey> = HashMap::new();
for addr in &silent_addresses {
let B_scan = decode_scan_pubkey(addr.to_owned()).unwrap();
let ecdh_shared_secret =
sender_calculate_shared_secret(a_sum, B_scan, outpoints_hash);
ecdh_shared_secrets.insert(B_scan, ecdh_shared_secret);
}
let outputs =
generate_recipient_pubkeys(silent_addresses, ecdh_shared_secrets).unwrap();
for output_pubkeys in &outputs {
for pubkey in output_pubkeys.1 {
// TODO check if this is always true
sending_outputs.insert(hex::encode(pubkey.serialize()));
}
}
assert_eq!(sending_outputs, expected_output_addresses);
}
#[cfg(feature = "receiving")]
for receivingtest in test_case.receiving {
let given = receivingtest.given;
let mut expected = receivingtest.expected;
let receiving_outputs: HashSet<String> = given.outputs.iter().cloned().collect();
#[cfg(feature = "sending")]
// assert that the generated sending outputs are a subset
// of the expected receiving outputs
// i.e. all the generated outputs are present
assert!(sending_outputs.is_subset(&receiving_outputs));
let b_scan = SecretKey::from_str(&given.scan_priv_key).unwrap();
let b_spend = SecretKey::from_str(&given.spend_priv_key).unwrap();
let mut sp_receiver = SilentPayment::new(0, b_scan, b_spend, IS_TESTNET).unwrap();
let outputs_to_check = decode_outputs_to_check(&given.outputs);
let outpoints = decode_outpoints(&given.outpoints);
let input_pub_keys = decode_input_pub_keys(&given.input_pub_keys);
for (_, label) in &given.labels {
let label = label[..].try_into().unwrap();
sp_receiver.add_label(label).unwrap();
}
let mut receiving_addresses: HashSet<String> = HashSet::new();
// get receiving address for no label
receiving_addresses.insert(sp_receiver.get_receiving_address(None).unwrap());
// get receiving addresses for every label
let labels = sp_receiver.list_labels();
for label in &labels {
receiving_addresses.insert(sp_receiver.get_receiving_address(Some(label)).unwrap());
}
let set1: HashSet<_> = receiving_addresses.iter().collect();
let set2: HashSet<_> = expected.addresses.iter().collect();
// check that the receiving addresses generated are equal
// to the expected addresses
assert_eq!(set1, set2);
let tweak_data = calculate_tweak_data_for_recipient(&input_pub_keys, &outpoints);
let scanned_outputs_received = sp_receiver
.scan_transaction(&tweak_data, outputs_to_check)
.unwrap();
let privkeys: Vec<SecretKey> = scanned_outputs_received
.into_iter()
.flat_map(|(_, list)| {
let mut ret: Vec<SecretKey> = vec![];
for l in list {
ret.push(l);
}
ret
})
.collect();
let mut res = verify_and_calculate_signatures(privkeys, b_spend).unwrap();
res.sort_by_key(|output| output.pub_key.clone());
expected
.outputs
.sort_by_key(|output| output.pub_key.clone());
assert_eq!(res, expected.outputs);
}
}
}