From 49ad468a215fc4935eb43d74e4e8662a52b73f69 Mon Sep 17 00:00:00 2001 From: pasta Date: Tue, 22 Sep 2026 21:18:02 -0500 Subject: [PATCH 1/4] chore(platform)!: bump rust-dashcore to 719de34b (secp256k1 0.33) Bump every rust-dashcore git dependency from e4208c90 to 719de34b (dashpay/rust-dashcore dev, the merge of #1049). The breaking change in range is rust-dashcore #1042: secp256k1 0.30 -> 0.33, rand 0.9, getrandom 0.4, and the secp256k1 context argument dropped API-wide. The range also carries key-wallet fixes #1035 (DIP-15 contact pools extend as payments arrive), #1009 (provider transactions consult every fund-bearing account), #1048, and test-only #920/#1038. Mechanical call-site migration: drop Secp256k1 contexts (derive_priv/from_priv/public_key/from_secret_key/Keypair::new take no context); secp.sign_ecdsa/recover_ecdsa/verify_ecdsa become methods on the key/signature; SecretKey::from_slice/from_byte_array become from_secret_bytes (slices go through <[u8; 32]>::try_from mapped to Error::InvalidSecretKey, the error from_slice returned); secret_bytes -> to_secret_bytes; SecretKey/SharedSecret lost AsRef<[u8]>, so use as_secret_bytes; thread_rng -> rng; StdRng::from_entropy -> from_os_rng. The secp256k1::hashes re-export is gone, so hex rendering uses the hex crate (same output). Seeded RNG bridging (rand 0.8 caller -> secp's rand 0.9 StdRng) now fills a 32-byte seed and calls from_seed, which is what rand_core 0.6 from_rng did, so seeded keys are unchanged; drive-abci tests that feed seed_from_u64 into Keypair::new use the secp re-exported StdRng (seed_from_u64 and ChaCha12 are identical across rand_core 0.6/0.9). rs-platform-encryption moves its own secp256k1 to 0.33.1 so only one secp256k1 is in the graph. simple-signer takes a direct rand 0.8 dep for the RngCore its callers pass. rs-dpp enables getrandom 0.3/0.4 wasm_js on wasm32-unknown-unknown, which the new transitive getrandom versions require there. Rust toolchain already at 1.98.1, matching rust-dashcore. Co-Authored-By: Claude Opus 5.5 (1M context) --- Cargo.lock | 85 ++++++------- Cargo.toml | 16 +-- packages/rs-dpp/Cargo.toml | 10 ++ .../src/address_funds/platform_address.rs | 19 +-- .../identity/identity_public_key/key_type.rs | 51 ++++---- .../identity_public_key/v0/methods/mod.rs | 11 +- .../v0/mod.rs | 10 +- packages/rs-dpp/src/state_transition/mod.rs | 17 +-- .../signing_tests.rs | 17 ++- .../signing_tests.rs | 9 +- .../signing_tests.rs | 10 +- .../state_transition_identity_signed.rs | 7 +- .../instant_asset_lock_proof_fixture.rs | 10 +- .../src/execution/check_tx/v0/mod.rs | 17 ++- .../address_funding_from_asset_lock/tests.rs | 4 +- .../batch/tests/token/direct_selling/mod.rs | 9 +- .../identity_create_from_addresses/tests.rs | 51 ++++---- .../state_transitions/identity_update/mod.rs | 117 ++++++++---------- .../shield_from_asset_lock/tests.rs | 2 +- .../state_transitions/test_helpers.rs | 15 +-- .../tests/strategy_tests/strategy.rs | 4 +- .../src/proof/token_direct_purchase.rs | 7 +- packages/rs-platform-encryption/Cargo.toml | 6 +- .../src/account_label.rs | 11 +- packages/rs-platform-encryption/src/aes.rs | 4 +- .../src/compact_xpub.rs | 11 +- packages/rs-platform-encryption/src/ecdh.rs | 25 ++-- .../rs-platform-wallet-ffi/src/dashpay.rs | 4 +- .../rs-platform-wallet-ffi/src/derivation.rs | 8 +- .../src/derive_identity_key_at_slot.rs | 3 +- .../src/identity_derive_and_persist.rs | 8 +- .../src/identity_key_preview.rs | 6 +- .../src/identity_keys_from_mnemonic.rs | 8 +- .../src/identity_registration_with_signer.rs | 2 +- .../rs-platform-wallet-ffi/src/invitation.rs | 2 +- .../rs-platform-wallet-ffi/src/persistence.rs | 10 +- .../src/secp256k1_primitives.rs | 14 +-- .../src/sign_with_mnemonic_resolver.rs | 22 ++-- packages/rs-platform-wallet-ffi/src/utils.rs | 21 ++-- .../examples/dpns_marketplace_testnet.rs | 7 +- .../src/masternode/locator.rs | 15 +-- .../rs-platform-wallet/src/test_support.rs | 11 +- .../src/wallet/core/sign_message.rs | 15 +-- .../src/wallet/core_address_key.rs | 14 +-- .../src/wallet/identity/crypto/auto_accept.rs | 35 +++--- .../wallet/identity/crypto/contact_info.rs | 2 +- .../src/wallet/identity/crypto/dip14.rs | 5 +- .../src/wallet/identity/crypto/invitation.rs | 20 +-- .../src/wallet/identity/crypto/validation.rs | 7 +- .../wallet/identity/network/contact_info.rs | 4 +- .../identity/network/contact_requests.rs | 11 +- .../src/wallet/identity/network/discovery.rs | 2 +- .../identity/network/identity_handle.rs | 14 +-- .../src/wallet/identity/network/invitation.rs | 4 +- .../src/wallet/identity/network/payments.rs | 23 ++-- .../src/wallet/masternode_withdrawal.rs | 28 ++--- .../src/wallet/platform_addresses/provider.rs | 4 +- .../src/wallet/provider_ecdsa_key_tests.rs | 7 +- .../src/wallet/provider_key_at_index.rs | 31 ++--- .../rs-scripts/src/bin/register_identity.rs | 6 +- .../src/address/transitions/transfer.rs | 15 ++- .../src/address/transitions/withdraw.rs | 5 +- .../transitions/cast_vote.rs | 7 +- .../src/identity/create_from_addresses.rs | 5 +- packages/rs-sdk-ffi/src/identity/helpers.rs | 2 +- .../src/identity/top_up_from_addresses.rs | 5 +- .../src/mnemonic_resolver_core_signer.rs | 50 ++++---- packages/rs-sdk-ffi/src/signer_simple.rs | 6 +- .../src/platform/dashpay/contact_request.rs | 26 ++-- .../rs-sdk/src/platform/dpns_usernames/mod.rs | 4 +- .../platform/transition/broadcast_identity.rs | 2 +- .../src/platform/transition/put_document.rs | 4 +- .../src/platform/transition/top_up_address.rs | 2 +- .../platform/transition/top_up_identity.rs | 2 +- packages/rs-unified-sdk-jni/src/tx_decode.rs | 7 +- packages/simple-signer/Cargo.toml | 3 + packages/simple-signer/src/signer.rs | 15 +-- .../simple-signer/src/single_key_signer.rs | 16 +-- packages/strategy-tests/src/lib.rs | 4 +- packages/strategy-tests/src/transitions.rs | 13 +- packages/wasm-dpp2/src/core/private_key.rs | 12 +- packages/wasm-dpp2/src/identity/public_key.rs | 7 +- packages/wasm-dpp2/src/public_key.rs | 8 +- .../base/state_transition.rs | 4 +- packages/wasm-sdk/src/wallet/dip14.rs | 21 ++-- .../src/wallet/extended_derivation.rs | 10 +- .../wasm-sdk/src/wallet/key_derivation.rs | 19 +-- .../wasm-sdk/src/wallet/key_generation.rs | 14 +-- 88 files changed, 542 insertions(+), 674 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0e4a6ff648..51bc3a52007 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ dependencies = [ "bitflags 2.13.0", "cexpr", "clang-sys", - "itertools 0.10.5", + "itertools 0.13.0", "proc-macro2", "quote", "regex", @@ -631,19 +631,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" -[[package]] -name = "bitcoin-io" -version = "0.1.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11301df0b06f22dea7bb1916403fdd88a371031e495c49b8f96931b28189e175" - [[package]] name = "bitcoin_hashes" version = "0.14.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c9901a56e133a1fc86eeb1113e2591f45f4682451ca893bff494d2f88918e3f" dependencies = [ - "bitcoin-io", "hex-conservative", ] @@ -1221,7 +1214,7 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -1654,7 +1647,7 @@ dependencies = [ [[package]] name = "dash-network" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "cbindgen 0.29.4", "grovedb-bincode", @@ -1665,7 +1658,7 @@ dependencies = [ [[package]] name = "dash-network-seeds" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "dash-network", ] @@ -1760,7 +1753,7 @@ dependencies = [ [[package]] name = "dash-spv" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "async-trait", "chrono", @@ -1773,7 +1766,7 @@ dependencies = [ "hex", "key-wallet", "key-wallet-manager", - "rand 0.8.6", + "rand 0.9.4", "rayon", "serde", "serde_json", @@ -1789,7 +1782,7 @@ dependencies = [ [[package]] name = "dashcore" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "anyhow", "base64-compat", @@ -1815,12 +1808,12 @@ dependencies = [ [[package]] name = "dashcore-private" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" [[package]] name = "dashcore-rpc" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "dashcore-rpc-json", "hex", @@ -1833,7 +1826,7 @@ dependencies = [ [[package]] name = "dashcore-rpc-json" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "dashcore", "grovedb-bincode", @@ -1848,7 +1841,7 @@ dependencies = [ [[package]] name = "dashcore_hashes" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "dashcore-private", "grovedb-bincode", @@ -2125,6 +2118,8 @@ dependencies = [ "dpp-json-convertible-derive", "env_logger", "getrandom 0.2.17", + "getrandom 0.3.4", + "getrandom 0.4.2", "grovedb-bincode", "grovedb-commitment-tree", "hex", @@ -2491,7 +2486,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2552,7 +2547,7 @@ checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2890,11 +2885,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", "wasip2", "wasip3", + "wasm-bindgen", ] [[package]] @@ -2921,7 +2918,7 @@ dependencies = [ [[package]] name = "git-state" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" [[package]] name = "glob" @@ -3897,7 +3894,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -4153,7 +4150,7 @@ dependencies = [ [[package]] name = "key-wallet" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "aes", "async-trait", @@ -4164,11 +4161,11 @@ dependencies = [ "dashcore", "dashcore-private", "dashcore_hashes", - "getrandom 0.2.17", + "getrandom 0.4.2", "grovedb-bincode", "grovedb-bincode-derive", "hex", - "rand 0.8.6", + "rand 0.9.4", "scrypt", "secp256k1", "serde", @@ -4182,7 +4179,7 @@ dependencies = [ [[package]] name = "key-wallet-ffi" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "cbindgen 0.29.4", "dash-network", @@ -4198,7 +4195,7 @@ dependencies = [ [[package]] name = "key-wallet-manager" version = "0.45.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=e4208c90786a6854bd498315bcb571ef24182c15#e4208c90786a6854bd498315bcb571ef24182c15" +source = "git+https://github.com/dashpay/rust-dashcore?rev=719de34bd90792efa77aa5e1065ab21ac09206ee#719de34bd90792efa77aa5e1065ab21ac09206ee" dependencies = [ "async-trait", "dashcore", @@ -4722,7 +4719,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5617,8 +5614,8 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042" dependencies = [ - "heck 0.5.0", - "itertools 0.10.5", + "heck 0.4.1", + "itertools 0.14.0", "log", "multimap", "petgraph", @@ -5639,7 +5636,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.117", @@ -5652,7 +5649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.117", @@ -5828,7 +5825,7 @@ dependencies = [ "once_cell", "socket2 0.5.10", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6644,7 +6641,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6657,7 +6654,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6716,7 +6713,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6875,21 +6872,20 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.30.0" +version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" +checksum = "d7f404a8dab7a7a5a631e741d8699aa9c8e1d689fc26ccf897c7187565490b69" dependencies = [ - "bitcoin_hashes", - "rand 0.8.6", + "rand 0.9.4", "secp256k1-sys", "serde", ] [[package]] name = "secp256k1-sys" -version = "0.10.1" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +checksum = "f6b2992d4a3cd244539a7d5d0966aadbe5ca7fb868a5d7e38c29499b9e709bbd" dependencies = [ "cc", ] @@ -7269,6 +7265,7 @@ dependencies = [ "dpp", "grovedb-bincode", "hex", + "rand 0.8.6", "tracing", "zeroize", ] @@ -7578,7 +7575,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -9024,7 +9021,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 09d41d94b47..8068ff3d235 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,14 +64,14 @@ grovedb-storage = { git = "https://github.com/dashpay/grovedb", rev = "74818ceb9 grovedb-version = { git = "https://github.com/dashpay/grovedb", rev = "74818ceb95805f56f141d24ca41f58b75c031a7f" } grovedb-epoch-based-storage-flags = { git = "https://github.com/dashpay/grovedb", rev = "74818ceb95805f56f141d24ca41f58b75c031a7f" } grovedb-commitment-tree = { git = "https://github.com/dashpay/grovedb", rev = "74818ceb95805f56f141d24ca41f58b75c031a7f" } -dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "e4208c90786a6854bd498315bcb571ef24182c15" } -dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "e4208c90786a6854bd498315bcb571ef24182c15" } -dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "e4208c90786a6854bd498315bcb571ef24182c15" } -key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "e4208c90786a6854bd498315bcb571ef24182c15" } -key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "e4208c90786a6854bd498315bcb571ef24182c15" } -key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "e4208c90786a6854bd498315bcb571ef24182c15" } -dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "e4208c90786a6854bd498315bcb571ef24182c15" } -dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "e4208c90786a6854bd498315bcb571ef24182c15" } +dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "719de34bd90792efa77aa5e1065ab21ac09206ee" } +dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "719de34bd90792efa77aa5e1065ab21ac09206ee" } +dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "719de34bd90792efa77aa5e1065ab21ac09206ee" } +key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "719de34bd90792efa77aa5e1065ab21ac09206ee" } +key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "719de34bd90792efa77aa5e1065ab21ac09206ee" } +key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "719de34bd90792efa77aa5e1065ab21ac09206ee" } +dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "719de34bd90792efa77aa5e1065ab21ac09206ee" } +dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "719de34bd90792efa77aa5e1065ab21ac09206ee" } tokio-metrics = "0.5" # Size-tuned profile for the iOS `rs-unified-sdk-ffi` staticlib, which diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index d98e26f03b6..d85c3e3fdcb 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -90,6 +90,16 @@ once_cell = "1.7" env_logger = { version = "0.11.8" } log = { version = "0.4.27" } +# secp256k1 0.33 pulls getrandom 0.3 (via rand 0.9) and key-wallet pulls +# getrandom 0.4; on wasm32-unknown-unknown both refuse to build without their +# `wasm_js` feature, so enable it here where every wasm crate picks it up. +[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] +getrandom_03 = { package = "getrandom", version = "0.3", features = ["wasm_js"] } +getrandom_04 = { package = "getrandom", version = "0.4", features = ["wasm_js"] } + +[package.metadata.cargo-machete] +ignored = ["getrandom_03", "getrandom_04"] + [features] default = ["state-transitions"] core_bincode = ["dashcore/bincode"] diff --git a/packages/rs-dpp/src/address_funds/platform_address.rs b/packages/rs-dpp/src/address_funds/platform_address.rs index 77a94d5b724..3eb72d2bbab 100644 --- a/packages/rs-dpp/src/address_funds/platform_address.rs +++ b/packages/rs-dpp/src/address_funds/platform_address.rs @@ -7,7 +7,6 @@ use bincode::{Decode, DecodeUntrusted, Encode}; use dashcore::address::Payload; use dashcore::blockdata::script::ScriptBuf; use dashcore::hashes::{sha256d, Hash}; -use dashcore::key::Secp256k1; use dashcore::secp256k1::ecdsa::RecoverableSignature; use dashcore::secp256k1::Message; use dashcore::signer::CompactSignature; @@ -243,8 +242,7 @@ impl From<&PrivateKey> for PlatformAddress { /// The address is derived as: P2PKH(Hash160(compressed_public_key)) /// where Hash160 = RIPEMD160(SHA256(x)), which is the standard Bitcoin P2PKH derivation. fn from(private_key: &PrivateKey) -> Self { - let secp = Secp256k1::new(); - let pubkey_hash = private_key.public_key(&secp).pubkey_hash(); + let pubkey_hash = private_key.public_key().pubkey_hash(); PlatformAddress::P2pkh(*pubkey_hash.as_byte_array()) } } @@ -551,7 +549,6 @@ impl PlatformAddress { let signable_bytes_hash = sha256d::Hash::hash(signable_bytes).to_byte_array(); let msg = Message::from_digest(signable_bytes_hash); - let secp = Secp256k1::new(); while sig_idx < valid_signatures.len() && pubkey_idx < pubkeys.len() { signature_verifications += 1; @@ -570,10 +567,7 @@ impl PlatformAddress { ProtocolError::AddressWitnessError(format!("Invalid public key: {}", e)) })?; - if secp - .verify_ecdsa(&msg, &sig.to_standard(), &pub_key.inner) - .is_ok() - { + if sig.to_standard().verify(msg, &pub_key.inner).is_ok() { matched += 1; sig_idx += 1; } @@ -794,7 +788,7 @@ mod tests { use super::*; use dashcore::blockdata::opcodes::all::*; use dashcore::hashes::Hash; - use dashcore::secp256k1::{PublicKey as RawPublicKey, Secp256k1, SecretKey as RawSecretKey}; + use dashcore::secp256k1::{PublicKey as RawPublicKey, SecretKey as RawSecretKey}; use dashcore::PublicKey; use platform_value::BinaryData; @@ -818,16 +812,15 @@ mod tests { /// Helper to create a keypair from a 32-byte seed fn create_keypair(seed: [u8; 32]) -> (RawSecretKey, PublicKey) { - let secp = Secp256k1::new(); - let secret_key = RawSecretKey::from_byte_array(&seed).expect("valid secret key"); - let raw_public_key = RawPublicKey::from_secret_key(&secp, &secret_key); + let secret_key = RawSecretKey::from_secret_bytes(seed).expect("valid secret key"); + let raw_public_key = RawPublicKey::from_secret_key(&secret_key); let public_key = PublicKey::new(raw_public_key); (secret_key, public_key) } /// Helper to sign data with a secret key fn sign_data(data: &[u8], secret_key: &RawSecretKey) -> Vec { - dashcore::signer::sign(data, secret_key.as_ref()) + dashcore::signer::sign(data, secret_key.as_secret_bytes()) .expect("signing should succeed") .to_vec() } diff --git a/packages/rs-dpp/src/identity/identity_public_key/key_type.rs b/packages/rs-dpp/src/identity/identity_public_key/key_type.rs index 0914d245a04..76ab962ae5e 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/key_type.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/key_type.rs @@ -7,7 +7,6 @@ use ciborium::value::Value as CborValue; use dashcore::secp256k1::rand::rngs::StdRng as EcdsaRng; #[cfg(feature = "random-public-keys")] use dashcore::secp256k1::rand::SeedableRng; -use dashcore::secp256k1::Secp256k1; use dashcore::Network; use itertools::Itertools; use lazy_static::lazy_static; @@ -161,11 +160,12 @@ impl KeyType { fn random_public_key_data_v0(&self, rng: &mut StdRng) -> Vec { match self { KeyType::ECDSA_SECP256K1 => { - let secp = Secp256k1::new(); - let mut rng = EcdsaRng::from_rng(rng).unwrap(); + let mut seed = [0u8; 32]; + rng.fill(&mut seed); + let mut rng = EcdsaRng::from_seed(seed); let secret_key = dashcore::secp256k1::SecretKey::new(&mut rng); let private_key = dashcore::PrivateKey::new(secret_key, Network::Mainnet); - private_key.public_key(&secp).to_bytes() + private_key.public_key().to_bytes() } KeyType::BLS12_381 => { let private_key = bls_signatures::SecretKey::::random(rng); @@ -207,12 +207,12 @@ impl KeyType { ) -> Result, ProtocolError> { match self { KeyType::ECDSA_SECP256K1 => { - let secp = Secp256k1::new(); - let secret_key = dashcore::secp256k1::SecretKey::from_byte_array(private_key_bytes) - .map_err(|e| ProtocolError::Generic(e.to_string()))?; + let secret_key = + dashcore::secp256k1::SecretKey::from_secret_bytes(*private_key_bytes) + .map_err(|e| ProtocolError::Generic(e.to_string()))?; let private_key = dashcore::PrivateKey::new(secret_key, network); - Ok(private_key.public_key(&secp).to_bytes()) + Ok(private_key.public_key().to_bytes()) } KeyType::BLS12_381 => { #[cfg(feature = "bls-signatures")] @@ -237,12 +237,12 @@ impl KeyType { )); } KeyType::ECDSA_HASH160 => { - let secp = Secp256k1::new(); - let secret_key = dashcore::secp256k1::SecretKey::from_byte_array(private_key_bytes) - .map_err(|e| ProtocolError::Generic(e.to_string()))?; + let secret_key = + dashcore::secp256k1::SecretKey::from_secret_bytes(*private_key_bytes) + .map_err(|e| ProtocolError::Generic(e.to_string()))?; let private_key = dashcore::PrivateKey::new(secret_key, network); - Ok(ripemd160_sha256(private_key.public_key(&secp).to_bytes().as_slice()).to_vec()) + Ok(ripemd160_sha256(private_key.public_key().to_bytes().as_slice()).to_vec()) } KeyType::EDDSA_25519_HASH160 => { #[cfg(feature = "ed25519-dalek")] @@ -267,13 +267,14 @@ impl KeyType { pub fn random_public_and_private_key_data_v0(&self, rng: &mut StdRng) -> (Vec, [u8; 32]) { match self { KeyType::ECDSA_SECP256K1 => { - let secp = Secp256k1::new(); - let mut rng = EcdsaRng::from_rng(rng).unwrap(); + let mut seed = [0u8; 32]; + rng.fill(&mut seed); + let mut rng = EcdsaRng::from_seed(seed); let secret_key = dashcore::secp256k1::SecretKey::new(&mut rng); let private_key = dashcore::PrivateKey::new(secret_key, Network::Mainnet); ( - private_key.public_key(&secp).to_bytes(), - private_key.inner.secret_bytes(), + private_key.public_key().to_bytes(), + private_key.inner.to_secret_bytes(), ) } KeyType::BLS12_381 => { @@ -282,13 +283,14 @@ impl KeyType { (public_key_bytes, private_key.0.to_be_bytes()) } KeyType::ECDSA_HASH160 => { - let secp = Secp256k1::new(); - let mut rng = EcdsaRng::from_rng(rng).unwrap(); + let mut seed = [0u8; 32]; + rng.fill(&mut seed); + let mut rng = EcdsaRng::from_seed(seed); let secret_key = dashcore::secp256k1::SecretKey::new(&mut rng); let private_key = dashcore::PrivateKey::new(secret_key, Network::Mainnet); ( - ripemd160_sha256(private_key.public_key(&secp).to_bytes().as_slice()).to_vec(), - private_key.inner.secret_bytes(), + ripemd160_sha256(private_key.public_key().to_bytes().as_slice()).to_vec(), + private_key.inner.to_secret_bytes(), ) } KeyType::EDDSA_25519_HASH160 => { @@ -300,13 +302,14 @@ impl KeyType { } KeyType::BIP13_SCRIPT_HASH => { //todo (using ECDSA_HASH160 for now) - let secp = Secp256k1::new(); - let mut rng = EcdsaRng::from_rng(rng).unwrap(); + let mut seed = [0u8; 32]; + rng.fill(&mut seed); + let mut rng = EcdsaRng::from_seed(seed); let secret_key = dashcore::secp256k1::SecretKey::new(&mut rng); let private_key = dashcore::PrivateKey::new(secret_key, Network::Mainnet); ( - ripemd160_sha256(private_key.public_key(&secp).to_bytes().as_slice()).to_vec(), - private_key.inner.secret_bytes(), + ripemd160_sha256(private_key.public_key().to_bytes().as_slice()).to_vec(), + private_key.inner.to_secret_bytes(), ) } } diff --git a/packages/rs-dpp/src/identity/identity_public_key/v0/methods/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/v0/methods/mod.rs index f1faa9d14e3..78613737f52 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/v0/methods/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/v0/methods/mod.rs @@ -7,7 +7,6 @@ use anyhow::anyhow; #[cfg(feature = "ed25519-dalek")] use dashcore::ed25519_dalek; use dashcore::hashes::Hash; -use dashcore::key::Secp256k1; use dashcore::secp256k1::SecretKey; use dashcore::{Network, PublicKey as ECDSAPublicKey}; use platform_value::{BinaryData, Bytes20}; @@ -83,14 +82,13 @@ pub(in crate::identity::identity_public_key) fn validate_private_key_bytes_for_k ) -> Result { match key_type { KeyType::ECDSA_SECP256K1 => { - let secp = Secp256k1::new(); - let secret_key = match SecretKey::from_byte_array(private_key_bytes) { + let secret_key = match SecretKey::from_secret_bytes(*private_key_bytes) { Ok(secret_key) => secret_key, Err(_) => return Ok(false), }; let private_key = dashcore::PrivateKey::new(secret_key, network); - Ok(private_key.public_key(&secp).to_bytes() == data.as_slice()) + Ok(private_key.public_key().to_bytes() == data.as_slice()) } KeyType::BLS12_381 => { #[cfg(feature = "bls-signatures")] @@ -111,15 +109,14 @@ pub(in crate::identity::identity_public_key) fn validate_private_key_bytes_for_k )); } KeyType::ECDSA_HASH160 => { - let secp = Secp256k1::new(); - let secret_key = match SecretKey::from_byte_array(private_key_bytes) { + let secret_key = match SecretKey::from_secret_bytes(*private_key_bytes) { Ok(secret_key) => secret_key, Err(_) => return Ok(false), }; let private_key = dashcore::PrivateKey::new(secret_key, network); Ok( - ripemd160_sha256(private_key.public_key(&secp).to_bytes().as_slice()).as_slice() + ripemd160_sha256(private_key.public_key().to_bytes().as_slice()).as_slice() == data.as_slice(), ) } diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/validate_asset_lock_transaction_structure/v0/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/validate_asset_lock_transaction_structure/v0/mod.rs index fe354a865a2..8b2c1560226 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/validate_asset_lock_transaction_structure/v0/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/validate_asset_lock_transaction_structure/v0/mod.rs @@ -58,24 +58,22 @@ pub(super) fn validate_asset_lock_transaction_structure_v0( #[cfg(test)] mod tests { use super::*; - use dashcore::secp256k1::rand::thread_rng; - use dashcore::secp256k1::Secp256k1; + use dashcore::secp256k1::rand::rng; use dashcore::transaction::special_transaction::asset_lock::AssetLockPayload; use dashcore::{Network, OutPoint, PrivateKey, ScriptBuf, TxIn, Txid}; use std::str::FromStr; fn make_asset_lock_transaction(num_inputs: usize) -> Transaction { - let secp = Secp256k1::new(); - let mut rng = thread_rng(); + let mut rng = rng(); let input_secret_key = dashcore::secp256k1::SecretKey::new(&mut rng); let private_key = PrivateKey::new(input_secret_key, Network::Testnet); - let public_key = private_key.public_key(&secp); + let public_key = private_key.public_key(); let public_key_hash = public_key.pubkey_hash(); let secret_key = dashcore::secp256k1::SecretKey::new(&mut rng); let one_time_private_key = PrivateKey::new(secret_key, Network::Testnet); - let one_time_public_key = one_time_private_key.public_key(&secp); + let one_time_public_key = one_time_private_key.public_key(); let one_time_key_hash = one_time_public_key.pubkey_hash(); let base_txid = diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index af8612a1f0d..576c06230e4 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -2040,7 +2040,7 @@ impl StateTransition { signer: &S, ) -> Result<(), ProtocolError> { use dashcore::secp256k1::ecdsa::{RecoverableSignature, RecoveryId}; - use dashcore::secp256k1::{Message, Secp256k1}; + use dashcore::secp256k1::Message; use dashcore::signer::{double_sha, CompactSignature}; let data = self.signable_bytes()?; @@ -2065,7 +2065,6 @@ impl StateTransition { // `r||s` payload is bit-identical to what `dashcore::signer::sign` // produces. let compact_64 = signature.serialize_compact(); - let secp = Secp256k1::new(); let msg = Message::from_digest(digest); let mut found: Option = None; @@ -2078,7 +2077,7 @@ impl StateTransition { Ok(s) => s, Err(_) => continue, }; - if let Ok(recovered) = secp.recover_ecdsa(&msg, &candidate) { + if let Ok(recovered) = candidate.recover_ecdsa(msg) { if recovered == public_key { found = Some(candidate); break; @@ -4346,9 +4345,7 @@ mod tests { #[tokio::test] async fn sign_with_core_signer_matches_sign_by_private_key_byte_for_byte() { use async_trait::async_trait; - use dashcore::secp256k1::{ - ecdsa, rand::rngs::OsRng, Message, PublicKey, Secp256k1, SecretKey, - }; + use dashcore::secp256k1::{self, ecdsa, rand, Message, PublicKey, SecretKey}; use key_wallet::bip32::{DerivationPath, ExtendedPubKey}; use key_wallet::signer::{ExtendedPubKeySigner, Signer as KwSigner, SignerMethod}; @@ -4375,9 +4372,8 @@ mod tests { _path: &DerivationPath, sighash: [u8; 32], ) -> Result<(ecdsa::Signature, PublicKey), Self::Error> { - let secp = Secp256k1::new(); let msg = Message::from_digest(sighash); - let sig = secp.sign_ecdsa(&msg, &self.secret); + let sig = self.secret.sign_ecdsa(msg); Ok((sig, self.public)) } @@ -4400,9 +4396,8 @@ mod tests { // load-bearing: the legacy path signs raw bytes, the signer path // derives + signs inside the trust boundary. If the digest pre-image // or compact-encoding differs, the bytes will diverge. - let secp = Secp256k1::new(); - let (secret_key, public_key) = secp.generate_keypair(&mut OsRng); - let private_key_bytes = secret_key.secret_bytes(); + let (secret_key, public_key) = secp256k1::generate_keypair(&mut rand::rng()); + let private_key_bytes = secret_key.to_secret_bytes(); let signer = FixedKeySigner { secret: secret_key, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/signing_tests.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/signing_tests.rs index 8719b18ea90..fa7c6f13398 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/signing_tests.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/signing_tests.rs @@ -14,7 +14,7 @@ use std::collections::{BTreeMap, HashMap}; use dashcore::hashes::Hash; -use dashcore::secp256k1::{PublicKey as RawPublicKey, Secp256k1, SecretKey as RawSecretKey}; +use dashcore::secp256k1::{PublicKey as RawPublicKey, SecretKey as RawSecretKey}; use dashcore::{OutPoint, PublicKey}; use platform_value::BinaryData; use platform_version::version::PlatformVersion; @@ -38,9 +38,8 @@ struct TestAddressSigner { impl TestAddressSigner { fn add_p2pkh(&mut self, seed: [u8; 32]) -> PlatformAddress { - let secp = Secp256k1::new(); - let secret = RawSecretKey::from_byte_array(&seed).expect("valid secret key"); - let public = PublicKey::new(RawPublicKey::from_secret_key(&secp, &secret)); + let secret = RawSecretKey::from_secret_bytes(seed).expect("valid secret key"); + let public = PublicKey::new(RawPublicKey::from_secret_key(&secret)); let hash = *public.pubkey_hash().as_byte_array(); self.keys.insert(hash, (secret, public)); PlatformAddress::P2pkh(hash) @@ -59,7 +58,7 @@ impl Signer for TestAddressSigner { .keys .get(hash) .ok_or_else(|| ProtocolError::Generic(format!("unknown key {}", hex::encode(hash))))?; - let sig = dashcore::signer::sign(data, secret.as_ref()) + let sig = dashcore::signer::sign(data, secret.as_secret_bytes()) .map_err(|e| ProtocolError::Generic(e.to_string()))?; Ok(BinaryData::new(sig.to_vec())) } @@ -229,9 +228,8 @@ async fn try_from_asset_lock_with_signers_produces_matching_signature() { _path: &DerivationPath, sighash: [u8; 32], ) -> Result<(ecdsa::Signature, RawPublicKey), Self::Error> { - let secp = Secp256k1::new(); let msg = Message::from_digest(sighash); - Ok((secp.sign_ecdsa(&msg, &self.secret), self.public)) + Ok((self.secret.sign_ecdsa(msg), self.public)) } async fn public_key(&self, _path: &DerivationPath) -> Result { @@ -249,9 +247,8 @@ async fn try_from_asset_lock_with_signers_produces_matching_signature() { } } - let secp = Secp256k1::new(); - let asset_lock_secret = RawSecretKey::from_byte_array(&[7u8; 32]).expect("valid secret"); - let asset_lock_public = RawPublicKey::from_secret_key(&secp, &asset_lock_secret); + let asset_lock_secret = RawSecretKey::from_secret_bytes([7u8; 32]).expect("valid secret"); + let asset_lock_public = RawPublicKey::from_secret_key(&asset_lock_secret); let mut input_signer = TestAddressSigner::default(); let input_addr = input_signer.add_p2pkh([1u8; 32]); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/signing_tests.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/signing_tests.rs index 866e39f123c..6ac8d35825d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/signing_tests.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/signing_tests.rs @@ -13,7 +13,7 @@ use std::collections::{BTreeMap, HashMap}; use dashcore::blockdata::opcodes::all::*; use dashcore::blockdata::script::ScriptBuf; use dashcore::hashes::Hash; -use dashcore::secp256k1::{PublicKey as RawPublicKey, Secp256k1, SecretKey as RawSecretKey}; +use dashcore::secp256k1::{PublicKey as RawPublicKey, SecretKey as RawSecretKey}; use dashcore::PublicKey; use platform_value::BinaryData; @@ -64,16 +64,15 @@ impl TestAddressSigner { /// Creates a keypair from a 32-byte seed fn create_keypair(seed: [u8; 32]) -> (RawSecretKey, PublicKey) { - let secp = Secp256k1::new(); - let secret_key = RawSecretKey::from_byte_array(&seed).expect("valid secret key"); - let raw_public_key = RawPublicKey::from_secret_key(&secp, &secret_key); + let secret_key = RawSecretKey::from_secret_bytes(seed).expect("valid secret key"); + let raw_public_key = RawPublicKey::from_secret_key(&secret_key); let public_key = PublicKey::new(raw_public_key); (secret_key, public_key) } /// Signs data with a secret key fn sign_data(data: &[u8], secret_key: &RawSecretKey) -> Vec { - dashcore::signer::sign(data, secret_key.as_ref()) + dashcore::signer::sign(data, secret_key.as_secret_bytes()) .expect("signing should succeed") .to_vec() } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/signing_tests.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/signing_tests.rs index 719074e382e..37c590d971b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/signing_tests.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/signing_tests.rs @@ -32,7 +32,7 @@ use dashcore::OutPoint; use platform_version::version::PlatformVersion; use async_trait::async_trait; -use dashcore::secp256k1::{ecdsa, Message, PublicKey, Secp256k1, SecretKey}; +use dashcore::secp256k1::{ecdsa, Message, PublicKey, SecretKey}; use key_wallet::bip32::{DerivationPath, ExtendedPubKey}; use key_wallet::signer::{ExtendedPubKeySigner, Signer as KwSigner, SignerMethod}; @@ -49,9 +49,8 @@ struct FixedKeySigner { impl FixedKeySigner { fn new(seed: [u8; 32]) -> Self { - let secp = Secp256k1::new(); - let secret = SecretKey::from_byte_array(&seed).expect("valid secret"); - let public = PublicKey::from_secret_key(&secp, &secret); + let secret = SecretKey::from_secret_bytes(seed).expect("valid secret"); + let public = PublicKey::from_secret_key(&secret); Self { secret, public } } } @@ -69,9 +68,8 @@ impl KwSigner for FixedKeySigner { _path: &DerivationPath, sighash: [u8; 32], ) -> Result<(ecdsa::Signature, PublicKey), Self::Error> { - let secp = Secp256k1::new(); let msg = Message::from_digest(sighash); - Ok((secp.sign_ecdsa(&msg, &self.secret), self.public)) + Ok((self.secret.sign_ecdsa(msg), self.public)) } async fn public_key(&self, _path: &DerivationPath) -> Result { diff --git a/packages/rs-dpp/src/state_transition/traits/state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/traits/state_transition_identity_signed.rs index f005be86412..ff38671e537 100644 --- a/packages/rs-dpp/src/state_transition/traits/state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/traits/state_transition_identity_signed.rs @@ -106,11 +106,12 @@ pub trait StateTransitionIdentitySigned: StateTransitionLike { } pub fn get_compressed_public_ec_key(private_key: &[u8]) -> Result<[u8; 33], ProtocolError> { - let sk = RawSecretKey::from_slice(private_key) + let sk = <[u8; 32]>::try_from(private_key) + .map_err(|_| dashcore::secp256k1::Error::InvalidSecretKey) + .and_then(RawSecretKey::from_secret_bytes) .map_err(|e| anyhow!("Invalid ECDSA private key: {}", e))?; - let secp = dashcore::secp256k1::Secp256k1::new(); - let public_key_compressed = RawPublicKey::from_secret_key(&secp, &sk).serialize(); + let public_key_compressed = RawPublicKey::from_secret_key(&sk).serialize(); Ok(public_key_compressed) } diff --git a/packages/rs-dpp/src/tests/fixtures/instant_asset_lock_proof_fixture.rs b/packages/rs-dpp/src/tests/fixtures/instant_asset_lock_proof_fixture.rs index f55590029df..23e620c6f81 100644 --- a/packages/rs-dpp/src/tests/fixtures/instant_asset_lock_proof_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/instant_asset_lock_proof_fixture.rs @@ -4,8 +4,7 @@ use dashcore::bls_sig_utils::BLSSignature; use dashcore::hash_types::CycleHash; use crate::balances::credits::Duffs; -use dashcore::secp256k1::rand::thread_rng; -use dashcore::secp256k1::Secp256k1; +use dashcore::secp256k1::rand::rng; use dashcore::transaction::special_transaction::asset_lock::AssetLockPayload; use dashcore::transaction::special_transaction::TransactionPayload; use dashcore::{ @@ -46,18 +45,17 @@ pub fn instant_asset_lock_proof_transaction_fixture( one_time_private_key: Option, amount: Option, ) -> Transaction { - let mut rng = thread_rng(); - let secp = Secp256k1::new(); + let mut rng = rng(); let private_key_hex = "cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY"; let private_key = PrivateKey::from_str(private_key_hex).unwrap(); - let public_key = private_key.public_key(&secp); + let public_key = private_key.public_key(); let public_key_hash = public_key.pubkey_hash(); //let from_address = Address::p2pkh(&public_key, Network::Testnet); let secret_key = SecretKey::new(&mut rng); let one_time_private_key = one_time_private_key.unwrap_or_else(|| PrivateKey::new(secret_key, Network::Testnet)); - let one_time_public_key = one_time_private_key.public_key(&secp); + let one_time_public_key = one_time_private_key.public_key(); // We are going to fund 1 Dash and // assume that input has 100005000 diff --git a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs index da4dbce479c..181a4e2f5b5 100644 --- a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs @@ -257,7 +257,6 @@ mod tests { use simple_signer::signer::SimpleSigner; use dpp::consensus::ConsensusError; - use dpp::dashcore::secp256k1::Secp256k1; use dpp::dashcore::{key::Keypair, signer, Network, PrivateKey}; use dpp::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; @@ -300,6 +299,8 @@ mod tests { use assert_matches::assert_matches; use dpp::consensus::state::state_error::StateError; use dpp::dash_to_credits; + use dpp::dashcore::secp256k1::rand::rngs::StdRng as SecpStdRng; + use dpp::dashcore::secp256k1::rand::SeedableRng as _; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Setters; use dpp::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use dpp::data_contract::change_control_rules::v0::ChangeControlRulesV0; @@ -3868,15 +3869,13 @@ mod tests { .build_with_mock_rpc() .set_genesis_state(); - let mut rng = StdRng::seed_from_u64(433); + let mut rng = SecpStdRng::seed_from_u64(433); let platform_state = platform.state.load(); let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); - let secp = Secp256k1::new(); - - let new_key_pair = Keypair::new(&secp, &mut rng); + let new_key_pair = Keypair::new(&mut rng); let mut new_key = IdentityPublicKeyInCreationV0 { id: 2, @@ -3894,7 +3893,7 @@ mod tests { .expect("expected to get signable bytes"); let secret = new_key_pair.secret_key(); let signature = - signer::sign(&signable_bytes, &secret.secret_bytes()).expect("expected to sign"); + signer::sign(&signable_bytes, &secret.to_secret_bytes()).expect("expected to sign"); new_key.signature = signature.to_vec().into(); @@ -3972,13 +3971,11 @@ mod tests { let (identity, signer, _, key) = setup_identity_return_master_key(&mut platform, 958, dash_to_credits!(0.1)); - let mut rng = StdRng::seed_from_u64(1); - - let secp = Secp256k1::new(); + let mut rng = SecpStdRng::seed_from_u64(1); let platform_state = platform.state.load(); - let new_key_pair = Keypair::new(&secp, &mut rng); + let new_key_pair = Keypair::new(&mut rng); let new_key = IdentityPublicKeyInCreationV0 { id: 2, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funding_from_asset_lock/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funding_from_asset_lock/tests.rs index 7a002a2c7e8..53664f399df 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funding_from_asset_lock/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funding_from_asset_lock/tests.rs @@ -21,7 +21,6 @@ mod tests { use dpp::consensus::ConsensusError; use dpp::dash_to_credits; use dpp::dashcore::blockdata::script::ScriptBuf; - use dpp::dashcore::secp256k1::Secp256k1; use dpp::dashcore::transaction::special_transaction::asset_lock::AssetLockPayload; use dpp::dashcore::transaction::special_transaction::TransactionPayload; use dpp::dashcore::{BlockHash, Network, OutPoint, PrivateKey, Transaction, TxIn, TxOut, Txid}; @@ -137,7 +136,6 @@ mod tests { use dpp::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; let platform_version = PlatformVersion::latest(); - let secp = Secp256k1::new(); // Generate the one-time key that will receive the asset lock funds let (_, pk) = ECDSA_SECP256K1 @@ -145,7 +143,7 @@ mod tests { .unwrap(); let one_time_private_key = PrivateKey::from_byte_array(&pk, Network::Testnet).unwrap(); - let one_time_public_key = one_time_private_key.public_key(&secp); + let one_time_public_key = one_time_private_key.public_key(); let one_time_key_hash = one_time_public_key.pubkey_hash(); // Create a fake input (doesn't need to be real for our tests) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs index f20e9b5abf9..62b086cb01c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs @@ -9,7 +9,6 @@ mod token_selling_tests { use super::*; use dpp::{ - dashcore::secp256k1::hashes::hex::{Case, DisplayHex}, prelude::{DataContract, Identity, IdentityPublicKey}, tokens::token_pricing_schedule::TokenPricingSchedule, }; @@ -635,7 +634,7 @@ mod token_selling_tests { expected_price, format!( "price in proof mismatch for token {}", - token_id.to_hex_string(Case::Lower) + hex::encode(token_id) ) .as_str(), ); @@ -645,11 +644,7 @@ mod token_selling_tests { fetched_prices.clone(), token_id, expected_price, - format!( - "fetched price mismatch for token {}", - token_id.to_hex_string(Case::Lower) - ) - .as_str(), + format!("fetched price mismatch for token {}", hex::encode(token_id)).as_str(), ); } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create_from_addresses/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create_from_addresses/tests.rs index f07845366b1..2404f2032a5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create_from_addresses/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create_from_addresses/tests.rs @@ -5,7 +5,6 @@ mod tests { use crate::execution::validation::state_transition::state_transitions::test_helpers::{ create_dummy_witness, create_platform_address, setup_address_with_balance, TestAddressSigner, TestHash as Hash, TestPublicKey as PublicKey, - TestSecp256k1 as Secp256k1, }; use crate::platform_types::state_transitions_processing_result::StateTransitionExecutionResult; use crate::test::helpers::setup::TestPlatformBuilder; @@ -9377,7 +9376,7 @@ mod tests { mod actual_signature_verification { use super::*; use dpp::dashcore::hashes::Hash; - use dpp::dashcore::secp256k1::{PublicKey as RawSecp256k1PublicKey, Secp256k1}; + use dpp::dashcore::secp256k1::PublicKey as RawSecp256k1PublicKey; use dpp::serialization::Signable; /// Helper to create a properly signed P2PKH witness @@ -9386,15 +9385,15 @@ mod tests { secret_key: &dpp::dashcore::secp256k1::SecretKey, signable_bytes: &[u8], ) -> (PlatformAddress, AddressWitness) { - let secp = Secp256k1::new(); - let raw_pubkey = RawSecp256k1PublicKey::from_secret_key(&secp, secret_key); + let raw_pubkey = RawSecp256k1PublicKey::from_secret_key(secret_key); let pubkey = PublicKey::new(raw_pubkey); let pubkey_hash = dpp::dashcore::hashes::hash160::Hash::hash(&pubkey.to_bytes()); let address = PlatformAddress::P2pkh(pubkey_hash.to_byte_array()); // Sign using dashcore::signer which creates a recoverable signature - let signature = dpp::dashcore::signer::sign(signable_bytes, secret_key.as_ref()) - .expect("signing should succeed"); + let signature = + dpp::dashcore::signer::sign(signable_bytes, secret_key.as_secret_bytes()) + .expect("signing should succeed"); let witness = AddressWitness::P2pkh { signature: BinaryData::new(signature.to_vec()), @@ -9411,15 +9410,14 @@ mod tests { let public_keys = create_default_public_keys(&mut rng, platform_version); // Create a real secret key - let secret_key = dpp::dashcore::secp256k1::SecretKey::from_slice(&[ + let secret_key = dpp::dashcore::secp256k1::SecretKey::from_secret_bytes([ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, ]) .expect("valid secret key"); - let secp = Secp256k1::new(); - let raw_pubkey = RawSecp256k1PublicKey::from_secret_key(&secp, &secret_key); + let raw_pubkey = RawSecp256k1PublicKey::from_secret_key(&secret_key); let pubkey = PublicKey::new(raw_pubkey); let pubkey_hash = dpp::dashcore::hashes::hash160::Hash::hash(&pubkey.to_bytes()); let address = PlatformAddress::P2pkh(pubkey_hash.to_byte_array()); @@ -9447,8 +9445,9 @@ mod tests { .expect("should get signable bytes"); // Now create the signature using recoverable signing - let signature = dpp::dashcore::signer::sign(&signable_bytes, secret_key.as_ref()) - .expect("signing should succeed"); + let signature = + dpp::dashcore::signer::sign(&signable_bytes, secret_key.as_secret_bytes()) + .expect("signing should succeed"); // Create the signed transition let signed_transition = IdentityCreateFromAddressesTransition::V0( @@ -9487,17 +9486,16 @@ mod tests { let public_keys = create_default_public_keys(&mut rng, platform_version); // Create address from one key - let correct_secret = dpp::dashcore::secp256k1::SecretKey::from_slice(&[1u8; 32]) + let correct_secret = dpp::dashcore::secp256k1::SecretKey::from_secret_bytes([1u8; 32]) .expect("valid secret key"); - let secp = Secp256k1::new(); - let raw_correct_pubkey = RawSecp256k1PublicKey::from_secret_key(&secp, &correct_secret); + let raw_correct_pubkey = RawSecp256k1PublicKey::from_secret_key(&correct_secret); let correct_pubkey = PublicKey::new(raw_correct_pubkey); let pubkey_hash = dpp::dashcore::hashes::hash160::Hash::hash(&correct_pubkey.to_bytes()); let address = PlatformAddress::P2pkh(pubkey_hash.to_byte_array()); // But sign with different key - let wrong_secret = dpp::dashcore::secp256k1::SecretKey::from_slice(&[2u8; 32]) + let wrong_secret = dpp::dashcore::secp256k1::SecretKey::from_secret_bytes([2u8; 32]) .expect("valid secret key"); let mut inputs = BTreeMap::new(); @@ -9525,7 +9523,7 @@ mod tests { // Sign with WRONG key - this will produce a signature that when recovered // will give a different public key than expected let wrong_signature = - dpp::dashcore::signer::sign(&signable_bytes, wrong_secret.as_ref()) + dpp::dashcore::signer::sign(&signable_bytes, wrong_secret.as_secret_bytes()) .expect("signing should succeed"); // Create transition with mismatched signature (signed by wrong key) @@ -9553,21 +9551,21 @@ mod tests { let mut rng = StdRng::seed_from_u64(6002); let public_keys = create_default_public_keys(&mut rng, platform_version); - let secp = Secp256k1::new(); // Create multiple addresses with their secret keys let secrets: Vec<_> = (1..=3) .map(|i| { let mut key_bytes = [0u8; 32]; key_bytes[0] = i; - dpp::dashcore::secp256k1::SecretKey::from_slice(&key_bytes).expect("valid") + dpp::dashcore::secp256k1::SecretKey::from_secret_bytes(key_bytes) + .expect("valid") }) .collect(); let addresses: Vec<_> = secrets .iter() .map(|secret| { - let raw_pubkey = RawSecp256k1PublicKey::from_secret_key(&secp, secret); + let raw_pubkey = RawSecp256k1PublicKey::from_secret_key(secret); let pubkey = PublicKey::new(raw_pubkey); let pubkey_hash = dpp::dashcore::hashes::hash160::Hash::hash(&pubkey.to_bytes()); @@ -9611,8 +9609,9 @@ mod tests { .position(|a| a == addr) .expect("should find"); let secret = &secrets[idx]; - let signature = dpp::dashcore::signer::sign(&signable_bytes, secret.as_ref()) - .expect("signing should succeed"); + let signature = + dpp::dashcore::signer::sign(&signable_bytes, secret.as_secret_bytes()) + .expect("signing should succeed"); witnesses.push(AddressWitness::P2pkh { signature: BinaryData::new(signature.to_vec()), @@ -9641,21 +9640,21 @@ mod tests { let mut rng = StdRng::seed_from_u64(6003); let public_keys = create_default_public_keys(&mut rng, platform_version); - let secp = Secp256k1::new(); // Create 3 keys for 2-of-3 multisig let secrets: Vec<_> = (1..=3) .map(|i| { let mut key_bytes = [0u8; 32]; key_bytes[0] = i + 10; - dpp::dashcore::secp256k1::SecretKey::from_slice(&key_bytes).expect("valid") + dpp::dashcore::secp256k1::SecretKey::from_secret_bytes(key_bytes) + .expect("valid") }) .collect(); let pubkeys: Vec<[u8; 33]> = secrets .iter() .map(|secret| { - let raw_pubkey = RawSecp256k1PublicKey::from_secret_key(&secp, secret); + let raw_pubkey = RawSecp256k1PublicKey::from_secret_key(secret); raw_pubkey.serialize() }) .collect(); @@ -9700,9 +9699,9 @@ mod tests { .expect("should get signable bytes"); // Sign with first 2 keys (2-of-3) using DER signatures for P2SH - let sig1 = dpp::dashcore::signer::sign(&signable_bytes, secrets[0].as_ref()) + let sig1 = dpp::dashcore::signer::sign(&signable_bytes, secrets[0].as_secret_bytes()) .expect("signing should succeed"); - let sig2 = dpp::dashcore::signer::sign(&signable_bytes, secrets[1].as_ref()) + let sig2 = dpp::dashcore::signer::sign(&signable_bytes, secrets[1].as_secret_bytes()) .expect("signing should succeed"); let _signed_transition = IdentityCreateFromAddressesTransition::V0( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs index 96fddc39cd7..25d5ca0b898 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs @@ -139,7 +139,9 @@ mod tests { use dpp::consensus::codes::ErrorWithCode; use dpp::consensus::ConsensusError; use dpp::dash_to_credits; - use dpp::dashcore::key::{Keypair, Secp256k1}; + use dpp::dashcore::key::Keypair; + use dpp::dashcore::secp256k1::rand::rngs::StdRng as SecpStdRng; + use dpp::dashcore::secp256k1::rand::SeedableRng as _; use dpp::dashcore::signer; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::identifier::Identifier; @@ -257,11 +259,9 @@ mod tests { let platform_state = platform.state.load(); - let secp = Secp256k1::new(); + let mut rng = SecpStdRng::seed_from_u64(292); - let mut rng = StdRng::seed_from_u64(292); - - let new_key_pair = Keypair::new(&secp, &mut rng); + let new_key_pair = Keypair::new(&mut rng); let mut new_key = IdentityPublicKeyInCreationV0 { id: 2, @@ -294,7 +294,7 @@ mod tests { let secret = new_key_pair.secret_key(); let signature = - signer::sign(&signable_bytes, &secret.secret_bytes()).expect("expected to sign"); + signer::sign(&signable_bytes, &secret.to_secret_bytes()).expect("expected to sign"); new_key.signature = signature.to_vec().into(); @@ -540,9 +540,8 @@ mod tests { document_type_name: "profile".into(), }; let platform_state = platform.state.load(); - let secp = Secp256k1::new(); - let mut rng = StdRng::seed_from_u64(292); - let new_key_pair = Keypair::new(&secp, &mut rng); + let mut rng = SecpStdRng::seed_from_u64(292); + let new_key_pair = Keypair::new(&mut rng); let mut new_key = IdentityPublicKeyInCreationV0 { id: 2, purpose: Purpose::AUTHENTICATION, @@ -567,11 +566,13 @@ mod tests { .into() }; let signable_bytes = build(new_key.clone()).signable_bytes().unwrap(); - new_key.signature = - signer::sign(&signable_bytes, &new_key_pair.secret_key().secret_bytes()) - .unwrap() - .to_vec() - .into(); + new_key.signature = signer::sign( + &signable_bytes, + &new_key_pair.secret_key().to_secret_bytes(), + ) + .unwrap() + .to_vec() + .into(); let mut update_transition = build(new_key); update_transition .set_signature(signer.sign(&key, signable_bytes.as_slice()).await.unwrap()); @@ -749,9 +750,8 @@ mod tests { id: contract_group_id, }; let platform_state = platform.state.load(); - let secp = Secp256k1::new(); - let mut rng = StdRng::seed_from_u64(293); - let new_key_pair = Keypair::new(&secp, &mut rng); + let mut rng = SecpStdRng::seed_from_u64(293); + let new_key_pair = Keypair::new(&mut rng); let build = |revision: u64, nonce: u64, add: Vec, disable| { StateTransition::from(IdentityUpdateTransition::from(IdentityUpdateTransitionV0 { @@ -783,11 +783,13 @@ mod tests { let signable_bytes = build(revision, nonce, vec![new_key.clone()], vec![]) .signable_bytes() .unwrap(); - new_key.signature = - signer::sign(&signable_bytes, &new_key_pair.secret_key().secret_bytes()) - .unwrap() - .to_vec() - .into(); + new_key.signature = signer::sign( + &signable_bytes, + &new_key_pair.secret_key().to_secret_bytes(), + ) + .unwrap() + .to_vec() + .into(); let mut update = build(revision, nonce, vec![new_key], vec![]); update.set_signature(signer.sign(&key, signable_bytes.as_slice()).await.unwrap()); signed_updates.push(update); @@ -1107,11 +1109,10 @@ mod tests { .load_dashpay(version) .unwrap(); let bounds = ContractBounds::SingleContract { id: dashpay.id() }; - let secp = Secp256k1::new(); - let mut rng = StdRng::seed_from_u64(292); + let mut rng = SecpStdRng::seed_from_u64(292); let pairs: BTreeMap = [2u32, 3, 4] .into_iter() - .map(|id| (id, Keypair::new(&secp, &mut rng))) + .map(|id| (id, Keypair::new(&mut rng))) .collect(); let bound_key = |id: u32| IdentityPublicKeyInCreationV0 { id, @@ -1226,7 +1227,7 @@ mod tests { let mut adds = vec![bound_key(3), bound_key(2)]; let signable = unsigned(1, adds.clone(), vec![]).signable_bytes().unwrap(); for key in &mut adds { - key.signature = signer::sign(&signable, &pairs[&key.id].secret_key().secret_bytes()) + key.signature = signer::sign(&signable, &pairs[&key.id].secret_key().to_secret_bytes()) .unwrap() .to_vec() .into(); @@ -1241,7 +1242,7 @@ mod tests { let mut adds = vec![bound_key(4)]; let signable = unsigned(2, adds.clone(), vec![3]).signable_bytes().unwrap(); for key in &mut adds { - key.signature = signer::sign(&signable, &pairs[&key.id].secret_key().secret_bytes()) + key.signature = signer::sign(&signable, &pairs[&key.id].secret_key().to_secret_bytes()) .unwrap() .to_vec() .into(); @@ -1673,11 +1674,9 @@ mod tests { let platform_state = platform.state.load(); - let secp = Secp256k1::new(); + let mut rng = SecpStdRng::seed_from_u64(1292); - let mut rng = StdRng::seed_from_u64(1292); - - let new_key_pair = Keypair::new(&secp, &mut rng); + let new_key_pair = Keypair::new(&mut rng); let new_key = IdentityPublicKeyInCreationV0 { id: 2, @@ -1862,11 +1861,9 @@ mod tests { ) .await; - let secp = Secp256k1::new(); - - let mut rng = StdRng::seed_from_u64(1292); + let mut rng = SecpStdRng::seed_from_u64(1292); - let new_key_pair = Keypair::new(&secp, &mut rng); + let new_key_pair = Keypair::new(&mut rng); let mut new_key = IdentityPublicKeyInCreationV0 { id: 2, @@ -1902,7 +1899,7 @@ mod tests { // Sign the new key with its own private key let secret = new_key_pair.secret_key(); let signature = - signer::sign(&signable_bytes, &secret.secret_bytes()).expect("expected to sign"); + signer::sign(&signable_bytes, &secret.to_secret_bytes()).expect("expected to sign"); new_key.signature = signature.to_vec().into(); @@ -2147,14 +2144,13 @@ mod tests { let bounds = ContractBounds::SingleContract { id: data_contract.id(), }; - let secp = Secp256k1::new(); - let mut rng = StdRng::seed_from_u64(1292); + let mut rng = SecpStdRng::seed_from_u64(1292); // Two encryption keys, the newer one listed first: both write the encryption // current-key alias, and the one naming the highest key id must win. let pairs: Vec<(u32, Purpose, Keypair)> = vec![ - (4, Purpose::ENCRYPTION, Keypair::new(&secp, &mut rng)), - (2, Purpose::ENCRYPTION, Keypair::new(&secp, &mut rng)), - (3, Purpose::DECRYPTION, Keypair::new(&secp, &mut rng)), + (4, Purpose::ENCRYPTION, Keypair::new(&mut rng)), + (2, Purpose::ENCRYPTION, Keypair::new(&mut rng)), + (3, Purpose::DECRYPTION, Keypair::new(&mut rng)), ]; let mut adds: Vec = pairs .iter() @@ -2270,7 +2266,7 @@ mod tests { .signable_bytes() .expect("expected signable bytes"); for (key, (_, _, pair)) in adds.iter_mut().zip(&pairs) { - key.signature = signer::sign(&signable, &pair.secret_key().secret_bytes()) + key.signature = signer::sign(&signable, &pair.secret_key().to_secret_bytes()) .expect("expected to sign") .to_vec() .into(); @@ -2637,11 +2633,9 @@ mod tests { ) .await; - let secp = Secp256k1::new(); + let mut rng = SecpStdRng::seed_from_u64(1292); - let mut rng = StdRng::seed_from_u64(1292); - - let new_key_pair = Keypair::new(&secp, &mut rng); + let new_key_pair = Keypair::new(&mut rng); let mut new_key = IdentityPublicKeyInCreationV0 { id: 2, @@ -2678,7 +2672,7 @@ mod tests { // Sign the new key with its own private key let secret = new_key_pair.secret_key(); let signature = - signer::sign(&signable_bytes, &secret.secret_bytes()).expect("expected to sign"); + signer::sign(&signable_bytes, &secret.to_secret_bytes()).expect("expected to sign"); new_key.signature = signature.to_vec().into(); @@ -3011,9 +3005,8 @@ mod tests { let platform_state = platform.state.load(); - let secp = Secp256k1::new(); - let mut rng = StdRng::seed_from_u64(292); - let new_key_pair = Keypair::new(&secp, &mut rng); + let mut rng = SecpStdRng::seed_from_u64(292); + let new_key_pair = Keypair::new(&mut rng); // Add a key with id 2 and also disable key id 2 in the same transition let new_key = IdentityPublicKeyInCreationV0 { @@ -3241,9 +3234,8 @@ mod tests { let platform_state = platform.state.load(); - let secp = Secp256k1::new(); - let mut rng = StdRng::seed_from_u64(292); - let new_key_pair = Keypair::new(&secp, &mut rng); + let mut rng = SecpStdRng::seed_from_u64(292); + let new_key_pair = Keypair::new(&mut rng); let signable_transition: IdentityUpdateTransition = IdentityUpdateTransitionV0 { identity_id: identity.id(), @@ -3276,7 +3268,7 @@ mod tests { // Sign the new key let secret = new_key_pair.secret_key(); let key_sig = - signer::sign(&signable_bytes, &secret.secret_bytes()).expect("expected to sign"); + signer::sign(&signable_bytes, &secret.to_secret_bytes()).expect("expected to sign"); let mut new_key = IdentityPublicKeyInCreationV0 { id: 1, // existing key ID @@ -3377,9 +3369,8 @@ mod tests { setup_identity_return_master_key(&mut platform, 958, dash_to_credits!(0.1)); let platform_state = platform.state.load(); - let secp = Secp256k1::new(); - let mut rng = StdRng::seed_from_u64(292); - let new_key_pair = Keypair::new(&secp, &mut rng); + let mut rng = SecpStdRng::seed_from_u64(292); + let new_key_pair = Keypair::new(&mut rng); let mut new_key = IdentityPublicKeyInCreationV1 { id: NEW_KEY_ID, purpose: added_key.purpose, @@ -3413,11 +3404,13 @@ mod tests { let signable_bytes = transition_adding(new_key.clone()) .signable_bytes() .expect("expected signable bytes"); - new_key.signature = - signer::sign(&signable_bytes, &new_key_pair.secret_key().secret_bytes()) - .expect("expected to sign") - .to_vec() - .into(); + new_key.signature = signer::sign( + &signable_bytes, + &new_key_pair.secret_key().to_secret_bytes(), + ) + .expect("expected to sign") + .to_vec() + .into(); let mut update_transition = transition_adding(new_key); update_transition.set_signature( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield_from_asset_lock/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield_from_asset_lock/tests.rs index a4337de4fb7..e9839851020 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield_from_asset_lock/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield_from_asset_lock/tests.rs @@ -609,7 +609,7 @@ mod tests { let transition = create_signed_shield_from_asset_lock_transition( asset_lock_proof, - &wrong_private_key.inner.secret_bytes(), // Wrong key + &wrong_private_key.inner.to_secret_bytes(), // Wrong key vec![create_dummy_serialized_action()], 5000, [42u8; 32], diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/test_helpers.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/test_helpers.rs index 1e19a410e66..9ff1ddf3825 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/test_helpers.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/test_helpers.rs @@ -12,7 +12,7 @@ use dpp::address_funds::{AddressWitness, PlatformAddress}; use dpp::block::block_info::BlockInfo; use dpp::dashcore::blockdata::script::ScriptBuf; use dpp::dashcore::hashes::{sha256, Hash}; -use dpp::dashcore::secp256k1::{PublicKey as RawPublicKey, Secp256k1, SecretKey as RawSecretKey}; +use dpp::dashcore::secp256k1::{PublicKey as RawPublicKey, SecretKey as RawSecretKey}; use dpp::dashcore::PublicKey; use dpp::identity::signer::Signer; use dpp::platform_value::BinaryData; @@ -37,8 +37,6 @@ pub use dpp::dashcore::blockdata::opcodes::all::{ pub use dpp::dashcore::blockdata::script::ScriptBuf as TestScriptBuf; pub use dpp::dashcore::hashes::Hash as TestHash; #[allow(unused_imports)] -pub use dpp::dashcore::secp256k1::Secp256k1 as TestSecp256k1; -#[allow(unused_imports)] pub use dpp::dashcore::PublicKey as TestPublicKey; pub use dpp::ProtocolError as TestProtocolError; @@ -73,19 +71,18 @@ impl TestAddressSigner { } pub fn create_keypair(seed: [u8; 32]) -> (RawSecretKey, PublicKey) { - let secp = Secp256k1::new(); // Hash the seed to ensure it's always a valid secret key // (non-zero, less than curve order). Raw seeds like [0u8; 32] are invalid. let hashed_seed = sha256::Hash::hash(&seed); - let secret_key = - RawSecretKey::from_byte_array(hashed_seed.as_byte_array()).expect("valid secret key"); - let raw_public_key = RawPublicKey::from_secret_key(&secp, &secret_key); + let secret_key = RawSecretKey::from_secret_bytes(*hashed_seed.as_byte_array()) + .expect("valid secret key"); + let raw_public_key = RawPublicKey::from_secret_key(&secret_key); let public_key = PublicKey::new(raw_public_key); (secret_key, public_key) } pub fn sign_data(data: &[u8], secret_key: &RawSecretKey) -> Vec { - dpp::dashcore::signer::sign(data, secret_key.as_ref()) + dpp::dashcore::signer::sign(data, secret_key.as_secret_bytes()) .expect("signing should succeed") .to_vec() } @@ -139,7 +136,7 @@ impl TestAddressSigner { PlatformAddress::P2pkh(hash) => self .p2pkh_keys .get(hash) - .map(|entry| entry.secret_key.secret_bytes()), + .map(|entry| entry.secret_key.to_secret_bytes()), _ => None, } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index 96820a70270..bf491224e93 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -2246,7 +2246,7 @@ impl NetworkStrategy { IdentityTopUpTransition::try_from_identity_with_private_key( identity, asset_lock_proof, - secret_key.as_ref(), + secret_key.as_secret_bytes(), 0, platform_version, None, @@ -2320,7 +2320,7 @@ impl NetworkStrategy { ( asset_lock_proof, - secret_key.secret_bytes().to_vec(), + secret_key.to_secret_bytes().to_vec(), funded_amount, ) } diff --git a/packages/rs-drive-proof-verifier/src/proof/token_direct_purchase.rs b/packages/rs-drive-proof-verifier/src/proof/token_direct_purchase.rs index 0a4d2256791..5584e0eef93 100644 --- a/packages/rs-drive-proof-verifier/src/proof/token_direct_purchase.rs +++ b/packages/rs-drive-proof-verifier/src/proof/token_direct_purchase.rs @@ -9,10 +9,7 @@ use dapi_grpc::platform::{ }, VersionedGrpcResponse, }; -use dpp::{ - dashcore::{secp256k1::hashes::hex::DisplayHex, Network}, - version::PlatformVersion, -}; +use dpp::{dashcore::Network, version::PlatformVersion}; use drive::drive::Drive; use crate::{ @@ -51,7 +48,7 @@ impl FromProof for TokenDirectPurchasePrice .map(<[u8; 32]>::try_from) .collect::, _>>() // BTreeSet to make it unique .map_err(|e| Error::RequestError { - error: format!("token id {} has invalid length", e.to_lower_hex_string()), + error: format!("token id {} has invalid length", hex::encode(e)), })? .into_iter() .collect::>(); diff --git a/packages/rs-platform-encryption/Cargo.toml b/packages/rs-platform-encryption/Cargo.toml index 7c6757d23a0..32c8f7a74ab 100644 --- a/packages/rs-platform-encryption/Cargo.toml +++ b/packages/rs-platform-encryption/Cargo.toml @@ -9,9 +9,9 @@ description = "Cryptographic utilities for Dash Platform (DIP-15 DashPay encrypt [dependencies] # Cryptography — direct deps only, so a consumer that needs just this crate # doesn't pull in/compile all of dashcore. `secp256k1` is pinned to the same -# 0.30 dashcore re-exports, so the public `SecretKey`/`PublicKey` types unify +# 0.33 dashcore re-exports, so the public `SecretKey`/`PublicKey` types unify # with dashcore-typed callers (platform-wallet, rs-sdk-ffi). -secp256k1 = { version = "0.30.0", features = ["std"] } +secp256k1 = { version = "0.33.1", features = ["std"] } aes = "0.8" cbc = "0.1" hmac = "0.12" @@ -21,4 +21,4 @@ thiserror = "1.0" [dev-dependencies] # Tests generate keypairs via secp256k1's RNG helpers (`generate_keypair`, # `secp256k1::rand`), gated behind the `rand` feature. -secp256k1 = { version = "0.30.0", features = ["std", "rand"] } +secp256k1 = { version = "0.33.1", features = ["std", "rand"] } diff --git a/packages/rs-platform-encryption/src/account_label.rs b/packages/rs-platform-encryption/src/account_label.rs index 9f281be8c60..4c2abc4a43c 100644 --- a/packages/rs-platform-encryption/src/account_label.rs +++ b/packages/rs-platform-encryption/src/account_label.rs @@ -113,21 +113,20 @@ pub fn decrypt_account_label( mod tests { use super::*; use crate::ecdh::derive_shared_key_ecdh; - use secp256k1::rand::{thread_rng, RngCore}; - use secp256k1::Secp256k1; + use secp256k1::generate_keypair; + use secp256k1::rand::{rng, RngCore}; #[test] fn test_account_label_encryption() { - let secp = Secp256k1::new(); - let (secret1, _public1) = secp.generate_keypair(&mut thread_rng()); - let (_secret2, public2) = secp.generate_keypair(&mut thread_rng()); + let (secret1, _public1) = generate_keypair(&mut rng()); + let (_secret2, public2) = generate_keypair(&mut rng()); // Derive shared key let shared_key = derive_shared_key_ecdh(&secret1, &public2); // Generate random IV let mut iv = [0u8; 16]; - thread_rng().fill_bytes(&mut iv); + rng().fill_bytes(&mut iv); let label = "My DashPay Account"; diff --git a/packages/rs-platform-encryption/src/aes.rs b/packages/rs-platform-encryption/src/aes.rs index c1609592fd7..5ea3ba3a60f 100644 --- a/packages/rs-platform-encryption/src/aes.rs +++ b/packages/rs-platform-encryption/src/aes.rs @@ -63,13 +63,13 @@ pub fn decrypt_aes_256_cbc( #[cfg(test)] mod tests { use super::*; - use secp256k1::rand::{thread_rng, RngCore}; + use secp256k1::rand::{rng, RngCore}; #[test] fn test_aes_encryption_decryption() { let key = [0u8; 32]; let mut iv = [0u8; 16]; - thread_rng().fill_bytes(&mut iv); + rng().fill_bytes(&mut iv); let plaintext = b"Hello, DashPay!"; diff --git a/packages/rs-platform-encryption/src/compact_xpub.rs b/packages/rs-platform-encryption/src/compact_xpub.rs index 01816f34006..b13dd1934c6 100644 --- a/packages/rs-platform-encryption/src/compact_xpub.rs +++ b/packages/rs-platform-encryption/src/compact_xpub.rs @@ -139,21 +139,20 @@ pub fn parse_compact_xpub(bytes: &[u8]) -> Result { mod tests { use super::*; use crate::ecdh::derive_shared_key_ecdh; - use secp256k1::rand::{thread_rng, RngCore}; - use secp256k1::Secp256k1; + use secp256k1::generate_keypair; + use secp256k1::rand::{rng, RngCore}; #[test] fn test_extended_public_key_encryption() { - let secp = Secp256k1::new(); - let (secret1, _public1) = secp.generate_keypair(&mut thread_rng()); - let (_secret2, public2) = secp.generate_keypair(&mut thread_rng()); + let (secret1, _public1) = generate_keypair(&mut rng()); + let (_secret2, public2) = generate_keypair(&mut rng()); // Derive shared key let shared_key = derive_shared_key_ecdh(&secret1, &public2); // Generate random IV let mut iv = [0u8; 16]; - thread_rng().fill_bytes(&mut iv); + rng().fill_bytes(&mut iv); // DIP-15 compact xpub plaintext (69 bytes). 69 → PKCS7 → 80, + 16-byte // IV = exactly 96 bytes, matching the contract's minItems/maxItems: 96. diff --git a/packages/rs-platform-encryption/src/ecdh.rs b/packages/rs-platform-encryption/src/ecdh.rs index 7e165365eec..54806ea3c4a 100644 --- a/packages/rs-platform-encryption/src/ecdh.rs +++ b/packages/rs-platform-encryption/src/ecdh.rs @@ -21,23 +21,21 @@ pub fn derive_shared_key_ecdh(private_key: &SecretKey, public_key: &PublicKey) - let shared_secret = SharedSecret::new(public_key, private_key); let mut key = [0u8; 32]; - key.copy_from_slice(shared_secret.as_ref()); + key.copy_from_slice(shared_secret.as_secret_bytes()); key } #[cfg(test)] mod tests { use super::*; - use secp256k1::rand::thread_rng; - use secp256k1::Secp256k1; + use secp256k1::generate_keypair; + use secp256k1::rand::rng; #[test] fn test_ecdh_key_derivation() { - let secp = Secp256k1::new(); - // Generate two key pairs - let (secret1, public1) = secp.generate_keypair(&mut thread_rng()); - let (secret2, public2) = secp.generate_keypair(&mut thread_rng()); + let (secret1, public1) = generate_keypair(&mut rng()); + let (secret2, public2) = generate_keypair(&mut rng()); // Derive shared keys from both sides let shared1 = derive_shared_key_ecdh(&secret1, &public2); @@ -55,14 +53,13 @@ mod tests { /// (b) the exact compressed-y-prefix-‖-x preimage convention. #[test] fn ecdh_matches_sha256_y_parity_prefix_convention() { - use secp256k1::{Scalar, Secp256k1}; + use secp256k1::Scalar; use sha2::{Digest, Sha256}; - let secp = Secp256k1::new(); - let priv_a = SecretKey::from_slice(&[0xC0u8; 32]).expect("valid scalar"); - let priv_b = SecretKey::from_slice(&[0x0Du8; 32]).expect("valid scalar"); - let pub_a = PublicKey::from_secret_key(&secp, &priv_a); - let pub_b = PublicKey::from_secret_key(&secp, &priv_b); + let priv_a = SecretKey::from_secret_bytes([0xC0u8; 32]).expect("valid scalar"); + let priv_b = SecretKey::from_secret_bytes([0x0Du8; 32]).expect("valid scalar"); + let pub_a = PublicKey::from_secret_key(&priv_a); + let pub_b = PublicKey::from_secret_key(&priv_b); let ab = derive_shared_key_ecdh(&priv_a, &pub_b); let ba = derive_shared_key_ecdh(&priv_b, &pub_a); @@ -73,7 +70,7 @@ mod tests { // SHA256( (0x02 | (P.y & 1)) ‖ P.x ). Pins that it's the compressed-y // prefix + x, NOT x‖y or some other layout. let scalar_a = Scalar::from_be_bytes([0xC0u8; 32]).expect("scalar in range"); - let shared_point = pub_b.mul_tweak(&secp, &scalar_a).expect("point mul"); + let shared_point = pub_b.mul_tweak(&scalar_a).expect("point mul"); let uncompressed = shared_point.serialize_uncompressed(); // 0x04 ‖ x(32) ‖ y(32) let prefix = 0x02u8 | (uncompressed[64] & 1); // y parity from the last y byte let mut preimage = Vec::with_capacity(33); diff --git a/packages/rs-platform-wallet-ffi/src/dashpay.rs b/packages/rs-platform-wallet-ffi/src/dashpay.rs index b3e7418b090..49aea2b6300 100644 --- a/packages/rs-platform-wallet-ffi/src/dashpay.rs +++ b/packages/rs-platform-wallet-ffi/src/dashpay.rs @@ -769,7 +769,7 @@ impl platform_wallet::ContactCryptoProvider for ResolverContactCryptoProvider { .map_err(|e| { platform_wallet::PlatformWalletError::InvalidIdentityData(e.to_string()) })?; - dashcore::secp256k1::SecretKey::from_slice(scalar.as_ref()) + dashcore::secp256k1::SecretKey::from_secret_bytes(*scalar) .map_err(|e| platform_wallet::PlatformWalletError::InvalidIdentityData(e.to_string())) } @@ -783,7 +783,7 @@ impl platform_wallet::ContactCryptoProvider for ResolverContactCryptoProvider { .map_err(|e| { platform_wallet::PlatformWalletError::InvalidIdentityData(e.to_string()) })?; - dashcore::secp256k1::SecretKey::from_slice(scalar.as_ref()) + dashcore::secp256k1::SecretKey::from_secret_bytes(*scalar) .map_err(|e| platform_wallet::PlatformWalletError::InvalidIdentityData(e.to_string())) } diff --git a/packages/rs-platform-wallet-ffi/src/derivation.rs b/packages/rs-platform-wallet-ffi/src/derivation.rs index 81b1020276d..5d30ac8ef6a 100644 --- a/packages/rs-platform-wallet-ffi/src/derivation.rs +++ b/packages/rs-platform-wallet-ffi/src/derivation.rs @@ -4,7 +4,6 @@ use std::ffi::CStr; use std::os::raw::c_char; use std::str::FromStr; -use dashcore::secp256k1::Secp256k1; use key_wallet::bip32::{DerivationPath, ExtendedPrivKey}; use key_wallet::mnemonic::Mnemonic; use zeroize::Zeroizing; @@ -90,16 +89,15 @@ pub unsafe extern "C" fn platform_wallet_derive_ext_priv_key_from_mnemonic( let master = unwrap_result_or_return!(ExtendedPrivKey::new_master(network, &*seed)); - let secp = Secp256k1::new(); - let derived = unwrap_result_or_return!(master.derive_priv(&secp, &path)); + let derived = unwrap_result_or_return!(master.derive_priv(&path)); - let secret = Zeroizing::new(derived.private_key.secret_bytes()); + let secret = Zeroizing::new(derived.private_key.to_secret_bytes()); std::ptr::copy_nonoverlapping(secret.as_ptr(), out_secret_key, 32); std::ptr::copy_nonoverlapping(derived.chain_code.as_ref().as_ptr(), out_chain_code, 32); if !out_public_key.is_null() { - let pubkey_bytes = derived.private_key.public_key(&secp).serialize(); + let pubkey_bytes = derived.private_key.public_key().serialize(); std::ptr::copy_nonoverlapping(pubkey_bytes.as_ptr(), out_public_key, 33); } diff --git a/packages/rs-platform-wallet-ffi/src/derive_identity_key_at_slot.rs b/packages/rs-platform-wallet-ffi/src/derive_identity_key_at_slot.rs index ed2463e3cdc..d2d9f0da1ec 100644 --- a/packages/rs-platform-wallet-ffi/src/derive_identity_key_at_slot.rs +++ b/packages/rs-platform-wallet-ffi/src/derive_identity_key_at_slot.rs @@ -81,8 +81,7 @@ unsafe fn derive_at_slot_inner( let pub_len = pub_box.len(); std::mem::forget(pub_box); - let secret_key = match dashcore::secp256k1::SecretKey::from_slice(derived.private_key.as_ref()) - { + let secret_key = match dashcore::secp256k1::SecretKey::from_secret_bytes(*derived.private_key) { Ok(k) => k, Err(e) => { drop(Box::from_raw(std::ptr::slice_from_raw_parts_mut( diff --git a/packages/rs-platform-wallet-ffi/src/identity_derive_and_persist.rs b/packages/rs-platform-wallet-ffi/src/identity_derive_and_persist.rs index 9ce63c81f56..7beb37acde8 100644 --- a/packages/rs-platform-wallet-ffi/src/identity_derive_and_persist.rs +++ b/packages/rs-platform-wallet-ffi/src/identity_derive_and_persist.rs @@ -93,7 +93,6 @@ use std::ptr; use crate::types::{FFINetwork, Network}; use dashcore::hashes::Hash; -use dashcore::secp256k1::Secp256k1; use key_wallet::bip32::{ExtendedPrivKey, ExtendedPubKey}; use zeroize::{Zeroize, Zeroizing}; @@ -260,7 +259,6 @@ pub unsafe extern "C" fn dash_sdk_derive_and_persist_identity_keys( let kw_network: Network = network.into(); let master = unwrap_result_or_return!(ExtendedPrivKey::new_master(kw_network, seed.as_ref())); - let secp = Secp256k1::new(); // ---- Walk derivation paths, persist, build pubkey-only rows -------------- let persister = &*persister_handle; @@ -298,7 +296,7 @@ pub unsafe extern "C" fn dash_sdk_derive_and_persist_identity_keys( } }; - let derived = match master.derive_priv(&secp, &path) { + let derived = match master.derive_priv(&path) { Ok(d) => d, Err(e) => { cleanup(rows); @@ -313,13 +311,13 @@ pub unsafe extern "C" fn dash_sdk_derive_and_persist_identity_keys( }; // Materialize pubkey + hash160 once. - let extended_pub = ExtendedPubKey::from_priv(&secp, &derived); + let extended_pub = ExtendedPubKey::from_priv(&derived); let pub_bytes: [u8; 33] = extended_pub.public_key.serialize(); let pub_hash: [u8; 20] = dashcore::hashes::hash160::Hash::hash(&pub_bytes).to_byte_array(); // Hold the secret scalar in a buffer that drops with // `zeroize::Zeroize::zeroize` at scope end. - let mut priv_scalar: [u8; 32] = derived.private_key.secret_bytes(); + let mut priv_scalar: [u8; 32] = derived.private_key.to_secret_bytes(); let path_cstring = match CString::new(path.to_string()) { Ok(s) => s, diff --git a/packages/rs-platform-wallet-ffi/src/identity_key_preview.rs b/packages/rs-platform-wallet-ffi/src/identity_key_preview.rs index cecc569c051..837722a5dbd 100644 --- a/packages/rs-platform-wallet-ffi/src/identity_key_preview.rs +++ b/packages/rs-platform-wallet-ffi/src/identity_key_preview.rs @@ -366,8 +366,8 @@ unsafe fn preview_identity_registration_keys_inner( // WIF: network-aware (mainnet → 0xCC, testnet/devnet/ // regtest → 0xEF) and compressed. Same construction // `key_wallet::derive_private_key_as_wif` performs. - let secret_key = dashcore::secp256k1::SecretKey::from_slice( - material.private_key.as_ref(), + let secret_key = dashcore::secp256k1::SecretKey::from_secret_bytes( + *material.private_key, ) .map_err(|e| { PlatformWalletFFIResult::err( @@ -455,7 +455,7 @@ unsafe fn preview_identity_registration_keys_inner( identity_index, key_index, )?; - let private_key = Zeroizing::new(ext_priv.private_key.secret_bytes()); + let private_key = Zeroizing::new(ext_priv.private_key.to_secret_bytes()); // Belt-and-braces: the pinned key-wallet rev zeroizes // `ExtendedPrivKey` on Drop; erase explicitly anyway // (cheap, and robust to an upstream Drop regression). diff --git a/packages/rs-platform-wallet-ffi/src/identity_keys_from_mnemonic.rs b/packages/rs-platform-wallet-ffi/src/identity_keys_from_mnemonic.rs index 2afc08840fc..0ac906848c1 100644 --- a/packages/rs-platform-wallet-ffi/src/identity_keys_from_mnemonic.rs +++ b/packages/rs-platform-wallet-ffi/src/identity_keys_from_mnemonic.rs @@ -2,7 +2,6 @@ use std::ffi::CString; -use dashcore::secp256k1::Secp256k1; use dashcore::PrivateKey as DashPrivateKey; use key_wallet::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey}; use key_wallet::dip9::{ @@ -319,7 +318,6 @@ pub unsafe extern "C" fn dash_sdk_derive_identity_keys_from_mnemonic( let kw_network: Network = network.into(); let master = unwrap_result_or_return!(ExtendedPrivKey::new_master(kw_network, seed.as_ref())); - let secp = Secp256k1::new(); let mut rows: Vec = Vec::with_capacity(key_count as usize); @@ -347,7 +345,7 @@ pub unsafe extern "C" fn dash_sdk_derive_identity_keys_from_mnemonic( } }; - let derived = match master.derive_priv(&secp, &path) { + let derived = match master.derive_priv(&path) { Ok(d) => d, Err(e) => { cleanup(rows); @@ -360,7 +358,7 @@ pub unsafe extern "C" fn dash_sdk_derive_identity_keys_from_mnemonic( ); } }; - let extended_pub = ExtendedPubKey::from_priv(&secp, &derived); + let extended_pub = ExtendedPubKey::from_priv(&derived); let public_key = extended_pub.public_key; let path_cstring = match CString::new(path.to_string()) { @@ -404,7 +402,7 @@ pub unsafe extern "C" fn dash_sdk_derive_identity_keys_from_mnemonic( public_key: pub_ptr, public_key_len: pub_len, private_key_wif: wif_cstring.into_raw(), - private_key_bytes: derived.private_key.secret_bytes(), + private_key_bytes: derived.private_key.to_secret_bytes(), }); } diff --git a/packages/rs-platform-wallet-ffi/src/identity_registration_with_signer.rs b/packages/rs-platform-wallet-ffi/src/identity_registration_with_signer.rs index 7dbda21ff29..e9cdf4bce92 100644 --- a/packages/rs-platform-wallet-ffi/src/identity_registration_with_signer.rs +++ b/packages/rs-platform-wallet-ffi/src/identity_registration_with_signer.rs @@ -704,7 +704,7 @@ pub unsafe extern "C" fn platform_wallet_derive_identity_keys_for_index( public_key: pub_ptr, public_key_len: pub_len, private_key_wif: wif_cstring.into_raw(), - private_key_bytes: ext_priv.private_key.secret_bytes(), + private_key_bytes: ext_priv.private_key.to_secret_bytes(), }); } Ok(rows) diff --git a/packages/rs-platform-wallet-ffi/src/invitation.rs b/packages/rs-platform-wallet-ffi/src/invitation.rs index 089e95bc6c5..8e6600c7ed4 100644 --- a/packages/rs-platform-wallet-ffi/src/invitation.rs +++ b/packages/rs-platform-wallet-ffi/src/invitation.rs @@ -747,7 +747,7 @@ mod tests { /// unknown wallet is looked up, and no signer/network work is attempted. #[test] fn claim_invitation_rejects_duplicate_key_ids_before_wallet_lookup() { - let voucher = SecretKey::from_slice(&[0x11u8; 32]).expect("valid scalar"); + let voucher = SecretKey::from_secret_bytes([0x11u8; 32]).expect("valid scalar"); let wif = PrivateKey::new(voucher, Network::Testnet).to_wif(); let uri = std::ffi::CString::new(format!("dashpay://invite?assetlocktx=aa&pk={wif}")).unwrap(); diff --git a/packages/rs-platform-wallet-ffi/src/persistence.rs b/packages/rs-platform-wallet-ffi/src/persistence.rs index d95a1f31db8..9334cde2789 100644 --- a/packages/rs-platform-wallet-ffi/src/persistence.rs +++ b/packages/rs-platform-wallet-ffi/src/persistence.rs @@ -8968,7 +8968,6 @@ mod tests { use dashcore::blockdata::transaction::txout::TxOut; use dashcore::blockdata::transaction::Transaction; use dashcore::consensus::encode::serialize; - use dashcore::secp256k1::Secp256k1; use dashcore::{Network, ScriptBuf}; use key_wallet::account::{Account, AccountType, StandardAccountType}; use key_wallet::bip32::{ExtendedPrivKey, ExtendedPubKey}; @@ -9127,8 +9126,7 @@ mod tests { let seed = mnemonic.to_seed(""); let master = ExtendedPrivKey::new_master(Network::Testnet, &seed) .expect("master derivation must succeed"); - let secp = Secp256k1::new(); - let xpub = ExtendedPubKey::from_priv(&secp, &master); + let xpub = ExtendedPubKey::from_priv(&master); let account = Account::from_xpub( None, AccountType::Standard { @@ -9160,8 +9158,7 @@ mod tests { let seed = mnemonic.to_seed(""); let master = ExtendedPrivKey::new_master(Network::Testnet, &seed) .expect("master derivation must succeed"); - let secp = Secp256k1::new(); - let xpub = ExtendedPubKey::from_priv(&secp, &master); + let xpub = ExtendedPubKey::from_priv(&master); let account = Account::from_xpub(None, account_type, xpub, Network::Testnet) .expect("Account::from_xpub on a valid xpub must succeed"); let mut accounts = key_wallet::AccountCollection::new(); @@ -9275,8 +9272,7 @@ mod tests { let seed = mnemonic.to_seed(""); let master = ExtendedPrivKey::new_master(Network::Testnet, &seed) .expect("master derivation must succeed"); - let secp = Secp256k1::new(); - let xpub = ExtendedPubKey::from_priv(&secp, &master); + let xpub = ExtendedPubKey::from_priv(&master); let account = Account::from_xpub(None, AccountType::ProviderOwnerKeys, xpub, Network::Testnet) .expect("Account::from_xpub on a valid xpub must succeed"); diff --git a/packages/rs-platform-wallet-ffi/src/secp256k1_primitives.rs b/packages/rs-platform-wallet-ffi/src/secp256k1_primitives.rs index d97d5e5f149..5615d7b2259 100644 --- a/packages/rs-platform-wallet-ffi/src/secp256k1_primitives.rs +++ b/packages/rs-platform-wallet-ffi/src/secp256k1_primitives.rs @@ -3,7 +3,7 @@ use std::slice; use dashcore::secp256k1::ecdh::shared_secret_point; -use dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use dashcore::secp256k1::{PublicKey, SecretKey}; use zeroize::Zeroizing; use crate::error::*; @@ -34,14 +34,14 @@ fn parse_secret_key( ))); } - // `SecretKey::from_slice` converts the slice into an unguarded local - // `[u8; 32]` on its way to the returned key, so parsing straight from the - // caller's slice would leave a second, unscrubbed copy of the scalar on - // the stack. Staging it here keeps every copy this side owns wiped. + // Converting the caller's slice straight into the `[u8; 32]` + // `SecretKey::from_secret_bytes` takes would leave an unguarded copy of + // the scalar on the stack. Staging it here keeps every copy this side + // owns wiped. let mut staged = Zeroizing::new([0u8; 32]); staged.copy_from_slice(unsafe { slice::from_raw_parts(private_key, private_key_len) }); - SecretKey::from_byte_array(&staged) + SecretKey::from_secret_bytes(*staged) .map(WipingSecretKey) .map_err(|error| invalid_parameter(format!("Invalid secp256k1 private key: {error}"))) } @@ -94,7 +94,7 @@ pub unsafe extern "C" fn platform_wallet_secp256k1_compressed_public_key( check_ptr!(out_pubkey); let secret_key = unwrap_result_or_return!(parse_secret_key(seckey, seckey_len)); - let compressed = PublicKey::from_secret_key(&Secp256k1::new(), &secret_key.0).serialize(); + let compressed = PublicKey::from_secret_key(&secret_key.0).serialize(); std::ptr::copy_nonoverlapping(compressed.as_ptr(), out_pubkey, compressed.len()); PlatformWalletFFIResult::ok() } diff --git a/packages/rs-platform-wallet-ffi/src/sign_with_mnemonic_resolver.rs b/packages/rs-platform-wallet-ffi/src/sign_with_mnemonic_resolver.rs index 0225e653a77..c2ea005a996 100644 --- a/packages/rs-platform-wallet-ffi/src/sign_with_mnemonic_resolver.rs +++ b/packages/rs-platform-wallet-ffi/src/sign_with_mnemonic_resolver.rs @@ -41,7 +41,6 @@ use std::os::raw::c_char; use std::str::FromStr; use crate::types::{FFINetwork, Network}; -use dashcore::secp256k1::Secp256k1; use key_wallet::bip32::{DerivationPath, ExtendedPrivKey}; use zeroize::Zeroizing; @@ -274,12 +273,11 @@ pub unsafe extern "C" fn dash_sdk_sign_with_mnemonic_resolver_and_path( Ok(m) => m, Err(_) => return fail(SIGN_WITH_RESOLVER_ERR_DERIVATION), }; - let secp = Secp256k1::new(); - let derived = match master.derive_priv(&secp, &path) { + let derived = match master.derive_priv(&path) { Ok(d) => d, Err(_) => return fail(SIGN_WITH_RESOLVER_ERR_DERIVATION), }; - let secret_bytes: Zeroizing<[u8; 32]> = Zeroizing::new(derived.private_key.secret_bytes()); + let secret_bytes: Zeroizing<[u8; 32]> = Zeroizing::new(derived.private_key.to_secret_bytes()); // ---- Bind the derived key to the expected on-chain key ------------------- // Reject before signing if the key derived here doesn't reproduce the @@ -290,7 +288,7 @@ pub unsafe extern "C" fn dash_sdk_sign_with_mnemonic_resolver_and_path( // `validate_private_key_bytes` decision (33-byte expected = compressed // pubkey equality; 20-byte expected = `ripemd160_sha256` of it). if !expected_key_data.is_null() && expected_key_data_len > 0 { - let derived_pubkey = key_wallet::bip32::ExtendedPubKey::from_priv(&secp, &derived) + let derived_pubkey = key_wallet::bip32::ExtendedPubKey::from_priv(&derived) .public_key .serialize(); // Build the expected slice only for the two lengths the binding @@ -494,14 +492,11 @@ mod tests { // same mnemonic the resolver returns. let mnemonic = parse_mnemonic_any_language(ENGLISH_PHRASE).expect("mnemonic"); let seed = mnemonic.to_seed(""); - let secp = Secp256k1::new(); let master = ExtendedPrivKey::new_master(Network::Testnet, &seed).expect("master"); let derived = master - .derive_priv(&secp, &DerivationPath::from_str(path_str).unwrap()) + .derive_priv(&DerivationPath::from_str(path_str).unwrap()) .expect("derive"); - let expected_pubkey = ExtendedPubKey::from_priv(&secp, &derived) - .public_key - .serialize(); + let expected_pubkey = ExtendedPubKey::from_priv(&derived).public_key.serialize(); let mut sig_buf = [0u8; 128]; let mut sig_len: usize = 0; @@ -590,14 +585,11 @@ mod tests { let mnemonic = parse_mnemonic_any_language(ENGLISH_PHRASE).expect("mnemonic"); let seed = mnemonic.to_seed(""); - let secp = Secp256k1::new(); let master = ExtendedPrivKey::new_master(Network::Testnet, &seed).expect("master"); let derived = master - .derive_priv(&secp, &DerivationPath::from_str(path_str).unwrap()) + .derive_priv(&DerivationPath::from_str(path_str).unwrap()) .expect("derive"); - let pubkey = ExtendedPubKey::from_priv(&secp, &derived) - .public_key - .serialize(); + let pubkey = ExtendedPubKey::from_priv(&derived).public_key.serialize(); let expected_hash = dash_sdk::dpp::util::hash::ripemd160_sha256(&pubkey); let mut sig_buf = [0u8; 128]; diff --git a/packages/rs-platform-wallet-ffi/src/utils.rs b/packages/rs-platform-wallet-ffi/src/utils.rs index bf84c88170e..770ae09777c 100644 --- a/packages/rs-platform-wallet-ffi/src/utils.rs +++ b/packages/rs-platform-wallet-ffi/src/utils.rs @@ -2,7 +2,7 @@ use crate::error::*; use crate::{check_ptr, unwrap_result_or_return}; use std::os::raw::{c_char, c_uchar}; -/// RAII guard that scrubs a `secp256k1::SecretKey`'s scalar on drop. `from_slice` +/// RAII guard that scrubs a `secp256k1::SecretKey`'s scalar on drop. `from_secret_bytes` /// allocates a 32-byte scalar copy of the caller's private key, and `SecretKey` /// has no `Drop` wipe of its own — so without this the copy would survive on the /// stack after the call returns. Mirrors `WipingSecretKey` in @@ -202,19 +202,21 @@ pub unsafe extern "C" fn platform_wallet_pubkey_hash_from_private_key( return -1; } use dashcore::hashes::Hash; - use dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; + use dashcore::secp256k1::{PublicKey, SecretKey}; let sk_bytes = std::slice::from_raw_parts(private_key, 32); - let secp = Secp256k1::new(); - // `WipingSecretKey` scrubs the `from_slice`-allocated scalar copy on every + // `WipingSecretKey` scrubs the `from_secret_bytes`-allocated scalar copy on every // exit path (the success return below, the `Err` early return, and any // panic) — the caller's `private_key` bytes are theirs to manage, but this // copy must not linger. - let secret_key = match SecretKey::from_slice(sk_bytes) { + let secret_key = match <[u8; 32]>::try_from(sk_bytes) + .map_err(|_| dashcore::secp256k1::Error::InvalidSecretKey) + .and_then(SecretKey::from_secret_bytes) + { Ok(sk) => WipingSecretKey(sk), Err(_) => return -1, }; - let pubkey = PublicKey::from_secret_key(&secp, &secret_key.0).serialize(); + let pubkey = PublicKey::from_secret_key(&secret_key.0).serialize(); let hash = dashcore::hashes::hash160::Hash::hash(&pubkey); let h: [u8; 20] = hash.to_byte_array(); std::ptr::copy_nonoverlapping(h.as_ptr(), out_hash, 20); @@ -263,7 +265,7 @@ mod tests { #[test] fn test_pubkey_hash_from_private_key_matches_canonical_derivation() { use dashcore::hashes::Hash; - use dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; + use dashcore::secp256k1::{PublicKey, SecretKey}; // A fixed, in-range scalar. let mut scalar = [0u8; 32]; @@ -275,9 +277,8 @@ mod tests { }; assert_eq!(rc, 0); - let secp = Secp256k1::new(); - let sk = SecretKey::from_slice(&scalar).expect("in-range scalar"); - let pubkey = PublicKey::from_secret_key(&secp, &sk).serialize(); + let sk = SecretKey::from_secret_bytes(scalar).expect("in-range scalar"); + let pubkey = PublicKey::from_secret_key(&sk).serialize(); let expected: [u8; 20] = dashcore::hashes::hash160::Hash::hash(&pubkey).to_byte_array(); assert_eq!(out, expected); } diff --git a/packages/rs-platform-wallet/examples/dpns_marketplace_testnet.rs b/packages/rs-platform-wallet/examples/dpns_marketplace_testnet.rs index 9db1d6a312a..ec012b74803 100644 --- a/packages/rs-platform-wallet/examples/dpns_marketplace_testnet.rs +++ b/packages/rs-platform-wallet/examples/dpns_marketplace_testnet.rs @@ -115,11 +115,10 @@ fn dapi_addresses() -> AddressList { /// Whether `sk_bytes` is the private key for `key` (33-byte pubkey for /// ECDSA_SECP256K1, hash160 for ECDSA_HASH160). fn private_key_matches(key: &dpp::identity::IdentityPublicKey, sk_bytes: &[u8; 32]) -> bool { - let secp = dashcore::secp256k1::Secp256k1::new(); - let Ok(sk) = dashcore::secp256k1::SecretKey::from_byte_array(sk_bytes) else { + let Ok(sk) = dashcore::secp256k1::SecretKey::from_secret_bytes(*sk_bytes) else { return false; }; - let pubkey = dashcore::secp256k1::PublicKey::from_secret_key(&secp, &sk).serialize(); + let pubkey = dashcore::secp256k1::PublicKey::from_secret_key(&sk).serialize(); match key.key_type() { KeyType::ECDSA_SECP256K1 => key.data().as_slice() == pubkey.as_slice(), KeyType::ECDSA_HASH160 => { @@ -174,7 +173,7 @@ fn parse_private_key(raw: &str) -> Option<[u8; 32]> { } dashcore::PrivateKey::from_wif(trimmed) .ok() - .map(|pk| pk.inner.secret_bytes()) + .map(|pk| pk.inner.to_secret_bytes()) } async fn discover( diff --git a/packages/rs-platform-wallet/src/masternode/locator.rs b/packages/rs-platform-wallet/src/masternode/locator.rs index faf0513f8f8..1a07ff91f7e 100644 --- a/packages/rs-platform-wallet/src/masternode/locator.rs +++ b/packages/rs-platform-wallet/src/masternode/locator.rs @@ -37,7 +37,7 @@ use dashcore::blsful::{ }; use dashcore::ed25519_dalek::SigningKey; use dashcore::hashes::{hash160, Hash}; -use dashcore::secp256k1::{PublicKey as SecpPublicKey, Secp256k1, SecretKey as SecpSecretKey}; +use dashcore::secp256k1::{PublicKey as SecpPublicKey, SecretKey as SecpSecretKey}; use dashcore::{Network, PlatformNodeId, PrivateKey}; use dpp::identifier::MasternodeIdentifiers; use dpp::identity::accessors::IdentityGettersV0; @@ -223,7 +223,7 @@ fn is_mainnet(network: Network) -> bool { /// only when below the group order; ed25519 accepts any 32 bytes as a seed. fn secret_candidates(bytes: &[u8; 32]) -> Vec { let mut out = Vec::with_capacity(3); - if SecpSecretKey::from_slice(bytes).is_ok() { + if SecpSecretKey::from_secret_bytes(*bytes).is_ok() { out.push(MasternodeLocatorInput::Secret(LocatorSecret::Ecdsa { secret: Zeroizing::new(*bytes), compressed: true, @@ -314,7 +314,7 @@ pub fn parse_locator_input( } return Ok(ParsedLocatorInput { candidates: vec![MasternodeLocatorInput::Secret(LocatorSecret::Ecdsa { - secret: Zeroizing::new(key.inner.secret_bytes()), + secret: Zeroizing::new(key.inner.to_secret_bytes()), compressed: key.compressed, })], }); @@ -353,8 +353,8 @@ pub fn parse_locator_input( /// hash160 of the secp256k1 public key for `secret`, or `None` when the /// scalar is out of range. pub fn ecdsa_key_id(secret: &[u8; 32], compressed: bool) -> Option<[u8; 20]> { - let sk = SecpSecretKey::from_slice(secret).ok()?; - let pk = SecpPublicKey::from_secret_key(&Secp256k1::signing_only(), &sk); + let sk = SecpSecretKey::from_secret_bytes(*secret).ok()?; + let pk = SecpPublicKey::from_secret_key(&sk); let bytes: Vec = if compressed { pk.serialize().to_vec() } else { @@ -1135,10 +1135,7 @@ mod tests { #[test] fn ecdsa_key_id_matches_dashcore_address_hash() { let key = PrivateKey::from_byte_array(&SECP_SECRET, Network::Mainnet).unwrap(); - let expected: [u8; 20] = key - .public_key(&Secp256k1::new()) - .pubkey_hash() - .to_byte_array(); + let expected: [u8; 20] = key.public_key().pubkey_hash().to_byte_array(); assert_eq!(secp_key_id(), expected); assert_ne!( ecdsa_key_id(&SECP_SECRET, false).unwrap(), diff --git a/packages/rs-platform-wallet/src/test_support.rs b/packages/rs-platform-wallet/src/test_support.rs index b9446432ee0..63e42594fc6 100644 --- a/packages/rs-platform-wallet/src/test_support.rs +++ b/packages/rs-platform-wallet/src/test_support.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use async_trait::async_trait; use dashcore::hashes::Hash; -use dashcore::secp256k1::{ecdsa, Message, PublicKey, Secp256k1}; +use dashcore::secp256k1::{ecdsa, Message, PublicKey}; use dashcore::BlockHash; #[cfg(test)] use dashcore::Txid; @@ -135,25 +135,20 @@ impl Signer for WalletSigner { path: &DerivationPath, sighash: [u8; 32], ) -> Result<(ecdsa::Signature, PublicKey), Self::Error> { - let secp = Secp256k1::new(); let key = self .wallet .derive_private_key(path) .map_err(|e| e.to_string())?; let message = Message::from_digest(sighash); - Ok(( - secp.sign_ecdsa(&message, &key), - PublicKey::from_secret_key(&secp, &key), - )) + Ok((key.sign_ecdsa(message), PublicKey::from_secret_key(&key))) } async fn public_key(&self, path: &DerivationPath) -> Result { - let secp = Secp256k1::new(); let key = self .wallet .derive_private_key(path) .map_err(|e| e.to_string())?; - Ok(PublicKey::from_secret_key(&secp, &key)) + Ok(PublicKey::from_secret_key(&key)) } } diff --git a/packages/rs-platform-wallet/src/wallet/core/sign_message.rs b/packages/rs-platform-wallet/src/wallet/core/sign_message.rs index 65321a9d099..9316053883b 100644 --- a/packages/rs-platform-wallet/src/wallet/core/sign_message.rs +++ b/packages/rs-platform-wallet/src/wallet/core/sign_message.rs @@ -46,7 +46,7 @@ use std::str::FromStr; use dashcore::address::Payload; use dashcore::hashes::Hash; use dashcore::secp256k1::ecdsa::{RecoverableSignature, RecoveryId}; -use dashcore::secp256k1::{Message, Secp256k1}; +use dashcore::secp256k1::Message; use dashcore::sign_message::{signed_msg_hash, MessageSignature}; use dashcore::{Address as DashAddress, AddressType, PublicKey as DashPublicKey}; use key_wallet::managed_account::managed_account_trait::ManagedAccountTrait; @@ -274,10 +274,6 @@ impl CoreWallet { }); } - // `recover_ecdsa` needs only a `Verification` context — the signing - // tables a full `Secp256k1::new()` would also allocate are dead weight - // here, since the signature itself came from the signer. - let secp = Secp256k1::verification_only(); let digest = Message::from_digest(hash.to_byte_array()); let compact = signature.serialize_compact(); @@ -286,7 +282,8 @@ impl CoreWallet { .filter_map(|id| RecoveryId::try_from(id).ok()) .filter_map(|recid| RecoverableSignature::from_compact(&compact, recid).ok()) .find(|candidate| { - secp.recover_ecdsa(&digest, candidate) + candidate + .recover_ecdsa(digest) .is_ok_and(|recovered| recovered == public_key) }) .ok_or_else(|| PlatformWalletError::MessageSigningFailed { @@ -303,7 +300,7 @@ mod tests { use std::str::FromStr; use std::sync::Arc; - use dashcore::secp256k1::{ecdsa, PublicKey, Secp256k1}; + use dashcore::secp256k1::{ecdsa, PublicKey}; use dashcore::sign_message::{signed_msg_hash, MessageSignature}; use dashcore::{Address as DashAddress, Network}; use key_wallet::signer::{Signer, SignerMethod, TransactionCategory}; @@ -349,7 +346,7 @@ mod tests { fn verifies_for(signature_base64: &str, address: &DashAddress) -> bool { MessageSignature::from_base64(signature_base64) .expect("signature is valid base64 of a 65-byte recoverable signature") - .is_signed_by_address(&Secp256k1::new(), address, signed_msg_hash(MESSAGE)) + .is_signed_by_address(address, signed_msg_hash(MESSAGE)) .expect("P2PKH address is a supported verification target") } @@ -403,7 +400,7 @@ mod tests { assert!( MessageSignature::from_base64(&signature) .expect("valid base64 of a 65-byte recoverable signature") - .is_signed_by_address(&Secp256k1::new(), &address, signed_msg_hash("")) + .is_signed_by_address(&address, signed_msg_hash("")) .expect("P2PKH address is a supported verification target"), "a signature over the empty message must verify against signed_msg_hash(\"\")" ); diff --git a/packages/rs-platform-wallet/src/wallet/core_address_key.rs b/packages/rs-platform-wallet/src/wallet/core_address_key.rs index f7cbc1e8299..7adb517e769 100644 --- a/packages/rs-platform-wallet/src/wallet/core_address_key.rs +++ b/packages/rs-platform-wallet/src/wallet/core_address_key.rs @@ -22,7 +22,6 @@ use std::str::FromStr; -use dashcore::secp256k1::Secp256k1; use dashcore::{Address, PrivateKey as DashPrivateKey}; use key_wallet::bip32::{DerivationPath, ExtendedPrivKey}; use zeroize::Zeroizing; @@ -115,13 +114,12 @@ impl PlatformWallet { // Derive the raw scalar from the selected key source. let secret_bytes: Zeroizing<[u8; 32]> = match resolved_master { Some(master) => { - let secp = Secp256k1::new(); - let derived = master.derive_priv(&secp, &path).map_err(|e| { + let derived = master.derive_priv(&path).map_err(|e| { PlatformWalletError::KeyDerivation(format!( "failed to derive private key at {path}: {e}" )) })?; - Zeroizing::new(derived.private_key.secret_bytes()) + Zeroizing::new(derived.private_key.to_secret_bytes()) } None => { // Resident key-bearing wallet — derive from its own root. @@ -133,15 +131,15 @@ impl PlatformWallet { "failed to derive private key at {path} from resident wallet: {e}" )) })?; - Zeroizing::new(secret_key.secret_bytes()) + Zeroizing::new(secret_key.to_secret_bytes()) } }; - // Build the network-aware compressed WIF. `SecretKey::from_slice` + // Build the network-aware compressed WIF. `SecretKey::from_secret_bytes` // over the just-derived bytes is infallible, but map its error // rather than unwrap to keep the boundary panic-free. - let secret_key = dashcore::secp256k1::SecretKey::from_slice(secret_bytes.as_ref()) - .map_err(|e| { + let secret_key = + dashcore::secp256k1::SecretKey::from_secret_bytes(*secret_bytes).map_err(|e| { PlatformWalletError::KeyDerivation(format!( "derived private key bytes were not a valid secp256k1 scalar: {e}" )) diff --git a/packages/rs-platform-wallet/src/wallet/identity/crypto/auto_accept.rs b/packages/rs-platform-wallet/src/wallet/identity/crypto/auto_accept.rs index ed20b65f11e..f86e120c84b 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/crypto/auto_accept.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/crypto/auto_accept.rs @@ -25,7 +25,7 @@ //! `m/9'/coin'/16'/timestamp'` (all segments hardened) use dashcore::hashes::{sha256, Hash, HashEngine}; -use dashcore::secp256k1::{ecdsa::Signature, Message, Secp256k1, SecretKey}; +use dashcore::secp256k1::{ecdsa::Signature, Message, SecretKey}; use dpp::prelude::Identifier; use key_wallet::bip32::{ChildNumber, DerivationPath}; use key_wallet::dip9::{ @@ -112,9 +112,9 @@ pub fn derive_auto_accept_private_key( PlatformWalletError::InvalidIdentityData(format!("Failed to derive auto-accept key: {}", e)) })?; - let secret_bytes = zeroize::Zeroizing::new(ext_priv.private_key.secret_bytes()); + let secret_bytes = zeroize::Zeroizing::new(ext_priv.private_key.to_secret_bytes()); - SecretKey::from_slice(&*secret_bytes).map_err(|e| { + SecretKey::from_secret_bytes(*secret_bytes).map_err(|e| { PlatformWalletError::InvalidIdentityData(format!( "Invalid derived auto-accept private key: {}", e @@ -147,8 +147,7 @@ pub fn sign_auto_accept_proof( let msg_hash = build_message_hash(sender_id, recipient_id, account_reference); let message = Message::from_digest(msg_hash); - let secp = Secp256k1::new(); - let signature = secp.sign_ecdsa(&message, secret_key); + let signature = secret_key.sign_ecdsa(message); let sig_bytes = signature.serialize_compact(); let mut proof = Vec::with_capacity(1 + 4 + 1 + 64); @@ -240,9 +239,7 @@ pub fn verify_auto_accept_proof_with_pubkey( Err(_) => return false, }; - Secp256k1::new() - .verify_ecdsa(&message, &signature, pubkey) - .is_ok() + signature.verify(message, pubkey).is_ok() } /// Verify an auto-accept proof by re-deriving the expected key from `wallet`. @@ -265,7 +262,7 @@ pub fn verify_auto_accept_proof( return Ok(false); }; let secret_key = derive_auto_accept_private_key(wallet, network, timestamp)?; - let pubkey = dashcore::secp256k1::PublicKey::from_secret_key(&Secp256k1::new(), &secret_key); + let pubkey = dashcore::secp256k1::PublicKey::from_secret_key(&secret_key); Ok(verify_auto_accept_proof_with_pubkey( &pubkey, proof_bytes, @@ -294,7 +291,7 @@ pub fn encode_auto_accept_key_blob(secret_key: &SecretKey, expiry: u32) -> Vec Result<(SecretKey, u32), Plat if blob[5] != ECDSA_KEY_SIZE { return Err(invalid("auto-accept key size must be 32")); } - let secret_key = SecretKey::from_slice(&blob[6..KEY_BLOB_LEN]) + let secret_key = <[u8; 32]>::try_from(&blob[6..KEY_BLOB_LEN]) + .map_err(|_| dashcore::secp256k1::Error::InvalidSecretKey) + .and_then(SecretKey::from_secret_bytes) .map_err(|e| invalid(format!("invalid auto-accept private key: {e}")))?; Ok((secret_key, expiry)) } @@ -571,7 +570,7 @@ mod tests { assert_eq!(proof.len(), 70); assert_eq!(auto_accept_proof_expiry(&proof), Some(expiry)); - let pubkey = dashcore::secp256k1::PublicKey::from_secret_key(&Secp256k1::new(), &owner_key); + let pubkey = dashcore::secp256k1::PublicKey::from_secret_key(&owner_key); assert!( verify_auto_accept_proof_with_pubkey(&pubkey, &proof, &scanner, &owner, account_ref), "owner verifies the scanner's proof against its own re-derived pubkey" @@ -593,14 +592,14 @@ mod tests { #[test] fn key_blob_round_trip_and_rejects_malformed() { - let key = SecretKey::from_slice(&[0x07u8; 32]).unwrap(); + let key = SecretKey::from_secret_bytes([0x07u8; 32]).unwrap(); let blob = encode_auto_accept_key_blob(&key, 12345); assert_eq!(blob.len(), 38); assert_eq!(blob[0], 0x00); // key type assert_eq!(blob[5], 0x20); // key size let (k2, e2) = decode_auto_accept_key_blob(&blob).expect("decode"); - assert_eq!(k2.secret_bytes(), key.secret_bytes()); + assert_eq!(k2.to_secret_bytes(), key.to_secret_bytes()); assert_eq!(e2, 12345); assert!(decode_auto_accept_key_blob(&blob[..37]).is_err(), "short"); @@ -614,7 +613,7 @@ mod tests { #[test] fn uri_round_trip_and_rejects_malformed() { - let key = SecretKey::from_slice(&[0x09u8; 32]).unwrap(); + let key = SecretKey::from_secret_bytes([0x09u8; 32]).unwrap(); let blob = encode_auto_accept_key_blob(&key, 999); let uri = encode_dashpay_contact_uri("bobspizza", &blob); assert!(uri.starts_with("dash:?du=bobspizza&dapk=")); @@ -662,7 +661,7 @@ mod tests { ); // The cap must not reject a normal-length (valid) dapk. - let key = SecretKey::from_slice(&[0x09u8; 32]).unwrap(); + let key = SecretKey::from_secret_bytes([0x09u8; 32]).unwrap(); let blob = encode_auto_accept_key_blob(&key, 1); let uri = encode_dashpay_contact_uri("alice", &blob); assert!( @@ -673,8 +672,8 @@ mod tests { #[test] fn verify_with_pubkey_rejects_truncated_and_no_expiry() { - let key = SecretKey::from_slice(&[0x05u8; 32]).unwrap(); - let pubkey = dashcore::secp256k1::PublicKey::from_secret_key(&Secp256k1::new(), &key); + let key = SecretKey::from_secret_bytes([0x05u8; 32]).unwrap(); + let pubkey = dashcore::secp256k1::PublicKey::from_secret_key(&key); let (s, r) = test_ids(); assert!(!verify_auto_accept_proof_with_pubkey( &pubkey, &[0u8; 3], &s, &r, 0 diff --git a/packages/rs-platform-wallet/src/wallet/identity/crypto/contact_info.rs b/packages/rs-platform-wallet/src/wallet/identity/crypto/contact_info.rs index 63b07a87f11..015fb085795 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/crypto/contact_info.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/crypto/contact_info.rs @@ -121,7 +121,7 @@ pub fn derive_contact_info_keys( "Failed to derive contactInfo key: {e}" )) })?; - Ok(Zeroizing::new(ext.private_key.secret_bytes())) + Ok(Zeroizing::new(ext.private_key.to_secret_bytes())) }; Ok(ContactInfoKeys { diff --git a/packages/rs-platform-wallet/src/wallet/identity/crypto/dip14.rs b/packages/rs-platform-wallet/src/wallet/identity/crypto/dip14.rs index 9145403be8f..4287f0ca2a9 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/crypto/dip14.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/crypto/dip14.rs @@ -26,7 +26,6 @@ //! - [DIP-14](https://github.com/dashpay/dips/blob/master/dip-0014.md) //! - [DIP-15](https://github.com/dashpay/dips/blob/master/dip-0015.md) -use dashcore::secp256k1::Secp256k1; use dashcore::{Address, Network, PublicKey}; use dpp::prelude::Identifier; use key_wallet::account::AccountType; @@ -210,13 +209,11 @@ pub fn derive_contact_payment_address( index: u32, network: Network, ) -> Result { - let secp = Secp256k1::new(); - let child_number = ChildNumber::from_normal_idx(index).map_err(|e| { PlatformWalletError::InvalidIdentityData(format!("Invalid payment address index: {}", e)) })?; - let address_key = contact_xpub.ckd_pub(&secp, child_number).map_err(|e| { + let address_key = contact_xpub.ckd_pub(child_number).map_err(|e| { PlatformWalletError::InvalidIdentityData(format!( "Failed to derive contact payment key at index {}: {}", index, e diff --git a/packages/rs-platform-wallet/src/wallet/identity/crypto/invitation.rs b/packages/rs-platform-wallet/src/wallet/identity/crypto/invitation.rs index 6060013024a..75812e041eb 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/crypto/invitation.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/crypto/invitation.rs @@ -41,7 +41,7 @@ //! and its network is validated against the wallet at claim (a wrong-network WIF //! is a valid key on the wrong chain, caught before the funding fetch). -use dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use dashcore::secp256k1::{PublicKey, SecretKey}; use dashcore::transaction::special_transaction::TransactionPayload; use dashcore::{Network, PrivateKey, ScriptBuf, Transaction}; use dpp::prelude::AssetLockProof; @@ -160,8 +160,7 @@ fn invalid(msg: impl Into) -> PlatformWalletError { /// is the selector that binds the voucher key to its funded credit output. /// `pub(crate)` so the claim-side proof-assembly tests can build a funding tx. pub(crate) fn voucher_credit_script(voucher_key: &SecretKey) -> ScriptBuf { - let secp = Secp256k1::new(); - let pubkey = PublicKey::from_secret_key(&secp, voucher_key); + let pubkey = PublicKey::from_secret_key(voucher_key); let hash = dashcore::PublicKey::new(pubkey).pubkey_hash(); ScriptBuf::new_p2pkh(&hash) } @@ -541,7 +540,7 @@ mod tests { use dpp::identity::state_transition::asset_lock_proof::InstantAssetLockProof; fn voucher() -> SecretKey { - SecretKey::from_slice(&[0x11u8; 32]).expect("valid scalar") + SecretKey::from_secret_bytes([0x11u8; 32]).expect("valid scalar") } fn inviter_info() -> InviterInfo { @@ -555,7 +554,7 @@ mod tests { /// Build an asset-lock tx whose credit output at `index` pays the voucher /// key (and `index` decoy outputs before it that do not). fn asset_lock_tx_paying_voucher_at(key: &SecretKey, index: usize) -> Transaction { - let decoy = SecretKey::from_slice(&[0x22u8; 32]).unwrap(); + let decoy = SecretKey::from_secret_bytes([0x22u8; 32]).unwrap(); let mut credit_outputs = Vec::new(); for _ in 0..index { credit_outputs.push(TxOut { @@ -593,7 +592,7 @@ mod tests { let decoded = PrivateKey::from_wif(&wif).expect("wif decodes"); assert!(decoded.compressed, "voucher WIF must be compressed"); assert_eq!(decoded.network, network, "network preserved"); - assert_eq!(decoded.inner.secret_bytes(), voucher().secret_bytes()); + assert_eq!(decoded.inner.to_secret_bytes(), voucher().to_secret_bytes()); // Network byte matches bitcoinj/legacy (0xCC mainnet, 0xEF testnet). let raw = bs58::decode(&wif).into_vec().unwrap(); assert_eq!(raw[0], first_byte); @@ -609,7 +608,10 @@ mod tests { assert!(uri.starts_with("dashpay://invite?")); let parsed = parse_invitation_uri(&uri).expect("parse"); - assert_eq!(parsed.voucher_key.secret_bytes(), voucher().secret_bytes()); + assert_eq!( + parsed.voucher_key.to_secret_bytes(), + voucher().to_secret_bytes() + ); assert_eq!(parsed.inviter, Some(info)); assert!(parsed.islock_hex.is_some()); // The parsed txid matches the proof's transaction id (big-endian). @@ -771,7 +773,7 @@ mod tests { #[test] fn voucher_output_index_rejects_no_match() { let key = voucher(); - let other = SecretKey::from_slice(&[0x33u8; 32]).unwrap(); + let other = SecretKey::from_secret_bytes([0x33u8; 32]).unwrap(); let tx = asset_lock_tx_paying_voucher_at(&other, 0); let err = voucher_output_index(&tx, &key).unwrap_err(); assert!(err.to_string().contains("does not control")); @@ -811,7 +813,7 @@ mod tests { fn parse_rejects_duplicate_required_keys() { let wif = PrivateKey::new(voucher(), Network::Testnet).to_wif(); let other = PrivateKey::new( - SecretKey::from_slice(&[0x44u8; 32]).unwrap(), + SecretKey::from_secret_bytes([0x44u8; 32]).unwrap(), Network::Testnet, ) .to_wif(); diff --git a/packages/rs-platform-wallet/src/wallet/identity/crypto/validation.rs b/packages/rs-platform-wallet/src/wallet/identity/crypto/validation.rs index 374bd425440..c14757f7d56 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/crypto/validation.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/crypto/validation.rs @@ -851,12 +851,11 @@ mod tests { /// Derive the compressed secp256k1 pubkey (`[u8; 33]`) for a fixed /// in-range scalar — the shape a breadcrumb re-derivation produces. fn fixed_scalar_and_compressed_pubkey() -> ([u8; 32], [u8; 33]) { - use dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; + use dashcore::secp256k1::{PublicKey, SecretKey}; let mut scalar = [0u8; 32]; scalar[31] = 7; - let secp = Secp256k1::new(); - let sk = SecretKey::from_slice(&scalar).expect("in-range scalar"); - let pubkey = PublicKey::from_secret_key(&secp, &sk).serialize(); + let sk = SecretKey::from_secret_bytes(scalar).expect("in-range scalar"); + let pubkey = PublicKey::from_secret_key(&sk).serialize(); (scalar, pubkey) } diff --git a/packages/rs-platform-wallet/src/wallet/identity/network/contact_info.rs b/packages/rs-platform-wallet/src/wallet/identity/network/contact_info.rs index 965742e2c45..55dfd8402da 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/network/contact_info.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/network/contact_info.rs @@ -514,7 +514,7 @@ impl DashPayView<'_, B> { S: Signer + Send + Sync, C: super::ContactCryptoProvider + Sync, { - use dashcore::secp256k1::rand::{thread_rng, RngCore}; + use dashcore::secp256k1::rand::{rng, RngCore}; use dpp::data_contract::accessors::v0::DataContractV0Getters; // Build the decrypted-payload struct once: it is both the local @@ -696,7 +696,7 @@ impl DashPayView<'_, B> { write_root_id, )?; let mut iv = [0u8; 16]; - thread_rng().fill_bytes(&mut iv); + rng().fill_bytes(&mut iv); let sealed = crypto .contact_info_seal( &root_path, diff --git a/packages/rs-platform-wallet/src/wallet/identity/network/contact_requests.rs b/packages/rs-platform-wallet/src/wallet/identity/network/contact_requests.rs index 8f95fed9279..50d41630dd8 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/network/contact_requests.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/network/contact_requests.rs @@ -241,7 +241,7 @@ impl ContactCryptoProvider for SeedCryptoProvider { PlatformWalletError::InvalidIdentityData(format!("test accountRef derive: {e}")) })?; Ok(platform_encryption::calculate_account_reference( - &xprv.private_key.secret_bytes(), + &xprv.private_key.to_secret_bytes(), compact_xpub, account_index, version, @@ -259,7 +259,7 @@ impl ContactCryptoProvider for SeedCryptoProvider { })?; Ok(platform_encryption::unmask_account_reference( account_reference, - &xprv.private_key.secret_bytes(), + &xprv.private_key.to_secret_bytes(), compact_xpub, )) } @@ -340,7 +340,7 @@ impl SeedCryptoProvider { .map_err(|e| { PlatformWalletError::InvalidIdentityData(format!("test contactInfo derive: {e}")) })?; - Ok(xprv.private_key.secret_bytes()) + Ok(xprv.private_key.to_secret_bytes()) } } @@ -5551,7 +5551,7 @@ mod contact_info_provider_tests { /// the resident `derive_shared_key_ecdh` at the same path. #[tokio::test] async fn ecdh_shared_secret_returns_zeroizing_matching_resident_derivation() { - use dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; + use dashcore::secp256k1::{PublicKey, SecretKey}; let seed = Mnemonic::from_phrase(PHRASE) .expect("valid mnemonic") @@ -5563,8 +5563,7 @@ mod contact_info_provider_tests { .expect("auth path"); let peer = PublicKey::from_secret_key( - &Secp256k1::new(), - &SecretKey::from_slice(&[0x42u8; 32]).expect("peer secret"), + &SecretKey::from_secret_bytes([0x42u8; 32]).expect("peer secret"), ); let provider = SeedCryptoProvider::from_seed(seed, network); diff --git a/packages/rs-platform-wallet/src/wallet/identity/network/discovery.rs b/packages/rs-platform-wallet/src/wallet/identity/network/discovery.rs index 6117a170f7b..8b3c33e150d 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/network/discovery.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/network/discovery.rs @@ -304,7 +304,7 @@ impl IdentityWallet { { candidate_scalars.insert( *key_id, - zeroize::Zeroizing::new(xpriv.private_key.secret_bytes()), + zeroize::Zeroizing::new(xpriv.private_key.to_secret_bytes()), ); } } diff --git a/packages/rs-platform-wallet/src/wallet/identity/network/identity_handle.rs b/packages/rs-platform-wallet/src/wallet/identity/network/identity_handle.rs index 402b6930737..7b568a5bf78 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/network/identity_handle.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/network/identity_handle.rs @@ -147,7 +147,6 @@ pub fn derive_ecdsa_identity_auth_keypair_from_master( identity_index: u32, key_index: u32, ) -> Result { - use dashcore::secp256k1::Secp256k1; use key_wallet::bip32::ExtendedPubKey; let path = identity_auth_derivation_path_for_type( @@ -156,7 +155,6 @@ pub fn derive_ecdsa_identity_auth_keypair_from_master( identity_index, key_index, )?; - let secp = Secp256k1::new(); // `ExtendedPrivKey` doesn't implement `Zeroize`, so we can't // wrap it in `Zeroizing` directly — but its inner // `secp256k1::SecretKey` does implement `Drop` with a memzero, @@ -167,16 +165,16 @@ pub fn derive_ecdsa_identity_auth_keypair_from_master( // returned `private_key` is wrapped in `Zeroizing` below so // the 32-byte scalar copy crossing the function boundary is // also scrubbed on the caller's drop. - let derived = master.derive_priv(&secp, &path).map_err(|e| { + let derived = master.derive_priv(&path).map_err(|e| { PlatformWalletError::InvalidIdentityData(format!( "Failed to derive private key at (identity={identity_index}, key={key_index}): {e}" )) })?; - let extended_pub = ExtendedPubKey::from_priv(&secp, &derived); + let extended_pub = ExtendedPubKey::from_priv(&derived); Ok(DerivedIdentityAuthKey { derivation_path: path, - private_key: Zeroizing::new(derived.private_key.secret_bytes()), + private_key: Zeroizing::new(derived.private_key.to_secret_bytes()), public_key: extended_pub.public_key.serialize(), }) } @@ -196,7 +194,6 @@ pub fn derive_identity_auth_keypair( identity_index: u32, key_index: u32, ) -> Result<(DerivationPath, ExtendedPrivKey, PublicKey), PlatformWalletError> { - use dashcore::secp256k1::Secp256k1; use key_wallet::bip32::ExtendedPubKey; let full_path = identity_auth_derivation_path(network, identity_index, key_index)?; @@ -209,8 +206,7 @@ pub fn derive_identity_auth_keypair( )) })?; - let secp = Secp256k1::new(); - let extended_pub = ExtendedPubKey::from_priv(&secp, &auth_key); + let extended_pub = ExtendedPubKey::from_priv(&auth_key); Ok((full_path, auth_key, extended_pub.public_key)) } @@ -434,7 +430,7 @@ impl IdentityWallet { )) })?; - Ok(Zeroizing::new(secret_key.secret_bytes())) + Ok(Zeroizing::new(secret_key.to_secret_bytes())) } /// Get a read-lock handle to the shared [`WalletManager`]. diff --git a/packages/rs-platform-wallet/src/wallet/identity/network/invitation.rs b/packages/rs-platform-wallet/src/wallet/identity/network/invitation.rs index 76ccd55ce9e..4e17646ad22 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/network/invitation.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/network/invitation.rs @@ -940,7 +940,7 @@ mod tests { use dpp::dashcore::{Network, TxOut}; fn voucher_secret() -> SecretKey { - SecretKey::from_slice(&[0x11u8; 32]).unwrap() + SecretKey::from_secret_bytes([0x11u8; 32]).unwrap() } /// An asset-lock tx whose single credit output pays the voucher key. @@ -1071,7 +1071,7 @@ mod tests { #[test] fn prospective_id_follows_the_selected_credit_output() { let key = voucher_secret(); - let decoy = SecretKey::from_slice(&[0x22u8; 32]).unwrap(); + let decoy = SecretKey::from_secret_bytes([0x22u8; 32]).unwrap(); let payload = AssetLockPayload { version: 1, credit_outputs: vec![ diff --git a/packages/rs-platform-wallet/src/wallet/identity/network/payments.rs b/packages/rs-platform-wallet/src/wallet/identity/network/payments.rs index 940b8da96ec..ad136c8ae71 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/network/payments.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/network/payments.rs @@ -1856,10 +1856,9 @@ mod tests { .wallet .derive_extended_private_key(path) .map_err(|e| e.to_string())?; - let secp = dashcore::secp256k1::Secp256k1::new(); let msg = dashcore::secp256k1::Message::from_digest(sighash); - let sig = secp.sign_ecdsa(&msg, &xprv.private_key); - let pk = dashcore::secp256k1::PublicKey::from_secret_key(&secp, &xprv.private_key); + let sig = xprv.private_key.sign_ecdsa(msg); + let pk = dashcore::secp256k1::PublicKey::from_secret_key(&xprv.private_key); Ok((sig, pk)) } @@ -1871,9 +1870,7 @@ mod tests { .wallet .derive_extended_private_key(path) .map_err(|e| e.to_string())?; - let secp = dashcore::secp256k1::Secp256k1::new(); Ok(dashcore::secp256k1::PublicKey::from_secret_key( - &secp, &xprv.private_key, )) } @@ -2028,8 +2025,7 @@ mod tests { use dpp::identity::identity_public_key::v0::IdentityPublicKeyV0; use dpp::identity::{IdentityPublicKey, SecurityLevel}; let data = dashcore::secp256k1::PublicKey::from_secret_key( - &dashcore::secp256k1::Secp256k1::new(), - &dashcore::secp256k1::SecretKey::from_slice(&[0x37u8; 32]).expect("secret"), + &dashcore::secp256k1::SecretKey::from_secret_bytes([0x37u8; 32]).expect("secret"), ) .serialize() .to_vec(); @@ -5493,8 +5489,7 @@ mod tests { key_type: KeyType::ECDSA_SECP256K1, read_only: false, data: dashcore::secp256k1::PublicKey::from_secret_key( - &dashcore::secp256k1::Secp256k1::new(), - &dashcore::secp256k1::SecretKey::from_slice(&[0x24u8; 32]).expect("secret"), + &dashcore::secp256k1::SecretKey::from_secret_bytes([0x24u8; 32]).expect("secret"), ) .serialize() .to_vec() @@ -5762,11 +5757,9 @@ mod tests { let provider = SeedCryptoProvider::from_seed(seed, Network::Testnet); // The contact's encryption keypair (the "sender" of the request). - let secp = dashcore::secp256k1::Secp256k1::new(); - let contact_secret = dashcore::secp256k1::SecretKey::from_slice(&[0x42u8; 32]) + let contact_secret = dashcore::secp256k1::SecretKey::from_secret_bytes([0x42u8; 32]) .expect("valid contact secret"); - let contact_public = - dashcore::secp256k1::PublicKey::from_secret_key(&secp, &contact_secret); + let contact_public = dashcore::secp256k1::PublicKey::from_secret_key(&contact_secret); // Our side, through the production provider. let ours = provider @@ -5850,7 +5843,6 @@ mod tests { let owner = Identifier::from([0xAA; 32]); let contact = Identifier::from([0xBB; 32]); - let secp = dashcore::secp256k1::Secp256k1::new(); let key_at = |id: u32, purpose: Purpose, byte: u8| { IdentityPublicKey::V0(IdentityPublicKeyV0 { id, @@ -5860,8 +5852,7 @@ mod tests { key_type: KeyType::ECDSA_SECP256K1, read_only: false, data: dashcore::secp256k1::PublicKey::from_secret_key( - &secp, - &dashcore::secp256k1::SecretKey::from_slice(&[byte; 32]).expect("secret"), + &dashcore::secp256k1::SecretKey::from_secret_bytes([byte; 32]).expect("secret"), ) .serialize() .to_vec() diff --git a/packages/rs-platform-wallet/src/wallet/masternode_withdrawal.rs b/packages/rs-platform-wallet/src/wallet/masternode_withdrawal.rs index 4ecf07f3b14..85e99301f1a 100644 --- a/packages/rs-platform-wallet/src/wallet/masternode_withdrawal.rs +++ b/packages/rs-platform-wallet/src/wallet/masternode_withdrawal.rs @@ -30,7 +30,7 @@ use std::fmt; use async_trait::async_trait; use dashcore::hashes::{hash160, sha256d, Hash}; use dashcore::secp256k1::ecdsa::{RecoverableSignature, RecoveryId}; -use dashcore::secp256k1::{Message, Secp256k1}; +use dashcore::secp256k1::Message; use dashcore::signer::CompactSignature; use dashcore::{Address as DashAddress, AddressType, Network, ScriptBuf}; use dpp::address_funds::AddressWitness; @@ -533,7 +533,7 @@ pub struct RawSecretCoreSigner { impl RawSecretCoreSigner { /// `secret` must be a valid secp256k1 scalar (32 bytes). pub fn from_bytes(secret: &[u8; 32]) -> Result { - let secret = dashcore::secp256k1::SecretKey::from_slice(secret).map_err(|_| { + let secret = dashcore::secp256k1::SecretKey::from_secret_bytes(*secret).map_err(|_| { PlatformWalletError::InvalidParameter("not a valid secp256k1 private key".to_string()) })?; Ok(Self { secret }) @@ -541,8 +541,7 @@ impl RawSecretCoreSigner { /// hash160 of this key's compressed public key. pub fn public_key_hash160(&self) -> [u8; 20] { - let secp = Secp256k1::signing_only(); - let public = dashcore::secp256k1::PublicKey::from_secret_key(&secp, &self.secret); + let public = dashcore::secp256k1::PublicKey::from_secret_key(&self.secret); hash160::Hash::hash(&public.serialize()).to_byte_array() } } @@ -573,11 +572,10 @@ impl CoreSigner for RawSecretCoreSigner { ), Self::Error, > { - let secp = Secp256k1::new(); let msg = Message::from_digest(sighash); Ok(( - secp.sign_ecdsa(&msg, &self.secret), - dashcore::secp256k1::PublicKey::from_secret_key(&secp, &self.secret), + self.secret.sign_ecdsa(msg), + dashcore::secp256k1::PublicKey::from_secret_key(&self.secret), )) } @@ -586,7 +584,6 @@ impl CoreSigner for RawSecretCoreSigner { _path: &DerivationPath, ) -> Result { Ok(dashcore::secp256k1::PublicKey::from_secret_key( - &Secp256k1::new(), &self.secret, )) } @@ -703,14 +700,14 @@ where ))); } - let secp = Secp256k1::verification_only(); let msg = Message::from_digest(digest); let compact = signature.serialize_compact(); let recoverable = (0..4i32) .filter_map(|id| RecoveryId::try_from(id).ok()) .filter_map(|recid| RecoverableSignature::from_compact(&compact, recid).ok()) .find(|candidate| { - secp.recover_ecdsa(&msg, candidate) + candidate + .recover_ecdsa(msg) .is_ok_and(|recovered| recovered == public_key) }) .ok_or_else(|| { @@ -763,22 +760,21 @@ mod tests { _path: &DerivationPath, sighash: [u8; 32], ) -> Result<(dashcore::secp256k1::ecdsa::Signature, PublicKey), Self::Error> { - let secp = Secp256k1::new(); let msg = Message::from_digest(sighash); Ok(( - secp.sign_ecdsa(&msg, &self.secret), - PublicKey::from_secret_key(&secp, &self.secret), + self.secret.sign_ecdsa(msg), + PublicKey::from_secret_key(&self.secret), )) } async fn public_key(&self, _path: &DerivationPath) -> Result { - Ok(PublicKey::from_secret_key(&Secp256k1::new(), &self.secret)) + Ok(PublicKey::from_secret_key(&self.secret)) } } fn fixture() -> (FixedKeySigner, [u8; 20], IdentityPublicKey) { - let secret = SecretKey::from_slice(&[0x42u8; 32]).expect("valid scalar"); - let pubkey = PublicKey::from_secret_key(&Secp256k1::new(), &secret); + let secret = SecretKey::from_secret_bytes([0x42u8; 32]).expect("valid scalar"); + let pubkey = PublicKey::from_secret_key(&secret); let hash: [u8; 20] = hash160::Hash::hash(&pubkey.serialize()).to_byte_array(); let key = IdentityPublicKey::V0(IdentityPublicKeyV0 { id: 0, diff --git a/packages/rs-platform-wallet/src/wallet/platform_addresses/provider.rs b/packages/rs-platform-wallet/src/wallet/platform_addresses/provider.rs index 6eb140ab58b..d522927468f 100644 --- a/packages/rs-platform-wallet/src/wallet/platform_addresses/provider.rs +++ b/packages/rs-platform-wallet/src/wallet/platform_addresses/provider.rs @@ -1142,7 +1142,6 @@ impl PlatformPaymentAddressProvider { #[cfg(test)] mod tests { use super::*; - use dashcore::secp256k1::Secp256k1; use key_wallet::bip32::ExtendedPrivKey; use key_wallet::Network; use key_wallet_manager::WalletManager; @@ -1151,10 +1150,9 @@ mod tests { const ACCOUNT: u32 = 0; fn test_xpub() -> ExtendedPubKey { - let secp = Secp256k1::new(); let seed = [42u8; 32]; let xprv = ExtendedPrivKey::new_master(Network::Testnet, &seed).expect("master xprv"); - ExtendedPubKey::from_priv(&secp, &xprv) + ExtendedPubKey::from_priv(&xprv) } fn p2pkh(byte: u8) -> PlatformP2PKHAddress { diff --git a/packages/rs-platform-wallet/src/wallet/provider_ecdsa_key_tests.rs b/packages/rs-platform-wallet/src/wallet/provider_ecdsa_key_tests.rs index 2e38a340120..6cd3bd07510 100644 --- a/packages/rs-platform-wallet/src/wallet/provider_ecdsa_key_tests.rs +++ b/packages/rs-platform-wallet/src/wallet/provider_ecdsa_key_tests.rs @@ -100,7 +100,6 @@ async fn private_reveal_is_internally_consistent() { let wallet = platform_wallet().await; let network = wallet_network(&wallet).await; - let secp = dashcore::key::Secp256k1::new(); for kind in [ProviderKeyKind::Owner, ProviderKeyKind::Voting] { for index in [0u32, 1, 19] { @@ -115,21 +114,21 @@ async fn private_reveal_is_internally_consistent() { // WIF and raw scalar must be the same key. let from_wif = PrivateKey::from_wif(wif).expect("valid WIF"); assert_eq!( - from_wif.inner.secret_bytes().to_vec(), + from_wif.inner.to_secret_bytes().to_vec(), **scalar, "{kind:?}#{index}: WIF and raw scalar disagree" ); // The reported public key must be this private key's. assert_eq!( - from_wif.public_key(&secp).to_bytes(), + from_wif.public_key().to_bytes(), derived.public_key_bytes, "{kind:?}#{index}: public key does not belong to the returned private key" ); // ...and the reported address must be that public key's P2PKH on // this wallet's own network, not a hardcoded chain. - let expected = dashcore::Address::p2pkh(&from_wif.public_key(&secp), network); + let expected = dashcore::Address::p2pkh(&from_wif.public_key(), network); assert_eq!( address, &expected.to_string(), diff --git a/packages/rs-platform-wallet/src/wallet/provider_key_at_index.rs b/packages/rs-platform-wallet/src/wallet/provider_key_at_index.rs index 7568ab06cfe..6d86b5946a9 100644 --- a/packages/rs-platform-wallet/src/wallet/provider_key_at_index.rs +++ b/packages/rs-platform-wallet/src/wallet/provider_key_at_index.rs @@ -635,7 +635,6 @@ impl PlatformWallet { "failed to build master xpriv: {e}" )) })?; - let secp = dashcore::key::Secp256k1::new(); // The ACCOUNT's own path, not `account_type.derivation_path(network)`. // The public side above comes off `account.account_xpub`, built from // this path using the ACCOUNT's network; resolving it again from the @@ -654,11 +653,11 @@ impl PlatformWallet { )) })?; let mut child_xpriv = master - .derive_priv(&secp, &account_path) + .derive_priv(&account_path) .and_then(|acct| { let child_path: key_wallet::bip32::DerivationPath = vec![child].into(); - acct.derive_priv(&secp, &child_path) + acct.derive_priv(&child_path) }) .map_err(|e| { PlatformWalletError::KeyDerivation(format!( @@ -666,7 +665,7 @@ impl PlatformWallet { )) })?; let mut private = child_xpriv.to_priv(); - let derived_public = private.public_key(&secp); + let derived_public = private.public_key(); // Produce every output while the scalar is still live, // then erase it. `dashcore::PrivateKey` is `Copy` and @@ -677,7 +676,7 @@ impl PlatformWallet { // the `PrivateKey` itself. let outputs = if derived_public == public_key { Some(( - Zeroizing::new(private.inner.secret_bytes().to_vec()), + Zeroizing::new(private.inner.to_secret_bytes().to_vec()), Zeroizing::new(private.to_wif()), )) } else { @@ -1096,7 +1095,6 @@ mod tests { let wallet = seed_bearing_wallet(network); let seed = wallet.wallet_seed_bytes().expect("resident seed"); let master = ExtendedPrivKey::new_master(network, &seed).expect("master xpriv"); - let secp = dashcore::key::Secp256k1::new(); for (kind, family) in [ (ProviderKeyKind::Owner, "2'"), @@ -1115,11 +1113,11 @@ mod tests { let path = DerivationPath::from_str(&format!("m/9'/{coin}/3'/{family}/{index}")) .expect("explicit DIP-3 path"); - let expected = master.derive_priv(&secp, &path).expect("path derivation"); + let expected = master.derive_priv(&path).expect("path derivation"); assert_eq!( - derived.inner.secret_bytes(), - expected.private_key.secret_bytes(), + derived.inner.to_secret_bytes(), + expected.private_key.to_secret_bytes(), "{kind:?} key at index {index} on {network:?} must come from \ m/9'/{coin}/3'/{family}/{index}" ); @@ -1150,14 +1148,13 @@ mod tests { let master = ExtendedPrivKey::new_master(Network::Mainnet, &seed).expect("master"); let doubled = master .derive_priv( - &dashcore::key::Secp256k1::new(), &DerivationPath::from_str("m/9'/5'/3'/1'/9'/5'/3'/1'/19").expect("doubled path"), ) .expect("doubled derivation"); assert_ne!( - derived.inner.secret_bytes(), - doubled.private_key.secret_bytes(), + derived.inner.to_secret_bytes(), + doubled.private_key.to_secret_bytes(), "the account derivation path is being applied twice again" ); } @@ -1181,7 +1178,6 @@ mod tests { let wallet = seed_bearing_wallet(Network::Mainnet); let seed = wallet.wallet_seed_bytes().expect("resident seed"); - let secp = dashcore::key::Secp256k1::new(); let master = ExtendedPrivKey::new_master(Network::Mainnet, &seed).expect("master"); for (kind, family) in [ @@ -1216,22 +1212,21 @@ mod tests { let child = ChildNumber::from_normal_idx(19).expect("child index"); let child_path: DerivationPath = vec![child].into(); let derived = master - .derive_priv(&secp, &account_path) - .and_then(|acct| acct.derive_priv(&secp, &child_path)) + .derive_priv(&account_path) + .and_then(|acct| acct.derive_priv(&child_path)) .expect("gate-free derivation") .to_priv(); let expected = master .derive_priv( - &secp, &DerivationPath::from_str(&format!("m/9'/5'/3'/{family}/19")) .expect("explicit path"), ) .expect("path derivation"); assert_eq!( - derived.inner.secret_bytes(), - expected.private_key.secret_bytes(), + derived.inner.to_secret_bytes(), + expected.private_key.to_secret_bytes(), "{kind:?} watch-only derivation must match m/9'/5'/3'/{family}/19" ); } diff --git a/packages/rs-scripts/src/bin/register_identity.rs b/packages/rs-scripts/src/bin/register_identity.rs index f8c5f873b34..5caa3060869 100644 --- a/packages/rs-scripts/src/bin/register_identity.rs +++ b/packages/rs-scripts/src/bin/register_identity.rs @@ -88,7 +88,6 @@ use dash_sdk::platform::types::epoch::Epoch; use dash_sdk::{Sdk, SdkBuilder}; use dpp::balances::credits::CREDITS_PER_DUFF; use dpp::dashcore::consensus::encode::{deserialize, serialize}; -use dpp::dashcore::secp256k1::Secp256k1; use dpp::dashcore::transaction::special_transaction::asset_lock::AssetLockPayload; use dpp::dashcore::transaction::special_transaction::TransactionPayload; use dpp::dashcore::{ @@ -515,11 +514,10 @@ async fn run() -> Result<(), String> { } else { // FRESH: generate a one-time key, build + Core-sign + broadcast the // asset lock, capturing all recovery credentials BEFORE broadcast. - let secp = Secp256k1::new(); - let mut secp_rng = dpp::dashcore::secp256k1::rand::thread_rng(); + let mut secp_rng = dpp::dashcore::secp256k1::rand::rng(); let one_time_secret = dpp::dashcore::secp256k1::SecretKey::new(&mut secp_rng); let one_time_private_key = PrivateKey::new(one_time_secret, network); - let one_time_public_key = one_time_private_key.public_key(&secp); + let one_time_public_key = one_time_private_key.public_key(); let one_time_key_hash = one_time_public_key.pubkey_hash(); let one_time_address = Address::p2pkh(&one_time_public_key, network); diff --git a/packages/rs-sdk-ffi/src/address/transitions/transfer.rs b/packages/rs-sdk-ffi/src/address/transitions/transfer.rs index 7e8523710eb..a3ef56455f6 100644 --- a/packages/rs-sdk-ffi/src/address/transitions/transfer.rs +++ b/packages/rs-sdk-ffi/src/address/transitions/transfer.rs @@ -59,8 +59,9 @@ impl Signer for AddressSigner { })?; // Sign the data using dashcore signer - let signature = dash_sdk::dpp::dashcore::signer::sign(data, private_key.inner.as_ref()) - .map_err(|e| ProtocolError::Generic(format!("Signing failed: {}", e)))?; + let signature = + dash_sdk::dpp::dashcore::signer::sign(data, private_key.inner.as_secret_bytes()) + .map_err(|e| ProtocolError::Generic(format!("Signing failed: {}", e)))?; Ok(BinaryData::new(signature.to_vec())) } @@ -83,8 +84,9 @@ impl Signer for AddressSigner { })?; // Sign the data - let signature = dash_sdk::dpp::dashcore::signer::sign(data, private_key.inner.as_ref()) - .map_err(|e| ProtocolError::Generic(format!("Signing failed: {}", e)))?; + let signature = + dash_sdk::dpp::dashcore::signer::sign(data, private_key.inner.as_secret_bytes()) + .map_err(|e| ProtocolError::Generic(format!("Signing failed: {}", e)))?; // Create P2PKH witness (most common for single key) Ok(AddressWitness::P2pkh { @@ -236,7 +238,10 @@ unsafe fn dash_sdk_address_transfer_funds_inner( // Parse private key (32 bytes) let pk_bytes = std::slice::from_raw_parts(input.private_key, 32); - let secret_key = match SecretKey::from_slice(pk_bytes) { + let secret_key = match <[u8; 32]>::try_from(pk_bytes) + .map_err(|_| dash_sdk::dpp::dashcore::secp256k1::Error::InvalidSecretKey) + .and_then(SecretKey::from_secret_bytes) + { Ok(sk) => sk, Err(e) => { return DashSDKResult::error(DashSDKError::new( diff --git a/packages/rs-sdk-ffi/src/address/transitions/withdraw.rs b/packages/rs-sdk-ffi/src/address/transitions/withdraw.rs index 54f7d590fb3..db685b4bf0b 100644 --- a/packages/rs-sdk-ffi/src/address/transitions/withdraw.rs +++ b/packages/rs-sdk-ffi/src/address/transitions/withdraw.rs @@ -210,7 +210,10 @@ unsafe fn dash_sdk_address_withdraw_funds_inner( // Parse private key (32 bytes) let pk_bytes = std::slice::from_raw_parts(input.private_key, 32); - let secret_key = match SecretKey::from_slice(pk_bytes) { + let secret_key = match <[u8; 32]>::try_from(pk_bytes) + .map_err(|_| dash_sdk::dpp::dashcore::secp256k1::Error::InvalidSecretKey) + .and_then(SecretKey::from_secret_bytes) + { Ok(sk) => sk, Err(e) => { return DashSDKResult::error(DashSDKError::new( diff --git a/packages/rs-sdk-ffi/src/contested_resource/transitions/cast_vote.rs b/packages/rs-sdk-ffi/src/contested_resource/transitions/cast_vote.rs index 6a8570f0309..2451b3ce171 100644 --- a/packages/rs-sdk-ffi/src/contested_resource/transitions/cast_vote.rs +++ b/packages/rs-sdk-ffi/src/contested_resource/transitions/cast_vote.rs @@ -61,7 +61,7 @@ use crate::sdk::SDKWrapper; use crate::types::{FFINetwork, Network, SDKHandle}; use crate::{DashSDKResult, FFIError}; use dash_sdk::dpp::dashcore::hashes::{hash160, Hash}; -use dash_sdk::dpp::dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use dash_sdk::dpp::dashcore::secp256k1::{PublicKey, SecretKey}; use dash_sdk::dpp::dashcore::ProTxHash; use dash_sdk::dpp::platform_value::{Identifier, Value}; use dash_sdk::dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; @@ -341,10 +341,9 @@ unsafe fn cast_vote_inner( // `masternode_voting_key.public_key_hash()` to derive the voter // identifier, and `SingleKeySigner::can_sign_with` recomputes the same // hash160 from the private key, so the two agree by construction. - let secp = Secp256k1::new(); - let secret_key = SecretKey::from_byte_array(&key_array) + let secret_key = SecretKey::from_secret_bytes(*key_array) .map_err(|e| invalid(&format!("Invalid voting private key: {}", e)))?; - let public_key = PublicKey::from_secret_key(&secp, &secret_key); + let public_key = PublicKey::from_secret_key(&secret_key); let voting_address = hash160::Hash::hash(&public_key.serialize()).to_byte_array(); // ---- Broadcast, then diagnose only on failure --------------------------- diff --git a/packages/rs-sdk-ffi/src/identity/create_from_addresses.rs b/packages/rs-sdk-ffi/src/identity/create_from_addresses.rs index c90e2e3dae3..cc32e028811 100644 --- a/packages/rs-sdk-ffi/src/identity/create_from_addresses.rs +++ b/packages/rs-sdk-ffi/src/identity/create_from_addresses.rs @@ -170,7 +170,10 @@ unsafe fn dash_sdk_identity_create_from_addresses_inner( // Parse private key (32 bytes) let pk_bytes = std::slice::from_raw_parts(input.private_key, 32); - let secret_key = match SecretKey::from_slice(pk_bytes) { + let secret_key = match <[u8; 32]>::try_from(pk_bytes) + .map_err(|_| dash_sdk::dpp::dashcore::secp256k1::Error::InvalidSecretKey) + .and_then(SecretKey::from_secret_bytes) + { Ok(sk) => sk, Err(e) => { return DashSDKResult::error(DashSDKError::new( diff --git a/packages/rs-sdk-ffi/src/identity/helpers.rs b/packages/rs-sdk-ffi/src/identity/helpers.rs index e92ec59259d..3dcb3e647d6 100644 --- a/packages/rs-sdk-ffi/src/identity/helpers.rs +++ b/packages/rs-sdk-ffi/src/identity/helpers.rs @@ -88,7 +88,7 @@ pub unsafe fn parse_private_key( private_key_bytes: *const [u8; 32], ) -> Result { let key_bytes = *private_key_bytes; - let secret_key = dashcore::secp256k1::SecretKey::from_byte_array(&key_bytes) + let secret_key = dashcore::secp256k1::SecretKey::from_secret_bytes(key_bytes) .map_err(|e| FFIError::InternalError(format!("Invalid private key: {}", e)))?; Ok(PrivateKey::new(secret_key, Network::Mainnet)) } diff --git a/packages/rs-sdk-ffi/src/identity/top_up_from_addresses.rs b/packages/rs-sdk-ffi/src/identity/top_up_from_addresses.rs index c40346e102b..9cc74ccd280 100644 --- a/packages/rs-sdk-ffi/src/identity/top_up_from_addresses.rs +++ b/packages/rs-sdk-ffi/src/identity/top_up_from_addresses.rs @@ -151,7 +151,10 @@ unsafe fn dash_sdk_identity_top_up_from_addresses_inner( // Parse private key (32 bytes) let pk_bytes = std::slice::from_raw_parts(input.private_key, 32); - let secret_key = match SecretKey::from_slice(pk_bytes) { + let secret_key = match <[u8; 32]>::try_from(pk_bytes) + .map_err(|_| dash_sdk::dpp::dashcore::secp256k1::Error::InvalidSecretKey) + .and_then(SecretKey::from_secret_bytes) + { Ok(sk) => sk, Err(e) => { return DashSDKResult::error(DashSDKError::new( diff --git a/packages/rs-sdk-ffi/src/mnemonic_resolver_core_signer.rs b/packages/rs-sdk-ffi/src/mnemonic_resolver_core_signer.rs index e6a9367c4ab..c4be3c24dc6 100644 --- a/packages/rs-sdk-ffi/src/mnemonic_resolver_core_signer.rs +++ b/packages/rs-sdk-ffi/src/mnemonic_resolver_core_signer.rs @@ -52,7 +52,7 @@ //! seed, and the final derived 32-byte scalar. //! - **The `WipingSecretKey` RAII guard** scrubs the raw //! [`secp256k1::SecretKey`] copies at the two sign sites, where the -//! scalar comes back out of `SecretKey::from_slice`. `SecretKey` is an +//! scalar comes back out of `SecretKey::from_secret_bytes`. `SecretKey` is an //! upstream secp256k1 type with no `Zeroize` impl (only //! `non_secure_erase()`), so it can't ride a `Zeroizing` wrapper; the //! guard wipes it on every exit path — normal return, `?`-early-return, @@ -67,7 +67,7 @@ use std::os::raw::c_char; use async_trait::async_trait; use key_wallet::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey}; -use key_wallet::dashcore::secp256k1::{self, Secp256k1}; +use key_wallet::dashcore::secp256k1; use key_wallet::dip9::{ DASHPAY_CONTACT_INFO_ENC_TO_USER_ID_CHILD, DASHPAY_CONTACT_INFO_PRIVATE_DATA_CHILD, FEATURE_PURPOSE, FEATURE_PURPOSE_DASHPAY_AUTO_ACCEPT, FEATURE_PURPOSE_IDENTITIES, @@ -330,11 +330,10 @@ impl MnemonicResolverCoreSigner { let seed: Zeroizing<[u8; 64]> = Zeroizing::new(mnemonic.to_seed("")); drop(mnemonic); - let secp = Secp256k1::new(); let master = ExtendedPrivKey::new_master(self.network, seed.as_ref()) .map_err(|e| MnemonicResolverSignerError::DerivationFailed(format!("master: {e}")))?; let derived = master - .derive_priv(&secp, path) + .derive_priv(path) .map_err(|e| MnemonicResolverSignerError::DerivationFailed(format!("path: {e}")))?; Ok(extract(&derived)) @@ -350,10 +349,10 @@ impl MnemonicResolverCoreSigner { &self, path: &DerivationPath, ) -> Result, MnemonicResolverSignerError> { - // `secret_bytes()` copies the scalar out of the borrowed key; the + // `to_secret_bytes()` copies the scalar out of the borrowed key; the // `ExtendedPrivKey` itself never leaves `resolve_and_derive`. self.resolve_and_derive(path, |derived| { - Zeroizing::new(derived.private_key.secret_bytes()) + Zeroizing::new(derived.private_key.to_secret_bytes()) }) } @@ -607,7 +606,7 @@ pub struct ContactInfoOpened { /// /// `SecretKey` is an upstream secp256k1 type with no `Zeroize` impl (only /// `non_secure_erase()`), so it can't ride a `Zeroizing` wrapper. Wrapping the -/// `SecretKey::from_slice` copy here wipes it on every exit path — normal +/// `SecretKey::from_secret_bytes` copy here wipes it on every exit path — normal /// return, `?`-early-return, and panic-unwind — closing the leak window a bare /// inline `non_secure_erase()` would leave open between construction and the /// manual scrub. This is the one key intermediate that upstream key-wallet's @@ -637,31 +636,29 @@ impl Signer for MnemonicResolverCoreSigner { sighash: [u8; 32], ) -> Result<(secp256k1::ecdsa::Signature, secp256k1::PublicKey), Self::Error> { let secret_bytes = self.derive_priv(path)?; - let secp = Secp256k1::new(); - // `SecretKey::from_slice` validates the 32-byte scalar is a + // `SecretKey::from_secret_bytes` validates the 32-byte scalar is a // legitimate field element. The `WipingSecretKey` guard scrubs this // separate copy on every exit path, including a panic between here and // the return — `Zeroizing<[u8;32]>` already covers `secret_bytes`. let secret = WipingSecretKey( - secp256k1::SecretKey::from_slice(secret_bytes.as_ref()) + secp256k1::SecretKey::from_secret_bytes(*secret_bytes) .map_err(|e| MnemonicResolverSignerError::InvalidScalar(e.to_string()))?, ); let msg = secp256k1::Message::from_digest(sighash); - let signature = secp.sign_ecdsa(&msg, &secret.0); - let pubkey = secp256k1::PublicKey::from_secret_key(&secp, &secret.0); + let signature = secret.0.sign_ecdsa(msg); + let pubkey = secp256k1::PublicKey::from_secret_key(&secret.0); Ok((signature, pubkey)) } async fn public_key(&self, path: &DerivationPath) -> Result { let secret_bytes = self.derive_priv(path)?; - let secp = Secp256k1::new(); - // `WipingSecretKey` scrubs this `from_slice` copy on every exit path, + // `WipingSecretKey` scrubs this `from_secret_bytes` copy on every exit path, // including panic-unwind — `Zeroizing<[u8;32]>` covers `secret_bytes`. let secret = WipingSecretKey( - secp256k1::SecretKey::from_slice(secret_bytes.as_ref()) + secp256k1::SecretKey::from_secret_bytes(*secret_bytes) .map_err(|e| MnemonicResolverSignerError::InvalidScalar(e.to_string()))?, ); - let pubkey = secp256k1::PublicKey::from_secret_key(&secp, &secret.0); + let pubkey = secp256k1::PublicKey::from_secret_key(&secret.0); Ok(pubkey) } } @@ -680,10 +677,9 @@ impl ExtendedPubKeySigner for MnemonicResolverCoreSigner { &self, path: &DerivationPath, ) -> Result { - let secp = Secp256k1::new(); // `ExtendedPubKey` carries only public material (chain code + point); // the borrowed private key never leaves `resolve_and_derive`. - self.resolve_and_derive(path, |derived| ExtendedPubKey::from_priv(&secp, derived)) + self.resolve_and_derive(path, ExtendedPubKey::from_priv) } } @@ -750,9 +746,8 @@ mod tests { .await .expect("signing succeeds"); - let secp = Secp256k1::new(); let msg = secp256k1::Message::from_digest(sighash); - secp.verify_ecdsa(&msg, &sig, &pk) + sig.verify(msg, &pk) .expect("signature must verify against returned pubkey"); unsafe { dash_sdk_mnemonic_resolver_destroy(resolver) }; @@ -899,12 +894,11 @@ mod tests { // Independently derive the expected xpub straight from the known // BIP-39 vector — same network + path, no resolver in the loop. - let secp = Secp256k1::new(); let mnemonic = parse_mnemonic_any_language(ENGLISH_PHRASE).expect("valid phrase"); let master = ExtendedPrivKey::new_master(Network::Testnet, &mnemonic.to_seed("")) .expect("master derivation"); - let derived = master.derive_priv(&secp, &path).expect("path derivation"); - let expected = ExtendedPubKey::from_priv(&secp, &derived); + let derived = master.derive_priv(&path).expect("path derivation"); + let expected = ExtendedPubKey::from_priv(&derived); // Field-level checks run first so a silently-dropped BIP-32 metadatum // fails here with a precise message — not just the public point. The @@ -1005,9 +999,9 @@ mod tests { let path = test_path(); // A fixed peer keypair (the contact's encryption key). - let secp = Secp256k1::new(); - let peer_sk = secp256k1::SecretKey::from_slice(&[0x42u8; 32]).expect("peer secret key"); - let peer_pk = secp256k1::PublicKey::from_secret_key(&secp, &peer_sk); + let peer_sk = + secp256k1::SecretKey::from_secret_bytes([0x42u8; 32]).expect("peer secret key"); + let peer_pk = secp256k1::PublicKey::from_secret_key(&peer_sk); // Old route: resident-seed wallet from the same mnemonic → derive the // scalar at `path` → ECDH through the single crypto source. @@ -1072,7 +1066,7 @@ mod tests { .derive_extended_private_key(&path) .expect("wallet derives the private key at path") .private_key - .secret_bytes(); + .to_secret_bytes(); let expected = platform_encryption::calculate_account_reference( &secret, &compact_xpub, @@ -1164,7 +1158,7 @@ mod tests { .derive_extended_private_key(&path) .expect("derive encToUserId key") .private_key - .secret_bytes() + .to_secret_bytes() }; let expected_enc = platform_encryption::encrypt_enc_to_user_id(&enc_key, &contact_id); assert_eq!( diff --git a/packages/rs-sdk-ffi/src/signer_simple.rs b/packages/rs-sdk-ffi/src/signer_simple.rs index e3b3d34e2ba..3ad020582d8 100644 --- a/packages/rs-sdk-ffi/src/signer_simple.rs +++ b/packages/rs-sdk-ffi/src/signer_simple.rs @@ -311,7 +311,6 @@ pub unsafe extern "C" fn dash_sdk_sign_with_mnemonic_and_path( out_signature_len: *mut usize, out_error: *mut u8, ) -> i32 { - use dash_sdk::dpp::dashcore::secp256k1::Secp256k1; use dash_sdk::dpp::identity::KeyType; use key_wallet::bip32::{DerivationPath, ExtendedPrivKey}; use std::ffi::CStr; @@ -396,8 +395,7 @@ pub unsafe extern "C" fn dash_sdk_sign_with_mnemonic_and_path( Ok(m) => m, Err(_) => return fail(SIGN_WITH_MNEMONIC_ERR_DERIVATION), }; - let secp = Secp256k1::new(); - let derived = match master.derive_priv(&secp, &path) { + let derived = match master.derive_priv(&path) { Ok(d) => d, Err(_) => return fail(SIGN_WITH_MNEMONIC_ERR_DERIVATION), }; @@ -406,7 +404,7 @@ pub unsafe extern "C" fn dash_sdk_sign_with_mnemonic_and_path( // returns. `derived` self-wipes separately: `ExtendedPrivKey` // zeroizes on `Drop`. let secret_bytes: zeroize::Zeroizing<[u8; 32]> = - zeroize::Zeroizing::new(derived.private_key.secret_bytes()); + zeroize::Zeroizing::new(derived.private_key.to_secret_bytes()); // ---- Sign --------------------------------------------------------------- // `dashcore::signer::sign` returns a 65-byte compact recoverable diff --git a/packages/rs-sdk/src/platform/dashpay/contact_request.rs b/packages/rs-sdk/src/platform/dashpay/contact_request.rs index e40be3284e4..a435dad8d79 100644 --- a/packages/rs-sdk/src/platform/dashpay/contact_request.rs +++ b/packages/rs-sdk/src/platform/dashpay/contact_request.rs @@ -6,7 +6,7 @@ use crate::platform::transition::put_document::PutDocument; use crate::platform::Document; use crate::{Error, Sdk}; use dpp::dashcore::secp256k1::rand::rngs::StdRng; -use dpp::dashcore::secp256k1::rand::{RngCore, SeedableRng}; +use dpp::dashcore::secp256k1::rand::{Rng, RngCore, SeedableRng}; use dpp::dashcore::secp256k1::{PublicKey, SecretKey}; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; @@ -365,7 +365,7 @@ impl Sdk { } // Generate random IVs for encryption - let mut rng = StdRng::from_entropy(); + let mut rng = StdRng::from_os_rng(); let mut xpub_iv = [0u8; 16]; rng.fill_bytes(&mut xpub_iv); @@ -410,8 +410,8 @@ impl Sdk { })?; // Generate entropy for document ID - let mut rng = StdRng::from_entropy(); - let entropy = Bytes32::random_with_rng(&mut rng); + let mut rng = StdRng::from_os_rng(); + let entropy = Bytes32::new(rng.random()); // Generate document ID let sender_id = input.sender_identity.id().to_owned(); @@ -573,15 +573,14 @@ impl Sdk { #[cfg(test)] mod tests { use super::*; + use dpp::dashcore::secp256k1; use dpp::dashcore::secp256k1::rand::{self, RngCore}; - use dpp::dashcore::secp256k1::Secp256k1; #[test] fn test_ecdh_encryption_produces_correct_size() { // Test that ECDH encryption produces the correct output sizes - let secp = Secp256k1::new(); - let (secret1, _public1) = secp.generate_keypair(&mut rand::thread_rng()); - let (_secret2, public2) = secp.generate_keypair(&mut rand::thread_rng()); + let (secret1, _public1) = secp256k1::generate_keypair(&mut rand::rng()); + let (_secret2, public2) = secp256k1::generate_keypair(&mut rand::rng()); // Derive shared key let shared_key = derive_shared_key_ecdh(&secret1, &public2); @@ -589,8 +588,8 @@ mod tests { // Generate random IVs let mut xpub_iv = [0u8; 16]; let mut label_iv = [0u8; 16]; - rand::thread_rng().fill_bytes(&mut xpub_iv); - rand::thread_rng().fill_bytes(&mut label_iv); + rand::rng().fill_bytes(&mut xpub_iv); + rand::rng().fill_bytes(&mut label_iv); // Test extended public key encryption: the DIP-15 compact plaintext is // 69 bytes (parentFingerprint ‖ chainCode ‖ pubKey) → 96 bytes with IV @@ -652,7 +651,7 @@ mod tests { // send_contact_request would generate fresh entropy E2 != E1 and this // invariant could not even be expressed. This test pins it. let mut rng = StdRng::seed_from_u64(0x6732_4732); // deterministic, no network - let entropy = Bytes32::random_with_rng(&mut rng); + let entropy = Bytes32::new(rng.random()); let contract_id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -770,9 +769,8 @@ mod tests { #[test] fn test_ecdh_shared_secret_symmetry() { // Test that both parties derive the same shared secret - let secp = Secp256k1::new(); - let (secret_alice, public_alice) = secp.generate_keypair(&mut rand::thread_rng()); - let (secret_bob, public_bob) = secp.generate_keypair(&mut rand::thread_rng()); + let (secret_alice, public_alice) = secp256k1::generate_keypair(&mut rand::rng()); + let (secret_bob, public_bob) = secp256k1::generate_keypair(&mut rand::rng()); // Alice derives shared secret using her private key and Bob's public key let shared_alice = derive_shared_key_ecdh(&secret_alice, &public_bob); diff --git a/packages/rs-sdk/src/platform/dpns_usernames/mod.rs b/packages/rs-sdk/src/platform/dpns_usernames/mod.rs index a8e02b29175..077cba9a7b8 100644 --- a/packages/rs-sdk/src/platform/dpns_usernames/mod.rs +++ b/packages/rs-sdk/src/platform/dpns_usernames/mod.rs @@ -161,8 +161,8 @@ impl Sdk { .map_err(|_| Error::Generic("DPNS domain document type not found".to_string()))?; // Generate the preorder salt - let mut rng = StdRng::from_entropy(); - let salt: [u8; 32] = rng.gen(); + let mut rng = StdRng::from_os_rng(); + let salt: [u8; 32] = rng.random(); // The id of a new document commits to the identity contract nonce of // its create transition, so it only exists once `put_to_platform` has diff --git a/packages/rs-sdk/src/platform/transition/broadcast_identity.rs b/packages/rs-sdk/src/platform/transition/broadcast_identity.rs index 3b07883f310..319fa8d5269 100644 --- a/packages/rs-sdk/src/platform/transition/broadcast_identity.rs +++ b/packages/rs-sdk/src/platform/transition/broadcast_identity.rs @@ -154,7 +154,7 @@ impl> IdentityCreateTransition::try_from_identity_with_signer_and_private_key( self, asset_lock_proof, - asset_lock_proof_private_key.inner.as_ref(), + asset_lock_proof_private_key.inner.as_secret_bytes(), signer, &NativeBlsModule, user_fee_increase, diff --git a/packages/rs-sdk/src/platform/transition/put_document.rs b/packages/rs-sdk/src/platform/transition/put_document.rs index 792b356c7a3..22ad2719917 100644 --- a/packages/rs-sdk/src/platform/transition/put_document.rs +++ b/packages/rs-sdk/src/platform/transition/put_document.rs @@ -148,9 +148,9 @@ impl> PutDocument for Document { (document, entropy) } None => { - let mut rng = StdRng::from_entropy(); + let mut rng = StdRng::from_os_rng(); let mut document = document; - let entropy = rng.gen::<[u8; 32]>(); + let entropy = rng.random::<[u8; 32]>(); document.set_id(Document::generate_document_id( &document_type.data_contract_id(), &document.owner_id(), diff --git a/packages/rs-sdk/src/platform/transition/top_up_address.rs b/packages/rs-sdk/src/platform/transition/top_up_address.rs index 3e7bfa58826..e8de2cc33c6 100644 --- a/packages/rs-sdk/src/platform/transition/top_up_address.rs +++ b/packages/rs-sdk/src/platform/transition/top_up_address.rs @@ -159,7 +159,7 @@ impl> TopUpAddress for AddressesWithBalances { let state_transition = create_address_funding_from_asset_lock_transition( asset_lock_proof, - asset_lock_private_key.inner.as_ref(), + asset_lock_private_key.inner.as_secret_bytes(), BTreeMap::new(), self.clone(), fee_strategy, diff --git a/packages/rs-sdk/src/platform/transition/top_up_identity.rs b/packages/rs-sdk/src/platform/transition/top_up_identity.rs index aa98bf00219..3962ff00fcf 100644 --- a/packages/rs-sdk/src/platform/transition/top_up_identity.rs +++ b/packages/rs-sdk/src/platform/transition/top_up_identity.rs @@ -81,7 +81,7 @@ impl TopUpIdentity for Identity { let state_transition = IdentityTopUpTransition::try_from_identity_with_private_key( self, asset_lock_proof, - asset_lock_proof_private_key.inner.as_ref(), + asset_lock_proof_private_key.inner.as_secret_bytes(), user_fee_increase, sdk.version(), None, diff --git a/packages/rs-unified-sdk-jni/src/tx_decode.rs b/packages/rs-unified-sdk-jni/src/tx_decode.rs index 015a88a8bc6..f5b5772e440 100644 --- a/packages/rs-unified-sdk-jni/src/tx_decode.rs +++ b/packages/rs-unified-sdk-jni/src/tx_decode.rs @@ -210,7 +210,7 @@ mod tests { use super::*; use dashcore::consensus::serialize; use dashcore::hashes::Hash; - use dashcore::secp256k1::{Secp256k1, SecretKey}; + use dashcore::secp256k1::SecretKey; use dashcore::{ Address, Network, OutPoint, PublicKey, ScriptBuf, Transaction, TxIn, TxOut, Txid, Witness, }; @@ -247,9 +247,8 @@ mod tests { } fn test_pubkey() -> PublicKey { - let secp = Secp256k1::new(); - let sk = SecretKey::from_slice(&[0x42u8; 32]).expect("valid secret key"); - PublicKey::new(sk.public_key(&secp)) + let sk = SecretKey::from_secret_bytes([0x42u8; 32]).expect("valid secret key"); + PublicKey::new(sk.public_key()) } /// The same deterministic fixture as key-wallet-ffi's diff --git a/packages/simple-signer/Cargo.toml b/packages/simple-signer/Cargo.toml index 089fae064ff..d09a1910d2a 100644 --- a/packages/simple-signer/Cargo.toml +++ b/packages/simple-signer/Cargo.toml @@ -23,6 +23,9 @@ async-trait = { version = "0.1.79" } bincode = { workspace = true, features = ["serde"] } base64 = { version = "0.22.1" } hex = { version = "0.4.3" } +# rand 0.8 `RngCore`, the RNG type strategy-tests/drive-abci pass in; the +# secp256k1 re-export is rand 0.9. +rand = { version = "0.8", default-features = false } tracing = "0.1.41" zeroize = "1" diff --git a/packages/simple-signer/src/signer.rs b/packages/simple-signer/src/signer.rs index c7fc229e551..da4baa0c3c1 100644 --- a/packages/simple-signer/src/signer.rs +++ b/packages/simple-signer/src/signer.rs @@ -4,8 +4,8 @@ use base64::Engine; use dpp::address_funds::{AddressWitness, PlatformAddress}; use dpp::bincode::{Decode, Encode}; use dpp::bls_signatures::{Bls12381G2Impl, SignatureSchemes}; -use dpp::dashcore::secp256k1::rand::{RngCore, SeedableRng}; -use dpp::dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use dpp::dashcore::secp256k1::rand::SeedableRng; +use dpp::dashcore::secp256k1::{PublicKey, SecretKey}; use dpp::dashcore::signer; use dpp::ed25519_dalek::Signer as BlsSigner; use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0; @@ -15,6 +15,7 @@ use dpp::platform_value::BinaryData; use dpp::state_transition::errors::InvalidIdentityPublicKeyTypeError; use dpp::util::hash::ripemd160_sha256; use dpp::{bls_signatures, dashcore, ed25519_dalek, ProtocolError}; +use rand::RngCore; use std::collections::BTreeMap; use std::fmt::{Debug, Formatter}; @@ -95,14 +96,14 @@ impl SimpleSigner { /// /// This is only for tests. pub fn add_random_address_key(&mut self, rng: &mut R) -> PlatformAddress { - let secp = Secp256k1::new(); - // Generate a valid secp256k1 secret key from random bytes - let mut ecdsa_rng = dashcore::secp256k1::rand::rngs::StdRng::from_rng(rng).unwrap(); + let mut seed = [0u8; 32]; + rng.fill_bytes(&mut seed); + let mut ecdsa_rng = dashcore::secp256k1::rand::rngs::StdRng::from_seed(seed); let secret_key = SecretKey::new(&mut ecdsa_rng); // Derive compressed public key - let public_key = PublicKey::from_secret_key(&secp, &secret_key); + let public_key = PublicKey::from_secret_key(&secret_key); let pubkey_ser = public_key.serialize(); // 33-byte compressed let address_hash = ripemd160_sha256(&pubkey_ser); @@ -110,7 +111,7 @@ impl SimpleSigner { // Store private key so this signer can later sign for this address // (use *_in_creation to mirror your identity key behavior) self.address_private_keys_in_creation - .insert(address_hash, secret_key.secret_bytes()); + .insert(address_hash, secret_key.to_secret_bytes()); PlatformAddress::P2pkh(address_hash) } diff --git a/packages/simple-signer/src/single_key_signer.rs b/packages/simple-signer/src/single_key_signer.rs index ad76b20af51..30cd749ed28 100644 --- a/packages/simple-signer/src/single_key_signer.rs +++ b/packages/simple-signer/src/single_key_signer.rs @@ -114,7 +114,7 @@ impl Signer for SingleKeySigner { KeyType::ECDSA_SECP256K1 | KeyType::ECDSA_HASH160 => { // Do not log private key material. Log data fingerprint only. debug!(data_hex = %hex::encode(data), "SingleKeySigner: signing data"); - let secret_bytes = Zeroizing::new(self.private_key.inner.secret_bytes()); + let secret_bytes = Zeroizing::new(self.private_key.inner.to_secret_bytes()); let signature = signer::sign(data, &secret_bytes[..])?; Ok(signature.to_vec().into()) } @@ -156,9 +156,8 @@ impl Signer for SingleKeySigner { match identity_public_key.key_type() { KeyType::ECDSA_SECP256K1 => { // Compare full public key - let secp = dashcore::secp256k1::Secp256k1::new(); let public_key = - dashcore::secp256k1::PublicKey::from_secret_key(&secp, &self.private_key.inner); + dashcore::secp256k1::PublicKey::from_secret_key(&self.private_key.inner); let public_key_bytes = public_key.serialize(); identity_public_key.data().as_slice() == public_key_bytes @@ -167,9 +166,8 @@ impl Signer for SingleKeySigner { // Compare hash160 of public key use dpp::dashcore::hashes::{hash160, Hash}; - let secp = dashcore::secp256k1::Secp256k1::new(); let public_key = - dashcore::secp256k1::PublicKey::from_secret_key(&secp, &self.private_key.inner); + dashcore::secp256k1::PublicKey::from_secret_key(&self.private_key.inner); let public_key_bytes = public_key.serialize(); let public_key_hash160 = hash160::Hash::hash(&public_key_bytes) .to_byte_array() @@ -222,7 +220,7 @@ mod tests { let hex = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; let signer = SingleKeySigner::from_hex(hex, Network::Testnet) .map_err(|e| format!("signer init failed: {}", e))?; - assert_eq!(signer.private_key().inner.secret_bytes().len(), 32); + assert_eq!(signer.private_key().inner.to_secret_bytes().len(), 32); Ok(()) } @@ -250,10 +248,8 @@ mod tests { use dpp::dashcore::hashes::{hash160, Hash}; let signer = SingleKeySigner::new_from_slice(&[0x03; 32], Network::Testnet)?; - let secp = dashcore::secp256k1::Secp256k1::new(); let public_key = - dashcore::secp256k1::PublicKey::from_secret_key(&secp, &signer.private_key.inner) - .serialize(); + dashcore::secp256k1::PublicKey::from_secret_key(&signer.private_key.inner).serialize(); let full_key = identity_key(KeyType::ECDSA_SECP256K1, public_key.to_vec()); assert!(signer.can_sign_with(&full_key)); @@ -275,7 +271,7 @@ mod tests { let hex = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; let signer = SingleKeySigner::from_string(hex, Network::Testnet) .map_err(|e| format!("signer init failed: {}", e))?; - assert_eq!(signer.private_key().inner.secret_bytes().len(), 32); + assert_eq!(signer.private_key().inner.to_secret_bytes().len(), 32); // Test WIF detection let private_key = PrivateKey::from_byte_array(&[0x02; 32], Network::Testnet) diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index f471c417d5c..9a8ad37941f 100644 --- a/packages/strategy-tests/src/lib.rs +++ b/packages/strategy-tests/src/lib.rs @@ -761,7 +761,7 @@ impl Strategy { let funding_transition = AddressFundingFromAssetLockTransitionV0::try_from_asset_lock_with_signer_and_private_key( asset_lock_proof, - private_key.inner.secret_bytes().as_slice(), + private_key.inner.to_secret_bytes().as_slice(), BTreeMap::new(), // no additional inputs outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], @@ -2206,7 +2206,7 @@ impl Strategy { let funding_transition = AddressFundingFromAssetLockTransitionV0::try_from_asset_lock_with_signer_and_private_key( asset_lock_proof, - private_key.inner.secret_bytes().as_slice(), + private_key.inner.to_secret_bytes().as_slice(), BTreeMap::new(), // no additional inputs outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], diff --git a/packages/strategy-tests/src/transitions.rs b/packages/strategy-tests/src/transitions.rs index d954e502009..bf678e6b412 100644 --- a/packages/strategy-tests/src/transitions.rs +++ b/packages/strategy-tests/src/transitions.rs @@ -32,7 +32,6 @@ //! each action. use dpp::address_funds::PlatformAddress; -use dpp::dashcore::secp256k1::Secp256k1; use dpp::dashcore::secp256k1::SecretKey; use dpp::dashcore::{ bls_sig_utils::BLSSignature, hash_types::CycleHash, InstantLock, OutPoint, ScriptBuf, @@ -173,14 +172,12 @@ pub fn instant_asset_lock_proof_fixture_with_dynamic_range( pub fn instant_asset_lock_proof_transaction_fixture( one_time_private_key: PrivateKey, ) -> Transaction { - let secp = Secp256k1::new(); - let private_key_hex = "cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY"; let private_key = PrivateKey::from_str(private_key_hex).unwrap(); - let public_key = private_key.public_key(&secp); + let public_key = private_key.public_key(); let public_key_hash = public_key.pubkey_hash(); //let from_address = Address::p2pkh(&public_key, Network::Testnet); - let one_time_public_key = one_time_private_key.public_key(&secp); + let one_time_public_key = one_time_private_key.public_key(); // We are going to fund 1 Dash and // assume that input has 100005000 @@ -251,14 +248,12 @@ pub fn instant_asset_lock_proof_transaction_fixture_with_dynamic_amount( amount_range: &AmountRange, rng: &mut StdRng, ) -> Transaction { - let secp = Secp256k1::new(); - let private_key_hex = "cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY"; let private_key = PrivateKey::from_str(private_key_hex).unwrap(); - let public_key = private_key.public_key(&secp); + let public_key = private_key.public_key(); let public_key_hash = public_key.pubkey_hash(); //let from_address = Address::p2pkh(&public_key, Network::Testnet); - let one_time_public_key = one_time_private_key.public_key(&secp); + let one_time_public_key = one_time_private_key.public_key(); // We are going to fund 1 Dash and // assume that input has 100005000 diff --git a/packages/wasm-dpp2/src/core/private_key.rs b/packages/wasm-dpp2/src/core/private_key.rs index 17a41c969e8..fbb099162e4 100644 --- a/packages/wasm-dpp2/src/core/private_key.rs +++ b/packages/wasm-dpp2/src/core/private_key.rs @@ -9,8 +9,6 @@ use crate::public_key::PublicKeyWasm; use crate::utils::try_vec_to_fixed_bytes; use dpp::dashcore::PrivateKey; use dpp::dashcore::hashes::hex::FromHex; -use dpp::dashcore::key::Secp256k1; -use dpp::dashcore::secp256k1::hashes::hex::{Case, DisplayHex}; use wasm_bindgen::prelude::wasm_bindgen; #[wasm_bindgen(js_name = "PrivateKey")] @@ -78,9 +76,7 @@ impl PrivateKeyWasm { #[wasm_bindgen(js_name = "getPublicKey")] pub fn get_public_key(&self) -> PublicKeyWasm { - let secp = Secp256k1::new(); - - let public_key = self.0.public_key(&secp); + let public_key = self.0.public_key(); public_key.into() } @@ -100,14 +96,12 @@ impl PrivateKeyWasm { #[wasm_bindgen(js_name = "toHex")] pub fn to_hex(&self) -> String { - self.0.to_bytes().to_hex_string(Case::Upper) + hex::encode_upper(self.0.to_bytes()) } #[wasm_bindgen(js_name = "getPublicKeyHash")] pub fn get_public_key_hash(&self) -> String { - let secp = Secp256k1::new(); - - self.0.public_key(&secp).pubkey_hash().to_hex() + self.0.public_key().pubkey_hash().to_hex() } } diff --git a/packages/wasm-dpp2/src/identity/public_key.rs b/packages/wasm-dpp2/src/identity/public_key.rs index 8e2c1b42fe8..578dba11293 100644 --- a/packages/wasm-dpp2/src/identity/public_key.rs +++ b/packages/wasm-dpp2/src/identity/public_key.rs @@ -14,7 +14,6 @@ use crate::utils::{ }; use crate::version::PlatformVersionLikeJs; use dpp::dashcore::Network; -use dpp::dashcore::secp256k1::hashes::hex::{Case, DisplayHex}; use dpp::fee::Credits; use dpp::identity::contract_bounds::ContractBounds; use dpp::identity::hash::IdentityPublicKeyHashMethodsV0; @@ -397,11 +396,7 @@ impl IdentityPublicKeyWasm { #[wasm_bindgen(js_name = "getPublicKeyHash")] pub fn public_key_hash(&self) -> WasmDppResult { - let hash = self - .0 - .public_key_hash()? - .to_vec() - .to_hex_string(Case::Lower); + let hash = hex::encode(self.0.public_key_hash()?); Ok(hash) } diff --git a/packages/wasm-dpp2/src/public_key.rs b/packages/wasm-dpp2/src/public_key.rs index abd1dfc8d01..a5da3562345 100644 --- a/packages/wasm-dpp2/src/public_key.rs +++ b/packages/wasm-dpp2/src/public_key.rs @@ -39,7 +39,7 @@ impl PublicKeyWasm { public_key_bytes.try_into().map_err(|_| { WasmDppError::invalid_argument("compressed public key must contain 33 bytes") })?; - secp256k1::PublicKey::from_byte_array_compressed(&bytes) + secp256k1::PublicKey::from_byte_array_compressed(bytes) } else { if public_key_bytes.len() != constants::UNCOMPRESSED_PUBLIC_KEY_SIZE { return Err(WasmDppError::invalid_argument(format!( @@ -53,7 +53,7 @@ impl PublicKeyWasm { WasmDppError::invalid_argument("uncompressed public key must contain 65 bytes") })?; - secp256k1::PublicKey::from_byte_array_uncompressed(&bytes) + secp256k1::PublicKey::from_byte_array_uncompressed(bytes) } .map_err(|err| WasmDppError::invalid_argument(err.to_string()))?; @@ -87,7 +87,7 @@ impl PublicKeyWasm { })?; self.0.compressed = true; - self.0.inner = secp256k1::PublicKey::from_byte_array_compressed(&bytes) + self.0.inner = secp256k1::PublicKey::from_byte_array_compressed(bytes) .map_err(|err| WasmDppError::invalid_argument(err.to_string()))?; } else { if inner.len() != constants::UNCOMPRESSED_PUBLIC_KEY_SIZE { @@ -103,7 +103,7 @@ impl PublicKeyWasm { })?; self.0.compressed = false; - self.0.inner = secp256k1::PublicKey::from_byte_array_uncompressed(&bytes) + self.0.inner = secp256k1::PublicKey::from_byte_array_uncompressed(bytes) .map_err(|err| WasmDppError::invalid_argument(err.to_string()))?; } diff --git a/packages/wasm-dpp2/src/state_transitions/base/state_transition.rs b/packages/wasm-dpp2/src/state_transitions/base/state_transition.rs index cda6a045da5..d657865075e 100644 --- a/packages/wasm-dpp2/src/state_transitions/base/state_transition.rs +++ b/packages/wasm-dpp2/src/state_transitions/base/state_transition.rs @@ -7,8 +7,6 @@ use crate::identifier::{IdentifierLikeJs, IdentifierWasm}; use crate::identity::public_key::IdentityPublicKeyWasm; use crate::impl_wasm_type_info; use crate::mock_bls::MockBLS; -use dpp::dashcore::secp256k1::hashes::hex::Case::Lower; -use dpp::dashcore::secp256k1::hashes::hex::DisplayHex; use dpp::data_contract::serialized_version::DataContractInSerializationFormat; use dpp::identity::{KeyID, KeyType}; use dpp::platform_value::BinaryData; @@ -330,7 +328,7 @@ impl StateTransitionWasm { dpp::serialization::PlatformSerializable::serialize_to_bytes(&self.0)? }; - Ok(Sha256::digest(payload).to_hex_string(Lower)) + Ok(hex::encode(Sha256::digest(payload))) } #[wasm_bindgen(getter = "actionType")] diff --git a/packages/wasm-sdk/src/wallet/dip14.rs b/packages/wasm-sdk/src/wallet/dip14.rs index a1a5c3a3b56..1deb3fb80e1 100644 --- a/packages/wasm-sdk/src/wallet/dip14.rs +++ b/packages/wasm-sdk/src/wallet/dip14.rs @@ -4,7 +4,7 @@ //! instead of the standard 31-bit limitation. use dash_sdk::dpp::dashcore::hashes::{sha256, Hash}; -use dash_sdk::dpp::dashcore::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey}; +use dash_sdk::dpp::dashcore::secp256k1::{self, PublicKey, Scalar, SecretKey}; use dash_sdk::dpp::dashcore::Network; use dash_sdk::dpp::key_wallet; use dash_sdk::dpp::key_wallet::bip32::{ExtendedPrivKey, ExtendedPubKey}; @@ -97,8 +97,6 @@ impl Dip14ExtendedPrivKey { /// Derive a child key using DIP14 extended derivation pub fn derive_child(&self, index: &[u8; 32], hardened: bool) -> Result { - let secp = Secp256k1::new(); - // Prepare HMAC input based on hardened flag let mut hmac = HmacSha512::new_from_slice(&self.chain_code) .map_err(|_| Dip14Error::DerivationFailed("Invalid chain code".to_string()))?; @@ -106,11 +104,11 @@ impl Dip14ExtendedPrivKey { if hardened { // Hardened: 0x00 || ser256(k_parent) || ser256(i) hmac.update(&[0x00]); - hmac.update(&self.private_key.secret_bytes()); + hmac.update(&self.private_key.to_secret_bytes()); hmac.update(&ser256(index)); } else { // Non-hardened: ser_P(point(k_parent)) || ser256(i) - let public_key = PublicKey::from_secret_key(&secp, &self.private_key); + let public_key = PublicKey::from_secret_key(&self.private_key); hmac.update(&public_key.serialize()); hmac.update(&ser256(index)); } @@ -122,7 +120,10 @@ impl Dip14ExtendedPrivKey { // This is the core of BIP32/DIP14 child key derivation // First, try to create a secret key from IL - let il_scalar = match SecretKey::from_slice(il_bytes) { + let il_scalar = match <[u8; 32]>::try_from(il_bytes) + .map_err(|_| secp256k1::Error::InvalidSecretKey) + .and_then(SecretKey::from_secret_bytes) + { Ok(key) => key, Err(_) => { return Err(Dip14Error::DerivationFailed( @@ -134,7 +135,7 @@ impl Dip14ExtendedPrivKey { // Add parent key to IL // In secp256k1, we perform scalar addition: child_key = parent_key + IL (mod n) // Convert IL to a Scalar for the tweak operation - let il_scalar_bytes = il_scalar.secret_bytes(); + let il_scalar_bytes = il_scalar.to_secret_bytes(); let tweak = Scalar::from_be_bytes(il_scalar_bytes).map_err(|_| { Dip14Error::DerivationFailed("Failed to convert IL to scalar".to_string()) })?; @@ -146,7 +147,7 @@ impl Dip14ExtendedPrivKey { .map_err(|e| Dip14Error::DerivationFailed(format!("Failed to add tweak: {}", e)))?; // Calculate parent fingerprint (first 4 bytes of parent pubkey hash160) - let parent_pubkey = PublicKey::from_secret_key(&secp, &self.private_key); + let parent_pubkey = PublicKey::from_secret_key(&self.private_key); // Use sha256 then ripemd160 to create hash160 let sha256_hash = sha256::Hash::hash(&parent_pubkey.serialize()); let parent_pubkey_hash = @@ -167,8 +168,8 @@ impl Dip14ExtendedPrivKey { } /// Get the extended public key - pub fn to_extended_pub_key(&self, secp: &Secp256k1) -> Dip14ExtendedPubKey { - let public_key = PublicKey::from_secret_key(secp, &self.private_key); + pub fn to_extended_pub_key(&self) -> Dip14ExtendedPubKey { + let public_key = PublicKey::from_secret_key(&self.private_key); Dip14ExtendedPubKey { network: self.network, diff --git a/packages/wasm-sdk/src/wallet/extended_derivation.rs b/packages/wasm-sdk/src/wallet/extended_derivation.rs index b8a929605df..8a1de840261 100644 --- a/packages/wasm-sdk/src/wallet/extended_derivation.rs +++ b/packages/wasm-sdk/src/wallet/extended_derivation.rs @@ -7,7 +7,6 @@ use crate::impl_wasm_serde_conversions; use crate::queries::utils::deserialize_required_query; use crate::sdk::WasmSdk; use dash_sdk::dpp::dashcore; -use dash_sdk::dpp::dashcore::secp256k1::Secp256k1; use dash_sdk::dpp::key_wallet::{bip32, DerivationPath, ExtendedPrivKey}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -109,20 +108,19 @@ fn derive_common_from_mnemonic( let derivation_path = DerivationPath::from_str(path) .map_err(|e| WasmSdkError::invalid_argument(format!("Invalid derivation path: {}", e)))?; - let secp = Secp256k1::new(); let derived_key = master_key - .derive_priv(&secp, &derivation_path) + .derive_priv(&derivation_path) .map_err(|e| WasmSdkError::generic(format!("Failed to derive key: {}", e)))?; - let xpub = bip32::ExtendedPubKey::from_priv(&secp, &derived_key); + let xpub = bip32::ExtendedPubKey::from_priv(&derived_key); let private_key = dashcore::PrivateKey::new(derived_key.private_key, net); - let public_key = private_key.public_key(&secp); + let public_key = private_key.public_key(); let address = dashcore::Address::p2pkh(&public_key, net); Ok(CommonDerivation { path: path.to_string(), private_key_wif: private_key.to_wif(), - private_key_hex: hex::encode(private_key.inner.secret_bytes()), + private_key_hex: hex::encode(private_key.inner.to_secret_bytes()), public_key_hex: hex::encode(public_key.to_bytes()), address: address.to_string(), network: network.to_string(), diff --git a/packages/wasm-sdk/src/wallet/key_derivation.rs b/packages/wasm-sdk/src/wallet/key_derivation.rs index ad5db95a1b5..9423e329d74 100644 --- a/packages/wasm-sdk/src/wallet/key_derivation.rs +++ b/packages/wasm-sdk/src/wallet/key_derivation.rs @@ -8,7 +8,6 @@ use crate::queries::utils::{deserialize_query_with_default, deserialize_required use crate::sdk::WasmSdk; use bip39::{Language, Mnemonic}; use dash_sdk::dpp::dashcore; -use dash_sdk::dpp::dashcore::secp256k1::Secp256k1; use dash_sdk::dpp::key_wallet::bip32::{ ChildNumber, DerivationPath as BIP32DerivationPath, ExtendedPrivKey as BIP32ExtendedPrivKey, ExtendedPubKey as BIP32ExtendedPubKey, @@ -430,10 +429,7 @@ impl WasmSdk { .map_err(|e| WasmSdkError::generic(format!("Failed to create private key: {}", e)))?; // Get public key - use dash_sdk::dpp::dashcore::secp256k1::Secp256k1; - let secp = Secp256k1::new(); - - let public_key = private_key.public_key(&secp); + let public_key = private_key.public_key(); let public_key_bytes = public_key.inner.serialize(); // Get address let address = dashcore::Address::p2pkh(&public_key, net); @@ -483,7 +479,7 @@ impl WasmSdk { // Derive the key at the specified path let derived_key = master_key - .derive_priv(&dashcore::secp256k1::Secp256k1::new(), &derivation_path) + .derive_priv(&derivation_path) .map_err(|e| WasmSdkError::generic(format!("Failed to derive key: {}", e)))?; // In v0.40-dev, ExtendedPrivKey might have a different structure @@ -491,8 +487,7 @@ impl WasmSdk { let private_key = dashcore::PrivateKey::new(derived_key.private_key, net); // Get public key - let secp = dash_sdk::dpp::dashcore::secp256k1::Secp256k1::new(); - let public_key = private_key.public_key(&secp); + let public_key = private_key.public_key(); // Get address let address = dashcore::Address::p2pkh(&public_key, net); @@ -500,7 +495,7 @@ impl WasmSdk { Ok(PathDerivedKeyInfoWasm { path, private_key_wif: private_key.to_wif(), - private_key_hex: hex::encode(private_key.inner.secret_bytes()), + private_key_hex: hex::encode(private_key.inner.to_secret_bytes()), public_key: hex::encode(public_key.to_bytes()), address: address.to_string(), network, @@ -613,9 +608,8 @@ impl WasmSdk { // Build a one-step derivation path and derive let child_number: ChildNumber = ChildNumber::from(index); let path = BIP32DerivationPath::from(vec![child_number]); - let secp = Secp256k1::new(); let child_xpub = parent_xpub - .derive_pub(&secp, &path) + .derive_pub(&path) .map_err(|e| WasmSdkError::generic(format!("Failed to derive child key: {}", e)))?; Ok(child_xpub.to_string()) @@ -628,8 +622,7 @@ impl WasmSdk { let ext_prv = BIP32ExtendedPrivKey::from_str(xprv).map_err(|e| { WasmSdkError::invalid_argument(format!("Invalid extended private key: {}", e)) })?; - let secp = Secp256k1::new(); - let ext_pub = BIP32ExtendedPubKey::from_priv(&secp, &ext_prv); + let ext_pub = BIP32ExtendedPubKey::from_priv(&ext_prv); Ok(ext_pub.to_string()) } } diff --git a/packages/wasm-sdk/src/wallet/key_generation.rs b/packages/wasm-sdk/src/wallet/key_generation.rs index e1678d374fa..8830b5b13e3 100644 --- a/packages/wasm-sdk/src/wallet/key_generation.rs +++ b/packages/wasm-sdk/src/wallet/key_generation.rs @@ -6,7 +6,7 @@ use crate::error::WasmSdkError; use crate::impl_wasm_serde_conversions; use crate::sdk::WasmSdk; use dash_sdk::dpp::dashcore::hashes::{sha256, Hash}; -use dash_sdk::dpp::dashcore::secp256k1::{Secp256k1, SecretKey}; +use dash_sdk::dpp::dashcore::secp256k1::SecretKey; use dash_sdk::dpp::dashcore::{Address, Network, PrivateKey, PublicKey}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -67,14 +67,13 @@ impl WasmSdk { network: Network, network_label: &str, ) -> Result { - let secp = Secp256k1::new(); - let public_key = private_key.public_key(&secp); + let public_key = private_key.public_key(); let public_key_bytes = public_key.inner.serialize(); let address = Address::p2pkh(&public_key, network); Ok(KeyPair { private_key_wif: private_key.to_wif(), - private_key_hex: hex::encode(private_key.inner.secret_bytes()), + private_key_hex: hex::encode(private_key.inner.to_secret_bytes()), public_key: hex::encode(public_key_bytes), address: address.to_string(), network: network_label.to_string(), @@ -96,7 +95,7 @@ impl WasmSdk { .map_err(|e| WasmSdkError::generic(format!("Failed to create private key: {}", e)))?; // Ensure secret key is valid before building info - SecretKey::from_slice(&key_bytes) + SecretKey::from_secret_bytes(key_bytes) .map_err(|e| WasmSdkError::invalid_argument(format!("Invalid secret key: {}", e)))?; let key_pair = Self::build_key_pair(&private_key, net, network_wasm.as_str())?; @@ -221,13 +220,12 @@ impl WasmSdk { let hash = sha256::Hash::hash(message_bytes); // Sign the hash - let secp = Secp256k1::new(); - let secret_key = SecretKey::from_slice(&private_key.inner.secret_bytes()) + let secret_key = SecretKey::from_secret_bytes(private_key.inner.to_secret_bytes()) .map_err(|e| WasmSdkError::invalid_argument(format!("Invalid secret key: {}", e)))?; let message_hash = dash_sdk::dpp::dashcore::secp256k1::Message::from_digest(hash.to_byte_array()); - let signature = secp.sign_ecdsa(&message_hash, &secret_key); + let signature = secret_key.sign_ecdsa(message_hash); Ok(hex::encode(signature.serialize_compact())) } From 7b63fc6ef4964cafd8e40113955c37b4aa276a57 Mon Sep 17 00:00:00 2001 From: infraclaw-dash Date: Tue, 29 Sep 2026 05:17:23 +0000 Subject: [PATCH 2/4] ci: bootstrap trusted publisher before feature runner adoption --- .github/workflows/runner-image-candidate.yml | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/runner-image-candidate.yml diff --git a/.github/workflows/runner-image-candidate.yml b/.github/workflows/runner-image-candidate.yml new file mode 100644 index 00000000000..02df53334f2 --- /dev/null +++ b/.github/workflows/runner-image-candidate.yml @@ -0,0 +1,33 @@ +name: Runner image candidate + +on: + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review, closed] + branches: [master, 'v*-dev', 'ci/*', 'chore/bump-rust-dashcore-secp-033'] + paths: ['.github/runner-requirements.json'] + +# This is trusted base-branch orchestration. Never check out PR code or select +# the control revision from PR data. Build/publish execute on separate hosted VMs. +permissions: + contents: read + pull-requests: read + actions: read + statuses: write + +concurrency: + group: ${{ github.event.action == 'closed' && format('runner-image-promote-{0}', github.event.pull_request.base.ref) || format('runner-image-pr-{0}', github.event.pull_request.number) }} + cancel-in-progress: ${{ github.event.action != 'closed' }} + +jobs: + image: + if: >- + (github.event.action != 'closed' && !github.event.pull_request.draft) + || (github.event.action == 'closed' && github.event.pull_request.merged) + uses: dashpay/dash-selfhosted-image/.github/workflows/platform-candidate.yml@7d901150bd3d0789d50c46f365b058f2f5f1f52d + with: + pull_request: ${{ github.event.pull_request.number }} + control_revision: 7d901150bd3d0789d50c46f365b058f2f5f1f52d + mode: ${{ github.event.action == 'closed' && 'promote' || 'candidate' }} + secrets: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} From bf382b1601f40ff7bcf98b58051b992dcec3cf53 Mon Sep 17 00:00:00 2001 From: pasta Date: Sun, 4 Oct 2026 22:32:23 -0500 Subject: [PATCH 3/4] fix(sdk)!: require Node.js 20 for the WASM packages secp256k1 0.33 draws randomness through rand 0.9 / getrandom 0.3, and key-wallet through getrandom 0.4. Their `wasm_js` backend reads only `globalThis.crypto.getRandomValues`; getrandom 0.2's `js` feature also fell back to Node's `require("crypto")`. Node.js exposes the WebCrypto global by default from v19, so on Node 18 even a deterministic call such as deriving a public key (secp256k1 rerandomizes its context afterwards) traps. Node 18 has been end-of-life since April 2025. Raise `engines.node` of wasm-sdk, wasm-dpp2 and js-evo-sdk to >=20, matching dashmate, and say why in the evo-sdk README and next to the getrandom features in rs-dpp. BREAKING CHANGE: @dashevo/wasm-sdk, @dashevo/wasm-dpp2 and @dashevo/evo-sdk require Node.js >= 20. Co-Authored-By: Claude Opus 5.5 (1M context) --- packages/js-evo-sdk/README.md | 2 +- packages/js-evo-sdk/package.json | 2 +- packages/rs-dpp/Cargo.toml | 3 +++ packages/wasm-dpp2/package.json | 2 +- packages/wasm-sdk/package.json | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/js-evo-sdk/README.md b/packages/js-evo-sdk/README.md index 25fd8dfa1df..9b40e141920 100644 --- a/packages/js-evo-sdk/README.md +++ b/packages/js-evo-sdk/README.md @@ -32,7 +32,7 @@ Evo SDK provides a high-level, strongly-typed interface for interacting with [Da npm install @dashevo/evo-sdk ``` -The package is ESM-only (`"type": "module"`). In CommonJS projects, use dynamic `import()`. Requires Node.js >= 18.18. +The package is ESM-only (`"type": "module"`). In CommonJS projects, use dynamic `import()`. Requires Node.js >= 20 (the bundled WASM draws entropy from the global WebCrypto `crypto` object, which Node.js exposes by default from v19). ## Usage diff --git a/packages/js-evo-sdk/package.json b/packages/js-evo-sdk/package.json index e2218e4fb7a..5378177073d 100644 --- a/packages/js-evo-sdk/package.json +++ b/packages/js-evo-sdk/package.json @@ -15,7 +15,7 @@ }, "sideEffects": false, "engines": { - "node": ">=18.18" + "node": ">=20" }, "files": [ "dist/**", diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index 2e059d1d1e8..fbaaea5f073 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -93,6 +93,9 @@ log = { version = "0.4.27" } # secp256k1 0.33 pulls getrandom 0.3 (via rand 0.9) and key-wallet pulls # getrandom 0.4; on wasm32-unknown-unknown both refuse to build without their # `wasm_js` feature, so enable it here where every wasm crate picks it up. +# Unlike getrandom 0.2's `js` (which falls back to Node's `require("crypto")`), +# `wasm_js` only reads `globalThis.crypto.getRandomValues`, which Node.js +# exposes by default from v19; the JS packages therefore require Node >= 20. [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] getrandom_03 = { package = "getrandom", version = "0.3", features = ["wasm_js"] } getrandom_04 = { package = "getrandom", version = "0.4", features = ["wasm_js"] } diff --git a/packages/wasm-dpp2/package.json b/packages/wasm-dpp2/package.json index 9b730a1f055..4dd99a705be 100644 --- a/packages/wasm-dpp2/package.json +++ b/packages/wasm-dpp2/package.json @@ -25,7 +25,7 @@ ], "sideEffects": false, "engines": { - "node": ">=18.18" + "node": ">=20" }, "scripts": { "build": "./scripts/build.sh && node ./scripts/bundle.cjs", diff --git a/packages/wasm-sdk/package.json b/packages/wasm-sdk/package.json index ee6ae546636..5d0325901e8 100644 --- a/packages/wasm-sdk/package.json +++ b/packages/wasm-sdk/package.json @@ -25,7 +25,7 @@ ], "sideEffects": false, "engines": { - "node": ">=18.18" + "node": ">=20" }, "scripts": { "build": "./scripts/build.sh && node ./scripts/bundle.cjs", From 1b823095b78363179da4d067c1e7f902d84d5ee0 Mon Sep 17 00:00:00 2001 From: pasta Date: Mon, 5 Oct 2026 00:43:24 -0500 Subject: [PATCH 4/4] fix(sdk): move v5.0-dev's encrypted-for and moderation-charter code to secp256k1 0.33 Code that landed on v5.0-dev after this bump was first written (encrypted_for in rs-sdk and wasm-sdk, moderation charter requests) still used the secp256k1 0.30 / rand 0.8 API. Migrate it the same way as the rest of the bump: drop the `Secp256k1` context from `PublicKey::from_secret_key`, `SecretKey::from_slice` -> `from_secret_bytes`, `StdRng::from_entropy` -> `from_os_rng`, and `Bytes32::random_with_rng` -> `Bytes32::new(rng.random())` since platform-value's helper takes a rand 0.8 `StdRng`. Co-Authored-By: Claude Opus 5.5 (1M context) --- packages/rs-sdk/src/platform/encrypted_for.rs | 7 +++---- packages/rs-sdk/src/platform/encrypted_for/tests.rs | 4 ++-- .../src/platform/moderation_charters/requests.rs | 10 +++++----- packages/wasm-sdk/src/encrypted_for.rs | 6 ++---- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/packages/rs-sdk/src/platform/encrypted_for.rs b/packages/rs-sdk/src/platform/encrypted_for.rs index 6c778b8885b..2d8af5f5e93 100644 --- a/packages/rs-sdk/src/platform/encrypted_for.rs +++ b/packages/rs-sdk/src/platform/encrypted_for.rs @@ -28,7 +28,7 @@ use dpp::dashcore::secp256k1::rand::rngs::StdRng; use dpp::dashcore::secp256k1::rand::{RngCore, SeedableRng}; -use dpp::dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use dpp::dashcore::secp256k1::{PublicKey, SecretKey}; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::data_contract::document_type::{ DocumentPropertyReferenceTarget, DocumentPropertyType, DocumentTypeRef, EncryptedFor, @@ -235,7 +235,7 @@ pub fn encrypt_property( fn random_iv() -> [u8; AES_CBC_IV_LENGTH] { let mut iv = [0u8; AES_CBC_IV_LENGTH]; - StdRng::from_entropy().fill_bytes(&mut iv); + StdRng::from_os_rng().fill_bytes(&mut iv); iv } @@ -425,8 +425,7 @@ fn select_declared_keys<'a>( let contract_id = document_type.data_contract_id(); let sender_requirements = key_requirements_naming(document_type, &declaration.sender_key); - let sender_public_key = - PublicKey::from_secret_key(&Secp256k1::signing_only(), sender_private_key); + let sender_public_key = PublicKey::from_secret_key(sender_private_key); let sender_public_key_bytes = sender_public_key.serialize(); let no_sender_key = |reason: String| EncryptedForError::NoSuitableKey { identity_id: sender.id(), diff --git a/packages/rs-sdk/src/platform/encrypted_for/tests.rs b/packages/rs-sdk/src/platform/encrypted_for/tests.rs index 5660550e359..8f88a83288b 100644 --- a/packages/rs-sdk/src/platform/encrypted_for/tests.rs +++ b/packages/rs-sdk/src/platform/encrypted_for/tests.rs @@ -34,8 +34,8 @@ const DASHPAY_VECTOR_HEX: &str = "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a864d1b3807cf80 b97cd32a5e36309f3bf9535c519b1b32b2f206696ec6d0e244a2e182fceaa750"; fn key_pair(scalar: u8) -> (SecretKey, PublicKey) { - let secret_key = SecretKey::from_slice(&[scalar; 32]).expect("a valid scalar"); - let public_key = PublicKey::from_secret_key(&Secp256k1::signing_only(), &secret_key); + let secret_key = SecretKey::from_secret_bytes([scalar; 32]).expect("a valid scalar"); + let public_key = PublicKey::from_secret_key(&secret_key); (secret_key, public_key) } diff --git a/packages/rs-sdk/src/platform/moderation_charters/requests.rs b/packages/rs-sdk/src/platform/moderation_charters/requests.rs index a51d8402385..9af9df68a99 100644 --- a/packages/rs-sdk/src/platform/moderation_charters/requests.rs +++ b/packages/rs-sdk/src/platform/moderation_charters/requests.rs @@ -4,7 +4,7 @@ use crate::platform::encrypted_for::encrypt_property_for; use crate::platform::{DataContract, Document, Fetch, Identity}; use crate::{Error, Sdk}; use dpp::dashcore::secp256k1::rand::rngs::StdRng; -use dpp::dashcore::secp256k1::rand::SeedableRng; +use dpp::dashcore::secp256k1::rand::{Rng, SeedableRng}; use dpp::dashcore::secp256k1::SecretKey; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::methods::DocumentTypeBasicMethods; @@ -240,14 +240,14 @@ impl Sdk { } fn fresh_entropy() -> Bytes32 { - Bytes32::random_with_rng(&mut StdRng::from_entropy()) + Bytes32::new(StdRng::from_os_rng().random()) } #[cfg(test)] mod tests { use super::*; use crate::platform::encrypted_for::{decrypt_property, EncryptedPropertyEnvelope}; - use dpp::dashcore::secp256k1::{PublicKey, Secp256k1}; + use dpp::dashcore::secp256k1::PublicKey; use dpp::data_contract::document_type::property_constraints::DocumentSystemValues; use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; use dpp::identity::contract_bounds::ContractBounds; @@ -260,8 +260,8 @@ mod tests { use dpp::version::PlatformVersion; fn key_pair(scalar: u8) -> (SecretKey, PublicKey) { - let secret_key = SecretKey::from_slice(&[scalar; 32]).expect("a valid scalar"); - let public_key = PublicKey::from_secret_key(&Secp256k1::signing_only(), &secret_key); + let secret_key = SecretKey::from_secret_bytes([scalar; 32]).expect("a valid scalar"); + let public_key = PublicKey::from_secret_key(&secret_key); (secret_key, public_key) } diff --git a/packages/wasm-sdk/src/encrypted_for.rs b/packages/wasm-sdk/src/encrypted_for.rs index 45e6f3575cc..5e86489b3c7 100644 --- a/packages/wasm-sdk/src/encrypted_for.rs +++ b/packages/wasm-sdk/src/encrypted_for.rs @@ -5,7 +5,7 @@ use crate::error::WasmSdkError; use crate::sdk::WasmSdk; -use dash_sdk::dpp::dashcore::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use dash_sdk::dpp::dashcore::secp256k1::{PublicKey, SecretKey}; use dash_sdk::dpp::data_contract::accessors::v0::DataContractV0Getters; use dash_sdk::dpp::data_contract::document_type::methods::DocumentTypeV0Methods; use dash_sdk::dpp::data_contract::document_type::DocumentTypeRef; @@ -215,9 +215,7 @@ impl WasmSdk { // A private key that is not the sender key's would write a message nobody can read let sender_public_key = secp256k1_public_key(&sender_key, "senderKey")?; - if PublicKey::from_secret_key(&Secp256k1::signing_only(), &sender_private_key) - != sender_public_key - { + if PublicKey::from_secret_key(&sender_private_key) != sender_public_key { return Err(WasmSdkError::invalid_argument( "senderPrivateKey is not the private half of senderKey", ));