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/main.rs b/applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs new file mode 100644 index 0000000000..2c5fafb234 --- /dev/null +++ b/applications/minotari_ledger_wallet/comms/examples/ledger_demo/main.rs @@ -0,0 +1,207 @@ +// Copyright 2022 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +//! # Multi-party Ledger - command line example + +use minotari_ledger_wallet_comms::{ + accessor_methods::{ + get_app_name, + get_dh_shared_secret, + get_public_alpha, + get_public_key, + get_raw_schnorr_signature, + get_script_offset, + get_script_schnorr_signature, + get_script_signature, + get_version, + get_view_key, + }, + ledger_wallet::{get_transport, LedgerWallet}, +}; +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::{Commitment, PrivateKey, PublicKey}; +use tari_core::transactions::{ + key_manager::TransactionKeyManagerBranch, + tari_amount::MicroMinotari, + transaction_components::TransactionInputVersion, +}; +use tari_crypto::{ + keys::{PublicKey as PK, SecretKey}, + ristretto::RistrettoSecretKey, +}; +use tari_utilities::{hex::Hex, ByteArray}; + +fn main() { + let account = OsRng.next_u64(); + let ledger = LedgerWallet::new(account, Network::LocalNet, None, None); + let transport = match get_transport() { + Ok(transport) => transport, + Err(e) => { + println!("\nError: {}\n", e); + return; + }, + }; + + println!(); + + // GetAppName + println!("\ntest: GetAppName"); + match get_app_name(&transport, &ledger) { + Ok(name) => println!("app name: {}", name), + Err(e) => println!("\n{}\n", e), + } + + // GetVersion + println!("\ntest: GetVersion"); + match get_version(&transport, &ledger) { + Ok(name) => println!("version: {}", name), + Err(e) => println!("\n{}\n", e), + } + + // GetPublicAlpha + println!("\ntest: GetPublicAlpha"); + match get_public_alpha(&transport, &ledger) { + Ok(public_alpha) => println!("public_alpha: {}", public_alpha.to_hex()), + Err(e) => println!("\n{}\n", e), + } + + // GetPublicKey + println!("\ntest: GetPublicKey"); + let index = OsRng.next_u64(); + let branch = TransactionKeyManagerBranch::CommitmentMask; + + match get_public_key(&transport, &ledger, index, branch) { + Ok(public_key) => println!("public_key: {}", public_key.to_hex()), + Err(e) => println!("\n{}\n", e), + } + + // GetScriptSignature + println!("\ntest: GetScriptSignature"); + let network = Network::LocalNet; + let version = TransactionInputVersion::get_current_version(); + let branch_key = get_random_nonce(); + let value = MicroMinotari(123456); + let spend_private_key = get_random_nonce(); + let commitment = Commitment::from_public_key(&PublicKey::from_secret_key(&get_random_nonce())); + let mut script_message = [0u8; 32]; + script_message.copy_from_slice(&get_random_nonce().to_vec()); + + match get_script_signature( + &transport, + &ledger, + network, + version, + &branch_key, + value, + &spend_private_key, + &commitment, + script_message, + ) { + Ok(signature) => 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!("\n{}\n", e), + } + + // GetScriptOffset + println!("\ntest: GetScriptOffset"); + let mut derived_key_commitments = Vec::new(); + let mut sender_offset_indexes = Vec::new(); + for _i in 0..5 { + derived_key_commitments.push(get_random_nonce()); + sender_offset_indexes.push(OsRng.next_u64()); + } + + match get_script_offset(&transport, &ledger, &derived_key_commitments, &sender_offset_indexes) { + Ok(script_offset) => println!("script_offset: {}", script_offset.to_hex()), + Err(e) => println!("\n{}\n", e), + } + + // GetViewKey + println!("\ntest: GetViewKey"); + + match get_view_key(&transport, &ledger) { + Ok(view_key) => println!("view_key: {}", view_key.to_hex()), + Err(e) => println!("\n{}\n", e), + } + + // GetDHSharedSecret + println!("\ntest: GetDHSharedSecret"); + let index = OsRng.next_u64(); + let branch = TransactionKeyManagerBranch::SenderOffset; + let public_key = PublicKey::from_secret_key(&get_random_nonce()); + + match get_dh_shared_secret(&transport, &ledger, index, branch, &public_key) { + Ok(shared_secret) => println!("shared_secret: {}", shared_secret.as_bytes().to_vec().to_hex()), + Err(e) => println!("\n{}\n", e), + } + + // GetRawSchnorrSignature + println!("\ntest: GetRawSchnorrSignature"); + let private_key_index = OsRng.next_u64(); + let private_key_branch = TransactionKeyManagerBranch::SenderOffset; + let nonce_index = OsRng.next_u64(); + let nonce_branch = TransactionKeyManagerBranch::SenderOffset; + let mut challenge = [0u8; 64]; + OsRng.fill_bytes(&mut challenge); + + match get_raw_schnorr_signature( + &transport, + &ledger, + private_key_index, + private_key_branch, + nonce_index, + nonce_branch, + challenge, + ) { + Ok(signature) => println!( + "signature: ({},{})", + signature.get_signature().to_hex(), + signature.get_public_nonce().to_hex() + ), + Err(e) => println!("\n{}\n", e), + } + + // GetScriptSchnorrSignature + println!("\ntest: GetScriptSchnorrSignature"); + let private_key_index = OsRng.next_u64(); + let private_key_branch = TransactionKeyManagerBranch::SenderOffset; + let mut challenge = [0u8; 64]; + OsRng.fill_bytes(&mut challenge); + + match get_script_schnorr_signature(&transport, &ledger, private_key_index, private_key_branch, challenge) { + Ok(signature) => println!( + "signature: ({},{})", + signature.get_signature().to_hex(), + signature.get_public_nonce().to_hex() + ), + Err(e) => println!("\n{}\n", e), + } + + println!("\nTest completed successfully\n"); +} + +pub fn get_random_nonce() -> PrivateKey { + let mut raw_bytes = [0u8; 64]; + OsRng.fill_bytes(&mut raw_bytes); + RistrettoSecretKey::from_uniform_bytes(&raw_bytes).expect("will not fail") +} diff --git a/applications/minotari_ledger_wallet/comms/src/accessor_methods.rs b/applications/minotari_ledger_wallet/comms/src/accessor_methods.rs new file mode 100644 index 0000000000..124449a4ae --- /dev/null +++ b/applications/minotari_ledger_wallet/comms/src/accessor_methods.rs @@ -0,0 +1,401 @@ +// Copyright 2024 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 ledger_transport_hid::TransportNativeHID; +use tari_common::configuration::Network; +use tari_common_types::types::{ComAndPubSignature, Commitment, PrivateKey, PublicKey, Signature}; +use tari_core::transactions::{ + key_manager::TransactionKeyManagerBranch, + tari_amount::MicroMinotari, + transaction_components::TransactionInputVersion, +}; +use tari_crypto::{ + dhke::DiffieHellmanSharedSecret, + hash_domain, + ristretto::{RistrettoPublicKey, RistrettoSecretKey}, + signatures::SchnorrSignature, +}; +use tari_utilities::ByteArray; + +use crate::{ + error::LedgerDeviceError, + ledger_wallet::{AppSW, Instruction, LedgerWallet, EXPECTED_NAME, EXPECTED_VERSION}, +}; + +hash_domain!(CheckSigHashDomain, "com.tari.script.check_sig", 1); +type CheckSigSchnorrSignature = SchnorrSignature; + +/// Returns the version of the ledger app. +pub fn verify_app_version(transport: &TransportNativeHID) -> Result<(), LedgerDeviceError> { + let ledger = LedgerWallet::new(0, Network::LocalNet, None, None); + + let app_name = get_app_name(transport, &ledger)?; + if app_name != EXPECTED_NAME { + return Err(LedgerDeviceError::Processing(format!( + "Ledger application is not the 'Minotari Wallet' application: expected '{}', running '{}'.", + EXPECTED_NAME, app_name + ))); + } + + let version = get_version(transport, &ledger)?; + if version != EXPECTED_VERSION { + return Err(LedgerDeviceError::Processing(format!( + "'Minotari Wallet' application version mismatch: expected '{}', running '{}'.", + EXPECTED_VERSION, version + ))); + } + + Ok(()) +} + +/// Get the app name from the ledger device +pub fn get_app_name(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result { + 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) => { + if val.is_empty() { + return Err(LedgerDeviceError::ApplicationNotStarted); + } + val + }, + Err(e) => return Err(LedgerDeviceError::Processing(format!("GetAppName: {}", e))), + }; + Ok(name.to_string()) + }, + Err(e) => Err(LedgerDeviceError::Processing(format!("GetAppName: {}", e))), + } +} + +/// Get the version from the ledger device +pub fn get_version(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result { + 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) => { + if val.is_empty() { + return Err(LedgerDeviceError::ApplicationNotStarted); + } + val + }, + Err(e) => return Err(LedgerDeviceError::Processing(format!("GetVersion: {}", e))), + }; + Ok(name.to_string()) + }, + Err(e) => Err(LedgerDeviceError::Processing(format!("GetVersion: {}", e))), + } +} + +/// Get the public alpha key from the ledger device +pub fn get_public_alpha(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result { + match ledger + .build_command(Instruction::GetPublicAlpha, vec![]) + .execute_with_transport(transport) + { + Ok(result) => { + if result.data().len() < 33 { + return Err(LedgerDeviceError::Processing(format!( + "GetPublicAlpha: expected 33 bytes, got {} ({:?})", + result.data().len(), + AppSW::from(result.retcode()) + ))); + } + let public_alpha = PublicKey::from_canonical_bytes(&result.data()[1..33]).unwrap(); + Ok(public_alpha) + }, + Err(e) => Err(LedgerDeviceError::Processing(format!("GetPublicAlpha: {}", e))), + } +} + +/// Get a public key from the ledger device +pub fn get_public_key( + transport: &TransportNativeHID, + ledger: &LedgerWallet, + index: u64, + branch: TransactionKeyManagerBranch, +) -> Result { + let mut data = Vec::new(); + data.extend_from_slice(&index.to_le_bytes()); + let branch_u64 = u64::from(branch.as_byte()).to_le_bytes(); + data.extend_from_slice(&branch_u64); + + match ledger + .build_command(Instruction::GetPublicKey, data) + .execute_with_transport(transport) + { + Ok(result) => { + if result.data().len() < 33 { + return Err(LedgerDeviceError::Processing(format!( + "GetPublicAlpha: expected 33 bytes, got {} ({:?})", + result.data().len(), + AppSW::from(result.retcode()) + ))); + } + let public_key = PublicKey::from_canonical_bytes(&result.data()[1..33]).unwrap(); + Ok(public_key) + }, + Err(e) => Err(LedgerDeviceError::Processing(format!("GetPublicKey: {}", e))), + } +} + +/// Get the script signature from the ledger device +pub fn get_script_signature( + transport: &TransportNativeHID, + ledger: &LedgerWallet, + network: Network, + version: TransactionInputVersion, + branch_key: &PrivateKey, + value: MicroMinotari, + spend_private_key: &PrivateKey, + commitment: &Commitment, + script_message: [u8; 32], +) -> Result { + let mut data = Vec::new(); + let network = u64::from(network.as_byte()).to_le_bytes(); + data.extend_from_slice(&network); + let version = u64::from(version.as_u8()).to_le_bytes(); + data.extend_from_slice(&version); + let branch_key = branch_key.to_vec(); + data.extend_from_slice(&branch_key); + let value = PrivateKey::from(value.as_u64()).to_vec(); + data.extend_from_slice(&value); + let spend_private_key = spend_private_key.to_vec(); + data.extend_from_slice(&spend_private_key); + let commitment = commitment.to_vec(); + data.extend_from_slice(&commitment); + data.extend_from_slice(&script_message); + + match ledger + .build_command(Instruction::GetScriptSignature, data) + .execute_with_transport(transport) + { + Ok(result) => { + if result.data().len() < 161 { + return Err(LedgerDeviceError::Processing(format!( + "GetScriptSignature: expected 161 bytes, got {} ({:?})", + result.data().len(), + AppSW::from(result.retcode()) + ))); + } + 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(), + ); + Ok(signature) + }, + Err(e) => Err(LedgerDeviceError::Processing(format!("GetScriptSignature: {}", e))), + } +} + +/// Get the script offset from the ledger device +pub fn get_script_offset( + transport: &TransportNativeHID, + ledger: &LedgerWallet, + derived_key_commitments: &[PrivateKey], + sender_offset_indexes: &[u64], +) -> Result { + let num_commitments = derived_key_commitments.len() as u64; + let num_offset_key = sender_offset_indexes.len() as u64; + + let mut instructions = num_offset_key.to_le_bytes().to_vec(); + instructions.extend_from_slice(&num_commitments.to_le_bytes()); + + let mut data: Vec> = vec![instructions.to_vec()]; + let total_script_private_key = PrivateKey::default(); + data.push(total_script_private_key.to_vec()); + + for sender_offset_index in sender_offset_indexes { + data.push(sender_offset_index.to_le_bytes().to_vec()); + } + + for derived_key_commitment in derived_key_commitments { + data.push(derived_key_commitment.to_vec()); + } + + let commands = ledger.chunk_command(Instruction::GetScriptOffset, data); + + let mut result = None; + for command in commands { + match command.execute_with_transport(transport) { + Ok(r) => result = Some(r), + Err(e) => return Err(LedgerDeviceError::Processing(format!("GetScriptOffset: {}", e))), + } + } + + match result { + Some(result) => { + if result.data().len() < 33 { + return Err(LedgerDeviceError::Processing(format!( + "GetScriptOffset: expected 33 bytes, got {} ({:?})", + result.data().len(), + AppSW::from(result.retcode()) + ))); + } + let script_offset = PrivateKey::from_canonical_bytes(&result.data()[1..33]).unwrap(); + Ok(script_offset) + }, + None => Err(LedgerDeviceError::Processing("GetScriptOffset: No result".to_string())), + } +} + +/// Get the view key from the ledger device +pub fn get_view_key(transport: &TransportNativeHID, ledger: &LedgerWallet) -> Result { + match ledger + .build_command(Instruction::GetViewKey, vec![]) + .execute_with_transport(transport) + { + Ok(result) => { + if result.data().len() < 33 { + return Err(LedgerDeviceError::Processing(format!( + "GetViewKey: expected 33 bytes, got {} ({:?})", + result.data().len(), + AppSW::from(result.retcode()) + ))); + } + let view_key = PrivateKey::from_canonical_bytes(&result.data()[1..33]).unwrap(); + Ok(view_key) + }, + Err(e) => Err(LedgerDeviceError::Processing(format!("GetViewKey: {}", e))), + } +} + +/// Get the Diffie-Hellman shared secret from the ledger device +pub fn get_dh_shared_secret( + transport: &TransportNativeHID, + ledger: &LedgerWallet, + index: u64, + branch: TransactionKeyManagerBranch, + public_key: &PublicKey, +) -> Result, LedgerDeviceError> { + let mut data = Vec::new(); + data.extend_from_slice(&index.to_le_bytes()); + data.extend_from_slice(&u64::from(branch.as_byte()).to_le_bytes()); + data.extend_from_slice(&public_key.to_vec()); + + match ledger + .build_command(Instruction::GetDHSharedSecret, data) + .execute_with_transport(transport) + { + Ok(result) => { + if result.data().len() < 33 { + return Err(LedgerDeviceError::Processing(format!( + "GetDHSharedSecret: expected 33 bytes, got {} ({:?})", + result.data().len(), + AppSW::from(result.retcode()) + ))); + } + let shared_secret = + DiffieHellmanSharedSecret::::from_canonical_bytes(&result.data()[1..33]).unwrap(); + Ok(shared_secret) + }, + Err(e) => Err(LedgerDeviceError::Processing(format!("GetDHSharedSecret: {}", e))), + } +} + +/// Get the raw schnorr signature from the ledger device +pub fn get_raw_schnorr_signature( + transport: &TransportNativeHID, + ledger: &LedgerWallet, + private_key_index: u64, + private_key_branch: TransactionKeyManagerBranch, + nonce_index: u64, + nonce_branch: TransactionKeyManagerBranch, + challenge: [u8; 64], +) -> Result { + let mut data = Vec::new(); + data.extend_from_slice(&private_key_index.to_le_bytes()); + data.extend_from_slice(&u64::from(private_key_branch.as_byte()).to_le_bytes()); + data.extend_from_slice(&nonce_index.to_le_bytes()); + data.extend_from_slice(&u64::from(nonce_branch.as_byte()).to_le_bytes()); + data.extend_from_slice(&challenge); + + match ledger + .build_command(Instruction::GetRawSchnorrSignature, data) + .execute_with_transport(transport) + { + Ok(result) => { + if result.data().len() < 65 { + return Err(LedgerDeviceError::Processing(format!( + "GetRawSchnorrSignature: expected 65 bytes, got {} ({:?})", + result.data().len(), + AppSW::from(result.retcode()) + ))); + } + + let signature = Signature::new( + PublicKey::from_canonical_bytes(&result.data()[1..33]).unwrap(), + PrivateKey::from_canonical_bytes(&result.data()[33..65]).unwrap(), + ); + Ok(signature) + }, + Err(e) => Err(LedgerDeviceError::Processing(format!("GetRawSchnorrSignature: {}", e))), + } +} + +/// Get the script schnorr signature from the ledger device +pub fn get_script_schnorr_signature( + transport: &TransportNativeHID, + ledger: &LedgerWallet, + private_key_index: u64, + private_key_branch: TransactionKeyManagerBranch, + challenge: [u8; 64], +) -> Result { + let mut data = Vec::new(); + data.extend_from_slice(&private_key_index.to_le_bytes()); + data.extend_from_slice(&u64::from(private_key_branch.as_byte()).to_le_bytes()); + data.extend_from_slice(&challenge); + + match ledger + .build_command(Instruction::GetScriptSchnorrSignature, data) + .execute_with_transport(transport) + { + Ok(result) => { + if result.data().len() < 65 { + return Err(LedgerDeviceError::Processing(format!( + "GetScriptSchnorrSignature: expected 65 bytes, got {} ({:?})", + result.data().len(), + AppSW::from(result.retcode()) + ))); + } + + let signature = CheckSigSchnorrSignature::new( + PublicKey::from_canonical_bytes(&result.data()[1..33]).unwrap(), + PrivateKey::from_canonical_bytes(&result.data()[33..65]).unwrap(), + ); + Ok(signature) + }, + Err(e) => Err(LedgerDeviceError::Processing(format!( + "GetScriptSchnorrSignature: {}", + e + ))), + } +} diff --git a/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs b/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs index 44f897bfb8..3c93228543 100644 --- a/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs +++ b/applications/minotari_ledger_wallet/comms/src/ledger_wallet.rs @@ -20,14 +20,22 @@ // 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::ops::Deref; +use std::{ + fmt, + fmt::{Display, Formatter}, + ops::Deref, +}; use ledger_transport::{APDUAnswer, APDUCommand}; use ledger_transport_hid::{hidapi::HidApi, TransportNativeHID}; use num_derive::FromPrimitive; use num_traits::FromPrimitive; +use serde::{Deserialize, Serialize}; +use tari_common::configuration::Network; +use tari_common_types::types::{PrivateKey, PublicKey}; +use tari_utilities::ByteArray; -use crate::error::LedgerDeviceError; +use crate::{accessor_methods::verify_app_version, error::LedgerDeviceError}; #[repr(u8)] #[derive(FromPrimitive, Debug, Copy, Clone, PartialEq)] @@ -38,12 +46,58 @@ pub enum Instruction { GetPublicKey = 0x04, GetScriptSignature = 0x05, GetScriptOffset = 0x06, - GetMetadataSignature = 0x07, - GetScriptSignatureFromChallenge = 0x08, - GetViewKey = 0x09, - GetDHSharedSecret = 0x10, + GetViewKey = 0x07, + GetDHSharedSecret = 0x08, + GetRawSchnorrSignature = 0x09, + GetScriptSchnorrSignature = 0x10, } +#[repr(u16)] +#[derive(FromPrimitive, Debug, Copy, Clone, PartialEq)] +pub enum AppSW { + Deny = 0xB001, + WrongP1P2 = 0xB002, + InsNotSupported = 0xB003, + ClaNotSupported = 0xB004, + ScriptSignatureFail = 0xB005, + MetadataSignatureFail = 0xB006, + RawSchnorrSignatureFail = 0xB007, + SchnorrSignatureFail = 0xB008, + KeyDeriveFail = 0xB009, + KeyDeriveFromCanonical = 0xB00A, + KeyDeriveFromUniform = 0xB00B, + VersionParsingFail = 0xB00C, + TooManyPayloads = 0xB00D, + RandomNonceFail = 0xB00E, + WrongApduLength = 0x6e03, // See ledger-device-rust-sdk/ledger_device_sdk/src/io.rs:16 +} + +impl From for AppSW { + fn from(value: u16) -> Self { + match value { + 0xB001 => AppSW::Deny, + 0xB002 => AppSW::WrongP1P2, + 0xB003 => AppSW::InsNotSupported, + 0xB004 => AppSW::ClaNotSupported, + 0xB005 => AppSW::ScriptSignatureFail, + 0xB006 => AppSW::MetadataSignatureFail, + 0xB007 => AppSW::RawSchnorrSignatureFail, + 0xB008 => AppSW::SchnorrSignatureFail, + 0xB009 => AppSW::KeyDeriveFail, + 0xB00A => AppSW::KeyDeriveFromCanonical, + 0xB00B => AppSW::KeyDeriveFromUniform, + 0xB00C => AppSW::VersionParsingFail, + 0xB00D => AppSW::TooManyPayloads, + 0xB00E => AppSW::RandomNonceFail, + 0x6e03 => AppSW::WrongApduLength, + _ => AppSW::Deny, + } + } +} + +pub const EXPECTED_NAME: &str = "minotari_ledger_wallet"; +pub const EXPECTED_VERSION: &str = "1.0.0-pre.16"; + impl Instruction { pub fn as_byte(self) -> u8 { self as u8 @@ -56,7 +110,9 @@ impl Instruction { pub fn get_transport() -> Result { let hid = HidApi::new().map_err(|e| LedgerDeviceError::HidApi(e.to_string()))?; - TransportNativeHID::new(&hid).map_err(|e| LedgerDeviceError::NativeTransport(e.to_string())) + let transport = TransportNativeHID::new(&hid).map_err(|e| LedgerDeviceError::NativeTransport(e.to_string()))?; + verify_app_version(&transport)?; + Ok(transport) } #[derive(Debug, Clone)] @@ -84,3 +140,80 @@ impl> Command { .map_err(|e| LedgerDeviceError::NativeTransport(e.to_string())) } } + +#[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/src/lib.rs b/applications/minotari_ledger_wallet/comms/src/lib.rs index a14b091c78..d9c242ccc9 100644 --- a/applications/minotari_ledger_wallet/comms/src/lib.rs +++ b/applications/minotari_ledger_wallet/comms/src/lib.rs @@ -20,5 +20,6 @@ // 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. +pub mod accessor_methods; pub mod error; pub mod ledger_wallet; diff --git a/applications/minotari_ledger_wallet/wallet/Cargo.toml b/applications/minotari_ledger_wallet/wallet/Cargo.toml index 1c4839ab69..fb6f08f3cc 100644 --- a/applications/minotari_ledger_wallet/wallet/Cargo.toml +++ b/applications/minotari_ledger_wallet/wallet/Cargo.toml @@ -15,7 +15,8 @@ critical-section = { version = "1.1.1" } digest = { version = "0.10", default-features = false } embedded-alloc = "0.5.0" include_gif = "1.0.1" -ledger_device_sdk = "1.7.1" +ledger_device_sdk = "1.7" +rand_core = { version = "0.6", default_features = false } zeroize = { version = "1", default-features = false } # once_cell defined here just to lock the version. Other dependencies may try to go to 1.19 which is incompatabile with @@ -32,7 +33,7 @@ lto = "fat" # same as `true` panic = "abort" [features] -default = ["pending_review_screen"] +default = [] pending_review_screen = [] [package.metadata.ledger] diff --git a/applications/minotari_ledger_wallet/wallet/src/handlers/get_dh_shared_secret.rs b/applications/minotari_ledger_wallet/wallet/src/handlers/get_dh_shared_secret.rs index 14a8b29da2..c5fa1d6872 100644 --- a/applications/minotari_ledger_wallet/wallet/src/handlers/get_dh_shared_secret.rs +++ b/applications/minotari_ledger_wallet/wallet/src/handlers/get_dh_shared_secret.rs @@ -3,7 +3,7 @@ use core::ops::Deref; -use ledger_device_sdk::io::Comm; +use ledger_device_sdk::{io::Comm, ui::gadgets::SingleMessage}; use tari_crypto::{ristretto::RistrettoPublicKey, tari_utilities::ByteArray}; use crate::{ @@ -15,6 +15,10 @@ use crate::{ pub fn handler_get_dh_shared_secret(comm: &mut Comm) -> Result<(), AppSW> { let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?; + if data.len() != 56 { + SingleMessage::new("Invalid data length").show_and_wait(); + return Err(AppSW::WrongApduLength); + } let mut account_bytes = [0u8; 8]; account_bytes.clone_from_slice(&data[0..8]); diff --git a/applications/minotari_ledger_wallet/wallet/src/handlers/get_public_alpha.rs b/applications/minotari_ledger_wallet/wallet/src/handlers/get_public_alpha.rs index 3904303734..a33eb76fa1 100644 --- a/applications/minotari_ledger_wallet/wallet/src/handlers/get_public_alpha.rs +++ b/applications/minotari_ledger_wallet/wallet/src/handlers/get_public_alpha.rs @@ -1,13 +1,17 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use ledger_device_sdk::io::Comm; +use ledger_device_sdk::{io::Comm, ui::gadgets::SingleMessage}; use tari_crypto::{keys::PublicKey, ristretto::RistrettoPublicKey, tari_utilities::ByteArray}; use crate::{utils::derive_from_bip32_key, AppSW, KeyType, RESPONSE_VERSION, STATIC_ALPHA_INDEX}; pub fn handler_get_public_alpha(comm: &mut Comm) -> Result<(), AppSW> { let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?; + if data.len() != 8 { + SingleMessage::new("Invalid data length").show_and_wait(); + return Err(AppSW::WrongApduLength); + } let mut account_bytes = [0u8; 8]; account_bytes.clone_from_slice(&data[0..8]); diff --git a/applications/minotari_ledger_wallet/wallet/src/handlers/get_public_key.rs b/applications/minotari_ledger_wallet/wallet/src/handlers/get_public_key.rs index 449cc8c218..a83cec9b1c 100644 --- a/applications/minotari_ledger_wallet/wallet/src/handlers/get_public_key.rs +++ b/applications/minotari_ledger_wallet/wallet/src/handlers/get_public_key.rs @@ -1,13 +1,17 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use ledger_device_sdk::io::Comm; +use ledger_device_sdk::{io::Comm, ui::gadgets::SingleMessage}; use tari_crypto::{keys::PublicKey, ristretto::RistrettoPublicKey, tari_utilities::ByteArray}; use crate::{utils::derive_from_bip32_key, AppSW, KeyType, RESPONSE_VERSION}; pub fn handler_get_public_key(comm: &mut Comm) -> Result<(), AppSW> { let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?; + if data.len() != 24 { + SingleMessage::new("Invalid data length").show_and_wait(); + return Err(AppSW::WrongApduLength); + } let mut account_bytes = [0u8; 8]; account_bytes.clone_from_slice(&data[0..8]); 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..a96a193039 --- /dev/null +++ b/applications/minotari_ledger_wallet/wallet/src/handlers/get_schnorr_signature.rs @@ -0,0 +1,126 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use alloc::format; +use core::ops::Deref; + +use ledger_device_sdk::{io::Comm, ui::gadgets::SingleMessage}; +use tari_crypto::{ + hash_domain, + ristretto::{RistrettoPublicKey, RistrettoSchnorr, RistrettoSecretKey}, + signatures::SchnorrSignature, + tari_utilities::ByteArray, +}; + +use crate::{ + alloc::string::ToString, + utils::{derive_from_bip32_key, get_random_nonce}, + AppSW, + KeyType, + RESPONSE_VERSION, +}; + +hash_domain!(CheckSigHashDomain, "com.tari.script.check_sig", 1); + +/// The type used for `CheckSig`, `CheckMultiSig`, and related opcodes' signatures +pub type CheckSigSchnorrSignature = SchnorrSignature; + +pub fn handler_get_raw_schnorr_signature(comm: &mut Comm) -> Result<(), AppSW> { + let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?; + if data.len() != 104 { + SingleMessage::new("Invalid data length").show_and_wait(); + return 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_script_schnorr_signature(comm: &mut Comm) -> Result<(), AppSW> { + let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?; + if data.len() != 88 { + SingleMessage::new("Invalid data length").show_and_wait(); + return 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 key_type = u64::from_le_bytes(private_key_type_bytes); + let private_key_type = KeyType::from_branch_key(key_type); + + 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[24..88]); + + let random_nonce_a = get_random_nonce()?.deref().clone(); + let random_nonce_b = get_random_nonce()?.deref().clone(); + if random_nonce_a == random_nonce_b { + SingleMessage::new("Nonces not unique!").show_and_wait(); + return Err(AppSW::SchnorrSignatureFail); + } + let signature = + match CheckSigSchnorrSignature::sign_with_nonce_and_message(&private_key, random_nonce_a, &challenge_bytes) { + Ok(sig) => sig, + Err(e) => { + SingleMessage::new(&format!("Signing error:",)).show_and_wait(); + SingleMessage::new(&format!("{}", e.to_string())).show_and_wait(); + return Err(AppSW::SchnorrSignatureFail); + }, + }; + + comm.append(&[RESPONSE_VERSION]); // version + comm.append(&signature.get_public_nonce().to_vec()); + comm.append(&signature.get_signature().to_vec()); + comm.reply_ok(); + + Ok(()) +} diff --git a/applications/minotari_ledger_wallet/wallet/src/handlers/get_script_signature.rs b/applications/minotari_ledger_wallet/wallet/src/handlers/get_script_signature.rs index 90b82603f7..d2d7219ba1 100644 --- a/applications/minotari_ledger_wallet/wallet/src/handlers/get_script_signature.rs +++ b/applications/minotari_ledger_wallet/wallet/src/handlers/get_script_signature.rs @@ -5,7 +5,7 @@ use alloc::format; use blake2::Blake2b; use digest::consts::U64; -use ledger_device_sdk::{io::Comm, random::Random, ui::gadgets::SingleMessage}; +use ledger_device_sdk::{io::Comm, ui::gadgets::SingleMessage}; use tari_crypto::{ commitment::HomomorphicCommitmentFactory, keys::PublicKey, @@ -22,7 +22,7 @@ use zeroize::Zeroizing; use crate::{ alloc::string::ToString, hashing::DomainSeparatedConsensusHasher, - utils::{alpha_hasher, derive_from_bip32_key, get_key_from_canonical_bytes}, + utils::{alpha_hasher, derive_from_bip32_key, get_key_from_canonical_bytes, get_random_nonce}, AppSW, KeyType, RESPONSE_VERSION, @@ -31,6 +31,10 @@ use crate::{ pub fn handler_get_script_signature(comm: &mut Comm) -> Result<(), AppSW> { let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?; + if data.len() != 184 { + SingleMessage::new("Invalid data length").show_and_wait(); + return Err(AppSW::WrongApduLength); + } let mut account_bytes = [0u8; 8]; account_bytes.clone_from_slice(&data[0..8]); @@ -60,9 +64,13 @@ pub fn handler_get_script_signature(comm: &mut Comm) -> Result<(), AppSW> { let mut script_message = [0u8; 32]; script_message.clone_from_slice(&data[152..184]); - let r_a = derive_from_bip32_key(account, u32::random().into(), KeyType::Nonce)?; - let r_x = derive_from_bip32_key(account, u32::random().into(), KeyType::Nonce)?; - let r_y = derive_from_bip32_key(account, u32::random().into(), KeyType::Nonce)?; + let r_a = get_random_nonce()?; + let r_x = get_random_nonce()?; + let r_y = get_random_nonce()?; + if r_a == r_x || r_a == r_y || r_x == r_y { + SingleMessage::new("Nonces not unique!").show_and_wait(); + return Err(AppSW::ScriptSignatureFail); + } let factory = ExtendedPedersenCommitmentFactory::default(); diff --git a/applications/minotari_ledger_wallet/wallet/src/handlers/get_view_key.rs b/applications/minotari_ledger_wallet/wallet/src/handlers/get_view_key.rs index 7fc11b9f27..e22397e3d3 100644 --- a/applications/minotari_ledger_wallet/wallet/src/handlers/get_view_key.rs +++ b/applications/minotari_ledger_wallet/wallet/src/handlers/get_view_key.rs @@ -1,13 +1,17 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use ledger_device_sdk::io::Comm; +use ledger_device_sdk::{io::Comm, ui::gadgets::SingleMessage}; use tari_crypto::tari_utilities::ByteArray; use crate::{utils::derive_from_bip32_key, AppSW, KeyType, RESPONSE_VERSION, STATIC_VIEW_INDEX}; pub fn handler_get_view_key(comm: &mut Comm) -> Result<(), AppSW> { let data = comm.get_data().map_err(|_| AppSW::WrongApduLength)?; + if data.len() != 8 { + SingleMessage::new("Invalid data length").show_and_wait(); + return Err(AppSW::WrongApduLength); + } let mut account_bytes = [0u8; 8]; account_bytes.clone_from_slice(&data[0..8]); diff --git a/applications/minotari_ledger_wallet/wallet/src/main.rs b/applications/minotari_ledger_wallet/wallet/src/main.rs index e27c78b93c..afe4444012 100644 --- a/applications/minotari_ledger_wallet/wallet/src/main.rs +++ b/applications/minotari_ledger_wallet/wallet/src/main.rs @@ -8,7 +8,7 @@ extern crate alloc; mod hashing; -mod utils; +pub mod utils; mod app_ui { pub mod menu; @@ -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_script_schnorr_signature}, get_script_offset::{handler_get_script_offset, ScriptOffsetCtx}, get_script_signature::handler_get_script_signature, get_version::handler_get_version, @@ -87,18 +89,21 @@ unsafe impl critical_section::Impl for MyCriticalSection { // Application status words. #[repr(u16)] pub enum AppSW { - Deny = 0x6985, - WrongP1P2 = 0x6A86, - InsNotSupported = 0x6D00, - ClaNotSupported = 0x6E00, - ScriptSignatureFail = 0xB001, - MetadataSignatureFail = 0xB002, + Deny = 0xB001, + WrongP1P2 = 0xB002, + InsNotSupported = 0xB003, + ClaNotSupported = 0xB004, + ScriptSignatureFail = 0xB005, + MetadataSignatureFail = 0xB006, + RawSchnorrSignatureFail = 0xB007, + SchnorrSignatureFail = 0xB008, KeyDeriveFail = 0xB009, - KeyDeriveFromCanonical = 0xB010, - KeyDeriveFromUniform = 0xB011, - VersionParsingFail = 0xB00A, - TooManyPayloads = 0xB003, - WrongApduLength = StatusWords::BadLen as u16, + KeyDeriveFromCanonical = 0xB00A, + KeyDeriveFromUniform = 0xB00B, + VersionParsingFail = 0xB00C, + TooManyPayloads = 0xB00D, + RandomNonceFail = 0xB00E, + WrongApduLength = StatusWords::BadLen as u16, // See ledger-device-rust-sdk/ledger_device_sdk/src/io.rs:16 } impl From for Reply { @@ -115,9 +120,10 @@ pub enum Instruction { GetPublicAlpha, GetScriptSignature, GetScriptOffset { chunk: u8, more: bool }, - GetScriptSignatureFromChallenge, GetViewKey, GetDHSharedSecret, + GetRawSchnorrSignature, + GetScriptSchnorrSignature, } const P2_MORE: u8 = 0x01; @@ -126,12 +132,15 @@ const STATIC_VIEW_INDEX: u64 = 57311; // No significance, just a random number b const MAX_PAYLOADS: u8 = 250; #[repr(u8)] +#[derive(Debug)] pub enum KeyType { Alpha = 0x01, Nonce = 0x02, Recovery = 0x03, SenderOffset = 0x04, ViewKey = 0x05, + Random = 0x06, + WalletSpendKey = 0x07, } impl KeyType { @@ -140,9 +149,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 +187,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::GetScriptSchnorrSignature), (0x06, _, _) => Err(AppSW::WrongP1P2), (_, _, _) => Err(AppSW::InsNotSupported), } @@ -221,8 +236,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::GetScriptSchnorrSignature => handler_get_script_schnorr_signature(comm), } } diff --git a/applications/minotari_ledger_wallet/wallet/src/utils.rs b/applications/minotari_ledger_wallet/wallet/src/utils.rs index 9441768268..e5b5161801 100644 --- a/applications/minotari_ledger_wallet/wallet/src/utils.rs +++ b/applications/minotari_ledger_wallet/wallet/src/utils.rs @@ -9,8 +9,10 @@ use digest::{consts::U64, Digest}; use ledger_device_sdk::{ ecc::{bip32_derive, make_bip32_path, CurvesId, CxError}, io::SyscallError, + random::LedgerRng, ui::gadgets::SingleMessage, }; +use rand_core::RngCore; use tari_crypto::{ hashing::DomainSeparatedHasher, keys::SecretKey, @@ -158,6 +160,9 @@ fn get_raw_key_hash(path: &[u32]) -> Result, String> { let raw_key_64 = match bip32_derive(CurvesId::Ed25519, path, key_buffer.as_mut(), Some(&mut [])) { Ok(_) => { let binding = &key_buffer.as_ref()[..BIP32_KEY_LENGTH]; + if binding == &[0u8; BIP32_KEY_LENGTH] { + return Err(cx_error_to_string(CxError::InternalError)); + } let mut key_bytes = Zeroizing::new([0u8; BIP32_KEY_LENGTH]); // `copy_from_slice` will not panic as the length of the slice is equal to the length of the array key_bytes.as_mut().copy_from_slice(binding); @@ -258,3 +263,14 @@ pub fn derive_from_bip32_key( }, } } + +pub fn get_random_nonce() -> Result, AppSW> { + let mut raw_bytes = [0u8; 64]; + LedgerRng.fill_bytes(&mut raw_bytes); + if raw_bytes == [0u8; 64] { + return Err(AppSW::RandomNonceFail); + } + Ok(Zeroizing::new( + RistrettoSecretKey::from_uniform_bytes(&raw_bytes).expect("will not fail"), + )) +} diff --git a/base_layer/core/src/transactions/key_manager/inner.rs b/base_layer/core/src/transactions/key_manager/inner.rs index a8d48a37ea..d6b4803ff1 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::GetScriptSchnorrSignature, 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( 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();