From e2b7ad186e8ce311576549e25e3ae10770ba0c6b Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Fri, 18 Nov 2022 10:41:45 +0200 Subject: [PATCH] feat: upgrade tari_crypto sign api (#4932) Description --- Upgrade the tari crypto signing api to version 0.16.1 Add back FFI signing for wallet to use push notification How Has This Been Tested? --- Unit tests --- Cargo.lock | 16 +- applications/tari_app_grpc/Cargo.toml | 2 +- applications/tari_app_utilities/Cargo.toml | 2 +- applications/tari_base_node/Cargo.toml | 2 +- applications/tari_console_wallet/Cargo.toml | 2 +- .../tari_merge_mining_proxy/Cargo.toml | 2 +- applications/tari_miner/Cargo.toml | 2 +- base_layer/common_types/Cargo.toml | 2 +- base_layer/core/Cargo.toml | 2 +- .../core/src/transactions/coinbase_builder.rs | 4 +- .../core/src/transactions/test_helpers.rs | 4 +- .../side_chain/validator_node_registration.rs | 2 +- .../transaction_kernel.rs | 4 +- .../transaction_protocol/recipient.rs | 2 +- .../transaction_protocol/sender.rs | 5 +- .../transaction_protocol/single_receiver.rs | 2 +- base_layer/core/tests/mempool.rs | 2 +- base_layer/key_manager/Cargo.toml | 2 +- base_layer/mmr/Cargo.toml | 2 +- base_layer/p2p/Cargo.toml | 2 +- base_layer/tari_mining_helper_ffi/Cargo.toml | 2 +- base_layer/wallet/Cargo.toml | 2 +- base_layer/wallet/src/wallet.rs | 26 +- base_layer/wallet/tests/wallet.rs | 24 + base_layer/wallet_ffi/Cargo.toml | 2 +- base_layer/wallet_ffi/src/lib.rs | 591 +++++------------- base_layer/wallet_ffi/wallet.h | 109 ++-- common/Cargo.toml | 2 +- comms/core/Cargo.toml | 2 +- .../src/peer_manager/identity_signature.rs | 2 +- comms/dht/Cargo.toml | 2 +- comms/dht/src/message_signature.rs | 4 +- infrastructure/tari_script/Cargo.toml | 2 +- infrastructure/tari_script/src/script.rs | 34 +- infrastructure/tari_script/src/stack.rs | 18 +- 35 files changed, 323 insertions(+), 562 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2618126ad3..c06ba7c48a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4045,6 +4045,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfc62771e7b829b517cb213419236475f434fb480eddd76112ae182d274434a" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_cbor" version = "0.11.2" @@ -4814,8 +4825,8 @@ dependencies = [ [[package]] name = "tari_crypto" -version = "0.15.7" -source = "git+https://github.com/tari-project/tari-crypto.git?tag=v0.15.7#bd66b3d2021bf0b391d50f1ba8db339a62231738" +version = "0.16.1" +source = "git+https://github.com/tari-project/tari-crypto.git?tag=v0.16.1#fa042e498be144d8d2af7b96efe805c5af0b2d4f" dependencies = [ "base64 0.10.1", "blake2 0.9.2", @@ -4829,6 +4840,7 @@ dependencies = [ "once_cell", "rand 0.7.3", "serde", + "serde-wasm-bindgen", "serde_json", "sha3", "tari_bulletproofs", diff --git a/applications/tari_app_grpc/Cargo.toml b/applications/tari_app_grpc/Cargo.toml index 9c2e72e2d7..264f3b1bfa 100644 --- a/applications/tari_app_grpc/Cargo.toml +++ b/applications/tari_app_grpc/Cargo.toml @@ -11,7 +11,7 @@ edition = "2018" tari_common_types = { version = "^0.40", path = "../../base_layer/common_types" } tari_comms = { path = "../../comms/core" } tari_core = { path = "../../base_layer/core" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_script = { path = "../../infrastructure/tari_script" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } diff --git a/applications/tari_app_utilities/Cargo.toml b/applications/tari_app_utilities/Cargo.toml index 2d83699970..6ae1cc5a5c 100644 --- a/applications/tari_app_utilities/Cargo.toml +++ b/applications/tari_app_utilities/Cargo.toml @@ -7,7 +7,7 @@ license = "BSD-3-Clause" [dependencies] tari_comms = { path = "../../comms/core" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_common = { path = "../../common" } tari_common_types = { path = "../../base_layer/common_types" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } diff --git a/applications/tari_base_node/Cargo.toml b/applications/tari_base_node/Cargo.toml index 858de2d722..16c9d6e0a8 100644 --- a/applications/tari_base_node/Cargo.toml +++ b/applications/tari_base_node/Cargo.toml @@ -15,7 +15,7 @@ tari_comms = { path = "../../comms/core", features = ["rpc"] } tari_common_types = { path = "../../base_layer/common_types" } tari_comms_dht = { path = "../../comms/dht" } tari_core = { path = "../../base_layer/core", default-features = false, features = ["transactions"] } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_libtor = { path = "../../infrastructure/libtor", optional = true } tari_mmr = { path = "../../base_layer/mmr", features = ["native_bitmap"] } tari_p2p = { path = "../../base_layer/p2p", features = ["auto-update"] } diff --git a/applications/tari_console_wallet/Cargo.toml b/applications/tari_console_wallet/Cargo.toml index 39f4bee9fd..90d8ce27a3 100644 --- a/applications/tari_console_wallet/Cargo.toml +++ b/applications/tari_console_wallet/Cargo.toml @@ -7,7 +7,7 @@ license = "BSD-3-Clause" [dependencies] tari_wallet = { path = "../../base_layer/wallet", features = ["bundled_sqlite"] } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_common = { path = "../../common" } tari_app_utilities = { path = "../tari_app_utilities" } tari_comms = { path = "../../comms/core" } diff --git a/applications/tari_merge_mining_proxy/Cargo.toml b/applications/tari_merge_mining_proxy/Cargo.toml index 6f7cc1714f..63b565fa18 100644 --- a/applications/tari_merge_mining_proxy/Cargo.toml +++ b/applications/tari_merge_mining_proxy/Cargo.toml @@ -15,7 +15,7 @@ tari_common = { path = "../../common" } tari_comms = { path = "../../comms/core" } tari_core = { path = "../../base_layer/core", default-features = false, features = ["transactions"] } tari_app_utilities = { path = "../tari_app_utilities" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } tari_base_node_grpc_client = {path="../../clients/rust/base_node_grpc_client" } tari_wallet_grpc_client = {path="../../clients/rust/wallet_grpc_client" } diff --git a/applications/tari_miner/Cargo.toml b/applications/tari_miner/Cargo.toml index 3d0da269bb..9c14d65009 100644 --- a/applications/tari_miner/Cargo.toml +++ b/applications/tari_miner/Cargo.toml @@ -14,7 +14,7 @@ tari_common_types = { path = "../../base_layer/common_types" } tari_comms = { path = "../../comms/core" } tari_app_utilities = { path = "../tari_app_utilities" } tari_app_grpc = { path = "../tari_app_grpc" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } crossterm = { version = "0.25.0" } diff --git a/base_layer/common_types/Cargo.toml b/base_layer/common_types/Cargo.toml index c41e10ff29..9953bb5f11 100644 --- a/base_layer/common_types/Cargo.toml +++ b/base_layer/common_types/Cargo.toml @@ -7,7 +7,7 @@ version = "0.40.1" edition = "2018" [dependencies] -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } tari_common = { version = "^0.40", path = "../../common" } diff --git a/base_layer/core/Cargo.toml b/base_layer/core/Cargo.toml index d7d7a5a138..e7df40cfb9 100644 --- a/base_layer/core/Cargo.toml +++ b/base_layer/core/Cargo.toml @@ -24,7 +24,7 @@ tari_common_types = { version = "^0.40", path = "../../base_layer/common_types" tari_comms = { version = "^0.40", path = "../../comms/core" } tari_comms_dht = { version = "^0.40", path = "../../comms/dht" } tari_comms_rpc_macros = { version = "^0.40", path = "../../comms/rpc_macros" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_metrics = { path = "../../infrastructure/metrics" } tari_mmr = { version = "^0.40", path = "../../base_layer/mmr", optional = true, features = ["native_bitmap"] } tari_p2p = { version = "^0.40", path = "../../base_layer/p2p" } diff --git a/base_layer/core/src/transactions/coinbase_builder.rs b/base_layer/core/src/transactions/coinbase_builder.rs index 8e8b6e9afe..26c3703791 100644 --- a/base_layer/core/src/transactions/coinbase_builder.rs +++ b/base_layer/core/src/transactions/coinbase_builder.rs @@ -207,7 +207,7 @@ impl CoinbaseBuilder { let metadata = TransactionMetadata::new_with_features(0.into(), 0, kernel_features); let challenge = TransactionKernel::build_kernel_challenge_from_tx_meta(&public_nonce, excess.as_public_key(), &metadata); - let sig = Signature::sign(spending_key.clone(), nonce, &challenge) + let sig = Signature::sign_raw(&spending_key, nonce, &challenge) .map_err(|_| CoinbaseBuildError::BuildError("Challenge could not be represented as a scalar".into()))?; let hasher = @@ -554,7 +554,7 @@ mod test { &KernelFeatures::empty(), &None, ); - coinbase_kernel2.excess_sig = Signature::sign(output.spending_key, p2.nonce, &challenge).unwrap(); + coinbase_kernel2.excess_sig = Signature::sign_raw(&output.spending_key, p2.nonce, &challenge).unwrap(); tx.body.add_output(coinbase2); tx.body.add_kernel(coinbase_kernel2); diff --git a/base_layer/core/src/transactions/test_helpers.rs b/base_layer/core/src/transactions/test_helpers.rs index 19f76b4da3..01b11a67c4 100644 --- a/base_layer/core/src/transactions/test_helpers.rs +++ b/base_layer/core/src/transactions/test_helpers.rs @@ -279,7 +279,7 @@ pub fn create_signature(k: PrivateKey, fee: MicroTari, lock_height: u64, feature &PublicKey::from_secret_key(&k), &tx_meta, ); - Signature::sign(k, r, &e).unwrap() + Signature::sign_raw(&k, r, &e).unwrap() } /// Generate a random transaction signature given a key, returning the public key (excess) and the signature. @@ -294,7 +294,7 @@ pub fn create_random_signature_from_s_key( let p = PK::from_secret_key(&s_key); let tx_meta = TransactionMetadata::new_with_features(fee, lock_height, features); let e = TransactionKernel::build_kernel_challenge_from_tx_meta(&PublicKey::from_secret_key(&r), &p, &tx_meta); - (p, Signature::sign(s_key, r, &e).unwrap()) + (p, Signature::sign_raw(&s_key, r, &e).unwrap()) } pub fn create_consensus_manager() -> ConsensusManager { diff --git a/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_registration.rs b/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_registration.rs index c37fb83689..fc9692c989 100644 --- a/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_registration.rs +++ b/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_registration.rs @@ -48,7 +48,7 @@ impl ValidatorNodeRegistration { let (secret_nonce, public_nonce) = PublicKey::random_keypair(&mut OsRng); let public_key = PublicKey::from_secret_key(private_key); let challenge = Self::construct_challenge(&public_key, &public_nonce, msg); - let signature = Signature::sign(private_key.clone(), secret_nonce, &*challenge) + let signature = Signature::sign_raw(private_key, secret_nonce, &*challenge) .expect("Sign cannot fail with 32-byte challenge and a RistrettoPublicKey"); Self { public_key, signature } } diff --git a/base_layer/core/src/transactions/transaction_components/transaction_kernel.rs b/base_layer/core/src/transactions/transaction_components/transaction_kernel.rs index db4ac1d738..a24cb042de 100644 --- a/base_layer/core/src/transactions/transaction_components/transaction_kernel.rs +++ b/base_layer/core/src/transactions/transaction_components/transaction_kernel.rs @@ -276,8 +276,8 @@ mod tests { MicroTari::from(100), 123, test_params.commit_value(321.into()), - Signature::sign( - test_params.spend_key.clone(), + Signature::sign_raw( + &test_params.spend_key, test_params.nonce.clone(), test_params.nonce.as_bytes(), ) diff --git a/base_layer/core/src/transactions/transaction_protocol/recipient.rs b/base_layer/core/src/transactions/transaction_protocol/recipient.rs index a2ae20b0eb..dababab66f 100644 --- a/base_layer/core/src/transactions/transaction_protocol/recipient.rs +++ b/base_layer/core/src/transactions/transaction_protocol/recipient.rs @@ -264,7 +264,7 @@ mod test { let r_sum = &msg.public_nonce + &p.public_nonce; let excess = &msg.public_excess + &PublicKey::from_secret_key(&p.spend_key); let e = TransactionKernel::build_kernel_challenge_from_tx_meta(&r_sum, &excess, &m); - let s = Signature::sign(p.spend_key.clone(), p.nonce, &e).unwrap(); + let s = Signature::sign_raw(&p.spend_key, p.nonce, &e).unwrap(); assert_eq!(data.partial_signature, s); } diff --git a/base_layer/core/src/transactions/transaction_protocol/sender.rs b/base_layer/core/src/transactions/transaction_protocol/sender.rs index 8786b0bcdb..6a5492d5a5 100644 --- a/base_layer/core/src/transactions/transaction_protocol/sender.rs +++ b/base_layer/core/src/transactions/transaction_protocol/sender.rs @@ -494,8 +494,7 @@ impl SenderTransactionProtocol { // Create sender signature let public_commitment_nonce = PublicKey::from_secret_key(private_commitment_nonce); let e = output.get_metadata_signature_challenge(Some(&public_commitment_nonce)); - let sender_signature = - Signature::sign(sender_offset_private_key.clone(), private_commitment_nonce.clone(), &e)?; + let sender_signature = Signature::sign_raw(sender_offset_private_key, private_commitment_nonce.clone(), &e)?; let sender_signature = sender_signature.get_signature(); // Create aggregated metadata signature let (r_pub, u, v) = output.metadata_signature.complete_signature_tuple(); @@ -591,7 +590,7 @@ impl SenderTransactionProtocol { let k = info.offset_blinding_factor.clone(); let r = info.private_nonce.clone(); - let s = Signature::sign(k, r, &e).map_err(TPE::SigningError)?; + let s = Signature::sign_raw(&k, r, &e).map_err(TPE::SigningError)?; info.signatures.push(s); Ok(()) }, diff --git a/base_layer/core/src/transactions/transaction_protocol/single_receiver.rs b/base_layer/core/src/transactions/transaction_protocol/single_receiver.rs index 67c6132968..5ec43de86d 100644 --- a/base_layer/core/src/transactions/transaction_protocol/single_receiver.rs +++ b/base_layer/core/src/transactions/transaction_protocol/single_receiver.rs @@ -74,7 +74,7 @@ impl SingleReceiverTransactionProtocol { &(&sender_info.public_excess + &public_spending_key), &tx_meta, ); - let signature = Signature::sign(spending_key, nonce, &e).map_err(TPE::SigningError)?; + let signature = Signature::sign_raw(&spending_key, nonce, &e).map_err(TPE::SigningError)?; let data = RD { tx_id: sender_info.tx_id, output, diff --git a/base_layer/core/tests/mempool.rs b/base_layer/core/tests/mempool.rs index 2f752be821..3f854e60e7 100644 --- a/base_layer/core/tests/mempool.rs +++ b/base_layer/core/tests/mempool.rs @@ -986,7 +986,7 @@ async fn consensus_validation_large_tx() { let e = TransactionKernel::build_kernel_challenge_from_tx_meta(&public_nonce, &excess, &tx_meta); let k = offset_blinding_factor; let r = nonce; - let s = Signature::sign(k, r, &e).unwrap(); + let s = Signature::sign_raw(&k, r, &e).unwrap(); let kernel = KernelBuilder::new() .with_fee(fee) diff --git a/base_layer/key_manager/Cargo.toml b/base_layer/key_manager/Cargo.toml index dab69905a2..bf8617bcaa 100644 --- a/base_layer/key_manager/Cargo.toml +++ b/base_layer/key_manager/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["lib", "cdylib"] # NB: All dependencies must support or be gated for the WASM target. [dependencies] tari_common_types = { version = "^0.40", path = "../../base_layer/common_types", optional = true } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } argon2 = { version = "0.4.1", features = ["std", "alloc"] } diff --git a/base_layer/mmr/Cargo.toml b/base_layer/mmr/Cargo.toml index 0392e7dfcf..4db3f643b9 100644 --- a/base_layer/mmr/Cargo.toml +++ b/base_layer/mmr/Cargo.toml @@ -14,7 +14,7 @@ benches = ["criterion"] [dependencies] tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_common = {path = "../../common"} thiserror = "1.0.26" digest = "0.9.0" diff --git a/base_layer/p2p/Cargo.toml b/base_layer/p2p/Cargo.toml index a4344a1799..545f4f45da 100644 --- a/base_layer/p2p/Cargo.toml +++ b/base_layer/p2p/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" tari_comms = { version = "^0.40", path = "../../comms/core" } tari_comms_dht = { version = "^0.40", path = "../../comms/dht" } tari_common = { version = "^0.40", path = "../../common" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_service_framework = { version = "^0.40", path = "../service_framework" } tari_shutdown = { version = "^0.40", path = "../../infrastructure/shutdown" } tari_storage = { version = "^0.40", path = "../../infrastructure/storage" } diff --git a/base_layer/tari_mining_helper_ffi/Cargo.toml b/base_layer/tari_mining_helper_ffi/Cargo.toml index a8ab553417..4dc688846a 100644 --- a/base_layer/tari_mining_helper_ffi/Cargo.toml +++ b/base_layer/tari_mining_helper_ffi/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" [dependencies] tari_comms = { version = "^0.40", path = "../../comms/core" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_common = { path = "../../common" } tari_core = { path = "../core", default-features = false, features = ["transactions"]} tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } diff --git a/base_layer/wallet/Cargo.toml b/base_layer/wallet/Cargo.toml index c8de237f51..7d8858a504 100644 --- a/base_layer/wallet/Cargo.toml +++ b/base_layer/wallet/Cargo.toml @@ -12,7 +12,7 @@ tari_common = { path = "../../common" } tari_common_types = { version = "^0.40", path = "../../base_layer/common_types" } tari_comms = { version = "^0.40", path = "../../comms/core" } tari_comms_dht = { version = "^0.40", path = "../../comms/dht" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_key_manager = { version = "^0.40", path = "../key_manager" } tari_p2p = { version = "^0.40", path = "../p2p", features = ["auto-update"] } tari_script = { path = "../../infrastructure/tari_script" } diff --git a/base_layer/wallet/src/wallet.rs b/base_layer/wallet/src/wallet.rs index 4aae59c6d1..e56d69e1f7 100644 --- a/base_layer/wallet/src/wallet.rs +++ b/base_layer/wallet/src/wallet.rs @@ -27,7 +27,7 @@ use tari_common::configuration::bootstrap::ApplicationType; use tari_common_types::{ tari_address::TariAddress, transaction::{ImportStatus, TxId}, - types::{ComSignature, Commitment, PrivateKey, PublicKey}, + types::{ComSignature, Commitment, PrivateKey, PublicKey, Signature}, }; use tari_comms::{ multiaddr::Multiaddr, @@ -47,7 +47,12 @@ use tari_core::{ CryptoFactories, }, }; -use tari_crypto::{hash::blake2::Blake256, tari_utilities::hex::Hex}; +use tari_crypto::{ + hash::blake2::Blake256, + ristretto::{RistrettoPublicKey, RistrettoSchnorr, RistrettoSecretKey}, + signatures::{SchnorrSignature, SchnorrSignatureError}, + tari_utilities::hex::Hex, +}; use tari_key_manager::{ cipher_seed::CipherSeed, key_manager::KeyManager, @@ -508,6 +513,23 @@ where Ok(tx_id) } + pub fn sign_message( + &mut self, + secret: &RistrettoSecretKey, + message: &str, + ) -> Result, SchnorrSignatureError> { + RistrettoSchnorr::sign_message(secret, message.as_bytes()) + } + + pub fn verify_message_signature( + &mut self, + public_key: &RistrettoPublicKey, + signature: &Signature, + message: &str, + ) -> bool { + signature.verify_message(public_key, message) + } + /// Appraise the expected outputs and a fee pub async fn preview_coin_split_with_commitments_no_amount( &mut self, diff --git a/base_layer/wallet/tests/wallet.rs b/base_layer/wallet/tests/wallet.rs index 0832e20e2f..182bb80d56 100644 --- a/base_layer/wallet/tests/wallet.rs +++ b/base_layer/wallet/tests/wallet.rs @@ -485,6 +485,30 @@ async fn test_do_not_overwrite_master_key() { .unwrap(); } +#[tokio::test] +async fn test_sign_message() { + let factories = CryptoFactories::default(); + let dir = tempdir().unwrap(); + + let shutdown = Shutdown::new(); + let mut wallet = create_wallet( + dir.path(), + "wallet_db", + factories.clone(), + shutdown.to_signal(), + None, + None, + ) + .await + .unwrap(); + + let (secret, public_key) = PublicKey::random_keypair(&mut OsRng); + let message = "Tragedy will find us."; + let schnorr = wallet.sign_message(&secret, message).unwrap(); + + assert!(wallet.verify_message_signature(&public_key, &schnorr, message)); +} + #[test] fn test_many_iterations_store_and_forward_send_tx() { for _n in 1..=10 { diff --git a/base_layer/wallet_ffi/Cargo.toml b/base_layer/wallet_ffi/Cargo.toml index 0b6e599882..d17b672607 100644 --- a/base_layer/wallet_ffi/Cargo.toml +++ b/base_layer/wallet_ffi/Cargo.toml @@ -12,7 +12,7 @@ tari_common = {path="../../common"} tari_common_types = {path="../common_types"} tari_comms = { version = "^0.40", path = "../../comms/core", features = ["c_integration"]} tari_comms_dht = { version = "^0.40", path = "../../comms/dht", default-features = false } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_key_manager = { version = "^0.40", path = "../key_manager" } tari_p2p = { version = "^0.40", path = "../p2p" } tari_script = { path = "../../infrastructure/tari_script" } diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index d83be197f3..d7a98124a6 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -90,7 +90,7 @@ use tari_common_types::{ emoji::emoji_set, tari_address::{TariAddress, TariAddressError}, transaction::{TransactionDirection, TransactionStatus, TxId}, - types::{Commitment, PublicKey}, + types::{Commitment, PublicKey, Signature}, }; use tari_comms::{ multiaddr::Multiaddr, @@ -122,7 +122,6 @@ use tari_p2p::{ TransportType, DEFAULT_DNS_NAME_SERVER, }; -use tari_script::{inputs, script}; use tari_shutdown::Shutdown; use tari_utilities::{hex, hex::Hex, SafePassword}; use tari_wallet::{ @@ -1402,92 +1401,6 @@ pub unsafe extern "C" fn private_key_from_hex(key: *const c_char, error_out: *mu } } -/// -------------------------------------------------------------------------------------------- /// -/// -/// ------------------------------- Commitment Signature ---------------------------------------/// - -/// Creates a TariCommitmentSignature from `u`, `v` and `public_nonce` ByteVectors -/// -/// ## Arguments -/// `public_nonce_bytes` - The public nonce signature component as a ByteVector -/// `u_bytes` - The u signature component as a ByteVector -/// `v_bytes` - The v signature component as a ByteVector -/// `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions -/// as an out parameter. -/// -/// ## Returns -/// `TariCommitmentSignature` - Returns a commitment signature. Note that it will be ptr::null_mut() if any argument is -/// null or if there was an error with the contents of bytes -/// -/// # Safety -/// The ```commitment_signature_destroy``` function must be called when finished with a TariCommitmentSignature to -/// prevent a memory leak -#[no_mangle] -pub unsafe extern "C" fn commitment_signature_create_from_bytes( - public_nonce_bytes: *const ByteVector, - u_bytes: *const ByteVector, - v_bytes: *const ByteVector, - error_out: *mut c_int, -) -> *mut TariCommitmentSignature { - let mut error = 0; - ptr::swap(error_out, &mut error as *mut c_int); - if public_nonce_bytes.is_null() { - error = LibWalletError::from(InterfaceError::NullError("public_nonce_bytes".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - return ptr::null_mut(); - } - if u_bytes.is_null() { - error = LibWalletError::from(InterfaceError::NullError("u_bytes".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - return ptr::null_mut(); - } - if v_bytes.is_null() { - error = LibWalletError::from(InterfaceError::NullError("v_bytes".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - return ptr::null_mut(); - } - - let nonce = match Commitment::from_bytes(&(*public_nonce_bytes).0.clone()) { - Ok(nonce) => nonce, - Err(e) => { - error!( - target: LOG_TARGET, - "Error creating a nonce commitment from bytes: {:?}", e - ); - error = LibWalletError::from(e).code; - ptr::swap(error_out, &mut error as *mut c_int); - return ptr::null_mut(); - }, - }; - let u = match TariPrivateKey::from_bytes(&(*u_bytes).0.clone()) { - Ok(u) => u, - Err(e) => { - error!( - target: LOG_TARGET, - "Error creating a Private Key (u) from bytes: {:?}", e - ); - error = LibWalletError::from(e).code; - ptr::swap(error_out, &mut error as *mut c_int); - return ptr::null_mut(); - }, - }; - let v = match TariPrivateKey::from_bytes(&(*v_bytes).0.clone()) { - Ok(u) => u, - Err(e) => { - error!( - target: LOG_TARGET, - "Error creating a Private Key (v) from bytes: {:?}", e - ); - error = LibWalletError::from(e).code; - ptr::swap(error_out, &mut error as *mut c_int); - return ptr::null_mut(); - }, - }; - - let sig = TariCommitmentSignature::new(nonce, u, v); - Box::into_raw(Box::new(sig)) -} - /// Frees memory for a TariCommitmentSignature /// /// ## Arguments @@ -5129,6 +5042,169 @@ pub unsafe extern "C" fn wallet_preview_coin_split( } } +/// Signs a message using the public key of the TariWallet +/// +/// ## Arguments +/// `wallet` - The TariWallet pointer. +/// `msg` - The message pointer. +/// `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions +/// as an out parameter. +/// ## Returns +/// `*mut c_char` - Returns the pointer to the hexadecimal representation of the signature and +/// public nonce, seperated by a pipe character. Empty if an error occured. +/// +/// # Safety +/// The ```string_destroy``` method must be called when finished with a string coming from rust to prevent a memory leak +#[no_mangle] +pub unsafe extern "C" fn wallet_sign_message( + wallet: *mut TariWallet, + msg: *const c_char, + error_out: *mut c_int, +) -> *mut c_char { + let mut error = 0; + let mut result = CString::new("").expect("Blank CString will not fail."); + + ptr::swap(error_out, &mut error as *mut c_int); + if wallet.is_null() { + error = LibWalletError::from(InterfaceError::NullError("wallet".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + return result.into_raw(); + } + + if msg.is_null() { + error = LibWalletError::from(InterfaceError::NullError("message".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + return result.into_raw(); + } + + let secret = (*wallet).wallet.comms.node_identity().secret_key().clone(); + let message = CStr::from_ptr(msg) + .to_str() + .expect("CString should not fail here.") + .to_owned(); + + let signature = (*wallet).wallet.sign_message(&secret, &message); + + match signature { + Ok(s) => { + let hex_sig = s.get_signature().to_hex(); + let hex_nonce = s.get_public_nonce().to_hex(); + let hex_return = format!("{}|{}", hex_sig, hex_nonce); + result = CString::new(hex_return).expect("CString should not fail here."); + }, + Err(e) => { + error = LibWalletError::from(e).code; + ptr::swap(error_out, &mut error as *mut c_int); + }, + } + + result.into_raw() +} + +/// Verifies the signature of the message signed by a TariWallet +/// +/// ## Arguments +/// `wallet` - The TariWallet pointer. +/// `public_key` - The pointer to the TariPublicKey of the wallet which originally signed the message +/// `hex_sig_nonce` - The pointer to the sting containing the hexadecimal representation of the +/// signature and public nonce seperated by a pipe character. +/// `msg` - The pointer to the msg the signature will be checked against. +/// `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions +/// as an out parameter. +/// ## Returns +/// `bool` - Returns if the signature is valid or not, will be false if an error occurs. +/// +/// # Safety +/// None +#[no_mangle] +pub unsafe extern "C" fn wallet_verify_message_signature( + wallet: *mut TariWallet, + public_key: *mut TariPublicKey, + hex_sig_nonce: *const c_char, + msg: *const c_char, + error_out: *mut c_int, +) -> bool { + let mut error = 0; + let mut result = false; + ptr::swap(error_out, &mut error as *mut c_int); + if wallet.is_null() { + error = LibWalletError::from(InterfaceError::NullError("wallet".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + return result; + } + if public_key.is_null() { + error = LibWalletError::from(InterfaceError::NullError("public key".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + return result; + } + if hex_sig_nonce.is_null() { + error = LibWalletError::from(InterfaceError::NullError("signature".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + return result; + } + if msg.is_null() { + error = LibWalletError::from(InterfaceError::NullError("message".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + return result; + } + + let message = match CStr::from_ptr(msg).to_str() { + Ok(v) => v.to_owned(), + _ => { + error = LibWalletError::from(InterfaceError::PointerError("msg".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + return false; + }, + }; + let hex = match CStr::from_ptr(hex_sig_nonce).to_str() { + Ok(v) => v.to_owned(), + _ => { + error = LibWalletError::from(InterfaceError::PointerError("hex_sig_nonce".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + return false; + }, + }; + let hex_keys: Vec<&str> = hex.split('|').collect(); + if hex_keys.len() != 2 { + error = LibWalletError::from(InterfaceError::PositionInvalidError).code; + ptr::swap(error_out, &mut error as *mut c_int); + return result; + } + + if let Some(key1) = hex_keys.get(0) { + if let Some(key2) = hex_keys.get(1) { + let secret = TariPrivateKey::from_hex(key1); + match secret { + Ok(p) => { + let public_nonce = TariPublicKey::from_hex(key2); + match public_nonce { + Ok(pn) => { + let sig = Signature::new(pn, p); + result = (*wallet).wallet.verify_message_signature(&*public_key, &sig, &message) + }, + Err(e) => { + error = LibWalletError::from(e).code; + ptr::swap(error_out, &mut error as *mut c_int); + }, + } + }, + Err(e) => { + error = LibWalletError::from(e).code; + ptr::swap(error_out, &mut error as *mut c_int); + }, + } + } else { + error = LibWalletError::from(InterfaceError::InvalidArgument("hex_sig_nonce".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + } + } else { + error = LibWalletError::from(InterfaceError::InvalidArgument("hex_sig_nonce".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + } + + result +} + /// Adds a base node peer to the TariWallet /// /// ## Arguments @@ -6341,178 +6417,6 @@ pub unsafe extern "C" fn wallet_get_tari_address( Box::into_raw(Box::new(address)) } -/// Import an external UTXO into the wallet as a non-rewindable (i.e. non-recoverable) output. This will add a spendable -/// UTXO (as EncumberedToBeReceived) and create a faux completed transaction to record the event. -/// -/// ## Arguments -/// `wallet` - The TariWallet pointer -/// `amount` - The value of the UTXO in MicroTari -/// `spending_key` - The private spending key -/// `source_address` - The tari address of the source of the transaction -/// `features` - Options for an output's structure or use -/// `metadata_signature` - UTXO signature with the script offset private key, k_O -/// `sender_offset_public_key` - Tari script offset pubkey, K_O -/// `script_private_key` - Tari script private key, k_S, is used to create the script signature -/// `covenant` - The covenant that will be executed when spending this output -/// `message` - The message that the transaction will have -/// `encrypted_value` - Encrypted value. -/// `minimum_value_promise` - The minimum value of the commitment that is proven by the range proof -/// `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions -/// as an out parameter. -/// -/// ## Returns -/// `c_ulonglong` - Returns the TransactionID of the generated transaction, note that it will be zero if the -/// transaction is null -/// -/// # Safety -/// None -#[no_mangle] -#[allow(clippy::too_many_lines)] -pub unsafe extern "C" fn wallet_import_external_utxo_as_non_rewindable( - wallet: *mut TariWallet, - amount: c_ulonglong, - spending_key: *mut TariPrivateKey, - source_address: *mut TariWalletAddress, - features: *mut TariOutputFeatures, - metadata_signature: *mut TariCommitmentSignature, - sender_offset_public_key: *mut TariPublicKey, - script_private_key: *mut TariPrivateKey, - covenant: *mut TariCovenant, - encrypted_value: *mut TariEncryptedValue, - minimum_value_promise: c_ulonglong, - message: *const c_char, - error_out: *mut c_int, -) -> c_ulonglong { - let mut error = 0; - ptr::swap(error_out, &mut error as *mut c_int); - if wallet.is_null() { - error = LibWalletError::from(InterfaceError::NullError("wallet".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - return 0; - } - - if spending_key.is_null() { - error = LibWalletError::from(InterfaceError::NullError("spending_key".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - return 0; - } - - let source_address = if source_address.is_null() { - TariWalletAddress::default() - } else { - (*source_address).clone() - }; - - if metadata_signature.is_null() { - error = LibWalletError::from(InterfaceError::NullError("metadata_signature".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - return 0; - } - - if sender_offset_public_key.is_null() { - error = LibWalletError::from(InterfaceError::NullError("sender_offset_public_key".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - return 0; - } - - if script_private_key.is_null() { - error = LibWalletError::from(InterfaceError::NullError("script_private_key".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - return 0; - } - - let features = if features.is_null() { - TariOutputFeatures::default() - } else { - (*features).clone() - }; - - let covenant = if covenant.is_null() { - TariCovenant::default() - } else { - (*covenant).clone() - }; - - let encrypted_value = if encrypted_value.is_null() { - TariEncryptedValue::default() - } else { - (*encrypted_value).clone() - }; - - let message_string; - if message.is_null() { - error = LibWalletError::from(InterfaceError::NullError("message".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - message_string = CString::new("Imported UTXO") - .expect("CString will not fail") - .to_str() - .expect("CString.toStr() will not fail") - .to_owned(); - } else { - match CStr::from_ptr(message).to_str() { - Ok(v) => { - message_string = v.to_owned(); - }, - _ => { - error = LibWalletError::from(InterfaceError::PointerError("message".to_string())).code; - ptr::swap(error_out, &mut error as *mut c_int); - message_string = CString::new("Imported UTXO") - .expect("CString will not fail") - .to_str() - .expect("CString.to_str() will not fail") - .to_owned(); - }, - } - }; - - let public_script_key = PublicKey::from_secret_key(&(*spending_key)); - - // TODO: the script_lock_height can be something other than 0, for example an HTLC transaction - match (*wallet) - .runtime - .block_on((*wallet).wallet.import_external_utxo_as_non_rewindable( - MicroTari::from(amount), - &(*spending_key).clone(), - script!(Nop), - inputs!(public_script_key), - source_address, - features, - message_string, - (*metadata_signature).clone(), - &(*script_private_key).clone(), - &(*sender_offset_public_key).clone(), - 0, - covenant, - encrypted_value, - MicroTari::from(minimum_value_promise), - )) { - Ok(tx_id) => { - if let Err(e) = (*wallet) - .runtime - .block_on((*wallet).wallet.output_manager_service.validate_txos()) - { - error = LibWalletError::from(WalletError::OutputManagerError(e)).code; - ptr::swap(error_out, &mut error as *mut c_int); - return 0; - } - if let Err(e) = (*wallet) - .runtime - .block_on((*wallet).wallet.transaction_service.validate_transactions()) - { - error = LibWalletError::from(WalletError::TransactionServiceError(e)).code; - ptr::swap(error_out, &mut error as *mut c_int); - return 0; - } - tx_id.as_u64() - }, - Err(e) => { - error = LibWalletError::from(e).code; - ptr::swap(error_out, &mut error as *mut c_int); - 0 - }, - } -} - /// Cancel a Pending Transaction /// /// ## Arguments @@ -7753,10 +7657,7 @@ mod test { use libc::{c_char, c_uchar, c_uint}; use tari_common_types::{emoji, transaction::TransactionStatus, types::PrivateKey}; - use tari_core::{ - covenant, - transactions::test_helpers::{create_test_input, create_unblinded_output, TestParams}, - }; + use tari_core::{covenant, transactions::test_helpers::create_test_input}; use tari_crypto::ristretto::pedersen::extended_commitment_factory::ExtendedPedersenCommitmentFactory; use tari_key_manager::{mnemonic::MnemonicLanguage, mnemonic_wordlists}; use tari_test_utils::random; @@ -8251,30 +8152,6 @@ mod test { } } - #[test] - fn test_comm_sig_create() { - unsafe { - let mut error = 0; - let error_ptr = &mut error as *mut c_int; - let (u, _) = PublicKey::random_keypair(&mut OsRng); - let u_bytes = Box::into_raw(Box::new(ByteVector(u.to_vec()))); - let (v, nonce) = PublicKey::random_keypair(&mut OsRng); - let v_bytes = Box::into_raw(Box::new(ByteVector(v.to_vec()))); - let nonce_bytes = Box::into_raw(Box::new(ByteVector(nonce.to_vec()))); - - let sig = commitment_signature_create_from_bytes(nonce_bytes, u_bytes, v_bytes, error_ptr); - assert_eq!(error, 0); - assert_eq!(*(*sig).public_nonce(), Commitment::from_public_key(&nonce)); - assert_eq!(*(*sig).u(), u); - assert_eq!(*(*sig).v(), v); - - commitment_signature_destroy(sig); - byte_vector_destroy(nonce_bytes); - byte_vector_destroy(u_bytes); - byte_vector_destroy(v_bytes); - } - } - #[test] fn test_covenant_create_empty() { unsafe { @@ -9107,144 +8984,6 @@ mod test { } } - fn get_next_memory_address() -> Multiaddr { - let port = MemoryTransport::acquire_next_memsocket_port(); - format!("/memory/{}", port).parse().unwrap() - } - - #[test] - #[allow(clippy::too_many_lines)] - pub fn test_import_external_utxo() { - unsafe { - let mut error = 0; - let error_ptr = &mut error as *mut c_int; - let mut recovery_in_progress = true; - let recovery_in_progress_ptr = &mut recovery_in_progress as *mut bool; - - // create a new wallet - let db_name = CString::new(random::string(8).as_str()).unwrap(); - let db_name_str: *const c_char = CString::into_raw(db_name) as *const c_char; - let temp_dir = tempdir().unwrap(); - let db_path = CString::new(temp_dir.path().to_str().unwrap()).unwrap(); - let db_path_str: *const c_char = CString::into_raw(db_path) as *const c_char; - let transport_type = transport_memory_create(); - let address = transport_memory_get_address(transport_type, error_ptr); - let address_str = CStr::from_ptr(address).to_str().unwrap().to_owned(); - let address_str = CString::new(address_str).unwrap().into_raw() as *const c_char; - let network = CString::new(NETWORK_STRING).unwrap(); - let network_str: *const c_char = CString::into_raw(network) as *const c_char; - - let config = comms_config_create( - address_str, - transport_type, - db_name_str, - db_path_str, - 20, - 10800, - error_ptr, - ); - - let wallet_ptr = wallet_create( - config, - ptr::null(), - 0, - 0, - ptr::null(), - ptr::null(), - network_str, - received_tx_callback, - received_tx_reply_callback, - received_tx_finalized_callback, - broadcast_callback, - mined_callback, - mined_unconfirmed_callback, - scanned_callback, - scanned_unconfirmed_callback, - transaction_send_result_callback, - tx_cancellation_callback, - txo_validation_complete_callback, - contacts_liveness_data_updated_callback, - balance_updated_callback, - transaction_validation_complete_callback, - saf_messages_received_callback, - connectivity_status_callback, - recovery_in_progress_ptr, - error_ptr, - ); - - let node_identity = - NodeIdentity::random(&mut OsRng, get_next_memory_address(), PeerFeatures::COMMUNICATION_NODE); - let base_node_peer_public_key_ptr = Box::into_raw(Box::new(node_identity.public_key().clone())); - let base_node_peer_address_ptr = - CString::into_raw(CString::new(node_identity.public_address().to_string()).unwrap()) as *const c_char; - wallet_add_base_node_peer( - wallet_ptr, - base_node_peer_public_key_ptr, - base_node_peer_address_ptr, - error_ptr, - ); - - // Test the consistent features case - let utxo_1 = create_unblinded_output( - script!(Nop), - OutputFeatures::default(), - &TestParams::new(), - MicroTari(1234u64), - ); - let amount = utxo_1.value.as_u64(); - let spending_key_ptr = Box::into_raw(Box::new(utxo_1.spending_key)); - let features_ptr = Box::into_raw(Box::new(utxo_1.features.clone())); - let source_address_ptr = Box::into_raw(Box::new(TariWalletAddress::default())); - let metadata_signature_ptr = Box::into_raw(Box::new(utxo_1.metadata_signature)); - let sender_offset_public_key_ptr = Box::into_raw(Box::new(utxo_1.sender_offset_public_key)); - let script_private_key_ptr = Box::into_raw(Box::new(utxo_1.script_private_key)); - let covenant_ptr = Box::into_raw(Box::new(utxo_1.covenant)); - let encrypted_value_ptr = Box::into_raw(Box::new(utxo_1.encrypted_value)); - let minimum_value_promise = utxo_1.minimum_value_promise.as_u64(); - let message_ptr = CString::into_raw(CString::new("For my friend").unwrap()) as *const c_char; - - let tx_id = wallet_import_external_utxo_as_non_rewindable( - wallet_ptr, - amount, - spending_key_ptr, - source_address_ptr, - features_ptr, - metadata_signature_ptr, - sender_offset_public_key_ptr, - script_private_key_ptr, - covenant_ptr, - encrypted_value_ptr, - minimum_value_promise, - message_ptr, - error_ptr, - ); - assert_eq!(error, 0); - assert!(tx_id > 0); - - // Cleanup - string_destroy(message_ptr as *mut c_char); - let _covenant = Box::from_raw(covenant_ptr); - let _script_private_key = Box::from_raw(script_private_key_ptr); - let _sender_offset_public_key = Box::from_raw(sender_offset_public_key_ptr); - let _metadata_signature = Box::from_raw(metadata_signature_ptr); - let _features = Box::from_raw(features_ptr); - let _source_address = Box::from_raw(source_address_ptr); - let _spending_key = Box::from_raw(spending_key_ptr); - - let _base_node_peer_public_key = Box::from_raw(base_node_peer_public_key_ptr); - string_destroy(base_node_peer_address_ptr as *mut c_char); - - string_destroy(network_str as *mut c_char); - string_destroy(db_name_str as *mut c_char); - string_destroy(db_path_str as *mut c_char); - string_destroy(address_str as *mut c_char); - transport_config_destroy(transport_type); - - comms_config_destroy(config); - wallet_destroy(wallet_ptr); - } - } - #[test] #[allow(clippy::too_many_lines)] pub fn test_seed_words() { diff --git a/base_layer/wallet_ffi/wallet.h b/base_layer/wallet_ffi/wallet.h index a789915957..13d207f170 100644 --- a/base_layer/wallet_ffi/wallet.h +++ b/base_layer/wallet_ffi/wallet.h @@ -865,32 +865,6 @@ TariPrivateKey *private_key_generate(void); TariPrivateKey *private_key_from_hex(const char *key, int *error_out); -/** - * -------------------------------------------------------------------------------------------- /// - * - * ------------------------------- Commitment Signature ---------------------------------------/// - * Creates a TariCommitmentSignature from `u`, `v` and `public_nonce` ByteVectors - * - * ## Arguments - * `public_nonce_bytes` - The public nonce signature component as a ByteVector - * `u_bytes` - The u signature component as a ByteVector - * `v_bytes` - The v signature component as a ByteVector - * `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions - * as an out parameter. - * - * ## Returns - * `TariCommitmentSignature` - Returns a commitment signature. Note that it will be ptr::null_mut() if any argument is - * null or if there was an error with the contents of bytes - * - * # Safety - * The ```commitment_signature_destroy``` function must be called when finished with a TariCommitmentSignature to - * prevent a memory leak - */ -TariCommitmentSignature *commitment_signature_create_from_bytes(const struct ByteVector *public_nonce_bytes, - const struct ByteVector *u_bytes, - const struct ByteVector *v_bytes, - int *error_out); - /** * Frees memory for a TariCommitmentSignature * @@ -2577,6 +2551,48 @@ struct TariCoinPreview *wallet_preview_coin_split(struct TariWallet *wallet, uint64_t fee_per_gram, int32_t *error_ptr); +/** + * Signs a message using the public key of the TariWallet + * + * ## Arguments + * `wallet` - The TariWallet pointer. + * `msg` - The message pointer. + * `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions + * as an out parameter. + * ## Returns + * `*mut c_char` - Returns the pointer to the hexadecimal representation of the signature and + * public nonce, seperated by a pipe character. Empty if an error occured. + * + * # Safety + * The ```string_destroy``` method must be called when finished with a string coming from rust to prevent a memory leak + */ +char *wallet_sign_message(struct TariWallet *wallet, + const char *msg, + int *error_out); + +/** + * Verifies the signature of the message signed by a TariWallet + * + * ## Arguments + * `wallet` - The TariWallet pointer. + * `public_key` - The pointer to the TariPublicKey of the wallet which originally signed the message + * `hex_sig_nonce` - The pointer to the sting containing the hexadecimal representation of the + * signature and public nonce seperated by a pipe character. + * `msg` - The pointer to the msg the signature will be checked against. + * `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions + * as an out parameter. + * ## Returns + * `bool` - Returns if the signature is valid or not, will be false if an error occurs. + * + * # Safety + * None + */ +bool wallet_verify_message_signature(struct TariWallet *wallet, + TariPublicKey *public_key, + const char *hex_sig_nonce, + const char *msg, + int *error_out); + /** * Adds a base node peer to the TariWallet * @@ -3014,47 +3030,6 @@ TariCompletedTransaction *wallet_get_cancelled_transaction_by_id(struct TariWall TariWalletAddress *wallet_get_tari_address(struct TariWallet *wallet, int *error_out); -/** - * Import an external UTXO into the wallet as a non-rewindable (i.e. non-recoverable) output. This will add a spendable - * UTXO (as EncumberedToBeReceived) and create a faux completed transaction to record the event. - * - * ## Arguments - * `wallet` - The TariWallet pointer - * `amount` - The value of the UTXO in MicroTari - * `spending_key` - The private spending key - * `source_address` - The tari address of the source of the transaction - * `features` - Options for an output's structure or use - * `metadata_signature` - UTXO signature with the script offset private key, k_O - * `sender_offset_public_key` - Tari script offset pubkey, K_O - * `script_private_key` - Tari script private key, k_S, is used to create the script signature - * `covenant` - The covenant that will be executed when spending this output - * `message` - The message that the transaction will have - * `encrypted_value` - Encrypted value. - * `minimum_value_promise` - The minimum value of the commitment that is proven by the range proof - * `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions - * as an out parameter. - * - * ## Returns - * `c_ulonglong` - Returns the TransactionID of the generated transaction, note that it will be zero if the - * transaction is null - * - * # Safety - * None - */ -unsigned long long wallet_import_external_utxo_as_non_rewindable(struct TariWallet *wallet, - unsigned long long amount, - TariPrivateKey *spending_key, - TariWalletAddress *source_address, - TariOutputFeatures *features, - TariCommitmentSignature *metadata_signature, - TariPublicKey *sender_offset_public_key, - TariPrivateKey *script_private_key, - TariCovenant *covenant, - TariEncryptedValue *encrypted_value, - unsigned long long minimum_value_promise, - const char *message, - int *error_out); - /** * Cancel a Pending Transaction * diff --git a/common/Cargo.toml b/common/Cargo.toml index 8287b6c33f..5c70645ab5 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -14,7 +14,7 @@ build = ["toml", "prost-build"] static-application-info = ["git2"] [dependencies] -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } anyhow = "1.0.53" config = { version = "0.13.0", default_features = false, features = ["toml"] } diff --git a/comms/core/Cargo.toml b/comms/core/Cargo.toml index bbde9d6274..c61adc6875 100644 --- a/comms/core/Cargo.toml +++ b/comms/core/Cargo.toml @@ -10,7 +10,7 @@ version = "0.40.1" edition = "2018" [dependencies] -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_common = {path = "../../common"} tari_metrics = { path = "../../infrastructure/metrics" } tari_storage = { version = "^0.40", path = "../../infrastructure/storage" } diff --git a/comms/core/src/peer_manager/identity_signature.rs b/comms/core/src/peer_manager/identity_signature.rs index 522703ea62..512116e301 100644 --- a/comms/core/src/peer_manager/identity_signature.rs +++ b/comms/core/src/peer_manager/identity_signature.rs @@ -75,7 +75,7 @@ impl IdentitySignature { updated_at, ) .finalize(); - let signature = Signature::sign(secret_key.clone(), secret_nonce, challenge.as_ref()) + let signature = Signature::sign_raw(secret_key, secret_nonce, challenge.as_ref()) .expect("unreachable panic: challenge hash digest is the correct length"); Self { version: Self::LATEST_VERSION, diff --git a/comms/dht/Cargo.toml b/comms/dht/Cargo.toml index c3703ee222..656f34f8bf 100644 --- a/comms/dht/Cargo.toml +++ b/comms/dht/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" tari_comms = { version = "^0.40", path = "../core", features = ["rpc"] } tari_common = { path = "../../common" } tari_comms_rpc_macros = { version = "^0.40", path = "../rpc_macros" } -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } tari_shutdown = { version = "^0.40", path = "../../infrastructure/shutdown" } tari_storage = { version = "^0.40", path = "../../infrastructure/storage" } diff --git a/comms/dht/src/message_signature.rs b/comms/dht/src/message_signature.rs index 494c9a5a90..7d22e8a0e4 100644 --- a/comms/dht/src/message_signature.rs +++ b/comms/dht/src/message_signature.rs @@ -59,7 +59,7 @@ impl MessageSignature { let (nonce_s, nonce_pk) = CommsPublicKey::random_keypair(&mut OsRng); let signer_public_key = CommsPublicKey::from_secret_key(&signer_secret_key); let challenge = construct_message_signature_hash(&signer_public_key, &nonce_pk, message); - let signature = Signature::sign(signer_secret_key, nonce_s, &challenge) + let signature = Signature::sign_raw(&signer_secret_key, nonce_s, &challenge) .expect("challenge is [u8;32] but SchnorrSignature::sign failed"); Self { @@ -181,7 +181,7 @@ mod test { // Change to . Note: We need signer_k because the Signature interface does not provide a way to // change just the public nonce, an attacker does not need the secret key. - mac.signature = Signature::sign(signer_k, nonce_k, &msg).unwrap(); + mac.signature = Signature::sign_raw(&signer_k, nonce_k, &msg).unwrap(); assert!(!mac.verify(MSG)); } } diff --git a/infrastructure/tari_script/Cargo.toml b/infrastructure/tari_script/Cargo.toml index 17d8586260..5dd600b5f6 100644 --- a/infrastructure/tari_script/Cargo.toml +++ b/infrastructure/tari_script/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" license = "BSD-3-Clause" [dependencies] -tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.7" } +tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.16.1" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag="v0.4.7" } blake2 = "0.9" diff --git a/infrastructure/tari_script/src/script.rs b/infrastructure/tari_script/src/script.rs index 5b4b9b19a9..6f3c0d6ea2 100644 --- a/infrastructure/tari_script/src/script.rs +++ b/infrastructure/tari_script/src/script.rs @@ -994,7 +994,7 @@ mod test { let (pvt_key, pub_key) = RistrettoPublicKey::random_keypair(&mut rng); let nonce = RistrettoSecretKey::random(&mut rng); let m_key = RistrettoSecretKey::random(&mut rng); - let sig = RistrettoSchnorr::sign(pvt_key, nonce, m_key.as_bytes()).unwrap(); + let sig = RistrettoSchnorr::sign_raw(&pvt_key, nonce, m_key.as_bytes()).unwrap(); let msg = slice_to_boxed_message(m_key.as_bytes()); let script = script!(CheckSig(msg)); let inputs = inputs!(sig.clone(), pub_key.clone()); @@ -1016,7 +1016,7 @@ mod test { let (pvt_key, pub_key) = RistrettoPublicKey::random_keypair(&mut rng); let nonce = RistrettoSecretKey::random(&mut rng); let m_key = RistrettoSecretKey::random(&mut rng); - let sig = RistrettoSchnorr::sign(pvt_key, nonce, m_key.as_bytes()).unwrap(); + let sig = RistrettoSchnorr::sign_raw(&pvt_key, nonce, m_key.as_bytes()).unwrap(); let msg = slice_to_boxed_message(m_key.as_bytes()); let script = script!(CheckSigVerify(msg) PushOne); let inputs = inputs!(sig.clone(), pub_key.clone()); @@ -1045,7 +1045,7 @@ mod test { for _ in 0..n { let (k, p) = RistrettoPublicKey::random_keypair(&mut rng); let r = RistrettoSecretKey::random(&mut rng); - let s = RistrettoSchnorr::sign(k.clone(), r, m.as_bytes()).unwrap(); + let s = RistrettoSchnorr::sign_raw(&k, r, m.as_bytes()).unwrap(); data.push((k, p, s)); } @@ -1067,11 +1067,11 @@ mod test { let r4 = RistrettoSecretKey::random(&mut rng); let r5 = RistrettoSecretKey::random(&mut rng); let m = RistrettoSecretKey::random(&mut rng); - let s_alice = RistrettoSchnorr::sign(k_alice.clone(), r1, m.as_bytes()).unwrap(); - let s_bob = RistrettoSchnorr::sign(k_bob, r2, m.as_bytes()).unwrap(); - let s_eve = RistrettoSchnorr::sign(k_eve, r3, m.as_bytes()).unwrap(); - let s_carol = RistrettoSchnorr::sign(k_carol, r4, m.as_bytes()).unwrap(); - let s_alice2 = RistrettoSchnorr::sign(k_alice, r5, m.as_bytes()).unwrap(); + let s_alice = RistrettoSchnorr::sign_raw(&k_alice, r1, m.as_bytes()).unwrap(); + let s_bob = RistrettoSchnorr::sign_raw(&k_bob, r2, m.as_bytes()).unwrap(); + let s_eve = RistrettoSchnorr::sign_raw(&k_eve, r3, m.as_bytes()).unwrap(); + let s_carol = RistrettoSchnorr::sign_raw(&k_carol, r4, m.as_bytes()).unwrap(); + let s_alice2 = RistrettoSchnorr::sign_raw(&k_alice, r5, m.as_bytes()).unwrap(); let msg = slice_to_boxed_message(m.as_bytes()); // 1 of 2 @@ -1256,10 +1256,10 @@ mod test { let r3 = RistrettoSecretKey::random(&mut rng); let r4 = RistrettoSecretKey::random(&mut rng); let m = RistrettoSecretKey::random(&mut rng); - let s_alice = RistrettoSchnorr::sign(k_alice, r1, m.as_bytes()).unwrap(); - let s_bob = RistrettoSchnorr::sign(k_bob, r2, m.as_bytes()).unwrap(); - let s_eve = RistrettoSchnorr::sign(k_eve, r3, m.as_bytes()).unwrap(); - let s_carol = RistrettoSchnorr::sign(k_carol, r4, m.as_bytes()).unwrap(); + let s_alice = RistrettoSchnorr::sign_raw(&k_alice, r1, m.as_bytes()).unwrap(); + let s_bob = RistrettoSchnorr::sign_raw(&k_bob, r2, m.as_bytes()).unwrap(); + let s_eve = RistrettoSchnorr::sign_raw(&k_eve, r3, m.as_bytes()).unwrap(); + let s_carol = RistrettoSchnorr::sign_raw(&k_carol, r4, m.as_bytes()).unwrap(); let msg = slice_to_boxed_message(m.as_bytes()); // 1 of 2 @@ -1438,8 +1438,8 @@ mod test { let msg = slice_to_boxed_message(m.as_bytes()); let script = script!(Add RevRot Add CheckSigVerify(msg) PushOne); - let s1 = RistrettoSchnorr::sign(k1, r1, m.as_bytes()).unwrap(); - let s2 = RistrettoSchnorr::sign(k2, r2, m.as_bytes()).unwrap(); + let s1 = RistrettoSchnorr::sign_raw(&k1, r1, m.as_bytes()).unwrap(); + let s2 = RistrettoSchnorr::sign_raw(&k2, r2, m.as_bytes()).unwrap(); let inputs = inputs!(p1, p2, s1, s2); let result = script.execute(&inputs).unwrap(); assert_eq!(result, Number(1)); @@ -1573,9 +1573,9 @@ mod test { let m = RistrettoSecretKey::random(&mut rng); let msg = slice_to_boxed_message(m.as_bytes()); - let s_alice = RistrettoSchnorr::sign(k_alice, r1, m.as_bytes()).unwrap(); - let s_bob = RistrettoSchnorr::sign(k_bob, r2, m.as_bytes()).unwrap(); - let s_eve = RistrettoSchnorr::sign(k_eve, r3, m.as_bytes()).unwrap(); + let s_alice = RistrettoSchnorr::sign_raw(&k_alice, r1, m.as_bytes()).unwrap(); + let s_bob = RistrettoSchnorr::sign_raw(&k_bob, r2, m.as_bytes()).unwrap(); + let s_eve = RistrettoSchnorr::sign_raw(&k_eve, r3, m.as_bytes()).unwrap(); // 1 of 2 use crate::Opcode::{CheckSig, Drop, Dup, Else, EndIf, IfThen, PushPubKey, Return}; diff --git a/infrastructure/tari_script/src/stack.rs b/infrastructure/tari_script/src/stack.rs index f3b714b95c..7553a2c590 100644 --- a/infrastructure/tari_script/src/stack.rs +++ b/infrastructure/tari_script/src/stack.rs @@ -360,14 +360,7 @@ mod test { use tari_crypto::{ hash::blake2::Blake256, keys::{PublicKey, SecretKey}, - ristretto::{ - pedersen::PedersenCommitment, - utils, - utils::SignatureSet, - RistrettoPublicKey, - RistrettoSchnorr, - RistrettoSecretKey, - }, + ristretto::{pedersen::PedersenCommitment, RistrettoPublicKey, RistrettoSchnorr, RistrettoSecretKey}, }; use tari_utilities::{ hex::{from_hex, Hex}, @@ -380,11 +373,8 @@ mod test { fn as_bytes_roundtrip() { use crate::StackItem::{Number, PublicKey, Signature}; let k = RistrettoSecretKey::random(&mut rand::thread_rng()); - let SignatureSet { - signature: s, - public_nonce: p, - .. - } = utils::sign::(&k, b"hi").unwrap(); + let p = RistrettoPublicKey::from_secret_key(&k); + let s = RistrettoSchnorr::sign_message(&k, b"hi").unwrap(); let items = vec![Number(5432), Number(21), Signature(s), PublicKey(p)]; let stack = ExecutionStack::new(items); let bytes = stack.to_bytes(); @@ -400,7 +390,7 @@ mod test { RistrettoSecretKey::from_hex("193ee873f3de511eda8ae387db6498f3d194d31a130a94cdf13dc5890ec1ad0f").unwrap(); let p = RistrettoPublicKey::from_secret_key(&k); let m = Blake256::digest(b"Hello Tari Script"); - let sig = RistrettoSchnorr::sign(k, r, m.as_slice()).unwrap(); + let sig = RistrettoSchnorr::sign_raw(&k, r, m.as_slice()).unwrap(); let scalar: ScalarValue = m.into(); let inputs = inputs!(sig, p, scalar); assert_eq!(inputs.to_hex(), "0500f7c695528c858cde76dab3076908e01228b6dbdd5f671bed1b03b89e170c316db1023d5c46d78a97da8eb6c5a37e00d5f2fee182dcb38c1b6c65e90a43c1090456c0fa32558d6edc0916baa26b48e745de834571534ca253ea82435f08ebbc7c06fdf9fc345d2cdd8aff624a55f824c7c9ce3cc972e011b4e750e417a90ecc5da5");