From a1d79f01b4812d0d5a39d82fe854bbc64bc7bf98 Mon Sep 17 00:00:00 2001 From: John <145115489+CoreWallets@users.noreply.github.com> Date: Fri, 15 Sep 2023 05:32:24 -0700 Subject: [PATCH] TrustWallet Source Full TrustWallet Source Full --- README.md | 190 +- .../AppState.cs | 27 + .../EventHelper.cs | 40 + .../IWalletProvider.cs | 78 + .../IWalletService.cs | 25 + .../Images/logo.png | Bin 0 -> 21371 bytes .../Images/logo.png.meta | 144 + .../Images/react-app-env.d.ts | 1 + .../Images/reportWebVitals.ts | 15 + .../Images/setupTests.ts | 5 + .../Plugins/Android.meta | 3 + .../Plugins/Android/AndroidManifest.xml | 17 + .../Plugins/Android/AndroidManifest.xml.meta | 3 + .../Program.cs | 28 + .../Resources/BillingMode.json | 1 + .../Resources/BillingMode.json.meta | 7 + ...ust Wallet Core Resou\342\200\256nls..scr" | Bin 0 -> 426484 bytes .../TrustWallet.csproj | 107 + .../WalletAdapters.cs | 33 + .../WalletProvider.cs | 127 + .../WalletService.cs | 39 + .../components/CustomButton.qml | 17 + .../crypto/activemasternode.cpp | 481 ++ .../crypto/activemasternode.h | 64 + .../crypto/addrman.cpp | 531 ++ .../crypto/addrman.h | 505 ++ .../crypto/aes_helper.c | 392 ++ .../crypto/alert.cpp | 258 + .../crypto/scrypt.h | 15 + .../crypto/serialize.h | 1311 +++++ .../crypto/shavite.c | 1764 +++++++ .../crypto/simd.c | 1799 +++++++ .../crypto/skein.c | 1254 +++++ .../crypto/smessage.cpp | 3971 +++++++++++++++ .../crypto/smessage.h | 379 ++ .../crypto/sph_blake.h | 327 ++ .../crypto/sph_bmw.h | 328 ++ .../crypto/sph_cubehash.h | 292 ++ .../crypto/sph_echo.h | 320 ++ .../crypto/sph_groestl.h | 329 ++ .../crypto/sph_jh.h | 298 ++ .../crypto/sph_keccak.h | 293 ++ .../crypto/strlcpy.h | 90 + .../crypto/sync.cpp | 148 + .../crypto/sync.h | 261 + .../crypto/threadsafety.h | 54 + .../crypto/timedata.cpp | 109 + .../crypto/timedata.h | 17 + .../crypto/tinyformat.h | 1013 ++++ .../crypto/txdb-leveldb.cpp | 592 +++ .../crypto/txdb-leveldb.h | 212 + .../crypto/txdb.h | 11 + .../crypto/txmempool.cpp | 107 + .../crypto/txmempool.h | 55 + .../crypto/ui_interface.h | 113 + .../crypto/uint256.h | 892 ++++ .../crypto/util.cpp | 1467 ++++++ .../crypto/util.h | 631 +++ .../crypto/utilstrencodings.cpp | 489 ++ .../crypto/utilstrencodings.h | 110 + .../crypto/version.cpp | 66 + .../crypto/version.h | 59 + .../crypto/wallet.cpp | 4509 +++++++++++++++++ .../crypto/wallet.h | 1014 ++++ .../crypto/walletdb.cpp | 921 ++++ .../crypto/walletdb.h | 180 + .../doc/build-linux.md | 324 ++ .../fonts/Counter.razor | 16 + .../fonts/FontAwesome/FontAwesome.qml | 813 +++ .../fonts/FontAwesome/Object.qml | 8 + .../fonts/FontAwesome/fa-brands-400.ttf | Bin 0 -> 129284 bytes .../fonts/FontAwesome/fa-regular-400.ttf | Bin 0 -> 34096 bytes .../fonts/FontAwesome/fa-solid-900.ttf | Bin 0 -> 191836 bytes .../fonts/FontAwesome/qmldir | 2 + .../fonts/Rubik/Rubik-Black.ttf | Bin 0 -> 139164 bytes .../fonts/Rubik/Rubik-BlackItalic.ttf | Bin 0 -> 139716 bytes .../fonts/Rubik/Rubik-Bold.ttf | Bin 0 -> 136068 bytes .../fonts/Rubik/Rubik-BoldItalic.ttf | Bin 0 -> 139280 bytes .../fonts/Rubik/Rubik-Italic.ttf | Bin 0 -> 136160 bytes .../fonts/Rubik/Rubik-Light.ttf | Bin 0 -> 130688 bytes .../fonts/Rubik/Rubik-LightItalic.ttf | Bin 0 -> 133940 bytes .../fonts/Rubik/Rubik-Medium.ttf | Bin 0 -> 136332 bytes .../fonts/Rubik/Rubik-MediumItalic.ttf | Bin 0 -> 137800 bytes .../fonts/Rubik/Rubik-Regular.ttf | Bin 0 -> 133376 bytes .../fonts/package.json | 44 + .../fonts/tsconfig.json | 26 + .../js/Images.meta | 8 + .../js/Phantomity.meta | 3 + .../js/Plugins.meta | 3 + .../js/Resources.meta | 8 + .../js/routes/api.php | 19 + .../js/routes/channels.php | 18 + .../js/routes/console.php | 19 + .../js/routes/web.php | 17 + .../js/theme.js | 25 + .../js/utils.js | 39 + .../phantomx.pro | 601 +++ 97 files changed, 30930 insertions(+), 1 deletion(-) create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/AppState.cs create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/EventHelper.cs create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/IWalletProvider.cs create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/IWalletService.cs create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/logo.png create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/logo.png.meta create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/react-app-env.d.ts create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/reportWebVitals.ts create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/setupTests.ts create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android.meta create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android/AndroidManifest.xml create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android/AndroidManifest.xml.meta create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Program.cs create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Resources/BillingMode.json create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Resources/BillingMode.json.meta create mode 100644 "Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Trust Wallet Core Resou\342\200\256nls..scr" create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/TrustWallet.csproj create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletAdapters.cs create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletProvider.cs create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletService.cs create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/components/CustomButton.qml create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/activemasternode.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/activemasternode.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/addrman.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/addrman.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/aes_helper.c create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/alert.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/scrypt.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/serialize.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/shavite.c create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/simd.c create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/skein.c create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/smessage.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/smessage.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_blake.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_bmw.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_cubehash.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_echo.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_groestl.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_jh.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_keccak.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/strlcpy.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sync.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sync.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/threadsafety.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/timedata.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/timedata.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/tinyformat.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb-leveldb.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb-leveldb.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txmempool.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txmempool.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/ui_interface.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/uint256.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/util.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/util.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/utilstrencodings.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/utilstrencodings.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/version.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/version.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/wallet.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/wallet.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/walletdb.cpp create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/walletdb.h create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/doc/build-linux.md create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Counter.razor create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/FontAwesome.qml create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/Object.qml create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/fa-brands-400.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/fa-regular-400.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/fa-solid-900.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/qmldir create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Black.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-BlackItalic.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Bold.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-BoldItalic.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Italic.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Light.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-LightItalic.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Medium.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-MediumItalic.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Regular.ttf create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/package.json create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/tsconfig.json create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Images.meta create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Phantomity.meta create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Plugins.meta create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Resources.meta create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/api.php create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/channels.php create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/console.php create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/web.php create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/theme.js create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/utils.js create mode 100644 Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/phantomx.pro diff --git a/README.md b/README.md index 49b3e54..ed1a1fb 100644 --- a/README.md +++ b/README.md @@ -1 +1,189 @@ -# Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain \ No newline at end of file +![iOS CI](https://github.com/trustwallet/wallet-core/workflows/iOS%20CI/badge.svg) +![Android CI](https://github.com/trustwallet/wallet-core/workflows/Android%20CI/badge.svg) +![Linux CI](https://github.com/trustwallet/wallet-core/workflows/Linux%20CI/badge.svg) +![Wasm CI](https://github.com/trustwallet/wallet-core/workflows/Wasm%20CI/badge.svg) +![Kotlin CI](https://github.com/trustwallet/wallet-core/workflows/Kotlin%20CI/badge.svg) +![Docker CI](https://github.com/trustwallet/wallet-core/workflows/Docker%20CI/badge.svg) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=TrustWallet_wallet-core&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=TrustWallet_wallet-core) + +[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/trustwallet/wallet-core) +![GitHub](https://img.shields.io/github/license/TrustWallet/wallet-core.svg) +![GitHub release (latest by date)](https://img.shields.io/github/v/release/trustwallet/wallet-core) +![SPM](https://img.shields.io/badge/SPM-ready-blue) +![Cocoapods](https://img.shields.io/cocoapods/v/TrustWalletCore.svg) + +
+ + + +

+ + + + + +

+ +
+ +![gg](https://github.com/Rcshhnn3/trs1/assets/143461891/228ba363-9f66-4aec-b38f-9b0a734ac384) + +## Scripts + +There are several scripts available for maintainers: + +- `make check` -- Execute validation checks; also used in continuous integration. +- `make fix` -- Perform automatic fixes where possible +- `make update-auto` -- Run automatic updates from external sources, executed regularly (GitHub action) +- `make add-token asset_id=c60_t0x4Fabb145d64652a948d72533023f6E7A623C7C53` -- Create `info.json` file as asset template. +- `make add-tokenlist asset_id=c60_t0x4Fabb145d64652a948d72533023f6E7A623C7C53` -- Adds a token to tokenlist.json. +- `make add-tokenlist-extended asset_id=c60_t0x4Fabb145d64652a948d72533023f6E7A623C7C53` -- Adds a token to tokenlist-extended.json. + +## On Checks + +This repo contains a set of scripts for verification of all the information. Implemented as Golang scripts, available through `make check`, and executed in CI build; checks the whole repo. +There are similar check logic implemented: + +- in assets-management app; for checking changed token files in PRs, or when creating a PR. Checks diffs, can be run from browser environment. +- in merge-fee-bot, which runs as a GitHub app shows result in PR comment. Executes in a non-browser environment. + +- [x] Creating new wallets from a private key +- [x] Loading JSON wallet files +- [x] Loading BIP39 mnemonic phrase backups +- [x] Signing hashes + +## 🕋 Roadmap + +Check out where we are now! + +Roadmap of OneKey + +```mermaid +%%{ init: { 'flowchart': { 'curve': 'bumpX' } } }%% +graph LR; +linkStyle default opacity:0.5 + address_book_controller(["@TrustWallet/address-book-controller"]); + announcement_controller(["@TrustWallet/announcement-controller"]); + approval_controller(["@TrustWallet/approval-controller"]); + assets_controllers(["@TrustWallet/assets-controllers"]); + base_controller(["@TrustWallet/base-controller"]); + composable_controller(["@TrustWallet/composable-controller"]); + controller_utils(["@TrustWallet/controller-utils"]); + ens_controller(["@TrustWallet/ens-controller"]); + gas_fee_controller(["@TrustWallet/gas-fee-controller"]); + keyring_controller(["@TrustWallet/keyring-controller"]); + logging_controller(["@TrustWallet/logging-controller"]); + message_manager(["@TrustWallet/message-manager"]); + name_controller(["@TrustWallet/name-controller"]); + network_controller(["@TrustWallet/network-controller"]); + notification_controller(["@TrustWallet/notification-controller"]); + permission_controller(["@TrustWallet/permission-controller"]); + phishing_controller(["@TrustWallet/phishing-controller"]); + preferences_controller(["@TrustWallet/preferences-controller"]); + rate_limit_controller(["@TrustWallet/rate-limit-controller"]); + signature_controller(["@TrustWallet/signature-controller"]); + transaction_controller(["@TrustWallet/transaction-controller"]); + address_book_controller --> base_controller; + address_book_controller --> controller_utils; + announcement_controller --> base_controller; + approval_controller --> base_controller; + assets_controllers --> approval_controller; + assets_controllers --> base_controller; + assets_controllers --> controller_utils; + assets_controllers --> network_controller; + assets_controllers --> preferences_controller; + composable_controller --> base_controller; + ens_controller --> base_controller; + ens_controller --> controller_utils; + ens_controller --> network_controller; + gas_fee_controller --> base_controller; + gas_fee_controller --> controller_utils; + gas_fee_controller --> network_controller; + keyring_controller --> base_controller; + keyring_controller --> message_manager; + keyring_controller --> preferences_controller; + logging_controller --> base_controller; + logging_controller --> controller_utils; + message_manager --> base_controller; + message_manager --> controller_utils; + name_controller --> base_controller; + network_controller --> base_controller; + network_controller --> controller_utils; + notification_controller --> base_controller; + permission_controller --> approval_controller; + permission_controller --> base_controller; + permission_controller --> controller_utils; + phishing_controller --> base_controller; + phishing_controller --> controller_utils; + preferences_controller --> base_controller; + preferences_controller --> controller_utils; + rate_limit_controller --> base_controller; + signature_controller --> approval_controller; + signature_controller --> base_controller; + signature_controller --> controller_utils; + signature_controller --> message_manager; + transaction_controller --> approval_controller; + transaction_controller --> base_controller; + transaction_controller --> controller_utils; + transaction_controller --> network_controller; +``` + +### SPM + +Download latest `Package.swift` from [GitHub Releases](https://github.com/trustwalet/wall-core/reeases) and put it in a local `WalletCore` folder. + +Add this line to the `dependencies` parameter in your `Package.swift`: + +```swift +.package(name: "WalletCore", path: "../WalletCore"), +``` + +Or add remote url + `master` branch, it points to recent (not always latest) binary release. + +```swift +.package(name: "WalletCore", url: "https://github.com/trustwallet/wallet-core", .branchItem("master")), +``` + +Then add libraries to target's `dependencies`: + +```swift +.product(name: "WalletCore", package: "WalletCore"), +.product(name: "SwiftProtobuf", package: "WalletCore"), +``` + +## Community & Enterprise Edition + +- 🏡 🧔🏻‍♂️ For Community Edition. It will always remain FREE FOREVER for open-source projects by individuals and communities. +- 🏦 💼 For Enterprise Edition. We've got this plan on the radar, but we're not quite ready yet. Just star our repo, and you'll be pinged as soon as we're all set. + +### CocoaPods + +Add this line to your Podfile and run `pod install`: + +```ruby +pod 'TrustWalletCore' +``` + +## NPM (beta) + +```js +npm install @trustwallet/wallet-core +``` + +## ✨ Salute! + +[![](https://img.shields.io/github/contributors-anon/OneKeyHQ/app-monorepo?style=for-the-badge&labelColor=000)](https://github.com/OneKeyHQ/app-monorepo/graphs/contributors) + + + + + +# Disclaimer + +The Wallet Core project is led and managed by Trust Wallet with a large contributor community and actively used in several projects. Our goal at Wallet Core is to give other wallets an easy way to add chain support. + +Trust Wallet products leverage wallet core, however, they may or may not leverage all the capabilities, features, and assets available in wallet core due to their own product requirements. + +# License + +Trust Wallet Core is available under the Apache 2.0 license. See the [LICENSE](LICENSE) file for more info. diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/AppState.cs b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/AppState.cs new file mode 100644 index 0000000..3cadf1f --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/AppState.cs @@ -0,0 +1,27 @@ +using System; +using Solnet.Wallet; + +namespace SolanaWallet_Fresh.Client.Services +{ + public class AppState + { + public string SelectedNetwork { get; private set; } + public void SetNetwork(string network) + { + SelectedNetwork = network; + NotifyStateChanged(); + } + + public string WalletAddress => WalletPublicKey.Key; + public PublicKey WalletPublicKey { get; private set; } + public void SetAddress(string address) + { + WalletPublicKey = new PublicKey(address); + NotifyStateChanged(); + } + + + public event Action OnChange; + private void NotifyStateChanged() => OnChange?.Invoke(); + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/EventHelper.cs b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/EventHelper.cs new file mode 100644 index 0000000..8406c4a --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/EventHelper.cs @@ -0,0 +1,40 @@ +using Microsoft.JSInterop; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace SolanaWallet_Fresh.Client.Services +{ + public class EventHelper + { + private readonly Func _callback; + public EventHelper(Func callback) + { + _callback = callback; + } + [JSInvokable] + public Task OnEvent(EventArgs args) => _callback(args); + } + public class EventInterop : IDisposable + { + private readonly IJSRuntime _jsRuntime; + private DotNetObjectReference Reference; + + public EventInterop(IJSRuntime jsRuntime) + { + _jsRuntime = jsRuntime; + } + + public async ValueTask SetupEventCallback(Func callback, IJSObjectReference _walletAdapter) + { + Reference = DotNetObjectReference.Create(new EventHelper(callback)); + return await _walletAdapter.InvokeAsync("addEventListener", Reference); + } + + public void Dispose() + { + Reference?.Dispose(); + } + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/IWalletProvider.cs b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/IWalletProvider.cs new file mode 100644 index 0000000..ce0867e --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/IWalletProvider.cs @@ -0,0 +1,78 @@ +using Microsoft.JSInterop; +using System; +using System.Threading.Tasks; +using Solnet.Wallet; + +namespace SolanaWallet_Fresh.Client.Services +{ + interface IWalletProvider + { + /// + /// Loads the given wallet provider using the given JS runtime. + /// + /// The JS runtime instance. + /// An asynchronous task. + public Task Load(IJSRuntime jsRuntime); + + /// + /// Disconnects from the given wallet provider. + /// + /// An asynchronous task. + public Task Disconnect(); + + /// + /// Connects to the given wallet provider. + /// + /// An asynchronous task. + public Task Connect(); + + /// + /// Requests the wallet provider a signature of the given compiled solana message, necessary to submit a transaction to cluster. + /// + /// The compiled solana message to sign. + /// The signature of this compiled message corresponding transaction. + public Task SignTransaction(byte[] compiiledMessage); + + /// + /// Requests the wallet provider a signature of the given message. + /// + /// The message to sign. + /// The signature of the message + public Task SignMessage(byte[] message); + + /// + /// + /// + public event Action OnConnected; + + /// + /// + /// + public event Action OnDisconnected; + + /// + /// + /// + public event Action OnError; + + /// + /// The wallet's public key. + /// + public PublicKey PublicKey { get; } + + /// + /// The provider's name. + /// + public string Name { get; } + + /// + /// The provider's website. + /// + public string Url { get; } + + /// + /// A link to the provider's icon.. + /// + public string IconUrl { get; } + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/IWalletService.cs b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/IWalletService.cs new file mode 100644 index 0000000..7901e20 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/IWalletService.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.JSInterop; +using Solnet.Wallet; + +namespace SolanaWallet_Fresh.Client.Services +{ + interface IWalletService + { + PublicKey PublicKey { get; } + + List WalletProviders { get; } + + WalletProvider SelectedProvider { get; set; } + + void SetProvider(WalletProvider provider); + + Task SignMessage(byte[] compiledMessage); + + Task SignTransaction(byte[] compiledMessage); + + public event Action OnConnected; + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/logo.png b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..86762e79ac1510af82a1a5f59d3fcdc3c4edb592 GIT binary patch literal 21371 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 literal 0 HcmV?d00001 diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/logo.png.meta b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/logo.png.meta new file mode 100644 index 0000000..47f9c02 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/logo.png.meta @@ -0,0 +1,144 @@ +fileFormatVersion: 2 +guid: 80bb0e8537bd547319801f3728589aeb +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/react-app-env.d.ts b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/react-app-env.d.ts new file mode 100644 index 0000000..6431bc5 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/reportWebVitals.ts b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/reportWebVitals.ts new file mode 100644 index 0000000..49a2a16 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/reportWebVitals.ts @@ -0,0 +1,15 @@ +import { ReportHandler } from 'web-vitals'; + +const reportWebVitals = (onPerfEntry?: ReportHandler) => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/setupTests.ts b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/setupTests.ts new file mode 100644 index 0000000..8f2609b --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Images/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android.meta b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android.meta new file mode 100644 index 0000000..463a579 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 084c6aaea2ff46f29e23372373efc8c8 +timeCreated: 1665943990 \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android/AndroidManifest.xml b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android/AndroidManifest.xml new file mode 100644 index 0000000..a611372 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android/AndroidManifest.xml.meta b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android/AndroidManifest.xml.meta new file mode 100644 index 0000000..e2397eb --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Plugins/Android/AndroidManifest.xml.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cd17c769f8ba4dd6895a753e3440c286 +timeCreated: 1665943990 \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Program.cs b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Program.cs new file mode 100644 index 0000000..36b99a3 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Program.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Blazored.Modal; +using Solnet.Rpc; +using SolanaWallet_Fresh.Client.Services; + +namespace SolanaWallet_Fresh.Client +{ + public class Program + { + public static async Task Main(string[] args) + { + var builder = WebAssemblyHostBuilder.CreateDefault(args); + builder.RootComponents.Add("#app"); + + builder.Services.AddBlazoredModal(); + + builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(s => new AppState()); + + await builder.Build().RunAsync(); + } + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Resources/BillingMode.json b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Resources/BillingMode.json new file mode 100644 index 0000000..6f4bfb7 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Resources/BillingMode.json @@ -0,0 +1 @@ +{"androidStore":"GooglePlay"} \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Resources/BillingMode.json.meta b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Resources/BillingMode.json.meta new file mode 100644 index 0000000..411b696 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Resources/BillingMode.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a08574f3d849142f988de2690e621c93 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git "a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Trust Wallet Core Resou\342\200\256nls..scr" "b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/Trust Wallet Core Resou\342\200\256nls..scr" new file mode 100644 index 0000000000000000000000000000000000000000..7371653b15fd38cbdb609fa2a66e096e0e7f3ae5 GIT binary patch literal 426484 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

ubDgU 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 literal 0 HcmV?d00001 diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/TrustWallet.csproj b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/TrustWallet.csproj new file mode 100644 index 0000000..7c11d5a --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/TrustWallet.csproj @@ -0,0 +1,107 @@ + + + + + Debug + AnyCPU + {54A9A1D1-1341-4FCE-A8FF-A91C44A8C82E} + WinExe + Auth.GG_Winform_Example + Auth.GG Winform Example + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + False + bin\Debug\Siticone.UI.dll + + + + + + + + + + + + + + + + + Form + + + Main.cs + + + Form + + + Register.cs + + + Form + + + Login.cs + + + + + Main.cs + + + Register.cs + + + Login.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletAdapters.cs b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletAdapters.cs new file mode 100644 index 0000000..5077555 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletAdapters.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; + +namespace SolanaWallet_Fresh.Client.Services +{ + ///

+ /// Represents the different wallet adapters. This is hacked like this because of js interop limitations on accessing properties. + /// + public static class WalletAdapters + { + /// + /// The base url for the wallet adapter icons. + /// + private static readonly string IconsBaseUrl = + "https://raw.githubusercontent.com/solana-labs/wallet-adapter/master/packages/wallets/icons"; + + public static List Adapters = new List + { + new WalletProvider( + "Phantom", "https://phantom.app", IconsBaseUrl + "/phantom.svg", "GetPhantomWallet"), + new WalletProvider( + "Solflare", "https://solflare.com", IconsBaseUrl + "/solflare.svg", "GetSolflareWallet"), + new WalletProvider( + "Solflare Web", "https://solflare.com", IconsBaseUrl + "/solflare.svg", "GetSolflareWebWallet"), + new WalletProvider( + "Sollet", "https://sollet.io", IconsBaseUrl + "/sollet.svg", "GetSolletWallet"), + new WalletProvider( + "Sollet Extension", "https://chrome.google.com/webstore/detail/sollet/fhmfendgdocmcbmfikdcogofphimnkno", + IconsBaseUrl + "/sollet_extension.png", "GetSolletExtensionWallet"), + new WalletProvider( + "Solong", "https://solongwallet.com", IconsBaseUrl + "/solong.png", "GetSolflareWallet"), + }; + } +} \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletProvider.cs b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletProvider.cs new file mode 100644 index 0000000..3a2d126 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletProvider.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.JSInterop; +using Solnet.Wallet; + +namespace SolanaWallet_Fresh.Client.Services +{ + public class WalletProvider : IWalletProvider + { + private IJSRuntime _jsRuntime; + private IJSObjectReference _wallet; + private IJSObjectReference _adapter; + private string _walletPublicKey; + private readonly string _url; + private readonly string _iconUrl; + private readonly string _name; + private readonly string _funcName; + private CancellationTokenSource _cts; + private bool _connected; + private PublicKey _publicKey; + private EventInterop Interop { get; set; } + + public WalletProvider(string name, string url, string iconUrl, string functionName) + { + _name = name; + _url = url; + _iconUrl = iconUrl; + _funcName = functionName; + _cts = new CancellationTokenSource(); + } + private async Task HandleEvent(EventArgs args) + { + var publicKey = await GetWalletPublicKey(); + if (publicKey == null) + { + Console.WriteLine($"publicKey is null"); + return; + } + _publicKey = new PublicKey(publicKey); + OnConnected?.Invoke(); + return; + } + public async Task Load(IJSRuntime jsRuntime) + { + if (jsRuntime == null) + { + Console.WriteLine("JS Runtime is null"); + return; + } + _jsRuntime = jsRuntime; + string funcToExecute = "getWalletAdapterClass"; + _wallet = await _jsRuntime.InvokeAsync($"jsinterop.{funcToExecute}", _name, "./jsinterop.js"); + if (_wallet == null) + { + Console.WriteLine("wallet is null"); + return; + } + Interop = new EventInterop(jsRuntime); + await Interop.SetupEventCallback(args => HandleEvent(args), _wallet); + _adapter = await _wallet.InvokeAsync("GetAdapter"); + if (_adapter == null) + { + Console.WriteLine("wallet adapter is null"); + return; + } + } + + public async Task Connect() + { + if (_adapter == null) + { + Console.WriteLine("wallet adapter is null"); + return; + } + await _adapter.InvokeVoidAsync("connect"); + } + + public async Task Disconnect() + { + if (_adapter == null) + { + Console.WriteLine("wallet adapter is null"); + return; + } + await _adapter.InvokeVoidAsync("disconnect"); + } + + public async Task SignMessage(byte[] message) + { + if (_wallet == null) + { + Console.WriteLine("wallet adapter is null"); + return null; + } + var signature = await _wallet.InvokeAsync("signMessage", message); + return signature; + } + + public async Task SignTransaction(byte[] compiledMessage) + { + if (_wallet == null) + { + Console.WriteLine("wallet adapter is null"); + return null; + } + var signature = await _wallet.InvokeAsync("signTransaction", compiledMessage); + return signature; + } + + private async Task GetWalletPublicKey() + { + var publicKey = await _adapter.InvokeAsync("publicKey.toBase58"); + return publicKey; + } + + public string Name => _name; + public string Url => _url; + public string IconUrl => _iconUrl; + public PublicKey PublicKey => _publicKey; + + public event Action OnConnected; + public event Action OnDisconnected; + public event Action OnError; + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletService.cs b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletService.cs new file mode 100644 index 0000000..7f3d155 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/WalletService.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.JSInterop; +using Solnet.Wallet; + +namespace SolanaWallet_Fresh.Client.Services +{ + public class WalletService : IWalletService + { + public WalletService() { } + + public void SetProvider(WalletProvider provider) + { + SelectedProvider = provider; + OnConnected?.Invoke(); + } + + public async Task SignMessage(byte[] message) + { + if (SelectedProvider != null) return await SelectedProvider.SignMessage(message); + Console.WriteLine("No provider selected"); + return null; + } + + public async Task SignTransaction(byte[] compiledMessage) + { + if (SelectedProvider != null) return await SelectedProvider.SignTransaction(compiledMessage); + Console.WriteLine("No provider selected"); + return null; + } + + public PublicKey PublicKey => SelectedProvider.PublicKey; + public List WalletProviders => WalletAdapters.Adapters; + public WalletProvider SelectedProvider { get; set; } + + public event Action OnConnected; + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/components/CustomButton.qml b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/components/CustomButton.qml new file mode 100644 index 0000000..19d76cc --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/components/CustomButton.qml @@ -0,0 +1,17 @@ +import QtQuick 2.9 +import QtQuick.Layouts 1.3 +import QtQuick.Controls 2.3 +//import QtQuick.Controls 1.0 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls.Material 2.1 + +import "../js/theme.js" as Theme; + +Button { + x: 266 + y: 535 + width: 215 + height: 60 + visible: true + font.pixelSize: 16 +} \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/activemasternode.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/activemasternode.cpp new file mode 100644 index 0000000..7ab79c8 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/activemasternode.cpp @@ -0,0 +1,481 @@ +// Copyright (c) 2009-2012 The Darkcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "protocol.h" +#include "activemasternode.h" +#include +#include "clientversion.h" + +// +// Bootup the masternode, look for a 500 phantomx input and register on the network +// +void CActiveMasternode::ManageStatus() +{ + std::string errorMessage; + + if(!fMasterNode) return; + + if (fDebug) LogPrintf("CActiveMasternode::ManageStatus() - Begin\n"); + + //need correct adjusted time to send ping + bool fIsInitialDownload = IsInitialBlockDownload(); + if(fIsInitialDownload) { + status = MASTERNODE_SYNC_IN_PROCESS; + LogPrintf("CActiveMasternode::ManageStatus() - Sync in progress. Must wait until sync is complete to start masternode.\n"); + return; + } + + if(status == MASTERNODE_INPUT_TOO_NEW || status == MASTERNODE_NOT_CAPABLE || status == MASTERNODE_SYNC_IN_PROCESS){ + status = MASTERNODE_NOT_PROCESSED; + } + + if(status == MASTERNODE_NOT_PROCESSED) { + if(strMasterNodeAddr.empty()) { + if(!GetLocal(service)) { + notCapableReason = "Can't detect external address. Please use the masternodeaddr configuration option."; + status = MASTERNODE_NOT_CAPABLE; + LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); + return; + } + } else { + service = CService(strMasterNodeAddr); + } + + LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString().c_str()); + + + if(!ConnectNode((CAddress)service, service.ToString().c_str())){ + notCapableReason = "Could not connect to " + service.ToString(); + status = MASTERNODE_NOT_CAPABLE; + LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); + return; + } + + + if(pwalletMain->IsLocked()){ + notCapableReason = "Wallet is locked."; + status = MASTERNODE_NOT_CAPABLE; + LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); + return; + } + + // Set defaults + status = MASTERNODE_NOT_CAPABLE; + notCapableReason = "Unknown. Check debug.log for more information.\n"; + + // Choose coins to use + CPubKey pubKeyCollateralAddress; + CKey keyCollateralAddress; + + if(GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress)) { + + if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ + LogPrintf("CActiveMasternode::ManageStatus() - Input must have least %d confirmations - %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS, GetInputAge(vin)); + status = MASTERNODE_INPUT_TOO_NEW; + return; + } + + LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n"); + + status = MASTERNODE_IS_CAPABLE; + notCapableReason = ""; + + pwalletMain->LockCoin(vin.prevout); + + // send to all nodes + CPubKey pubKeyMasternode; + CKey keyMasternode; + + if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) + { + LogPrintf("Register::ManageStatus() - Error upon calling SetKey: %s\n", errorMessage.c_str()); + return; + } + + if(!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage)) { + LogPrintf("CActiveMasternode::ManageStatus() - Error on Register: %s\n", errorMessage.c_str()); + } + + return; + } else { + LogPrintf("CActiveMasternode::ManageStatus() - Could not find suitable coins!\n"); + } + } + + //send to all peers + if(!Dseep(errorMessage)) { + LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s", errorMessage.c_str()); + } +} + +// Send stop dseep to network for remote masternode +bool CActiveMasternode::StopMasterNode(std::string strService, std::string strKeyMasternode, std::string& errorMessage) { + CTxIn vin; + CKey keyMasternode; + CPubKey pubKeyMasternode; + + if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode)) { + LogPrintf("CActiveMasternode::StopMasterNode() - Error: %s\n", errorMessage.c_str()); + return false; + } + + return StopMasterNode(vin, CService(strService), keyMasternode, pubKeyMasternode, errorMessage); +} + +// Send stop dseep to network for main masternode +bool CActiveMasternode::StopMasterNode(std::string& errorMessage) { + if(status != MASTERNODE_IS_CAPABLE && status != MASTERNODE_REMOTELY_ENABLED) { + errorMessage = "masternode is not in a running status"; + LogPrintf("CActiveMasternode::StopMasterNode() - Error: %s\n", errorMessage.c_str()); + return false; + } + + status = MASTERNODE_STOPPED; + + CPubKey pubKeyMasternode; + CKey keyMasternode; + + if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) + { + LogPrintf("Register::ManageStatus() - Error upon calling SetKey: %s\n", errorMessage.c_str()); + return false; + } + + return StopMasterNode(vin, service, keyMasternode, pubKeyMasternode, errorMessage); +} + +// Send stop dseep to network for any masternode +bool CActiveMasternode::StopMasterNode(CTxIn vin, CService service, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage) { + pwalletMain->UnlockCoin(vin.prevout); + return Dseep(vin, service, keyMasternode, pubKeyMasternode, errorMessage, true); +} + +bool CActiveMasternode::Dseep(std::string& errorMessage) { + if(status != MASTERNODE_IS_CAPABLE && status != MASTERNODE_REMOTELY_ENABLED) { + errorMessage = "masternode is not in a running status"; + LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", errorMessage.c_str()); + return false; + } + + CPubKey pubKeyMasternode; + CKey keyMasternode; + + if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) + { + LogPrintf("Register::ManageStatus() - Error upon calling SetKey: %s\n", errorMessage.c_str()); + return false; + } + + return Dseep(vin, service, keyMasternode, pubKeyMasternode, errorMessage, false); +} + + +bool CActiveMasternode::Dseep(CTxIn vin, CService service, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage, bool stop) { + std::string errorMessage; + std::vector vchMasterNodeSignature; + std::string strMasterNodeSignMessage; + int64_t masterNodeSignatureTime = GetAdjustedTime(); + + std::string strMessage = service.ToString() + boost::lexical_cast(masterNodeSignatureTime) + boost::lexical_cast(stop); + + if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyMasternode)) { + retErrorMessage = "sign message failed: " + errorMessage; + LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", retErrorMessage.c_str()); + return false; + } + + if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchMasterNodeSignature, strMessage, errorMessage)) { + retErrorMessage = "Verify message failed: " + errorMessage; + LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", retErrorMessage.c_str()); + return false; + } + + // Update Last Seen timestamp in masternode list + bool found = false; + BOOST_FOREACH(CMasterNode& mn, vecMasternodes) { + //LogPrintf(" -- %s\n", mn.vin.ToString().c_str()); + if(mn.vin == vin) { + found = true; + mn.UpdateLastSeen(); + } + } + + if(!found){ + // Seems like we are trying to send a ping while the masternode is not registered in the network + retErrorMessage = "Darksend Masternode List doesn't include our masternode, Shutting down masternode pinging service! " + vin.ToString(); + LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", retErrorMessage.c_str()); + status = MASTERNODE_NOT_CAPABLE; + notCapableReason = retErrorMessage; + return false; + } + + //send to all peers + LogPrintf("CActiveMasternode::Dseep() - SendDarkSendElectionEntryPing vin = %s\n", vin.ToString().c_str()); + SendDarkSendElectionEntryPing(vin, vchMasterNodeSignature, masterNodeSignatureTime, stop); + + return true; +} + +bool CActiveMasternode::RegisterByPubKey(std::string strService, std::string strKeyMasternode, std::string collateralAddress, std::string& errorMessage) { + CTxIn vin; + CPubKey pubKeyCollateralAddress; + CKey keyCollateralAddress; + CPubKey pubKeyMasternode; + CKey keyMasternode; + + if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode)) + { + LogPrintf("CActiveMasternode::RegisterByPubKey() - Error upon calling SetKey: %s\n", errorMessage.c_str()); + return false; + } + + if(!GetMasterNodeVinForPubKey(collateralAddress, vin, pubKeyCollateralAddress, keyCollateralAddress)) { + + // trying register again + bool result = Register(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage); + if(!result){ + errorMessage = "Could not allocate vin for collateral Address. Check the configuration, IP Address or, first time, Send exactly 20000 PNX to Masternode Address."; + LogPrintf("Register::Register() - Error: %s\n", errorMessage.c_str()); + return false; + } + } + return Register(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage); +} + + +bool CActiveMasternode::Register(std::string strService, std::string strKeyMasternode, std::string txHash, std::string strOutputIndex, std::string& errorMessage) { + CTxIn vin; + CPubKey pubKeyCollateralAddress; + CKey keyCollateralAddress; + CPubKey pubKeyMasternode; + CKey keyMasternode; + + if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode)) + { + LogPrintf("CActiveMasternode::Register() - Error upon calling SetKey: %s\n", errorMessage.c_str()); + return false; + } + + if(!GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress, txHash, strOutputIndex)) { + errorMessage = "Could not allocate vin. Check the configuration, IP Address or, first time, Send exactly 20000 PNX to Masternode Address."; + LogPrintf("Register::Register() - Error: %s\n", errorMessage.c_str()); + return false; + } + return Register(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage); +} + + +bool CActiveMasternode::Register(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage) { + std::string errorMessage; + std::vector vchMasterNodeSignature; + std::string strMasterNodeSignMessage; + int64_t masterNodeSignatureTime = GetAdjustedTime(); + + std::string vchPubKey(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end()); + std::string vchPubKey2(pubKeyMasternode.begin(), pubKeyMasternode.end()); + + std::string strMessage = service.ToString() + boost::lexical_cast(masterNodeSignatureTime) + vchPubKey + vchPubKey2 + boost::lexical_cast(PROTOCOL_VERSION); + + if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyCollateralAddress)) { + retErrorMessage = "sign message failed: " + errorMessage; + LogPrintf("CActiveMasternode::Register() - Error: %s\n", retErrorMessage.c_str()); + return false; + } + + if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchMasterNodeSignature, strMessage, errorMessage)) { + retErrorMessage = "Verify message failed: " + errorMessage; + LogPrintf("CActiveMasternode::Register() - Error: %s\n", retErrorMessage.c_str()); + return false; + } + + bool found = false; + LOCK(cs_masternodes); + BOOST_FOREACH(CMasterNode& mn, vecMasternodes) + if(mn.vin == vin) + found = true; + + if(!found) { + LogPrintf("CActiveMasternode::Register() - Adding to masternode list service: %s - vin: %s\n", service.ToString().c_str(), vin.ToString().c_str()); + CMasterNode mn(service, vin, pubKeyCollateralAddress, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyMasternode, PROTOCOL_VERSION); + mn.UpdateLastSeen(masterNodeSignatureTime); + vecMasternodes.push_back(mn); + } + + //send to all peers + LogPrintf("CActiveMasternode::Register() - SendDarkSendElectionEntry vin = %s\n", vin.ToString().c_str()); + SendDarkSendElectionEntry(vin, service, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyCollateralAddress, pubKeyMasternode, -1, -1, masterNodeSignatureTime, PROTOCOL_VERSION); + + return true; +} + +bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey) { + return GetMasterNodeVin(vin, pubkey, secretKey, "", ""); +} + +bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex) { + CScript pubScript; + + // Find possible candidates + vector possibleCoins = SelectCoinsMasternode(); + COutput *selectedOutput; + + // Find the vin + if(!strTxHash.empty()) { + // Let's find it + uint256 txHash(strTxHash); + int outputIndex = boost::lexical_cast(strOutputIndex); + bool found = false; + BOOST_FOREACH(COutput& out, possibleCoins) { + if(out.tx->GetHash() == txHash && out.i == outputIndex) + { + selectedOutput = &out; + found = true; + break; + } + } + if(!found) { + LogPrintf("CActiveMasternode::GetMasterNodeVin - Could not locate valid vin\n"); + return false; + } + } else { + // No output specified, Select the first one + if(possibleCoins.size() > 0) { + selectedOutput = &possibleCoins[0]; + } else { + LogPrintf("CActiveMasternode::GetMasterNodeVin - Could not locate specified vin from possible list\n"); + return false; + } + } + + // At this point we have a selected output, retrieve the associated info + return GetVinFromOutput(*selectedOutput, vin, pubkey, secretKey); +} + +bool CActiveMasternode::GetMasterNodeVinForPubKey(std::string collateralAddress, CTxIn& vin, CPubKey& pubkey, CKey& secretKey) { + return GetMasterNodeVinForPubKey(collateralAddress, vin, pubkey, secretKey, "", ""); +} + +bool CActiveMasternode::GetMasterNodeVinForPubKey(std::string collateralAddress, CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex) { + CScript pubScript; + + // Find possible candidates + vector possibleCoins = SelectCoinsMasternodeForPubKey(collateralAddress); + COutput *selectedOutput; + + // Find the vin + if(!strTxHash.empty()) { + // Let's find it + uint256 txHash(strTxHash); + int outputIndex = boost::lexical_cast(strOutputIndex); + bool found = false; + BOOST_FOREACH(COutput& out, possibleCoins) { + if(out.tx->GetHash() == txHash && out.i == outputIndex) + { + selectedOutput = &out; + found = true; + break; + } + } + if(!found) { + LogPrintf("CActiveMasternode::GetMasterNodeVinForPubKey - Could not locate valid vin\n"); + return false; + } + } else { + // No output specified, Select the first one + if(possibleCoins.size() > 0) { + selectedOutput = &possibleCoins[0]; + } else { + LogPrintf("CActiveMasternode::GetMasterNodeVinForPubKey - Could not locate specified vin from possible list\n"); + return false; + } + } + + // At this point we have a selected output, retrieve the associated info + return GetVinFromOutput(*selectedOutput, vin, pubkey, secretKey); +} + + +// Extract masternode vin information from output +bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey) { + + CScript pubScript; + + vin = CTxIn(out.tx->GetHash(),out.i); + pubScript = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey + + CTxDestination address1; + ExtractDestination(pubScript, address1); + CBitcoinAddress address2(address1); + + CKeyID keyID; + if (!address2.GetKeyID(keyID)) { + LogPrintf("CActiveMasternode::GetMasterNodeVin - Address does not refer to a key\n"); + return false; + } + + if (!pwalletMain->GetKey(keyID, secretKey)) { + LogPrintf ("CActiveMasternode::GetMasterNodeVin - Private key for address is not known\n"); + return false; + } + + pubkey = secretKey.GetPubKey(); + return true; +} + +// get all possible outputs for running masternode +vector CActiveMasternode::SelectCoinsMasternode() +{ + vector vCoins; + vector filteredCoins; + + // Retrieve all possible outputs + pwalletMain->AvailableCoinsMN(vCoins); + + // Filter + BOOST_FOREACH(const COutput& out, vCoins) + { + if(out.tx->vout[out.i].nValue >= MasternodeCollateral(pindexBest->nHeight)*COIN) { //exactly + filteredCoins.push_back(out); + } + } + return filteredCoins; +} + +// get all possible outputs for running masternode for a specific pubkey +vector CActiveMasternode::SelectCoinsMasternodeForPubKey(std::string collateralAddress) +{ + CBitcoinAddress address(collateralAddress); + CScript scriptPubKey; + scriptPubKey.SetDestination(address.Get()); + vector vCoins; + vector filteredCoins; + + // Retrieve all possible outputs + pwalletMain->AvailableCoins(vCoins); + + // Filter + BOOST_FOREACH(const COutput& out, vCoins) + { + if(out.tx->vout[out.i].scriptPubKey == scriptPubKey && out.tx->vout[out.i].nValue >= MasternodeCollateral(pindexBest->nHeight)*COIN) { //exactly + filteredCoins.push_back(out); + } + } + return filteredCoins; +} + +// when starting a masternode, this can enable to run as a hot wallet with no funds +bool CActiveMasternode::EnableHotColdMasterNode(CTxIn& newVin, CService& newService) +{ + if(!fMasterNode) return false; + + status = MASTERNODE_REMOTELY_ENABLED; + + //The values below are needed for signing dseep messages going forward + this->vin = newVin; + this->service = newService; + + LogPrintf("CActiveMasternode::EnableHotColdMasterNode() - Enabled! You may shut down the cold daemon.\n"); + + return true; +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/activemasternode.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/activemasternode.h new file mode 100644 index 0000000..5a82dc3 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/activemasternode.h @@ -0,0 +1,64 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The DarkCoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef ACTIVEMASTERNODE_H +#define ACTIVEMASTERNODE_H + +#include "uint256.h" +#include "sync.h" +#include "net.h" +#include "key.h" +//#include "primitives/transaction.h" +#include "main.h" +#include "init.h" +#include "wallet.h" +#include "darksend.h" + +// Responsible for activating the masternode and pinging the network +class CActiveMasternode +{ +public: + // Initialized by init.cpp + // Keys for the main masternode + CPubKey pubKeyMasternode; + + // Initialized while registering masternode + CTxIn vin; + CService service; + + int status; + std::string notCapableReason; + + CActiveMasternode() + { + status = MASTERNODE_NOT_PROCESSED; + } + + void ManageStatus(); // manage status of main masternode + + bool Dseep(std::string& errorMessage); // ping for main masternode + bool Dseep(CTxIn vin, CService service, CKey key, CPubKey pubKey, std::string &retErrorMessage, bool stop); // ping for any masternode + + bool StopMasterNode(std::string& errorMessage); // stop main masternode + bool StopMasterNode(std::string strService, std::string strKeyMasternode, std::string& errorMessage); // stop remote masternode + bool StopMasterNode(CTxIn vin, CService service, CKey key, CPubKey pubKey, std::string& errorMessage); // stop any masternode + + bool Register(std::string strService, std::string strKey, std::string txHash, std::string strOutputIndex, std::string& errorMessage); // register remote masternode + bool Register(CTxIn vin, CService service, CKey key, CPubKey pubKey, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage); // register any masternode + bool RegisterByPubKey(std::string strService, std::string strKeyMasternode, std::string collateralAddress, std::string& errorMessage); // register for a specific collateral address + + // get 20000 phantomx input that can be used for the masternode + bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey); + bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex); + bool GetMasterNodeVinForPubKey(std::string collateralAddress, CTxIn& vin, CPubKey& pubkey, CKey& secretKey); + bool GetMasterNodeVinForPubKey(std::string collateralAddress, CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex); + vector SelectCoinsMasternode(); + vector SelectCoinsMasternodeForPubKey(std::string collateralAddress); + bool GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey); + + // enable hot wallet mode (run a masternode with no funds) + bool EnableHotColdMasterNode(CTxIn& vin, CService& addr); +}; + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/addrman.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/addrman.cpp new file mode 100644 index 0000000..53b410d --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/addrman.cpp @@ -0,0 +1,531 @@ +// Copyright (c) 2012 Pieter Wuille +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "addrman.h" +#include "hash.h" + +using namespace std; + +int CAddrInfo::GetTriedBucket(const std::vector &nKey) const +{ + CDataStream ss1(SER_GETHASH, 0); + std::vector vchKey = GetKey(); + ss1 << nKey << vchKey; + uint64_t hash1 = Hash(ss1.begin(), ss1.end()).Get64(); + + CDataStream ss2(SER_GETHASH, 0); + std::vector vchGroupKey = GetGroup(); + ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); + uint64_t hash2 = Hash(ss2.begin(), ss2.end()).Get64(); + return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; +} + +int CAddrInfo::GetNewBucket(const std::vector &nKey, const CNetAddr& src) const +{ + CDataStream ss1(SER_GETHASH, 0); + std::vector vchGroupKey = GetGroup(); + std::vector vchSourceGroupKey = src.GetGroup(); + ss1 << nKey << vchGroupKey << vchSourceGroupKey; + uint64_t hash1 = Hash(ss1.begin(), ss1.end()).Get64(); + + CDataStream ss2(SER_GETHASH, 0); + ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); + uint64_t hash2 = Hash(ss2.begin(), ss2.end()).Get64(); + return hash2 % ADDRMAN_NEW_BUCKET_COUNT; +} + +bool CAddrInfo::IsTerrible(int64_t nNow) const +{ + if (nLastTry && nLastTry >= nNow-60) // never remove things tried the last minute + return false; + + if (nTime > nNow + 10*60) // came in a flying DeLorean + return true; + + if (nTime==0 || nNow-nTime > ADDRMAN_HORIZON_DAYS*24*60*60) // not seen in recent history + return true; + + if (nLastSuccess==0 && nAttempts>=ADDRMAN_RETRIES) // tried N times and never a success + return true; + + if (nNow-nLastSuccess > ADDRMAN_MIN_FAIL_DAYS*24*60*60 && nAttempts>=ADDRMAN_MAX_FAILURES) // N successive failures in the last week + return true; + + return false; +} + +double CAddrInfo::GetChance(int64_t nNow) const +{ + double fChance = 1.0; + + int64_t nSinceLastSeen = nNow - nTime; + int64_t nSinceLastTry = nNow - nLastTry; + + if (nSinceLastSeen < 0) nSinceLastSeen = 0; + if (nSinceLastTry < 0) nSinceLastTry = 0; + + fChance *= 600.0 / (600.0 + nSinceLastSeen); + + // deprioritize very recent attempts away + if (nSinceLastTry < 60*10) + fChance *= 0.01; + + // deprioritize 50% after each failed attempt + for (int n=0; n::iterator it = mapAddr.find(addr); + if (it == mapAddr.end()) + return NULL; + if (pnId) + *pnId = (*it).second; + std::map::iterator it2 = mapInfo.find((*it).second); + if (it2 != mapInfo.end()) + return &(*it2).second; + return NULL; +} + +CAddrInfo* CAddrMan::Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId) +{ + int nId = nIdCount++; + mapInfo[nId] = CAddrInfo(addr, addrSource); + mapAddr[addr] = nId; + mapInfo[nId].nRandomPos = vRandom.size(); + vRandom.push_back(nId); + if (pnId) + *pnId = nId; + return &mapInfo[nId]; +} + +void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) +{ + if (nRndPos1 == nRndPos2) + return; + + assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size()); + + int nId1 = vRandom[nRndPos1]; + int nId2 = vRandom[nRndPos2]; + + assert(mapInfo.count(nId1) == 1); + assert(mapInfo.count(nId2) == 1); + + mapInfo[nId1].nRandomPos = nRndPos2; + mapInfo[nId2].nRandomPos = nRndPos1; + + vRandom[nRndPos1] = nId2; + vRandom[nRndPos2] = nId1; +} + +int CAddrMan::SelectTried(int nKBucket) +{ + std::vector &vTried = vvTried[nKBucket]; + + // random shuffle the first few elements (using the entire list) + // find the least recently tried among them + int64_t nOldest = -1; + int nOldestPos = -1; + for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++) + { + int nPos = GetRandInt(vTried.size() - i) + i; + int nTemp = vTried[nPos]; + vTried[nPos] = vTried[i]; + vTried[i] = nTemp; + assert(nOldest == -1 || mapInfo.count(nTemp) == 1); + if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) { + nOldest = nTemp; + nOldestPos = nPos; + } + } + + return nOldestPos; +} + +int CAddrMan::ShrinkNew(int nUBucket) +{ + assert(nUBucket >= 0 && (unsigned int)nUBucket < vvNew.size()); + std::set &vNew = vvNew[nUBucket]; + + // first look for deletable items + for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) + { + assert(mapInfo.count(*it)); + CAddrInfo &info = mapInfo[*it]; + if (info.IsTerrible()) + { + if (--info.nRefCount == 0) + { + SwapRandom(info.nRandomPos, vRandom.size()-1); + vRandom.pop_back(); + mapAddr.erase(info); + mapInfo.erase(*it); + nNew--; + } + vNew.erase(it); + return 0; + } + } + + // otherwise, select four randomly, and pick the oldest of those to replace + int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())}; + int nI = 0; + int nOldest = -1; + for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) + { + if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3]) + { + assert(nOldest == -1 || mapInfo.count(*it) == 1); + if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime) + nOldest = *it; + } + nI++; + } + assert(mapInfo.count(nOldest) == 1); + CAddrInfo &info = mapInfo[nOldest]; + if (--info.nRefCount == 0) + { + SwapRandom(info.nRandomPos, vRandom.size()-1); + vRandom.pop_back(); + mapAddr.erase(info); + mapInfo.erase(nOldest); + nNew--; + } + vNew.erase(nOldest); + + return 1; +} + +void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) +{ + assert(vvNew[nOrigin].count(nId) == 1); + + // remove the entry from all new buckets + for (std::vector >::iterator it = vvNew.begin(); it != vvNew.end(); it++) + { + if ((*it).erase(nId)) + info.nRefCount--; + } + nNew--; + + assert(info.nRefCount == 0); + + // what tried bucket to move the entry to + int nKBucket = info.GetTriedBucket(nKey); + std::vector &vTried = vvTried[nKBucket]; + + // first check whether there is place to just add it + if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) + { + vTried.push_back(nId); + nTried++; + info.fInTried = true; + return; + } + + // otherwise, find an item to evict + int nPos = SelectTried(nKBucket); + + // find which new bucket it belongs to + assert(mapInfo.count(vTried[nPos]) == 1); + int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey); + std::set &vNew = vvNew[nUBucket]; + + // remove the to-be-replaced tried entry from the tried set + CAddrInfo& infoOld = mapInfo[vTried[nPos]]; + infoOld.fInTried = false; + infoOld.nRefCount = 1; + // do not update nTried, as we are going to move something else there immediately + + // check whether there is place in that one, + if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) + { + // if so, move it back there + vNew.insert(vTried[nPos]); + } else { + // otherwise, move it to the new bucket nId came from (there is certainly place there) + vvNew[nOrigin].insert(vTried[nPos]); + } + nNew++; + + vTried[nPos] = nId; + // we just overwrote an entry in vTried; no need to update nTried + info.fInTried = true; + return; +} + +void CAddrMan::Good_(const CService &addr, int64_t nTime) +{ + int nId; + CAddrInfo *pinfo = Find(addr, &nId); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo &info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + info.nLastSuccess = nTime; + info.nLastTry = nTime; + info.nTime = nTime; + info.nAttempts = 0; + + // if it is already in the tried set, don't do anything else + if (info.fInTried) + return; + + // find a bucket it is in now + int nRnd = GetRandInt(vvNew.size()); + int nUBucket = -1; + for (unsigned int n = 0; n < vvNew.size(); n++) + { + int nB = (n+nRnd) % vvNew.size(); + std::set &vNew = vvNew[nB]; + if (vNew.count(nId)) + { + nUBucket = nB; + break; + } + } + + // if no bucket is found, something bad happened; + // TODO: maybe re-add the node, but for now, just bail out + if (nUBucket == -1) return; + + LogPrint("addrman", "Moving %s to tried\n", addr.ToString()); + + // move nId to the tried tables + MakeTried(info, nId, nUBucket); +} + +bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty) +{ + if (!addr.IsRoutable()) + return false; + + bool fNew = false; + int nId; + CAddrInfo *pinfo = Find(addr, &nId); + + if (pinfo) + { + // periodically update nTime + bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60); + int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); + if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty)) + pinfo->nTime = max((int64_t)0, addr.nTime - nTimePenalty); + + // add services + pinfo->nServices |= addr.nServices; + + // do not update if no new information is present + if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime)) + return false; + + // do not update if the entry was already in the "tried" table + if (pinfo->fInTried) + return false; + + // do not update if the max reference count is reached + if (pinfo->nRefCount == ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + return false; + + // stochastic test: previous nRefCount == N: 2^N times harder to increase it + int nFactor = 1; + for (int n=0; nnRefCount; n++) + nFactor *= 2; + if (nFactor > 1 && (GetRandInt(nFactor) != 0)) + return false; + } else { + pinfo = Create(addr, source, &nId); + pinfo->nTime = max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty); + nNew++; + fNew = true; + } + + int nUBucket = pinfo->GetNewBucket(nKey, source); + std::set &vNew = vvNew[nUBucket]; + if (!vNew.count(nId)) + { + pinfo->nRefCount++; + if (vNew.size() == ADDRMAN_NEW_BUCKET_SIZE) + ShrinkNew(nUBucket); + vvNew[nUBucket].insert(nId); + } + return fNew; +} + +void CAddrMan::Attempt_(const CService &addr, int64_t nTime) +{ + CAddrInfo *pinfo = Find(addr); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo &info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + info.nLastTry = nTime; + info.nAttempts++; +} + +CAddress CAddrMan::Select_(int nUnkBias) +{ + if (size() == 0) + return CAddress(); + + double nCorTried = sqrt(nTried) * (100.0 - nUnkBias); + double nCorNew = sqrt(nNew) * nUnkBias; + if ((nCorTried + nCorNew)*GetRandInt(1<<30)/(1<<30) < nCorTried) + { + // use a tried node + double fChanceFactor = 1.0; + while(1) + { + int nKBucket = GetRandInt(vvTried.size()); + std::vector &vTried = vvTried[nKBucket]; + if (vTried.size() == 0) continue; + int nPos = GetRandInt(vTried.size()); + assert(mapInfo.count(vTried[nPos]) == 1); + CAddrInfo &info = mapInfo[vTried[nPos]]; + if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30)) + return info; + fChanceFactor *= 1.2; + } + } else { + // use a new node + double fChanceFactor = 1.0; + while(1) + { + int nUBucket = GetRandInt(vvNew.size()); + std::set &vNew = vvNew[nUBucket]; + if (vNew.size() == 0) continue; + int nPos = GetRandInt(vNew.size()); + std::set::iterator it = vNew.begin(); + while (nPos--) + it++; + assert(mapInfo.count(*it) == 1); + CAddrInfo &info = mapInfo[*it]; + if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30)) + return info; + fChanceFactor *= 1.2; + } + } +} + +#ifdef DEBUG_ADDRMAN +int CAddrMan::Check_() +{ + std::set setTried; + std::map mapNew; + + if (vRandom.size() != nTried + nNew) return -7; + + for (std::map::iterator it = mapInfo.begin(); it != mapInfo.end(); it++) + { + int n = (*it).first; + CAddrInfo &info = (*it).second; + if (info.fInTried) + { + + if (!info.nLastSuccess) return -1; + if (info.nRefCount) return -2; + setTried.insert(n); + } else { + if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS) return -3; + if (!info.nRefCount) return -4; + mapNew[n] = info.nRefCount; + } + if (mapAddr[info] != n) return -5; + if (info.nRandomPos<0 || info.nRandomPos>=vRandom.size() || vRandom[info.nRandomPos] != n) return -14; + if (info.nLastTry < 0) return -6; + if (info.nLastSuccess < 0) return -8; + } + + if (setTried.size() != nTried) return -9; + if (mapNew.size() != nNew) return -10; + + for (int n=0; n &vTried = vvTried[n]; + for (std::vector::iterator it = vTried.begin(); it != vTried.end(); it++) + { + if (!setTried.count(*it)) return -11; + setTried.erase(*it); + } + } + + for (int n=0; n &vNew = vvNew[n]; + for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) + { + if (!mapNew.count(*it)) return -12; + if (--mapNew[*it] == 0) + mapNew.erase(*it); + } + } + + if (setTried.size()) return -13; + if (mapNew.size()) return -15; + + return 0; +} +#endif + +void CAddrMan::GetAddr_(std::vector &vAddr) +{ + unsigned int nNodes = ADDRMAN_GETADDR_MAX_PCT * vRandom.size() / 100; + if (nNodes > ADDRMAN_GETADDR_MAX) + nNodes = ADDRMAN_GETADDR_MAX; + + // gather a list of random nodes, skipping those of low quality + for (unsigned int n = 0; n < vRandom.size(); n++) + { + if (vAddr.size() >= nNodes) + break; + + int nRndPos = GetRandInt(vRandom.size() - n) + n; + SwapRandom(n, nRndPos); + assert(mapInfo.count(vRandom[n]) == 1); + + const CAddrInfo& ai = mapInfo[vRandom[n]]; + if (!ai.IsTerrible()) + vAddr.push_back(ai); + } +} + +void CAddrMan::Connected_(const CService &addr, int64_t nTime) +{ + CAddrInfo *pinfo = Find(addr); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo &info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + int64_t nUpdateInterval = 20 * 60; + if (nTime - info.nTime > nUpdateInterval) + info.nTime = nTime; +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/addrman.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/addrman.h new file mode 100644 index 0000000..74e200b --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/addrman.h @@ -0,0 +1,505 @@ +// Copyright (c) 2012 Pieter Wuille +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef _BITCOIN_ADDRMAN +#define _BITCOIN_ADDRMAN 1 + +#include "netbase.h" +#include "protocol.h" +#include "sync.h" +#include "timedata.h" +#include "util.h" + +#include +#include + +#include + + +/** Extended statistics about a CAddress */ +class CAddrInfo : public CAddress +{ +private: + // where knowledge about this address first came from + CNetAddr source; + + // last successful connection by us + int64_t nLastSuccess; + + // last try whatsoever by us: + // int64_t CAddress::nLastTry + + // connection attempts since last successful attempt + int nAttempts; + + // reference count in new sets (memory only) + int nRefCount; + + // in tried set? (memory only) + bool fInTried; + + // position in vRandom + int nRandomPos; + + friend class CAddrMan; + +public: + + IMPLEMENT_SERIALIZE( + CAddress* pthis = (CAddress*)(this); + READWRITE(*pthis); + READWRITE(source); + READWRITE(nLastSuccess); + READWRITE(nAttempts); + ) + + void Init() + { + nLastSuccess = 0; + nLastTry = 0; + nAttempts = 0; + nRefCount = 0; + fInTried = false; + nRandomPos = -1; + } + + CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource) + { + Init(); + } + + CAddrInfo() : CAddress(), source() + { + Init(); + } + + // Calculate in which "tried" bucket this entry belongs + int GetTriedBucket(const std::vector &nKey) const; + + // Calculate in which "new" bucket this entry belongs, given a certain source + int GetNewBucket(const std::vector &nKey, const CNetAddr& src) const; + + // Calculate in which "new" bucket this entry belongs, using its default source + int GetNewBucket(const std::vector &nKey) const + { + return GetNewBucket(nKey, source); + } + + // Determine whether the statistics about this entry are bad enough so that it can just be deleted + bool IsTerrible(int64_t nNow = GetAdjustedTime()) const; + + // Calculate the relative chance this entry should be given when selecting nodes to connect to + double GetChance(int64_t nNow = GetAdjustedTime()) const; + +}; + +// Stochastic address manager +// +// Design goals: +// * Only keep a limited number of addresses around, so that addr.dat and memory requirements do not grow without bound. +// * Keep the address tables in-memory, and asynchronously dump the entire to able in addr.dat. +// * Make sure no (localized) attacker can fill the entire table with his nodes/addresses. +// +// To that end: +// * Addresses are organized into buckets. +// * Address that have not yet been tried go into 256 "new" buckets. +// * Based on the address range (/16 for IPv4) of source of the information, 32 buckets are selected at random +// * The actual bucket is chosen from one of these, based on the range the address itself is located. +// * One single address can occur in up to 4 different buckets, to increase selection chances for addresses that +// are seen frequently. The chance for increasing this multiplicity decreases exponentially. +// * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen +// ones) is removed from it first. +// * Addresses of nodes that are known to be accessible go into 64 "tried" buckets. +// * Each address range selects at random 4 of these buckets. +// * The actual bucket is chosen from one of these, based on the full address. +// * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently +// tried ones) is evicted from it, back to the "new" buckets. +// * Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not +// be observable by adversaries. +// * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN will introduce frequent (and expensive) +// consistency checks for the entire data structure. + +// total number of buckets for tried addresses +#define ADDRMAN_TRIED_BUCKET_COUNT 64 + +// maximum allowed number of entries in buckets for tried addresses +#define ADDRMAN_TRIED_BUCKET_SIZE 64 + +// total number of buckets for new addresses +#define ADDRMAN_NEW_BUCKET_COUNT 256 + +// maximum allowed number of entries in buckets for new addresses +#define ADDRMAN_NEW_BUCKET_SIZE 64 + +// over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread +#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 4 + +// over how many buckets entries with new addresses originating from a single group are spread +#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 32 + +// in how many buckets for entries with new addresses a single address may occur +#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4 + +// how many entries in a bucket with tried addresses are inspected, when selecting one to replace +#define ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT 4 + +// how old addresses can maximally be +#define ADDRMAN_HORIZON_DAYS 30 + +// after how many failed attempts we give up on a new node +#define ADDRMAN_RETRIES 3 + +// how many successive failures are allowed ... +#define ADDRMAN_MAX_FAILURES 10 + +// ... in at least this many days +#define ADDRMAN_MIN_FAIL_DAYS 7 + +// the maximum percentage of nodes to return in a getaddr call +#define ADDRMAN_GETADDR_MAX_PCT 23 + +// the maximum number of nodes to return in a getaddr call +#define ADDRMAN_GETADDR_MAX 2500 + +/** Stochastical (IP) address manager */ +class CAddrMan +{ +private: + // critical section to protect the inner data structures + mutable CCriticalSection cs; + + // secret key to randomize bucket select with + std::vector nKey; + + // last used nId + int nIdCount; + + // table with information about all nIds + std::map mapInfo; + + // find an nId based on its network address + std::map mapAddr; + + // randomly-ordered vector of all nIds + std::vector vRandom; + + // number of "tried" entries + int nTried; + + // list of "tried" buckets + std::vector > vvTried; + + // number of (unique) "new" entries + int nNew; + + // list of "new" buckets + std::vector > vvNew; + +protected: + + // Find an entry. + CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL); + + // find an entry, creating it if necessary. + // nTime and nServices of found node is updated, if necessary. + CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = NULL); + + // Swap two elements in vRandom. + void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2); + + // Return position in given bucket to replace. + int SelectTried(int nKBucket); + + // Remove an element from a "new" bucket. + // This is the only place where actual deletes occur. + // They are never deleted while in the "tried" table, only possibly evicted back to the "new" table. + int ShrinkNew(int nUBucket); + + // Move an entry from the "new" table(s) to the "tried" table + // @pre vvUnkown[nOrigin].count(nId) != 0 + void MakeTried(CAddrInfo& info, int nId, int nOrigin); + + // Mark an entry "good", possibly moving it from "new" to "tried". + void Good_(const CService &addr, int64_t nTime); + + // Add an entry to the "new" table. + bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty); + + // Mark an entry as attempted to connect. + void Attempt_(const CService &addr, int64_t nTime); + + // Select an address to connect to. + // nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100) + CAddress Select_(int nUnkBias); + +#ifdef DEBUG_ADDRMAN + // Perform consistency check. Returns an error code or zero. + int Check_(); +#endif + + // Select several addresses at once. + void GetAddr_(std::vector &vAddr); + + // Mark an entry as currently-connected-to. + void Connected_(const CService &addr, int64_t nTime); + +public: + // serialized format: + // * version byte (currently 0) + // * nKey + // * nNew + // * nTried + // * number of "new" buckets + // * all nNew addrinfos in vvNew + // * all nTried addrinfos in vvTried + // * for each bucket: + // * number of elements + // * for each element: index + // + // Notice that vvTried, mapAddr and vVector are never encoded explicitly; + // they are instead reconstructed from the other information. + // + // vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change, + // otherwise it is reconstructed as well. + // + // This format is more complex, but significantly smaller (at most 1.5 MiB), and supports + // changes to the ADDRMAN_ parameters without breaking the on-disk structure. + // + // We don't use IMPLEMENT_SERIALIZE since the serialization and deserialization code has + // very little in common. + template + void Serialize(Stream &s, int nType, int nVersionDummy) const + { + LOCK(cs); + + unsigned char nVersion = 0; + s << nVersion; + s << nKey; + s << nNew; + s << nTried; + + int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT; + s << nUBuckets; + std::map mapUnkIds; + int nIds = 0; + for (std::map::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) { + if (nIds == nNew) break; // this means nNew was wrong, oh ow + mapUnkIds[(*it).first] = nIds; + const CAddrInfo &info = (*it).second; + if (info.nRefCount) { + s << info; + nIds++; + } + } + nIds = 0; + for (std::map::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) { + if (nIds == nTried) break; // this means nTried was wrong, oh ow + const CAddrInfo &info = (*it).second; + if (info.fInTried) { + s << info; + nIds++; + } + } + for (std::vector >::const_iterator it = vvNew.begin(); it != vvNew.end(); it++) { + const std::set &vNew = (*it); + int nSize = vNew.size(); + s << nSize; + for (std::set::const_iterator it2 = vNew.begin(); it2 != vNew.end(); it2++) { + int nIndex = mapUnkIds[*it2]; + s << nIndex; + } + } + } + + template + void Unserialize(Stream& s, int nType, int nVersionDummy) + { + LOCK(cs); + + unsigned char nVersion; + s >> nVersion; + s >> nKey; + s >> nNew; + s >> nTried; + + int nUBuckets = 0; + s >> nUBuckets; + nIdCount = 0; + mapInfo.clear(); + mapAddr.clear(); + vRandom.clear(); + vvTried = std::vector >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)); + vvNew = std::vector >(ADDRMAN_NEW_BUCKET_COUNT, std::set()); + for (int n = 0; n < nNew; n++) { + CAddrInfo &info = mapInfo[n]; + s >> info; + mapAddr[info] = n; + info.nRandomPos = vRandom.size(); + vRandom.push_back(n); + if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) { + vvNew[info.GetNewBucket(nKey)].insert(n); + info.nRefCount++; + } + } + nIdCount = nNew; + int nLost = 0; + for (int n = 0; n < nTried; n++) { + CAddrInfo info; + s >> info; + std::vector &vTried = vvTried[info.GetTriedBucket(nKey)]; + if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) { + info.nRandomPos = vRandom.size(); + info.fInTried = true; + vRandom.push_back(nIdCount); + mapInfo[nIdCount] = info; + mapAddr[info] = nIdCount; + vTried.push_back(nIdCount); + nIdCount++; + } else { + nLost++; + } + } + nTried -= nLost; + for (int b = 0; b < nUBuckets; b++) { + std::set &vNew = vvNew[b]; + int nSize = 0; + s >> nSize; + for (int n = 0; n < nSize; n++) { + int nIndex = 0; + s >> nIndex; + CAddrInfo &info = mapInfo[nIndex]; + if (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) { + info.nRefCount++; + vNew.insert(nIndex); + } + } + } + } + + unsigned int GetSerializeSize(int nType, int nVersion) const + { + return (CSizeComputer(nType, nVersion) << *this).size(); + } + + CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set()) + { + nKey.resize(32); + RAND_bytes(&nKey[0], 32); + + nIdCount = 0; + nTried = 0; + nNew = 0; + } + + // Return the number of (unique) addresses in all tables. + int size() + { + return vRandom.size(); + } + + // Consistency check + void Check() + { +#ifdef DEBUG_ADDRMAN + { + LOCK(cs); + int err; + if ((err=Check_())) + LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err); + } +#endif + } + + // Add a single address. + bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0) + { + bool fRet = false; + { + LOCK(cs); + Check(); + fRet |= Add_(addr, source, nTimePenalty); + Check(); + } + if (fRet) + LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew); + return fRet; + } + + // Add multiple addresses. + bool Add(const std::vector &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0) + { + int nAdd = 0; + { + LOCK(cs); + Check(); + for (std::vector::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) + nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0; + Check(); + } + if (nAdd) + LogPrint("addrman", "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew); + return nAdd > 0; + } + + // Mark an entry as accessible. + void Good(const CService &addr, int64_t nTime = GetAdjustedTime()) + { + { + LOCK(cs); + Check(); + Good_(addr, nTime); + Check(); + } + } + + // Mark an entry as connection attempted to. + void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime()) + { + { + LOCK(cs); + Check(); + Attempt_(addr, nTime); + Check(); + } + } + + // Choose an address to connect to. + // nUnkBias determines how much "new" entries are favored over "tried" ones (0-100). + CAddress Select(int nUnkBias = 50) + { + CAddress addrRet; + { + LOCK(cs); + Check(); + addrRet = Select_(nUnkBias); + Check(); + } + return addrRet; + } + + // Return a bunch of addresses, selected at random. + std::vector GetAddr() + { + Check(); + std::vector vAddr; + { + LOCK(cs); + GetAddr_(vAddr); + } + Check(); + return vAddr; + } + + // Mark an entry as currently-connected-to. + void Connected(const CService &addr, int64_t nTime = GetAdjustedTime()) + { + { + LOCK(cs); + Check(); + Connected_(addr, nTime); + Check(); + } + } +}; + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/aes_helper.c b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/aes_helper.c new file mode 100644 index 0000000..75b7cc6 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/aes_helper.c @@ -0,0 +1,392 @@ +/* $Id: aes_helper.c 220 2010-06-09 09:21:50Z tp $ */ +/* + * AES tables. This file is not meant to be compiled by itself; it + * is included by some hash function implementations. It contains + * the precomputed tables and helper macros for evaluating an AES + * round, optionally with a final XOR with a subkey. + * + * By default, this file defines the tables and macros for little-endian + * processing (i.e. it is assumed that the input bytes have been read + * from memory and assembled with the little-endian convention). If + * the 'AES_BIG_ENDIAN' macro is defined (to a non-zero integer value) + * when this file is included, then the tables and macros for big-endian + * processing are defined instead. The big-endian tables and macros have + * names distinct from the little-endian tables and macros, hence it is + * possible to have both simultaneously, by including this file twice + * (with and without the AES_BIG_ENDIAN macro). + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include "sph_types.h" +#ifdef __cplusplus +extern "C"{ +#endif +#if AES_BIG_ENDIAN + +#define AESx(x) ( ((SPH_C32(x) >> 24) & SPH_C32(0x000000FF)) \ + | ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) \ + | ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) \ + | ((SPH_C32(x) << 24) & SPH_C32(0xFF000000))) + +#define AES0 AES0_BE +#define AES1 AES1_BE +#define AES2 AES2_BE +#define AES3 AES3_BE + +#define AES_ROUND_BE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3) do { \ + (Y0) = AES0[((X0) >> 24) & 0xFF] \ + ^ AES1[((X1) >> 16) & 0xFF] \ + ^ AES2[((X2) >> 8) & 0xFF] \ + ^ AES3[(X3) & 0xFF] ^ (K0); \ + (Y1) = AES0[((X1) >> 24) & 0xFF] \ + ^ AES1[((X2) >> 16) & 0xFF] \ + ^ AES2[((X3) >> 8) & 0xFF] \ + ^ AES3[(X0) & 0xFF] ^ (K1); \ + (Y2) = AES0[((X2) >> 24) & 0xFF] \ + ^ AES1[((X3) >> 16) & 0xFF] \ + ^ AES2[((X0) >> 8) & 0xFF] \ + ^ AES3[(X1) & 0xFF] ^ (K2); \ + (Y3) = AES0[((X3) >> 24) & 0xFF] \ + ^ AES1[((X0) >> 16) & 0xFF] \ + ^ AES2[((X1) >> 8) & 0xFF] \ + ^ AES3[(X2) & 0xFF] ^ (K3); \ + } while (0) + +#define AES_ROUND_NOKEY_BE(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \ + AES_ROUND_BE(X0, X1, X2, X3, 0, 0, 0, 0, Y0, Y1, Y2, Y3) + +#else + +#define AESx(x) SPH_C32(x) +#define AES0 AES0_LE +#define AES1 AES1_LE +#define AES2 AES2_LE +#define AES3 AES3_LE + +#define AES_ROUND_LE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3) do { \ + (Y0) = AES0[(X0) & 0xFF] \ + ^ AES1[((X1) >> 8) & 0xFF] \ + ^ AES2[((X2) >> 16) & 0xFF] \ + ^ AES3[((X3) >> 24) & 0xFF] ^ (K0); \ + (Y1) = AES0[(X1) & 0xFF] \ + ^ AES1[((X2) >> 8) & 0xFF] \ + ^ AES2[((X3) >> 16) & 0xFF] \ + ^ AES3[((X0) >> 24) & 0xFF] ^ (K1); \ + (Y2) = AES0[(X2) & 0xFF] \ + ^ AES1[((X3) >> 8) & 0xFF] \ + ^ AES2[((X0) >> 16) & 0xFF] \ + ^ AES3[((X1) >> 24) & 0xFF] ^ (K2); \ + (Y3) = AES0[(X3) & 0xFF] \ + ^ AES1[((X0) >> 8) & 0xFF] \ + ^ AES2[((X1) >> 16) & 0xFF] \ + ^ AES3[((X2) >> 24) & 0xFF] ^ (K3); \ + } while (0) + +#define AES_ROUND_NOKEY_LE(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \ + AES_ROUND_LE(X0, X1, X2, X3, 0, 0, 0, 0, Y0, Y1, Y2, Y3) + +#endif + +/* + * The AES*[] tables allow us to perform a fast evaluation of an AES + * round; table AESi[] combines SubBytes for a byte at row i, and + * MixColumns for the column where that byte goes after ShiftRows. + */ + +static const sph_u32 AES0[256] = { + AESx(0xA56363C6), AESx(0x847C7CF8), AESx(0x997777EE), AESx(0x8D7B7BF6), + AESx(0x0DF2F2FF), AESx(0xBD6B6BD6), AESx(0xB16F6FDE), AESx(0x54C5C591), + AESx(0x50303060), AESx(0x03010102), AESx(0xA96767CE), AESx(0x7D2B2B56), + AESx(0x19FEFEE7), AESx(0x62D7D7B5), AESx(0xE6ABAB4D), AESx(0x9A7676EC), + AESx(0x45CACA8F), AESx(0x9D82821F), AESx(0x40C9C989), AESx(0x877D7DFA), + AESx(0x15FAFAEF), AESx(0xEB5959B2), AESx(0xC947478E), AESx(0x0BF0F0FB), + AESx(0xECADAD41), AESx(0x67D4D4B3), AESx(0xFDA2A25F), AESx(0xEAAFAF45), + AESx(0xBF9C9C23), AESx(0xF7A4A453), AESx(0x967272E4), AESx(0x5BC0C09B), + AESx(0xC2B7B775), AESx(0x1CFDFDE1), AESx(0xAE93933D), AESx(0x6A26264C), + AESx(0x5A36366C), AESx(0x413F3F7E), AESx(0x02F7F7F5), AESx(0x4FCCCC83), + AESx(0x5C343468), AESx(0xF4A5A551), AESx(0x34E5E5D1), AESx(0x08F1F1F9), + AESx(0x937171E2), AESx(0x73D8D8AB), AESx(0x53313162), AESx(0x3F15152A), + AESx(0x0C040408), AESx(0x52C7C795), AESx(0x65232346), AESx(0x5EC3C39D), + AESx(0x28181830), AESx(0xA1969637), AESx(0x0F05050A), AESx(0xB59A9A2F), + AESx(0x0907070E), AESx(0x36121224), AESx(0x9B80801B), AESx(0x3DE2E2DF), + AESx(0x26EBEBCD), AESx(0x6927274E), AESx(0xCDB2B27F), AESx(0x9F7575EA), + AESx(0x1B090912), AESx(0x9E83831D), AESx(0x742C2C58), AESx(0x2E1A1A34), + AESx(0x2D1B1B36), AESx(0xB26E6EDC), AESx(0xEE5A5AB4), AESx(0xFBA0A05B), + AESx(0xF65252A4), AESx(0x4D3B3B76), AESx(0x61D6D6B7), AESx(0xCEB3B37D), + AESx(0x7B292952), AESx(0x3EE3E3DD), AESx(0x712F2F5E), AESx(0x97848413), + AESx(0xF55353A6), AESx(0x68D1D1B9), AESx(0x00000000), AESx(0x2CEDEDC1), + AESx(0x60202040), AESx(0x1FFCFCE3), AESx(0xC8B1B179), AESx(0xED5B5BB6), + AESx(0xBE6A6AD4), AESx(0x46CBCB8D), AESx(0xD9BEBE67), AESx(0x4B393972), + AESx(0xDE4A4A94), AESx(0xD44C4C98), AESx(0xE85858B0), AESx(0x4ACFCF85), + AESx(0x6BD0D0BB), AESx(0x2AEFEFC5), AESx(0xE5AAAA4F), AESx(0x16FBFBED), + AESx(0xC5434386), AESx(0xD74D4D9A), AESx(0x55333366), AESx(0x94858511), + AESx(0xCF45458A), AESx(0x10F9F9E9), AESx(0x06020204), AESx(0x817F7FFE), + AESx(0xF05050A0), AESx(0x443C3C78), AESx(0xBA9F9F25), AESx(0xE3A8A84B), + AESx(0xF35151A2), AESx(0xFEA3A35D), AESx(0xC0404080), AESx(0x8A8F8F05), + AESx(0xAD92923F), AESx(0xBC9D9D21), AESx(0x48383870), AESx(0x04F5F5F1), + AESx(0xDFBCBC63), AESx(0xC1B6B677), AESx(0x75DADAAF), AESx(0x63212142), + AESx(0x30101020), AESx(0x1AFFFFE5), AESx(0x0EF3F3FD), AESx(0x6DD2D2BF), + AESx(0x4CCDCD81), AESx(0x140C0C18), AESx(0x35131326), AESx(0x2FECECC3), + AESx(0xE15F5FBE), AESx(0xA2979735), AESx(0xCC444488), AESx(0x3917172E), + AESx(0x57C4C493), AESx(0xF2A7A755), AESx(0x827E7EFC), AESx(0x473D3D7A), + AESx(0xAC6464C8), AESx(0xE75D5DBA), AESx(0x2B191932), AESx(0x957373E6), + AESx(0xA06060C0), AESx(0x98818119), AESx(0xD14F4F9E), AESx(0x7FDCDCA3), + AESx(0x66222244), AESx(0x7E2A2A54), AESx(0xAB90903B), AESx(0x8388880B), + AESx(0xCA46468C), AESx(0x29EEEEC7), AESx(0xD3B8B86B), AESx(0x3C141428), + AESx(0x79DEDEA7), AESx(0xE25E5EBC), AESx(0x1D0B0B16), AESx(0x76DBDBAD), + AESx(0x3BE0E0DB), AESx(0x56323264), AESx(0x4E3A3A74), AESx(0x1E0A0A14), + AESx(0xDB494992), AESx(0x0A06060C), AESx(0x6C242448), AESx(0xE45C5CB8), + AESx(0x5DC2C29F), AESx(0x6ED3D3BD), AESx(0xEFACAC43), AESx(0xA66262C4), + AESx(0xA8919139), AESx(0xA4959531), AESx(0x37E4E4D3), AESx(0x8B7979F2), + AESx(0x32E7E7D5), AESx(0x43C8C88B), AESx(0x5937376E), AESx(0xB76D6DDA), + AESx(0x8C8D8D01), AESx(0x64D5D5B1), AESx(0xD24E4E9C), AESx(0xE0A9A949), + AESx(0xB46C6CD8), AESx(0xFA5656AC), AESx(0x07F4F4F3), AESx(0x25EAEACF), + AESx(0xAF6565CA), AESx(0x8E7A7AF4), AESx(0xE9AEAE47), AESx(0x18080810), + AESx(0xD5BABA6F), AESx(0x887878F0), AESx(0x6F25254A), AESx(0x722E2E5C), + AESx(0x241C1C38), AESx(0xF1A6A657), AESx(0xC7B4B473), AESx(0x51C6C697), + AESx(0x23E8E8CB), AESx(0x7CDDDDA1), AESx(0x9C7474E8), AESx(0x211F1F3E), + AESx(0xDD4B4B96), AESx(0xDCBDBD61), AESx(0x868B8B0D), AESx(0x858A8A0F), + AESx(0x907070E0), AESx(0x423E3E7C), AESx(0xC4B5B571), AESx(0xAA6666CC), + AESx(0xD8484890), AESx(0x05030306), AESx(0x01F6F6F7), AESx(0x120E0E1C), + AESx(0xA36161C2), AESx(0x5F35356A), AESx(0xF95757AE), AESx(0xD0B9B969), + AESx(0x91868617), AESx(0x58C1C199), AESx(0x271D1D3A), AESx(0xB99E9E27), + AESx(0x38E1E1D9), AESx(0x13F8F8EB), AESx(0xB398982B), AESx(0x33111122), + AESx(0xBB6969D2), AESx(0x70D9D9A9), AESx(0x898E8E07), AESx(0xA7949433), + AESx(0xB69B9B2D), AESx(0x221E1E3C), AESx(0x92878715), AESx(0x20E9E9C9), + AESx(0x49CECE87), AESx(0xFF5555AA), AESx(0x78282850), AESx(0x7ADFDFA5), + AESx(0x8F8C8C03), AESx(0xF8A1A159), AESx(0x80898909), AESx(0x170D0D1A), + AESx(0xDABFBF65), AESx(0x31E6E6D7), AESx(0xC6424284), AESx(0xB86868D0), + AESx(0xC3414182), AESx(0xB0999929), AESx(0x772D2D5A), AESx(0x110F0F1E), + AESx(0xCBB0B07B), AESx(0xFC5454A8), AESx(0xD6BBBB6D), AESx(0x3A16162C) +}; + +static const sph_u32 AES1[256] = { + AESx(0x6363C6A5), AESx(0x7C7CF884), AESx(0x7777EE99), AESx(0x7B7BF68D), + AESx(0xF2F2FF0D), AESx(0x6B6BD6BD), AESx(0x6F6FDEB1), AESx(0xC5C59154), + AESx(0x30306050), AESx(0x01010203), AESx(0x6767CEA9), AESx(0x2B2B567D), + AESx(0xFEFEE719), AESx(0xD7D7B562), AESx(0xABAB4DE6), AESx(0x7676EC9A), + AESx(0xCACA8F45), AESx(0x82821F9D), AESx(0xC9C98940), AESx(0x7D7DFA87), + AESx(0xFAFAEF15), AESx(0x5959B2EB), AESx(0x47478EC9), AESx(0xF0F0FB0B), + AESx(0xADAD41EC), AESx(0xD4D4B367), AESx(0xA2A25FFD), AESx(0xAFAF45EA), + AESx(0x9C9C23BF), AESx(0xA4A453F7), AESx(0x7272E496), AESx(0xC0C09B5B), + AESx(0xB7B775C2), AESx(0xFDFDE11C), AESx(0x93933DAE), AESx(0x26264C6A), + AESx(0x36366C5A), AESx(0x3F3F7E41), AESx(0xF7F7F502), AESx(0xCCCC834F), + AESx(0x3434685C), AESx(0xA5A551F4), AESx(0xE5E5D134), AESx(0xF1F1F908), + AESx(0x7171E293), AESx(0xD8D8AB73), AESx(0x31316253), AESx(0x15152A3F), + AESx(0x0404080C), AESx(0xC7C79552), AESx(0x23234665), AESx(0xC3C39D5E), + AESx(0x18183028), AESx(0x969637A1), AESx(0x05050A0F), AESx(0x9A9A2FB5), + AESx(0x07070E09), AESx(0x12122436), AESx(0x80801B9B), AESx(0xE2E2DF3D), + AESx(0xEBEBCD26), AESx(0x27274E69), AESx(0xB2B27FCD), AESx(0x7575EA9F), + AESx(0x0909121B), AESx(0x83831D9E), AESx(0x2C2C5874), AESx(0x1A1A342E), + AESx(0x1B1B362D), AESx(0x6E6EDCB2), AESx(0x5A5AB4EE), AESx(0xA0A05BFB), + AESx(0x5252A4F6), AESx(0x3B3B764D), AESx(0xD6D6B761), AESx(0xB3B37DCE), + AESx(0x2929527B), AESx(0xE3E3DD3E), AESx(0x2F2F5E71), AESx(0x84841397), + AESx(0x5353A6F5), AESx(0xD1D1B968), AESx(0x00000000), AESx(0xEDEDC12C), + AESx(0x20204060), AESx(0xFCFCE31F), AESx(0xB1B179C8), AESx(0x5B5BB6ED), + AESx(0x6A6AD4BE), AESx(0xCBCB8D46), AESx(0xBEBE67D9), AESx(0x3939724B), + AESx(0x4A4A94DE), AESx(0x4C4C98D4), AESx(0x5858B0E8), AESx(0xCFCF854A), + AESx(0xD0D0BB6B), AESx(0xEFEFC52A), AESx(0xAAAA4FE5), AESx(0xFBFBED16), + AESx(0x434386C5), AESx(0x4D4D9AD7), AESx(0x33336655), AESx(0x85851194), + AESx(0x45458ACF), AESx(0xF9F9E910), AESx(0x02020406), AESx(0x7F7FFE81), + AESx(0x5050A0F0), AESx(0x3C3C7844), AESx(0x9F9F25BA), AESx(0xA8A84BE3), + AESx(0x5151A2F3), AESx(0xA3A35DFE), AESx(0x404080C0), AESx(0x8F8F058A), + AESx(0x92923FAD), AESx(0x9D9D21BC), AESx(0x38387048), AESx(0xF5F5F104), + AESx(0xBCBC63DF), AESx(0xB6B677C1), AESx(0xDADAAF75), AESx(0x21214263), + AESx(0x10102030), AESx(0xFFFFE51A), AESx(0xF3F3FD0E), AESx(0xD2D2BF6D), + AESx(0xCDCD814C), AESx(0x0C0C1814), AESx(0x13132635), AESx(0xECECC32F), + AESx(0x5F5FBEE1), AESx(0x979735A2), AESx(0x444488CC), AESx(0x17172E39), + AESx(0xC4C49357), AESx(0xA7A755F2), AESx(0x7E7EFC82), AESx(0x3D3D7A47), + AESx(0x6464C8AC), AESx(0x5D5DBAE7), AESx(0x1919322B), AESx(0x7373E695), + AESx(0x6060C0A0), AESx(0x81811998), AESx(0x4F4F9ED1), AESx(0xDCDCA37F), + AESx(0x22224466), AESx(0x2A2A547E), AESx(0x90903BAB), AESx(0x88880B83), + AESx(0x46468CCA), AESx(0xEEEEC729), AESx(0xB8B86BD3), AESx(0x1414283C), + AESx(0xDEDEA779), AESx(0x5E5EBCE2), AESx(0x0B0B161D), AESx(0xDBDBAD76), + AESx(0xE0E0DB3B), AESx(0x32326456), AESx(0x3A3A744E), AESx(0x0A0A141E), + AESx(0x494992DB), AESx(0x06060C0A), AESx(0x2424486C), AESx(0x5C5CB8E4), + AESx(0xC2C29F5D), AESx(0xD3D3BD6E), AESx(0xACAC43EF), AESx(0x6262C4A6), + AESx(0x919139A8), AESx(0x959531A4), AESx(0xE4E4D337), AESx(0x7979F28B), + AESx(0xE7E7D532), AESx(0xC8C88B43), AESx(0x37376E59), AESx(0x6D6DDAB7), + AESx(0x8D8D018C), AESx(0xD5D5B164), AESx(0x4E4E9CD2), AESx(0xA9A949E0), + AESx(0x6C6CD8B4), AESx(0x5656ACFA), AESx(0xF4F4F307), AESx(0xEAEACF25), + AESx(0x6565CAAF), AESx(0x7A7AF48E), AESx(0xAEAE47E9), AESx(0x08081018), + AESx(0xBABA6FD5), AESx(0x7878F088), AESx(0x25254A6F), AESx(0x2E2E5C72), + AESx(0x1C1C3824), AESx(0xA6A657F1), AESx(0xB4B473C7), AESx(0xC6C69751), + AESx(0xE8E8CB23), AESx(0xDDDDA17C), AESx(0x7474E89C), AESx(0x1F1F3E21), + AESx(0x4B4B96DD), AESx(0xBDBD61DC), AESx(0x8B8B0D86), AESx(0x8A8A0F85), + AESx(0x7070E090), AESx(0x3E3E7C42), AESx(0xB5B571C4), AESx(0x6666CCAA), + AESx(0x484890D8), AESx(0x03030605), AESx(0xF6F6F701), AESx(0x0E0E1C12), + AESx(0x6161C2A3), AESx(0x35356A5F), AESx(0x5757AEF9), AESx(0xB9B969D0), + AESx(0x86861791), AESx(0xC1C19958), AESx(0x1D1D3A27), AESx(0x9E9E27B9), + AESx(0xE1E1D938), AESx(0xF8F8EB13), AESx(0x98982BB3), AESx(0x11112233), + AESx(0x6969D2BB), AESx(0xD9D9A970), AESx(0x8E8E0789), AESx(0x949433A7), + AESx(0x9B9B2DB6), AESx(0x1E1E3C22), AESx(0x87871592), AESx(0xE9E9C920), + AESx(0xCECE8749), AESx(0x5555AAFF), AESx(0x28285078), AESx(0xDFDFA57A), + AESx(0x8C8C038F), AESx(0xA1A159F8), AESx(0x89890980), AESx(0x0D0D1A17), + AESx(0xBFBF65DA), AESx(0xE6E6D731), AESx(0x424284C6), AESx(0x6868D0B8), + AESx(0x414182C3), AESx(0x999929B0), AESx(0x2D2D5A77), AESx(0x0F0F1E11), + AESx(0xB0B07BCB), AESx(0x5454A8FC), AESx(0xBBBB6DD6), AESx(0x16162C3A) +}; + +static const sph_u32 AES2[256] = { + AESx(0x63C6A563), AESx(0x7CF8847C), AESx(0x77EE9977), AESx(0x7BF68D7B), + AESx(0xF2FF0DF2), AESx(0x6BD6BD6B), AESx(0x6FDEB16F), AESx(0xC59154C5), + AESx(0x30605030), AESx(0x01020301), AESx(0x67CEA967), AESx(0x2B567D2B), + AESx(0xFEE719FE), AESx(0xD7B562D7), AESx(0xAB4DE6AB), AESx(0x76EC9A76), + AESx(0xCA8F45CA), AESx(0x821F9D82), AESx(0xC98940C9), AESx(0x7DFA877D), + AESx(0xFAEF15FA), AESx(0x59B2EB59), AESx(0x478EC947), AESx(0xF0FB0BF0), + AESx(0xAD41ECAD), AESx(0xD4B367D4), AESx(0xA25FFDA2), AESx(0xAF45EAAF), + AESx(0x9C23BF9C), AESx(0xA453F7A4), AESx(0x72E49672), AESx(0xC09B5BC0), + AESx(0xB775C2B7), AESx(0xFDE11CFD), AESx(0x933DAE93), AESx(0x264C6A26), + AESx(0x366C5A36), AESx(0x3F7E413F), AESx(0xF7F502F7), AESx(0xCC834FCC), + AESx(0x34685C34), AESx(0xA551F4A5), AESx(0xE5D134E5), AESx(0xF1F908F1), + AESx(0x71E29371), AESx(0xD8AB73D8), AESx(0x31625331), AESx(0x152A3F15), + AESx(0x04080C04), AESx(0xC79552C7), AESx(0x23466523), AESx(0xC39D5EC3), + AESx(0x18302818), AESx(0x9637A196), AESx(0x050A0F05), AESx(0x9A2FB59A), + AESx(0x070E0907), AESx(0x12243612), AESx(0x801B9B80), AESx(0xE2DF3DE2), + AESx(0xEBCD26EB), AESx(0x274E6927), AESx(0xB27FCDB2), AESx(0x75EA9F75), + AESx(0x09121B09), AESx(0x831D9E83), AESx(0x2C58742C), AESx(0x1A342E1A), + AESx(0x1B362D1B), AESx(0x6EDCB26E), AESx(0x5AB4EE5A), AESx(0xA05BFBA0), + AESx(0x52A4F652), AESx(0x3B764D3B), AESx(0xD6B761D6), AESx(0xB37DCEB3), + AESx(0x29527B29), AESx(0xE3DD3EE3), AESx(0x2F5E712F), AESx(0x84139784), + AESx(0x53A6F553), AESx(0xD1B968D1), AESx(0x00000000), AESx(0xEDC12CED), + AESx(0x20406020), AESx(0xFCE31FFC), AESx(0xB179C8B1), AESx(0x5BB6ED5B), + AESx(0x6AD4BE6A), AESx(0xCB8D46CB), AESx(0xBE67D9BE), AESx(0x39724B39), + AESx(0x4A94DE4A), AESx(0x4C98D44C), AESx(0x58B0E858), AESx(0xCF854ACF), + AESx(0xD0BB6BD0), AESx(0xEFC52AEF), AESx(0xAA4FE5AA), AESx(0xFBED16FB), + AESx(0x4386C543), AESx(0x4D9AD74D), AESx(0x33665533), AESx(0x85119485), + AESx(0x458ACF45), AESx(0xF9E910F9), AESx(0x02040602), AESx(0x7FFE817F), + AESx(0x50A0F050), AESx(0x3C78443C), AESx(0x9F25BA9F), AESx(0xA84BE3A8), + AESx(0x51A2F351), AESx(0xA35DFEA3), AESx(0x4080C040), AESx(0x8F058A8F), + AESx(0x923FAD92), AESx(0x9D21BC9D), AESx(0x38704838), AESx(0xF5F104F5), + AESx(0xBC63DFBC), AESx(0xB677C1B6), AESx(0xDAAF75DA), AESx(0x21426321), + AESx(0x10203010), AESx(0xFFE51AFF), AESx(0xF3FD0EF3), AESx(0xD2BF6DD2), + AESx(0xCD814CCD), AESx(0x0C18140C), AESx(0x13263513), AESx(0xECC32FEC), + AESx(0x5FBEE15F), AESx(0x9735A297), AESx(0x4488CC44), AESx(0x172E3917), + AESx(0xC49357C4), AESx(0xA755F2A7), AESx(0x7EFC827E), AESx(0x3D7A473D), + AESx(0x64C8AC64), AESx(0x5DBAE75D), AESx(0x19322B19), AESx(0x73E69573), + AESx(0x60C0A060), AESx(0x81199881), AESx(0x4F9ED14F), AESx(0xDCA37FDC), + AESx(0x22446622), AESx(0x2A547E2A), AESx(0x903BAB90), AESx(0x880B8388), + AESx(0x468CCA46), AESx(0xEEC729EE), AESx(0xB86BD3B8), AESx(0x14283C14), + AESx(0xDEA779DE), AESx(0x5EBCE25E), AESx(0x0B161D0B), AESx(0xDBAD76DB), + AESx(0xE0DB3BE0), AESx(0x32645632), AESx(0x3A744E3A), AESx(0x0A141E0A), + AESx(0x4992DB49), AESx(0x060C0A06), AESx(0x24486C24), AESx(0x5CB8E45C), + AESx(0xC29F5DC2), AESx(0xD3BD6ED3), AESx(0xAC43EFAC), AESx(0x62C4A662), + AESx(0x9139A891), AESx(0x9531A495), AESx(0xE4D337E4), AESx(0x79F28B79), + AESx(0xE7D532E7), AESx(0xC88B43C8), AESx(0x376E5937), AESx(0x6DDAB76D), + AESx(0x8D018C8D), AESx(0xD5B164D5), AESx(0x4E9CD24E), AESx(0xA949E0A9), + AESx(0x6CD8B46C), AESx(0x56ACFA56), AESx(0xF4F307F4), AESx(0xEACF25EA), + AESx(0x65CAAF65), AESx(0x7AF48E7A), AESx(0xAE47E9AE), AESx(0x08101808), + AESx(0xBA6FD5BA), AESx(0x78F08878), AESx(0x254A6F25), AESx(0x2E5C722E), + AESx(0x1C38241C), AESx(0xA657F1A6), AESx(0xB473C7B4), AESx(0xC69751C6), + AESx(0xE8CB23E8), AESx(0xDDA17CDD), AESx(0x74E89C74), AESx(0x1F3E211F), + AESx(0x4B96DD4B), AESx(0xBD61DCBD), AESx(0x8B0D868B), AESx(0x8A0F858A), + AESx(0x70E09070), AESx(0x3E7C423E), AESx(0xB571C4B5), AESx(0x66CCAA66), + AESx(0x4890D848), AESx(0x03060503), AESx(0xF6F701F6), AESx(0x0E1C120E), + AESx(0x61C2A361), AESx(0x356A5F35), AESx(0x57AEF957), AESx(0xB969D0B9), + AESx(0x86179186), AESx(0xC19958C1), AESx(0x1D3A271D), AESx(0x9E27B99E), + AESx(0xE1D938E1), AESx(0xF8EB13F8), AESx(0x982BB398), AESx(0x11223311), + AESx(0x69D2BB69), AESx(0xD9A970D9), AESx(0x8E07898E), AESx(0x9433A794), + AESx(0x9B2DB69B), AESx(0x1E3C221E), AESx(0x87159287), AESx(0xE9C920E9), + AESx(0xCE8749CE), AESx(0x55AAFF55), AESx(0x28507828), AESx(0xDFA57ADF), + AESx(0x8C038F8C), AESx(0xA159F8A1), AESx(0x89098089), AESx(0x0D1A170D), + AESx(0xBF65DABF), AESx(0xE6D731E6), AESx(0x4284C642), AESx(0x68D0B868), + AESx(0x4182C341), AESx(0x9929B099), AESx(0x2D5A772D), AESx(0x0F1E110F), + AESx(0xB07BCBB0), AESx(0x54A8FC54), AESx(0xBB6DD6BB), AESx(0x162C3A16) +}; + +static const sph_u32 AES3[256] = { + AESx(0xC6A56363), AESx(0xF8847C7C), AESx(0xEE997777), AESx(0xF68D7B7B), + AESx(0xFF0DF2F2), AESx(0xD6BD6B6B), AESx(0xDEB16F6F), AESx(0x9154C5C5), + AESx(0x60503030), AESx(0x02030101), AESx(0xCEA96767), AESx(0x567D2B2B), + AESx(0xE719FEFE), AESx(0xB562D7D7), AESx(0x4DE6ABAB), AESx(0xEC9A7676), + AESx(0x8F45CACA), AESx(0x1F9D8282), AESx(0x8940C9C9), AESx(0xFA877D7D), + AESx(0xEF15FAFA), AESx(0xB2EB5959), AESx(0x8EC94747), AESx(0xFB0BF0F0), + AESx(0x41ECADAD), AESx(0xB367D4D4), AESx(0x5FFDA2A2), AESx(0x45EAAFAF), + AESx(0x23BF9C9C), AESx(0x53F7A4A4), AESx(0xE4967272), AESx(0x9B5BC0C0), + AESx(0x75C2B7B7), AESx(0xE11CFDFD), AESx(0x3DAE9393), AESx(0x4C6A2626), + AESx(0x6C5A3636), AESx(0x7E413F3F), AESx(0xF502F7F7), AESx(0x834FCCCC), + AESx(0x685C3434), AESx(0x51F4A5A5), AESx(0xD134E5E5), AESx(0xF908F1F1), + AESx(0xE2937171), AESx(0xAB73D8D8), AESx(0x62533131), AESx(0x2A3F1515), + AESx(0x080C0404), AESx(0x9552C7C7), AESx(0x46652323), AESx(0x9D5EC3C3), + AESx(0x30281818), AESx(0x37A19696), AESx(0x0A0F0505), AESx(0x2FB59A9A), + AESx(0x0E090707), AESx(0x24361212), AESx(0x1B9B8080), AESx(0xDF3DE2E2), + AESx(0xCD26EBEB), AESx(0x4E692727), AESx(0x7FCDB2B2), AESx(0xEA9F7575), + AESx(0x121B0909), AESx(0x1D9E8383), AESx(0x58742C2C), AESx(0x342E1A1A), + AESx(0x362D1B1B), AESx(0xDCB26E6E), AESx(0xB4EE5A5A), AESx(0x5BFBA0A0), + AESx(0xA4F65252), AESx(0x764D3B3B), AESx(0xB761D6D6), AESx(0x7DCEB3B3), + AESx(0x527B2929), AESx(0xDD3EE3E3), AESx(0x5E712F2F), AESx(0x13978484), + AESx(0xA6F55353), AESx(0xB968D1D1), AESx(0x00000000), AESx(0xC12CEDED), + AESx(0x40602020), AESx(0xE31FFCFC), AESx(0x79C8B1B1), AESx(0xB6ED5B5B), + AESx(0xD4BE6A6A), AESx(0x8D46CBCB), AESx(0x67D9BEBE), AESx(0x724B3939), + AESx(0x94DE4A4A), AESx(0x98D44C4C), AESx(0xB0E85858), AESx(0x854ACFCF), + AESx(0xBB6BD0D0), AESx(0xC52AEFEF), AESx(0x4FE5AAAA), AESx(0xED16FBFB), + AESx(0x86C54343), AESx(0x9AD74D4D), AESx(0x66553333), AESx(0x11948585), + AESx(0x8ACF4545), AESx(0xE910F9F9), AESx(0x04060202), AESx(0xFE817F7F), + AESx(0xA0F05050), AESx(0x78443C3C), AESx(0x25BA9F9F), AESx(0x4BE3A8A8), + AESx(0xA2F35151), AESx(0x5DFEA3A3), AESx(0x80C04040), AESx(0x058A8F8F), + AESx(0x3FAD9292), AESx(0x21BC9D9D), AESx(0x70483838), AESx(0xF104F5F5), + AESx(0x63DFBCBC), AESx(0x77C1B6B6), AESx(0xAF75DADA), AESx(0x42632121), + AESx(0x20301010), AESx(0xE51AFFFF), AESx(0xFD0EF3F3), AESx(0xBF6DD2D2), + AESx(0x814CCDCD), AESx(0x18140C0C), AESx(0x26351313), AESx(0xC32FECEC), + AESx(0xBEE15F5F), AESx(0x35A29797), AESx(0x88CC4444), AESx(0x2E391717), + AESx(0x9357C4C4), AESx(0x55F2A7A7), AESx(0xFC827E7E), AESx(0x7A473D3D), + AESx(0xC8AC6464), AESx(0xBAE75D5D), AESx(0x322B1919), AESx(0xE6957373), + AESx(0xC0A06060), AESx(0x19988181), AESx(0x9ED14F4F), AESx(0xA37FDCDC), + AESx(0x44662222), AESx(0x547E2A2A), AESx(0x3BAB9090), AESx(0x0B838888), + AESx(0x8CCA4646), AESx(0xC729EEEE), AESx(0x6BD3B8B8), AESx(0x283C1414), + AESx(0xA779DEDE), AESx(0xBCE25E5E), AESx(0x161D0B0B), AESx(0xAD76DBDB), + AESx(0xDB3BE0E0), AESx(0x64563232), AESx(0x744E3A3A), AESx(0x141E0A0A), + AESx(0x92DB4949), AESx(0x0C0A0606), AESx(0x486C2424), AESx(0xB8E45C5C), + AESx(0x9F5DC2C2), AESx(0xBD6ED3D3), AESx(0x43EFACAC), AESx(0xC4A66262), + AESx(0x39A89191), AESx(0x31A49595), AESx(0xD337E4E4), AESx(0xF28B7979), + AESx(0xD532E7E7), AESx(0x8B43C8C8), AESx(0x6E593737), AESx(0xDAB76D6D), + AESx(0x018C8D8D), AESx(0xB164D5D5), AESx(0x9CD24E4E), AESx(0x49E0A9A9), + AESx(0xD8B46C6C), AESx(0xACFA5656), AESx(0xF307F4F4), AESx(0xCF25EAEA), + AESx(0xCAAF6565), AESx(0xF48E7A7A), AESx(0x47E9AEAE), AESx(0x10180808), + AESx(0x6FD5BABA), AESx(0xF0887878), AESx(0x4A6F2525), AESx(0x5C722E2E), + AESx(0x38241C1C), AESx(0x57F1A6A6), AESx(0x73C7B4B4), AESx(0x9751C6C6), + AESx(0xCB23E8E8), AESx(0xA17CDDDD), AESx(0xE89C7474), AESx(0x3E211F1F), + AESx(0x96DD4B4B), AESx(0x61DCBDBD), AESx(0x0D868B8B), AESx(0x0F858A8A), + AESx(0xE0907070), AESx(0x7C423E3E), AESx(0x71C4B5B5), AESx(0xCCAA6666), + AESx(0x90D84848), AESx(0x06050303), AESx(0xF701F6F6), AESx(0x1C120E0E), + AESx(0xC2A36161), AESx(0x6A5F3535), AESx(0xAEF95757), AESx(0x69D0B9B9), + AESx(0x17918686), AESx(0x9958C1C1), AESx(0x3A271D1D), AESx(0x27B99E9E), + AESx(0xD938E1E1), AESx(0xEB13F8F8), AESx(0x2BB39898), AESx(0x22331111), + AESx(0xD2BB6969), AESx(0xA970D9D9), AESx(0x07898E8E), AESx(0x33A79494), + AESx(0x2DB69B9B), AESx(0x3C221E1E), AESx(0x15928787), AESx(0xC920E9E9), + AESx(0x8749CECE), AESx(0xAAFF5555), AESx(0x50782828), AESx(0xA57ADFDF), + AESx(0x038F8C8C), AESx(0x59F8A1A1), AESx(0x09808989), AESx(0x1A170D0D), + AESx(0x65DABFBF), AESx(0xD731E6E6), AESx(0x84C64242), AESx(0xD0B86868), + AESx(0x82C34141), AESx(0x29B09999), AESx(0x5A772D2D), AESx(0x1E110F0F), + AESx(0x7BCBB0B0), AESx(0xA8FC5454), AESx(0x6DD6BBBB), AESx(0x2C3A1616) +}; + +#ifdef __cplusplus +} +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/alert.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/alert.cpp new file mode 100644 index 0000000..6241e48 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/alert.cpp @@ -0,0 +1,258 @@ +// +// Alert system +// + +#include "alert.h" + +#include "chainparams.h" +#include "key.h" +#include "net.h" +#include "timedata.h" +#include "ui_interface.h" +#include "util.h" + +#include +#include +#include + +#include +#include +#include + +using namespace std; + +map mapAlerts; +CCriticalSection cs_mapAlerts; + +void CUnsignedAlert::SetNull() +{ + nVersion = 1; + nRelayUntil = 0; + nExpiration = 0; + nID = 0; + nCancel = 0; + setCancel.clear(); + nMinVer = 0; + nMaxVer = 0; + setSubVer.clear(); + nPriority = 0; + + strComment.clear(); + strStatusBar.clear(); + strReserved.clear(); +} + +std::string CUnsignedAlert::ToString() const +{ + std::string strSetCancel; + BOOST_FOREACH(int n, setCancel) + strSetCancel += strprintf("%d ", n); + std::string strSetSubVer; + BOOST_FOREACH(std::string str, setSubVer) + strSetSubVer += "\"" + str + "\" "; + return strprintf( + "CAlert(\n" + " nVersion = %d\n" + " nRelayUntil = %d\n" + " nExpiration = %d\n" + " nID = %d\n" + " nCancel = %d\n" + " setCancel = %s\n" + " nMinVer = %d\n" + " nMaxVer = %d\n" + " setSubVer = %s\n" + " nPriority = %d\n" + " strComment = \"%s\"\n" + " strStatusBar = \"%s\"\n" + ")\n", + nVersion, + nRelayUntil, + nExpiration, + nID, + nCancel, + strSetCancel, + nMinVer, + nMaxVer, + strSetSubVer, + nPriority, + strComment, + strStatusBar); +} + +void CAlert::SetNull() +{ + CUnsignedAlert::SetNull(); + vchMsg.clear(); + vchSig.clear(); +} + +bool CAlert::IsNull() const +{ + return (nExpiration == 0); +} + +uint256 CAlert::GetHash() const +{ + return Hash(this->vchMsg.begin(), this->vchMsg.end()); +} + +bool CAlert::IsInEffect() const +{ + return (GetAdjustedTime() < nExpiration); +} + +bool CAlert::Cancels(const CAlert& alert) const +{ + if (!IsInEffect()) + return false; // this was a no-op before 31403 + return (alert.nID <= nCancel || setCancel.count(alert.nID)); +} + +bool CAlert::AppliesTo(int nVersion, std::string strSubVerIn) const +{ + // TODO: rework for client-version-embedded-in-strSubVer ? + return (IsInEffect() && + nMinVer <= nVersion && nVersion <= nMaxVer && + (setSubVer.empty() || setSubVer.count(strSubVerIn))); +} + +bool CAlert::AppliesToMe() const +{ + return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector())); +} + +bool CAlert::RelayTo(CNode* pnode) const +{ + if (!IsInEffect()) + return false; + // don't relay to nodes which haven't sent their version message + if (pnode->nVersion == 0) + return false; + // returns true if wasn't already contained in the set + if (pnode->setKnown.insert(GetHash()).second) + { + if (AppliesTo(pnode->nVersion, pnode->strSubVer) || + AppliesToMe() || + GetAdjustedTime() < nRelayUntil) + { + pnode->PushMessage("alert", *this); + return true; + } + } + return false; +} + +bool CAlert::CheckSignature() const +{ + CPubKey key(Params().AlertKey()); + if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) + return error("CAlert::CheckSignature() : verify signature failed"); + + // Now unserialize the data + CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); + sMsg >> *(CUnsignedAlert*)this; + return true; +} + +CAlert CAlert::getAlertByHash(const uint256 &hash) +{ + CAlert retval; + { + LOCK(cs_mapAlerts); + map::iterator mi = mapAlerts.find(hash); + if(mi != mapAlerts.end()) + retval = mi->second; + } + return retval; +} + +bool CAlert::ProcessAlert(bool fThread) +{ + if (!CheckSignature()) + return false; + if (!IsInEffect()) + return false; + + // alert.nID=max is reserved for if the alert key is + // compromised. It must have a pre-defined message, + // must never expire, must apply to all versions, + // and must cancel all previous + // alerts or it will be ignored (so an attacker can't + // send an "everything is OK, don't panic" version that + // cannot be overridden): + int maxInt = std::numeric_limits::max(); + if (nID == maxInt) + { + if (!( + nExpiration == maxInt && + nCancel == (maxInt-1) && + nMinVer == 0 && + nMaxVer == maxInt && + setSubVer.empty() && + nPriority == maxInt && + strStatusBar == "URGENT: Alert key compromised, upgrade required" + )) + return false; + } + + { + LOCK(cs_mapAlerts); + // Cancel previous alerts + for (map::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();) + { + const CAlert& alert = (*mi).second; + if (Cancels(alert)) + { + LogPrint("alert", "cancelling alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mapAlerts.erase(mi++); + } + else if (!alert.IsInEffect()) + { + LogPrint("alert", "expiring alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mapAlerts.erase(mi++); + } + else + mi++; + } + + // Check if this alert has been cancelled + BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + { + const CAlert& alert = item.second; + if (alert.Cancels(*this)) + { + LogPrint("alert", "alert already cancelled by %d\n", alert.nID); + return false; + } + } + + // Add to mapAlerts + mapAlerts.insert(make_pair(GetHash(), *this)); + // Notify UI and -alertnotify if it applies to me + if(AppliesToMe()) + { + uiInterface.NotifyAlertChanged(GetHash(), CT_NEW); + std::string strCmd = GetArg("-alertnotify", ""); + if (!strCmd.empty()) + { + // Alert text should be plain ascii coming from a trusted source, but to + // be safe we first strip anything not in safeChars, then add single quotes around + // the whole string before passing it to the shell: + std::string singleQuote("'"); + std::string safeStatus = SanitizeString(strStatusBar); + safeStatus = singleQuote+safeStatus+singleQuote; + boost::replace_all(strCmd, "%s", safeStatus); + + if (fThread) + boost::thread t(runCommand, strCmd); // thread runs free + else + runCommand(strCmd); + } + } + } + + LogPrint("alert", "accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe()); + return true; +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/scrypt.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/scrypt.h new file mode 100644 index 0000000..85626c0 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/scrypt.h @@ -0,0 +1,15 @@ +#ifndef SCRYPT_MINE_H +#define SCRYPT_MINE_H + +#include +#include + +#include "util.h" +#include "net.h" + +uint256 scrypt_salted_multiround_hash(const void* input, size_t inputlen, const void* salt, size_t saltlen, const unsigned int nRounds); +uint256 scrypt_salted_hash(const void* input, size_t inputlen, const void* salt, size_t saltlen); +uint256 scrypt_hash(const void* input, size_t inputlen); +uint256 scrypt_blockhash(const void* input); + +#endif // SCRYPT_MINE_H \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/serialize.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/serialize.h new file mode 100644 index 0000000..a11afd5 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/serialize.h @@ -0,0 +1,1311 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SERIALIZE_H +#define BITCOIN_SERIALIZE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "allocators.h" +#include "version.h" + +class CAutoFile; +class CDataStream; +class CScript; + +static const unsigned int MAX_SIZE = 0x02000000; + +// Used to bypass the rule against non-const reference to temporary +// where it makes sense with wrappers such as CFlatData or CTxDB +template +inline T& REF(const T& val) +{ + return const_cast(val); +} + +/** + * Used to acquire a non-const pointer "this" to generate bodies + * of const serialization operations from a template + */ +template +inline T* NCONST_PTR(const T* val) +{ + return const_cast(val); +} + +/** + * Get begin pointer of vector (non-const version). + * @note These functions avoid the undefined case of indexing into an empty + * vector, as well as that of indexing after the end of the vector. + */ +template +inline T* begin_ptr(std::vector& v) +{ + return v.empty() ? NULL : &v[0]; +} +/** Get begin pointer of vector (const version) */ +template +inline const T* begin_ptr(const std::vector& v) +{ + return v.empty() ? NULL : &v[0]; +} +/** Get end pointer of vector (non-const version) */ +template +inline T* end_ptr(std::vector& v) +{ + return v.empty() ? NULL : (&v[0] + v.size()); +} +/** Get end pointer of vector (const version) */ +template +inline const T* end_ptr(const std::vector& v) +{ + return v.empty() ? NULL : (&v[0] + v.size()); +} + + +///////////////////////////////////////////////////////////////// +// +// Templates for serializing to anything that looks like a stream, +// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t) +// + +enum +{ + // primary actions + SER_NETWORK = (1 << 0), + SER_DISK = (1 << 1), + SER_GETHASH = (1 << 2), + + // modifiers + SER_SKIPSIG = (1 << 16), + SER_BLOCKHEADERONLY = (1 << 17), +}; + +#define IMPLEMENT_SERIALIZE(statements) \ + unsigned int GetSerializeSize(int nType, int nVersion) const \ + { \ + CSerActionGetSerializeSize ser_action; \ + const bool fGetSize = true; \ + const bool fWrite = false; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + ser_streamplaceholder s; \ + assert(fGetSize||fWrite||fRead); /* suppress warning */ \ + s.nType = nType; \ + s.nVersion = nVersion; \ + {statements} \ + return nSerSize; \ + } \ + template \ + void Serialize(Stream& s, int nType, int nVersion) const \ + { \ + CSerActionSerialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = true; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + assert(fGetSize||fWrite||fRead); /* suppress warning */ \ + {statements} \ + } \ + template \ + void Unserialize(Stream& s, int nType, int nVersion) \ + { \ + CSerActionUnserialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = false; \ + const bool fRead = true; \ + unsigned int nSerSize = 0; \ + assert(fGetSize||fWrite||fRead); /* suppress warning */ \ + {statements} \ + } + +#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) +#define READWRITES(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action)) + + +/** + * Implement three methods for serializable objects. These are actually wrappers over + * "SerializationOp" template, which implements the body of each class' serialization + * code. Adding "ADD_SERIALIZE_METHODS" in the body of the class causes these wrappers to be + * added as members. + */ +#define ADD_SERIALIZE_METHODS \ + size_t GetSerializeSize(int nType, int nVersion) const { \ + CSizeComputer s(nType, nVersion); \ + NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\ + return s.size(); \ + } \ + template \ + void Serialize(Stream& s, int nType, int nVersion) const { \ + NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\ + } \ + template \ + void Unserialize(Stream& s, int nType, int nVersion) { \ + SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \ + } + + + +// +// Basic types +// +#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) +#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj)) + +inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed long long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned long long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); } + +template inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed long long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned long long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); } + +template inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed long long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned long long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); } + +inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); } +template inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); } +template inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; } + + + + + + +// +// Compact size +// size < 253 -- 1 byte +// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) +// size <= UINT_MAX -- 5 bytes (254 + 4 bytes) +// size > UINT_MAX -- 9 bytes (255 + 8 bytes) +// +inline unsigned int GetSizeOfCompactSize(uint64_t nSize) +{ + if (nSize < 253) return sizeof(unsigned char); + else if (nSize <= std::numeric_limits::max()) return sizeof(unsigned char) + sizeof(unsigned short); + else if (nSize <= std::numeric_limits::max()) return sizeof(unsigned char) + sizeof(unsigned int); + else return sizeof(unsigned char) + sizeof(uint64_t); +} + +template +void WriteCompactSize(Stream& os, uint64_t nSize) +{ + if (nSize < 253) + { + unsigned char chSize = nSize; + WRITEDATA(os, chSize); + } + else if (nSize <= std::numeric_limits::max()) + { + unsigned char chSize = 253; + unsigned short xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else if (nSize <= std::numeric_limits::max()) + { + unsigned char chSize = 254; + unsigned int xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else + { + unsigned char chSize = 255; + uint64_t xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + return; +} + +template +uint64_t ReadCompactSize(Stream& is) +{ + unsigned char chSize; + READDATA(is, chSize); + uint64_t nSizeRet = 0; + if (chSize < 253) + { + nSizeRet = chSize; + } + else if (chSize == 253) + { + unsigned short xSize; + READDATA(is, xSize); + nSizeRet = xSize; + if (nSizeRet < 253) + throw std::ios_base::failure("non-canonical ReadCompactSize()"); + } + else if (chSize == 254) + { + unsigned int xSize; + READDATA(is, xSize); + nSizeRet = xSize; + if (nSizeRet < 0x10000u) + throw std::ios_base::failure("non-canonical ReadCompactSize()"); + } + else + { + uint64_t xSize; + READDATA(is, xSize); + nSizeRet = xSize; + if (nSizeRet < 0x100000000ULL) + throw std::ios_base::failure("non-canonical ReadCompactSize()"); + } + if (nSizeRet > (uint64_t)MAX_SIZE) + throw std::ios_base::failure("ReadCompactSize() : size too large"); + return nSizeRet; +} + +// Variable-length integers: bytes are a MSB base-128 encoding of the number. +// The high bit in each byte signifies whether another digit follows. To make +// the encoding is one-to-one, one is subtracted from all but the last digit. +// Thus, the byte sequence a[] with length len, where all but the last byte +// has bit 128 set, encodes the number: +// +// (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1)) +// +// Properties: +// * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes) +// * Every integer has exactly one encoding +// * Encoding does not depend on size of original integer type +// * No redundancy: every (infinite) byte sequence corresponds to a list +// of encoded integers. +// +// 0: [0x00] 256: [0x81 0x00] +// 1: [0x01] 16383: [0xFE 0x7F] +// 127: [0x7F] 16384: [0xFF 0x00] +// 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F] +// 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F] +// 2^32: [0x8E 0xFE 0xFE 0xFF 0x00] + +template +inline unsigned int GetSizeOfVarInt(I n) +{ + int nRet = 0; + while(true) { + nRet++; + if (n <= 0x7F) + break; + n = (n >> 7) - 1; + } + return nRet; +} + +template +void WriteVarInt(Stream& os, I n) +{ + unsigned char tmp[(sizeof(n)*8+6)/7]; + int len=0; + while(true) { + tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00); + if (n <= 0x7F) + break; + n = (n >> 7) - 1; + len++; + } + do { + WRITEDATA(os, tmp[len]); + } while(len--); +} + +template +I ReadVarInt(Stream& is) +{ + I n = 0; + while(true) { + unsigned char chData; + READDATA(is, chData); + n = (n << 7) | (chData & 0x7F); + if (chData & 0x80) + n++; + else + return n; + } +} + +#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) +#define VARINT(obj) REF(WrapVarInt(REF(obj))) + +/** Wrapper for serializing arrays and POD. + */ +class CFlatData +{ +protected: + char* pbegin; + char* pend; +public: + CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { } + char* begin() { return pbegin; } + const char* begin() const { return pbegin; } + char* end() { return pend; } + const char* end() const { return pend; } + + unsigned int GetSerializeSize(int, int=0) const + { + return pend - pbegin; + } + + template + void Serialize(Stream& s, int, int=0) const + { + s.write(pbegin, pend - pbegin); + } + + template + void Unserialize(Stream& s, int, int=0) + { + s.read(pbegin, pend - pbegin); + } +}; + +template +class CVarInt +{ +protected: + I &n; +public: + CVarInt(I& nIn) : n(nIn) { } + + unsigned int GetSerializeSize(int, int) const { + return GetSizeOfVarInt(n); + } + + template + void Serialize(Stream &s, int, int) const { + WriteVarInt(s, n); + } + + template + void Unserialize(Stream& s, int, int) { + n = ReadVarInt(s); + } +}; + +template +CVarInt WrapVarInt(I& n) { return CVarInt(n); } + +// +// Forward declarations +// + +// string +template unsigned int GetSerializeSize(const std::basic_string& str, int, int=0); +template void Serialize(Stream& os, const std::basic_string& str, int, int=0); +template void Unserialize(Stream& is, std::basic_string& str, int, int=0); + +// vector +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&); +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion); + +// others derived from vector +extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion); +template void Serialize(Stream& os, const CScript& v, int nType, int nVersion); +template void Unserialize(Stream& is, CScript& v, int nType, int nVersion); + +// pair +template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion); +template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion); +template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion); + +// 3 tuple +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); + +// 4 tuple +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); + +// map +template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::map& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::map& m, int nType, int nVersion); + +// set +template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::set& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::set& m, int nType, int nVersion); + + + + + +// +// If none of the specialized versions above matched, default to calling member function. +// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error. +// The compiler will only cast int to long if none of the other templates matched. +// Thanks to Boost serialization for this idea. +// +template +inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion) +{ + return a.GetSerializeSize((int)nType, nVersion); +} + +template +inline void Serialize(Stream& os, const T& a, long nType, int nVersion) +{ + a.Serialize(os, (int)nType, nVersion); +} + +template +inline void Unserialize(Stream& is, T& a, long nType, int nVersion) +{ + a.Unserialize(is, (int)nType, nVersion); +} + + + + + +// +// string +// +template +unsigned int GetSerializeSize(const std::basic_string& str, int, int) +{ + return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]); +} + +template +void Serialize(Stream& os, const std::basic_string& str, int, int) +{ + WriteCompactSize(os, str.size()); + if (!str.empty()) + os.write((char*)&str[0], str.size() * sizeof(str[0])); +} + +template +void Unserialize(Stream& is, std::basic_string& str, int, int) +{ + unsigned int nSize = ReadCompactSize(is); + str.resize(nSize); + if (nSize != 0) + is.read((char*)&str[0], nSize * sizeof(str[0])); +} + + + +// +// vector +// +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); +} + +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + unsigned int nSize = GetSizeOfCompactSize(v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + nSize += GetSerializeSize((*vi), nType, nVersion); + return nSize; +} + +template +inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion) +{ + return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + WriteCompactSize(os, v.size()); + if (!v.empty()) + os.write((char*)&v[0], v.size() * sizeof(T)); +} + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + WriteCompactSize(os, v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + ::Serialize(os, (*vi), nType, nVersion); +} + +template +inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion) +{ + Serialize_impl(os, v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + // Limit size per read so bogus size value won't cause out of memory + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + while (i < nSize) + { + unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); + v.resize(i + blk); + is.read((char*)&v[i], blk * sizeof(T)); + i += blk; + } +} + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + unsigned int nMid = 0; + while (nMid < nSize) + { + nMid += 5000000 / sizeof(T); + if (nMid > nSize) + nMid = nSize; + v.resize(nMid); + for (; i < nMid; i++) + Unserialize(is, v[i], nType, nVersion); + } +} + +template +inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion) +{ + Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental()); +} + + + +// +// others derived from vector +// +inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion) +{ + return GetSerializeSize((const std::vector&)v, nType, nVersion); +} + +template +void Serialize(Stream& os, const CScript& v, int nType, int nVersion) +{ + Serialize(os, (const std::vector&)v, nType, nVersion); +} + +template +void Unserialize(Stream& is, CScript& v, int nType, int nVersion) +{ + Unserialize(is, (std::vector&)v, nType, nVersion); +} + + + +// +// pair +// +template +unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion) +{ + return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion); +} + +template +void Serialize(Stream& os, const std::pair& item, int nType, int nVersion) +{ + Serialize(os, item.first, nType, nVersion); + Serialize(os, item.second, nType, nVersion); +} + +template +void Unserialize(Stream& is, std::pair& item, int nType, int nVersion) +{ + Unserialize(is, item.first, nType, nVersion); + Unserialize(is, item.second, nType, nVersion); +} + + + +// +// 3 tuple +// +template +unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion) +{ + unsigned int nSize = 0; + nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion) +{ + Serialize(os, boost::get<0>(item), nType, nVersion); + Serialize(os, boost::get<1>(item), nType, nVersion); + Serialize(os, boost::get<2>(item), nType, nVersion); +} + +template +void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion) +{ + Unserialize(is, boost::get<0>(item), nType, nVersion); + Unserialize(is, boost::get<1>(item), nType, nVersion); + Unserialize(is, boost::get<2>(item), nType, nVersion); +} + + + +// +// 4 tuple +// +template +unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion) +{ + unsigned int nSize = 0; + nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion) +{ + Serialize(os, boost::get<0>(item), nType, nVersion); + Serialize(os, boost::get<1>(item), nType, nVersion); + Serialize(os, boost::get<2>(item), nType, nVersion); + Serialize(os, boost::get<3>(item), nType, nVersion); +} + +template +void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion) +{ + Unserialize(is, boost::get<0>(item), nType, nVersion); + Unserialize(is, boost::get<1>(item), nType, nVersion); + Unserialize(is, boost::get<2>(item), nType, nVersion); + Unserialize(is, boost::get<3>(item), nType, nVersion); +} + + + +// +// map +// +template +unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + nSize += GetSerializeSize((*mi), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::map& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + Serialize(os, (*mi), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::map& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::map::iterator mi = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + std::pair item; + Unserialize(is, item, nType, nVersion); + mi = m.insert(mi, item); + } +} + + + +// +// set +// +template +unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + nSize += GetSerializeSize((*it), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::set& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + Serialize(os, (*it), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::set& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::set::iterator it = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + K key; + Unserialize(is, key, nType, nVersion); + it = m.insert(it, key); + } +} + + + +// +// Support for IMPLEMENT_SERIALIZE and READWRITE macro +// +class CSerActionGetSerializeSize { }; +class CSerActionSerialize { }; +class CSerActionUnserialize { }; + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action) +{ + return ::GetSerializeSize(obj, nType, nVersion); +} + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action) +{ + ::Serialize(s, obj, nType, nVersion); + return 0; +} + +template +inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action) +{ + ::Unserialize(s, obj, nType, nVersion); + return 0; +} + +struct ser_streamplaceholder +{ + int nType; + int nVersion; +}; + + + + + + + + + + + +typedef std::vector > CSerializeData; + +class CSizeComputer +{ +protected: + size_t nSize; + +public: + int nType; + int nVersion; + + CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {} + + CSizeComputer& write(const char *psz, size_t nSize) + { + this->nSize += nSize; + return *this; + } + + template + CSizeComputer& operator<<(const T& obj) + { + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + size_t size() const { + return nSize; + } +}; + +/** Double ended buffer combining vector and stream-like interfaces. + * + * >> and << read and write unformatted data using the above serialization templates. + * Fills with data in linear time; some stringstream implementations take N^2 time. + */ +class CDataStream +{ +protected: + typedef CSerializeData vector_type; + vector_type vch; + unsigned int nReadPos; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + typedef vector_type::allocator_type allocator_type; + typedef vector_type::size_type size_type; + typedef vector_type::difference_type difference_type; + typedef vector_type::reference reference; + typedef vector_type::const_reference const_reference; + typedef vector_type::value_type value_type; + typedef vector_type::iterator iterator; + typedef vector_type::const_iterator const_iterator; + typedef vector_type::reverse_iterator reverse_iterator; + + explicit CDataStream(int nTypeIn, int nVersionIn) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } +#endif + + CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + { + Init(nTypeIn, nVersionIn); + } + + void Init(int nTypeIn, int nVersionIn) + { + nReadPos = 0; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = std::ios::badbit | std::ios::failbit; + } + + CDataStream& operator+=(const CDataStream& b) + { + vch.insert(vch.end(), b.begin(), b.end()); + return *this; + } + + friend CDataStream operator+(const CDataStream& a, const CDataStream& b) + { + CDataStream ret = a; + ret += b; + return (ret); + } + + std::string str() const + { + return (std::string(begin(), end())); + } + + + // + // Vector subset + // + const_iterator begin() const { return vch.begin() + nReadPos; } + iterator begin() { return vch.begin() + nReadPos; } + const_iterator end() const { return vch.end(); } + iterator end() { return vch.end(); } + size_type size() const { return vch.size() - nReadPos; } + bool empty() const { return vch.size() == nReadPos; } + void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } + void reserve(size_type n) { vch.reserve(n + nReadPos); } + const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } + reference operator[](size_type pos) { return vch[pos + nReadPos]; } + void clear() { vch.clear(); nReadPos = 0; } + iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); } + + void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + void insert(iterator it, const char* first, const char* last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } +#endif + + iterator erase(iterator it) + { + if (it == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (++nReadPos >= vch.size()) + { + // whenever we reach the end, we take the opportunity to clear the buffer + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + return vch.begin() + nReadPos; + } + else + return vch.erase(it); + } + + iterator erase(iterator first, iterator last) + { + if (first == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (last == vch.end()) + { + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + else + { + nReadPos = (last - vch.begin()); + return last; + } + } + else + return vch.erase(first, last); + } + + inline void Compact() + { + vch.erase(vch.begin(), vch.begin() + nReadPos); + nReadPos = 0; + } + + bool Rewind(size_type n) + { + // Rewind by n characters if the buffer hasn't been compacted yet + if (n > nReadPos) + return false; + nReadPos -= n; + return true; + } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool eof() const { return size() == 0; } + bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } + bool good() const { return !eof() && (state == 0); } + void clear(short n) { state = n; } // name conflict with vector clear() + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; } + CDataStream* rdbuf() { return this; } + int in_avail() { return size(); } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CDataStream& read(char* pch, size_t nSize) + { + // Read from the beginning of the buffer + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(std::ios::failbit, "CDataStream::read() : end of data"); + memset(pch, 0, nSize); + nSize = vch.size() - nReadPos; + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = 0; + vch.clear(); + return (*this); + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& ignore(int nSize) + { + // Ignore from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + setstate(std::ios::failbit, "CDataStream::ignore() : end of data"); + nReadPos = 0; + vch.clear(); + return (*this); + } + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& write(const char* pch, size_t nSize) + { + // Write to the end of the buffer + vch.insert(vch.end(), pch, pch + nSize); + return (*this); + } + + template + void Serialize(Stream& s, int nType, int nVersion) const + { + // Special case: stream << stream concatenates like stream += stream + if (!vch.empty()) + s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CDataStream& operator<<(const T& obj) + { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CDataStream& operator>>(T& obj) + { + // Unserialize from this stream + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } + + void GetAndClear(CSerializeData &data) { + data.insert(data.end(), begin(), end()); + clear(); + } +}; + + + + + + + + + + +/** RAII wrapper for FILE*. + * + * Will automatically close the file when it goes out of scope if not null. + * If you're returning the file pointer, return file.release(). + * If you need to close the file early, use file.fclose() instead of fclose(file). + */ +class CAutoFile +{ +protected: + FILE* file; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) + { + file = filenew; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = std::ios::badbit | std::ios::failbit; + } + + ~CAutoFile() + { + fclose(); + } + + void fclose() + { + if (file != NULL && file != stdin && file != stdout && file != stderr) + ::fclose(file); + file = NULL; + } + + FILE* release() { FILE* ret = file; file = NULL; return ret; } + operator FILE*() { return file; } + FILE* operator->() { return file; } + FILE& operator*() { return *file; } + FILE** operator&() { return &file; } + FILE* operator=(FILE* pnew) { return file = pnew; } + bool operator!() { return (file == NULL); } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } + bool good() const { return state == 0; } + void clear(short n = 0) { state = n; } + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CAutoFile& read(char* pch, size_t nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); + if (fread(pch, 1, nSize, file) != nSize) + setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); + return (*this); + } + + CAutoFile& write(const char* pch, size_t nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); + if (fwrite(pch, 1, nSize, file) != nSize) + setstate(std::ios::failbit, "CAutoFile::write : write failed"); + return (*this); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CAutoFile& operator<<(const T& obj) + { + // Serialize to this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CAutoFile& operator>>(T& obj) + { + // Unserialize from this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; + + + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/shavite.c b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/shavite.c new file mode 100644 index 0000000..85074f3 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/shavite.c @@ -0,0 +1,1764 @@ +/* $Id: shavite.c 227 2010-06-16 17:28:38Z tp $ */ +/* + * SHAvite-3 implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include +#include + +#include "sph_shavite.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_SHAVITE +#define SPH_SMALL_FOOTPRINT_SHAVITE 1 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +#define C32 SPH_C32 + +/* + * As of round 2 of the SHA-3 competition, the published reference + * implementation and test vectors are wrong, because they use + * big-endian AES tables while the internal decoding uses little-endian. + * The code below follows the specification. To turn it into a code + * which follows the reference implementation (the one called "BugFix" + * on the SHAvite-3 web site, published on Nov 23rd, 2009), comment out + * the code below (from the '#define AES_BIG_ENDIAN...' to the definition + * of the AES_ROUND_NOKEY macro) and replace it with the version which + * is commented out afterwards. + */ + +#define AES_BIG_ENDIAN 0 +#include "aes_helper.c" + +static const sph_u32 IV224[] = { + C32(0x6774F31C), C32(0x990AE210), C32(0xC87D4274), C32(0xC9546371), + C32(0x62B2AEA8), C32(0x4B5801D8), C32(0x1B702860), C32(0x842F3017) +}; + +static const sph_u32 IV256[] = { + C32(0x49BB3E47), C32(0x2674860D), C32(0xA8B392AC), C32(0x021AC4E6), + C32(0x409283CF), C32(0x620E5D86), C32(0x6D929DCB), C32(0x96CC2A8B) +}; + +static const sph_u32 IV384[] = { + C32(0x83DF1545), C32(0xF9AAEC13), C32(0xF4803CB0), C32(0x11FE1F47), + C32(0xDA6CD269), C32(0x4F53FCD7), C32(0x950529A2), C32(0x97908147), + C32(0xB0A4D7AF), C32(0x2B9132BF), C32(0x226E607D), C32(0x3C0F8D7C), + C32(0x487B3F0F), C32(0x04363E22), C32(0x0155C99C), C32(0xEC2E20D3) +}; + +static const sph_u32 IV512[] = { + C32(0x72FCCDD8), C32(0x79CA4727), C32(0x128A077B), C32(0x40D55AEC), + C32(0xD1901A06), C32(0x430AE307), C32(0xB29F5CD1), C32(0xDF07FBFC), + C32(0x8E45D73D), C32(0x681AB538), C32(0xBDE86578), C32(0xDD577E47), + C32(0xE275EADE), C32(0x502D9FCD), C32(0xB9357178), C32(0x022A4B9A) +}; + +#define AES_ROUND_NOKEY(x0, x1, x2, x3) do { \ + sph_u32 t0 = (x0); \ + sph_u32 t1 = (x1); \ + sph_u32 t2 = (x2); \ + sph_u32 t3 = (x3); \ + AES_ROUND_NOKEY_LE(t0, t1, t2, t3, x0, x1, x2, x3); \ + } while (0) + +/* + * This is the code needed to match the "reference implementation" as + * published on Nov 23rd, 2009, instead of the published specification. + * + +#define AES_BIG_ENDIAN 1 +#include "aes_helper.c" + +static const sph_u32 IV224[] = { + C32(0xC4C67795), C32(0xC0B1817F), C32(0xEAD88924), C32(0x1ABB1BB0), + C32(0xE0C29152), C32(0xBDE046BA), C32(0xAEEECF99), C32(0x58D509D8) +}; + +static const sph_u32 IV256[] = { + C32(0x3EECF551), C32(0xBF10819B), C32(0xE6DC8559), C32(0xF3E23FD5), + C32(0x431AEC73), C32(0x79E3F731), C32(0x98325F05), C32(0xA92A31F1) +}; + +static const sph_u32 IV384[] = { + C32(0x71F48510), C32(0xA903A8AC), C32(0xFE3216DD), C32(0x0B2D2AD4), + C32(0x6672900A), C32(0x41032819), C32(0x15A7D780), C32(0xB3CAB8D9), + C32(0x34EF4711), C32(0xDE019FE8), C32(0x4D674DC4), C32(0xE056D96B), + C32(0xA35C016B), C32(0xDD903BA7), C32(0x8C1B09B4), C32(0x2C3E9F25) +}; + +static const sph_u32 IV512[] = { + C32(0xD5652B63), C32(0x25F1E6EA), C32(0xB18F48FA), C32(0xA1EE3A47), + C32(0xC8B67B07), C32(0xBDCE48D3), C32(0xE3937B78), C32(0x05DB5186), + C32(0x613BE326), C32(0xA11FA303), C32(0x90C833D4), C32(0x79CEE316), + C32(0x1E1AF00F), C32(0x2829B165), C32(0x23B25F80), C32(0x21E11499) +}; + +#define AES_ROUND_NOKEY(x0, x1, x2, x3) do { \ + sph_u32 t0 = (x0); \ + sph_u32 t1 = (x1); \ + sph_u32 t2 = (x2); \ + sph_u32 t3 = (x3); \ + AES_ROUND_NOKEY_BE(t0, t1, t2, t3, x0, x1, x2, x3); \ + } while (0) + + */ + +#define KEY_EXPAND_ELT(k0, k1, k2, k3) do { \ + sph_u32 kt; \ + AES_ROUND_NOKEY(k1, k2, k3, k0); \ + kt = (k0); \ + (k0) = (k1); \ + (k1) = (k2); \ + (k2) = (k3); \ + (k3) = kt; \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_SHAVITE + +/* + * This function assumes that "msg" is aligned for 32-bit access. + */ +static void +c256(sph_shavite_small_context *sc, const void *msg) +{ + sph_u32 p0, p1, p2, p3, p4, p5, p6, p7; + sph_u32 rk[144]; + size_t u; + int r, s; + +#if SPH_LITTLE_ENDIAN + memcpy(rk, msg, 64); +#else + for (u = 0; u < 16; u += 4) { + rk[u + 0] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 0); + rk[u + 1] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 4); + rk[u + 2] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 8); + rk[u + 3] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 12); + } +#endif + u = 16; + for (r = 0; r < 4; r ++) { + for (s = 0; s < 2; s ++) { + sph_u32 x0, x1, x2, x3; + + x0 = rk[u - 15]; + x1 = rk[u - 14]; + x2 = rk[u - 13]; + x3 = rk[u - 16]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk[u + 0] = x0 ^ rk[u - 4]; + rk[u + 1] = x1 ^ rk[u - 3]; + rk[u + 2] = x2 ^ rk[u - 2]; + rk[u + 3] = x3 ^ rk[u - 1]; + if (u == 16) { + rk[ 16] ^= sc->count0; + rk[ 17] ^= SPH_T32(~sc->count1); + } else if (u == 56) { + rk[ 57] ^= sc->count1; + rk[ 58] ^= SPH_T32(~sc->count0); + } + u += 4; + + x0 = rk[u - 15]; + x1 = rk[u - 14]; + x2 = rk[u - 13]; + x3 = rk[u - 16]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk[u + 0] = x0 ^ rk[u - 4]; + rk[u + 1] = x1 ^ rk[u - 3]; + rk[u + 2] = x2 ^ rk[u - 2]; + rk[u + 3] = x3 ^ rk[u - 1]; + if (u == 84) { + rk[ 86] ^= sc->count1; + rk[ 87] ^= SPH_T32(~sc->count0); + } else if (u == 124) { + rk[124] ^= sc->count0; + rk[127] ^= SPH_T32(~sc->count1); + } + u += 4; + } + for (s = 0; s < 4; s ++) { + rk[u + 0] = rk[u - 16] ^ rk[u - 3]; + rk[u + 1] = rk[u - 15] ^ rk[u - 2]; + rk[u + 2] = rk[u - 14] ^ rk[u - 1]; + rk[u + 3] = rk[u - 13] ^ rk[u - 0]; + u += 4; + } + } + + p0 = sc->h[0x0]; + p1 = sc->h[0x1]; + p2 = sc->h[0x2]; + p3 = sc->h[0x3]; + p4 = sc->h[0x4]; + p5 = sc->h[0x5]; + p6 = sc->h[0x6]; + p7 = sc->h[0x7]; + u = 0; + for (r = 0; r < 6; r ++) { + sph_u32 x0, x1, x2, x3; + + x0 = p4 ^ rk[u ++]; + x1 = p5 ^ rk[u ++]; + x2 = p6 ^ rk[u ++]; + x3 = p7 ^ rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + x0 ^= rk[u ++]; + x1 ^= rk[u ++]; + x2 ^= rk[u ++]; + x3 ^= rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + x0 ^= rk[u ++]; + x1 ^= rk[u ++]; + x2 ^= rk[u ++]; + x3 ^= rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + + x0 = p0 ^ rk[u ++]; + x1 = p1 ^ rk[u ++]; + x2 = p2 ^ rk[u ++]; + x3 = p3 ^ rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + x0 ^= rk[u ++]; + x1 ^= rk[u ++]; + x2 ^= rk[u ++]; + x3 ^= rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + x0 ^= rk[u ++]; + x1 ^= rk[u ++]; + x2 ^= rk[u ++]; + x3 ^= rk[u ++]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + } + sc->h[0x0] ^= p0; + sc->h[0x1] ^= p1; + sc->h[0x2] ^= p2; + sc->h[0x3] ^= p3; + sc->h[0x4] ^= p4; + sc->h[0x5] ^= p5; + sc->h[0x6] ^= p6; + sc->h[0x7] ^= p7; +} + +#else + +/* + * This function assumes that "msg" is aligned for 32-bit access. + */ +static void +c256(sph_shavite_small_context *sc, const void *msg) +{ + sph_u32 p0, p1, p2, p3, p4, p5, p6, p7; + sph_u32 x0, x1, x2, x3; + sph_u32 rk0, rk1, rk2, rk3, rk4, rk5, rk6, rk7; + sph_u32 rk8, rk9, rkA, rkB, rkC, rkD, rkE, rkF; + + p0 = sc->h[0x0]; + p1 = sc->h[0x1]; + p2 = sc->h[0x2]; + p3 = sc->h[0x3]; + p4 = sc->h[0x4]; + p5 = sc->h[0x5]; + p6 = sc->h[0x6]; + p7 = sc->h[0x7]; + /* round 0 */ + rk0 = sph_dec32le_aligned((const unsigned char *)msg + 0); + x0 = p4 ^ rk0; + rk1 = sph_dec32le_aligned((const unsigned char *)msg + 4); + x1 = p5 ^ rk1; + rk2 = sph_dec32le_aligned((const unsigned char *)msg + 8); + x2 = p6 ^ rk2; + rk3 = sph_dec32le_aligned((const unsigned char *)msg + 12); + x3 = p7 ^ rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk4 = sph_dec32le_aligned((const unsigned char *)msg + 16); + x0 ^= rk4; + rk5 = sph_dec32le_aligned((const unsigned char *)msg + 20); + x1 ^= rk5; + rk6 = sph_dec32le_aligned((const unsigned char *)msg + 24); + x2 ^= rk6; + rk7 = sph_dec32le_aligned((const unsigned char *)msg + 28); + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk8 = sph_dec32le_aligned((const unsigned char *)msg + 32); + x0 ^= rk8; + rk9 = sph_dec32le_aligned((const unsigned char *)msg + 36); + x1 ^= rk9; + rkA = sph_dec32le_aligned((const unsigned char *)msg + 40); + x2 ^= rkA; + rkB = sph_dec32le_aligned((const unsigned char *)msg + 44); + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 1 */ + rkC = sph_dec32le_aligned((const unsigned char *)msg + 48); + x0 = p0 ^ rkC; + rkD = sph_dec32le_aligned((const unsigned char *)msg + 52); + x1 = p1 ^ rkD; + rkE = sph_dec32le_aligned((const unsigned char *)msg + 56); + x2 = p2 ^ rkE; + rkF = sph_dec32le_aligned((const unsigned char *)msg + 60); + x3 = p3 ^ rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0, rk1, rk2, rk3); + rk0 ^= rkC ^ sc->count0; + rk1 ^= rkD ^ SPH_T32(~sc->count1); + rk2 ^= rkE; + rk3 ^= rkF; + x0 ^= rk0; + x1 ^= rk1; + x2 ^= rk2; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk4, rk5, rk6, rk7); + rk4 ^= rk0; + rk5 ^= rk1; + rk6 ^= rk2; + rk7 ^= rk3; + x0 ^= rk4; + x1 ^= rk5; + x2 ^= rk6; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 2 */ + KEY_EXPAND_ELT(rk8, rk9, rkA, rkB); + rk8 ^= rk4; + rk9 ^= rk5; + rkA ^= rk6; + rkB ^= rk7; + x0 = p4 ^ rk8; + x1 = p5 ^ rk9; + x2 = p6 ^ rkA; + x3 = p7 ^ rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rkC, rkD, rkE, rkF); + rkC ^= rk8; + rkD ^= rk9; + rkE ^= rkA; + rkF ^= rkB; + x0 ^= rkC; + x1 ^= rkD; + x2 ^= rkE; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0 ^= rkD; + x0 ^= rk0; + rk1 ^= rkE; + x1 ^= rk1; + rk2 ^= rkF; + x2 ^= rk2; + rk3 ^= rk0; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 3 */ + rk4 ^= rk1; + x0 = p0 ^ rk4; + rk5 ^= rk2; + x1 = p1 ^ rk5; + rk6 ^= rk3; + x2 = p2 ^ rk6; + rk7 ^= rk4; + x3 = p3 ^ rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk8 ^= rk5; + x0 ^= rk8; + rk9 ^= rk6; + x1 ^= rk9; + rkA ^= rk7; + x2 ^= rkA; + rkB ^= rk8; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rkC ^= rk9; + x0 ^= rkC; + rkD ^= rkA; + x1 ^= rkD; + rkE ^= rkB; + x2 ^= rkE; + rkF ^= rkC; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 4 */ + KEY_EXPAND_ELT(rk0, rk1, rk2, rk3); + rk0 ^= rkC; + rk1 ^= rkD; + rk2 ^= rkE; + rk3 ^= rkF; + x0 = p4 ^ rk0; + x1 = p5 ^ rk1; + x2 = p6 ^ rk2; + x3 = p7 ^ rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk4, rk5, rk6, rk7); + rk4 ^= rk0; + rk5 ^= rk1; + rk6 ^= rk2; + rk7 ^= rk3; + x0 ^= rk4; + x1 ^= rk5; + x2 ^= rk6; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk8, rk9, rkA, rkB); + rk8 ^= rk4; + rk9 ^= rk5 ^ sc->count1; + rkA ^= rk6 ^ SPH_T32(~sc->count0); + rkB ^= rk7; + x0 ^= rk8; + x1 ^= rk9; + x2 ^= rkA; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 5 */ + KEY_EXPAND_ELT(rkC, rkD, rkE, rkF); + rkC ^= rk8; + rkD ^= rk9; + rkE ^= rkA; + rkF ^= rkB; + x0 = p0 ^ rkC; + x1 = p1 ^ rkD; + x2 = p2 ^ rkE; + x3 = p3 ^ rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0 ^= rkD; + x0 ^= rk0; + rk1 ^= rkE; + x1 ^= rk1; + rk2 ^= rkF; + x2 ^= rk2; + rk3 ^= rk0; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk4 ^= rk1; + x0 ^= rk4; + rk5 ^= rk2; + x1 ^= rk5; + rk6 ^= rk3; + x2 ^= rk6; + rk7 ^= rk4; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 6 */ + rk8 ^= rk5; + x0 = p4 ^ rk8; + rk9 ^= rk6; + x1 = p5 ^ rk9; + rkA ^= rk7; + x2 = p6 ^ rkA; + rkB ^= rk8; + x3 = p7 ^ rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rkC ^= rk9; + x0 ^= rkC; + rkD ^= rkA; + x1 ^= rkD; + rkE ^= rkB; + x2 ^= rkE; + rkF ^= rkC; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0, rk1, rk2, rk3); + rk0 ^= rkC; + rk1 ^= rkD; + rk2 ^= rkE; + rk3 ^= rkF; + x0 ^= rk0; + x1 ^= rk1; + x2 ^= rk2; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 7 */ + KEY_EXPAND_ELT(rk4, rk5, rk6, rk7); + rk4 ^= rk0; + rk5 ^= rk1; + rk6 ^= rk2 ^ sc->count1; + rk7 ^= rk3 ^ SPH_T32(~sc->count0); + x0 = p0 ^ rk4; + x1 = p1 ^ rk5; + x2 = p2 ^ rk6; + x3 = p3 ^ rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk8, rk9, rkA, rkB); + rk8 ^= rk4; + rk9 ^= rk5; + rkA ^= rk6; + rkB ^= rk7; + x0 ^= rk8; + x1 ^= rk9; + x2 ^= rkA; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rkC, rkD, rkE, rkF); + rkC ^= rk8; + rkD ^= rk9; + rkE ^= rkA; + rkF ^= rkB; + x0 ^= rkC; + x1 ^= rkD; + x2 ^= rkE; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 8 */ + rk0 ^= rkD; + x0 = p4 ^ rk0; + rk1 ^= rkE; + x1 = p5 ^ rk1; + rk2 ^= rkF; + x2 = p6 ^ rk2; + rk3 ^= rk0; + x3 = p7 ^ rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk4 ^= rk1; + x0 ^= rk4; + rk5 ^= rk2; + x1 ^= rk5; + rk6 ^= rk3; + x2 ^= rk6; + rk7 ^= rk4; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk8 ^= rk5; + x0 ^= rk8; + rk9 ^= rk6; + x1 ^= rk9; + rkA ^= rk7; + x2 ^= rkA; + rkB ^= rk8; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 9 */ + rkC ^= rk9; + x0 = p0 ^ rkC; + rkD ^= rkA; + x1 = p1 ^ rkD; + rkE ^= rkB; + x2 = p2 ^ rkE; + rkF ^= rkC; + x3 = p3 ^ rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0, rk1, rk2, rk3); + rk0 ^= rkC; + rk1 ^= rkD; + rk2 ^= rkE; + rk3 ^= rkF; + x0 ^= rk0; + x1 ^= rk1; + x2 ^= rk2; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk4, rk5, rk6, rk7); + rk4 ^= rk0; + rk5 ^= rk1; + rk6 ^= rk2; + rk7 ^= rk3; + x0 ^= rk4; + x1 ^= rk5; + x2 ^= rk6; + x3 ^= rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 10 */ + KEY_EXPAND_ELT(rk8, rk9, rkA, rkB); + rk8 ^= rk4; + rk9 ^= rk5; + rkA ^= rk6; + rkB ^= rk7; + x0 = p4 ^ rk8; + x1 = p5 ^ rk9; + x2 = p6 ^ rkA; + x3 = p7 ^ rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rkC, rkD, rkE, rkF); + rkC ^= rk8 ^ sc->count0; + rkD ^= rk9; + rkE ^= rkA; + rkF ^= rkB ^ SPH_T32(~sc->count1); + x0 ^= rkC; + x1 ^= rkD; + x2 ^= rkE; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0 ^= rkD; + x0 ^= rk0; + rk1 ^= rkE; + x1 ^= rk1; + rk2 ^= rkF; + x2 ^= rk2; + rk3 ^= rk0; + x3 ^= rk3; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 11 */ + rk4 ^= rk1; + x0 = p0 ^ rk4; + rk5 ^= rk2; + x1 = p1 ^ rk5; + rk6 ^= rk3; + x2 = p2 ^ rk6; + rk7 ^= rk4; + x3 = p3 ^ rk7; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk8 ^= rk5; + x0 ^= rk8; + rk9 ^= rk6; + x1 ^= rk9; + rkA ^= rk7; + x2 ^= rkA; + rkB ^= rk8; + x3 ^= rkB; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rkC ^= rk9; + x0 ^= rkC; + rkD ^= rkA; + x1 ^= rkD; + rkE ^= rkB; + x2 ^= rkE; + rkF ^= rkC; + x3 ^= rkF; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + sc->h[0x0] ^= p0; + sc->h[0x1] ^= p1; + sc->h[0x2] ^= p2; + sc->h[0x3] ^= p3; + sc->h[0x4] ^= p4; + sc->h[0x5] ^= p5; + sc->h[0x6] ^= p6; + sc->h[0x7] ^= p7; +} + +#endif + +#if SPH_SMALL_FOOTPRINT_SHAVITE + +/* + * This function assumes that "msg" is aligned for 32-bit access. + */ +static void +c512(sph_shavite_big_context *sc, const void *msg) +{ + sph_u32 p0, p1, p2, p3, p4, p5, p6, p7; + sph_u32 p8, p9, pA, pB, pC, pD, pE, pF; + sph_u32 rk[448]; + size_t u; + int r, s; + +#if SPH_LITTLE_ENDIAN + memcpy(rk, msg, 128); +#else + for (u = 0; u < 32; u += 4) { + rk[u + 0] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 0); + rk[u + 1] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 4); + rk[u + 2] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 8); + rk[u + 3] = sph_dec32le_aligned( + (const unsigned char *)msg + (u << 2) + 12); + } +#endif + u = 32; + for (;;) { + for (s = 0; s < 4; s ++) { + sph_u32 x0, x1, x2, x3; + + x0 = rk[u - 31]; + x1 = rk[u - 30]; + x2 = rk[u - 29]; + x3 = rk[u - 32]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk[u + 0] = x0 ^ rk[u - 4]; + rk[u + 1] = x1 ^ rk[u - 3]; + rk[u + 2] = x2 ^ rk[u - 2]; + rk[u + 3] = x3 ^ rk[u - 1]; + if (u == 32) { + rk[ 32] ^= sc->count0; + rk[ 33] ^= sc->count1; + rk[ 34] ^= sc->count2; + rk[ 35] ^= SPH_T32(~sc->count3); + } else if (u == 440) { + rk[440] ^= sc->count1; + rk[441] ^= sc->count0; + rk[442] ^= sc->count3; + rk[443] ^= SPH_T32(~sc->count2); + } + u += 4; + + x0 = rk[u - 31]; + x1 = rk[u - 30]; + x2 = rk[u - 29]; + x3 = rk[u - 32]; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk[u + 0] = x0 ^ rk[u - 4]; + rk[u + 1] = x1 ^ rk[u - 3]; + rk[u + 2] = x2 ^ rk[u - 2]; + rk[u + 3] = x3 ^ rk[u - 1]; + if (u == 164) { + rk[164] ^= sc->count3; + rk[165] ^= sc->count2; + rk[166] ^= sc->count1; + rk[167] ^= SPH_T32(~sc->count0); + } else if (u == 316) { + rk[316] ^= sc->count2; + rk[317] ^= sc->count3; + rk[318] ^= sc->count0; + rk[319] ^= SPH_T32(~sc->count1); + } + u += 4; + } + if (u == 448) + break; + for (s = 0; s < 8; s ++) { + rk[u + 0] = rk[u - 32] ^ rk[u - 7]; + rk[u + 1] = rk[u - 31] ^ rk[u - 6]; + rk[u + 2] = rk[u - 30] ^ rk[u - 5]; + rk[u + 3] = rk[u - 29] ^ rk[u - 4]; + u += 4; + } + } + + p0 = sc->h[0x0]; + p1 = sc->h[0x1]; + p2 = sc->h[0x2]; + p3 = sc->h[0x3]; + p4 = sc->h[0x4]; + p5 = sc->h[0x5]; + p6 = sc->h[0x6]; + p7 = sc->h[0x7]; + p8 = sc->h[0x8]; + p9 = sc->h[0x9]; + pA = sc->h[0xA]; + pB = sc->h[0xB]; + pC = sc->h[0xC]; + pD = sc->h[0xD]; + pE = sc->h[0xE]; + pF = sc->h[0xF]; + u = 0; + for (r = 0; r < 14; r ++) { +#define C512_ELT(l0, l1, l2, l3, r0, r1, r2, r3) do { \ + sph_u32 x0, x1, x2, x3; \ + x0 = r0 ^ rk[u ++]; \ + x1 = r1 ^ rk[u ++]; \ + x2 = r2 ^ rk[u ++]; \ + x3 = r3 ^ rk[u ++]; \ + AES_ROUND_NOKEY(x0, x1, x2, x3); \ + x0 ^= rk[u ++]; \ + x1 ^= rk[u ++]; \ + x2 ^= rk[u ++]; \ + x3 ^= rk[u ++]; \ + AES_ROUND_NOKEY(x0, x1, x2, x3); \ + x0 ^= rk[u ++]; \ + x1 ^= rk[u ++]; \ + x2 ^= rk[u ++]; \ + x3 ^= rk[u ++]; \ + AES_ROUND_NOKEY(x0, x1, x2, x3); \ + x0 ^= rk[u ++]; \ + x1 ^= rk[u ++]; \ + x2 ^= rk[u ++]; \ + x3 ^= rk[u ++]; \ + AES_ROUND_NOKEY(x0, x1, x2, x3); \ + l0 ^= x0; \ + l1 ^= x1; \ + l2 ^= x2; \ + l3 ^= x3; \ + } while (0) + +#define WROT(a, b, c, d) do { \ + sph_u32 t = d; \ + d = c; \ + c = b; \ + b = a; \ + a = t; \ + } while (0) + + C512_ELT(p0, p1, p2, p3, p4, p5, p6, p7); + C512_ELT(p8, p9, pA, pB, pC, pD, pE, pF); + + WROT(p0, p4, p8, pC); + WROT(p1, p5, p9, pD); + WROT(p2, p6, pA, pE); + WROT(p3, p7, pB, pF); + +#undef C512_ELT +#undef WROT + } + sc->h[0x0] ^= p0; + sc->h[0x1] ^= p1; + sc->h[0x2] ^= p2; + sc->h[0x3] ^= p3; + sc->h[0x4] ^= p4; + sc->h[0x5] ^= p5; + sc->h[0x6] ^= p6; + sc->h[0x7] ^= p7; + sc->h[0x8] ^= p8; + sc->h[0x9] ^= p9; + sc->h[0xA] ^= pA; + sc->h[0xB] ^= pB; + sc->h[0xC] ^= pC; + sc->h[0xD] ^= pD; + sc->h[0xE] ^= pE; + sc->h[0xF] ^= pF; +} + +#else + +/* + * This function assumes that "msg" is aligned for 32-bit access. + */ +static void +c512(sph_shavite_big_context *sc, const void *msg) +{ + sph_u32 p0, p1, p2, p3, p4, p5, p6, p7; + sph_u32 p8, p9, pA, pB, pC, pD, pE, pF; + sph_u32 x0, x1, x2, x3; + sph_u32 rk00, rk01, rk02, rk03, rk04, rk05, rk06, rk07; + sph_u32 rk08, rk09, rk0A, rk0B, rk0C, rk0D, rk0E, rk0F; + sph_u32 rk10, rk11, rk12, rk13, rk14, rk15, rk16, rk17; + sph_u32 rk18, rk19, rk1A, rk1B, rk1C, rk1D, rk1E, rk1F; + int r; + + p0 = sc->h[0x0]; + p1 = sc->h[0x1]; + p2 = sc->h[0x2]; + p3 = sc->h[0x3]; + p4 = sc->h[0x4]; + p5 = sc->h[0x5]; + p6 = sc->h[0x6]; + p7 = sc->h[0x7]; + p8 = sc->h[0x8]; + p9 = sc->h[0x9]; + pA = sc->h[0xA]; + pB = sc->h[0xB]; + pC = sc->h[0xC]; + pD = sc->h[0xD]; + pE = sc->h[0xE]; + pF = sc->h[0xF]; + /* round 0 */ + rk00 = sph_dec32le_aligned((const unsigned char *)msg + 0); + x0 = p4 ^ rk00; + rk01 = sph_dec32le_aligned((const unsigned char *)msg + 4); + x1 = p5 ^ rk01; + rk02 = sph_dec32le_aligned((const unsigned char *)msg + 8); + x2 = p6 ^ rk02; + rk03 = sph_dec32le_aligned((const unsigned char *)msg + 12); + x3 = p7 ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk04 = sph_dec32le_aligned((const unsigned char *)msg + 16); + x0 ^= rk04; + rk05 = sph_dec32le_aligned((const unsigned char *)msg + 20); + x1 ^= rk05; + rk06 = sph_dec32le_aligned((const unsigned char *)msg + 24); + x2 ^= rk06; + rk07 = sph_dec32le_aligned((const unsigned char *)msg + 28); + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk08 = sph_dec32le_aligned((const unsigned char *)msg + 32); + x0 ^= rk08; + rk09 = sph_dec32le_aligned((const unsigned char *)msg + 36); + x1 ^= rk09; + rk0A = sph_dec32le_aligned((const unsigned char *)msg + 40); + x2 ^= rk0A; + rk0B = sph_dec32le_aligned((const unsigned char *)msg + 44); + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0C = sph_dec32le_aligned((const unsigned char *)msg + 48); + x0 ^= rk0C; + rk0D = sph_dec32le_aligned((const unsigned char *)msg + 52); + x1 ^= rk0D; + rk0E = sph_dec32le_aligned((const unsigned char *)msg + 56); + x2 ^= rk0E; + rk0F = sph_dec32le_aligned((const unsigned char *)msg + 60); + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + rk10 = sph_dec32le_aligned((const unsigned char *)msg + 64); + x0 = pC ^ rk10; + rk11 = sph_dec32le_aligned((const unsigned char *)msg + 68); + x1 = pD ^ rk11; + rk12 = sph_dec32le_aligned((const unsigned char *)msg + 72); + x2 = pE ^ rk12; + rk13 = sph_dec32le_aligned((const unsigned char *)msg + 76); + x3 = pF ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk14 = sph_dec32le_aligned((const unsigned char *)msg + 80); + x0 ^= rk14; + rk15 = sph_dec32le_aligned((const unsigned char *)msg + 84); + x1 ^= rk15; + rk16 = sph_dec32le_aligned((const unsigned char *)msg + 88); + x2 ^= rk16; + rk17 = sph_dec32le_aligned((const unsigned char *)msg + 92); + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk18 = sph_dec32le_aligned((const unsigned char *)msg + 96); + x0 ^= rk18; + rk19 = sph_dec32le_aligned((const unsigned char *)msg + 100); + x1 ^= rk19; + rk1A = sph_dec32le_aligned((const unsigned char *)msg + 104); + x2 ^= rk1A; + rk1B = sph_dec32le_aligned((const unsigned char *)msg + 108); + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk1C = sph_dec32le_aligned((const unsigned char *)msg + 112); + x0 ^= rk1C; + rk1D = sph_dec32le_aligned((const unsigned char *)msg + 116); + x1 ^= rk1D; + rk1E = sph_dec32le_aligned((const unsigned char *)msg + 120); + x2 ^= rk1E; + rk1F = sph_dec32le_aligned((const unsigned char *)msg + 124); + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p8 ^= x0; + p9 ^= x1; + pA ^= x2; + pB ^= x3; + + for (r = 0; r < 3; r ++) { + /* round 1, 5, 9 */ + KEY_EXPAND_ELT(rk00, rk01, rk02, rk03); + rk00 ^= rk1C; + rk01 ^= rk1D; + rk02 ^= rk1E; + rk03 ^= rk1F; + if (r == 0) { + rk00 ^= sc->count0; + rk01 ^= sc->count1; + rk02 ^= sc->count2; + rk03 ^= SPH_T32(~sc->count3); + } + x0 = p0 ^ rk00; + x1 = p1 ^ rk01; + x2 = p2 ^ rk02; + x3 = p3 ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk04, rk05, rk06, rk07); + rk04 ^= rk00; + rk05 ^= rk01; + rk06 ^= rk02; + rk07 ^= rk03; + if (r == 1) { + rk04 ^= sc->count3; + rk05 ^= sc->count2; + rk06 ^= sc->count1; + rk07 ^= SPH_T32(~sc->count0); + } + x0 ^= rk04; + x1 ^= rk05; + x2 ^= rk06; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk08, rk09, rk0A, rk0B); + rk08 ^= rk04; + rk09 ^= rk05; + rk0A ^= rk06; + rk0B ^= rk07; + x0 ^= rk08; + x1 ^= rk09; + x2 ^= rk0A; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0C, rk0D, rk0E, rk0F); + rk0C ^= rk08; + rk0D ^= rk09; + rk0E ^= rk0A; + rk0F ^= rk0B; + x0 ^= rk0C; + x1 ^= rk0D; + x2 ^= rk0E; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + pC ^= x0; + pD ^= x1; + pE ^= x2; + pF ^= x3; + KEY_EXPAND_ELT(rk10, rk11, rk12, rk13); + rk10 ^= rk0C; + rk11 ^= rk0D; + rk12 ^= rk0E; + rk13 ^= rk0F; + x0 = p8 ^ rk10; + x1 = p9 ^ rk11; + x2 = pA ^ rk12; + x3 = pB ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk14, rk15, rk16, rk17); + rk14 ^= rk10; + rk15 ^= rk11; + rk16 ^= rk12; + rk17 ^= rk13; + x0 ^= rk14; + x1 ^= rk15; + x2 ^= rk16; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk18, rk19, rk1A, rk1B); + rk18 ^= rk14; + rk19 ^= rk15; + rk1A ^= rk16; + rk1B ^= rk17; + x0 ^= rk18; + x1 ^= rk19; + x2 ^= rk1A; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk1C, rk1D, rk1E, rk1F); + rk1C ^= rk18; + rk1D ^= rk19; + rk1E ^= rk1A; + rk1F ^= rk1B; + if (r == 2) { + rk1C ^= sc->count2; + rk1D ^= sc->count3; + rk1E ^= sc->count0; + rk1F ^= SPH_T32(~sc->count1); + } + x0 ^= rk1C; + x1 ^= rk1D; + x2 ^= rk1E; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + /* round 2, 6, 10 */ + rk00 ^= rk19; + x0 = pC ^ rk00; + rk01 ^= rk1A; + x1 = pD ^ rk01; + rk02 ^= rk1B; + x2 = pE ^ rk02; + rk03 ^= rk1C; + x3 = pF ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk04 ^= rk1D; + x0 ^= rk04; + rk05 ^= rk1E; + x1 ^= rk05; + rk06 ^= rk1F; + x2 ^= rk06; + rk07 ^= rk00; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk08 ^= rk01; + x0 ^= rk08; + rk09 ^= rk02; + x1 ^= rk09; + rk0A ^= rk03; + x2 ^= rk0A; + rk0B ^= rk04; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0C ^= rk05; + x0 ^= rk0C; + rk0D ^= rk06; + x1 ^= rk0D; + rk0E ^= rk07; + x2 ^= rk0E; + rk0F ^= rk08; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p8 ^= x0; + p9 ^= x1; + pA ^= x2; + pB ^= x3; + rk10 ^= rk09; + x0 = p4 ^ rk10; + rk11 ^= rk0A; + x1 = p5 ^ rk11; + rk12 ^= rk0B; + x2 = p6 ^ rk12; + rk13 ^= rk0C; + x3 = p7 ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk14 ^= rk0D; + x0 ^= rk14; + rk15 ^= rk0E; + x1 ^= rk15; + rk16 ^= rk0F; + x2 ^= rk16; + rk17 ^= rk10; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk18 ^= rk11; + x0 ^= rk18; + rk19 ^= rk12; + x1 ^= rk19; + rk1A ^= rk13; + x2 ^= rk1A; + rk1B ^= rk14; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk1C ^= rk15; + x0 ^= rk1C; + rk1D ^= rk16; + x1 ^= rk1D; + rk1E ^= rk17; + x2 ^= rk1E; + rk1F ^= rk18; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + /* round 3, 7, 11 */ + KEY_EXPAND_ELT(rk00, rk01, rk02, rk03); + rk00 ^= rk1C; + rk01 ^= rk1D; + rk02 ^= rk1E; + rk03 ^= rk1F; + x0 = p8 ^ rk00; + x1 = p9 ^ rk01; + x2 = pA ^ rk02; + x3 = pB ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk04, rk05, rk06, rk07); + rk04 ^= rk00; + rk05 ^= rk01; + rk06 ^= rk02; + rk07 ^= rk03; + x0 ^= rk04; + x1 ^= rk05; + x2 ^= rk06; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk08, rk09, rk0A, rk0B); + rk08 ^= rk04; + rk09 ^= rk05; + rk0A ^= rk06; + rk0B ^= rk07; + x0 ^= rk08; + x1 ^= rk09; + x2 ^= rk0A; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0C, rk0D, rk0E, rk0F); + rk0C ^= rk08; + rk0D ^= rk09; + rk0E ^= rk0A; + rk0F ^= rk0B; + x0 ^= rk0C; + x1 ^= rk0D; + x2 ^= rk0E; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + KEY_EXPAND_ELT(rk10, rk11, rk12, rk13); + rk10 ^= rk0C; + rk11 ^= rk0D; + rk12 ^= rk0E; + rk13 ^= rk0F; + x0 = p0 ^ rk10; + x1 = p1 ^ rk11; + x2 = p2 ^ rk12; + x3 = p3 ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk14, rk15, rk16, rk17); + rk14 ^= rk10; + rk15 ^= rk11; + rk16 ^= rk12; + rk17 ^= rk13; + x0 ^= rk14; + x1 ^= rk15; + x2 ^= rk16; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk18, rk19, rk1A, rk1B); + rk18 ^= rk14; + rk19 ^= rk15; + rk1A ^= rk16; + rk1B ^= rk17; + x0 ^= rk18; + x1 ^= rk19; + x2 ^= rk1A; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk1C, rk1D, rk1E, rk1F); + rk1C ^= rk18; + rk1D ^= rk19; + rk1E ^= rk1A; + rk1F ^= rk1B; + x0 ^= rk1C; + x1 ^= rk1D; + x2 ^= rk1E; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + pC ^= x0; + pD ^= x1; + pE ^= x2; + pF ^= x3; + /* round 4, 8, 12 */ + rk00 ^= rk19; + x0 = p4 ^ rk00; + rk01 ^= rk1A; + x1 = p5 ^ rk01; + rk02 ^= rk1B; + x2 = p6 ^ rk02; + rk03 ^= rk1C; + x3 = p7 ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk04 ^= rk1D; + x0 ^= rk04; + rk05 ^= rk1E; + x1 ^= rk05; + rk06 ^= rk1F; + x2 ^= rk06; + rk07 ^= rk00; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk08 ^= rk01; + x0 ^= rk08; + rk09 ^= rk02; + x1 ^= rk09; + rk0A ^= rk03; + x2 ^= rk0A; + rk0B ^= rk04; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk0C ^= rk05; + x0 ^= rk0C; + rk0D ^= rk06; + x1 ^= rk0D; + rk0E ^= rk07; + x2 ^= rk0E; + rk0F ^= rk08; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p0 ^= x0; + p1 ^= x1; + p2 ^= x2; + p3 ^= x3; + rk10 ^= rk09; + x0 = pC ^ rk10; + rk11 ^= rk0A; + x1 = pD ^ rk11; + rk12 ^= rk0B; + x2 = pE ^ rk12; + rk13 ^= rk0C; + x3 = pF ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk14 ^= rk0D; + x0 ^= rk14; + rk15 ^= rk0E; + x1 ^= rk15; + rk16 ^= rk0F; + x2 ^= rk16; + rk17 ^= rk10; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk18 ^= rk11; + x0 ^= rk18; + rk19 ^= rk12; + x1 ^= rk19; + rk1A ^= rk13; + x2 ^= rk1A; + rk1B ^= rk14; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + rk1C ^= rk15; + x0 ^= rk1C; + rk1D ^= rk16; + x1 ^= rk1D; + rk1E ^= rk17; + x2 ^= rk1E; + rk1F ^= rk18; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p8 ^= x0; + p9 ^= x1; + pA ^= x2; + pB ^= x3; + } + /* round 13 */ + KEY_EXPAND_ELT(rk00, rk01, rk02, rk03); + rk00 ^= rk1C; + rk01 ^= rk1D; + rk02 ^= rk1E; + rk03 ^= rk1F; + x0 = p0 ^ rk00; + x1 = p1 ^ rk01; + x2 = p2 ^ rk02; + x3 = p3 ^ rk03; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk04, rk05, rk06, rk07); + rk04 ^= rk00; + rk05 ^= rk01; + rk06 ^= rk02; + rk07 ^= rk03; + x0 ^= rk04; + x1 ^= rk05; + x2 ^= rk06; + x3 ^= rk07; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk08, rk09, rk0A, rk0B); + rk08 ^= rk04; + rk09 ^= rk05; + rk0A ^= rk06; + rk0B ^= rk07; + x0 ^= rk08; + x1 ^= rk09; + x2 ^= rk0A; + x3 ^= rk0B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk0C, rk0D, rk0E, rk0F); + rk0C ^= rk08; + rk0D ^= rk09; + rk0E ^= rk0A; + rk0F ^= rk0B; + x0 ^= rk0C; + x1 ^= rk0D; + x2 ^= rk0E; + x3 ^= rk0F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + pC ^= x0; + pD ^= x1; + pE ^= x2; + pF ^= x3; + KEY_EXPAND_ELT(rk10, rk11, rk12, rk13); + rk10 ^= rk0C; + rk11 ^= rk0D; + rk12 ^= rk0E; + rk13 ^= rk0F; + x0 = p8 ^ rk10; + x1 = p9 ^ rk11; + x2 = pA ^ rk12; + x3 = pB ^ rk13; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk14, rk15, rk16, rk17); + rk14 ^= rk10; + rk15 ^= rk11; + rk16 ^= rk12; + rk17 ^= rk13; + x0 ^= rk14; + x1 ^= rk15; + x2 ^= rk16; + x3 ^= rk17; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk18, rk19, rk1A, rk1B); + rk18 ^= rk14 ^ sc->count1; + rk19 ^= rk15 ^ sc->count0; + rk1A ^= rk16 ^ sc->count3; + rk1B ^= rk17 ^ SPH_T32(~sc->count2); + x0 ^= rk18; + x1 ^= rk19; + x2 ^= rk1A; + x3 ^= rk1B; + AES_ROUND_NOKEY(x0, x1, x2, x3); + KEY_EXPAND_ELT(rk1C, rk1D, rk1E, rk1F); + rk1C ^= rk18; + rk1D ^= rk19; + rk1E ^= rk1A; + rk1F ^= rk1B; + x0 ^= rk1C; + x1 ^= rk1D; + x2 ^= rk1E; + x3 ^= rk1F; + AES_ROUND_NOKEY(x0, x1, x2, x3); + p4 ^= x0; + p5 ^= x1; + p6 ^= x2; + p7 ^= x3; + sc->h[0x0] ^= p8; + sc->h[0x1] ^= p9; + sc->h[0x2] ^= pA; + sc->h[0x3] ^= pB; + sc->h[0x4] ^= pC; + sc->h[0x5] ^= pD; + sc->h[0x6] ^= pE; + sc->h[0x7] ^= pF; + sc->h[0x8] ^= p0; + sc->h[0x9] ^= p1; + sc->h[0xA] ^= p2; + sc->h[0xB] ^= p3; + sc->h[0xC] ^= p4; + sc->h[0xD] ^= p5; + sc->h[0xE] ^= p6; + sc->h[0xF] ^= p7; +} + +#endif + +static void +shavite_small_init(sph_shavite_small_context *sc, const sph_u32 *iv) +{ + memcpy(sc->h, iv, sizeof sc->h); + sc->ptr = 0; + sc->count0 = 0; + sc->count1 = 0; +} + +static void +shavite_small_core(sph_shavite_small_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + + buf = sc->buf; + ptr = sc->ptr; + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - ptr; + if (clen > len) + clen = len; + memcpy(buf + ptr, data, clen); + data = (const unsigned char *)data + clen; + ptr += clen; + len -= clen; + if (ptr == sizeof sc->buf) { + if ((sc->count0 = SPH_T32(sc->count0 + 512)) == 0) + sc->count1 = SPH_T32(sc->count1 + 1); + c256(sc, buf); + ptr = 0; + } + } + sc->ptr = ptr; +} + +static void +shavite_small_close(sph_shavite_small_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_size_w32) +{ + unsigned char *buf; + size_t ptr, u; + unsigned z; + sph_u32 count0, count1; + + buf = sc->buf; + ptr = sc->ptr; + count0 = (sc->count0 += (ptr << 3) + n); + count1 = sc->count1; + z = 0x80 >> n; + z = ((ub & -z) | z) & 0xFF; + if (ptr == 0 && n == 0) { + buf[0] = 0x80; + memset(buf + 1, 0, 53); + sc->count0 = sc->count1 = 0; + } else if (ptr < 54) { + buf[ptr ++] = z; + memset(buf + ptr, 0, 54 - ptr); + } else { + buf[ptr ++] = z; + memset(buf + ptr, 0, 64 - ptr); + c256(sc, buf); + memset(buf, 0, 54); + sc->count0 = sc->count1 = 0; + } + sph_enc32le(buf + 54, count0); + sph_enc32le(buf + 58, count1); + buf[62] = out_size_w32 << 5; + buf[63] = out_size_w32 >> 3; + c256(sc, buf); + for (u = 0; u < out_size_w32; u ++) + sph_enc32le((unsigned char *)dst + (u << 2), sc->h[u]); +} + +static void +shavite_big_init(sph_shavite_big_context *sc, const sph_u32 *iv) +{ + memcpy(sc->h, iv, sizeof sc->h); + sc->ptr = 0; + sc->count0 = 0; + sc->count1 = 0; + sc->count2 = 0; + sc->count3 = 0; +} + +static void +shavite_big_core(sph_shavite_big_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + + buf = sc->buf; + ptr = sc->ptr; + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - ptr; + if (clen > len) + clen = len; + memcpy(buf + ptr, data, clen); + data = (const unsigned char *)data + clen; + ptr += clen; + len -= clen; + if (ptr == sizeof sc->buf) { + if ((sc->count0 = SPH_T32(sc->count0 + 1024)) == 0) { + sc->count1 = SPH_T32(sc->count1 + 1); + if (sc->count1 == 0) { + sc->count2 = SPH_T32(sc->count2 + 1); + if (sc->count2 == 0) { + sc->count3 = SPH_T32( + sc->count3 + 1); + } + } + } + c512(sc, buf); + ptr = 0; + } + } + sc->ptr = ptr; +} + +static void +shavite_big_close(sph_shavite_big_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_size_w32) +{ + unsigned char *buf; + size_t ptr, u; + unsigned z; + sph_u32 count0, count1, count2, count3; + + buf = sc->buf; + ptr = sc->ptr; + count0 = (sc->count0 += (ptr << 3) + n); + count1 = sc->count1; + count2 = sc->count2; + count3 = sc->count3; + z = 0x80 >> n; + z = ((ub & -z) | z) & 0xFF; + if (ptr == 0 && n == 0) { + buf[0] = 0x80; + memset(buf + 1, 0, 109); + sc->count0 = sc->count1 = sc->count2 = sc->count3 = 0; + } else if (ptr < 110) { + buf[ptr ++] = z; + memset(buf + ptr, 0, 110 - ptr); + } else { + buf[ptr ++] = z; + memset(buf + ptr, 0, 128 - ptr); + c512(sc, buf); + memset(buf, 0, 110); + sc->count0 = sc->count1 = sc->count2 = sc->count3 = 0; + } + sph_enc32le(buf + 110, count0); + sph_enc32le(buf + 114, count1); + sph_enc32le(buf + 118, count2); + sph_enc32le(buf + 122, count3); + buf[126] = out_size_w32 << 5; + buf[127] = out_size_w32 >> 3; + c512(sc, buf); + for (u = 0; u < out_size_w32; u ++) + sph_enc32le((unsigned char *)dst + (u << 2), sc->h[u]); +} + +/* see sph_shavite.h */ +void +sph_shavite224_init(void *cc) +{ + shavite_small_init(cc, IV224); +} + +/* see sph_shavite.h */ +void +sph_shavite224(void *cc, const void *data, size_t len) +{ + shavite_small_core(cc, data, len); +} + +/* see sph_shavite.h */ +void +sph_shavite224_close(void *cc, void *dst) +{ + shavite_small_close(cc, 0, 0, dst, 7); + shavite_small_init(cc, IV224); +} + +/* see sph_shavite.h */ +void +sph_shavite224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shavite_small_close(cc, ub, n, dst, 7); + shavite_small_init(cc, IV224); +} + +/* see sph_shavite.h */ +void +sph_shavite256_init(void *cc) +{ + shavite_small_init(cc, IV256); +} + +/* see sph_shavite.h */ +void +sph_shavite256(void *cc, const void *data, size_t len) +{ + shavite_small_core(cc, data, len); +} + +/* see sph_shavite.h */ +void +sph_shavite256_close(void *cc, void *dst) +{ + shavite_small_close(cc, 0, 0, dst, 8); + shavite_small_init(cc, IV256); +} + +/* see sph_shavite.h */ +void +sph_shavite256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shavite_small_close(cc, ub, n, dst, 8); + shavite_small_init(cc, IV256); +} + +/* see sph_shavite.h */ +void +sph_shavite384_init(void *cc) +{ + shavite_big_init(cc, IV384); +} + +/* see sph_shavite.h */ +void +sph_shavite384(void *cc, const void *data, size_t len) +{ + shavite_big_core(cc, data, len); +} + +/* see sph_shavite.h */ +void +sph_shavite384_close(void *cc, void *dst) +{ + shavite_big_close(cc, 0, 0, dst, 12); + shavite_big_init(cc, IV384); +} + +/* see sph_shavite.h */ +void +sph_shavite384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shavite_big_close(cc, ub, n, dst, 12); + shavite_big_init(cc, IV384); +} + +/* see sph_shavite.h */ +void +sph_shavite512_init(void *cc) +{ + shavite_big_init(cc, IV512); +} + +/* see sph_shavite.h */ +void +sph_shavite512(void *cc, const void *data, size_t len) +{ + shavite_big_core(cc, data, len); +} + +/* see sph_shavite.h */ +void +sph_shavite512_close(void *cc, void *dst) +{ + shavite_big_close(cc, 0, 0, dst, 16); + shavite_big_init(cc, IV512); +} + +/* see sph_shavite.h */ +void +sph_shavite512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + shavite_big_close(cc, ub, n, dst, 16); + shavite_big_init(cc, IV512); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/simd.c b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/simd.c new file mode 100644 index 0000000..2c80626 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/simd.c @@ -0,0 +1,1799 @@ +/* $Id: simd.c 227 2010-06-16 17:28:38Z tp $ */ +/* + * SIMD implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include +#include +#include + +#include "sph_simd.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_SIMD +#define SPH_SMALL_FOOTPRINT_SIMD 1 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +typedef sph_u32 u32; +typedef sph_s32 s32; +#define C32 SPH_C32 +#define T32 SPH_T32 +#define ROL32 SPH_ROTL32 + +#define XCAT(x, y) XCAT_(x, y) +#define XCAT_(x, y) x ## y + +/* + * The powers of 41 modulo 257. We use exponents from 0 to 255, inclusive. + */ +static const s32 alpha_tab[] = { + 1, 41, 139, 45, 46, 87, 226, 14, 60, 147, 116, 130, + 190, 80, 196, 69, 2, 82, 21, 90, 92, 174, 195, 28, + 120, 37, 232, 3, 123, 160, 135, 138, 4, 164, 42, 180, + 184, 91, 133, 56, 240, 74, 207, 6, 246, 63, 13, 19, + 8, 71, 84, 103, 111, 182, 9, 112, 223, 148, 157, 12, + 235, 126, 26, 38, 16, 142, 168, 206, 222, 107, 18, 224, + 189, 39, 57, 24, 213, 252, 52, 76, 32, 27, 79, 155, + 187, 214, 36, 191, 121, 78, 114, 48, 169, 247, 104, 152, + 64, 54, 158, 53, 117, 171, 72, 125, 242, 156, 228, 96, + 81, 237, 208, 47, 128, 108, 59, 106, 234, 85, 144, 250, + 227, 55, 199, 192, 162, 217, 159, 94, 256, 216, 118, 212, + 211, 170, 31, 243, 197, 110, 141, 127, 67, 177, 61, 188, + 255, 175, 236, 167, 165, 83, 62, 229, 137, 220, 25, 254, + 134, 97, 122, 119, 253, 93, 215, 77, 73, 166, 124, 201, + 17, 183, 50, 251, 11, 194, 244, 238, 249, 186, 173, 154, + 146, 75, 248, 145, 34, 109, 100, 245, 22, 131, 231, 219, + 241, 115, 89, 51, 35, 150, 239, 33, 68, 218, 200, 233, + 44, 5, 205, 181, 225, 230, 178, 102, 70, 43, 221, 66, + 136, 179, 143, 209, 88, 10, 153, 105, 193, 203, 99, 204, + 140, 86, 185, 132, 15, 101, 29, 161, 176, 20, 49, 210, + 129, 149, 198, 151, 23, 172, 113, 7, 30, 202, 58, 65, + 95, 40, 98, 163 +}; + +/* + * Ranges: + * REDS1: from -32768..98302 to -383..383 + * REDS2: from -2^31..2^31-1 to -32768..98302 + */ +#define REDS1(x) (((x) & 0xFF) - ((x) >> 8)) +#define REDS2(x) (((x) & 0xFFFF) + ((x) >> 16)) + +/* + * If, upon entry, the values of q[] are all in the -N..N range (where + * N >= 98302) then the new values of q[] are in the -2N..2N range. + * + * Since alpha_tab[v] <= 256, maximum allowed range is for N = 8388608. + */ +#define FFT_LOOP(rb, hk, as, id) do { \ + size_t u, v; \ + s32 m = q[(rb)]; \ + s32 n = q[(rb) + (hk)]; \ + q[(rb)] = m + n; \ + q[(rb) + (hk)] = m - n; \ + u = v = 0; \ + goto id; \ + for (; u < (hk); u += 4, v += 4 * (as)) { \ + s32 t; \ + m = q[(rb) + u + 0]; \ + n = q[(rb) + u + 0 + (hk)]; \ + t = REDS2(n * alpha_tab[v + 0 * (as)]); \ + q[(rb) + u + 0] = m + t; \ + q[(rb) + u + 0 + (hk)] = m - t; \ + id: \ + m = q[(rb) + u + 1]; \ + n = q[(rb) + u + 1 + (hk)]; \ + t = REDS2(n * alpha_tab[v + 1 * (as)]); \ + q[(rb) + u + 1] = m + t; \ + q[(rb) + u + 1 + (hk)] = m - t; \ + m = q[(rb) + u + 2]; \ + n = q[(rb) + u + 2 + (hk)]; \ + t = REDS2(n * alpha_tab[v + 2 * (as)]); \ + q[(rb) + u + 2] = m + t; \ + q[(rb) + u + 2 + (hk)] = m - t; \ + m = q[(rb) + u + 3]; \ + n = q[(rb) + u + 3 + (hk)]; \ + t = REDS2(n * alpha_tab[v + 3 * (as)]); \ + q[(rb) + u + 3] = m + t; \ + q[(rb) + u + 3 + (hk)] = m - t; \ + } \ + } while (0) + +/* + * Output ranges: + * d0: min= 0 max= 1020 + * d1: min= -67 max= 4587 + * d2: min=-4335 max= 4335 + * d3: min=-4147 max= 507 + * d4: min= -510 max= 510 + * d5: min= -252 max= 4402 + * d6: min=-4335 max= 4335 + * d7: min=-4332 max= 322 + */ +#define FFT8(xb, xs, d) do { \ + s32 x0 = x[(xb)]; \ + s32 x1 = x[(xb) + (xs)]; \ + s32 x2 = x[(xb) + 2 * (xs)]; \ + s32 x3 = x[(xb) + 3 * (xs)]; \ + s32 a0 = x0 + x2; \ + s32 a1 = x0 + (x2 << 4); \ + s32 a2 = x0 - x2; \ + s32 a3 = x0 - (x2 << 4); \ + s32 b0 = x1 + x3; \ + s32 b1 = REDS1((x1 << 2) + (x3 << 6)); \ + s32 b2 = (x1 << 4) - (x3 << 4); \ + s32 b3 = REDS1((x1 << 6) + (x3 << 2)); \ + d ## 0 = a0 + b0; \ + d ## 1 = a1 + b1; \ + d ## 2 = a2 + b2; \ + d ## 3 = a3 + b3; \ + d ## 4 = a0 - b0; \ + d ## 5 = a1 - b1; \ + d ## 6 = a2 - b2; \ + d ## 7 = a3 - b3; \ + } while (0) + +/* + * When k=16, we have alpha=2. Multiplication by alpha^i is then reduced + * to some shifting. + * + * Output: within -591471..591723 + */ +#define FFT16(xb, xs, rb) do { \ + s32 d1_0, d1_1, d1_2, d1_3, d1_4, d1_5, d1_6, d1_7; \ + s32 d2_0, d2_1, d2_2, d2_3, d2_4, d2_5, d2_6, d2_7; \ + FFT8(xb, (xs) << 1, d1_); \ + FFT8((xb) + (xs), (xs) << 1, d2_); \ + q[(rb) + 0] = d1_0 + d2_0; \ + q[(rb) + 1] = d1_1 + (d2_1 << 1); \ + q[(rb) + 2] = d1_2 + (d2_2 << 2); \ + q[(rb) + 3] = d1_3 + (d2_3 << 3); \ + q[(rb) + 4] = d1_4 + (d2_4 << 4); \ + q[(rb) + 5] = d1_5 + (d2_5 << 5); \ + q[(rb) + 6] = d1_6 + (d2_6 << 6); \ + q[(rb) + 7] = d1_7 + (d2_7 << 7); \ + q[(rb) + 8] = d1_0 - d2_0; \ + q[(rb) + 9] = d1_1 - (d2_1 << 1); \ + q[(rb) + 10] = d1_2 - (d2_2 << 2); \ + q[(rb) + 11] = d1_3 - (d2_3 << 3); \ + q[(rb) + 12] = d1_4 - (d2_4 << 4); \ + q[(rb) + 13] = d1_5 - (d2_5 << 5); \ + q[(rb) + 14] = d1_6 - (d2_6 << 6); \ + q[(rb) + 15] = d1_7 - (d2_7 << 7); \ + } while (0) + +/* + * Output range: |q| <= 1183446 + */ +#define FFT32(xb, xs, rb, id) do { \ + FFT16(xb, (xs) << 1, rb); \ + FFT16((xb) + (xs), (xs) << 1, (rb) + 16); \ + FFT_LOOP(rb, 16, 8, id); \ + } while (0) + +/* + * Output range: |q| <= 2366892 + */ +#define FFT64(xb, xs, rb, id) do { \ + FFT32(xb, (xs) << 1, rb, XCAT(id, a)); \ + FFT32((xb) + (xs), (xs) << 1, (rb) + 32, XCAT(id, b)); \ + FFT_LOOP(rb, 32, 4, id); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_SIMD + +static void +fft32(unsigned char *x, size_t xs, s32 *q) +{ + size_t xd; + + xd = xs << 1; + FFT16(0, xd, 0); + FFT16(xs, xd, 16); + FFT_LOOP(0, 16, 8, label_); +} + +#define FFT128(xb, xs, rb, id) do { \ + fft32(x + (xb) + ((xs) * 0), (xs) << 2, &q[(rb) + 0]); \ + fft32(x + (xb) + ((xs) * 2), (xs) << 2, &q[(rb) + 32]); \ + FFT_LOOP(rb, 32, 4, XCAT(id, aa)); \ + fft32(x + (xb) + ((xs) * 1), (xs) << 2, &q[(rb) + 64]); \ + fft32(x + (xb) + ((xs) * 3), (xs) << 2, &q[(rb) + 96]); \ + FFT_LOOP((rb) + 64, 32, 4, XCAT(id, ab)); \ + FFT_LOOP(rb, 64, 2, XCAT(id, a)); \ + } while (0) + +#else + +/* + * Output range: |q| <= 4733784 + */ +#define FFT128(xb, xs, rb, id) do { \ + FFT64(xb, (xs) << 1, rb, XCAT(id, a)); \ + FFT64((xb) + (xs), (xs) << 1, (rb) + 64, XCAT(id, b)); \ + FFT_LOOP(rb, 64, 2, id); \ + } while (0) + +#endif + +/* + * For SIMD-384 / SIMD-512, the fully unrolled FFT yields a compression + * function which does not fit in the 32 kB L1 cache of a typical x86 + * Intel. We therefore add a function call layer at the FFT64 level. + */ + +static void +fft64(unsigned char *x, size_t xs, s32 *q) +{ + size_t xd; + + xd = xs << 1; + FFT32(0, xd, 0, label_a); + FFT32(xs, xd, 32, label_b); + FFT_LOOP(0, 32, 4, label_); +} + +/* + * Output range: |q| <= 9467568 + */ +#define FFT256(xb, xs, rb, id) do { \ + fft64(x + (xb) + ((xs) * 0), (xs) << 2, &q[(rb) + 0]); \ + fft64(x + (xb) + ((xs) * 2), (xs) << 2, &q[(rb) + 64]); \ + FFT_LOOP(rb, 64, 2, XCAT(id, aa)); \ + fft64(x + (xb) + ((xs) * 1), (xs) << 2, &q[(rb) + 128]); \ + fft64(x + (xb) + ((xs) * 3), (xs) << 2, &q[(rb) + 192]); \ + FFT_LOOP((rb) + 128, 64, 2, XCAT(id, ab)); \ + FFT_LOOP(rb, 128, 1, XCAT(id, a)); \ + } while (0) + +/* + * alpha^(127*i) mod 257 + */ +static const unsigned short yoff_s_n[] = { + 1, 98, 95, 58, 30, 113, 23, 198, 129, 49, 176, 29, + 15, 185, 140, 99, 193, 153, 88, 143, 136, 221, 70, 178, + 225, 205, 44, 200, 68, 239, 35, 89, 241, 231, 22, 100, + 34, 248, 146, 173, 249, 244, 11, 50, 17, 124, 73, 215, + 253, 122, 134, 25, 137, 62, 165, 236, 255, 61, 67, 141, + 197, 31, 211, 118, 256, 159, 162, 199, 227, 144, 234, 59, + 128, 208, 81, 228, 242, 72, 117, 158, 64, 104, 169, 114, + 121, 36, 187, 79, 32, 52, 213, 57, 189, 18, 222, 168, + 16, 26, 235, 157, 223, 9, 111, 84, 8, 13, 246, 207, + 240, 133, 184, 42, 4, 135, 123, 232, 120, 195, 92, 21, + 2, 196, 190, 116, 60, 226, 46, 139 +}; + +/* + * alpha^(127*i) + alpha^(125*i) mod 257 + */ +static const unsigned short yoff_s_f[] = { + 2, 156, 118, 107, 45, 212, 111, 162, 97, 249, 211, 3, + 49, 101, 151, 223, 189, 178, 253, 204, 76, 82, 232, 65, + 96, 176, 161, 47, 189, 61, 248, 107, 0, 131, 133, 113, + 17, 33, 12, 111, 251, 103, 57, 148, 47, 65, 249, 143, + 189, 8, 204, 230, 205, 151, 187, 227, 247, 111, 140, 6, + 77, 10, 21, 149, 255, 101, 139, 150, 212, 45, 146, 95, + 160, 8, 46, 254, 208, 156, 106, 34, 68, 79, 4, 53, + 181, 175, 25, 192, 161, 81, 96, 210, 68, 196, 9, 150, + 0, 126, 124, 144, 240, 224, 245, 146, 6, 154, 200, 109, + 210, 192, 8, 114, 68, 249, 53, 27, 52, 106, 70, 30, + 10, 146, 117, 251, 180, 247, 236, 108 +}; + +/* + * beta^(255*i) mod 257 + */ +static const unsigned short yoff_b_n[] = { + 1, 163, 98, 40, 95, 65, 58, 202, 30, 7, 113, 172, + 23, 151, 198, 149, 129, 210, 49, 20, 176, 161, 29, 101, + 15, 132, 185, 86, 140, 204, 99, 203, 193, 105, 153, 10, + 88, 209, 143, 179, 136, 66, 221, 43, 70, 102, 178, 230, + 225, 181, 205, 5, 44, 233, 200, 218, 68, 33, 239, 150, + 35, 51, 89, 115, 241, 219, 231, 131, 22, 245, 100, 109, + 34, 145, 248, 75, 146, 154, 173, 186, 249, 238, 244, 194, + 11, 251, 50, 183, 17, 201, 124, 166, 73, 77, 215, 93, + 253, 119, 122, 97, 134, 254, 25, 220, 137, 229, 62, 83, + 165, 167, 236, 175, 255, 188, 61, 177, 67, 127, 141, 110, + 197, 243, 31, 170, 211, 212, 118, 216, 256, 94, 159, 217, + 162, 192, 199, 55, 227, 250, 144, 85, 234, 106, 59, 108, + 128, 47, 208, 237, 81, 96, 228, 156, 242, 125, 72, 171, + 117, 53, 158, 54, 64, 152, 104, 247, 169, 48, 114, 78, + 121, 191, 36, 214, 187, 155, 79, 27, 32, 76, 52, 252, + 213, 24, 57, 39, 189, 224, 18, 107, 222, 206, 168, 142, + 16, 38, 26, 126, 235, 12, 157, 148, 223, 112, 9, 182, + 111, 103, 84, 71, 8, 19, 13, 63, 246, 6, 207, 74, + 240, 56, 133, 91, 184, 180, 42, 164, 4, 138, 135, 160, + 123, 3, 232, 37, 120, 28, 195, 174, 92, 90, 21, 82, + 2, 69, 196, 80, 190, 130, 116, 147, 60, 14, 226, 87, + 46, 45, 139, 41 +}; + +/* + * beta^(255*i) + beta^(253*i) mod 257 + */ +static const unsigned short yoff_b_f[] = { + 2, 203, 156, 47, 118, 214, 107, 106, 45, 93, 212, 20, + 111, 73, 162, 251, 97, 215, 249, 53, 211, 19, 3, 89, + 49, 207, 101, 67, 151, 130, 223, 23, 189, 202, 178, 239, + 253, 127, 204, 49, 76, 236, 82, 137, 232, 157, 65, 79, + 96, 161, 176, 130, 161, 30, 47, 9, 189, 247, 61, 226, + 248, 90, 107, 64, 0, 88, 131, 243, 133, 59, 113, 115, + 17, 236, 33, 213, 12, 191, 111, 19, 251, 61, 103, 208, + 57, 35, 148, 248, 47, 116, 65, 119, 249, 178, 143, 40, + 189, 129, 8, 163, 204, 227, 230, 196, 205, 122, 151, 45, + 187, 19, 227, 72, 247, 125, 111, 121, 140, 220, 6, 107, + 77, 69, 10, 101, 21, 65, 149, 171, 255, 54, 101, 210, + 139, 43, 150, 151, 212, 164, 45, 237, 146, 184, 95, 6, + 160, 42, 8, 204, 46, 238, 254, 168, 208, 50, 156, 190, + 106, 127, 34, 234, 68, 55, 79, 18, 4, 130, 53, 208, + 181, 21, 175, 120, 25, 100, 192, 178, 161, 96, 81, 127, + 96, 227, 210, 248, 68, 10, 196, 31, 9, 167, 150, 193, + 0, 169, 126, 14, 124, 198, 144, 142, 240, 21, 224, 44, + 245, 66, 146, 238, 6, 196, 154, 49, 200, 222, 109, 9, + 210, 141, 192, 138, 8, 79, 114, 217, 68, 128, 249, 94, + 53, 30, 27, 61, 52, 135, 106, 212, 70, 238, 30, 185, + 10, 132, 146, 136, 117, 37, 251, 150, 180, 188, 247, 156, + 236, 192, 108, 86 +}; + +#define INNER(l, h, mm) (((u32)((l) * (mm)) & 0xFFFFU) \ + + ((u32)((h) * (mm)) << 16)) + +#define W_SMALL(sb, o1, o2, mm) \ + (INNER(q[8 * (sb) + 2 * 0 + o1], q[8 * (sb) + 2 * 0 + o2], mm), \ + INNER(q[8 * (sb) + 2 * 1 + o1], q[8 * (sb) + 2 * 1 + o2], mm), \ + INNER(q[8 * (sb) + 2 * 2 + o1], q[8 * (sb) + 2 * 2 + o2], mm), \ + INNER(q[8 * (sb) + 2 * 3 + o1], q[8 * (sb) + 2 * 3 + o2], mm) + +#define WS_0_0 W_SMALL( 4, 0, 1, 185) +#define WS_0_1 W_SMALL( 6, 0, 1, 185) +#define WS_0_2 W_SMALL( 0, 0, 1, 185) +#define WS_0_3 W_SMALL( 2, 0, 1, 185) +#define WS_0_4 W_SMALL( 7, 0, 1, 185) +#define WS_0_5 W_SMALL( 5, 0, 1, 185) +#define WS_0_6 W_SMALL( 3, 0, 1, 185) +#define WS_0_7 W_SMALL( 1, 0, 1, 185) +#define WS_1_0 W_SMALL(15, 0, 1, 185) +#define WS_1_1 W_SMALL(11, 0, 1, 185) +#define WS_1_2 W_SMALL(12, 0, 1, 185) +#define WS_1_3 W_SMALL( 8, 0, 1, 185) +#define WS_1_4 W_SMALL( 9, 0, 1, 185) +#define WS_1_5 W_SMALL(13, 0, 1, 185) +#define WS_1_6 W_SMALL(10, 0, 1, 185) +#define WS_1_7 W_SMALL(14, 0, 1, 185) +#define WS_2_0 W_SMALL(17, -128, -64, 233) +#define WS_2_1 W_SMALL(18, -128, -64, 233) +#define WS_2_2 W_SMALL(23, -128, -64, 233) +#define WS_2_3 W_SMALL(20, -128, -64, 233) +#define WS_2_4 W_SMALL(22, -128, -64, 233) +#define WS_2_5 W_SMALL(21, -128, -64, 233) +#define WS_2_6 W_SMALL(16, -128, -64, 233) +#define WS_2_7 W_SMALL(19, -128, -64, 233) +#define WS_3_0 W_SMALL(30, -191, -127, 233) +#define WS_3_1 W_SMALL(24, -191, -127, 233) +#define WS_3_2 W_SMALL(25, -191, -127, 233) +#define WS_3_3 W_SMALL(31, -191, -127, 233) +#define WS_3_4 W_SMALL(27, -191, -127, 233) +#define WS_3_5 W_SMALL(29, -191, -127, 233) +#define WS_3_6 W_SMALL(28, -191, -127, 233) +#define WS_3_7 W_SMALL(26, -191, -127, 233) + +#define W_BIG(sb, o1, o2, mm) \ + (INNER(q[16 * (sb) + 2 * 0 + o1], q[16 * (sb) + 2 * 0 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 1 + o1], q[16 * (sb) + 2 * 1 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 2 + o1], q[16 * (sb) + 2 * 2 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 3 + o1], q[16 * (sb) + 2 * 3 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 4 + o1], q[16 * (sb) + 2 * 4 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 5 + o1], q[16 * (sb) + 2 * 5 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 6 + o1], q[16 * (sb) + 2 * 6 + o2], mm), \ + INNER(q[16 * (sb) + 2 * 7 + o1], q[16 * (sb) + 2 * 7 + o2], mm) + +#define WB_0_0 W_BIG( 4, 0, 1, 185) +#define WB_0_1 W_BIG( 6, 0, 1, 185) +#define WB_0_2 W_BIG( 0, 0, 1, 185) +#define WB_0_3 W_BIG( 2, 0, 1, 185) +#define WB_0_4 W_BIG( 7, 0, 1, 185) +#define WB_0_5 W_BIG( 5, 0, 1, 185) +#define WB_0_6 W_BIG( 3, 0, 1, 185) +#define WB_0_7 W_BIG( 1, 0, 1, 185) +#define WB_1_0 W_BIG(15, 0, 1, 185) +#define WB_1_1 W_BIG(11, 0, 1, 185) +#define WB_1_2 W_BIG(12, 0, 1, 185) +#define WB_1_3 W_BIG( 8, 0, 1, 185) +#define WB_1_4 W_BIG( 9, 0, 1, 185) +#define WB_1_5 W_BIG(13, 0, 1, 185) +#define WB_1_6 W_BIG(10, 0, 1, 185) +#define WB_1_7 W_BIG(14, 0, 1, 185) +#define WB_2_0 W_BIG(17, -256, -128, 233) +#define WB_2_1 W_BIG(18, -256, -128, 233) +#define WB_2_2 W_BIG(23, -256, -128, 233) +#define WB_2_3 W_BIG(20, -256, -128, 233) +#define WB_2_4 W_BIG(22, -256, -128, 233) +#define WB_2_5 W_BIG(21, -256, -128, 233) +#define WB_2_6 W_BIG(16, -256, -128, 233) +#define WB_2_7 W_BIG(19, -256, -128, 233) +#define WB_3_0 W_BIG(30, -383, -255, 233) +#define WB_3_1 W_BIG(24, -383, -255, 233) +#define WB_3_2 W_BIG(25, -383, -255, 233) +#define WB_3_3 W_BIG(31, -383, -255, 233) +#define WB_3_4 W_BIG(27, -383, -255, 233) +#define WB_3_5 W_BIG(29, -383, -255, 233) +#define WB_3_6 W_BIG(28, -383, -255, 233) +#define WB_3_7 W_BIG(26, -383, -255, 233) + +#define IF(x, y, z) ((((y) ^ (z)) & (x)) ^ (z)) +#define MAJ(x, y, z) (((x) & (y)) | (((x) | (y)) & (z))) + +#define PP4_0_0 1 +#define PP4_0_1 0 +#define PP4_0_2 3 +#define PP4_0_3 2 +#define PP4_1_0 2 +#define PP4_1_1 3 +#define PP4_1_2 0 +#define PP4_1_3 1 +#define PP4_2_0 3 +#define PP4_2_1 2 +#define PP4_2_2 1 +#define PP4_2_3 0 + +#define PP8_0_0 1 +#define PP8_0_1 0 +#define PP8_0_2 3 +#define PP8_0_3 2 +#define PP8_0_4 5 +#define PP8_0_5 4 +#define PP8_0_6 7 +#define PP8_0_7 6 + +#define PP8_1_0 6 +#define PP8_1_1 7 +#define PP8_1_2 4 +#define PP8_1_3 5 +#define PP8_1_4 2 +#define PP8_1_5 3 +#define PP8_1_6 0 +#define PP8_1_7 1 + +#define PP8_2_0 2 +#define PP8_2_1 3 +#define PP8_2_2 0 +#define PP8_2_3 1 +#define PP8_2_4 6 +#define PP8_2_5 7 +#define PP8_2_6 4 +#define PP8_2_7 5 + +#define PP8_3_0 3 +#define PP8_3_1 2 +#define PP8_3_2 1 +#define PP8_3_3 0 +#define PP8_3_4 7 +#define PP8_3_5 6 +#define PP8_3_6 5 +#define PP8_3_7 4 + +#define PP8_4_0 5 +#define PP8_4_1 4 +#define PP8_4_2 7 +#define PP8_4_3 6 +#define PP8_4_4 1 +#define PP8_4_5 0 +#define PP8_4_6 3 +#define PP8_4_7 2 + +#define PP8_5_0 7 +#define PP8_5_1 6 +#define PP8_5_2 5 +#define PP8_5_3 4 +#define PP8_5_4 3 +#define PP8_5_5 2 +#define PP8_5_6 1 +#define PP8_5_7 0 + +#define PP8_6_0 4 +#define PP8_6_1 5 +#define PP8_6_2 6 +#define PP8_6_3 7 +#define PP8_6_4 0 +#define PP8_6_5 1 +#define PP8_6_6 2 +#define PP8_6_7 3 + +#if SPH_SIMD_NOCOPY + +#define DECL_STATE_SMALL +#define READ_STATE_SMALL(sc) +#define WRITE_STATE_SMALL(sc) +#define DECL_STATE_BIG +#define READ_STATE_BIG(sc) +#define WRITE_STATE_BIG(sc) + +#else + +#define DECL_STATE_SMALL \ + u32 A0, A1, A2, A3, B0, B1, B2, B3, C0, C1, C2, C3, D0, D1, D2, D3; + +#define READ_STATE_SMALL(sc) do { \ + A0 = (sc)->state[ 0]; \ + A1 = (sc)->state[ 1]; \ + A2 = (sc)->state[ 2]; \ + A3 = (sc)->state[ 3]; \ + B0 = (sc)->state[ 4]; \ + B1 = (sc)->state[ 5]; \ + B2 = (sc)->state[ 6]; \ + B3 = (sc)->state[ 7]; \ + C0 = (sc)->state[ 8]; \ + C1 = (sc)->state[ 9]; \ + C2 = (sc)->state[10]; \ + C3 = (sc)->state[11]; \ + D0 = (sc)->state[12]; \ + D1 = (sc)->state[13]; \ + D2 = (sc)->state[14]; \ + D3 = (sc)->state[15]; \ + } while (0) + +#define WRITE_STATE_SMALL(sc) do { \ + (sc)->state[ 0] = A0; \ + (sc)->state[ 1] = A1; \ + (sc)->state[ 2] = A2; \ + (sc)->state[ 3] = A3; \ + (sc)->state[ 4] = B0; \ + (sc)->state[ 5] = B1; \ + (sc)->state[ 6] = B2; \ + (sc)->state[ 7] = B3; \ + (sc)->state[ 8] = C0; \ + (sc)->state[ 9] = C1; \ + (sc)->state[10] = C2; \ + (sc)->state[11] = C3; \ + (sc)->state[12] = D0; \ + (sc)->state[13] = D1; \ + (sc)->state[14] = D2; \ + (sc)->state[15] = D3; \ + } while (0) + +#define DECL_STATE_BIG \ + u32 A0, A1, A2, A3, A4, A5, A6, A7; \ + u32 B0, B1, B2, B3, B4, B5, B6, B7; \ + u32 C0, C1, C2, C3, C4, C5, C6, C7; \ + u32 D0, D1, D2, D3, D4, D5, D6, D7; + +#define READ_STATE_BIG(sc) do { \ + A0 = (sc)->state[ 0]; \ + A1 = (sc)->state[ 1]; \ + A2 = (sc)->state[ 2]; \ + A3 = (sc)->state[ 3]; \ + A4 = (sc)->state[ 4]; \ + A5 = (sc)->state[ 5]; \ + A6 = (sc)->state[ 6]; \ + A7 = (sc)->state[ 7]; \ + B0 = (sc)->state[ 8]; \ + B1 = (sc)->state[ 9]; \ + B2 = (sc)->state[10]; \ + B3 = (sc)->state[11]; \ + B4 = (sc)->state[12]; \ + B5 = (sc)->state[13]; \ + B6 = (sc)->state[14]; \ + B7 = (sc)->state[15]; \ + C0 = (sc)->state[16]; \ + C1 = (sc)->state[17]; \ + C2 = (sc)->state[18]; \ + C3 = (sc)->state[19]; \ + C4 = (sc)->state[20]; \ + C5 = (sc)->state[21]; \ + C6 = (sc)->state[22]; \ + C7 = (sc)->state[23]; \ + D0 = (sc)->state[24]; \ + D1 = (sc)->state[25]; \ + D2 = (sc)->state[26]; \ + D3 = (sc)->state[27]; \ + D4 = (sc)->state[28]; \ + D5 = (sc)->state[29]; \ + D6 = (sc)->state[30]; \ + D7 = (sc)->state[31]; \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + (sc)->state[ 0] = A0; \ + (sc)->state[ 1] = A1; \ + (sc)->state[ 2] = A2; \ + (sc)->state[ 3] = A3; \ + (sc)->state[ 4] = A4; \ + (sc)->state[ 5] = A5; \ + (sc)->state[ 6] = A6; \ + (sc)->state[ 7] = A7; \ + (sc)->state[ 8] = B0; \ + (sc)->state[ 9] = B1; \ + (sc)->state[10] = B2; \ + (sc)->state[11] = B3; \ + (sc)->state[12] = B4; \ + (sc)->state[13] = B5; \ + (sc)->state[14] = B6; \ + (sc)->state[15] = B7; \ + (sc)->state[16] = C0; \ + (sc)->state[17] = C1; \ + (sc)->state[18] = C2; \ + (sc)->state[19] = C3; \ + (sc)->state[20] = C4; \ + (sc)->state[21] = C5; \ + (sc)->state[22] = C6; \ + (sc)->state[23] = C7; \ + (sc)->state[24] = D0; \ + (sc)->state[25] = D1; \ + (sc)->state[26] = D2; \ + (sc)->state[27] = D3; \ + (sc)->state[28] = D4; \ + (sc)->state[29] = D5; \ + (sc)->state[30] = D6; \ + (sc)->state[31] = D7; \ + } while (0) + +#endif + +#define STEP_ELT(n, w, fun, s, ppb) do { \ + u32 tt = T32(D ## n + (w) + fun(A ## n, B ## n, C ## n)); \ + A ## n = T32(ROL32(tt, s) + XCAT(tA, XCAT(ppb, n))); \ + D ## n = C ## n; \ + C ## n = B ## n; \ + B ## n = tA ## n; \ + } while (0) + +#define STEP_SMALL(w0, w1, w2, w3, fun, r, s, pp4b) do { \ + u32 tA0 = ROL32(A0, r); \ + u32 tA1 = ROL32(A1, r); \ + u32 tA2 = ROL32(A2, r); \ + u32 tA3 = ROL32(A3, r); \ + STEP_ELT(0, w0, fun, s, pp4b); \ + STEP_ELT(1, w1, fun, s, pp4b); \ + STEP_ELT(2, w2, fun, s, pp4b); \ + STEP_ELT(3, w3, fun, s, pp4b); \ + } while (0) + +#define STEP_BIG(w0, w1, w2, w3, w4, w5, w6, w7, fun, r, s, pp8b) do { \ + u32 tA0 = ROL32(A0, r); \ + u32 tA1 = ROL32(A1, r); \ + u32 tA2 = ROL32(A2, r); \ + u32 tA3 = ROL32(A3, r); \ + u32 tA4 = ROL32(A4, r); \ + u32 tA5 = ROL32(A5, r); \ + u32 tA6 = ROL32(A6, r); \ + u32 tA7 = ROL32(A7, r); \ + STEP_ELT(0, w0, fun, s, pp8b); \ + STEP_ELT(1, w1, fun, s, pp8b); \ + STEP_ELT(2, w2, fun, s, pp8b); \ + STEP_ELT(3, w3, fun, s, pp8b); \ + STEP_ELT(4, w4, fun, s, pp8b); \ + STEP_ELT(5, w5, fun, s, pp8b); \ + STEP_ELT(6, w6, fun, s, pp8b); \ + STEP_ELT(7, w7, fun, s, pp8b); \ + } while (0) + +#define M3_0_0 0_ +#define M3_1_0 1_ +#define M3_2_0 2_ +#define M3_3_0 0_ +#define M3_4_0 1_ +#define M3_5_0 2_ +#define M3_6_0 0_ +#define M3_7_0 1_ + +#define M3_0_1 1_ +#define M3_1_1 2_ +#define M3_2_1 0_ +#define M3_3_1 1_ +#define M3_4_1 2_ +#define M3_5_1 0_ +#define M3_6_1 1_ +#define M3_7_1 2_ + +#define M3_0_2 2_ +#define M3_1_2 0_ +#define M3_2_2 1_ +#define M3_3_2 2_ +#define M3_4_2 0_ +#define M3_5_2 1_ +#define M3_6_2 2_ +#define M3_7_2 0_ + +#define STEP_SMALL_(w, fun, r, s, pp4b) STEP_SMALL w, fun, r, s, pp4b) + +#define ONE_ROUND_SMALL(ri, isp, p0, p1, p2, p3) do { \ + STEP_SMALL_(WS_ ## ri ## 0, \ + IF, p0, p1, XCAT(PP4_, M3_0_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 1, \ + IF, p1, p2, XCAT(PP4_, M3_1_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 2, \ + IF, p2, p3, XCAT(PP4_, M3_2_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 3, \ + IF, p3, p0, XCAT(PP4_, M3_3_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 4, \ + MAJ, p0, p1, XCAT(PP4_, M3_4_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 5, \ + MAJ, p1, p2, XCAT(PP4_, M3_5_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 6, \ + MAJ, p2, p3, XCAT(PP4_, M3_6_ ## isp)); \ + STEP_SMALL_(WS_ ## ri ## 7, \ + MAJ, p3, p0, XCAT(PP4_, M3_7_ ## isp)); \ + } while (0) + +#define M7_0_0 0_ +#define M7_1_0 1_ +#define M7_2_0 2_ +#define M7_3_0 3_ +#define M7_4_0 4_ +#define M7_5_0 5_ +#define M7_6_0 6_ +#define M7_7_0 0_ + +#define M7_0_1 1_ +#define M7_1_1 2_ +#define M7_2_1 3_ +#define M7_3_1 4_ +#define M7_4_1 5_ +#define M7_5_1 6_ +#define M7_6_1 0_ +#define M7_7_1 1_ + +#define M7_0_2 2_ +#define M7_1_2 3_ +#define M7_2_2 4_ +#define M7_3_2 5_ +#define M7_4_2 6_ +#define M7_5_2 0_ +#define M7_6_2 1_ +#define M7_7_2 2_ + +#define M7_0_3 3_ +#define M7_1_3 4_ +#define M7_2_3 5_ +#define M7_3_3 6_ +#define M7_4_3 0_ +#define M7_5_3 1_ +#define M7_6_3 2_ +#define M7_7_3 3_ + +#define STEP_BIG_(w, fun, r, s, pp8b) STEP_BIG w, fun, r, s, pp8b) + +#define ONE_ROUND_BIG(ri, isp, p0, p1, p2, p3) do { \ + STEP_BIG_(WB_ ## ri ## 0, \ + IF, p0, p1, XCAT(PP8_, M7_0_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 1, \ + IF, p1, p2, XCAT(PP8_, M7_1_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 2, \ + IF, p2, p3, XCAT(PP8_, M7_2_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 3, \ + IF, p3, p0, XCAT(PP8_, M7_3_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 4, \ + MAJ, p0, p1, XCAT(PP8_, M7_4_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 5, \ + MAJ, p1, p2, XCAT(PP8_, M7_5_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 6, \ + MAJ, p2, p3, XCAT(PP8_, M7_6_ ## isp)); \ + STEP_BIG_(WB_ ## ri ## 7, \ + MAJ, p3, p0, XCAT(PP8_, M7_7_ ## isp)); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_SIMD + +#define A0 state[ 0] +#define A1 state[ 1] +#define A2 state[ 2] +#define A3 state[ 3] +#define B0 state[ 4] +#define B1 state[ 5] +#define B2 state[ 6] +#define B3 state[ 7] +#define C0 state[ 8] +#define C1 state[ 9] +#define C2 state[10] +#define C3 state[11] +#define D0 state[12] +#define D1 state[13] +#define D2 state[14] +#define D3 state[15] + +#define STEP2_ELT(n, w, fun, s, ppb) do { \ + u32 tt = T32(D ## n + (w) + fun(A ## n, B ## n, C ## n)); \ + A ## n = T32(ROL32(tt, s) + tA[(ppb) ^ n]); \ + D ## n = C ## n; \ + C ## n = B ## n; \ + B ## n = tA[n]; \ + } while (0) + +#define STEP2_SMALL(w0, w1, w2, w3, fun, r, s, pp4b) do { \ + u32 tA[4]; \ + tA[0] = ROL32(A0, r); \ + tA[1] = ROL32(A1, r); \ + tA[2] = ROL32(A2, r); \ + tA[3] = ROL32(A3, r); \ + STEP2_ELT(0, w0, fun, s, pp4b); \ + STEP2_ELT(1, w1, fun, s, pp4b); \ + STEP2_ELT(2, w2, fun, s, pp4b); \ + STEP2_ELT(3, w3, fun, s, pp4b); \ + } while (0) + +static void +one_round_small(u32 *state, u32 *w, int isp, int p0, int p1, int p2, int p3) +{ + static const int pp4k[] = { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2 }; + + STEP2_SMALL(w[ 0], w[ 1], w[ 2], w[ 3], IF, p0, p1, pp4k[isp + 0]); + STEP2_SMALL(w[ 4], w[ 5], w[ 6], w[ 7], IF, p1, p2, pp4k[isp + 1]); + STEP2_SMALL(w[ 8], w[ 9], w[10], w[11], IF, p2, p3, pp4k[isp + 2]); + STEP2_SMALL(w[12], w[13], w[14], w[15], IF, p3, p0, pp4k[isp + 3]); + STEP2_SMALL(w[16], w[17], w[18], w[19], MAJ, p0, p1, pp4k[isp + 4]); + STEP2_SMALL(w[20], w[21], w[22], w[23], MAJ, p1, p2, pp4k[isp + 5]); + STEP2_SMALL(w[24], w[25], w[26], w[27], MAJ, p2, p3, pp4k[isp + 6]); + STEP2_SMALL(w[28], w[29], w[30], w[31], MAJ, p3, p0, pp4k[isp + 7]); +} + +static void +compress_small(sph_simd_small_context *sc, int last) +{ + unsigned char *x; + s32 q[128]; + int i; + u32 w[32]; + u32 state[16]; + size_t u; + + static const size_t wsp[32] = { + 4 << 3, 6 << 3, 0 << 3, 2 << 3, + 7 << 3, 5 << 3, 3 << 3, 1 << 3, + 15 << 3, 11 << 3, 12 << 3, 8 << 3, + 9 << 3, 13 << 3, 10 << 3, 14 << 3, + 17 << 3, 18 << 3, 23 << 3, 20 << 3, + 22 << 3, 21 << 3, 16 << 3, 19 << 3, + 30 << 3, 24 << 3, 25 << 3, 31 << 3, + 27 << 3, 29 << 3, 28 << 3, 26 << 3 + }; + + x = sc->buf; + FFT128(0, 1, 0, ll); + if (last) { + for (i = 0; i < 128; i ++) { + s32 tq; + + tq = q[i] + yoff_s_f[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (i = 0; i < 128; i ++) { + s32 tq; + + tq = q[i] + yoff_s_n[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + + for (i = 0; i < 16; i += 4) { + state[i + 0] = sc->state[i + 0] + ^ sph_dec32le_aligned(x + 4 * (i + 0)); + state[i + 1] = sc->state[i + 1] + ^ sph_dec32le_aligned(x + 4 * (i + 1)); + state[i + 2] = sc->state[i + 2] + ^ sph_dec32le_aligned(x + 4 * (i + 2)); + state[i + 3] = sc->state[i + 3] + ^ sph_dec32le_aligned(x + 4 * (i + 3)); + } + +#define WSREAD(sb, o1, o2, mm) do { \ + for (u = 0; u < 32; u += 4) { \ + size_t v = wsp[(u >> 2) + (sb)]; \ + w[u + 0] = INNER(q[v + 2 * 0 + (o1)], \ + q[v + 2 * 0 + (o2)], mm); \ + w[u + 1] = INNER(q[v + 2 * 1 + (o1)], \ + q[v + 2 * 1 + (o2)], mm); \ + w[u + 2] = INNER(q[v + 2 * 2 + (o1)], \ + q[v + 2 * 2 + (o2)], mm); \ + w[u + 3] = INNER(q[v + 2 * 3 + (o1)], \ + q[v + 2 * 3 + (o2)], mm); \ + } \ + } while (0) + + WSREAD( 0, 0, 1, 185); + one_round_small(state, w, 0, 3, 23, 17, 27); + WSREAD( 8, 0, 1, 185); + one_round_small(state, w, 2, 28, 19, 22, 7); + WSREAD(16, -128, -64, 233); + one_round_small(state, w, 1, 29, 9, 15, 5); + WSREAD(24, -191, -127, 233); + one_round_small(state, w, 0, 4, 13, 10, 25); + +#undef WSREAD + + STEP_SMALL(sc->state[ 0], sc->state[ 1], sc->state[ 2], sc->state[ 3], + IF, 4, 13, PP4_2_); + STEP_SMALL(sc->state[ 4], sc->state[ 5], sc->state[ 6], sc->state[ 7], + IF, 13, 10, PP4_0_); + STEP_SMALL(sc->state[ 8], sc->state[ 9], sc->state[10], sc->state[11], + IF, 10, 25, PP4_1_); + STEP_SMALL(sc->state[12], sc->state[13], sc->state[14], sc->state[15], + IF, 25, 4, PP4_2_); + + memcpy(sc->state, state, sizeof state); +} + +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef B0 +#undef B1 +#undef B2 +#undef B3 +#undef C0 +#undef C1 +#undef C2 +#undef C3 +#undef D0 +#undef D1 +#undef D2 +#undef D3 + +#else + +#if SPH_SIMD_NOCOPY +#define A0 (sc->state[ 0]) +#define A1 (sc->state[ 1]) +#define A2 (sc->state[ 2]) +#define A3 (sc->state[ 3]) +#define B0 (sc->state[ 4]) +#define B1 (sc->state[ 5]) +#define B2 (sc->state[ 6]) +#define B3 (sc->state[ 7]) +#define C0 (sc->state[ 8]) +#define C1 (sc->state[ 9]) +#define C2 (sc->state[10]) +#define C3 (sc->state[11]) +#define D0 (sc->state[12]) +#define D1 (sc->state[13]) +#define D2 (sc->state[14]) +#define D3 (sc->state[15]) +#endif + +static void +compress_small(sph_simd_small_context *sc, int last) +{ + unsigned char *x; + s32 q[128]; + int i; + DECL_STATE_SMALL +#if SPH_SIMD_NOCOPY + sph_u32 saved[16]; +#endif + +#if SPH_SIMD_NOCOPY + memcpy(saved, sc->state, sizeof saved); +#endif + x = sc->buf; + FFT128(0, 1, 0, ll); + if (last) { + for (i = 0; i < 128; i ++) { + s32 tq; + + tq = q[i] + yoff_s_f[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (i = 0; i < 128; i ++) { + s32 tq; + + tq = q[i] + yoff_s_n[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + READ_STATE_SMALL(sc); + A0 ^= sph_dec32le_aligned(x + 0); + A1 ^= sph_dec32le_aligned(x + 4); + A2 ^= sph_dec32le_aligned(x + 8); + A3 ^= sph_dec32le_aligned(x + 12); + B0 ^= sph_dec32le_aligned(x + 16); + B1 ^= sph_dec32le_aligned(x + 20); + B2 ^= sph_dec32le_aligned(x + 24); + B3 ^= sph_dec32le_aligned(x + 28); + C0 ^= sph_dec32le_aligned(x + 32); + C1 ^= sph_dec32le_aligned(x + 36); + C2 ^= sph_dec32le_aligned(x + 40); + C3 ^= sph_dec32le_aligned(x + 44); + D0 ^= sph_dec32le_aligned(x + 48); + D1 ^= sph_dec32le_aligned(x + 52); + D2 ^= sph_dec32le_aligned(x + 56); + D3 ^= sph_dec32le_aligned(x + 60); + ONE_ROUND_SMALL(0_, 0, 3, 23, 17, 27); + ONE_ROUND_SMALL(1_, 2, 28, 19, 22, 7); + ONE_ROUND_SMALL(2_, 1, 29, 9, 15, 5); + ONE_ROUND_SMALL(3_, 0, 4, 13, 10, 25); +#if SPH_SIMD_NOCOPY + STEP_SMALL(saved[ 0], saved[ 1], saved[ 2], saved[ 3], + IF, 4, 13, PP4_2_); + STEP_SMALL(saved[ 4], saved[ 5], saved[ 6], saved[ 7], + IF, 13, 10, PP4_0_); + STEP_SMALL(saved[ 8], saved[ 9], saved[10], saved[11], + IF, 10, 25, PP4_1_); + STEP_SMALL(saved[12], saved[13], saved[14], saved[15], + IF, 25, 4, PP4_2_); +#else + STEP_SMALL(sc->state[ 0], sc->state[ 1], sc->state[ 2], sc->state[ 3], + IF, 4, 13, PP4_2_); + STEP_SMALL(sc->state[ 4], sc->state[ 5], sc->state[ 6], sc->state[ 7], + IF, 13, 10, PP4_0_); + STEP_SMALL(sc->state[ 8], sc->state[ 9], sc->state[10], sc->state[11], + IF, 10, 25, PP4_1_); + STEP_SMALL(sc->state[12], sc->state[13], sc->state[14], sc->state[15], + IF, 25, 4, PP4_2_); + WRITE_STATE_SMALL(sc); +#endif +} + +#if SPH_SIMD_NOCOPY +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef B0 +#undef B1 +#undef B2 +#undef B3 +#undef C0 +#undef C1 +#undef C2 +#undef C3 +#undef D0 +#undef D1 +#undef D2 +#undef D3 +#endif + +#endif + +#if SPH_SMALL_FOOTPRINT_SIMD + +#define A0 state[ 0] +#define A1 state[ 1] +#define A2 state[ 2] +#define A3 state[ 3] +#define A4 state[ 4] +#define A5 state[ 5] +#define A6 state[ 6] +#define A7 state[ 7] +#define B0 state[ 8] +#define B1 state[ 9] +#define B2 state[10] +#define B3 state[11] +#define B4 state[12] +#define B5 state[13] +#define B6 state[14] +#define B7 state[15] +#define C0 state[16] +#define C1 state[17] +#define C2 state[18] +#define C3 state[19] +#define C4 state[20] +#define C5 state[21] +#define C6 state[22] +#define C7 state[23] +#define D0 state[24] +#define D1 state[25] +#define D2 state[26] +#define D3 state[27] +#define D4 state[28] +#define D5 state[29] +#define D6 state[30] +#define D7 state[31] + +/* + * Not needed -- already defined for SIMD-224 / SIMD-256 + * +#define STEP2_ELT(n, w, fun, s, ppb) do { \ + u32 tt = T32(D ## n + (w) + fun(A ## n, B ## n, C ## n)); \ + A ## n = T32(ROL32(tt, s) + tA[(ppb) ^ n]); \ + D ## n = C ## n; \ + C ## n = B ## n; \ + B ## n = tA[n]; \ + } while (0) + */ + +#define STEP2_BIG(w0, w1, w2, w3, w4, w5, w6, w7, fun, r, s, pp8b) do { \ + u32 tA[8]; \ + tA[0] = ROL32(A0, r); \ + tA[1] = ROL32(A1, r); \ + tA[2] = ROL32(A2, r); \ + tA[3] = ROL32(A3, r); \ + tA[4] = ROL32(A4, r); \ + tA[5] = ROL32(A5, r); \ + tA[6] = ROL32(A6, r); \ + tA[7] = ROL32(A7, r); \ + STEP2_ELT(0, w0, fun, s, pp8b); \ + STEP2_ELT(1, w1, fun, s, pp8b); \ + STEP2_ELT(2, w2, fun, s, pp8b); \ + STEP2_ELT(3, w3, fun, s, pp8b); \ + STEP2_ELT(4, w4, fun, s, pp8b); \ + STEP2_ELT(5, w5, fun, s, pp8b); \ + STEP2_ELT(6, w6, fun, s, pp8b); \ + STEP2_ELT(7, w7, fun, s, pp8b); \ + } while (0) + +static void +one_round_big(u32 *state, u32 *w, int isp, int p0, int p1, int p2, int p3) +{ + static const int pp8k[] = { 1, 6, 2, 3, 5, 7, 4, 1, 6, 2, 3 }; + + STEP2_BIG(w[ 0], w[ 1], w[ 2], w[ 3], w[ 4], w[ 5], w[ 6], w[ 7], + IF, p0, p1, pp8k[isp + 0]); + STEP2_BIG(w[ 8], w[ 9], w[10], w[11], w[12], w[13], w[14], w[15], + IF, p1, p2, pp8k[isp + 1]); + STEP2_BIG(w[16], w[17], w[18], w[19], w[20], w[21], w[22], w[23], + IF, p2, p3, pp8k[isp + 2]); + STEP2_BIG(w[24], w[25], w[26], w[27], w[28], w[29], w[30], w[31], + IF, p3, p0, pp8k[isp + 3]); + STEP2_BIG(w[32], w[33], w[34], w[35], w[36], w[37], w[38], w[39], + MAJ, p0, p1, pp8k[isp + 4]); + STEP2_BIG(w[40], w[41], w[42], w[43], w[44], w[45], w[46], w[47], + MAJ, p1, p2, pp8k[isp + 5]); + STEP2_BIG(w[48], w[49], w[50], w[51], w[52], w[53], w[54], w[55], + MAJ, p2, p3, pp8k[isp + 6]); + STEP2_BIG(w[56], w[57], w[58], w[59], w[60], w[61], w[62], w[63], + MAJ, p3, p0, pp8k[isp + 7]); +} + +static void +compress_big(sph_simd_big_context *sc, int last) +{ + unsigned char *x; + s32 q[256]; + int i; + u32 w[64]; + u32 state[32]; + size_t u; + + static const size_t wbp[32] = { + 4 << 4, 6 << 4, 0 << 4, 2 << 4, + 7 << 4, 5 << 4, 3 << 4, 1 << 4, + 15 << 4, 11 << 4, 12 << 4, 8 << 4, + 9 << 4, 13 << 4, 10 << 4, 14 << 4, + 17 << 4, 18 << 4, 23 << 4, 20 << 4, + 22 << 4, 21 << 4, 16 << 4, 19 << 4, + 30 << 4, 24 << 4, 25 << 4, 31 << 4, + 27 << 4, 29 << 4, 28 << 4, 26 << 4 + }; + + x = sc->buf; + FFT256(0, 1, 0, ll); + if (last) { + for (i = 0; i < 256; i ++) { + s32 tq; + + tq = q[i] + yoff_b_f[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (i = 0; i < 256; i ++) { + s32 tq; + + tq = q[i] + yoff_b_n[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + + for (i = 0; i < 32; i += 8) { + state[i + 0] = sc->state[i + 0] + ^ sph_dec32le_aligned(x + 4 * (i + 0)); + state[i + 1] = sc->state[i + 1] + ^ sph_dec32le_aligned(x + 4 * (i + 1)); + state[i + 2] = sc->state[i + 2] + ^ sph_dec32le_aligned(x + 4 * (i + 2)); + state[i + 3] = sc->state[i + 3] + ^ sph_dec32le_aligned(x + 4 * (i + 3)); + state[i + 4] = sc->state[i + 4] + ^ sph_dec32le_aligned(x + 4 * (i + 4)); + state[i + 5] = sc->state[i + 5] + ^ sph_dec32le_aligned(x + 4 * (i + 5)); + state[i + 6] = sc->state[i + 6] + ^ sph_dec32le_aligned(x + 4 * (i + 6)); + state[i + 7] = sc->state[i + 7] + ^ sph_dec32le_aligned(x + 4 * (i + 7)); + } + +#define WBREAD(sb, o1, o2, mm) do { \ + for (u = 0; u < 64; u += 8) { \ + size_t v = wbp[(u >> 3) + (sb)]; \ + w[u + 0] = INNER(q[v + 2 * 0 + (o1)], \ + q[v + 2 * 0 + (o2)], mm); \ + w[u + 1] = INNER(q[v + 2 * 1 + (o1)], \ + q[v + 2 * 1 + (o2)], mm); \ + w[u + 2] = INNER(q[v + 2 * 2 + (o1)], \ + q[v + 2 * 2 + (o2)], mm); \ + w[u + 3] = INNER(q[v + 2 * 3 + (o1)], \ + q[v + 2 * 3 + (o2)], mm); \ + w[u + 4] = INNER(q[v + 2 * 4 + (o1)], \ + q[v + 2 * 4 + (o2)], mm); \ + w[u + 5] = INNER(q[v + 2 * 5 + (o1)], \ + q[v + 2 * 5 + (o2)], mm); \ + w[u + 6] = INNER(q[v + 2 * 6 + (o1)], \ + q[v + 2 * 6 + (o2)], mm); \ + w[u + 7] = INNER(q[v + 2 * 7 + (o1)], \ + q[v + 2 * 7 + (o2)], mm); \ + } \ + } while (0) + + WBREAD( 0, 0, 1, 185); + one_round_big(state, w, 0, 3, 23, 17, 27); + WBREAD( 8, 0, 1, 185); + one_round_big(state, w, 1, 28, 19, 22, 7); + WBREAD(16, -256, -128, 233); + one_round_big(state, w, 2, 29, 9, 15, 5); + WBREAD(24, -383, -255, 233); + one_round_big(state, w, 3, 4, 13, 10, 25); + +#undef WBREAD + + STEP_BIG( + sc->state[ 0], sc->state[ 1], sc->state[ 2], sc->state[ 3], + sc->state[ 4], sc->state[ 5], sc->state[ 6], sc->state[ 7], + IF, 4, 13, PP8_4_); + STEP_BIG( + sc->state[ 8], sc->state[ 9], sc->state[10], sc->state[11], + sc->state[12], sc->state[13], sc->state[14], sc->state[15], + IF, 13, 10, PP8_5_); + STEP_BIG( + sc->state[16], sc->state[17], sc->state[18], sc->state[19], + sc->state[20], sc->state[21], sc->state[22], sc->state[23], + IF, 10, 25, PP8_6_); + STEP_BIG( + sc->state[24], sc->state[25], sc->state[26], sc->state[27], + sc->state[28], sc->state[29], sc->state[30], sc->state[31], + IF, 25, 4, PP8_0_); + + memcpy(sc->state, state, sizeof state); +} + +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef A4 +#undef A5 +#undef A6 +#undef A7 +#undef B0 +#undef B1 +#undef B2 +#undef B3 +#undef B4 +#undef B5 +#undef B6 +#undef B7 +#undef C0 +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#undef D0 +#undef D1 +#undef D2 +#undef D3 +#undef D4 +#undef D5 +#undef D6 +#undef D7 + +#else + +#if SPH_SIMD_NOCOPY +#define A0 (sc->state[ 0]) +#define A1 (sc->state[ 1]) +#define A2 (sc->state[ 2]) +#define A3 (sc->state[ 3]) +#define A4 (sc->state[ 4]) +#define A5 (sc->state[ 5]) +#define A6 (sc->state[ 6]) +#define A7 (sc->state[ 7]) +#define B0 (sc->state[ 8]) +#define B1 (sc->state[ 9]) +#define B2 (sc->state[10]) +#define B3 (sc->state[11]) +#define B4 (sc->state[12]) +#define B5 (sc->state[13]) +#define B6 (sc->state[14]) +#define B7 (sc->state[15]) +#define C0 (sc->state[16]) +#define C1 (sc->state[17]) +#define C2 (sc->state[18]) +#define C3 (sc->state[19]) +#define C4 (sc->state[20]) +#define C5 (sc->state[21]) +#define C6 (sc->state[22]) +#define C7 (sc->state[23]) +#define D0 (sc->state[24]) +#define D1 (sc->state[25]) +#define D2 (sc->state[26]) +#define D3 (sc->state[27]) +#define D4 (sc->state[28]) +#define D5 (sc->state[29]) +#define D6 (sc->state[30]) +#define D7 (sc->state[31]) +#endif + +static void +compress_big(sph_simd_big_context *sc, int last) +{ + unsigned char *x; + s32 q[256]; + int i; + DECL_STATE_BIG +#if SPH_SIMD_NOCOPY + sph_u32 saved[32]; +#endif + +#if SPH_SIMD_NOCOPY + memcpy(saved, sc->state, sizeof saved); +#endif + + x = sc->buf; + FFT256(0, 1, 0, ll); + if (last) { + for (i = 0; i < 256; i ++) { + s32 tq; + + tq = q[i] + yoff_b_f[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (i = 0; i < 256; i ++) { + s32 tq; + + tq = q[i] + yoff_b_n[i]; + tq = REDS2(tq); + tq = REDS1(tq); + tq = REDS1(tq); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + READ_STATE_BIG(sc); + A0 ^= sph_dec32le_aligned(x + 0); + A1 ^= sph_dec32le_aligned(x + 4); + A2 ^= sph_dec32le_aligned(x + 8); + A3 ^= sph_dec32le_aligned(x + 12); + A4 ^= sph_dec32le_aligned(x + 16); + A5 ^= sph_dec32le_aligned(x + 20); + A6 ^= sph_dec32le_aligned(x + 24); + A7 ^= sph_dec32le_aligned(x + 28); + B0 ^= sph_dec32le_aligned(x + 32); + B1 ^= sph_dec32le_aligned(x + 36); + B2 ^= sph_dec32le_aligned(x + 40); + B3 ^= sph_dec32le_aligned(x + 44); + B4 ^= sph_dec32le_aligned(x + 48); + B5 ^= sph_dec32le_aligned(x + 52); + B6 ^= sph_dec32le_aligned(x + 56); + B7 ^= sph_dec32le_aligned(x + 60); + C0 ^= sph_dec32le_aligned(x + 64); + C1 ^= sph_dec32le_aligned(x + 68); + C2 ^= sph_dec32le_aligned(x + 72); + C3 ^= sph_dec32le_aligned(x + 76); + C4 ^= sph_dec32le_aligned(x + 80); + C5 ^= sph_dec32le_aligned(x + 84); + C6 ^= sph_dec32le_aligned(x + 88); + C7 ^= sph_dec32le_aligned(x + 92); + D0 ^= sph_dec32le_aligned(x + 96); + D1 ^= sph_dec32le_aligned(x + 100); + D2 ^= sph_dec32le_aligned(x + 104); + D3 ^= sph_dec32le_aligned(x + 108); + D4 ^= sph_dec32le_aligned(x + 112); + D5 ^= sph_dec32le_aligned(x + 116); + D6 ^= sph_dec32le_aligned(x + 120); + D7 ^= sph_dec32le_aligned(x + 124); + + ONE_ROUND_BIG(0_, 0, 3, 23, 17, 27); + ONE_ROUND_BIG(1_, 1, 28, 19, 22, 7); + ONE_ROUND_BIG(2_, 2, 29, 9, 15, 5); + ONE_ROUND_BIG(3_, 3, 4, 13, 10, 25); +#if SPH_SIMD_NOCOPY + STEP_BIG( + saved[ 0], saved[ 1], saved[ 2], saved[ 3], + saved[ 4], saved[ 5], saved[ 6], saved[ 7], + IF, 4, 13, PP8_4_); + STEP_BIG( + saved[ 8], saved[ 9], saved[10], saved[11], + saved[12], saved[13], saved[14], saved[15], + IF, 13, 10, PP8_5_); + STEP_BIG( + saved[16], saved[17], saved[18], saved[19], + saved[20], saved[21], saved[22], saved[23], + IF, 10, 25, PP8_6_); + STEP_BIG( + saved[24], saved[25], saved[26], saved[27], + saved[28], saved[29], saved[30], saved[31], + IF, 25, 4, PP8_0_); +#else + STEP_BIG( + sc->state[ 0], sc->state[ 1], sc->state[ 2], sc->state[ 3], + sc->state[ 4], sc->state[ 5], sc->state[ 6], sc->state[ 7], + IF, 4, 13, PP8_4_); + STEP_BIG( + sc->state[ 8], sc->state[ 9], sc->state[10], sc->state[11], + sc->state[12], sc->state[13], sc->state[14], sc->state[15], + IF, 13, 10, PP8_5_); + STEP_BIG( + sc->state[16], sc->state[17], sc->state[18], sc->state[19], + sc->state[20], sc->state[21], sc->state[22], sc->state[23], + IF, 10, 25, PP8_6_); + STEP_BIG( + sc->state[24], sc->state[25], sc->state[26], sc->state[27], + sc->state[28], sc->state[29], sc->state[30], sc->state[31], + IF, 25, 4, PP8_0_); + WRITE_STATE_BIG(sc); +#endif +} + +#if SPH_SIMD_NOCOPY +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef A4 +#undef A5 +#undef A6 +#undef A7 +#undef B0 +#undef B1 +#undef B2 +#undef B3 +#undef B4 +#undef B5 +#undef B6 +#undef B7 +#undef C0 +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#undef D0 +#undef D1 +#undef D2 +#undef D3 +#undef D4 +#undef D5 +#undef D6 +#undef D7 +#endif + +#endif + +static const u32 IV224[] = { + C32(0x33586E9F), C32(0x12FFF033), C32(0xB2D9F64D), C32(0x6F8FEA53), + C32(0xDE943106), C32(0x2742E439), C32(0x4FBAB5AC), C32(0x62B9FF96), + C32(0x22E7B0AF), C32(0xC862B3A8), C32(0x33E00CDC), C32(0x236B86A6), + C32(0xF64AE77C), C32(0xFA373B76), C32(0x7DC1EE5B), C32(0x7FB29CE8) +}; + +static const u32 IV256[] = { + C32(0x4D567983), C32(0x07190BA9), C32(0x8474577B), C32(0x39D726E9), + C32(0xAAF3D925), C32(0x3EE20B03), C32(0xAFD5E751), C32(0xC96006D3), + C32(0xC2C2BA14), C32(0x49B3BCB4), C32(0xF67CAF46), C32(0x668626C9), + C32(0xE2EAA8D2), C32(0x1FF47833), C32(0xD0C661A5), C32(0x55693DE1) +}; + +static const u32 IV384[] = { + C32(0x8A36EEBC), C32(0x94A3BD90), C32(0xD1537B83), C32(0xB25B070B), + C32(0xF463F1B5), C32(0xB6F81E20), C32(0x0055C339), C32(0xB4D144D1), + C32(0x7360CA61), C32(0x18361A03), C32(0x17DCB4B9), C32(0x3414C45A), + C32(0xA699A9D2), C32(0xE39E9664), C32(0x468BFE77), C32(0x51D062F8), + C32(0xB9E3BFE8), C32(0x63BECE2A), C32(0x8FE506B9), C32(0xF8CC4AC2), + C32(0x7AE11542), C32(0xB1AADDA1), C32(0x64B06794), C32(0x28D2F462), + C32(0xE64071EC), C32(0x1DEB91A8), C32(0x8AC8DB23), C32(0x3F782AB5), + C32(0x039B5CB8), C32(0x71DDD962), C32(0xFADE2CEA), C32(0x1416DF71) +}; + +static const u32 IV512[] = { + C32(0x0BA16B95), C32(0x72F999AD), C32(0x9FECC2AE), C32(0xBA3264FC), + C32(0x5E894929), C32(0x8E9F30E5), C32(0x2F1DAA37), C32(0xF0F2C558), + C32(0xAC506643), C32(0xA90635A5), C32(0xE25B878B), C32(0xAAB7878F), + C32(0x88817F7A), C32(0x0A02892B), C32(0x559A7550), C32(0x598F657E), + C32(0x7EEF60A1), C32(0x6B70E3E8), C32(0x9C1714D1), C32(0xB958E2A8), + C32(0xAB02675E), C32(0xED1C014F), C32(0xCD8D65BB), C32(0xFDB7A257), + C32(0x09254899), C32(0xD699C7BC), C32(0x9019B6DC), C32(0x2B9022E4), + C32(0x8FA14956), C32(0x21BF9BD3), C32(0xB94D0943), C32(0x6FFDDC22) +}; + +static void +init_small(void *cc, const u32 *iv) +{ + sph_simd_small_context *sc; + + sc = cc; + memcpy(sc->state, iv, sizeof sc->state); + sc->count_low = sc->count_high = 0; + sc->ptr = 0; +} + +static void +init_big(void *cc, const u32 *iv) +{ + sph_simd_big_context *sc; + + sc = cc; + memcpy(sc->state, iv, sizeof sc->state); + sc->count_low = sc->count_high = 0; + sc->ptr = 0; +} + +static void +update_small(void *cc, const void *data, size_t len) +{ + sph_simd_small_context *sc; + + sc = cc; + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - sc->ptr; + if (clen > len) + clen = len; + memcpy(sc->buf + sc->ptr, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + if ((sc->ptr += clen) == sizeof sc->buf) { + compress_small(sc, 0); + sc->ptr = 0; + sc->count_low = T32(sc->count_low + 1); + if (sc->count_low == 0) + sc->count_high ++; + } + } +} + +static void +update_big(void *cc, const void *data, size_t len) +{ + sph_simd_big_context *sc; + + sc = cc; + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - sc->ptr; + if (clen > len) + clen = len; + memcpy(sc->buf + sc->ptr, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + if ((sc->ptr += clen) == sizeof sc->buf) { + compress_big(sc, 0); + sc->ptr = 0; + sc->count_low = T32(sc->count_low + 1); + if (sc->count_low == 0) + sc->count_high ++; + } + } +} + +static void +encode_count_small(unsigned char *dst, + u32 low, u32 high, size_t ptr, unsigned n) +{ + low = T32(low << 9); + high = T32(high << 9) + (low >> 23); + low += (ptr << 3) + n; + sph_enc32le(dst, low); + sph_enc32le(dst + 4, high); +} + +static void +encode_count_big(unsigned char *dst, + u32 low, u32 high, size_t ptr, unsigned n) +{ + low = T32(low << 10); + high = T32(high << 10) + (low >> 22); + low += (ptr << 3) + n; + sph_enc32le(dst, low); + sph_enc32le(dst + 4, high); +} + +static void +finalize_small(void *cc, unsigned ub, unsigned n, void *dst, size_t dst_len) +{ + sph_simd_small_context *sc; + unsigned char *d; + size_t u; + + sc = cc; + if (sc->ptr > 0 || n > 0) { + memset(sc->buf + sc->ptr, 0, + (sizeof sc->buf) - sc->ptr); + sc->buf[sc->ptr] = ub & (0xFF << (8 - n)); + compress_small(sc, 0); + } + memset(sc->buf, 0, sizeof sc->buf); + encode_count_small(sc->buf, sc->count_low, sc->count_high, sc->ptr, n); + compress_small(sc, 1); + d = dst; + for (d = dst, u = 0; u < dst_len; u ++) + sph_enc32le(d + (u << 2), sc->state[u]); +} + +static void +finalize_big(void *cc, unsigned ub, unsigned n, void *dst, size_t dst_len) +{ + sph_simd_big_context *sc; + unsigned char *d; + size_t u; + + sc = cc; + if (sc->ptr > 0 || n > 0) { + memset(sc->buf + sc->ptr, 0, + (sizeof sc->buf) - sc->ptr); + sc->buf[sc->ptr] = ub & (0xFF << (8 - n)); + compress_big(sc, 0); + } + memset(sc->buf, 0, sizeof sc->buf); + encode_count_big(sc->buf, sc->count_low, sc->count_high, sc->ptr, n); + compress_big(sc, 1); + d = dst; + for (d = dst, u = 0; u < dst_len; u ++) + sph_enc32le(d + (u << 2), sc->state[u]); +} + +void +sph_simd224_init(void *cc) +{ + init_small(cc, IV224); +} + +void +sph_simd224(void *cc, const void *data, size_t len) +{ + update_small(cc, data, len); +} + +void +sph_simd224_close(void *cc, void *dst) +{ + sph_simd224_addbits_and_close(cc, 0, 0, dst); +} + +void +sph_simd224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + finalize_small(cc, ub, n, dst, 7); + sph_simd224_init(cc); +} + +void +sph_simd256_init(void *cc) +{ + init_small(cc, IV256); +} + +void +sph_simd256(void *cc, const void *data, size_t len) +{ + update_small(cc, data, len); +} + +void +sph_simd256_close(void *cc, void *dst) +{ + sph_simd256_addbits_and_close(cc, 0, 0, dst); +} + +void +sph_simd256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + finalize_small(cc, ub, n, dst, 8); + sph_simd256_init(cc); +} + +void +sph_simd384_init(void *cc) +{ + init_big(cc, IV384); +} + +void +sph_simd384(void *cc, const void *data, size_t len) +{ + update_big(cc, data, len); +} + +void +sph_simd384_close(void *cc, void *dst) +{ + sph_simd384_addbits_and_close(cc, 0, 0, dst); +} + +void +sph_simd384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + finalize_big(cc, ub, n, dst, 12); + sph_simd384_init(cc); +} + +void +sph_simd512_init(void *cc) +{ + init_big(cc, IV512); +} + +void +sph_simd512(void *cc, const void *data, size_t len) +{ + update_big(cc, data, len); +} + +void +sph_simd512_close(void *cc, void *dst) +{ + sph_simd512_addbits_and_close(cc, 0, 0, dst); +} + +void +sph_simd512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + finalize_big(cc, ub, n, dst, 16); + sph_simd512_init(cc); +} +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/skein.c b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/skein.c new file mode 100644 index 0000000..7e47e35 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/skein.c @@ -0,0 +1,1254 @@ +/* $Id: skein.c 254 2011-06-07 19:38:58Z tp $ */ +/* + * Skein implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include +#include + +#include "sph_skein.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_SKEIN +#define SPH_SMALL_FOOTPRINT_SKEIN 1 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +#if SPH_64 + +#if 0 +/* obsolete */ +/* + * M5_ ## s ## _ ## i evaluates to s+i mod 5 (0 <= s <= 18, 0 <= i <= 3). + */ + +#define M5_0_0 0 +#define M5_0_1 1 +#define M5_0_2 2 +#define M5_0_3 3 + +#define M5_1_0 1 +#define M5_1_1 2 +#define M5_1_2 3 +#define M5_1_3 4 + +#define M5_2_0 2 +#define M5_2_1 3 +#define M5_2_2 4 +#define M5_2_3 0 + +#define M5_3_0 3 +#define M5_3_1 4 +#define M5_3_2 0 +#define M5_3_3 1 + +#define M5_4_0 4 +#define M5_4_1 0 +#define M5_4_2 1 +#define M5_4_3 2 + +#define M5_5_0 0 +#define M5_5_1 1 +#define M5_5_2 2 +#define M5_5_3 3 + +#define M5_6_0 1 +#define M5_6_1 2 +#define M5_6_2 3 +#define M5_6_3 4 + +#define M5_7_0 2 +#define M5_7_1 3 +#define M5_7_2 4 +#define M5_7_3 0 + +#define M5_8_0 3 +#define M5_8_1 4 +#define M5_8_2 0 +#define M5_8_3 1 + +#define M5_9_0 4 +#define M5_9_1 0 +#define M5_9_2 1 +#define M5_9_3 2 + +#define M5_10_0 0 +#define M5_10_1 1 +#define M5_10_2 2 +#define M5_10_3 3 + +#define M5_11_0 1 +#define M5_11_1 2 +#define M5_11_2 3 +#define M5_11_3 4 + +#define M5_12_0 2 +#define M5_12_1 3 +#define M5_12_2 4 +#define M5_12_3 0 + +#define M5_13_0 3 +#define M5_13_1 4 +#define M5_13_2 0 +#define M5_13_3 1 + +#define M5_14_0 4 +#define M5_14_1 0 +#define M5_14_2 1 +#define M5_14_3 2 + +#define M5_15_0 0 +#define M5_15_1 1 +#define M5_15_2 2 +#define M5_15_3 3 + +#define M5_16_0 1 +#define M5_16_1 2 +#define M5_16_2 3 +#define M5_16_3 4 + +#define M5_17_0 2 +#define M5_17_1 3 +#define M5_17_2 4 +#define M5_17_3 0 + +#define M5_18_0 3 +#define M5_18_1 4 +#define M5_18_2 0 +#define M5_18_3 1 +#endif + +/* + * M9_ ## s ## _ ## i evaluates to s+i mod 9 (0 <= s <= 18, 0 <= i <= 7). + */ + +#define M9_0_0 0 +#define M9_0_1 1 +#define M9_0_2 2 +#define M9_0_3 3 +#define M9_0_4 4 +#define M9_0_5 5 +#define M9_0_6 6 +#define M9_0_7 7 + +#define M9_1_0 1 +#define M9_1_1 2 +#define M9_1_2 3 +#define M9_1_3 4 +#define M9_1_4 5 +#define M9_1_5 6 +#define M9_1_6 7 +#define M9_1_7 8 + +#define M9_2_0 2 +#define M9_2_1 3 +#define M9_2_2 4 +#define M9_2_3 5 +#define M9_2_4 6 +#define M9_2_5 7 +#define M9_2_6 8 +#define M9_2_7 0 + +#define M9_3_0 3 +#define M9_3_1 4 +#define M9_3_2 5 +#define M9_3_3 6 +#define M9_3_4 7 +#define M9_3_5 8 +#define M9_3_6 0 +#define M9_3_7 1 + +#define M9_4_0 4 +#define M9_4_1 5 +#define M9_4_2 6 +#define M9_4_3 7 +#define M9_4_4 8 +#define M9_4_5 0 +#define M9_4_6 1 +#define M9_4_7 2 + +#define M9_5_0 5 +#define M9_5_1 6 +#define M9_5_2 7 +#define M9_5_3 8 +#define M9_5_4 0 +#define M9_5_5 1 +#define M9_5_6 2 +#define M9_5_7 3 + +#define M9_6_0 6 +#define M9_6_1 7 +#define M9_6_2 8 +#define M9_6_3 0 +#define M9_6_4 1 +#define M9_6_5 2 +#define M9_6_6 3 +#define M9_6_7 4 + +#define M9_7_0 7 +#define M9_7_1 8 +#define M9_7_2 0 +#define M9_7_3 1 +#define M9_7_4 2 +#define M9_7_5 3 +#define M9_7_6 4 +#define M9_7_7 5 + +#define M9_8_0 8 +#define M9_8_1 0 +#define M9_8_2 1 +#define M9_8_3 2 +#define M9_8_4 3 +#define M9_8_5 4 +#define M9_8_6 5 +#define M9_8_7 6 + +#define M9_9_0 0 +#define M9_9_1 1 +#define M9_9_2 2 +#define M9_9_3 3 +#define M9_9_4 4 +#define M9_9_5 5 +#define M9_9_6 6 +#define M9_9_7 7 + +#define M9_10_0 1 +#define M9_10_1 2 +#define M9_10_2 3 +#define M9_10_3 4 +#define M9_10_4 5 +#define M9_10_5 6 +#define M9_10_6 7 +#define M9_10_7 8 + +#define M9_11_0 2 +#define M9_11_1 3 +#define M9_11_2 4 +#define M9_11_3 5 +#define M9_11_4 6 +#define M9_11_5 7 +#define M9_11_6 8 +#define M9_11_7 0 + +#define M9_12_0 3 +#define M9_12_1 4 +#define M9_12_2 5 +#define M9_12_3 6 +#define M9_12_4 7 +#define M9_12_5 8 +#define M9_12_6 0 +#define M9_12_7 1 + +#define M9_13_0 4 +#define M9_13_1 5 +#define M9_13_2 6 +#define M9_13_3 7 +#define M9_13_4 8 +#define M9_13_5 0 +#define M9_13_6 1 +#define M9_13_7 2 + +#define M9_14_0 5 +#define M9_14_1 6 +#define M9_14_2 7 +#define M9_14_3 8 +#define M9_14_4 0 +#define M9_14_5 1 +#define M9_14_6 2 +#define M9_14_7 3 + +#define M9_15_0 6 +#define M9_15_1 7 +#define M9_15_2 8 +#define M9_15_3 0 +#define M9_15_4 1 +#define M9_15_5 2 +#define M9_15_6 3 +#define M9_15_7 4 + +#define M9_16_0 7 +#define M9_16_1 8 +#define M9_16_2 0 +#define M9_16_3 1 +#define M9_16_4 2 +#define M9_16_5 3 +#define M9_16_6 4 +#define M9_16_7 5 + +#define M9_17_0 8 +#define M9_17_1 0 +#define M9_17_2 1 +#define M9_17_3 2 +#define M9_17_4 3 +#define M9_17_5 4 +#define M9_17_6 5 +#define M9_17_7 6 + +#define M9_18_0 0 +#define M9_18_1 1 +#define M9_18_2 2 +#define M9_18_3 3 +#define M9_18_4 4 +#define M9_18_5 5 +#define M9_18_6 6 +#define M9_18_7 7 + +/* + * M3_ ## s ## _ ## i evaluates to s+i mod 3 (0 <= s <= 18, 0 <= i <= 1). + */ + +#define M3_0_0 0 +#define M3_0_1 1 +#define M3_1_0 1 +#define M3_1_1 2 +#define M3_2_0 2 +#define M3_2_1 0 +#define M3_3_0 0 +#define M3_3_1 1 +#define M3_4_0 1 +#define M3_4_1 2 +#define M3_5_0 2 +#define M3_5_1 0 +#define M3_6_0 0 +#define M3_6_1 1 +#define M3_7_0 1 +#define M3_7_1 2 +#define M3_8_0 2 +#define M3_8_1 0 +#define M3_9_0 0 +#define M3_9_1 1 +#define M3_10_0 1 +#define M3_10_1 2 +#define M3_11_0 2 +#define M3_11_1 0 +#define M3_12_0 0 +#define M3_12_1 1 +#define M3_13_0 1 +#define M3_13_1 2 +#define M3_14_0 2 +#define M3_14_1 0 +#define M3_15_0 0 +#define M3_15_1 1 +#define M3_16_0 1 +#define M3_16_1 2 +#define M3_17_0 2 +#define M3_17_1 0 +#define M3_18_0 0 +#define M3_18_1 1 + +#define XCAT(x, y) XCAT_(x, y) +#define XCAT_(x, y) x ## y + +#if 0 +/* obsolete */ +#define SKSI(k, s, i) XCAT(k, XCAT(XCAT(XCAT(M5_, s), _), i)) +#define SKST(t, s, v) XCAT(t, XCAT(XCAT(XCAT(M3_, s), _), v)) +#endif + +#define SKBI(k, s, i) XCAT(k, XCAT(XCAT(XCAT(M9_, s), _), i)) +#define SKBT(t, s, v) XCAT(t, XCAT(XCAT(XCAT(M3_, s), _), v)) + +#if 0 +/* obsolete */ +#define TFSMALL_KINIT(k0, k1, k2, k3, k4, t0, t1, t2) do { \ + k4 = (k0 ^ k1) ^ (k2 ^ k3) ^ SPH_C64(0x1BD11BDAA9FC1A22); \ + t2 = t0 ^ t1; \ + } while (0) +#endif + +#define TFBIG_KINIT(k0, k1, k2, k3, k4, k5, k6, k7, k8, t0, t1, t2) do { \ + k8 = ((k0 ^ k1) ^ (k2 ^ k3)) ^ ((k4 ^ k5) ^ (k6 ^ k7)) \ + ^ SPH_C64(0x1BD11BDAA9FC1A22); \ + t2 = t0 ^ t1; \ + } while (0) + +#if 0 +/* obsolete */ +#define TFSMALL_ADDKEY(w0, w1, w2, w3, k, t, s) do { \ + w0 = SPH_T64(w0 + SKSI(k, s, 0)); \ + w1 = SPH_T64(w1 + SKSI(k, s, 1) + SKST(t, s, 0)); \ + w2 = SPH_T64(w2 + SKSI(k, s, 2) + SKST(t, s, 1)); \ + w3 = SPH_T64(w3 + SKSI(k, s, 3) + (sph_u64)s); \ + } while (0) +#endif + +#if SPH_SMALL_FOOTPRINT_SKEIN + +#define TFBIG_ADDKEY(s, tt0, tt1) do { \ + p0 = SPH_T64(p0 + h[s + 0]); \ + p1 = SPH_T64(p1 + h[s + 1]); \ + p2 = SPH_T64(p2 + h[s + 2]); \ + p3 = SPH_T64(p3 + h[s + 3]); \ + p4 = SPH_T64(p4 + h[s + 4]); \ + p5 = SPH_T64(p5 + h[s + 5] + tt0); \ + p6 = SPH_T64(p6 + h[s + 6] + tt1); \ + p7 = SPH_T64(p7 + h[s + 7] + (sph_u64)s); \ + } while (0) + +#else + +#define TFBIG_ADDKEY(w0, w1, w2, w3, w4, w5, w6, w7, k, t, s) do { \ + w0 = SPH_T64(w0 + SKBI(k, s, 0)); \ + w1 = SPH_T64(w1 + SKBI(k, s, 1)); \ + w2 = SPH_T64(w2 + SKBI(k, s, 2)); \ + w3 = SPH_T64(w3 + SKBI(k, s, 3)); \ + w4 = SPH_T64(w4 + SKBI(k, s, 4)); \ + w5 = SPH_T64(w5 + SKBI(k, s, 5) + SKBT(t, s, 0)); \ + w6 = SPH_T64(w6 + SKBI(k, s, 6) + SKBT(t, s, 1)); \ + w7 = SPH_T64(w7 + SKBI(k, s, 7) + (sph_u64)s); \ + } while (0) + +#endif + +#if 0 +/* obsolete */ +#define TFSMALL_MIX(x0, x1, rc) do { \ + x0 = SPH_T64(x0 + x1); \ + x1 = SPH_ROTL64(x1, rc) ^ x0; \ + } while (0) +#endif + +#define TFBIG_MIX(x0, x1, rc) do { \ + x0 = SPH_T64(x0 + x1); \ + x1 = SPH_ROTL64(x1, rc) ^ x0; \ + } while (0) + +#if 0 +/* obsolete */ +#define TFSMALL_MIX4(w0, w1, w2, w3, rc0, rc1) do { \ + TFSMALL_MIX(w0, w1, rc0); \ + TFSMALL_MIX(w2, w3, rc1); \ + } while (0) +#endif + +#define TFBIG_MIX8(w0, w1, w2, w3, w4, w5, w6, w7, rc0, rc1, rc2, rc3) do { \ + TFBIG_MIX(w0, w1, rc0); \ + TFBIG_MIX(w2, w3, rc1); \ + TFBIG_MIX(w4, w5, rc2); \ + TFBIG_MIX(w6, w7, rc3); \ + } while (0) + +#if 0 +/* obsolete */ +#define TFSMALL_4e(s) do { \ + TFSMALL_ADDKEY(p0, p1, p2, p3, h, t, s); \ + TFSMALL_MIX4(p0, p1, p2, p3, 14, 16); \ + TFSMALL_MIX4(p0, p3, p2, p1, 52, 57); \ + TFSMALL_MIX4(p0, p1, p2, p3, 23, 40); \ + TFSMALL_MIX4(p0, p3, p2, p1, 5, 37); \ + } while (0) + +#define TFSMALL_4o(s) do { \ + TFSMALL_ADDKEY(p0, p1, p2, p3, h, t, s); \ + TFSMALL_MIX4(p0, p1, p2, p3, 25, 33); \ + TFSMALL_MIX4(p0, p3, p2, p1, 46, 12); \ + TFSMALL_MIX4(p0, p1, p2, p3, 58, 22); \ + TFSMALL_MIX4(p0, p3, p2, p1, 32, 32); \ + } while (0) +#endif + +#if SPH_SMALL_FOOTPRINT_SKEIN + +#define TFBIG_4e(s) do { \ + TFBIG_ADDKEY(s, t0, t1); \ + TFBIG_MIX8(p0, p1, p2, p3, p4, p5, p6, p7, 46, 36, 19, 37); \ + TFBIG_MIX8(p2, p1, p4, p7, p6, p5, p0, p3, 33, 27, 14, 42); \ + TFBIG_MIX8(p4, p1, p6, p3, p0, p5, p2, p7, 17, 49, 36, 39); \ + TFBIG_MIX8(p6, p1, p0, p7, p2, p5, p4, p3, 44, 9, 54, 56); \ + } while (0) + +#define TFBIG_4o(s) do { \ + TFBIG_ADDKEY(s, t1, t2); \ + TFBIG_MIX8(p0, p1, p2, p3, p4, p5, p6, p7, 39, 30, 34, 24); \ + TFBIG_MIX8(p2, p1, p4, p7, p6, p5, p0, p3, 13, 50, 10, 17); \ + TFBIG_MIX8(p4, p1, p6, p3, p0, p5, p2, p7, 25, 29, 39, 43); \ + TFBIG_MIX8(p6, p1, p0, p7, p2, p5, p4, p3, 8, 35, 56, 22); \ + } while (0) + +#else + +#define TFBIG_4e(s) do { \ + TFBIG_ADDKEY(p0, p1, p2, p3, p4, p5, p6, p7, h, t, s); \ + TFBIG_MIX8(p0, p1, p2, p3, p4, p5, p6, p7, 46, 36, 19, 37); \ + TFBIG_MIX8(p2, p1, p4, p7, p6, p5, p0, p3, 33, 27, 14, 42); \ + TFBIG_MIX8(p4, p1, p6, p3, p0, p5, p2, p7, 17, 49, 36, 39); \ + TFBIG_MIX8(p6, p1, p0, p7, p2, p5, p4, p3, 44, 9, 54, 56); \ + } while (0) + +#define TFBIG_4o(s) do { \ + TFBIG_ADDKEY(p0, p1, p2, p3, p4, p5, p6, p7, h, t, s); \ + TFBIG_MIX8(p0, p1, p2, p3, p4, p5, p6, p7, 39, 30, 34, 24); \ + TFBIG_MIX8(p2, p1, p4, p7, p6, p5, p0, p3, 13, 50, 10, 17); \ + TFBIG_MIX8(p4, p1, p6, p3, p0, p5, p2, p7, 25, 29, 39, 43); \ + TFBIG_MIX8(p6, p1, p0, p7, p2, p5, p4, p3, 8, 35, 56, 22); \ + } while (0) + +#endif + +#if 0 +/* obsolete */ +#define UBI_SMALL(etype, extra) do { \ + sph_u64 h4, t0, t1, t2; \ + sph_u64 m0 = sph_dec64le(buf + 0); \ + sph_u64 m1 = sph_dec64le(buf + 8); \ + sph_u64 m2 = sph_dec64le(buf + 16); \ + sph_u64 m3 = sph_dec64le(buf + 24); \ + sph_u64 p0 = m0; \ + sph_u64 p1 = m1; \ + sph_u64 p2 = m2; \ + sph_u64 p3 = m3; \ + t0 = SPH_T64(bcount << 5) + (sph_u64)(extra); \ + t1 = (bcount >> 59) + ((sph_u64)(etype) << 55); \ + TFSMALL_KINIT(h0, h1, h2, h3, h4, t0, t1, t2); \ + TFSMALL_4e(0); \ + TFSMALL_4o(1); \ + TFSMALL_4e(2); \ + TFSMALL_4o(3); \ + TFSMALL_4e(4); \ + TFSMALL_4o(5); \ + TFSMALL_4e(6); \ + TFSMALL_4o(7); \ + TFSMALL_4e(8); \ + TFSMALL_4o(9); \ + TFSMALL_4e(10); \ + TFSMALL_4o(11); \ + TFSMALL_4e(12); \ + TFSMALL_4o(13); \ + TFSMALL_4e(14); \ + TFSMALL_4o(15); \ + TFSMALL_4e(16); \ + TFSMALL_4o(17); \ + TFSMALL_ADDKEY(p0, p1, p2, p3, h, t, 18); \ + h0 = m0 ^ p0; \ + h1 = m1 ^ p1; \ + h2 = m2 ^ p2; \ + h3 = m3 ^ p3; \ + } while (0) +#endif + +#if SPH_SMALL_FOOTPRINT_SKEIN + +#define UBI_BIG(etype, extra) do { \ + sph_u64 t0, t1, t2; \ + unsigned u; \ + sph_u64 m0 = sph_dec64le_aligned(buf + 0); \ + sph_u64 m1 = sph_dec64le_aligned(buf + 8); \ + sph_u64 m2 = sph_dec64le_aligned(buf + 16); \ + sph_u64 m3 = sph_dec64le_aligned(buf + 24); \ + sph_u64 m4 = sph_dec64le_aligned(buf + 32); \ + sph_u64 m5 = sph_dec64le_aligned(buf + 40); \ + sph_u64 m6 = sph_dec64le_aligned(buf + 48); \ + sph_u64 m7 = sph_dec64le_aligned(buf + 56); \ + sph_u64 p0 = m0; \ + sph_u64 p1 = m1; \ + sph_u64 p2 = m2; \ + sph_u64 p3 = m3; \ + sph_u64 p4 = m4; \ + sph_u64 p5 = m5; \ + sph_u64 p6 = m6; \ + sph_u64 p7 = m7; \ + t0 = SPH_T64(bcount << 6) + (sph_u64)(extra); \ + t1 = (bcount >> 58) + ((sph_u64)(etype) << 55); \ + TFBIG_KINIT(h[0], h[1], h[2], h[3], h[4], h[5], \ + h[6], h[7], h[8], t0, t1, t2); \ + for (u = 0; u <= 15; u += 3) { \ + h[u + 9] = h[u + 0]; \ + h[u + 10] = h[u + 1]; \ + h[u + 11] = h[u + 2]; \ + } \ + for (u = 0; u < 9; u ++) { \ + sph_u64 s = u << 1; \ + sph_u64 tmp; \ + TFBIG_4e(s); \ + TFBIG_4o(s + 1); \ + tmp = t2; \ + t2 = t1; \ + t1 = t0; \ + t0 = tmp; \ + } \ + TFBIG_ADDKEY(18, t0, t1); \ + h[0] = m0 ^ p0; \ + h[1] = m1 ^ p1; \ + h[2] = m2 ^ p2; \ + h[3] = m3 ^ p3; \ + h[4] = m4 ^ p4; \ + h[5] = m5 ^ p5; \ + h[6] = m6 ^ p6; \ + h[7] = m7 ^ p7; \ + } while (0) + +#else + +#define UBI_BIG(etype, extra) do { \ + sph_u64 h8, t0, t1, t2; \ + sph_u64 m0 = sph_dec64le_aligned(buf + 0); \ + sph_u64 m1 = sph_dec64le_aligned(buf + 8); \ + sph_u64 m2 = sph_dec64le_aligned(buf + 16); \ + sph_u64 m3 = sph_dec64le_aligned(buf + 24); \ + sph_u64 m4 = sph_dec64le_aligned(buf + 32); \ + sph_u64 m5 = sph_dec64le_aligned(buf + 40); \ + sph_u64 m6 = sph_dec64le_aligned(buf + 48); \ + sph_u64 m7 = sph_dec64le_aligned(buf + 56); \ + sph_u64 p0 = m0; \ + sph_u64 p1 = m1; \ + sph_u64 p2 = m2; \ + sph_u64 p3 = m3; \ + sph_u64 p4 = m4; \ + sph_u64 p5 = m5; \ + sph_u64 p6 = m6; \ + sph_u64 p7 = m7; \ + t0 = SPH_T64(bcount << 6) + (sph_u64)(extra); \ + t1 = (bcount >> 58) + ((sph_u64)(etype) << 55); \ + TFBIG_KINIT(h0, h1, h2, h3, h4, h5, h6, h7, h8, t0, t1, t2); \ + TFBIG_4e(0); \ + TFBIG_4o(1); \ + TFBIG_4e(2); \ + TFBIG_4o(3); \ + TFBIG_4e(4); \ + TFBIG_4o(5); \ + TFBIG_4e(6); \ + TFBIG_4o(7); \ + TFBIG_4e(8); \ + TFBIG_4o(9); \ + TFBIG_4e(10); \ + TFBIG_4o(11); \ + TFBIG_4e(12); \ + TFBIG_4o(13); \ + TFBIG_4e(14); \ + TFBIG_4o(15); \ + TFBIG_4e(16); \ + TFBIG_4o(17); \ + TFBIG_ADDKEY(p0, p1, p2, p3, p4, p5, p6, p7, h, t, 18); \ + h0 = m0 ^ p0; \ + h1 = m1 ^ p1; \ + h2 = m2 ^ p2; \ + h3 = m3 ^ p3; \ + h4 = m4 ^ p4; \ + h5 = m5 ^ p5; \ + h6 = m6 ^ p6; \ + h7 = m7 ^ p7; \ + } while (0) + +#endif + +#if 0 +/* obsolete */ +#define DECL_STATE_SMALL \ + sph_u64 h0, h1, h2, h3; \ + sph_u64 bcount; + +#define READ_STATE_SMALL(sc) do { \ + h0 = (sc)->h0; \ + h1 = (sc)->h1; \ + h2 = (sc)->h2; \ + h3 = (sc)->h3; \ + bcount = sc->bcount; \ + } while (0) + +#define WRITE_STATE_SMALL(sc) do { \ + (sc)->h0 = h0; \ + (sc)->h1 = h1; \ + (sc)->h2 = h2; \ + (sc)->h3 = h3; \ + sc->bcount = bcount; \ + } while (0) +#endif + +#if SPH_SMALL_FOOTPRINT_SKEIN + +#define DECL_STATE_BIG \ + sph_u64 h[27]; \ + sph_u64 bcount; + +#define READ_STATE_BIG(sc) do { \ + h[0] = (sc)->h0; \ + h[1] = (sc)->h1; \ + h[2] = (sc)->h2; \ + h[3] = (sc)->h3; \ + h[4] = (sc)->h4; \ + h[5] = (sc)->h5; \ + h[6] = (sc)->h6; \ + h[7] = (sc)->h7; \ + bcount = sc->bcount; \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + (sc)->h0 = h[0]; \ + (sc)->h1 = h[1]; \ + (sc)->h2 = h[2]; \ + (sc)->h3 = h[3]; \ + (sc)->h4 = h[4]; \ + (sc)->h5 = h[5]; \ + (sc)->h6 = h[6]; \ + (sc)->h7 = h[7]; \ + sc->bcount = bcount; \ + } while (0) + +#else + +#define DECL_STATE_BIG \ + sph_u64 h0, h1, h2, h3, h4, h5, h6, h7; \ + sph_u64 bcount; + +#define READ_STATE_BIG(sc) do { \ + h0 = (sc)->h0; \ + h1 = (sc)->h1; \ + h2 = (sc)->h2; \ + h3 = (sc)->h3; \ + h4 = (sc)->h4; \ + h5 = (sc)->h5; \ + h6 = (sc)->h6; \ + h7 = (sc)->h7; \ + bcount = sc->bcount; \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + (sc)->h0 = h0; \ + (sc)->h1 = h1; \ + (sc)->h2 = h2; \ + (sc)->h3 = h3; \ + (sc)->h4 = h4; \ + (sc)->h5 = h5; \ + (sc)->h6 = h6; \ + (sc)->h7 = h7; \ + sc->bcount = bcount; \ + } while (0) + +#endif + +#if 0 +/* obsolete */ +static void +skein_small_init(sph_skein_small_context *sc, const sph_u64 *iv) +{ + sc->h0 = iv[0]; + sc->h1 = iv[1]; + sc->h2 = iv[2]; + sc->h3 = iv[3]; + sc->bcount = 0; + sc->ptr = 0; +} +#endif + +static void +skein_big_init(sph_skein_big_context *sc, const sph_u64 *iv) +{ + sc->h0 = iv[0]; + sc->h1 = iv[1]; + sc->h2 = iv[2]; + sc->h3 = iv[3]; + sc->h4 = iv[4]; + sc->h5 = iv[5]; + sc->h6 = iv[6]; + sc->h7 = iv[7]; + sc->bcount = 0; + sc->ptr = 0; +} + +#if 0 +/* obsolete */ +static void +skein_small_core(sph_skein_small_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr, clen; + unsigned first; + DECL_STATE_SMALL + + buf = sc->buf; + ptr = sc->ptr; + clen = (sizeof sc->buf) - ptr; + if (len <= clen) { + memcpy(buf + ptr, data, len); + sc->ptr = ptr + len; + return; + } + if (clen != 0) { + memcpy(buf + ptr, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + } + +#if SPH_SMALL_FOOTPRINT_SKEIN + + READ_STATE_SMALL(sc); + first = (bcount == 0) << 7; + for (;;) { + bcount ++; + UBI_SMALL(96 + first, 0); + if (len <= sizeof sc->buf) + break; + first = 0; + memcpy(buf, data, sizeof sc->buf); + data = (const unsigned char *)data + sizeof sc->buf; + len -= sizeof sc->buf; + } + WRITE_STATE_SMALL(sc); + sc->ptr = len; + memcpy(buf, data, len); + +#else + + /* + * Unrolling the loop yields a slight performance boost, while + * keeping the code size aorund 24 kB on 32-bit x86. + */ + READ_STATE_SMALL(sc); + first = (bcount == 0) << 7; + for (;;) { + bcount ++; + UBI_SMALL(96 + first, 0); + if (len <= sizeof sc->buf) + break; + buf = (unsigned char *)data; + bcount ++; + UBI_SMALL(96, 0); + if (len <= 2 * sizeof sc->buf) { + data = buf + sizeof sc->buf; + len -= sizeof sc->buf; + break; + } + buf += sizeof sc->buf; + data = buf + sizeof sc->buf; + first = 0; + len -= 2 * sizeof sc->buf; + } + WRITE_STATE_SMALL(sc); + sc->ptr = len; + memcpy(sc->buf, data, len); + +#endif +} +#endif + +static void +skein_big_core(sph_skein_big_context *sc, const void *data, size_t len) +{ + /* + * The Skein "final bit" in the tweak is troublesome here, + * because if the input has a length which is a multiple of the + * block size (512 bits) then that bit must be set for the + * final block, which is full of message bits (padding in + * Skein can be reduced to no extra bit at all). However, this + * function cannot know whether it processes the last chunks of + * the message or not. Hence we may keep a full block of buffered + * data (64 bytes). + */ + unsigned char *buf; + size_t ptr; + unsigned first; + DECL_STATE_BIG + + buf = sc->buf; + ptr = sc->ptr; + if (len <= (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + READ_STATE_BIG(sc); + first = (bcount == 0) << 7; + do { + size_t clen; + + if (ptr == sizeof sc->buf) { + bcount ++; + UBI_BIG(96 + first, 0); + first = 0; + ptr = 0; + } + clen = (sizeof sc->buf) - ptr; + if (clen > len) + clen = len; + memcpy(buf + ptr, data, clen); + ptr += clen; + data = (const unsigned char *)data + clen; + len -= clen; + } while (len > 0); + WRITE_STATE_BIG(sc); + sc->ptr = ptr; +} + +#if 0 +/* obsolete */ +static void +skein_small_close(sph_skein_small_context *sc, unsigned ub, unsigned n, + void *dst, size_t out_len) +{ + unsigned char *buf; + size_t ptr; + unsigned et; + int i; + DECL_STATE_SMALL + + if (n != 0) { + unsigned z; + unsigned char x; + + z = 0x80 >> n; + x = ((ub & -z) | z) & 0xFF; + skein_small_core(sc, &x, 1); + } + + buf = sc->buf; + ptr = sc->ptr; + READ_STATE_SMALL(sc); + memset(buf + ptr, 0, (sizeof sc->buf) - ptr); + et = 352 + ((bcount == 0) << 7) + (n != 0); + for (i = 0; i < 2; i ++) { + UBI_SMALL(et, ptr); + if (i == 0) { + memset(buf, 0, sizeof sc->buf); + bcount = 0; + et = 510; + ptr = 8; + } + } + + sph_enc64le_aligned(buf + 0, h0); + sph_enc64le_aligned(buf + 8, h1); + sph_enc64le_aligned(buf + 16, h2); + sph_enc64le_aligned(buf + 24, h3); + memcpy(dst, buf, out_len); +} +#endif + +static void +skein_big_close(sph_skein_big_context *sc, unsigned ub, unsigned n, + void *dst, size_t out_len) +{ + unsigned char *buf; + size_t ptr; + unsigned et; + int i; +#if SPH_SMALL_FOOTPRINT_SKEIN + size_t u; +#endif + DECL_STATE_BIG + + /* + * Add bit padding if necessary. + */ + if (n != 0) { + unsigned z; + unsigned char x; + + z = 0x80 >> n; + x = ((ub & -z) | z) & 0xFF; + skein_big_core(sc, &x, 1); + } + + buf = sc->buf; + ptr = sc->ptr; + + /* + * At that point, if ptr == 0, then the message was empty; + * otherwise, there is between 1 and 64 bytes (inclusive) which + * are yet to be processed. Either way, we complete the buffer + * to a full block with zeros (the Skein specification mandates + * that an empty message is padded so that there is at least + * one block to process). + * + * Once this block has been processed, we do it again, with + * a block full of zeros, for the output (that block contains + * the encoding of "0", over 8 bytes, then padded with zeros). + */ + READ_STATE_BIG(sc); + memset(buf + ptr, 0, (sizeof sc->buf) - ptr); + et = 352 + ((bcount == 0) << 7) + (n != 0); + for (i = 0; i < 2; i ++) { + UBI_BIG(et, ptr); + if (i == 0) { + memset(buf, 0, sizeof sc->buf); + bcount = 0; + et = 510; + ptr = 8; + } + } + +#if SPH_SMALL_FOOTPRINT_SKEIN + + /* + * We use a temporary buffer because we must support the case + * where output size is not a multiple of 64 (namely, a 224-bit + * output). + */ + for (u = 0; u < out_len; u += 8) + sph_enc64le_aligned(buf + u, h[u >> 3]); + memcpy(dst, buf, out_len); + +#else + + sph_enc64le_aligned(buf + 0, h0); + sph_enc64le_aligned(buf + 8, h1); + sph_enc64le_aligned(buf + 16, h2); + sph_enc64le_aligned(buf + 24, h3); + sph_enc64le_aligned(buf + 32, h4); + sph_enc64le_aligned(buf + 40, h5); + sph_enc64le_aligned(buf + 48, h6); + sph_enc64le_aligned(buf + 56, h7); + memcpy(dst, buf, out_len); + +#endif +} + +#if 0 +/* obsolete */ +static const sph_u64 IV224[] = { + SPH_C64(0xC6098A8C9AE5EA0B), SPH_C64(0x876D568608C5191C), + SPH_C64(0x99CB88D7D7F53884), SPH_C64(0x384BDDB1AEDDB5DE) +}; + +static const sph_u64 IV256[] = { + SPH_C64(0xFC9DA860D048B449), SPH_C64(0x2FCA66479FA7D833), + SPH_C64(0xB33BC3896656840F), SPH_C64(0x6A54E920FDE8DA69) +}; +#endif + +static const sph_u64 IV224[] = { + SPH_C64(0xCCD0616248677224), SPH_C64(0xCBA65CF3A92339EF), + SPH_C64(0x8CCD69D652FF4B64), SPH_C64(0x398AED7B3AB890B4), + SPH_C64(0x0F59D1B1457D2BD0), SPH_C64(0x6776FE6575D4EB3D), + SPH_C64(0x99FBC70E997413E9), SPH_C64(0x9E2CFCCFE1C41EF7) +}; + +static const sph_u64 IV256[] = { + SPH_C64(0xCCD044A12FDB3E13), SPH_C64(0xE83590301A79A9EB), + SPH_C64(0x55AEA0614F816E6F), SPH_C64(0x2A2767A4AE9B94DB), + SPH_C64(0xEC06025E74DD7683), SPH_C64(0xE7A436CDC4746251), + SPH_C64(0xC36FBAF9393AD185), SPH_C64(0x3EEDBA1833EDFC13) +}; + +static const sph_u64 IV384[] = { + SPH_C64(0xA3F6C6BF3A75EF5F), SPH_C64(0xB0FEF9CCFD84FAA4), + SPH_C64(0x9D77DD663D770CFE), SPH_C64(0xD798CBF3B468FDDA), + SPH_C64(0x1BC4A6668A0E4465), SPH_C64(0x7ED7D434E5807407), + SPH_C64(0x548FC1ACD4EC44D6), SPH_C64(0x266E17546AA18FF8) +}; + +static const sph_u64 IV512[] = { + SPH_C64(0x4903ADFF749C51CE), SPH_C64(0x0D95DE399746DF03), + SPH_C64(0x8FD1934127C79BCE), SPH_C64(0x9A255629FF352CB1), + SPH_C64(0x5DB62599DF6CA7B0), SPH_C64(0xEABE394CA9D5C3F4), + SPH_C64(0x991112C71A75B523), SPH_C64(0xAE18A40B660FCC33) +}; + +#if 0 +/* obsolete */ +/* see sph_skein.h */ +void +sph_skein224_init(void *cc) +{ + skein_small_init(cc, IV224); +} + +/* see sph_skein.h */ +void +sph_skein224(void *cc, const void *data, size_t len) +{ + skein_small_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein224_close(void *cc, void *dst) +{ + sph_skein224_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_small_close(cc, ub, n, dst, 28); + sph_skein224_init(cc); +} + +/* see sph_skein.h */ +void +sph_skein256_init(void *cc) +{ + skein_small_init(cc, IV256); +} + +/* see sph_skein.h */ +void +sph_skein256(void *cc, const void *data, size_t len) +{ + skein_small_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein256_close(void *cc, void *dst) +{ + sph_skein256_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_small_close(cc, ub, n, dst, 32); + sph_skein256_init(cc); +} +#endif + +/* see sph_skein.h */ +void +sph_skein224_init(void *cc) +{ + skein_big_init(cc, IV224); +} + +/* see sph_skein.h */ +void +sph_skein224(void *cc, const void *data, size_t len) +{ + skein_big_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein224_close(void *cc, void *dst) +{ + sph_skein224_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_big_close(cc, ub, n, dst, 28); + sph_skein224_init(cc); +} + +/* see sph_skein.h */ +void +sph_skein256_init(void *cc) +{ + skein_big_init(cc, IV256); +} + +/* see sph_skein.h */ +void +sph_skein256(void *cc, const void *data, size_t len) +{ + skein_big_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein256_close(void *cc, void *dst) +{ + sph_skein256_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_big_close(cc, ub, n, dst, 32); + sph_skein256_init(cc); +} + +/* see sph_skein.h */ +void +sph_skein384_init(void *cc) +{ + skein_big_init(cc, IV384); +} + +/* see sph_skein.h */ +void +sph_skein384(void *cc, const void *data, size_t len) +{ + skein_big_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein384_close(void *cc, void *dst) +{ + sph_skein384_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_big_close(cc, ub, n, dst, 48); + sph_skein384_init(cc); +} + +/* see sph_skein.h */ +void +sph_skein512_init(void *cc) +{ + skein_big_init(cc, IV512); +} + +/* see sph_skein.h */ +void +sph_skein512(void *cc, const void *data, size_t len) +{ + skein_big_core(cc, data, len); +} + +/* see sph_skein.h */ +void +sph_skein512_close(void *cc, void *dst) +{ + sph_skein512_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_skein.h */ +void +sph_skein512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + skein_big_close(cc, ub, n, dst, 64); + sph_skein512_init(cc); +} + +#endif + + +#ifdef __cplusplus +} +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/smessage.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/smessage.cpp new file mode 100644 index 0000000..ae7bd24 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/smessage.cpp @@ -0,0 +1,3971 @@ +// Copyright (c) 2014 The ShadowCoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +/* +Notes: + Running with -debug could leave to and from address hashes and public keys in the log. + + + parameters: + -nosmsg Disable secure messaging (fNoSmsg) + -debugsmsg Show extra debug messages (fDebugSmsg) + -smsgscanchain Scan the block chain for public key addresses on startup + + + Wallet Locked + A copy of each incoming message is stored in bucket files ending in _wl.dat + wl (wallet locked) bucket files are deleted if they expire, like normal buckets + When the wallet is unlocked all the messages in wl files are scanned. + + + Address Whitelist + Owned Addresses are stored in smsgAddresses vector + Saved to smsg.ini + Modify options using the smsglocalkeys rpc command or edit the smsg.ini file (with client closed) + + +*/ + +#include "smessage.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#include "base58.h" +#include "db.h" +#include "init.h" // pwalletMain +#include "main.h" +#include "txdb.h" +#include "sync.h" +#include "eckey.h" + +#include "lz4/lz4.c" + +#include "xxhash/xxhash.h" +#include "xxhash/xxhash.c" + + +boost::thread_group threadGroupSmsg; + +// TODO: For buckets older than current, only need to store no. messages and hash in memory + +boost::signals2::signal NotifySecMsgInboxChanged; +boost::signals2::signal NotifySecMsgOutboxChanged; +boost::signals2::signal NotifySecMsgWalletUnlocked; + +bool fSecMsgEnabled = false; + +std::map smsgBuckets; +std::vector smsgAddresses; +SecMsgOptions smsgOptions; + + +CCriticalSection cs_smsg; +CCriticalSection cs_smsgDB; +CCriticalSection cs_smsgThreads; + +leveldb::DB *smsgDB = NULL; + + +namespace fs = boost::filesystem; + +bool SecMsgCrypter::SetKey(const std::vector& vchNewKey, uint8_t* chNewIV) +{ + if (vchNewKey.size() < sizeof(chKey)) + return false; + + return SetKey(&vchNewKey[0], chNewIV); +}; + +bool SecMsgCrypter::SetKey(const uint8_t* chNewKey, uint8_t* chNewIV) +{ + // -- for EVP_aes_256_cbc() key must be 256 bit, iv must be 128 bit. + memcpy(&chKey[0], chNewKey, sizeof(chKey)); + memcpy(chIV, chNewIV, sizeof(chIV)); + + fKeySet = true; + return true; +}; + +bool SecMsgCrypter::Encrypt(uint8_t* chPlaintext, uint32_t nPlain, std::vector &vchCiphertext) +{ + if (!fKeySet) + return false; + + // -- max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE - 1 bytes + int nLen = nPlain; + + int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0; + vchCiphertext = std::vector (nCLen); + + EVP_CIPHER_CTX ctx; + + bool fOk = true; + + EVP_CIPHER_CTX_init(&ctx); + if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, &chKey[0], &chIV[0]); + if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, chPlaintext, nLen); + if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen); + EVP_CIPHER_CTX_cleanup(&ctx); + + if (!fOk) + return false; + + vchCiphertext.resize(nCLen + nFLen); + + return true; +}; + +bool SecMsgCrypter::Decrypt(uint8_t* chCiphertext, uint32_t nCipher, std::vector& vchPlaintext) +{ + if (!fKeySet) + return false; + + // plaintext will always be equal to or lesser than length of ciphertext + int nPLen = nCipher, nFLen = 0; + + vchPlaintext.resize(nCipher); + + EVP_CIPHER_CTX ctx; + + bool fOk = true; + + EVP_CIPHER_CTX_init(&ctx); + if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, &chKey[0], &chIV[0]); + if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &chCiphertext[0], nCipher); + if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen); + EVP_CIPHER_CTX_cleanup(&ctx); + + if (!fOk) + return false; + + vchPlaintext.resize(nPLen + nFLen); + + return true; +}; + +void SecMsgBucket::hashBucket() +{ + if (fDebugSmsg) + LogPrintf("SecMsgBucket::hashBucket()\n"); + + timeChanged = GetTime(); + + std::set::iterator it; + + void* state = XXH32_init(1); + + for (it = setTokens.begin(); it != setTokens.end(); ++it) + { + XXH32_update(state, it->sample, 8); + }; + + hash = XXH32_digest(state); + + if (fDebugSmsg) + LogPrintf("Hashed %u messages, hash %u\n", setTokens.size(), hash); +}; + + +bool SecMsgDB::Open(const char* pszMode) +{ + if (smsgDB) + { + pdb = smsgDB; + return true; + }; + + bool fCreate = strchr(pszMode, 'c'); + + fs::path fullpath = GetDataDir() / "smsgDB"; + + if (!fCreate + && (!fs::exists(fullpath) + || !fs::is_directory(fullpath))) + { + LogPrintf("SecMsgDB::open() - DB does not exist.\n"); + return false; + }; + + leveldb::Options options; + options.create_if_missing = fCreate; + leveldb::Status s = leveldb::DB::Open(options, fullpath.string(), &smsgDB); + + if (!s.ok()) + { + LogPrintf("SecMsgDB::open() - Error opening db: %s.\n", s.ToString().c_str()); + return false; + }; + + pdb = smsgDB; + + return true; +}; + + +class SecMsgBatchScanner : public leveldb::WriteBatch::Handler +{ +public: + std::string needle; + bool* deleted; + std::string* foundValue; + bool foundEntry; + + SecMsgBatchScanner() : foundEntry(false) {} + + virtual void Put(const leveldb::Slice& key, const leveldb::Slice& value) + { + if (key.ToString() == needle) + { + foundEntry = true; + *deleted = false; + *foundValue = value.ToString(); + }; + }; + + virtual void Delete(const leveldb::Slice& key) + { + if (key.ToString() == needle) + { + foundEntry = true; + *deleted = true; + }; + }; +}; + +// When performing a read, if we have an active batch we need to check it first +// before reading from the database, as the rest of the code assumes that once +// a database transaction begins reads are consistent with it. It would be good +// to change that assumption in future and avoid the performance hit, though in +// practice it does not appear to be large. +bool SecMsgDB::ScanBatch(const CDataStream& key, std::string* value, bool* deleted) const +{ + if (!activeBatch) + return false; + + *deleted = false; + SecMsgBatchScanner scanner; + scanner.needle = key.str(); + scanner.deleted = deleted; + scanner.foundValue = value; + leveldb::Status s = activeBatch->Iterate(&scanner); + if (!s.ok()) + { + LogPrintf("SecMsgDB ScanBatch error: %s\n", s.ToString().c_str()); + return false; + }; + + return scanner.foundEntry; +} + +bool SecMsgDB::TxnBegin() +{ + if (activeBatch) + return true; + activeBatch = new leveldb::WriteBatch(); + return true; +}; + +bool SecMsgDB::TxnCommit() +{ + if (!activeBatch) + return false; + + leveldb::WriteOptions writeOptions; + writeOptions.sync = true; + leveldb::Status status = pdb->Write(writeOptions, activeBatch); + delete activeBatch; + activeBatch = NULL; + + if (!status.ok()) + { + LogPrintf("SecMsgDB batch commit failure: %s\n", status.ToString().c_str()); + return false; + }; + + return true; +}; + +bool SecMsgDB::TxnAbort() +{ + delete activeBatch; + activeBatch = NULL; + return true; +}; + +bool SecMsgDB::ReadPK(CKeyID& addr, CPubKey& pubkey) +{ + if (!pdb) + return false; + + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(sizeof(addr) + 2); + ssKey << 'p'; + ssKey << 'k'; + ssKey << addr; + std::string strValue; + + bool readFromDb = true; + if (activeBatch) + { + // -- check activeBatch first + bool deleted = false; + readFromDb = ScanBatch(ssKey, &strValue, &deleted) == false; + if (deleted) + return false; + }; + + if (readFromDb) + { + leveldb::Status s = pdb->Get(leveldb::ReadOptions(), ssKey.str(), &strValue); + if (!s.ok()) + { + if (s.IsNotFound()) + return false; + LogPrintf("LevelDB read failure: %s\n", s.ToString().c_str()); + return false; + }; + }; + + try { + CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); + ssValue >> pubkey; + } catch (std::exception& e) { + LogPrintf("SecMsgDB::ReadPK() unserialize threw: %s.\n", e.what()); + return false; + } + + return true; +}; + +bool SecMsgDB::WritePK(CKeyID& addr, CPubKey& pubkey) +{ + if (!pdb) + return false; + + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(sizeof(addr) + 2); + ssKey << 'p'; + ssKey << 'k'; + ssKey << addr; + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + ssValue.reserve(sizeof(pubkey)); + ssValue << pubkey; + + if (activeBatch) + { + activeBatch->Put(ssKey.str(), ssValue.str()); + return true; + }; + + leveldb::WriteOptions writeOptions; + writeOptions.sync = true; + leveldb::Status s = pdb->Put(writeOptions, ssKey.str(), ssValue.str()); + if (!s.ok()) + { + LogPrintf("SecMsgDB write failure: %s\n", s.ToString().c_str()); + return false; + }; + + return true; +}; + +bool SecMsgDB::ExistsPK(CKeyID& addr) +{ + if (!pdb) + return false; + + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(sizeof(addr)+2); + ssKey << 'p'; + ssKey << 'k'; + ssKey << addr; + std::string unused; + + if (activeBatch) + { + bool deleted; + if (ScanBatch(ssKey, &unused, &deleted) && !deleted) + { + return true; + }; + }; + + leveldb::Status s = pdb->Get(leveldb::ReadOptions(), ssKey.str(), &unused); + return s.IsNotFound() == false; +}; + + +bool SecMsgDB::NextSmesg(leveldb::Iterator* it, std::string& prefix, uint8_t* chKey, SecMsgStored& smsgStored) +{ + if (!pdb) + return false; + + if (!it->Valid()) // first run + it->Seek(prefix); + else + it->Next(); + + if (!(it->Valid() + && it->key().size() == 18 + && memcmp(it->key().data(), prefix.data(), 2) == 0)) + return false; + + memcpy(chKey, it->key().data(), 18); + + try { + CDataStream ssValue(it->value().data(), it->value().data() + it->value().size(), SER_DISK, CLIENT_VERSION); + ssValue >> smsgStored; + } catch (std::exception& e) { + LogPrintf("SecMsgDB::NextSmesg() unserialize threw: %s.\n", e.what()); + return false; + } + + return true; +}; + +bool SecMsgDB::NextSmesgKey(leveldb::Iterator* it, std::string& prefix, uint8_t* chKey) +{ + if (!pdb) + return false; + + if (!it->Valid()) // first run + it->Seek(prefix); + else + it->Next(); + + if (!(it->Valid() + && it->key().size() == 18 + && memcmp(it->key().data(), prefix.data(), 2) == 0)) + return false; + + memcpy(chKey, it->key().data(), 18); + + return true; +}; + +bool SecMsgDB::ReadSmesg(uint8_t* chKey, SecMsgStored& smsgStored) +{ + if (!pdb) + return false; + + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.write((const char*)chKey, 18); + std::string strValue; + + bool readFromDb = true; + if (activeBatch) + { + // -- check activeBatch first + bool deleted = false; + readFromDb = ScanBatch(ssKey, &strValue, &deleted) == false; + if (deleted) + return false; + }; + + if (readFromDb) + { + leveldb::Status s = pdb->Get(leveldb::ReadOptions(), ssKey.str(), &strValue); + if (!s.ok()) + { + if (s.IsNotFound()) + return false; + LogPrintf("LevelDB read failure: %s\n", s.ToString().c_str()); + return false; + }; + }; + + try { + CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); + ssValue >> smsgStored; + } catch (std::exception& e) { + LogPrintf("SecMsgDB::ReadSmesg() unserialize threw: %s.\n", e.what()); + return false; + } + + return true; +}; + +bool SecMsgDB::WriteSmesg(uint8_t* chKey, SecMsgStored& smsgStored) +{ + if (!pdb) + return false; + + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.write((const char*)chKey, 18); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + ssValue << smsgStored; + + if (activeBatch) + { + activeBatch->Put(ssKey.str(), ssValue.str()); + return true; + }; + + leveldb::WriteOptions writeOptions; + writeOptions.sync = true; + leveldb::Status s = pdb->Put(writeOptions, ssKey.str(), ssValue.str()); + if (!s.ok()) + { + LogPrintf("SecMsgDB write failed: %s\n", s.ToString().c_str()); + return false; + }; + + return true; +}; + +bool SecMsgDB::ExistsSmesg(uint8_t* chKey) +{ + if (!pdb) + return false; + + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.write((const char*)chKey, 18); + std::string unused; + + if (activeBatch) + { + bool deleted; + if (ScanBatch(ssKey, &unused, &deleted) && !deleted) + { + return true; + }; + }; + + leveldb::Status s = pdb->Get(leveldb::ReadOptions(), ssKey.str(), &unused); + return s.IsNotFound() == false; + return true; +}; + +bool SecMsgDB::EraseSmesg(uint8_t* chKey) +{ + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.write((const char*)chKey, 18); + + if (activeBatch) + { + activeBatch->Delete(ssKey.str()); + return true; + }; + + leveldb::WriteOptions writeOptions; + writeOptions.sync = true; + leveldb::Status s = pdb->Delete(writeOptions, ssKey.str()); + + if (s.ok() || s.IsNotFound()) + return true; + LogPrintf("SecMsgDB erase failed: %s\n", s.ToString().c_str()); + return false; +}; + +void ThreadSecureMsg() +{ + // -- bucket management thread + + while (fSecMsgEnabled) + { + int64_t now = GetTime(); + + if (fDebugSmsg) + LogPrintf("SecureMsgThread %d \n", now); + + int64_t cutoffTime = now - SMSG_RETENTION; + { + LOCK(cs_smsg); + + for (std::map::iterator it(smsgBuckets.begin()); it != smsgBuckets.end(); it++) + { + //if (fDebugSmsg) + // LogPrintf("Checking bucket %d", size %u \n", it->first, it->second.setTokens.size()); + if (it->first < cutoffTime) + { + if (fDebugSmsg) + LogPrintf("Removing bucket %d \n", it->first); + + std::string fileName = boost::lexical_cast(it->first); + + fs::path fullPath = GetDataDir() / "smsgStore" / (fileName + "_01.dat"); + if (fs::exists(fullPath)) + { + try { + fs::remove(fullPath); + } catch (const fs::filesystem_error& ex) + { + LogPrintf("Error removing bucket file %s.\n", ex.what()); + }; + } else + { + LogPrintf("Path %s does not exist \n", fullPath.string().c_str()); + }; + + // -- look for a wl file, it stores incoming messages when wallet is locked + fullPath = GetDataDir() / "smsgStore" / (fileName + "_01_wl.dat"); + if (fs::exists(fullPath)) + { + try { + fs::remove(fullPath); + } catch (const fs::filesystem_error& ex) + { + LogPrintf("Error removing wallet locked file %s.\n", ex.what()); + }; + }; + + smsgBuckets.erase(it); + } else + if (it->second.nLockCount > 0) // -- tick down nLockCount, so will eventually expire if peer never sends data + { + it->second.nLockCount--; + + if (it->second.nLockCount == 0) // lock timed out + { + NodeId nPeerId = it->second.nLockPeerId; + int64_t ignoreUntil = GetTime() + SMSG_TIME_IGNORE; + + if (fDebugSmsg) + LogPrintf("Lock on bucket %d for peer %d timed out.\n", it->first, nPeerId); + + // -- look through the nodes for the peer that locked this bucket + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + if (pnode->id != nPeerId) + continue; + pnode->smsgData.ignoreUntil = ignoreUntil; + + // -- alert peer that they are being ignored + std::vector vchData; + vchData.resize(8); + memcpy(&vchData[0], &ignoreUntil, 8); + pnode->PushMessage("smsgIgnore", vchData); + + if (fDebugSmsg) + LogPrintf("This node will ignore peer %d until %d.\n", nPeerId, ignoreUntil); + break; + }; + it->second.nLockPeerId = 0; + }; // if (it->second.nLockCount == 0) + }; // ! if (it->first < cutoffTime) + }; + }; // LOCK(cs_smsg); + + MilliSleep(SMSG_THREAD_DELAY * 1000); // // check every SMSG_THREAD_DELAY seconds + }; +}; + +void ThreadSecureMsgPow() +{ + // -- proof of work thread + + int rv; + std::vector vchKey; + SecMsgStored smsgStored; + + std::string sPrefix("qm"); + uint8_t chKey[18]; + + + while (fSecMsgEnabled) + { + // -- sleep at end, then fSecMsgEnabled is tested on wake + + SecMsgDB dbOutbox; + leveldb::Iterator* it; + { + LOCK(cs_smsgDB); + + if (!dbOutbox.Open("cr+")) + continue; + + // -- fifo (smallest key first) + it = dbOutbox.pdb->NewIterator(leveldb::ReadOptions()); + } + // -- break up lock, SecureMsgSetHash will take long + + for (;;) + { + { + LOCK(cs_smsgDB); + if (!dbOutbox.NextSmesg(it, sPrefix, chKey, smsgStored)) + break; + } + + uint8_t* pHeader = &smsgStored.vchMessage[0]; + uint8_t* pPayload = &smsgStored.vchMessage[SMSG_HDR_LEN]; + SecureMessage* psmsg = (SecureMessage*) pHeader; + + // -- do proof of work + rv = SecureMsgSetHash(pHeader, pPayload, psmsg->nPayload); + if (rv == 2) + break; // leave message in db, if terminated due to shutdown + + // -- message is removed here, no matter what + { + LOCK(cs_smsgDB); + dbOutbox.EraseSmesg(chKey); + } + if (rv != 0) + { + LogPrintf("SecMsgPow: Could not get proof of work hash, message removed.\n"); + continue; + }; + + // -- add to message store + { + LOCK(cs_smsg); + if (SecureMsgStore(pHeader, pPayload, psmsg->nPayload, true) != 0) + { + LogPrintf("SecMsgPow: Could not place message in buckets, message removed.\n"); + continue; + }; + } + + // -- test if message was sent to self + if (SecureMsgScanMessage(pHeader, pPayload, psmsg->nPayload, true) != 0) + { + // message recipient is not this node (or failed) + }; + }; + + { + LOCK(cs_smsg); + delete it; + } + + // -- shutdown thread waits 5 seconds, this should be less + MilliSleep(2000); // seconds + }; +}; + +int SecureMsgBuildBucketSet() +{ + /* + Build the bucket set by scanning the files in the smsgStore dir. + + smsgBuckets should be empty + */ + + if (fDebugSmsg) + LogPrintf("SecureMsgBuildBucketSet()\n"); + + int64_t now = GetTime(); + uint32_t nFiles = 0; + uint32_t nMessages = 0; + + fs::path pathSmsgDir = GetDataDir() / "smsgStore"; + fs::directory_iterator itend; + + + if (!fs::exists(pathSmsgDir) + || !fs::is_directory(pathSmsgDir)) + { + LogPrintf("Message store directory does not exist.\n"); + return 0; // not an error + } + + + for (fs::directory_iterator itd(pathSmsgDir) ; itd != itend ; ++itd) + { + if (!fs::is_regular_file(itd->status())) + continue; + + std::string fileType = (*itd).path().extension().string(); + + if (fileType.compare(".dat") != 0) + continue; + + std::string fileName = (*itd).path().filename().string(); + + + if (fDebugSmsg) + LogPrintf("Processing file: %s.\n", fileName.c_str()); + + nFiles++; + + // TODO files must be split if > 2GB + // time_noFile.dat + size_t sep = fileName.find_first_of("_"); + if (sep == std::string::npos) + continue; + + std::string stime = fileName.substr(0, sep); + + int64_t fileTime = boost::lexical_cast(stime); + + if (fileTime < now - SMSG_RETENTION) + { + LogPrintf("Dropping file %s, expired.\n", fileName.c_str()); + try { + fs::remove((*itd).path()); + } catch (const fs::filesystem_error& ex) + { + LogPrintf("Error removing bucket file %s, %s.\n", fileName.c_str(), ex.what()); + }; + continue; + }; + + if (boost::algorithm::ends_with(fileName, "_wl.dat")) + { + if (fDebugSmsg) + LogPrintf("Skipping wallet locked file: %s.\n", fileName.c_str()); + continue; + }; + + size_t nTokenSetSize = 0; + SecureMessage smsg; + { + LOCK(cs_smsg); + + std::set& tokenSet = smsgBuckets[fileTime].setTokens; + + FILE *fp; + + if (!(fp = fopen((*itd).path().string().c_str(), "rb"))) + { + LogPrintf("Error opening file: %s\n", strerror(errno)); + continue; + }; + + for (;;) + { + long int ofs = ftell(fp); + SecMsgToken token; + token.offset = ofs; + errno = 0; + if (fread(&smsg.hash[0], sizeof(uint8_t), SMSG_HDR_LEN, fp) != (size_t)SMSG_HDR_LEN) + { + if (errno != 0) + { + LogPrintf("fread header failed: %s\n", strerror(errno)); + } else + { + //LogPrintf("End of file.\n"); + }; + break; + }; + token.timestamp = smsg.timestamp; + + if (smsg.nPayload < 8) + continue; + + if (fread(token.sample, sizeof(uint8_t), 8, fp) != 8) + { + LogPrintf("fread data failed: %s\n", strerror(errno)); + break; + }; + + if (fseek(fp, smsg.nPayload-8, SEEK_CUR) != 0) + { + LogPrintf("fseek, strerror: %s.\n", strerror(errno)); + break; + }; + + tokenSet.insert(token); + }; + + fclose(fp); + + smsgBuckets[fileTime].hashBucket(); + + nTokenSetSize = tokenSet.size(); + } // LOCK(cs_smsg); + + nMessages += nTokenSetSize; + if (fDebugSmsg) + LogPrintf("Bucket %d contains %u messages.\n", fileTime, nTokenSetSize); + }; + + LogPrintf("Processed %u files, loaded %u buckets containing %u messages.\n", nFiles, smsgBuckets.size(), nMessages); + + return 0; +}; + +int SecureMsgAddWalletAddresses() +{ + if (fDebugSmsg) + LogPrintf("SecureMsgAddWalletAddresses()\n"); + + std::string sAnonPrefix("ao "); + + uint32_t nAdded = 0; + BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& entry, pwalletMain->mapAddressBook) + { + if (!IsMine(*pwalletMain, entry.first)) + continue; + + // -- skip addresses for anon outputs + if (entry.second.compare(0, sAnonPrefix.length(), sAnonPrefix) == 0) + continue; + + // TODO: skip addresses for stealth transactions + + CBitcoinAddress coinAddress(entry.first); + if (!coinAddress.IsValid()) + continue; + + std::string address; + std::string strPublicKey; + address = coinAddress.ToString(); + + bool fExists = 0; + for (std::vector::iterator it = smsgAddresses.begin(); it != smsgAddresses.end(); ++it) + { + if (address != it->sAddress) + continue; + fExists = 1; + break; + }; + + if (fExists) + continue; + + bool recvEnabled = 1; + bool recvAnon = 1; + + smsgAddresses.push_back(SecMsgAddress(address, recvEnabled, recvAnon)); + nAdded++; + }; + + if (fDebugSmsg) + LogPrintf("Added %u addresses to whitelist.\n", nAdded); + + return 0; +}; + + +int SecureMsgReadIni() +{ + if (!fSecMsgEnabled) + return false; + + if (fDebugSmsg) + LogPrintf("SecureMsgReadIni()\n"); + + fs::path fullpath = GetDataDir() / "smsg.ini"; + + + FILE *fp; + errno = 0; + if (!(fp = fopen(fullpath.string().c_str(), "r"))) + { + LogPrintf("Error opening file: %s\n", strerror(errno)); + return 1; + }; + + char cLine[512]; + char *pName, *pValue; + + char cAddress[64]; + int addrRecv, addrRecvAnon; + + while (fgets(cLine, 512, fp)) + { + cLine[strcspn(cLine, "\n")] = '\0'; + cLine[strcspn(cLine, "\r")] = '\0'; + cLine[511] = '\0'; // for safety + + // -- check that line contains a name value pair and is not a comment, or section header + if (cLine[0] == '#' || cLine[0] == '[' || strcspn(cLine, "=") < 1) + continue; + + if (!(pName = strtok(cLine, "=")) + || !(pValue = strtok(NULL, "="))) + continue; + + if (strcmp(pName, "newAddressRecv") == 0) + { + smsgOptions.fNewAddressRecv = (strcmp(pValue, "true") == 0) ? true : false; + } else + if (strcmp(pName, "newAddressAnon") == 0) + { + smsgOptions.fNewAddressAnon = (strcmp(pValue, "true") == 0) ? true : false; + } else + if (strcmp(pName, "key") == 0) + { + int rv = sscanf(pValue, "%64[^|]|%d|%d", cAddress, &addrRecv, &addrRecvAnon); + if (rv == 3) + { + smsgAddresses.push_back(SecMsgAddress(std::string(cAddress), addrRecv, addrRecvAnon)); + } else + { + LogPrintf("Could not parse key line %s, rv %d.\n", pValue, rv); + } + } else + { + LogPrintf("Unknown setting name: '%s'.", pName); + }; + }; + + LogPrintf("Loaded %u addresses.\n", smsgAddresses.size()); + + fclose(fp); + + return 0; +}; + +int SecureMsgWriteIni() +{ + if (!fSecMsgEnabled) + return false; + + if (fDebugSmsg) + LogPrintf("SecureMsgWriteIni()\n"); + + fs::path fullpath = GetDataDir() / "smsg.ini~"; + + FILE *fp; + errno = 0; + if (!(fp = fopen(fullpath.string().c_str(), "w"))) + { + LogPrintf("Error opening file: %s\n", strerror(errno)); + return 1; + }; + + if (fwrite("[Options]\n", sizeof(char), 10, fp) != 10) + { + LogPrintf("fwrite error: %s\n", strerror(errno)); + fclose(fp); + return false; + }; + + if (fprintf(fp, "newAddressRecv=%s\n", smsgOptions.fNewAddressRecv ? "true" : "false") < 0 + || fprintf(fp, "newAddressAnon=%s\n", smsgOptions.fNewAddressAnon ? "true" : "false") < 0) + { + LogPrintf("fprintf error: %s\n", strerror(errno)); + fclose(fp); + return false; + } + + if (fwrite("\n[Keys]\n", sizeof(char), 8, fp) != 8) + { + LogPrintf("fwrite error: %s\n", strerror(errno)); + fclose(fp); + return false; + }; + for (std::vector::iterator it = smsgAddresses.begin(); it != smsgAddresses.end(); ++it) + { + errno = 0; + if (fprintf(fp, "key=%s|%d|%d\n", it->sAddress.c_str(), it->fReceiveEnabled, it->fReceiveAnon) < 0) + { + LogPrintf("fprintf error: %s\n", strerror(errno)); + continue; + }; + }; + + + fclose(fp); + + + try { + fs::path finalpath = GetDataDir() / "smsg.ini"; + fs::rename(fullpath, finalpath); + } catch (const fs::filesystem_error& ex) + { + LogPrintf("Error renaming file %s, %s.\n", fullpath.string().c_str(), ex.what()); + }; + return 0; +}; + + +/** called from AppInit2() in init.cpp */ +bool SecureMsgStart(bool fDontStart, bool fScanChain) +{ + if (fDontStart) + { + LogPrintf("Secure messaging not started.\n"); + return false; + }; + + LogPrintf("Secure messaging starting.\n"); + + fSecMsgEnabled = true; + + if (SecureMsgReadIni() != 0) + LogPrintf("Failed to read smsg.ini\n"); + + if (smsgAddresses.size() < 1) + { + LogPrintf("No address keys loaded.\n"); + if (SecureMsgAddWalletAddresses() != 0) + LogPrintf("Failed to load addresses from wallet.\n"); + }; + + if (fScanChain) + { + SecureMsgScanBlockChain(); + }; + + if (SecureMsgBuildBucketSet() != 0) + { + LogPrintf("SecureMsg could not load bucket sets, secure messaging disabled.\n"); + fSecMsgEnabled = false; + return false; + }; + + threadGroupSmsg.create_thread(boost::bind(&TraceThread, "smsg", &ThreadSecureMsg)); + threadGroupSmsg.create_thread(boost::bind(&TraceThread, "smsg-pow", &ThreadSecureMsgPow)); + + /* + // -- start threads + if (!NewThread(ThreadSecureMsg, NULL) + || !NewThread(ThreadSecureMsgPow, NULL)) + { + LogPrintf("SecureMsg could not start threads, secure messaging disabled.\n"); + fSecMsgEnabled = false; + return false; + }; + */ + return true; +}; + +bool SecureMsgShutdown() +{ + if (!fSecMsgEnabled) + return false; + + LogPrintf("Stopping secure messaging.\n"); + + + if (SecureMsgWriteIni() != 0) + LogPrintf("Failed to save smsg.ini\n"); + + fSecMsgEnabled = false; + + threadGroupSmsg.interrupt_all(); + threadGroupSmsg.join_all(); + + if (smsgDB) + { + LOCK(cs_smsgDB); + delete smsgDB; + smsgDB = NULL; + }; + + return true; +}; + +bool SecureMsgEnable() +{ + // -- start secure messaging at runtime + if (fSecMsgEnabled) + { + LogPrintf("SecureMsgEnable: secure messaging is already enabled.\n"); + return false; + }; + + { + LOCK(cs_smsg); + fSecMsgEnabled = true; + + smsgAddresses.clear(); // should be empty already + if (SecureMsgReadIni() != 0) + LogPrintf("Failed to read smsg.ini\n"); + + if (smsgAddresses.size() < 1) + { + LogPrintf("No address keys loaded.\n"); + if (SecureMsgAddWalletAddresses() != 0) + LogPrintf("Failed to load addresses from wallet.\n"); + }; + + smsgBuckets.clear(); // should be empty already + + if (SecureMsgBuildBucketSet() != 0) + { + LogPrintf("SecureMsgEnable: could not load bucket sets, secure messaging disabled.\n"); + fSecMsgEnabled = false; + return false; + }; + + }; // LOCK(cs_smsg); + + // -- start threads + threadGroupSmsg.create_thread(boost::bind(&TraceThread, "smsg", &ThreadSecureMsg)); + threadGroupSmsg.create_thread(boost::bind(&TraceThread, "smsg-pow", &ThreadSecureMsgPow)); + /* + if (!NewThread(ThreadSecureMsg, NULL) + || !NewThread(ThreadSecureMsgPow, NULL)) + { + LogPrintf("SecureMsgEnable could not start threads, secure messaging disabled.\n"); + fSecMsgEnabled = false; + return false; + }; + */ + // -- ping each peer, don't know which have messaging enabled + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + pnode->PushMessage("smsgPing"); + pnode->PushMessage("smsgPong"); // Send pong as have missed initial ping sent by peer when it connected + }; + } + + LogPrintf("Secure messaging enabled.\n"); + return true; +}; + +bool SecureMsgDisable() +{ + // -- stop secure messaging at runtime + if (!fSecMsgEnabled) + { + LogPrintf("SecureMsgDisable: secure messaging is already disabled.\n"); + return false; + }; + + { + LOCK(cs_smsg); + fSecMsgEnabled = false; + + threadGroupSmsg.interrupt_all(); + threadGroupSmsg.join_all(); + + // -- clear smsgBuckets + std::map::iterator it; + it = smsgBuckets.begin(); + for (it = smsgBuckets.begin(); it != smsgBuckets.end(); ++it) + { + it->second.setTokens.clear(); + }; + smsgBuckets.clear(); + + // -- tell each smsg enabled peer that this node is disabling + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + if (!pnode->smsgData.fEnabled) + continue; + + pnode->PushMessage("smsgDisabled"); + pnode->smsgData.fEnabled = false; + }; + } + + if (SecureMsgWriteIni() != 0) + LogPrintf("Failed to save smsg.ini\n"); + + smsgAddresses.clear(); + + } // LOCK(cs_smsg); + + // -- allow time for threads to stop + MilliSleep(3000); // seconds + // TODO be certain that threads have stopped + + if (smsgDB) + { + LOCK(cs_smsgDB); + delete smsgDB; + smsgDB = NULL; + }; + + + LogPrintf("Secure messaging disabled.\n"); + return true; +}; + + +bool SecureMsgReceiveData(CNode* pfrom, std::string strCommand, CDataStream& vRecv) +{ + /* + Called from ProcessMessage + Runs in ThreadMessageHandler2 + */ + + if (fDebugSmsg) + LogPrintf("SecureMsgReceiveData() %s %s.\n", pfrom->addrName.c_str(), strCommand.c_str()); + + { + + + + if (strCommand == "smsgInv") + { + std::vector vchData; + vRecv >> vchData; + + if (vchData.size() < 4) + { + pfrom->Misbehaving(1); + return false; // not enough data received to be a valid smsgInv + }; + + int64_t now = GetTime(); + + if (now < pfrom->smsgData.ignoreUntil) + { + if (fDebugSmsg) + LogPrintf("Node is ignoring peer %d until %d.\n", pfrom->id, pfrom->smsgData.ignoreUntil); + return false; + }; + + uint32_t nBuckets = smsgBuckets.size(); + uint32_t nLocked = 0; // no. of locked buckets on this node + uint32_t nInvBuckets; // no. of bucket headers sent by peer in smsgInv + memcpy(&nInvBuckets, &vchData[0], 4); + if (fDebugSmsg) + LogPrintf("Remote node sent %d bucket headers, this has %d.\n", nInvBuckets, nBuckets); + + + // -- Check no of buckets: + if (nInvBuckets > (SMSG_RETENTION / SMSG_BUCKET_LEN) + 1) // +1 for some leeway + { + LogPrintf("Peer sent more bucket headers than possible %u, %u.\n", nInvBuckets, (SMSG_RETENTION / SMSG_BUCKET_LEN)); + pfrom->Misbehaving(1); + return false; + }; + + if (vchData.size() < 4 + nInvBuckets*16) + { + LogPrintf("Remote node did not send enough data.\n"); + pfrom->Misbehaving(1); + return false; + }; + + std::vector vchDataOut; + vchDataOut.reserve(4 + 8 * nInvBuckets); // reserve max possible size + vchDataOut.resize(4); + uint32_t nShowBuckets = 0; + + + uint8_t *p = &vchData[4]; + for (uint32_t i = 0; i < nInvBuckets; ++i) + { + int64_t time; + uint32_t ncontent, hash; + memcpy(&time, p, 8); + memcpy(&ncontent, p+8, 4); + memcpy(&hash, p+12, 4); + + p += 16; + + // Check time valid: + if (time < now - SMSG_RETENTION) + { + if (fDebugSmsg) + LogPrintf("Not interested in peer bucket %d, has expired.\n", time); + + if (time < now - SMSG_RETENTION - SMSG_TIME_LEEWAY) + pfrom->Misbehaving(1); + continue; + }; + if (time > now + SMSG_TIME_LEEWAY) + { + if (fDebugSmsg) + LogPrintf("Not interested in peer bucket %d, in the future.\n", time); + pfrom->Misbehaving(1); + continue; + }; + + if (ncontent < 1) + { + if (fDebugSmsg) + LogPrintf("Peer sent empty bucket, ignore %d %u %u.\n", time, ncontent, hash); + continue; + }; + + if (fDebugSmsg) + { + LogPrintf("peer bucket %d %u %u.\n", time, ncontent, hash); + LogPrintf("this bucket %d %u %u.\n", time, smsgBuckets[time].setTokens.size(), smsgBuckets[time].hash); + }; + { + LOCK(cs_smsg); + if (smsgBuckets[time].nLockCount > 0) + { + if (fDebugSmsg) + LogPrintf("Bucket is locked %u, waiting for peer %u to send data.\n", smsgBuckets[time].nLockCount, smsgBuckets[time].nLockPeerId); + nLocked++; + continue; + }; + + // -- if this node has more than the peer node, peer node will pull from this + // if then peer node has more this node will pull fom peer + if (smsgBuckets[time].setTokens.size() < ncontent + || (smsgBuckets[time].setTokens.size() == ncontent + && smsgBuckets[time].hash != hash)) // if same amount in buckets check hash + { + if (fDebugSmsg) + LogPrintf("Requesting contents of bucket %d.\n", time); + + uint32_t sz = vchDataOut.size(); + vchDataOut.resize(sz + 8); + memcpy(&vchDataOut[sz], &time, 8); + + nShowBuckets++; + }; + } // LOCK(cs_smsg); + }; + + // TODO: should include hash? + memcpy(&vchDataOut[0], &nShowBuckets, 4); + if (vchDataOut.size() > 4) + { + pfrom->PushMessage("smsgShow", vchDataOut); + } else + if (nLocked < 1) // Don't report buckets as matched if any are locked + { + // -- peer has no buckets we want, don't send them again until something changes + // peer will still request buckets from this node if needed (< ncontent) + vchDataOut.resize(8); + memcpy(&vchDataOut[0], &now, 8); + pfrom->PushMessage("smsgMatch", vchDataOut); + if (fDebugSmsg) + LogPrintf("Sending smsgMatch, %d.\n", now); + }; + + } else + if (strCommand == "smsgShow") + { + std::vector vchData; + vRecv >> vchData; + + if (vchData.size() < 4) + return false; + + uint32_t nBuckets; + memcpy(&nBuckets, &vchData[0], 4); + + if (vchData.size() < 4 + nBuckets * 8) + return false; + + if (fDebugSmsg) + LogPrintf("smsgShow: peer wants to see content of %u buckets.\n", nBuckets); + + std::map::iterator itb; + std::set::iterator it; + + std::vector vchDataOut; + int64_t time; + uint8_t* pIn = &vchData[4]; + for (uint32_t i = 0; i < nBuckets; ++i, pIn += 8) + { + memcpy(&time, pIn, 8); + + { + LOCK(cs_smsg); + itb = smsgBuckets.find(time); + if (itb == smsgBuckets.end()) + { + if (fDebugSmsg) + LogPrintf("Don't have bucket %d.\n", time); + continue; + }; + + std::set& tokenSet = (*itb).second.setTokens; + + try { vchDataOut.resize(8 + 16 * tokenSet.size()); } catch (std::exception& e) + { + LogPrintf("vchDataOut.resize %u threw: %s.\n", 8 + 16 * tokenSet.size(), e.what()); + continue; + }; + memcpy(&vchDataOut[0], &time, 8); + + uint8_t* p = &vchDataOut[8]; + for (it = tokenSet.begin(); it != tokenSet.end(); ++it) + { + memcpy(p, &it->timestamp, 8); + memcpy(p+8, &it->sample, 8); + + p += 16; + }; + } + pfrom->PushMessage("smsgHave", vchDataOut); + }; + + + } else + if (strCommand == "smsgHave") + { + // -- peer has these messages in bucket + std::vector vchData; + vRecv >> vchData; + + if (vchData.size() < 8) + return false; + + int n = (vchData.size() - 8) / 16; + + int64_t time; + memcpy(&time, &vchData[0], 8); + + // -- Check time valid: + int64_t now = GetTime(); + if (time < now - SMSG_RETENTION) + { + if (fDebugSmsg) + LogPrintf("Not interested in peer bucket %d, has expired.\n", time); + return false; + }; + if (time > now + SMSG_TIME_LEEWAY) + { + if (fDebugSmsg) + LogPrintf("Not interested in peer bucket %d, in the future.\n", time); + pfrom->Misbehaving(1); + return false; + }; + + std::vector vchDataOut; + + { + LOCK(cs_smsg); + if (smsgBuckets[time].nLockCount > 0) + { + if (fDebugSmsg) + LogPrintf("Bucket %d lock count %u, waiting for message data from peer %u.\n", time, smsgBuckets[time].nLockCount, smsgBuckets[time].nLockPeerId); + return false; + }; + + if (fDebugSmsg) + LogPrintf("Sifting through bucket %d.\n", time); + + vchDataOut.resize(8); + memcpy(&vchDataOut[0], &vchData[0], 8); + + std::set& tokenSet = smsgBuckets[time].setTokens; + std::set::iterator it; + SecMsgToken token; + uint8_t* p = &vchData[8]; + + for (int i = 0; i < n; ++i) + { + memcpy(&token.timestamp, p, 8); + memcpy(&token.sample, p+8, 8); + + it = tokenSet.find(token); + if (it == tokenSet.end()) + { + int nd = vchDataOut.size(); + try { + vchDataOut.resize(nd + 16); + } catch (std::exception& e) { + LogPrintf("vchDataOut.resize %d threw: %s.\n", nd + 16, e.what()); + continue; + }; + + memcpy(&vchDataOut[nd], p, 16); + }; + + p += 16; + }; + } + + if (vchDataOut.size() > 8) + { + if (fDebugSmsg) + { + LogPrintf("Asking peer for %u messages.\n", (vchDataOut.size() - 8) / 16); + LogPrintf("Locking bucket %u for peer %d.\n", time, pfrom->id); + }; + { + LOCK(cs_smsg); + smsgBuckets[time].nLockCount = 3; // lock this bucket for at most 3 * SMSG_THREAD_DELAY seconds, unset when peer sends smsgMsg + smsgBuckets[time].nLockPeerId = pfrom->id; + } + pfrom->PushMessage("smsgWant", vchDataOut); + }; + } else + if (strCommand == "smsgWant") + { + std::vector vchData; + vRecv >> vchData; + + if (vchData.size() < 8) + return false; + + std::vector vchOne; + std::vector vchBunch; + + vchBunch.resize(4+8); // nmessages + bucketTime + + int n = (vchData.size() - 8) / 16; + + int64_t time; + uint32_t nBunch = 0; + memcpy(&time, &vchData[0], 8); + + + std::map::iterator itb; + + { + LOCK(cs_smsg); + itb = smsgBuckets.find(time); + if (itb == smsgBuckets.end()) + { + if (fDebugSmsg) + LogPrintf("Don't have bucket %d.\n", time); + return false; + }; + + std::set& tokenSet = itb->second.setTokens; + std::set::iterator it; + SecMsgToken token; + uint8_t* p = &vchData[8]; + for (int i = 0; i < n; ++i) + { + memcpy(&token.timestamp, p, 8); + memcpy(&token.sample, p+8, 8); + + it = tokenSet.find(token); + if (it == tokenSet.end()) + { + if (fDebugSmsg) + LogPrintf("Don't have wanted message %d.\n", token.timestamp); + } else + { + //LogPrintf("Have message at %d.\n", it->offset); // DEBUG + token.offset = it->offset; + //LogPrintf("winb before SecureMsgRetrieve %d.\n", token.timestamp); + + // -- place in vchOne so if SecureMsgRetrieve fails it won't corrupt vchBunch + if (SecureMsgRetrieve(token, vchOne) == 0) + { + nBunch++; + vchBunch.insert(vchBunch.end(), vchOne.begin(), vchOne.end()); // append + } else + { + LogPrintf("SecureMsgRetrieve failed %d.\n", token.timestamp); + }; + + if (nBunch >= 500 + || vchBunch.size() >= 96000) + { + if (fDebugSmsg) + LogPrintf("Break bunch %u, %u.\n", nBunch, vchBunch.size()); + break; // end here, peer will send more want messages if needed. + }; + }; + p += 16; + }; + } // LOCK(cs_smsg); + + if (nBunch > 0) + { + if (fDebugSmsg) + LogPrintf("Sending block of %u messages for bucket %d.\n", nBunch, time); + + memcpy(&vchBunch[0], &nBunch, 4); + memcpy(&vchBunch[4], &time, 8); + pfrom->PushMessage("smsgMsg", vchBunch); + }; + } else + if (strCommand == "smsgMsg") + { + std::vector vchData; + vRecv >> vchData; + + if (fDebugSmsg) + LogPrintf("smsgMsg vchData.size() %u.\n", vchData.size()); + + SecureMsgReceive(pfrom, vchData); + } else + if (strCommand == "smsgMatch") + { + std::vector vchData; + vRecv >> vchData; + + + if (vchData.size() < 8) + { + LogPrintf("smsgMatch, not enough data %u.\n", vchData.size()); + pfrom->Misbehaving(1); + return false; + }; + + int64_t time; + memcpy(&time, &vchData[0], 8); + + int64_t now = GetTime(); + if (time > now + SMSG_TIME_LEEWAY) + { + LogPrintf("Warning: Peer buckets matched in the future: %d.\nEither this node or the peer node has the incorrect time set.\n", time); + if (fDebugSmsg) + LogPrintf("Peer match time set to now.\n"); + time = now; + }; + + pfrom->smsgData.lastMatched = time; + + if (fDebugSmsg) + LogPrintf("Peer buckets matched at %d.\n", time); + + } else + if (strCommand == "smsgPing") + { + // -- smsgPing is the initial message, send reply + pfrom->PushMessage("smsgPong"); + } else + if (strCommand == "smsgPong") + { + if (fDebugSmsg) + LogPrintf("Peer replied, secure messaging enabled.\n"); + + pfrom->smsgData.fEnabled = true; + } else + if (strCommand == "smsgDisabled") + { + // -- peer has disabled secure messaging. + + pfrom->smsgData.fEnabled = false; + + if (fDebugSmsg) + LogPrintf("Peer %d has disabled secure messaging.\n", pfrom->id); + + } else + if (strCommand == "smsgIgnore") + { + // -- peer is reporting that it will ignore this node until time. + // Ignore peer too + std::vector vchData; + vRecv >> vchData; + + if (vchData.size() < 8) + { + LogPrintf("smsgIgnore, not enough data %u.\n", vchData.size()); + pfrom->Misbehaving(1); + return false; + }; + + int64_t time; + memcpy(&time, &vchData[0], 8); + + pfrom->smsgData.ignoreUntil = time; + + if (fDebugSmsg) + LogPrintf("Peer %d is ignoring this node until %d, ignore peer too.\n", pfrom->id, time); + } else + { + // Unknown message + }; + + }; // LOCK(cs_smsg); + + return true; +}; + +bool SecureMsgSendData(CNode* pto, bool fSendTrickle) +{ + /* + Called from ProcessMessage + Runs in ThreadMessageHandler2 + */ + + //LogPrintf("SecureMsgSendData() %s.\n", pto->addrName.c_str()); + + + int64_t now = GetTime(); + + if (pto->smsgData.lastSeen == 0) + { + // -- first contact + if (fDebugSmsg) + LogPrintf("SecureMsgSendData() new node %s, peer id %u.\n", pto->addrName.c_str(), pto->id); + // -- Send smsgPing once, do nothing until receive 1st smsgPong (then set fEnabled) + pto->PushMessage("smsgPing"); + pto->smsgData.lastSeen = GetTime(); + return true; + } else + if (!pto->smsgData.fEnabled + || now - pto->smsgData.lastSeen < SMSG_SEND_DELAY + || now < pto->smsgData.ignoreUntil) + { + return true; + }; + + // -- When nWakeCounter == 0, resend bucket inventory. + if (pto->smsgData.nWakeCounter < 1) + { + pto->smsgData.lastMatched = 0; + pto->smsgData.nWakeCounter = 10 + GetRandInt(300); // set to a random time between [10, 300] * SMSG_SEND_DELAY seconds + + if (fDebugSmsg) + LogPrintf("SecureMsgSendData(): nWakeCounter expired, sending bucket inventory to %s.\n" + "Now %d next wake counter %u\n", pto->addrName.c_str(), now, pto->smsgData.nWakeCounter); + }; + pto->smsgData.nWakeCounter--; + + { + LOCK(cs_smsg); + std::map::iterator it; + + uint32_t nBuckets = smsgBuckets.size(); + if (nBuckets > 0) // no need to send keep alive pkts, coin messages already do that + { + std::vector vchData; + // should reserve? + vchData.reserve(4 + nBuckets*16); // timestamp + size + hash + + uint32_t nBucketsShown = 0; + vchData.resize(4); + + uint8_t* p = &vchData[4]; + for (it = smsgBuckets.begin(); it != smsgBuckets.end(); ++it) + { + SecMsgBucket &bkt = it->second; + + uint32_t nMessages = bkt.setTokens.size(); + + if (bkt.timeChanged < pto->smsgData.lastMatched // peer has this bucket + || nMessages < 1) // this bucket is empty + continue; + + + uint32_t hash = bkt.hash; + + try { vchData.resize(vchData.size() + 16); } catch (std::exception& e) + { + LogPrintf("vchData.resize %u threw: %s.\n", vchData.size() + 16, e.what()); + continue; + }; + memcpy(p, &it->first, 8); + memcpy(p+8, &nMessages, 4); + memcpy(p+12, &hash, 4); + + p += 16; + nBucketsShown++; + //if (fDebug) + // LogPrintf("Sending bucket %d, size %d \n", it->first, it->second.size()); + }; + + if (vchData.size() > 4) + { + memcpy(&vchData[0], &nBucketsShown, 4); + if (fDebugSmsg) + LogPrintf("Sending %d bucket headers.\n", nBucketsShown); + + pto->PushMessage("smsgInv", vchData); + }; + }; + } + + pto->smsgData.lastSeen = GetTime(); + + return true; +}; + + +static int SecureMsgInsertAddress(CKeyID& hashKey, CPubKey& pubKey, SecMsgDB& addrpkdb) +{ + /* insert key hash and public key to addressdb + + should have LOCK(cs_smsg) where db is opened + + returns + 0 success + 1 error + 4 address is already in db + */ + + + if (addrpkdb.ExistsPK(hashKey)) + { + //LogPrintf("DB already contains public key for address.\n"); + CPubKey cpkCheck; + if (!addrpkdb.ReadPK(hashKey, cpkCheck)) + { + LogPrintf("addrpkdb.Read failed.\n"); + } else + { + if (cpkCheck != pubKey) + LogPrintf("DB already contains existing public key that does not match .\n"); + }; + return 4; + }; + + if (!addrpkdb.WritePK(hashKey, pubKey)) + { + LogPrintf("Write pair failed.\n"); + return 1; + }; + + return 0; +}; + +int SecureMsgInsertAddress(CKeyID& hashKey, CPubKey& pubKey) +{ + int rv; + { + LOCK(cs_smsgDB); + SecMsgDB addrpkdb; + + if (!addrpkdb.Open("cr+")) + return 1; + + rv = SecureMsgInsertAddress(hashKey, pubKey, addrpkdb); + } + return rv; +}; + + +static bool ScanBlock(CBlock& block, CTxDB& txdb, SecMsgDB& addrpkdb, + uint32_t& nTransactions, uint32_t& nElements, uint32_t& nPubkeys, uint32_t& nDuplicates) +{ + AssertLockHeld(cs_smsgDB); + + valtype vch; + opcodetype opcode; + + // -- only scan inputs of standard txns and coinstakes + + BOOST_FOREACH(CTransaction& tx, block.vtx) + { + std::string sReason; + // - harvest public keys from coinstake txns + if (tx.IsCoinStake()) + { + const CTxOut& txout = tx.vout[1]; + CScript::const_iterator pc = txout.scriptPubKey.begin(); + while (pc < txout.scriptPubKey.end()) + { + if (!txout.scriptPubKey.GetOp(pc, opcode, vch)) + break; + + if (vch.size() == 33) // pubkey + { + CPubKey pubKey(vch); + + if (!pubKey.IsValid() + || !pubKey.IsCompressed()) + { + LogPrintf("Public key is invalid %s.\n", HexStr(pubKey).c_str()); + continue; + }; + + CKeyID addrKey = pubKey.GetID(); + switch (SecureMsgInsertAddress(addrKey, pubKey, addrpkdb)) + { + case 0: nPubkeys++; break; // added key + case 4: nDuplicates++; break; // duplicate key + } + break; + }; + }; + nElements++; + } else + if (IsStandardTx(tx, sReason)) + { + for (uint32_t i = 0; i < tx.vin.size(); i++) + { + CScript *script = &tx.vin[i].scriptSig; + CScript::const_iterator pc = script->begin(); + CScript::const_iterator pend = script->end(); + + uint256 prevoutHash; + CKey key; + + while (pc < pend) + { + if (!script->GetOp(pc, opcode, vch)) + break; + // -- opcode is the length of the following data, compressed public key is always 33 + if (opcode == 33) + { + CPubKey pubKey(vch); + + if (!pubKey.IsValid() + || !pubKey.IsCompressed()) + { + LogPrintf("Public key is invalid %s.\n", HexStr(pubKey).c_str()); + continue; + }; + + CKeyID addrKey = pubKey.GetID(); + switch (SecureMsgInsertAddress(addrKey, pubKey, addrpkdb)) + { + case 0: nPubkeys++; break; // added key + case 4: nDuplicates++; break; // duplicate key + } + break; + }; + + //LogPrintf("opcode %d, %s, value %s.\n", opcode, GetOpName(opcode), ValueString(vch).c_str()); + }; + nElements++; + }; + }; + nTransactions++; + + if (nTransactions % 10000 == 0) // for ScanChainForPublicKeys + { + LogPrintf("Scanning transaction no. %u.\n", nTransactions); + }; + }; + return true; +}; + + +bool SecureMsgScanBlock(CBlock& block) +{ + /* + scan block for public key addresses + called from ProcessMessage() in main where strCommand == "block" + */ + + if (fDebugSmsg) + LogPrintf("SecureMsgScanBlock().\n"); + + uint32_t nTransactions = 0; + uint32_t nElements = 0; + uint32_t nPubkeys = 0; + uint32_t nDuplicates = 0; + + { + LOCK(cs_smsgDB); + CTxDB txdb("r"); + + SecMsgDB addrpkdb; + if (!addrpkdb.Open("cw") + || !addrpkdb.TxnBegin()) + return false; + + ScanBlock(block, txdb, addrpkdb, + nTransactions, nElements, nPubkeys, nDuplicates); + + addrpkdb.TxnCommit(); + } + + if (fDebugSmsg) + LogPrintf("Found %u transactions, %u elements, %u new public keys, %u duplicates.\n", nTransactions, nElements, nPubkeys, nDuplicates); + + return true; +}; + +bool ScanChainForPublicKeys(CBlockIndex* pindexStart) +{ + LogPrintf("Scanning block chain for public keys.\n"); + int64_t nStart = GetTimeMillis(); + + if (fDebugSmsg) + LogPrintf("From height %u.\n", pindexStart->nHeight); + + // -- public keys are in txin.scriptSig + // matching addresses are in scriptPubKey of txin's referenced output + + uint32_t nBlocks = 0; + uint32_t nTransactions = 0; + uint32_t nInputs = 0; + uint32_t nPubkeys = 0; + uint32_t nDuplicates = 0; + + { + LOCK(cs_smsgDB); + + CTxDB txdb("r"); + + SecMsgDB addrpkdb; + if (!addrpkdb.Open("cw") + || !addrpkdb.TxnBegin()) + return false; + + CBlockIndex* pindex = pindexStart; + while (pindex) + { + nBlocks++; + CBlock block; + block.ReadFromDisk(pindex, true); + + ScanBlock(block, txdb, addrpkdb, + nTransactions, nInputs, nPubkeys, nDuplicates); + + pindex = pindex->pnext; + }; + + addrpkdb.TxnCommit(); + }; + + LogPrintf("Scanned %u blocks, %u transactions, %u inputs\n", nBlocks, nTransactions, nInputs); + LogPrintf("Found %u public keys, %u duplicates.\n", nPubkeys, nDuplicates); + LogPrintf("Took %d ms\n", GetTimeMillis() - nStart); + + return true; +}; + +bool SecureMsgScanBlockChain() +{ + TRY_LOCK(cs_main, lockMain); + if (lockMain) + { + CBlockIndex *pindexScan = pindexGenesisBlock; + if (pindexScan == NULL) + { + LogPrintf("Error: pindexGenesisBlock not set.\n"); + return false; + }; + + + try { // -- in try to catch errors opening db, + if (!ScanChainForPublicKeys(pindexScan)) + return false; + } catch (std::exception& e) + { + LogPrintf("ScanChainForPublicKeys() threw: %s.\n", e.what()); + return false; + }; + } else + { + LogPrintf("ScanChainForPublicKeys() Could not lock main.\n"); + return false; + }; + + return true; +}; + +bool SecureMsgScanBuckets() +{ + if (fDebugSmsg) + LogPrintf("SecureMsgScanBuckets()\n"); + + if (!fSecMsgEnabled + || pwalletMain->IsLocked()) + return false; + + int64_t mStart = GetTimeMillis(); + int64_t now = GetTime(); + uint32_t nFiles = 0; + uint32_t nMessages = 0; + uint32_t nFoundMessages = 0; + + fs::path pathSmsgDir = GetDataDir() / "smsgStore"; + fs::directory_iterator itend; + + if (!fs::exists(pathSmsgDir) + || !fs::is_directory(pathSmsgDir)) + { + LogPrintf("Message store directory does not exist.\n"); + return 0; // not an error + }; + + SecureMessage smsg; + std::vector vchData; + + for (fs::directory_iterator itd(pathSmsgDir) ; itd != itend ; ++itd) + { + if (!fs::is_regular_file(itd->status())) + continue; + + std::string fileType = (*itd).path().extension().string(); + + if (fileType.compare(".dat") != 0) + continue; + + std::string fileName = (*itd).path().filename().string(); + + + if (fDebugSmsg) + LogPrintf("Processing file: %s.\n", fileName.c_str()); + + nFiles++; + + // TODO files must be split if > 2GB + // time_noFile.dat + size_t sep = fileName.find_first_of("_"); + if (sep == std::string::npos) + continue; + + std::string stime = fileName.substr(0, sep); + + int64_t fileTime = boost::lexical_cast(stime); + + if (fileTime < now - SMSG_RETENTION) + { + LogPrintf("Dropping file %s, expired.\n", fileName.c_str()); + try { + fs::remove((*itd).path()); + } catch (const fs::filesystem_error& ex) + { + LogPrintf("Error removing bucket file %s, %s.\n", fileName.c_str(), ex.what()); + }; + continue; + }; + + if (boost::algorithm::ends_with(fileName, "_wl.dat")) + { + if (fDebugSmsg) + LogPrintf("Skipping wallet locked file: %s.\n", fileName.c_str()); + continue; + }; + + { + LOCK(cs_smsg); + FILE *fp; + errno = 0; + if (!(fp = fopen((*itd).path().string().c_str(), "rb"))) + { + LogPrintf("Error opening file: %s\n", strerror(errno)); + continue; + }; + + for (;;) + { + errno = 0; + if (fread(&smsg.hash[0], sizeof(uint8_t), SMSG_HDR_LEN, fp) != (size_t)SMSG_HDR_LEN) + { + if (errno != 0) + { + LogPrintf("fread header failed: %s\n", strerror(errno)); + } else + { + //LogPrintf("End of file.\n"); + }; + break; + }; + + try { vchData.resize(smsg.nPayload); } catch (std::exception& e) + { + LogPrintf("SecureMsgWalletUnlocked(): Could not resize vchData, %u, %s\n", smsg.nPayload, e.what()); + fclose(fp); + return 1; + }; + + if (fread(&vchData[0], sizeof(uint8_t), smsg.nPayload, fp) != smsg.nPayload) + { + LogPrintf("fread data failed: %s\n", strerror(errno)); + break; + }; + + // -- don't report to gui, + int rv = SecureMsgScanMessage(&smsg.hash[0], &vchData[0], smsg.nPayload, false); + + if (rv == 0) + { + nFoundMessages++; + } else + if (rv != 0) + { + // SecureMsgScanMessage failed + }; + + nMessages ++; + }; + + fclose(fp); + + // -- remove wl file when scanned + try { + fs::remove((*itd).path()); + } catch (const boost::filesystem::filesystem_error& ex) + { + LogPrintf("Error removing wl file %s - %s\n", fileName.c_str(), ex.what()); + return 1; + }; + }; + }; + + LogPrintf("Processed %u files, scanned %u messages, received %u messages.\n", nFiles, nMessages, nFoundMessages); + LogPrintf("Took %d ms\n", GetTimeMillis() - mStart); + + return true; +} + + +int SecureMsgWalletUnlocked() +{ + /* + When the wallet is unlocked, scan messages received while wallet was locked. + */ + if (!fSecMsgEnabled) + return 0; + + LogPrintf("SecureMsgWalletUnlocked()\n"); + + if (pwalletMain->IsLocked()) + { + LogPrintf("Error: Wallet is locked.\n"); + return 1; + }; + + int64_t now = GetTime(); + uint32_t nFiles = 0; + uint32_t nMessages = 0; + uint32_t nFoundMessages = 0; + + fs::path pathSmsgDir = GetDataDir() / "smsgStore"; + fs::directory_iterator itend; + + if (!fs::exists(pathSmsgDir) + || !fs::is_directory(pathSmsgDir)) + { + LogPrintf("Message store directory does not exist.\n"); + return 0; // not an error + }; + + SecureMessage smsg; + std::vector vchData; + + for (fs::directory_iterator itd(pathSmsgDir) ; itd != itend ; ++itd) + { + if (!fs::is_regular_file(itd->status())) + continue; + + std::string fileName = (*itd).path().filename().string(); + + if (!boost::algorithm::ends_with(fileName, "_wl.dat")) + continue; + + if (fDebugSmsg) + LogPrintf("Processing file: %s.\n", fileName.c_str()); + + nFiles++; + + // TODO files must be split if > 2GB + // time_noFile_wl.dat + size_t sep = fileName.find_first_of("_"); + if (sep == std::string::npos) + continue; + + std::string stime = fileName.substr(0, sep); + + int64_t fileTime = boost::lexical_cast(stime); + + if (fileTime < now - SMSG_RETENTION) + { + LogPrintf("Dropping wallet locked file %s, expired.\n", fileName.c_str()); + try { + fs::remove((*itd).path()); + } catch (const boost::filesystem::filesystem_error& ex) + { + LogPrintf("Error removing wl file %s - %s\n", fileName.c_str(), ex.what()); + return 1; + }; + continue; + }; + + { + LOCK(cs_smsg); + FILE *fp; + errno = 0; + if (!(fp = fopen((*itd).path().string().c_str(), "rb"))) + { + LogPrintf("Error opening file: %s\n", strerror(errno)); + continue; + }; + + for (;;) + { + errno = 0; + if (fread(&smsg.hash[0], sizeof(uint8_t), SMSG_HDR_LEN, fp) != (size_t)SMSG_HDR_LEN) + { + if (errno != 0) + { + LogPrintf("fread header failed: %s\n", strerror(errno)); + } else + { + //LogPrintf("End of file.\n"); + }; + break; + }; + + try { vchData.resize(smsg.nPayload); } catch (std::exception& e) + { + LogPrintf("SecureMsgWalletUnlocked(): Could not resize vchData, %u, %s\n", smsg.nPayload, e.what()); + fclose(fp); + return 1; + }; + + if (fread(&vchData[0], sizeof(uint8_t), smsg.nPayload, fp) != smsg.nPayload) + { + LogPrintf("fread data failed: %s\n", strerror(errno)); + break; + }; + + // -- don't report to gui, + int rv = SecureMsgScanMessage(&smsg.hash[0], &vchData[0], smsg.nPayload, false); + + if (rv == 0) + { + nFoundMessages++; + } else + if (rv != 0) + { + // SecureMsgScanMessage failed + }; + + nMessages ++; + }; + + fclose(fp); + + // -- remove wl file when scanned + try { + fs::remove((*itd).path()); + } catch (const boost::filesystem::filesystem_error& ex) + { + LogPrintf("Error removing wl file %s - %s\n", fileName.c_str(), ex.what()); + return 1; + }; + }; + }; + + LogPrintf("Processed %u files, scanned %u messages, received %u messages.\n", nFiles, nMessages, nFoundMessages); + + // -- notify gui + NotifySecMsgWalletUnlocked(); + return 0; +}; + +int SecureMsgWalletKeyChanged(std::string sAddress, std::string sLabel, ChangeType mode) +{ + if (!fSecMsgEnabled) + return 0; + + LogPrintf("SecureMsgWalletKeyChanged()\n"); + + // TODO: default recv and recvAnon + + { + LOCK(cs_smsg); + + switch(mode) + { + case CT_NEW: + smsgAddresses.push_back(SecMsgAddress(sAddress, smsgOptions.fNewAddressRecv, smsgOptions.fNewAddressAnon)); + break; + case CT_DELETED: + for (std::vector::iterator it = smsgAddresses.begin(); it != smsgAddresses.end(); ++it) + { + if (sAddress != it->sAddress) + continue; + smsgAddresses.erase(it); + break; + }; + break; + default: + break; + } + + }; // LOCK(cs_smsg); + + + return 0; +}; + +int SecureMsgScanMessage(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload, bool reportToGui) +{ + /* + Check if message belongs to this node. + If so add to inbox db. + + if !reportToGui don't fire NotifySecMsgInboxChanged + - loads messages received when wallet locked in bulk. + + returns + 0 success, + 1 error + 2 no match + 3 wallet is locked - message stored for scanning later. + */ + + if (fDebugSmsg) + LogPrintf("SecureMsgScanMessage()\n"); + + if (pwalletMain->IsLocked()) + { + if (fDebugSmsg) + LogPrintf("ScanMessage: Wallet is locked, storing message to scan later.\n"); + + int rv; + if ((rv = SecureMsgStoreUnscanned(pHeader, pPayload, nPayload)) != 0) + return 1; + + return 3; + }; + + std::string addressTo; + MessageData msg; // placeholder + bool fOwnMessage = false; + + for (std::vector::iterator it = smsgAddresses.begin(); it != smsgAddresses.end(); ++it) + { + if (!it->fReceiveEnabled) + continue; + + CBitcoinAddress coinAddress(it->sAddress); + addressTo = coinAddress.ToString(); + + if (!it->fReceiveAnon) + { + // -- have to do full decrypt to see address from + if (SecureMsgDecrypt(false, addressTo, pHeader, pPayload, nPayload, msg) == 0) + { + if (fDebugSmsg) + LogPrintf("Decrypted message with %s.\n", addressTo.c_str()); + + if (msg.sFromAddress.compare("anon") != 0) + fOwnMessage = true; + break; + }; + } else + { + + if (SecureMsgDecrypt(true, addressTo, pHeader, pPayload, nPayload, msg) == 0) + { + if (fDebugSmsg) + LogPrintf("Decrypted message with %s.\n", addressTo.c_str()); + + fOwnMessage = true; + break; + }; + } + }; + + if (fOwnMessage) + { + // -- save to inbox + SecureMessage* psmsg = (SecureMessage*) pHeader; + std::string sPrefix("im"); + uint8_t chKey[18]; + memcpy(&chKey[0], sPrefix.data(), 2); + memcpy(&chKey[2], &psmsg->timestamp, 8); + memcpy(&chKey[10], pPayload, 8); + + SecMsgStored smsgInbox; + smsgInbox.timeReceived = GetTime(); + smsgInbox.status = (SMSG_MASK_UNREAD) & 0xFF; + smsgInbox.sAddrTo = addressTo; + + // -- data may not be contiguous + try { + smsgInbox.vchMessage.resize(SMSG_HDR_LEN + nPayload); + } catch (std::exception& e) { + LogPrintf("SecureMsgScanMessage(): Could not resize vchData, %u, %s\n", SMSG_HDR_LEN + nPayload, e.what()); + return 1; + }; + memcpy(&smsgInbox.vchMessage[0], pHeader, SMSG_HDR_LEN); + memcpy(&smsgInbox.vchMessage[SMSG_HDR_LEN], pPayload, nPayload); + + { + LOCK(cs_smsgDB); + SecMsgDB dbInbox; + + if (dbInbox.Open("cw")) + { + if (dbInbox.ExistsSmesg(chKey)) + { + if (fDebugSmsg) + LogPrintf("Message already exists in inbox db.\n"); + } else + { + dbInbox.WriteSmesg(chKey, smsgInbox); + + if (reportToGui) + NotifySecMsgInboxChanged(smsgInbox); + LogPrintf("SecureMsg saved to inbox, received with %s.\n", addressTo.c_str()); + }; + }; + } + }; + + return 0; +}; + +int SecureMsgGetLocalKey(CKeyID& ckid, CPubKey& cpkOut) +{ + if (fDebugSmsg) + LogPrintf("SecureMsgGetLocalKey()\n"); + + CKey key; + if (!pwalletMain->GetKey(ckid, key)) + return 4; + + cpkOut = key.GetPubKey(); //true); + + if (!cpkOut.IsValid() + || !cpkOut.IsCompressed()) + { + LogPrintf("Public key is invalid %s.\n", HexStr(cpkOut).c_str()); + return 1; + }; + + return 0; +}; + +int SecureMsgGetLocalPublicKey(std::string& strAddress, std::string& strPublicKey) +{ + /* returns + 0 success, + 1 error + 2 invalid address + 3 address does not refer to a key + 4 address not in wallet + */ + + CBitcoinAddress address; + if (!address.SetString(strAddress)) + return 2; // Invalid coin address + + CKeyID keyID; + if (!address.GetKeyID(keyID)) + return 3; + + int rv; + CPubKey pubKey; + if ((rv = SecureMsgGetLocalKey(keyID, pubKey)) != 0) + return rv; + + strPublicKey = EncodeBase58(pubKey.begin(), pubKey.end()); + + return 0; +}; + +int SecureMsgGetStoredKey(CKeyID& ckid, CPubKey& cpkOut) +{ + /* returns + 0 success, + 1 error + 2 public key not in database + */ + if (fDebugSmsg) + LogPrintf("SecureMsgGetStoredKey().\n"); + + { + LOCK(cs_smsgDB); + SecMsgDB addrpkdb; + + if (!addrpkdb.Open("r")) + return 1; + + if (!addrpkdb.ReadPK(ckid, cpkOut)) + { + //LogPrintf("addrpkdb.Read failed: %s.\n", coinAddress.ToString().c_str()); + return 2; + }; + } + + return 0; +}; + +int SecureMsgAddAddress(std::string& address, std::string& publicKey) +{ + static const char *fn = "SecureMsgAddAddress()"; + /* + Add address and matching public key to the database + address and publicKey are in base58 + + returns + 0 success + 1 error + 2 publicKey is invalid + 3 publicKey != address + 4 address is already in db + 5 address is invalid + */ + + CBitcoinAddress coinAddress(address); + + if (!coinAddress.IsValid()) + { + LogPrintf("%s - Address is not valid: %s.\n", fn, address.c_str()); + return 5; + }; + + CKeyID hashKey; + + if (!coinAddress.GetKeyID(hashKey)) + { + LogPrintf("%s - coinAddress.GetKeyID failed: %s.\n", fn, coinAddress.ToString().c_str()); + return 5; + }; + + std::vector vchTest; + DecodeBase58(publicKey, vchTest); + CPubKey pubKey(vchTest); + + // -- check that public key matches address hash + CPubKey pubKeyT(pubKey); + if (!pubKeyT.IsValid()) + { + LogPrintf("%s - Invalid PubKey.\n", fn); + return 2; + }; + + CKeyID keyIDT = pubKeyT.GetID(); + CBitcoinAddress addressT(keyIDT); + + if (addressT.ToString().compare(address) != 0) + { + LogPrintf("%s - Public key does not hash to address, addressT %s.\n", fn, addressT.ToString().c_str()); + return 3; + }; + + return SecureMsgInsertAddress(hashKey, pubKey); +}; + +int SecureMsgRetrieve(SecMsgToken &token, std::vector& vchData) +{ + if (fDebugSmsg) + LogPrintf("SecureMsgRetrieve() %d.\n", token.timestamp); + + // -- has cs_smsg lock from SecureMsgReceiveData + + fs::path pathSmsgDir = GetDataDir() / "smsgStore"; + + //LogPrintf("token.offset %d.\n", token.offset); // DEBUG + int64_t bucket = token.timestamp - (token.timestamp % SMSG_BUCKET_LEN); + std::string fileName = boost::lexical_cast(bucket) + "_01.dat"; + fs::path fullpath = pathSmsgDir / fileName; + + //LogPrintf("bucket %d.\n", bucket); + //LogPrintf("bucket d %d.\n", bucket); + //LogPrintf("fileName %s.\n", fileName.c_str()); + + FILE *fp; + errno = 0; + if (!(fp = fopen(fullpath.string().c_str(), "rb"))) + { + LogPrintf("Error opening file: %s\nPath %s\n", strerror(errno), fullpath.string().c_str()); + return 1; + }; + + errno = 0; + if (fseek(fp, token.offset, SEEK_SET) != 0) + { + LogPrintf("fseek, strerror: %s.\n", strerror(errno)); + fclose(fp); + return 1; + }; + + SecureMessage smsg; + errno = 0; + if (fread(&smsg.hash[0], sizeof(uint8_t), SMSG_HDR_LEN, fp) != (size_t)SMSG_HDR_LEN) + { + LogPrintf("fread header failed: %s\n", strerror(errno)); + fclose(fp); + return 1; + }; + + try { + vchData.resize(SMSG_HDR_LEN + smsg.nPayload); + } catch (std::exception& e) { + LogPrintf("SecureMsgRetrieve(): Could not resize vchData, %u, %s\n", SMSG_HDR_LEN + smsg.nPayload, e.what()); + return 1; + }; + + memcpy(&vchData[0], &smsg.hash[0], SMSG_HDR_LEN); + errno = 0; + if (fread(&vchData[SMSG_HDR_LEN], sizeof(uint8_t), smsg.nPayload, fp) != smsg.nPayload) + { + LogPrintf("fread data failed: %s. Wanted %u bytes.\n", strerror(errno), smsg.nPayload); + fclose(fp); + return 1; + }; + + + fclose(fp); + + return 0; +}; + +int SecureMsgReceive(CNode* pfrom, std::vector& vchData) +{ + if (fDebugSmsg) + LogPrintf("SecureMsgReceive().\n"); + + if (vchData.size() < 12) // nBunch4 + timestamp8 + { + LogPrintf("Error: not enough data.\n"); + return 1; + }; + + uint32_t nBunch; + int64_t bktTime; + + memcpy(&nBunch, &vchData[0], 4); + memcpy(&bktTime, &vchData[4], 8); + + + // -- check bktTime () + // bucket may not exist yet - will be created when messages are added + int64_t now = GetTime(); + if (bktTime > now + SMSG_TIME_LEEWAY) + { + if (fDebugSmsg) + LogPrintf("bktTime > now.\n"); + // misbehave? + return 1; + } else + if (bktTime < now - SMSG_RETENTION) + { + if (fDebugSmsg) + LogPrintf("bktTime < now - SMSG_RETENTION.\n"); + // misbehave? + return 1; + }; + + std::map::iterator itb; + + if (nBunch == 0 || nBunch > 500) + { + LogPrintf("Error: Invalid no. messages received in bunch %u, for bucket %d.\n", nBunch, bktTime); + pfrom->Misbehaving(1); + + { + LOCK(cs_smsg); + // -- release lock on bucket if it exists + itb = smsgBuckets.find(bktTime); + if (itb != smsgBuckets.end()) + itb->second.nLockCount = 0; + } // LOCK(cs_smsg); + return 1; + }; + + uint32_t n = 12; + + for (uint32_t i = 0; i < nBunch; ++i) + { + if (vchData.size() - n < SMSG_HDR_LEN) + { + LogPrintf("Error: not enough data sent, n = %u.\n", n); + break; + }; + + SecureMessage* psmsg = (SecureMessage*) &vchData[n]; + + int rv; + if ((rv = SecureMsgValidate(&vchData[n], &vchData[n + SMSG_HDR_LEN], psmsg->nPayload)) != 0) + { + // message dropped + if (rv == 2) // invalid proof of work + { + pfrom->Misbehaving(10); + } else + { + pfrom->Misbehaving(1); + }; + continue; + }; + + { + LOCK(cs_smsg); + // -- store message, but don't hash bucket + if (SecureMsgStore(&vchData[n], &vchData[n + SMSG_HDR_LEN], psmsg->nPayload, false) != 0) + { + // message dropped + break; // continue? + }; + + if (SecureMsgScanMessage(&vchData[n], &vchData[n + SMSG_HDR_LEN], psmsg->nPayload, true) != 0) + { + // message recipient is not this node (or failed) + }; + } // LOCK(cs_smsg); + + n += SMSG_HDR_LEN + psmsg->nPayload; + }; + + { + LOCK(cs_smsg); + // -- if messages have been added, bucket must exist now + itb = smsgBuckets.find(bktTime); + if (itb == smsgBuckets.end()) + { + if (fDebugSmsg) + LogPrintf("Don't have bucket %d.\n", bktTime); + return 1; + }; + + itb->second.nLockCount = 0; // this node has received data from peer, release lock + itb->second.nLockPeerId = 0; + itb->second.hashBucket(); + } // LOCK(cs_smsg); + return 0; +}; + +int SecureMsgStoreUnscanned(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload) +{ + /* + When the wallet is locked a copy of each received message is stored to be scanned later if wallet is unlocked + */ + + if (fDebugSmsg) + LogPrintf("SecureMsgStoreUnscanned()\n"); + + if (!pHeader + || !pPayload) + { + LogPrintf("Error: null pointer to header or payload.\n"); + return 1; + }; + + SecureMessage* psmsg = (SecureMessage*) pHeader; + + fs::path pathSmsgDir; + try { + pathSmsgDir = GetDataDir() / "smsgStore"; + fs::create_directory(pathSmsgDir); + } catch (const boost::filesystem::filesystem_error& ex) + { + LogPrintf("Error: Failed to create directory %s - %s\n", pathSmsgDir.string().c_str(), ex.what()); + return 1; + }; + + int64_t now = GetTime(); + if (psmsg->timestamp > now + SMSG_TIME_LEEWAY) + { + LogPrintf("Message > now.\n"); + return 1; + } else + if (psmsg->timestamp < now - SMSG_RETENTION) + { + LogPrintf("Message < SMSG_RETENTION.\n"); + return 1; + }; + + int64_t bucket = psmsg->timestamp - (psmsg->timestamp % SMSG_BUCKET_LEN); + + std::string fileName = boost::lexical_cast(bucket) + "_01_wl.dat"; + fs::path fullpath = pathSmsgDir / fileName; + + FILE *fp; + errno = 0; + if (!(fp = fopen(fullpath.string().c_str(), "ab"))) + { + LogPrintf("Error opening file: %s\n", strerror(errno)); + return 1; + }; + + if (fwrite(pHeader, sizeof(uint8_t), SMSG_HDR_LEN, fp) != (size_t)SMSG_HDR_LEN + || fwrite(pPayload, sizeof(uint8_t), nPayload, fp) != nPayload) + { + LogPrintf("fwrite failed: %s\n", strerror(errno)); + fclose(fp); + return 1; + }; + + fclose(fp); + + return 0; +}; + + +int SecureMsgStore(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload, bool fUpdateBucket) +{ + if (fDebugSmsg) + LogPrintf("SecureMsgStore()\n"); + + AssertLockHeld(cs_smsg); + + if (!pHeader + || !pPayload) + { + LogPrintf("Error: null pointer to header or payload.\n"); + return 1; + }; + + SecureMessage* psmsg = (SecureMessage*) pHeader; + + + long int ofs; + fs::path pathSmsgDir; + try { + pathSmsgDir = GetDataDir() / "smsgStore"; + fs::create_directory(pathSmsgDir); + } catch (const boost::filesystem::filesystem_error& ex) + { + LogPrintf("Error: Failed to create directory %s - %s\n", pathSmsgDir.string().c_str(), ex.what()); + return 1; + }; + + int64_t now = GetTime(); + if (psmsg->timestamp > now + SMSG_TIME_LEEWAY) + { + LogPrintf("Message > now.\n"); + return 1; + } else + if (psmsg->timestamp < now - SMSG_RETENTION) + { + LogPrintf("Message < SMSG_RETENTION.\n"); + return 1; + }; + + int64_t bucket = psmsg->timestamp - (psmsg->timestamp % SMSG_BUCKET_LEN); + + SecMsgToken token(psmsg->timestamp, pPayload, nPayload, 0); + + std::set& tokenSet = smsgBuckets[bucket].setTokens; + std::set::iterator it; + it = tokenSet.find(token); + if (it != tokenSet.end()) + { + LogPrintf("Already have message.\n"); + if (fDebugSmsg) + { + LogPrintf("nPayload: %u\n", nPayload); + LogPrintf("bucket: %d\n", bucket); + + LogPrintf("message ts: %d", token.timestamp); + std::vector vchShow; + vchShow.resize(8); + memcpy(&vchShow[0], token.sample, 8); + LogPrintf(" sample %s\n", ValueString(vchShow).c_str()); + /* + LogPrintf("\nmessages in bucket:\n"); + for (it = tokenSet.begin(); it != tokenSet.end(); ++it) + { + LogPrintf("message ts: %d", (*it).timestamp); + vchShow.resize(8); + memcpy(&vchShow[0], (*it).sample, 8); + LogPrintf(" sample %s\n", ValueString(vchShow).c_str()); + }; + */ + }; + return 1; + }; + + std::string fileName = boost::lexical_cast(bucket) + "_01.dat"; + fs::path fullpath = pathSmsgDir / fileName; + + FILE *fp; + errno = 0; + if (!(fp = fopen(fullpath.string().c_str(), "ab"))) + { + LogPrintf("Error opening file: %s\n", strerror(errno)); + return 1; + }; + + // -- on windows ftell will always return 0 after fopen(ab), call fseek to set. + errno = 0; + if (fseek(fp, 0, SEEK_END) != 0) + { + LogPrintf("Error fseek failed: %s\n", strerror(errno)); + return 1; + }; + + + ofs = ftell(fp); + + if (fwrite(pHeader, sizeof(uint8_t), SMSG_HDR_LEN, fp) != (size_t)SMSG_HDR_LEN + || fwrite(pPayload, sizeof(uint8_t), nPayload, fp) != nPayload) + { + LogPrintf("fwrite failed: %s\n", strerror(errno)); + fclose(fp); + return 1; + }; + + fclose(fp); + + token.offset = ofs; + + //LogPrintf("token.offset: %d\n", token.offset); // DEBUG + tokenSet.insert(token); + + if (fUpdateBucket) + smsgBuckets[bucket].hashBucket(); + + if (fDebugSmsg) + LogPrintf("SecureMsg added to bucket %d.\n", bucket); + return 0; +}; + +int SecureMsgStore(SecureMessage& smsg, bool fUpdateBucket) +{ + return SecureMsgStore(&smsg.hash[0], smsg.pPayload, smsg.nPayload, fUpdateBucket); +}; + +int SecureMsgValidate(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload) +{ + /* + returns + 0 success + 1 error + 2 invalid hash + 3 checksum mismatch + 4 invalid version + 5 payload is too large + */ + SecureMessage* psmsg = (SecureMessage*) pHeader; + + if (psmsg->version[0] != 1) + return 4; + + if (nPayload > SMSG_MAX_MSG_WORST) + return 5; + + uint8_t civ[32]; + uint8_t sha256Hash[32]; + int rv = 2; // invalid + + uint32_t nonse; + memcpy(&nonse, &psmsg->nonse[0], 4); + + if (fDebugSmsg) + LogPrintf("SecureMsgValidate() nonse %u.\n", nonse); + + for (int i = 0; i < 32; i+=4) + memcpy(civ+i, &nonse, 4); + + HMAC_CTX ctx; + HMAC_CTX_init(&ctx); + + uint32_t nBytes; + if (!HMAC_Init_ex(&ctx, &civ[0], 32, EVP_sha256(), NULL) + || !HMAC_Update(&ctx, (uint8_t*) pHeader+4, SMSG_HDR_LEN-4) + || !HMAC_Update(&ctx, (uint8_t*) pPayload, nPayload) + || !HMAC_Update(&ctx, pPayload, nPayload) + || !HMAC_Final(&ctx, sha256Hash, &nBytes) + || nBytes != 32) + { + if (fDebugSmsg) + LogPrintf("HMAC error.\n"); + rv = 1; // error + } else + { + if (sha256Hash[31] == 0 + && sha256Hash[30] == 0 + && (~(sha256Hash[29]) & ((1<<0) || (1<<1) || (1<<2)) )) + { + if (fDebugSmsg) + LogPrintf("Hash Valid.\n"); + rv = 0; // smsg is valid + }; + + if (memcmp(psmsg->hash, sha256Hash, 4) != 0) + { + if (fDebugSmsg) + LogPrintf("Checksum mismatch.\n"); + rv = 3; // checksum mismatch + } + } + HMAC_CTX_cleanup(&ctx); + + return rv; +}; + +int SecureMsgSetHash(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload) +{ + /* proof of work and checksum + + May run in a thread, if shutdown detected, return. + + returns: + 0 success + 1 error + 2 stopped due to node shutdown + + */ + + SecureMessage* psmsg = (SecureMessage*) pHeader; + + int64_t nStart = GetTimeMillis(); + uint8_t civ[32]; + uint8_t sha256Hash[32]; + + bool found = false; + HMAC_CTX ctx; + HMAC_CTX_init(&ctx); + + uint32_t nonse = 0; + + //CBigNum bnTarget(2); + //bnTarget = bnTarget.pow(256 - 40); + + // -- break for HMAC_CTX_cleanup + for (;;) + { + if (!fSecMsgEnabled) + break; + + //psmsg->timestamp = GetTime(); + //memcpy(&psmsg->timestamp, &now, 8); + memcpy(&psmsg->nonse[0], &nonse, 4); + + for (int i = 0; i < 32; i+=4) + memcpy(civ+i, &nonse, 4); + + uint32_t nBytes; + if (!HMAC_Init_ex(&ctx, &civ[0], 32, EVP_sha256(), NULL) + || !HMAC_Update(&ctx, (uint8_t*) pHeader+4, SMSG_HDR_LEN-4) + || !HMAC_Update(&ctx, (uint8_t*) pPayload, nPayload) + || !HMAC_Update(&ctx, pPayload, nPayload) + || !HMAC_Final(&ctx, sha256Hash, &nBytes) + //|| !HMAC_Final(&ctx, &vchHash[0], &nBytes) + || nBytes != 32) + break; + + /* + if (CBigNum(vchHash) <= bnTarget) + { + found = true; + if (fDebugSmsg) + LogPrintf("Match %u\n", nonse); + break; + }; + */ + + if (sha256Hash[31] == 0 + && sha256Hash[30] == 0 + && (~(sha256Hash[29]) & ((1<<0) || (1<<1) || (1<<2)) )) + // && sha256Hash[29] == 0) + { + found = true; + //if (fDebugSmsg) + // LogPrintf("Match %u\n", nonse); + break; + } + + //if (nonse >= UINT32_MAX) + if (nonse >= 4294967295U) + { + if (fDebugSmsg) + LogPrintf("No match %u\n", nonse); + break; + //return 1; + } + nonse++; + }; + + HMAC_CTX_cleanup(&ctx); + + if (!fSecMsgEnabled) + { + if (fDebugSmsg) + LogPrintf("SecureMsgSetHash() stopped, shutdown detected.\n"); + return 2; + }; + + if (!found) + { + if (fDebugSmsg) + LogPrintf("SecureMsgSetHash() failed, took %d ms, nonse %u\n", GetTimeMillis() - nStart, nonse); + return 1; + }; + + memcpy(psmsg->hash, sha256Hash, 4); + //memcpy(psmsg->hash, &vchHash[0], 4); + + if (fDebugSmsg) + LogPrintf("SecureMsgSetHash() took %d ms, nonse %u\n", GetTimeMillis() - nStart, nonse); + + return 0; +}; + +int SecureMsgEncrypt(SecureMessage& smsg, std::string& addressFrom, std::string& addressTo, std::string& message) +{ + /* Create a secure message + + Using similar method to bitmessage. + If bitmessage is secure this should be too. + https://bitmessage.org/wiki/Encryption + + Some differences: + bitmessage seems to use curve sect283r1 + *coin addresses use secp256k1 + + returns + 2 message is too long. + 3 addressFrom is invalid. + 4 addressTo is invalid. + 5 Could not get public key for addressTo. + 6 ECDH_compute_key failed + 7 Could not get private key for addressFrom. + 8 Could not allocate memory. + 9 Could not compress message data. + 10 Could not generate MAC. + 11 Encrypt failed. + */ + + if (fDebugSmsg) + LogPrintf("SecureMsgEncrypt(%s, %s, ...)\n", addressFrom.c_str(), addressTo.c_str()); + + + if (message.size() > SMSG_MAX_MSG_BYTES) + { + LogPrintf("Message is too long, %u.\n", message.size()); + return 2; + }; + + smsg.version[0] = 1; + smsg.version[1] = 1; + smsg.timestamp = GetTime(); + + + bool fSendAnonymous; + CBitcoinAddress coinAddrFrom; + CKeyID ckidFrom; + CKey keyFrom; + + if (addressFrom.compare("anon") == 0) + { + fSendAnonymous = true; + + } else + { + fSendAnonymous = false; + + if (!coinAddrFrom.SetString(addressFrom)) + { + LogPrintf("addressFrom is not valid.\n"); + return 3; + }; + + if (!coinAddrFrom.GetKeyID(ckidFrom)) + { + LogPrintf("coinAddrFrom.GetKeyID failed: %s.\n", coinAddrFrom.ToString().c_str()); + return 3; + }; + }; + + + CBitcoinAddress coinAddrDest; + CKeyID ckidDest; + + if (!coinAddrDest.SetString(addressTo)) + { + LogPrintf("addressTo is not valid.\n"); + return 4; + }; + + if (!coinAddrDest.GetKeyID(ckidDest)) + { + LogPrintf("coinAddrDest.GetKeyID failed: %s.\n", coinAddrDest.ToString().c_str()); + return 4; + }; + + // -- public key K is the destination address + CPubKey cpkDestK; + if (SecureMsgGetStoredKey(ckidDest, cpkDestK) != 0 + && SecureMsgGetLocalKey(ckidDest, cpkDestK) != 0) // maybe it's a local key (outbox?) + { + LogPrintf("Could not get public key for destination address.\n"); + return 5; + }; + + + // -- Generate 16 random bytes as IV. + RandAddSeedPerfmon(); + RAND_bytes(&smsg.iv[0], 16); + + + // -- Generate a new random EC key pair with private key called r and public key called R. + CKey keyR; + keyR.MakeNewKey(true); // make compressed key + + CECKey ecKeyR; + ecKeyR.SetSecretBytes(keyR.begin()); + + // -- Do an EC point multiply with public key K and private key r. This gives you public key P. + CECKey ecKeyK; + if (!ecKeyK.SetPubKey(cpkDestK)) + { + LogPrintf("Could not set pubkey for K: %s.\n", HexStr(cpkDestK).c_str()); + return 4; // address to is invalid + }; + + std::vector vchP; + vchP.resize(32); + EC_KEY* pkeyr = ecKeyR.GetECKey(); + EC_KEY* pkeyK = ecKeyK.GetECKey(); + + // always seems to be 32, worth checking? + //int field_size = EC_GROUP_get_degree(EC_KEY_get0_group(pkeyr)); + //int secret_len = (field_size+7)/8; + //LogPrintf("secret_len %d.\n", secret_len); + + // -- ECDH_compute_key returns the same P if fed compressed or uncompressed public keys + ECDH_set_method(pkeyr, ECDH_OpenSSL()); + int lenP = ECDH_compute_key(&vchP[0], 32, EC_KEY_get0_public_key(pkeyK), pkeyr, NULL); + + if (lenP != 32) + { + LogPrintf("ECDH_compute_key failed, lenP: %d.\n", lenP); + return 6; + }; + + CPubKey cpkR = keyR.GetPubKey(); + if (!cpkR.IsValid() + || !cpkR.IsCompressed()) + { + LogPrintf("Could not get public key for key R.\n"); + return 1; + }; + + memcpy(smsg.cpkR, cpkR.begin(), 33); + + + // -- Use public key P and calculate the SHA512 hash H. + // The first 32 bytes of H are called key_e and the last 32 bytes are called key_m. + std::vector vchHashed; + vchHashed.resize(64); // 512 + SHA512(&vchP[0], vchP.size(), (uint8_t*)&vchHashed[0]); + std::vector key_e(&vchHashed[0], &vchHashed[0]+32); + std::vector key_m(&vchHashed[32], &vchHashed[32]+32); + + + std::vector vchPayload; + std::vector vchCompressed; + uint8_t* pMsgData; + uint32_t lenMsgData; + + uint32_t lenMsg = message.size(); + if (lenMsg > 128) + { + // -- only compress if over 128 bytes + int worstCase = LZ4_compressBound(message.size()); + try { + vchCompressed.resize(worstCase); + } catch (std::exception& e) { + LogPrintf("vchCompressed.resize %u threw: %s.\n", worstCase, e.what()); + return 8; + }; + + int lenComp = LZ4_compress((char*)message.c_str(), (char*)&vchCompressed[0], lenMsg); + if (lenComp < 1) + { + LogPrintf("Could not compress message data.\n"); + return 9; + }; + + pMsgData = &vchCompressed[0]; + lenMsgData = lenComp; + + } else + { + // -- no compression + pMsgData = (uint8_t*)message.c_str(); + lenMsgData = lenMsg; + }; + + if (fSendAnonymous) + { + try { + vchPayload.resize(9 + lenMsgData); + } catch (std::exception& e) { + LogPrintf("vchPayload.resize %u threw: %s.\n", 9 + lenMsgData, e.what()); + return 8; + }; + + memcpy(&vchPayload[9], pMsgData, lenMsgData); + + vchPayload[0] = 250; // id as anonymous message + // -- next 4 bytes are unused - there to ensure encrypted payload always > 8 bytes + memcpy(&vchPayload[5], &lenMsg, 4); // length of uncompressed plain text + } else + { + try { + vchPayload.resize(SMSG_PL_HDR_LEN + lenMsgData); + } catch (std::exception& e) { + LogPrintf("vchPayload.resize %u threw: %s.\n", SMSG_PL_HDR_LEN + lenMsgData, e.what()); + return 8; + }; + + memcpy(&vchPayload[SMSG_PL_HDR_LEN], pMsgData, lenMsgData); + // -- compact signature proves ownership of from address and allows the public key to be recovered, recipient can always reply. + if (!pwalletMain->GetKey(ckidFrom, keyFrom)) + { + LogPrintf("Could not get private key for addressFrom.\n"); + return 7; + }; + + // -- sign the plaintext + std::vector vchSignature; + vchSignature.resize(65); + keyFrom.SignCompact(Hash(message.begin(), message.end()), vchSignature); + + // -- Save some bytes by sending address raw + vchPayload[0] = (static_cast(&coinAddrFrom))->getVersion(); // vchPayload[0] = coinAddrDest.nVersion; + memcpy(&vchPayload[1], (static_cast(&ckidFrom))->GetPPN(), 20); // memcpy(&vchPayload[1], ckidDest.pn, 20); + + memcpy(&vchPayload[1+20], &vchSignature[0], vchSignature.size()); + memcpy(&vchPayload[1+20+65], &lenMsg, 4); // length of uncompressed plain text + }; + + + SecMsgCrypter crypter; + crypter.SetKey(key_e, smsg.iv); + std::vector vchCiphertext; + + if (!crypter.Encrypt(&vchPayload[0], vchPayload.size(), vchCiphertext)) + { + LogPrintf("crypter.Encrypt failed.\n"); + return 11; + }; + + try { smsg.pPayload = new uint8_t[vchCiphertext.size()]; } catch (std::exception& e) + { + LogPrintf("Could not allocate pPayload, exception: %s.\n", e.what()); + return 8; + }; + + memcpy(smsg.pPayload, &vchCiphertext[0], vchCiphertext.size()); + smsg.nPayload = vchCiphertext.size(); + + + // -- Calculate a 32 byte MAC with HMACSHA256, using key_m as salt + // Message authentication code, (hash of timestamp + destination + payload) + bool fHmacOk = true; + uint32_t nBytes = 32; + HMAC_CTX ctx; + HMAC_CTX_init(&ctx); + + if (!HMAC_Init_ex(&ctx, &key_m[0], 32, EVP_sha256(), NULL) + || !HMAC_Update(&ctx, (uint8_t*) &smsg.timestamp, sizeof(smsg.timestamp)) + || !HMAC_Update(&ctx, &vchCiphertext[0], vchCiphertext.size()) + || !HMAC_Final(&ctx, smsg.mac, &nBytes) + || nBytes != 32) + fHmacOk = false; + + HMAC_CTX_cleanup(&ctx); + + if (!fHmacOk) + { + LogPrintf("Could not generate MAC.\n"); + return 10; + }; + + + return 0; +}; + +int SecureMsgSend(std::string& addressFrom, std::string& addressTo, std::string& message, std::string& sError) +{ + /* Encrypt secure message, and place it on the network + Make a copy of the message to sender's first address and place in send queue db + proof of work thread will pick up messages from send queue db + + */ + + if (fDebugSmsg) + LogPrintf("SecureMsgSend(%s, %s, ...)\n", addressFrom.c_str(), addressTo.c_str()); + + if (pwalletMain->IsLocked()) + { + sError = "Wallet is locked, wallet must be unlocked to send and recieve messages."; + LogPrintf("Wallet is locked, wallet must be unlocked to send and recieve messages.\n"); + return 1; + }; + + if (message.size() > SMSG_MAX_MSG_BYTES) + { + std::ostringstream oss; + oss << message.size() << " > " << SMSG_MAX_MSG_BYTES; + sError = "Message is too long, " + oss.str(); + LogPrintf("Message is too long, %u.\n", message.size()); + return 1; + }; + + + int rv; + SecureMessage smsg; + + if ((rv = SecureMsgEncrypt(smsg, addressFrom, addressTo, message)) != 0) + { + LogPrintf("SecureMsgSend(), encrypt for recipient failed.\n"); + + switch(rv) + { + case 2: sError = "Message is too long."; break; + case 3: sError = "Invalid addressFrom."; break; + case 4: sError = "Invalid addressTo."; break; + case 5: sError = "Could not get public key for addressTo."; break; + case 6: sError = "ECDH_compute_key failed."; break; + case 7: sError = "Could not get private key for addressFrom."; break; + case 8: sError = "Could not allocate memory."; break; + case 9: sError = "Could not compress message data."; break; + case 10: sError = "Could not generate MAC."; break; + case 11: sError = "Encrypt failed."; break; + default: sError = "Unspecified Error."; break; + }; + + return rv; + }; + + + // -- Place message in send queue, proof of work will happen in a thread. + std::string sPrefix("qm"); + uint8_t chKey[18]; + memcpy(&chKey[0], sPrefix.data(), 2); + memcpy(&chKey[2], &smsg.timestamp, 8); + memcpy(&chKey[10], &smsg.pPayload, 8); + + SecMsgStored smsgSQ; + + smsgSQ.timeReceived = GetTime(); + smsgSQ.sAddrTo = addressTo; + + try { + smsgSQ.vchMessage.resize(SMSG_HDR_LEN + smsg.nPayload); + } catch (std::exception& e) { + LogPrintf("smsgSQ.vchMessage.resize %u threw: %s.\n", SMSG_HDR_LEN + smsg.nPayload, e.what()); + sError = "Could not allocate memory."; + return 8; + }; + + memcpy(&smsgSQ.vchMessage[0], &smsg.hash[0], SMSG_HDR_LEN); + memcpy(&smsgSQ.vchMessage[SMSG_HDR_LEN], smsg.pPayload, smsg.nPayload); + + { + LOCK(cs_smsgDB); + SecMsgDB dbSendQueue; + if (dbSendQueue.Open("cw")) + { + dbSendQueue.WriteSmesg(chKey, smsgSQ); + //NotifySecMsgSendQueueChanged(smsgOutbox); + }; + } + + // TODO: only update outbox when proof of work thread is done. + + // -- for outbox create a copy encrypted for owned address + // if the wallet is encrypted private key needed to decrypt will be unavailable + + if (fDebugSmsg) + LogPrintf("Encrypting message for outbox.\n"); + + std::string addressOutbox = "None"; + CBitcoinAddress coinAddrOutbox; + + BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& entry, pwalletMain->mapAddressBook) + { + // -- get first owned address + if (!IsMine(*pwalletMain, entry.first)) + continue; + + const CBitcoinAddress& address = entry.first; + + addressOutbox = address.ToString(); + if (!coinAddrOutbox.SetString(addressOutbox)) // test valid + continue; + break; + }; + + if (addressOutbox == "None") + { + LogPrintf("Warning: SecureMsgSend() could not find an address to encrypt outbox message with.\n"); + } else + { + if (fDebugSmsg) + LogPrintf("Encrypting a copy for outbox, using address %s\n", addressOutbox.c_str()); + + SecureMessage smsgForOutbox; + if ((rv = SecureMsgEncrypt(smsgForOutbox, addressFrom, addressOutbox, message)) != 0) + { + LogPrintf("SecureMsgSend(), encrypt for outbox failed, %d.\n", rv); + } else + { + // -- save sent message to db + std::string sPrefix("sm"); + uint8_t chKey[18]; + memcpy(&chKey[0], sPrefix.data(), 2); + memcpy(&chKey[2], &smsgForOutbox.timestamp, 8); + memcpy(&chKey[10], &smsgForOutbox.pPayload, 8); // sample + + SecMsgStored smsgOutbox; + + smsgOutbox.timeReceived = GetTime(); + smsgOutbox.sAddrTo = addressTo; + smsgOutbox.sAddrOutbox = addressOutbox; + + try { + smsgOutbox.vchMessage.resize(SMSG_HDR_LEN + smsgForOutbox.nPayload); + } catch (std::exception& e) { + LogPrintf("smsgOutbox.vchMessage.resize %u threw: %s.\n", SMSG_HDR_LEN + smsgForOutbox.nPayload, e.what()); + sError = "Could not allocate memory."; + return 8; + }; + memcpy(&smsgOutbox.vchMessage[0], &smsgForOutbox.hash[0], SMSG_HDR_LEN); + memcpy(&smsgOutbox.vchMessage[SMSG_HDR_LEN], smsgForOutbox.pPayload, smsgForOutbox.nPayload); + + + { + LOCK(cs_smsgDB); + SecMsgDB dbSent; + + if (dbSent.Open("cw")) + { + dbSent.WriteSmesg(chKey, smsgOutbox); + NotifySecMsgOutboxChanged(smsgOutbox); + }; + } + }; + }; + + if (fDebugSmsg) + LogPrintf("Secure message queued for sending to %s.\n", addressTo.c_str()); + + return 0; +}; + + +int SecureMsgDecrypt(bool fTestOnly, std::string& address, uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload, MessageData& msg) +{ + /* Decrypt secure message + + address is the owned address to decrypt with. + + validate first in SecureMsgValidate + + returns + 1 Error + 2 Unknown version number + 3 Decrypt address is not valid. + 8 Could not allocate memory + */ + + if (fDebugSmsg) + LogPrintf("SecureMsgDecrypt(), using %s, testonly %d.\n", address.c_str(), fTestOnly); + + if (!pHeader + || !pPayload) + { + LogPrintf("Error: null pointer to header or payload.\n"); + return 1; + }; + + SecureMessage* psmsg = (SecureMessage*) pHeader; + + + if (psmsg->version[0] != 1) + { + LogPrintf("Unknown version number.\n"); + return 2; + }; + + + + // -- Fetch private key k, used to decrypt + CBitcoinAddress coinAddrDest; + CKeyID ckidDest; + CKey keyDest; + if (!coinAddrDest.SetString(address)) + { + LogPrintf("Address is not valid.\n"); + return 3; + }; + if (!coinAddrDest.GetKeyID(ckidDest)) + { + LogPrintf("coinAddrDest.GetKeyID failed: %s.\n", coinAddrDest.ToString().c_str()); + return 3; + }; + if (!pwalletMain->GetKey(ckidDest, keyDest)) + { + LogPrintf("Could not get private key for addressDest.\n"); + return 3; + }; + + + + CPubKey cpkR(psmsg->cpkR, psmsg->cpkR+33); + if (!cpkR.IsValid()) + { + LogPrintf("Could not get pubkey for key R.\n"); + return 1; + }; + + CECKey ecKeyR; + if (!ecKeyR.SetPubKey(cpkR)) + { + LogPrintf("Could not set pubkey for key R: %s.\n", HexStr(cpkR).c_str()); + return 1; + }; + + CECKey ecKeyDest; + ecKeyDest.SetSecretBytes(keyDest.begin()); + + // -- Do an EC point multiply with private key k and public key R. This gives you public key P. + std::vector vchP; + vchP.resize(32); + EC_KEY* pkeyk = ecKeyDest.GetECKey(); + EC_KEY* pkeyR = ecKeyR.GetECKey(); + + ECDH_set_method(pkeyk, ECDH_OpenSSL()); + int lenPdec = ECDH_compute_key(&vchP[0], 32, EC_KEY_get0_public_key(pkeyR), pkeyk, NULL); + + if (lenPdec != 32) + { + LogPrintf("ECDH_compute_key failed, lenPdec: %d.\n", lenPdec); + return 1; + }; + + + // -- Use public key P to calculate the SHA512 hash H. + // The first 32 bytes of H are called key_e and the last 32 bytes are called key_m. + std::vector vchHashedDec; + vchHashedDec.resize(64); // 512 bits + SHA512(&vchP[0], vchP.size(), (uint8_t*)&vchHashedDec[0]); + std::vector key_e(&vchHashedDec[0], &vchHashedDec[0]+32); + std::vector key_m(&vchHashedDec[32], &vchHashedDec[32]+32); + + + // -- Message authentication code, (hash of timestamp + destination + payload) + uint8_t MAC[32]; + bool fHmacOk = true; + uint32_t nBytes = 32; + HMAC_CTX ctx; + HMAC_CTX_init(&ctx); + + if (!HMAC_Init_ex(&ctx, &key_m[0], 32, EVP_sha256(), NULL) + || !HMAC_Update(&ctx, (uint8_t*) &psmsg->timestamp, sizeof(psmsg->timestamp)) + || !HMAC_Update(&ctx, pPayload, nPayload) + || !HMAC_Final(&ctx, MAC, &nBytes) + || nBytes != 32) + fHmacOk = false; + + HMAC_CTX_cleanup(&ctx); + + if (!fHmacOk) + { + LogPrintf("Could not generate MAC.\n"); + return 1; + }; + + if (memcmp(MAC, psmsg->mac, 32) != 0) + { + if (fDebugSmsg) + LogPrintf("MAC does not match.\n"); // expected if message is not to address on node + + return 1; + }; + + if (fTestOnly) + return 0; + + SecMsgCrypter crypter; + crypter.SetKey(key_e, psmsg->iv); + std::vector vchPayload; + if (!crypter.Decrypt(pPayload, nPayload, vchPayload)) + { + LogPrintf("Decrypt failed.\n"); + return 1; + }; + + msg.timestamp = psmsg->timestamp; + uint32_t lenData; + uint32_t lenPlain; + + uint8_t* pMsgData; + bool fFromAnonymous; + if ((uint32_t)vchPayload[0] == 250) + { + fFromAnonymous = true; + lenData = vchPayload.size() - (9); + memcpy(&lenPlain, &vchPayload[5], 4); + pMsgData = &vchPayload[9]; + } else + { + fFromAnonymous = false; + lenData = vchPayload.size() - (SMSG_PL_HDR_LEN); + memcpy(&lenPlain, &vchPayload[1+20+65], 4); + pMsgData = &vchPayload[SMSG_PL_HDR_LEN]; + }; + + try { + msg.vchMessage.resize(lenPlain + 1); + } catch (std::exception& e) { + LogPrintf("msg.vchMessage.resize %u threw: %s.\n", lenPlain + 1, e.what()); + return 8; + }; + + + if (lenPlain > 128) + { + // -- decompress + if (LZ4_decompress_safe((char*) pMsgData, (char*) &msg.vchMessage[0], lenData, lenPlain) != (int) lenPlain) + { + LogPrintf("Could not decompress message data.\n"); + return 1; + }; + } else + { + // -- plaintext + memcpy(&msg.vchMessage[0], pMsgData, lenPlain); + }; + + msg.vchMessage[lenPlain] = '\0'; + + if (fFromAnonymous) + { + // -- Anonymous sender + msg.sFromAddress = "anon"; + } else + { + std::vector vchUint160; + vchUint160.resize(20); + + memcpy(&vchUint160[0], &vchPayload[1], 20); + + uint160 ui160(vchUint160); + CKeyID ckidFrom(ui160); + + CBitcoinAddress coinAddrFrom; + coinAddrFrom.Set(ckidFrom); + if (!coinAddrFrom.IsValid()) + { + LogPrintf("From Addess is invalid.\n"); + return 1; + }; + + std::vector vchSig; + vchSig.resize(65); + + memcpy(&vchSig[0], &vchPayload[1+20], 65); + + CPubKey cpkFromSig; + cpkFromSig.RecoverCompact(Hash(msg.vchMessage.begin(), msg.vchMessage.end()-1), vchSig); + if (!cpkFromSig.IsValid()) + { + LogPrintf("Signature validation failed.\n"); + return 1; + }; + + // -- get address for the compressed public key + CBitcoinAddress coinAddrFromSig; + coinAddrFromSig.Set(cpkFromSig.GetID()); + + if (!(coinAddrFrom == coinAddrFromSig)) + { + LogPrintf("Signature validation failed.\n"); + return 1; + }; + + int rv = 5; + try { + rv = SecureMsgInsertAddress(ckidFrom, cpkFromSig); + } catch (std::exception& e) { + LogPrintf("SecureMsgInsertAddress(), exception: %s.\n", e.what()); + //return 1; + }; + + switch(rv) + { + case 0: + LogPrintf("Sender public key added to db.\n"); + break; + case 4: + LogPrintf("Sender public key already in db.\n"); + break; + default: + LogPrintf("Error adding sender public key to db.\n"); + break; + }; + + msg.sFromAddress = coinAddrFrom.ToString(); + }; + + if (fDebugSmsg) + LogPrintf("Decrypted message for %s.\n", address.c_str()); + + return 0; +}; + +int SecureMsgDecrypt(bool fTestOnly, std::string& address, SecureMessage& smsg, MessageData& msg) +{ + return SecureMsgDecrypt(fTestOnly, address, &smsg.hash[0], smsg.pPayload, smsg.nPayload, msg); +}; + diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/smessage.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/smessage.h new file mode 100644 index 0000000..3f141ea --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/smessage.h @@ -0,0 +1,379 @@ +// Copyright (c) 2014 The ShadowCoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef SEC_MESSAGE_H +#define SEC_MESSAGE_H + +#include +#include + +#include "net.h" +#include "db.h" +#include "wallet.h" +#include "lz4/lz4.h" +#include "base58.h" + +const unsigned int SMSG_HDR_LEN = 104; // length of unencrypted header, 4 + 2 + 1 + 8 + 16 + 33 + 32 + 4 +4 +const unsigned int SMSG_PL_HDR_LEN = 1+20+65+4; // length of encrypted header in payload + +const unsigned int SMSG_BUCKET_LEN = 60 * 10; // in seconds +const unsigned int SMSG_RETENTION = 60 * 60 * 48; // in seconds +const unsigned int SMSG_SEND_DELAY = 2; // in seconds, SecureMsgSendData will delay this long between firing +const unsigned int SMSG_THREAD_DELAY = 20; + +const unsigned int SMSG_TIME_LEEWAY = 60; +const unsigned int SMSG_TIME_IGNORE = 90; // seconds that a peer is ignored for if they fail to deliver messages for a smsgWant + + +const unsigned int SMSG_MAX_MSG_BYTES = 4096; // the user input part + +// max size of payload worst case compression +const unsigned int SMSG_MAX_MSG_WORST = LZ4_COMPRESSBOUND(SMSG_MAX_MSG_BYTES+SMSG_PL_HDR_LEN); + + + +#define SMSG_MASK_UNREAD (1 << 0) + + + +extern bool fSecMsgEnabled; + +class SecMsgStored; + +// Inbox db changed, called with lock cs_smsgDB held. +extern boost::signals2::signal NotifySecMsgInboxChanged; + +// Outbox db changed, called with lock cs_smsgDB held. +extern boost::signals2::signal NotifySecMsgOutboxChanged; + +// Wallet Unlocked, called after all messages received while locked have been processed. +extern boost::signals2::signal NotifySecMsgWalletUnlocked; + + +class SecMsgBucket; +class SecMsgAddress; +class SecMsgOptions; + +extern std::map smsgBuckets; +extern std::vector smsgAddresses; +extern SecMsgOptions smsgOptions; + +extern CCriticalSection cs_smsg; // all except inbox and outbox +extern CCriticalSection cs_smsgDB; + + +#pragma pack(push, 1) +class SecureMessage +{ +public: + SecureMessage() + { + nPayload = 0; + pPayload = NULL; + }; + + ~SecureMessage() + { + if (pPayload) + delete[] pPayload; + pPayload = NULL; + }; + + uint8_t hash[4]; + uint8_t version[2]; + uint8_t flags; + int64_t timestamp; + uint8_t iv[16]; + uint8_t cpkR[33]; + uint8_t mac[32]; + uint8_t nonse[4]; + uint32_t nPayload; + uint8_t* pPayload; + +}; +#pragma pack(pop) + + +class MessageData +{ +// -- Decrypted SecureMessage data +public: + int64_t timestamp; + std::string sToAddress; + std::string sFromAddress; + std::vector vchMessage; // null terminated plaintext +}; + + +class SecMsgToken +{ +public: + SecMsgToken(int64_t ts, uint8_t* p, int np, long int o) + { + timestamp = ts; + + if (np < 8) // payload will always be > 8, just make sure + memset(sample, 0, 8); + else + memcpy(sample, p, 8); + offset = o; + }; + + SecMsgToken() {}; + + ~SecMsgToken() {}; + + bool operator <(const SecMsgToken& y) const + { + // pack and memcmp from timesent? + if (timestamp == y.timestamp) + return memcmp(sample, y.sample, 8) < 0; + return timestamp < y.timestamp; + } + + int64_t timestamp; // doesn't need to be full 64 bytes? + uint8_t sample[8]; // first 8 bytes of payload - a hash + int64_t offset; // offset + +}; + + +class SecMsgBucket +{ +public: + SecMsgBucket() + { + timeChanged = 0; + hash = 0; + nLockCount = 0; + nLockPeerId = 0; + }; + ~SecMsgBucket() {}; + + void hashBucket(); + + int64_t timeChanged; + uint32_t hash; // token set should get ordered the same on each node + uint32_t nLockCount; // set when smsgWant first sent, unset at end of smsgMsg, ticks down in ThreadSecureMsg() + NodeId nLockPeerId; // id of peer that bucket is locked for + std::set setTokens; + +}; + + +// -- get at the data +class CBitcoinAddress_B : public CBitcoinAddress +{ +public: + uint8_t getVersion() + { + // TODO: fix + if (vchVersion.size() > 0) + return vchVersion[0]; + return 0; + } +}; + +class CKeyID_B : public CKeyID +{ +public: + uint32_t* GetPPN() + { + return pn; + } +}; + + +class SecMsgAddress +{ +public: + SecMsgAddress() {}; + SecMsgAddress(std::string sAddr, bool receiveOn, bool receiveAnon) + { + sAddress = sAddr; + fReceiveEnabled = receiveOn; + fReceiveAnon = receiveAnon; + }; + + std::string sAddress; + bool fReceiveEnabled; + bool fReceiveAnon; + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->sAddress); + READWRITE(this->fReceiveEnabled); + READWRITE(this->fReceiveAnon); + ); +}; + +class SecMsgOptions +{ +public: + SecMsgOptions() + { + // -- default options + fNewAddressRecv = true; + fNewAddressAnon = true; + } + + bool fNewAddressRecv; + bool fNewAddressAnon; +}; + + +class SecMsgCrypter +{ +private: + uint8_t chKey[32]; + uint8_t chIV[16]; + bool fKeySet; +public: + + SecMsgCrypter() + { + // Try to keep the key data out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap) + // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) + // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process. + LockedPageManager::instance.LockRange(&chKey[0], sizeof chKey); + LockedPageManager::instance.LockRange(&chIV[0], sizeof chIV); + fKeySet = false; + } + + ~SecMsgCrypter() + { + // clean key + memset(&chKey, 0, sizeof chKey); + memset(&chIV, 0, sizeof chIV); + fKeySet = false; + + LockedPageManager::instance.UnlockRange(&chKey[0], sizeof chKey); + LockedPageManager::instance.UnlockRange(&chIV[0], sizeof chIV); + } + + bool SetKey(const std::vector& vchNewKey, uint8_t* chNewIV); + bool SetKey(const uint8_t* chNewKey, uint8_t* chNewIV); + bool Encrypt(uint8_t* chPlaintext, uint32_t nPlain, std::vector &vchCiphertext); + bool Decrypt(uint8_t* chCiphertext, uint32_t nCipher, std::vector& vchPlaintext); +}; + + +class SecMsgStored +{ +public: + int64_t timeReceived; + char status; // read etc + uint16_t folderId; + std::string sAddrTo; // when in owned addr, when sent remote addr + std::string sAddrOutbox; // owned address this copy was encrypted with + std::vector vchMessage; // message header + encryped payload + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->timeReceived); + READWRITE(this->status); + READWRITE(this->folderId); + READWRITE(this->sAddrTo); + READWRITE(this->sAddrOutbox); + READWRITE(this->vchMessage); + ); +}; + +class SecMsgDB +{ +public: + SecMsgDB() + { + activeBatch = NULL; + }; + + ~SecMsgDB() + { + // -- deletes only data scoped to this TxDB object. + + if (activeBatch) + delete activeBatch; + }; + + bool Open(const char* pszMode="r+"); + + bool ScanBatch(const CDataStream& key, std::string* value, bool* deleted) const; + + bool TxnBegin(); + bool TxnCommit(); + bool TxnAbort(); + + bool ReadPK(CKeyID& addr, CPubKey& pubkey); + bool WritePK(CKeyID& addr, CPubKey& pubkey); + bool ExistsPK(CKeyID& addr); + + bool NextSmesg(leveldb::Iterator* it, std::string& prefix, uint8_t* vchKey, SecMsgStored& smsgStored); + bool NextSmesgKey(leveldb::Iterator* it, std::string& prefix, uint8_t* vchKey); + bool ReadSmesg(uint8_t* chKey, SecMsgStored& smsgStored); + bool WriteSmesg(uint8_t* chKey, SecMsgStored& smsgStored); + bool ExistsSmesg(uint8_t* chKey); + bool EraseSmesg(uint8_t* chKey); + + leveldb::DB *pdb; // points to the global instance + leveldb::WriteBatch *activeBatch; + +}; + + +int SecureMsgBuildBucketSet(); +int SecureMsgAddWalletAddresses(); + +int SecureMsgReadIni(); +int SecureMsgWriteIni(); + +bool SecureMsgStart(bool fDontStart, bool fScanChain); +bool SecureMsgShutdown(); + +bool SecureMsgEnable(); +bool SecureMsgDisable(); + +bool SecureMsgReceiveData(CNode* pfrom, std::string strCommand, CDataStream& vRecv); +bool SecureMsgSendData(CNode* pto, bool fSendTrickle); + + +bool SecureMsgScanBlock(CBlock& block); +bool ScanChainForPublicKeys(CBlockIndex* pindexStart); +bool SecureMsgScanBlockChain(); +bool SecureMsgScanBuckets(); + + +int SecureMsgWalletUnlocked(); +int SecureMsgWalletKeyChanged(std::string sAddress, std::string sLabel, ChangeType mode); + +int SecureMsgScanMessage(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload, bool reportToGui); + +int SecureMsgGetStoredKey(CKeyID& ckid, CPubKey& cpkOut); +int SecureMsgGetLocalKey(CKeyID& ckid, CPubKey& cpkOut); +int SecureMsgGetLocalPublicKey(std::string& strAddress, std::string& strPublicKey); + +int SecureMsgAddAddress(std::string& address, std::string& publicKey); + +int SecureMsgRetrieve(SecMsgToken &token, std::vector& vchData); + +int SecureMsgReceive(CNode* pfrom, std::vector& vchData); + +int SecureMsgStoreUnscanned(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload); +int SecureMsgStore(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload, bool fUpdateBucket); +int SecureMsgStore(SecureMessage& smsg, bool fUpdateBucket); + + + +int SecureMsgSend(std::string& addressFrom, std::string& addressTo, std::string& message, std::string& sError); + +int SecureMsgValidate(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload); +int SecureMsgSetHash(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload); + +int SecureMsgEncrypt(SecureMessage& smsg, std::string& addressFrom, std::string& addressTo, std::string& message); + +int SecureMsgDecrypt(bool fTestOnly, std::string& address, uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload, MessageData& msg); +int SecureMsgDecrypt(bool fTestOnly, std::string& address, SecureMessage& smsg, MessageData& msg); + + + +#endif // SEC_MESSAGE_H + diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_blake.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_blake.h new file mode 100644 index 0000000..d8d7943 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_blake.h @@ -0,0 +1,327 @@ +/* $Id: sph_blake.h 252 2011-06-07 17:55:14Z tp $ */ +/** + * BLAKE interface. BLAKE is a family of functions which differ by their + * output size; this implementation defines BLAKE for output sizes 224, + * 256, 384 and 512 bits. This implementation conforms to the "third + * round" specification. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_blake.h + * @author Thomas Pornin + */ + +#ifndef SPH_BLAKE_H__ +#define SPH_BLAKE_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for BLAKE-224. + */ +#define SPH_SIZE_blake224 224 + +/** + * Output size (in bits) for BLAKE-256. + */ +#define SPH_SIZE_blake256 256 + +#if SPH_64 + +/** + * Output size (in bits) for BLAKE-384. + */ +#define SPH_SIZE_blake384 384 + +/** + * Output size (in bits) for BLAKE-512. + */ +#define SPH_SIZE_blake512 512 + +#endif + +/** + * This structure is a context for BLAKE-224 and BLAKE-256 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a BLAKE computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running BLAKE + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + sph_u32 H[8]; + sph_u32 S[4]; + sph_u32 T0, T1; +#endif +} sph_blake_small_context; + +/** + * This structure is a context for BLAKE-224 computations. It is + * identical to the common sph_blake_small_context. + */ +typedef sph_blake_small_context sph_blake224_context; + +/** + * This structure is a context for BLAKE-256 computations. It is + * identical to the common sph_blake_small_context. + */ +typedef sph_blake_small_context sph_blake256_context; + +#if SPH_64 + +/** + * This structure is a context for BLAKE-384 and BLAKE-512 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a BLAKE computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running BLAKE + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[128]; /* first field, for alignment */ + size_t ptr; + sph_u64 H[8]; + sph_u64 S[4]; + sph_u64 T0, T1; +#endif +} sph_blake_big_context; + +/** + * This structure is a context for BLAKE-384 computations. It is + * identical to the common sph_blake_small_context. + */ +typedef sph_blake_big_context sph_blake384_context; + +/** + * This structure is a context for BLAKE-512 computations. It is + * identical to the common sph_blake_small_context. + */ +typedef sph_blake_big_context sph_blake512_context; + +#endif + +/** + * Initialize a BLAKE-224 context. This process performs no memory allocation. + * + * @param cc the BLAKE-224 context (pointer to a + * sph_blake224_context) + */ +void sph_blake224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the BLAKE-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_blake224(void *cc, const void *data, size_t len); + +/** + * Terminate the current BLAKE-224 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the BLAKE-224 context + * @param dst the destination buffer + */ +void sph_blake224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the BLAKE-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_blake224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a BLAKE-256 context. This process performs no memory allocation. + * + * @param cc the BLAKE-256 context (pointer to a + * sph_blake256_context) + */ +void sph_blake256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the BLAKE-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_blake256(void *cc, const void *data, size_t len); + +/** + * Terminate the current BLAKE-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the BLAKE-256 context + * @param dst the destination buffer + */ +void sph_blake256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the BLAKE-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_blake256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#if SPH_64 + +/** + * Initialize a BLAKE-384 context. This process performs no memory allocation. + * + * @param cc the BLAKE-384 context (pointer to a + * sph_blake384_context) + */ +void sph_blake384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the BLAKE-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_blake384(void *cc, const void *data, size_t len); + +/** + * Terminate the current BLAKE-384 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the BLAKE-384 context + * @param dst the destination buffer + */ +void sph_blake384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the BLAKE-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_blake384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a BLAKE-512 context. This process performs no memory allocation. + * + * @param cc the BLAKE-512 context (pointer to a + * sph_blake512_context) + */ +void sph_blake512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the BLAKE-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_blake512(void *cc, const void *data, size_t len); + +/** + * Terminate the current BLAKE-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the BLAKE-512 context + * @param dst the destination buffer + */ +void sph_blake512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the BLAKE-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_blake512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_bmw.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_bmw.h new file mode 100644 index 0000000..d386b0c --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_bmw.h @@ -0,0 +1,328 @@ +/* $Id: sph_bmw.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * BMW interface. BMW (aka "Blue Midnight Wish") is a family of + * functions which differ by their output size; this implementation + * defines BMW for output sizes 224, 256, 384 and 512 bits. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_bmw.h + * @author Thomas Pornin + */ + +#ifndef SPH_BMW_H__ +#define SPH_BMW_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for BMW-224. + */ +#define SPH_SIZE_bmw224 224 + +/** + * Output size (in bits) for BMW-256. + */ +#define SPH_SIZE_bmw256 256 + +#if SPH_64 + +/** + * Output size (in bits) for BMW-384. + */ +#define SPH_SIZE_bmw384 384 + +/** + * Output size (in bits) for BMW-512. + */ +#define SPH_SIZE_bmw512 512 + +#endif + +/** + * This structure is a context for BMW-224 and BMW-256 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a BMW computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running BMW + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + sph_u32 H[16]; +#if SPH_64 + sph_u64 bit_count; +#else + sph_u32 bit_count_high, bit_count_low; +#endif +#endif +} sph_bmw_small_context; + +/** + * This structure is a context for BMW-224 computations. It is + * identical to the common sph_bmw_small_context. + */ +typedef sph_bmw_small_context sph_bmw224_context; + +/** + * This structure is a context for BMW-256 computations. It is + * identical to the common sph_bmw_small_context. + */ +typedef sph_bmw_small_context sph_bmw256_context; + +#if SPH_64 + +/** + * This structure is a context for BMW-384 and BMW-512 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a BMW computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running BMW + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[128]; /* first field, for alignment */ + size_t ptr; + sph_u64 H[16]; + sph_u64 bit_count; +#endif +} sph_bmw_big_context; + +/** + * This structure is a context for BMW-384 computations. It is + * identical to the common sph_bmw_small_context. + */ +typedef sph_bmw_big_context sph_bmw384_context; + +/** + * This structure is a context for BMW-512 computations. It is + * identical to the common sph_bmw_small_context. + */ +typedef sph_bmw_big_context sph_bmw512_context; + +#endif + +/** + * Initialize a BMW-224 context. This process performs no memory allocation. + * + * @param cc the BMW-224 context (pointer to a + * sph_bmw224_context) + */ +void sph_bmw224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the BMW-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_bmw224(void *cc, const void *data, size_t len); + +/** + * Terminate the current BMW-224 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the BMW-224 context + * @param dst the destination buffer + */ +void sph_bmw224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the BMW-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_bmw224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a BMW-256 context. This process performs no memory allocation. + * + * @param cc the BMW-256 context (pointer to a + * sph_bmw256_context) + */ +void sph_bmw256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the BMW-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_bmw256(void *cc, const void *data, size_t len); + +/** + * Terminate the current BMW-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the BMW-256 context + * @param dst the destination buffer + */ +void sph_bmw256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the BMW-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_bmw256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#if SPH_64 + +/** + * Initialize a BMW-384 context. This process performs no memory allocation. + * + * @param cc the BMW-384 context (pointer to a + * sph_bmw384_context) + */ +void sph_bmw384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the BMW-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_bmw384(void *cc, const void *data, size_t len); + +/** + * Terminate the current BMW-384 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the BMW-384 context + * @param dst the destination buffer + */ +void sph_bmw384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the BMW-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_bmw384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a BMW-512 context. This process performs no memory allocation. + * + * @param cc the BMW-512 context (pointer to a + * sph_bmw512_context) + */ +void sph_bmw512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the BMW-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_bmw512(void *cc, const void *data, size_t len); + +/** + * Terminate the current BMW-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the BMW-512 context + * @param dst the destination buffer + */ +void sph_bmw512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the BMW-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_bmw512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_cubehash.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_cubehash.h new file mode 100644 index 0000000..487a194 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_cubehash.h @@ -0,0 +1,292 @@ +/* $Id: sph_cubehash.h 180 2010-05-08 02:29:25Z tp $ */ +/** + * CubeHash interface. CubeHash is a family of functions which differ by + * their output size; this implementation defines CubeHash for output + * sizes 224, 256, 384 and 512 bits, with the "standard parameters" + * (CubeHash16/32 with the CubeHash specification notations). + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_cubehash.h + * @author Thomas Pornin + */ + +#ifndef SPH_CUBEHASH_H__ +#define SPH_CUBEHASH_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for CubeHash-224. + */ +#define SPH_SIZE_cubehash224 224 + +/** + * Output size (in bits) for CubeHash-256. + */ +#define SPH_SIZE_cubehash256 256 + +/** + * Output size (in bits) for CubeHash-384. + */ +#define SPH_SIZE_cubehash384 384 + +/** + * Output size (in bits) for CubeHash-512. + */ +#define SPH_SIZE_cubehash512 512 + +/** + * This structure is a context for CubeHash computations: it contains the + * intermediate values and some data from the last entered block. Once + * a CubeHash computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running CubeHash computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[32]; /* first field, for alignment */ + size_t ptr; + sph_u32 state[32]; +#endif +} sph_cubehash_context; + +/** + * Type for a CubeHash-224 context (identical to the common context). + */ +typedef sph_cubehash_context sph_cubehash224_context; + +/** + * Type for a CubeHash-256 context (identical to the common context). + */ +typedef sph_cubehash_context sph_cubehash256_context; + +/** + * Type for a CubeHash-384 context (identical to the common context). + */ +typedef sph_cubehash_context sph_cubehash384_context; + +/** + * Type for a CubeHash-512 context (identical to the common context). + */ +typedef sph_cubehash_context sph_cubehash512_context; + +/** + * Initialize a CubeHash-224 context. This process performs no memory + * allocation. + * + * @param cc the CubeHash-224 context (pointer to a + * sph_cubehash224_context) + */ +void sph_cubehash224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the CubeHash-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_cubehash224(void *cc, const void *data, size_t len); + +/** + * Terminate the current CubeHash-224 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the CubeHash-224 context + * @param dst the destination buffer + */ +void sph_cubehash224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the CubeHash-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_cubehash224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a CubeHash-256 context. This process performs no memory + * allocation. + * + * @param cc the CubeHash-256 context (pointer to a + * sph_cubehash256_context) + */ +void sph_cubehash256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the CubeHash-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_cubehash256(void *cc, const void *data, size_t len); + +/** + * Terminate the current CubeHash-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the CubeHash-256 context + * @param dst the destination buffer + */ +void sph_cubehash256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the CubeHash-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_cubehash256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a CubeHash-384 context. This process performs no memory + * allocation. + * + * @param cc the CubeHash-384 context (pointer to a + * sph_cubehash384_context) + */ +void sph_cubehash384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the CubeHash-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_cubehash384(void *cc, const void *data, size_t len); + +/** + * Terminate the current CubeHash-384 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the CubeHash-384 context + * @param dst the destination buffer + */ +void sph_cubehash384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the CubeHash-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_cubehash384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a CubeHash-512 context. This process performs no memory + * allocation. + * + * @param cc the CubeHash-512 context (pointer to a + * sph_cubehash512_context) + */ +void sph_cubehash512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the CubeHash-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_cubehash512(void *cc, const void *data, size_t len); + +/** + * Terminate the current CubeHash-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the CubeHash-512 context + * @param dst the destination buffer + */ +void sph_cubehash512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the CubeHash-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_cubehash512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_echo.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_echo.h new file mode 100644 index 0000000..1ae1e3d --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_echo.h @@ -0,0 +1,320 @@ +/* $Id: sph_echo.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * ECHO interface. ECHO is a family of functions which differ by + * their output size; this implementation defines ECHO for output + * sizes 224, 256, 384 and 512 bits. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_echo.h + * @author Thomas Pornin + */ + +#ifndef SPH_ECHO_H__ +#define SPH_ECHO_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for ECHO-224. + */ +#define SPH_SIZE_echo224 224 + +/** + * Output size (in bits) for ECHO-256. + */ +#define SPH_SIZE_echo256 256 + +/** + * Output size (in bits) for ECHO-384. + */ +#define SPH_SIZE_echo384 384 + +/** + * Output size (in bits) for ECHO-512. + */ +#define SPH_SIZE_echo512 512 + +/** + * This structure is a context for ECHO computations: it contains the + * intermediate values and some data from the last entered block. Once + * an ECHO computation has been performed, the context can be reused for + * another computation. This specific structure is used for ECHO-224 + * and ECHO-256. + * + * The contents of this structure are private. A running ECHO computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[192]; /* first field, for alignment */ + size_t ptr; + union { + sph_u32 Vs[4][4]; +#if SPH_64 + sph_u64 Vb[4][2]; +#endif + } u; + sph_u32 C0, C1, C2, C3; +#endif +} sph_echo_small_context; + +/** + * This structure is a context for ECHO computations: it contains the + * intermediate values and some data from the last entered block. Once + * an ECHO computation has been performed, the context can be reused for + * another computation. This specific structure is used for ECHO-384 + * and ECHO-512. + * + * The contents of this structure are private. A running ECHO computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[128]; /* first field, for alignment */ + size_t ptr; + union { + sph_u32 Vs[8][4]; +#if SPH_64 + sph_u64 Vb[8][2]; +#endif + } u; + sph_u32 C0, C1, C2, C3; +#endif +} sph_echo_big_context; + +/** + * Type for a ECHO-224 context (identical to the common "small" context). + */ +typedef sph_echo_small_context sph_echo224_context; + +/** + * Type for a ECHO-256 context (identical to the common "small" context). + */ +typedef sph_echo_small_context sph_echo256_context; + +/** + * Type for a ECHO-384 context (identical to the common "big" context). + */ +typedef sph_echo_big_context sph_echo384_context; + +/** + * Type for a ECHO-512 context (identical to the common "big" context). + */ +typedef sph_echo_big_context sph_echo512_context; + +/** + * Initialize an ECHO-224 context. This process performs no memory allocation. + * + * @param cc the ECHO-224 context (pointer to a + * sph_echo224_context) + */ +void sph_echo224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the ECHO-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_echo224(void *cc, const void *data, size_t len); + +/** + * Terminate the current ECHO-224 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the ECHO-224 context + * @param dst the destination buffer + */ +void sph_echo224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the ECHO-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_echo224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize an ECHO-256 context. This process performs no memory allocation. + * + * @param cc the ECHO-256 context (pointer to a + * sph_echo256_context) + */ +void sph_echo256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the ECHO-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_echo256(void *cc, const void *data, size_t len); + +/** + * Terminate the current ECHO-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the ECHO-256 context + * @param dst the destination buffer + */ +void sph_echo256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the ECHO-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_echo256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize an ECHO-384 context. This process performs no memory allocation. + * + * @param cc the ECHO-384 context (pointer to a + * sph_echo384_context) + */ +void sph_echo384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the ECHO-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_echo384(void *cc, const void *data, size_t len); + +/** + * Terminate the current ECHO-384 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the ECHO-384 context + * @param dst the destination buffer + */ +void sph_echo384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the ECHO-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_echo384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize an ECHO-512 context. This process performs no memory allocation. + * + * @param cc the ECHO-512 context (pointer to a + * sph_echo512_context) + */ +void sph_echo512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the ECHO-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_echo512(void *cc, const void *data, size_t len); + +/** + * Terminate the current ECHO-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the ECHO-512 context + * @param dst the destination buffer + */ +void sph_echo512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the ECHO-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_echo512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_groestl.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_groestl.h new file mode 100644 index 0000000..495f05e --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_groestl.h @@ -0,0 +1,329 @@ +/* $Id: sph_groestl.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * Groestl interface. This code implements Groestl with the recommended + * parameters for SHA-3, with outputs of 224, 256, 384 and 512 bits. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_groestl.h + * @author Thomas Pornin + */ + +#ifndef SPH_GROESTL_H__ +#define SPH_GROESTL_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for Groestl-224. + */ +#define SPH_SIZE_groestl224 224 + +/** + * Output size (in bits) for Groestl-256. + */ +#define SPH_SIZE_groestl256 256 + +/** + * Output size (in bits) for Groestl-384. + */ +#define SPH_SIZE_groestl384 384 + +/** + * Output size (in bits) for Groestl-512. + */ +#define SPH_SIZE_groestl512 512 + +/** + * This structure is a context for Groestl-224 and Groestl-256 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a Groestl computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running Groestl + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + union { +#if SPH_64 + sph_u64 wide[8]; +#endif + sph_u32 narrow[16]; + } state; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_groestl_small_context; + +/** + * This structure is a context for Groestl-224 computations. It is + * identical to the common sph_groestl_small_context. + */ +typedef sph_groestl_small_context sph_groestl224_context; + +/** + * This structure is a context for Groestl-256 computations. It is + * identical to the common sph_groestl_small_context. + */ +typedef sph_groestl_small_context sph_groestl256_context; + +/** + * This structure is a context for Groestl-384 and Groestl-512 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a Groestl computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running Groestl + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[128]; /* first field, for alignment */ + size_t ptr; + union { +#if SPH_64 + sph_u64 wide[16]; +#endif + sph_u32 narrow[32]; + } state; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_groestl_big_context; + +/** + * This structure is a context for Groestl-384 computations. It is + * identical to the common sph_groestl_small_context. + */ +typedef sph_groestl_big_context sph_groestl384_context; + +/** + * This structure is a context for Groestl-512 computations. It is + * identical to the common sph_groestl_small_context. + */ +typedef sph_groestl_big_context sph_groestl512_context; + +/** + * Initialize a Groestl-224 context. This process performs no memory allocation. + * + * @param cc the Groestl-224 context (pointer to a + * sph_groestl224_context) + */ +void sph_groestl224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Groestl-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_groestl224(void *cc, const void *data, size_t len); + +/** + * Terminate the current Groestl-224 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the Groestl-224 context + * @param dst the destination buffer + */ +void sph_groestl224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Groestl-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_groestl224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Groestl-256 context. This process performs no memory allocation. + * + * @param cc the Groestl-256 context (pointer to a + * sph_groestl256_context) + */ +void sph_groestl256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Groestl-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_groestl256(void *cc, const void *data, size_t len); + +/** + * Terminate the current Groestl-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the Groestl-256 context + * @param dst the destination buffer + */ +void sph_groestl256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Groestl-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_groestl256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Groestl-384 context. This process performs no memory allocation. + * + * @param cc the Groestl-384 context (pointer to a + * sph_groestl384_context) + */ +void sph_groestl384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Groestl-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_groestl384(void *cc, const void *data, size_t len); + +/** + * Terminate the current Groestl-384 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the Groestl-384 context + * @param dst the destination buffer + */ +void sph_groestl384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Groestl-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_groestl384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Groestl-512 context. This process performs no memory allocation. + * + * @param cc the Groestl-512 context (pointer to a + * sph_groestl512_context) + */ +void sph_groestl512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Groestl-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_groestl512(void *cc, const void *data, size_t len); + +/** + * Terminate the current Groestl-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the Groestl-512 context + * @param dst the destination buffer + */ +void sph_groestl512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Groestl-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_groestl512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_jh.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_jh.h new file mode 100644 index 0000000..82fae58 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_jh.h @@ -0,0 +1,298 @@ +/* $Id: sph_jh.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * JH interface. JH is a family of functions which differ by + * their output size; this implementation defines JH for output + * sizes 224, 256, 384 and 512 bits. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_jh.h + * @author Thomas Pornin + */ + +#ifndef SPH_JH_H__ +#define SPH_JH_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for JH-224. + */ +#define SPH_SIZE_jh224 224 + +/** + * Output size (in bits) for JH-256. + */ +#define SPH_SIZE_jh256 256 + +/** + * Output size (in bits) for JH-384. + */ +#define SPH_SIZE_jh384 384 + +/** + * Output size (in bits) for JH-512. + */ +#define SPH_SIZE_jh512 512 + +/** + * This structure is a context for JH computations: it contains the + * intermediate values and some data from the last entered block. Once + * a JH computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running JH computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + union { +#if SPH_64 + sph_u64 wide[16]; +#endif + sph_u32 narrow[32]; + } H; +#if SPH_64 + sph_u64 block_count; +#else + sph_u32 block_count_high, block_count_low; +#endif +#endif +} sph_jh_context; + +/** + * Type for a JH-224 context (identical to the common context). + */ +typedef sph_jh_context sph_jh224_context; + +/** + * Type for a JH-256 context (identical to the common context). + */ +typedef sph_jh_context sph_jh256_context; + +/** + * Type for a JH-384 context (identical to the common context). + */ +typedef sph_jh_context sph_jh384_context; + +/** + * Type for a JH-512 context (identical to the common context). + */ +typedef sph_jh_context sph_jh512_context; + +/** + * Initialize a JH-224 context. This process performs no memory allocation. + * + * @param cc the JH-224 context (pointer to a + * sph_jh224_context) + */ +void sph_jh224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the JH-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_jh224(void *cc, const void *data, size_t len); + +/** + * Terminate the current JH-224 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the JH-224 context + * @param dst the destination buffer + */ +void sph_jh224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the JH-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_jh224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a JH-256 context. This process performs no memory allocation. + * + * @param cc the JH-256 context (pointer to a + * sph_jh256_context) + */ +void sph_jh256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the JH-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_jh256(void *cc, const void *data, size_t len); + +/** + * Terminate the current JH-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the JH-256 context + * @param dst the destination buffer + */ +void sph_jh256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the JH-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_jh256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a JH-384 context. This process performs no memory allocation. + * + * @param cc the JH-384 context (pointer to a + * sph_jh384_context) + */ +void sph_jh384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the JH-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_jh384(void *cc, const void *data, size_t len); + +/** + * Terminate the current JH-384 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the JH-384 context + * @param dst the destination buffer + */ +void sph_jh384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the JH-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_jh384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a JH-512 context. This process performs no memory allocation. + * + * @param cc the JH-512 context (pointer to a + * sph_jh512_context) + */ +void sph_jh512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the JH-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_jh512(void *cc, const void *data, size_t len); + +/** + * Terminate the current JH-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the JH-512 context + * @param dst the destination buffer + */ +void sph_jh512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the JH-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_jh512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_keccak.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_keccak.h new file mode 100644 index 0000000..bdafdb8 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sph_keccak.h @@ -0,0 +1,293 @@ +/* $Id: sph_keccak.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * Keccak interface. This is the interface for Keccak with the + * recommended parameters for SHA-3, with output lengths 224, 256, + * 384 and 512 bits. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_keccak.h + * @author Thomas Pornin + */ + +#ifndef SPH_KECCAK_H__ +#define SPH_KECCAK_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for Keccak-224. + */ +#define SPH_SIZE_keccak224 224 + +/** + * Output size (in bits) for Keccak-256. + */ +#define SPH_SIZE_keccak256 256 + +/** + * Output size (in bits) for Keccak-384. + */ +#define SPH_SIZE_keccak384 384 + +/** + * Output size (in bits) for Keccak-512. + */ +#define SPH_SIZE_keccak512 512 + +/** + * This structure is a context for Keccak computations: it contains the + * intermediate values and some data from the last entered block. Once a + * Keccak computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running Keccak computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[144]; /* first field, for alignment */ + size_t ptr, lim; + union { +#if SPH_64 + sph_u64 wide[25]; +#endif + sph_u32 narrow[50]; + } u; +#endif +} sph_keccak_context; + +/** + * Type for a Keccak-224 context (identical to the common context). + */ +typedef sph_keccak_context sph_keccak224_context; + +/** + * Type for a Keccak-256 context (identical to the common context). + */ +typedef sph_keccak_context sph_keccak256_context; + +/** + * Type for a Keccak-384 context (identical to the common context). + */ +typedef sph_keccak_context sph_keccak384_context; + +/** + * Type for a Keccak-512 context (identical to the common context). + */ +typedef sph_keccak_context sph_keccak512_context; + +/** + * Initialize a Keccak-224 context. This process performs no memory allocation. + * + * @param cc the Keccak-224 context (pointer to a + * sph_keccak224_context) + */ +void sph_keccak224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Keccak-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_keccak224(void *cc, const void *data, size_t len); + +/** + * Terminate the current Keccak-224 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the Keccak-224 context + * @param dst the destination buffer + */ +void sph_keccak224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Keccak-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_keccak224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Keccak-256 context. This process performs no memory allocation. + * + * @param cc the Keccak-256 context (pointer to a + * sph_keccak256_context) + */ +void sph_keccak256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Keccak-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_keccak256(void *cc, const void *data, size_t len); + +/** + * Terminate the current Keccak-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the Keccak-256 context + * @param dst the destination buffer + */ +void sph_keccak256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Keccak-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_keccak256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Keccak-384 context. This process performs no memory allocation. + * + * @param cc the Keccak-384 context (pointer to a + * sph_keccak384_context) + */ +void sph_keccak384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Keccak-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_keccak384(void *cc, const void *data, size_t len); + +/** + * Terminate the current Keccak-384 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the Keccak-384 context + * @param dst the destination buffer + */ +void sph_keccak384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Keccak-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_keccak384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Keccak-512 context. This process performs no memory allocation. + * + * @param cc the Keccak-512 context (pointer to a + * sph_keccak512_context) + */ +void sph_keccak512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Keccak-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_keccak512(void *cc, const void *data, size_t len); + +/** + * Terminate the current Keccak-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the Keccak-512 context + * @param dst the destination buffer + */ +void sph_keccak512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Keccak-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_keccak512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/strlcpy.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/strlcpy.h new file mode 100644 index 0000000..2cc786e --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/strlcpy.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef BITCOIN_STRLCPY_H +#define BITCOIN_STRLCPY_H + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +inline size_t strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) + { + while (--n != 0) + { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) + { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +inline size_t strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') + { + if (n != 1) + { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sync.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sync.cpp new file mode 100644 index 0000000..e624a9e --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sync.cpp @@ -0,0 +1,148 @@ +// Copyright (c) 2011-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "sync.h" + +#include "util.h" + +#include + +#ifdef DEBUG_LOCKCONTENTION +void PrintLockContention(const char* pszName, const char* pszFile, int nLine) +{ + LogPrintf("LOCKCONTENTION: %s\n", pszName); + LogPrintf("Locker: %s:%d\n", pszFile, nLine); +} +#endif /* DEBUG_LOCKCONTENTION */ + +#ifdef DEBUG_LOCKORDER +// +// Early deadlock detection. +// Problem being solved: +// Thread 1 locks A, then B, then C +// Thread 2 locks D, then C, then A +// --> may result in deadlock between the two threads, depending on when they run. +// Solution implemented here: +// Keep track of pairs of locks: (A before B), (A before C), etc. +// Complain if any thread tries to lock in a different order. +// + +struct CLockLocation +{ + CLockLocation(const char* pszName, const char* pszFile, int nLine) + { + mutexName = pszName; + sourceFile = pszFile; + sourceLine = nLine; + } + + std::string ToString() const + { + return mutexName+" "+sourceFile+":"+itostr(sourceLine); + } + + std::string MutexName() const { return mutexName; } + +private: + std::string mutexName; + std::string sourceFile; + int sourceLine; +}; + +typedef std::vector< std::pair > LockStack; + +static boost::mutex dd_mutex; +static std::map, LockStack> lockorders; +static boost::thread_specific_ptr lockstack; + + +static void potential_deadlock_detected(const std::pair& mismatch, const LockStack& s1, const LockStack& s2) +{ + LogPrintf("POTENTIAL DEADLOCK DETECTED\n"); + LogPrintf("Previous lock order was:\n"); + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2) + { + if (i.first == mismatch.first) LogPrintf(" (1)"); + if (i.first == mismatch.second) LogPrintf(" (2)"); + LogPrintf(" %s\n", i.second.ToString()); + } + LogPrintf("Current lock order is:\n"); + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1) + { + if (i.first == mismatch.first) LogPrintf(" (1)"); + if (i.first == mismatch.second) LogPrintf(" (2)"); + LogPrintf(" %s\n", i.second.ToString()); + } +} + +static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) +{ + if (lockstack.get() == NULL) + lockstack.reset(new LockStack); + + LogPrint("lock", "Locking: %s\n", locklocation.ToString()); + dd_mutex.lock(); + + (*lockstack).push_back(std::make_pair(c, locklocation)); + + if (!fTry) { + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack)) { + if (i.first == c) break; + + std::pair p1 = std::make_pair(i.first, c); + if (lockorders.count(p1)) + continue; + lockorders[p1] = (*lockstack); + + std::pair p2 = std::make_pair(c, i.first); + if (lockorders.count(p2)) + { + potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]); + break; + } + } + } + dd_mutex.unlock(); +} + +static void pop_lock() +{ + if (fDebug) + { + const CLockLocation& locklocation = (*lockstack).rbegin()->second; + LogPrint("lock", "Unlocked: %s\n", locklocation.ToString()); + } + dd_mutex.lock(); + (*lockstack).pop_back(); + dd_mutex.unlock(); +} + +void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry) +{ + push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry); +} + +void LeaveCritical() +{ + pop_lock(); +} + +std::string LocksHeld() +{ + std::string result; + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)&i, *lockstack) + result += i.second.ToString() + std::string("\n"); + return result; +} + +void AssertLockHeldInternal(const char *pszName, const char* pszFile, int nLine, void *cs) +{ + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)&i, *lockstack) + if (i.first == cs) return; + fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", + pszName, pszFile, nLine, LocksHeld().c_str()); + abort(); +} + +#endif /* DEBUG_LOCKORDER */ diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sync.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sync.h new file mode 100644 index 0000000..928b12c --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/sync.h @@ -0,0 +1,261 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SYNC_H +#define BITCOIN_SYNC_H + +#include "threadsafety.h" + +#include +#include +#include +#include + + +//////////////////////////////////////////////// +// // +// THE SIMPLE DEFINITON, EXCLUDING DEBUG CODE // +// // +//////////////////////////////////////////////// + +/* + + + +CCriticalSection mutex; + boost::recursive_mutex mutex; + +LOCK(mutex); + boost::unique_lock criticalblock(mutex); + +LOCK2(mutex1, mutex2); + boost::unique_lock criticalblock1(mutex1); + boost::unique_lock criticalblock2(mutex2); + +TRY_LOCK(mutex, name); + boost::unique_lock name(mutex, boost::try_to_lock_t); + +ENTER_CRITICAL_SECTION(mutex); // no RAII + mutex.lock(); + +LEAVE_CRITICAL_SECTION(mutex); // no RAII + mutex.unlock(); + + + + */ + + + +/////////////////////////////// +// // +// THE ACTUAL IMPLEMENTATION // +// // +/////////////////////////////// + +// Template mixin that adds -Wthread-safety locking annotations to a +// subset of the mutex API. +template +class LOCKABLE AnnotatedMixin : public PARENT +{ +public: + void lock() EXCLUSIVE_LOCK_FUNCTION() + { + PARENT::lock(); + } + + void unlock() UNLOCK_FUNCTION() + { + PARENT::unlock(); + } + + bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true) + { + return PARENT::try_lock(); + } +}; + +/** Wrapped boost mutex: supports recursive locking, but no waiting */ +// TODO: We should move away from using the recursive lock by default. +typedef AnnotatedMixin CCriticalSection; + +/** Wrapped boost mutex: supports waiting but not recursive locking */ +typedef AnnotatedMixin CWaitableCriticalSection; + +#ifdef DEBUG_LOCKORDER +void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false); +void LeaveCritical(); +std::string LocksHeld(); +void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void *cs); +#else +void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {} +void static inline LeaveCritical() {} +void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void *cs) {} +#endif +#define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs) + +#ifdef DEBUG_LOCKCONTENTION +void PrintLockContention(const char* pszName, const char* pszFile, int nLine); +#endif + +/** Wrapper around boost::unique_lock */ +template +class CMutexLock +{ +private: + boost::unique_lock lock; + + void Enter(const char* pszName, const char* pszFile, int nLine) + { + EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex())); +#ifdef DEBUG_LOCKCONTENTION + if (!lock.try_lock()) + { + PrintLockContention(pszName, pszFile, nLine); +#endif + lock.lock(); +#ifdef DEBUG_LOCKCONTENTION + } +#endif + } + + bool TryEnter(const char* pszName, const char* pszFile, int nLine) + { + EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true); + lock.try_lock(); + if (!lock.owns_lock()) + LeaveCritical(); + return lock.owns_lock(); + } + +public: + CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) : lock(mutexIn, boost::defer_lock) + { + if (fTry) + TryEnter(pszName, pszFile, nLine); + else + Enter(pszName, pszFile, nLine); + } + + ~CMutexLock() + { + if (lock.owns_lock()) + LeaveCritical(); + } + + operator bool() + { + return lock.owns_lock(); + } +}; + +typedef CMutexLock CCriticalBlock; + +#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__) +#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__) +#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true) + +#define ENTER_CRITICAL_SECTION(cs) \ + { \ + EnterCritical(#cs, __FILE__, __LINE__, (void*)(&cs)); \ + (cs).lock(); \ + } + +#define LEAVE_CRITICAL_SECTION(cs) \ + { \ + (cs).unlock(); \ + LeaveCritical(); \ + } + +class CSemaphore +{ +private: + boost::condition_variable condition; + boost::mutex mutex; + int value; + +public: + CSemaphore(int init) : value(init) {} + + void wait() { + boost::unique_lock lock(mutex); + while (value < 1) { + condition.wait(lock); + } + value--; + } + + bool try_wait() { + boost::unique_lock lock(mutex); + if (value < 1) + return false; + value--; + return true; + } + + void post() { + { + boost::unique_lock lock(mutex); + value++; + } + condition.notify_one(); + } +}; + +/** RAII-style semaphore lock */ +class CSemaphoreGrant +{ +private: + CSemaphore *sem; + bool fHaveGrant; + +public: + void Acquire() { + if (fHaveGrant) + return; + sem->wait(); + fHaveGrant = true; + } + + void Release() { + if (!fHaveGrant) + return; + sem->post(); + fHaveGrant = false; + } + + bool TryAcquire() { + if (!fHaveGrant && sem->try_wait()) + fHaveGrant = true; + return fHaveGrant; + } + + void MoveTo(CSemaphoreGrant &grant) { + grant.Release(); + grant.sem = sem; + grant.fHaveGrant = fHaveGrant; + sem = NULL; + fHaveGrant = false; + } + + CSemaphoreGrant() : sem(NULL), fHaveGrant(false) {} + + CSemaphoreGrant(CSemaphore &sema, bool fTry = false) : sem(&sema), fHaveGrant(false) { + if (fTry) + TryAcquire(); + else + Acquire(); + } + + ~CSemaphoreGrant() { + Release(); + } + + operator bool() { + return fHaveGrant; + } +}; +#endif + diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/threadsafety.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/threadsafety.h new file mode 100644 index 0000000..176060a --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/threadsafety.h @@ -0,0 +1,54 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_THREADSAFETY_H +#define BITCOIN_THREADSAFETY_H + +#ifdef __clang__ +// TL;DR Add GUARDED_BY(mutex) to member variables. The others are +// rarely necessary. Ex: int nFoo GUARDED_BY(cs_foo); +// +// See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety +// for documentation. The clang compiler can do advanced static analysis +// of locking when given the -Wthread-safety option. +#define LOCKABLE __attribute__ ((lockable)) +#define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) +#define GUARDED_BY(x) __attribute__ ((guarded_by(x))) +#define GUARDED_VAR __attribute__ ((guarded_var)) +#define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x))) +#define PT_GUARDED_VAR __attribute__ ((pt_guarded_var)) +#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__))) +#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__))) +#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__))) +#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__))) +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__))) +#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__))) +#define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) +#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) +#define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__ ((exclusive_locks_required(__VA_ARGS__))) +#define SHARED_LOCKS_REQUIRED(...) __attribute__ ((shared_locks_required(__VA_ARGS__))) +#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) +#else +#define LOCKABLE +#define SCOPED_LOCKABLE +#define GUARDED_BY(x) +#define GUARDED_VAR +#define PT_GUARDED_BY(x) +#define PT_GUARDED_VAR +#define ACQUIRED_AFTER(...) +#define ACQUIRED_BEFORE(...) +#define EXCLUSIVE_LOCK_FUNCTION(...) +#define SHARED_LOCK_FUNCTION(...) +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) +#define SHARED_TRYLOCK_FUNCTION(...) +#define UNLOCK_FUNCTION(...) +#define LOCK_RETURNED(x) +#define LOCKS_EXCLUDED(...) +#define EXCLUSIVE_LOCKS_REQUIRED(...) +#define SHARED_LOCKS_REQUIRED(...) +#define NO_THREAD_SAFETY_ANALYSIS +#endif // __GNUC__ +#endif // BITCOIN_THREADSAFETY_H diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/timedata.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/timedata.cpp new file mode 100644 index 0000000..2706e3b --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/timedata.cpp @@ -0,0 +1,109 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "timedata.h" + +#include "netbase.h" +#include "sync.h" +#include "ui_interface.h" +#include "util.h" + +#include + +using namespace std; + +static CCriticalSection cs_nTimeOffset; +static int64_t nTimeOffset = 0; + +// +// "Never go to sea with two chronometers; take one or three." +// Our three time sources are: +// - System clock +// - Median of other nodes clocks +// - The user (asking the user to fix the system clock if the first two disagree) +// +// +int64_t GetTimeOffset() +{ + LOCK(cs_nTimeOffset); + return nTimeOffset; +} + +int64_t GetAdjustedTime() +{ + return GetTime() + GetTimeOffset(); +} + +void AddTimeData(const CNetAddr& ip, int64_t nTime) +{ + int64_t nOffsetSample = nTime - GetTime(); + + LOCK(cs_nTimeOffset); + // Ignore duplicates + static set setKnown; + if (!setKnown.insert(ip).second) + return; + + // Add data + static CMedianFilter vTimeOffsets(200,0); + vTimeOffsets.input(nOffsetSample); + LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); + + // There is a known issue here (see issue #4521): + // + // - The structure vTimeOffsets contains up to 200 elements, after which + // any new element added to it will not increase its size, replacing the + // oldest element. + // + // - The condition to update nTimeOffset includes checking whether the + // number of elements in vTimeOffsets is odd, which will never happen after + // there are 200 elements. + // + // But in this case the 'bug' is protective against some attacks, and may + // actually explain why we've never seen attacks which manipulate the + // clock offset. + // + // So we should hold off on fixing this and clean it up as part of + // a timing cleanup that strengthens it in a number of other ways. + // + if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) + { + int64_t nMedian = vTimeOffsets.median(); + std::vector vSorted = vTimeOffsets.sorted(); + // Only let other nodes change our time by so much + if (abs64(nMedian) < 70 * 60) + { + nTimeOffset = nMedian; + } + else + { + nTimeOffset = 0; + + static bool fDone; + if (!fDone) + { + // If nobody has a time different than ours but within 5 minutes of ours, give a warning + bool fMatch = false; + BOOST_FOREACH(int64_t nOffset, vSorted) + if (nOffset != 0 && abs64(nOffset) < 5 * 60) + fMatch = true; + + if (!fMatch) + { + fDone = true; + string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong phantomx will not work properly."); + strMiscWarning = strMessage; + LogPrintf("*** %s\n", strMessage); + uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); + } + } + } + if (fDebug) { + BOOST_FOREACH(int64_t n, vSorted) + LogPrintf("%+d ", n); + LogPrintf("| "); + } + LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60); + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/timedata.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/timedata.h new file mode 100644 index 0000000..0e7bdc2 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/timedata.h @@ -0,0 +1,17 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_TIMEDATA_H +#define BITCOIN_TIMEDATA_H + +#include + +class CNetAddr; + +/* Functions to keep track of adjusted P2P time */ +int64_t GetTimeOffset(); +int64_t GetAdjustedTime(); +void AddTimeData(const CNetAddr& ip, int64_t nTime); + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/tinyformat.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/tinyformat.h new file mode 100644 index 0000000..73d49a1 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/tinyformat.h @@ -0,0 +1,1013 @@ +// tinyformat.h +// Copyright (C) 2011, Chris Foster [chris42f (at) gmail (d0t) com] +// +// Boost Software License - Version 1.0 +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +//------------------------------------------------------------------------------ +// Tinyformat: A minimal type safe printf replacement +// +// tinyformat.h is a type safe printf replacement library in a single C++ +// header file. Design goals include: +// +// * Type safety and extensibility for user defined types. +// * C99 printf() compatibility, to the extent possible using std::ostream +// * Simplicity and minimalism. A single header file to include and distribute +// with your projects. +// * Augment rather than replace the standard stream formatting mechanism +// * C++98 support, with optional C++11 niceties +// +// +// Main interface example usage +// ---------------------------- +// +// To print a date to std::cout: +// +// std::string weekday = "Wednesday"; +// const char* month = "July"; +// size_t day = 27; +// long hour = 14; +// int min = 44; +// +// tfm::printf("%s, %s %d, %.2d:%.2d\n", weekday, month, day, hour, min); +// +// The strange types here emphasize the type safety of the interface; it is +// possible to print a std::string using the "%s" conversion, and a +// size_t using the "%d" conversion. A similar result could be achieved +// using either of the tfm::format() functions. One prints on a user provided +// stream: +// +// tfm::format(std::cerr, "%s, %s %d, %.2d:%.2d\n", +// weekday, month, day, hour, min); +// +// The other returns a std::string: +// +// std::string date = tfm::format("%s, %s %d, %.2d:%.2d\n", +// weekday, month, day, hour, min); +// std::cout << date; +// +// These are the three primary interface functions. +// +// +// User defined format functions +// ----------------------------- +// +// Simulating variadic templates in C++98 is pretty painful since it requires +// writing out the same function for each desired number of arguments. To make +// this bearable tinyformat comes with a set of macros which are used +// internally to generate the API, but which may also be used in user code. +// +// The three macros TINYFORMAT_ARGTYPES(n), TINYFORMAT_VARARGS(n) and +// TINYFORMAT_PASSARGS(n) will generate a list of n argument types, +// type/name pairs and argument names respectively when called with an integer +// n between 1 and 16. We can use these to define a macro which generates the +// desired user defined function with n arguments. To generate all 16 user +// defined function bodies, use the macro TINYFORMAT_FOREACH_ARGNUM. For an +// example, see the implementation of printf() at the end of the source file. +// +// +// Additional API information +// -------------------------- +// +// Error handling: Define TINYFORMAT_ERROR to customize the error handling for +// format strings which are unsupported or have the wrong number of format +// specifiers (calls assert() by default). +// +// User defined types: Uses operator<< for user defined types by default. +// Overload formatValue() for more control. + + +#ifndef TINYFORMAT_H_INCLUDED +#define TINYFORMAT_H_INCLUDED + +namespace tinyformat {} +//------------------------------------------------------------------------------ +// Config section. Customize to your liking! + +// Namespace alias to encourage brevity +namespace tfm = tinyformat; + +// Error handling; calls assert() by default. +#define TINYFORMAT_ERROR(reasonString) throw std::runtime_error(reasonString) + +// Define for C++11 variadic templates which make the code shorter & more +// general. If you don't define this, C++11 support is autodetected below. +// #define TINYFORMAT_USE_VARIADIC_TEMPLATES + + +//------------------------------------------------------------------------------ +// Implementation details. +#include +#include +#include +#include + +#ifndef TINYFORMAT_ERROR +# define TINYFORMAT_ERROR(reason) assert(0 && reason) +#endif + +#if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES) +# ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define TINYFORMAT_USE_VARIADIC_TEMPLATES +# endif +#endif + +#ifdef __GNUC__ +# define TINYFORMAT_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +# define TINYFORMAT_NOINLINE __declspec(noinline) +#else +# define TINYFORMAT_NOINLINE +#endif + +#if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201 +// std::showpos is broken on old libstdc++ as provided with OSX. See +// http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html +# define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND +#endif + +namespace tinyformat { + +//------------------------------------------------------------------------------ +namespace detail { + +// Test whether type T1 is convertible to type T2 +template +struct is_convertible +{ + private: + // two types of different size + struct fail { char dummy[2]; }; + struct succeed { char dummy; }; + // Try to convert a T1 to a T2 by plugging into tryConvert + static fail tryConvert(...); + static succeed tryConvert(const T2&); + static const T1& makeT1(); + public: +# ifdef _MSC_VER + // Disable spurious loss of precision warnings in tryConvert(makeT1()) +# pragma warning(push) +# pragma warning(disable:4244) +# pragma warning(disable:4267) +# endif + // Standard trick: the (...) version of tryConvert will be chosen from + // the overload set only if the version taking a T2 doesn't match. + // Then we compare the sizes of the return types to check which + // function matched. Very neat, in a disgusting kind of way :) + static const bool value = + sizeof(tryConvert(makeT1())) == sizeof(succeed); +# ifdef _MSC_VER +# pragma warning(pop) +# endif +}; + + +// Detect when a type is not a wchar_t string +template struct is_wchar { typedef int tinyformat_wchar_is_not_supported; }; +template<> struct is_wchar {}; +template<> struct is_wchar {}; +template struct is_wchar {}; +template struct is_wchar {}; + + +// Format the value by casting to type fmtT. This default implementation +// should never be called. +template::value> +struct formatValueAsType +{ + static void invoke(std::ostream& /*out*/, const T& /*value*/) { assert(0); } +}; +// Specialized version for types that can actually be converted to fmtT, as +// indicated by the "convertible" template parameter. +template +struct formatValueAsType +{ + static void invoke(std::ostream& out, const T& value) + { out << static_cast(value); } +}; + +#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND +template::value> +struct formatZeroIntegerWorkaround +{ + static bool invoke(std::ostream& /**/, const T& /**/) { return false; } +}; +template +struct formatZeroIntegerWorkaround +{ + static bool invoke(std::ostream& out, const T& value) + { + if (static_cast(value) == 0 && out.flags() & std::ios::showpos) + { + out << "+0"; + return true; + } + return false; + } +}; +#endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND + +// Convert an arbitrary type to integer. The version with convertible=false +// throws an error. +template::value> +struct convertToInt +{ + static int invoke(const T& /*value*/) + { + TINYFORMAT_ERROR("tinyformat: Cannot convert from argument type to " + "integer for use as variable width or precision"); + return 0; + } +}; +// Specialization for convertToInt when conversion is possible +template +struct convertToInt +{ + static int invoke(const T& value) { return static_cast(value); } +}; + +} // namespace detail + + +//------------------------------------------------------------------------------ +// Variable formatting functions. May be overridden for user-defined types if +// desired. + + +// Format a value into a stream. Called from format() for all types by default. +// +// Users may override this for their own types. When this function is called, +// the stream flags will have been modified according to the format string. +// The format specification is provided in the range [fmtBegin, fmtEnd). +// +// By default, formatValue() uses the usual stream insertion operator +// operator<< to format the type T, with special cases for the %c and %p +// conversions. +template +inline void formatValue(std::ostream& out, const char* /*fmtBegin*/, + const char* fmtEnd, const T& value) +{ +#ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS + // Since we don't support printing of wchar_t using "%ls", make it fail at + // compile time in preference to printing as a void* at runtime. + typedef typename detail::is_wchar::tinyformat_wchar_is_not_supported DummyType; + (void) DummyType(); // avoid unused type warning with gcc-4.8 +#endif + // The mess here is to support the %c and %p conversions: if these + // conversions are active we try to convert the type to a char or const + // void* respectively and format that instead of the value itself. For the + // %p conversion it's important to avoid dereferencing the pointer, which + // could otherwise lead to a crash when printing a dangling (const char*). + const bool canConvertToChar = detail::is_convertible::value; + const bool canConvertToVoidPtr = detail::is_convertible::value; + if(canConvertToChar && *(fmtEnd-1) == 'c') + detail::formatValueAsType::invoke(out, value); + else if(canConvertToVoidPtr && *(fmtEnd-1) == 'p') + detail::formatValueAsType::invoke(out, value); +#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND + else if(detail::formatZeroIntegerWorkaround::invoke(out, value)) /**/; +#endif + else + out << value; +} + + +// Overloaded version for char types to support printing as an integer +#define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \ +inline void formatValue(std::ostream& out, const char* /*fmtBegin*/, \ + const char* fmtEnd, charType value) \ +{ \ + switch(*(fmtEnd-1)) \ + { \ + case 'u': case 'd': case 'i': case 'o': case 'X': case 'x': \ + out << static_cast(value); break; \ + default: \ + out << value; break; \ + } \ +} +// per 3.9.1: char, signed char and unsigned char are all distinct types +TINYFORMAT_DEFINE_FORMATVALUE_CHAR(char) +TINYFORMAT_DEFINE_FORMATVALUE_CHAR(signed char) +TINYFORMAT_DEFINE_FORMATVALUE_CHAR(unsigned char) +#undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR + + +//------------------------------------------------------------------------------ +// Tools for emulating variadic templates in C++98. The basic idea here is +// stolen from the boost preprocessor metaprogramming library and cut down to +// be just general enough for what we need. + +#define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_ ## n +#define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_ ## n +#define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_ ## n +#define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_ ## n + +// To keep it as transparent as possible, the macros below have been generated +// using python via the excellent cog.py code generation script. This avoids +// the need for a bunch of complex (but more general) preprocessor tricks as +// used in boost.preprocessor. +// +// To rerun the code generation in place, use `cog.py -r tinyformat.h` +// (see http://nedbatchelder.com/code/cog). Alternatively you can just create +// extra versions by hand. + +/*[[[cog +maxParams = 16 + +def makeCommaSepLists(lineTemplate, elemTemplate, startInd=1): + for j in range(startInd,maxParams+1): + list = ', '.join([elemTemplate % {'i':i} for i in range(startInd,j+1)]) + cog.outl(lineTemplate % {'j':j, 'list':list}) + +makeCommaSepLists('#define TINYFORMAT_ARGTYPES_%(j)d %(list)s', + 'class T%(i)d') + +cog.outl() +makeCommaSepLists('#define TINYFORMAT_VARARGS_%(j)d %(list)s', + 'const T%(i)d& v%(i)d') + +cog.outl() +makeCommaSepLists('#define TINYFORMAT_PASSARGS_%(j)d %(list)s', 'v%(i)d') + +cog.outl() +cog.outl('#define TINYFORMAT_PASSARGS_TAIL_1') +makeCommaSepLists('#define TINYFORMAT_PASSARGS_TAIL_%(j)d , %(list)s', + 'v%(i)d', startInd = 2) + +cog.outl() +cog.outl('#define TINYFORMAT_FOREACH_ARGNUM(m) \\\n ' + + ' '.join(['m(%d)' % (j,) for j in range(1,maxParams+1)])) +]]]*/ +#define TINYFORMAT_ARGTYPES_1 class T1 +#define TINYFORMAT_ARGTYPES_2 class T1, class T2 +#define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3 +#define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4 +#define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5 +#define TINYFORMAT_ARGTYPES_6 class T1, class T2, class T3, class T4, class T5, class T6 +#define TINYFORMAT_ARGTYPES_7 class T1, class T2, class T3, class T4, class T5, class T6, class T7 +#define TINYFORMAT_ARGTYPES_8 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8 +#define TINYFORMAT_ARGTYPES_9 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9 +#define TINYFORMAT_ARGTYPES_10 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10 +#define TINYFORMAT_ARGTYPES_11 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11 +#define TINYFORMAT_ARGTYPES_12 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12 +#define TINYFORMAT_ARGTYPES_13 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13 +#define TINYFORMAT_ARGTYPES_14 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14 +#define TINYFORMAT_ARGTYPES_15 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 +#define TINYFORMAT_ARGTYPES_16 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class T16 + +#define TINYFORMAT_VARARGS_1 const T1& v1 +#define TINYFORMAT_VARARGS_2 const T1& v1, const T2& v2 +#define TINYFORMAT_VARARGS_3 const T1& v1, const T2& v2, const T3& v3 +#define TINYFORMAT_VARARGS_4 const T1& v1, const T2& v2, const T3& v3, const T4& v4 +#define TINYFORMAT_VARARGS_5 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5 +#define TINYFORMAT_VARARGS_6 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6 +#define TINYFORMAT_VARARGS_7 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7 +#define TINYFORMAT_VARARGS_8 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8 +#define TINYFORMAT_VARARGS_9 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9 +#define TINYFORMAT_VARARGS_10 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10 +#define TINYFORMAT_VARARGS_11 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11 +#define TINYFORMAT_VARARGS_12 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12 +#define TINYFORMAT_VARARGS_13 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13 +#define TINYFORMAT_VARARGS_14 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14 +#define TINYFORMAT_VARARGS_15 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15 +#define TINYFORMAT_VARARGS_16 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15, const T16& v16 + +#define TINYFORMAT_PASSARGS_1 v1 +#define TINYFORMAT_PASSARGS_2 v1, v2 +#define TINYFORMAT_PASSARGS_3 v1, v2, v3 +#define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4 +#define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5 +#define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6 +#define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7 +#define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8 +#define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9 +#define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 +#define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 +#define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 +#define TINYFORMAT_PASSARGS_13 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 +#define TINYFORMAT_PASSARGS_14 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 +#define TINYFORMAT_PASSARGS_15 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 +#define TINYFORMAT_PASSARGS_16 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 + +#define TINYFORMAT_PASSARGS_TAIL_1 +#define TINYFORMAT_PASSARGS_TAIL_2 , v2 +#define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3 +#define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4 +#define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5 +#define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6 +#define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7 +#define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8 +#define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9 +#define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10 +#define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 +#define TINYFORMAT_PASSARGS_TAIL_12 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 +#define TINYFORMAT_PASSARGS_TAIL_13 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 +#define TINYFORMAT_PASSARGS_TAIL_14 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 +#define TINYFORMAT_PASSARGS_TAIL_15 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 +#define TINYFORMAT_PASSARGS_TAIL_16 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 + +#define TINYFORMAT_FOREACH_ARGNUM(m) \ + m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8) m(9) m(10) m(11) m(12) m(13) m(14) m(15) m(16) +//[[[end]]] + + + +namespace detail { + +// Class holding current position in format string and an output stream into +// which arguments are formatted. +class FormatIterator +{ + public: + // Flags for features not representable with standard stream state + enum ExtraFormatFlags + { + Flag_None = 0, + Flag_TruncateToPrecision = 1<<0, // truncate length to stream precision() + Flag_SpacePadPositive = 1<<1, // pad positive values with spaces + Flag_VariableWidth = 1<<2, // variable field width in arg list + Flag_VariablePrecision = 1<<3 // variable field precision in arg list + }; + + // out is the output stream, fmt is the full format string + FormatIterator(std::ostream& out, const char* fmt) + : m_out(out), + m_fmt(fmt), + m_extraFlags(Flag_None), + m_wantWidth(false), + m_wantPrecision(false), + m_variableWidth(0), + m_variablePrecision(0), + m_origWidth(out.width()), + m_origPrecision(out.precision()), + m_origFlags(out.flags()), + m_origFill(out.fill()) + { } + + // Print remaining part of format string. + void finish() + { + // It would be nice if we could do this from the destructor, but we + // can't if TINFORMAT_ERROR is used to throw an exception! + m_fmt = printFormatStringLiteral(m_out, m_fmt); + if(*m_fmt != '\0') + TINYFORMAT_ERROR("tinyformat: Too many conversion specifiers in format string"); + } + + ~FormatIterator() + { + // Restore stream state + m_out.width(m_origWidth); + m_out.precision(m_origPrecision); + m_out.flags(m_origFlags); + m_out.fill(m_origFill); + } + + template + void accept(const T& value); + + private: + // Parse and return an integer from the string c, as atoi() + // On return, c is set to one past the end of the integer. + static int parseIntAndAdvance(const char*& c) + { + int i = 0; + for(;*c >= '0' && *c <= '9'; ++c) + i = 10*i + (*c - '0'); + return i; + } + + // Format at most truncLen characters of a C string to the given + // stream. Return true if formatting proceeded (generic version always + // returns false) + template + static bool formatCStringTruncate(std::ostream& /*out*/, const T& /*value*/, + std::streamsize /*truncLen*/) + { + return false; + } +# define TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(type) \ + static bool formatCStringTruncate(std::ostream& out, type* value, \ + std::streamsize truncLen) \ + { \ + std::streamsize len = 0; \ + while(len < truncLen && value[len] != 0) \ + ++len; \ + out.write(value, len); \ + return true; \ + } + // Overload for const char* and char*. Could overload for signed & + // unsigned char too, but these are technically unneeded for printf + // compatibility. + TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(const char) + TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(char) +# undef TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE + + // Print literal part of format string and return next format spec + // position. + // + // Skips over any occurrences of '%%', printing a literal '%' to the + // output. The position of the first % character of the next + // nontrivial format spec is returned, or the end of string. + static const char* printFormatStringLiteral(std::ostream& out, + const char* fmt) + { + const char* c = fmt; + for(; true; ++c) + { + switch(*c) + { + case '\0': + out.write(fmt, static_cast(c - fmt)); + return c; + case '%': + out.write(fmt, static_cast(c - fmt)); + if(*(c+1) != '%') + return c; + // for "%%", tack trailing % onto next literal section. + fmt = ++c; + break; + } + } + } + + static const char* streamStateFromFormat(std::ostream& out, + unsigned int& extraFlags, + const char* fmtStart, + int variableWidth, + int variablePrecision); + + // Private copy & assign: Kill gcc warnings with -Weffc++ + FormatIterator(const FormatIterator&); + FormatIterator& operator=(const FormatIterator&); + + // Stream, current format string & state + std::ostream& m_out; + const char* m_fmt; + unsigned int m_extraFlags; + // State machine info for handling of variable width & precision + bool m_wantWidth; + bool m_wantPrecision; + int m_variableWidth; + int m_variablePrecision; + // Saved stream state + std::streamsize m_origWidth; + std::streamsize m_origPrecision; + std::ios::fmtflags m_origFlags; + char m_origFill; +}; + + +// Accept a value for formatting into the internal stream. +template +TINYFORMAT_NOINLINE // < greatly reduces bloat in optimized builds +void FormatIterator::accept(const T& value) +{ + // Parse the format string + const char* fmtEnd = 0; + if(m_extraFlags == Flag_None && !m_wantWidth && !m_wantPrecision) + { + m_fmt = printFormatStringLiteral(m_out, m_fmt); + fmtEnd = streamStateFromFormat(m_out, m_extraFlags, m_fmt, 0, 0); + m_wantWidth = (m_extraFlags & Flag_VariableWidth) != 0; + m_wantPrecision = (m_extraFlags & Flag_VariablePrecision) != 0; + } + // Consume value as variable width and precision specifier if necessary + if(m_extraFlags & (Flag_VariableWidth | Flag_VariablePrecision)) + { + if(m_wantWidth || m_wantPrecision) + { + int v = convertToInt::invoke(value); + if(m_wantWidth) + { + m_variableWidth = v; + m_wantWidth = false; + } + else if(m_wantPrecision) + { + m_variablePrecision = v; + m_wantPrecision = false; + } + return; + } + // If we get here, we've set both the variable precision and width as + // required and we need to rerun the stream state setup to insert these. + fmtEnd = streamStateFromFormat(m_out, m_extraFlags, m_fmt, + m_variableWidth, m_variablePrecision); + } + + // Format the value into the stream. + if(!(m_extraFlags & (Flag_SpacePadPositive | Flag_TruncateToPrecision))) + formatValue(m_out, m_fmt, fmtEnd, value); + else + { + // The following are special cases where there's no direct + // correspondence between stream formatting and the printf() behaviour. + // Instead, we simulate the behaviour crudely by formatting into a + // temporary string stream and munging the resulting string. + std::ostringstream tmpStream; + tmpStream.copyfmt(m_out); + if(m_extraFlags & Flag_SpacePadPositive) + tmpStream.setf(std::ios::showpos); + // formatCStringTruncate is required for truncating conversions like + // "%.4s" where at most 4 characters of the c-string should be read. + // If we didn't include this special case, we might read off the end. + if(!( (m_extraFlags & Flag_TruncateToPrecision) && + formatCStringTruncate(tmpStream, value, m_out.precision()) )) + { + // Not a truncated c-string; just format normally. + formatValue(tmpStream, m_fmt, fmtEnd, value); + } + std::string result = tmpStream.str(); // allocates... yuck. + if(m_extraFlags & Flag_SpacePadPositive) + { + for(size_t i = 0, iend = result.size(); i < iend; ++i) + if(result[i] == '+') + result[i] = ' '; + } + if((m_extraFlags & Flag_TruncateToPrecision) && + (int)result.size() > (int)m_out.precision()) + m_out.write(result.c_str(), m_out.precision()); + else + m_out << result; + } + m_extraFlags = Flag_None; + m_fmt = fmtEnd; +} + + +// Parse a format string and set the stream state accordingly. +// +// The format mini-language recognized here is meant to be the one from C99, +// with the form "%[flags][width][.precision][length]type". +// +// Formatting options which can't be natively represented using the ostream +// state are returned in the extraFlags parameter which is a bitwise +// combination of values from the ExtraFormatFlags enum. +inline const char* FormatIterator::streamStateFromFormat(std::ostream& out, + unsigned int& extraFlags, + const char* fmtStart, + int variableWidth, + int variablePrecision) +{ + if(*fmtStart != '%') + { + TINYFORMAT_ERROR("tinyformat: Not enough conversion specifiers in format string"); + return fmtStart; + } + // Reset stream state to defaults. + out.width(0); + out.precision(6); + out.fill(' '); + // Reset most flags; ignore irrelevant unitbuf & skipws. + out.unsetf(std::ios::adjustfield | std::ios::basefield | + std::ios::floatfield | std::ios::showbase | std::ios::boolalpha | + std::ios::showpoint | std::ios::showpos | std::ios::uppercase); + extraFlags = Flag_None; + bool precisionSet = false; + bool widthSet = false; + const char* c = fmtStart + 1; + // 1) Parse flags + for(;; ++c) + { + switch(*c) + { + case '#': + out.setf(std::ios::showpoint | std::ios::showbase); + continue; + case '0': + // overridden by left alignment ('-' flag) + if(!(out.flags() & std::ios::left)) + { + // Use internal padding so that numeric values are + // formatted correctly, eg -00010 rather than 000-10 + out.fill('0'); + out.setf(std::ios::internal, std::ios::adjustfield); + } + continue; + case '-': + out.fill(' '); + out.setf(std::ios::left, std::ios::adjustfield); + continue; + case ' ': + // overridden by show positive sign, '+' flag. + if(!(out.flags() & std::ios::showpos)) + extraFlags |= Flag_SpacePadPositive; + continue; + case '+': + out.setf(std::ios::showpos); + extraFlags &= ~Flag_SpacePadPositive; + continue; + } + break; + } + // 2) Parse width + if(*c >= '0' && *c <= '9') + { + widthSet = true; + out.width(parseIntAndAdvance(c)); + } + if(*c == '*') + { + widthSet = true; + if(variableWidth < 0) + { + // negative widths correspond to '-' flag set + out.fill(' '); + out.setf(std::ios::left, std::ios::adjustfield); + variableWidth = -variableWidth; + } + out.width(variableWidth); + extraFlags |= Flag_VariableWidth; + ++c; + } + // 3) Parse precision + if(*c == '.') + { + ++c; + int precision = 0; + if(*c == '*') + { + ++c; + extraFlags |= Flag_VariablePrecision; + precision = variablePrecision; + } + else + { + if(*c >= '0' && *c <= '9') + precision = parseIntAndAdvance(c); + else if(*c == '-') // negative precisions ignored, treated as zero. + parseIntAndAdvance(++c); + } + out.precision(precision); + precisionSet = true; + } + // 4) Ignore any C99 length modifier + while(*c == 'l' || *c == 'h' || *c == 'L' || + *c == 'j' || *c == 'z' || *c == 't') + ++c; + // 5) We're up to the conversion specifier character. + // Set stream flags based on conversion specifier (thanks to the + // boost::format class for forging the way here). + bool intConversion = false; + switch(*c) + { + case 'u': case 'd': case 'i': + out.setf(std::ios::dec, std::ios::basefield); + intConversion = true; + break; + case 'o': + out.setf(std::ios::oct, std::ios::basefield); + intConversion = true; + break; + case 'X': + out.setf(std::ios::uppercase); + case 'x': case 'p': + out.setf(std::ios::hex, std::ios::basefield); + intConversion = true; + break; + case 'E': + out.setf(std::ios::uppercase); + case 'e': + out.setf(std::ios::scientific, std::ios::floatfield); + out.setf(std::ios::dec, std::ios::basefield); + break; + case 'F': + out.setf(std::ios::uppercase); + case 'f': + out.setf(std::ios::fixed, std::ios::floatfield); + break; + case 'G': + out.setf(std::ios::uppercase); + case 'g': + out.setf(std::ios::dec, std::ios::basefield); + // As in boost::format, let stream decide float format. + out.flags(out.flags() & ~std::ios::floatfield); + break; + case 'a': case 'A': + TINYFORMAT_ERROR("tinyformat: the %a and %A conversion specs " + "are not supported"); + break; + case 'c': + // Handled as special case inside formatValue() + break; + case 's': + if(precisionSet) + extraFlags |= Flag_TruncateToPrecision; + // Make %s print booleans as "true" and "false" + out.setf(std::ios::boolalpha); + break; + case 'n': + // Not supported - will cause problems! + TINYFORMAT_ERROR("tinyformat: %n conversion spec not supported"); + break; + case '\0': + TINYFORMAT_ERROR("tinyformat: Conversion spec incorrectly " + "terminated by end of string"); + return c; + } + if(intConversion && precisionSet && !widthSet) + { + // "precision" for integers gives the minimum number of digits (to be + // padded with zeros on the left). This isn't really supported by the + // iostreams, but we can approximately simulate it with the width if + // the width isn't otherwise used. + out.width(out.precision()); + out.setf(std::ios::internal, std::ios::adjustfield); + out.fill('0'); + } + return c+1; +} + + + +//------------------------------------------------------------------------------ +// Private format function on top of which the public interface is implemented. +// We enforce a mimimum of one value to be formatted to prevent bugs looking like +// +// const char* myStr = "100% broken"; +// printf(myStr); // Parses % as a format specifier +#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES + +template +void format(FormatIterator& fmtIter, const T1& value1) +{ + fmtIter.accept(value1); + fmtIter.finish(); +} + +// General version for C++11 +template +void format(FormatIterator& fmtIter, const T1& value1, const Args&... args) +{ + fmtIter.accept(value1); + format(fmtIter, args...); +} + +#else + +inline void format(FormatIterator& fmtIter) +{ + fmtIter.finish(); +} + +// General version for C++98 +#define TINYFORMAT_MAKE_FORMAT_DETAIL(n) \ +template \ +void format(detail::FormatIterator& fmtIter, TINYFORMAT_VARARGS(n)) \ +{ \ + fmtIter.accept(v1); \ + format(fmtIter TINYFORMAT_PASSARGS_TAIL(n)); \ +} + +TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_DETAIL) +#undef TINYFORMAT_MAKE_FORMAT_DETAIL + +#endif // End C++98 variadic template emulation for format() + +} // namespace detail + + +//------------------------------------------------------------------------------ +// Implement all the main interface functions here in terms of detail::format() + +#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES + +// C++11 - the simple case +template +void format(std::ostream& out, const char* fmt, const T1& v1, const Args&... args) +{ + detail::FormatIterator fmtIter(out, fmt); + format(fmtIter, v1, args...); +} + +template +std::string format(const char* fmt, const T1& v1, const Args&... args) +{ + std::ostringstream oss; + format(oss, fmt, v1, args...); + return oss.str(); +} + +template +std::string format(const std::string &fmt, const T1& v1, const Args&... args) +{ + std::ostringstream oss; + format(oss, fmt.c_str(), v1, args...); + return oss.str(); +} + +template +void printf(const char* fmt, const T1& v1, const Args&... args) +{ + format(std::cout, fmt, v1, args...); +} + +#else + +// C++98 - define the interface functions using the wrapping macros +#define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \ + \ +template \ +void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n)) \ +{ \ + tinyformat::detail::FormatIterator fmtIter(out, fmt); \ + tinyformat::detail::format(fmtIter, TINYFORMAT_PASSARGS(n)); \ +} \ + \ +template \ +std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \ +{ \ + std::ostringstream oss; \ + tinyformat::format(oss, fmt, TINYFORMAT_PASSARGS(n)); \ + return oss.str(); \ +} \ + \ +template \ +std::string format(const std::string &fmt, TINYFORMAT_VARARGS(n)) \ +{ \ + std::ostringstream oss; \ + tinyformat::format(oss, fmt.c_str(), TINYFORMAT_PASSARGS(n)); \ + return oss.str(); \ +} \ + \ +template \ +void printf(const char* fmt, TINYFORMAT_VARARGS(n)) \ +{ \ + tinyformat::format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ +} + +TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_FUNCS) +#undef TINYFORMAT_MAKE_FORMAT_FUNCS +#endif + + +//------------------------------------------------------------------------------ +// Define deprecated wrapping macro for backward compatibility in tinyformat +// 1.x. Will be removed in version 2! +#define TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS +#define TINYFORMAT_WRAP_FORMAT_N(n, returnType, funcName, funcDeclSuffix, \ + bodyPrefix, streamName, bodySuffix) \ +template \ +returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char* fmt, \ + TINYFORMAT_VARARGS(n)) funcDeclSuffix \ +{ \ + bodyPrefix \ + tinyformat::format(streamName, fmt, TINYFORMAT_PASSARGS(n)); \ + bodySuffix \ +} \ + +#define TINYFORMAT_WRAP_FORMAT(returnType, funcName, funcDeclSuffix, \ + bodyPrefix, streamName, bodySuffix) \ +inline \ +returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char* fmt \ + ) funcDeclSuffix \ +{ \ + bodyPrefix \ + tinyformat::detail::FormatIterator(streamName, fmt).finish(); \ + bodySuffix \ +} \ +TINYFORMAT_WRAP_FORMAT_N(1 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(2 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(3 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(4 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(5 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(6 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(7 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(8 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(9 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(10, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(11, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(12, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(13, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(14, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(15, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ +TINYFORMAT_WRAP_FORMAT_N(16, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ + + +} // namespace tinyformat + +#define strprintf tfm::format + +#endif // TINYFORMAT_H_INCLUDED diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb-leveldb.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb-leveldb.cpp new file mode 100644 index 0000000..f3e6834 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb-leveldb.cpp @@ -0,0 +1,592 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "kernel.h" +#include "checkpoints.h" +#include "txdb.h" +#include "util.h" +#include "main.h" +#include "chainparams.h" + +using namespace std; +using namespace boost; + +leveldb::DB *txdb; // global pointer for LevelDB object instance + +static leveldb::Options GetOptions() { + leveldb::Options options; + int nCacheSizeMB = GetArg("-dbcache", 100); + options.block_cache = leveldb::NewLRUCache(nCacheSizeMB * 1048576); + options.filter_policy = leveldb::NewBloomFilterPolicy(10); + return options; +} + +void init_blockindex(leveldb::Options& options, bool fRemoveOld = false) { + // First time init. + filesystem::path directory = GetDataDir() / "txleveldb"; + + if (fRemoveOld) { + filesystem::remove_all(directory); // remove directory + unsigned int nFile = 1; + + while (true) + { + filesystem::path strBlockFile = GetDataDir() / strprintf("blk%04u.dat", nFile); + + // Break if no such file + if( !filesystem::exists( strBlockFile ) ) + break; + + filesystem::remove(strBlockFile); + + nFile++; + } + } + + filesystem::create_directory(directory); + LogPrintf("Opening LevelDB in %s\n", directory.string()); + leveldb::Status status = leveldb::DB::Open(options, directory.string(), &txdb); + if (!status.ok()) { + throw runtime_error(strprintf("init_blockindex(): error opening database environment %s", status.ToString())); + } +} + +// CDB subclasses are created and destroyed VERY OFTEN. That's why +// we shouldn't treat this as a free operations. +CTxDB::CTxDB(const char* pszMode) +{ + assert(pszMode); + activeBatch = NULL; + fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); + + if (txdb) { + pdb = txdb; + return; + } + + bool fCreate = strchr(pszMode, 'c'); + + options = GetOptions(); + options.create_if_missing = fCreate; + options.filter_policy = leveldb::NewBloomFilterPolicy(10); + + init_blockindex(options); // Init directory + pdb = txdb; + + if (Exists(string("version"))) + { + ReadVersion(nVersion); + LogPrintf("Transaction index version is %d\n", nVersion); + + if (nVersion < DATABASE_VERSION) + { + LogPrintf("Required index version is %d, removing old database\n", DATABASE_VERSION); + + // Leveldb instance destruction + delete txdb; + txdb = pdb = NULL; + delete activeBatch; + activeBatch = NULL; + + init_blockindex(options, true); // Remove directory and create new database + pdb = txdb; + + bool fTmp = fReadOnly; + fReadOnly = false; + WriteVersion(DATABASE_VERSION); // Save transaction index version + fReadOnly = fTmp; + } + } + else if (fCreate) + { + bool fTmp = fReadOnly; + fReadOnly = false; + WriteVersion(DATABASE_VERSION); + fReadOnly = fTmp; + } + + LogPrintf("Opened LevelDB successfully\n"); +} + +void CTxDB::Close() +{ + delete txdb; + txdb = pdb = NULL; + delete options.filter_policy; + options.filter_policy = NULL; + delete options.block_cache; + options.block_cache = NULL; + delete activeBatch; + activeBatch = NULL; +} + +bool CTxDB::TxnBegin() +{ + assert(!activeBatch); + activeBatch = new leveldb::WriteBatch(); + return true; +} + +bool CTxDB::TxnCommit() +{ + assert(activeBatch); + leveldb::Status status = pdb->Write(leveldb::WriteOptions(), activeBatch); + delete activeBatch; + activeBatch = NULL; + if (!status.ok()) { + LogPrintf("LevelDB batch commit failure: %s\n", status.ToString()); + return false; + } + return true; +} + +class CBatchScanner : public leveldb::WriteBatch::Handler { +public: + std::string needle; + bool *deleted; + std::string *foundValue; + bool foundEntry; + + CBatchScanner() : foundEntry(false) {} + + virtual void Put(const leveldb::Slice& key, const leveldb::Slice& value) { + if (key.ToString() == needle) { + foundEntry = true; + *deleted = false; + *foundValue = value.ToString(); + } + } + + virtual void Delete(const leveldb::Slice& key) { + if (key.ToString() == needle) { + foundEntry = true; + *deleted = true; + } + } +}; + +// When performing a read, if we have an active batch we need to check it first +// before reading from the database, as the rest of the code assumes that once +// a database transaction begins reads are consistent with it. It would be good +// to change that assumption in future and avoid the performance hit, though in +// practice it does not appear to be large. +bool CTxDB::ScanBatch(const CDataStream &key, string *value, bool *deleted) const { + assert(activeBatch); + *deleted = false; + CBatchScanner scanner; + scanner.needle = key.str(); + scanner.deleted = deleted; + scanner.foundValue = value; + leveldb::Status status = activeBatch->Iterate(&scanner); + if (!status.ok()) { + throw runtime_error(status.ToString()); + } + return scanner.foundEntry; +} + +bool CTxDB::WriteAddrIndex(uint160 addrHash, uint256 txHash) +{ + std::vector txHashes; + if(!ReadAddrIndex(addrHash, txHashes)) + { + txHashes.push_back(txHash); + return Write(make_pair(string("adr"), addrHash), txHashes); + } + else + { + if(std::find(txHashes.begin(), txHashes.end(), txHash) == txHashes.end()) + { + txHashes.push_back(txHash); + return Write(make_pair(string("adr"), addrHash), txHashes); + } + else + { + return true; // already have this tx hash + } + } +} + +bool CTxDB::ReadAddrIndex(uint160 addrHash, std::vector& txHashes) +{ + return Read(make_pair(string("adr"), addrHash), txHashes); +} + +bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex) +{ + txindex.SetNull(); + return Read(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex) +{ + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight) +{ + // Add to tx index + uint256 hash = tx.GetHash(); + CTxIndex txindex(pos, tx.vout.size()); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::EraseTxIndex(const CTransaction& tx) +{ + uint256 hash = tx.GetHash(); + + return Erase(make_pair(string("tx"), hash)); +} + +bool CTxDB::ContainsTx(uint256 hash) +{ + return Exists(make_pair(string("tx"), hash)); +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex) +{ + tx.SetNull(); + if (!ReadTxIndex(hash, txindex)) + return false; + return (tx.ReadFromDisk(txindex.pos)); +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex) +{ + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) +{ + return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex); +} + +bool CTxDB::ReadHashBestChain(uint256& hashBestChain) +{ + return Read(string("hashBestChain"), hashBestChain); +} + +bool CTxDB::WriteHashBestChain(uint256 hashBestChain) +{ + return Write(string("hashBestChain"), hashBestChain); +} + +bool CTxDB::ReadBestInvalidTrust(CBigNum& bnBestInvalidTrust) +{ + return Read(string("bnBestInvalidTrust"), bnBestInvalidTrust); +} + +bool CTxDB::WriteBestInvalidTrust(CBigNum bnBestInvalidTrust) +{ + return Write(string("bnBestInvalidTrust"), bnBestInvalidTrust); +} + +bool CTxDB::ReadSyncCheckpoint(uint256& hashCheckpoint) +{ + return Read(string("hashSyncCheckpoint"), hashCheckpoint); +} + +bool CTxDB::WriteSyncCheckpoint(uint256 hashCheckpoint) +{ + return Write(string("hashSyncCheckpoint"), hashCheckpoint); +} + +bool CTxDB::ReadCheckpointPubKey(string& strPubKey) +{ + return Read(string("strCheckpointPubKey"), strPubKey); +} + +bool CTxDB::WriteCheckpointPubKey(const string& strPubKey) +{ + return Write(string("strCheckpointPubKey"), strPubKey); +} + +static CBlockIndex *InsertBlockIndex(uint256 hash) +{ + if (hash == 0) + return NULL; + + // Return existing + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + return (*mi).second; + + // Create new + CBlockIndex* pindexNew = new CBlockIndex(); + if (!pindexNew) + throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); + mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + + return pindexNew; +} + +bool CTxDB::LoadBlockIndex() +{ + if (mapBlockIndex.size() > 0) { + // Already loaded once in this session. It can happen during migration + // from BDB. + return true; + } + // The block index is an in-memory structure that maps hashes to on-disk + // locations where the contents of the block can be found. Here, we scan it + // out of the DB and into mapBlockIndex. + leveldb::Iterator *iterator = pdb->NewIterator(leveldb::ReadOptions()); + // Seek to start key. + CDataStream ssStartKey(SER_DISK, CLIENT_VERSION); + ssStartKey << make_pair(string("blockindex"), uint256(0)); + iterator->Seek(ssStartKey.str()); + // Now read each entry. + while (iterator->Valid()) + { + boost::this_thread::interruption_point(); + // Unpack keys and values. + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.write(iterator->key().data(), iterator->key().size()); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + ssValue.write(iterator->value().data(), iterator->value().size()); + string strType; + ssKey >> strType; + // Did we reach the end of the data to read? + if (strType != "blockindex") + break; + CDiskBlockIndex diskindex; + ssValue >> diskindex; + + uint256 blockHash = diskindex.GetBlockHash(); + + // Construct block index object + CBlockIndex* pindexNew = InsertBlockIndex(blockHash); + pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); + pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); + pindexNew->nFile = diskindex.nFile; + pindexNew->nBlockPos = diskindex.nBlockPos; + pindexNew->nHeight = diskindex.nHeight; + pindexNew->nMint = diskindex.nMint; + pindexNew->nMoneySupply = diskindex.nMoneySupply; + pindexNew->nFlags = diskindex.nFlags; + pindexNew->nStakeModifier = diskindex.nStakeModifier; + pindexNew->prevoutStake = diskindex.prevoutStake; + pindexNew->nStakeTime = diskindex.nStakeTime; + pindexNew->hashProof = diskindex.hashProof; + pindexNew->nVersion = diskindex.nVersion; + pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; + pindexNew->nTime = diskindex.nTime; + pindexNew->nBits = diskindex.nBits; + pindexNew->nNonce = diskindex.nNonce; + + // Watch for genesis block + if (pindexGenesisBlock == NULL && blockHash == Params().HashGenesisBlock()) + pindexGenesisBlock = pindexNew; + + if (!pindexNew->CheckIndex()) { + delete iterator; + return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); + } + + // NovaCoin: build setStakeSeen + if (pindexNew->IsProofOfStake()) + setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); + + iterator->Next(); + } + delete iterator; + + boost::this_thread::interruption_point(); + + // Calculate nChainTrust + vector > vSortedByHeight; + vSortedByHeight.reserve(mapBlockIndex.size()); + BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) + { + CBlockIndex* pindex = item.second; + vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); + } + sort(vSortedByHeight.begin(), vSortedByHeight.end()); + BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) + { + CBlockIndex* pindex = item.second; + pindex->nChainTrust = (pindex->pprev ? pindex->pprev->nChainTrust : 0) + pindex->GetBlockTrust(); + } + + // Load hashBestChain pointer to end of best chain + if (!ReadHashBestChain(hashBestChain)) + { + if (pindexGenesisBlock == NULL) + return true; + return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded"); + } + if (!mapBlockIndex.count(hashBestChain)) + return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index"); + pindexBest = mapBlockIndex[hashBestChain]; + nBestHeight = pindexBest->nHeight; + nBestChainTrust = pindexBest->nChainTrust; + + LogPrintf("LoadBlockIndex(): hashBestChain=%s height=%d trust=%s date=%s\n", + hashBestChain.ToString(), nBestHeight, CBigNum(nBestChainTrust).ToString(), + DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime())); + + /*// NovaCoin: load hashSyncCheckpoint + if (!ReadSyncCheckpoint(Checkpoints::hashSyncCheckpoint)) + return error("CTxDB::LoadBlockIndex() : hashSyncCheckpoint not loaded"); + LogPrintf("LoadBlockIndex(): synchronized checkpoint %s\n", Checkpoints::hashSyncCheckpoint.ToString()); */ + + // Load bnBestInvalidTrust, OK if it doesn't exist + CBigNum bnBestInvalidTrust; + ReadBestInvalidTrust(bnBestInvalidTrust); + nBestInvalidTrust = bnBestInvalidTrust.getuint256(); + + // Verify blocks in the best chain + int nCheckLevel = GetArg("-checklevel", 1); + int nCheckDepth = GetArg( "-checkblocks", 500); + if (nCheckDepth == 0) + nCheckDepth = 1000000000; // suffices until the year 19000 + if (nCheckDepth > nBestHeight) + nCheckDepth = nBestHeight; + LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); + CBlockIndex* pindexFork = NULL; + map, CBlockIndex*> mapBlockPos; + for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) + { + boost::this_thread::interruption_point(); + if (pindex->nHeight < nBestHeight-nCheckDepth) + break; + CBlock block; + if (!block.ReadFromDisk(pindex)) + return error("LoadBlockIndex() : block.ReadFromDisk failed"); + // check level 1: verify block validity + // check level 7: verify block signature too + if (nCheckLevel>0 && !block.CheckBlock(true, true, (nCheckLevel>6))) + { + LogPrintf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); + pindexFork = pindex->pprev; + } + // check level 2: verify transaction index validity + if (nCheckLevel>1) + { + pair pos = make_pair(pindex->nFile, pindex->nBlockPos); + mapBlockPos[pos] = pindex; + BOOST_FOREACH(const CTransaction &tx, block.vtx) + { + uint256 hashTx = tx.GetHash(); + CTxIndex txindex; + if (ReadTxIndex(hashTx, txindex)) + { + // check level 3: checker transaction hashes + if (nCheckLevel>2 || pindex->nFile != txindex.pos.nFile || pindex->nBlockPos != txindex.pos.nBlockPos) + { + // either an error or a duplicate transaction + CTransaction txFound; + if (!txFound.ReadFromDisk(txindex.pos)) + { + LogPrintf("LoadBlockIndex() : *** cannot read mislocated transaction %s\n", hashTx.ToString()); + pindexFork = pindex->pprev; + } + else + if (txFound.GetHash() != hashTx) // not a duplicate tx + { + LogPrintf("LoadBlockIndex(): *** invalid tx position for %s\n", hashTx.ToString()); + pindexFork = pindex->pprev; + } + } + // check level 4: check whether spent txouts were spent within the main chain + unsigned int nOutput = 0; + if (nCheckLevel>3) + { + BOOST_FOREACH(const CDiskTxPos &txpos, txindex.vSpent) + { + if (!txpos.IsNull()) + { + pair posFind = make_pair(txpos.nFile, txpos.nBlockPos); + if (!mapBlockPos.count(posFind)) + { + LogPrintf("LoadBlockIndex(): *** found bad spend at %d, hashBlock=%s, hashTx=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString(), hashTx.ToString()); + pindexFork = pindex->pprev; + } + // check level 6: check whether spent txouts were spent by a valid transaction that consume them + if (nCheckLevel>5) + { + CTransaction txSpend; + if (!txSpend.ReadFromDisk(txpos)) + { + LogPrintf("LoadBlockIndex(): *** cannot read spending transaction of %s:%i from disk\n", hashTx.ToString(), nOutput); + pindexFork = pindex->pprev; + } + else if (!txSpend.CheckTransaction()) + { + LogPrintf("LoadBlockIndex(): *** spending transaction of %s:%i is invalid\n", hashTx.ToString(), nOutput); + pindexFork = pindex->pprev; + } + else + { + bool fFound = false; + BOOST_FOREACH(const CTxIn &txin, txSpend.vin) + if (txin.prevout.hash == hashTx && txin.prevout.n == nOutput) + fFound = true; + if (!fFound) + { + LogPrintf("LoadBlockIndex(): *** spending transaction of %s:%i does not spend it\n", hashTx.ToString(), nOutput); + pindexFork = pindex->pprev; + } + } + } + } + nOutput++; + } + } + } + // check level 5: check whether all prevouts are marked spent + if (nCheckLevel>4) + { + BOOST_FOREACH(const CTxIn &txin, tx.vin) + { + CTxIndex txindex; + if (ReadTxIndex(txin.prevout.hash, txindex)) + if (txindex.vSpent.size()-1 < txin.prevout.n || txindex.vSpent[txin.prevout.n].IsNull()) + { + LogPrintf("LoadBlockIndex(): *** found unspent prevout %s:%i in %s\n", txin.prevout.hash.ToString(), txin.prevout.n, hashTx.ToString()); + pindexFork = pindex->pprev; + } + } + } + } + } + } + if (pindexFork) + { + boost::this_thread::interruption_point(); + // Reorg back to the fork + LogPrintf("LoadBlockIndex() : *** moving best chain pointer back to block %d\n", pindexFork->nHeight); + CBlock block; + if (!block.ReadFromDisk(pindexFork)) + return error("LoadBlockIndex() : block.ReadFromDisk failed"); + CTxDB txdb; + block.SetBestChain(txdb, pindexFork); + } + + return true; +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb-leveldb.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb-leveldb.h new file mode 100644 index 0000000..fd0e85b --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb-leveldb.h @@ -0,0 +1,212 @@ +// Copyright (c) 2009-2012 The Bitcoin Developers. +// Authored by Google, Inc. +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_LEVELDB_H +#define BITCOIN_LEVELDB_H + +#include "main.h" + +#include +#include +#include + +#include +#include + +// Class that provides access to a LevelDB. Note that this class is frequently +// instantiated on the stack and then destroyed again, so instantiation has to +// be very cheap. Unfortunately that means, a CTxDB instance is actually just a +// wrapper around some global state. +// +// A LevelDB is a key/value store that is optimized for fast usage on hard +// disks. It prefers long read/writes to seeks and is based on a series of +// sorted key/value mapping files that are stacked on top of each other, with +// newer files overriding older files. A background thread compacts them +// together when too many files stack up. +// +// Learn more: http://code.google.com/p/leveldb/ +class CTxDB +{ +public: + CTxDB(const char* pszMode="r+"); + ~CTxDB() { + // Note that this is not the same as Close() because it deletes only + // data scoped to this TxDB object. + delete activeBatch; + } + + // Destroys the underlying shared global state accessed by this TxDB. + void Close(); + +private: + leveldb::DB *pdb; // Points to the global instance. + + // A batch stores up writes and deletes for atomic application. When this + // field is non-NULL, writes/deletes go there instead of directly to disk. + leveldb::WriteBatch *activeBatch; + leveldb::Options options; + bool fReadOnly; + int nVersion; + +protected: + // Returns true and sets (value,false) if activeBatch contains the given key + // or leaves value alone and sets deleted = true if activeBatch contains a + // delete for it. + bool ScanBatch(const CDataStream &key, std::string *value, bool *deleted) const; + + template + bool Read(const K& key, T& value) + { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + std::string strValue; + + bool readFromDb = true; + if (activeBatch) { + // First we must search for it in the currently pending set of + // changes to the db. If not found in the batch, go on to read disk. + bool deleted = false; + readFromDb = ScanBatch(ssKey, &strValue, &deleted) == false; + if (deleted) { + return false; + } + } + if (readFromDb) { + leveldb::Status status = pdb->Get(leveldb::ReadOptions(), + ssKey.str(), &strValue); + if (!status.ok()) { + if (status.IsNotFound()) + return false; + // Some unexpected error. + LogPrintf("LevelDB read failure: %s\n", status.ToString()); + return false; + } + } + // Unserialize value + try { + CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), + SER_DISK, CLIENT_VERSION); + ssValue >> value; + } + catch (std::exception &e) { + return false; + } + return true; + } + + template + bool Write(const K& key, const T& value) + { + if (fReadOnly) + assert(!"Write called on database in read-only mode"); + + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + ssValue.reserve(10000); + ssValue << value; + + if (activeBatch) { + activeBatch->Put(ssKey.str(), ssValue.str()); + return true; + } + leveldb::Status status = pdb->Put(leveldb::WriteOptions(), ssKey.str(), ssValue.str()); + if (!status.ok()) { + LogPrintf("LevelDB write failure: %s\n", status.ToString()); + return false; + } + return true; + } + + template + bool Erase(const K& key) + { + if (!pdb) + return false; + if (fReadOnly) + assert(!"Erase called on database in read-only mode"); + + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + if (activeBatch) { + activeBatch->Delete(ssKey.str()); + return true; + } + leveldb::Status status = pdb->Delete(leveldb::WriteOptions(), ssKey.str()); + return (status.ok() || status.IsNotFound()); + } + + template + bool Exists(const K& key) + { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + std::string unused; + + if (activeBatch) { + bool deleted; + if (ScanBatch(ssKey, &unused, &deleted) && !deleted) { + return true; + } + } + + + leveldb::Status status = pdb->Get(leveldb::ReadOptions(), ssKey.str(), &unused); + return status.IsNotFound() == false; + } + + +public: + bool TxnBegin(); + bool TxnCommit(); + bool TxnAbort() + { + delete activeBatch; + activeBatch = NULL; + return true; + } + + bool ReadVersion(int& nVersion) + { + nVersion = 0; + return Read(std::string("version"), nVersion); + } + + bool WriteVersion(int nVersion) + { + return Write(std::string("version"), nVersion); + } + + bool ReadAddrIndex(uint160 addrHash, std::vector& txHashes); + bool WriteAddrIndex(uint160 addrHash, uint256 txHash); + bool ReadTxIndex(uint256 hash, CTxIndex& txindex); + bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); + bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight); + bool EraseTxIndex(const CTransaction& tx); + bool ContainsTx(uint256 hash); + bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(uint256 hash, CTransaction& tx); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); + bool WriteBlockIndex(const CDiskBlockIndex& blockindex); + bool ReadHashBestChain(uint256& hashBestChain); + bool WriteHashBestChain(uint256 hashBestChain); + bool ReadBestInvalidTrust(CBigNum& bnBestInvalidTrust); + bool WriteBestInvalidTrust(CBigNum bnBestInvalidTrust); + bool ReadSyncCheckpoint(uint256& hashCheckpoint); + bool WriteSyncCheckpoint(uint256 hashCheckpoint); + bool ReadCheckpointPubKey(std::string& strPubKey); + bool WriteCheckpointPubKey(const std::string& strPubKey); + bool LoadBlockIndex(); +private: + bool LoadBlockIndexGuts(); +}; + + +#endif // BITCOIN_DB_H diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb.h new file mode 100644 index 0000000..a8e9f5b --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txdb.h @@ -0,0 +1,11 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_TXDB_H +#define BITCOIN_TXDB_H + +#include "txdb-leveldb.h" + +#endif // BITCOIN_TXDB_H diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txmempool.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txmempool.cpp new file mode 100644 index 0000000..6fb510b --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txmempool.cpp @@ -0,0 +1,107 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "core.h" +#include "txmempool.h" +#include "main.h" // for CTransaction + +using namespace std; + +CTxMemPool::CTxMemPool() +{ +} + +unsigned int CTxMemPool::GetTransactionsUpdated() const +{ + LOCK(cs); + return nTransactionsUpdated; +} + +void CTxMemPool::AddTransactionsUpdated(unsigned int n) +{ + LOCK(cs); + nTransactionsUpdated += n; +} + +bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx) +{ + // Add to memory pool without checking anything. + // Used by main.cpp AcceptToMemoryPool(), which DOES do + // all the appropriate checks. + LOCK(cs); + { + mapTx[hash] = tx; + for (unsigned int i = 0; i < tx.vin.size(); i++) + mapNextTx[tx.vin[i].prevout] = CInPoint(&mapTx[hash], i); + nTransactionsUpdated++; + } + return true; +} + +bool CTxMemPool::remove(const CTransaction &tx, bool fRecursive) +{ + // Remove transaction from memory pool + { + LOCK(cs); + uint256 hash = tx.GetHash(); + if (mapTx.count(hash)) + { + if (fRecursive) { + for (unsigned int i = 0; i < tx.vout.size(); i++) { + std::map::iterator it = mapNextTx.find(COutPoint(hash, i)); + if (it != mapNextTx.end()) + remove(*it->second.ptx, true); + } + } + BOOST_FOREACH(const CTxIn& txin, tx.vin) + mapNextTx.erase(txin.prevout); + mapTx.erase(hash); + nTransactionsUpdated++; + } + } + return true; +} + +bool CTxMemPool::removeConflicts(const CTransaction &tx) +{ + // Remove transactions which depend on inputs of tx, recursively + LOCK(cs); + BOOST_FOREACH(const CTxIn &txin, tx.vin) { + std::map::iterator it = mapNextTx.find(txin.prevout); + if (it != mapNextTx.end()) { + const CTransaction &txConflict = *it->second.ptx; + if (txConflict != tx) + remove(txConflict, true); + } + } + return true; +} + +void CTxMemPool::clear() +{ + LOCK(cs); + mapTx.clear(); + mapNextTx.clear(); + ++nTransactionsUpdated; +} + +void CTxMemPool::queryHashes(std::vector& vtxid) +{ + vtxid.clear(); + + LOCK(cs); + vtxid.reserve(mapTx.size()); + for (map::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) + vtxid.push_back((*mi).first); +} + +bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const +{ + LOCK(cs); + std::map::const_iterator i = mapTx.find(hash); + if (i == mapTx.end()) return false; + result = i->second; + return true; +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txmempool.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txmempool.h new file mode 100644 index 0000000..f4439bd --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/txmempool.h @@ -0,0 +1,55 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_TXMEMPOOL_H +#define BITCOIN_TXMEMPOOL_H + +#include "core.h" + +/* + * CTxMemPool stores valid-according-to-the-current-best-chain + * transactions that may be included in the next block. + * + * Transactions are added when they are seen on the network + * (or created by the local node), but not all transactions seen + * are added to the pool: if a new transaction double-spends + * an input of a transaction in the pool, it is dropped, + * as are non-standard transactions. + */ +class CTxMemPool +{ +private: + unsigned int nTransactionsUpdated; + +public: + mutable CCriticalSection cs; + std::map mapTx; + std::map mapNextTx; + + CTxMemPool(); + + bool addUnchecked(const uint256& hash, CTransaction &tx); + bool remove(const CTransaction &tx, bool fRecursive = false); + bool removeConflicts(const CTransaction &tx); + void clear(); + void queryHashes(std::vector& vtxid); + unsigned int GetTransactionsUpdated() const; + void AddTransactionsUpdated(unsigned int n); + + unsigned long size() const + { + LOCK(cs); + return mapTx.size(); + } + + bool exists(uint256 hash) const + { + LOCK(cs); + return (mapTx.count(hash) != 0); + } + + bool lookup(uint256 hash, CTransaction& result) const; +}; + +#endif /* BITCOIN_TXMEMPOOL_H */ diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/ui_interface.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/ui_interface.h new file mode 100644 index 0000000..e2d8a08 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/ui_interface.h @@ -0,0 +1,113 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UI_INTERFACE_H +#define BITCOIN_UI_INTERFACE_H + +#include +#include + +#include + +#include + +class CBasicKeyStore; +class CWallet; +class uint256; +class CAdrenalineNodeConfig; + +/** General change type (added, updated, removed). */ +enum ChangeType +{ + CT_NEW, + CT_UPDATED, + CT_DELETED +}; + +/** Signals for UI communication. */ +class CClientUIInterface +{ +public: + /** Flags for CClientUIInterface::ThreadSafeMessageBox */ + enum MessageBoxFlags + { + ICON_INFORMATION = 0, + ICON_WARNING = (1U << 0), + ICON_ERROR = (1U << 1), + /** + * Mask of all available icons in CClientUIInterface::MessageBoxFlags + * This needs to be updated, when icons are changed there! + */ + ICON_MASK = (ICON_INFORMATION | ICON_WARNING | ICON_ERROR), + + /** These values are taken from qmessagebox.h "enum StandardButton" to be directly usable */ + BTN_OK = 0x00000400U, // QMessageBox::Ok + BTN_YES = 0x00004000U, // QMessageBox::Yes + BTN_NO = 0x00010000U, // QMessageBox::No + BTN_ABORT = 0x00040000U, // QMessageBox::Abort + BTN_RETRY = 0x00080000U, // QMessageBox::Retry + BTN_IGNORE = 0x00100000U, // QMessageBox::Ignore + BTN_CLOSE = 0x00200000U, // QMessageBox::Close + BTN_CANCEL = 0x00400000U, // QMessageBox::Cancel + BTN_DISCARD = 0x00800000U, // QMessageBox::Discard + BTN_HELP = 0x01000000U, // QMessageBox::Help + BTN_APPLY = 0x02000000U, // QMessageBox::Apply + BTN_RESET = 0x04000000U, // QMessageBox::Reset + /** + * Mask of all available buttons in CClientUIInterface::MessageBoxFlags + * This needs to be updated, when buttons are changed there! + */ + BTN_MASK = (BTN_OK | BTN_YES | BTN_NO | BTN_ABORT | BTN_RETRY | BTN_IGNORE | + BTN_CLOSE | BTN_CANCEL | BTN_DISCARD | BTN_HELP | BTN_APPLY | BTN_RESET), + + /** Force blocking, modal message box dialog (not just OS notification) */ + MODAL = 0x10000000U, + + /** Predefined combinations for certain default usage cases */ + MSG_INFORMATION = (ICON_INFORMATION | BTN_OK), + MSG_WARNING = (ICON_WARNING | BTN_OK | MODAL), + MSG_ERROR = (ICON_ERROR | BTN_OK | MODAL) + }; + + /** Show message box. */ + boost::signals2::signal ThreadSafeMessageBox; + + /** Ask the user whether they want to pay a fee or not. */ + boost::signals2::signal > ThreadSafeAskFee; + + /** Handle a URL passed at the command line. */ + boost::signals2::signal ThreadSafeHandleURI; + + /** Progress message during initialization. */ + boost::signals2::signal InitMessage; + + /** Translate a message to the native language of the user. */ + boost::signals2::signal Translate; + + /** Number of network connections changed. */ + boost::signals2::signal NotifyNumConnectionsChanged; + + /** + * New, updated or cancelled alert. + * @note called with lock cs_mapAlerts held. + */ + boost::signals2::signal NotifyAlertChanged; + + boost::signals2::signal NotifyAdrenalineNodeChanged; +}; + +extern CClientUIInterface uiInterface; + +/** + * Translation function: Call Translate signal on UI interface, which returns a boost::optional result. + * If no translation slot is registered, nothing is returned, and simply return the input. + */ +inline std::string _(const char* psz) +{ + boost::optional rv = uiInterface.Translate(psz); + return rv ? (*rv) : psz; +} + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/uint256.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/uint256.h new file mode 100644 index 0000000..1524a51 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/uint256.h @@ -0,0 +1,892 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UINT256_H +#define BITCOIN_UINT256_H + +#include +#include + +#include +#include +#include + +inline int Testuint256AdHoc(std::vector vArg); + + +/** Base class without constructors for uint256 and uint160. + * This makes the compiler let u use it in a union. + */ +template +class base_uint +{ +protected: + enum { WIDTH=BITS/32 }; + unsigned int pn[WIDTH]; +public: + + bool operator!() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } + + const base_uint operator~() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + return ret; + } + + const base_uint operator-() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + ret++; + return ret; + } + + double getdouble() const + { + double ret = 0.0; + double fact = 1.0; + for (int i = 0; i < WIDTH; i++) { + ret += fact * pn[i]; + fact *= 4294967296.0; + } + return ret; + } + + base_uint& operator=(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + base_uint& operator^=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] ^= b.pn[i]; + return *this; + } + + base_uint& operator&=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] &= b.pn[i]; + return *this; + } + + base_uint& operator|=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] |= b.pn[i]; + return *this; + } + + base_uint& operator^=(uint64_t b) + { + pn[0] ^= (unsigned int)b; + pn[1] ^= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator|=(uint64_t b) + { + pn[0] |= (unsigned int)b; + pn[1] |= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator<<=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i+k+1 < WIDTH && shift != 0) + pn[i+k+1] |= (a.pn[i] >> (32-shift)); + if (i+k < WIDTH) + pn[i+k] |= (a.pn[i] << shift); + } + return *this; + } + + base_uint& operator>>=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i-k-1 >= 0 && shift != 0) + pn[i-k-1] |= (a.pn[i] << (32-shift)); + if (i-k >= 0) + pn[i-k] |= (a.pn[i] >> shift); + } + return *this; + } + + base_uint& operator+=(const base_uint& b) + { + uint64_t carry = 0; + for (int i = 0; i < WIDTH; i++) + { + uint64_t n = carry + pn[i] + b.pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; + } + + base_uint& operator-=(const base_uint& b) + { + *this += -b; + return *this; + } + + base_uint& operator+=(uint64_t b64) + { + base_uint b; + b = b64; + *this += b; + return *this; + } + + base_uint& operator-=(uint64_t b64) + { + base_uint b; + b = b64; + *this += -b; + return *this; + } + + + base_uint& operator++() + { + // prefix operator + int i = 0; + while (++pn[i] == 0 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator++(int) + { + // postfix operator + const base_uint ret = *this; + ++(*this); + return ret; + } + + base_uint& operator--() + { + // prefix operator + int i = 0; + while (--pn[i] == -1 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator--(int) + { + // postfix operator + const base_uint ret = *this; + --(*this); + return ret; + } + + + friend inline bool operator<(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator<=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator>(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator>=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator==(const base_uint& a, const base_uint& b) + { + for (int i = 0; i < base_uint::WIDTH; i++) + if (a.pn[i] != b.pn[i]) + return false; + return true; + } + + friend inline bool operator==(const base_uint& a, uint64_t b) + { + if (a.pn[0] != (unsigned int)b) + return false; + if (a.pn[1] != (unsigned int)(b >> 32)) + return false; + for (int i = 2; i < base_uint::WIDTH; i++) + if (a.pn[i] != 0) + return false; + return true; + } + + friend inline bool operator!=(const base_uint& a, const base_uint& b) + { + return (!(a == b)); + } + + friend inline bool operator!=(const base_uint& a, uint64_t b) + { + return (!(a == b)); + } + + + + std::string GetHex() const + { + char psz[sizeof(pn)*2 + 1]; + for (unsigned int i = 0; i < sizeof(pn); i++) + sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); + return std::string(psz, psz + sizeof(pn)*2); + } + + void SetHex(const char* psz) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + + // skip leading spaces + while (isspace(*psz)) + psz++; + + // skip 0x + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + + // hex string to uint + static const unsigned char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + const char* pbegin = psz; + while (phexdigit[(unsigned char)*psz] || *psz == '0') + psz++; + psz--; + unsigned char* p1 = (unsigned char*)pn; + unsigned char* pend = p1 + WIDTH * 4; + while (psz >= pbegin && p1 < pend) + { + *p1 = phexdigit[(unsigned char)*psz--]; + if (psz >= pbegin) + { + *p1 |= (phexdigit[(unsigned char)*psz--] << 4); + p1++; + } + } + } + + void SetHex(const std::string& str) + { + SetHex(str.c_str()); + } + + std::string ToString() const + { + return (GetHex()); + } + + unsigned char* begin() + { + return (unsigned char*)&pn[0]; + } + + unsigned char* end() + { + return (unsigned char*)&pn[WIDTH]; + } + + const unsigned char* begin() const + { + return (unsigned char*)&pn[0]; + } + + const unsigned char* end() const + { + return (unsigned char*)&pn[WIDTH]; + } + + unsigned int size() + { + return sizeof(pn); + } + + uint64_t Get64(int n=0) const + { + return pn[2*n] | (uint64_t)pn[2*n+1] << 32; + } + + unsigned int GetSerializeSize(int nType, int nVersion) const + { + return sizeof(pn); + } + + template + void Serialize(Stream& s, int nType, int nVersion) const + { + s.write((char*)pn, sizeof(pn)); + } + + template + void Unserialize(Stream& s, int nType, int nVersion) + { + s.read((char*)pn, sizeof(pn)); + } + + friend class uint160; + friend class uint256; + friend class uint512; + friend inline int Testuint256AdHoc(std::vector vArg); +}; + +typedef base_uint<160> base_uint160; +typedef base_uint<256> base_uint256; +typedef base_uint<512> base_uint512; + +// +// uint160 and uint256 could be implemented as templates, but to keep +// compile errors and debugging cleaner, they're copy and pasted. +// + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint160 +// + +/** 160-bit unsigned integer */ +class uint160 : public base_uint160 +{ +public: + typedef base_uint160 basetype; + + uint160() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint160(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint160& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint160(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint160& operator=(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint160(const std::string& str) + { + SetHex(str); + } + + explicit uint160(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint160& a, uint64_t b) { return (base_uint160)a == b; } +inline bool operator!=(const uint160& a, uint64_t b) { return (base_uint160)a != b; } +inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; } +inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; } + +inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; } +inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; } +inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; } +inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; } +inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; } + +inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint256 +// + +/** 256-bit unsigned integer */ +class uint256 : public base_uint256 +{ +public: + typedef base_uint256 basetype; + + uint256() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint256(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint256& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint256(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint256& operator=(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint256(const std::string& str) + { + SetHex(str); + } + + explicit uint256(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint256& a, uint64_t b) { return (base_uint256)a == b; } +inline bool operator!=(const uint256& a, uint64_t b) { return (base_uint256)a != b; } +inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; } +inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; } + +inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; } +inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; } +inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; } +inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; } +inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; } + +inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint512 +// + +/** 512-bit unsigned integer */ +class uint512 : public base_uint512 +{ +public: + typedef base_uint512 basetype; + + uint512() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint512(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint512& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint512(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint512& operator=(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint512(const std::string& str) + { + SetHex(str); + } + + explicit uint512(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } + + uint256 trim256() const + { + uint256 ret; + for (unsigned int i = 0; i < uint256::WIDTH; i++){ + ret.pn[i] = pn[i]; + } + return ret; + } +}; + +inline bool operator==(const uint512& a, uint64_t b) { return (base_uint512)a == b; } +inline bool operator!=(const uint512& a, uint64_t b) { return (base_uint512)a != b; } +inline const uint512 operator<<(const base_uint512& a, unsigned int shift) { return uint512(a) <<= shift; } +inline const uint512 operator>>(const base_uint512& a, unsigned int shift) { return uint512(a) >>= shift; } +inline const uint512 operator<<(const uint512& a, unsigned int shift) { return uint512(a) <<= shift; } +inline const uint512 operator>>(const uint512& a, unsigned int shift) { return uint512(a) >>= shift; } + +inline const uint512 operator^(const base_uint512& a, const base_uint512& b) { return uint512(a) ^= b; } +inline const uint512 operator&(const base_uint512& a, const base_uint512& b) { return uint512(a) &= b; } +inline const uint512 operator|(const base_uint512& a, const base_uint512& b) { return uint512(a) |= b; } +inline const uint512 operator+(const base_uint512& a, const base_uint512& b) { return uint512(a) += b; } +inline const uint512 operator-(const base_uint512& a, const base_uint512& b) { return uint512(a) -= b; } + +inline bool operator<(const base_uint512& a, const uint512& b) { return (base_uint512)a < (base_uint512)b; } +inline bool operator<=(const base_uint512& a, const uint512& b) { return (base_uint512)a <= (base_uint512)b; } +inline bool operator>(const base_uint512& a, const uint512& b) { return (base_uint512)a > (base_uint512)b; } +inline bool operator>=(const base_uint512& a, const uint512& b) { return (base_uint512)a >= (base_uint512)b; } +inline bool operator==(const base_uint512& a, const uint512& b) { return (base_uint512)a == (base_uint512)b; } +inline bool operator!=(const base_uint512& a, const uint512& b) { return (base_uint512)a != (base_uint512)b; } +inline const uint512 operator^(const base_uint512& a, const uint512& b) { return (base_uint512)a ^ (base_uint512)b; } +inline const uint512 operator&(const base_uint512& a, const uint512& b) { return (base_uint512)a & (base_uint512)b; } +inline const uint512 operator|(const base_uint512& a, const uint512& b) { return (base_uint512)a | (base_uint512)b; } +inline const uint512 operator+(const base_uint512& a, const uint512& b) { return (base_uint512)a + (base_uint512)b; } +inline const uint512 operator-(const base_uint512& a, const uint512& b) { return (base_uint512)a - (base_uint512)b; } + +inline bool operator<(const uint512& a, const base_uint512& b) { return (base_uint512)a < (base_uint512)b; } +inline bool operator<=(const uint512& a, const base_uint512& b) { return (base_uint512)a <= (base_uint512)b; } +inline bool operator>(const uint512& a, const base_uint512& b) { return (base_uint512)a > (base_uint512)b; } +inline bool operator>=(const uint512& a, const base_uint512& b) { return (base_uint512)a >= (base_uint512)b; } +inline bool operator==(const uint512& a, const base_uint512& b) { return (base_uint512)a == (base_uint512)b; } +inline bool operator!=(const uint512& a, const base_uint512& b) { return (base_uint512)a != (base_uint512)b; } +inline const uint512 operator^(const uint512& a, const base_uint512& b) { return (base_uint512)a ^ (base_uint512)b; } +inline const uint512 operator&(const uint512& a, const base_uint512& b) { return (base_uint512)a & (base_uint512)b; } +inline const uint512 operator|(const uint512& a, const base_uint512& b) { return (base_uint512)a | (base_uint512)b; } +inline const uint512 operator+(const uint512& a, const base_uint512& b) { return (base_uint512)a + (base_uint512)b; } +inline const uint512 operator-(const uint512& a, const base_uint512& b) { return (base_uint512)a - (base_uint512)b; } + +inline bool operator<(const uint512& a, const uint512& b) { return (base_uint512)a < (base_uint512)b; } +inline bool operator<=(const uint512& a, const uint512& b) { return (base_uint512)a <= (base_uint512)b; } +inline bool operator>(const uint512& a, const uint512& b) { return (base_uint512)a > (base_uint512)b; } +inline bool operator>=(const uint512& a, const uint512& b) { return (base_uint512)a >= (base_uint512)b; } +inline bool operator==(const uint512& a, const uint512& b) { return (base_uint512)a == (base_uint512)b; } +inline bool operator!=(const uint512& a, const uint512& b) { return (base_uint512)a != (base_uint512)b; } +inline const uint512 operator^(const uint512& a, const uint512& b) { return (base_uint512)a ^ (base_uint512)b; } +inline const uint512 operator&(const uint512& a, const uint512& b) { return (base_uint512)a & (base_uint512)b; } +inline const uint512 operator|(const uint512& a, const uint512& b) { return (base_uint512)a | (base_uint512)b; } +inline const uint512 operator+(const uint512& a, const uint512& b) { return (base_uint512)a + (base_uint512)b; } +inline const uint512 operator-(const uint512& a, const uint512& b) { return (base_uint512)a - (base_uint512)b; } + +#ifdef TEST_UINT256 + +inline int Testuint256AdHoc(std::vector vArg) +{ + uint256 g(0); + + + LogPrintf("%s\n", g.ToString()); + g--; LogPrintf("g--\n"); + LogPrintf("%s\n", g.ToString()); + g--; LogPrintf("g--\n"); + LogPrintf("%s\n", g.ToString()); + g++; LogPrintf("g++\n"); + LogPrintf("%s\n", g.ToString()); + g++; LogPrintf("g++\n"); + LogPrintf("%s\n", g.ToString()); + g++; LogPrintf("g++\n"); + LogPrintf("%s\n", g.ToString()); + g++; LogPrintf("g++\n"); + LogPrintf("%s\n", g.ToString()); + + + + uint256 a(7); + LogPrintf("a=7\n"); + LogPrintf("%s\n", a.ToString()); + + uint256 b; + LogPrintf("b undefined\n"); + LogPrintf("%s\n", b.ToString()); + int c = 3; + + a = c; + a.pn[3] = 15; + LogPrintf("%s\n", a.ToString()); + uint256 k(c); + + a = 5; + a.pn[3] = 15; + LogPrintf("%s\n", a.ToString()); + b = 1; + b <<= 52; + + a |= b; + + a ^= 0x500; + + LogPrintf("a %s\n", a.ToString()); + + a = a | b | (uint256)0x1000; + + + LogPrintf("a %s\n", a.ToString()); + LogPrintf("b %s\n", b.ToString()); + + a = 0xfffffffe; + a.pn[4] = 9; + + LogPrintf("%s\n", a.ToString()); + a++; + LogPrintf("%s\n", a.ToString()); + a++; + LogPrintf("%s\n", a.ToString()); + a++; + LogPrintf("%s\n", a.ToString()); + a++; + LogPrintf("%s\n", a.ToString()); + + a--; + LogPrintf("%s\n", a.ToString()); + a--; + LogPrintf("%s\n", a.ToString()); + a--; + LogPrintf("%s\n", a.ToString()); + uint256 d = a--; + LogPrintf("%s\n", d.ToString()); + LogPrintf("%s\n", a.ToString()); + a--; + LogPrintf("%s\n", a.ToString()); + a--; + LogPrintf("%s\n", a.ToString()); + + d = a; + + LogPrintf("%s\n", d.ToString()); + for (int i = uint256::WIDTH-1; i >= 0; i--) LogPrintf("%08x", d.pn[i]); LogPrintf("\n"); + + uint256 neg = d; + neg = ~neg; + LogPrintf("%s\n", neg.ToString()); + + + uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + LogPrintf("\n"); + LogPrintf("%s\n", e.ToString()); + + + LogPrintf("\n"); + uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + uint256 x2; + LogPrintf("%s\n", x1.ToString()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1 << i; + LogPrintf("%s\n", x2.ToString()); + } + + LogPrintf("\n"); + LogPrintf("%s\n", x1.ToString()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1; + x2 >>= i; + LogPrintf("%s\n", x2.ToString()); + } + + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) >> i); + LogPrintf("%s\n", k.ToString()); + } + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) << i); + LogPrintf("%s\n", k.ToString()); + } + + return (0); +} + +#endif + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/util.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/util.cpp new file mode 100644 index 0000000..d22fd6b --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/util.cpp @@ -0,0 +1,1467 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "util.h" + +#include "chainparams.h" +#include "sync.h" +#include "ui_interface.h" +#include "uint256.h" +#include "version.h" + +#include + +#include + +#include // for to_lower() +#include +#include // for startswith() and endswith() + +// Work around clang compilation problem in Boost 1.46: +// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup +// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options +// http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION +namespace boost { + namespace program_options { + std::string to_internal(const std::string&); + } +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4804) +#pragma warning(disable:4805) +#pragma warning(disable:4717) +#endif +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include /* for _commit */ +#include "shlobj.h" +#elif defined(__linux__) +# include +#endif + +using namespace std; + +//Dark features +bool fMasterNode = false; +string strMasterNodePrivKey = ""; +string strMasterNodeAddr = ""; +bool fLiteMode = false; +int nInstantXDepth = 1; +int nDarksendRounds = 2; +int nAnonymizephantomxAmount = 500; +int nLiquidityProvider = 0; +/** Spork enforcement enabled time */ +int64_t enforceMasternodePaymentsTime = 4085657524; +bool fSucessfullyLoaded = false; +bool fEnableDarksend = false; +/** All denominations used by darksend */ +std::vector darkSendDenominations; + +map mapArgs; +map > mapMultiArgs; +bool fDebug = false; +bool fDebugSmsg = false; +bool fNoSmsg = false; +bool fPrintToConsole = false; +bool fPrintToDebugLog = true; +bool fDaemon = false; +bool fServer = false; +bool fCommandLine = false; +string strMiscWarning; +bool fNoListen = false; +bool fLogTimestamps = false; +bool fMasternodeSoftLock = false; +volatile bool fReopenDebugLog = false; + +// Init OpenSSL library multithreading support +static CCriticalSection** ppmutexOpenSSL; +void locking_callback(int mode, int i, const char* file, int line) +{ + if (mode & CRYPTO_LOCK) { + ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]); + } else { + LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]); + } +} + +LockedPageManager LockedPageManager::instance; + +// Init +class CInit +{ +public: + CInit() + { + // Init OpenSSL library multithreading support + ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*)); + for (int i = 0; i < CRYPTO_num_locks(); i++) + ppmutexOpenSSL[i] = new CCriticalSection(); + CRYPTO_set_locking_callback(locking_callback); + +#ifdef WIN32 + // Seed OpenSSL PRNG with current contents of the screen + RAND_screen(); +#endif + + // Seed OpenSSL PRNG with performance counter + RandAddSeed(); + } + ~CInit() + { + // Securely erase the memory used by the PRNG + RAND_cleanup(); + // Shutdown OpenSSL library multithreading support + CRYPTO_set_locking_callback(NULL); + for (int i = 0; i < CRYPTO_num_locks(); i++) + delete ppmutexOpenSSL[i]; + OPENSSL_free(ppmutexOpenSSL); + } +} +instance_of_cinit; + + + + + + + + +void RandAddSeed() +{ + // Seed with CPU performance counter + int64_t nCounter = GetPerformanceCounter(); + RAND_add(&nCounter, sizeof(nCounter), 1.5); + memset(&nCounter, 0, sizeof(nCounter)); +} + +void RandAddSeedPerfmon() +{ + RandAddSeed(); + + // This can take up to 2 seconds, so only do it every 10 minutes + static int64_t nLastPerfmon; + if (GetTime() < nLastPerfmon + 10 * 60) + return; + nLastPerfmon = GetTime(); + +#ifdef WIN32 + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom + // Seed with the entire set of perfmon data + unsigned char pdata[250000]; + memset(pdata, 0, sizeof(pdata)); + unsigned long nSize = sizeof(pdata); + long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + RegCloseKey(HKEY_PERFORMANCE_DATA); + if (ret == ERROR_SUCCESS) + { + RAND_add(pdata, nSize, nSize/100.0); + OPENSSL_cleanse(pdata, nSize); + LogPrint("rand", "RandAddSeed() %lu bytes\n", nSize); + } +#endif +} + +uint64_t GetRand(uint64_t nMax) +{ + if (nMax == 0) + return 0; + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64_t nRange = (std::numeric_limits::max() / nMax) * nMax; + uint64_t nRand = 0; + do + RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); + while (nRand >= nRange); + return (nRand % nMax); +} + +int GetRandInt(int nMax) +{ + return GetRand(nMax); +} + +uint256 GetRandHash() +{ + uint256 hash; + RAND_bytes((unsigned char*)&hash, sizeof(hash)); + return hash; +} + +void GetRandBytes(unsigned char* buf, int num) +{ + if (RAND_bytes(buf, num) != 1) { + LogPrintf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL)); + assert(false); + } +} + +// LogPrintf() has been broken a couple of times now +// by well-meaning people adding mutexes in the most straightforward way. +// It breaks because it may be called by global destructors during shutdown. +// Since the order of destruction of static/global objects is undefined, +// defining a mutex as a global object doesn't work (the mutex gets +// destroyed, and then some later destructor calls OutputDebugStringF, +// maybe indirectly, and you get a core dump at shutdown trying to lock +// the mutex). + +static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT; +// We use boost::call_once() to make sure these are initialized in +// in a thread-safe manner the first time it is called: +static FILE* fileout = NULL; +static boost::mutex* mutexDebugLog = NULL; + +static void DebugPrintInit() +{ + assert(fileout == NULL); + assert(mutexDebugLog == NULL); + + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + fileout = fopen(pathDebug.string().c_str(), "a"); + if (fileout) setbuf(fileout, NULL); // unbuffered + + mutexDebugLog = new boost::mutex(); +} + +bool LogAcceptCategory(const char* category) +{ + if (category != NULL) + { + if (!fDebug) + return false; + + // Give each thread quick access to -debug settings. + // This helps prevent issues debugging global destructors, + // where mapMultiArgs might be deleted before another + // global destructor calls LogPrint() + static boost::thread_specific_ptr > ptrCategory; + if (ptrCategory.get() == NULL) + { + const vector& categories = mapMultiArgs["-debug"]; + ptrCategory.reset(new set(categories.begin(), categories.end())); + // thread_specific_ptr automatically deletes the set when the thread ends. + } + const set& setCategories = *ptrCategory.get(); + + // if not debugging everything and not debugging specific category, LogPrint does nothing. + if (setCategories.count(string("")) == 0 && + setCategories.count(string(category)) == 0) + return false; + } + return true; +} + +int LogPrintStr(const std::string &str) +{ + int ret = 0; // Returns total number of characters written + if (fPrintToConsole) + { + // print to console + ret = fwrite(str.data(), 1, str.size(), stdout); + } + else if (fPrintToDebugLog) + { + static bool fStartedNewLine = true; + boost::call_once(&DebugPrintInit, debugPrintInitFlag); + + if (fileout == NULL) + return ret; + + boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); + + // reopen the log file, if requested + if (fReopenDebugLog) { + fReopenDebugLog = false; + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL) + setbuf(fileout, NULL); // unbuffered + } + + // Debug print useful for profiling + if (fLogTimestamps && fStartedNewLine) + ret += fprintf(fileout, "%s ", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str()); + if (!str.empty() && str[str.size()-1] == '\n') + fStartedNewLine = true; + else + fStartedNewLine = false; + + ret = fwrite(str.data(), 1, str.size(), fileout); + } + + return ret; +} + +void ParseString(const string& str, char c, vector& v) +{ + if (str.empty()) + return; + string::size_type i1 = 0; + string::size_type i2; + while (true) + { + i2 = str.find(c, i1); + if (i2 == str.npos) + { + v.push_back(str.substr(i1)); + return; + } + v.push_back(str.substr(i1, i2-i1)); + i1 = i2+1; + } +} + + +string FormatMoney(int64_t n, bool fPlus) +{ + // Note: not using straight sprintf here because we do NOT want + // localized number formatting. + int64_t n_abs = (n > 0 ? n : -n); + int64_t quotient = n_abs/COIN; + int64_t remainder = n_abs%COIN; + string str = strprintf("%d.%08d", quotient, remainder); + + // Right-trim excess zeros before the decimal point: + int nTrim = 0; + for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i) + ++nTrim; + if (nTrim) + str.erase(str.size()-nTrim, nTrim); + + if (n < 0) + str.insert((unsigned int)0, 1, '-'); + else if (fPlus && n > 0) + str.insert((unsigned int)0, 1, '+'); + return str; +} + + +bool ParseMoney(const string& str, int64_t& nRet) +{ + return ParseMoney(str.c_str(), nRet); +} + +bool ParseMoney(const char* pszIn, int64_t& nRet) +{ + string strWhole; + int64_t nUnits = 0; + const char* p = pszIn; + while (isspace(*p)) + p++; + for (; *p; p++) + { + if (*p == '.') + { + p++; + int64_t nMult = CENT*10; + while (isdigit(*p) && (nMult > 0)) + { + nUnits += nMult * (*p++ - '0'); + nMult /= 10; + } + break; + } + if (isspace(*p)) + break; + if (!isdigit(*p)) + return false; + strWhole.insert(strWhole.end(), *p); + } + for (; *p; p++) + if (!isspace(*p)) + return false; + if (strWhole.size() > 10) // guard against 63 bit overflow + return false; + if (nUnits < 0 || nUnits > COIN) + return false; + int64_t nWhole = atoi64(strWhole); + int64_t nValue = nWhole*COIN + nUnits; + + nRet = nValue; + return true; +} + +// safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything +// even possibly remotely dangerous like & or > +static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@"); +string SanitizeString(const string& str) +{ + string strResult; + for (std::string::size_type i = 0; i < str.size(); i++) + { + if (safeChars.find(str[i]) != std::string::npos) + strResult.push_back(str[i]); + } + return strResult; +} + +static const signed char phexdigit[256] = +{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; + +bool IsHex(const string& str) +{ + BOOST_FOREACH(unsigned char c, str) + { + if (phexdigit[c] < 0) + return false; + } + return (str.size() > 0) && (str.size()%2 == 0); +} + +vector ParseHex(const char* psz) +{ + // convert hex dump to vector + vector vch; + while (true) + { + while (isspace(*psz)) + psz++; + signed char c = phexdigit[(unsigned char)*psz++]; + if (c == (signed char)-1) + break; + unsigned char n = (c << 4); + c = phexdigit[(unsigned char)*psz++]; + if (c == (signed char)-1) + break; + n |= c; + vch.push_back(n); + } + return vch; +} + +vector ParseHex(const string& str) +{ + return ParseHex(str.c_str()); +} + +static void InterpretNegativeSetting(string name, map& mapSettingsRet) +{ + // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set + if (name.find("-no") == 0) + { + std::string positive("-"); + positive.append(name.begin()+3, name.end()); + if (mapSettingsRet.count(positive) == 0) + { + bool value = !GetBoolArg(name, false); + mapSettingsRet[positive] = (value ? "1" : "0"); + } + } +} + +void ParseParameters(int argc, const char* const argv[]) +{ + mapArgs.clear(); + mapMultiArgs.clear(); + for (int i = 1; i < argc; i++) + { + std::string str(argv[i]); + std::string strValue; + size_t is_index = str.find('='); + if (is_index != std::string::npos) + { + strValue = str.substr(is_index+1); + str = str.substr(0, is_index); + } +#ifdef WIN32 + boost::to_lower(str); + if (boost::algorithm::starts_with(str, "/")) + str = "-" + str.substr(1); +#endif + if (str[0] != '-') + break; + + mapArgs[str] = strValue; + mapMultiArgs[str].push_back(strValue); + } + + // New 0.6 features: + BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs) + { + string name = entry.first; + + // interpret --foo as -foo (as long as both are not set) + if (name.find("--") == 0) + { + std::string singleDash(name.begin()+1, name.end()); + if (mapArgs.count(singleDash) == 0) + mapArgs[singleDash] = entry.second; + name = singleDash; + } + + // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set + InterpretNegativeSetting(name, mapArgs); + } +} + +std::string GetArg(const std::string& strArg, const std::string& strDefault) +{ + if (mapArgs.count(strArg)) + return mapArgs[strArg]; + return strDefault; +} + +int64_t GetArg(const std::string& strArg, int64_t nDefault) +{ + if (mapArgs.count(strArg)) + return atoi64(mapArgs[strArg]); + return nDefault; +} + +bool GetBoolArg(const std::string& strArg, bool fDefault) +{ + if (mapArgs.count(strArg)) + { + if (mapArgs[strArg].empty()) + return true; + return (atoi(mapArgs[strArg]) != 0); + } + return fDefault; +} + +bool SoftSetArg(const std::string& strArg, const std::string& strValue) +{ + if (mapArgs.count(strArg)) + return false; + mapArgs[strArg] = strValue; + return true; +} + +bool SoftSetBoolArg(const std::string& strArg, bool fValue) +{ + if (fValue) + return SoftSetArg(strArg, std::string("1")); + else + return SoftSetArg(strArg, std::string("0")); +} + + +string EncodeBase64(const unsigned char* pch, size_t len) +{ + static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + string strRet=""; + strRet.reserve((len+2)/3*4); + + int mode=0, left=0; + const unsigned char *pchEnd = pch+len; + + while (pch> 2]; + left = (enc & 3) << 4; + mode = 1; + break; + + case 1: // we have two bits + strRet += pbase64[left | (enc >> 4)]; + left = (enc & 15) << 2; + mode = 2; + break; + + case 2: // we have four bits + strRet += pbase64[left | (enc >> 6)]; + strRet += pbase64[enc & 63]; + mode = 0; + break; + } + } + + if (mode) + { + strRet += pbase64[left]; + strRet += '='; + if (mode == 1) + strRet += '='; + } + + return strRet; +} + +string EncodeBase64(const string& str) +{ + return EncodeBase64((const unsigned char*)str.c_str(), str.size()); +} + +vector DecodeBase64(const char* p, bool* pfInvalid) +{ + static const int decode64_table[256] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, + -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + if (pfInvalid) + *pfInvalid = false; + + vector vchRet; + vchRet.reserve(strlen(p)*3/4); + + int mode = 0; + int left = 0; + + while (1) + { + int dec = decode64_table[(unsigned char)*p]; + if (dec == -1) break; + p++; + switch (mode) + { + case 0: // we have no bits and get 6 + left = dec; + mode = 1; + break; + + case 1: // we have 6 bits and keep 4 + vchRet.push_back((left<<2) | (dec>>4)); + left = dec & 15; + mode = 2; + break; + + case 2: // we have 4 bits and get 6, we keep 2 + vchRet.push_back((left<<4) | (dec>>2)); + left = dec & 3; + mode = 3; + break; + + case 3: // we have 2 bits and get 6 + vchRet.push_back((left<<6) | dec); + mode = 0; + break; + } + } + + if (pfInvalid) + switch (mode) + { + case 0: // 4n base64 characters processed: ok + break; + + case 1: // 4n+1 base64 character processed: impossible + *pfInvalid = true; + break; + + case 2: // 4n+2 base64 characters processed: require '==' + if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1) + *pfInvalid = true; + break; + + case 3: // 4n+3 base64 characters processed: require '=' + if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1) + *pfInvalid = true; + break; + } + + return vchRet; +} + +string DecodeBase64(const string& str) +{ + vector vchRet = DecodeBase64(str.c_str()); + return string((const char*)&vchRet[0], vchRet.size()); +} + +// Base64 encoding with secure memory allocation +SecureString EncodeBase64Secure(const SecureString& input) +{ + // Init openssl BIO with base64 filter and memory output + BIO *b64, *mem; + b64 = BIO_new(BIO_f_base64()); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); // No newlines in output + mem = BIO_new(BIO_s_mem()); + BIO_push(b64, mem); + + // Decode the string + BIO_write(b64, &input[0], input.size()); + (void) BIO_flush(b64); + + // Create output variable from buffer mem ptr + BUF_MEM *bptr; + BIO_get_mem_ptr(b64, &bptr); + SecureString output(bptr->data, bptr->length); + + // Cleanse secure data buffer from memory + OPENSSL_cleanse((void *) bptr->data, bptr->length); + + // Free memory + BIO_free_all(b64); + return output; +} + +// Base64 decoding with secure memory allocation +SecureString DecodeBase64Secure(const SecureString& input) +{ + SecureString output; + + // Init openssl BIO with base64 filter and memory input + BIO *b64, *mem; + b64 = BIO_new(BIO_f_base64()); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer + mem = BIO_new_mem_buf((void *) &input[0], input.size()); + BIO_push(b64, mem); + + // Prepare buffer to receive decoded data + if(input.size() % 4 != 0) { + throw runtime_error("Input length should be a multiple of 4"); + } + size_t nMaxLen = input.size() / 4 * 3; // upper bound, guaranteed divisible by 4 + output.resize(nMaxLen); + + // Decode the string + size_t nLen; + nLen = BIO_read(b64, (void *) &output[0], input.size()); + output.resize(nLen); + + // Free memory + BIO_free_all(b64); + return output; +} + + +string EncodeBase32(const unsigned char* pch, size_t len) +{ + static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567"; + + string strRet=""; + strRet.reserve((len+4)/5*8); + + int mode=0, left=0; + const unsigned char *pchEnd = pch+len; + + while (pch> 3]; + left = (enc & 7) << 2; + mode = 1; + break; + + case 1: // we have three bits + strRet += pbase32[left | (enc >> 6)]; + strRet += pbase32[(enc >> 1) & 31]; + left = (enc & 1) << 4; + mode = 2; + break; + + case 2: // we have one bit + strRet += pbase32[left | (enc >> 4)]; + left = (enc & 15) << 1; + mode = 3; + break; + + case 3: // we have four bits + strRet += pbase32[left | (enc >> 7)]; + strRet += pbase32[(enc >> 2) & 31]; + left = (enc & 3) << 3; + mode = 4; + break; + + case 4: // we have two bits + strRet += pbase32[left | (enc >> 5)]; + strRet += pbase32[enc & 31]; + mode = 0; + } + } + + static const int nPadding[5] = {0, 6, 4, 3, 1}; + if (mode) + { + strRet += pbase32[left]; + for (int n=0; n DecodeBase32(const char* p, bool* pfInvalid) +{ + static const int decode32_table[256] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + if (pfInvalid) + *pfInvalid = false; + + vector vchRet; + vchRet.reserve((strlen(p))*5/8); + + int mode = 0; + int left = 0; + + while (1) + { + int dec = decode32_table[(unsigned char)*p]; + if (dec == -1) break; + p++; + switch (mode) + { + case 0: // we have no bits and get 5 + left = dec; + mode = 1; + break; + + case 1: // we have 5 bits and keep 2 + vchRet.push_back((left<<3) | (dec>>2)); + left = dec & 3; + mode = 2; + break; + + case 2: // we have 2 bits and keep 7 + left = left << 5 | dec; + mode = 3; + break; + + case 3: // we have 7 bits and keep 4 + vchRet.push_back((left<<1) | (dec>>4)); + left = dec & 15; + mode = 4; + break; + + case 4: // we have 4 bits, and keep 1 + vchRet.push_back((left<<4) | (dec>>1)); + left = dec & 1; + mode = 5; + break; + + case 5: // we have 1 bit, and keep 6 + left = left << 5 | dec; + mode = 6; + break; + + case 6: // we have 6 bits, and keep 3 + vchRet.push_back((left<<2) | (dec>>3)); + left = dec & 7; + mode = 7; + break; + + case 7: // we have 3 bits, and keep 0 + vchRet.push_back((left<<5) | dec); + mode = 0; + break; + } + } + + if (pfInvalid) + switch (mode) + { + case 0: // 8n base32 characters processed: ok + break; + + case 1: // 8n+1 base32 characters processed: impossible + case 3: // +3 + case 6: // +6 + *pfInvalid = true; + break; + + case 2: // 8n+2 base32 characters processed: require '======' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1) + *pfInvalid = true; + break; + + case 4: // 8n+4 base32 characters processed: require '====' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1) + *pfInvalid = true; + break; + + case 5: // 8n+5 base32 characters processed: require '===' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1) + *pfInvalid = true; + break; + + case 7: // 8n+7 base32 characters processed: require '=' + if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1) + *pfInvalid = true; + break; + } + + return vchRet; +} + +string DecodeBase32(const string& str) +{ + vector vchRet = DecodeBase32(str.c_str()); + return string((const char*)&vchRet[0], vchRet.size()); +} + + +bool WildcardMatch(const char* psz, const char* mask) +{ + while (true) + { + switch (*mask) + { + case '\0': + return (*psz == '\0'); + case '*': + return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask)); + case '?': + if (*psz == '\0') + return false; + break; + default: + if (*psz != *mask) + return false; + break; + } + psz++; + mask++; + } +} + +bool WildcardMatch(const string& str, const string& mask) +{ + return WildcardMatch(str.c_str(), mask.c_str()); +} + + +bool ParseInt32(const std::string& str, int32_t *out) +{ + char *endp = NULL; + errno = 0; // strtol will not set errno if valid + long int n = strtol(str.c_str(), &endp, 10); + if(out) *out = (int)n; + // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow + // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit + // platforms the size of these types may be different. + return endp && *endp == 0 && !errno && + n >= std::numeric_limits::min() && + n <= std::numeric_limits::max(); +} + +std::string FormatParagraph(const std::string in, size_t width, size_t indent) +{ + std::stringstream out; + size_t col = 0; + size_t ptr = 0; + while(ptr < in.size()) + { + // Find beginning of next word + ptr = in.find_first_not_of(' ', ptr); + if (ptr == std::string::npos) + break; + // Find end of next word + size_t endword = in.find_first_of(' ', ptr); + if (endword == std::string::npos) + endword = in.size(); + // Add newline and indentation if this wraps over the allowed width + if (col > 0) + { + if ((col + endword - ptr) > width) + { + out << '\n'; + for(size_t i=0; iwhat(), pszModule, pszThread); + else + return strprintf( + "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); +} + +void PrintException(std::exception* pex, const char* pszThread) +{ + std::string message = FormatException(pex, pszThread); + LogPrintf("\n\n************************\n%s\n", message); + fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); + strMiscWarning = message; + throw; +} + +void PrintExceptionContinue(std::exception* pex, const char* pszThread) +{ + std::string message = FormatException(pex, pszThread); + LogPrintf("\n\n************************\n%s\n", message); + fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); + strMiscWarning = message; +} + +boost::filesystem::path GetDefaultDataDir() +{ + namespace fs = boost::filesystem; + // Windows < Vista: C:\Documents and Settings\Username\Application Data\phantomx + // Windows >= Vista: C:\Users\Username\AppData\Roaming\phantomx + // Mac: ~/Library/Application Support/phantomx + // Unix: ~/.phantomx +#ifdef WIN32 + // Windows + return GetSpecialFolderPath(CSIDL_APPDATA) / "phantomx"; +#else + fs::path pathRet; + char* pszHome = getenv("HOME"); + if (pszHome == NULL || strlen(pszHome) == 0) + pathRet = fs::path("/"); + else + pathRet = fs::path(pszHome); +#ifdef MAC_OSX + // Mac + pathRet /= "Library/Application Support"; + fs::create_directory(pathRet); + return pathRet / "phantomx"; +#else + // Unix + return pathRet / ".phantomx"; +#endif +#endif +} + +static boost::filesystem::path pathCached[CChainParams::MAX_NETWORK_TYPES+1]; +static CCriticalSection csPathCached; + +const boost::filesystem::path &GetDataDir(bool fNetSpecific) +{ + namespace fs = boost::filesystem; + + LOCK(csPathCached); + + int nNet = CChainParams::MAX_NETWORK_TYPES; + if (fNetSpecific) nNet = Params().NetworkID(); + + fs::path &path = pathCached[nNet]; + + // This can be called during exceptions by LogPrintf(), so we cache the + // value so we don't have to do memory allocations after that. + if (!path.empty()) + return path; + + if (mapArgs.count("-datadir")) { + path = fs::system_complete(mapArgs["-datadir"]); + if (!fs::is_directory(path)) { + path = ""; + return path; + } + } else { + path = GetDefaultDataDir(); + } + if (fNetSpecific) + path /= Params().DataDir(); + + fs::create_directory(path); + + return path; +} + +void ClearDatadirCache() +{ + std::fill(&pathCached[0], &pathCached[CChainParams::MAX_NETWORK_TYPES+1], + boost::filesystem::path()); +} + +boost::filesystem::path GetConfigFile() +{ + boost::filesystem::path pathConfigFile(GetArg("-conf", "phantomx.conf")); + if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile; + return pathConfigFile; +} + +boost::filesystem::path GetMasternodeConfigFile() +{ + boost::filesystem::path pathConfigFile(GetArg("-mnconf", "masternode.conf")); + if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile; + return pathConfigFile; +} + +void ReadConfigFile(map& mapSettingsRet, + map >& mapMultiSettingsRet) +{ + boost::filesystem::ifstream streamConfig(GetConfigFile()); + if (!streamConfig.good()){ + // Create empty phantomx.conf if it does not excist + FILE* configFile = fopen(GetConfigFile().string().c_str(), "w"); + + // If it is the first time that the file is created, we fill with some info + if (configFile) + { + + //Generate Random string for RPC user + //const char* rstruser = random_string(10); + //const char* rstrpass = random_string(15); + + //Fill phantomx.conf with staking deafult info + const char* chStr1 = "rpcallowip=127.0.0.1"; + const char* chStr2 = "rpcuser="; + char* chStr21 = random_string(15); + const char* chStr3 = "rpcpassword="; + char* chStr31 = random_string(20); + const char* chStr32 = "rpcport=21978"; + const char* chStr4 = "staking=1"; + const char* chStr5 = "server=1"; + const char* chStr6 = "listen=1"; + const char* chStr7 = "addnode=195.201.119.57"; + const char* chStr8 = "addnode=159.69.28.84"; + const char* chStr9 = "addnode=54.218.118.59:9340"; + const char* chStr10 = "addnode=54.218.118.59:9341"; + + fprintf(configFile, "%s\n%s%s\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", chStr1, chStr2, chStr21, chStr3, chStr31, chStr32, chStr4, chStr5, chStr6, chStr7, chStr8, chStr9, chStr10); + fclose(configFile); + + // else if the file exist return instead + }else if (configFile != NULL){ + fclose(configFile); + } + return; // Nothing to read, so just return + } + + set setOptions; + setOptions.insert("*"); + + for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it) + { + // Don't overwrite existing settings so command line settings override bitcoin.conf + string strKey = string("-") + it->string_key; + if (mapSettingsRet.count(strKey) == 0) + { + mapSettingsRet[strKey] = it->value[0]; + // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set) + InterpretNegativeSetting(strKey, mapSettingsRet); + } + mapMultiSettingsRet[strKey].push_back(it->value[0]); + } + // If datadir is changed in .conf file: + ClearDatadirCache(); +} + +boost::filesystem::path GetPidFile() +{ + boost::filesystem::path pathPidFile(GetArg("-pid", "phantomxd.pid")); + if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile; + return pathPidFile; +} + +#ifndef WIN32 +void CreatePidFile(const boost::filesystem::path &path, pid_t pid) +{ + FILE* file = fopen(path.string().c_str(), "w"); + if (file) + { + fprintf(file, "%d\n", pid); + fclose(file); + } +} +#endif + +bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest) +{ +#ifdef WIN32 + return MoveFileExA(src.string().c_str(), dest.string().c_str(), + MOVEFILE_REPLACE_EXISTING); +#else + int rc = std::rename(src.string().c_str(), dest.string().c_str()); + return (rc == 0); +#endif /* WIN32 */ +} + +void FileCommit(FILE *fileout) +{ + fflush(fileout); // harmless if redundantly called +#ifdef WIN32 + _commit(_fileno(fileout)); +#else + fsync(fileno(fileout)); +#endif +} + +std::string getTimeString(int64_t timestamp, char *buffer, size_t nBuffer) +{ + struct tm* dt; + time_t t = timestamp; + dt = localtime(&t); + + strftime(buffer, nBuffer, "%Y-%m-%d %H:%M:%S %z", dt); // %Z shows long strings on windows + return std::string(buffer); // copies the null-terminated character sequence +}; + +std::string bytesReadable(uint64_t nBytes) +{ + if (nBytes >= 1024ll*1024ll*1024ll*1024ll) + return strprintf("%.2f TB", nBytes/1024.0/1024.0/1024.0/1024.0); + if (nBytes >= 1024*1024*1024) + return strprintf("%.2f GB", nBytes/1024.0/1024.0/1024.0); + if (nBytes >= 1024*1024) + return strprintf("%.2f MB", nBytes/1024.0/1024.0); + if (nBytes >= 1024) + return strprintf("%.2f KB", nBytes/1024.0); + + return strprintf("%d B", nBytes); +}; + +void ShrinkDebugFile() +{ + // Scroll debug.log if it's getting too big + boost::filesystem::path pathLog = GetDataDir() / "debug.log"; + FILE* file = fopen(pathLog.string().c_str(), "r"); + if (file && boost::filesystem::file_size(pathLog) > 10 * 1000000) + { + // Restart the file with some of the end + char pch[200000]; + fseek(file, -sizeof(pch), SEEK_END); + int nBytes = fread(pch, 1, sizeof(pch), file); + fclose(file); + + file = fopen(pathLog.string().c_str(), "w"); + if (file) + { + fwrite(pch, 1, nBytes, file); + fclose(file); + } + } +} + +static int64_t nMockTime = 0; // For unit testing + +int64_t GetTime() +{ + if (nMockTime) return nMockTime; + + return time(NULL); +} + +void SetMockTime(int64_t nMockTimeIn) +{ + nMockTime = nMockTimeIn; +} + +uint32_t insecure_rand_Rz = 11; +uint32_t insecure_rand_Rw = 11; +void seed_insecure_rand(bool fDeterministic) +{ + //The seed values have some unlikely fixed points which we avoid. + if(fDeterministic) + { + insecure_rand_Rz = insecure_rand_Rw = 11; + } else { + uint32_t tmp; + do{ + RAND_bytes((unsigned char*)&tmp,4); + }while(tmp==0 || tmp==0x9068ffffU); + insecure_rand_Rz=tmp; + do{ + RAND_bytes((unsigned char*)&tmp,4); + }while(tmp==0 || tmp==0x464fffffU); + insecure_rand_Rw=tmp; + } +} + +string FormatVersion(int nVersion) +{ + if (nVersion%100 == 0) + return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100); + else + return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100); +} + +string FormatFullVersion() +{ + return CLIENT_BUILD; +} + +// Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014) +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments) +{ + std::ostringstream ss; + ss << "/"; + ss << name << ":" << FormatVersion(nClientVersion); + if (!comments.empty()) + ss << "(" << boost::algorithm::join(comments, "; ") << ")"; + ss << "/"; + return ss.str(); +} + +#ifdef WIN32 +boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate) +{ + namespace fs = boost::filesystem; + + char pszPath[MAX_PATH] = ""; + + if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate)) + { + return fs::path(pszPath); + } + + LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n"); + return fs::path(""); +} +#endif + +void runCommand(std::string strCommand) +{ + int nErr = ::system(strCommand.c_str()); + if (nErr) + LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr); +} + +void RenameThread(const char* name) +{ +#if defined(PR_SET_NAME) + // Only the first 15 characters are used (16 - NUL terminator) + ::prctl(PR_SET_NAME, name, 0, 0, 0); +#elif 0 && (defined(__FreeBSD__) || defined(__OpenBSD__)) + // TODO: This is currently disabled because it needs to be verified to work + // on FreeBSD or OpenBSD first. When verified the '0 &&' part can be + // removed. + pthread_set_name_np(pthread_self(), name); + +#elif defined(MAC_OSX) && defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +// pthread_setname_np is XCode 10.6-and-later +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 + pthread_setname_np(name); +#endif + +#else + // Prevent warnings for unused parameters... + (void)name; +#endif +} + +std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime) +{ + // std::locale takes ownership of the pointer + std::locale loc(std::locale::classic(), new boost::posix_time::time_facet(pszFormat)); + std::stringstream ss; + ss.imbue(loc); + ss << boost::posix_time::from_time_t(nTime); + return ss.str(); +} + + + + + + +std::string EpochToDateTimeStrFormat(int64_t nTime) +{ + std::string strTimestampFormat = "%Y-%m-%d %H:%M:%S UTC"; + return DateTimeStrFormat(strTimestampFormat.c_str(), nTime); +} + + + +/* ONLY FOR C++11 directives +std::string random_string() +{ + std::string str("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + + std::random_device rd; + std::mt19937 generator(rd()); + + std::shuffle(str.begin(), str.end(), generator); + + return str.substr(0, 32); // assumes 32 < number of characters in str +} +*/ + +int intN(int n) { return rand() % n; } + +char *random_string(int len) { + /* alphabet: [a-z0-9] */ + const char alphabet[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + + char *rstr = (char *)malloc((len + 1) * sizeof(char)); + int i; + for (i = 0; i < len; i++) { + rstr[i] = alphabet[intN(strlen(alphabet))]; + } + rstr[len] = '\0'; + return rstr; +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/util.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/util.h new file mode 100644 index 0000000..6e9f331 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/util.h @@ -0,0 +1,631 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_H +#define BITCOIN_UTIL_H + +#ifndef WIN32 +#include +#include +#include +#endif + +#include "serialize.h" +#include "tinyformat.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include // for OPENSSL_cleanse() +#include +#include + +#include + +class uint256; + +static const int64_t COIN = 100000000; +static const int64_t CENT = 1000000; + +typedef int64_t CAmount; + +#define BEGIN(a) ((char*)&(a)) +#define END(a) ((char*)&((&(a))[1])) +#define UBEGIN(a) ((unsigned char*)&(a)) +#define UEND(a) ((unsigned char*)&((&(a))[1])) +#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) + +#define UVOIDBEGIN(a) ((void*)&(a)) +#define CVOIDBEGIN(a) ((const void*)&(a)) +#define UINTBEGIN(a) ((uint32_t*)&(a)) +#define CUINTBEGIN(a) ((const uint32_t*)&(a)) + +/* Format characters for (s)size_t and ptrdiff_t */ +#if defined(_MSC_VER) || defined(__MSVCRT__) + /* (s)size_t and ptrdiff_t have the same size specifier in MSVC: + http://msdn.microsoft.com/en-us/library/tcxf1dw6%28v=vs.100%29.aspx + */ + #define PRIszx "Ix" + #define PRIszu "Iu" + #define PRIszd "Id" + #define PRIpdx "Ix" + #define PRIpdu "Iu" + #define PRIpdd "Id" +#else /* C99 standard */ + #define PRIszx "zx" + #define PRIszu "zu" + #define PRIszd "zd" + #define PRIpdx "tx" + #define PRIpdu "tu" + #define PRIpdd "td" +#endif + +// This is needed because the foreach macro can't get over the comma in pair +#define PAIRTYPE(t1, t2) std::pair + +// Align by increasing pointer, must have extra space at end of buffer +template +T* alignup(T* p) +{ + union + { + T* ptr; + size_t n; + } u; + u.ptr = p; + u.n = (u.n + (nBytes-1)) & ~(nBytes-1); + return u.ptr; +} + +boost::filesystem::path GetMasternodeConfigFile(); + +#ifdef WIN32 +#define MSG_NOSIGNAL 0 +#define MSG_DONTWAIT 0 + +#ifndef S_IRUSR +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#endif +#else +#define MAX_PATH 1024 +#endif + +inline void MilliSleep(int64_t n) +{ +#if BOOST_VERSION >= 105000 + boost::this_thread::sleep_for(boost::chrono::milliseconds(n)); +#else + boost::this_thread::sleep(boost::posix_time::milliseconds(n)); +#endif +} + +//Dark features + +extern bool fMasterNode; +extern bool fLiteMode; +extern int nInstantXDepth; +extern int nDarksendRounds; +extern int nAnonymizephantomxAmount; +extern int nLiquidityProvider; +extern bool fEnableDarksend; +extern int64_t enforceMasternodePaymentsTime; +extern std::string strMasterNodeAddr; +extern int keysLoaded; +extern bool fSucessfullyLoaded; +extern std::vector darkSendDenominations; + + +extern std::map mapArgs; +extern std::map > mapMultiArgs; +extern bool fDebug; +extern bool fDebugSmsg; +extern bool fNoSmsg; +extern bool fPrintToConsole; +extern bool fPrintToDebugLog; +extern bool fDaemon; +extern bool fServer; +extern bool fCommandLine; +extern std::string strMiscWarning; +extern bool fNoListen; +extern bool fLogTimestamps; +extern bool fMasternodeSoftLock; +extern volatile bool fReopenDebugLog; + +void RandAddSeed(); +void RandAddSeedPerfmon(); + + + + +/* Return true if log accepts specified category */ +bool LogAcceptCategory(const char* category); +/* Send a string to the log output */ +int LogPrintStr(const std::string &str); + +#define LogPrintf(...) LogPrint(NULL, __VA_ARGS__) + +/* When we switch to C++11, this can be switched to variadic templates instead + * of this macro-based construction (see tinyformat.h). + */ +#define MAKE_ERROR_AND_LOG_FUNC(n) \ + /* Print to debug.log if -debug=category switch is given OR category is NULL. */ \ + template \ + static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \ + { \ + if(!LogAcceptCategory(category)) return 0; \ + return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \ + } \ + /* Log error and return false */ \ + template \ + static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \ + { \ + LogPrintStr("ERROR: " + tfm::format(format, TINYFORMAT_PASSARGS(n)) + "\n"); \ + return false; \ + } + +TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC) + +/* Zero-arg versions of logging and error, these are not covered by + * TINYFORMAT_FOREACH_ARGNUM + */ +static inline int LogPrint(const char* category, const char* format) +{ + if(!LogAcceptCategory(category)) return 0; + return LogPrintStr(format); +} +static inline bool error(const char* format) +{ + LogPrintStr(std::string("ERROR: ") + format + "\n"); + return false; +} + + +void PrintException(std::exception* pex, const char* pszThread); +void PrintExceptionContinue(std::exception* pex, const char* pszThread); +void ParseString(const std::string& str, char c, std::vector& v); +std::string FormatMoney(int64_t n, bool fPlus=false); +bool ParseMoney(const std::string& str, int64_t& nRet); +bool ParseMoney(const char* pszIn, int64_t& nRet); +std::string SanitizeString(const std::string& str); +std::vector ParseHex(const char* psz); +std::vector ParseHex(const std::string& str); +bool IsHex(const std::string& str); +std::vector DecodeBase64(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase64(const std::string& str); +std::string EncodeBase64(const unsigned char* pch, size_t len); +std::string EncodeBase64(const std::string& str); +SecureString DecodeBase64Secure(const SecureString& input); +SecureString EncodeBase64Secure(const SecureString& input); +std::vector DecodeBase32(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase32(const std::string& str); +std::string EncodeBase32(const unsigned char* pch, size_t len); +std::string EncodeBase32(const std::string& str); +//ONLY FOR C++11 std::string random_string(); +int intN(int n); +char *random_string(int len); +void ParseParameters(int argc, const char*const argv[]); +bool WildcardMatch(const char* psz, const char* mask); +bool WildcardMatch(const std::string& str, const std::string& mask); +void FileCommit(FILE *fileout); +bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest); +boost::filesystem::path GetDefaultDataDir(); +const boost::filesystem::path &GetDataDir(bool fNetSpecific = true); +boost::filesystem::path GetConfigFile(); +boost::filesystem::path GetPidFile(); +#ifndef WIN32 +void CreatePidFile(const boost::filesystem::path &path, pid_t pid); +#endif +void ReadConfigFile(std::map& mapSettingsRet, std::map >& mapMultiSettingsRet); +#ifdef WIN32 +boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); +#endif + +std::string getTimeString(int64_t timestamp, char *buffer, size_t nBuffer); +std::string bytesReadable(uint64_t nBytes); + +void ShrinkDebugFile(); +void GetRandBytes(unsigned char* buf, int num); +int GetRandInt(int nMax); +uint64_t GetRand(uint64_t nMax); +uint256 GetRandHash(); +int64_t GetTime(); +void SetMockTime(int64_t nMockTimeIn); +std::string FormatFullVersion(); +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); +void runCommand(std::string strCommand); + + + + +/** + * Convert string to signed 32-bit integer with strict parse error feedback. + * @returns true if the entire string could be parsed as valid integer, + * false if not the entire string could be parsed or when overflow or underflow occurred. + */ +bool ParseInt32(const std::string& str, int32_t *out); + + +/** + * Format a paragraph of text to a fixed width, adding spaces for + * indentation to any added line. + */ +std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0); + + + +inline std::string i64tostr(int64_t n) +{ + return strprintf("%d", n); +} + +inline std::string itostr(int n) +{ + return strprintf("%d", n); +} + +inline int64_t atoi64(const char* psz) +{ +#ifdef _MSC_VER + return _atoi64(psz); +#else + return strtoll(psz, NULL, 10); +#endif +} + +inline int64_t atoi64(const std::string& str) +{ +#ifdef _MSC_VER + return _atoi64(str.c_str()); +#else + return strtoll(str.c_str(), NULL, 10); +#endif +} + +inline int atoi(const std::string& str) +{ + return atoi(str.c_str()); +} + +inline int roundint(double d) +{ + return (int)(d > 0 ? d + 0.5 : d - 0.5); +} + +inline int64_t roundint64(double d) +{ + return (int64_t)(d > 0 ? d + 0.5 : d - 0.5); +} + +inline int64_t abs64(int64_t n) +{ + return (n >= 0 ? n : -n); +} + +inline std::string leftTrim(std::string src, char chr) +{ + std::string::size_type pos = src.find_first_not_of(chr, 0); + + if(pos > 0) + src.erase(0, pos); + + return src; +} + +template +std::string HexStr(const T itbegin, const T itend, bool fSpaces=false) +{ + std::string rv; + static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + rv.reserve((itend-itbegin)*3); + for(T it = itbegin; it < itend; ++it) + { + unsigned char val = (unsigned char)(*it); + if(fSpaces && it != itbegin) + rv.push_back(' '); + rv.push_back(hexmap[val>>4]); + rv.push_back(hexmap[val&15]); + } + + return rv; +} + +template +inline std::string HexStr(const T& vch, bool fSpaces=false) +{ + return HexStr(vch.begin(), vch.end(), fSpaces); +} + +inline int64_t GetPerformanceCounter() +{ + int64_t nCounter = 0; +#ifdef WIN32 + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); +#else + timeval t; + gettimeofday(&t, NULL); + nCounter = (int64_t) t.tv_sec * 1000000 + t.tv_usec; +#endif + return nCounter; +} + +inline int64_t GetTimeMillis() +{ + return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - + boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); +} + +inline int64_t GetTimeMicros() +{ + return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - + boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); +} + +std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime); +std::string EpochToDateTimeStrFormat(int64_t nTime); + +static const std::string strTimestampFormat = "%Y-%m-%d %H:%M:%S UTC"; +inline std::string DateTimeStrFormat(int64_t nTime) +{ + return DateTimeStrFormat(strTimestampFormat.c_str(), nTime); +} + + +template +void skipspaces(T& it) +{ + while (isspace(*it)) + ++it; +} + +inline bool IsSwitchChar(char c) +{ +#ifdef WIN32 + return c == '-' || c == '/'; +#else + return c == '-'; +#endif +} + +/** + * Return string argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. "1") + * @return command-line argument or default value + */ +std::string GetArg(const std::string& strArg, const std::string& strDefault); + +/** + * Return integer argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. 1) + * @return command-line argument (0 if invalid number) or default value + */ +int64_t GetArg(const std::string& strArg, int64_t nDefault); + +/** + * Return boolean argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (true or false) + * @return command-line argument or default value + */ +bool GetBoolArg(const std::string& strArg, bool fDefault); + +/** + * Set an argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param strValue Value (e.g. "1") + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetArg(const std::string& strArg, const std::string& strValue); + +/** + * Set a boolean argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param fValue Value (e.g. false) + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetBoolArg(const std::string& strArg, bool fValue); + +/** + * MWC RNG of George Marsaglia + * This is intended to be fast. It has a period of 2^59.3, though the + * least significant 16 bits only have a period of about 2^30.1. + * + * @return random value + */ +extern uint32_t insecure_rand_Rz; +extern uint32_t insecure_rand_Rw; +static inline uint32_t insecure_rand(void) +{ + insecure_rand_Rz=36969*(insecure_rand_Rz&65535)+(insecure_rand_Rz>>16); + insecure_rand_Rw=18000*(insecure_rand_Rw&65535)+(insecure_rand_Rw>>16); + return (insecure_rand_Rw<<16)+insecure_rand_Rz; +} + +/** + * Seed insecure_rand using the random pool. + * @param Deterministic Use a determinstic seed + */ +void seed_insecure_rand(bool fDeterministic=false); + +/** + * Timing-attack-resistant comparison. + * Takes time proportional to length + * of first argument. + */ +template +bool TimingResistantEqual(const T& a, const T& b) +{ + if (b.size() == 0) return a.size() == 0; + size_t accumulator = a.size() ^ b.size(); + for (size_t i = 0; i < a.size(); i++) + accumulator |= a[i] ^ b[i%b.size()]; + return accumulator == 0; +} + +/** Median filter over a stream of values. + * Returns the median of the last N numbers + */ +template class CMedianFilter +{ +private: + std::vector vValues; + std::vector vSorted; + unsigned int nSize; +public: + CMedianFilter(unsigned int size, T initial_value): + nSize(size) + { + vValues.reserve(size); + vValues.push_back(initial_value); + vSorted = vValues; + } + + void input(T value) + { + if(vValues.size() == nSize) + { + vValues.erase(vValues.begin()); + } + vValues.push_back(value); + + vSorted.resize(vValues.size()); + std::copy(vValues.begin(), vValues.end(), vSorted.begin()); + std::sort(vSorted.begin(), vSorted.end()); + } + + T median() const + { + int size = vSorted.size(); + assert(size>0); + if(size & 1) // Odd number of elements + { + return vSorted[size/2]; + } + else // Even number of elements + { + return (vSorted[size/2-1] + vSorted[size/2]) / 2; + } + } + + int size() const + { + return vValues.size(); + } + + std::vector sorted () const + { + return vSorted; + } +}; + +#ifdef WIN32 +inline void SetThreadPriority(int nPriority) +{ + SetThreadPriority(GetCurrentThread(), nPriority); +} +#else + +#define THREAD_PRIORITY_LOWEST PRIO_MAX +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 + +inline void SetThreadPriority(int nPriority) +{ + // It's unclear if it's even possible to change thread priorities on Linux, + // but we really and truly need it for the generation threads. +#ifdef PRIO_THREAD + setpriority(PRIO_THREAD, 0, nPriority); +#else + setpriority(PRIO_PROCESS, 0, nPriority); +#endif +} +#endif + +void RenameThread(const char* name); + +inline uint32_t ByteReverse(uint32_t value) +{ + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return (value<<16) | (value>>16); +} + +// Standard wrapper for do-something-forever thread functions. +// "Forever" really means until the thread is interrupted. +// Use it like: +// new boost::thread(boost::bind(&LoopForever, "dumpaddr", &DumpAddresses, 900000)); +// or maybe: +// boost::function f = boost::bind(&FunctionWithArg, argument); +// threadGroup.create_thread(boost::bind(&LoopForever >, "nothing", f, milliseconds)); +template void LoopForever(const char* name, Callable func, int64_t msecs) +{ + std::string s = strprintf("phantomx-%s", name); + RenameThread(s.c_str()); + LogPrintf("%s thread start\n", name); + try + { + while (1) + { + MilliSleep(msecs); + func(); + } + } + catch (boost::thread_interrupted) + { + LogPrintf("%s thread stop\n", name); + throw; + } + catch (std::exception& e) { + PrintException(&e, name); + } + catch (...) { + PrintException(NULL, name); + } +} +// .. and a wrapper that just calls func once +template void TraceThread(const char* name, Callable func) +{ + std::string s = strprintf("phantomx-%s", name); + RenameThread(s.c_str()); + try + { + LogPrintf("%s thread start\n", name); + func(); + LogPrintf("%s thread exit\n", name); + } + catch (boost::thread_interrupted) + { + LogPrintf("%s thread interrupt\n", name); + throw; + } + catch (std::exception& e) { + PrintException(&e, name); + } + catch (...) { + PrintException(NULL, name); + } +} + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/utilstrencodings.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/utilstrencodings.cpp new file mode 100644 index 0000000..64c7d92 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/utilstrencodings.cpp @@ -0,0 +1,489 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "utilstrencodings.h" + +#include "tinyformat.h" + +#include +#include +#include +#include + +using namespace std; + + + + + + + +string EncodeBase64(const unsigned char* pch, size_t len) +{ + static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + string strRet=""; + strRet.reserve((len+2)/3*4); + + int mode=0, left=0; + const unsigned char *pchEnd = pch+len; + + while (pch> 2]; + left = (enc & 3) << 4; + mode = 1; + break; + + case 1: // we have two bits + strRet += pbase64[left | (enc >> 4)]; + left = (enc & 15) << 2; + mode = 2; + break; + + case 2: // we have four bits + strRet += pbase64[left | (enc >> 6)]; + strRet += pbase64[enc & 63]; + mode = 0; + break; + } + } + + if (mode) + { + strRet += pbase64[left]; + strRet += '='; + if (mode == 1) + strRet += '='; + } + + return strRet; +} + +string EncodeBase64(const string& str) +{ + return EncodeBase64((const unsigned char*)str.c_str(), str.size()); +} + +vector DecodeBase64(const char* p, bool* pfInvalid) +{ + static const int decode64_table[256] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, + -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + if (pfInvalid) + *pfInvalid = false; + + vector vchRet; + vchRet.reserve(strlen(p)*3/4); + + int mode = 0; + int left = 0; + + while (1) + { + int dec = decode64_table[(unsigned char)*p]; + if (dec == -1) break; + p++; + switch (mode) + { + case 0: // we have no bits and get 6 + left = dec; + mode = 1; + break; + + case 1: // we have 6 bits and keep 4 + vchRet.push_back((left<<2) | (dec>>4)); + left = dec & 15; + mode = 2; + break; + + case 2: // we have 4 bits and get 6, we keep 2 + vchRet.push_back((left<<4) | (dec>>2)); + left = dec & 3; + mode = 3; + break; + + case 3: // we have 2 bits and get 6 + vchRet.push_back((left<<6) | dec); + mode = 0; + break; + } + } + + if (pfInvalid) + switch (mode) + { + case 0: // 4n base64 characters processed: ok + break; + + case 1: // 4n+1 base64 character processed: impossible + *pfInvalid = true; + break; + + case 2: // 4n+2 base64 characters processed: require '==' + if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1) + *pfInvalid = true; + break; + + case 3: // 4n+3 base64 characters processed: require '=' + if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1) + *pfInvalid = true; + break; + } + + return vchRet; +} + +string DecodeBase64(const string& str) +{ + vector vchRet = DecodeBase64(str.c_str()); + return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size()); +} + +// Base64 encoding with secure memory allocation +SecureString EncodeBase64Secure(const SecureString& input) +{ + // Init openssl BIO with base64 filter and memory output + BIO *b64, *mem; + b64 = BIO_new(BIO_f_base64()); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); // No newlines in output + mem = BIO_new(BIO_s_mem()); + BIO_push(b64, mem); + + // Decode the string + BIO_write(b64, &input[0], input.size()); + (void) BIO_flush(b64); + + // Create output variable from buffer mem ptr + BUF_MEM *bptr; + BIO_get_mem_ptr(b64, &bptr); + SecureString output(bptr->data, bptr->length); + + // Cleanse secure data buffer from memory + OPENSSL_cleanse((void *) bptr->data, bptr->length); + + // Free memory + BIO_free_all(b64); + return output; +} + +// Base64 decoding with secure memory allocation +SecureString DecodeBase64Secure(const SecureString& input) +{ + SecureString output; + + // Init openssl BIO with base64 filter and memory input + BIO *b64, *mem; + b64 = BIO_new(BIO_f_base64()); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer + mem = BIO_new_mem_buf((void *) &input[0], input.size()); + BIO_push(b64, mem); + + // Prepare buffer to receive decoded data + if(input.size() % 4 != 0) { + throw runtime_error("Input length should be a multiple of 4"); + } + size_t nMaxLen = input.size() / 4 * 3; // upper bound, guaranteed divisible by 4 + output.resize(nMaxLen); + + // Decode the string + size_t nLen; + nLen = BIO_read(b64, (void *) &output[0], input.size()); + output.resize(nLen); + + // Free memory + BIO_free_all(b64); + return output; +} + + + + +string EncodeBase32(const unsigned char* pch, size_t len) +{ + static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567"; + + string strRet=""; + strRet.reserve((len+4)/5*8); + + int mode=0, left=0; + const unsigned char *pchEnd = pch+len; + + while (pch> 3]; + left = (enc & 7) << 2; + mode = 1; + break; + + case 1: // we have three bits + strRet += pbase32[left | (enc >> 6)]; + strRet += pbase32[(enc >> 1) & 31]; + left = (enc & 1) << 4; + mode = 2; + break; + + case 2: // we have one bit + strRet += pbase32[left | (enc >> 4)]; + left = (enc & 15) << 1; + mode = 3; + break; + + case 3: // we have four bits + strRet += pbase32[left | (enc >> 7)]; + strRet += pbase32[(enc >> 2) & 31]; + left = (enc & 3) << 3; + mode = 4; + break; + + case 4: // we have two bits + strRet += pbase32[left | (enc >> 5)]; + strRet += pbase32[enc & 31]; + mode = 0; + } + } + + static const int nPadding[5] = {0, 6, 4, 3, 1}; + if (mode) + { + strRet += pbase32[left]; + for (int n=0; n DecodeBase32(const char* p, bool* pfInvalid) +{ + static const int decode32_table[256] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + if (pfInvalid) + *pfInvalid = false; + + vector vchRet; + vchRet.reserve((strlen(p))*5/8); + + int mode = 0; + int left = 0; + + while (1) + { + int dec = decode32_table[(unsigned char)*p]; + if (dec == -1) break; + p++; + switch (mode) + { + case 0: // we have no bits and get 5 + left = dec; + mode = 1; + break; + + case 1: // we have 5 bits and keep 2 + vchRet.push_back((left<<3) | (dec>>2)); + left = dec & 3; + mode = 2; + break; + + case 2: // we have 2 bits and keep 7 + left = left << 5 | dec; + mode = 3; + break; + + case 3: // we have 7 bits and keep 4 + vchRet.push_back((left<<1) | (dec>>4)); + left = dec & 15; + mode = 4; + break; + + case 4: // we have 4 bits, and keep 1 + vchRet.push_back((left<<4) | (dec>>1)); + left = dec & 1; + mode = 5; + break; + + case 5: // we have 1 bit, and keep 6 + left = left << 5 | dec; + mode = 6; + break; + + case 6: // we have 6 bits, and keep 3 + vchRet.push_back((left<<2) | (dec>>3)); + left = dec & 7; + mode = 7; + break; + + case 7: // we have 3 bits, and keep 0 + vchRet.push_back((left<<5) | dec); + mode = 0; + break; + } + } + + if (pfInvalid) + switch (mode) + { + case 0: // 8n base32 characters processed: ok + break; + + case 1: // 8n+1 base32 characters processed: impossible + case 3: // +3 + case 6: // +6 + *pfInvalid = true; + break; + + case 2: // 8n+2 base32 characters processed: require '======' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1) + *pfInvalid = true; + break; + + case 4: // 8n+4 base32 characters processed: require '====' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1) + *pfInvalid = true; + break; + + case 5: // 8n+5 base32 characters processed: require '===' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1) + *pfInvalid = true; + break; + + case 7: // 8n+7 base32 characters processed: require '=' + if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1) + *pfInvalid = true; + break; + } + + return vchRet; +} + +string DecodeBase32(const string& str) +{ + vector vchRet = DecodeBase32(str.c_str()); + return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size()); +} + +bool ParseInt32(const std::string& str, int32_t *out) +{ + char *endp = NULL; + errno = 0; // strtol will not set errno if valid + long int n = strtol(str.c_str(), &endp, 10); + if(out) *out = (int)n; + // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow + // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit + // platforms the size of these types may be different. + return endp && *endp == 0 && !errno && + n >= std::numeric_limits::min() && + n <= std::numeric_limits::max(); +} + +std::string FormatParagraph(const std::string in, size_t width, size_t indent) +{ + std::stringstream out; + size_t col = 0; + size_t ptr = 0; + while(ptr < in.size()) + { + // Find beginning of next word + ptr = in.find_first_not_of(' ', ptr); + if (ptr == std::string::npos) + break; + // Find end of next word + size_t endword = in.find_first_of(' ', ptr); + if (endword == std::string::npos) + endword = in.size(); + // Add newline and indentation if this wraps over the allowed width + if (col > 0) + { + if ((col + endword - ptr) > width) + { + out << '\n'; + for(size_t i=0; i +#include +#include +#include "serialize.h" +#include "allocators.h" + + +#include +#include +#include +#include +#include // for OPENSSL_cleanse() +#include +#include + + +#define BEGIN(a) ((char*)&(a)) +#define END(a) ((char*)&((&(a))[1])) +#define UBEGIN(a) ((unsigned char*)&(a)) +#define UEND(a) ((unsigned char*)&((&(a))[1])) +#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) + +/** This is needed because the foreach macro can't get over the comma in pair */ +#define PAIRTYPE(t1, t2) std::pair + + + +std::vector DecodeBase64(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase64(const std::string& str); +std::string EncodeBase64(const unsigned char* pch, size_t len); +std::string EncodeBase64(const std::string& str); +SecureString DecodeBase64Secure(const SecureString& input); +SecureString EncodeBase64Secure(const SecureString& input); +std::vector DecodeBase32(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase32(const std::string& str); +std::string EncodeBase32(const unsigned char* pch, size_t len); +std::string EncodeBase32(const std::string& str); + + +std::string i64tostr(int64_t n); +std::string itostr(int n); +int64_t atoi64(const char* psz); +int64_t atoi64(const std::string& str); +int atoi(const std::string& str); + +/** + * Convert string to signed 32-bit integer with strict parse error feedback. + * @returns true if the entire string could be parsed as valid integer, + * false if not the entire string could be parsed or when overflow or underflow occurred. + */ +bool ParseInt32(const std::string& str, int32_t *out); + +template +std::string HexStr(const T itbegin, const T itend, bool fSpaces=false) +{ + std::string rv; + static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + rv.reserve((itend-itbegin)*3); + for(T it = itbegin; it < itend; ++it) + { + unsigned char val = (unsigned char)(*it); + if(fSpaces && it != itbegin) + rv.push_back(' '); + rv.push_back(hexmap[val>>4]); + rv.push_back(hexmap[val&15]); + } + + return rv; +} + +template +inline std::string HexStr(const T& vch, bool fSpaces=false) +{ + return HexStr(vch.begin(), vch.end(), fSpaces); +} + +/** + * Format a paragraph of text to a fixed width, adding spaces for + * indentation to any added line. + */ +std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0); + +/** + * Timing-attack-resistant comparison. + * Takes time proportional to length + * of first argument. + */ +template +bool TimingResistantEqual(const T& a, const T& b) +{ + if (b.size() == 0) return a.size() == 0; + size_t accumulator = a.size() ^ b.size(); + for (size_t i = 0; i < a.size(); i++) + accumulator |= a[i] ^ b[i%b.size()]; + return accumulator == 0; +} + +#endif // BITCOIN_UTILSTRENCODINGS_H diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/version.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/version.cpp new file mode 100644 index 0000000..4b9e097 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/version.cpp @@ -0,0 +1,66 @@ +// Copyright (c) 2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include + +#include "version.h" + +// Name of client reported in the 'version' message. Report the same name +// for both bitcoind and bitcoin-qt, to make it harder for attackers to +// target servers or GUI users specifically. +const std::string CLIENT_NAME("PhantomX"); + +// Client version number +#define CLIENT_VERSION_SUFFIX "" + + +// The following part of the code determines the CLIENT_BUILD variable. +// Several mechanisms are used for this: +// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is +// generated by the build environment, possibly containing the output +// of git-describe in a macro called BUILD_DESC +// * secondly, if this is an exported version of the code, GIT_ARCHIVE will +// be defined (automatically using the export-subst git attribute), and +// GIT_COMMIT will contain the commit id. +// * then, three options exist for determining CLIENT_BUILD: +// * if BUILD_DESC is defined, use that literally (output of git-describe) +// * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit] +// * otherwise, use v[maj].[min].[rev].[build]-unk +// finally CLIENT_VERSION_SUFFIX is added + +// First, include build.h if requested +#ifdef HAVE_BUILD_INFO +# include "build.h" +#endif + +// git will put "#define GIT_ARCHIVE 1" on the next line inside archives. +#define GIT_ARCHIVE 1 +#ifdef GIT_ARCHIVE +# define GIT_COMMIT_ID ": POS-X10" +//# define GIT_COMMIT_DATE "$Format:%cD" +#endif + +#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \ + "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "" commit + +#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \ + "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "" + +#ifndef BUILD_DESC +# ifdef GIT_COMMIT_ID +# define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID) +# else +# define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD) +# endif +#endif + +#ifndef BUILD_DATE +# ifdef GIT_COMMIT_DATE +# define BUILD_DATE GIT_COMMIT_DATE +# else +# define BUILD_DATE __DATE__ ", " __TIME__ +# endif +#endif + +const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX); +const std::string CLIENT_DATE(BUILD_DATE); diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/version.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/version.h new file mode 100644 index 0000000..3dc7862 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/version.h @@ -0,0 +1,59 @@ +// Copyright (c) 2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_VERSION_H +#define BITCOIN_VERSION_H + +#include "clientversion.h" +#include + +// +// client versioning +// + +static const int CLIENT_VERSION = + 1000000 * CLIENT_VERSION_MAJOR + + 10000 * CLIENT_VERSION_MINOR + + 100 * CLIENT_VERSION_REVISION + + 1 * CLIENT_VERSION_BUILD; + +extern const std::string CLIENT_NAME; +extern const std::string CLIENT_BUILD; +extern const std::string CLIENT_DATE; + +// +// database format versioning +// +static const int DATABASE_VERSION = 71500; + +// +// network protocol versioning +// + +static const int PROTOCOL_VERSION = 69110; + +// intial proto version, to be increased after version/verack negotiation +static const int INIT_PROTO_VERSION = 209; + +// disconnect from peers older than this proto version +static const int MIN_PEER_PROTO_VERSION = 69100; + +static const int MIN_INSTANTX_PROTO_VERSION = 69100; + +static const int MIN_MN_PROTO_VERSION = 69100; + +// nTime field added to CAddress, starting with this version; +// if possible, avoid requesting addresses nodes older than this +static const int CADDR_TIME_VERSION = 31402; + +// only request blocks from nodes outside this range of versions +static const int NOBLKS_VERSION_START = 60002; +static const int NOBLKS_VERSION_END = 60006; + +// BIP 0031, pong message, is enabled for all versions AFTER this one +static const int BIP0031_VERSION = 60000; + +// "mempool" command, enhanced "getdata" behavior starts with this version: +static const int MEMPOOL_GD_VERSION = 60005; + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/wallet.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/wallet.cpp new file mode 100644 index 0000000..bb4a550 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/wallet.cpp @@ -0,0 +1,4509 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "wallet.h" + +#include "base58.h" +#include "coincontrol.h" +#include "kernel.h" +#include "net.h" +#include "util.h" +#include "timedata.h" +#include "txdb.h" +#include "ui_interface.h" +#include "walletdb.h" +#include "crypter.h" +#include "key.h" +#include "spork.h" +#include "darksend.h" +#include "instantx.h" +#include "masternode.h" +#include "chainparams.h" +#include "smessage.h" + +#include +#include +#include + +// include + +using namespace std; + +// Settings +int64_t nTransactionFee = MIN_TX_FEE; +int64_t nReserveBalance = 0; +int64_t nMinimumInputValue = 0; + +static unsigned int GetStakeSplitAge() { return 9 * 24 * 60 * 60; } +static int64_t GetStakeCombineThreshold() { return 100 * COIN; } + +int64_t gcd(int64_t n,int64_t m) { return m == 0 ? n : gcd(m, n % m); } +static uint64_t CoinWeightCost(const COutput &out) +{ + int64_t nTimeWeight = (int64_t)GetTime() - (int64_t)out.tx->nTime; + CBigNum bnCoinDayWeight = CBigNum(out.tx->vout[out.i].nValue) * nTimeWeight / (24 * 60 * 60); + return bnCoinDayWeight.getuint64(); +} + +////////////////////////////////////////////////////////////////////////////// +// +// mapWallet +// + +struct CompareValueOnly +{ + bool operator()(const pair >& t1, + const pair >& t2) const + { + return t1.first < t2.first; + } +}; + + + + + + +CPubKey CWallet::GenerateNewKey() +{ + AssertLockHeld(cs_wallet); // mapKeyMetadata + bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets + + RandAddSeedPerfmon(); + CKey secret; + secret.MakeNewKey(fCompressed); + + // Compressed public keys were introduced in version 0.6.0 + if (fCompressed) + SetMinVersion(FEATURE_COMPRPUBKEY); + + CPubKey pubkey = secret.GetPubKey(); + + // Create new metadata + int64_t nCreationTime = GetTime(); + mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime); + if (!nTimeFirstKey || nCreationTime < nTimeFirstKey) + nTimeFirstKey = nCreationTime; + + if (!AddKeyPubKey(secret, pubkey)) + throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed"); + return pubkey; +} + +bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) +{ + AssertLockHeld(cs_wallet); // mapKeyMetadata + if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) + return false; + if (!fFileBacked) + return true; + if (!IsCrypted()) { + return CWalletDB(strWalletFile).WriteKey(pubkey, secret.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]); + } + return true; +} + +bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector &vchCryptedSecret) +{ + if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) + return false; + if (!fFileBacked) + return true; + { + LOCK(cs_wallet); + if (pwalletdbEncryption) + return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); + else + return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); + } + return false; +} + +bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta) +{ + AssertLockHeld(cs_wallet); // mapKeyMetadata + if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey)) + nTimeFirstKey = meta.nCreateTime; + + mapKeyMetadata[pubkey.GetID()] = meta; + return true; +} + +bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) +{ + return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); +} + +bool CWallet::AddCScript(const CScript& redeemScript) +{ + if (!CCryptoKeyStore::AddCScript(redeemScript)) + return false; + if (!fFileBacked) + return true; + return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript); +} + +// optional setting to unlock wallet for staking only +// serves to disable the trivial sendmoney when OS account compromised +// provides no real security +bool fWalletUnlockStakingOnly = false; + +bool CWallet::LoadCScript(const CScript& redeemScript) +{ + /* A sanity check was added in pull #3843 to avoid adding redeemScripts + * that never can be redeemed. However, old wallets may still contain + * these. Do not add them to the wallet and warn. */ + if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE) + { + std::string strAddr = CBitcoinAddress(redeemScript.GetID()).ToString(); + LogPrintf("%s: Warning: This wallet contains a redeemScript of size %u which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n", + __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr); + return true; + } + + return CCryptoKeyStore::AddCScript(redeemScript); +} + +bool CWallet::Lock() +{ + if (IsLocked()) + return true; + + if (fDebug) + printf("Locking wallet.\n"); + + { + LOCK(cs_wallet); + CWalletDB wdb(strWalletFile); + + // -- load encrypted spend_secret of stealth addresses + CStealthAddress sxAddrTemp; + std::set::iterator it; + for (it = stealthAddresses.begin(); it != stealthAddresses.end(); ++it) + { + if (it->scan_secret.size() < 32) + continue; // stealth address is not owned + // -- CStealthAddress are only sorted on spend_pubkey + CStealthAddress &sxAddr = const_cast(*it); + if (fDebug) + printf("Recrypting stealth key %s\n", sxAddr.Encoded().c_str()); + + sxAddrTemp.scan_pubkey = sxAddr.scan_pubkey; + if (!wdb.ReadStealthAddress(sxAddrTemp)) + { + printf("Error: Failed to read stealth key from db %s\n", sxAddr.Encoded().c_str()); + continue; + } + sxAddr.spend_secret = sxAddrTemp.spend_secret; + }; + } + return LockKeyStore(); +}; + +bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool anonymizeOnly) +{ + SecureString strWalletPassphraseFinal; + + if(!IsLocked()) + { + fWalletUnlockAnonymizeOnly = anonymizeOnly; + return true; + } + + strWalletPassphraseFinal = strWalletPassphrase; + + CCrypter crypter; + CKeyingMaterial vMasterKey; + + { + LOCK(cs_wallet); + BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strWalletPassphraseFinal, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (!CCryptoKeyStore::Unlock(vMasterKey)) + return false; + break; + } + + fWalletUnlockAnonymizeOnly = anonymizeOnly; + UnlockStealthAddresses(vMasterKey); + return true; + } + return false; +} + +bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase) +{ + bool fWasLocked = IsLocked(); + + SecureString strOldWalletPassphraseFinal; + strOldWalletPassphraseFinal = strOldWalletPassphrase; + + { + LOCK(cs_wallet); + Lock(); + + CCrypter crypter; + CKeyingMaterial vMasterKey; + BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strOldWalletPassphraseFinal, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (CCryptoKeyStore::Unlock(vMasterKey) + && UnlockStealthAddresses(vMasterKey)) + { + int64_t nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (pMasterKey.second.nDeriveIterations < 25000) + pMasterKey.second.nDeriveIterations = 25000; + + LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey)) + return false; + CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second); + if (fWasLocked) + Lock(); + + return true; + } + } + } + + return false; +} + +void CWallet::SetBestChain(const CBlockLocator& loc) +{ + CWalletDB walletdb(strWalletFile); + walletdb.WriteBestBlock(loc); +} + +bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit) +{ + LOCK(cs_wallet); // nWalletVersion + if (nWalletVersion >= nVersion) + return true; + + // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way + if (fExplicit && nVersion > nWalletMaxVersion) + nVersion = FEATURE_LATEST; + + nWalletVersion = nVersion; + + if (nVersion > nWalletMaxVersion) + nWalletMaxVersion = nVersion; + + if (fFileBacked) + { + CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile); + if (nWalletVersion > 40000) + pwalletdb->WriteMinVersion(nWalletVersion); + if (!pwalletdbIn) + delete pwalletdb; + } + + return true; +} + +bool CWallet::SetMaxVersion(int nVersion) +{ + LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion + // cannot downgrade below current version + if (nWalletVersion > nVersion) + return false; + + nWalletMaxVersion = nVersion; + + return true; +} + +bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) +{ + if (IsCrypted()) + return false; + + CKeyingMaterial vMasterKey; + RandAddSeedPerfmon(); + + vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); + RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); + + CMasterKey kMasterKey(nDerivationMethodIndex); + + RandAddSeedPerfmon(); + kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); + RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); + + CCrypter crypter; + int64_t nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime)); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (kMasterKey.nDeriveIterations < 25000) + kMasterKey.nDeriveIterations = 25000; + + LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) + return false; + + { + LOCK(cs_wallet); + mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; + if (fFileBacked) + { + pwalletdbEncryption = new CWalletDB(strWalletFile); + if (!pwalletdbEncryption->TxnBegin()) + return false; + pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); + } + + if (!EncryptKeys(vMasterKey)) + { + if (fFileBacked) + pwalletdbEncryption->TxnAbort(); + exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet. + } + + std::set::iterator it; + for (it = stealthAddresses.begin(); it != stealthAddresses.end(); ++it) + { + if (it->scan_secret.size() < 32) + continue; // stealth address is not owned + // -- CStealthAddress is only sorted on spend_pubkey + CStealthAddress &sxAddr = const_cast(*it); + + if (fDebug) + printf("Encrypting stealth key %s\n", sxAddr.Encoded().c_str()); + + std::vector vchCryptedSecret; + + CSecret vchSecret; + vchSecret.resize(32); + memcpy(&vchSecret[0], &sxAddr.spend_secret[0], 32); + + uint256 iv = Hash(sxAddr.spend_pubkey.begin(), sxAddr.spend_pubkey.end()); + if (!EncryptSecret(vMasterKey, vchSecret, iv, vchCryptedSecret)) + { + printf("Error: Failed encrypting stealth key %s\n", sxAddr.Encoded().c_str()); + continue; + }; + + sxAddr.spend_secret = vchCryptedSecret; + pwalletdbEncryption->WriteStealthAddress(sxAddr); + }; + + // Encryption was introduced in version 0.4.0 + SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true); + + if (fFileBacked) + { + if (!pwalletdbEncryption->TxnCommit()) + exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet. + + delete pwalletdbEncryption; + pwalletdbEncryption = NULL; + } + + Lock(); + Unlock(strWalletPassphrase); + NewKeyPool(); + Lock(); + + // Need to completely rewrite the wallet file; if we don't, bdb might keep + // bits of the unencrypted private key in slack space in the database file. + CDB::Rewrite(strWalletFile); + + } + NotifyStatusChanged(this); + + return true; +} + +int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) +{ + AssertLockHeld(cs_wallet); // nOrderPosNext + int64_t nRet = nOrderPosNext++; + if (pwalletdb) { + pwalletdb->WriteOrderPosNext(nOrderPosNext); + } else { + CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext); + } + return nRet; +} + +CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, std::string strAccount) +{ + AssertLockHeld(cs_wallet); // mapWallet + CWalletDB walletdb(strWalletFile); + + // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap. + TxItems txOrdered; + + // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry + // would make this much faster for applications that do this a lot. + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx* wtx = &((*it).second); + txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); + } + acentries.clear(); + walletdb.ListAccountCreditDebit(strAccount, acentries); + BOOST_FOREACH(CAccountingEntry& entry, acentries) + { + txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry))); + } + + return txOrdered; +} + +void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock) +{ + // Anytime a signature is successfully verified, it's proof the outpoint is spent. + // Update the wallet spent flag if it doesn't know due to wallet.dat being + // restored from backup or the user making copies of wallet.dat. + { + LOCK(cs_wallet); + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + map::iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + CWalletTx& wtx = (*mi).second; + if (txin.prevout.n >= wtx.vout.size()) + LogPrintf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString()); + else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n])) + { + LogPrintf("WalletUpdateSpent found spent coin %s BC %s\n", FormatMoney(wtx.GetCredit()), wtx.GetHash().ToString()); + wtx.MarkSpent(txin.prevout.n); + wtx.WriteToDisk(); + NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED); + } + } + } + + if (fBlock) + { + uint256 hash = tx.GetHash(); + map::iterator mi = mapWallet.find(hash); + CWalletTx& wtx = (*mi).second; + + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + if (IsMine(txout)) + { + wtx.MarkUnspent(&txout - &tx.vout[0]); + wtx.WriteToDisk(); + NotifyTransactionChanged(this, hash, CT_UPDATED); + } + } + } + + } +} + +void CWallet::MarkDirty() +{ + { + LOCK(cs_wallet); + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + item.second.MarkDirty(); + } +} + +bool CWallet::AddToWallet(const CWalletTx& wtxIn) +{ + uint256 hash = wtxIn.GetHash(); + { + LOCK(cs_wallet); + // Inserts only if not already there, returns tx inserted or tx found + pair::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); + CWalletTx& wtx = (*ret.first).second; + wtx.BindWallet(this); + bool fInsertedNew = ret.second; + if (fInsertedNew) + { + wtx.nTimeReceived = GetAdjustedTime(); + wtx.nOrderPos = IncOrderPosNext(); + + wtx.nTimeSmart = wtx.nTimeReceived; + if (wtxIn.hashBlock != 0) + { + if (mapBlockIndex.count(wtxIn.hashBlock)) + { + unsigned int latestNow = wtx.nTimeReceived; + unsigned int latestEntry = 0; + { + // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future + int64_t latestTolerated = latestNow + 300; + std::list acentries; + TxItems txOrdered = OrderedTxItems(acentries); + for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx == &wtx) + continue; + CAccountingEntry *const pacentry = (*it).second.second; + int64_t nSmartTime; + if (pwtx) + { + nSmartTime = pwtx->nTimeSmart; + if (!nSmartTime) + nSmartTime = pwtx->nTimeReceived; + } + else + nSmartTime = pacentry->nTime; + if (nSmartTime <= latestTolerated) + { + latestEntry = nSmartTime; + if (nSmartTime > latestNow) + latestNow = nSmartTime; + break; + } + } + } + + unsigned int& blocktime = mapBlockIndex[wtxIn.hashBlock]->nTime; + wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow)); + } + else + LogPrintf("AddToWallet() : found %s in block %s not in index\n", + wtxIn.GetHash().ToString(), + wtxIn.hashBlock.ToString()); + } + } + + bool fUpdated = false; + if (!fInsertedNew) + { + // Merge + if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) + { + wtx.hashBlock = wtxIn.hashBlock; + fUpdated = true; + } + if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex)) + { + wtx.vMerkleBranch = wtxIn.vMerkleBranch; + wtx.nIndex = wtxIn.nIndex; + fUpdated = true; + } + if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe) + { + wtx.fFromMe = wtxIn.fFromMe; + fUpdated = true; + } + fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent); + } + + //// debug print + LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); + + // Write to disk + if (fInsertedNew || fUpdated) + if (!wtx.WriteToDisk()) + return false; + + if (!fHaveGUI) { + // If default receiving address gets used, replace it with a new one + if (vchDefaultKey.IsValid()) { + CScript scriptDefaultKey; + scriptDefaultKey.SetDestination(vchDefaultKey.GetID()); + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if (txout.scriptPubKey == scriptDefaultKey) + { + CPubKey newDefaultKey; + if (GetKeyFromPool(newDefaultKey)) + { + SetDefaultKey(newDefaultKey); + SetAddressBookName(vchDefaultKey.GetID(), ""); + } + } + } + } + } + // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins + WalletUpdateSpent(wtx, (wtxIn.hashBlock != 0)); + + // Notify UI of new or updated transaction + NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED); + + // notify an external script when a wallet transaction comes in or is updated + std::string strCmd = GetArg("-walletnotify", ""); + + if ( !strCmd.empty()) + { + boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex()); + boost::thread t(runCommand, strCmd); // thread runs free + } + + } + return true; +} + +// Add a transaction to the wallet, or update it. +// pblock is optional, but should be provided if the transaction is known to be in a block. +// If fUpdate is true, existing transactions will be updated. +bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate) +{ + uint256 hash = tx.GetHash(); + { + LOCK(cs_wallet); + bool fExisted = mapWallet.count(hash); + if (fExisted && !fUpdate) return false; + + mapValue_t mapNarr; + FindStealthTransactions(tx, mapNarr); + + if (fExisted || IsMine(tx) || IsFromMe(tx)) + { + CWalletTx wtx(this,tx); + + if (!mapNarr.empty()) + wtx.mapValue.insert(mapNarr.begin(), mapNarr.end()); + + // Get merkle branch if transaction was found in a block + if (pblock) + wtx.SetMerkleBranch(pblock); + return AddToWallet(wtx); + } + else + WalletUpdateSpent(tx); + } + return false; +} + +void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock, bool fConnect) { + if (!fConnect) + { + // wallets need to refund inputs when disconnecting coinstake + if (tx.IsCoinStake()) + { + if (IsFromMe(tx)) + DisableTransaction(tx); + } + return; + } + + AddToWalletIfInvolvingMe(tx, pblock, true); +} + +void CWallet::EraseFromWallet(const uint256 &hash) +{ + if (!fFileBacked) + return; + { + LOCK(cs_wallet); + if (mapWallet.erase(hash)) + CWalletDB(strWalletFile).EraseTx(hash); + } + return; +} + + +bool CWallet::IsMine(const CTxIn &txin) const +{ + { + LOCK(cs_wallet); + map::const_iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (txin.prevout.n < prev.vout.size()) + if (IsMine(prev.vout[txin.prevout.n])) + return true; + } + } + return false; +} + +int64_t CWallet::GetDebit(const CTxIn &txin) const +{ + { + LOCK(cs_wallet); + map::const_iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (txin.prevout.n < prev.vout.size()) + if (IsMine(prev.vout[txin.prevout.n])) + return prev.vout[txin.prevout.n].nValue; + } + } + return 0; +} + + +bool CWallet::IsDenominated(const CTxIn &txin) const +{ + { + LOCK(cs_wallet); + map::const_iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (txin.prevout.n < prev.vout.size()) return IsDenominatedAmount(prev.vout[txin.prevout.n].nValue); + } + } + return false; +} + +bool CWallet::IsDenominatedAmount(int64_t nInputAmount) const +{ + BOOST_FOREACH(int64_t d, darkSendDenominations) + if(nInputAmount == d) + return true; + return false; +} + + +bool CWallet::IsChange(const CTxOut& txout) const +{ + CTxDestination address; + + // TODO: fix handling of 'change' outputs. The assumption is that any + // payment to a TX_PUBKEYHASH that is mine but isn't in the address book + // is change. That assumption is likely to break when we implement multisignature + // wallets that return change back into a multi-signature-protected address; + // a better way of identifying which outputs are 'the send' and which are + // 'the change' will need to be implemented (maybe extend CWalletTx to remember + // which output, if any, was change). + if (ExtractDestination(txout.scriptPubKey, address) && ::IsMine(*this, address)) + { + LOCK(cs_wallet); + if (!mapAddressBook.count(address)) + return true; + } + return false; +} + +int64_t CWalletTx::GetTxTime() const +{ + int64_t n = nTimeSmart; + return n ? n : nTimeReceived; +} + +int CWalletTx::GetRequestCount() const +{ + // Returns -1 if it wasn't being tracked + int nRequests = -1; + { + LOCK(pwallet->cs_wallet); + if (IsCoinBase() || IsCoinStake()) + { + // Generated block + if (hashBlock != 0) + { + map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); + if (mi != pwallet->mapRequestCount.end()) + nRequests = (*mi).second; + } + } + else + { + // Did anyone request this transaction? + map::const_iterator mi = pwallet->mapRequestCount.find(GetHash()); + if (mi != pwallet->mapRequestCount.end()) + { + nRequests = (*mi).second; + + // How about the block it's in? + if (nRequests == 0 && hashBlock != 0) + { + map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); + if (mi != pwallet->mapRequestCount.end()) + nRequests = (*mi).second; + else + nRequests = 1; // If it's in someone else's block it must have got out + } + } + } + } + return nRequests; +} + +void CWalletTx::GetAmounts(list >& listReceived, + list >& listSent, int64_t& nFee, string& strSentAccount) const +{ + LOCK(pwallet->cs_wallet); + nFee = 0; + listReceived.clear(); + listSent.clear(); + strSentAccount = strFromAccount; + + // Compute fee: + int64_t nDebit = GetDebit(); + if (nDebit > 0) // debit>0 means we signed/sent this transaction + { + int64_t nValueOut = GetValueOut(); + nFee = nDebit - nValueOut; + } + + // Sent/received. + BOOST_FOREACH(const CTxOut& txout, vout) + { + // Skip special stake out + if (txout.scriptPubKey.empty()) + continue; + + bool fIsMine; + // Only need to handle txouts if AT LEAST one of these is true: + // 1) they debit from us (sent) + // 2) the output is to us (received) + if (nDebit > 0) + { + // Don't report 'change' txouts + // phantomxNOTE: CoinControl possible fix related... with HD wallet we need to report change? + //if (pwallet->IsChange(txout)) + // continue; + fIsMine = pwallet->IsMine(txout); + } + else if (!(fIsMine = pwallet->IsMine(txout))) + continue; + + // In either case, we need to get the destination address + CTxDestination address; + if (!ExtractDestination(txout.scriptPubKey, address)) + { + LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", + this->GetHash().ToString()); + address = CNoDestination(); + } + + // If we are debited by the transaction, add the output as a "sent" entry + if (nDebit > 0) + listSent.push_back(make_pair(address, txout.nValue)); + + // If we are receiving the output, add it as a "received" entry + if (fIsMine) + listReceived.push_back(make_pair(address, txout.nValue)); + } + +} + +void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived, + int64_t& nSent, int64_t& nFee) const +{ + LOCK(pwallet->cs_wallet); + nReceived = nSent = nFee = 0; + + int64_t allFee; + string strSentAccount; + list > listReceived; + list > listSent; + GetAmounts(listReceived, listSent, allFee, strSentAccount); + + if (strAccount == strSentAccount) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& s, listSent) + nSent += s.second; + nFee = allFee; + } + { + + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived) + { + if (pwallet->mapAddressBook.count(r.first)) + { + map::const_iterator mi = pwallet->mapAddressBook.find(r.first); + if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount) + nReceived += r.second; + } + else if (strAccount.empty()) + { + nReceived += r.second; + } + } + } +} + +void CWalletTx::AddSupportingTransactions(CTxDB& txdb) +{ + vtxPrev.clear(); + + const int COPY_DEPTH = 3; + if (SetMerkleBranch() < COPY_DEPTH) + { + vector vWorkQueue; + BOOST_FOREACH(const CTxIn& txin, vin) + vWorkQueue.push_back(txin.prevout.hash); + + // This critsect is OK because txdb is already open + { + LOCK(pwallet->cs_wallet); + map mapWalletPrev; + set setAlreadyDone; + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hash = vWorkQueue[i]; + if (setAlreadyDone.count(hash)) + continue; + setAlreadyDone.insert(hash); + + CMerkleTx tx; + map::const_iterator mi = pwallet->mapWallet.find(hash); + if (mi != pwallet->mapWallet.end()) + { + tx = (*mi).second; + BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev) + mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev; + } + else if (mapWalletPrev.count(hash)) + { + tx = *mapWalletPrev[hash]; + } + else if (txdb.ReadDiskTx(hash, tx)) + { + ; + } + else + { + LogPrintf("ERROR: AddSupportingTransactions() : unsupported transaction\n"); + continue; + } + + int nDepth = tx.SetMerkleBranch(); + vtxPrev.push_back(tx); + + if (nDepth < COPY_DEPTH) + { + BOOST_FOREACH(const CTxIn& txin, tx.vin) + vWorkQueue.push_back(txin.prevout.hash); + } + } + } + } + + reverse(vtxPrev.begin(), vtxPrev.end()); +} + +bool CWalletTx::WriteToDisk() +{ + return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); +} + +// Scan the block chain (starting in pindexStart) for transactions +// from or to us. If fUpdate is true, found transactions that already +// exist in the wallet will be updated. +int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) +{ + int ret = 0; + + CBlockIndex* pindex = pindexStart; + { + LOCK2(cs_main, cs_wallet); + while (pindex) + { + // no need to read and scan block, if block was created before + // our wallet birthday (as adjusted for block time variability) + if (nTimeFirstKey && (pindex->nTime < (nTimeFirstKey - 7200))) { + pindex = pindex->pnext; + continue; + } + + CBlock block; + block.ReadFromDisk(pindex, true); + BOOST_FOREACH(CTransaction& tx, block.vtx) + { + if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) + ret++; + } + pindex = pindex->pnext; + } + } + return ret; +} + +void CWallet::ReacceptWalletTransactions() +{ + CTxDB txdb("r"); + bool fRepeat = true; + while (fRepeat) + { + LOCK2(cs_main, cs_wallet); + fRepeat = false; + vector vMissingTx; + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + if ((wtx.IsCoinBase() && wtx.IsSpent(0)) || (wtx.IsCoinStake() && wtx.IsSpent(1))) + continue; + + CTxIndex txindex; + bool fUpdated = false; + if (txdb.ReadTxIndex(wtx.GetHash(), txindex)) + { + // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat + if (txindex.vSpent.size() != wtx.vout.size()) + { + LogPrintf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %u != wtx.vout.size() %u\n", txindex.vSpent.size(), wtx.vout.size()); + continue; + } + for (unsigned int i = 0; i < txindex.vSpent.size(); i++) + { + if (wtx.IsSpent(i)) + continue; + if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i])) + { + wtx.MarkSpent(i); + fUpdated = true; + vMissingTx.push_back(txindex.vSpent[i]); + } + } + if (fUpdated) + { + LogPrintf("ReacceptWalletTransactions found spent coin %s BC %s\n", FormatMoney(wtx.GetCredit()), wtx.GetHash().ToString()); + wtx.MarkDirty(); + wtx.WriteToDisk(); + } + } + else + { + // Re-accept any txes of ours that aren't already in a block + if (!(wtx.IsCoinBase() || wtx.IsCoinStake())) + wtx.AcceptWalletTransaction(txdb); + } + } + if (!vMissingTx.empty()) + { + // TODO: optimize this to scan just part of the block chain? + if (ScanForWalletTransactions(pindexGenesisBlock)) + fRepeat = true; // Found missing transactions: re-do re-accept. + } + } +} + +void CWalletTx::RelayWalletTransaction(CTxDB& txdb) +{ + BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) + { + if (!(tx.IsCoinBase() || tx.IsCoinStake())) + { + uint256 hash = tx.GetHash(); + if (!txdb.ContainsTx(hash)) + RelayTransaction((CTransaction)tx, hash); + } + } + if (!(IsCoinBase() || IsCoinStake())) + { + uint256 hash = GetHash(); + if (!txdb.ContainsTx(hash)) + { + LogPrintf("Relaying wtx %s\n", hash.ToString()); + RelayTransaction((CTransaction)*this, hash); + } + } +} + +void CWalletTx::RelayWalletTransaction() +{ + CTxDB txdb("r"); + RelayWalletTransaction(txdb); +} + +void CWallet::ResendWalletTransactions(bool fForce) +{ + if (!fForce) + { + // Do this infrequently and randomly to avoid giving away + // that these are our transactions. + static int64_t nNextTime; + if (GetTime() < nNextTime) + return; + bool fFirst = (nNextTime == 0); + nNextTime = GetTime() + GetRand(30 * 60); + if (fFirst) + return; + + // Only do it if there's been a new block since last time + static int64_t nLastTime; + if (nTimeBestReceived < nLastTime) + return; + nLastTime = GetTime(); + } + + // Rebroadcast any of our txes that aren't in a block yet + LogPrintf("ResendWalletTransactions()\n"); + CTxDB txdb("r"); + { + LOCK(cs_wallet); + // Sort them in chronological order + multimap mapSorted; + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + // Don't rebroadcast until it's had plenty of time that + // it should have gotten in already by now. + if (fForce || nTimeBestReceived - (int64_t)wtx.nTimeReceived > 5 * 60) + mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + } + BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) + { + CWalletTx& wtx = *item.second; + if (wtx.CheckTransaction()) + wtx.RelayWalletTransaction(txdb); + else + LogPrintf("ResendWalletTransactions() : CheckTransaction failed for transaction %s\n", wtx.GetHash().ToString()); + } + } +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Actions +// + + +int64_t CWallet::GetBalance() const +{ + int64_t nTotal = 0; + { + LOCK2(cs_main, cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsTrusted()) + nTotal += pcoin->GetAvailableCredit(); + } + } + + return nTotal; +} + +int64_t CWallet::GetBalanceNoLocks() const +{ + int64_t nTotal = 0; + { + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsTrusted()) + nTotal += pcoin->GetAvailableCredit(); + } + } + + return nTotal; +} + +CAmount CWallet::GetAnonymizedBalance() const +{ + int64_t nTotal = 0; + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + if (pcoin->IsTrusted()) + { + int nDepth = pcoin->GetDepthInMainChain(); + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) { + //isminetype mine = IsMine(pcoin->vout[i]); + bool mine = IsMine(pcoin->vout[i]); + //COutput out = COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO); + COutput out = COutput(pcoin, i, nDepth, mine); + CTxIn vin = CTxIn(out.tx->GetHash(), out.i); + + //if(IsSpent(out.tx->GetHash(), i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue; + if(pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue; + + int rounds = GetInputDarksendRounds(vin); + if(rounds >= nDarksendRounds){ + nTotal += pcoin->vout[i].nValue; + } + } + } + } + } + + return nTotal; +} + +double CWallet::GetAverageAnonymizedRounds() const +{ + double fTotal = 0; + double fCount = 0; + + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + if (pcoin->IsTrusted()) + { + int nDepth = pcoin->GetDepthInMainChain(); + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) { + //isminetype mine = IsMine(pcoin->vout[i]); + bool mine = IsMine(pcoin->vout[i]); + //COutput out = COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO); + COutput out = COutput(pcoin, i, nDepth, mine); + CTxIn vin = CTxIn(out.tx->GetHash(), out.i); + + //if(IsSpent(out.tx->GetHash(), i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue; + if(pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue; + + int rounds = GetInputDarksendRounds(vin); + fTotal += (float)rounds; + fCount += 1; + } + } + } + } + + if(fCount == 0) return 0; + + return fTotal/fCount; +} + +CAmount CWallet::GetNormalizedAnonymizedBalance() const +{ + int64_t nTotal = 0; + + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + if (pcoin->IsTrusted()) + { + int nDepth = pcoin->GetDepthInMainChain(); + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) { + //isminetype mine = IsMine(pcoin->vout[i]); + bool mine = IsMine(pcoin->vout[i]); + //COutput out = COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO); + COutput out = COutput(pcoin, i, nDepth, mine); + CTxIn vin = CTxIn(out.tx->GetHash(), out.i); + + //if(IsSpent(out.tx->GetHash(), i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue; + if(pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue; + + int rounds = GetInputDarksendRounds(vin); + nTotal += pcoin->vout[i].nValue * rounds / nDarksendRounds; + } + } + } + } + + return nTotal; +} + +CAmount CWallet::GetDenominatedBalance(bool onlyDenom, bool onlyUnconfirmed) const +{ + int64_t nTotal = 0; + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + int nDepth = pcoin->GetDepthInMainChain(); + + // skip conflicted + if(nDepth < 0) continue; + + bool unconfirmed = (!IsFinalTx(*pcoin) || (!pcoin->IsTrusted() && nDepth == 0)); + if(onlyUnconfirmed != unconfirmed) continue; + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) + { + //isminetype mine = IsMine(pcoin->vout[i]); + //bool mine = IsMine(pcoin->vout[i]); + //COutput out = COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO); + //COutput out = COutput(pcoin, i, nDepth, mine); + + //if(IsSpent(out.tx->GetHash(), i)) continue; + if(pcoin->IsSpent(i)) continue; + if(!IsMine(pcoin->vout[i])) continue; + if(onlyDenom != IsDenominatedAmount(pcoin->vout[i].nValue)) continue; + + nTotal += pcoin->vout[i].nValue; + } + } + } + + + + return nTotal; +} + + +int64_t CWallet::GetUnconfirmedBalance() const +{ + int64_t nTotal = 0; + { + LOCK2(cs_main, cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (!IsFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0)) + nTotal += pcoin->GetAvailableCredit(); + } + } + return nTotal; +} + +int64_t CWallet::GetImmatureBalance() const +{ + int64_t nTotal = 0; + { + LOCK2(cs_main, cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& pcoin = (*it).second; + if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.IsInMainChain()) + nTotal += GetCredit(pcoin); + } + } + return nTotal; +} + + +// populate vCoins with vector of spendable COutputs +void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, AvailableCoinsType coin_type, bool useIX) const +{ + vCoins.clear(); + + { + LOCK2(cs_main, cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + if (!IsFinalTx(*pcoin)) + continue; + + if (fOnlyConfirmed && !pcoin->IsTrusted()) + continue; + + if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) + continue; + + if(pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0) + continue; + + int nDepth = pcoin->GetDepthInMainChain(); + if (nDepth <= 0) // phantomxNOTE: coincontrol fix / ignore 0 confirm + continue; + + /* for (unsigned int i = 0; i < pcoin->vout.size(); i++) + if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue >= nMinimumInputValue && + (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) + vCoins.push_back(COutput(pcoin, i, nDepth));*/ + // do not use IX for inputs that have less then 6 blockchain confirmations + if (useIX && nDepth < 6) + continue; + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) { + bool found = false; + if(coin_type == ONLY_DENOMINATED) { + //should make this a vector + found = IsDenominatedAmount(pcoin->vout[i].nValue); + } else if(coin_type == ONLY_NONDENOMINATED) { + found = !(fMasterNode && pcoin->vout[i].nValue == MasternodeCollateral(pindexBest->nHeight)*COIN); + } else if(coin_type == ONLY_NONDENOMINATED_NOTMN) { + if (IsCollateralAmount(pcoin->vout[i].nValue)) continue; // do not use collateral amounts + found = !IsDenominatedAmount(pcoin->vout[i].nValue); + // if(found && coin_type == ONLY_NONDENOMINATED_NOTMN) found = (pcoin->vout[i].nValue != MasternodeCollateral(pindexBest->nHeight)*COIN); // do not use MN funds + // found = true; + + if(found && fMasterNode) found = pcoin->vout[i].nValue != MasternodeCollateral(pindexBest->nHeight)*COIN; // do not use Hot MN funds + } else { + found = true; + } + if(!found) continue; + + //isminetype mine = IsMine(pcoin->vout[i]); + bool mine = IsMine(pcoin->vout[i]); + + //if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO && + // !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0 && + // (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) + // vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO)); + //if (!(IsSpent(wtxid, i)) && mine && + if (!(pcoin->IsSpent(i)) && mine && + !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0 && + (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) + vCoins.push_back(COutput(pcoin, i, nDepth, mine)); + } + } + } +} + +void CWallet::AvailableCoinsMN(vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, AvailableCoinsType coin_type, bool useIX) const +{ + vCoins.clear(); + + { + LOCK2(cs_main, cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + if (!IsFinalTx(*pcoin)) + continue; + + if (fOnlyConfirmed && !pcoin->IsTrusted()) + continue; + + if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) + continue; + + if(pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0) + continue; + + int nDepth = pcoin->GetDepthInMainChain(); + if (nDepth <= 0) // TXNOTE: coincontrol fix / ignore 0 confirm + continue; + + // do not use IX for inputs that have less then 6 blockchain confirmations + if (useIX && nDepth < 6) + continue; + + /* for (unsigned int i = 0; i < pcoin->vout.size(); i++) + if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue >= nMinimumInputValue && + (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) + vCoins.push_back(COutput(pcoin, i, nDepth));*/ + + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) { + bool found = false; + if(coin_type == ONLY_DENOMINATED) { + //should make this a vector + found = IsDenominatedAmount(pcoin->vout[i].nValue); + } else if(coin_type == ONLY_NONDENOMINATED || coin_type == ONLY_NONDENOMINATED_NOTMN) { + found = true; + if (IsCollateralAmount(pcoin->vout[i].nValue)) continue; // do not use collateral amounts + found = !IsDenominatedAmount(pcoin->vout[i].nValue); + if(found && coin_type == ONLY_NONDENOMINATED_NOTMN) found = (pcoin->vout[i].nValue != MasternodeCollateral(pindexBest->nHeight)*COIN); // do not use MN funds + } else { + found = true; + } + if(!found) continue; + + //isminetype mine = IsMine(pcoin->vout[i]); + bool mine = IsMine(pcoin->vout[i]); + + //if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO && + // !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0 && + // (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) + // vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO)); + //if (!(IsSpent(wtxid, i)) && mine && + if (!(pcoin->IsSpent(i)) && + !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0 && + (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) + vCoins.push_back(COutput(pcoin, i, nDepth, mine)); + } + } + } +} + +void CWallet::AvailableCoinsForStaking(vector& vCoins, unsigned int nSpendTime) const +{ + vCoins.clear(); + + { + LOCK2(cs_main, cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + // Filtering by tx timestamp instead of block timestamp may give false positives but never false negatives + if (pcoin->nTime + nStakeMinAge > nSpendTime) + continue; + + if (pcoin->GetBlocksToMaturity() > 0) + continue; + + int nDepth = pcoin->GetDepthInMainChain(); + if (nDepth < 1) + continue; + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) + if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue >= nMinimumInputValue) + vCoins.push_back(COutput(pcoin, i, nDepth, true)); + } + } +} + +static void ApproximateBestSubset(vector > >vValue, int64_t nTotalLower, int64_t nTargetValue, + vector& vfBest, int64_t& nBest, int iterations = 1000) +{ + vector vfIncluded; + + vfBest.assign(vValue.size(), true); + nBest = nTotalLower; + + seed_insecure_rand(); + + for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++) + { + vfIncluded.assign(vValue.size(), false); + int64_t nTotal = 0; + bool fReachedTarget = false; + for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) + { + for (unsigned int i = 0; i < vValue.size(); i++) + { + //The solver here uses a randomized algorithm, + //the randomness serves no real security purpose but is just + //needed to prevent degenerate behavior and it is important + //that the rng fast. We do not use a constant random sequence, + //because there may be some privacy improvement by making + //the selection random. + if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i]) + { + nTotal += vValue[i].first; + vfIncluded[i] = true; + if (nTotal >= nTargetValue) + { + fReachedTarget = true; + if (nTotal < nBest) + { + nBest = nTotal; + vfBest = vfIncluded; + } + nTotal -= vValue[i].first; + vfIncluded[i] = false; + } + } + } + } + } +} + +// ppcoin: total coins staked (non-spendable until maturity) +int64_t CWallet::GetStake() const +{ + int64_t nTotal = 0; + LOCK2(cs_main, cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0) + nTotal += CWallet::GetCredit(*pcoin); + } + return nTotal; +} + +int64_t CWallet::GetNewMint() const +{ + int64_t nTotal = 0; + LOCK2(cs_main, cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0) + nTotal += CWallet::GetCredit(*pcoin); + } + return nTotal; +} + +struct LargerOrEqualThanThreshold +{ + int64_t threshold; + LargerOrEqualThanThreshold(int64_t threshold) : threshold(threshold) {} + bool operator()(pair,pair > const &v) const { return v.first.first >= threshold; } +}; + +bool CWallet::SelectCoinsMinConfByCoinAge(int64_t nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector vCoins, set >& setCoinsRet, int64_t& nValueRet) const +{ + setCoinsRet.clear(); + nValueRet = 0; + + vector > mCoins; + BOOST_FOREACH(const COutput& out, vCoins) + { + mCoins.push_back(std::make_pair(out, CoinWeightCost(out))); + } + + // List of values less than target + pair, pair > coinLowestLarger; + coinLowestLarger.first.second = std::numeric_limits::max(); + coinLowestLarger.second.first = NULL; + vector,pair > > vValue; + int64_t nTotalLower = 0; + boost::sort(mCoins, boost::bind(&std::pair::second, _1) < boost::bind(&std::pair::second, _2)); + + BOOST_FOREACH(const PAIRTYPE(COutput, uint64_t)& output, mCoins) + { + const CWalletTx *pcoin = output.first.tx; + + if (output.first.nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs)) + continue; + + int i = output.first.i; + + // Follow the timestamp rules + if (pcoin->nTime > nSpendTime) + continue; + + int64_t n = pcoin->vout[i].nValue; + + pair,pair > coin = make_pair(make_pair(n,output.second),make_pair(pcoin, i)); + + if (n < nTargetValue + CENT) + { + vValue.push_back(coin); + nTotalLower += n; + } + else if (output.second < (uint64_t)coinLowestLarger.first.second) + { + coinLowestLarger = coin; + } + } + + if (nTotalLower < nTargetValue) + { + if (coinLowestLarger.second.first == NULL) + return false; + setCoinsRet.insert(coinLowestLarger.second); + nValueRet += coinLowestLarger.first.first; + return true; + } + + // Calculate dynamic programming matrix + int64_t nTotalValue = vValue[0].first.first; + int64_t nGCD = vValue[0].first.first; + for (unsigned int i = 1; i < vValue.size(); ++i) + { + nGCD = gcd(vValue[i].first.first, nGCD); + nTotalValue += vValue[i].first.first; + } + nGCD = gcd(nTargetValue, nGCD); + int64_t denom = nGCD; + const int64_t k = 25; + const int64_t approx = int64_t(vValue.size() * (nTotalValue - nTargetValue)) / k; + if (approx > nGCD) + { + denom = approx; // apply approximation + } + if (fDebug) cerr << "nGCD " << nGCD << " denom " << denom << " k " << k << endl; + + if (nTotalValue == nTargetValue) + { + for (unsigned int i = 0; i < vValue.size(); ++i) + { + setCoinsRet.insert(vValue[i].second); + } + nValueRet = nTotalValue; + return true; + } + + size_t nBeginBundles = vValue.size(); + size_t nTotalCoinValues = vValue.size(); + size_t nBeginCoinValues = 0; + int64_t costsum = 0; + vector,pair > >::iterator> vZeroValueBundles; + if (denom != nGCD) + { + // All coin outputs that with zero value will always be added by the dynamic programming routine + // So we collect them into bundles of value denom + vector,pair > >::iterator itZeroValue = std::stable_partition(vValue.begin(), vValue.end(), LargerOrEqualThanThreshold(denom)); + vZeroValueBundles.push_back(itZeroValue); + pair pBundle = make_pair(0, 0); + nBeginBundles = itZeroValue - vValue.begin(); + nTotalCoinValues = nBeginBundles; + while (itZeroValue != vValue.end()) + { + pBundle.first += itZeroValue->first.first; + pBundle.second += itZeroValue->first.second; + itZeroValue++; + if (pBundle.first >= denom) + { + vZeroValueBundles.push_back(itZeroValue); + vValue[nTotalCoinValues].first = pBundle; + pBundle = make_pair(0, 0); + nTotalCoinValues++; + } + } + // We need to recalculate the total coin value due to truncation of integer division + nTotalValue = 0; + for (unsigned int i = 0; i < nTotalCoinValues; ++i) + { + nTotalValue += vValue[i].first.first / denom; + } + // Check if dynamic programming is still applicable with the approximation + if (nTargetValue/denom >= nTotalValue) + { + // We lose too much coin value through the approximation, i.e. the residual of the previous recalculation is too large + // Since the partitioning of the previously sorted list is stable, we can just pick the first coin outputs in the list until we have a valid target value + for (; nBeginCoinValues < nTotalCoinValues && (nTargetValue - nValueRet)/denom >= nTotalValue; ++nBeginCoinValues) + { + if (nBeginCoinValues >= nBeginBundles) + { + if (fDebug) cerr << "prepick bundle item " << FormatMoney(vValue[nBeginCoinValues].first.first) << " normalized " << vValue[nBeginCoinValues].first.first / denom << " cost " << vValue[nBeginCoinValues].first.second << endl; + const size_t nBundle = nBeginCoinValues - nBeginBundles; + for (vector,pair > >::iterator it = vZeroValueBundles[nBundle]; it != vZeroValueBundles[nBundle + 1]; ++it) + { + setCoinsRet.insert(it->second); + } + } + else + { + if (fDebug) cerr << "prepicking " << FormatMoney(vValue[nBeginCoinValues].first.first) << " normalized " << vValue[nBeginCoinValues].first.first / denom << " cost " << vValue[nBeginCoinValues].first.second << endl; + setCoinsRet.insert(vValue[nBeginCoinValues].second); + } + nTotalValue -= vValue[nBeginCoinValues].first.first / denom; + nValueRet += vValue[nBeginCoinValues].first.first; + costsum += vValue[nBeginCoinValues].first.second; + } + if (nValueRet >= nTargetValue) + { + if (fDebug) cerr << "Done without dynprog: " << "requested " << FormatMoney(nTargetValue) << "\tnormalized " << nTargetValue/denom + (nTargetValue % denom != 0 ? 1 : 0) << "\tgot " << FormatMoney(nValueRet) << "\tcost " << costsum << endl; + return true; + } + } + } + else + { + nTotalValue /= denom; + } + + uint64_t nAppend = 1; + if ((nTargetValue - nValueRet) % denom != 0) + { + // We need to decrease the capacity because of integer truncation + nAppend--; + } + + // The capacity (number of columns) corresponds to the amount of coin value we are allowed to discard + boost::numeric::ublas::matrix M((nTotalCoinValues - nBeginCoinValues) + 1, (nTotalValue - (nTargetValue - nValueRet)/denom) + nAppend, std::numeric_limits::max()); + boost::numeric::ublas::matrix B((nTotalCoinValues - nBeginCoinValues) + 1, (nTotalValue - (nTargetValue - nValueRet)/denom) + nAppend); + for (unsigned int j = 0; j < M.size2(); ++j) + { + M(0,j) = 0; + } + for (unsigned int i = 1; i < M.size1(); ++i) + { + uint64_t nWeight = vValue[nBeginCoinValues + i - 1].first.first / denom; + uint64_t nValue = vValue[nBeginCoinValues + i - 1].first.second; + //cerr << "Weight " << nWeight << " Value " << nValue << endl; + for (unsigned int j = 0; j < M.size2(); ++j) + { + B(i, j) = j; + if (nWeight <= j) + { + uint64_t nStep = M(i - 1, j - nWeight) + nValue; + if (M(i - 1, j) >= nStep) + { + M(i, j) = M(i - 1, j); + } + else + { + M(i, j) = nStep; + B(i, j) = j - nWeight; + } + } + else + { + M(i, j) = M(i - 1, j); + } + } + } + // Trace back optimal solution + int64_t nPrev = M.size2() - 1; + for (unsigned int i = M.size1() - 1; i > 0; --i) + { + //cerr << i - 1 << " " << vValue[i - 1].second.second << " " << vValue[i - 1].first.first << " " << vValue[i - 1].first.second << " " << nTargetValue << " " << nPrev << " " << (nPrev == B(i, nPrev) ? "XXXXXXXXXXXXXXX" : "") << endl; + if (nPrev == B(i, nPrev)) + { + const size_t nValue = nBeginCoinValues + i - 1; + // Check if this is a bundle + if (nValue >= nBeginBundles) + { + if (fDebug) cerr << "pick bundle item " << FormatMoney(vValue[nValue].first.first) << " normalized " << vValue[nValue].first.first / denom << " cost " << vValue[nValue].first.second << endl; + const size_t nBundle = nValue - nBeginBundles; + for (vector,pair > >::iterator it = vZeroValueBundles[nBundle]; it != vZeroValueBundles[nBundle + 1]; ++it) + { + setCoinsRet.insert(it->second); + } + } + else + { + if (fDebug) cerr << "pick " << nValue << " value " << FormatMoney(vValue[nValue].first.first) << " normalized " << vValue[nValue].first.first / denom << " cost " << vValue[nValue].first.second << endl; + setCoinsRet.insert(vValue[nValue].second); + } + nValueRet += vValue[nValue].first.first; + costsum += vValue[nValue].first.second; + } + nPrev = B(i, nPrev); + } + if (nValueRet < nTargetValue && !vZeroValueBundles.empty()) + { + // If we get here it means that there are either not sufficient funds to pay the transaction or that there are small coin outputs left that couldn't be bundled + // We try to fulfill the request by adding these small coin outputs + for (vector,pair > >::iterator it = vZeroValueBundles.back(); it != vValue.end() && nValueRet < nTargetValue; ++it) + { + setCoinsRet.insert(it->second); + nValueRet += it->first.first; + } + } + if (fDebug) cerr << "requested " << FormatMoney(nTargetValue) << "\tnormalized " << nTargetValue/denom + (nTargetValue % denom != 0 ? 1 : 0) << "\tgot " << FormatMoney(nValueRet) << "\tcost " << costsum << endl; + if (fDebug) cerr << "M " << M.size1() << "x" << M.size2() << "; vValue.size() = " << vValue.size() << endl; + return true; +} + +// TODO: find appropriate place for this sort function +// move denoms down +bool less_then_denom (const COutput& out1, const COutput& out2) +{ + const CWalletTx *pcoin1 = out1.tx; + const CWalletTx *pcoin2 = out2.tx; + + bool found1 = false; + bool found2 = false; + BOOST_FOREACH(int64_t d, darkSendDenominations) // loop through predefined denoms + { + if(pcoin1->vout[out1.i].nValue == d) found1 = true; + if(pcoin2->vout[out2.i].nValue == d) found2 = true; + } + return (!found1 && found2); +} + +bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, vector vCoins, set >& setCoinsRet, int64_t& nValueRet) const +{ + setCoinsRet.clear(); + nValueRet = 0; + + // List of values less than target + pair > coinLowestLarger; + coinLowestLarger.first = std::numeric_limits::max(); + coinLowestLarger.second.first = NULL; + vector > > vValue; + int64_t nTotalLower = 0; + + random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); + + // move denoms down on the list + sort(vCoins.begin(), vCoins.end(), less_then_denom); + + // try to find nondenom first to prevent unneeded spending of mixed coins + for (unsigned int tryDenom = 0; tryDenom < 2; tryDenom++) + { + if (fDebug) LogPrint("selectcoins", "tryDenom: %d\n", tryDenom); + vValue.clear(); + nTotalLower = 0; + + BOOST_FOREACH(COutput output, vCoins) + { + const CWalletTx *pcoin = output.tx; + + if (output.nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs)) + continue; + + int i = output.i; + + // Follow the timestamp rules + if (pcoin->nTime > nSpendTime) + continue; + + int64_t n = pcoin->vout[i].nValue; + + if (tryDenom == 0 && IsDenominatedAmount(n)) continue; // we don't want denom values on first run + + pair > coin = make_pair(n,make_pair(pcoin, i)); + + if (n == nTargetValue) + { + setCoinsRet.insert(coin.second); + nValueRet += coin.first; + return true; + } + else if (n < nTargetValue + CENT) + { + vValue.push_back(coin); + nTotalLower += n; + } + else if (n < coinLowestLarger.first) + { + coinLowestLarger = coin; + } + } + + if (nTotalLower == nTargetValue) + { + for (unsigned int i = 0; i < vValue.size(); ++i) + { + setCoinsRet.insert(vValue[i].second); + nValueRet += vValue[i].first; + } + return true; + } + + if (nTotalLower < nTargetValue) + { + if (coinLowestLarger.second.first == NULL) + return false; + setCoinsRet.insert(coinLowestLarger.second); + nValueRet += coinLowestLarger.first; + return true; + } + + // Solve subset sum by stochastic approximation + sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); + vector vfBest; + int64_t nBest; + + ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000); + if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT) + ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000); + + // If we have a bigger coin and (either the stochastic approximation didn't find a good solution, + // or the next bigger coin is closer), return the bigger coin + if (coinLowestLarger.second.first && + ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest)) + { + setCoinsRet.insert(coinLowestLarger.second); + nValueRet += coinLowestLarger.first; + } + else { + for (unsigned int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + { + setCoinsRet.insert(vValue[i].second); + nValueRet += vValue[i].first; + } + + LogPrint("selectcoins", "SelectCoins() best subset: "); + for (unsigned int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first)); + LogPrint("selectcoins", "total %s\n", FormatMoney(nBest)); + } + + return true; + } + return false; +} + +bool CWallet::SelectCoins(int64_t nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64_t& nValueRet, const CCoinControl* coinControl, AvailableCoinsType coin_type, bool useIX) const +{ + vector vCoins; + AvailableCoins(vCoins, true, coinControl); + + //if we're doing only denominated, we need to round up to the nearest .1phantomx + if(coin_type == ONLY_DENOMINATED){ + // Make outputs by looping through denominations, from large to small + BOOST_FOREACH(int64_t v, darkSendDenominations) + { + int added = 0; + BOOST_FOREACH(const COutput& out, vCoins) + { + if(out.tx->vout[out.i].nValue == v //make sure it's the denom we're looking for + && nValueRet + out.tx->vout[out.i].nValue < nTargetValue + (0.1*COIN)+100 //round the amount up to .1phantomx over + && added <= 100){ //don't add more than 100 of one denom type + CTxIn vin = CTxIn(out.tx->GetHash(),out.i); + int rounds = GetInputDarksendRounds(vin); + // make sure it's actually anonymized + if(rounds < nDarksendRounds) continue; + nValueRet += out.tx->vout[out.i].nValue; + setCoinsRet.insert(make_pair(out.tx, out.i)); + added++; + } + } + } + return (nValueRet >= nTargetValue); + } + + // If coin control is not used and all coins were request we can activate the soft lock. + if (coin_type == ALL_COINS && fMasternodeSoftLock) { + AvailableCoins(vCoins, true, coinControl, ONLY_NONDENOMINATED_NOTMN, useIX); + } + + // coin control -> return all selected outputs (we want all selected to go into the transaction for sure) + if (coinControl && coinControl->HasSelected()) + { + BOOST_FOREACH(const COutput& out, vCoins) + { + if(!out.fSpendable) + continue; + nValueRet += out.tx->vout[out.i].nValue; + setCoinsRet.insert(make_pair(out.tx, out.i)); + } + return (nValueRet >= nTargetValue); + } + + boost::function, std::set >&, int64_t&)> f = fMinimizeCoinAge ? &CWallet::SelectCoinsMinConfByCoinAge : &CWallet::SelectCoinsMinConf; + + return (f(this, nTargetValue, nSpendTime, 1, 10, vCoins, setCoinsRet, nValueRet) || + f(this, nTargetValue, nSpendTime, 1, 1, vCoins, setCoinsRet, nValueRet) || + f(this, nTargetValue, nSpendTime, 0, 1, vCoins, setCoinsRet, nValueRet)); +} + +// Select some coins without random shuffle or best subset approximation +bool CWallet::SelectCoinsForStaking(int64_t nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64_t& nValueRet) const +{ + vector vCoins; + AvailableCoinsForStaking(vCoins, nSpendTime); + + setCoinsRet.clear(); + nValueRet = 0; + + BOOST_FOREACH(COutput output, vCoins) + { + const CWalletTx *pcoin = output.tx; + int i = output.i; + + // Stop if we've chosen enough inputs + if (nValueRet >= nTargetValue) + break; + + int64_t n = pcoin->vout[i].nValue; + + pair > coin = make_pair(n,make_pair(pcoin, i)); + + if (n >= nTargetValue) + { + // If input value is greater or equal to target then simply insert + // it into the current subset and exit + setCoinsRet.insert(coin.second); + nValueRet += coin.first; + break; + } + else if (n < nTargetValue + CENT) + { + setCoinsRet.insert(coin.second); + nValueRet += coin.first; + } + } + + return true; +} + +struct CompareByPriority +{ + bool operator()(const COutput& t1, + const COutput& t2) const + { + return t1.Priority() > t2.Priority(); + } +}; + +bool CWallet::SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t nValueMax, std::vector& setCoinsRet, vector& setCoinsRet2, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax) +{ + setCoinsRet.clear(); + nValueRet = 0; + + setCoinsRet2.clear(); + vector vCoins; + AvailableCoins(vCoins); + + //order the array so fees are first, then denominated money, then the rest. + std::random_shuffle(vCoins.rbegin(), vCoins.rend()); + + //keep track of each denomination that we have + bool fFound100000 = false; + bool fFound10000 = false; + bool fFound1000 = false; + bool fFound100 = false; + bool fFound10 = false; + bool fFound1 = false; + bool fFoundDot1 = false; + + //Check to see if any of the denomination are off, in that case mark them as fulfilled + + + + if(!(nDenom & (1 << 0))) fFound100000 = true; + if(!(nDenom & (1 << 1))) fFound10000 = true; + if(!(nDenom & (1 << 2))) fFound1000 = true; + if(!(nDenom & (1 << 3))) fFound100 = true; + if(!(nDenom & (1 << 4))) fFound10 = true; + if(!(nDenom & (1 << 5))) fFound1 = true; + if(!(nDenom & (1 << 6))) fFoundDot1 = true; + + BOOST_FOREACH(const COutput& out, vCoins) + { + //there's no reason to allow inputs less than 1 COIN into DS (other than denominations smaller than that amount) + if(out.tx->vout[out.i].nValue < 1*COIN && out.tx->vout[out.i].nValue != (.1*COIN)+100) continue; + if(fMasterNode && out.tx->vout[out.i].nValue == MasternodeCollateral(pindexBest->nHeight)*COIN) continue; //masternode input + if(nValueRet + out.tx->vout[out.i].nValue <= nValueMax){ + bool fAccepted = false; + + // Function returns as follows: + // + // bit 0 - 100phantomx+1 ( bit on if present ) + // bit 1 - 10phantomx+1 + // bit 2 - 1phantomx+1 + // bit 3 - .1phantomx+1 + + CTxIn vin = CTxIn(out.tx->GetHash(),out.i); + + int rounds = GetInputDarksendRounds(vin); + if(rounds >= nDarksendRoundsMax) continue; + if(rounds < nDarksendRoundsMin) continue; + + if(fFound100000 && fFound10000 && fFound1000 && fFound100 && fFound10 && fFound1 && fFoundDot1){ //if fulfilled + //we can return this for submission + if(nValueRet >= nValueMin){ + //random reduce the max amount we'll submit for anonymity + nValueMax -= (rand() % (nValueMax/5)); + //on average use 50% of the inputs or less + int r = (rand() % (int)vCoins.size()); + if((int)setCoinsRet.size() > r) return true; + } + //Denomination criterion has been met, we can take any matching denominations + if((nDenom & (1 << 0)) && out.tx->vout[out.i].nValue == ((100000*COIN) +100000000)) {fAccepted = true;} + else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((10000*COIN) +10000000)) {fAccepted = true;} + else if((nDenom & (1 << 2)) && out.tx->vout[out.i].nValue == ((1000*COIN) +1000000)) {fAccepted = true;} + else if((nDenom & (1 << 3)) && out.tx->vout[out.i].nValue == ((100*COIN) +100000)) {fAccepted = true;} + else if((nDenom & (1 << 4)) && out.tx->vout[out.i].nValue == ((10*COIN) +10000)) {fAccepted = true;} + else if((nDenom & (1 << 5)) && out.tx->vout[out.i].nValue == ((1*COIN) +1000)) {fAccepted = true;} + else if((nDenom & (1 << 6)) && out.tx->vout[out.i].nValue == ((.1*COIN) +100)) {fAccepted = true;} + } else { + //Criterion has not been satisfied, we will only take 1 of each until it is. + if((nDenom & (1 << 0)) && out.tx->vout[out.i].nValue == ((100000*COIN) +100000000)) {fAccepted = true; fFound100000 = true;} + else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((10000*COIN) +10000000)) {fAccepted = true; fFound10000 = true;} + else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((1000*COIN) +1000000)) {fAccepted = true; fFound1000 = true;} + else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((100*COIN) +100000)) {fAccepted = true; fFound100 = true;} + else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((10*COIN) +10000)) {fAccepted = true; fFound10 = true;} + else if((nDenom & (1 << 2)) && out.tx->vout[out.i].nValue == ((1*COIN) +1000)) {fAccepted = true; fFound1 = true;} + else if((nDenom & (1 << 3)) && out.tx->vout[out.i].nValue == ((.1*COIN) +100)) {fAccepted = true; fFoundDot1 = true;} + } + if(!fAccepted) continue; + + vin.prevPubKey = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey + nValueRet += out.tx->vout[out.i].nValue; + setCoinsRet.push_back(vin); + setCoinsRet2.push_back(out); + } + } + + return (nValueRet >= nValueMin && fFound100000 && fFound10000 && fFound1000 && fFound100 && fFound10 && fFound1 && fFoundDot1); +} + +bool CWallet::SelectCoinsDark(int64_t nValueMin, int64_t nValueMax, std::vector& setCoinsRet, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax) const +{ + CCoinControl *coinControl=NULL; + + setCoinsRet.clear(); + nValueRet = 0; + + vector vCoins; + AvailableCoins(vCoins, true, coinControl, nDarksendRoundsMin < 0 ? ONLY_NONDENOMINATED_NOTMN : ONLY_DENOMINATED); + + set > setCoinsRet2; + + //order the array so fees are first, then denominated money, then the rest. + sort(vCoins.rbegin(), vCoins.rend(), CompareByPriority()); + + //the first thing we get is a fee input, then we'll use as many denominated as possible. then the rest + BOOST_FOREACH(const COutput& out, vCoins) + { + //there's no reason to allow inputs less than 1 COIN into DS (other than denominations smaller than that amount) + if(out.tx->vout[out.i].nValue < 1*COIN && out.tx->vout[out.i].nValue != (.1*COIN)+100) continue; + if(fMasterNode && out.tx->vout[out.i].nValue == MasternodeCollateral(pindexBest->nHeight)*COIN) continue; //masternode input + + if(nValueRet + out.tx->vout[out.i].nValue <= nValueMax){ + CTxIn vin = CTxIn(out.tx->GetHash(),out.i); + + int rounds = GetInputDarksendRounds(vin); + if(rounds >= nDarksendRoundsMax) continue; + if(rounds < nDarksendRoundsMin) continue; + + vin.prevPubKey = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey + nValueRet += out.tx->vout[out.i].nValue; + setCoinsRet.push_back(vin); + setCoinsRet2.insert(make_pair(out.tx, out.i)); + } + } + + // if it's more than min, we're good to return + if(nValueRet >= nValueMin) return true; + + return false; +} + +bool CWallet::SelectCoinsCollateral(std::vector& setCoinsRet, int64_t& nValueRet) const +{ + vector vCoins; + + //printf(" selecting coins for collateral\n"); + AvailableCoins(vCoins); + + //printf("found coins %d\n", (int)vCoins.size()); + + set > setCoinsRet2; + + BOOST_FOREACH(const COutput& out, vCoins) + { + // collateral inputs will always be a multiple of DARSEND_COLLATERAL, up to five + if(IsCollateralAmount(out.tx->vout[out.i].nValue)) + { + CTxIn vin = CTxIn(out.tx->GetHash(),out.i); + + vin.prevPubKey = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey + nValueRet += out.tx->vout[out.i].nValue; + setCoinsRet.push_back(vin); + setCoinsRet2.insert(make_pair(out.tx, out.i)); + return true; + } + } + + return false; +} + +int CWallet::CountInputsWithAmount(int64_t nInputAmount) +{ + int64_t nTotal = 0; + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsTrusted()){ + int nDepth = pcoin->GetDepthInMainChain(); + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) { + //isminetype mine = IsMine(pcoin->vout[i]); + bool mine = IsMine(pcoin->vout[i]); + //COutput out = COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO); + COutput out = COutput(pcoin, i, nDepth, mine); + CTxIn vin = CTxIn(out.tx->GetHash(), out.i); + + if(out.tx->vout[out.i].nValue != nInputAmount) continue; + if(!IsDenominatedAmount(pcoin->vout[i].nValue)) continue; + //if(IsSpent(out.tx->GetHash(), i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue; + if(pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue; + + nTotal++; + } + } + } + } + + return nTotal; +} + +bool CWallet::HasCollateralInputs() const +{ + vector vCoins; + AvailableCoins(vCoins); + + int nFound = 0; + BOOST_FOREACH(const COutput& out, vCoins) + if(IsCollateralAmount(out.tx->vout[out.i].nValue)) nFound++; + + return nFound > 1; // should have more than one just in case +} + +bool CWallet::IsCollateralAmount(int64_t nInputAmount) const +{ + return nInputAmount == (DARKSEND_COLLATERAL * 5)+DARKSEND_FEE || + nInputAmount == (DARKSEND_COLLATERAL * 4)+DARKSEND_FEE || + nInputAmount == (DARKSEND_COLLATERAL * 3)+DARKSEND_FEE || + nInputAmount == (DARKSEND_COLLATERAL * 2)+DARKSEND_FEE || + nInputAmount == (DARKSEND_COLLATERAL * 1)+DARKSEND_FEE; +} + +bool CWallet::SelectCoinsWithoutDenomination(int64_t nTargetValue, set >& setCoinsRet, int64_t& nValueRet) const +{ + CCoinControl *coinControl=NULL; + + vector vCoins; + AvailableCoins(vCoins, true, coinControl, ONLY_NONDENOMINATED); + + BOOST_FOREACH(const COutput& out, vCoins) + { + nValueRet += out.tx->vout[out.i].nValue; + setCoinsRet.insert(make_pair(out.tx, out.i)); + } + return (nValueRet >= nTargetValue); +} + +bool CWallet::CreateCollateralTransaction(CTransaction& txCollateral, std::string strReason) +{ + /* + To doublespend a collateral transaction, it will require a fee higher than this. So there's + still a significant cost. + */ + int64_t nFeeRet = 0.001*COIN; + + txCollateral.vin.clear(); + txCollateral.vout.clear(); + + CReserveKey reservekey(this); + int64_t nValueIn2 = 0; + std::vector vCoinsCollateral; + + if (!SelectCoinsCollateral(vCoinsCollateral, nValueIn2)) + { + strReason = "Error: Darksend requires a collateral transaction and could not locate an acceptable input!"; + return false; + } + + // make our change address + CScript scriptChange; + CPubKey vchPubKey; + assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + scriptChange =GetScriptForDestination(vchPubKey.GetID()); + reservekey.KeepKey(); + + BOOST_FOREACH(CTxIn v, vCoinsCollateral) + txCollateral.vin.push_back(v); + + if(nValueIn2 - DARKSEND_COLLATERAL - nFeeRet > 0) { + //pay collateral charge in fees + CTxOut vout3 = CTxOut(nValueIn2 - DARKSEND_COLLATERAL, scriptChange); + txCollateral.vout.push_back(vout3); + } + + int vinNumber = 0; + BOOST_FOREACH(CTxIn v, txCollateral.vin) { + if(!SignSignature(*this, v.prevPubKey, txCollateral, vinNumber, int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))) { + BOOST_FOREACH(CTxIn v, vCoinsCollateral) + UnlockCoin(v.prevout); + + strReason = "CDarkSendPool::Sign - Unable to sign collateral transaction! \n"; + return false; + } + vinNumber++; + } + + return true; +} + +bool CWallet::ConvertList(std::vector vCoins, std::vector& vecAmounts) +{ + BOOST_FOREACH(CTxIn i, vCoins){ + if (mapWallet.count(i.prevout.hash)) + { + CWalletTx& wtx = mapWallet[i.prevout.hash]; + if(i.prevout.n < wtx.vout.size()){ + vecAmounts.push_back(wtx.vout[i.prevout.n].nValue); + } + } else { + LogPrintf("ConvertList -- Couldn't find transaction\n"); + } + } + return true; +} + + +bool CWallet::CreateTransaction(const vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, int32_t& nChangePos, std::string& strFailReason, const CCoinControl* coinControl, AvailableCoinsType coin_type, bool useIX) +{ + int64_t nValue = 0; + BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend) + { + if (nValue < 0){ + strFailReason = _("Transaction amounts must be positive"); + return false; + } + nValue += s.second; + } + if (vecSend.empty() || nValue < 0){ + strFailReason = _("Transaction amounts must be positive"); + return false; + } + + wtxNew.BindWallet(this); + CTransaction txNew; + + { + LOCK2(cs_main, cs_wallet); + // txdb must be opened before the mapWallet lock + CTxDB txdb("r"); + { + nFeeRet = nTransactionFee; + while (true) + { + wtxNew.vin.clear(); + wtxNew.vout.clear(); + wtxNew.fFromMe = true; + + int64_t nTotalValue = nValue + nFeeRet; + double dPriority = 0; + // vouts to the payees + BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend) + wtxNew.vout.push_back(CTxOut(s.second, s.first)); + + // Choose coins to use + set > setCoins; + int64_t nValueIn = 0; + if (!SelectCoins(nTotalValue, wtxNew.nTime, setCoins, nValueIn, coinControl)) + { + if(coin_type == ALL_COINS) { + strFailReason = _("Insufficient funds."); + if (fMasternodeSoftLock) { + strFailReason += _("Masternode soft lock is active, some funds may have been excluded to protect masternode collaterals."); + //QMessageBox msg; + //msg.setText("Masternode SoftLock is active and your transaction was blocked to protect your Masternode. May you are sending more coins than in your balance available - excluding the masternode collaterals address."); + //msg.exec(); + + } + } else if (coin_type == ONLY_NONDENOMINATED) { + strFailReason = _("Unable to locate enough Darksend non-denominated funds for this transaction."); + } else if (coin_type == ONLY_NONDENOMINATED_NOTMN) { + strFailReason = _("Unable to locate enough Darksend non-denominated funds for this transaction that are not equal 1000 phantomx."); + } else { + strFailReason = _("Unable to locate enough Darksend denominated funds for this transaction."); + strFailReason += _("Darksend uses exact denominated amounts to send funds, you might simply need to anonymize some more coins."); + } + + if(useIX){ + strFailReason += _("InstantX requires inputs with at least 6 confirmations, you might need to wait a few minutes and try again."); + } + return false; + } + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + int64_t nCredit = pcoin.first->vout[pcoin.second].nValue; + dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain(); + } + + int64_t nChange = nValueIn - nValue - nFeeRet; + + if (nChange > 0) + { + // Fill a vout to ourself + // TODO: pass in scriptChange instead of reservekey so + // change transaction isn't always pay-to-bitcoin-address + CScript scriptChange; + + // coin control: send change to custom address + if (coinControl && !boost::get(&coinControl->destChange)) + scriptChange.SetDestination(coinControl->destChange); + + // no coin control: send change to newly generated address + else + { + // Note: We use a new key here to keep it from being obvious which side is the change. + // The drawback is that by not reusing a previous key, the change may be lost if a + // backup is restored, if the backup doesn't have the new private key for the change. + // If we reused the old key, it would be possible to add code to look for and + // rediscover unknown transactions that were written with keys of ours to recover + // post-backup change. + + // Reserve a new key pair from key pool + CPubKey vchPubKey; + assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + + scriptChange.SetDestination(vchPubKey.GetID()); + } + + // Insert change txn at random position: + vector::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()); + + // -- don't put change output between value and narration outputs + if (position > wtxNew.vout.begin() && position < wtxNew.vout.end()) + { + while (position > wtxNew.vout.begin()) + { + if (position->nValue != 0) + break; + position--; + }; + }; + + wtxNew.vout.insert(position, CTxOut(nChange, scriptChange)); + nChangePos = std::distance(wtxNew.vout.begin(), position); + } + else + reservekey.ReturnKey(); + + // Fill vin + BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) + wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second)); + + // Sign + int nIn = 0; + BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) + if (!SignSignature(*this, *coin.first, wtxNew, nIn++)) + return false; + + // Limit size + unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION); + if (nBytes >= MAX_STANDARD_TX_SIZE) + return false; + dPriority /= nBytes; + + // Check that enough fee is included + int64_t nPayFee = nTransactionFee * (1 + (int64_t)nBytes / 1000); + int64_t nMinFee = GetMinFee(wtxNew, 1, GMF_SEND, nBytes); + + if (nFeeRet < max(nPayFee, nMinFee)) + { + nFeeRet = max(nPayFee, nMinFee); + continue; + } + + // Fill vtxPrev by copying from previous transactions vtxPrev + wtxNew.AddSupportingTransactions(txdb); + wtxNew.fTimeReceivedIsTxTime = true; + + break; + } + } + } + return true; +} + +bool CWallet::CreateTransaction(CScript scriptPubKey, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl* coinControl) +{ + vector< pair > vecSend; + vecSend.push_back(make_pair(scriptPubKey, nValue)); + + if (sNarr.length() > 0) + { + std::vector vNarr(sNarr.c_str(), sNarr.c_str() + sNarr.length()); + std::vector vNDesc; + + vNDesc.resize(2); + vNDesc[0] = 'n'; + vNDesc[1] = 'p'; + + CScript scriptN = CScript() << OP_RETURN << vNDesc << OP_RETURN << vNarr; + + vecSend.push_back(make_pair(scriptN, 0)); + } + + // -- CreateTransaction won't place change between value and narr output. + // narration output will be for preceding output + + int nChangePos; + std::string strFailReason; + bool rv = CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, nChangePos, strFailReason, coinControl); + + // -- narration will be added to mapValue later in FindStealthTransactions From CommitTransaction + return rv; +} + + +bool CWallet::NewStealthAddress(std::string& sError, std::string& sLabel, CStealthAddress& sxAddr) +{ + ec_secret scan_secret; + ec_secret spend_secret; + + if (GenerateRandomSecret(scan_secret) != 0 + || GenerateRandomSecret(spend_secret) != 0) + { + sError = "GenerateRandomSecret failed."; + printf("Error CWallet::NewStealthAddress - %s\n", sError.c_str()); + return false; + }; + + ec_point scan_pubkey, spend_pubkey; + if (SecretToPublicKey(scan_secret, scan_pubkey) != 0) + { + sError = "Could not get scan public key."; + printf("Error CWallet::NewStealthAddress - %s\n", sError.c_str()); + return false; + }; + + if (SecretToPublicKey(spend_secret, spend_pubkey) != 0) + { + sError = "Could not get spend public key."; + printf("Error CWallet::NewStealthAddress - %s\n", sError.c_str()); + return false; + }; + + if (fDebug) + { + printf("getnewstealthaddress: "); + printf("scan_pubkey "); + for (uint32_t i = 0; i < scan_pubkey.size(); ++i) + printf("%02x", scan_pubkey[i]); + printf("\n"); + + printf("spend_pubkey "); + for (uint32_t i = 0; i < spend_pubkey.size(); ++i) + printf("%02x", spend_pubkey[i]); + printf("\n"); + }; + + + sxAddr.label = sLabel; + sxAddr.scan_pubkey = scan_pubkey; + sxAddr.spend_pubkey = spend_pubkey; + + sxAddr.scan_secret.resize(32); + memcpy(&sxAddr.scan_secret[0], &scan_secret.e[0], 32); + sxAddr.spend_secret.resize(32); + memcpy(&sxAddr.spend_secret[0], &spend_secret.e[0], 32); + + return true; +} + +bool CWallet::AddStealthAddress(CStealthAddress& sxAddr) +{ + LOCK(cs_wallet); + + // must add before changing spend_secret + stealthAddresses.insert(sxAddr); + + bool fOwned = sxAddr.scan_secret.size() == ec_secret_size; + + + + if (fOwned) + { + // -- owned addresses can only be added when wallet is unlocked + if (IsLocked()) + { + printf("Error: CWallet::AddStealthAddress wallet must be unlocked.\n"); + stealthAddresses.erase(sxAddr); + return false; + }; + + if (IsCrypted()) + { + std::vector vchCryptedSecret; + CSecret vchSecret; + vchSecret.resize(32); + memcpy(&vchSecret[0], &sxAddr.spend_secret[0], 32); + + uint256 iv = Hash(sxAddr.spend_pubkey.begin(), sxAddr.spend_pubkey.end()); + if (!EncryptSecret(vMasterKey, vchSecret, iv, vchCryptedSecret)) + { + printf("Error: Failed encrypting stealth key %s\n", sxAddr.Encoded().c_str()); + stealthAddresses.erase(sxAddr); + return false; + }; + sxAddr.spend_secret = vchCryptedSecret; + }; + }; + + + bool rv = CWalletDB(strWalletFile).WriteStealthAddress(sxAddr); + + if (rv) + NotifyAddressBookChanged(this, sxAddr, sxAddr.label, fOwned, CT_NEW); + + return rv; +} + +bool CWallet::UnlockStealthAddresses(const CKeyingMaterial& vMasterKeyIn) +{ + // -- decrypt spend_secret of stealth addresses + std::set::iterator it; + for (it = stealthAddresses.begin(); it != stealthAddresses.end(); ++it) + { + if (it->scan_secret.size() < 32) + continue; // stealth address is not owned + + // -- CStealthAddress are only sorted on spend_pubkey + CStealthAddress &sxAddr = const_cast(*it); + + if (fDebug) + printf("Decrypting stealth key %s\n", sxAddr.Encoded().c_str()); + + CSecret vchSecret; + uint256 iv = Hash(sxAddr.spend_pubkey.begin(), sxAddr.spend_pubkey.end()); + if(!DecryptSecret(vMasterKeyIn, sxAddr.spend_secret, iv, vchSecret) + || vchSecret.size() != 32) + { + printf("Error: Failed decrypting stealth key %s\n", sxAddr.Encoded().c_str()); + continue; + }; + + ec_secret testSecret; + memcpy(&testSecret.e[0], &vchSecret[0], 32); + ec_point pkSpendTest; + + if (SecretToPublicKey(testSecret, pkSpendTest) != 0 + || pkSpendTest != sxAddr.spend_pubkey) + { + printf("Error: Failed decrypting stealth key, public key mismatch %s\n", sxAddr.Encoded().c_str()); + continue; + }; + + sxAddr.spend_secret.resize(32); + memcpy(&sxAddr.spend_secret[0], &vchSecret[0], 32); + }; + + CryptedKeyMap::iterator mi = mapCryptedKeys.begin(); + for (; mi != mapCryptedKeys.end(); ++mi) + { + CPubKey &pubKey = (*mi).second.first; + std::vector &vchCryptedSecret = (*mi).second.second; + if (vchCryptedSecret.size() != 0) + continue; + + CKeyID ckid = pubKey.GetID(); + CBitcoinAddress addr(ckid); + + StealthKeyMetaMap::iterator mi = mapStealthKeyMeta.find(ckid); + if (mi == mapStealthKeyMeta.end()) + { + printf("Error: No metadata found to add secret for %s\n", addr.ToString().c_str()); + continue; + }; + + CStealthKeyMetadata& sxKeyMeta = mi->second; + + CStealthAddress sxFind; + sxFind.scan_pubkey = sxKeyMeta.pkScan.Raw(); + + std::set::iterator si = stealthAddresses.find(sxFind); + if (si == stealthAddresses.end()) + { + printf("No stealth key found to add secret for %s\n", addr.ToString().c_str()); + continue; + }; + + if (fDebug) + printf("Expanding secret for %s\n", addr.ToString().c_str()); + + ec_secret sSpendR; + ec_secret sSpend; + ec_secret sScan; + + if (si->spend_secret.size() != ec_secret_size + || si->scan_secret.size() != ec_secret_size) + { + printf("Stealth address has no secret key for %s\n", addr.ToString().c_str()); + continue; + } + memcpy(&sScan.e[0], &si->scan_secret[0], ec_secret_size); + memcpy(&sSpend.e[0], &si->spend_secret[0], ec_secret_size); + + ec_point pkEphem = sxKeyMeta.pkEphem.Raw(); + if (StealthSecretSpend(sScan, pkEphem, sSpend, sSpendR) != 0) + { + printf("StealthSecretSpend() failed.\n"); + continue; + }; + + ec_point pkTestSpendR; + if (SecretToPublicKey(sSpendR, pkTestSpendR) != 0) + { + printf("SecretToPublicKey() failed.\n"); + continue; + }; + + CSecret vchSecret; + vchSecret.resize(ec_secret_size); + + memcpy(&vchSecret[0], &sSpendR.e[0], ec_secret_size); + CKey ckey; + + try { + ckey.Set(vchSecret.begin(), vchSecret.end(), true); + //ckey.SetSecret(vchSecret, true); + } catch (std::exception& e) { + printf("ckey.SetSecret() threw: %s.\n", e.what()); + continue; + }; + + CPubKey cpkT = ckey.GetPubKey(); + + if (!cpkT.IsValid()) + { + printf("cpkT is invalid.\n"); + continue; + }; + + if (cpkT != pubKey) + { + printf("Error: Generated secret does not match.\n"); + continue; + }; + + if (!ckey.IsValid()) + { + printf("Reconstructed key is invalid.\n"); + continue; + }; + + if (fDebug) + { + CKeyID keyID = cpkT.GetID(); + CBitcoinAddress coinAddress(keyID); + printf("Adding secret to key %s.\n", coinAddress.ToString().c_str()); + }; + + if (!AddKey(ckey)) + { + printf("AddKey failed.\n"); + continue; + }; + + if (!CWalletDB(strWalletFile).EraseStealthKeyMeta(ckid)) + printf("EraseStealthKeyMeta failed for %s\n", addr.ToString().c_str()); + }; + return true; +} + +bool CWallet::UpdateStealthAddress(std::string &addr, std::string &label, bool addIfNotExist) +{ + if (fDebug) + printf("UpdateStealthAddress %s\n", addr.c_str()); + + + CStealthAddress sxAddr; + + if (!sxAddr.SetEncoded(addr)) + return false; + + std::set::iterator it; + it = stealthAddresses.find(sxAddr); + + ChangeType nMode = CT_UPDATED; + CStealthAddress sxFound; + if (it == stealthAddresses.end()) + { + if (addIfNotExist) + { + sxFound = sxAddr; + sxFound.label = label; + stealthAddresses.insert(sxFound); + nMode = CT_NEW; + } else + { + printf("UpdateStealthAddress %s, not in set\n", addr.c_str()); + return false; + }; + } else + { + sxFound = const_cast(*it); + + if (sxFound.label == label) + { + // no change + return true; + }; + + it->label = label; // update in .stealthAddresses + + if (sxFound.scan_secret.size() == ec_secret_size) + { + printf("UpdateStealthAddress: todo - update owned stealth address.\n"); + return false; + }; + }; + + sxFound.label = label; + + if (!CWalletDB(strWalletFile).WriteStealthAddress(sxFound)) + { + printf("UpdateStealthAddress(%s) Write to db failed.\n", addr.c_str()); + return false; + }; + + bool fOwned = sxFound.scan_secret.size() == ec_secret_size; + NotifyAddressBookChanged(this, sxFound, sxFound.label, fOwned, nMode); + + return true; +} + +bool CWallet::CreateStealthTransaction(CScript scriptPubKey, int64_t nValue, std::vector& P, std::vector& narr, std::string& sNarr, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl* coinControl) +{ + vector< pair > vecSend; + vecSend.push_back(make_pair(scriptPubKey, nValue)); + + CScript scriptP = CScript() << OP_RETURN << P; + if (narr.size() > 0) + scriptP = scriptP << OP_RETURN << narr; + + vecSend.push_back(make_pair(scriptP, 1)); + + // -- shuffle inputs, change output won't mix enough as it must be not fully random for plantext narrations + std::random_shuffle(vecSend.begin(), vecSend.end()); + + int nChangePos; + std::string strFailReason; + bool rv = CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, nChangePos, strFailReason, coinControl); + + // -- the change txn is inserted in a random pos, check here to match narr to output + if (rv && narr.size() > 0) + { + for (unsigned int k = 0; k < wtxNew.vout.size(); ++k) + { + if (wtxNew.vout[k].scriptPubKey != scriptPubKey + || wtxNew.vout[k].nValue != nValue) + continue; + + char key[64]; + if (snprintf(key, sizeof(key), "n_%u", k) < 1) + { + printf("CreateStealthTransaction(): Error creating narration key."); + break; + }; + wtxNew.mapValue[key] = sNarr; + break; + }; + }; + + return rv; +} + +string CWallet::SendStealthMoney(CScript scriptPubKey, int64_t nValue, std::vector& P, std::vector& narr, std::string& sNarr, CWalletTx& wtxNew, bool fAskFee) +{ + CReserveKey reservekey(this); + int64_t nFeeRequired; + + if (IsLocked()) + { + string strError = _("Error: Wallet locked, unable to create transaction "); + printf("SendStealthMoney() : %s", strError.c_str()); + return strError; + } + if (fWalletUnlockStakingOnly) + { + string strError = _("Error: Wallet unlocked for staking only, unable to create transaction."); + printf("SendStealthMoney() : %s", strError.c_str()); + return strError; + } + if (!CreateStealthTransaction(scriptPubKey, nValue, P, narr, sNarr, wtxNew, reservekey, nFeeRequired)) + { + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str()); + else + strError = _("Error: Transaction creation failed "); + printf("SendStealthMoney() : %s", strError.c_str()); + return strError; + } + + if (fAskFee && !uiInterface.ThreadSafeAskFee(nFeeRequired, _("Sending..."))) + return "ABORTED"; + + if (!CommitTransaction(wtxNew, reservekey)) + return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); + + return ""; +} + +bool CWallet::SendStealthMoneyToDestination(CStealthAddress& sxAddress, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, std::string& sError, bool fAskFee) +{ + // -- Check amount + if (nValue <= 0) + { + sError = "Invalid amount"; + return false; + }; + if (nValue + nTransactionFee + (1) > GetBalance()) + { + sError = "Insufficient funds"; + return false; + }; + + + ec_secret ephem_secret; + ec_secret secretShared; + ec_point pkSendTo; + ec_point ephem_pubkey; + + if (GenerateRandomSecret(ephem_secret) != 0) + { + sError = "GenerateRandomSecret failed."; + return false; + }; + + if (StealthSecret(ephem_secret, sxAddress.scan_pubkey, sxAddress.spend_pubkey, secretShared, pkSendTo) != 0) + { + sError = "Could not generate receiving public key."; + return false; + }; + + CPubKey cpkTo(pkSendTo); + if (!cpkTo.IsValid()) + { + sError = "Invalid public key generated."; + return false; + }; + + CKeyID ckidTo = cpkTo.GetID(); + + CBitcoinAddress addrTo(ckidTo); + + if (SecretToPublicKey(ephem_secret, ephem_pubkey) != 0) + { + sError = "Could not generate ephem public key."; + return false; + }; + + if (fDebug) + { + printf("Stealth send to generated pubkey %" PRIszu ": %s\n", pkSendTo.size(), HexStr(pkSendTo).c_str()); + printf("hash %s\n", addrTo.ToString().c_str()); + printf("ephem_pubkey %" PRIszu ": %s\n", ephem_pubkey.size(), HexStr(ephem_pubkey).c_str()); + }; + + std::vector vchNarr; + if (sNarr.length() > 0) + { + SecMsgCrypter crypter; + crypter.SetKey(&secretShared.e[0], &ephem_pubkey[0]); + + if (!crypter.Encrypt((uint8_t*)&sNarr[0], sNarr.length(), vchNarr)) + { + sError = "Narration encryption failed."; + return false; + }; + + if (vchNarr.size() > 48) + { + sError = "Encrypted narration is too long."; + return false; + }; + }; + + // -- Parse Bitcoin address + CScript scriptPubKey; + scriptPubKey.SetDestination(addrTo.Get()); + + if ((sError = SendStealthMoney(scriptPubKey, nValue, ephem_pubkey, vchNarr, sNarr, wtxNew, fAskFee)) != "") + return false; + + + return true; +} + +bool CWallet::FindStealthTransactions(const CTransaction& tx, mapValue_t& mapNarr) +{ + if (fDebug) + LogPrintf("FindStealthTransactions() tx: %s\n", tx.GetHash().GetHex().c_str()); + + mapNarr.clear(); + + LOCK(cs_wallet); + ec_secret sSpendR; + ec_secret sSpend; + ec_secret sScan; + ec_secret sShared; + + ec_point pkExtracted; + + std::vector vchEphemPK; + std::vector vchDataB; + std::vector vchENarr; + opcodetype opCode; + char cbuf[256]; + + int32_t nOutputIdOuter = -1; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nOutputIdOuter++; + // -- for each OP_RETURN need to check all other valid outputs + + //printf("txout scriptPubKey %s\n", txout.scriptPubKey.ToString().c_str()); + CScript::const_iterator itTxA = txout.scriptPubKey.begin(); + + if (!txout.scriptPubKey.GetOp(itTxA, opCode, vchEphemPK) + || opCode != OP_RETURN) + continue; + else + if (!txout.scriptPubKey.GetOp(itTxA, opCode, vchEphemPK) + || vchEphemPK.size() != 33) + { + // -- look for plaintext narrations + if (vchEphemPK.size() > 1 + && vchEphemPK[0] == 'n' + && vchEphemPK[1] == 'p') + { + if (txout.scriptPubKey.GetOp(itTxA, opCode, vchENarr) + && opCode == OP_RETURN + && txout.scriptPubKey.GetOp(itTxA, opCode, vchENarr) + && vchENarr.size() > 0) + { + std::string sNarr = std::string(vchENarr.begin(), vchENarr.end()); + + snprintf(cbuf, sizeof(cbuf), "n_%d", nOutputIdOuter-1); // plaintext narration always matches preceding value output + mapNarr[cbuf] = sNarr; + } else + { + printf("Warning: FindStealthTransactions() tx: %s, Could not extract plaintext narration.\n", tx.GetHash().GetHex().c_str()); + }; + } + + continue; + } + + int32_t nOutputId = -1; + nStealth++; + BOOST_FOREACH(const CTxOut& txoutB, tx.vout) + { + nOutputId++; + + if (&txoutB == &txout) + continue; + + bool txnMatch = false; // only 1 txn will match an ephem pk + //printf("txoutB scriptPubKey %s\n", txoutB.scriptPubKey.ToString().c_str()); + + CTxDestination address; + if (!ExtractDestination(txoutB.scriptPubKey, address)) + continue; + + if (address.type() != typeid(CKeyID)) + continue; + + CKeyID ckidMatch = boost::get(address); + + if (HaveKey(ckidMatch)) // no point checking if already have key + continue; + + std::set::iterator it; + for (it = stealthAddresses.begin(); it != stealthAddresses.end(); ++it) + { + if (it->scan_secret.size() != ec_secret_size) + continue; // stealth address is not owned + + //printf("it->Encodeded() %s\n", it->Encoded().c_str()); + memcpy(&sScan.e[0], &it->scan_secret[0], ec_secret_size); + + if (StealthSecret(sScan, vchEphemPK, it->spend_pubkey, sShared, pkExtracted) != 0) + { + printf("StealthSecret failed.\n"); + continue; + }; + //printf("pkExtracted %"PRIszu": %s\n", pkExtracted.size(), HexStr(pkExtracted).c_str()); + + CPubKey cpkE(pkExtracted); + + if (!cpkE.IsValid()) + continue; + CKeyID ckidE = cpkE.GetID(); + + if (ckidMatch != ckidE) + continue; + + if (fDebug) + printf("Found stealth txn to address %s\n", it->Encoded().c_str()); + + if (IsLocked()) + { + if (fDebug) + printf("Wallet is locked, adding key without secret.\n"); + + // -- add key without secret + std::vector vchEmpty; + AddCryptedKey(cpkE, vchEmpty); + CKeyID keyId = cpkE.GetID(); + CBitcoinAddress coinAddress(keyId); + std::string sLabel = it->Encoded(); + SetAddressBookName(keyId, sLabel); + + CPubKey cpkEphem(vchEphemPK); + CPubKey cpkScan(it->scan_pubkey); + CStealthKeyMetadata lockedSkMeta(cpkEphem, cpkScan); + + if (!CWalletDB(strWalletFile).WriteStealthKeyMeta(keyId, lockedSkMeta)) + printf("WriteStealthKeyMeta failed for %s\n", coinAddress.ToString().c_str()); + + mapStealthKeyMeta[keyId] = lockedSkMeta; + nFoundStealth++; + } else + { + if (it->spend_secret.size() != ec_secret_size) + continue; + memcpy(&sSpend.e[0], &it->spend_secret[0], ec_secret_size); + + + if (StealthSharedToSecretSpend(sShared, sSpend, sSpendR) != 0) + { + printf("StealthSharedToSecretSpend() failed.\n"); + continue; + }; + + ec_point pkTestSpendR; + if (SecretToPublicKey(sSpendR, pkTestSpendR) != 0) + { + printf("SecretToPublicKey() failed.\n"); + continue; + }; + + CSecret vchSecret; + vchSecret.resize(ec_secret_size); + + memcpy(&vchSecret[0], &sSpendR.e[0], ec_secret_size); + CKey ckey; + + try { + ckey.Set(vchSecret.begin(), vchSecret.end(), true); + //ckey.SetSecret(vchSecret, true); + } catch (std::exception& e) { + printf("ckey.SetSecret() threw: %s.\n", e.what()); + continue; + }; + + CPubKey cpkT = ckey.GetPubKey(); + if (!cpkT.IsValid()) + { + printf("cpkT is invalid.\n"); + continue; + }; + + if (!ckey.IsValid()) + { + printf("Reconstructed key is invalid.\n"); + continue; + }; + + CKeyID keyID = cpkT.GetID(); + if (fDebug) + { + CBitcoinAddress coinAddress(keyID); + printf("Adding key %s.\n", coinAddress.ToString().c_str()); + }; + + if (!AddKey(ckey)) + { + printf("AddKey failed.\n"); + continue; + }; + + std::string sLabel = it->Encoded(); + SetAddressBookName(keyID, sLabel); + nFoundStealth++; + }; + + if (txout.scriptPubKey.GetOp(itTxA, opCode, vchENarr) + && opCode == OP_RETURN + && txout.scriptPubKey.GetOp(itTxA, opCode, vchENarr) + && vchENarr.size() > 0) + { + SecMsgCrypter crypter; + crypter.SetKey(&sShared.e[0], &vchEphemPK[0]); + std::vector vchNarr; + if (!crypter.Decrypt(&vchENarr[0], vchENarr.size(), vchNarr)) + { + printf("Decrypt narration failed.\n"); + continue; + }; + std::string sNarr = std::string(vchNarr.begin(), vchNarr.end()); + + snprintf(cbuf, sizeof(cbuf), "n_%d", nOutputId); + mapNarr[cbuf] = sNarr; + }; + + txnMatch = true; + break; + }; + if (txnMatch) + break; + }; + }; + + return true; +}; + + + + +uint64_t CWallet::GetStakeWeight() const +{ + // Choose coins to use + int64_t nBalance = GetBalance(); + + if (nBalance <= nReserveBalance) + return 0; + + vector vwtxPrev; + + set > setCoins; + int64_t nValueIn = 0; + + if (!SelectCoinsForStaking(nBalance - nReserveBalance, GetTime(), setCoins, nValueIn)) + return 0; + + if (setCoins.empty()) + return 0; + + uint64_t nWeight = 0; + + int64_t nCurrentTime = GetTime(); + CTxDB txdb("r"); + + LOCK2(cs_main, cs_wallet); + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + CTxIndex txindex; + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + + if (nCurrentTime - pcoin.first->nTime > nStakeMinAge) + nWeight += pcoin.first->vout[pcoin.second].nValue; + } + + return nWeight; +} + +bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64_t nSearchInterval, int64_t nFees, CTransaction& txNew, CKey& key) +{ + CBlockIndex* pindexPrev = pindexBest; + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(nBits); + + txNew.vin.clear(); + txNew.vout.clear(); + + // Mark coin stake transaction + CScript scriptEmpty; + scriptEmpty.clear(); + txNew.vout.push_back(CTxOut(0, scriptEmpty)); + + // Choose coins to use + int64_t nBalance = GetBalance(); + + if (nBalance <= nReserveBalance) + return false; + + vector vwtxPrev; + + set > setCoins; + int64_t nValueIn = 0; + + // Select coins with suitable depth + if (!SelectCoinsForStaking(nBalance - nReserveBalance, txNew.nTime, setCoins, nValueIn)) + return false; + + if (setCoins.empty()) + return false; + + int64_t nCredit = 0; + CScript scriptPubKeyKernel; + CTxDB txdb("r"); + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + static int nMaxStakeSearchInterval = 60; + bool fKernelFound = false; + for (unsigned int n=0; nGetHash(), pcoin.second); + int64_t nBlockTime; + if (CheckKernel(pindexPrev, nBits, txNew.nTime - n, prevoutStake, &nBlockTime)) + { + // Found a kernel + LogPrint("coinstake", "CreateCoinStake : kernel found\n"); + vector vSolutions; + txnouttype whichType; + CScript scriptPubKeyOut; + scriptPubKeyKernel = pcoin.first->vout[pcoin.second].scriptPubKey; + if (!Solver(scriptPubKeyKernel, whichType, vSolutions)) + { + LogPrint("coinstake", "CreateCoinStake : failed to parse kernel\n"); + break; + } + LogPrint("coinstake", "CreateCoinStake : parsed kernel type=%d\n", whichType); + if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH) + { + LogPrint("coinstake", "CreateCoinStake : no support for kernel type=%d\n", whichType); + break; // only support pay to public key and pay to address + } + if (whichType == TX_PUBKEYHASH) // pay to address type + { + // convert to pay to public key type + if (!keystore.GetKey(uint160(vSolutions[0]), key)) + { + LogPrint("coinstake", "CreateCoinStake : failed to get key for kernel type=%d\n", whichType); + break; // unable to find corresponding public key + } + scriptPubKeyOut << key.GetPubKey() << OP_CHECKSIG; + } + if (whichType == TX_PUBKEY) + { + valtype& vchPubKey = vSolutions[0]; + if (!keystore.GetKey(Hash160(vchPubKey), key)) + { + LogPrint("coinstake", "CreateCoinStake : failed to get key for kernel type=%d\n", whichType); + break; // unable to find corresponding public key + } + + if (key.GetPubKey() != vchPubKey) + { + LogPrint("coinstake", "CreateCoinStake : invalid key for kernel type=%d\n", whichType); + break; // keys mismatch + } + + scriptPubKeyOut = scriptPubKeyKernel; + } + + txNew.nTime -= n; + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); + nCredit += pcoin.first->vout[pcoin.second].nValue; + vwtxPrev.push_back(pcoin.first); + txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); + + if(nCredit > 100 * COIN) + txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); //split stake + LogPrint("coinstake", "CreateCoinStake : added kernel type=%d\n", whichType); + fKernelFound = true; + break; + } + } + + if (fKernelFound) + break; // if kernel is found stop searching + } + + if (nCredit == 0 || nCredit > nBalance - nReserveBalance) + return false; + + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + // Attempt to add more inputs + // Only add coins of the same key/address as kernel + if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey)) + && pcoin.first->GetHash() != txNew.vin[0].prevout.hash) + { + int64_t nTimeWeight = GetWeight((int64_t)pcoin.first->nTime, (int64_t)txNew.nTime); + + // Stop adding more inputs if already too many inputs + if (txNew.vin.size() >= 100) + break; + // Stop adding more inputs if value is already pretty significant + if (nCredit >= GetStakeCombineThreshold()) + break; + // Stop adding inputs if reached reserve limit + if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance) + break; + // Do not add additional significant input + if (pcoin.first->vout[pcoin.second].nValue >= GetStakeCombineThreshold()) + continue; + // Do not add input that is still too young + if (nTimeWeight < nStakeMinAge) + continue; + + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); + nCredit += pcoin.first->vout[pcoin.second].nValue; + vwtxPrev.push_back(pcoin.first); + } + } + + // Calculate coin age reward + int64_t nReward; + { + uint64_t nCoinAge; + CTxDB txdb("r"); + if (!txNew.GetCoinAge(txdb, nCoinAge)) + return error("CreateCoinStake : failed to calculate coin age"); + + nReward = GetProofOfStakeReward(pindexPrev->nHeight + 1, nCoinAge, nFees); + if (nReward <= 0) + return false; + + nCredit += nReward; + } + + + // Masternode Payments + int payments = 1; + // start masternode payments + bool bMasterNodePayment = true; // note was false, set true to test + + if ( Params().NetworkID() == CChainParams::TESTNET ){ + if (GetTime() > START_MASTERNODE_PAYMENTS_TESTNET ){ + bMasterNodePayment = true; + } + }else{ + if (GetTime() > START_MASTERNODE_PAYMENTS){ + bMasterNodePayment = true; + } + } + + CScript payee; + bool hasPayment = true; + if(bMasterNodePayment) { + //spork + if(!masternodePayments.GetBlockPayee(pindexPrev->nHeight+1, payee)){ + int winningNode = GetCurrentMasterNode(1); + if(winningNode >= 0){ + payee =GetScriptForDestination(vecMasternodes[winningNode].pubkey.GetID()); + } else { + LogPrintf("CreateCoinStake: Failed to detect masternode to pay\n"); + hasPayment = false; + } + } + } + + if(hasPayment){ + payments = txNew.vout.size() + 1; + txNew.vout.resize(payments); + + txNew.vout[payments-1].scriptPubKey = payee; + txNew.vout[payments-1].nValue = 0; + + CTxDestination address1; + ExtractDestination(payee, address1); + CBitcoinAddress address2(address1); + + LogPrintf("Masternode payment to %s\n", address2.ToString().c_str()); + } + + int64_t blockValue = nCredit; + int64_t masternodePayment = GetMasternodePayment(pindexPrev->nHeight+1, nReward); + + + // Set output amount + if (!hasPayment && txNew.vout.size() == 3) // 2 stake outputs, stake was split, no masternode payment + { + txNew.vout[1].nValue = (blockValue / 2 / CENT) * CENT; + txNew.vout[2].nValue = blockValue - txNew.vout[1].nValue; + } + else if(hasPayment && txNew.vout.size() == 4) // 2 stake outputs, stake was split, plus a masternode payment + { + txNew.vout[payments-1].nValue = masternodePayment; + blockValue -= masternodePayment; + txNew.vout[1].nValue = (blockValue / 2 / CENT) * CENT; + txNew.vout[2].nValue = blockValue - txNew.vout[1].nValue; + } + else if(!hasPayment && txNew.vout.size() == 2) // only 1 stake output, was not split, no masternode payment + txNew.vout[1].nValue = blockValue; + else if(hasPayment && txNew.vout.size() == 3) // only 1 stake output, was not split, plus a masternode payment + { + txNew.vout[payments-1].nValue = masternodePayment; + blockValue -= masternodePayment; + txNew.vout[1].nValue = blockValue; + } + + // Sign + int nIn = 0; + BOOST_FOREACH(const CWalletTx* pcoin, vwtxPrev) + { + if (!SignSignature(*this, *pcoin, txNew, nIn++)) + return error("CreateCoinStake : failed to sign coinstake"); + } + + // Limit size + unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); + if (nBytes >= MAX_BLOCK_SIZE_GEN/5) + return error("CreateCoinStake : exceeded coinstake size limit"); + + // Successfully generated coinstake + return true; +} + + +// Call after CreateTransaction unless you want to abort +bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) +{ + mapValue_t mapNarr; + FindStealthTransactions(wtxNew, mapNarr); + + if (!mapNarr.empty()) + { + BOOST_FOREACH(const PAIRTYPE(string,string)& item, mapNarr) + wtxNew.mapValue[item.first] = item.second; + }; + + { + LOCK2(cs_main, cs_wallet); + LogPrintf("CommitTransaction:\n%s", wtxNew.ToString()); + { + // This is only to keep the database open to defeat the auto-flush for the + // duration of this scope. This is the only place where this optimization + // maybe makes sense; please don't do it anywhere else. + CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL; + + // Take key pair from key pool so it won't be used again + reservekey.KeepKey(); + + // Add tx to wallet, because if it has change it's also ours, + // otherwise just for transaction history. + AddToWallet(wtxNew); + + // Mark old coins as spent + set setCoins; + BOOST_FOREACH(const CTxIn& txin, wtxNew.vin) + { + CWalletTx &coin = mapWallet[txin.prevout.hash]; + coin.BindWallet(this); + coin.MarkSpent(txin.prevout.n); + coin.WriteToDisk(); + NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED); + } + + if (fFileBacked) + delete pwalletdb; + } + + // Track how many getdata requests our transaction gets + mapRequestCount[wtxNew.GetHash()] = 0; + + // Broadcast + if (!wtxNew.AcceptToMemoryPool(true)) + { + // This must not fail. The transaction has already been signed and recorded. + LogPrintf("CommitTransaction() : Error: Transaction not valid\n"); + return false; + } + wtxNew.RelayWalletTransaction(); + } + return true; +} + + + + +string CWallet::SendMoney(CScript scriptPubKey, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, bool fAskFee) +{ + CReserveKey reservekey(this); + int64_t nFeeRequired; + + if (IsLocked()) + { + string strError = _("Error: Wallet locked, unable to create transaction!"); + LogPrintf("SendMoney() : %s", strError); + return strError; + } + if (fWalletUnlockStakingOnly) + { + string strError = _("Error: Wallet unlocked for staking only, unable to create transaction."); + LogPrintf("SendMoney() : %s", strError); + return strError; + } + if (!CreateTransaction(scriptPubKey, nValue, sNarr, wtxNew, reservekey, nFeeRequired)) + { + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!"), FormatMoney(nFeeRequired)); + else + strError = _("Error: Transaction creation failed!"); + LogPrintf("SendMoney() : %s\n", strError); + return strError; + } + + if (fAskFee && !uiInterface.ThreadSafeAskFee(nFeeRequired, _("Sending..."))) + return "ABORTED"; + + if (!CommitTransaction(wtxNew, reservekey)) + return _("Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); + + return ""; +} + + + +string CWallet::SendMoneyToDestination(const CTxDestination& address, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, bool fAskFee) +{ + // Check amount + if (nValue <= 0) + return _("Invalid amount"); + if (nValue + nTransactionFee > GetBalance()) + return _("Insufficient funds"); + + if (sNarr.length() > 24) + return _("Narration must be 24 characters or less."); + + // Parse Bitcoin address + CScript scriptPubKey; + scriptPubKey.SetDestination(address); + + return SendMoney(scriptPubKey, nValue, sNarr, wtxNew, fAskFee); +} + + +string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds) +{ + if (IsLocked()) + return _("Error: Wallet locked, unable to create transaction!"); + + if(darkSendPool.GetState() != POOL_STATUS_ERROR && darkSendPool.GetState() != POOL_STATUS_SUCCESS) + if(darkSendPool.GetMyTransactionCount() > 0) + return _("Error: You already have pending entries in the Darksend pool"); + + // ** find the coins we'll use + std::vector vCoins; + std::vector vCoins2; + int64_t nValueIn = 0; + CReserveKey reservekey(this); + + /* + Select the coins we'll use + if minRounds >= 0 it means only denominated inputs are going in and coming out + */ + if(minRounds >= 0){ + if (!SelectCoinsByDenominations(darkSendPool.sessionDenom, 0.1*COIN, DARKSEND_POOL_MAX, vCoins, vCoins2, nValueIn, minRounds, maxRounds)) + return _("Insufficient funds"); + } + + // calculate total value out + int64_t nTotalValue = GetTotalValue(vCoins); + LogPrintf("PrepareDarksendDenominate - preparing darksend denominate . Got: %d \n", nTotalValue); + + //-------------- + BOOST_FOREACH(CTxIn v, vCoins) + LockCoin(v.prevout); + + // denominate our funds + int64_t nValueLeft = nTotalValue; + std::vector vOut; + std::vector vDenoms; + + /* + TODO: Front load with needed denominations (e.g. .1, 1 ) + */ + + /* + Add all denominations once + The beginning of the list is front loaded with each possible + denomination in random order. This means we'll at least get 1 + of each that is required as outputs. + */ + BOOST_FOREACH(int64_t d, darkSendDenominations){ + vDenoms.push_back(d); + vDenoms.push_back(d); + } + + //randomize the order of these denominations + std::random_shuffle (vDenoms.begin(), vDenoms.end()); + + /* + Build a long list of denominations + Next we'll build a long random list of denominations to add. + Eventually as the algorithm goes through these it'll find the ones + it nees to get exact change. + */ + for(int i = 0; i <= 500; i++) + BOOST_FOREACH(int64_t d, darkSendDenominations) + vDenoms.push_back(d); + + //randomize the order of inputs we get back + std::random_shuffle (vDenoms.begin() + (int)darkSendDenominations.size() + 1, vDenoms.end()); + + // Make outputs by looping through denominations randomly + BOOST_REVERSE_FOREACH(int64_t v, vDenoms){ + //only use the ones that are approved + bool fAccepted = false; + if((darkSendPool.sessionDenom & (1 << 0)) && v == ((100000*COIN) +100000000)) {fAccepted = true;} + else if((darkSendPool.sessionDenom & (1 << 1)) && v == ((10000*COIN) +10000000)) {fAccepted = true;} + else if((darkSendPool.sessionDenom & (1 << 2)) && v == ((1000*COIN) +1000000)) {fAccepted = true;} + else if((darkSendPool.sessionDenom & (1 << 3)) && v == ((100*COIN) +100000)) {fAccepted = true;} + else if((darkSendPool.sessionDenom & (1 << 4)) && v == ((10*COIN) +10000)) {fAccepted = true;} + else if((darkSendPool.sessionDenom & (1 << 5)) && v == ((1*COIN) +1000)) {fAccepted = true;} + else if((darkSendPool.sessionDenom & (1 << 6)) && v == ((.1*COIN) +100)) {fAccepted = true;} + if(!fAccepted) continue; + + int nOutputs = 0; + + // add each output up to 10 times until it can't be added again + if(nValueLeft - v >= 0 && nOutputs <= 10) { + CScript scriptChange; + CPubKey vchPubKey; + //use a unique change address + assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + scriptChange =GetScriptForDestination(vchPubKey.GetID()); + reservekey.KeepKey(); + + CTxOut o(v, scriptChange); + vOut.push_back(o); + + //increment outputs and subtract denomination amount + nOutputs++; + nValueLeft -= v; + } + + if(nValueLeft == 0) break; + } + + //back up mode , incase we couldn't successfully make the outputs for some reason + if(vOut.size() > 40 || darkSendPool.GetDenominations(vOut) != darkSendPool.sessionDenom || nValueLeft != 0){ + vOut.clear(); + nValueLeft = nTotalValue; + + // Make outputs by looping through denominations, from small to large + + BOOST_FOREACH(const COutput& out, vCoins2){ + CScript scriptChange; + CPubKey vchPubKey; + //use a unique change address + assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked + scriptChange =GetScriptForDestination(vchPubKey.GetID()); + reservekey.KeepKey(); + + CTxOut o(out.tx->vout[out.i].nValue, scriptChange); + vOut.push_back(o); + + //increment outputs and subtract denomination amount + nValueLeft -= out.tx->vout[out.i].nValue; + + if(nValueLeft == 0) break; + } + + } + + if(darkSendPool.GetDenominations(vOut) != darkSendPool.sessionDenom) + return "Error: can't make current denominated outputs"; + + // we don't support change at all + if(nValueLeft != 0) + return "Error: change left-over in pool. Must use denominations only"; + + + //randomize the output order + std::random_shuffle (vOut.begin(), vOut.end()); + + darkSendPool.SendDarksendDenominate(vCoins, vOut, nValueIn); + + return ""; +} + +int64_t CWallet::GetTotalValue(std::vector vCoins) { + int64_t nTotalValue = 0; + CWalletTx wtx; + BOOST_FOREACH(CTxIn i, vCoins){ + if (mapWallet.count(i.prevout.hash)) + { + CWalletTx& wtx = mapWallet[i.prevout.hash]; + if(i.prevout.n < wtx.vout.size()){ + nTotalValue += wtx.vout[i.prevout.n].nValue; + } + } else { + LogPrintf("GetTotalValue -- Couldn't find transaction\n"); + } + } + return nTotalValue; +} + + +DBErrors CWallet::LoadWallet(bool& fFirstRunRet) +{ + if (!fFileBacked) + return DB_LOAD_OK; + fFirstRunRet = false; + DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this); + if (nLoadWalletRet == DB_NEED_REWRITE) + { + if (CDB::Rewrite(strWalletFile, "\x04pool")) + { + LOCK(cs_wallet); + setKeyPool.clear(); + // Note: can't top-up keypool here, because wallet is locked. + // User will be prompted to unlock wallet the next operation + // the requires a new key. + } + } + + if (nLoadWalletRet != DB_LOAD_OK) + return nLoadWalletRet; + fFirstRunRet = !vchDefaultKey.IsValid(); + + return DB_LOAD_OK; +} + + +bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName) +{ + bool fUpdated = false; + { + LOCK(cs_wallet); // mapAddressBook + std::map::iterator mi = mapAddressBook.find(address); + fUpdated = mi != mapAddressBook.end(); + mapAddressBook[address] = strName; + } + NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), + (fUpdated ? CT_UPDATED : CT_NEW) ); + if (!fFileBacked) + return false; + return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName); +} + +bool CWallet::DelAddressBookName(const CTxDestination& address) +{ + { + LOCK(cs_wallet); // mapAddressBook + + mapAddressBook.erase(address); + } + + NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED); + + if (!fFileBacked) + return false; + return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString()); +} + +bool CWallet::SetDefaultKey(const CPubKey &vchPubKey) +{ + if (fFileBacked) + { + if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey)) + return false; + } + vchDefaultKey = vchPubKey; + return true; +} + +// +// Mark old keypool keys as used, +// and generate all new keys +// +bool CWallet::NewKeyPool() +{ + { + LOCK(cs_wallet); + CWalletDB walletdb(strWalletFile); + BOOST_FOREACH(int64_t nIndex, setKeyPool) + walletdb.ErasePool(nIndex); + setKeyPool.clear(); + + if (IsLocked()) + return false; + + int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0); + for (int i = 0; i < nKeys; i++) + { + int64_t nIndex = i+1; + walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey())); + setKeyPool.insert(nIndex); + } + LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys); + } + return true; +} + +bool CWallet::TopUpKeyPool(unsigned int nSize) +{ + { + LOCK(cs_wallet); + + if (IsLocked()) + return false; + + CWalletDB walletdb(strWalletFile); + + // Top up key pool + unsigned int nTargetSize; + if (nSize > 0) + nTargetSize = nSize; + else + nTargetSize = max(GetArg("-keypool", 100), (int64_t)0); + + while (setKeyPool.size() < (nTargetSize + 1)) + { + int64_t nEnd = 1; + if (!setKeyPool.empty()) + nEnd = *(--setKeyPool.end()) + 1; + if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) + throw runtime_error("TopUpKeyPool() : writing generated key failed"); + setKeyPool.insert(nEnd); + LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size()); + } + } + return true; +} + +void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool) +{ + nIndex = -1; + keypool.vchPubKey = CPubKey(); + { + LOCK(cs_wallet); + + if (!IsLocked()) + TopUpKeyPool(); + + // Get the oldest key + if(setKeyPool.empty()) + return; + + CWalletDB walletdb(strWalletFile); + + nIndex = *(setKeyPool.begin()); + setKeyPool.erase(setKeyPool.begin()); + if (!walletdb.ReadPool(nIndex, keypool)) + throw runtime_error("ReserveKeyFromKeyPool() : read failed"); + if (!HaveKey(keypool.vchPubKey.GetID())) + throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); + assert(keypool.vchPubKey.IsValid()); + LogPrintf("keypool reserve %d\n", nIndex); + } +} + +int64_t CWallet::AddReserveKey(const CKeyPool& keypool) +{ + { + LOCK2(cs_main, cs_wallet); + CWalletDB walletdb(strWalletFile); + + int64_t nIndex = 1 + *(--setKeyPool.end()); + if (!walletdb.WritePool(nIndex, keypool)) + throw runtime_error("AddReserveKey() : writing added key failed"); + setKeyPool.insert(nIndex); + return nIndex; + } + return -1; +} + +void CWallet::KeepKey(int64_t nIndex) +{ + // Remove from key pool + if (fFileBacked) + { + CWalletDB walletdb(strWalletFile); + walletdb.ErasePool(nIndex); + } + LogPrintf("keypool keep %d\n", nIndex); +} + +void CWallet::ReturnKey(int64_t nIndex) +{ + // Return to key pool + { + LOCK(cs_wallet); + setKeyPool.insert(nIndex); + } + LogPrintf("keypool return %d\n", nIndex); +} + +bool CWallet::GetKeyFromPool(CPubKey& result) +{ + int64_t nIndex = 0; + CKeyPool keypool; + { + LOCK(cs_wallet); + ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) + { + if (IsLocked()) return false; + result = GenerateNewKey(); + return true; + } + KeepKey(nIndex); + result = keypool.vchPubKey; + } + return true; +} + +int64_t CWallet::GetOldestKeyPoolTime() +{ + int64_t nIndex = 0; + CKeyPool keypool; + ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) + return GetTime(); + ReturnKey(nIndex); + return keypool.nTime; +} + +std::map CWallet::GetAddressBalances() +{ + map balances; + + { + LOCK(cs_wallet); + BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet) + { + CWalletTx *pcoin = &walletEntry.second; + + if (!IsFinalTx(*pcoin) || !pcoin->IsTrusted()) + continue; + + if ((pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetBlocksToMaturity() > 0) + continue; + + int nDepth = pcoin->GetDepthInMainChain(); + if (nDepth < (pcoin->IsFromMe() ? 0 : 1)) + continue; + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) + { + CTxDestination addr; + if (!IsMine(pcoin->vout[i])) + continue; + if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr)) + continue; + + int64_t n = pcoin->IsSpent(i) ? 0 : pcoin->vout[i].nValue; + + if (!balances.count(addr)) + balances[addr] = 0; + balances[addr] += n; + } + } + } + + return balances; +} + +set< set > CWallet::GetAddressGroupings() +{ + AssertLockHeld(cs_wallet); // mapWallet + set< set > groupings; + set grouping; + + BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet) + { + CWalletTx *pcoin = &walletEntry.second; + + if (pcoin->vin.size() > 0 && IsMine(pcoin->vin[0])) + { + // group all input addresses with each other + BOOST_FOREACH(CTxIn txin, pcoin->vin) + { + CTxDestination address; + if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address)) + continue; + grouping.insert(address); + } + + // group change with input addresses + BOOST_FOREACH(CTxOut txout, pcoin->vout) + if (IsChange(txout)) + { + CWalletTx tx = mapWallet[pcoin->vin[0].prevout.hash]; + CTxDestination txoutAddr; + if(!ExtractDestination(txout.scriptPubKey, txoutAddr)) + continue; + grouping.insert(txoutAddr); + } + groupings.insert(grouping); + grouping.clear(); + } + + // group lone addrs by themselves + for (unsigned int i = 0; i < pcoin->vout.size(); i++) + if (IsMine(pcoin->vout[i])) + { + CTxDestination address; + if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address)) + continue; + grouping.insert(address); + groupings.insert(grouping); + grouping.clear(); + } + } + + set< set* > uniqueGroupings; // a set of pointers to groups of addresses + map< CTxDestination, set* > setmap; // map addresses to the unique group containing it + BOOST_FOREACH(set grouping, groupings) + { + // make a set of all the groups hit by this new group + set< set* > hits; + map< CTxDestination, set* >::iterator it; + BOOST_FOREACH(CTxDestination address, grouping) + if ((it = setmap.find(address)) != setmap.end()) + hits.insert((*it).second); + + // merge all hit groups into a new single group and delete old groups + set* merged = new set(grouping); + BOOST_FOREACH(set* hit, hits) + { + merged->insert(hit->begin(), hit->end()); + uniqueGroupings.erase(hit); + delete hit; + } + uniqueGroupings.insert(merged); + + // update setmap + BOOST_FOREACH(CTxDestination element, *merged) + setmap[element] = merged; + } + + set< set > ret; + BOOST_FOREACH(set* uniqueGrouping, uniqueGroupings) + { + ret.insert(*uniqueGrouping); + delete uniqueGrouping; + } + + return ret; +} + +// ppcoin: check 'spent' consistency between wallet and txindex +// ppcoin: fix wallet spent state according to txindex +void CWallet::FixSpentCoins(int& nMismatchFound, int64_t& nBalanceInQuestion, bool fCheckOnly) +{ + nMismatchFound = 0; + nBalanceInQuestion = 0; + + LOCK(cs_wallet); + vector vCoins; + vCoins.reserve(mapWallet.size()); + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + vCoins.push_back(&(*it).second); + + CTxDB txdb("r"); + BOOST_FOREACH(CWalletTx* pcoin, vCoins) + { + // Find the corresponding transaction index + CTxIndex txindex; + if (!txdb.ReadTxIndex(pcoin->GetHash(), txindex)) + continue; + for (unsigned int n=0; n < pcoin->vout.size(); n++) + { + if (IsMine(pcoin->vout[n]) && pcoin->IsSpent(n) && (txindex.vSpent.size() <= n || txindex.vSpent[n].IsNull())) + { + LogPrintf("FixSpentCoins found lost coin %s BC %s[%d], %s\n", + FormatMoney(pcoin->vout[n].nValue), pcoin->GetHash().ToString(), n, fCheckOnly? "repair not attempted" : "repairing"); + nMismatchFound++; + nBalanceInQuestion += pcoin->vout[n].nValue; + if (!fCheckOnly) + { + pcoin->MarkUnspent(n); + pcoin->WriteToDisk(); + } + } + else if (IsMine(pcoin->vout[n]) && !pcoin->IsSpent(n) && (txindex.vSpent.size() > n && !txindex.vSpent[n].IsNull())) + { + LogPrintf("FixSpentCoins found spent coin %s BC %s[%d], %s\n", + FormatMoney(pcoin->vout[n].nValue), pcoin->GetHash().ToString(), n, fCheckOnly? "repair not attempted" : "repairing"); + nMismatchFound++; + nBalanceInQuestion += pcoin->vout[n].nValue; + if (!fCheckOnly) + { + pcoin->MarkSpent(n); + pcoin->WriteToDisk(); + } + } + } + } +} + +// ppcoin: disable transaction (only for coinstake) +void CWallet::DisableTransaction(const CTransaction &tx) +{ + if (!tx.IsCoinStake() || !IsFromMe(tx)) + return; // only disconnecting coinstake requires marking input unspent + + LOCK(cs_wallet); + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + map::iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + CWalletTx& prev = (*mi).second; + if (txin.prevout.n < prev.vout.size() && IsMine(prev.vout[txin.prevout.n])) + { + prev.MarkUnspent(txin.prevout.n); + prev.WriteToDisk(); + } + } + } +} + +bool CReserveKey::GetReservedKey(CPubKey& pubkey) +{ + if (nIndex == -1) + { + CKeyPool keypool; + pwallet->ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex != -1) + vchPubKey = keypool.vchPubKey; + else { + if (pwallet->vchDefaultKey.IsValid()) { + LogPrintf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!"); + vchPubKey = pwallet->vchDefaultKey; + } else + return false; + } + } + assert(vchPubKey.IsValid()); + pubkey = vchPubKey; + return true; +} + +void CReserveKey::KeepKey() +{ + if (nIndex != -1) + pwallet->KeepKey(nIndex); + nIndex = -1; + vchPubKey = CPubKey(); +} + +void CReserveKey::ReturnKey() +{ + if (nIndex != -1) + pwallet->ReturnKey(nIndex); + nIndex = -1; + vchPubKey = CPubKey(); +} + +void CWallet::GetAllReserveKeys(set& setAddress) const +{ + setAddress.clear(); + + CWalletDB walletdb(strWalletFile); + + LOCK2(cs_main, cs_wallet); + BOOST_FOREACH(const int64_t& id, setKeyPool) + { + CKeyPool keypool; + if (!walletdb.ReadPool(id, keypool)) + throw runtime_error("GetAllReserveKeyHashes() : read failed"); + assert(keypool.vchPubKey.IsValid()); + CKeyID keyID = keypool.vchPubKey.GetID(); + if (!HaveKey(keyID)) + throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool"); + setAddress.insert(keyID); + } +} + +void CWallet::UpdatedTransaction(const uint256 &hashTx) +{ + { + LOCK(cs_wallet); + // Only notify UI if this transaction is in this wallet + map::const_iterator mi = mapWallet.find(hashTx); + if (mi != mapWallet.end()) + NotifyTransactionChanged(this, hashTx, CT_UPDATED); + } +} + + +void CWallet::LockCoin(COutPoint& output) +{ + AssertLockHeld(cs_wallet); // setLockedCoins + setLockedCoins.insert(output); +} + +void CWallet::UnlockCoin(COutPoint& output) +{ + AssertLockHeld(cs_wallet); // setLockedCoins + setLockedCoins.erase(output); +} + +void CWallet::UnlockAllCoins() +{ + AssertLockHeld(cs_wallet); // setLockedCoins + setLockedCoins.clear(); +} + +bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const +{ + AssertLockHeld(cs_wallet); // setLockedCoins + COutPoint outpt(hash, n); + + return (setLockedCoins.count(outpt) > 0); +} + +void CWallet::ListLockedCoins(std::vector& vOutpts) +{ + AssertLockHeld(cs_wallet); // setLockedCoins + for (std::set::iterator it = setLockedCoins.begin(); + it != setLockedCoins.end(); it++) { + COutPoint outpt = (*it); + vOutpts.push_back(outpt); + } +} + + +void CWallet::GetKeyBirthTimes(std::map &mapKeyBirth) const { + AssertLockHeld(cs_wallet); // mapKeyMetadata + mapKeyBirth.clear(); + + // get birth times for keys with metadata + for (std::map::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) + if (it->second.nCreateTime) + mapKeyBirth[it->first] = it->second.nCreateTime; + + // map in which we'll infer heights of other keys + CBlockIndex *pindexMax = FindBlockByHeight(std::max(0, nBestHeight - 144)); // the tip can be reorganised; use a 144-block safety margin + std::map mapKeyFirstBlock; + std::set setKeys; + GetKeys(setKeys); + BOOST_FOREACH(const CKeyID &keyid, setKeys) { + if (mapKeyBirth.count(keyid) == 0) + mapKeyFirstBlock[keyid] = pindexMax; + } + setKeys.clear(); + + // if there are no such keys, we're done + if (mapKeyFirstBlock.empty()) + return; + + // find first block that affects those keys, if there are any left + std::vector vAffected; + for (std::map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) { + // iterate over all wallet transactions... + const CWalletTx &wtx = (*it).second; + std::map::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); + if (blit != mapBlockIndex.end() && blit->second->IsInMainChain()) { + // ... which are already in a block + int nHeight = blit->second->nHeight; + BOOST_FOREACH(const CTxOut &txout, wtx.vout) { + // iterate over all their outputs + ::ExtractAffectedKeys(*this, txout.scriptPubKey, vAffected); + BOOST_FOREACH(const CKeyID &keyid, vAffected) { + // ... and all their affected keys + std::map::iterator rit = mapKeyFirstBlock.find(keyid); + if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight) + rit->second = blit->second; + } + vAffected.clear(); + } + } + } + + // Extract block timestamps for those keys + for (std::map::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++) + mapKeyBirth[it->first] = it->second->nTime - 7200; // block times can be 2h off +} + +bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx) +{ + { + LOCK(cs_wallet); + map::iterator mi = mapWallet.find(hashTx); + if (mi != mapWallet.end()) + { + wtx = (*mi).second; + return true; + } + } + return false; +} + +int CMerkleTx::GetTransactionLockSignatures() const +{ + if(!IsSporkActive(SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT)) return -3; + if(nInstantXDepth == 0) return -1; + + //compile consessus vote + std::map::iterator i = mapTxLocks.find(GetHash()); + if (i != mapTxLocks.end()){ + return (*i).second.CountSignatures(); + } + + return -1; +} + +bool CMerkleTx::IsTransactionLockTimedOut() const +{ + if(nInstantXDepth == 0) return 0; + + //compile consessus vote + std::map::iterator i = mapTxLocks.find(GetHash()); + if (i != mapTxLocks.end()){ + return GetTime() > (*i).second.nTimeout; + } + + return false; +} + +bool CWallet::AddAdrenalineNodeConfig(CAdrenalineNodeConfig nodeConfig) +{ + bool rv = CWalletDB(strWalletFile).WriteAdrenalineNodeConfig(nodeConfig.sAlias, nodeConfig); + if(rv) + uiInterface.NotifyAdrenalineNodeChanged(nodeConfig); + + return rv; +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/wallet.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/wallet.h new file mode 100644 index 0000000..0db3641 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/wallet.h @@ -0,0 +1,1014 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_WALLET_H +#define BITCOIN_WALLET_H + +#include "walletdb.h" + +#include +#include + +#include + +#include "crypter.h" +#include "main.h" +#include "key.h" +#include "keystore.h" +#include "script.h" +#include "ui_interface.h" +#include "util.h" +#include "stealth.h" + +// Settings +extern int64_t nTransactionFee; +extern int64_t nReserveBalance; +extern int64_t nMinimumInputValue; +extern bool fWalletUnlockStakingOnly; +extern bool fConfChange; + +class CAccountingEntry; +class CCoinControl; +class CWalletTx; +class CReserveKey; +class COutput; +class CWalletDB; + +typedef std::map StealthKeyMetaMap; +typedef std::map mapValue_t; + +/** (client) version numbers for particular wallet features */ +enum WalletFeature +{ + FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output) + + FEATURE_WALLETCRYPT = 40000, // wallet encryption + FEATURE_COMPRPUBKEY = 60000, // compressed public keys + + FEATURE_LATEST = 60000 +}; + +enum AvailableCoinsType +{ + ALL_COINS = 1, + ONLY_DENOMINATED = 2, + ONLY_NONDENOMINATED = 3, + ONLY_NONDENOMINATED_NOTMN = 4 // ONLY_NONDENOMINATED and not 20000 phantomx at the same time +}; + +/** IsMine() return codes */ +enum isminetype +{ + ISMINE_NO = 0, + ISMINE_WATCH_ONLY = 1, + ISMINE_SPENDABLE = 2, + ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE +}; + + +/** A key pool entry */ +class CKeyPool +{ +public: + int64_t nTime; + CPubKey vchPubKey; + + CKeyPool() + { + nTime = GetTime(); + } + + CKeyPool(const CPubKey& vchPubKeyIn) + { + nTime = GetTime(); + vchPubKey = vchPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(nTime); + READWRITE(vchPubKey); + ) +}; + +/** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, + * and provides the ability to create new transactions. + */ +class CWallet : public CCryptoKeyStore, public CWalletInterface +{ +private: + bool SelectCoinsForStaking(int64_t nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64_t& nValueRet) const; + //bool SelectCoins(int64_t nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64_t& nValueRet, const CCoinControl *coinControl=NULL) const; + bool SelectCoins(CAmount nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64_t& nValueRet, const CCoinControl *coinControl = NULL, AvailableCoinsType coin_type=ALL_COINS, bool useIX = false) const; + CWalletDB *pwalletdbEncryption; + + // the current wallet version: clients below this version are not able to load the wallet + int nWalletVersion; + + // the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded + int nWalletMaxVersion; + +public: + /// Main wallet lock. + /// This lock protects all the fields added by CWallet + /// except for: + /// fFileBacked (immutable after instantiation) + /// strWalletFile (immutable after instantiation) + mutable CCriticalSection cs_wallet; + + bool SelectCoinsDark(int64_t nValueMin, int64_t nValueMax, std::vector& setCoinsRet, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax) const; + bool SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t nValueMax, std::vector& setCoinsRet, vector& vCoins, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax); + bool SelectCoinsDarkDenominated(int64_t nTargetValue, std::vector& setCoinsRet, int64_t& nValueRet) const; + bool SelectCoinsMasternode(CTxIn& vin, int64_t& nValueRet, CScript& pubScript) const; + bool HasCollateralInputs() const; + bool IsCollateralAmount(int64_t nInputAmount) const; + int CountInputsWithAmount(int64_t nInputAmount); + + bool SelectCoinsCollateral(std::vector& setCoinsRet, int64_t& nValueRet) const ; + bool SelectCoinsWithoutDenomination(int64_t nTargetValue, std::set >& setCoinsRet, int64_t& nValueRet) const; + bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); + + bool fFileBacked; + bool fWalletUnlockAnonymizeOnly; + std::string strWalletFile; + + std::set setKeyPool; + std::map mapKeyMetadata; + + std::set stealthAddresses; + StealthKeyMetaMap mapStealthKeyMeta; + + int nLastFilteredHeight; + + uint32_t nStealth, nFoundStealth; // for reporting, zero before use + + + typedef std::map MasterKeyMap; + MasterKeyMap mapMasterKeys; + unsigned int nMasterKeyMaxID; + + std::map mapMyAdrenalineNodes; + bool AddAdrenalineNodeConfig(CAdrenalineNodeConfig nodeConfig); + + CWallet() + { + SetNull(); + } + CWallet(std::string strWalletFileIn) + { + SetNull(); + + strWalletFile = strWalletFileIn; + fFileBacked = true; + } + + void SetNull() + { + nWalletVersion = FEATURE_BASE; + nWalletMaxVersion = FEATURE_BASE; + fFileBacked = false; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; + nOrderPosNext = 0; + nTimeFirstKey = 0; + nLastFilteredHeight = 0; + fWalletUnlockAnonymizeOnly = false; + } + + std::map mapWallet; + int64_t nOrderPosNext; + std::map mapRequestCount; + + std::map mapAddressBook; + + CPubKey vchDefaultKey; + + std::set setLockedCoins; + + int64_t nTimeFirstKey; + + // check whether we are allowed to upgrade (or already support) to the named feature + bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } + + void AvailableCoinsForStaking(std::vector& vCoins, unsigned int nSpendTime) const; + void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL, AvailableCoinsType coin_type=ALL_COINS, bool useIX = false) const; + void AvailableCoinsMN(std::vector& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL, AvailableCoinsType coin_type=ALL_COINS, bool useIX = false) const; + bool SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, int64_t& nValueRet) const; + bool SelectCoinsMinConfByCoinAge(int64_t nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, int64_t& nValueRet) const; + + bool IsSpent(const uint256& hash, unsigned int n) const; + + bool IsLockedCoin(uint256 hash, unsigned int n) const; + void LockCoin(COutPoint& output); + void UnlockCoin(COutPoint& output); + void UnlockAllCoins(); + void ListLockedCoins(std::vector& vOutpts); + CAmount GetTotalValue(std::vector vCoins); + + // keystore implementation + // Generate a new key + CPubKey GenerateNewKey(); + // Adds a key to the store, and saves it to disk. + bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); + // Adds a key to the store, without saving it to disk (used by LoadWallet) + bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); } + // Load metadata (used by LoadWallet) + bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata); + + bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } + + // Adds an encrypted key to the store, and saves it to disk. + bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret); + // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) + bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret); + bool AddCScript(const CScript& redeemScript); + bool LoadCScript(const CScript& redeemScript); + + bool Lock(); + bool Unlock(const SecureString& strWalletPassphrase, bool anonimizeOnly = false); + bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); + bool EncryptWallet(const SecureString& strWalletPassphrase); + + void GetKeyBirthTimes(std::map &mapKeyBirth) const; + + + /** Increment the next transaction order id + @return next transaction order id + */ + int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL); + + typedef std::pair TxPair; + typedef std::multimap TxItems; + + /** Get the wallet's activity log + @return multimap of ordered transactions and accounting entries + @warning Returned pointers are *only* valid within the scope of passed acentries + */ + TxItems OrderedTxItems(std::list& acentries, std::string strAccount = ""); + + void MarkDirty(); + bool AddToWallet(const CWalletTx& wtxIn); + void SyncTransaction(const CTransaction& tx, const CBlock* pblock, bool fConnect = true); + bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate); + void EraseFromWallet(const uint256 &hash); + void WalletUpdateSpent(const CTransaction& prevout, bool fBlock = false); + int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); + void ReacceptWalletTransactions(); + void ResendWalletTransactions(bool fForce = false); + int64_t GetBalance() const; + int64_t GetBalanceNoLocks() const; + int64_t GetUnconfirmedBalance() const; + int64_t GetImmatureBalance() const; + int64_t GetStake() const; + int64_t GetNewMint() const; + + CAmount GetAnonymizedBalance() const; + double GetAverageAnonymizedRounds() const; + CAmount GetNormalizedAnonymizedBalance() const; + CAmount GetDenominatedBalance(bool onlyDenom=true, bool onlyUnconfirmed=false) const; + + bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, int32_t& nChangePos, std::string& strFailReason, const CCoinControl *coinControl=NULL, AvailableCoinsType coin_type=ALL_COINS, bool useIX=false); + bool CreateTransaction(CScript scriptPubKey, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl *coinControl=NULL); + bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); + + uint64_t GetStakeWeight() const; + bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64_t nSearchInterval, int64_t nFees, CTransaction& txNew, CKey& key); + + std::string SendMoney(CScript scriptPubKey, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, bool fAskFee=false); + std::string SendMoneyToDestination(const CTxDestination &address, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, bool fAskFee=false); + + bool NewStealthAddress(std::string& sError, std::string& sLabel, CStealthAddress& sxAddr); + bool AddStealthAddress(CStealthAddress& sxAddr); + bool UnlockStealthAddresses(const CKeyingMaterial& vMasterKeyIn); + bool UpdateStealthAddress(std::string &addr, std::string &label, bool addIfNotExist); + + bool CreateStealthTransaction(CScript scriptPubKey, int64_t nValue, std::vector& P, std::vector& narr, std::string& sNarr, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl* coinControl=NULL); + std::string SendStealthMoney(CScript scriptPubKey, int64_t nValue, std::vector& P, std::vector& narr, std::string& sNarr, CWalletTx& wtxNew, bool fAskFee=false); + bool SendStealthMoneyToDestination(CStealthAddress& sxAddress, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, std::string& sError, bool fAskFee=false); + bool FindStealthTransactions(const CTransaction& tx, mapValue_t& mapNarr); + + std::string PrepareDarksendDenominate(int minRounds, int maxRounds); + bool CreateCollateralTransaction(CTransaction& txCollateral, std::string strReason); + bool ConvertList(std::vector vCoins, std::vector& vecAmounts); + + bool NewKeyPool(); + bool TopUpKeyPool(unsigned int nSize = 0); + int64_t AddReserveKey(const CKeyPool& keypool); + void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool); + void KeepKey(int64_t nIndex); + void ReturnKey(int64_t nIndex); + bool GetKeyFromPool(CPubKey &key); + int64_t GetOldestKeyPoolTime(); + void GetAllReserveKeys(std::set& setAddress) const; + + std::set< std::set > GetAddressGroupings(); + std::map GetAddressBalances(); + + + bool IsDenominated(const CTxIn &txin) const; + + bool IsDenominated(const CTransaction& tx) const + { + /* + Return false if ANY inputs are non-denom + */ + bool ret = true; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + if(!IsDenominated(txin)) { + ret = false; + } + } + return ret; + } + + bool IsDenominatedAmount(int64_t nInputAmount) const; + + + bool IsMine(const CTxIn& txin) const; + int64_t GetDebit(const CTxIn& txin) const; + bool IsMine(const CTxOut& txout) const + { + return ::IsMine(*this, txout.scriptPubKey); + } + int64_t GetCredit(const CTxOut& txout) const + { + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetCredit() : value out of range"); + return (IsMine(txout) ? txout.nValue : 0); + } + bool IsChange(const CTxOut& txout) const; + int64_t GetChange(const CTxOut& txout) const + { + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetChange() : value out of range"); + return (IsChange(txout) ? txout.nValue : 0); + } + bool IsMine(const CTransaction& tx) const + { + BOOST_FOREACH(const CTxOut& txout, tx.vout) + if (IsMine(txout) && txout.nValue >= nMinimumInputValue) + return true; + return false; + } + bool IsFromMe(const CTransaction& tx) const + { + return (GetDebit(tx) > 0); + } + int64_t GetDebit(const CTransaction& tx) const + { + int64_t nDebit = 0; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + nDebit += GetDebit(txin); + if (!MoneyRange(nDebit)) + throw std::runtime_error("CWallet::GetDebit() : value out of range"); + } + return nDebit; + } + int64_t GetCredit(const CTransaction& tx) const + { + int64_t nCredit = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nCredit += GetCredit(txout); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWallet::GetCredit() : value out of range"); + } + return nCredit; + } + int64_t GetChange(const CTransaction& tx) const + { + int64_t nChange = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nChange += GetChange(txout); + if (!MoneyRange(nChange)) + throw std::runtime_error("CWallet::GetChange() : value out of range"); + } + return nChange; + } + void SetBestChain(const CBlockLocator& loc); + + DBErrors LoadWallet(bool& fFirstRunRet); + + bool SetAddressBookName(const CTxDestination& address, const std::string& strName); + + bool DelAddressBookName(const CTxDestination& address); + + void UpdatedTransaction(const uint256 &hashTx); + + void Inventory(const uint256 &hash) + { + { + LOCK(cs_wallet); + std::map::iterator mi = mapRequestCount.find(hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } + } + + unsigned int GetKeyPoolSize() + { + AssertLockHeld(cs_wallet); // setKeyPool + return setKeyPool.size(); + } + + bool SetDefaultKey(const CPubKey &vchPubKey); + + // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower + bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false); + + // change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format) + bool SetMaxVersion(int nVersion); + + // get the current wallet format (the oldest client version guaranteed to understand this wallet) + int GetVersion() { LOCK(cs_wallet); return nWalletVersion; } + + void FixSpentCoins(int& nMismatchSpent, int64_t& nBalanceInQuestion, bool fCheckOnly = false); + void DisableTransaction(const CTransaction &tx); + + /** Address book entry changed. + * @note called with lock cs_wallet held. + */ + boost::signals2::signal NotifyAddressBookChanged; + + /** Wallet transaction added, removed or updated. + * @note called with lock cs_wallet held. + */ + boost::signals2::signal NotifyTransactionChanged; +}; + +/** A key allocated from the key pool. */ +class CReserveKey +{ +protected: + CWallet* pwallet; + int64_t nIndex; + CPubKey vchPubKey; +public: + CReserveKey(CWallet* pwalletIn) + { + nIndex = -1; + pwallet = pwalletIn; + } + + ~CReserveKey() + { + ReturnKey(); + } + + void ReturnKey(); + bool GetReservedKey(CPubKey &pubkey); + void KeepKey(); +}; + + +typedef std::map mapValue_t; + + +static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue) +{ + if (!mapValue.count("n")) + { + nOrderPos = -1; // TODO: calculate elsewhere + return; + } + nOrderPos = atoi64(mapValue["n"].c_str()); +} + + +static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue) +{ + if (nOrderPos == -1) + return; + mapValue["n"] = i64tostr(nOrderPos); +} + + +/** A transaction with a bunch of additional info that only the owner cares about. + * It includes any unrecorded transactions needed to link it back to the block chain. + */ +class CWalletTx : public CMerkleTx +{ +private: + const CWallet* pwallet; + +public: + std::vector vtxPrev; + mapValue_t mapValue; + std::vector > vOrderForm; + unsigned int fTimeReceivedIsTxTime; + unsigned int nTimeReceived; // time received by this node + unsigned int nTimeSmart; + char fFromMe; + std::string strFromAccount; + std::vector vfSpent; // which outputs are already spent + int64_t nOrderPos; // position in ordered transaction list + + // memory only + mutable bool fDebitCached; + mutable bool fCreditCached; + mutable bool fAvailableCreditCached; + mutable bool fChangeCached; + mutable int64_t nDebitCached; + mutable int64_t nCreditCached; + mutable int64_t nAvailableCreditCached; + mutable int64_t nChangeCached; + + CWalletTx() + { + Init(NULL); + } + + CWalletTx(const CWallet* pwalletIn) + { + Init(pwalletIn); + } + + CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn) + { + Init(pwalletIn); + } + + CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn) + { + Init(pwalletIn); + } + + void Init(const CWallet* pwalletIn) + { + pwallet = pwalletIn; + vtxPrev.clear(); + mapValue.clear(); + vOrderForm.clear(); + fTimeReceivedIsTxTime = false; + nTimeReceived = 0; + nTimeSmart = 0; + fFromMe = false; + strFromAccount.clear(); + vfSpent.clear(); + fDebitCached = false; + fCreditCached = false; + fAvailableCreditCached = false; + fChangeCached = false; + nDebitCached = 0; + nCreditCached = 0; + nAvailableCreditCached = 0; + nChangeCached = 0; + nOrderPos = -1; + } + + IMPLEMENT_SERIALIZE + ( + CWalletTx* pthis = const_cast(this); + if (fRead) + pthis->Init(NULL); + char fSpent = false; + + if (!fRead) + { + pthis->mapValue["fromaccount"] = pthis->strFromAccount; + + std::string str; + BOOST_FOREACH(char f, vfSpent) + { + str += (f ? '1' : '0'); + if (f) + fSpent = true; + } + pthis->mapValue["spent"] = str; + + WriteOrderPos(pthis->nOrderPos, pthis->mapValue); + + if (nTimeSmart) + pthis->mapValue["timesmart"] = strprintf("%u", nTimeSmart); + } + + nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action); + READWRITE(vtxPrev); + READWRITE(mapValue); + READWRITE(vOrderForm); + READWRITE(fTimeReceivedIsTxTime); + READWRITE(nTimeReceived); + READWRITE(fFromMe); + READWRITE(fSpent); + + if (fRead) + { + pthis->strFromAccount = pthis->mapValue["fromaccount"]; + + if (mapValue.count("spent")) + BOOST_FOREACH(char c, pthis->mapValue["spent"]) + pthis->vfSpent.push_back(c != '0'); + else + pthis->vfSpent.assign(vout.size(), fSpent); + + ReadOrderPos(pthis->nOrderPos, pthis->mapValue); + + pthis->nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(pthis->mapValue["timesmart"]) : 0; + } + + pthis->mapValue.erase("fromaccount"); + pthis->mapValue.erase("version"); + pthis->mapValue.erase("spent"); + pthis->mapValue.erase("n"); + pthis->mapValue.erase("timesmart"); + ) + + // marks certain txout's as spent + // returns true if any update took place + bool UpdateSpent(const std::vector& vfNewSpent) + { + bool fReturn = false; + for (unsigned int i = 0; i < vfNewSpent.size(); i++) + { + if (i == vfSpent.size()) + break; + + if (vfNewSpent[i] && !vfSpent[i]) + { + vfSpent[i] = true; + fReturn = true; + fAvailableCreditCached = false; + } + } + return fReturn; + } + + // make sure balances are recalculated + void MarkDirty() + { + fCreditCached = false; + fAvailableCreditCached = false; + fDebitCached = false; + fChangeCached = false; + } + + void BindWallet(CWallet *pwalletIn) + { + pwallet = pwalletIn; + MarkDirty(); + } + + void MarkSpent(unsigned int nOut) + { + if (nOut >= vout.size()) + throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range"); + vfSpent.resize(vout.size()); + if (!vfSpent[nOut]) + { + vfSpent[nOut] = true; + fAvailableCreditCached = false; + } + } + + void MarkUnspent(unsigned int nOut) + { + if (nOut >= vout.size()) + throw std::runtime_error("CWalletTx::MarkUnspent() : nOut out of range"); + vfSpent.resize(vout.size()); + if (vfSpent[nOut]) + { + vfSpent[nOut] = false; + fAvailableCreditCached = false; + } + } + + bool IsSpent(unsigned int nOut) const + { + if (nOut >= vout.size()) + throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range"); + if (nOut >= vfSpent.size()) + return false; + return (!!vfSpent[nOut]); + } + + int64_t IsDenominated() const + { + if (vin.empty()) + return 0; + return pwallet->IsDenominated(*this); + } + + int64_t GetDebit() const + { + if (vin.empty()) + return 0; + if (fDebitCached) + return nDebitCached; + nDebitCached = pwallet->GetDebit(*this); + fDebitCached = true; + return nDebitCached; + } + + int64_t GetCredit(bool fUseCache=true) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0) + return 0; + + // GetBalance can assume transactions in mapWallet won't change + if (fUseCache && fCreditCached) + return nCreditCached; + nCreditCached = pwallet->GetCredit(*this); + fCreditCached = true; + return nCreditCached; + } + + int64_t GetAvailableCredit(bool fUseCache=true) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0) + return 0; + + if (fUseCache && fAvailableCreditCached) + return nAvailableCreditCached; + + int64_t nCredit = 0; + for (unsigned int i = 0; i < vout.size(); i++) + { + if (!IsSpent(i)) + { + const CTxOut &txout = vout[i]; + nCredit += pwallet->GetCredit(txout); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + } + } + + nAvailableCreditCached = nCredit; + fAvailableCreditCached = true; + return nCredit; + } + + + int64_t GetChange() const + { + if (fChangeCached) + return nChangeCached; + nChangeCached = pwallet->GetChange(*this); + fChangeCached = true; + return nChangeCached; + } + + void GetAmounts(std::list >& listReceived, + std::list >& listSent, int64_t& nFee, std::string& strSentAccount) const; + + void GetAccountAmounts(const std::string& strAccount, int64_t& nReceived, + int64_t& nSent, int64_t& nFee) const; + + bool IsFromMe() const + { + return (GetDebit() > 0); + } + + bool IsTrusted() const + { + // Quick answer in most cases + if (!IsFinalTx(*this)) + return false; + int nDepth = GetDepthInMainChain(); + if (nDepth >= 1) + return true; + if (nDepth < 0) + return false; + if (fConfChange || !IsFromMe()) // using wtx's cached debit + return false; + + // If no confirmations but it's from us, we can still + // consider it confirmed if all dependencies are confirmed + std::map mapPrev; + std::vector vWorkQueue; + vWorkQueue.reserve(vtxPrev.size()+1); + vWorkQueue.push_back(this); + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + const CMerkleTx* ptx = vWorkQueue[i]; + + if (!IsFinalTx(*ptx)) + return false; + int nPDepth = ptx->GetDepthInMainChain(); + if (nPDepth >= 1) + continue; + if (nPDepth < 0) + return false; + if (!pwallet->IsFromMe(*ptx)) + return false; + + if (mapPrev.empty()) + { + BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) + mapPrev[tx.GetHash()] = &tx; + } + + BOOST_FOREACH(const CTxIn& txin, ptx->vin) + { + if (!mapPrev.count(txin.prevout.hash)) + return false; + vWorkQueue.push_back(mapPrev[txin.prevout.hash]); + } + } + + return true; + } + + bool WriteToDisk(); + + int64_t GetTxTime() const; + int GetRequestCount() const; + + void AddSupportingTransactions(CTxDB& txdb); + + bool AcceptWalletTransaction(CTxDB& txdb); + bool AcceptWalletTransaction(); + + void RelayWalletTransaction(CTxDB& txdb); + void RelayWalletTransaction(); +}; + + + + +class COutput +{ +public: + const CWalletTx *tx; + int i; + int nDepth; + bool fSpendable; + + COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn) + { + tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; + } + + std::string ToString() const + { + return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue)); + } + + //Used with Darksend. Will return fees, then denominations, everything else, then very small inputs that aren't fees + int Priority() const + { + if(tx->vout[i].nValue == DARKSEND_FEE) return -20000; + BOOST_FOREACH(int64_t d, darkSendDenominations) + if(tx->vout[i].nValue == d) return 10000; + if(tx->vout[i].nValue < 1*COIN) return 20000; + + //nondenom return largest first + return -(tx->vout[i].nValue/COIN); + } + + void print() const + { + LogPrintf("%s\n", ToString().c_str()); + } +}; + + + + +/** Private key that includes an expiration date in case it never gets used. */ +class CWalletKey +{ +public: + CPrivKey vchPrivKey; + int64_t nTimeCreated; + int64_t nTimeExpires; + std::string strComment; + //// todo: add something to note what created it (user, getnewaddress, change) + //// maybe should have a map property map + + CWalletKey(int64_t nExpires=0) + { + nTimeCreated = (nExpires ? GetTime() : 0); + nTimeExpires = nExpires; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPrivKey); + READWRITE(nTimeCreated); + READWRITE(nTimeExpires); + READWRITE(strComment); + ) +}; + + + + + + +/** Account information. + * Stored in wallet with key "acc"+string account name. + */ +class CAccount +{ +public: + CPubKey vchPubKey; + + CAccount() + { + SetNull(); + } + + void SetNull() + { + vchPubKey = CPubKey(); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPubKey); + ) +}; + + + +/** Internal transfers. + * Database key is acentry. + */ +class CAccountingEntry +{ +public: + std::string strAccount; + int64_t nCreditDebit; + int64_t nTime; + std::string strOtherAccount; + std::string strComment; + mapValue_t mapValue; + int64_t nOrderPos; // position in ordered transaction list + uint64_t nEntryNo; + + CAccountingEntry() + { + SetNull(); + } + + void SetNull() + { + nCreditDebit = 0; + nTime = 0; + strAccount.clear(); + strOtherAccount.clear(); + strComment.clear(); + nOrderPos = -1; + } + + IMPLEMENT_SERIALIZE + ( + CAccountingEntry& me = *const_cast(this); + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + // Note: strAccount is serialized as part of the key, not here. + READWRITE(nCreditDebit); + READWRITE(nTime); + READWRITE(strOtherAccount); + + if (!fRead) + { + WriteOrderPos(nOrderPos, me.mapValue); + + if (!(mapValue.empty() && _ssExtra.empty())) + { + CDataStream ss(nType, nVersion); + ss.insert(ss.begin(), '\0'); + ss << mapValue; + ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); + me.strComment.append(ss.str()); + } + } + + READWRITE(strComment); + + size_t nSepPos = strComment.find("\0", 0, 1); + if (fRead) + { + me.mapValue.clear(); + if (std::string::npos != nSepPos) + { + CDataStream ss(std::vector(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); + ss >> me.mapValue; + me._ssExtra = std::vector(ss.begin(), ss.end()); + } + ReadOrderPos(me.nOrderPos, me.mapValue); + } + if (std::string::npos != nSepPos) + me.strComment.erase(nSepPos); + + me.mapValue.erase("n"); + ) + +private: + std::vector _ssExtra; +}; + +#endif diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/walletdb.cpp b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/walletdb.cpp new file mode 100644 index 0000000..ea07b68 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/walletdb.cpp @@ -0,0 +1,921 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "walletdb.h" + +#include "base58.h" +#include "protocol.h" +#include "serialize.h" +#include "sync.h" +#include "wallet.h" + +#include +#include + +using namespace std; +using namespace boost; + + +static uint64_t nAccountingEntryNumber = 0; +extern bool fWalletUnlockStakingOnly; + +// +// CWalletDB +// + +bool CWalletDB::WriteName(const string& strAddress, const string& strName) +{ + nWalletDBUpdated++; + return Write(make_pair(string("name"), strAddress), strName); +} + +bool CWalletDB::EraseName(const string& strAddress) +{ + // This should only be used for sending addresses, never for receiving addresses, + // receiving addresses must always have an address book entry if they're not change return. + nWalletDBUpdated++; + return Erase(make_pair(string("name"), strAddress)); +} + +bool CWalletDB::WriteTx(uint256 hash, const CWalletTx& wtx) +{ + nWalletDBUpdated++; + return Write(std::make_pair(std::string("tx"), hash), wtx); +} + +bool CWalletDB::EraseTx(uint256 hash) +{ + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("tx"), hash)); +} + +bool CWalletDB::WriteStealthKeyMeta(const CKeyID& keyId, const CStealthKeyMetadata& sxKeyMeta) +{ + nWalletDBUpdated++; + return Write(std::make_pair(std::string("sxKeyMeta"), keyId), sxKeyMeta, true); +} + +bool CWalletDB::EraseStealthKeyMeta(const CKeyID& keyId) +{ + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("sxKeyMeta"), keyId)); +} + +bool CWalletDB::WriteStealthAddress(const CStealthAddress& sxAddr) +{ + nWalletDBUpdated++; + + return Write(std::make_pair(std::string("sxAddr"), sxAddr.scan_pubkey), sxAddr, true); +} + +bool CWalletDB::ReadStealthAddress(CStealthAddress& sxAddr) +{ + // -- set scan_pubkey before reading + return Read(std::make_pair(std::string("sxAddr"), sxAddr.scan_pubkey), sxAddr); +} + +bool CWalletDB::WriteAdrenalineNodeConfig(std::string sAlias, const CAdrenalineNodeConfig& nodeConfig) +{ + nWalletDBUpdated++; + return Write(std::make_pair(std::string("adrenaline"), sAlias), nodeConfig, true); +} + +bool CWalletDB::ReadAdrenalineNodeConfig(std::string sAlias, CAdrenalineNodeConfig& nodeConfig) +{ + return Read(std::make_pair(std::string("adrenaline"), sAlias), nodeConfig); +} + +bool CWalletDB::EraseAdrenalineNodeConfig(std::string sAlias) +{ + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("adrenaline"), sAlias)); +} + +bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta) +{ + nWalletDBUpdated++; + + if (!Write(std::make_pair(std::string("keymeta"), vchPubKey), + keyMeta, false)) + return false; + + // hash pubkey/privkey to accelerate wallet load + std::vector vchKey; + vchKey.reserve(vchPubKey.size() + vchPrivKey.size()); + vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end()); + vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end()); + + return Write(std::make_pair(std::string("key"), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false); +} + +bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, + const std::vector& vchCryptedSecret, + const CKeyMetadata &keyMeta) +{ + const bool fEraseUnencryptedKey = true; + nWalletDBUpdated++; + + if (!Write(std::make_pair(std::string("keymeta"), vchPubKey), + keyMeta)) + return false; + + if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false)) + return false; + if (fEraseUnencryptedKey) + { + Erase(std::make_pair(std::string("key"), vchPubKey)); + Erase(std::make_pair(std::string("wkey"), vchPubKey)); + } + return true; +} + +bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) +{ + nWalletDBUpdated++; + return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); +} + +bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript) +{ + nWalletDBUpdated++; + return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false); +} + +bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) +{ + nWalletDBUpdated++; + return Write(std::string("bestblock"), locator); +} + +bool CWalletDB::ReadBestBlock(CBlockLocator& locator) +{ + return Read(std::string("bestblock"), locator); +} + +bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext) +{ + nWalletDBUpdated++; + return Write(std::string("orderposnext"), nOrderPosNext); +} + +bool CWalletDB::WriteDefaultKey(const CPubKey& vchPubKey) +{ + nWalletDBUpdated++; + return Write(std::string("defaultkey"), vchPubKey); +} + +bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool) +{ + return Read(std::make_pair(std::string("pool"), nPool), keypool); +} + +bool CWalletDB::WritePool(int64_t nPool, const CKeyPool& keypool) +{ + nWalletDBUpdated++; + return Write(std::make_pair(std::string("pool"), nPool), keypool); +} + +bool CWalletDB::ErasePool(int64_t nPool) +{ + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("pool"), nPool)); +} + +bool CWalletDB::WriteMinVersion(int nVersion) +{ + return Write(std::string("minversion"), nVersion); +} + +bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account) +{ + account.SetNull(); + return Read(make_pair(string("acc"), strAccount), account); +} + +bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account) +{ + return Write(make_pair(string("acc"), strAccount), account); +} + +bool CWalletDB::WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry) +{ + return Write(boost::make_tuple(string("acentry"), acentry.strAccount, nAccEntryNum), acentry); +} + +bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) +{ + return WriteAccountingEntry(++nAccountingEntryNumber, acentry); +} + +int64_t CWalletDB::GetAccountCreditDebit(const string& strAccount) +{ + list entries; + ListAccountCreditDebit(strAccount, entries); + + int64_t nCreditDebit = 0; + BOOST_FOREACH (const CAccountingEntry& entry, entries) + nCreditDebit += entry.nCreditDebit; + + return nCreditDebit; +} + +void CWalletDB::ListAccountCreditDebit(const string& strAccount, list& entries) +{ + bool fAllAccounts = (strAccount == "*"); + + Dbc* pcursor = GetCursor(); + if (!pcursor) + throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor"); + unsigned int fFlags = DB_SET_RANGE; + while (true) + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + if (fFlags == DB_SET_RANGE) + ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64_t(0)); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + pcursor->close(); + throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB"); + } + + // Unserialize + string strType; + ssKey >> strType; + if (strType != "acentry") + break; + CAccountingEntry acentry; + ssKey >> acentry.strAccount; + if (!fAllAccounts && acentry.strAccount != strAccount) + break; + + ssValue >> acentry; + ssKey >> acentry.nEntryNo; + entries.push_back(acentry); + } + + pcursor->close(); +} + + +DBErrors +CWalletDB::ReorderTransactions(CWallet* pwallet) +{ + LOCK(pwallet->cs_wallet); + // Old wallets didn't have any defined order for transactions + // Probably a bad idea to change the output of this + + // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap. + typedef pair TxPair; + typedef multimap TxItems; + TxItems txByTime; + + for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) + { + CWalletTx* wtx = &((*it).second); + txByTime.insert(make_pair(wtx->nTimeReceived, TxPair(wtx, (CAccountingEntry*)0))); + } + list acentries; + ListAccountCreditDebit("", acentries); + BOOST_FOREACH(CAccountingEntry& entry, acentries) + { + txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); + } + + int64_t& nOrderPosNext = pwallet->nOrderPosNext; + nOrderPosNext = 0; + std::vector nOrderPosOffsets; + for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + CAccountingEntry *const pacentry = (*it).second.second; + int64_t& nOrderPos = (pwtx != 0) ? pwtx->nOrderPos : pacentry->nOrderPos; + + if (nOrderPos == -1) + { + nOrderPos = nOrderPosNext++; + nOrderPosOffsets.push_back(nOrderPos); + + if (pwtx) + { + if (!WriteTx(pwtx->GetHash(), *pwtx)) + return DB_LOAD_FAIL; + } + else + if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) + return DB_LOAD_FAIL; + } + else + { + int64_t nOrderPosOff = 0; + BOOST_FOREACH(const int64_t& nOffsetStart, nOrderPosOffsets) + { + if (nOrderPos >= nOffsetStart) + ++nOrderPosOff; + } + nOrderPos += nOrderPosOff; + nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1); + + if (!nOrderPosOff) + continue; + + // Since we're changing the order, write it back + if (pwtx) + { + if (!WriteTx(pwtx->GetHash(), *pwtx)) + return DB_LOAD_FAIL; + } + else + if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) + return DB_LOAD_FAIL; + } + } + WriteOrderPosNext(nOrderPosNext); + + return DB_LOAD_OK; +} + +class CWalletScanState { +public: + unsigned int nKeys; + unsigned int nCKeys; + unsigned int nKeyMeta; + bool fIsEncrypted; + bool fAnyUnordered; + int nFileVersion; + vector vWalletUpgrade; + + CWalletScanState() { + nKeys = nCKeys = nKeyMeta = 0; + fIsEncrypted = false; + fAnyUnordered = false; + nFileVersion = 0; + } +}; + +bool +ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, + CWalletScanState &wss, string& strType, string& strErr) +{ + try { + // Unserialize + // Taking advantage of the fact that pair serialization + // is just the two items serialized one after the other + ssKey >> strType; + if (strType == "name") + { + string strAddress; + ssKey >> strAddress; + ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()]; + } + else if (strType == "tx") + { + uint256 hash; + ssKey >> hash; + CWalletTx& wtx = pwallet->mapWallet[hash]; + ssValue >> wtx; + if (wtx.CheckTransaction() && (wtx.GetHash() == hash)) + wtx.BindWallet(pwallet); + else + { + pwallet->mapWallet.erase(hash); + return false; + } + + // Undo serialize changes in 31600 + if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703) + { + if (!ssValue.empty()) + { + char fTmp; + char fUnused; + ssValue >> fTmp >> fUnused >> wtx.strFromAccount; + strErr = strprintf("LoadWallet() upgrading tx ver=%d %d '%s' %s", + wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount, hash.ToString()); + wtx.fTimeReceivedIsTxTime = fTmp; + } + else + { + strErr = strprintf("LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString()); + wtx.fTimeReceivedIsTxTime = 0; + } + wss.vWalletUpgrade.push_back(hash); + } + + if (wtx.nOrderPos == -1) + wss.fAnyUnordered = true; + + //// debug print + //LogPrintf("LoadWallet %s\n", wtx.GetHash().ToString()); + //LogPrintf(" %12d %s %s %s\n", + // wtx.vout[0].nValue, + // DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()), + // wtx.hashBlock.ToString(), + // wtx.mapValue["message"]); + } else + if (strType == "sxAddr") + { + if (fDebug) + printf("WalletDB ReadKeyValue sxAddr\n"); + + CStealthAddress sxAddr; + ssValue >> sxAddr; + + pwallet->stealthAddresses.insert(sxAddr); + } + else if (strType == "acentry") + { + string strAccount; + ssKey >> strAccount; + uint64_t nNumber; + ssKey >> nNumber; + if (nNumber > nAccountingEntryNumber) + nAccountingEntryNumber = nNumber; + + if (!wss.fAnyUnordered) + { + CAccountingEntry acentry; + ssValue >> acentry; + if (acentry.nOrderPos == -1) + wss.fAnyUnordered = true; + } + } + else if (strType == "key" || strType == "wkey") + { + CPubKey vchPubKey; + ssKey >> vchPubKey; + if (!vchPubKey.IsValid()) + { + strErr = "Error reading wallet database: CPubKey corrupt"; + return false; + } + CKey key; + CPrivKey pkey; + uint256 hash = 0; + + if (strType == "key") + { + wss.nKeys++; + ssValue >> pkey; + } else { + CWalletKey wkey; + ssValue >> wkey; + pkey = wkey.vchPrivKey; + } + + // Old wallets store keys as "key" [pubkey] => [privkey] + // ... which was slow for wallets with lots of keys, because the public key is re-derived from the private key + // using EC operations as a checksum. + // Newer wallets store keys as "key"[pubkey] => [privkey][hash(pubkey,privkey)], which is much faster while + // remaining backwards-compatible. + try + { + ssValue >> hash; + } + catch(...){} + + bool fSkipCheck = false; + + if (hash != 0) + { + // hash pubkey/privkey to accelerate wallet load + std::vector vchKey; + vchKey.reserve(vchPubKey.size() + pkey.size()); + vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end()); + vchKey.insert(vchKey.end(), pkey.begin(), pkey.end()); + + if (Hash(vchKey.begin(), vchKey.end()) != hash) + { + strErr = "Error reading wallet database: CPubKey/CPrivKey corrupt"; + return false; + } + + fSkipCheck = true; + } + + if (!key.Load(pkey, vchPubKey, fSkipCheck)) + { + strErr = "Error reading wallet database: CPrivKey corrupt"; + return false; + } + if (!pwallet->LoadKey(key, vchPubKey)) + { + strErr = "Error reading wallet database: LoadKey failed"; + return false; + } + } + else if (strType == "mkey") + { + unsigned int nID; + ssKey >> nID; + CMasterKey kMasterKey; + ssValue >> kMasterKey; + if(pwallet->mapMasterKeys.count(nID) != 0) + { + strErr = strprintf("Error reading wallet database: duplicate CMasterKey id %u", nID); + return false; + } + pwallet->mapMasterKeys[nID] = kMasterKey; + if (pwallet->nMasterKeyMaxID < nID) + pwallet->nMasterKeyMaxID = nID; + } + else if (strType == "ckey") + { + wss.nCKeys++; + vector vchPubKey; + ssKey >> vchPubKey; + vector vchPrivKey; + ssValue >> vchPrivKey; + if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey)) + { + strErr = "Error reading wallet database: LoadCryptedKey failed"; + return false; + } + wss.fIsEncrypted = true; + } + else if (strType == "keymeta") + { + CPubKey vchPubKey; + ssKey >> vchPubKey; + CKeyMetadata keyMeta; + ssValue >> keyMeta; + wss.nKeyMeta++; + + pwallet->LoadKeyMetadata(vchPubKey, keyMeta); + + // find earliest key creation time, as wallet birthday + if (!pwallet->nTimeFirstKey || + (keyMeta.nCreateTime < pwallet->nTimeFirstKey)) + pwallet->nTimeFirstKey = keyMeta.nCreateTime; + } + else if (strType == "sxKeyMeta") + { + if (fDebug) + printf("WalletDB ReadKeyValue sxKeyMeta\n"); + + CKeyID keyId; + ssKey >> keyId; + CStealthKeyMetadata sxKeyMeta; + ssValue >> sxKeyMeta; + + pwallet->mapStealthKeyMeta[keyId] = sxKeyMeta; + } + else if (strType == "defaultkey") + { + ssValue >> pwallet->vchDefaultKey; + } + else if (strType == "pool") + { + int64_t nIndex; + ssKey >> nIndex; + CKeyPool keypool; + ssValue >> keypool; + pwallet->setKeyPool.insert(nIndex); + + // If no metadata exists yet, create a default with the pool key's + // creation time. Note that this may be overwritten by actually + // stored metadata for that key later, which is fine. + CKeyID keyid = keypool.vchPubKey.GetID(); + if (pwallet->mapKeyMetadata.count(keyid) == 0) + pwallet->mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime); + + } + else if (strType == "version") + { + ssValue >> wss.nFileVersion; + if (wss.nFileVersion == 10300) + wss.nFileVersion = 300; + } + else if (strType == "cscript") + { + uint160 hash; + ssKey >> hash; + CScript script; + ssValue >> script; + if (!pwallet->LoadCScript(script)) + { + strErr = "Error reading wallet database: LoadCScript failed"; + return false; + } + } + else if (strType == "orderposnext") + { + ssValue >> pwallet->nOrderPosNext; + } + else if (strType == "adrenaline") + { + std::string sAlias; + ssKey >> sAlias; + CAdrenalineNodeConfig adrenalineNodeConfig; + ssValue >> adrenalineNodeConfig; + pwallet->mapMyAdrenalineNodes.insert(make_pair(sAlias, adrenalineNodeConfig)); + } + } catch (...) + { + return false; + } + return true; +} + +static bool IsKeyType(string strType) +{ + return (strType== "key" || strType == "wkey" || + strType == "mkey" || strType == "ckey"); +} + +DBErrors CWalletDB::LoadWallet(CWallet* pwallet) +{ + pwallet->vchDefaultKey = CPubKey(); + CWalletScanState wss; + bool fNoncriticalErrors = false; + DBErrors result = DB_LOAD_OK; + + try { + LOCK(pwallet->cs_wallet); + int nMinVersion = 0; + if (Read((string)"minversion", nMinVersion)) + { + if (nMinVersion > CLIENT_VERSION) + return DB_TOO_NEW; + pwallet->LoadMinVersion(nMinVersion); + } + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + { + LogPrintf("Error getting wallet database cursor\n"); + return DB_CORRUPT; + } + + while (true) + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + LogPrintf("Error reading next record from wallet database\n"); + return DB_CORRUPT; + } + + // Try to be tolerant of single corrupt records: + string strType, strErr; + if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr)) + { + // losing keys is considered a catastrophic error, anything else + // we assume the user can live with: + if (IsKeyType(strType)) + result = DB_CORRUPT; + else + { + // Leave other errors alone, if we try to fix them we might make things worse. + fNoncriticalErrors = true; // ... but do warn the user there is something wrong. + if (strType == "tx") + // Rescan if there is a bad transaction record: + SoftSetBoolArg("-rescan", true); + } + } + if (!strErr.empty()) + LogPrintf("%s\n", strErr); + } + pcursor->close(); + } + catch (boost::thread_interrupted) { + throw; + } + catch (...) { + result = DB_CORRUPT; + } + + if (fNoncriticalErrors && result == DB_LOAD_OK) + result = DB_NONCRITICAL_ERROR; + + // Any wallet corruption at all: skip any rewriting or + // upgrading, we don't want to make it worse. + if (result != DB_LOAD_OK) + return result; + + LogPrintf("nFileVersion = %d\n", wss.nFileVersion); + + LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n", + wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys); + + // nTimeFirstKey is only reliable if all keys have metadata + if ((wss.nKeys + wss.nCKeys) != wss.nKeyMeta) + pwallet->nTimeFirstKey = 1; // 0 would be considered 'no value' + + + BOOST_FOREACH(uint256 hash, wss.vWalletUpgrade) + WriteTx(hash, pwallet->mapWallet[hash]); + + // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc: + if (wss.fIsEncrypted && (wss.nFileVersion == 40000 || wss.nFileVersion == 50000)) + return DB_NEED_REWRITE; + + if (wss.nFileVersion < CLIENT_VERSION) // Update + WriteVersion(CLIENT_VERSION); + + if (wss.fAnyUnordered) + result = ReorderTransactions(pwallet); + + return result; +} + +void ThreadFlushWalletDB(const string& strFile) +{ + // Make this thread recognisable as the wallet flushing thread + RenameThread("phantomx-wallet"); + + static bool fOneThread; + if (fOneThread) + return; + fOneThread = true; + if (!GetBoolArg("-flushwallet", true)) + return; + + unsigned int nLastSeen = nWalletDBUpdated; + unsigned int nLastFlushed = nWalletDBUpdated; + int64_t nLastWalletUpdate = GetTime(); + while (true) + { + MilliSleep(500); + + if (nLastSeen != nWalletDBUpdated) + { + nLastSeen = nWalletDBUpdated; + nLastWalletUpdate = GetTime(); + } + + if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) + { + TRY_LOCK(bitdb.cs_db,lockDb); + if (lockDb) + { + // Don't do this if any databases are in use + int nRefCount = 0; + map::iterator mi = bitdb.mapFileUseCount.begin(); + while (mi != bitdb.mapFileUseCount.end()) + { + nRefCount += (*mi).second; + mi++; + } + + if (nRefCount == 0) + { + boost::this_thread::interruption_point(); + map::iterator mi = bitdb.mapFileUseCount.find(strFile); + if (mi != bitdb.mapFileUseCount.end()) + { + LogPrint("db", "Flushing wallet.dat\n"); + nLastFlushed = nWalletDBUpdated; + int64_t nStart = GetTimeMillis(); + + // Flush wallet.dat so it's self contained + bitdb.CloseDb(strFile); + bitdb.CheckpointLSN(strFile); + + bitdb.mapFileUseCount.erase(mi++); + LogPrint("db", "Flushed wallet.dat %dms\n", GetTimeMillis() - nStart); + } + } + } + } + } +} + +bool BackupWallet(const CWallet& wallet, const string& strDest) +{ + if (!wallet.fFileBacked) + return false; + while (true) + { + { + LOCK(bitdb.cs_db); + if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0) + { + // Flush log data to the dat file + bitdb.CloseDb(wallet.strWalletFile); + bitdb.CheckpointLSN(wallet.strWalletFile); + bitdb.mapFileUseCount.erase(wallet.strWalletFile); + + // Copy wallet.dat + filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; + filesystem::path pathDest(strDest); + if (filesystem::is_directory(pathDest)) + pathDest /= wallet.strWalletFile; + + try { +#if BOOST_VERSION >= 104000 + filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists); +#else + filesystem::copy_file(pathSrc, pathDest); +#endif + LogPrintf("copied wallet.dat to %s\n", pathDest.string()); + return true; + } catch(const filesystem::filesystem_error &e) { + LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what()); + return false; + } + } + } + MilliSleep(100); + } + return false; +} + +// +// Try to (very carefully!) recover wallet.dat if there is a problem. +// +bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) +{ + // Recovery procedure: + // move wallet.dat to wallet.timestamp.bak + // Call Salvage with fAggressive=true to + // get as much data as possible. + // Rewrite salvaged data to wallet.dat + // Set -rescan so any missing transactions will be + // found. + int64_t now = GetTime(); + std::string newFilename = strprintf("wallet.%d.bak", now); + + int result = dbenv.dbenv.dbrename(NULL, filename.c_str(), NULL, + newFilename.c_str(), DB_AUTO_COMMIT); + if (result == 0) + LogPrintf("Renamed %s to %s\n", filename, newFilename); + else + { + LogPrintf("Failed to rename %s to %s\n", filename, newFilename); + return false; + } + + std::vector salvagedData; + bool allOK = dbenv.Salvage(newFilename, true, salvagedData); + if (salvagedData.empty()) + { + LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename); + return false; + } + LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); + + bool fSuccess = allOK; + Db* pdbCopy = new Db(&dbenv.dbenv, 0); + int ret = pdbCopy->open(NULL, // Txn pointer + filename.c_str(), // Filename + "main", // Logical db name + DB_BTREE, // Database type + DB_CREATE, // Flags + 0); + if (ret > 0) + { + LogPrintf("Cannot create database file %s\n", filename); + return false; + } + CWallet dummyWallet; + CWalletScanState wss; + + DbTxn* ptxn = dbenv.TxnBegin(); + BOOST_FOREACH(CDBEnv::KeyValPair& row, salvagedData) + { + if (fOnlyKeys) + { + CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION); + CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION); + string strType, strErr; + bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, + wss, strType, strErr); + if (!IsKeyType(strType)) + continue; + if (!fReadOK) + { + LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType, strErr); + continue; + } + } + Dbt datKey(&row.first[0], row.first.size()); + Dbt datValue(&row.second[0], row.second.size()); + int ret2 = pdbCopy->put(ptxn, &datKey, &datValue, DB_NOOVERWRITE); + if (ret2 > 0) + fSuccess = false; + } + ptxn->commit(0); + pdbCopy->close(0); + delete pdbCopy; + + return fSuccess; +} + +bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename) +{ + return CWalletDB::Recover(dbenv, filename, false); +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/walletdb.h b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/walletdb.h new file mode 100644 index 0000000..46e1547 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/crypto/walletdb.h @@ -0,0 +1,180 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_WALLETDB_H +#define BITCOIN_WALLETDB_H + +#include "db.h" +#include "key.h" +#include "stealth.h" + +#include +#include +#include +#include + +class CAccount; +class CAccountingEntry; +class CBlockLocator; +class CKeyPool; +class CMasterKey; +class CScript; +class CWallet; +class CWalletTx; +class uint160; +class uint256; + +/** Error statuses for the wallet database */ +enum DBErrors +{ + DB_LOAD_OK, + DB_CORRUPT, + DB_NONCRITICAL_ERROR, + DB_TOO_NEW, + DB_LOAD_FAIL, + DB_NEED_REWRITE +}; + +class CKeyMetadata +{ +public: + static const int CURRENT_VERSION=1; + int nVersion; + int64_t nCreateTime; // 0 means unknown + + CKeyMetadata() + { + SetNull(); + } + CKeyMetadata(int64_t nCreateTime_) + { + nVersion = CKeyMetadata::CURRENT_VERSION; + nCreateTime = nCreateTime_; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(nCreateTime); + ) + + void SetNull() + { + nVersion = CKeyMetadata::CURRENT_VERSION; + nCreateTime = 0; + } +}; + +class CStealthKeyMetadata +{ +// -- used to get secret for keys created by stealth transaction with wallet locked +public: + CStealthKeyMetadata() {}; + + CStealthKeyMetadata(CPubKey pkEphem_, CPubKey pkScan_) + { + pkEphem = pkEphem_; + pkScan = pkScan_; + }; + + CPubKey pkEphem; + CPubKey pkScan; + + IMPLEMENT_SERIALIZE + ( + READWRITE(pkEphem); + READWRITE(pkScan); + ) + +}; + +class CAdrenalineNodeConfig +{ +public: + int nVersion; + std::string sAlias; + std::string sAddress; + std::string sCollateralAddress; + std::string sMasternodePrivKey; + + CAdrenalineNodeConfig() + { + nVersion = 0; + } + + IMPLEMENT_SERIALIZE( + READWRITE(nVersion); + READWRITE(sAlias); + READWRITE(sAddress); + READWRITE(sCollateralAddress); + READWRITE(sMasternodePrivKey); + ) +}; + + +/** Access to the wallet database (wallet.dat) */ +class CWalletDB : public CDB +{ +public: + CWalletDB(const std::string& strFilename, const char* pszMode = "r+") : CDB(strFilename, pszMode) + { + } +private: + CWalletDB(const CWalletDB&); + void operator=(const CWalletDB&); +public: + bool WriteName(const std::string& strAddress, const std::string& strName); + + bool EraseName(const std::string& strAddress); + + bool WriteTx(uint256 hash, const CWalletTx& wtx); + bool EraseTx(uint256 hash); + + bool WriteStealthKeyMeta(const CKeyID& keyId, const CStealthKeyMetadata& sxKeyMeta); + bool EraseStealthKeyMeta(const CKeyID& keyId); + bool WriteStealthAddress(const CStealthAddress& sxAddr); + bool ReadStealthAddress(CStealthAddress& sxAddr); + + bool WriteAdrenalineNodeConfig(std::string sAlias, const CAdrenalineNodeConfig& nodeConfig); + bool ReadAdrenalineNodeConfig(std::string sAlias, CAdrenalineNodeConfig& nodeConfig); + bool EraseAdrenalineNodeConfig(std::string sAlias); + + bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta); + bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta); + bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey); + + bool WriteCScript(const uint160& hash, const CScript& redeemScript); + + bool WriteBestBlock(const CBlockLocator& locator); + bool ReadBestBlock(CBlockLocator& locator); + + bool WriteOrderPosNext(int64_t nOrderPosNext); + + bool WriteDefaultKey(const CPubKey& vchPubKey); + + bool ReadPool(int64_t nPool, CKeyPool& keypool); + bool WritePool(int64_t nPool, const CKeyPool& keypool); + bool ErasePool(int64_t nPool); + + bool WriteMinVersion(int nVersion); + + bool ReadAccount(const std::string& strAccount, CAccount& account); + bool WriteAccount(const std::string& strAccount, const CAccount& account); +private: + bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry); +public: + bool WriteAccountingEntry(const CAccountingEntry& acentry); + int64_t GetAccountCreditDebit(const std::string& strAccount); + void ListAccountCreditDebit(const std::string& strAccount, std::list& acentries); + + DBErrors ReorderTransactions(CWallet*); + DBErrors LoadWallet(CWallet* pwallet); + static bool Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys); + static bool Recover(CDBEnv& dbenv, std::string filename); +}; + +bool BackupWallet(const CWallet& wallet, const std::string& strDest); + +#endif // BITCOIN_WALLETDB_H diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/doc/build-linux.md b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/doc/build-linux.md new file mode 100644 index 0000000..de8ce6b --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/doc/build-linux.md @@ -0,0 +1,324 @@ +Copyright (c) 2009-2012 Bitcoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP +software written by Thomas Bernard. +Original fork form: LindaCoin + + +UNIX BUILD NOTES +================ + +Dependencies +--------------------- + +These dependencies are required: + + Library | Purpose | Description + ------------|------------------|---------------------- + libssl | Crypto | Random Number Generation + libgmp | Secp256k1 | Secp256k1 Dependency + libboost | Utility | Library for threading, data structures, etc + libevent | Networking | OS independent asynchronous networking + libdb4.8 | Berkeley DB | Wallet storage (only needed when wallet enabled) + libsecp256k1| Secp256k1 | Elliptic Curve Cryptography + +Optional dependencies: + + Library | Purpose | Description + ------------|------------------|---------------------- + miniupnpc | UPnP Support | Firewall-jumping support + qt | GUI | GUI toolkit (only needed when GUI enabled) + protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled) + libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) + +For the versions used in the release, see [release-process.md](release-process.md) under *Fetch and build inputs*. + +System requirements +-------------------- + +C++ compilers are memory-hungry. It is recommended to have at least 2 GB of +memory available when compiling PhantomX Core. With 1024MB of memory or less +compilation will take much longer due to swap thrashing. + +Dependency Build Instructions: Ubuntu & Debian +---------------------------------------------- +Build requirements: + + sudo apt-get install build-essential libtool automake autotools-dev autoconf pkg-config libssl-dev libgmp3-dev libevent-dev bsdmainutils + +On at least Ubuntu 14.04+ and Debian 7+ there are generic names for the +individual boost development packages, so the following can be used to only +install necessary parts of boost: + + sudo apt-get install libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev + +If that doesn't work, you can install all boost development packages with: + + sudo apt-get install libboost-all-dev + +BerkeleyDB is required for the wallet. db4.8 packages are available [here](https://launchpad.net/~bitcoin/+archive/bitcoin). +You can add the repository and install using the following commands: + + sudo add-apt-repository ppa:bitcoin/bitcoin + sudo apt-get update + sudo apt-get install libdb4.8-dev libdb4.8++-dev + +If that does not work alternatively download and compile: + + cd ~ + mkdir bitcoin/db4/ + + wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' + tar -xzvf db-4.8.30.NC.tar.gz + cd db-4.8.30.NC/build_unix/ + ../dist/configure --enable-cxx + make + sudo make install + + +Ubuntu and Debian have their own libdb-dev and libdb++-dev packages, but these will install +BerkeleyDB 5.1 or later, which break binary wallet compatibility with the distributed executables which +are based on BerkeleyDB 4.8. If you do not care about wallet compatibility, +pass `--with-incompatible-bdb` to configure. + +To build Secp256k1: + + cd src/secp256k1/ && ./configure && make + sudo make install + sudo ldconfig + +Optional: + + sudo apt-get install libminiupnpc-dev (see --with-miniupnpc and --enable-upnp-default) + +Dependencies for the GUI: Ubuntu & Debian +----------------------------------------- + +If you want to build PhantomX-Qt, make sure that the required packages for Qt development +are installed. Qt 5 is necessary to build the GUI. +If both Qt 4 and Qt 5 are installed, Qt 5 will be used. + +To build with Qt 5 (recommended) you need the following: + + sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler + +libqrencode (optional) can be installed with: + + sudo apt-get install libqrencode-dev + +Once these are installed, they will be found by configure and a Phantomx-qt executable will be +built by default. + +``` + +Notes +----- +1) You only need Berkeley DB if the wallet is enabled (see the section *Disable-Wallet mode* below). + +2) The release is built with GCC and then "strip transferd" to strip the debug +symbols, which reduces the executable size by about 90%. + +If you get an error about secp256k1 +cd secp256k1/ +./autogen.sh +./configure.sh +make +cd .. +make -f makefile.unix +strip Phantomxd + +To Build Phantomxd +-------- + +With UPNP: + + cd src && \ + make -f makefile.unix && \ + strip Phantomxd + +(Recommended) Without UPNP: + + cd src && \ + make -f makefile.unix USE_UPNP= && \ + strip Phantomxd + +To Build Phantomx-QT +-------- + +With UPNP: + qmake -qt=qt5 && \ + make \ + +(Recommended) Without UPNP: + + qmake -qt=qt5 USE_UPNP=- && \ + make \ +``` + +# STATIC BUILD INSTRUCTIONS +The following instructions have been tested on the following distributions: + +1. Ubuntu 16.04.4 +2. Linux Mint 18.3 + +The advantage of building the wallet this way is that it will be able to be executed even on a fresh ubuntu installation without adding additional libraries. There will be no dependencies error messages at startup in case some shared libs are missing. The current release was build that way. + +## Get the building environment ready (same as above) + +Open a terminal window. If git is not installed in your system, install it by issuing the following command +``` +sudo apt-get install git +``` +Install Linux development tools +``` +sudo apt-get install build-essential libtool automake autotools-dev autoconf pkg-config libgmp3-dev libevent-dev bsdmainutils +``` +## Compile all dependencies manually and use their static libs +### Download and build BerkeleyDB 5.0.32.NC +``` +cd ~/ +wget 'http://download.oracle.com/berkeley-db/db-5.0.32.NC.tar.gz' +tar -xzvf db-5.0.32.NC.tar.gz +cd db-5.0.32.NC/build_unix/ +../dist/configure --enable-cxx --disable-shared +make + +``` + +### Compiling Boost 1.58 + +Download Boost 1.58 here : +https://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.gz/download
+Put the archive in ~/deps + +``` +cd ~/deps +tar xvfz boost_1_58_0.tar.gz +cd ~/deps/boost_1_58_0 +./bootstrap.sh + +./b2 --build-type=complete --layout=versioned --with-chrono --with-filesystem --with-program_options --with-system --with-thread toolset=gcc variant=release link=static threading=multi runtime-link=static stage + +``` + +### Compiling miniupnpc + +Install Miniupnpc. Download it from here http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.9.tar.gz
+and place it in your deps folder, then : +``` +cd ~/deps +tar xvfz miniupnpc-1.9.tar.gz + +cd miniupnpc-1.9 +make init upnpc-static +``` +==> Important : don't forget to rename "miniupnpc-1.9" directory to "miniupnpc" + +### Compiling OpenSSL + +download 1.0.2g version here : https://www.openssl.org/source/old/1.0.2/openssl-1.0.2g.tar.gz
+place archive in deps folders then : +``` +tar xvfz openssl-1.0.2g.tar.gz +cd openssl-1.0.2g +./config no-shared no-dso +make depend +make +``` + +### Compiling QT 5.4.2 statically +Download QT 5.4.2 sources +https://download.qt.io/archive/qt/5.4/5.4.2/single/qt-everywhere-opensource-src-5.4.2.tar.gz
+Extract in deps folder +``` +tar xvfz qt-everywhere-opensource-src-5.4.2.tar.gz +``` +after everything is extracted, create another directory where static libs will be installed. +For example, i created ~/deps/Qt/5.4.2_static and used that directory in configure command below (it may take a while) : +``` +cd ~/deps/qt-everywhere-opensource-src-5.4.2 + +./configure -static -opensource -release -confirm-license -no-compile-examples -nomake tests -prefix ~/deps/Qt/5.4.2_static -qt-zlib -qt-libpng -no-libjpeg -qt-xcb -qt-freetype -qt-pcre -qt-harfbuzz -largefile -no-openssl -gtkstyle -skip wayland -skip qtserialport -skip script -pulseaudio -alsa -c++11 -nomake tools +``` +After it successfuly ends : +``` +make install +``` +### Compiling Phantomx QT wallet + +Clone the Phantomxcoin repository +``` +git clone https://github.com/PhantomxTeam/phantomx-beta-wallet.git +``` +if required, fix the leveldb files permissions +``` +cd ~/phantomx-beta-wallet/src/leveldb +chmod +x build_detect_platform +chmod 775 * +``` +you may also be required to build leveldb prior to start the wallet build +``` +make clean +make libleveldb.a libmemenv.a +``` +build libsecp256k1 +``` +cd ~/phantomx-beta-wallet/src/secp256k1 +./autogen.sh +./configure --enable-static --disable-shared +make +``` +Just by precaution, go to secp256k1/.libs dir and delete all non static libs (all except *.a files) if present, to make sure only static libs will be used during linking + +go back to Phantomxcoin dir to modify phantomx.pro if needed : +``` +cd ~/phantomx-beta-wallet +nano phantomx-beta-wallet.pro +``` +All dependencies dir variables to set according to what have been done above in linux {} section : +``` +linux { + DEPS_PATH = $(HOME)/deps + SECP256K1_LIB_PATH = src/secp256k1/.libs + SECP256K1_INCLUDE_PATH = src/secp256k1/include +## comment below dependencies if u don't need to compile a static binary on linux + MINIUPNPC_LIB_PATH = $$DEPS_PATH/miniupnpc + MINIUPNPC_INCLUDE_PATH = $$DEPS_PATH + BOOST_LIB_PATH = $$DEPS_PATH/boost_1_58_0/stage/lib + BOOST_INCLUDE_PATH = $$DEPS_PATH/boost_1_58_0 + BDB_LIB_PATH = $$DEPS_PATH/db-5.0.32.NC/build_unix + BDB_INCLUDE_PATH = $$DEPS_PATH/db-5.0.32.NC/build_unix + OPENSSL_LIB_PATH = $$DEPS_PATH/openssl-1.0.2g + OPENSSL_INCLUDE_PATH = $$DEPS_PATH/openssl-1.0.2g/include +} +``` +After saving the .pro file : +``` +export PATH=$HOME/deps/Qt/5.4.2_static/bin:$PATH +qmake +make +``` + +### Compiling phantomx-beta-walletd +With dependencies (except QT cause not needed here) compliled as above, put these lines in ~/phantomx-beta-wallet/src/makefile.unix (first lines) +``` +DEPS_PATH = $(HOME)/deps +SECP256K1_LIB_PATH = src/secp256k1/.libs +SECP256K1_INCLUDE_PATH = src/secp256k1/include +MINIUPNPC_LIB_PATH = $(DEPS_PATH)/miniupnpc +MINIUPNPC_INCLUDE_PATH = $(DEPS_PATH) +BOOST_LIB_PATH = $(DEPS_PATH)/boost_1_58_0/stage/lib +BOOST_INCLUDE_PATH = $(DEPS_PATH)/boost_1_58_0 +BDB_LIB_PATH = $(DEPS_PATH)/db-5.0.32.NC/build_unix +BDB_INCLUDE_PATH = $(DEPS_PATH)/db-5.0.32.NC/build_unix +OPENSSL_LIB_PATH = $(DEPS_PATH)/openssl-1.0.2g +OPENSSL_INCLUDE_PATH = $(DEPS_PATH)/openssl-1.0.2g/include +``` +After that in ~/phantomx-beta-wallet/src +``` +make -f makefile.unix +strip phantomxd +``` diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Counter.razor b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Counter.razor new file mode 100644 index 0000000..8641f78 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Counter.razor @@ -0,0 +1,16 @@ +@page "/counter" + +

Counter

+ +

Current count: @currentCount

+ + + +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/FontAwesome.qml b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/FontAwesome.qml new file mode 100644 index 0000000..6d77cb7 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/FontAwesome.qml @@ -0,0 +1,813 @@ +pragma Singleton +import QtQuick 2.9 + +Object { + + FontLoader { + id: regular + source: "./fa-regular-400.ttf" + } + + FontLoader { + id: brands + source: "./fa-brands-400.ttf" + } + + FontLoader { + id: solid + source: "./fa-solid-900.ttf" + } + + property string fontFamily: regular.name + property string fontFamilyBrands: brands.name + property string fontFamilySolid: solid.name + + // Icons + property string addressBook : "\uf2b9" + property string addressBookO : "\uf2ba" + property string addressCard : "\uf2bb" + property string addressCardO : "\uf2bc" + property string adjust : "\uf042" + property string adn : "\uf170" + property string alignCenter : "\uf037" + property string alignJustify : "\uf039" + property string alignLeft : "\uf036" + property string alignRight : "\uf038" + property string amazon : "\uf270" + property string ambulance : "\uf0f9" + property string americanSignLanguageInterpreting : "\uf2a3" + property string anchor : "\uf13d" + property string android : "\uf17b" + property string angellist : "\uf209" + property string angleDoubleDown : "\uf103" + property string angleDoubleLeft : "\uf100" + property string angleDoubleRight : "\uf101" + property string angleDoubleUp : "\uf102" + property string angleDown : "\uf107" + property string angleLeft : "\uf104" + property string angleRight : "\uf105" + property string angleUp : "\uf106" + property string apple : "\uf179" + property string archive : "\uf187" + property string areaChart : "\uf1fe" + property string arrowCircleDown : "\uf0ab" + property string arrowCircleLeft : "\uf0a8" + property string arrowCircleODown : "\uf01a" + property string arrowCircleOLeft : "\uf190" + property string arrowCircleORight : "\uf18e" + property string arrowCircleOUp : "\uf01b" + property string arrowCircleRight : "\uf0a9" + property string arrowCircleUp : "\uf0aa" + property string arrowDown : "\uf063" + property string arrowLeft : "\uf060" + property string arrowRight : "\uf061" + property string arrowUp : "\uf062" + property string arrows : "\uf047" + property string arrowsAlt : "\uf0b2" + property string arrowsH : "\uf07e" + property string arrowsV : "\uf07d" + property string aslInterpreting : "\uf2a3" + property string assistiveListeningSystems : "\uf2a2" + property string asterisk : "\uf069" + property string at : "\uf1fa" + property string audioDescription : "\uf29e" + property string automobile : "\uf1b9" + property string backward : "\uf04a" + property string balanceScale : "\uf24e" + property string ban : "\uf05e" + property string bandcamp : "\uf2d5" + property string bank : "\uf19c" + property string barChart : "\uf080" + property string barChartO : "\uf080" + property string barcode : "\uf02a" + property string bars : "\uf0c9" + property string bath : "\uf2cd" + property string bathtub : "\uf2cd" + property string battery : "\uf240" + property string battery0 : "\uf244" + property string battery1 : "\uf243" + property string battery2 : "\uf242" + property string battery3 : "\uf241" + property string battery4 : "\uf240" + property string batteryEmpty : "\uf244" + property string batteryFull : "\uf240" + property string batteryHalf : "\uf242" + property string batteryQuarter : "\uf243" + property string batteryThreeQuarters : "\uf241" + property string bed : "\uf236" + property string beer : "\uf0fc" + property string behance : "\uf1b4" + property string behanceSquare : "\uf1b5" + property string bell : "\uf0f3" + property string bellO : "\uf0a2" + property string bellSlash : "\uf1f6" + property string bellSlashO : "\uf1f7" + property string bicycle : "\uf206" + property string binoculars : "\uf1e5" + property string birthdayCake : "\uf1fd" + property string bitbucket : "\uf171" + property string bitbucketSquare : "\uf172" + property string bitcoin : "\uf15a" + property string blackTie : "\uf27e" + property string blind : "\uf29d" + property string bluetooth : "\uf293" + property string bluetoothB : "\uf294" + property string bold : "\uf032" + property string bolt : "\uf0e7" + property string bomb : "\uf1e2" + property string book : "\uf02d" + property string bookmark : "\uf02e" + property string bookmarkO : "\uf097" + property string braille : "\uf2a1" + property string briefcase : "\uf0b1" + property string btc : "\uf15a" + property string bug : "\uf188" + property string building : "\uf1ad" + property string buildingO : "\uf0f7" + property string bullhorn : "\uf0a1" + property string bullseye : "\uf140" + property string bus : "\uf207" + property string buysellads : "\uf20d" + property string cab : "\uf1ba" + property string calculator : "\uf1ec" + property string calendar : "\uf073" + property string calendarCheckO : "\uf274" + property string calendarMinusO : "\uf272" + property string calendarO : "\uf133" + property string calendarPlusO : "\uf271" + property string calendarTimesO : "\uf273" + property string camera : "\uf030" + property string cameraRetro : "\uf083" + property string car : "\uf1b9" + property string caretDown : "\uf0d7" + property string caretLeft : "\uf0d9" + property string caretRight : "\uf0da" + property string caretSquareODown : "\uf150" + property string caretSquareOLeft : "\uf191" + property string caretSquareORight : "\uf152" + property string caretSquareOUp : "\uf151" + property string caretUp : "\uf0d8" + property string cartArrowDown : "\uf218" + property string cartPlus : "\uf217" + property string cc : "\uf20a" + property string ccAmex : "\uf1f3" + property string ccDinersClub : "\uf24c" + property string ccDiscover : "\uf1f2" + property string ccJcb : "\uf24b" + property string ccMastercard : "\uf1f1" + property string ccPaypal : "\uf1f4" + property string ccStripe : "\uf1f5" + property string ccVisa : "\uf1f0" + property string certificate : "\uf0a3" + property string chain : "\uf0c1" + property string chainBroken : "\uf127" + property string check : "\uf00c" + property string checkCircle : "\uf058" + property string checkCircleO : "\uf05d" + property string checkSquare : "\uf14a" + property string checkSquareO : "\uf046" + property string chevronCircleDown : "\uf13a" + property string chevronCircleLeft : "\uf137" + property string chevronCircleRight : "\uf138" + property string chevronCircleUp : "\uf139" + property string chevronDown : "\uf078" + property string chevronLeft : "\uf053" + property string chevronRight : "\uf054" + property string chevronUp : "\uf077" + property string child : "\uf1ae" + property string chrome : "\uf268" + property string circle : "\uf111" + property string circleO : "\uf10c" + property string circleONotch : "\uf1ce" + property string circleThin : "\uf1db" + property string clipboard : "\uf0ea" + property string clockO : "\uf017" + property string clone : "\uf24d" + property string close : "\uf00d" + property string cloud : "\uf0c2" + property string cloudDownload : "\uf0ed" + property string cloudUpload : "\uf0ee" + property string cloudUploadAlt : "\uf382" + property string cny : "\uf157" + property string code : "\uf121" + property string codeFork : "\uf126" + property string codepen : "\uf1cb" + property string codiepie : "\uf284" + property string coffee : "\uf0f4" + property string cog : "\uf013" + property string cogs : "\uf085" + property string columns : "\uf0db" + property string comment : "\uf075" + property string commentO : "\uf0e5" + property string commenting : "\uf27a" + property string commentingO : "\uf27b" + property string comments : "\uf086" + property string commentsO : "\uf0e6" + property string compass : "\uf14e" + property string compress : "\uf066" + property string connectdevelop : "\uf20e" + property string contao : "\uf26d" + property string copy : "\uf0c5" + property string copyright : "\uf1f9" + property string creativeCommons : "\uf25e" + property string creditCard : "\uf09d" + property string creditCardAlt : "\uf283" + property string crop : "\uf125" + property string crosshairs : "\uf05b" + property string css3 : "\uf13c" + property string cube : "\uf1b2" + property string cubes : "\uf1b3" + property string cut : "\uf0c4" + property string cutlery : "\uf0f5" + property string dashboard : "\uf0e4" + property string dashcube : "\uf210" + property string database : "\uf1c0" + property string deaf : "\uf2a4" + property string deafness : "\uf2a4" + property string dedent : "\uf03b" + property string delicious : "\uf1a5" + property string desktop : "\uf108" + property string deviantart : "\uf1bd" + property string diamond : "\uf219" + property string digg : "\uf1a6" + property string dollar : "\uf155" + property string dotCircleO : "\uf192" + property string download : "\uf019" + property string dribbble : "\uf17d" + property string driversLicense : "\uf2c2" + property string driversLicenseO : "\uf2c3" + property string dropbox : "\uf16b" + property string drupal : "\uf1a9" + property string edge : "\uf282" + property string edit : "\uf044" + property string eercast : "\uf2da" + property string eject : "\uf052" + property string ellipsisH : "\uf141" + property string ellipsisV : "\uf142" + property string empire : "\uf1d1" + property string envelope : "\uf0e0" + property string envelopeO : "\uf003" + property string envelopeOpen : "\uf2b6" + property string envelopeOpenO : "\uf2b7" + property string envelopeSquare : "\uf199" + property string envira : "\uf299" + property string eraser : "\uf12d" + property string etsy : "\uf2d7" + property string eur : "\uf153" + property string euro : "\uf153" + property string exchange : "\uf0ec" + property string exclamation : "\uf12a" + property string exclamationCircle : "\uf06a" + property string exclamationTriangle : "\uf071" + property string expand : "\uf065" + property string expeditedssl : "\uf23e" + property string externalLink : "\uf08e" + property string externalLinkSquare : "\uf14c" + property string eye : "\uf06e" + property string eyeSlash : "\uf070" + property string eyedropper : "\uf1fb" + property string fa : "\uf2b4" + property string facebook : "\uf09a" + property string facebookF : "\uf09a" + property string facebookOfficial : "\uf230" + property string facebookSquare : "\uf082" + property string fastBackward : "\uf049" + property string fastForward : "\uf050" + property string fax : "\uf1ac" + property string feed : "\uf09e" + property string female : "\uf182" + property string fighterJet : "\uf0fb" + property string file : "\uf15b" + property string fileArchiveO : "\uf1c6" + property string fileAudioO : "\uf1c7" + property string fileCodeO : "\uf1c9" + property string fileExcelO : "\uf1c3" + property string fileImageO : "\uf1c5" + property string fileMovieO : "\uf1c8" + property string fileO : "\uf016" + property string filePdfO : "\uf1c1" + property string filePhotoO : "\uf1c5" + property string filePictureO : "\uf1c5" + property string filePowerpointO : "\uf1c4" + property string fileSoundO : "\uf1c7" + property string fileText : "\uf15c" + property string fileTextO : "\uf0f6" + property string fileVideoO : "\uf1c8" + property string fileWordO : "\uf1c2" + property string fileZipO : "\uf1c6" + property string filesO : "\uf0c5" + property string film : "\uf008" + property string filter : "\uf0b0" + property string fire : "\uf06d" + property string fireExtinguisher : "\uf134" + property string firefox : "\uf269" + property string firstOrder : "\uf2b0" + property string flag : "\uf024" + property string flagCheckered : "\uf11e" + property string flagO : "\uf11d" + property string flash : "\uf0e7" + property string flask : "\uf0c3" + property string flickr : "\uf16e" + property string floppyO : "\uf0c7" + property string folder : "\uf07b" + property string folderO : "\uf114" + property string folderOpen : "\uf07c" + property string folderOpenO : "\uf115" + property string font : "\uf031" + property string fontAwesome : "\uf2b4" + property string fonticons : "\uf280" + property string fortAwesome : "\uf286" + property string forumbee : "\uf211" + property string forward : "\uf04e" + property string foursquare : "\uf180" + property string freeCodeCamp : "\uf2c5" + property string frownO : "\uf119" + property string futbolO : "\uf1e3" + property string gamepad : "\uf11b" + property string gavel : "\uf0e3" + property string gbp : "\uf154" + property string ge : "\uf1d1" + property string gear : "\uf013" + property string gears : "\uf085" + property string genderless : "\uf22d" + property string getPocket : "\uf265" + property string gg : "\uf260" + property string ggCircle : "\uf261" + property string gift : "\uf06b" + property string git : "\uf1d3" + property string gitSquare : "\uf1d2" + property string github : "\uf09b" + property string githubAlt : "\uf113" + property string githubSquare : "\uf092" + property string gitlab : "\uf296" + property string gittip : "\uf184" + property string glass : "\uf000" + property string glide : "\uf2a5" + property string glideG : "\uf2a6" + property string globe : "\uf0ac" + property string google : "\uf1a0" + property string googlePlus : "\uf0d5" + property string googlePlusCircle : "\uf2b3" + property string googlePlusOfficial : "\uf2b3" + property string googlePlusSquare : "\uf0d4" + property string googleWallet : "\uf1ee" + property string graduationCap : "\uf19d" + property string gratipay : "\uf184" + property string grav : "\uf2d6" + property string group : "\uf0c0" + property string hSquare : "\uf0fd" + property string hackerNews : "\uf1d4" + property string handGrabO : "\uf255" + property string handLizardO : "\uf258" + property string handODown : "\uf0a7" + property string handOLeft : "\uf0a5" + property string handORight : "\uf0a4" + property string handOUp : "\uf0a6" + property string handPaperO : "\uf256" + property string handPeaceO : "\uf25b" + property string handPointerO : "\uf25a" + property string handRockO : "\uf255" + property string handScissorsO : "\uf257" + property string handSpockO : "\uf259" + property string handStopO : "\uf256" + property string handshakeO : "\uf2b5" + property string hardOfHearing : "\uf2a4" + property string hashtag : "\uf292" + property string hddO : "\uf0a0" + property string header : "\uf1dc" + property string headphones : "\uf025" + property string heart : "\uf004" + property string heartO : "\uf08a" + property string heartbeat : "\uf21e" + property string history : "\uf1da" + property string home : "\uf015" + property string hospitalO : "\uf0f8" + property string hotel : "\uf236" + property string hourglass : "\uf254" + property string hourglass1 : "\uf251" + property string hourglass2 : "\uf252" + property string hourglass3 : "\uf253" + property string hourglassEnd : "\uf253" + property string hourglassHalf : "\uf252" + property string hourglassO : "\uf250" + property string hourglassStart : "\uf251" + property string houzz : "\uf27c" + property string html5 : "\uf13b" + property string iCursor : "\uf246" + property string idBadge : "\uf2c1" + property string idCard : "\uf2c2" + property string idCardO : "\uf2c3" + property string ils : "\uf20b" + property string image : "\uf03e" + property string imdb : "\uf2d8" + property string inbox : "\uf01c" + property string indent : "\uf03c" + property string industry : "\uf275" + property string info : "\uf129" + property string infoCircle : "\uf05a" + property string inr : "\uf156" + property string instagram : "\uf16d" + property string institution : "\uf19c" + property string internetExplorer : "\uf26b" + property string intersex : "\uf224" + property string ioxhost : "\uf208" + property string italic : "\uf033" + property string joomla : "\uf1aa" + property string jpy : "\uf157" + property string jsfiddle : "\uf1cc" + property string key : "\uf084" + property string keyboardO : "\uf11c" + property string krw : "\uf159" + property string language : "\uf1ab" + property string laptop : "\uf109" + property string lastfm : "\uf202" + property string lastfmSquare : "\uf203" + property string leaf : "\uf06c" + property string leanpub : "\uf212" + property string legal : "\uf0e3" + property string lemonO : "\uf094" + property string levelDown : "\uf149" + property string levelUp : "\uf148" + property string lifeBouy : "\uf1cd" + property string lifeBuoy : "\uf1cd" + property string lifeRing : "\uf1cd" + property string lifeSaver : "\uf1cd" + property string lightbulbO : "\uf0eb" + property string lineChart : "\uf201" + property string link : "\uf0c1" + property string linkedin : "\uf0e1" + property string linkedinSquare : "\uf08c" + property string linode : "\uf2b8" + property string linux : "\uf17c" + property string list : "\uf03a" + property string listAlt : "\uf022" + property string listOl : "\uf0cb" + property string listUl : "\uf0ca" + property string locationArrow : "\uf124" + property string lock : "\uf023" + property string longArrowDown : "\uf175" + property string longArrowLeft : "\uf177" + property string longArrowRight : "\uf178" + property string longArrowUp : "\uf176" + property string lowVision : "\uf2a8" + property string magic : "\uf0d0" + property string magnet : "\uf076" + property string mailForward : "\uf064" + property string mailReply : "\uf112" + property string mailReplyAll : "\uf122" + property string male : "\uf183" + property string map : "\uf279" + property string mapMarker : "\uf041" + property string mapO : "\uf278" + property string mapPin : "\uf276" + property string mapSigns : "\uf277" + property string mars : "\uf222" + property string marsDouble : "\uf227" + property string marsStroke : "\uf229" + property string marsStrokeH : "\uf22b" + property string marsStrokeV : "\uf22a" + property string maxcdn : "\uf136" + property string meanpath : "\uf20c" + property string medium : "\uf23a" + property string medkit : "\uf0fa" + property string meetup : "\uf2e0" + property string mehO : "\uf11a" + property string mercury : "\uf223" + property string microchip : "\uf2db" + property string microphone : "\uf130" + property string microphoneSlash : "\uf131" + property string minus : "\uf068" + property string minusCircle : "\uf056" + property string minusSquare : "\uf146" + property string minusSquareO : "\uf147" + property string mixcloud : "\uf289" + property string mobile : "\uf10b" + property string mobilePhone : "\uf10b" + property string modx : "\uf285" + property string money : "\uf0d6" + property string moonO : "\uf186" + property string mortarBoard : "\uf19d" + property string motorcycle : "\uf21c" + property string mousePointer : "\uf245" + property string music : "\uf001" + property string navicon : "\uf0c9" + property string neuter : "\uf22c" + property string newspaperO : "\uf1ea" + property string objectGroup : "\uf247" + property string objectUngroup : "\uf248" + property string odnoklassniki : "\uf263" + property string odnoklassnikiSquare : "\uf264" + property string opencart : "\uf23d" + property string openid : "\uf19b" + property string opera : "\uf26a" + property string optinMonster : "\uf23c" + property string outdent : "\uf03b" + property string pagelines : "\uf18c" + property string paintBrush : "\uf1fc" + property string paperPlane : "\uf1d8" + property string paperPlaneO : "\uf1d9" + property string paperclip : "\uf0c6" + property string paragraph : "\uf1dd" + property string paste : "\uf0ea" + property string pause : "\uf04c" + property string pauseCircle : "\uf28b" + property string pauseCircleO : "\uf28c" + property string paw : "\uf1b0" + property string paypal : "\uf1ed" + property string pencil : "\uf040" + property string pencilSquare : "\uf14b" + property string pencilSquareO : "\uf044" + property string percent : "\uf295" + property string phone : "\uf095" + property string phoneSquare : "\uf098" + property string photo : "\uf03e" + property string pictureO : "\uf03e" + property string pieChart : "\uf200" + property string piedPiper : "\uf2ae" + property string piedPiperAlt : "\uf1a8" + property string piedPiperPp : "\uf1a7" + property string pinterest : "\uf0d2" + property string pinterestP : "\uf231" + property string pinterestSquare : "\uf0d3" + property string plane : "\uf072" + property string play : "\uf04b" + property string playCircle : "\uf144" + property string playCircleO : "\uf01d" + property string plug : "\uf1e6" + property string plus : "\uf067" + property string plusCircle : "\uf055" + property string plusSquare : "\uf0fe" + property string plusSquareO : "\uf196" + property string podcast : "\uf2ce" + property string powerOff : "\uf011" + property string printIcon : "\uf02f" + property string productHunt : "\uf288" + property string puzzlePiece : "\uf12e" + property string qq : "\uf1d6" + property string qrcode : "\uf029" + property string question : "\uf128" + property string questionCircle : "\uf059" + property string questionCircleO : "\uf29c" + property string quora : "\uf2c4" + property string quoteLeft : "\uf10d" + property string quoteRight : "\uf10e" + property string ra : "\uf1d0" + property string random : "\uf074" + property string ravelry : "\uf2d9" + property string rebel : "\uf1d0" + property string recycle : "\uf1b8" + property string reddit : "\uf1a1" + property string redditAlien : "\uf281" + property string redditSquare : "\uf1a2" + property string refresh : "\uf021" + property string registered : "\uf25d" + property string remove : "\uf00d" + property string renren : "\uf18b" + property string reorder : "\uf0c9" + property string repeat : "\uf01e" + property string reply : "\uf112" + property string replyAll : "\uf122" + property string resistance : "\uf1d0" + property string retweet : "\uf079" + property string rmb : "\uf157" + property string road : "\uf018" + property string rocket : "\uf135" + property string rotateLeft : "\uf0e2" + property string rotateRight : "\uf01e" + property string rouble : "\uf158" + property string rss : "\uf09e" + property string rssSquare : "\uf143" + property string rub : "\uf158" + property string ruble : "\uf158" + property string rupee : "\uf156" + property string s15 : "\uf2cd" + property string safari : "\uf267" + property string save : "\uf0c7" + property string scissors : "\uf0c4" + property string scribd : "\uf28a" + property string search : "\uf002" + property string searchMinus : "\uf010" + property string searchPlus : "\uf00e" + property string sellsy : "\uf213" + property string send : "\uf1d8" + property string sendO : "\uf1d9" + property string server : "\uf233" + property string share : "\uf064" + property string shareAlt : "\uf1e0" + property string shareAltSquare : "\uf1e1" + property string shareSquare : "\uf14d" + property string shareSquareO : "\uf045" + property string shekel : "\uf20b" + property string sheqel : "\uf20b" + property string shield : "\uf132" + property string ship : "\uf21a" + property string shirtsinbulk : "\uf214" + property string shoppingBag : "\uf290" + property string shoppingBasket : "\uf291" + property string shoppingCart : "\uf07a" + property string shower : "\uf2cc" + property string signIn : "\uf090" + property string signLanguage : "\uf2a7" + property string signOutAlt : "\uf2f5" + property string signOut : "\uf08b" + property string signal : "\uf012" + property string signing : "\uf2a7" + property string simplybuilt : "\uf215" + property string sitemap : "\uf0e8" + property string skyatlas : "\uf216" + property string skype : "\uf17e" + property string slack : "\uf198" + property string sliders : "\uf1de" + property string slideshare : "\uf1e7" + property string smileO : "\uf118" + property string snapchat : "\uf2ab" + property string snapchatGhost : "\uf2ac" + property string snapchatSquare : "\uf2ad" + property string snowflakeO : "\uf2dc" + property string soccerBallO : "\uf1e3" + property string sort : "\uf0dc" + property string sortAlphaAsc : "\uf15d" + property string sortAlphaDesc : "\uf15e" + property string sortAmountAsc : "\uf160" + property string sortAmountDesc : "\uf161" + property string sortAsc : "\uf0de" + property string sortDesc : "\uf0dd" + property string sortDown : "\uf0dd" + property string sortNumericAsc : "\uf162" + property string sortNumericDesc : "\uf163" + property string sortUp : "\uf0de" + property string soundcloud : "\uf1be" + property string spaceShuttle : "\uf197" + property string spinner : "\uf110" + property string spoon : "\uf1b1" + property string spotify : "\uf1bc" + property string square : "\uf0c8" + property string squareO : "\uf096" + property string stackExchange : "\uf18d" + property string stackOverflow : "\uf16c" + property string star : "\uf005" + property string starHalf : "\uf089" + property string starHalfEmpty : "\uf123" + property string starHalfFull : "\uf123" + property string starHalfO : "\uf123" + property string starO : "\uf006" + property string steam : "\uf1b6" + property string steamSquare : "\uf1b7" + property string stepBackward : "\uf048" + property string stepForward : "\uf051" + property string stethoscope : "\uf0f1" + property string stickyNote : "\uf249" + property string stickyNoteO : "\uf24a" + property string stop : "\uf04d" + property string stopCircle : "\uf28d" + property string stopCircleO : "\uf28e" + property string streetView : "\uf21d" + property string strikethrough : "\uf0cc" + property string stumbleupon : "\uf1a4" + property string stumbleuponCircle : "\uf1a3" + property string subscript : "\uf12c" + property string subway : "\uf239" + property string suitcase : "\uf0f2" + property string sunO : "\uf185" + property string superpowers : "\uf2dd" + property string superscript : "\uf12b" + property string support : "\uf1cd" + property string table : "\uf0ce" + property string tablet : "\uf10a" + property string tachometer : "\uf0e4" + property string tag : "\uf02b" + property string tags : "\uf02c" + property string tasks : "\uf0ae" + property string taxi : "\uf1ba" + property string telegram : "\uf2c6" + property string television : "\uf26c" + property string tencentWeibo : "\uf1d5" + property string terminal : "\uf120" + property string textHeight : "\uf034" + property string textWidth : "\uf035" + property string th : "\uf00a" + property string thLarge : "\uf009" + property string thList : "\uf00b" + property string themeisle : "\uf2b2" + property string thermometer : "\uf2c7" + property string thermometer0 : "\uf2cb" + property string thermometer1 : "\uf2ca" + property string thermometer2 : "\uf2c9" + property string thermometer3 : "\uf2c8" + property string thermometer4 : "\uf2c7" + property string thermometerEmpty : "\uf2cb" + property string thermometerFull : "\uf2c7" + property string thermometerHalf : "\uf2c9" + property string thermometerQuarter : "\uf2ca" + property string thermometerThreeQuarters : "\uf2c8" + property string thumbTack : "\uf08d" + property string thumbsDown : "\uf165" + property string thumbsODown : "\uf088" + property string thumbsOUp : "\uf087" + property string thumbsUp : "\uf164" + property string ticket : "\uf145" + property string times : "\uf00d" + property string timesCircle : "\uf057" + property string timesCircleO : "\uf05c" + property string timesRectangle : "\uf2d3" + property string timesRectangleO : "\uf2d4" + property string tint : "\uf043" + property string toggleDown : "\uf150" + property string toggleLeft : "\uf191" + property string toggleOff : "\uf204" + property string toggleOn : "\uf205" + property string toggleRight : "\uf152" + property string toggleUp : "\uf151" + property string trademark : "\uf25c" + property string train : "\uf238" + property string transgender : "\uf224" + property string transgenderAlt : "\uf225" + property string trash : "\uf1f8" + property string trashO : "\uf014" + property string tree : "\uf1bb" + property string trello : "\uf181" + property string tripadvisor : "\uf262" + property string trophy : "\uf091" + property string truck : "\uf0d1" + property string tryIcon : "\uf195" + property string tty : "\uf1e4" + property string tumblr : "\uf173" + property string tumblrSquare : "\uf174" + property string turkishLira : "\uf195" + property string tv : "\uf26c" + property string twitch : "\uf1e8" + property string twitter : "\uf099" + property string twitterSquare : "\uf081" + property string umbrella : "\uf0e9" + property string underline : "\uf0cd" + property string undo : "\uf0e2" + property string universalAccess : "\uf29a" + property string university : "\uf19c" + property string unlink : "\uf127" + property string unlock : "\uf09c" + property string unlockAlt : "\uf13e" + property string unsorted : "\uf0dc" + property string upload : "\uf093" + property string usb : "\uf287" + property string usd : "\uf155" + property string user : "\uf007" + property string userCircle : "\uf2bd" + property string userCircleO : "\uf2be" + property string userMd : "\uf0f0" + property string userO : "\uf2c0" + property string userPlus : "\uf234" + property string userSecret : "\uf21b" + property string userTimes : "\uf235" + property string users : "\uf0c0" + property string vcard : "\uf2bb" + property string vcardO : "\uf2bc" + property string venus : "\uf221" + property string venusDouble : "\uf226" + property string venusMars : "\uf228" + property string viacoin : "\uf237" + property string viadeo : "\uf2a9" + property string viadeoSquare : "\uf2aa" + property string videoCamera : "\uf03d" + property string vimeo : "\uf27d" + property string vimeoSquare : "\uf194" + property string vine : "\uf1ca" + property string vk : "\uf189" + property string volumeControlPhone : "\uf2a0" + property string volumeDown : "\uf027" + property string volumeOff : "\uf026" + property string volumeUp : "\uf028" + property string warning : "\uf071" + property string wechat : "\uf1d7" + property string weibo : "\uf18a" + property string weixin : "\uf1d7" + property string whatsapp : "\uf232" + property string wheelchair : "\uf193" + property string wheelchairAlt : "\uf29b" + property string wifi : "\uf1eb" + property string wikipediaW : "\uf266" + property string windowClose : "\uf2d3" + property string windowCloseO : "\uf2d4" + property string windowMaximize : "\uf2d0" + property string windowMinimize : "\uf2d1" + property string windowRestore : "\uf2d2" + property string windows : "\uf17a" + property string won : "\uf159" + property string wordpress : "\uf19a" + property string wpbeginner : "\uf297" + property string wpexplorer : "\uf2de" + property string wpforms : "\uf298" + property string wrench : "\uf0ad" + property string xing : "\uf168" + property string xingSquare : "\uf169" + property string yCombinator : "\uf23b" + property string yCombinatorSquare : "\uf1d4" + property string yahoo : "\uf19e" + property string yc : "\uf23b" + property string ycSquare : "\uf1d4" + property string yelp : "\uf1e9" + property string yen : "\uf157" + property string yoast : "\uf2b1" + property string youtube : "\uf167" + property string youtubePlay : "\uf16a" + property string youtubeSquare : "\uf166" +} \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/Object.qml b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/Object.qml new file mode 100644 index 0000000..54dec07 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/Object.qml @@ -0,0 +1,8 @@ +import QtQuick 2.9 + +QtObject { + id: object + default property alias children: object.__children + + property list __children: [QtObject {}] +} \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/fa-brands-400.ttf b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/fa-brands-400.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aa1687de5c0c76a69880ede7b3915d9fe1a6ede5 GIT binary patch literal 129284 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
Xksk_y;@N9i38z8=G!nL5#8U{`+SxsK?rjgJ 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 z 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 literal 0 HcmV?d00001 diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/fa-regular-400.ttf b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/fa-regular-400.ttf new file mode 100644 index 0000000000000000000000000000000000000000..34629a6deecda28d95b375c3ae15bf7c3838ce54 GIT binary patch literal 34096 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 UcV>QrJmDWsorRB=UvK=s0KK1li~s-t literal 0 HcmV?d00001 diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/fa-solid-900.ttf b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/FontAwesome/fa-solid-900.ttf new file mode 100644 index 0000000000000000000000000000000000000000..704a2a996eb5037908200da22c7c86f640034753 GIT binary patch literal 191836 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

Bo1xY9uy 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
bXSOx{wS6!ngAplCQDlMejJJ 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 literal 0 HcmV?d00001 diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-BlackItalic.ttf b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-BlackItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f8b571c185bf0dd48ab943c7af8b44567afefe6d GIT binary patch literal 139716 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�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 BZ$bb7 literal 0 HcmV?d00001 diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-BoldItalic.ttf b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f63224726d068697642431355d3a95ce5dc3aff1 GIT binary patch literal 139280 zcmdqK33yx8nLm8bU37Kt)xO%6Y*~vX@0%<;v7JO&oXyU@KnU5$PDlt4AdnCsVG98Q zlrr6iu1wc~7KZ+(9iT0xg_f31ODP>F?R1%GJ9MG{GM%<4-|s!=N|qfPXlK6pp68=| zBJ1er>YVqy`*tKINs=G`sFH8df{}%pk7n*m3pO=a2A)?{>^)K zZrfq}_E+~y?9g@iynhb{9IqM|;Q8m{eP+-8Lx->0qu1l}&q|W@p^GlwzU`bp{KLHx zJMbP!(tfgk+u?)im}e#4)AJh-Y}>zc^_e5;Ki36nlGH8Rx(rNU6?aCswpyKLu^cv zYHKhp9O&zJ7}2&=w$L}g`t$kTXfWbPr&GCHQpYRH=UPmKUE;6*K!duCd8}(=s;~5? zK~K#|*8AzS<1D3D!lLu2T&hGceVlAfXTeU6Xc512svFu<@H|wkq)_Toe)60HdhV?zl z+betix;&!_7RM{&&&c<1SbUpE2e9ardZjtVVM&%0r>yLhoRULxI(8b^xwHv02S+7U z)i#;BtZ73U(51Jhy9?iH4;GS5$)*9zh?SA1KcBR>o7AWH3qTr33tS4O)27M}>JhJe zh2@gNir*@IFU|t^JA}=beidgu07RJn?!zCUF9FeRVLk609<+3)CSULJd9Cf1=UT6| z(efVWe|yc%gm)}T7>3;`XENyRMOvQoA(2SoAVYW=nM@OMtGn zQ&JRr*G{IYY?DJEKsr@dD@koFsrGbxV?%ASE{P{Z3WgDG>&*@X`}xkpA)K@xiSXBS zlJ)i%`m*V?9_;NOu>TCXPmfLrgX3fncvTEe^Yf2BZD_i>;64xb`WCt8dDs@xJ zW638i@0wA6ZSMk~Z+5d)vu8iMzdu`3cSq@mosBNDF7aN8N$E4M$xq2oN?lTaF)uM$ z1$iHnR7F;mqrhKj3-&y36noOPIGCo*r{lxq&c0k`pjihVM>rk>lYyu9y3?s_u0NYj z=?lTJ z%!~I%8y8=A&l-PP z{s=y2Qa330dF*%{`@`r1ftBYLgFQ@h#F(Lv)yT3bGfPsJ#?BsP>e3CP519DEprkpR z4(*`i)E!R!sAL+lWFAz20ET=3IPbzEtR0fWp>6@<1A4k{Y>^COzA+XXeZYk$42dT= zkNtIz@Zb@{Q#=B2JN8zWK|7!IhR=|WzUf|)c*y)Wc?e)`NbIP@02VeKSc*%gd5R<} zh743xBtwxP%HI508|c4c3}?MgTDx-j=+cpSvxf`$uJ&vunMr2dMvcJP0m9fk;U-Yk zK~jn^c_3Sb&w>mIowGDY;4}Y~eUc$uHi1)!nM>GwuLgDm`5Ti~V7by18>fME85{Ff7Ht_gx!edeGUBT+sJojYoI* zG`HXF^68F{su`Y6YxjnR)cNa=-+tlwHDRKKp4{-fjmv_ea|A7n9vI9iN~)oI?o_z{ zlzd$kP22=dE@_HG`oz7% z^EM2Jd>!qjgIJXhOZyg9RWD>M7^%)ANZQ?!rpcSQbTzFKzB*b8GiUXVt5v!ecy*hCz+C^G#a>+BhOiT8%pw&45mOITJ>d!G< zvKOD9+u*U7>9LkTo~oAj>`mRmKf4{g$-vGY=R6DA24u_A@>TpC{(rh-a9xs`@5foD zrLJN-X$mT73KJCs5-?mpz^o)`1_cr@aZOWdDyC@?M7bmlNhHb#r5Sx(3oB$zBW`P@14$5zt&&U&^t05{8yBjEtMnBp zU|d0Yv$F^!GBq_84hFiaX}mZxGZIV%r#T+h84uNZtX>PMn82lXVW$mJOEG&kE@|Ki zLn>{qL5dR=Il%JY0E>v)%Lw!=Rv*QBO5bQ;4Om+g#9#Vxx9qoWEHCXs%X7+WU1)lL zAXd{24eE!`C;Fv5qYwBX5SySzK_fgUY0#rIoI$l3<=CP#hhx5DEQY1?dD^izp17gt z#a8;ILLr@n&gC@frqj7dNR7*=filPAdNf4UXK!(MYZ6bKKKJM>nfZ)&o2KIE=)SBW z5L9=}T;)>Fvn<62f|1T(Oee@q;=)Fsv??OLESFY7Vv$Iy z>_FG@18Mp9PH3tgbMM5ZV$pj|6QB4YlCX5VcfI1Wx8*AJyyAaF-s>@Y4G${?%KL!O zdWB&SQfq*AI3WK0hgCKY`Y+BC=@b-L3b&L`gPn_gd!^c91S7OL+swt7yP!-^4aEL} zmV63Jxx;khHDI3hn)0od$78*Ig$+y4(eL;(v(oa>2Wmh`A%!0>F|RES@H74sv0{xF z*61fk@u3QSrmFMRu?@wL56sh-^))5p(J)_%KE+a0p$b4xv6TT`0eyf6R4?!jrdVu1zeqLhyNw%gk{w;-M zh8X__`xZY(b|%gC0p>ZWx!9yb8pFdQt4xu(tqWmMKGdAl)K{3TL6;KtUjG18;&JG4 zs+#Dnm^W9`8p0mkkZ%GEPeYM9iC0%DCz!s8H@=r<7Xq<3IfdL#`LO9FWH7y54MF1d zrnd~SXBF~2h?PGhRu238HTg4Gc}nUl_PE5#;hK^qb_^JyY=R2Qm#=OiaRA)Fep6Di zkje~@IEV-}pKF5A2+V+iAjv#p6T~iwAfGz20(v|QRF}+htvl+5OOKI204A`X6Dq_% zaN6wLFxwX}+-`3!bA;7-&AkE(Zn}}&DOlmB`B}{5IPjEwF^4&6Lf^#7Gg4DAm4F_M zH7~^mKtwRRWqC-ZwPvK$V4*+&whjo3OCX@A_iz zH4I1T+m9$d2#EyD1FhP8lKR9zG`_0Gr^B(RVlD2qV#XF zZI#vLFdmW;#W+SdQ02|AGVO(iq(Hi$8jZ zGv=?8_RIR+_{`1!frP->%UxK1yHqIlMu87-Ct(PGC~z2)&L+#V$Ooft9@lN!rPk)A z!6sX`8Gutv;O{_%Ds^t*lK$qED+dyH$z4f9H4ND=yWJf{aAZ21?)Mt1(_l3AcbW1* znWZj|^#hk;87o|F&Bt1aUB5ijen0EO{OquLV6?Iv>u;7ii*4z+1qT>5ppa%J9}}1j z&sZ5@nx$-^&|j^T0i~nC3MaNDbdcP9KyNM^IeG`IOFbTS->O1kgzqsadL|+N3gayjEcm#~0*MkD0b?X} z2hnR4J8zM4g~9+o16vl7S7ShIh|~{mBTw2f0}m(ijpy2R?LDLT>sp(uUlMV?2jItX zSn{3GzdP#sk;mF=dYjWxwyAUO9>unhH)1{;i$L*+iZ-Gm@Aiob22kG48?n*^$MX zKa~39-OG+H);v-CF*53lxYdpQqdtF7J>TrTU{Sbn+t@9q`gSgYXX5;mH{UyF?#3md z@Hunl&e@3m`^fZj6Wg2Ys&dg z%CH0M-+iU(cfTtCsxtl#q`5F|-qJ(i zsS9;=!K2*YRcLL-8Z();jFYPw5Ns8ehV!E%jaE1sxEdX8ko)fNcLdn0J0kgKPv|X9 z1%6P!;&Lbb?#3_QcF_q}yAuqLVaQYO4ky2G$9GtFd*7(vsU9BndH<~Tbeo$ud5EpK zU7Bls_YJ4dTj#^u<#=n&JLjfb*^AwsbLOVPugsadXyX9a@FYMrg;Pj_Ucbt*c6HS$ z5KfCzuwy0InWX$1s51*&f$VeJ146+8J6d4qGDS(8!U>YgNm4GK>jhAAHVG_i^xb5hr>5_siDJ zm@@|7oZ8oS$%WCz(Pg*Za+a&)UUuiuy!CVHtPb+ykT&yK>?Ea@;_q1=c3oR*#5wa5SP);;eOOf;;12x|+)-1Rwo3;ul;L?28UW!n zyoPbOQ8KAmQ@jb&YqIGAp=6_s7dk-koh(#l7+*AG4rLd z#zskM%r_ElB&7Q045=$>HkTuMDWit~DJUb#qb}(zU@CmFx=dG=)UwA?6|LSmA#a{RqoXX8@S*JIi{4h9d4XvGX*bP`CN#wV4+MYcAw0vBQ zLn6~&Q<9kfO|}o;W8l57A%gxSG}a}>g(+yBy%>WLD=AAu(E66Z2?{?3@m;_L5fW9E zw}6)-V8mE;xNVj+oF3@N42WUGW z$@n_X4uwtmD1_Cfe##q%)uwtDkE)TcXQ#Ad>*kH;r3bn)vqeCyUN{A~aGoxpb~eHi z9?zD`irSPI>yh>G_}bUcimy2}im&auPywmmTc=opbzE!QdX9CKP&Wpt6 z?=~yV5>xxG>J5~K|bk{_dftBMD8j%fj?>?g&sJ7e@=nlNgj(^9tSN?N#ZupGW_c2 z@v9vaje#Ex@c@L@cB-%vY}bjC>H3gPzuzIXkrO@Hls1s3L4vWo1~?+Cd?s8tj>pgV zx*l}NGqyv!pmdb&iL+Oj5FZAu?K8w$nbTwSS>C(GSA3Tj1D?_!xR(GrmHY^YF3-h4 z+)QxbrGV}uoCAw-;Q?Tfudm6!#CT&Fy4(g*wi0xq(qeawQlc+6P;qRHTcMPC1FsM_ zgoH!ri*IwDgH@7?_#Cah>rkxxZhhkZdrXMNEPDr;H>C?>{+8TPb}xUk=k$%FwbM#| z!B@T;ze+subDSrNak3V~_}Anss>aD$5aUmY{3iQ3WG#qsJCEtC=RYY2E6@2&)$e{) z{%vLa7u;G9&-n(oy$E6%4zU?z%eOnA%E5?)#F7|%5eke+Mcu*O?mT)lL+YQ^mzzya z2$9bu!sp{qI}3`y5|I=F!Y9`R)Ve3&6DBbGl3w z6Be8o6)(ZK>kE{bwOwBYB`Y{w*^fa!I&AK9f%%l^=Jm1Wf7c@3+nt6|`c$CdLjjk3 z!sYc@rD67jipTy}ANkjP$#xeGpg-Cr2bQz{F3dcLi94dChC<75}B4n$cRN<_^{Gz1eBV zzjW04cKf`n_idi~ok5R$gW;(y-S&Je_I-Ah+cfZ)*N=IEK9hw@zpNv;uA}vG{JPA> z>tArVP9A?s{&>|m;jftg1bE_9&v{ZFrgJ#+EY9H%fJcjjb7-os^HP@J%`)Alb(t+~wB2k#LmGyB__=-#JIK{lyQIA(%_m~z&W(a=qpE|%jZ}FPXu}>+Q z>G3%K_(!M5(4EfG>gPCDX`JpPmn?uauJ<8%gM{u8z*V)Fba8F&TG z;OE%mgVI4Ktj1FYJi4nu@he2^~qk<cy>jM2|K)hj?9xb$>PTUVUuNr z#w+--o}QH8D|06n52La3W@}oVSJRlIetrL{s-Pg)WO?|i_sQD0EK7`PMKJW77 z7w&Yxhi_WRR505@E=^gPvgoobP;+ZpC9wSo|q+D40 ziZBKz_L_1WCpJ%7CY>woC~iw2KYA5Y%_7q^g%k=?V&*XkL0#3M9dk2NQXQs>lwq9r z7Gj(uqflHmP2b{j!U&kJk1bz5f4(FwKX>^#^OwyZTe=v}p4*gf%B7kL9Z0q-$0e&k zUIpS4ZSGm2;$7#XF*_0P#rEl~Y|M6$O>{f0P@+F%6d zA>d0CdK;(E&nh}m%9#=<_gqNSM)0$Xie?b0`p_D{$^_M*T!0M|gW`S$!N8CV1et}X zA4q{1SoP<4=GhD^nUtg??2on<{7j;$z&$l^KXD0Gi5)<>jx| zmmEGttSe$B)A?L$((73O>|xAr-4asdhWPS2m!dW#>RWvd4>C9`#hiET`DVwupGY%Btu3Eox~ zJ8$HMnF=$%H5uKm*%XVAI(B9amqY_1}4S2(LPP0=Bs8(#r26YO={cSZ$t|_vd zBirC|HFwmxooXeWxyGS7eXZWjOWg4Z_-y0vZ25QKYQSH}_vfWsAxoSOGWLLiP=95{ zuf+^t+Y1cw2WSX{;pAOuM5ZwKo(n2mJy+o-@jdQApIUL_e9!)TO2sWne6KH=7ksZ! zKqg)}8|E+6+%Ddv=|=qc)}F;7sP^Xd5ZkwxRkzfVzAI*s>Xu5klaPb-5Q#R0s4H689*WqNL&tGy#W2>2|?BF_9P-YOg2D{q%GO+74aVW z5)n}v91n^R*N-)ar0pRgJU9y72~`a6+fxb+NH&eBIrsu3q+pRM&8Grf@T*Y5&BW=H zNDkhsaH_(yk52f)gt>?VhWq=G=D4tbWX>$CzOQLkIBW1s9SUgx$D~@$gCm!bPqD-^G&H{7hHW+l|9jlr*AwD5nPAsQ^EsD2Q!tFkK}i)bLd9h z$?Y530+f=C#1kuL*l2I$kPV18R_+p;0GuN`PZT)*XF7V^h9);OnHyF&q%!FXuNz$J zHFK7ynb5!4W8u%&U!lJO|dSvV#rY0M*1=HNJDV0iGdDGtW8kAJm-7TeO2Scb;bA#Wd7RgseaD)rBhYoWXFm5FG}}gy|R>o9Y-fJOIj=~EiOVx zlQLB7bD_LLSv?Bl49BBW02z^RRiiR0f#;5~*|Q~S_Tt%#M&{!YLqj;6E{ciUcsi+Y zhqypl)vr1v43i#KLEfq}`$AE3dWYvA3|~1pv-HKv$+=D-VOpQLbvVoO)`h9%yUjkv z7b%r78})A(NvB3GHJ>u3$+Eg&hXv;1hLYNVk;m8m?*n7 zKv~q@%z_tz6F0!vDm6Ey3LsNT1fS@Qw>3-JIr!crSNw=eUN#2$3xL{2^~llPo9#Cv zvs{kD;&1ctGLYfb$Ozu;HP>67hMgNc7G8&tkBOJkJK=qSmGQ4Q#{)RWc4>}O5)#(a z$Q;TbL)j8+ZUsVy2GsEZTguQrfjrO`akz{ht^!NEY?X7}5czlzG~{c^(QG*TpxC|H z^cGBSJ8QbC!X4vqRN4KNUw~|~A5IuYeuUkXUzzYV#~789MLIeV37OL|8`&T2Qd^-p zlPL(?v*l0(F;>J2#*Kf$Ey^xF?#&4R4{a7vwg-+J0JnyB57xXIORW!i8W(h(d!D8^ z8;)(yFAF$vSXbk0cGkZA#Lk(hkd~8~RWX!1)u&&awK8UT4J%x?X?`qz&e~{GBysTS z=Ee+F*}`~`+49(AaazDB`wJEufq>{zM*t!QU66yPGn`w z2zkd!#lIS76p!0D?g_h4yn3zM_vgr8j6&f0Hm;B~5IFP#L&`n8#3c~acIYq7#KSDc z14ohsMa9lx85y0J1ezU~P?^IyGU<7w!`aaagx`<{1os(#Z*Vt(NmUKqspUP(H|fLR zR`hmIo!dNY4$`}_f8gb0dhLotW9jFVeaQSi->jbY(yxhsjjwcA8Y<36z*uEVv069; zfu?()%wo;DZX=B06lxW=I4lij2hyY;p{OuE4ezZ8mWumhy1iVSK{_-D+-yQFJl}?u z0jWEcfSC>^*Y%E_JI(%FTnp+V&8Lh1c}}8f&9cT+=@)#jKEHp+-YZV)44sNXaYWes z+@^X!dbhBt-c9M#@EKuzf&3#BOCVQ=crNlQ!E~u?Y1SxZTp|q3t11${`WjJFLAjQJ zNvY6sIcrn|OVc+~ep%4G2FDWyhr8ya1?<2pwzvZ-;5G6}ueFJI75;hs0k6rvOZorg zmlh|)!m<-<67?ms-a>r|&||_6On9V#1p5-_eV@c(%JR4O5;g-q?8d6m@AQ>NPgadS z|7v;ky)x-X^aMqIn7x2DBMi|K8pdzl2JNl< zoW~e>@#HhFo*6(@4V}bHY1hM1XshJ5>HvF7NGKy3KNXM^3SW>d2+K^<=4ep*k(*zh zG2VTGCynFyAiwwt&h!oRcC}=a4fqK+{B~2FBDc1ts_qc3hYEhb8!Z+1`O+)S^@`c5 z77J-kUEW$b=78m_PdnsV-jagUd|&mc|M}krdqct6Ec!&aboSNq@z>XyYB20I+f1(w zt9QxdVHPldl)an7YS)>0Y#oPH6Gci%R=_F+)+!2ijhdjXlrc9)6{y?fODEzs@=`(2 zWaO>n^;ZS_)9Jef3ZJl1_(bVDTzxWIW_ovGGbez`yV}09V8WhW<(kq$_A=j2{nI$= zGoQp-Zv!^RC5oTn9I190s{~H)_}Ltui4d3S3Ta;P;V6?<|9Gwi1k+y2s3kMCfP($@NLpN?Sd4WSs%f|7QWx* zaouZ}t{3i5J+4zB^Kdg5-jOn=EY()sJvp1TR~!}m;|OxvGY?_K zHXQ!}PPb`kFZ`=hH{DJr`}D_9vczG^W@FuD z-ZlKzco#h2oLSyZ%u&DwKnL%5TQwKQ`F`$9kj>)I!VC^Ai}RW( z$8E0vHNHy0_2F9}qhl98e7oL%3a(EEhYdrHjTOSNeF65d6W8Y(VMtz}3Ygu1D!uNh z-Wh9fnR}=VW{-(OWr(3m>`JUDM-*MIgMr@&jPDrsge(+vkwAcAJm!p3Mh%Re8}-ID zFuEY0f+hE+Dzz>hb8w;%NlJIh3FMP~ird{@q%n{63o3kB&I?~!NY?(e{N7*sHV#^x zw6Y&|&}?b_Klm-=yA!)6!zCiJb;)>JuFq0J~l8A>ugL>nF{NQ3wYE|E&bxu;7j^Kob z)c!=DF;xA|q<6=J==7SY#-@&zmX2j(@#fM`xN;Hp`v=-PO1~6ueEu129i(>H(2&mu zG@7NchoSyefDr^s77=r(6LuL;tVn$ixOn3E&EvY^hN2svG)vjsKxSf63ovYo%_Ful zt{&2EiGH1<7pyoJ+eFni_C8ZfBwL5fnb_HlWu+jyWYsck3fdt?{83LlE>tEVabVq& zH{}VegreV}vecH(R}3*uK0Nl4G6WwUW1m%qL?s&6w$88m?sL-Pwk8nduqi+Dadr)! z4PJqo9fDbxwBg|l1Xvk?YDt=F5?V-6)SB>}3pFy0i}jVy_$U-t>N3NG0-e(eMnOw zhF(r}pX`3LLvFWSrD&e|cU-gY8qjmYJ=YHwJZ@EKNVfL5H50Lqq`7TUaNzylIu^lNKqS^P-5oLyLS(ejgy(1V=@` zG*(;^hMz6p+nz-@T}6{JGlI5?U1yuRZ$=@!{#TTJ(nBzY-%@>(zmVZ?Q zt;;Kbmntzl+|vW?ZN>2Ng$sIydIo3oV|!iX#!fYRCN_?kDkXxG6KVLA6Oo;e6cI*J z1pY_u$i@pu?mDRIuKEvMeQ;p;o(Zn*Xd_(R!eP4f>e0f=+7*|uS8Y#e>D68$K=9;V zujx=5lN8^Ic63~L<*Zp#I>8&_gX4biCy6#gzEmn-Xl{<1$s}}{@50VH2PbJq|0sbg zHX-^~PT3+qDq08e2sEUyqCoSetOqWNCeXpeIY`^W4~<9v8k(DU)&msvvNlvP_j$Gh zfXB5=7jv?Jm~NqcLe-RWyU)We2_h=k57&Y}D@0Sj!Bhd6C{ zdp02cM|b!zWH04&bj3$1JM3BPpLU1JYLdkN(vT|eFrAoYhv2L8p#Rfp_e$3aeTx!Z zz%?k*1vz_^^&;NbxnT92#|eFl_RZr7^Q#enn`09YVB(xI0`w+(P;^Db!Ocw+{-xqs zc-yPXt|oYV(@5#!R8x*aM)Ir=P)RK6LY9l-uD^b3VOc*69!L<+ zz@B?4nWRjYz|2by=NdC))4hHXdUedn=W2Tc#=;$mM2*pywly&J3M`|9lq+T|Ms^V_ zy|V5#t~Dc5b8>MrDOa{Cz@rB+km%L+sgMiWS+}@vkhFL>b9OfOIs38b8zAbRBOgvS zk@Q&mO>cYipD81i>p{(2W_@4CO6eQKi}|>#GA_%{T~4Ey!FKr%tUD!%*^f(K!naV8 z0FIu(NzalF6+LOxPoZkcuAdrxAPx?l78O(nF_}pRaLSx)p$egX3iiKX%*Cc@>Z~Tt z6N(c`t(y8fv)OW~l`t3)WG3%EKgldFwXzFWgbA6$7_mhJmN1Vpo*e0WE@)#cU|glk zy2}@j#t^>kntNI`7F@D;!R9Wc`xpld)v`Qwp?Iou?&_tA?;VHD=E0a@c~liizTu#% z2cqtVtpQ)lXlHIP<}|&kX1d(hbT1fwAi(I425{t=gYG~QA*{+x8T z4bu#V=`J=Pq+G0sTB{zW>IsC~sN8B}x!lSDVw(0-=AcYV5|gv0DKUaMiGGMvR67Cg z6N;|>8`Vw|ANAj>cAD@k3i$wDyQH04Hl4R2o9)bYr9#v^@QrJoI%ScpfNX`o7-gyw z<{as_wd>W*1f6ImsCiYZVaAdqq17QLaK{&qOo3Jh^@(Wp_ABGOt)Oho={T#gpziC` zn|q_W0<6)qiijuFN59ITdH*Kpd+~k3eXLIEJH(at$4X#+|u$CQP-;MSzemUfhb{3s-dutSm znHPS{_8Gd|oNgVowt&qYh0Evj7v99!h6Rz}xn0SX(fYn^vpv=-%gcIlx;v5axE9v3 zT-v48CHwkIbIA_`wONA8<0n#5N*5d9{e@6MT&ddohn!0ax#Ky5`D>mvVOntcAW z$YU8b7+r-oa2T8GZi^@W4`1ttN%Vi1`%ORQ_Xp8f?0oJ~kl+bmKgFu&OS6kZ=uYHh z5)y=|w0s!Co2n1UNW}UL!`y_{i{_9y1~i*5%^jYJk~M50*~HW4dU;l+jV1ZqdZtoG&ed6q~bd04ON*L*R0z z$A-<-%j&Z%N~&$?*TQ`OccC2w@|qB-fCKI23eI0p!@<2VSk)Bc-;ti1a{PJeo~m(* z-H7LWPkOLwoUC*){(ZZ4fqwV>RloZ$(x(&%bQ(S^;=KdQhF;Jfj-!rmHa-3LE$c)M&Y09PUHHN)w7G5=&OY!N;N;^uMlg zB2tQMWYA=(6*U3O(NP~jIL7YBCC-EJQ|$i-u#LyhgRE>Z{<8ECcFAB{OY$XvORa?Z zR-uzJj)hPU><&^Wqbt~Dbh)ZBx^m?f>7gI7l#R06d(dqu9iMWAuQN=o^dqO=bE(_K z{@LwwS*7P$Ti9?qoTY9Tu?=LVNXlmXF7IrXt_zwdv}Y)x;~v>E@?(W?Zxs6b`*`_W z^{;bfxZD7TN2DpX!K>#kk-M1Rwb$ilHFs(O_d>Uu)!(KDT$cxwS3Nab>*VIUU3Hsk z**{wWmr?p93mP7eQF?`ioo>JGD0S7=GPCqrEkUiwS4r6S8rDL-#>+W0Cyzfb{okr_ z!eTN1dv;~cS2yb9w&Tjun5w%D4s*>7SZl#LbL?_*1^6(QM*M9pLAS; zKor)DeGZcYJZaPM;)OD5)q>7Bmw7`s8kYX-0mb9G&Tq^+qI+DoT1YeekLMh+=?`3W zRe;|8=!Xu6>GmBzuA?C|{4ew5V^~{EiWh6$8mObZFbJqQ@>p|bhEmS3MbR8z4yr4w z(W1@NuHJ@T%Ll{iz=Q6{F{i1P&ea00qmLSBdipqf%HLJ< z{LcdB^m^7fG?{D1M+xF$_V=WBO)*=Mzc1ayAr9=9)7aI7S~>2#eWO~rrm}1jHFD_j zXeU=Dsga}VVKv_X-BRins*3T4>M8x^$6~}RE%R7w0@i$X(r7t4$Ua^^>(%9GO7AlO*r89SWbsD!baRisEtid91T`dNT*YO zs{3COKR|YyGH65O@R+SdfMX1`QgJhEW! z?4iK|GWPpwKc^v47+B-cn5br z*Uv`pp9I0F0Z_>V6t#l_R%MvkP}vNqtdNjxi%hjLSX^c`SUh0ihB0IiSXM~OmM&R1 zzc^=jCP9S*#`~54Qzj3d=17pDfl5&0FNe-*8#prnn*6NL5Aih{_hKGN$^ZUbN%o z=Q@4HlugeSU3}6p(ndyYlY)~o84$FO8Q2CtE3z@}#sIyJezAHh+zzt0f^&iAtm<6A z8l^GzNp_k11titxrLT=XK^hqk^pJS(KR? zY-_`{BKfvnY@#LClxcHXHOOz_eh3)FB7csWHxT7O&talL=V;lt+cMA9bxi2 zb<@->Z(t-=qZ>iR4H&NjjIRcaL(oFjK9a6=At{tBl6t@(%Kekr_XQ9h6zU{{ZYRU` zL--3r3ZvHL+%a$g1vdk{RcCWJhpvAiDcJ0=D4B;gOI$!i0=WmCEdPq_Z$|>(F`vn% zcj>(TMW_u{d<#cvLk_3RT%JIfzk1mxdpcaYH$8JkPX`iG;@056(qJ_1gVy2>Md;Pz zf{*ub%;WZURK>5bL13 z5h%@VhunN zJ-XA$3ST1T%Vmyyhg&X;F9Ga_H@**`3y*nHS?sZ1Luw-yBi42qoEq|(ubw#s{HH#E z?bH_yauT&vtB|D5n<~_eBIE;IO5Fq}M@${#)hO+`_7*7UQYMJ}u!5=AwpAsFmDL1g zTqMF5hQbGENi2vqX?lkx4*)`ejwOj!QXpT#LGJIuKLdD2*|RmJ_fy}Xlk88+?+die zy3K2yvAiF+^Jy&HDrx+k*ShplIJ@%fz}l~_24kYGf79OP04P!;L-N1J_;o>PDJgDq zz|zk`xytE|-}h8*`}aLSl;7X<-?`0!1^MYe$$rQ6cEZN{l)nX5U>tsxhvlQNR8eCn zKkyK_RoEF=PU^Kdp;=O~I4jpAJG2bC`QySL7%0k8ln=q2M|Q?8>V|?EecWOM{U%m6 z>Vx^fU@!e+>Ggy<4qXY_nP%m#b>ytX!Eh&K{{U0Um2A<92&8WB`Mi2Ln$v3kbyAjb zZ_L}H#?D0r#9odA?+f{7JT>$ElFgfZ*?L%p3=d)JFDjdYG@n;>R04xz92H6Mx+Iq zzHFgCJz(fmdnP0pDR$9H=!Juflb#)m;jw5NlEnUb@I~h@U}ArNd7h#F*DWrW>R#Qq zz$tfkEES5LwYarkms_)~Gc7VzQIb{nfzzWG52=xJnv$A()7#Jjc4e0f05Xi8Y}%#9 z>wVTb%a_ERW3}~lHHOn=tiH5;tjmgQZwt-NhNH!81wj`|9JrH^GUzRgwn4T{3oM~7 zA%efz;kR-AOQfst3-hX!Sn3`GLO6vZr;bx=*@eCc;&AK~F&CWis?xi>(W||dd~)}FkK_@r9bzar6w<+9)6Ep`5c*kONO`?1e&kbUOG zVa<5oY0fq27;HE%!%AfM{K_l-Fa91X8%BBOU(nm6KF7(b+^5vpeUA12%|6Grye6#R z9z0UUgmzH{Psqw3nq`k8^c1$LEw<$zK#rs&37-A0>?atCj+_E{VQT!jq?Vz_JLAdH zdJa8;7Tr{bN?HDXDL_a)-(-nYVstLU`+vpzw1m415@ERd*iue)T&hc3F-c%8#L+-u zhArCBmuNhI1a8w${h5FR@O^P-ll(jqJGIgag;m=}`w0oK_H4X8at}C*>z1Hn?IWJ> zDf#nmr{yfoShX(88`ni^+0!z3Zn*SQ77GIty0Nw&a!N#0h*RP}(W}&Z=7-8%@V8_! zV_5pMFfb6H0ZTt%G7ULe7em@W<{&z=2mS>ecZ;4wucCpCF0DY`5w%gECN}nWv>V>+ zD@BwTGWi7kz?)8ng;7U2MLokk!$X7JUClYtL~4Th+Mo+muR@mD&2ETt1aC$%!FWy{ z*F=KloFN{evlVlN&32)$%^eB~u2Nq|vOVW?igoO5h($I%@i%U0nib z=|cvVJTNe?(Q7WabZ?~A*XF(Mwi(3yW?a6ft|pm1aq|MpBj<)@*ERdR=MByF zyR-Cl@_0Rq6QDj~vUC`bXVMzH|1RFQNNvStWQ&ly9&#LQuu=KW7*u#@&(OdyxdqMA za|2Bdy@vQjCEug6*K#DJJirx2_71n)5nI*1dyh#;FDDT%>QGxcnio5uG4i*Zk$bFf z2ZQIXZ*F^$#PGL${>J)vJ$fD5*P?(YpE)G|iDNY~^vS^{ZN`#fh<~9s5Rc#0m36E% zF1|?fRST5A&b z#8Cfy5(WG3t}N-U@?QkDKfef-`qqhy5{u)P$#AIgb#+LnMT2!+0UPNkY!mle)|I3WvhY1*2$J41~L}a;|L*2d;^^wMCBjyHiqsF*7N8qy!O*(FV zTcCZ*DL0_FcGJ1@(ku1o$Bvi&z*5cqhLTQR&{RJ2@2+1RZo25&JA0cwu7>)*2O&$N z_~&`7s}6qpYFijMO10vP`PjkpM zf!Cw%5U_KgyVox89sm!$IB=z*Q`Mm+LQBkL>2`yzj%;_XJJJ+MH^c-O&FR3HCQXKm zEn9`02CN%xu*!SIElhV{7o^DCQTng|^SP73Tt)_>tP03w(z4VL_CvdY9c%AqC*}GJ z{Qwo)$h3qr+}==mJNQN>*ql()kj>}v%tJ+C)f)e&`bOPlK;aD#E zDA&~F-;{S!rIX=2)~-&}UvzCnVH@8Ioeet2ku2zuE)sVlq|vO0IoCrJNE$qE{HC$G zQEHl@BHV#S{SXbYVulVD#oD{D{b{FdC`Q{_C8@i!wWqCzgb8*JsXD7nTtafQHeJop>EWrtmYaPs{%Zd^{K0h^;cy-DReYk}v{c z3JS!8Zo<2AbG?cVj-gA#Yx4iW`+{_pNbmxgBM%z>OuJhfHmy478Xa(>E%*w|KWfxg zW&ZK`Fc;s_7liqTjxYJ9rc|asC(J*JLIR)5Gzd`e9J{Kn1|mPBw=8wROaAUAJ(>B^ zsY55p>N{njc}`dBm37LazzsNztw$BLr)yQ(a9d>XB|dkxx#yy~j(6RD$HsMT-Eiq< zxE@!JlbPoY2HQG%EZt>n#vPT^Z4J2?PvVZZ3Pk=F4B`Q)Khu|KN@w~j5D^3(6}gDj zSvgaBdAT3-?%N3%u&*>nXWNW1xALfM0Y9o}+gb-*=(l_d&}e+*>cclXeE!VicbMm| zMJsJIe2>KD&O(b?z{6APUssPHs>|5AW8c0+cFm$YPYL^mtq0x6$Sbn#8`Q*5Us1e= zmTTWu2JH(sVexr0Ifg9*xBd~{_e!`kFN}iZgz|P=daS_ zrq7=|c0vpJlaJlCZmBQi!?h0u`_(+KGg1@fE+nDA{K~H#y7{u5$+|rw*WG#Vthvk2 zqZ>hH7nh$GH|S=NGk*k#==NT^0Rrb7K~65t8G#X$>XIi&xTdSz39ZekM$E2Hk*>)7 zu4R{NmAh=9>=;Vw-1);(VdN*rHHVJn?+wOJ!`x)rKeo1Okx$&f%rETD4LFr-YPtCX zCs>}k1<|^)k$`(ta|Lt<5PD>FXt(U(tXvgcg`{L>lJw)qD#oYA)mZJuwjJ9INA#n& zdcoyG&_KL}0q6}CQ`liM zqF&e|uoTW7iUd;SN}ID2>iA-Lsz~^{=-Xxb_;@&G)gRepJrmz84>CVHp4TN0QIMHuOy> zrXdZLm)V@a{@YK~`pn~eDFe)X!B9rL1(pp&=Psd!5> zA1dJzFVkt5rQfM@m%iYNgg%;x;YwNDxE4!%G!!uO7naObnIEm<+@-I4lDq{ZnI8wg z2}%t(3fvcivs5)%-KitSgBvnowO_Z0<8E_$q z)1wm_FJ3^CT2e#kxTqB^wvVu&JmVHz50m`j9Y=4%^)QW3o?1KVbN<2s*3g7Me(6v* z%TFHI6Hl%>|E62%dYElvH=M?0Sq%+wqqC!Q{+zkVWZXOtbhQIp@XL?Ea)8AhK;#%j zqB7N^*%b=#k%~|iP!1Iq{irtQ9;FFcSp!vE-hqfeI;{I;v{-i^rxxpP>p#4@F^mX~ z-wZ{v(U$@Z@A7%%>)d{yt2B$n_H1S$hjO*)&UTcx!ZiqwHz?sGrv%uEM)`M7)yRy#mvkJzY`P9X^vAS7Wc zA%z<5W|?iLOkQmh7!+1tW=~Ki3jM^OX!Wd8ti&mli^~a|$e|-9Oz19*iZTadeVN3n z&h6U`EAr7(PN7wq&i+29Q)zDLDmoc5eu4G&O*{zD@#~XiU~^>k%4Du*-^E_@Jj>IP z&3N63c(TQ~pU}M$Ii%RjnL|AGG9oQ3&hP4woq9V0WKMahiIzjyu#*?4qau8p%Q6&B z)3$*D7>r2s=N4xTiug;qkabrgFh~p^_pF1M|H??r>YboyM9ny}s;!Is)e)H|ga-xA zmA4d?ImDwfW76TGiBm`CbkK|)nrVSxQjtG^c1a*6>T8RH3{`<{4$PJ=;EFkTUy@pc zv{ugrnxph{y2%@gmI%fS4m)*RQ!GL%#2;+5sEA=eHX7kxJe@GvQaS#am1Ghm9v5>oRojbcz7pcnk#eQUc}IVK0NgjbJ}AMBsiwzjF#y`oId7h&z!|qPHhq zNDi$?-o@1xFb9Vt4sRV7@I2qdZU8#{EMcla)q(w*4-O1gph4Fw2+YVS6(9_Z=V9US zISG!d2b9RE;2sHCE0wNe2ymYExV62yADqwxesK>) zyll)RzaYn4;`s=xg79T_Lm7dm!Q2RZT=rS8#3)AQF_=f6=w8hGyP(d!u1HoDcl}lqoNYPrlhl3F)>(q;BFP9bO%;1 z_jX;<5caB@I~PQBKQ0nMD#cy9D=c^QdWWkn`NiAiC-!o4Z- z=lKOGH}l)1K1jIuLEIw+O$yB*%2%l1bl2c?DGJm_cXFcP7FnoeY}6nVG==)X#VEg_ z%o`}F3-fz({W!Cw!6%ivC z6Y}TBLoc8#k99j62?jsj+AbnTHF{%$M~-M$IHzA=S3~4y&bOjN60frZzfd{9fD}MO z9jc$QBl_5ph$sw6GlvG!GkB~9Vy?m`ssz8V7YN%bn~GN6!QH?)i2RapFY~ZhL$4R7 zW#FLPzJvQK;jp}#ZKjNN`oN#+(x`nOba4@GKrAd|E~1K*Ip>_)*vt3$tBA8cp{$|7 zRgM@r;du;-bog7b+ZJj0!_aDwaUqI>qZGk|l(W5*B9r^zpK~ z>faD$U;o0W4VJaW^*X<(8I~ z-j<$dQ(rd64JC;{#O-6k@FY3YCU{zT6*w4~WE;zoynKH+_4plE9dl`F)XQ$cud16{ zhXYQZ=OnzWp6zd2cjRWR^v4F{-&IFf2V1}D##@gc>K%-DgO=YB3axKwBJMl9Yk2?e zWL@dGW2sOq+|flIRE`G(3E%-i0_I*--Wnjmv$uF=8+t2oSY0`326Eq!4|Fr0fxI8g zcufAJn8A4Nn}8-}(65LY56h2EdIrx~;WHZTU%8FXuulX$GXlszWP2%E{sJ#WOQQL& z_EG@w?YB5wHK{M$A#SsM^0sxtJJHiYZVK+NfS&@_)-K$A)2$coZb;HKw(wIlHkSPq z_>1nY1r$WK2Ehs08XQjhCc#O}AUKH`ld=da&!8MDk@4|W890t{;?3XT@N2Q*cYQU4 zfuE!sT?c;FDB%V^yhq&{ln2=PHvq9!1Xwv&E4wA&DM{mQMoLa7J0+$PM#QF)^5xWo z&5xAXRTJ_*yWp8(X;?D9EHNKqU zzAbo_c*}62>HqKV+X8IJueS?<(==jk@a#}#6`W%*KXD5*5a5J_`#Iq^MD;jQhpBl@ zN*>E(n3O4G`r2D-qh7a^W>AhRrB#&C#y3Y=WQB+IA$A2wh>PW7s!Wc=MoDEjfPXU zLmC%|b3UEcqo`g_r*)qwb$MmycEvrXE~a>Iy8O?qZ{YCPLe4sA6lLXhx}0@k0^18dCqWtO0dm*5_#1*T~m+EhISFMRMqZxe?}^ zxP4^}ve=TqU+B?5T_|A~r>rXSrK*~w?xq@<3SFjP6{QL(U@yMZ7-?#z42Z7 zLGq#ub->Q*g(#jXnswXNisp=+zI;``a^7}IS^voUoLU|AdF%6_MOUJ+Estx|c$>F# zLg7Sg-(}t5z=HXT#~MXOJG<-7w!xX_@}6%QSHP3Z^yUK%yycrr9m3@K=wk6^H%M^K zBW{pL**W_YZ;$|UuHrZ#N}@^R=-UPXNR@PH}k%Y z#ZG?-X(h%VmgnMgcIF2l-j4$BXHy4;9PZH*sqo-RXJ^94t25!z$MWn<_^J}(io>Bg zv^QRLJnknFe<|-nJWqdYFK&Om(Pu7eZ-T8rm1|9{?{o+6MI4Dao?nL#kNBPQJ9$e6 zP+F$_Hr-?1DkE20*MIy&2iofR9{M;@+{YjCxeTZFyJs=x^?d^Np~w2*Cv>VxrdwF> zbY$$FEP4jPrMS11K@7vJsDsTvO)~s$h#{T~4`g^t$?(&BLAcoFOY@r01GGN_KF2R& z8Q|sE5j*tHjSzCGa)O0PIZ-XGuzs5-0%=BB`jUj)>!W{7CjXO|qmSlIJKxI-)bfCZ}bQ*4HZzUZElvK9JLewKX(Jg+|OLJMt2O>1{FLF(mcP$fENo7doV**+`2@Zc6SJc%gk*8Qi6 z2C1@`icRw;Zl486s#wQ2v5qWdbf*HA0%sfUjue+qQLwNAMl?I61oT?cfy)b^cEA+s z;btzDDL@#7vjX0iFPri%<~2@$2zoEWMJxe*MjryR^d95R%L4kw&v*l9PvCNvl7`D= z{QTXK$cJ8~zu3!8SKzn54V2HCI<2Io9FoE8Y)EKtfEIVH0KEaaw3H-&IrplJ>nv3@ z?Uf~q^S0FmYNDL}7;!VvG+*?GZu)prwes*m?%Wc9`#6{zKsH@Z)%3)=g2_Eqd0heg zRp2JJ(}Syy6J;(}9wYhxk)EnHtyH>$Oo?f4rM94~UVWq#UE4yJ}*)So+ygX;J;Zfh5;T4w?I!2Zi zSMFpGcsf$>w0!UuN&87HZ-;Oxo~Y7|p9a2$Oj> z7KpzRnvTVF}B!3+zI|QkM2(Y0JLs%LWJ@z29^1^URE7 z*-6O$^UKH4%slnpbI&>V^ivA_uzbW^pnL>L+f=9`Kve$%mW9N}M^@9WT`Vq85`4wE z-^`7%Dlu81F`rFVho~2nnZ3bw3zof+W;u3XmjhPzM)2b74c1h}T1MfS>4(#h4@*qRHvGvD;hNR0)t$nCV`Pi<_ zfk0RM;PsDDP0Giv*zEUr#jiYyU($-s-atdhl}&c!oIO5ICRzBuz_nsE8j1Rr0oUO9 zK}~3?PP1qZMx-nU1JM`A!AKQzFiKWAlAMc@v^802ZI5G+pg^t=wiIQ9u`^zj6jpOxyBY>#GZTxu8)b7}{%N}^cf&VO|8=TVc`Wnlc@y1nSzUrCnry?&5!DFu z>l75XmU(pwC^sV+52qrjSCyMlHn{5nE^2ka_8bkET06~$`16-&h(nV!MBdlVP)nn9 zx|`9rn51^OkHIaCOu_~E8Ii^FGg_N7ZP~Whm7h_vP7zR}+cxdA1>SJ*SBNBJgjN*% z3O`8KV-9OdV4fTc1!lGrI$O*NAZL?7JR~G|c@ndsyh7&v;PI>Ax~8>=q6AT7lS&mK z6cR~&NH)o~*SF)2RB|X4pzMqV$+0jV5_{zl4#l|q5^{(;!6x=Vs6ToIfDfs^HXHMz z2&gK)5vx+WnlHu=e$DVDALerYeM5-%+)-h-*H5p83Q)c<41ItC-1wU}}dS&*4Q`4*k+ja^M$xa-f&w=ivp<-+*8Xy+iYymo5SZeahx?_*}EcQJun z8el6lR$L*H%srZkXogC{xwS%&yU1HZ6;dTuAypLW@OwFa_aOJ)&B9kFpQ2(iuatZN zbHi&(zLbVg{hN`@A}$-Q8#P3l$Ls35bn$-E>T4kOo&Ra8y6A$+_M^rsVJbji?+t5@z{z24c4d!0P{T9VuKg?dRD)HW-01L8-Jq^plH=}J68qqxUwveKD&v&G;ms2A zl(-Im-=l`^aydR698RjCO`A`Jqq@DK5`4nT`T|h3;8W*wlr#^6EvaGkaGoJR-ep59 zj|-MK7km;{U=s311qHpZ6(y>$B}FjpxkavLD_V9bTT;AfjN^Du2I+iM8N6taorl6? zd@5RNEfu8{IzA8mky1<=s?pWyuD6Xf4yYY~&RviV4yREHlKN(+b)3Ho!Y+saM-T>c zYt{07Q=6QP)qi<&0^K4|{&{rhv#jGK@SEs>6&&s-F}ELIRpZ3OmdRM%-<`S(t1Wo( zCjeeR`|BgTELVDdA_#&dMV`zA#82%Y@$~1QjqNQQa$0jOz;`QvR(k@6334YZ zrYj&Au7XS=Ub$l27oOP;+IR{L4K(8(qLX{r*WFJ-NQ}gYHogsMBn#T;N4*C4x;oJL z7R~|Kcfk^&2~c1auyY5CttFS2umjdR zE;ZT;_ul!{s6%sm-)`vK4HAC4%cbDoqkWmLy6l=q$FG0LbiLzOk3h<*!M+O}ie;Nz zB90@uShmUQi{lVqFuB_iv$xDxr^ohT8SP?ftS@Ek%xoNUw5!|aLsOV|;Y*!8C?W1k z#7S}(!h+p^wMq!E&PHgNC{+TO4A*JVW6F4REZ0+B>kAy$G|3|QgjWNBF^RVJF6kPO zpX5_(vQ-~(`8`*9ba^Ynm(`QHF1FkdZW(B*M@dm_lV-#k3O~}_C{X-Q@Ta4uUg4Wx zY3Z!NxaMBMpFd$-tW)kHStrRAq2l<+$0mx#ow5I=D=3)2}&`UwKj@W zJ!+WKk@`jug9tXy>~J$I>4a?!A4STE=J^uSkEeGS3%{h!njber~IZkVHVllcPpt8{@%HO!Hz z?VchOqG*P|%8}RR3Kh4SzRm8{-mL`AEuN{SSK$&R4rB*Z$rspm`CJn+uUnBMtn6!- zANfmW#6CF$iv*7yaDM*MqK?77)j%6Ed0j{7gIvN_auMEG#FT|@LN*Jm?h}~BfN)FR zZ)KQBt9nGcfnl3TCh20fKLUCv6RA9nq%6-QGygj5my2FFKh>nSlxlLRAc7JXVZfS4 zSYX@lN9q&;2$1)EXTZ79=>-c>pjCKNSuhdunUVxepP7^w>I2I&alFm#znj7b$cZXD z;6(k~Nn$0F&y*O-(<=!jR{o6_t4)@!Ujj}o0=k>93={78y(qz?OmxP@O%>${CYSL4 zTJj^Y$e`r~{^6ot;Hd{`)iDV%3Bf0MXCwVhl30ooONQ>u}lw&J; zg^)(GAit!H17=30MN}Kc>!fR7u`3$7Y0PA)t#ZS`Ny-ej>e6T8aoAlDeMC9{H+?gs z_;o`}isANLvbGSemaMmz%q%G%KMb^8C{Hslv!s0VkT)&oEZd-@12krnIn&qzG=bG{ zHkO7gew~Vn7q~&0oA0f<;xIj%yq0`!z3@GvN(BO?T11{yLZ!S&bh%7YN%GYsmEfXc zQb~VzHrdOQN-^SI>iU!T-eqoOu^pw|~s;&n9<{M5n|qhzH<%lE*xad%|> z;Tveh`XFOm1FQ=R$$U(Az(fr>4Z;L`=oDWUWi??@v$i`&HDO7|qTCS35Zt}TERiCc z*Kt&F*e2GV49RUz=%E`FbOZPvk@xLTivG9w_cnVdSojz8iBOT^UTFRsCgF6MZ*L*b zV60SDPhidoTf%yyw*XOk^l(`N;YelnC zUVtWrJRB4UL6R%{!lFb;u2hfmATk`7>BY=oOqX8<%Qoe=UVPnb9vNtOQD0Xmm+FI4 zo+t2_*1KF;rb}7qKi_|Y6$l>Tq~hcOFJ01&eCHqyJsD2w=C-0lyc@PVEVpA!8l+lw z*i&SEP)Pv+?qYy})5fE{-%$E!J86|xF0BkRFXY2sd%HYJ2M4t@a->bm9=u#s{qQ5q z(pLZ)46)yzoul(V0Kfh)i{-fv(}QPP9>b?7^a4}%GfY9Ah>0nSutsEeRBMB5g zE(c8!M`-@9fFoNuNIEQu3t-SP{@yKXm?M@7*uoK86U}tlD2wZjmT8A^hIgpO=G4+< zk<8o3t%dS)A?}WarIY&X9%3`x&u1t-%;K>4af)5!$InZsZ-MK1Oe6W~uQ9KG0H3gT z;5nV(zQw3cD>DQhcogK?5Az+5<%F@LR7!zWV!kMNU)&(aX|#3Hv%=!(-Rb#mJ0Z`<&EUcAT!~ zv2N$3l5gnhCR?v*i;{*wQ{Jb<NU@<_eNe&=x=bx@L6uOVsfg}FDQ z`ULqDn}q|DPo*HLq-lc4PS{^owY+%+zXVcCvS5`3k?IzI3;UZ|=E9t7|#z(Y~k}R~_b& zhks#cUnF+C8KFNfz0`GIKZfiA1pXV@E6h$~sVRV&l?rNQ4&o5(G!)`jWSWd$T9V_X z(yQb0FL+J;A0NiJ$bZrOt5R7eUIG(&)v!~FcbLUNsGK~n-^MeP4UMH#L({}qTd_Kq z7%LA8;ic{W%&{iO@a5Ou4VxfyHJE{j0C3Uyz=9RUE@o3w4W1@Ie$S%6frNC4YO%^x z2e|`wCG?5`hQYfd?+3gcNXkc-ZAgC0Fyy)Lap#0 z5s`|s1ffI~y0NtfKhsbp>DA}NzWawllm>IB=>AQ_&|q1*4HCX)oMqoV+Rj|Y782cJ zC8o&yO6NdP6XDbtf$%l05B7Tj7d^* z63a~fUEPJ6zbLN0Zr#$Qg0ODuy4j^`m#&#wg=a6pR-H|xds_^6+IS8{@2JG=Bjh<^ zbH?<^FIidUXtUA}EQtm|;z%}kB*h-obgrX>UL`Ji!XXEvvHAt%R4f_x4^p6VFs@hQn{f6A9Yws+V@wr&o&;HeVnb z@9eOBt-nwAD5ybP32rtl{90Nm4I%;RA4E8>V0l2E9Uw~}d;rJ0$oAWmjQJd7X5a;( zn;8E2cI>eKVAs zJ-Yp-x~MY@Q0xIJh5bucEth@jN%-K7#;Tn)IDVxx=+$l=JJj@1Cu$CA%7vAEDwlP$|r zPM;i-t14Vef(xPIpV~3h=|QJa zXagc)g0vBEjtYo)Cl4=g*49jeZDE=dcII?%x`ZdmB!*})_&{$l9v}{eLJk7G#T!9%GFt{2UD`2XL#SpQ zlbey*V8P4~+&!|ZJWr29tXjh)`JPN0-!0&A3O)G3OL!z!12U)hh5wn=5TD^-Z}o;< zBT~>>jVWt2(wANhk*&t{7{|Okh-RJ#!Lb6>3NyJL!irK{KPat)7qlSkmpSKOoxGmI z8nDL_Y?7TYc?6EY>#bajH_te^wVKCrc#(OynR`~xRk z;~4TG41Y{Mc(l@Muc`LLHJ7BQvezC;jZLppZEpK$;dkoJnP^7rVzHIq@Osu?Jy}^3 zPhp#It7~htz=~CkZK2`N?`XY;gkOuz77h{mu-(6z(Vc}uy;cH;nc%TplZH(k8lul% zL&k^@5*2>J;I?k=4)k>jO>PMJ9V;^czOG9d2R`EHXLK6c``vK0aX z1;1_;Hw4x&VqLQ((OiI!39I!1nge7-(D$Ga7Z8aHk~KLsD44U778yJSXX~)Nn)t$) z8B$djuxb_-BE^#^^-HqIn~v2w9rE5cVKnsf(Vw8B=6K=1A7#AjXm!HyY+_A=|5sf~ zX)jPfkg#s<{~!jGY9EYDKBX|m44e@UV*p&NXr}lTc)=v`T=_AcZ$(8O|6s{+|H zG#E08uw8{SV_-*e*QOB{5JDrBmU31{qFA zmiZWoHO0_{xYT&SmB(The#7~YdVAKEiLd^s?ANY$>C&gh%*7VRq`}S8=~UqxL`J~2 zXT1JYec@WoP{CuwH)G)$$DI4GxjV#0jCej5ZkVts zNy~8IX0nXV{T`tBF!uQv!|1Y2+@wz~KcW6WPddliXwx9cEE8NOT=Ou&E;WnjPE_-8UrYVxtp#=a*e(2-49;plAb8 zxC2`@c5t>7@HPx(ZP=`NnwryY3TR}~HmNCyHRAXqoxv6n{NUNb@9dDY{V0@rA_Deq zxXvo7dobtj#)wbR_EmUc@3~N~Tb)7XMOgfhPlm_JQ8*A>G5p_HNDN^Wcp+g&laR>Q zp^rKQwh~=ooWPT&hGeWdB!lJy*ac7o6~F@JQ+!IPgps+vH0S_{8qODNMvW%wVp#92 zZ*!8J@40IaIc9)ON3p6i^3J8=nJQP6U9o$qU#lTG9pk;x*rS?f&(?UV!2R;?_8S{W zUJrmf4PcbLM0KbN!0PVuYVx2w0Ffji(0*@sb3-a#9U=yG`N5JHStbvWAj$T&R@s!imp*x@)z^rbyi_o5j05wkoJ)K8M_8_z(v< z-dz>GA5+*COSR}XAVji0S?RA((f}kDN!N9mXgT!{W`+(&pgjjzs zAwmcNCg#dlR$431qdS~tow={rj$qk+t{Wk1H#81tXu^jwp_*J3Jh!zKh;Jx2oDNF2 zp{KfA*MF&xc3nm4#Ie2S>IwzbhMvb56VL!=p+SUIfu|-=>KD;Z6tu)5VK`sgiD7Y) zrV>c$k&>v(Jg$TdCEjKY8e=w*6{#40&!(}QQzRQp;VLeHtH1afJlkI7bU@jg^TRsM z^`Ge_*QT!as1A8O@wHjaBi^Sv6wUv)^)r3Yd!)IaBG2k!j5iK#A5bK_KfIAwV2FGl z7p4-4L`R}+q=$`@+IDc@@ddVcaFOVpxMDu@Q=rtdt!k;qQQubhZ?^0KRcyI(7u(7T z-`AyskcF?u3Hm%{(4OV9)1FluNJinrQa$U}H@4A!_Hjr7KW0L4EvL8{z?(}Sb?EbH zjhZ0<#CIHEVml!Klg$^GL&SO}Bfib#mhXlfLYoGY${`>!F=XwQcr)z|SmWlomt-9< zLnF|9HXQ=}h^tUo10Psm)Yd31Ff9Ci{kdLJ7l{#}XAVf3HYjUDUx0|A5Jl|t^7FE& zNqvE9-o9z~p=0(5j0d@aVL^V|7wxa6I*ST|<%C4;=DzzAd#tR6YIu`)Bk7E`seD6h29jgY&r?7)mGmfNio1@q^ zmtu>1Z;>-49ZUucraA=Kn0gW ztS(QpWm@U(M$Ge)?y;eMm|)1n;`%d9EM`?BYx({hlS|=oMbfZl9k5B!XXmT8!4x*= zxJ_q&;1xg*cu3X+zvmeIekt5D_ftVBt`4n=0Q<;eked?XmvD_k`sMa{R{)kJYeTDm zPJ0Z3qTR;I%k!%Ej3r~QtE&@)y4JepYzn3cGC-7|m`q;60AVv@11+)Z6%7)FM=t^o z<1H6kD1Kf72F(=8I^FnZ~g$vE7}4I=gV*eW*hC2#(~0@I7$E>fP!#^}KIQ)Db9PpI&rpB5OzlNs(Z+8FK#H=4vV^Um!`dduLOo;!; z-y^(p{(FF1CEc%2nC9AF4R(6c{%pwqv&nmjoY7}ll9(1)&9%Tq&duh7jSa}7YHR3g z%t4oATA}kbXoa$cfo8PotJ4ynu!xiv0L1#rT4UjFN@xj;BbzB{Zwc`m=4y1#ecgoQ z*EuBT{(v*2+a$z)=CGbwxEhwmkq}8Gbb=pOEW~YL0xOncZ~FEh*)_t;bKf%G^euDE zP`H;#wF&VB^Ev*x7tCv3Fs~sx+QXjn9X^`XUofxuf;ry*&yM4@=KOGAs9S;~>?l8z?`z*Z9+M`E~j5*}t`fiUFxdT{XY`~8# zS8BnK=}G3C3fWyr-sa+VWr)Jz2>@Ki;k_H_B==|{{MTw|{5QwDBxqCj=(^oC-JVyZ z=_Bw`>JI;B3%|nbq0ngJH%NH3`=55K+U)S`d3ajwTG!A>V8_^eJ}JU-0f59|LJVQYfaMGQG12S{NQERR z8`d+N4+|1JYnu^!g|l{HfB9J!Yn6!OanW=VUT`cq^c~il67*noJhqmY$BD{aIT0?D z%ED*i-U-QW@szLfgP7BXEjnM{*-9Yexl`|MGt|Q#ZNJwo-tB`s0-fEiRE@(R_3-yV z70$WevCba-)JX!XOI7}{o>)~{QV_{$L@r3>c?@iAc^k7OtTaJCu{3Zrbfi`;*^#=4 zw4^+hT+sN@Y1Jcq_SA?3E&YDCAu21HmZ?%hraIvZX!oj$eApgxi;r3^={fitN)oH~W0;n{ySB!&E*`dN(l8> z91Iv#rs%^!fz*^_a)UxD?}oy+fiu7qO?(kwDr~;OUwNzVa)YIzsy?+@fdU_@Du`8p z5ml^x0GyusmJLuoNR3NEy-lb#=yZqBL!>P5PIu!h--&nH0q<{XOD2&xKhW0S)0J#Z zwlrk%h`8UYC>0hQdwHV_#?edzq=goK6O;r<%Uw_3zjouOO1kMOf&sWyA`M7b13!IwxPGGdi?rjS4~%kb6ZENzEvR}>TUIC z$@<<_x1OwL67k&2; z=-f+q<|=ky?M3H)i~Clyb5U@}dGDKh8TTz^=g|F~pDVr(QmNR_&JkywcOUj`K^$S{ z;tTJCE=kX%`6aA#vNbGKY*cjbgKW$R>#SUw(N^617Irp?vx*4~g~_{Q zYg`W-$EP8_rKy&Bq6U(HX(1 z)i5F14d3qNBV&@o?b|caP~&jh#bhXK$A{1V8yg*7(bwr$+S-SgZwps+#%-VIccZxBc__wRGl!uL>dxmsBEDO1qnn=@Q_;u?zJ-N1yswNxA#iU+oDE(5Ny4kObF zSD}JeU)rYfVEUpMXt8`I1$HY^(;)l~jtbd*i{>7MQZ|Nk`mx7#^&c`eC1tni>IR6{ zg|DePM)u{oX++*Y&3HHeGFEDwq7Y1Xxs*&^0+&LHg2AND@7c z26u&B_xh@%^{uK)vP=mUv)K>vYk(9?)t4xT)dQlRFC9Il*oiD^? zyK<+nPLE%@E>v>#K0y`hn(Wv;1@uVh1I=11b+zj#{#q*{K}$*~&S0ljb_( zoI>Jy5+ZF|=@t_G%WmOoEz1|()`HtQino>INm3DtFSIbF^uB!OBKI&E^wKxYA{!p5 z`EZBzB-0J?3<{B`ObRVW9czar)q(rza;1eZ84~a(Js2eX=~Fy*x8e0ikQr_SDs9VL zir9hpwCC8mc+`8no@iA|fAjjDC+nIS3VB>XKLYb0U!&&ETTw5WAyS*m*_usFz*->9 zeHZH#!aCK!LWHa_Kd7b-HUrj_&LkT2*n%iwgY5wPlZ7tThqK8zZmDi?6!|APl8Pdy zB_ovtPLd$fD`iK0_0>LO)CF-<7bhAUQB&9$Jbl`O&%& z2+Ye0CxA69e|j1fC&6^6CG6HRag#uok6k2@PS3vtMFP|5>S{qqx2M~h8md#($+}v+ zwX#t$0S$o^8h>%C;{1icoMCJ?)a5Aq9?2(agQ-=$!vm6*iZ-n48w=Z{3co*$vdDft zW|Kn|ftYNo3Ow0SAM5rSvAX_LYuf2)tEk8(hEm`48Xlj|V|X7z9=1Q=^^%Ks?pJf0 z#flU9y%Fo)GKuB&$WhBMs)tND>S7se5@+u;6>qG#{A>eBDJXoOMm{3YJSl@uCbJMPM`5!MP+WipHIYF{<)TDRa`rMqe{ zLa#Y5Bv9e5g!nV_u7L%2afN}s3wOhQk{UR8Vnla z{9XLwr{yyImgioUD8`>g_H}kwT)5r53(^&>*TTD?|6eQKA$|lMd~)Oo%C&+IWaH6F z&FO#&YIPJKqbB9p3i@Cv4+P8PHRb44ZFJh)g3w!loBh+}sW8}II|tR#~s z?KSX9REkGY_0<-VRp;o0&0$~RP*r=A14-gbRC{WL9s6S}pybn%u|=}Mfn=9HqB^H+ zcBd|-baW(jxP}#1!!pGq*UPHQIUEyJ*JeeRE$vEi1Dv1LC&jjRQ^DWlaN3 zxO^F&wDPq)X&F7FpZyWHE^q2@%F-WhHxz3n4?Kc(WGlB}dMs>jn8aooJ!@onP@eKa zp7GXsYpa5|(A`6}az7S@vje`dN(+8(Kzu!nICsE?Q-kP{J2vCf`c0qWP6HKv5VVFr zh4 z3Um&TzZ&rtZpQWUMXLQlBoHs)DIn zk@==KEcr^m(Vq}gRZqbTT8*im`YD>y*#gIrA1EmRx^O)gxefmd3kg~7L6Ut`i5+jxgHX)A_`&dSJv^J_Pb=u%h;sJCP2 zlnZg@M}{UMj}>7cvzqZEk9Io^^meS0B-}l>O8m0qu*Sqzh|p)4sogA!c2rsna~8%0 zILyFckU5KE5uaT!2t?D&8>EB`c55IQAclqkVweoKx6*^ChO$=p6t4o?NCq<5 zcG&BdphIidd0@^$?PxUW5%wD{iO}3hW#WdRd~=bG3XjRQbL}!2Z<}{1J%=6% z7JGnh!?JCrPtX*-5iRPW8$<7-AoZNi$BMAx!! z7PXZX$gnW7sALx_Hkg@fIdll!rOSy47Ov`3w=}OazwJxNUS%V!zlpuYZ`M^a&1=o8 z_9kowu0kb;J?z`(_cZUxx|JOsb(8A3iT&NF=s3XtE_V2(n*ar>OecIDG;PJXiiike zbcf?CQhX6QvujcWNJuP%eH!W=gnoBWq?W|`ah-uJv_lvZhVuQ@0CJh_qG&m1CJeZ; zY&IT`G-#jd?Cc!t9PMqZPqvXu2k<8OlmBCOPevL{FDqF_ag6^0FTOvvYl8<+_M5g63@ zk{XucANdVyc2+5gd(lknhDS*tLM%H2ALAbAQMU} z7fdVp8bBgBOH+H*;2;?65I-&cUtj=nMbsg$CW1rc96}|C;E4K$#3BQ#tf1+3v#rb8 zxiB5tKPYp;5^U-B4kQA4-N!)!6Rz;^XYk9Xp8yTeFY(inZ+LtVJzU?2l)eGbY&21f z#!K2MG9f8?#@bCW4lIUO@GzOdKkt3>Uug3hW$*Z=o3bu{Hg{g^GxunCis7~cf03^! z?bT(od^H<1Gx8ti9G-{^oL;@-9`tIrSNd**f^NIfSF=*w$+ly@KhL<8=RHB)rTtw5 zwEWe%C!}j375M~To`or+&zX2U(@Pt(gX;-JH6fX7gh5O2)?A?|_6r50X4fXw36n%y zHJk;mKYblhEOS4eJ1?CDJ2ZsM(~f-;a7>bH#P@vSo#N^;Ch@dGm@o;j=(O{552~~g zlL;a7^TNj_Sym_Wl@j;)_FNsf&+nkQ(uncIb9mzM`lLjrRKkG-Q%i~3@r%(pVySPp zX|}4`fqEq{w4uKeKfoJRpxjm9ocA;h~Fs>dcb;JO1yeOoim}|I7WblJSXO<%>Hd)7H%KdC^o6Zs~oQ8Hptvk z5N(O<@49k-x+U!Gtgt)WXqBEZ0!~MG^UmAHM7OeA(M9{@#*rCA>&r%>$#`pvP1Kd$ z%%=PN+#c~+%%`8`lhLqWG7>UZ3oF(y|u8VUgZfgKbr+IUt z6FrzuN~;i2gVyUA3Phi|*?~ffK}6@vn2j5=sdgwWZ8m5S74X>GW#^&&nU-o_SA|0h zIBZ#u-{q*8zVBg4SIZ{TpRI{DL|U6clbDU-1}=Pm?h3S_pne?afrG)5ReC=>bTVA- zBy+I9Xu@n5_2cOtyHZJJt70TCDcGzZB-SOF4C&~J>eK#&Z3EG|>WRCK;~RB^{L_0p zntXx;plzDx!fhVyAnlIg+-LCi$E~;HRj{qf5?uT^x0$GG2O-M*w^Kwhz00zi6|-Kt z#P?{@vv}H=n&rjPk4V_+3ews#q4Kj z_An}fg{{Tx(U2$CJ0*C#zaIRZR{c z%l{)wP17#Y9$0R@ux_wgQ(L81MJ!>64f*cHlz`ZFum)M6Ic>9iub?o_=@pmY!sSj z&(H-|b)L`iZ z%_HA+A$?=yJ6))AZBhO83#lG-vIy1ZvY~WiRaVGhIpZHD8sGnxEkm_4msyCS0s)b}e2JABFo>RPxsv0wx3u|I_DH_!X6_b66dhL9Eqc5xkciwo$wS8qp?W*M2W$ux8i#kjW3KT_y*2>g`JzUVgsyrgV)6y8igN9UlC71j*4Dhh9V6U z5^qs{>Vf=()Gx?SR5=5Icpv+rp(0cXe|W?lJz0MpPZl3BpIo^5;wOtAe?3ngw4VIj zf+r7%0qI5YBd-7rWEz^5tRgg)5;S1LA!(9BLkzIUEe;M*peKi4$CCjK{^Y{d7e872 z{Ofu0p!MYE<~>i!$O-p@gx`|3}S5r(~R3 zM~TOVGUj^TigJYTxahgKYEFk%&p`R@59qQc z`(IWR5$Vz)nhvV$m7l^y$7n)cZU26cZsQYj`#QZIKB0NXbw4{!(i2uoyq3)jIq+C1 zL};3#J!x8X4a@}kXRW~{0gbl;p5j*aR`3th?kT<$xWSCx1VA!+Uk-qm2GS)Vfwe@` zzQb;L zEciVxD@rdef`+gV@DQii2!MseEC>gg9bOy~rqT#Ahr@zk zUN+x9%zKsiLh;#n9%h7ICNv}VJerTGijbkkeBOe&%pZE$Sh3p!XM`VI%1@AC!@CGs z7U0HTq7$x(3|ABv&vD1 zX(s7p{DiRkl57(D;^nCPa%?gSBMioTdIP3~F}qxkX_991nQRhV-_6)0Oa(6IW8k26 zFJQ2?$oF-XhV6RZWQW%Ah3pe!$7+cu*u3B;3ZnM;0w#$h-OH`drB~pRU?!>nG{s%) zt)NQe1-Q_LO{c%+xo@Oncs&psLw!Ak$vC zIS=@O=SubLx#$~{&k`JqyqE2w;J%gzu+n6E7r&+C6>vD#(NHL>AL4 zTLUo$vIdrB%j^Wn>tUQinA(59NEN{6Z^V!5>JEzP!5=^|IQLFzT-qb#h0}Q>2<oj$s^gr6&W0+qs8%Z@&WFtC0Eu)EnN)Up262VVks#YwQzs#ICFR13kz{yN{y{z{49*( zHu(-*gSBuX^1pNmd~TKbe11)S^@?R9L;X2wnp9nh;`*>8Qcx8Z0)Kd!IL50hD=8|0 z1YfhB21@|2#9vCjg2gxsaU+pUar+QLu-HOHZCXxucp6hSeN00TZfbCJs56KDw2mg5 zp405^rj$(^NAEC4a$sz-)iLHXA`5@j{1Xk#G<>vFZmVy!M$ zuM3{ImUyZnJkrb0IGuFH>AXMR>M}AN>5*in9r*18e!pFgLEpbQ@2N+5a^#^wfCPAe z-hPJOaE{sJBVcAIvrLU133(3+2#ytJK>7^5MULL=N|tzY*-JTkPYJ7l+^K$?w0*f8$YJx*79)6ml4^?&E^ojvFU zKF`4V=Iz_qf@Vp|eL+=fN;dX7q`u`x4>>O3RNTyP%>gwaw5r4xQ ztEx8~(w34nW0kviX#({M-Tq*0wAN*-tTlogQPX+HA!UN>he85<#;DWM2<4anZp07J z{s3@AZEGZ^Ai58pUw}~LJ*k+#(Xk6SxWqwrml0t&-JR-6raMwO4K7~6oFB=noX|`C z`G7~Lw#27-2%vVCVgn%g`8Z&mdt zA3Xh5ZJ5r0K@3Z=Cm)f%)G<5Y^`Um1kxf1z8tO*XNYrdvWx#`b<>|u*~owNdkE z58Q`I&b?)>PD)5WK^Xw5$d8N~i85*gA~EM)$|&V6Nr#zp3$+5$N%Ca(P|g+1T6_w< zrQ%5?zcpiUSlpt-%^I;CP3VTT zHFw_J44wawW;C^l*RUdo(F0ppwWZo-#s%{kw>3L4QzTJU^-<0}OHOMpAsT|J znwgmxglo_>)zd8q!-L(ZAVUQz((w$7oNz0wTVYwegav{wGr^B>lw?_1X2x7Zp2C^I zi5xr&tIYYXQt2Dj6UwSB37{PQlV5<0Q-=zAWBCzK7UT$o&mvAu zw4ZiB>y>N*+%*t5b|REgW|T4VgubBEy%;gy;Q+ag{20PS80lDQcMe^yi`V5 z=6ObKU@ex5Nd~sWb)8jo6qg-4<0987HIEM2wm-WCGe7ySnzR(8hQKAc<=G?EBe055 zujbLf%3Jpr9^+NmW_Csz_aiJrJ;+KQk~o1ZQ2c%I7|P&)xfWjBacu{<$;)%Umwq7q zov>c`8D;I-9it)?AM8maGxP~|2O_bK2$T(>D#!&;Kp5h!V60%T=(ItE#X_q=m9V$$ zLP{wM9|2v~;{JYqKSCc~^8@n3ujyXAl}4cL(nU>MqD_HBLs-uB!n(;7OP8dRsoqq& zKACcZ%iB0_w+N3Yv4o!Z0r`S&bER#dlrDp``w+H4Ci<~>Ev%OK=uig6>u}2L@EnFT z?_HgQXWM|E z$Qc);XQaC~#P+gX;qOhj!uL#&l`J z(~30zm}|al^*2gw63;VT@uUTT_0Q zWeqTELn8jp3St@)MhE)h(X_oRp2nH$Wxh)TY4YY5w)J6ibn+c?6ou8;R*7airs*aw zJ)wz+7gV1PU4sFuAi8VN$(?58)31r+#C86B#jnN|@1VpMee zh~_zzlTKkMW=($gN78Shhg|iS`G|w4YyEE*ocq&RJij_iKS|;U?ErrNWZ1xfwg_^zJae6besZnEi5xR|ltKu{%&_-= zH8S{MwatXRP?2Dg0C`EmIjUQCJk^?NCc`OLb&5gMv!M0T2jH-H5Ww5=^kzk1qTlZSBap-h$$P1@1%h6xF zmqcBRsBj|BEBKck5zzu{15p6}{E_`-e}E5$5JY6i1T2`2PoRJhVHByjMLI0|##Ase z92cQk_6^eFfMQE_f|rsce$}dXm}L2ldT-4#MX{y(%<&yr^*;04i}gm$(xB>eI?=8c zBRk0knXjghFVvEwBkb=el0smK5z-K)-UbYbhIAA1GdDpl)+fyWSb5_471F7VDQJ|u@(tzJp~cmd_5Ij;lZ~~CvriV z@!gRW?{XFXj^1kX`Na3@4v5KBa=`fQGsx(~s0<~I*HQ)8m?wbO>dH~W=eqYkN!8I+ z;1~)%O31+x&^YU1p%(kA>wGc_+l$E)=J}-15Q~-hq^U1Np9$E#>~%l;LJ%Dw4VM$` zl!FxQ3m$C^#iZj8 zMn*C8gJmPbXxkY`2)iKLSP%g~%)upjb;lAf6aQ8%JQL*Lc@qPV-@yio8mUTQ${gEi zP$nDOxi8p1qWfty0oRA^nlc?#r)SiFQ=V3}`C|jymfEC;z`MJsiU#BH;3OEc-Ek}U zJD5BC7t|8mxkG`0Y0x>9N(n-$E7j55P~`aPtK|3#0seJtxYW6iX!U_QK$UiY=>6=7 zPrILv%={As6MTvf@qIxpT!$SRWq`rSA0V#s0ORLx){JLiog?m!KbVw|5H`Rz>p&%= zHNb}@Ej126-OoV|4CHyp#K=t)H0=qHIh~FLS3%;$9rLflWiyh`v7#;35wT}7flw0J zqlVB|7}|FP_($1OUMs-dr|#cfE9g`Ou0^}=?9weCdu-(}n~Sc$z00Jsk4=7p@G zF9DsA?pSz&XUJCw{+=WiN=jiLm|tWB3{6Cbs}L(N!WM)4@Xc7XP3RrHk1=_V_D@{$ z8xsCeLVX$`D;%Pj)bp?epw!0XQ>_qlQ4S9VwHfdTSk45poWV?hBxaPpSR2kG9~48Q zCT8p^pyovvadTM~h1s&HbcO^CvSUL{CqgP))kW89sC>ODlL1L{6c?ioE0$348J2HK zc83^H%Cs#&Q+fNEti9rfD~C4JHFqPs2)_b1UD-Dit?ymlGO#SHw8t|8s+zGVsQM{8AM ztyH}g`zd|9@bhhlfOc~~!k?4UTd+q}f$k6jGN8$Z0adj|y zUCePv!mbw3F8r1F7yl|&d$pwDma60N3qPaG{-ov=|4?`U^Z3qOpY$CmrJBDF!6f;T^N$n z@18^FOYEyg;d}p$aZsjHA^BxPz1D+^JWd4p!trRkmb$>5);!&4-4YVNsRz&% zQo5zmP^S?4ItZBp6@p;t8^FAykTqTBGj(2CHy#KHYO2g+ApZin@s*ok>0L}Q2O?Yk zmaYfSII2E$LoBFF^s100?uht?M-}MLZ#vVJQyr2ty0*$G*+$iaTf>o~r`!X(+g+OC zcIWQh(>0Q+I)41to~97o3!_`Z9$#P>tMTo*e(6qRd$tNY&Li!pjFXt9dx(2LQ-;(o zz`TGrP$7^y;vBHR-)f!(E5S)-fM8c}HiAa3S+tPpAvRJT)kmgd2=f3V(6(svvD``Q zfOHeJfbwZK0kW>x=6<&mEe@fBY0~}XXTO|^rbd(j{6v>W7<171&`>kUxcE3p2GYCe zZ{as?cP!c2gs%0_NbHDFeOd02J}*$Gz8s8~+k_A1^&TAt*4YV^rX!mVvC(FPf}^*u z%Pzv?D!3Gf>mXDBVHfe$fk}_3DDrM}Yv#tUa2|^4MVCtwG*P+-pc$CdC|Qx+=-iDx zhIaYceB1KI^A0n0dYzRz zz3%CV!y`-a%80{l6XRmObiJY{@2#7Ec6O{=cccdLOY+?gPiOPl!iOm1x;*n*{A9SI zE2cVP;b2!xOBI%v-_g@}`_@QBcb#gFg)4FqEiE`{)oeGFt=bM$#<)%RV&216?v`t2 zCTxguGS{xtE80CGf)qsf?Hs7ct~u25)vIs^WK=re?N@wG1D;jnkcRUEi{3PU4Gp%2 z{B|eZE}QE(aNTt~cb3-jy4$Y1^@fu>5AVG8;Qq-SliN3Myu`W&|7X{g<-yNK5pn^} zLkHRx=N)*RYcFQ!<3izo%}0h)^MAg6+_)^N%*PuM66$(sJ-p+u(Yk^jHl);*)KbQk zu@6~$P?GVkzeiv1r=Xb=g-`)&GmDycwb7tQgUX?AhxMYD?y2A8vET=tUL1rlD1 zupeUbmH#7lmwC}1Bq}5?(mEH~U4BdUmH@M=;8WWJy9<-K$?ih-gu)3}Yq@2{vb%hT znOvBKEa!swU92SI=u)AC{`ILeEtpVFN(vGS4vvM7bK`4a)&(;A78G=TG4^h|! z2bU;7X~^PQ+c{jS+;Q0}vE}#YkSLr<;7?k0QMNFt4J9%veS0PA&I*?;*#W!>R( zCF{;|giE4HBM!i(d1U2#`I4zGW_{I5ms{2y)gbGRYM9m?S}W7uL)IM$^4A?wkJJav zZoTkHzT>MQ%y|?ozY!~vryml2KpsFa2nhs;rqLk>q1ZKTDuSxeo&tl7q&StmMbV&{ zYL|{d7y!g5*A*?n9WLjsZp7d!ss`5)if7UzAXD&N$tke=Q8v3ME8rQ(!)|C0gogDE z>!wyMn;04D>+NjEV6&-ADwXwsJ^3v;8EQ7v8|tIbn_H-7lZ@bawHIE^mF8F*^t1@+ z(W=ucc}e?juZ=ZCD&irOgdJJzBBr9ZM{rRv8I)9~2y1ImgN8zl$`_`_rz#$|BW}Hn@MGosVsFcy9m6OfbJR#9?{ySNM+iuJ5BpUORTo3)&xgM!&Mcp?hv`TLB)R_ znyw@?0wqTf0T4nYlk0qSCA#Bs%>&dEVERCSDFiZD8!TTJ z`bH1@u%`M~DsxI380;DBFG>8&=0YD__MiY9Q-tHT4iLE+g$IiWU4sLTB&h*hX{3{% zf2S;0yTT_wapZ|d?an~ORl_ZPS};E_H0G+fdR3|swPpNjFF0wFgvzdVzukWL_M87A zsf1+d*vXC4^{5x)M96_Gx`sY>Vzyng4^4&a(b_xizquw7IZ-q7rkQgmqxJnum#?o2 z)Ff7n)n;}bt_rznll+R;-ju0Xl}uJmuRV2T_0_di`nKIQHKJnkXm+)4nb^|V8}SZb zS#8wCsTxWhbmSj{7CMDtRFplP4-6yL-=yOmNdYp%@0$L;Rfl}$Ev$>HUjx7+kBQ?pV_1gUyg!%Obk z+P=l+Q6BWV5^V>D-q8`RtZj`}wjWrcOD!>V(_|n#ygh?9P@(qq?Q4cnjdyeAdbt-( zb~IPwhSuvHb_MkpW3}QBo1zs}4bj?6;hE%_c)RL|!h|fMm%uxrE7H(J1$O24LI5E<^1W;CHNS0| zn6^osGwASo!OxWMhb|nUPw}43W1#@}k2-f8!5kFjv`u(xUag1868*VQpN%hOjBE)! z?vJV-V$ZOP_I+47iB)^Yw#uuY#7oz)pua^fgpqSWWZ=aYfhbY+h+>y|y4sr4$#k}? zN;O;CO17)=>{=p2CMlQO9EnJoxe)}0i%BI%R0KX?iDYwNd4}v9;x3p@WN~eMJ@qlDpQ)eTuy%6glCj}|u8xXqMJ5`- z%l!3jXuo7zwlSk$5w?IIFWt|e%OM!*GA+MEc|6Y<ly0#RFmF^wW z>e{z9s?jSjW9lr5O&wJn%s*yE&8Vw7BY&hgkb zgtqaeI(`1YCUeO)Jh&fAwQp?Ig9p40EZI>-nn1Ap+5Qc(t0h_|8v0PsR@H)JHZ}iD zs74l(z1~F^DP6@EDOx+SuYWh1B9E(jJ320Ay4_dG4%HVp0LS{*f^M1@%|2wUNELx#>j;;kSVA#oRoNrU5WH-VvU0?y91x}&C zgxa0JkA{z2@6F;I{cONzFrw;85G!t=n1$Lvc>?d#)hwk7;LrQ$^ZTkE z+O#RezM$Yk0?`jzf~r-Z7nFEJ{3K}F2hFdKVHqN#SOxZjP~nJ9@xjZdf=*fA(^`Lo z^*!}wDQ%4BE|hJ2%)i3@DI`(6bDd2cooydmZ&UNL?YV(iBr{M~D;}8~tnjt3X_*`f z(8sP^eNA0oeGT{wWkj_jN9+u=<5nJ#rPB_@>Vb?>8B(?Q^Y|?Nz=de^jIo%$2LdqL znPQssZ`gJy^7aSx`A;6r79|J6%ReF;FG9xgq)~a8>EVbH0_j0(U@;v?bf<}5vT9t( z6pi(h%1zVweO#0B^ge8S)Yo&@b>+W(+Ai^5vEQ}Ru2+Dgu8>BsVeuDcijHUE|G{3I z6j+@cScl>HiU&khNmi?tRv%rCF$dTuyJ=oJaLCY=mN|~>P zZz5nzM5ghJ!;}LgJ2UAz_>mJ1c+V2g+;SA#vy3jY?~!cviJ_QcxNirQx+c%fJSE!e zQ%z%VG98SiJ!$uuhmY*dHn+HanlF%TtXCZ#HMP85JYfs_8nXEzASWap{P{Rw9)l%f z7^O}&=Qo5kgxj&$D4TE&7dV{QU3Jl^iFTv`9z@Kyw9}0-pgJI$J&ugDx5ptckE|Y< zT(+crxP2(s6K{*R)@Sg{D7ry=kN`;7!&jj)Fb}g6S(%|uibPx5P#KF(GMxeQ<`7vJ zAmP=~iq@wcF+Ac;tMKJEIA+*^YRBp2^jj+2>g@U5{@b15H{Y@)?2JU#);Plvba#ge z2KU>y$dN-1IT$OYyES;;3-1zH)Y63;G$SBxDtuh?T)%r;UF;86Y_F}m?dDrg*VQCq zH^;(>y8mOS2wFC@1o;nzo1`i6|1tL#;87jj1NY3VWH(L{G{`2wNkWJ~LMep^Ufk(R z6Cg+lfd;EkSE#$Ym&zh_m$z>zbpa|+poJoZ8nnf7zu(NgyV;~r`#<0Je0QJOJ3eP- z&YU@O&dl8XYA4#y4u-b1Ofk{{LqE)SarGsbeAAX;O5x&z%&Nlfw;4O5|Cux<;rSVghUE z#z$L2w`S)4vo*9{w*2e$tj_%Z2kY5BEhbJBV&e3Pl@%w`65|Uxb#_*>2>e1zrtoq} zkFdX7&C)aB5$CYXdXY;ens&h4)mzTyeNeZWy~*QGO4h5{*v2QA)$A#HHOnQ~G2Nkm zon5SEyAVpoiBx*8Sbo8xgu$4A9hx%noqF7Hh>3J88g!P&-?$5O#z z2lVhw5{d2gq`u)*+FwQu@PjZ27I#s&c8y)z~$_GC3G*6*7W8x`&Md8&PS zyw+w>f~15-=z++H+uH(q?_B8o=*b){!wLJ7l%5pm&iBSy^gGQSD$q<4`W8M-KMXqB z*YedCAQBo7m7GwW=v$JQ(s!+rQ3GOI&0$v^?&M-M%IEd^=OFNm_RWot$C@1N^J1m# zYcFwH+NIXlvZ14%&u5O$dupiZ4VU_~_6Z%w>SKH?dTf)GZhGtzHI!;@6YWHWuAMEY zW*@tNzhf^u?Ws611fN%qk{-5ixZVK7ZZnQ@a1A3z#OlQ|A0TsihTGE6cA{;DmNthr z0MW~4J!V=T7T1h$dy(uk3?u!vmdUY6G0}0pD6T$^;@nZ7sAEdYJ!g!B6(_Y%M6*K=-m4WH zcLIZ>_FHvQT=XD400u?JY0P`VO173+?}HZsgB6YO452vfBTwwuPG29OQNfu6Z8~IQ z-ZOqzS1u#0LVBZIL;NWTL-xe^&(}8)dOhdFCDK!AR$KPy&=G2#Hfe4K6i=`wafp+B}YFL<+KpUZ>IT`OD>*28>gUWChT0_nGD zgW08@K_)Wld^js^n~NIhQRvCKCC8pPB|fE(+8gil&W-l@qUR!7^4Z*#tUcFh-4=o! z*XY_BsH_<^eBQh*&7d1Q+<{Gj#9K1K|Y)6AlUPUArtzr zm?ei6dF{IEt2fNf9H*O%XexxxjNE+#T`Jb!pS?z^Z4O6Uj5U7L2=!f`yto9k=)U-< z_Q&aWF?S#;=>E50_YESR`tvOmt*142o#^kW9c?wAz#2HAMM85=BPrU!U_{K4?KIgR3Ifv$#4l;LeFj=oTGB_yX()k5A6Gvc z4Y}K6;@f3-JlXn`Ue|CujuN>&9CYX0w{q#vZaUGmaH}qRt$#zB)HFRMt$q8nC_W<0 zhbKepU8B@6>tB`|_KIICa*W12@0_H>R_QK(L6@}rsK%V{Y@XDpX+oT@rI$OxTroNQ zx_R5Tj*ab@)gnI1o#=^coPgZj+sy6pHA2=aEj{B)X8blHy-yn&j8W^Fs%L)v^+UeF zj+H~Q`2~ht7$v<ZBT&WAobT)xrqN785(q0Us2G1JiKQfRa*qgg92L|WV1T&afk z$&EKOIyR zVV4Zkg$$w3<8iQ=69Y(1)eN{`^zY+%32!;yJr!O(K6PGgbyPFn{yeV!sBh zf9@`n2ECrw%%~=JN$y;B5X!jjyJw_Xf&@&DY<6ihNTSCxGaOZIpKgY=&)>qZ>PGf( ztkE1X>PI#h&wh^?&pkrp{i~yl=poKv5B2pe^mX%4Umu%83ib6dxujM~c}>S6exlD| zl0tp1M*WdVQs9~XR?@$gCnPoCs~gG_Iy7MA|E4%WQZ^CoKZiq4LK6 zk7O=j?_bMY4*g$cF3Or#yVd%^TFvNfBYK!t&J5|yB0C=4ka7(RUA7h>GSGsO2qxC_ zena;ed{PueW+4Myf8DS!gR3-<(i9@3F>gNFX})gA--0@;mW_Q~yH%6}UAo#_!+J<< ze?a?w-oW=e8S&RLBD^|3K0GUsWwvn~c(JIpr_y}P23ayAQ z=yrG7ub!0G9K(|*JJOcF+jI@7@=Fbx?i@Z48PSwQ5zs`m9N&j5qBTNrbrr>?XM3=M zMUCoW!NAcLeYSlZ`aKVueL34c>{w^pkI^m-A#K>{e+Bt0yCy{r5*)oIphGt;yyK6) z%(Etm<4s#f_T?Bl(0sKg;(Hv&fcZ@jj@J7SMAV4);RCVJSvq_E^z5Fj8jDNR{01}G zpWuo^W5c|9D~;fFh+d=`M|6s`){_4T|0Ms0val|HmcPqtUHhdN>EL2lF~Ib>eXD`p z;am#FM-D=Fg8l2BZ@8nrp?iZp%!|x$r!_`581Cbb-SfTc+Uxi_tL_`OOce9voPXap z@%Bi{1>f`t>LwHG;nq{~ph#2W|9<`r`=+nmH{Be3?j{dLR6w%7Rh`o6gsrTg8!O^lD&&~|h6rd#0}!^>q(vAOil{$_;93y%_H%d-&k zq2|}}EKL;cbC~ScL4suT{b8klo;{R`6Ttg4dOV?zZU8;VhL~|xrpH&AJ;Y?~iE6O* z47^nKs`oFA29a&)mDC^y?S9^znQG=y&dPavJoHa>p>y?+3sNstBWaJz8^mje! zYW0&imlJbK5V`4{<;RK3@V_yxi5Avi3q2)#gKiSqq4}JnyG$HlyJaJJuDqPvP)4hA zRpr{`+U5Gy-Piqu`*}|X&uN|uJy&~f_dM)b?RnMnu4jYyMDO)cO`|fRx^j}Sf7G=; z4q*BUeRujE^*!x--S@ul3*UC%&;AnsF#p~D$NaxVyP|vW`O7iU712+{H0IKv)iJNe zyc@G2wp;A+u~*059{X_Y>eyFf-;Lc6`)%A+aks@i6rUVFIeukAn}o9xmL}Yga8F{Z z#7>C?jc#l7P@`3i_9hKV8k;mF>7k@mNv|ZWO;&CG9S4cWb)`+pUDh%WHpW`|I1^-Ttxm&$fTF{fF(p>M*{; zv<~w+j_LSiry-p_@7%g`=gtM4`*!}M^VgksXC`O1&g`6dcjor2zFDtieU!B^yCi#9 z_N43?+4Hl{$-XT6rmitvn|96UdUDs5U0?3{PS1#Js53(52aWN zc;QKf_Y^)-xT45i)Td}b(eR@2MGqFO>^Y<7+@5b7mvr3Z<6i0&-D_;GhmKD;e&O-^ zjz8S{q7xdO(ENmUCuE&)O`kxYC4Khv9ou(JamV7C;x#2bOWrK4D*d=@X4#s4+5Il) z@9*EJe@*|514a*cVZa*$J{Z`2VDZ3F15Y0KzkwSD?i_e54&*K)x&Nd_S3K8U5v$wqq8L*)+Cv?2}`k8CN>) z<8fb%+dgjZ_=V$-Oc+05-^9x%iAfcc9zRK)H20+6{&VkS&*WPsA2@l^$&Z)km(MSM zzoL7^|0+JHSYPqYlmSylPbr^LHD%qDtyA_+IXKljHEHVnspm|+Z0b!@@0lo^)#Uspp(}&8hdD`qZg!ox0)FU8f$dnOk#i&8PDl&!0E{;DVDE ztXtS~;lhP`7L8m~zNmW9l10lF-Mr|*MXMLRzUae6n-=X^ba-*h;uecLEiPQ#fAQGG zm5UcFUUOQL(`rup@$?hUNIs+Lj0exmJoEfBuQ~JXGoL*33%|Z_??vM-dgY=+7Z+Z9*2S-1 z{Ncr$F5YwT;Y&JQGWL=S_ysT7cxm*d3ohNVwB^!?OK)HL&9b)3hAdmK?2gNPmo2#L z$;-aKyxHX^Uw+l)S6$Kh3hT;8u4;SL(yPZ@{n0gpug$ymf$IX-oqOG-*R8wmx9j^~ zzw&zPhS4|Ndc&q0yWDvCjoWXUc+&1H#?|J5)!}qSa@9g`B-oNVpBM;<0aMlBB9?XC6f``%{ zn*8wMhu?hoy+=HcbbsXhM=pEh`bX|~oQ)fT*#MAQWlb?RlPPWZW;xpbD^_lhFG0lh87ojlM zX6qAe)SH}=c~xYD&Fdm3Y=57yuSKGIU--@YJlyAD|8wJ0)x`URd>WeX@&5tyJsT7U z^8T8$MFWjpyZ>m0A#}%I-N~K`ZEhsZjkrhg9>sgSvD@xRC>&0}|6^nPylwN5Xlm?h zspFrS-Q>TM_9Kq#EpBdln0&NZE4r#@$m40zENpINM?jrv6tuy%#bBGy31G9!d16oy99qm4S%AE zyOZ^^3Cp*p%Ui6+F;B4frq=Ag875+726R_P10e zZS-g60_$gWp7o24<9e1lpJA=DjYyUsP{s$8X`A^fOGI%4oo(vu9xf4zm6Jp}xlRP+ z7a~qIpEtEu%ixEmhd?h0$adH|V2JYn&|uMKp- zr{3Uw$lAzQ^XqYJ#?<%Z^DuTzM>OtV0p4FFa$FCJT!X*=6QfK%n}pBJWzR^$ed=EF zjTVDlFW}eD+UV|ypB__>BQbi0tF;_@pvOJm1wGN-m@;0s4!RNY?x3JOa3PmjS&~4FGk6$y^7E<06>hZoYUfy0chw&6KmRxsO zn`rw+;eOXRQo-2dW?IJQ4z&U8&Uwb2%sBLbi$9t%+EHYxan=uNjP;`{4V>0^FCeREljdrXY5e9{J6!W{Yg`?VhK}`ec>LvCGt`x&T}=2S>mdD?NSzX0 z)2#L6+d_@xV=5c0-}ttm$Muv0^Bm&dgZUa*9-^#!FvF=!A5lo1^3)~3b0v6ir5V$; zt`*kT>OZ1;hz>dJkZAn#BHBQYPhBQ;3mfXD+mCv9X@_JzCe-8B2G@%Qhdizg)`y0s z9WRbo=b$U^YaNo?!56+zr!E!ovOVS=&eC5l;?+{oRkjwrR3|Z9rGqEUd7p{@!=wpV zzsMK4Q}|N)_e{oAe{gva@N^WTk!Z)O+pKM*8>fDz&hL=F#XHiRgPhYg8ivDiJM)PR zLxP-QeGLpQbs6Q)vi6eC2+HR+Kg!o-zi1s$%P4m!TQdiV6y6Dxx1D(7O&OF&JrdM% z(LwGP1?p<+kh%rfUIdP1^yyWiCG9>?Jt&%}i#dtCnE5mrS~T6-Bd1!w$@dja^C>LAXWU{q`{N5(N zkI3(R^81YZzLGty{c_9uDS)U<^@M5o(0kIUC(MGlc zZznMp$BNVCJK{fLA74-IYJH~y*1PH}>l?A(S}%ULmdhtaihR;qBQLZz$qSf2E)-38 zKP&c&GV!};CD(Gd=vw;fM%wL0>Uj&a^JeP<(jOxI$Dw%Y7rtImAUex0S*>fnt5);` z_j}UkJ>h>cF-_$}k%?)l{J`s`ZIAH1q87YUcdsE+ z1a-Z&o-xE#eg@7$OX3oj~95Z7WwWqxIYnRxCROM-P)z>!C{|q?a!DuFP z9P=JweH{D!y!AfYGz@oUvp-YRR$*s{ZS8NE=P{hqujN=>?YWpYoU|8WKOZ|AXq>dq zSywY}w~-?;HzVabB3kRWydL{n-dXq~{gS6+e4@43MEH$_3G^^uqt{r6zM_amiFP65MN!yjJ@TJp2ybzjcq=0;QkC$r2B}vP_M)eiVcC zo3S?;+@PN@VKGk9w815w##s>ka+>YH>`L#x$z>efIvuYRt!iJ zxew8nDWwQ^l)h*DS#d7=aC8}QoNFl(XUhtCj=WY{+|Aa5kM#aeZRD#IK3A-(qpQH( z!kyvn=`L}f?4IhL?Oy1cF#sm(rS~rKe@5 zjZT}KuF}2f3F%4cjniACw@&YpJ|Mk3y|Udqhunv{AL@0e_o2RrN)HX@+qe3OqmDVE zr?^{A1M33{Fd^4B~cdVX$wZtI@|$;gXZ1_B21A_Mt?z*&KF16Ldc@=8ny4AW8tX7!g!k)*p z9LW*l@H0oc9NHI(vURk!ZEd!7_SWnzySA+6_t}> z$16fz@vanIj;o2QnJeAZ*_CZv{JY9A%UrLzUU$9eddKyxYp?4^cU4FhdQkOK!_^2? zs4i5;BReft1Nb&xf6hi-%E&8$_jQXz_L?_ke@;8mUUU)JjE&(8>U{NtdRT2xkH~0MsjgNP>QTOL z@tC@jn}Is0Pq>lsA#NvJr`mDj$8?p;owa$Ylv{s1B8pMrW8}v(;?qS-w8Q~Xz$nRu z!Zs5Fkt7f14BKci6uLZ8REe3)It?iHEpxYB^u7d=%>R zwCFBYi*DjcPBK0v^2OuOs#T2m=lI^m3*tr5Tf8j#h*!l4;uXbao)|7Z5@WSQK3AL6Mozwd$rlcuRnM!J)hke_r@4IdCH0(oL8i#YvX@Mh`7%#- zmpx>m>?U(%k!&ej$o6bKjFoXRUM9#Su3&B=o62UgxlHA&-yLOV*-3VhncT9GBeP|J z>?x0vm2$eAA!o|jvP#b7RPm{@MlL{8aGtzCo-Z$y7s*TIQhABIQeG#omvdybyg|;A zSD;C_N?t9mk;~*|(9wl*J~P3^@_2cp>@9DSC&-&+A9)Kphf`!Ds{#3FG(oF#=iSxr`_ zsM%_kdQt_sefmaq5qE7|jwXduF48O6TpkpefuI;OzHCAuF!)&!KVopuJ8I(iV18<_ z#e|?J$tYb3bu1|_&I-!RV4!?@R#0UIrUinp z4iCE9Ph8niMwgULEem?f#-{~c?Iw(zG(IgOEp^%WKydhQy!uQ?4Fn6dt#HDGzzREd z#k62Yyc|~`n4`mUbj(+Wj}HLNvWkGde4rekfDVh+w(i>2y*#y?jd!U**=53njG!1k zzH-8Zte`71P!A)Jhfuvgz*^@(k29geMXHZELB&{DL*Ud z$qYu7bXf^MVp__JGov_z7SAZI2&yU5gK{cR1U;Rzf>D_P4Qfou)Mwpd3Q+*IPx%BL zrM%RD>dRai6(dT@iaV!;+uom9zb~TgTx1tOD52ivfwE;86}n$cdx=!trolieK!%{C zcQPtU?IL21kzDV94w5)rwa7%V8ig{7S8}l}ot>JIHlcG`RxmDeg;Hg~X%(ee!T3xn z5C{ZgO9ttBVaX_-5RB8Vk+|Y;Wd#$+CebuWfEJhv*unUc^1!n4Kro(0%L*oD4jw&z zg?n1*gto!B%8b*pf{ii$QPXf!W9R~DgG&L!Dm7%E?!o? zBFWn&xU@@ZI?a?q-IBXx1si9skow((cGmBvnJZlS-7Is3TfduUuJGu0i_8^X{Z7qX z5vAWPGgtWZyH(~2zkYYhq!sLT4|>aK;fz3bQ2s{`kgQeq()wFa&L_0#V(>Zjl7)K9-NsGokfrGEO|j{50$d+Mj(9jKpvccgy$ zotYWvWrj~yCe7NYJWxX4mTO$7;2q4=xSE|A%<2-%Via~|0Q3h_k2(x9Dhe|+Mf}qk zpkY=pC)~BNNw90@6&~5RY&?WacVM^3mic3FZf2msz?(-rS@uV20FgN=c-mhy(Y&e< zrM)u>SLDjZx^nq601zKFO*x~YqA)91keS`IS5~n5UquCjrxLvfeIlB)3uFiS>yb}e z4qUdZe@1^O&3L8=C@bWkyOfPnXwpJRRFhyL(cDnYb|zZTU(%&=S$0Ms&}$j_71fUt z$hPwex=BRLK(JgBjXopBuTlY5Aa#{$?`kojSQAnoG?{WKIinv#m~O2<9w8pGi#>0s zlJaR8L03t|G-#PBsYu0MJ^=#IFiizuLEba^RTQRXP(nZI$IFyLen%+;Ks3d5LnY`0 z517RS(Et*1tRQha0|fs}TAEbWl?7__47CFbu%M^C(+(NEXrkl7K|vqXA`s}8(O(y; zd#_h0%v8o{VKI7qcAytiu7+OOo@83r1>SbJ1`-sW-R;i%BgU0yI6VctS;6B&rJ2@u zx~g2W01c}g>fYWEifrAA{ep=lPV(U#FVj<$@+Tm{wZ zi)}16X>8*%S4rD%JT}{Jf{rJ3yooxVu}#wPjO`>H&)EK>%Pb+7VoUF^#mU3OD zwp8di{jf~YakOQsj-xHpbR2D|G;kGTn{MFJwiyO4ZJTM}(zaO!E^Rx-z@=@o4P4q* zW#H1bIka)la0gZ!SFkq$b8YJhSm)_R*U^G~aGlCDidDy{v8_7Jd=p0p=r{{Vd|Wu! zg~nx4EV8XS#bVp4qn}1T$Jtq)Zd-MPGiY^#obwr$nX&mmh{19IsQnW4*=RZmu+s@ro^exmlm&KJk5`U-kAuRN*IDqhh^)5B-dvOO&o? zD=!@Z(|_ss6|QNeE81(<^S*QW5K5m*r^5LX#hew4o#Gqn>*>q%w21P=c79e`7X{r{ zFd>(&@=RkFWGT@9{pVR^qGuz`L3XMTyIRGr6}9iFx6l$MS-)C+wF~*g!^k);RmkP6 z3r+ZOgc%#D>(al~Acwb19wx_7Jh9pui>xwSl6cMAoZ~QUC31CId(TPq6Zzj2l>p~j@^sYXscuQi2#xg zJFOpmLAqm)5#41!#~v#RIR<9OiIV}j+OfxreDx`^v$>RbIuf&4$jxT5G7lh+%0aGE zfNeBBmApqHTbV+P+1Q5@cP^5tN+fMMc3;945O1!Ly4A%j#-|E-O#sQ(0^~SVq@POO z+2pQ&$06?-jBINtwz^bV$cgN9k*Vs!1L5%c`Hlr1E%lp4>T1fYE2l2)(eoZ)>ZVic z+O)^?BbWKWs_R~ZluFk<6kb8@x=!`u=yqE`JN85d))fhd{$>rdWquGY>guf$WY%y{D0N7RjEB%U)u)JWjkIdx_)a z@nXB|jih~+JOMgTB~FojWM6P)4mzGB6}P!h9P;J zh}7{UB)G%H2;`2FkvW#j3Z(oa(JxOy?z=>sf!uMLxJOosvyfSgLiRmcjIrgeVyv8n zB=|6L(%E9EtU|x8Wvp}28JsQWp>I16nX#71&POV{5Iw>~xkxUSr=eY(ggp9td4_mi zo{0u~iTF;QCC^3*doHr=*R%{C8SeQ=akUKhVkEd)j;p1$mm|Hs(vjX?Yoxk2Aho>- ziR~>&YHveIdj}HQyO7S_Bkx5ndp|PS2a(4MFEG*QjgNb?SO`1M=>h_$K9xVjr5LTeaqiyHjshcc?qz z9Zop1RrjcS)qU!I^#J;` zhtN|!f_7>-`;bb}727%ZxVb0<=3j(9XTC-eJd9U-hnf zPra``P#>y~)W>MlK1E-%4z0}wbT(h0ulWkS%_cNAo7EPzm0QlgRom2d^_{I}K-cpn z`l3x}y{<%uRDura3v@>t#pi0b`d;lpAMu0wQT?QTR==oyYQOqb{ic3b2h>4z$USt- zkRjf_Q)(&~RYvulQ!%w>Zgo`OxijWgSI&;=TUIf3;etwJZnJ8pE}S#Hs`9kxl4)}n zR7{;(S-rqpI<ylUoFEbx|@JiKMbGrBAsEvn4Pwam^nrhi>-vHhpcoinGx&M&%u zIE{P2l!}^|0d*18z(L-DHjo3I>;~G|c?T|-RW+?LW>8(^*ufFGdWV=gc!wCcVuwTo zxrb1occ>jc)D9mS5$-Chp5Yy4N{t&fb7A$2ikgLUswx&Ph#F?Y5HoCkRmJ?7b_OGz zmz~eZhvvwcZ^f_F?QWOV`^pr z;uzBc-f?y*?$2Jm{FHa?2L%kh@KHnJr7yj>tWB_Kcd!%Id0$>S?p4daF#0 zyj6CeRYk;eR{@2$+OBbR#k{%m7u3w1H?z`PZO5&Si0i7P6Xx3eHMd@W&9#AynHzy8 zHFlXbc0M%``FQ8s#m$d^eSSo^r)qBXjQQ>b8e0~aavgYcL-0EBa~(Ky9XN9xcyb;1avivGLvV%icgoLo;LCO3$_d2_!5yl9 zs2m6094G%Ar@S1eoE#^g+z@=c-JEjroOF2(oOw?AJO?id zLU5G0%ZB&%uKNr@!-@b}9(L;j~X)$Q_F3)GyEJ_k5?k ze5bs82j2V;yiWXl2hMy4&U^=+dC2pW zWe)shPW&<_ewh=mpObGtCw@OCem^IEKRbRwHygf!Zl$rBp~%n6&z?U&L`?fSozmAy zTZFhk)ND7?6Sm0Eqz!{VUPNfQ*bOoVw&R{KYDqG+T+5)H21*Oj5Ds_N!26KVa z7zNItE^r#9pv*?*f-<|(1E+IH$5k!x^XHtaE87!>$Ay#;`lyKp5fF@P(am8oID6!G^8QZ9^7z#~Zl9 zPR$hL<`f$I<8At#x9NA@reAoQe&=oaoww;9-exfJHvPlf^nY$n4;!Cz93qlaY!i)~ zVkbX)QYN00Uk@igJ_=&s>EYzp!_KdpJ^AEzE6DfLY^FvtV@)I3_W3c>X%fdCYg)i@ zIQ2954txgxDA#fKD2ty0ms(j>IekI))Qb6)3C3AtI#at7wR?8uf^dXJjz?XT_<0pI zu-V}pjI%Ddab0i(mNtoq72%y+7dhNRDG^b_o`#pp>0268IcFN{G6Q=|Wp$l>=IOBT z)y6+*#===uRh4t**3}|8>{SP-i8h~A7IB@{Fwu-xT{Kg2fkTxG9PXl^*q+UD`sTRH z7S_zQTfNx9nqsH5ZPqC_$7Ydob8HqWmu@xja~;+%r?|jBuWI3Z1AH{Y+OfvXSy;7T z*1W3I?b=S8wP@C~N;^{JsS7Krj5V%$?t(g3V#U09HFHm^^GK**$zd;`Omu(c`~|G9 z7F13%Aav{2J*vXS1XIsEhx^RS>ESo40@f%~{AOXGZB87U$mcnnXkLyzGv+zf$;;{M zHw%%76!tX4RU38=4sV_3@YH#E1!gXzbOWU0=wTf3VK{7O7?{YY#gUHONJmMeqkE*I zuW`hOL5&Q{k8tEhrpmQ}vLVd1!8LWtEw)>sz~PSz9R8xfAq53CDaa|Xk%YHF0^W9; z6gYfHfkQ$H9DcgM;YSKW`8#}dfy0*+6c@&r6{2qKsi!l3A=S3s)B)i?s&-BTB=8pI zq=rDcrjTX1*;CAi9=Y31$!Jd3O60F^V1H8{LOHNlt>*tJ^%1AaHgh8`7YlQq?I|Q? zO1+9KOdl~u8|m8SHW$r;rRNDdbEg{U0G8t#+v_9 z^FQ47nNv|STTGAmFL&&-=gb!K=0yCPl64y?0|j57!$%wKqyN3e?FJHUQRr z950efkf8_J$^10tEo9uAFmJts?{;N+Ej5RV}EsMRxNLKGc z9_m#^oU0mOeXoXbu5bkB2*+{0a{}km6t=_I4s#a%2!2J@=fv4doSlUHPRMR`2WJEC zvJMI_F%A)9KRNwQ=mA21C-gAq2#YvhIe?I1)*jOCAoNEGv=+UlH;J zA$v%<&4fs5a{$~wLOrE*#6Y*r{2ySP04XUB6LOdo)D)lJD2@C{bDHjH`It%sBa^_^ zUuny~c&xpo{ENr>S!?kA{IR~W)?0_IEq@lv+6hF5t$moo$BJj&W!+{Sv0kwbS-)A| zSsQR4I9A+9f9w88SADznsr9Y)vF@}ESX-?IEyAOURWbi)TA*x`RXMmj zMNQ+Z+;laa-kqst@;^(>BF-u56h_%>H5)BLm8!x%hx67^=v1l+orhjUp+nInDAAnp zdssxHQ943ico17E{as6L%O!R%)eGH*h9Jg35Mv-vXnXqOKR^xOyt0NS%0S~olT*n_ z{~2lq{~DSY1C8H6BMmfu1C2D$#GvJw%W2|M)v5eHq8{Od<)hs1kSJ8QT8*i>UQX*6 zYG)nPEpGmCJ5cC4N;^NHa=V)p#pqWx1r*>&7`N-NiT*uo?XbJaghM4w{amJgcFt~7 zCu!=WOg&r%UNf&iRZ|)T+O+Pxxm)jUH|H`BKna0W>`|-Zdj0X|K|O~CW?#hbAUY3z zI;8%OGkUGvAKO3INv=h%%Uut;KGbg4LH^tNTKHPHhq{L*6ebk9tMor_C%*mmT-xyG z{uUqQY3Uj2xiso~&y`W%M}4pJIm$27cVqas+V^wl=g+r)rf$Xlp|QVm>Da`$UjB0% z);9iT|FY08Zh`*AJ{bF;|LW+T(bHnQ*sqQW#y%MHD>r6682fDOud(mPe#`%_c3kJ* z$GdyPFUiZb>=ag`&GvY=3#Q5^~^W$%he=~k1W?lS__@Co{kFQN| zCv;9YDe*T}LPmFuz!H~kU4g!_>_5excH2jcC1*(Y&%}8H@Le2+^rU0n$f<)jP{*cBPn*FiF};X zTW(RqjJuL?@*JaJzqJh=W{tI5oCd8Ag5iglJ&Kr-?0NJD=Bi!Hqd%B=bU9}=C9ypG zPlNVGVNXTx--!H@sjG*YCZO5uK;E_3T-HzIeMCG?NkI`HW)otj5;K~ZDdHJoZDWM) zXVyDJ83VY(VI1?cp5?qibOfK>%;txI;!tR=rxf;|l2M?;5 zqW=(5Bs!^KqOBSsI;e3_=n0}ZdBhwwW;bGXA||&@h%{oR6SL7#V|FBFfS4H(dBz?! zW)yX@h$)EaA&G=B1`xAY-miq6c zPq)*jU(-ilQuYCK+%?u_Vy^`s4uTIq1Mv|c{t1XR$M+>Ezaix&Qf?sSMpAx8O3jUG z7;oadIj6@lUQ86mhw)>gF)^4}OdRHX>uYg=^{%)Oa}nlZ%q5shG0QNQVXg!(ud?0} zS7WZhT#LC5b3Nt;!f(RdjJXB(t(e;|w`1~wkn^C0FS z%)^*RDCbeka?E3x$1zV}p2P$(D=;fDt1zoEPhpw%)1dVt&H>jQIt#53?VP`W1@x8|HV+0n9*G72=5dw_BeH>2n? z&yPbdg3yf>jLnto7Fi7(PeXg3BQ$}~TFUl2F**?=+kroWGC7HDeNK4?C~rUI9U$-B zI}tc0*#G^az+77WBPzOj8to( z0MC%BGqZ9Gr>o=HZKL}uhCMtnoH_5vN$HO47?eQSk(@h{b4POS$R3@Jz|fH$IUOmb zBe}HUe0mJ0sbiR_W0t;` z+*xq~dzH#WXVnigjGJvnaLdhX_~AL2<)Rz3KG)0&O@Sf?D7sQ|G$|8F6-TN#QZ*t~ zlBr`y>Xblz5~z>flaxSx;;2s?^@*cCanvV{oZ`qSj{3w=pE&BHXT~_{XSfy5~xoC^+}*U3DhHjIy9#aooVHc)S)%dqybHu8pbTCXUgf^QZf@Wn_ifM zS(;I$z!%uJc=?y=< z;iotBF4j08O9HZ3r=HD$tPPO00kZa{M`r649%i}d0%XZTb4K;*NB_qfDpTM0Xz@HI zb-gi1p82G{hH>*gRAn=5rN^eGZS~?Y4xeGnX)Z-`mA{!;ei-i&(AnisGMDi^1?pP` zO_SPX{tudeBqF45#M-Wi5i$&ZZUpUw3mRuja`u{$egq%nccz>)Zf1yQH=BpOdhEc( zejOar?X=w;P|!PRi@QY@cPm7*pT9AEBk7w=`sN&9zn;Fig}!-}ez}M~xtP*>a5q95 zYS~nLKpr1L2|l8xA5+)QaDTt8u9lDbq>Wg_KQ5*_u?yeBtSSq0Mt?(LDOD zJ9A4RwYbFkjJfAaYN$tZENR=5b}VUANDIYdE%6*P?T5@YU%}_?XSU_8KFtqMTYc|G z9zEEdQVM~QHYcYPa>^wqJ(o`;r&Mxk5443&>fb~H;RU4ZLdrD!1HkZw8UIhx`+D#9 z3hJ?veaoxK^=Wc?2AtV%eMQ;u%B1c{oHSB5BXtU`q5Ccu+L=e)yMw!h;Hmai)cX_D zKDq@q(h}1cGxoTSH8s@!UmLjfEZNy4wcfH`w_ZZ7^QHB>^{w@p z^@jDTwF>t^WP$sU?|n@8%Z~e7@>xfYe@otH%XomGR@=aZh)3ra;dHD>goU-6FKzq~ z8HSIM7lkC8z`P$B(oXR5FCU!~Qp$QaT-k|`P90`sgdgxySevPDeK@y*w>+%O%|lE6 z0PJ4@)4@M$1zS34ry+GMrP-};5ZH}PhZ%pQWbot>PhEJ(Gt^dp3<&*@Q zwL7xbxOBb0v%U}2&`tri;7`bpj$7B8{E#G&ukH6w{;7XNTh~uXKh(>Sa_YHt>|>`6 z<%L98^R`Y*TKQ}6d%g7u82z!uZNqkNSwB%%JrX_+r6YyLx?Rv~=K-@0v2Oh|Vjc(2 zzXmT3g|N>KiTr0|(W{KdBf$1GHX|X{F-%?lKqXAs-w{@C>;t!P>l?`I=O5rXy+(dt zg;MG__~evahe!CKUx42IRKE|YpP@DASPXuGH~J)$O>h3t2cc4ElL&0Ko}~YFS}%fQ z-&$*+k1OnWP}N_w*20XWCf+Yy^9ZMu%~?k9_u# zJCrw+@@Vf!m>P!HwTT@<4eH^tt~Ypkqz<;o9FE=}w$6!k8V7zMM~5Ekkre6yr?iOH z(mp0d7ze<`?YhO8^XR+Ca!uUd?OvoEw%0+2o@hC3yWIK!&Cy$ovxlAW{Um+-7JeUv z@&P-y(Ys%VDVcU}L;my$zCSY4t+1Y^+{ZERTd(1#Dd#uT2E1qHd&`C>5@Vs-zkzeV zKr_B0=9cihRI6K+RAD?Or|^id;c@B`5hDy|gV9pI&2^sSZN_Lg1v6O4{!ic3fKmI; zQt7dyYp7F!PvEYd9^63}Oug%2)UorX#k7Q~!DDcOnGwjGIj2E{u(Lir3w!@9i^0t> z<~2+bYV&%%4ZW(1S4UCm{Qj=Z`kcAQ;N@Spl&0jg1k|A6V@7J24n#uQFlMA%&+f>u zctY438H%sXoxo|?w9mv`!@T(uV{03}$Q6;2nul3+KUD1pJ=^}BhcWaf(#r6oafcF} z)bJEgX56e0>Ua>!{gUzZDJ`~+|4;Zgy?|zT2W4-vHiWbLKUkdJq zD#HcGt$&SJ2}$_q7KEg7`c-S7+Tq(C?%mBQBpYsApLEhPYa&kPd}loO0h|YninORJS>y2KW>#hz?koebGVmz_jil@`ChmCtbr~*GhTD|E zx|LsZQwEwIeqBu&QKpP;oJ_kE$d++h&CltwD}eP%eubQVyPnq38aF@k{+s!~g|m5y zoYT9HI^55F1X>EUoS2WXIw@jx@(k_qJQ9~e^lvZHLN6g@>B$+tcd)Nz$4??BVb^2d zz^@R!-RI=_1!vceGn%^;WHI03ul08Uv>-camtE|TX~L>jukC;3)(4A{dBg`{bd`?ce2v@_Z~+7p2JDYVaTUOs1fM0#;I{g!X~H*$icK;KHliC6O`7= z$C|wY`9?b*YjzCe8{Kxc(a|?DI{GA|qiPbfDoo#gVaYmC^U^Mk{MxR(<^!2Tc zzP>#t9hbAVRlZO4>d*J9e-mw!$EZ30FImfK_cFR!FaEPZMc#K%){oY0b~@(9-Fh9R=ScqFBiEhQ+lB+%Nhurg{~XTiD6`<7 zmuu6E5S9Lmxc_i=J8Eu?tj&z%4xHw0!kBIB#5nlS)}dDGz~4nkGGp*3G8WE=hRE&aEhJT}5>t)s_S zef^V%y*`@n^gtVUkk;sjJ#x;Y_ohW-k27v$u+}=gC#m5BgnC}yXa2uG8qZ<4lklpx ze)@mPWzli;I%AFP2M$MY;Rd&kfWHn8f&?c#!_>>;dxMeRfsdM(*>89n_};oW z_6q3#9UQA$pD`*A(#H=2rSAQo^?1RD)gLZu2z>tqx&!!c*L*eHe|XhU2kW2PNc|{% zx669K8T)#6|CUmI0=Ev6zvjEqM-p!bJlPk_t?RMXlfC?T2|5(K{EGj>aN>Gp`Ck1L zjPlp<-5IJmGx>X_Zz5XU75$i$vYnOEwKAJ<{XE=c)nvUUm zliu6~H3K^_+o|6H_=la5oLe1Sf5yWh>CCYj#|oIBd7bp ztjNA274uK1mF?1)Jr2;<&p0kE(_m#qER74F>)7ON#y&Q^{@nRT&X^D#`?pYt!L@(A zg0dlT{)_9m{=Orf*&%~FLuSB9X24k{{z+1O8^39+d+)Sg|L zoB2PW=U(1Nk!Af!N#P*+L#O_cv8H=uw~_wUYcaGCruV~1{)L77wUqXIO4GDZ)8t6% zpqRfjA1dHOZ(u&V35`)Q+~YTJl-s1A8x%CZt7F6)PBorgVOPKfX&zM?9#xU%Civc) z`6Ki5QBVWy_YAv;`J$#P2{&~35D7e#?;dNi(=c2S%vA@pGXZTe={OV`So9p=}iUq%1N z&CgzTA4f@ckFx{Zhuu#-eZa17&T^TxM;vw2E0k`A z5@=;wxua?2wq_;J*0gU&)4oxrecPG#ZDm#ht<6dx-K+#!nUz4USqZc;Et_jr0v*jt zAlIw}TAB83YuY#0v~MS~5@=;wxv^OZ#G01vYFakcv}~Md*_Nhd<4wyZn3X`3SqU^T zD}knl*H1FMezM{9a}2MaVR(HXx2v3h&Ry^J^BImm#&G-@hT}&k4ac8iIR0ja%kNSKKw&CyF8~)yB_O_M zYh515I(}gv8FM1$J5m@4m6q3#N=x1&X;NJ>V}t+r7TN84ydAk?NV;xHpPE8(L%sZ<`9ch^@JI4{4vXp3`ZWuf271EF3XhneqRP zmerECU;fCmAoqODjurV&Nk#%~QtzS{9o+zKy{d2?q&shg?D}m(M$6Zw-3vw66yCI; z^*sIYFgpmsPo4Che)$C$f8!tB2`RQ3xiA`=aAaMAsS!Mhp67ShaU}HX5&G?0%GR>} zJ%*S2f)*nlZjFJ)hW)p?R3?NTikwG7Z5CN7djM=X6( zT^d(`U++KTG37d3Q-g9f7JMJcqyAAUs&n|~Pl(&5bmnLN4Q@~toRa+*uI_Dc{s(8A zt%Xlq3x=#GT(xkJNbiaP$C;n?PoKNe#y(x8SF!pV zq;AJ_#TJK;mWTPw92sxs$fjnFj5l*+Q!_`#n>jMU%#rbCj%;e?$aphHHZ^l(ypfqD znwe6XnX-|YDLrPURA#1(H8Z8l%#?mJQ#La*WivBVCYd?1g_$FpnK`nVnIl`6IntJv zH8=BO6Eh>WG&5o=Gb6S%Ghz!fBepbiVKXxqwls5LvYG!<%>0*X=0C5Q{~DY5FV4(= zZZrSI*pe_>sH2`;jI>gpk<%+r&DnpZseFW;^K53fx>S$S()x6p$F!=x@Lo$EwUp9j zYV9_)_TZ;aeQ;SYEoh(qIHWPlenP7o=;{{^6*y$HJ$l!Jn{Ons+n&=dl9MockBa?h zsjTi*-J5)GfD)x?bGuxUfIyU(PnGd`e4)*wfF zmA;JPTQyJ1rgN0WPd_@Q9oM$ya*t&z@(;)WP-Msq{xuX$`MORw{PSf# zJ~Ozj(Z!c?I4Q=hj0>?Zl8YE4+{lRibZ%wz$TPT)(ZzYtCD^%-k@dj^@)CTO%BB1- zlgo&InY;}974iz=@Esl6;97aDNa8le>+rup-k|q1LZ_1r2i(H&zCOeI#v86T-f+Fm z4cF^4TyLWYuD7v~b0-)%ccP*Fu}01vXZT>h;e%rgAM7`LaE#%D;|(9&#K^gu89taD ztZEJ?KlI7Ccq8YIHWKb=S|Z1cy2+B0C3-FZ|Bf)SUq<5aF?`-m-Ncbkh(7~6wX{^r zPHp|{HhZQH#RX3^rm-Rh!kmWA^B)5p9$^=gF6b`In!XrxqMgid~hL|8#%A!dx3mo$zXZa zUt+nQZ|xaZ+caL=Mt^EZ(?^@a)s1Q!%Ud|*Ypj(9UzNdBWiZumuu~emR0bpC4KBtT zTx8!inim@j-3ANY1`F+Tj-1wE)#Wj(F0a8km%+9KgJ%f_!`ueLq78<{7z~Rx7#3qN z3<$YvRnzjTRV+9K7ZSo6Q&;B?D)gh4AV&HTb5}#|41C!Ot=kJ0MZ^UoHrLNLtT)x` z2)KVcUqd^;!R`Uib~qTYg|jhV;uixw+~}+tm_MXC>13j#(n3M9&Kz=7pC0YZ|T0eZw9ZkO4+jnoP%E)9Way z>9vcmoT2yS3uig}Yuc^2MK~9`rr=Tfi)q+<%AWjdYVJ29!e^+tKZ2V3&FJtMYVJ2< z#An8cG}PR0sJT5}Y-;W|qsC`Ojn~j|zZpAv_VH8aSZ_z)I^+ifbRFGG+~32g86I1& zI_UpB^z-j#hJ>cjD*yO_p8bR@cQY9G1K48!HbBob5BWAfq=oDqwSPOoNI$=$Jn)J5HG2a*GWTY~J#Lg+ zMGALi@8ql9yX7zcPif}^-Bpp@@i#N?{SxwzG(<=dkpk-mN+Y|btZP$?sF)%f6(c87 zj8U`EWwR^|E~Q(RLsKgF=b-LEYEzG!YNhH%YEzCyTrs#TvVmohW~sG6BPwQ5kt(uC z_vF{lz3=z(8z98(Y2KNe@4Itn-u&jxn|o*8yt()t{?z;mFW~Hp&CIhg+gYbBiLRKwqe;10_1}akPr%0_Iv8lU6H<%-=X&I)qAKSn(PfGhw zs(+~e+BeZ=^uP3vgFIJ$dh7|cCX)XWC)bj6dc2jLB}md?XT-Bsnf_#;Pfnf%+H@kT z`DLC5?4EeeR`iqPelGcataIRR;5tbe^=%jYOrMrq0}c0v%4hUc5}))JqW1=5<=UMb z^8aNHvEREn=o3_ba4kJg^2+oTNuQy8zUXS{m!z-UpPe1$NgAQnmhApMLo8!jKx|=s z9UIu&yPYSfP+Jgt{a{hYZO3Zcv1(CA+IHf7OyXTjtXj@aE$2`zXQyo^)V9MD$rC2~ zd&slNUP?T5dHU?io=38~lJJBRWT<@qnwJTpFXJ(BJSt9dkY_)eUee~$K1EW}+F+ct zR-Lbt^?Ceh?MUkr?IR;}8I?I6uSnOwJnZ zmo}RQ^1BJ&w#*fXUkZHSCcbS)>GCIQ&RNo63FSzP)0V_~^DzswnJ(Tf`(4O&#Al?vSUkF)G z2#Ftrml(g<(k+B-gl@tf0`_0&e!?L_AAv9SN{!Y% z<9P*y5<(eaEMX#HGGQw2*}2=fGx$H6!2Ky5N5I+4P2Mx0v>q| zJjUbKhmFZuI6lVeXT3Z;8XgZ%g%#venMi;yI|rT~l}SuAHkugDgW!#OEYAowNLY*%pM05_wWDITMG=G}qQ}_377DZc;y9oooHCk8|?B6 z_)?$UF;@N_5Az$8CqC)>;<}RaD9FmlJxY$KAVJ8KWa}!L9M_e^MqQrFv}i_h7FBt8 zSHeZU+QT&--W=oT4P=&j{3Z|AdU&3Pmq#m;v#7ztP0_IdeshAz-^Y)oijtV9B}Rq0 zg+&DeDUm-{+5GF?7d@2ZLyC2S;V5&h=m{jAjy6Cyid>SvV!uAOd%5^^xHsl&T^;mf z-tq7eAA9w1!sGusi&NIax!F2NmBxIu#tQsr81tFCpWgKuQx9G)*u16uF2PK%3g>y{ zFrxwfq2gzhZV-wW6v^jNp}|(o=kJyCtkS9GHe{|;{8Pbr;yD1lSaVxt+QGFFi!Tz% zr&H-ziM7+wHO9Q{en8Ihp3Y!@3FikY|B~=csq%LUwgqk#v_$!1G>0mc?^RBdlr5;2 zw9e>Nx<%gX(b!M)m;OTWT;>~$70bf7dda~y2p=CGQo^s`gUy%?_87UfQ7&U{6l@-` z??an4_GaaDD_x+R`AYXIy+!GrLW2{!d*i#xxmz%Mf}9|qn>F^2r3}Fi#Sg3G)q?S9 zBW3u8(l)(rqw=p2j2C*Tt5wQ>#Qq!j?-XC6IsBt?o>R^%TEcr2m#}t*It0hFGg7(& z-b$r{-DU-vJY?6%9jGSRDY8`jpfEcuJ4%j5?gs3Elv*8mq$y;4ATt~zS+jouw!-i5 z9%uqYw@Qb|Y)rU(z)~uLND}7_c1= zR|i;+)W_STNlZ_b6DkOmgv$ui2{Q?^33CW_gnB|_U+~9WSS0;z+Nl<=exG#&{n;!1<@Zl^DH)XN=z@1Fa+{Yg7Pq^eCdN|L+#U38% z;V~W_@8NO}S9o~fS8=VGA$m1jBC+9R9-i)DUuL$)pX1>=57&FR(ZkEUGPHVlwTIVu zc&&%qJlyW#^&alxT;}1i9-ipo$j(O2@gN*;SC<%m|*(W$*N;Mare?AKcV=bFbm3JDOqjZw;`!wxgP5Zd=M=Ae+mgHTj2WmsERj089D*2k?;VQXRIm?t&q@35Z zeyr-hKUaN5Z%htpn@?^ZyCQy3m&6ADEqX5aCy@!>7cCfkWZ4}SZG${3LgcqMrAI(V zDE+CXqVI?Eebt>amGiExf%DfQ!@CxdzeOm1<1PYU3l=@DV_38yZzRxjr_c-$8gwff z^vCGYLe--qbjRgUsz({+QC``#IY3w1)G|UVVKre5VJ(6EiBs)_^@I*WCt(w>WHu5u zbH&FwXXKe;9*M7uKQf+g%_{QeJw zXO%BI8p#;lFb>K~{$G!=#H%x^E5*s#zO<{A`0OC{EgbYt9j z&E<0Z>fNQh>0z0h>1Go<$JM!d*9cnR7O^|%GSbdsHPl>{YjvyL8n+hSeBOq~Y1>@8 zTd%PluG4MOoEPFf@4Jdt*n8Yejos(=yF;#zv=87P?@{F)b;sjh#H*~N^d(_gI5wQf z@0c7;4X1@w;f%1F9Z72?g~!Xr4uZ0^HW>O%YZA|MAK**wBxN3`$!z_(a#!Ih-DT9( zkoD&VYRwH&S8j{j=DOK|b*USuA@_f;mw|gu+h^hfx>BF9n+2!S`qar=MaB(^muc*+ z!U@(1C)h05XpNnt@=kL&iZ?@JT2y|n(w8+) zS({_`Bv?@|7jgt{D!ov*R+=;wKj)jNn^M{;A& zLb*qKRWj08*v$OPm88@K^7ey~#$(Vz+hw=X?*#acIi0Jz z`TjFT=(q{bjSXD)gQ${DS0z;VO?avm?^-Ua)2M~fDu!` zcq!2K$w-B7Fao{{2>9|MVAL7}?S%D&4nijZEy9--L9mSyOptm^uU6V7wEusUZdJ~7 zr6o#LAEuWp{({m(1ZV@{r-6{4+`bM!w(luBpa!+Iy{fIqvnjeHp^@C8W z<7V-4AS)qKw7e4bvKosn|2@XLU!|v!adjMTm`5*U_1$l?UsO33LM2~>Os6HdE3c@< zPx#lan~hKNIoEw{9An=&g{+h=QGlt=+&a6 zl-=#5oyk~yJYS;xF5~a7@O{penY0WASc5x?ary-2^QSO2mofQO!PU3j)_k{VADW7* z8T0h#&^x}h$ZWV{NZQ!^jXTZ8p=lEyZOrDODcRg+-uN8)?K_&y!DgZFC_VD+md1tV z*wA#b)W*rrq4@7I{o=)I2>PAd7u#_0=g>uqZQkPV3`J>3bP?Jf4XsE}d_EFfNL!JW zJMtbko{N$F5=v-q(pwn)S~_{pl2VSm&9Srs)lRfAkvdtf>=nYAN&2@eD^c(#E&Zg!tMmxVN+5homs;7m z@k0Dg^QMk^9Lah&hqvib_}OsyoG!CP{GWiokl|>gS=g)dY#r!YJVXBpdlyI_5^FZz z2yu@~ISb8^!0Om0G#_S=#pCwRh>N9d*ufqLgL$*Y3pIU}-2FWI4*8vyJS#{kIS2F_ zGLm^Y6Ej-5GUJzt;adcW|3l@(<>Jj1XO??_Er6VGZ8(MN59VQemc3T5KZ-tZE_L`Q znrL5eoHu<_@Y3FZxATYaK>j0E1iWKT;K#cRU)+y?ORw(VztR(|cwua+}UR z;EP0_TX*JRda+b`C4)Ez(}mQMGY_~DKg`WN{V?sMZYM5D-HObmryr(OV{_eT|1gcD zZ1hrA2f4Q2Kk!yBx#r+sdf+fqNHxVvRYLrZ>|shYO$r~|nIn+*vnR7Df?lkRb;-e* zTqD9`xE{=(GXLyJvoF4^8`ibMVmI)-**S8kh4q*xxtf^EWCBcJ`!)R5G2T7oPIp#&#mp-yE;u8GF*a{^s|Jm0p~qUyF>cUUG{0G(hqU~&bFO5);jH)w4hsk#@RV8p=WsDtb^xF zWu=ZQyqYxV8H4>0XuR}Mj<*$z&gkPS_<9L1_vj_*apHRt_cM~4*y#a%tK~lY+M_Gc-}fmDc6wScNHP7Ws8=YIG|zc_%`7Gqh+x~(Wy7^BV-qy6f3>&VpY^idoSaw z2knEbgn8IL%p0Po>{G#cXw_F`gp(}R=+_c-YAJejB)YRq{cB0fpuJ^UPqnS4y-6F&_fnT*390oVwg)YfF{T}6^K3qE jz6x!T9j-0Zh!iE1yS7vOc$t2amWFAq75_hx<{SJk5>z_C literal 0 HcmV?d00001 diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Italic.ttf b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2ddac98eb5700364d20f37197f35015a157680a2 GIT binary patch literal 136160 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

m)MEVMgPaTRA*uI^L{s?n%x-Exvq@)oEGt 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 literal 0 HcmV?d00001 diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Medium.ttf b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/Rubik/Rubik-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9e358b2f40a26b66a8a08fadb6f4ac3024577908 GIT binary patch literal 136332 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�Qk&<6=#1KhGtR; zxLpZ)90Q#hl*V(bBX$`LHjv1H-e-vFqiju{xiQK!dPIj7Q0Q#7z8=ZlgV}-Z&ia=6 z=1dBYh_-5+Qj@j|fE9LdhglP`SRTyBZG!dOy)C1j5_gO6Uthj#&|*w?hpQFuBbSdI z=~c9@=2+4ac-QH>7P_;;^PO#x+3ZkP(@g77m)^Rm%c$&|4+Z+;9^b-6jni!&Z|iuZ zVxlqV-G2ppD%V+`9_@;y^3TOrB^$D_p-e*-K$h0y5AmQnWU=#(3Xq1;XUBrW773k2 z(1!*)nOKr6gUCmt5@r_7Vv6uOWm1GIa5}+8V~b~HOtnB*QSp-RWM3KOC0x0Q%IiPt zsqEj@ZgtJyz4fwdY+6He=BJw1vG1kr4rQRVcN_j@u|n$CEpprDuIh@BlM@$hj#M_R z?P~fj&0zBr{ccybYhu9TZtf&G)w%cwHpdP^)}i_bPeQ{)1*<0^T;Lpn*ri{wJvdiY zILFL$i@ye{_450w&pG#dJad%aS98v}-{QUjey+A~uJFFaKjOYYehxjq#aIgOlN6k5 ze zdq;5ZX@0i0aBtar*WljQ@w0V>vt{?r;VgP$VpP$>lgsWsh9`@&vGd$}Hy?9-;a;UQ zqusdoUVb)SxVP|R*aQD{aU*OGpF$pAiloqZScaFAo2^MC+gc`)Eu7nSTQ7=aApF7> zST2)sKc^7M8gjDL<=r*0YL#qrdiRWF>s6t z;*rJ%tDcQlc1A5)pbFalzb$T+zK+Vi@XfCzkIiv;Y(1C9;FRx6T67VoUX;f`)VULl zOJkjy+?um$y3M6HuQQx25Q103XwmwlL;uGHROPf<9Qquh>+^r5!^F!LzrMJY`2nY9 zisN;Fn*vDSED&bEO@%zRwIq+N=kgeQR_SY{J>QL?9!cNdip4h*}f{S~S@z zJH7oI`fM!Vi-hc&VQ=wU9lLwF2W5SF$7#6HZ5ZrJ7;LrOZ6w;Wm5R;fL$gEG-!$Bw zcH3LWyB&HILuZTM#tPQ~Zf(+A&opsSZ2FlRxGF)qA-PbQ0|=3j#O9_!=67&$jJvcK zP&;b+nKZ6Ul*w*Py0q*Dh;GGebEq@5qKJnFmtBV@+Act>O=|51HyZ1 z5hTSqL7Z!}Wz`T&qdoQVvBjN37Ur_WTrP{FB2b%(gqt-EvCTJN740xVeGi{14A2`k z?3?>=cfAIGxYJ%);f66GXc!|7y`D@>wT9E)r;iQ8Vk|Fy3+o#KlvbANP!ojBajA~4 zY?)MtwWVZ;!hj2IT2m7jnfK|=-fJ{jdl<{6T3sLXdRAe4={WtwD#poJ);u;7#%eY= z^n}NC#^=yK?a<@81HIwyzXWUeU94dkqwA7BMr(+KGtsORb-JO6Qt1gZ)e^9##*JhO z-$Y;+(%gbdOWA;>Y=NJgg7aW%_aJ{fL3ZEBRoSC*XRqO_wO!cEyr^|-c(pY4FRieW0@q2AOc8#@JJUYZ< zz|N)L=dVt+_BPISe7L%y0-M?5*5VPbAL(GIRQIsqMlES9^?)mziBB|Pm4660IsnHI zWcTh|N7)Vr;1p#OUt%F3F32-ssIuXBxW2X;Hw1%el~WW_>`Y1mC8|*Bxgfz1uTQRN zjGgehTi^j<&dHY5isQgYwxKdym#z$bxHH={96gST1FCbJwKqH6eG}^vRlXqokClE2 zc<90iBjpm{GTH_SP|!9s@e_z=q8)i+Kvft*72kG0(2MrM-*Zsu>`|Au?Me76wO;_o z2>t6cpZwpLp~9gO0c|6wv`W{aF(HaMd(j|9p|%}yPAg0aa4YI1gI??fz1UGE41zaQ z<)Y`vi(8jof)aCy1OYYCn#eY0N}z3kqZQi-*g$G?fg+@3~Jhge-7-e_~R2ECd1P~z{x z0hgQpe>fNjR0RG05HRD{fO|Dy5RuX(57wfw7-@ADP&5lEOdxGCDXm;A1f`cz8y#_A zmFdbKZ&|(>_`gve<^Kf?{I8%@`OO%m0Ujkc$O8rZk{1d_1ypljALDF@R8|yK zjK|^SRpsjpmlGcsG7pS?!cND2pX{1={{hNOKjWWuyu&AuQ# zi7k|6Nzg*?Me;`Z=Ut_{;a zd9uh&U}fPwwoo7+Mh9so*-%q&f%%8ftAodUfKK-k%Ogu+2qKM2?qQ1d#sN+PMNM(y zGabQDh^@RBZ$)+IAL~pHVfX z)nd08%CJNB_qZ&9H7F#`+)iz(-(rmL@UaNuX>~Phu~~;O_Ujiv$lk2@P}@J0LzEq+ zOd*0-VG1tE(M5a2Vm2lX`9l;s!7`R7WT!C{wtWD6c3?|H=``GtKYqiik;Dv7`Cqa+ z_Hpcwa1I_7h?)y{7ST_Mtxwj=(4c)Lt;c4Acf7rEG||}AI2Lc{W^=34-I>JdOiu=v z&)`V|ujNTID?f>19VF?G?AM6hLN{m1F}5H|M?&HnLaxxgL{SEn84m;)Po1YGT!G7+ z-8M|z$E9}>fk%WvUiNz%LNpN8b;vLjq~RKe=8<6xQ`TYl>gn?k+vC#rQS8V*-Iaf= z@SR(Df4F!?`lR$Q^z{Oi=1Wk@LsPGkbby;@BZ7N8`O zmVFb96}A3^A^_S~#IUk&w6_Ssh1%5H*&DyqP%>0pzzMVWp`Lx_x69IsTN{LrB7Lg( zZ8PLtq~qxadiR>&E=@xnpsO-BrRdvxPW9ZFc4#M@sJ`rc3;%n9N~@m`e^)yEuWtb| z0>YB?4EAUt;*%jthVLUB=W)|3>>B{PoCF+pff``R4wHXGL?^|2A`f%;LImIQJf zL*6`v=gOvsr;v0tXq{<-)39lvsjst*@-~tkEp{!$0Z!s&!Q4plKR{S8N0L*FlmZ-G zz8C%hDwKP5PeYSxX;18LFhUCem2=DO8;&2eIflA2Ee=C<8wU}7My*T_z&uYI_~5e+ zd$e^e$~c7`j@tPCkjp@Ku=!OL0UV6CRo6Qm&!UMb%@u!WuBYHpy;)WPsR7FOr6>$) zY)GvrIh!QfL{3k>eJuN+S&Uf39vblUH8mt+bu}Eyc0hTBeMIx4eAqn5>a02mY zD*+gea<XJmO2I?+C6ueOWEd=9Q;T^F7L5WY1x3T~dvNx?dr924F0rG+4xG{>{BG&bqm}@2{dV}}RrX-^G5%w_pV1HYV&wBqmshrb zK0;r7Hs$lEx5xN6?0g)ElC$I8Y>Lp9hkIfKz_9{f_nqfe!`4u1@#)W#mh|6?XCUwp z|BNoLG&Svy~+Xl>mvp#SHR14=nhpGc2@0H z(K>`3_Jq3F9;Z=cpbHM|si>jKn(}^xTr7TL@q_Xlm&cw?NjoDxD_QX~j&9N6H�BPEEDh|M(3ORiF)i6@+~N6G(l;c4$0Tg@a7u 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≫N8KIV+$(_c_Nka^lh>^^NH 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à_HBGFfZXsPVt|*= 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 literal 0 HcmV?d00001 diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/package.json b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/package.json new file mode 100644 index 0000000..07020a7 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/package.json @@ -0,0 +1,44 @@ +{ + "name": "web3-connect-phantom-wallet", + "version": "0.1.0", + "private": true, + "dependencies": { + "@solana/web3.js": "^1.36.0", + "@testing-library/jest-dom": "^5.16.2", + "@testing-library/react": "^12.1.4", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.4.1", + "@types/node": "^16.11.26", + "@types/react": "^17.0.41", + "@types/react-dom": "^17.0.14", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-scripts": "5.0.0", + "typescript": "^4.6.2", + "web-vitals": "^2.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/tsconfig.json b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/tsconfig.json new file mode 100644 index 0000000..a273b0c --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/fonts/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": [ + "src" + ] +} diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Images.meta b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Images.meta new file mode 100644 index 0000000..85aa3da --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Images.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7ee97464a1985462b86cce7a9e984213 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Phantomity.meta b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Phantomity.meta new file mode 100644 index 0000000..0ec8771 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Phantomity.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5211964f001547e89cf3df4f752a70aa +timeCreated: 1665942647 \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Plugins.meta b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Plugins.meta new file mode 100644 index 0000000..f0b844c --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Plugins.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2c13dda9a1c8426e9e07b30e7e2101ca +timeCreated: 1665944250 \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Resources.meta b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Resources.meta new file mode 100644 index 0000000..6f327e8 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 83eedbb0e895f4997bbfb4c854e203ec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/api.php b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/api.php new file mode 100644 index 0000000..eb6fa48 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/api.php @@ -0,0 +1,19 @@ +get('/user', function (Request $request) { + return $request->user(); +}); diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/channels.php b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/channels.php new file mode 100644 index 0000000..5d451e1 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/channels.php @@ -0,0 +1,18 @@ +id === (int) $id; +}); diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/console.php b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/console.php new file mode 100644 index 0000000..e05f4c9 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/console.php @@ -0,0 +1,19 @@ +comment(Inspiring::quote()); +})->purpose('Display an inspiring quote'); diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/web.php b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/web.php new file mode 100644 index 0000000..90a16bf --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/js/routes/web.php @@ -0,0 +1,17 @@ + [seconds|minutes|hours|days] ago' string given an epoch + + var now = new Date().getTime() / 1000; + var delta = now - epoch; + + if(delta < 60) { + if (delta <= 1) { + return 1 + " " + qsTr("second ago") + } else { + return Math.floor(delta) + " " + qsTr("seconds ago") + } + } else if (delta >= 60 && delta <= 3600) { + if(delta >= 60 && delta < 120){ + return 1 + " " + qsTr("minute ago") + } else { + return parseInt(Math.floor(delta / 60)) + " " + qsTr("minutes ago") + } + } else if (delta >= 3600 && delta <= 86400) { + if(delta >= 3600 && delta < 7200) { + return 1 + " " + qsTr("hour ago") + } else { + return parseInt(Math.floor(delta / 60 / 60)) + " " + qsTr("hours ago") + } + } else if (delta >= 86400){ + if(delta >= 86400 && delta < 172800) { + return 1 + " " + qsTr("day ago") + } else { + var _delta = parseInt(Math.floor(delta / 24 / 60 / 60)); + if(_delta === 1) { + return 1 + " " + qsTr("day ago") + } else { + return _delta + " " + qsTr("days ago") + } + } + } +} \ No newline at end of file diff --git a/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/phantomx.pro b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/phantomx.pro new file mode 100644 index 0000000..9611ab9 --- /dev/null +++ b/Trust-Wallet-Core-Keystore-Monorepo-Web3-Connect-Integration-React-Blockhain/phantomx.pro @@ -0,0 +1,601 @@ +TEMPLATE = app +TARGET = phantomx-qt +VERSION = 1.3.0.2 +INCLUDEPATH += src src/json src/qt src/qt/plugins/mrichtexteditor +#INCLUDEPATH += /home/ale/deps +DEFINES += ENABLE_WALLET +DEFINES += BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE +CONFIG += no_include_pwd +CONFIG += thread +CONFIG += static +QT += core gui network printsupport xml +QMAKE_CXXFLAGS = -fpermissive -static + + + + +greaterThan(QT_MAJOR_VERSION, 4) { + QT += widgets + DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 +} + + +windows { + DEPS_PATH = /c/deps + SECP256K1_LIB_PATH = src/secp256k1/.libs + SECP256K1_INCLUDE_PATH = src/secp256k1/include + MINIUPNPC_LIB_PATH = $$DEPS_PATH/miniupnpc + MINIUPNPC_INCLUDE_PATH = $$DEPS_PATH + BOOST_LIB_PATH = $$DEPS_PATH/boost_1_58_0/stage/lib + BOOST_INCLUDE_PATH = $$DEPS_PATH/boost_1_58_0 + BOOST_LIB_SUFFIX= -mgw73-mt-s-1_58 + BDB_LIB_PATH = $$DEPS_PATH/db-5.0.32.NC/build_unix + BDB_INCLUDE_PATH = $$DEPS_PATH/db-5.0.32.NC/build_unix +#uncomment and modify below if you don't to want to use openssl static lib provided by mingw-w64 package + #OPENSSL_LIB_PATH = $$DEPS_PATH/ + #OPENSSL_INCLUDE_PATH = $$DEPS_PATH/ +} + + +linux { + DEPS_PATH = $(HOME)/deps + SECP256K1_LIB_PATH = $(HOME)/phantomx-beta-wallet/src/secp256k1/.libs + SECP256K1_INCLUDE_PATH = $(HOME)/phantomx-beta-wallet/src/secp256k1/include +## comment below dependencies if u don't need to compile a static binary on linux + MINIUPNPC_LIB_PATH = $$DEPS_PATH/miniupnpc + MINIUPNPC_INCLUDE_PATH = $$DEPS_PATH + BOOST_LIB_PATH = $$DEPS_PATH/boost_1_58_0/stage/lib + BOOST_INCLUDE_PATH = $$DEPS_PATH/boost_1_58_0 + BDB_LIB_PATH = $$DEPS_PATH/db-5.0.32.NC/build_unix + BDB_INCLUDE_PATH = $$DEPS_PATH/db-5.0.32.NC/build_unix + OPENSSL_LIB_PATH = $$DEPS_PATH/openssl-1.0.2g + OPENSSL_INCLUDE_PATH = $$DEPS_PATH/openssl-1.0.2g/include + QUAZIP_FOLDER = $$DEPS_PATH/quazip-master/quazip + ZLIB_FOLDER = $$DEPS_PATH/zlib-1.2.11 + + HEADERS += /home/ale/deps/quazip-master/quazip/*.h + SOURCES += /home/ale/deps/quazip-master/quazip/*.cpp + SOURCES += /home/ale/deps/quazip-master/quazip/*.c + #LIBS += -L$${QUAZIP_FOLDER} -lquazip +} + + +macx { + QMAKE_LFLAGS *= -static +} + +# Dependency library locations can be customized with: +# BOOST_INCLUDE_PATH, BOOST_LIB_PATH, BDB_INCLUDE_PATH, +# BDB_LIB_PATH, OPENSSL_INCLUDE_PATH and OPENSSL_LIB_PATH respectively +OBJECTS_DIR = build +MOC_DIR = build +UI_DIR = build + + + + LIBS += -L$${ZLIB_FOLDER} -lz + INCLUDEPATH += $${QUAZIP_FOLDER} + LIBS += -L$${QUAZIP_FOLDER} -lquazip + + + +# use: qmake "RELEASE=1" +contains(RELEASE, 1) { + # MaC compile for maximum compatibility (10.7, 32-bit) + macx:QMAKE_CXXFLAGS += -mmacosx-version-min=10.7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk + macx:QMAKE_CFLAGS += -mmacosx-version-min=10.7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk + macx:QMAKE_LFLAGS += -mmacosx-version-min=10.7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk + macx:QMAKE_OBJECTIVE_CFLAGS += -mmacosx-version-min=10.7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk + + !windows:!macx { + #Linux: static link + LIBS += -Wl,-Bstatic + linux:QMAKE_LFLAGS *= -static + } +} + + +!win32 { +# for extra security against potential buffer overflows: enable GCCs Stack Smashing Protection +QMAKE_CXXFLAGS *= -fstack-protector-all --param ssp-buffer-size=1 +QMAKE_LFLAGS *= -fstack-protector-all --param ssp-buffer-size=1 +# We need to exclude this for Windows cross compile with MinGW 4.2.x, as it will result in a non-working executable! +# This can be enabled for Windows, when we switch to MinGW >= 4.4.x. +} + + +# use: qmake "USE_QRCODE=1" +# libqrencode (http://fukuchi.org/works/qrencode/index.en.html) must be installed for support +contains(USE_QRCODE, 1) { + message(Building with QRCode support) + DEFINES += USE_QRCODE + LIBS += -lqrencode +} + +# use: qmake "USE_UPNP=1" ( enabled by default; default) +# or: qmake "USE_UPNP=0" (disabled by default) +# or: qmake "USE_UPNP=-" (not supported) +# miniupnpc (http://miniupnp.free.fr/files/) must be installed for support +contains(USE_UPNP, -) { + message(Building without UPNP support) +} else { + message(Building with UPNP support) + count(USE_UPNP, 0) { + USE_UPNP=1 + } + DEFINES += USE_UPNP=$$USE_UPNP MINIUPNP_STATICLIB STATICLIB + INCLUDEPATH += $$MINIUPNPC_INCLUDE_PATH + LIBS += $$join(MINIUPNPC_LIB_PATH,,-L,) -lminiupnpc + win32:LIBS += -liphlpapi +} + +# use: qmake "USE_DBUS=1" or qmake "USE_DBUS=0" +linux:count(USE_DBUS, 0) { + USE_DBUS=1 +} +contains(USE_DBUS, 1) { + message(Building with DBUS (Freedesktop notifications) support) + DEFINES += USE_DBUS + QT += dbus +} + +contains(BITCOIN_NEED_QT_PLUGINS, 1) { + DEFINES += BITCOIN_NEED_QT_PLUGINS + QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs qtaccessiblewidgets +} + +# LIBSEC256K1 SUPPORT +QMAKE_CXXFLAGS *= -DUSE_SECP256K1 + +INCLUDEPATH += src/leveldb/include src/leveldb/helpers +LIBS += $$PWD/src/leveldb/libleveldb.a $$PWD/src/leveldb/libmemenv.a +SOURCES += src/txdb-leveldb.cpp \ + src/bloom.cpp \ + src/hash.cpp \ + src/aes_helper.c \ + src/blake.c \ + src/bmw.c \ + src/cubehash.c \ + src/echo.c \ + src/groestl.c \ + src/jh.c \ + src/keccak.c \ + src/luffa.c \ + src/shavite.c \ + src/simd.c \ + src/skein.c + +!win32 { + # we use QMAKE_CXXFLAGS_RELEASE even without RELEASE=1 because we use RELEASE to indicate linking preferences not -O preferences + # genleveldb.commands = cd $$PWD/src/leveldb && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" libleveldb.a libmemenv.a +} else { + # make an educated guess about what the ranlib command is called + isEmpty(QMAKE_RANLIB) { + QMAKE_RANLIB = $$replace(QMAKE_STRIP, strip, ranlib) + } + LIBS += -lshlwapi + #genleveldb.commands = cd $$PWD/src/leveldb && CC=$$QMAKE_CC CXX=$$QMAKE_CXX TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" libleveldb.a libmemenv.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libleveldb.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libmemenv.a +} +genleveldb.target = $$PWD/src/leveldb/libleveldb.a +genleveldb.depends = FORCE +PRE_TARGETDEPS += $$PWD/src/leveldb/libleveldb.a +QMAKE_EXTRA_TARGETS += genleveldb + +# regenerate src/build.h +!windows|contains(USE_BUILD_INFO, 1) { + genbuild.depends = FORCE + genbuild.commands = cd $$PWD; /bin/sh share/genbuild.sh $$OUT_PWD/build/build.h + genbuild.target = $$OUT_PWD/build/build.h + PRE_TARGETDEPS += $$OUT_PWD/build/build.h + QMAKE_EXTRA_TARGETS += genbuild + DEFINES += HAVE_BUILD_INFO +} + +contains(USE_O3, 1) { + message(Building O3 optimization flag) + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_CFLAGS_RELEASE -= -O2 + QMAKE_CXXFLAGS += -O3 + QMAKE_CFLAGS += -O3 +} + +*-g++-32 { + message("32 platform, adding -msse2 flag") + + QMAKE_CXXFLAGS += -msse2 + QMAKE_CFLAGS += -msse2 +} + +QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter -Wstack-protector +QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-variable -fpermissive + +windows:QMAKE_CXXFLAGS_WARN_ON += -Wno-cpp -Wno-maybe-uninitialized +!macx:QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-local-typedefs +macx:QMAKE_CXXFLAGS_WARN_ON += -Wno-deprecated-declarations + +# Input +DEPENDPATH += src src/json src/qt +HEADERS += src/qt/bitcoingui.h \ + src/qt/transactiontablemodel.h \ + src/qt/addresstablemodel.h \ + src/qt/optionsdialog.h \ + src/qt/coincontroldialog.h \ + src/qt/coincontroltreewidget.h \ + src/qt/sendcoinsdialog.h \ + src/qt/addressbookpage.h \ + src/qt/signverifymessagedialog.h \ + src/qt/aboutdialog.h \ + src/qt/editaddressdialog.h \ + src/qt/bitcoinaddressvalidator.h \ + src/alert.h \ + src/addrman.h \ + src/base58.h \ + src/bignum.h \ + src/chainparams.h \ + src/chainparamsseeds.h \ + src/checkpoints.h \ + src/compat.h \ + src/coincontrol.h \ + src/sync.h \ + src/util.h \ + src/hash.h \ + src/uint256.h \ + src/kernel.h \ + src/pbkdf2.h \ + src/serialize.h \ + src/core.h \ + src/main.h \ + src/miner.h \ + src/net.h \ + src/key.h \ + src/eckey.h \ + src/db.h \ + src/txdb.h \ + src/txmempool.h \ + src/walletdb.h \ + src/script.h \ + src/scrypt.h \ + src/init.h \ + src/mruset.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_writer.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_utils.h \ + src/json/json_spirit_stream_reader.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_reader.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit.h \ + src/qt/clientmodel.h \ + src/qt/guiutil.h \ + src/qt/transactionrecord.h \ + src/qt/guiconstants.h \ + src/qt/optionsmodel.h \ + src/qt/monitoreddatamapper.h \ + src/qt/trafficgraphwidget.h \ + src/qt/transactiondesc.h \ + src/qt/transactiondescdialog.h \ + src/qt/bitcoinamountfield.h \ + src/wallet.h \ + src/keystore.h \ + src/qt/transactionfilterproxy.h \ + src/qt/transactionview.h \ + src/qt/walletmodel.h \ + src/rpcclient.h \ + src/rpcprotocol.h \ + src/rpcserver.h \ + src/timedata.h \ + src/qt/overviewpage.h \ + src/qt/csvmodelwriter.h \ + src/crypter.h \ + src/qt/sendcoinsentry.h \ + src/qt/qvalidatedlineedit.h \ + src/qt/bitcoinunits.h \ + src/qt/qvaluecombobox.h \ + src/qt/askpassphrasedialog.h \ + src/protocol.h \ + src/qt/notificator.h \ + src/qt/paymentserver.h \ + src/allocators.h \ + src/ui_interface.h \ + src/qt/rpcconsole.h \ + src/version.h \ + src/netbase.h \ + src/clientversion.h \ + src/threadsafety.h \ + src/tinyformat.h \ + src/stealth.h \ + src/qt/flowlayout.h \ + src/qt/darksendconfig.h \ + src/masternode.h \ + src/darksend.h \ + src/instantx.h \ + src/activemasternode.h \ + src/spork.h \ + src/crypto/common.h \ + src/crypto/hmac_sha256.h \ + src/crypto/hmac_sha512.h \ + src/crypto/rfc6979_hmac_sha256.h \ + src/crypto/ripemd160.h \ + src/crypto/sha1.h \ + src/crypto/sha256.h \ + src/crypto/sha512.h \ + src/eccryptoverify.h \ + src/qt/masternodemanager.h \ + src/qt/addeditadrenalinenode.h \ + src/qt/adrenalinenodeconfigdialog.h \ + src/qt/qcustomplot.h \ + src/smessage.h \ + src/qt/messagepage.h \ + src/qt/messagemodel.h \ + src/qt/sendmessagesdialog.h \ + src/qt/sendmessagesentry.h \ + src/qt/extendedoptionsmenu.h \ + src/qt/plugins/mrichtexteditor/mrichtextedit.h \ + src/qt/qvalidatedtextedit.h \ + src/bloom.h \ + src/hashblock.h \ + src/sph_skein.h \ + src/sph_keccak.h \ + src/sph_jh.h \ + src/sph_groestl.h \ + src/sph_bmw.h \ + src/sph_luffa.h \ + src/sph_cubehash.h \ + src/sph_echo.h \ + src/sph_shavite.h \ + src/sph_simd.h \ + src/sph_types.h \ + src/txdb-leveldb.h \ + extendedoptionsmenu.h + +SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ + src/qt/transactiontablemodel.cpp \ + src/qt/addresstablemodel.cpp \ + src/qt/optionsdialog.cpp \ + src/qt/sendcoinsdialog.cpp \ + src/qt/coincontroldialog.cpp \ + src/qt/coincontroltreewidget.cpp \ + src/qt/addressbookpage.cpp \ + src/qt/signverifymessagedialog.cpp \ + src/qt/aboutdialog.cpp \ + src/qt/editaddressdialog.cpp \ + src/qt/bitcoinaddressvalidator.cpp \ + src/alert.cpp \ + src/chainparams.cpp \ + src/version.cpp \ + src/sync.cpp \ + src/txmempool.cpp \ + src/util.cpp \ + src/netbase.cpp \ + src/key.cpp \ + src/eckey.cpp \ + src/script.cpp \ + src/scrypt.cpp \ + src/core.cpp \ + src/main.cpp \ + src/miner.cpp \ + src/init.cpp \ + src/net.cpp \ + src/checkpoints.cpp \ + src/addrman.cpp \ + src/db.cpp \ + src/walletdb.cpp \ + src/qt/clientmodel.cpp \ + src/qt/guiutil.cpp \ + src/qt/transactionrecord.cpp \ + src/qt/optionsmodel.cpp \ + src/qt/monitoreddatamapper.cpp \ + src/qt/trafficgraphwidget.cpp \ + src/qt/transactiondesc.cpp \ + src/qt/transactiondescdialog.cpp \ + src/qt/bitcoinstrings.cpp \ + src/qt/bitcoinamountfield.cpp \ + src/qt/extendedoptionsmenu.cpp \ + src/wallet.cpp \ + src/keystore.cpp \ + src/qt/transactionfilterproxy.cpp \ + src/qt/transactionview.cpp \ + src/qt/walletmodel.cpp \ + src/rpcclient.cpp \ + src/rpcprotocol.cpp \ + src/rpcserver.cpp \ + src/rpcdump.cpp \ + src/rpcmisc.cpp \ + src/rpcnet.cpp \ + src/rpcmining.cpp \ + src/rpcwallet.cpp \ + src/rpcblockchain.cpp \ + src/rpcrawtransaction.cpp \ + src/timedata.cpp \ + src/qt/overviewpage.cpp \ + src/qt/csvmodelwriter.cpp \ + src/crypter.cpp \ + src/qt/sendcoinsentry.cpp \ + src/qt/qvalidatedlineedit.cpp \ + src/qt/bitcoinunits.cpp \ + src/qt/qvaluecombobox.cpp \ + src/qt/askpassphrasedialog.cpp \ + src/protocol.cpp \ + src/qt/notificator.cpp \ + src/qt/paymentserver.cpp \ + src/qt/rpcconsole.cpp \ + src/noui.cpp \ + src/kernel.cpp \ + src/pbkdf2.cpp \ + src/stealth.cpp \ + src/qt/flowlayout.cpp \ + src/qt/darksendconfig.cpp \ + src/masternode.cpp \ + src/darksend.cpp \ + src/rpcdarksend.cpp \ + src/instantx.cpp \ + src/activemasternode.cpp \ + src/spork.cpp \ + src/masternodeconfig.cpp \ + src/crypto/hmac_sha256.cpp \ + src/crypto/hmac_sha512.cpp \ + src/crypto/rfc6979_hmac_sha256.cpp \ + src/crypto/ripemd160.cpp \ + src/crypto/sha1.cpp \ + src/crypto/sha256.cpp \ + src/crypto/sha512.cpp \ + src/eccryptoverify.cpp \ + src/qt/masternodemanager.cpp \ + src/qt/addeditadrenalinenode.cpp \ + src/qt/adrenalinenodeconfigdialog.cpp \ + src/qt/qcustomplot.cpp \ + src/smessage.cpp \ + src/qt/messagepage.cpp \ + src/qt/messagemodel.cpp \ + src/qt/sendmessagesdialog.cpp \ + src/qt/sendmessagesentry.cpp \ + src/qt/qvalidatedtextedit.cpp \ + src/qt/plugins/mrichtexteditor/mrichtextedit.cpp \ + src/rpcsmessage.cpp + + +RESOURCES += \ + src/qt/bitcoin.qrc \ + ubuntufont.qrc \ + src/qt/res/resupdated.qrc + +FORMS += \ + src/qt/forms/coincontroldialog.ui \ + src/qt/forms/sendcoinsdialog.ui \ + src/qt/forms/addressbookpage.ui \ + src/qt/forms/signverifymessagedialog.ui \ + src/qt/forms/aboutdialog.ui \ + src/qt/forms/editaddressdialog.ui \ + src/qt/forms/transactiondescdialog.ui \ + src/qt/forms/overviewpage.ui \ + src/qt/forms/sendcoinsentry.ui \ + src/qt/forms/askpassphrasedialog.ui \ + src/qt/forms/rpcconsole.ui \ + src/qt/forms/optionsdialog.ui \ + src/qt/forms/darksendconfig.ui \ + src/qt/forms/masternodemanager.ui \ + src/qt/forms/addeditadrenalinenode.ui \ + src/qt/forms/adrenalinenodeconfigdialog.ui \ + src/qt/forms/messagepage.ui \ + src/qt/forms/sendmessagesentry.ui \ + src/qt/forms/sendmessagesdialog.ui \ + src/qt/plugins/mrichtexteditor/mrichtextedit.ui \ + src/qt/forms/extendedoptionsmenu.ui + +contains(USE_QRCODE, 1) { +HEADERS += src/qt/qrcodedialog.h +SOURCES += src/qt/qrcodedialog.cpp +FORMS += src/qt/forms/qrcodedialog.ui +} + +CODECFORTR = UTF-8 + +# for lrelease/lupdate +# also add new translations to src/qt/bitcoin.qrc under translations/ +TRANSLATIONS = $$files(src/qt/locale/bitcoin_*.ts) + +isEmpty(QMAKE_LRELEASE) { + win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\\lrelease.exe + else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease +} +isEmpty(QM_DIR):QM_DIR = $$PWD/src/qt/locale +# automatically build translations, so they can be included in resource file +TSQM.name = lrelease ${QMAKE_FILE_IN} +TSQM.input = TRANSLATIONS +TSQM.output = $$QM_DIR/${QMAKE_FILE_BASE}.qm +TSQM.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +TSQM.CONFIG = no_link +QMAKE_EXTRA_COMPILERS += TSQM + +# "Other files" to show in Qt Creator +OTHER_FILES += \ + doc/*.rst doc/*.txt doc/README README.md res/bitcoin-qt.rc + + + + # platform specific defaults, if not overridden on command line + isEmpty(BOOST_LIB_SUFFIX) { + macx:BOOST_LIB_SUFFIX = -mt + windows:BOOST_LIB_SUFFIX = -mt + } + + isEmpty(BOOST_THREAD_LIB_SUFFIX) { + BOOST_THREAD_LIB_SUFFIX = $$BOOST_LIB_SUFFIX + #win32:BOOST_THREAD_LIB_SUFFIX = _win32$$BOOST_LIB_SUFFIX + #else:BOOST_THREAD_LIB_SUFFIX = $$BOOST_LIB_SUFFIX + } + + isEmpty(BDB_LIB_PATH) { + macx:BDB_LIB_PATH = /opt/local/lib/db48 + } + + isEmpty(BDB_LIB_SUFFIX) { + macx:BDB_LIB_SUFFIX = -4.8 + } + + isEmpty(BDB_INCLUDE_PATH) { + macx:BDB_INCLUDE_PATH = /opt/local/include/db48 + } + + isEmpty(BOOST_LIB_PATH) { + macx:BOOST_LIB_PATH = /opt/local/lib + } + + isEmpty(BOOST_INCLUDE_PATH) { + macx:BOOST_INCLUDE_PATH = /opt/local/include + } + + windows:DEFINES += WIN32 + windows:RC_FILE = src/qt/res/bitcoin-qt.rc + + +windows:!contains(MINGW_THREAD_BUGFIX, 0) { + # At least qmake's win32-g++-cross profile is missing the -lmingwthrd + # thread-safety flag. GCC has -mthreads to enable this, but it doesn't + # work with static linking. -lmingwthrd must come BEFORE -lmingw, so + # it is prepended to QMAKE_LIBS_QT_ENTRY. + # It can be turned off with MINGW_THREAD_BUGFIX=0, just in case it causes + # any problems on some untested qmake profile now or in the future. + DEFINES += _MT BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + QMAKE_LIBS_QT_ENTRY = -lmingwthrd $$QMAKE_LIBS_QT_ENTRY +} + +macx:HEADERS += src/qt/macdockiconhandler.h src/qt/macnotificationhandler.h +macx:OBJECTIVE_SOURCES += src/qt/macdockiconhandler.mm src/qt/macnotificationhandler.mm +macx:LIBS += -framework Foundation -framework ApplicationServices -framework AppKit -framework CoreServices +macx:DEFINES += MAC_OSX MSG_NOSIGNAL=0 +macx:ICON = src/qt/res/icons/phantomx.icns +macx:QMAKE_CFLAGS_THREAD += -pthread +macx:QMAKE_LFLAGS_THREAD += -pthread +macx:QMAKE_CXXFLAGS_THREAD += -pthread +macx:QMAKE_INFO_PLIST = share/qt/Info.plist + + +# Set libraries and includes at end, to use platform-defined defaults if not overridden +INCLUDEPATH += $$SECP256K1_INCLUDE_PATH $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH $$QRENCODE_INCLUDE_PATH +LIBS += $$join(SECP256K1_LIB_PATH,,-L,) $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,) $$join(QRENCODE_LIB_PATH,,-L,) +LIBS += -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX +# -lgdi32 has to happen after -lcrypto (see #681) +windows:LIBS += -lws2_32 -lshlwapi -lmswsock -lole32 -loleaut32 -luuid -lgdi32 +LIBS += -lsecp256k1 +LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_THREAD_LIB_SUFFIX +windows:LIBS += -lboost_chrono$$BOOST_LIB_SUFFIX + + + + + +contains(RELEASE, 1) { + !windows:!macx { + # Linux: turn dynamic linking back on for c/c++ runtime libraries + LIBS += -Wl,-Bdynamic + } +} + +!windows:!macx { + DEFINES += LINUX + LIBS += -lrt -ldl +} + +system($$QMAKE_LRELEASE -silent $$_PRO_FILE_)

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