From 010ac1dad93acdcb1618068b99a29d96f465a1b9 Mon Sep 17 00:00:00 2001 From: Hansie Odendaal Date: Mon, 15 Jul 2024 17:55:18 +0200 Subject: [PATCH] Add ledger methods Added ledger methods to support faucet spending. --- Cargo.lock | 871 +++++++++++++----- .../minotari_ledger_wallet/comms/Cargo.toml | 8 +- .../examples/ledger_demo/ledger_wallet.rs | 110 +++ .../comms/examples/ledger_demo/main.rs | 301 ++++++ .../comms/src/ledger_wallet.rs | 8 +- .../src/handlers/get_schnorr_signature.rs | 120 +++ .../minotari_ledger_wallet/wallet/src/main.rs | 23 +- .../src/transactions/key_manager/inner.rs | 358 +++++-- .../src/transactions/key_manager/interface.rs | 49 +- .../transaction_components/error.rs | 2 + .../src/key_manager_service/error.rs | 4 +- .../src/key_manager_service/service.rs | 12 +- 12 files changed, 1558 insertions(+), 308 deletions(-) create mode 100644 applications/minotari_ledger_wallet/comms/examples/ledger_demo/ledger_wallet.rs create mode 100644 applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs create mode 100644 applications/minotari_ledger_wallet/wallet/src/handlers/get_schnorr_signature.rs diff --git a/Cargo.lock b/Cargo.lock index ae9c6dcf2f..8e690c76b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ dependencies = [ "getrandom", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.32", ] [[package]] @@ -1250,7 +1250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -1262,7 +1262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] @@ -1394,7 +1394,7 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "group", - "rand_core", + "rand_core 0.6.4", "rustc_version", "serde", "subtle", @@ -1805,7 +1805,7 @@ dependencies = [ "hkdf", "pem-rfc7468", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -1939,7 +1939,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -1956,7 +1956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand", + "rand 0.8.5", "rustc-hex", "static_assertions", ] @@ -2275,7 +2275,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -2965,7 +2965,7 @@ dependencies = [ "libtor-derive", "libtor-sys", "log", - "rand", + "rand 0.8.5", "sha1 0.6.0", ] @@ -3071,7 +3071,7 @@ dependencies = [ "log-mdc", "once_cell", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "serde", "serde-value", "serde_json", @@ -3165,7 +3165,7 @@ checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" dependencies = [ "byteorder", "keccak", - "rand_core", + "rand_core 0.6.4", "zeroize", ] @@ -3232,15 +3232,15 @@ dependencies = [ "log", "prost", "prost-types", - "rand", + "rand 0.8.5", "rcgen", "subtle", - "tari_common_types", - "tari_comms", - "tari_core", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_core 1.0.0-pre.16", "tari_crypto", - "tari_features", - "tari_script", + "tari_features 1.0.0-pre.16", + "tari_script 1.0.0-pre.16", "tari_utilities", "thiserror", "tokio", @@ -3259,12 +3259,12 @@ dependencies = [ "json5", "log", "minotari_app_grpc", - "rand", + "rand 0.8.5", "serde", - "tari_common", - "tari_common_types", - "tari_comms", - "tari_features", + "tari_common 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_features 1.0.0-pre.16", "tari_utilities", "thiserror", "tokio", @@ -3283,14 +3283,14 @@ dependencies = [ "log4rs", "minotari_app_utilities", "openssl", - "rand", + "rand 0.8.5", "tari_chat_client", - "tari_common", - "tari_common_types", + "tari_common 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", "tari_contacts", "tari_crypto", - "tari_p2p", - "tari_shutdown", + "tari_p2p 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", "tari_utilities", "thiserror", "tokio", @@ -3314,10 +3314,10 @@ dependencies = [ "log4rs", "minotari_app_grpc", "minotari_app_utilities", - "minotari_ledger_wallet_comms", + "minotari_ledger_wallet_comms 1.0.0-pre.16", "minotari_wallet", "qrcode", - "rand", + "rand 0.8.5", "regex", "reqwest", "rpassword", @@ -3326,20 +3326,20 @@ dependencies = [ "serde_json", "sha2 0.10.8", "strum", - "tari_common", - "tari_common_types", - "tari_comms", - "tari_comms_dht", + "tari_common 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_dht 1.0.0-pre.16", "tari_contacts", - "tari_core", + "tari_core 1.0.0-pre.16", "tari_crypto", - "tari_features", - "tari_hashing", - "tari_key_manager", + "tari_features 1.0.0-pre.16", + "tari_hashing 1.0.0-pre.16", + "tari_key_manager 1.0.0-pre.16", "tari_libtor", - "tari_p2p", - "tari_script", - "tari_shutdown", + "tari_p2p 1.0.0-pre.16", + "tari_script 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", "tari_utilities", "thiserror", "tokio", @@ -3355,6 +3355,25 @@ dependencies = [ [[package]] name = "minotari_ledger_wallet_comms" version = "1.0.0-pre.16" +dependencies = [ + "ledger-transport 0.10.0 (git+https://github.com/Zondax/ledger-rs?rev=20e2a20)", + "ledger-transport-hid", + "num-derive", + "num-traits", + "rand 0.9.0-alpha.1", + "serde", + "tari_common 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_common_types 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_core 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_crypto", + "tari_utilities", + "thiserror", +] + +[[package]] +name = "minotari_ledger_wallet_comms" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" dependencies = [ "ledger-transport 0.10.0 (git+https://github.com/Zondax/ledger-rs?rev=20e2a20)", "ledger-transport-hid", @@ -3392,12 +3411,12 @@ dependencies = [ "scraper", "serde", "serde_json", - "tari_common", - "tari_common_types", - "tari_comms", - "tari_core", - "tari_features", - "tari_key_manager", + "tari_common 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_core 1.0.0-pre.16", + "tari_features 1.0.0-pre.16", + "tari_key_manager 1.0.0-pre.16", "tari_utilities", "thiserror", "tokio", @@ -3428,13 +3447,13 @@ dependencies = [ "native-tls", "num_cpus", "prost-types", - "rand", + "rand 0.8.5", "serde", "serde_json", - "tari_common", - "tari_common_types", - "tari_comms", - "tari_core", + "tari_common 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_core 1.0.0-pre.16", "tari_crypto", "tari_utilities", "thiserror", @@ -3450,13 +3469,13 @@ dependencies = [ "cbindgen", "hex", "libc", - "rand", - "tari_common", - "tari_common_types", - "tari_comms", - "tari_core", + "rand 0.8.5", + "tari_common 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_core 1.0.0-pre.16", "tari_crypto", - "tari_features", + "tari_features 1.0.0-pre.16", "tari_utilities", "thiserror", "tokio", @@ -3489,20 +3508,20 @@ dependencies = [ "rustyline-derive", "serde", "strum", - "tari_common", - "tari_common_types", - "tari_comms", - "tari_comms_dht", - "tari_core", + "tari_common 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_dht 1.0.0-pre.16", + "tari_core 1.0.0-pre.16", "tari_crypto", - "tari_features", - "tari_key_manager", + "tari_features 1.0.0-pre.16", + "tari_key_manager 1.0.0-pre.16", "tari_libtor", "tari_metrics", - "tari_p2p", - "tari_service_framework", - "tari_shutdown", - "tari_storage", + "tari_p2p 1.0.0-pre.16", + "tari_service_framework 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", + "tari_storage 1.0.0-pre.16", "tari_utilities", "thiserror", "tokio", @@ -3540,26 +3559,26 @@ dependencies = [ "libsqlite3-sys", "log", "prost", - "rand", + "rand 0.8.5", "serde", "serde_json", "sha2 0.10.8", "strum", "strum_macros", - "tari_common", - "tari_common_sqlite", - "tari_common_types", - "tari_comms", - "tari_comms_dht", + "tari_common 1.0.0-pre.16", + "tari_common_sqlite 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_dht 1.0.0-pre.16", "tari_contacts", - "tari_core", + "tari_core 1.0.0-pre.16", "tari_crypto", - "tari_key_manager", - "tari_p2p", - "tari_script", - "tari_service_framework", - "tari_shutdown", - "tari_test_utils", + "tari_key_manager 1.0.0-pre.16", + "tari_p2p 1.0.0-pre.16", + "tari_script 1.0.0-pre.16", + "tari_service_framework 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", "tari_utilities", "tempfile", "thiserror", @@ -3586,22 +3605,22 @@ dependencies = [ "num-traits", "once_cell", "openssl", - "rand", + "rand 0.8.5", "serde_json", - "tari_common", - "tari_common_types", - "tari_comms", - "tari_comms_dht", + "tari_common 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_dht 1.0.0-pre.16", "tari_contacts", - "tari_core", + "tari_core 1.0.0-pre.16", "tari_crypto", - "tari_features", - "tari_key_manager", - "tari_p2p", - "tari_script", - "tari_service_framework", - "tari_shutdown", - "tari_test_utils", + "tari_features 1.0.0-pre.16", + "tari_key_manager 1.0.0-pre.16", + "tari_p2p 1.0.0-pre.16", + "tari_script 1.0.0-pre.16", + "tari_service_framework 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", "tari_utilities", "tempfile", "thiserror", @@ -3614,7 +3633,7 @@ name = "minotari_wallet_grpc_client" version = "0.1.0" dependencies = [ "minotari_app_grpc", - "tari_common_types", + "tari_common_types 1.0.0-pre.16", "thiserror", "tokio", "tonic 0.8.3", @@ -3837,7 +3856,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.5", "serde", "smallvec", "zeroize", @@ -4143,7 +4162,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -4314,7 +4333,7 @@ dependencies = [ "num-traits", "p256", "p384", - "rand", + "rand 0.8.5", "ripemd", "rsa", "sha1 0.10.6", @@ -4364,7 +4383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ "phf_shared 0.10.0", - "rand", + "rand 0.8.5", ] [[package]] @@ -4374,7 +4393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared 0.11.2", - "rand", + "rand 0.8.5", ] [[package]] @@ -4759,7 +4778,7 @@ checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" dependencies = [ "env_logger 0.8.4", "log", - "rand", + "rand 0.8.5", ] [[package]] @@ -4805,8 +4824,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31e63ea85be51c423e52ba8f2e68a3efd53eed30203ee029dd09947333693e" +dependencies = [ + "rand_chacha 0.9.0-alpha.1", + "rand_core 0.9.0-alpha.1", + "zerocopy 0.8.0-alpha.6", ] [[package]] @@ -4816,7 +4846,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78674ef918c19451dbd250f8201f8619b494f64c9aa6f3adb28fd8a0f1f6da46" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.0-alpha.1", ] [[package]] @@ -4828,6 +4868,16 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_core" +version = "0.9.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc89dffba8377c5ec847d12bb41492bda235dba31a25e8b695cd0fe6589eb8c9" +dependencies = [ + "getrandom", + "zerocopy 0.8.0-alpha.6", +] + [[package]] name = "randomx-rs" version = "1.3.0" @@ -5071,7 +5121,7 @@ dependencies = [ "num-traits", "pkcs1", "pkcs8", - "rand_core", + "rand_core 0.6.4", "signature", "spki", "subtle", @@ -5554,7 +5604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest 0.10.7", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -5627,7 +5677,7 @@ dependencies = [ "blake2", "chacha20poly1305", "curve25519-dalek", - "rand_core", + "rand_core 0.6.4", "rustc_version", "sha2 0.10.8", "subtle", @@ -5933,7 +5983,7 @@ dependencies = [ "itertools 0.12.1", "merlin", "once_cell", - "rand_core", + "rand_core 0.6.4", "serde", "sha3", "thiserror-no-std", @@ -5951,18 +6001,18 @@ dependencies = [ "lmdb-zero", "log", "minotari_app_utilities", - "rand", + "rand 0.8.5", "serde", - "tari_common", - "tari_common_sqlite", - "tari_common_types", - "tari_comms", - "tari_comms_dht", + "tari_common 1.0.0-pre.16", + "tari_common_sqlite 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_dht 1.0.0-pre.16", "tari_contacts", - "tari_p2p", - "tari_service_framework", - "tari_shutdown", - "tari_storage", + "tari_p2p 1.0.0-pre.16", + "tari_service_framework 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", + "tari_storage 1.0.0-pre.16", "thiserror", ] @@ -5986,8 +6036,34 @@ dependencies = [ "sha2 0.10.8", "structopt", "tari_crypto", - "tari_features", - "tari_test_utils", + "tari_features 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", + "tempfile", + "thiserror", + "toml 0.5.11", +] + +[[package]] +name = "tari_common" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "anyhow", + "blake2", + "config", + "dirs-next 1.0.2", + "log", + "log4rs", + "multiaddr", + "path-clean", + "prost-build", + "serde", + "serde_json", + "serde_yaml", + "sha2 0.10.8", + "structopt", + "tari_crypto", + "tari_features 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", "tempfile", "thiserror", "toml 0.5.11", @@ -6001,15 +6077,56 @@ dependencies = [ "diesel_migrations", "log", "serde", - "tari_test_utils", + "tari_test_utils 1.0.0-pre.16", "tari_utilities", "thiserror", "tokio", ] +[[package]] +name = "tari_common_sqlite" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "diesel", + "diesel_migrations", + "log", + "serde", + "tari_utilities", + "thiserror", + "tokio", +] + +[[package]] +name = "tari_common_types" +version = "1.0.0-pre.16" +dependencies = [ + "base64 0.21.5", + "bitflags 2.4.1", + "blake2", + "borsh", + "bs58 0.5.1", + "chacha20poly1305", + "digest 0.10.7", + "ledger-transport 0.10.0 (git+https://github.com/Zondax/ledger-rs?rev=20e2a20)", + "minotari_ledger_wallet_comms 1.0.0-pre.16", + "newtype-ops", + "once_cell", + "primitive-types", + "rand 0.8.5", + "serde", + "strum", + "strum_macros", + "tari_common 1.0.0-pre.16", + "tari_crypto", + "tari_utilities", + "thiserror", +] + [[package]] name = "tari_common_types" version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" dependencies = [ "base64 0.21.5", "bitflags 2.4.1", @@ -6019,15 +6136,15 @@ dependencies = [ "chacha20poly1305", "digest 0.10.7", "ledger-transport 0.10.0 (git+https://github.com/Zondax/ledger-rs?rev=20e2a20)", - "minotari_ledger_wallet_comms", + "minotari_ledger_wallet_comms 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", "newtype-ops", "once_cell", "primitive-types", - "rand", + "rand 0.8.5", "serde", "strum", "strum_macros", - "tari_common", + "tari_common 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", "tari_crypto", "tari_utilities", "thiserror", @@ -6057,19 +6174,19 @@ dependencies = [ "once_cell", "pin-project 1.1.3", "prost", - "rand", + "rand 0.8.5", "serde", "serde_derive", "serde_json", "sha3", "snow", - "tari_common", - "tari_comms_rpc_macros", + "tari_common 1.0.0-pre.16", + "tari_comms_rpc_macros 1.0.0-pre.16", "tari_crypto", "tari_metrics", - "tari_shutdown", - "tari_storage", - "tari_test_utils", + "tari_shutdown 1.0.0-pre.16", + "tari_storage 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", "tari_utilities", "tempfile", "thiserror", @@ -6082,6 +6199,50 @@ dependencies = [ "zeroize", ] +[[package]] +name = "tari_comms" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "anyhow", + "async-trait", + "bitflags 2.4.1", + "blake2", + "bytes 1.5.0", + "chrono", + "cidr", + "data-encoding", + "derivative", + "digest 0.10.7", + "futures 0.3.29", + "lmdb-zero", + "log", + "log-mdc", + "multiaddr", + "nom", + "once_cell", + "pin-project 1.1.3", + "prost", + "rand 0.8.5", + "serde", + "serde_derive", + "sha3", + "snow", + "tari_common 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_crypto", + "tari_shutdown 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_storage 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_utilities", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util 0.6.10", + "tower", + "tracing", + "yamux", + "zeroize", +] + [[package]] name = "tari_comms_dht" version = "1.0.0-pre.16" @@ -6107,16 +6268,16 @@ dependencies = [ "petgraph 0.5.1", "pin-project 0.4.30", "prost", - "rand", + "rand 0.8.5", "serde", - "tari_common", - "tari_common_sqlite", - "tari_comms", - "tari_comms_rpc_macros", + "tari_common 1.0.0-pre.16", + "tari_common_sqlite 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_rpc_macros 1.0.0-pre.16", "tari_crypto", - "tari_shutdown", - "tari_storage", - "tari_test_utils", + "tari_shutdown 1.0.0-pre.16", + "tari_storage 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", "tari_utilities", "tempfile", "thiserror", @@ -6126,6 +6287,41 @@ dependencies = [ "zeroize", ] +[[package]] +name = "tari_comms_dht" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "anyhow", + "bitflags 2.4.1", + "blake2", + "chacha20 0.7.3", + "chacha20poly1305", + "chrono", + "diesel", + "diesel_migrations", + "digest 0.10.7", + "futures 0.3.29", + "log", + "log-mdc", + "pin-project 0.4.30", + "prost", + "rand 0.8.5", + "serde", + "tari_common 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_common_sqlite 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_comms 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_comms_rpc_macros 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_crypto", + "tari_shutdown 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_storage 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_utilities", + "thiserror", + "tokio", + "tower", + "zeroize", +] + [[package]] name = "tari_comms_rpc_macros" version = "1.0.0-pre.16" @@ -6135,12 +6331,22 @@ dependencies = [ "prost", "quote", "syn 1.0.109", - "tari_comms", - "tari_test_utils", + "tari_comms 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", "tokio", "tower-service", ] +[[package]] +name = "tari_comms_rpc_macros" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "tari_contacts" version = "1.0.0-pre.16" @@ -6153,19 +6359,19 @@ dependencies = [ "num-derive", "num-traits", "prost", - "rand", + "rand 0.8.5", "serde", "serde_json", - "tari_common", - "tari_common_sqlite", - "tari_common_types", - "tari_comms", - "tari_comms_dht", + "tari_common 1.0.0-pre.16", + "tari_common_sqlite 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_dht 1.0.0-pre.16", "tari_crypto", - "tari_p2p", - "tari_service_framework", - "tari_shutdown", - "tari_test_utils", + "tari_p2p 1.0.0-pre.16", + "tari_service_framework 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", "tari_utilities", "tempfile", "thiserror", @@ -6200,7 +6406,7 @@ dependencies = [ "lmdb-zero", "log", "log-mdc", - "minotari_ledger_wallet_comms", + "minotari_ledger_wallet_comms 1.0.0-pre.16", "monero", "newtype-ops", "num-derive", @@ -6210,7 +6416,7 @@ dependencies = [ "primitive-types", "prost", "quickcheck", - "rand", + "rand 0.8.5", "randomx-rs", "serde", "serde_json", @@ -6220,24 +6426,24 @@ dependencies = [ "strum", "strum_macros", "tari-tiny-keccak", - "tari_common", - "tari_common_sqlite", - "tari_common_types", - "tari_comms", - "tari_comms_dht", - "tari_comms_rpc_macros", + "tari_common 1.0.0-pre.16", + "tari_common_sqlite 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_dht 1.0.0-pre.16", + "tari_comms_rpc_macros 1.0.0-pre.16", "tari_crypto", - "tari_features", - "tari_hashing", - "tari_key_manager", + "tari_features 1.0.0-pre.16", + "tari_hashing 1.0.0-pre.16", + "tari_key_manager 1.0.0-pre.16", "tari_metrics", - "tari_mmr", - "tari_p2p", - "tari_script", - "tari_service_framework", - "tari_shutdown", - "tari_storage", - "tari_test_utils", + "tari_mmr 1.0.0-pre.16", + "tari_p2p 1.0.0-pre.16", + "tari_script 1.0.0-pre.16", + "tari_service_framework 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", + "tari_storage 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", "tari_utilities", "tempfile", "thiserror", @@ -6247,6 +6453,71 @@ dependencies = [ "zeroize", ] +[[package]] +name = "tari_core" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "async-trait", + "bincode", + "bitflags 2.4.1", + "blake2", + "borsh", + "bytes 0.5.6", + "chacha20poly1305", + "chrono", + "decimal-rs", + "derivative", + "digest 0.10.7", + "fs2", + "futures 0.3.29", + "hex", + "integer-encoding", + "lmdb-zero", + "log", + "log-mdc", + "monero", + "newtype-ops", + "num-derive", + "num-format", + "num-traits", + "once_cell", + "primitive-types", + "prost", + "rand 0.8.5", + "randomx-rs", + "serde", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "sha3", + "strum", + "strum_macros", + "tari-tiny-keccak", + "tari_common 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_common_sqlite 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_common_types 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_comms 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_comms_dht 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_comms_rpc_macros 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_crypto", + "tari_features 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_hashing 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_key_manager 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_mmr 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_p2p 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_script 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_service_framework 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_shutdown 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_storage 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_test_utils 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_utilities", + "thiserror", + "tokio", + "tracing", + "zeroize", +] + [[package]] name = "tari_crypto" version = "0.20.3" @@ -6260,8 +6531,8 @@ dependencies = [ "log", "merlin", "once_cell", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", "serde", "sha3", "snafu", @@ -6275,6 +6546,11 @@ dependencies = [ name = "tari_features" version = "1.0.0-pre.16" +[[package]] +name = "tari_features" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" + [[package]] name = "tari_hashing" version = "1.0.0-pre.16" @@ -6285,6 +6561,16 @@ dependencies = [ "tari_crypto", ] +[[package]] +name = "tari_hashing" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "borsh", + "digest 0.10.7", + "tari_crypto", +] + [[package]] name = "tari_integration_tests" version = "0.35.1" @@ -6310,21 +6596,21 @@ dependencies = [ "minotari_wallet", "minotari_wallet_ffi", "minotari_wallet_grpc_client", - "rand", + "rand 0.8.5", "reqwest", "serde_json", "tari_chat_client", - "tari_common", - "tari_common_types", - "tari_comms", - "tari_comms_dht", + "tari_common 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_dht 1.0.0-pre.16", "tari_contacts", - "tari_core", + "tari_core 1.0.0-pre.16", "tari_crypto", - "tari_key_manager", - "tari_p2p", - "tari_script", - "tari_shutdown", + "tari_key_manager 1.0.0-pre.16", + "tari_p2p 1.0.0-pre.16", + "tari_script 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", "tari_utilities", "tempfile", "thiserror", @@ -6351,16 +6637,16 @@ dependencies = [ "futures 0.3.29", "js-sys", "log", - "rand", + "rand 0.8.5", "serde", "sha2 0.9.9", "strum", "strum_macros", "subtle", - "tari_common_sqlite", - "tari_common_types", + "tari_common_sqlite 1.0.0-pre.16", + "tari_common_types 1.0.0-pre.16", "tari_crypto", - "tari_service_framework", + "tari_service_framework 1.0.0-pre.16", "tari_utilities", "tempfile", "thiserror", @@ -6368,6 +6654,39 @@ dependencies = [ "zeroize", ] +[[package]] +name = "tari_key_manager" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "argon2", + "async-trait", + "blake2", + "chacha20 0.7.3", + "chacha20poly1305", + "chrono", + "crc32fast", + "derivative", + "diesel", + "diesel_migrations", + "digest 0.10.7", + "futures 0.3.29", + "log", + "rand 0.8.5", + "serde", + "strum", + "strum_macros", + "subtle", + "tari_common_sqlite 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_common_types 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_crypto", + "tari_service_framework 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_utilities", + "thiserror", + "tokio", + "zeroize", +] + [[package]] name = "tari_libtor" version = "1.0.0-pre.16" @@ -6376,9 +6695,9 @@ dependencies = [ "libtor", "log", "openssl", - "rand", - "tari_common", - "tari_p2p", + "rand 0.8.5", + "tari_common 1.0.0-pre.16", + "tari_p2p 1.0.0-pre.16", "tempfile", "tor-hash-passwd", ] @@ -6408,10 +6727,25 @@ dependencies = [ "criterion 0.5.1", "digest 0.10.7", "log", - "rand", + "rand 0.8.5", "serde", "serde_json", - "tari_common", + "tari_common 1.0.0-pre.16", + "tari_crypto", + "tari_utilities", + "thiserror", +] + +[[package]] +name = "tari_mmr" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "borsh", + "digest 0.10.7", + "log", + "serde", + "tari_common 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", "tari_crypto", "tari_utilities", "thiserror", @@ -6430,19 +6764,19 @@ dependencies = [ "log", "pgp", "prost", - "rand", + "rand 0.8.5", "reqwest", "rustls", "semver", "serde", - "tari_common", - "tari_comms", - "tari_comms_dht", + "tari_common 1.0.0-pre.16", + "tari_comms 1.0.0-pre.16", + "tari_comms_dht 1.0.0-pre.16", "tari_crypto", - "tari_service_framework", - "tari_shutdown", - "tari_storage", - "tari_test_utils", + "tari_service_framework 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", + "tari_storage 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", "tari_utilities", "tempfile", "thiserror", @@ -6453,6 +6787,36 @@ dependencies = [ "webpki", ] +[[package]] +name = "tari_p2p" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "anyhow", + "fs2", + "futures 0.3.29", + "lmdb-zero", + "log", + "prost", + "rand 0.8.5", + "rustls", + "serde", + "tari_common 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_comms 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_comms_dht 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_crypto", + "tari_service_framework 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_shutdown 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_storage 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_utilities", + "thiserror", + "tokio", + "tokio-stream", + "tower", + "trust-dns-client", + "webpki", +] + [[package]] name = "tari_script" version = "1.0.0-pre.16" @@ -6461,7 +6825,24 @@ dependencies = [ "borsh", "digest 0.10.7", "integer-encoding", - "rand", + "rand 0.8.5", + "serde", + "sha2 0.10.8", + "sha3", + "tari_crypto", + "tari_utilities", + "thiserror", +] + +[[package]] +name = "tari_script" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "blake2", + "borsh", + "digest 0.10.7", + "integer-encoding", "serde", "sha2 0.10.8", "sha3", @@ -6479,14 +6860,29 @@ dependencies = [ "futures 0.3.29", "futures-test", "log", - "tari_shutdown", - "tari_test_utils", + "tari_shutdown 1.0.0-pre.16", + "tari_test_utils 1.0.0-pre.16", "thiserror", "tokio", "tower", "tower-service", ] +[[package]] +name = "tari_service_framework" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "anyhow", + "async-trait", + "futures 0.3.29", + "log", + "tari_shutdown 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "thiserror", + "tokio", + "tower-service", +] + [[package]] name = "tari_shutdown" version = "1.0.0-pre.16" @@ -6495,6 +6891,14 @@ dependencies = [ "tokio", ] +[[package]] +name = "tari_shutdown" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "futures 0.3.29", +] + [[package]] name = "tari_storage" version = "1.0.0-pre.16" @@ -6502,21 +6906,46 @@ dependencies = [ "bincode", "lmdb-zero", "log", - "rand", + "rand 0.8.5", "serde", "tari_utilities", "thiserror", ] +[[package]] +name = "tari_storage" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "bincode", + "lmdb-zero", + "log", + "serde", + "thiserror", +] + [[package]] name = "tari_test_utils" version = "1.0.0-pre.16" dependencies = [ "futures 0.3.29", "futures-test", - "rand", - "tari_comms", - "tari_shutdown", + "rand 0.8.5", + "tari_comms 1.0.0-pre.16", + "tari_shutdown 1.0.0-pre.16", + "tempfile", + "tokio", +] + +[[package]] +name = "tari_test_utils" +version = "1.0.0-pre.16" +source = "git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16#7d0281b7a8f56787986d74a2786730744dad77d5" +dependencies = [ + "futures 0.3.29", + "rand 0.8.5", + "tari_comms 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", + "tari_shutdown 1.0.0-pre.16 (git+https://github.com/tari-project/tari?tag=v1.0.0-pre.16)", "tempfile", "tokio", ] @@ -6993,7 +7422,7 @@ checksum = "8b83cd43a176c0c19d5db4401283e8f5c296b9c6c7fa29029de15cc445f26e12" dependencies = [ "hex", "hex-literal 0.3.4", - "rand", + "rand 0.8.5", "sha1 0.6.0", "thiserror", ] @@ -7010,7 +7439,7 @@ dependencies = [ "indexmap 1.9.3", "pin-project 1.1.3", "pin-project-lite", - "rand", + "rand 0.8.5", "slab", "tokio", "tokio-util 0.7.10", @@ -7102,7 +7531,7 @@ dependencies = [ "lazy_static", "log", "radix_trie", - "rand", + "rand 0.8.5", "ring 0.16.20", "rustls", "thiserror", @@ -7129,7 +7558,7 @@ dependencies = [ "ipnet", "lazy_static", "log", - "rand", + "rand 0.8.5", "ring 0.16.20", "rustls", "rustls-pemfile 0.3.0", @@ -7815,7 +8244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" dependencies = [ "curve25519-dalek", - "rand_core", + "rand_core 0.6.4", "serde", "zeroize", ] @@ -7841,7 +8270,7 @@ dependencies = [ "nohash-hasher", "parking_lot 0.12.1", "pin-project 1.1.3", - "rand", + "rand 0.8.5", "static_assertions", ] @@ -7860,7 +8289,16 @@ version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ - "zerocopy-derive", + "zerocopy-derive 0.7.32", +] + +[[package]] +name = "zerocopy" +version = "0.8.0-alpha.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db678a6ee512bd06adf35c35be471cae2f9c82a5aed2b5d15e03628c98bddd57" +dependencies = [ + "zerocopy-derive 0.8.0-alpha.6", ] [[package]] @@ -7874,6 +8312,17 @@ dependencies = [ "syn 2.0.38", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.0-alpha.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201585ea96d37ee69f2ac769925ca57160cef31acb137c16f38b02b76f4c1e62" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/applications/minotari_ledger_wallet/comms/Cargo.toml b/applications/minotari_ledger_wallet/comms/Cargo.toml index 585f1fe631..9b8825b7eb 100644 --- a/applications/minotari_ledger_wallet/comms/Cargo.toml +++ b/applications/minotari_ledger_wallet/comms/Cargo.toml @@ -7,10 +7,16 @@ edition = "2021" [dependencies] tari_crypto = { version = "0.20.2", default-features = false } +tari_utilities = { version = "0.7" } +tari_common = { git = "https://github.com/tari-project/tari", tag = "v1.0.0-pre.16" } +tari_common_types = { git = "https://github.com/tari-project/tari", tag = "v1.0.0-pre.16", features = ["ledger"] } +tari_core = { git = "https://github.com/tari-project/tari", tag = "v1.0.0-pre.16" } ledger-transport = { git = "https://github.com/Zondax/ledger-rs", rev = "20e2a20" } ledger-transport-hid = { git = "https://github.com/Zondax/ledger-rs", rev = "20e2a20" } num-derive = "0.4.2" num-traits = "0.2.15" serde = { version = "1.0.106", features = ["derive"] } -thiserror = "1.0.26" \ No newline at end of file +thiserror = "1.0.26" + +rand = "0.9.0-alpha.1" diff --git a/applications/minotari_ledger_wallet/comms/examples/ledger_demo/ledger_wallet.rs b/applications/minotari_ledger_wallet/comms/examples/ledger_demo/ledger_wallet.rs new file mode 100644 index 0000000000..c2d126cb15 --- /dev/null +++ b/applications/minotari_ledger_wallet/comms/examples/ledger_demo/ledger_wallet.rs @@ -0,0 +1,110 @@ +// Copyright 2023 The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use std::{ + fmt, + fmt::{Display, Formatter}, +}; + +use ledger_transport::APDUCommand; +use minotari_ledger_wallet_comms::ledger_wallet::{Command, Instruction}; +use serde::{Deserialize, Serialize}; +use tari_common::configuration::Network; +use tari_common_types::types::{PrivateKey, PublicKey}; +use tari_utilities::ByteArray; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LedgerWallet { + account: u64, + pub public_alpha: Option, + pub network: Network, + pub view_key: Option, +} + +impl Display for LedgerWallet { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "account {}", self.account)?; + write!(f, "pubkey {}", self.public_alpha.is_some())?; + Ok(()) + } +} + +const WALLET_CLA: u8 = 0x80; + +impl LedgerWallet { + pub fn new(account: u64, network: Network, public_alpha: Option, view_key: Option) -> Self { + Self { + account, + public_alpha, + network, + view_key, + } + } + + pub fn account_bytes(&self) -> Vec { + self.account.to_le_bytes().to_vec() + } + + pub fn build_command(&self, instruction: Instruction, data: Vec) -> Command> { + let mut base_data = self.account_bytes(); + base_data.extend_from_slice(&data); + + Command::new(APDUCommand { + cla: WALLET_CLA, + ins: instruction.as_byte(), + p1: 0x00, + p2: 0x00, + data: base_data, + }) + } + + pub fn chunk_command(&self, instruction: Instruction, data: Vec>) -> Vec>> { + let num_chunks = data.len(); + let mut more; + let mut commands = vec![]; + + for (i, chunk) in data.iter().enumerate() { + if i + 1 == num_chunks { + more = 0; + } else { + more = 1; + } + + // Prepend the account on the first payload + let mut base_data = vec![]; + if i == 0 { + base_data.extend_from_slice(&self.account_bytes()); + } + base_data.extend_from_slice(chunk); + + commands.push(Command::new(APDUCommand { + cla: WALLET_CLA, + ins: instruction.as_byte(), + p1: u8::try_from(i).unwrap_or(0), + p2: more, + data: base_data, + })); + } + + commands + } +} diff --git a/applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs b/applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs new file mode 100644 index 0000000000..eb2b7f48e5 --- /dev/null +++ b/applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs @@ -0,0 +1,301 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +//! # Multi-party Ledger - command line example + +// use tari_common_types::types::{PrivateKey, PublicKey}; +// use tari_crypto::keys::{PublicKey as PK, SecretKey}; +// use tari_utilities::hex::Hex; +// use minotari_ledger_wallet_comms::error::LedgerDeviceError; +use minotari_ledger_wallet_comms::ledger_wallet::{get_transport, Instruction}; +use rand::rngs::OsRng; +/// This example demonstrates how to use the Ledger Nano S/X for the Tari wallet. In order to run the example, you +/// need to have the `MinoTari Wallet` application installed on your Ledger device. For that, please follow the +/// instructions in the [README](../../wallet/README.md) file. +/// With this example, you can: +/// - Detect the hardware wallet +/// - Verify that the Ledger application is installed and the version is correct +/// - TBD +/// +/// ----------------------------------------------------------------------------------------------- +/// Example use: +/// `cargo run --release --example ledger_demo` +/// ----------------------------------------------------------------------------------------------- +use rand::RngCore; +use tari_common::configuration::Network; +use tari_common_types::types::{ComAndPubSignature, Commitment, PrivateKey, PublicKey}; +use tari_core::transactions::{ + key_manager::TransactionKeyManagerBranch, + transaction_components::TransactionInputVersion, +}; +use tari_crypto::{ + dhke::DiffieHellmanSharedSecret, + hash_domain, + keys::{PublicKey as PK, SecretKey}, + ristretto::{RistrettoPublicKey, RistrettoSecretKey}, + signatures::SchnorrSignature, +}; +use tari_utilities::{hex::Hex, ByteArray}; + +use crate::ledger_wallet::LedgerWallet; + +pub mod ledger_wallet; + +hash_domain!(CheckSigHashDomain, "com.tari.script.check_sig", 1); +type CheckSigSchnorrSignature = SchnorrSignature; + +fn main() { + let account = OsRng.next_u64(); + let ledger = LedgerWallet::new(account, Network::LocalNet, None, None); + + println!(); + + let transport = match get_transport() { + Ok(transport) => transport, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + }; + + // GetAppName + println!("\ntest: GetAppName"); + match ledger + .build_command(Instruction::GetAppName, vec![0]) + .execute_with_transport(&transport) + { + Ok(response) => { + let name = match std::str::from_utf8(response.data()) { + Ok(val) => val, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + }; + println!("app name: {}", name); + }, + Err(e) => { + println!("\nError: {}\n", e); + }, + } + + // GetVersion + println!("\ntest: GetVersion"); + match ledger + .build_command(Instruction::GetVersion, vec![0]) + .execute_with_transport(&transport) + { + Ok(response) => { + let name = match std::str::from_utf8(response.data()) { + Ok(val) => val, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + }; + println!("version: {}", name); + }, + Err(e) => { + println!("\nError: {}\n", e); + }, + } + + // GetPublicAlpha + println!("\ntest: GetPublicAlpha"); + match ledger + .build_command(Instruction::GetPublicAlpha, vec![]) + .execute_with_transport(&transport) + { + Ok(result) => { + if result.data().len() < 33 { + println!("\nError: result less than 33\n"); + return; + } + + let public_alpha = PublicKey::from_canonical_bytes(&result.data()[1..33]).unwrap(); + println!("public_alpha: {}", public_alpha.to_hex()); + }, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + } + + // GetPublicKey + println!("\ntest: GetPublicKey"); + let mut data = Vec::new(); + let index = 1u64.to_le_bytes(); // OsRng.next_u64().to_le_bytes(); + data.extend_from_slice(&index); + let branch = 1u64.to_le_bytes(); // OsRng.next_u64().to_le_bytes(); + data.extend_from_slice(&branch); + + match ledger + .build_command(Instruction::GetPublicKey, data) + .execute_with_transport(&transport) + { + Ok(result) => { + if result.data().len() < 33 { + println!("\nError: result less than 33\n"); + return; + } + + let public_key = PublicKey::from_canonical_bytes(&result.data()[1..33]).unwrap(); + println!("public_key: {}", public_key.to_hex()); + }, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + } + + // GetScriptSignature + println!("\ntest: GetScriptSignature"); + let mut data = Vec::new(); + let network = u64::from(Network::LocalNet.as_byte()).to_le_bytes(); + data.extend_from_slice(&network); + let version = u64::from(TransactionInputVersion::get_current_version().as_u8()).to_le_bytes(); + data.extend_from_slice(&version); + let branch_key = get_random_nonce().to_vec(); + data.extend_from_slice(&branch_key); + let value = PrivateKey::from(123456).to_vec(); + data.extend_from_slice(&value); + let spend_private_key = get_random_nonce().to_vec(); + data.extend_from_slice(&spend_private_key); + let commitment = Commitment::from_public_key(&PublicKey::from_secret_key(&get_random_nonce())).to_vec(); + data.extend_from_slice(&commitment); + let mut script_message = [0u8; 32]; + script_message.copy_from_slice(&get_random_nonce().to_vec()); + data.extend_from_slice(&script_message); + + match ledger + .build_command(Instruction::GetScriptSignature, data) + .execute_with_transport(&transport) + { + Ok(result) => { + if result.data().len() < 161 { + println!("\nError: result less than 161\n"); + return; + } + + let data = result.data(); + let signature = ComAndPubSignature::new( + Commitment::from_canonical_bytes(&data[1..33]).unwrap(), + PublicKey::from_canonical_bytes(&data[33..65]).unwrap(), + PrivateKey::from_canonical_bytes(&data[65..97]).unwrap(), + PrivateKey::from_canonical_bytes(&data[97..129]).unwrap(), + PrivateKey::from_canonical_bytes(&data[129..161]).unwrap(), + ); + println!( + "script_sig: ({},{},{},{},{})", + signature.ephemeral_commitment().to_hex(), + signature.ephemeral_pubkey().to_hex(), + signature.u_x().to_hex(), + signature.u_a().to_hex(), + signature.u_y().to_hex() + ); + }, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + } + + // GetViewKey + println!("\ntest: GetViewKey"); + match ledger + .build_command(Instruction::GetViewKey, vec![]) + .execute_with_transport(&transport) + { + Ok(result) => { + if result.data().len() < 33 { + println!("\nError: result less than 33\n"); + return; + } + + let view_key = PrivateKey::from_canonical_bytes(&result.data()[1..33]).unwrap(); + println!("view_key: {}", view_key.to_hex()); + }, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + } + + // GetDHSharedSecret + println!("\ntest: GetDHSharedSecret"); + let mut data = Vec::new(); + let index = 1u64.to_le_bytes(); // OsRng.next_u64().to_le_bytes(); + data.extend_from_slice(&index); + let branch_u8 = u64::from(TransactionKeyManagerBranch::SenderOffset.as_byte()).to_le_bytes(); + data.extend_from_slice(&branch_u8); + let public_key = PublicKey::from_secret_key(&get_random_nonce()).to_vec(); + data.extend_from_slice(&public_key); + + match ledger + .build_command(Instruction::GetDHSharedSecret, data) + .execute_with_transport(&transport) + { + Ok(result) => { + if result.data().len() < 33 { + println!("\nError: result less than 65\n"); + return; + } + + let shared_secret = + DiffieHellmanSharedSecret::::from_canonical_bytes(&result.data()[1..33]).unwrap(); + println!("shared_secret: {}", shared_secret.as_bytes().to_vec().to_hex()); + }, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + } + + // GetSchnorrSignature + println!("\ntest: GetSchnorrSignature"); + let mut data = Vec::new(); + let index = 1u64.to_le_bytes(); // OsRng.next_u64().to_le_bytes(); + data.extend_from_slice(&index); + let branch_u8 = u64::from(TransactionKeyManagerBranch::Nonce.as_byte()).to_le_bytes(); + data.extend_from_slice(&branch_u8); + let mut challenge = [0u8; 64]; + OsRng.fill_bytes(&mut challenge); + data.extend_from_slice(&challenge); + + match ledger + .build_command(Instruction::GetSchnorrSignature, data) + .execute_with_transport(&transport) + { + Ok(result) => { + if result.data().len() < 65 { + println!("\nError: result less than 65\n"); + return; + } + + let signature = CheckSigSchnorrSignature::new( + PublicKey::from_canonical_bytes(&result.data()[1..33]).unwrap(), + PrivateKey::from_canonical_bytes(&result.data()[33..65]).unwrap(), + ); + println!( + "signature: ({},{})", + signature.get_signature().to_hex(), + signature.get_public_nonce().to_hex() + ); + }, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + } + + println!("\nTest completed successfully\n"); +} + +fn get_random_nonce() -> PrivateKey { + let mut raw_bytes = [0u8; 64]; + for i in 0..8 { + let bytes = OsRng.next_u64().to_le_bytes(); + raw_bytes[i * 8..i * 8 + 8].copy_from_slice(&bytes); + } + PrivateKey::from_uniform_bytes(raw_bytes.as_bytes()).expect("will not fail") +} diff --git a/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs b/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs index 44f897bfb8..86fa612c53 100644 --- a/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs +++ b/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs @@ -38,10 +38,10 @@ pub enum Instruction { GetPublicKey = 0x04, GetScriptSignature = 0x05, GetScriptOffset = 0x06, - GetMetadataSignature = 0x07, - GetScriptSignatureFromChallenge = 0x08, - GetViewKey = 0x09, - GetDHSharedSecret = 0x10, + GetViewKey = 0x07, + GetDHSharedSecret = 0x08, + GetRawSchnorrSignature = 0x09, + GetSchnorrSignature = 0x10, } impl Instruction { diff --git a/applications/minotari_ledger_wallet/wallet/src/handlers/get_schnorr_signature.rs b/applications/minotari_ledger_wallet/wallet/src/handlers/get_schnorr_signature.rs new file mode 100644 index 0000000000..11695e415f --- /dev/null +++ b/applications/minotari_ledger_wallet/wallet/src/handlers/get_schnorr_signature.rs @@ -0,0 +1,120 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use alloc::format; +use core::ops::Deref; + +use ledger_device_sdk::{io::Comm, random::Random, ui::gadgets::SingleMessage}; +use tari_crypto::{ + keys::SecretKey, + ristretto::{RistrettoSchnorr, RistrettoSecretKey}, + tari_utilities::ByteArray, +}; +use zeroize::Zeroizing; + +use crate::{alloc::string::ToString, utils::derive_from_bip32_key, AppSW, KeyType, RESPONSE_VERSION}; + +pub fn handler_get_raw_schnorr_signature(comm: &mut Comm) -> Result<(), AppSW> { + let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?; + + let mut account_bytes = [0u8; 8]; + account_bytes.clone_from_slice(&data[0..8]); + let account = u64::from_le_bytes(account_bytes); + + let mut private_key_index_bytes = [0u8; 8]; + private_key_index_bytes.clone_from_slice(&data[8..16]); + let private_key_index = u64::from_le_bytes(private_key_index_bytes); + + let mut private_key_type_bytes = [0u8; 8]; + private_key_type_bytes.clone_from_slice(&data[16..24]); + let private_key_type = KeyType::from_branch_key(u64::from_le_bytes(private_key_type_bytes)); + + let private_key = derive_from_bip32_key(account, private_key_index, private_key_type)?; + + let mut private_nonce_index_bytes = [0u8; 8]; + private_nonce_index_bytes.clone_from_slice(&data[24..32]); + let private_nonce_index = u64::from_le_bytes(private_nonce_index_bytes); + + let mut nonce_key_type_bytes = [0u8; 8]; + nonce_key_type_bytes.clone_from_slice(&data[32..40]); + let nonce_key_type = KeyType::from_branch_key(u64::from_le_bytes(nonce_key_type_bytes)); + + let private_nonce = derive_from_bip32_key(account, private_nonce_index, nonce_key_type)?; + + let mut challenge_bytes = [0u8; 64]; + challenge_bytes.clone_from_slice(&data[40..104]); + + let signature = + match RistrettoSchnorr::sign_raw_uniform(&private_key, private_nonce.deref().clone(), &challenge_bytes) { + Ok(sig) => sig, + Err(e) => { + SingleMessage::new(&format!("Signing error: {:?}", e.to_string())).show_and_wait(); + return Err(AppSW::RawSchnorrSignatureFail); + }, + }; + + comm.append(&[RESPONSE_VERSION]); // version + comm.append(&signature.get_public_nonce().to_vec()); + comm.append(&signature.get_signature().to_vec()); + comm.reply_ok(); + + Ok(()) +} + +pub fn handler_get_schnorr_signature(comm: &mut Comm) -> Result<(), AppSW> { + SingleMessage::new(&format!("0. schnorr_signature")).show_and_wait(); + let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?; + + let mut account_bytes = [0u8; 8]; + account_bytes.clone_from_slice(&data[0..8]); + let account = u64::from_le_bytes(account_bytes); + + SingleMessage::new(&format!("1. account {}", account)).show_and_wait(); + + let mut private_key_index_bytes = [0u8; 8]; + private_key_index_bytes.clone_from_slice(&data[8..16]); + let private_key_index = u64::from_le_bytes(private_key_index_bytes); + + SingleMessage::new(&format!("2. pk_index {}", private_key_index)).show_and_wait(); + + let mut private_key_type_bytes = [0u8; 8]; + private_key_type_bytes.clone_from_slice(&data[16..24]); + let private_key_type = KeyType::from_branch_key(u64::from_le_bytes(private_key_type_bytes)); + + let private_key = derive_from_bip32_key(account, private_key_index, private_key_type)?; + + let mut challenge_bytes = [0u8; 64]; + challenge_bytes.clone_from_slice(&data[40..104]); + + SingleMessage::new(&format!("3. challenge_bytes")).show_and_wait(); + + let signature = match RistrettoSchnorr::sign_with_nonce_and_message( + &private_key, + get_random_nonce().deref().clone(), + &challenge_bytes, + ) { + Ok(sig) => sig, + Err(e) => { + SingleMessage::new(&format!("Signing error: {:?}", e.to_string())).show_and_wait(); + return Err(AppSW::RawSchnorrSignatureFail); + }, + }; + + SingleMessage::new(&format!("4. done")).show_and_wait(); + + comm.append(&[RESPONSE_VERSION]); // version + comm.append(&signature.get_public_nonce().to_vec()); + comm.append(&signature.get_signature().to_vec()); + comm.reply_ok(); + + Ok(()) +} + +fn get_random_nonce() -> Zeroizing { + let mut raw_bytes = Zeroizing::new([0u8; 64]); + for i in 0..16 { + let bytes = u32::random().to_le_bytes(); + raw_bytes[i * 4..i * 4 + 4].copy_from_slice(&bytes); + } + Zeroizing::new(RistrettoSecretKey::from_uniform_bytes(raw_bytes.as_bytes()).expect("will not fail")) +} diff --git a/applications/minotari_ledger_wallet/wallet/src/main.rs b/applications/minotari_ledger_wallet/wallet/src/main.rs index e27c78b93c..28627f8d68 100644 --- a/applications/minotari_ledger_wallet/wallet/src/main.rs +++ b/applications/minotari_ledger_wallet/wallet/src/main.rs @@ -17,6 +17,7 @@ mod handlers { pub mod get_dh_shared_secret; pub mod get_public_alpha; pub mod get_public_key; + pub mod get_schnorr_signature; pub mod get_script_offset; pub mod get_script_signature; pub mod get_version; @@ -31,6 +32,7 @@ use handlers::{ get_dh_shared_secret::handler_get_dh_shared_secret, get_public_alpha::handler_get_public_alpha, get_public_key::handler_get_public_key, + get_schnorr_signature::{handler_get_raw_schnorr_signature, handler_get_schnorr_signature}, get_script_offset::{handler_get_script_offset, ScriptOffsetCtx}, get_script_signature::handler_get_script_signature, get_version::handler_get_version, @@ -93,6 +95,7 @@ pub enum AppSW { ClaNotSupported = 0x6E00, ScriptSignatureFail = 0xB001, MetadataSignatureFail = 0xB002, + RawSchnorrSignatureFail = 0xB004, KeyDeriveFail = 0xB009, KeyDeriveFromCanonical = 0xB010, KeyDeriveFromUniform = 0xB011, @@ -115,9 +118,10 @@ pub enum Instruction { GetPublicAlpha, GetScriptSignature, GetScriptOffset { chunk: u8, more: bool }, - GetScriptSignatureFromChallenge, GetViewKey, GetDHSharedSecret, + GetRawSchnorrSignature, + GetSchnorrSignature, } const P2_MORE: u8 = 0x01; @@ -132,6 +136,8 @@ pub enum KeyType { Recovery = 0x03, SenderOffset = 0x04, ViewKey = 0x05, + Random = 0x06, + WalletSpendKey = 0x07, } impl KeyType { @@ -140,9 +146,14 @@ impl KeyType { } fn from_branch_key(n: u64) -> Self { + // See `pub enum TransactionKeyManagerBranch` in + // `tari_wallet/src/transaction_service/transaction_key_manager.rs` for the mapping of the branch key to + // the key type. match n { 1 => Self::Alpha, 7 => Self::SenderOffset, + 8 => Self::Random, + 9 => Self::WalletSpendKey, 5 | 2 | _ => Self::Nonce, } } @@ -173,9 +184,10 @@ impl TryFrom for Instruction { chunk: value.p1, more: value.p2 == P2_MORE, }), - (0x08, 0, 0) => Ok(Instruction::GetScriptSignatureFromChallenge), - (0x09, 0, 0) => Ok(Instruction::GetViewKey), - (0x10, 0, 0) => Ok(Instruction::GetDHSharedSecret), + (0x07, 0, 0) => Ok(Instruction::GetViewKey), + (0x08, 0, 0) => Ok(Instruction::GetDHSharedSecret), + (0x09, 0, 0) => Ok(Instruction::GetRawSchnorrSignature), + (0x10, 0, 0) => Ok(Instruction::GetSchnorrSignature), (0x06, _, _) => Err(AppSW::WrongP1P2), (_, _, _) => Err(AppSW::InsNotSupported), } @@ -221,8 +233,9 @@ fn handle_apdu(comm: &mut Comm, ins: Instruction, offset_ctx: &mut ScriptOffsetC Instruction::GetPublicAlpha => handler_get_public_alpha(comm), Instruction::GetScriptSignature => handler_get_script_signature(comm), Instruction::GetScriptOffset { chunk, more } => handler_get_script_offset(comm, chunk, more, offset_ctx), - Instruction::GetScriptSignatureFromChallenge => handler_get_script_signature_from_challenge(comm), Instruction::GetViewKey => handler_get_view_key(comm), Instruction::GetDHSharedSecret => handler_get_dh_shared_secret(comm), + Instruction::GetRawSchnorrSignature => handler_get_raw_schnorr_signature(comm), + Instruction::GetSchnorrSignature => handler_get_schnorr_signature(comm), } } diff --git a/base_layer/core/src/transactions/key_manager/inner.rs b/base_layer/core/src/transactions/key_manager/inner.rs index a8d48a37ea..a2a506cdd5 100644 --- a/base_layer/core/src/transactions/key_manager/inner.rs +++ b/base_layer/core/src/transactions/key_manager/inner.rs @@ -29,7 +29,7 @@ use minotari_ledger_wallet_comms::{ error::LedgerDeviceError, ledger_wallet::{get_transport, Instruction}, }; -use rand::rngs::OsRng; +use rand::{rngs::OsRng, RngCore}; use strum::IntoEnumIterator; #[cfg(feature = "ledger")] use tari_common_types::wallet_types::LedgerWallet; @@ -166,7 +166,10 @@ where TBackend: KeyManagerBackend + 'static let mut km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .write() .await; self.db.increment_key_index(branch)?; @@ -181,10 +184,51 @@ where TBackend: KeyManagerBackend + 'static } pub async fn get_random_key(&self) -> Result<(TariKeyId, PublicKey), KeyManagerServiceError> { - let random_private_key = PrivateKey::random(&mut OsRng); - let key_id = self.import_key(random_private_key).await?; - let public_key = self.get_public_key_at_key_id(&key_id).await?; - Ok((key_id, public_key)) + match &self.wallet_type { + WalletType::Ledger(ledger) => { + #[cfg(not(feature = "ledger"))] + { + return Err(KeyManagerServiceError::LedgerError( + "Ledger is not supported".to_string(), + )); + } + #[cfg(feature = "ledger")] + { + let random_index = OsRng.next_u64(); + let mut data = random_index.to_le_bytes().to_vec(); + data.extend_from_slice(&u64::from(TransactionKeyManagerBranch::RandomKey.as_byte()).to_le_bytes()); + let command = ledger.build_command(Instruction::GetPublicKey, data); + let transport = get_transport().map_err(|e| KeyManagerServiceError::LedgerError(e.to_string()))?; + + let public_key = match command.execute_with_transport(&transport) { + Ok(result) => { + debug!(target: LOG_TARGET, "result length: {}, data: {:?}", result.data().len(), result.data()); + if result.data().len() < 33 { + debug!(target: LOG_TARGET, "result less than 33"); + } + + PublicKey::from_canonical_bytes(&result.data()[1..33]) + .map_err(|e| KeyManagerServiceError::LedgerError(e.to_string()))? + }, + Err(e) => return Err(KeyManagerServiceError::LedgerError(e.to_string())), + }; + + Ok(( + KeyId::Managed { + branch: TransactionKeyManagerBranch::RandomKey.get_branch_key(), + index: random_index, + }, + public_key, + )) + } + }, + WalletType::Software => { + let random_private_key = PrivateKey::random(&mut OsRng); + let key_id = self.import_key(random_private_key).await?; + let public_key = self.get_public_key_at_key_id(&key_id).await?; + Ok((key_id, public_key)) + }, + } } pub async fn create_key_pair(&mut self, branch: &str) -> Result<(TariKeyId, PublicKey), KeyManagerServiceError> { @@ -195,7 +239,10 @@ where TBackend: KeyManagerBackend + 'static pub async fn get_static_key(&self, branch: &str) -> Result { match self.key_managers.get(branch) { - None => Err(KeyManagerServiceError::UnknownKeyBranch), + None => Err(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + ))), Some(_) => Ok(KeyId::Managed { branch: branch.to_string(), index: 0, @@ -210,51 +257,64 @@ where TBackend: KeyManagerBackend + 'static // SenderOffset than we fetch from the ledger, all other keys are fetched below. #[allow(unused_variables)] if let WalletType::Ledger(ledger) = &self.wallet_type { - if branch == &TransactionKeyManagerBranch::SenderOffsetLedger.get_branch_key() { - #[cfg(not(feature = "ledger"))] - { - return Err(KeyManagerServiceError::LedgerError( - "Ledger is not supported".to_string(), - )); - } - - #[cfg(feature = "ledger")] - { - let transport = - get_transport().map_err(|e| KeyManagerServiceError::LedgerError(e.to_string()))?; - let mut data = index.to_le_bytes().to_vec(); - let branch_u8 = TransactionKeyManagerBranch::from_key(branch).as_byte(); - data.extend_from_slice(&u64::from(branch_u8).to_le_bytes()); - let command = ledger.build_command(Instruction::GetPublicKey, data); - - match command.execute_with_transport(&transport) { - Ok(result) => { - debug!(target: LOG_TARGET, "result length: {}, data: {:?}", result.data().len(), result.data()); - if result.data().len() < 33 { - debug!(target: LOG_TARGET, "result less than 33"); - } - - return PublicKey::from_canonical_bytes(&result.data()[1..33]) - .map_err(|e| KeyManagerServiceError::LedgerError(e.to_string())); - }, - Err(e) => return Err(KeyManagerServiceError::LedgerError(e.to_string())), + match TransactionKeyManagerBranch::from_key(branch) { + TransactionKeyManagerBranch::MetadataEphemeralNonce | + TransactionKeyManagerBranch::SenderOffset | + TransactionKeyManagerBranch::RandomKey => { + #[cfg(not(feature = "ledger"))] + { + return Err(KeyManagerServiceError::LedgerError( + "Ledger is not supported".to_string(), + )); } - } - } - if &TransactionKeyManagerBranch::DataEncryption.get_branch_key() == branch { - let view_key = ledger - .view_key - .clone() - .ok_or(KeyManagerServiceError::LedgerViewKeyInaccessible)?; - return Ok(PublicKey::from_secret_key(&view_key)); + #[cfg(feature = "ledger")] + { + let mut data = index.to_le_bytes().to_vec(); + let branch_u8 = TransactionKeyManagerBranch::from_key(branch).as_byte(); + data.extend_from_slice(&u64::from(branch_u8).to_le_bytes()); + let command = ledger.build_command(Instruction::GetPublicKey, data); + let transport = + get_transport().map_err(|e| KeyManagerServiceError::LedgerError(e.to_string()))?; + + match command.execute_with_transport(&transport) { + Ok(result) => { + debug!(target: LOG_TARGET, "result length: {}, data: {:?}", result.data().len(), result.data()); + if result.data().len() < 33 { + debug!(target: LOG_TARGET, "result less than 33"); + } + + return PublicKey::from_canonical_bytes(&result.data()[1..33]) + .map_err(|e| KeyManagerServiceError::LedgerError(e.to_string())); + }, + Err(e) => return Err(KeyManagerServiceError::LedgerError(e.to_string())), + } + } + }, + _ => { + return if &TransactionKeyManagerBranch::DataEncryption.get_branch_key() == branch { + let view_key = ledger + .view_key + .clone() + .ok_or(KeyManagerServiceError::LedgerViewKeyInaccessible)?; + Ok(PublicKey::from_secret_key(&view_key)) + } else { + Err(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + ))) + } + }, } } let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; Ok(km.derive_public_key(*index)?.key) @@ -265,7 +325,10 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(&TransactionKeyManagerBranch::Alpha.get_branch_key()) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; @@ -280,7 +343,10 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; let branch_key = km.get_private_key(*index)?; @@ -366,7 +432,10 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; @@ -397,7 +466,10 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; @@ -433,7 +505,10 @@ where TBackend: KeyManagerBackend + 'static let mut km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .write() .await; let current_index = km.key_index(); @@ -478,7 +553,10 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; let key = km.get_private_key(*index)?; @@ -490,7 +568,10 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(&TransactionKeyManagerBranch::Alpha.get_branch_key()) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; @@ -499,7 +580,10 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; let branch_key = km.get_private_key(*index)?; @@ -613,12 +697,12 @@ where TBackend: KeyManagerBackend + 'static index: &u64, public_key: &PublicKey, ) -> Result { - let transport = get_transport().map_err(|e| KeyManagerServiceError::LedgerError(e.to_string()))?; let mut data = index.to_le_bytes().to_vec(); let branch_u8 = TransactionKeyManagerBranch::from_key(branch).as_byte(); data.extend_from_slice(&u64::from(branch_u8).to_le_bytes()); data.extend_from_slice(public_key.as_bytes()); let command = ledger.build_command(Instruction::GetDHSharedSecret, data); + let transport = get_transport().map_err(|e| KeyManagerServiceError::LedgerError(e.to_string()))?; return match command.execute_with_transport(&transport) { Ok(result) => { @@ -709,7 +793,10 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; let branch_key = km @@ -911,7 +998,10 @@ where TBackend: KeyManagerBackend + 'static let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(format!( + "{}, {}", + branch, self.wallet_type + )))? .read() .await; let branch_key = km @@ -1059,23 +1149,129 @@ where TBackend: KeyManagerBackend + 'static private_key_id: &TariKeyId, challenge: &[u8], ) -> Result { - let private_key = self.get_private_key(private_key_id).await?; - let signature = CheckSigSchnorrSignature::sign(&private_key, challenge, &mut OsRng)?; + match &self.wallet_type { + WalletType::Ledger(ledger) => { + #[cfg(not(feature = "ledger"))] + { + return Err(TransactionError::LedgerNotSupported); + } - Ok(signature) + #[cfg(feature = "ledger")] + { + match private_key_id { + KeyId::Managed { branch, index } => { + let mut data = index.to_le_bytes().to_vec(); + let branch_u8 = TransactionKeyManagerBranch::from_key(branch).as_byte(); + data.extend_from_slice(&u64::from(branch_u8).to_le_bytes()); + data.extend_from_slice(challenge); + let command = ledger.build_command(Instruction::GetSchnorrSignature, data); + let transport = + get_transport().map_err(|e| KeyManagerServiceError::LedgerError(e.to_string()))?; + + match command.execute_with_transport(&transport) { + Ok(result) => { + debug!(target: LOG_TARGET, "result length: {}, data: {:?}", result.data().len(), result.data()); + if result.data().len() < 65 { + debug!(target: LOG_TARGET, "result less than 65"); + } + + let signature = CheckSigSchnorrSignature::new( + PublicKey::from_canonical_bytes(&result.data()[1..33]) + .map_err(|e| LedgerDeviceError::ByteArrayError(e.to_string()))?, + PrivateKey::from_canonical_bytes(&result.data()[33..65]) + .map_err(|e| LedgerDeviceError::ByteArrayError(e.to_string()))?, + ); + Ok(signature) + }, + Err(e) => Err(e.into()), + } + }, + _ => Err(TransactionError::UnsupportedTariKeyId(format!( + "Expected 'KeyId::Managed', got {}", + private_key_id + ))), + } + } + }, + WalletType::Software => { + let private_key = self.get_private_key(private_key_id).await?; + let signature = CheckSigSchnorrSignature::sign(&private_key, challenge, &mut OsRng)?; + + Ok(signature) + }, + } } pub async fn sign_with_nonce_and_message( &self, private_key_id: &TariKeyId, - nonce: &TariKeyId, + nonce_key_id: &TariKeyId, challenge: &[u8; 64], ) -> Result { - let private_key = self.get_private_key(private_key_id).await?; - let private_nonce = self.get_private_key(nonce).await?; - let signature = Signature::sign_raw_uniform(&private_key, private_nonce, challenge)?; + match &self.wallet_type { + WalletType::Ledger(ledger) => { + #[cfg(not(feature = "ledger"))] + { + return Err(TransactionError::LedgerNotSupported); + } - Ok(signature) + #[cfg(feature = "ledger")] + { + match private_key_id { + KeyId::Managed { branch, index } => { + let mut data = index.to_le_bytes().to_vec(); + let branch_u8 = TransactionKeyManagerBranch::from_key(branch).as_byte(); + data.extend_from_slice(&u64::from(branch_u8).to_le_bytes()); + match nonce_key_id { + KeyId::Managed { branch, index } => { + data.extend_from_slice(index.to_le_bytes().as_ref()); + let branch_u8 = TransactionKeyManagerBranch::from_key(branch).as_byte(); + data.extend_from_slice(&u64::from(branch_u8).to_le_bytes()); + data.extend_from_slice(challenge); + + let command = ledger.build_command(Instruction::GetRawSchnorrSignature, data); + let transport = get_transport() + .map_err(|e| KeyManagerServiceError::LedgerError(e.to_string()))?; + + match command.execute_with_transport(&transport) { + Ok(result) => { + debug!(target: LOG_TARGET, "result length: {}, data: {:?}", result.data().len(), result.data()); + if result.data().len() < 65 { + debug!(target: LOG_TARGET, "result less than 65"); + } + + let signature = Signature::new( + PublicKey::from_canonical_bytes(&result.data()[1..33]) + .map_err(|e| LedgerDeviceError::ByteArrayError(e.to_string()))?, + PrivateKey::from_canonical_bytes(&result.data()[33..65]) + .map_err(|e| LedgerDeviceError::ByteArrayError(e.to_string()))?, + ); + Ok(signature) + }, + Err(e) => Err(e.into()), + } + }, + _ => Err(TransactionError::UnsupportedTariKeyId(format!( + "Expected 'KeyId::Managed', got {}", + nonce_key_id + ))), + } + }, + _ => Err(TransactionError::UnsupportedTariKeyId(format!( + "Expected 'KeyId::Managed', got {}", + private_key_id + ))), + } + } + }, + WalletType::Software => { + let private_key = self.get_private_key(private_key_id).await?; + let private_nonce = self.get_private_key(nonce_key_id).await?; + let signature = Signature::sign_raw_uniform(&private_key, private_nonce, challenge)?; + + Ok(signature) + }, + } } pub async fn get_metadata_signature( @@ -1335,3 +1531,39 @@ where TBackend: KeyManagerBackend + 'static Ok((key, value, payment_id)) } } + +#[cfg(test)] +mod test { + use std::ops::Deref; + + use rand::{rngs::OsRng, RngCore}; + use tari_common_types::types::Signature; + use tari_crypto::{keys::SecretKey, ristretto::RistrettoSecretKey}; + use tari_utilities::{hex::Hex, ByteArray}; + use zeroize::Zeroizing; + + fn get_random_nonce() -> Zeroizing { + let mut raw_bytes = Zeroizing::new([0u8; 64]); + for i in 0..16 { + let bytes = OsRng.next_u32().to_le_bytes(); + // let bytes = u32::random().to_le_bytes(); + raw_bytes[i * 4..i * 4 + 4].copy_from_slice(&bytes); + } + Zeroizing::new(RistrettoSecretKey::from_uniform_bytes(raw_bytes.as_bytes()).expect("will not fail")) + } + + #[test] + fn test_get_random_nonce() { + let v1 = get_random_nonce(); + let v2 = get_random_nonce(); + println!("v1: {}", v1.reveal()); + println!("v2: {}", v2.reveal()); + let challenge_bytes = [0u8; 64]; + let signature = Signature::sign_with_nonce_and_message(&v1, v2.deref().clone(), challenge_bytes).unwrap(); + println!( + "sig: ({},{})", + signature.get_public_nonce().to_hex(), + signature.get_signature().to_hex() + ); + } +} diff --git a/base_layer/core/src/transactions/key_manager/interface.rs b/base_layer/core/src/transactions/key_manager/interface.rs index 0d9ca012c5..d1aab244fa 100644 --- a/base_layer/core/src/transactions/key_manager/interface.rs +++ b/base_layer/core/src/transactions/key_manager/interface.rs @@ -65,34 +65,51 @@ pub enum TransactionKeyManagerBranch { KernelNonce = 0x05, SenderOffset = 0x06, SenderOffsetLedger = 0x07, + RandomKey = 0x08, + WalletSpendKey = 0x09, } +const DATA_ENCRYPTION: &str = "data encryption"; +const ALPHA: &str = "alpha"; +const COMMITMENT_MASK: &str = "commitment mask"; +const NONCE: &str = "nonce"; +const METADATA_EPHEMERAL_NONCE: &str = "metadata ephemeral nonce"; +const KERNEL_NONCE: &str = "kernel nonce"; +const SENDER_OFFSET: &str = "sender offset"; +const SENDER_OFFSET_LEDGER: &str = "sender offset ledger"; +const RANDOM_KEY: &str = "random key"; +const WALLET_SPEND_KEY: &str = "wallet spend key"; + impl TransactionKeyManagerBranch { /// Warning: Changing these strings will affect the backwards compatibility of the wallet with older databases or /// recovery. pub fn get_branch_key(self) -> String { match self { - TransactionKeyManagerBranch::DataEncryption => "data encryption".to_string(), - TransactionKeyManagerBranch::Alpha => "alpha".to_string(), - TransactionKeyManagerBranch::CommitmentMask => "commitment mask".to_string(), - TransactionKeyManagerBranch::Nonce => "nonce".to_string(), - TransactionKeyManagerBranch::MetadataEphemeralNonce => "metadata ephemeral nonce".to_string(), - TransactionKeyManagerBranch::KernelNonce => "kernel nonce".to_string(), - TransactionKeyManagerBranch::SenderOffset => "sender offset".to_string(), - TransactionKeyManagerBranch::SenderOffsetLedger => "sender offset ledger".to_string(), + TransactionKeyManagerBranch::DataEncryption => DATA_ENCRYPTION.to_string(), + TransactionKeyManagerBranch::Alpha => ALPHA.to_string(), + TransactionKeyManagerBranch::MetadataEphemeralNonce => METADATA_EPHEMERAL_NONCE.to_string(), + TransactionKeyManagerBranch::CommitmentMask => COMMITMENT_MASK.to_string(), + TransactionKeyManagerBranch::Nonce => NONCE.to_string(), + TransactionKeyManagerBranch::KernelNonce => KERNEL_NONCE.to_string(), + TransactionKeyManagerBranch::SenderOffset => SENDER_OFFSET.to_string(), + TransactionKeyManagerBranch::SenderOffsetLedger => SENDER_OFFSET_LEDGER.to_string(), + TransactionKeyManagerBranch::RandomKey => RANDOM_KEY.to_string(), + TransactionKeyManagerBranch::WalletSpendKey => WALLET_SPEND_KEY.to_string(), } } pub fn from_key(key: &str) -> Self { match key { - "data encryption" => TransactionKeyManagerBranch::DataEncryption, - "alpha" => TransactionKeyManagerBranch::Alpha, - "commitment mask" => TransactionKeyManagerBranch::CommitmentMask, - "metadata ephemeral nonce" => TransactionKeyManagerBranch::MetadataEphemeralNonce, - "kernel nonce" => TransactionKeyManagerBranch::KernelNonce, - "sender offset" => TransactionKeyManagerBranch::SenderOffset, - "sender offset ledger" => TransactionKeyManagerBranch::SenderOffsetLedger, - "nonce" => TransactionKeyManagerBranch::Nonce, + DATA_ENCRYPTION => TransactionKeyManagerBranch::DataEncryption, + ALPHA => TransactionKeyManagerBranch::Alpha, + METADATA_EPHEMERAL_NONCE => TransactionKeyManagerBranch::MetadataEphemeralNonce, + COMMITMENT_MASK => TransactionKeyManagerBranch::CommitmentMask, + NONCE => TransactionKeyManagerBranch::Nonce, + KERNEL_NONCE => TransactionKeyManagerBranch::KernelNonce, + SENDER_OFFSET => TransactionKeyManagerBranch::SenderOffset, + SENDER_OFFSET_LEDGER => TransactionKeyManagerBranch::SenderOffsetLedger, + RANDOM_KEY => TransactionKeyManagerBranch::RandomKey, + WALLET_SPEND_KEY => TransactionKeyManagerBranch::WalletSpendKey, _ => TransactionKeyManagerBranch::Nonce, } } diff --git a/base_layer/core/src/transactions/transaction_components/error.rs b/base_layer/core/src/transactions/transaction_components/error.rs index 28e0bcaed4..0a9e021315 100644 --- a/base_layer/core/src/transactions/transaction_components/error.rs +++ b/base_layer/core/src/transactions/transaction_components/error.rs @@ -84,6 +84,8 @@ pub enum TransactionError { ZeroWeight, #[error("Output with commitment {0} not found in transaction body")] OutputNotFound(String), + #[error("Unsupported TariKeyId: `{0}`")] + UnsupportedTariKeyId(String), } impl From for TransactionError { diff --git a/base_layer/key_manager/src/key_manager_service/error.rs b/base_layer/key_manager/src/key_manager_service/error.rs index 43c3196e80..4a9364d715 100644 --- a/base_layer/key_manager/src/key_manager_service/error.rs +++ b/base_layer/key_manager/src/key_manager_service/error.rs @@ -31,8 +31,8 @@ use crate::error::KeyManagerError as KMError; /// Error enum for the [KeyManagerService] #[derive(Debug, thiserror::Error)] pub enum KeyManagerServiceError { - #[error("Branch does not exist")] - UnknownKeyBranch, + #[error("Branch does not exist: `{0}`")] + UnknownKeyBranch(String), #[error("Key ID without an index, most likely `Imported`")] KyeIdWithoutIndex, #[error("Master seed does not match stored version")] diff --git a/base_layer/key_manager/src/key_manager_service/service.rs b/base_layer/key_manager/src/key_manager_service/service.rs index 560ee2d556..9320292524 100644 --- a/base_layer/key_manager/src/key_manager_service/service.rs +++ b/base_layer/key_manager/src/key_manager_service/service.rs @@ -101,7 +101,7 @@ where let mut km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(branch.to_string()))? .lock() .await; self.db.increment_key_index(branch)?; @@ -125,7 +125,7 @@ where pub async fn get_static_key(&self, branch: &str) -> Result, KeyManagerServiceError> { match self.key_managers.get(branch) { - None => Err(KeyManagerServiceError::UnknownKeyBranch), + None => Err(KeyManagerServiceError::UnknownKeyBranch(branch.to_string())), Some(_) => Ok(KeyId::Managed { branch: branch.to_string(), index: 0, @@ -139,7 +139,7 @@ where let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(branch.to_string()))? .lock() .await; Ok(km.derive_public_key(*index)?.key) @@ -148,7 +148,7 @@ where let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(branch.to_string()))? .lock() .await; let branch_key = km.get_private_key(*index)?; @@ -177,7 +177,7 @@ where let km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(branch.to_string()))? .lock() .await; @@ -203,7 +203,7 @@ where let mut km = self .key_managers .get(branch) - .ok_or(KeyManagerServiceError::UnknownKeyBranch)? + .ok_or(KeyManagerServiceError::UnknownKeyBranch(branch.to_string()))? .lock() .await; let current_index = km.key_index();