From f7f34ffa64e441a3a4a0b86bcbc4535a9ddfc476 Mon Sep 17 00:00:00 2001 From: cygnet Date: Sun, 23 Jul 2023 14:15:45 +0200 Subject: [PATCH] Add verify receiving signatures --- Cargo.lock | 90 ++++++------------------------------------------ Cargo.toml | 4 +-- src/input.rs | 2 +- src/main.rs | 42 ++++++++++------------ src/receiving.rs | 51 ++++++++++++++++++++++++--- src/sending.rs | 2 -- 6 files changed, 80 insertions(+), 111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5169fa..e6987d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,12 +9,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" [[package]] -name = "block-buffer" -version = "0.10.4" +name = "bitcoin-private" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" + +[[package]] +name = "bitcoin_hashes" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" dependencies = [ - "generic-array", + "bitcoin-private", ] [[package]] @@ -23,51 +29,6 @@ version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cpufeatures" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "hex" version = "0.4.3" @@ -80,12 +41,6 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" -[[package]] -name = "libc" -version = "0.2.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - [[package]] name = "proc-macro2" version = "1.0.63" @@ -116,6 +71,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" dependencies = [ + "bitcoin_hashes", "secp256k1-sys", ] @@ -159,17 +115,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha2" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "silentpayments" version = "0.1.0" @@ -179,7 +124,6 @@ dependencies = [ "secp256k1", "serde", "serde_json", - "sha2", ] [[package]] @@ -193,20 +137,8 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "typenum" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - [[package]] name = "unicode-ident" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/Cargo.toml b/Cargo.toml index f94bfc3..523c5a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,11 +7,11 @@ edition = "2021" [dependencies] # bdk = {version = "0.20.0", features= ["all-keys"] } -secp256k1 = "0.27" +secp256k1 = {version = "0.27", features = ["bitcoin-hashes-std"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # rust-crypto = "0.2" -sha2 = "0.10" +# sha2 = "0.10" hex = "0.4" bech32 = "0.9" # bip32 = { version = "0.5", features = ["alloc"] } diff --git a/src/input.rs b/src/input.rs index 4b7c31c..4191ae2 100644 --- a/src/input.rs +++ b/src/input.rs @@ -69,7 +69,7 @@ pub struct ReceivingDataExpected { pub outputs: Vec, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Eq, PartialEq)] pub struct ReceivingDataOutputs { pub pub_key: String, pub priv_key_tweak: String, diff --git a/src/main.rs b/src/main.rs index 0ddb56e..cc554a8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,29 +4,23 @@ mod receiving; mod sending; use hex::FromHex; -use secp256k1::PublicKey; -use std::collections::HashSet; +use secp256k1::{ + hashes::{sha256, Hash}, PublicKey, +}; use std::str::FromStr; - -use sha2::{Digest, Sha256}; +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, + scanning, verify_and_calculate_signatures, }, sending::create_outputs, }; fn sha256(message: &[u8]) -> [u8; 32] { - let mut hasher = Sha256::new(); - hasher.update(message); - let result = hasher.finalize(); - - let mut hash = [0u8; 32]; - hash.copy_from_slice(&result[..]); - hash + sha256::Hash::hash(message).to_byte_array() } fn ser_uint32(u: u32) -> Vec { @@ -45,16 +39,13 @@ fn hash_outpoints(sending_data: &Vec<(String, u32)>) -> [u8; 32] { } outpoints.sort(); - let mut hasher = Sha256::new(); + let mut engine = sha256::HashEngine::default(); + for v in outpoints { - hasher.update(&v[..]); + engine.write_all(&v).unwrap(); } - let result = hasher.finalize(); - - let mut hash = [0u8; 32]; - hash.copy_from_slice(&result[..]); - hash + sha256::Hash::from_engine(engine).to_byte_array() } fn main() { @@ -71,6 +62,7 @@ fn main() { let mut receiving_addresses: Vec = vec![]; receiving_addresses.push(encode_silent_payment_address(B_scan, B_spend, None, None)); + eprintln!("receiving_addresses = {:?}", receiving_addresses); // todo labels @@ -84,7 +76,7 @@ fn main() { let A_sum = get_A_sum_public_keys(&given.input_pub_keys); let labels = &given.labels; - let add_to_wallet = scanning( + let mut add_to_wallet = scanning( b_scan, B_spend, A_sum, @@ -92,11 +84,15 @@ fn main() { outputs_to_check, labels, ); - eprintln!("add_to_wallet = {:?}", add_to_wallet); - // todo check signature + let res = verify_and_calculate_signatures(&mut add_to_wallet, b_spend).unwrap(); + if res.eq(&expected.outputs) { + println!("succeeded"); + } else { + println!("failed"); + } - // check that sending outputs are equal to sending test + // todo: check that sending outputs are equal to sending test for test in testdata { eprintln!("test.comment = {:?}", test.comment); diff --git a/src/receiving.rs b/src/receiving.rs index a9ca897..e5a6bf5 100644 --- a/src/receiving.rs +++ b/src/receiving.rs @@ -1,9 +1,11 @@ use bech32::ToBase32; -use secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey}; +use secp256k1::{ + hashes::Hash, schnorr::Signature, Message, PublicKey, Scalar, Secp256k1, SecretKey, +}; use std::{collections::HashMap, str::FromStr}; -use crate::{ser_uint32, sha256}; +use crate::{input::ReceivingDataOutputs, ser_uint32, sha256}; pub fn derive_silent_payment_key_pair( _bytes: Vec, @@ -66,8 +68,8 @@ pub fn encode_silent_payment_address( #[derive(Debug)] pub struct WalletItem { - pub_key: String, - priv_key_tweak: String, + pub pub_key: String, + pub priv_key_tweak: String, } pub fn scanning( @@ -111,3 +113,44 @@ pub fn scanning( } wallet } + +pub fn verify_and_calculate_signatures( + add_to_wallet: &mut Vec, + b_spend: SecretKey, +) -> Result, secp256k1::Error> { + let secp = secp256k1::Secp256k1::new(); + let msg = Message::from_hashed_data::(b"message"); + let aux = sha256::Hash::hash(b"random auxiliary data").to_byte_array(); + + let mut res: Vec = vec![]; + for output in add_to_wallet { + let pubkey = PublicKey::from_str(&output.pub_key).unwrap(); + let tweak = hex::decode(&output.priv_key_tweak).unwrap(); + let scalar = Scalar::from_be_bytes(tweak.try_into().unwrap()).unwrap(); + let mut full_priv_key = b_spend.add_tweak(&scalar).unwrap(); + + let (_, parity) = full_priv_key.x_only_public_key(&secp); + + if parity == secp256k1::Parity::Odd { + full_priv_key = full_priv_key.negate(); + } + + let sig = secp.sign_schnorr_with_aux_rand(&msg, &full_priv_key.keypair(&secp), &aux); + + eprintln!("sig = {:?}", sig); + + let (x_only_public_key, _) = pubkey.x_only_public_key(); + secp.verify_schnorr(&sig, &msg, &x_only_public_key)?; + + res.push(ReceivingDataOutputs { + pub_key: output.pub_key[2..].to_string(), + priv_key_tweak: output.priv_key_tweak.clone(), + signature: sig.to_string(), + }); + } + Ok(res) +} + +fn check_expected_outputs(add_to_wallet: Vec, outputs: &Vec) { + for item in add_to_wallet {} +} diff --git a/src/sending.rs b/src/sending.rs index 1f55b59..48a47d1 100644 --- a/src/sending.rs +++ b/src/sending.rs @@ -3,8 +3,6 @@ use bech32::FromBase32; use secp256k1::{Parity, PublicKey, Scalar, Secp256k1, SecretKey}; use std::{collections::HashMap, str::FromStr}; -use sha2::Digest; - use crate::{hash_outpoints, input::SendingDataGiven, ser_uint32, sha256}; fn get_a_sum_secret_keys(input: &Vec<(String, bool)>) -> SecretKey {