From add2de9b51af4625e6f3bbda80784b04e0761dae Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 25 May 2021 16:43:47 +0200 Subject: [PATCH 01/29] fixed tracking wallet seed phrase --- src/wallet/plain_wallet_api.cpp | 8 ++--- src/wallet/wallet_helpers.h | 10 ++++++ src/wallet/wallet_public_structs_defs.h | 2 ++ tests/functional_tests/plain_wallet_tests.cpp | 32 +++++++++++++------ 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/wallet/plain_wallet_api.cpp b/src/wallet/plain_wallet_api.cpp index b7a91e8f..4b8a8fd6 100644 --- a/src/wallet/plain_wallet_api.cpp +++ b/src/wallet/plain_wallet_api.cpp @@ -95,21 +95,21 @@ namespace plain_wallet std::string get_wallets_folder() { #ifdef WIN32 - return ""; + std::string path = get_bundle_working_dir() + "/" + WALLETS_FOLDER_NAME + "/"; #else std::string path = get_bundle_working_dir() + "/" + WALLETS_FOLDER_NAME + "/"; - return path; #endif // WIN32 + return path; } std::string get_app_config_folder() { #ifdef WIN32 - return ""; + std::string path = get_bundle_working_dir() + "/" + APP_CONFIG_FOLDER + "/"; #else std::string path = get_bundle_working_dir() + "/" + APP_CONFIG_FOLDER + "/"; - return path; #endif // WIN32 + return path; } #ifdef ANDROID_BUILD class android_logger : public log_space::ibase_log_stream diff --git a/src/wallet/wallet_helpers.h b/src/wallet/wallet_helpers.h index 12355011..03533bf7 100644 --- a/src/wallet/wallet_helpers.h +++ b/src/wallet/wallet_helpers.h @@ -48,6 +48,16 @@ namespace tools result.hash_sum_matched = false; } } + if (!result.syntax_correct) + { + //possibly tracking wallet + currency::account_base acc; + result.syntax_correct = acc.restore_from_tracking_seed(seed_phrase); + if (result.syntax_correct) + { + result.tracking = true; + } + } return API_RETURN_CODE_OK; } } \ No newline at end of file diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 7b0c344e..5324b8d7 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -184,11 +184,13 @@ namespace wallet_public bool syntax_correct; bool require_password; bool hash_sum_matched; + bool tracking; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(syntax_correct) KV_SERIALIZE(require_password) KV_SERIALIZE(hash_sum_matched) + KV_SERIALIZE(tracking) END_KV_SERIALIZE_MAP() }; diff --git a/tests/functional_tests/plain_wallet_tests.cpp b/tests/functional_tests/plain_wallet_tests.cpp index 457dcefc..f6efe29f 100644 --- a/tests/functional_tests/plain_wallet_tests.cpp +++ b/tests/functional_tests/plain_wallet_tests.cpp @@ -31,17 +31,29 @@ struct try_pull_result_open_response void run_plain_wallet_api_test() { LOG_PRINT_L0("Creating instance..."); - std::string s = plain_wallet::init("195.201.107.230", "11211", boost::dll::program_location().parent_path().string(), 1); - s = plain_wallet::get_export_private_info("E:\\tmp\\check_export"); - std::string key = plain_wallet::generate_random_key(10); - std::string test_data = "1234567890 test test "; - std::string res = plain_wallet::set_appconfig(test_data, key); - std::string test_data2 = plain_wallet::get_appconfig(key); - if (test_data2 != test_data) - { - LOG_ERROR("Error"); - } + //plain_wallet::set_bundle_working_dir("E:\\tmp\\check_export"); + std::string s = plain_wallet::init("195.201.107.230", "33333", boost::dll::program_location().parent_path().string(), 1); + //s = plain_wallet::get_export_private_info("E:\\tmp\\check_export"); + + + std::string res = plain_wallet::sync_call("get_seed_phrase_info", 0, "{\"seed_phrase\":\"aZxat4HAWriVQ3enkGcVsrZRdMseAJswG3CSEwTqZS246VsFQ53w26eZstYsu1jWE74Atz9ajLxFnBsVTafncWNH5SMv4zHFaTS:1780c4d5dd7e97cc4a75ea8baa7977d12ef948b9a6dddc2a9a37e5e22ac7180e:1599495055\"}"); + + + res = plain_wallet::restore("footstep knowledge fur capture honey minute carefully peaceful lovely crawl lunch government nightmare friendship myself sign possibly plan flower depression bread rainbow wrong hardly dark chest", + "test_wall2.zan", "111", ""); + + + epee::misc_utils::sleep_no_w(10000000); + + //std::string key = plain_wallet::generate_random_key(10); + //std::string test_data = "1234567890 test test "; + //std::string res = plain_wallet::set_appconfig(test_data, key); + //std::string test_data2 = plain_wallet::get_appconfig(key); + //if (test_data2 != test_data) + //{ + // LOG_ERROR("Error"); + //} return; //std::string fres = plain_wallet::get_logs_buffer(); //std::string fres2 = plain_wallet::truncate_log(); From 3939277ed07d171953948dfdd63b3294e76439eb Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 25 May 2021 17:02:10 +0200 Subject: [PATCH 02/29] Added tracking attribute --- src/wallet/wallet_helpers.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/wallet_helpers.h b/src/wallet/wallet_helpers.h index 8e37d856..9ebf9137 100644 --- a/src/wallet/wallet_helpers.h +++ b/src/wallet/wallet_helpers.h @@ -37,6 +37,8 @@ namespace tools result.require_password = false; result.hash_sum_matched = false; result.syntax_correct = acc.restore_from_tracking_seed(seed_phrase); + if (result.syntax_correct) + result.tracking = true; } else { From b9d43f8834ff5397b9d44516f0a6ac896012ab3e Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 2 Jun 2021 00:19:06 +0300 Subject: [PATCH 03/29] increment build number script fix --- utils/increment_build_number.sh | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/utils/increment_build_number.sh b/utils/increment_build_number.sh index e9f78c08..c309f973 100644 --- a/utils/increment_build_number.sh +++ b/utils/increment_build_number.sh @@ -3,12 +3,11 @@ curr_path=${BASH_SOURCE%/*} version_file_path=../src/version.h.in pushd $curr_path + +# clear old local changes if any +git checkout -- src/* + git pull --ff-only -if [ $? -ne 0 ]; then - echo "Failed to pull" - popd - exit $? -fi build_no_before=`cat $version_file_path | grep 'PROJECT_VERSION_BUILD_NO ' | awk {'print $3'}` @@ -19,15 +18,11 @@ build_no_after=`cat $version_file_path | grep 'PROJECT_VERSION_BUILD_NO ' | awk echo "$build_no_before -> $build_no_after" echo $(pwd -P) + git status git commit -a -m"=== build number: $build_no_before -> $build_no_after ===" git push -if [ $? -ne 0 ]; then - echo "Failed to push" - popd - exit $? -fi echo "Build number was succesefully incremented." popd From 1a8c6b0dfa180c42cbd986e6a1be9bd3094559e3 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 2 Jun 2021 00:46:10 +0300 Subject: [PATCH 04/29] increment build number script fix 2 --- utils/increment_build_number.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/increment_build_number.sh b/utils/increment_build_number.sh index c309f973..3666c956 100644 --- a/utils/increment_build_number.sh +++ b/utils/increment_build_number.sh @@ -5,7 +5,7 @@ version_file_path=../src/version.h.in pushd $curr_path # clear old local changes if any -git checkout -- src/* +git checkout -- ../src/* git pull --ff-only From 907d428689c2d1f6647b3284bdbe58f0415e55d4 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 3 Jun 2021 16:02:15 +0300 Subject: [PATCH 05/29] readme: versions update, boost link fix, grammar corrections, GUI/server emphasized --- README.md | 70 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 6af4daa1..83722e9f 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,73 @@ [![Coverity Scan](https://scan.coverity.com/projects/18767/badge.svg)](https://scan.coverity.com/projects/zanoproject) [![Discord](https://img.shields.io/discord/538361472691077130?label=discord&logo=discord)](https://discord.gg/wE3rmYY) -Building +## Cloning + +Be sure to clone the repository properly:\ +`$ git clone --recursive https://github.com/hyle-team/zano.git` + +# Building -------- -### Cloning - -Be sure to properly clone the repository: - -`$ git clone --recursive https://github.com/hyle-team/zano.git` ### Dependencies | component / version | minimum
(not recommended but may work) | recommended | most recent of what we have ever tested | |--|--|--|--| -| gcc (Linux) | 5.4.0 | 7.2.0 | 8.3.0 | +| gcc (Linux) | 5.4.0 | 7.4.0 | 8.3.0 | | llvm/clang (Linux) | UNKNOWN | 7.0.1 | 8.0.0 | -| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2015 (14.0 update 1) | 2017 (15.5.7) | 2019 | -| [XCode](https://developer.apple.com/downloads/) (macOS) | 7.3.1 | 9.2 | 9.2 | -| [CMake](https://cmake.org/download/) | 2.8.6 | 3.15.5 | 3.15.5 | -| [Boost](https://www.boost.org/users/download/) | 1.56 | 1.68 | 1.68 | -| [Qt](https://download.qt.io/archive/qt/) (only for GUI) | 5.8.0 | 5.11.2 | 5.13.2 | +| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2015 (14.0 update 1) | 2017 (15.9.0) | 2019 | +| [XCode](https://developer.apple.com/downloads/) (macOS) | 9.2 | 12.3 | 12.3 | +| [CMake](https://cmake.org/download/) | 2.8.6 | 3.15.5 | 3.18.1 | +| [Boost](https://www.boost.org/users/download/) | 1.56 | 1.68 | 1.69 | +| [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.11.2 | 5.13.2 | ### Linux Recommended OS version: Ubuntu 18.04 LTS. 1. Prerequisites - 1. Prerequisites for server version: - - sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen - - 1. Prerequisites for GUI version: - sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen mesa-common-dev libglu1-mesa-dev` + [*server version*] + + sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen + + [*GUI version*] + + sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen mesa-common-dev libglu1-mesa-dev` 2. Download and build Boost - wget https://dl.bintray.com/boostorg/release/1.68.0/source/boost_1_68_0.tar.bz2 + wget https://boostorg.jfrog.io/artifactory/main/release/1.68.0/source/boost_1_68_0.tar.bz2 tar -xjf boost_1_68_0.tar.bz2 cd boost_1_68_0 ./bootstrap.sh --with-libraries=system,filesystem,thread,date_time,chrono,regex,serialization,atomic,program_options,locale,timer ./b2 -3. Install Qt +3. Install Qt\ +(*GUI version only, skip this step if you're building server version*) + + [*GUI version*] wget https://download.qt.io/new_archive/qt/5.11/5.11.2/qt-opensource-linux-x64-5.11.2.run chmod +x qt-opensource-linux-x64-5.11.2.run ./qt-opensource-linux-x64-5.11.2.run - Then follow the instructions in Wizard. Don't forget to tick WebEngine module! + Then follow the instructions in Wizard. Don't forget to tick the WebEngine module checkbox! + +4. Set environment variables properly\ +For instance, by adding the following lines to `~/.bashrc` + + [*server version*] + + export BOOST_ROOT=/home/user/boost_1_68_0 + + + [*GUI version*] -4. Set `BOOST_ROOT` and `QT_PREFIX_PATH` envinorment variables\ - For instance, by adding these lines to `~/.bashrc`: - export BOOST_ROOT=/home/user/boost_1_68_0 export QT_PREFIX_PATH=/home/user/Qt5.11.2/5.11.2/gcc_64 + 5. Building binaries 1. Building daemon and simplewallet: @@ -66,7 +78,7 @@ Recommended OS version: Ubuntu 18.04 LTS. cmake .. make -j1 daemon simplewallet - **NOTICE**: If you are building on machine with relatively high anount of RAM or with proper setting of virtual memory, then you can use `-j2` or `-j` option to speed up the building process. Use with caution. + **NOTICE**: If you are building on a machine with a relatively high amount of RAM or with the proper setting of virtual memory, then you can use `-j2` or `-j` option to speed up the building process. Use with caution. 1. Building GUI: @@ -75,6 +87,7 @@ Recommended OS version: Ubuntu 18.04 LTS. 7. Look for the binaries in `build` folder +
### Windows Recommended OS version: Windows 7 x64. 1. Install required prerequisites (Boost, Qt, CMake). @@ -83,13 +96,14 @@ Recommended OS version: Windows 7 x64. 4. Go to the build folder and open generated Zano.sln in MSVC. 5. Build. -In order to correctly deploy Qt GUI application you also need to do the following: +In order to correctly deploy Qt GUI application, you also need to do the following: 6. Copy Zano.exe to a folder (e.g. `depoy`). 7. Run `PATH_TO_QT\bin\windeployqt.exe deploy/Zano.exe`. 8. Copy folder `\src\gui\qt-daemon\html` to `deploy\html`. +
### macOS -Recommended OS version: macOS Sierra 10.12.6 x64. +Recommended OS version: macOS Sierra 10.15.4 x64. 1. Install required prerequisites. 2. Set environment variables as stated in `utils/macosx_build_config.command`. 3. `mkdir build`
`cd build`
`cmake ..`
`make` @@ -104,7 +118,7 @@ To build GUI application: e. Press “Create”, then “Done”.\ f. Make sure the certificate was added to keychain "System". If not—move it to "System".\ g. Double click the certificate you've just added, enter the trust section and under "When using this certificate" select "Always trust".\ - h. Unfold the certificate in Keychain Access window and double click underlying private key "Zano". Select "Access Control" tab, then select "Allow all applications to access this item". Click "Save Changes". + h. Unfold the certificate in Keychain Access window and double click the underlying private key "Zano". Select "Access Control" tab, then select "Allow all applications to access this item". Click "Save Changes". 2. Revise building script, comment out unwanted steps and run it: `utils/build_script_mac_osx.sh` 3. The application should be here: `/buid_mac_osx_64/release/src` From eda26e44d0663add591b200d40594a70c7d1e627 Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 3 Jun 2021 16:06:49 +0300 Subject: [PATCH 06/29] readme: more fixes --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 83722e9f..0ef375ea 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ For instance, by adding the following lines to `~/.bashrc` 7. Look for the binaries in `build` folder -
+ ### Windows Recommended OS version: Windows 7 x64. 1. Install required prerequisites (Boost, Qt, CMake). @@ -101,7 +101,7 @@ In order to correctly deploy Qt GUI application, you also need to do the followi 7. Run `PATH_TO_QT\bin\windeployqt.exe deploy/Zano.exe`. 8. Copy folder `\src\gui\qt-daemon\html` to `deploy\html`. -
+ ### macOS Recommended OS version: macOS Sierra 10.15.4 x64. 1. Install required prerequisites. From e0a6468241da93bae683cd8504513a3b8f06c41e Mon Sep 17 00:00:00 2001 From: "crypto.sowle" Date: Thu, 3 Jun 2021 16:21:00 +0300 Subject: [PATCH 07/29] readme: more fixes --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0ef375ea..be80f313 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,12 @@ Be sure to clone the repository properly:\ | [Boost](https://www.boost.org/users/download/) | 1.56 | 1.68 | 1.69 | | [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.11.2 | 5.13.2 | +Note:\ +[*server version*] denotes steps required for building command-line tools (daemon, simplewallet, etc.).\ +[*GUI version*] denotes steps required for building Zano executable with GUI. + +
+ ### Linux Recommended OS version: Ubuntu 18.04 LTS. @@ -87,6 +93,7 @@ For instance, by adding the following lines to `~/.bashrc` 7. Look for the binaries in `build` folder +
### Windows Recommended OS version: Windows 7 x64. @@ -97,10 +104,13 @@ Recommended OS version: Windows 7 x64. 5. Build. In order to correctly deploy Qt GUI application, you also need to do the following: -6. Copy Zano.exe to a folder (e.g. `depoy`). -7. Run `PATH_TO_QT\bin\windeployqt.exe deploy/Zano.exe`. -8. Copy folder `\src\gui\qt-daemon\html` to `deploy\html`. +6. Copy Zano.exe to a folder (e.g. `depoy`). +7. Run `PATH_TO_QT\bin\windeployqt.exe deploy\Zano.exe`. +8. Copy folder `\src\gui\qt-daemon\html` to `deploy\html`. +9. Now you can run `Zano.exe` + +
### macOS Recommended OS version: macOS Sierra 10.15.4 x64. From eaa3b92963c5cdeaf83794478268d1367b141147 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 4 Jun 2021 15:02:25 +0300 Subject: [PATCH 08/29] Dockerfile: fixed broken boost downloading link --- utils/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/docker/Dockerfile b/utils/docker/Dockerfile index 9176be64..08f2ffe1 100644 --- a/utils/docker/Dockerfile +++ b/utils/docker/Dockerfile @@ -46,7 +46,7 @@ RUN curl https://github.com/Kitware/CMake/releases/download/v3.15.5/cmake-3.15.5 # Boost 1.68 -RUN curl https://dl.bintray.com/boostorg/release/1.68.0/source/boost_1_68_0.tar.bz2 -OL &&\ +RUN curl https://boostorg.jfrog.io/artifactory/main/release/1.68.0/source/boost_1_68_0.tar.bz2 -OL &&\ echo '7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7 boost_1_68_0.tar.bz2' | sha256sum -c - &&\ tar -xjf boost_1_68_0.tar.bz2 &&\ rm boost_1_68_0.tar.bz2 &&\ From 5b1fa3d5e810c7d4bb02cdb811e8f9b3e194f46a Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 5 Jun 2021 02:18:45 +0300 Subject: [PATCH 09/29] crypto: scalar_t::assign_mul --- src/crypto/crypto-sugar.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index 43e69c42..30abccb9 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -315,6 +315,13 @@ namespace crypto return *this; } + // returns this = a * b + scalar_t& assign_mul(const scalar_t& a, const scalar_t& b) + { + sc_mul(m_s, a.m_s, b.m_s); + return *this; + } + /* I think it has bad symantic (operator-like), consider rename/reimplement -- sowle */ From 2fdeefb545f034b290b366b20c8335389d3b270b Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 5 Jun 2021 03:36:58 +0300 Subject: [PATCH 10/29] crypto: scalar_vec_t, scalar_mat_t --- src/crypto/crypto-sugar.h | 147 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index 30abccb9..1c1b1b9a 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -717,6 +717,146 @@ namespace crypto }; // struct point_g_t + // + // vector of scalars + // + struct scalar_vec_t : public std::vector + { + typedef std::vector super_t; + + scalar_vec_t() {} + scalar_vec_t(size_t n) : super_t(n) {} + scalar_vec_t(std::initializer_list init_list) : super_t(init_list) {} + + bool is_reduced() const + { + for (auto& el : *this) + if (!el.is_reduced()) + return false; + return true; + } + + // add a scalar rhs to each element + scalar_vec_t operator+(const scalar_t& rhs) const + { + scalar_vec_t result(size()); + for (size_t i = 0, n = size(); i < n; ++i) + result[i] = at(i) + rhs; + return result; + } + + // subtract a scalar rhs to each element + scalar_vec_t operator-(const scalar_t& rhs) const + { + scalar_vec_t result(size()); + for (size_t i = 0, n = size(); i < n; ++i) + result[i] = at(i) - rhs; + return result; + } + + // multiply each element of the vector by a scalar + scalar_vec_t operator*(const scalar_t& rhs) const + { + scalar_vec_t result(size()); + for (size_t i = 0, n = size(); i < n; ++i) + result[i] = at(i) * rhs; + return result; + } + + // component-wise multiplication (a.k.a the Hadamard product) (only if their sizes match) + scalar_vec_t operator*(const scalar_vec_t& rhs) const + { + scalar_vec_t result; + const size_t n = size(); + if (n != rhs.size()) + return result; + + result.resize(size()); + for (size_t i = 0; i < n; ++i) + result[i] = at(i) * rhs[i]; + return result; + } + + // add each element of two vectors, but only if their sizes match + scalar_vec_t operator+(const scalar_vec_t& rhs) const + { + scalar_vec_t result; + const size_t n = size(); + if (n != rhs.size()) + return result; + + result.resize(size()); + for (size_t i = 0; i < n; ++i) + result[i] = at(i) + rhs[i]; + return result; + } + + // zeroes all elements + void zero() + { + size_t size_bytes = sizeof(scalar_t) * size(); + memset(data(), 0, size_bytes); + } + + // invert all elements in-place efficiently: 4*N muptiplications + 1 inversion + void invert() + { + // muls muls_rev + // 0: 1 2 3 .. n-1 + // 1: 0 2 3 .. n-1 + // 2: 0 1 3 .. n-1 + // + // n-1: 0 1 2 3 .. n-2 + + const size_t size = this->size(); + + if (size < 2) + { + if (size == 1) + at(0) = at(0).reciprocal(); + return; + } + + scalar_vec_t muls(size), muls_rev(size); + muls[0] = 1; + for (size_t i = 0; i < size - 1; ++i) + muls[i + 1] = at(i) * muls[i]; + + muls_rev[size - 1] = 1; + for (size_t i = size - 1; i != 0; --i) + muls_rev[i - 1] = at(i) * muls_rev[i]; + + scalar_t inv = (muls[size - 1] * at(size - 1)).reciprocal(); + + for (size_t i = 0; i < size; ++i) + at(i) = muls[i] * inv * muls_rev[i]; + } + + scalar_t calc_hs() const; + + }; // scalar_vec_t + + + // treats vector of scalars as an M x N matrix just for convenience + template + struct scalar_mat_t : public scalar_vec_t + { + typedef scalar_vec_t super_t; + static_assert(N > 0, "invalid N value"); + + scalar_mat_t() {} + scalar_mat_t(size_t n) : super_t(n) {} + scalar_mat_t(std::initializer_list init_list) : super_t(init_list) {} + + // matrix accessor M rows x N cols + scalar_t& operator()(size_t row, size_t col) + { + return at(row * N + col); + } + }; // scalar_mat_t + + + // // Global constants // @@ -908,4 +1048,11 @@ namespace crypto }; // hash_helper_t struct + inline scalar_t scalar_vec_t::calc_hs() const + { + // hs won't touch memory if size is 0, so it's safe + return hash_helper_t::hs(data(), sizeof(scalar_t) * size()); + } + + } // namespace crypto From 57bc1278f46a5c48cc128cea9d6dad8e667e38f8 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 5 Jun 2021 03:42:09 +0300 Subject: [PATCH 11/29] Bulletproofs+: the first working version --- src/crypto/range_proofs.cpp | 12 + src/crypto/range_proofs.h | 822 ++++++++++++++++++++++++++++++++++++ 2 files changed, 834 insertions(+) create mode 100644 src/crypto/range_proofs.cpp create mode 100644 src/crypto/range_proofs.h diff --git a/src/crypto/range_proofs.cpp b/src/crypto/range_proofs.cpp new file mode 100644 index 00000000..b6750a09 --- /dev/null +++ b/src/crypto/range_proofs.cpp @@ -0,0 +1,12 @@ +// Copyright (c) 2021 Zano Project (https://zano.org/) +// Copyright (c) 2021 sowle (val@zano.org, crypto.sowle@gmail.com) +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "range_proofs.h" + +namespace crypto +{ + const point_t& bpp_crypto_trait_zano::bpp_H = c_point_H; + + +} diff --git a/src/crypto/range_proofs.h b/src/crypto/range_proofs.h new file mode 100644 index 00000000..7478e64b --- /dev/null +++ b/src/crypto/range_proofs.h @@ -0,0 +1,822 @@ +// Copyright (c) 2021 Zano Project (https://zano.org/) +// Copyright (c) 2021 sowle (val@zano.org, crypto.sowle@gmail.com) +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#pragma once + +// +// This file contains the implementation of range proof protocol. +// Namely, Bulletproofs+ https://eprint.iacr.org/2020/735.pdf +// + +#include "crypto-sugar.h" + +namespace crypto +{ + + // returns x + x^2 + x^3 + ... + x^(2^f) + // == x * (x + 1) * (x^2 + 1) * (x^4 + 1) * ...(x^(f+1) + 1) + inline scalar_t sum_of_powers(scalar_t x, size_t f) + { + scalar_t result = x; + for (size_t i = 0; i < f; ++i) + { + result.assign_muladd(result, x, result); + x *= x; + } + return result; + } + + constexpr size_t c_bpp_log2_n = 6; + constexpr size_t c_bpp_n = 64; // 2^64 is the upper bound for the witness's range + constexpr size_t c_bpp_values_max = 16; // maximum number of elements in BP+ proof, i.e. max allowed BP+ outputs + constexpr size_t c_bpp_mn_max = c_bpp_n * c_bpp_values_max; + + // returns smallest k, s.t. v <= 2**k + inline size_t calc_exp_power_of_2_upper_bound(size_t v) + { + constexpr size_t max_v = (SIZE_MAX >> 1) + 1; + //if (v > max_v) + // return 0; + + size_t pow = 1, result = 0; + while (v > pow) + { + pow <<= 1; + ++result; + } + return result; + } + + // returns least significant bit uing de Bruijn sequence + // http://graphics.stanford.edu/~seander/bithacks.html + inline uint8_t calc_lsb_32(uint32_t v) + { + static const uint8_t multiply_de_bruijn_bit_position[32] = + { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + return multiply_de_bruijn_bit_position[((uint32_t)((v & -(int32_t)v) * 0x077CB531U)) >> 27]; + } + + + //////////////////////////////////////// + // crypto trait for Zano + //////////////////////////////////////// + struct bpp_crypto_trait_zano + { + static void calc_pedersen_commitment(const scalar_t& value, const scalar_t& mask, point_t& commitment) + { + commitment = value * c_point_G + mask * c_point_H; + } + + static const scalar_t& get_initial_transcript() + { + static scalar_t value = hash_helper_t::hs("Zano BP+ initial transcript"); + return value; + } + + // assumes hsc is cleared + static void update_transcript(hash_helper_t::hs_t& hsc, scalar_t& e, const std::vector& points) + { + hsc.add_scalar(e); + hsc.add_points_array(points); + e = hsc.calc_hash(); + } + + static const point_t& get_generator(bool select_H, size_t index) + { + if (index >= c_bpp_mn_max) + return c_point_0; // out of bound + + static std::vector generators(2 * c_bpp_mn_max); + static bool calculated = false; + if (!calculated) + { + scalar_t hash_buf[2] = { hash_helper_t::hs("Zano BP+ generator"), 0 }; + for (size_t i = 0; i < 2 * c_bpp_mn_max; ++i) + { + hash_buf[1].m_u64[0] = i; + ge_bytes_hash_to_ec(&generators[i].m_p3, &hash_buf, sizeof hash_buf); + } + calculated = true; + } + + return generators[2 * index + (select_H ? 1 : 0)]; + } + + static const point_t& bpp_H; + }; + + + struct bpp_signature + { + std::vector L; // size = log_2(m * n) + std::vector R; + public_key A0; + public_key A; + public_key B; + scalar_t r; + scalar_t s; + scalar_t delta; + }; + +#define DBG_VAL_PRINT(x) std::cout << #x ": " << x << ENDL +#define DBG_PRINT(x) std::cout << x << ENDL + + template + bool bpp_gen(const std::vector& values, const scalar_vec_t& masks, bpp_signature& sig, std::vector& commitments, uint8_t* p_err = nullptr) + { +#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \ + if (!(cond)) { LOG_PRINT_RED("bpp_gen: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \ + if (p_err) { *p_err = err_code; } return false; } + + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(values.size() > 0 && values.size() <= c_bpp_values_max && values.size() == masks.size(), 1); + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(masks.is_reduced(), 3); + + const size_t c_bpp_log2_m = calc_exp_power_of_2_upper_bound(values.size()); + const size_t c_bpp_m = 1ull << c_bpp_log2_m; + const size_t c_bpp_mn = c_bpp_m * c_bpp_n; + const size_t c_bpp_log2_mn = c_bpp_log2_m + c_bpp_log2_n; + + // TODO: multiply values and masks by c_scalar_1div8 + // in order to enforce that points in verify() after mul by 8 will be in the prime-order subgroup + + // calc commitments vector as commitments[i] = 1/8 * values[i] * G + 1/8 * masks[i] * H + commitments.resize(values.size()); + for (size_t i = 0; i < values.size(); ++i) + CT::calc_pedersen_commitment(scalar_t(values[i]) * c_scalar_1div8, masks[i] * c_scalar_1div8, commitments[i]); + + + // s.a. BP+ paper, page 15, eq. 11 + // decompose v into aL and aR: + // v = aL o (1, 2, 2^2, ..., 2^n-1), o - component-wise product aka Hadamard product + // aR = aL - (1, 1, ... 1) + // aR o aL = 0 + + // aLs = (aL_0, aL_1, ..., aL_m-1) -- `bit` matrix of c_bpp_m x c_bpp_n, each element is a scalar + + scalar_mat_t aLs(c_bpp_mn), aRs(c_bpp_mn); + aLs.zero(); + aRs.zero(); + // m >= values.size, first set up [0..values.size-1], then -- [values.size..m-1] (padding area) + for (size_t i = 0; i < values.size(); ++i) + { + uint64_t v = values[i]; + for (size_t j = 0; j < c_bpp_n; ++j) + { + if (v & 1) + aLs(i, j) = c_scalar_1; // aL = 1, aR = 0 + else + aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1 + v >>= 1; + } + } + + for (size_t i = values.size(); i < c_bpp_m; ++i) + for (size_t j = 0; j < c_bpp_n; ++j) + aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1 + + + // using e as Fiat-Shamir transcript + scalar_t e = CT::get_initial_transcript(); + DBG_PRINT("initial transcript: " << e); + + hash_helper_t::hs_t hsc; + CT::update_transcript(hsc, e, commitments); + + // BP+ paper, page 15: The prover begins with sending A = g^aL h^aR h^alpha (group element) + // so we calculate A0 = alpha * H + SUM(aL_i * G_i) + SUM(aR_i * H_i) + + scalar_t alpha = scalar_t::random(); + point_t A0 = alpha * CT::bpp_H; + + for (size_t i = 0; i < c_bpp_mn; ++i) + A0 += aLs[i] * CT::get_generator(false, i) + aRs[i] * CT::get_generator(true, i); + + // part of 1/8 defense scheme + A0 *= c_scalar_1div8; + A0.to_public_key(sig.A0); + + DBG_VAL_PRINT(alpha); + DBG_VAL_PRINT(A0); + + // calculate scalar challenges y and z + hsc.add_scalar(e); + hsc.add_pub_key(sig.A0); + scalar_t y = hsc.calc_hash(); + scalar_t z = hash_helper_t::hs(y); + e = z; // transcript for further steps + DBG_VAL_PRINT(y); + DBG_VAL_PRINT(z); + + // Computing vector d for aggregated version of the protocol (BP+ paper, page 17) + // (note: elements is stored column-by-column in memory) + // d = | 1 * z^(2*1), 1 * z^(2*2), 1 * z^(2*3), ..., 1 * z^(2*m) | + // | 2 * z^(2*1), 2 * z^(2*2), 2 * z^(2*3), ..., 2 * z^(2*m) | + // | 4 * z^(2*1), 4 * z^(2*2), 4 * z^(2*3), ..., 4 * z^(2*m) | + // | ....................................................................................... | + // | 2^(n-1) * z^(2*1), 2^(n-1) * z^(2*2), 2^(n-1) * z^(2*3), ..., 2^(n-1) * z^(2*m)) | + // Note: sum(d_i) = (2^n - 1) * ((z^2)^1 + (z^2)^2 + ... (z^2)^m)) = (2^n-1) * sum_of_powers(x^2, log(m)) + + scalar_t z_sq = z * z; + scalar_mat_t d(c_bpp_mn); + d(0, 0) = z_sq; + // first row + for (size_t i = 1; i < c_bpp_m; ++i) + d(i, 0) = d(i - 1, 0) * z_sq; + // all rows + for (size_t j = 1; j < c_bpp_n; ++j) + for (size_t i = 0; i < c_bpp_m; ++i) + d(i, j) = d(i, j - 1) + d(i, j - 1); + + DBG_PRINT("Hs(d): " << d.calc_hs()); + + // calculate extended Vandermonde vector y = (1, y, y^2, ..., y^(mn+1)) (BP+ paper, page 18, Fig. 3) + // (calculate two more elements (1 and y^(mn+1)) for convenience) + scalar_vec_t y_powers(c_bpp_mn + 2); + y_powers[0] = 1; + for (size_t i = 1; i <= c_bpp_mn + 1; ++i) + y_powers[i] = y_powers[i - 1] * y; + + const scalar_t& y_mn_p1 = y_powers[c_bpp_mn + 1]; + + DBG_PRINT("Hs(y_powers): " << y_powers.calc_hs()); + + // aL_hat = aL - 1*z + scalar_vec_t aLs_hat = aLs - z; + // aL_hat = aR + d o y^leftarr + 1*z where y^leftarr = (y^n, y^(n-1), ..., y) (BP+ paper, page 18, Fig. 3) + scalar_vec_t aRs_hat = aRs + z; + for (size_t i = 0; i < c_bpp_mn; ++i) + aRs_hat[i] += d[i] * y_powers[c_bpp_mn - i]; + + DBG_PRINT("Hs(aLs_hat): " << aLs_hat.calc_hs()); + DBG_PRINT("Hs(aRs_hat): " << aRs_hat.calc_hs()); + + // calculate alpha_hat + // alpha_hat = alpha + SUM(z^(2j) * gamma_j * y^(mn+1)) for j = 1..m + // i.e. \hat{\alpha} = \alpha + y^{m n+1} \sum_{j = 1}^{m} z^{2j} \gamma_j + scalar_t alpha_hat = 0; + for (size_t i = 0; i < masks.size(); ++i) + alpha_hat += d(i, 0) * masks[i]; + alpha_hat = alpha + y_mn_p1 * alpha_hat; + + DBG_VAL_PRINT(alpha_hat); + + // calculate y^-1, y^-2, ... + const scalar_t y_inverse = y.reciprocal(); + scalar_vec_t y_inverse_powers(c_bpp_mn / 2 + 1); // the greatest power we need is c_bpp_mn/2 (at the first reduction round) + y_inverse_powers[0] = 1; + for (size_t i = 1, size = y_inverse_powers.size(); i < size; ++i) + y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inverse; + + // prepare generator's vector + std::vector g(c_bpp_mn), h(c_bpp_mn); + for (size_t i = 0; i < c_bpp_mn; ++i) + { + g[i] = CT::get_generator(false, i); + h[i] = CT::get_generator(true, i); + } + + // WIP zk-argument called with zk-WIP(g, h, G, H, A_hat, aL_hat, aR_hat, alpha_hat) + + scalar_vec_t& a = aLs_hat; + scalar_vec_t& b = aRs_hat; + + sig.L.resize(c_bpp_log2_mn); + sig.R.resize(c_bpp_log2_mn); + + // zk-WIP reduction rounds (s.a. the preprint page 13 Fig. 1) + for (size_t n = c_bpp_mn / 2, ni = 0; n >= 1; n /= 2, ++ni) + { + DBG_PRINT(ENDL << "#" << ni); + + // zk-WIP(g, h, G, H, P, a, b, alpha) + + scalar_t dL = scalar_t::random(); + DBG_VAL_PRINT(dL); + scalar_t dR = scalar_t::random(); + DBG_VAL_PRINT(dR); + + // a = (a1, a2), b = (b1, b2) -- vectors of scalars + // cL = -- scalar + scalar_t cL = 0; + for (size_t i = 0; i < n; ++i) + cL += a[i] * y_powers[i + 1] * b[n + i]; + + DBG_VAL_PRINT(cL); + + // cR = * y^n -- scalar + scalar_t cR = 0; + for (size_t i = 0; i < n; ++i) + cR += a[n + i] * y_powers[i + 1] * b[i]; + cR *= y_powers[n]; + + DBG_VAL_PRINT(cR); + + // L = y^-n * a1 * g2 + b2 * h1 + cL * G + dL * H -- point + point_t sum = c_point_0; + for (size_t i = 0; i < n; ++i) + sum += a[i] * g[n + i]; + point_t L; + CT::calc_pedersen_commitment(cL, dL, L); + for (size_t i = 0; i < n; ++i) + L += b[n + i] * h[i]; + L += y_inverse_powers[n] * sum; + L *= c_scalar_1div8; + DBG_VAL_PRINT(L); + + // R = y^n * a2 * g1 + b1 * h2 + cR * G + dR * H -- point + sum.zero(); + for (size_t i = 0; i < n; ++i) + sum += a[n + i] * g[i]; + point_t R; + CT::calc_pedersen_commitment(cR, dR, R); + for (size_t i = 0; i < n; ++i) + R += b[i] * h[n + i]; + R += y_powers[n] * sum; + R *= c_scalar_1div8; + DBG_VAL_PRINT(R); + + // put L, R to the sig + L.to_public_key(sig.L[ni]); + R.to_public_key(sig.R[ni]); + + // update the transcript + hsc.add_scalar(e); + hsc.add_pub_key(sig.L[ni]); + hsc.add_pub_key(sig.R[ni]); + e = hsc.calc_hash(); + DBG_VAL_PRINT(e); + + // recalculate arguments for the next round + scalar_t e_squared = e * e; + scalar_t e_inverse = e.reciprocal(); + scalar_t e_inverse_squared = e_inverse * e_inverse; + scalar_t e_y_inv_n = e * y_inverse_powers[n]; + scalar_t e_inv_y_n = e_inverse * y_powers[n]; + + // g_hat = e^-1 * g1 + (e * y^-n) * g2 -- vector of points + for (size_t i = 0; i < n; ++i) + g[i] = e_inverse * g[i] + e_y_inv_n * g[n + i]; + + // h_hat = e * h1 + e^-1 * h2 -- vector of points + for (size_t i = 0; i < n; ++i) + h[i] = e * h[i] + e_inverse * h[n + i]; + + // P_hat = e^2 * L + P + e^-2 * R -- point + + // a_hat = e * a1 + e^-1 * y^n * a2 -- vector of scalars + for (size_t i = 0; i < n; ++i) + a[i] = e * a[i] + e_inv_y_n * a[n + i]; + + // b_hat = e^-1 * b1 + e * b2 -- vector of scalars + for (size_t i = 0; i < n; ++i) + b[i] = e_inverse * b[i] + e * b[n + i]; + + // alpha_hat = e^2 * dL + alpha + e^-2 * dR -- scalar + alpha_hat += e_squared * dL + e_inverse_squared * dR; + + // run next iteraton zk-WIP(g_hat, h_hat, G, H, P_hat, a_hat, b_hat, alpha_hat) + } + DBG_PRINT(""); + + // zk-WIP last round + scalar_t r = scalar_t::random(); + scalar_t s = scalar_t::random(); + scalar_t delta = scalar_t::random(); + scalar_t eta = scalar_t::random(); + DBG_VAL_PRINT(r); + DBG_VAL_PRINT(s); + DBG_VAL_PRINT(delta); + DBG_VAL_PRINT(eta); + + // A = r * g + s * h + (r y b + s y a) * G + delta * H -- point + point_t A = c_point_0; + CT::calc_pedersen_commitment(y * (r * b[0] + s * a[0]), delta, A); + A += r * g[0] + s * h[0]; + A *= c_scalar_1div8; + A.to_public_key(sig.A); + DBG_VAL_PRINT(A); + + // B = (r * y * s) * G + eta * H + point_t B = c_point_0; + CT::calc_pedersen_commitment(r * y * s, eta, B); + B *= c_scalar_1div8; + B.to_public_key(sig.B); + DBG_VAL_PRINT(B); + + // update the transcript + hsc.add_scalar(e); + hsc.add_pub_key(sig.A); + hsc.add_pub_key(sig.B); + e = hsc.calc_hash(); + DBG_VAL_PRINT(e); + + // finalize the signature + sig.r = r + e * a[0]; + sig.s = s + e * b[0]; + sig.delta = eta + e * delta + e * e * alpha_hat; + DBG_VAL_PRINT(sig.r); + DBG_VAL_PRINT(sig.s); + DBG_VAL_PRINT(sig.delta); + + return true; +#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE + } // bpp_gen() + + + // efficient multiexponentiation (naive stub implementation atm, TODO) + template + bool multiexp_and_check_being_zero(const scalar_vec_t& g_scalars, const scalar_vec_t& h_scalars, const point_t& summand) + { + CHECK_AND_ASSERT_MES(g_scalars.size() < c_bpp_mn_max, false, "g_scalars oversized"); + CHECK_AND_ASSERT_MES(h_scalars.size() < c_bpp_mn_max, false, "h_scalars oversized"); + + point_t result = summand; + + for (size_t i = 0; i < g_scalars.size(); ++i) + result += g_scalars[i] * CT::get_generator(false, i); + + for (size_t i = 0; i < h_scalars.size(); ++i) + result += h_scalars[i] * CT::get_generator(true, i); + + if (!result.is_zero()) + { + LOG_PRINT_L0("multiexp result is non zero: " << result); + return false; + } + return true; + } + + + struct bpp_sig_commit_ref_t + { + bpp_sig_commit_ref_t(const bpp_signature& sig, const std::vector& commitments) + : sig(sig) + , commitments(commitments) + {} + const bpp_signature& sig; + const std::vector& commitments; + }; + + + template + bool bpp_verify(const std::vector& sigs, uint8_t* p_err = nullptr) + { +#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \ + if (!(cond)) { LOG_PRINT_RED("bpp_verify: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \ + if (p_err) { *p_err = err_code; } return false; } + + DBG_PRINT(ENDL << " . . . . bpp_verify() . . . . "); + + const size_t kn = sigs.size(); + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(kn > 0, 1); + + struct intermediate_element_t + { + scalar_t y; + scalar_t z; + scalar_t z_sq; + scalar_vec_t e; + scalar_vec_t e_sq; + scalar_t e_final; + scalar_t e_final_sq; + size_t inv_e_offset; // offset in batch_for_inverse + size_t inv_y_offset; // offset in batch_for_inverse + size_t c_bpp_log2_m; + size_t c_bpp_m; + size_t c_bpp_mn; + point_t A; + point_t A0; + point_t B; + std::vector L; + std::vector R; + }; + std::vector interms(kn); + + size_t c_bpp_log2_m_max = 0; + for (size_t k = 0; k < kn; ++k) + { + const bpp_sig_commit_ref_t& bsc = sigs[k]; + const bpp_signature& sig = bsc.sig; + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(bsc.commitments.size() > 0, 2); + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() > 0 && sig.L.size() == sig.R.size(), 3); + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.r.is_reduced() && sig.s.is_reduced() && sig.delta.is_reduced(), 4); + + intermediate_element_t& interm = interms[k]; + interm.c_bpp_log2_m = calc_exp_power_of_2_upper_bound(bsc.commitments.size()); + if (c_bpp_log2_m_max < interm.c_bpp_log2_m) + c_bpp_log2_m_max = interm.c_bpp_log2_m; + + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() == interm.c_bpp_log2_m + c_bpp_log2_n, 5); + + interm.c_bpp_m = 1ull << interm.c_bpp_log2_m; + interm.c_bpp_mn = interm.c_bpp_m * c_bpp_n; + + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A0.from_public_key(sig.A0), 6); + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A.from_public_key(sig.A), 7); + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.B.from_public_key(sig.B), 8); + interm.L.resize(sig.L.size()); + interm.R.resize(sig.R.size()); + for (size_t i = 0; i < interm.L.size(); ++i) + { + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.L[i].from_public_key(sig.L[i]), 9); + CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.R[i].from_public_key(sig.R[i]), 10); + } + } + const size_t c_bpp_m_max = 1ull << c_bpp_log2_m_max; + const size_t c_bpp_mn_max = c_bpp_m_max * c_bpp_n; + const size_t c_bpp_LR_size_max = c_bpp_log2_m_max + c_bpp_log2_n; + + + // + // prepare stuff + // + /* + std::vector g(c_bpp_mn_max), h(c_bpp_mn_max); + for (size_t i = 0; i < c_bpp_mn_max; ++i) + { + g[i] = CT::get_generator(false, i); + h[i] = CT::get_generator(true, i); + } + */ + + scalar_vec_t batch_for_inverse; + batch_for_inverse.reserve(kn + kn * c_bpp_LR_size_max); + + + for (size_t k = 0; k < kn; ++k) + { + DBG_PRINT(ENDL << "SIG #" << k); + const bpp_sig_commit_ref_t& bsc = sigs[k]; + const bpp_signature& sig = bsc.sig; + intermediate_element_t& interm = interms[k]; + + // restore y and z + // using e as Fiat-Shamir transcript + scalar_t e = CT::get_initial_transcript(); + DBG_PRINT("initial transcript: " << e); + hash_helper_t::hs_t hsc; + CT::update_transcript(hsc, e, bsc.commitments); + // calculate scalar challenges y and z + hsc.add_scalar(e); + hsc.add_pub_key(sig.A0); + hsc.assign_calc_hash(interm.y); + interm.z = hash_helper_t::hs(interm.y); + interm.z_sq = interm.z * interm.z; + DBG_VAL_PRINT(interm.y); + DBG_VAL_PRINT(interm.z); + e = interm.z; // transcript for further steps + + interm.inv_y_offset = batch_for_inverse.size(); + batch_for_inverse.push_back(interm.y); + interm.inv_e_offset = batch_for_inverse.size(); + + interm.e.resize(sig.L.size()); + interm.e_sq.resize(sig.L.size()); + + for (size_t i = 0; i < sig.L.size(); ++i) + { + hsc.add_scalar(e); + hsc.add_pub_key(sig.L[i]); + hsc.add_pub_key(sig.R[i]); + hsc.assign_calc_hash(e); + interm.e[i] = e; + interm.e_sq[i] = e * e; + DBG_PRINT("e[" << i << "]: " << e); + batch_for_inverse.push_back(e); + } + + hsc.add_scalar(e); + hsc.add_pub_key(sig.A); + hsc.add_pub_key(sig.B); + hsc.assign_calc_hash(interm.e_final); + interm.e_final_sq = interm.e_final * interm.e_final; + DBG_VAL_PRINT(interm.e_final); + } + + batch_for_inverse.invert(); + + // Notation: + // 1_vec ^ n = (1, 1, 1, ..., 1) + // 2_vec ^ n = (2^0, 2^1, 2^2, ..., 2^(n-1)) + // -1_vec ^ n = ((-1)^0, (-1)^1, (-1)^2, ... (-1)^(n-1)) = (1, -1, 1, -1, ...) + // y<^n = (y^n, y^(n-1), ..., y^1) + // y>^n = (y^1, y^2, ..., y^n) + + // from page 13, Fig 1: + // Verifier outputs Accept IFF the following equality holds (single proof): + // P^e^2 * A^e * B == g ^ (r' e) * h ^ (s' e) * G ^ (r' y s') * H ^ delta' + // (where g and h are calculated in each round) + // The same equation in additive notation: + // e^2 * P + e * A + B == (r' * e) * g + (s' * e) * h + (r' y s') * G + delta' * H + // <=> + // (r' * e) * g + (s' * e) * h + (r' y s') * G + delta' * H - e^2 * P - e * A - B == 0 (*) + // where A, B, r', s', delta' is taken from the signature + // and P_{k+1} = e^2 * L_k + P_k + e^-2 * R_k for all rounds + // + // from page 18, Fig 3: + // P and V computes: + // A_hat = A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h + + // + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) + + // + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G + // (calculated once) + // + // As suggested in Section 6.1 "Practical Optimizations": + // 1) g and h exponentianions can be optimized in order not to be calculated at each round as the following (page 20): + // + // (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta' * H - + // - e^2 * A_hat + // - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j) + // - e * A - B = 0 (**) + // + // where: + // g, h - vector of fixed generators + // s_vec_i = y^(1-i) * PROD{j=1..log(n)}(e_j ^ b(i,j)) + // s'_vec_i = PROD{j=1..log(n)}(e_j ^ -b(i,j)) + // b(i, j) = { 2 * ((1<<(j-1)) & (i-1)) - 1) (counting both from 1) (page 20) + // b(i, j) = { 2 * ((1< + + // (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta' * H - + // - e^2 * (A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h + + // + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) + + // + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G + // ) + // - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j) + // - e * A - B = 0 + + // => + + // (for single signature) + // + // (r' * e * s_vec - e^2 * (- 1_vec^(mn) * z)) * g | these are + // + (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z)) * h | fixed generators + // + (r' y s' - e^2 * ((z - z^2)*SUM(y^>mn) - z*y^(mn+1)*SUM(d)) * G | across all + // + delta' * H | the signatures + // + // - e^2 * A0 + // - e^2 * y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j)) + // - e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j) + // - e * A - B = 0 (***) + // + // All (***) will be muptiplied by random weightning factor and then summed up. + + // Calculate cummulative sclalar multiplicand for fixed generators across all the sigs. + scalar_vec_t g_scalars; + g_scalars.resize(c_bpp_mn_max, 0); + scalar_vec_t h_scalars; + h_scalars.resize(c_bpp_mn_max, 0); + scalar_t G_scalar = 0; + scalar_t H_scalar = 0; + point_t summand = c_point_0; + + for (size_t k = 0; k < kn; ++k) + { + DBG_PRINT(ENDL << "SIG #" << k); + const bpp_sig_commit_ref_t& bsc = sigs[k]; + const bpp_signature& sig = bsc.sig; + intermediate_element_t& interm = interms[k]; + + // random weightning factor for speed-optimized batch verification (preprint page 20) + const scalar_t rwf = scalar_t::random(); + DBG_PRINT("rwf: " << rwf); + + // prepare d vector (see also d structure description in proof function) + scalar_mat_t d(interm.c_bpp_mn); + d(0, 0) = interm.z_sq; + // first row + for (size_t i = 1; i < interm.c_bpp_m; ++i) + d(i, 0) = d(i - 1, 0) * interm.z_sq; + // all rows + for (size_t j = 1; j < c_bpp_n; ++j) + for (size_t i = 0; i < interm.c_bpp_m; ++i) + d(i, j) = d(i, j - 1) + d(i, j - 1); + // sum(d) (see also note in proof function for this) + static const scalar_t c_scalar_2_power_n_minus_1 = { 0xffffffffffffffff, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }; + const scalar_t sum_d = c_scalar_2_power_n_minus_1 * sum_of_powers(interm.z_sq, interm.c_bpp_log2_m); + + DBG_PRINT("Hs(d): " << d.calc_hs()); + DBG_PRINT("sum(d): " << sum_d); + + const scalar_t& y_inv = batch_for_inverse[interm.inv_y_offset]; + auto get_e_inv = [&](size_t i) { return batch_for_inverse[interm.inv_e_offset + i]; }; // i belongs to [0; L.size()-1] + + // prepare s_vec (unlike the paper here we moved y-component out of s_vec for convenience, so s_vec'[x] = s_vec[~x & (MN-1)]) + // complexity (sc_mul's): MN+2*log2(MN)-2 + // the idea is the following: + // s_vec[00000b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^-1 * (e_1)^-1 * (e_0)^-1 + // s_vec[00101b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^+1 * (e_1)^-1 * (e_0)^+1 + const size_t log2_mn = sig.L.size(); // at the beginning we made sure that sig.L.size() == c_bpp_log2_m + c_bpp_log2_n + scalar_vec_t s_vec(interm.c_bpp_mn); + s_vec[0] = get_e_inv(0); + for (size_t i = 1; i < log2_mn; ++i) + s_vec[0] *= get_e_inv(i); // s_vec[0] = (e_0)^-1 * (e_1)^-1 * .. (e_{log2_mn-1})^-1 + DBG_PRINT("[0] " << s_vec[0]); + for (size_t i = 1; i < interm.c_bpp_mn; ++i) + { + size_t base_el_index = i & (i - 1); // base element index: 0, 0, 2, 0, 4, 4, 6, 0, 8, 8, 10... base element differs in one bit (0) from the current one (1) + size_t bit_index = log2_mn - calc_lsb_32((uint32_t)i) - 1; // the bit index where current element has the difference with the base + s_vec[i] = s_vec[base_el_index] * interm.e_sq[bit_index]; // (e_j)^-1 * (e_j)^2 = (e_j)^+1 + DBG_PRINT("[" << i << "] " << " " << base_el_index << ", " << bit_index << " : " << s_vec[i]); + } + + // prepare y_inv vector + scalar_vec_t y_inverse_powers(interm.c_bpp_mn); + y_inverse_powers[0] = 1; + for (size_t i = 1; i < interm.c_bpp_mn; ++i) + y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inv; + + // y^(mn+1) + scalar_t y_power_mnp1 = interm.y; + for (size_t i = 0; i < log2_mn; ++i) + y_power_mnp1 *= y_power_mnp1; + y_power_mnp1 *= interm.y; + DBG_VAL_PRINT(y_power_mnp1); + + // now calculate all multiplicands for common generators + + // g vector multiplicands: + // rwf * (r' * e * (1, y^-1, y^-2, ...) o s_vec + e^2 * z) = + // rwf * r' * e * ((1, y^-1, ...) o s_vec) + rwf * e^2 * z * (1, 1, ...) + scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z; + scalar_t rwf_r_e = rwf * interm.e_final * sig.r; + for (size_t i = 0; i < interm.c_bpp_mn; ++i) + g_scalars[i] += rwf_r_e * y_inverse_powers[i] * s_vec[i] + rwf_e_sq_z; + + DBG_PRINT("Hs(g_scalars): " << g_scalars.calc_hs()); + + // h vector multiplicands: + // rwf * (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z)) + // rwf * s' * e * s'_vec - rwf * e^2 * z * (1, 1...) - rwf * e^2 * (d o y<^(mn)) + //scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z; + scalar_t rwf_s_e = rwf * sig.s * interm.e_final; + scalar_t rwf_e_sq_y = rwf * interm.e_final_sq * interm.y; + for (size_t i = interm.c_bpp_mn - 1; i != SIZE_MAX; --i) + { + h_scalars[i] += rwf_s_e * s_vec[interm.c_bpp_mn - 1 - i] - rwf_e_sq_z - rwf_e_sq_y * d[i]; + rwf_e_sq_y *= interm.y; + } + + DBG_PRINT("Hs(h_scalars): " << h_scalars.calc_hs()); + + // G point multiplicands: + // rwf * (r' y s' - e ^ 2 * ((z - z ^ 2)*SUM(y^>mn) - z * y^(mn+1) * SUM(d)) = + // = rwf * r' y s' - rwf * e^2 * (z - z ^ 2)*SUM(y^>mn) + rwf * e^2 * z * y^(mn+1) * SUM(d) + G_scalar += rwf * sig.r * interm.y * sig.s + rwf_e_sq_y * sum_d * interm.z; + G_scalar -= rwf * interm.e_final_sq * (interm.z - interm.z_sq) * sum_of_powers(interm.y, log2_mn); + DBG_PRINT("sum_y: " << sum_of_powers(interm.y, log2_mn)); + DBG_PRINT("G_scalar: " << G_scalar); + + // H point multiplicands: + // rwf * delta + H_scalar += rwf * sig.delta; + DBG_PRINT("H_scalar: " << H_scalar); + + // uncommon generators' multiplicands + point_t summand_8 = c_point_0; // this summand to be multiplied by 8 and rwf before adding to the main summand + // - rwf * e^2 * A0 + summand_8 -= rwf * interm.e_final_sq * interm.A0; + DBG_PRINT("A0_scalar: " << c_scalar_Lm1 * interm.e_final_sq * rwf); + + // - rwf * e^2 * y^(mn+1) * (SUM{j=1..m} (z^2)^j * V_j)) + scalar_t e_sq_y_mn1_z_sq_power = rwf * interm.e_final_sq * y_power_mnp1; + for (size_t j = 0; j < bsc.commitments.size(); ++j) + { + e_sq_y_mn1_z_sq_power *= interm.z_sq; + summand_8 -= e_sq_y_mn1_z_sq_power * bsc.commitments[j]; + DBG_PRINT("V_scalar[" << j << "]: " << c_scalar_Lm1 * e_sq_y_mn1_z_sq_power); + } + + // - rwf * e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j) + scalar_t rwf_e_sq = rwf * interm.e_final_sq; + for (size_t j = 0; j < log2_mn; ++j) + { + summand_8 -= rwf_e_sq * (interm.e_sq[j] * interm.L[j] + get_e_inv(j) * get_e_inv(j) * interm.R[j]); + DBG_PRINT("L_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * interm.e_sq[j]); + DBG_PRINT("R_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * get_e_inv(j) * get_e_inv(j)); + } + + // - rwf * e * A - rwf * B = 0 + summand_8 -= rwf * interm.e_final * interm.A + rwf * interm.B; + DBG_PRINT("A_scalar: " << c_scalar_Lm1 * rwf * interm.e_final); + DBG_PRINT("B_scalar: " << c_scalar_Lm1 * rwf); + + summand_8.modify_mul8(); + summand += summand_8; + } + + point_t GH_exponents = c_point_0; + CT::calc_pedersen_commitment(G_scalar, H_scalar, GH_exponents); + bool result = multiexp_and_check_being_zero(g_scalars, h_scalars, summand + GH_exponents); + if (result) + DBG_PRINT(ENDL << " . . . . bpp_verify() -- SUCCEEDED!!!" << ENDL); + return result; +#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE + } + +} // namespace crypto From 5fa0e1584380a414e435dda05fcb31d3c2be64be Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 7 Jun 2021 14:43:19 +0300 Subject: [PATCH 12/29] crypto tests: crypto_calc_lsb_32 --- tests/functional_tests/crypto_tests.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/functional_tests/crypto_tests.cpp b/tests/functional_tests/crypto_tests.cpp index ba4313fd..eaf5a5f3 100644 --- a/tests/functional_tests/crypto_tests.cpp +++ b/tests/functional_tests/crypto_tests.cpp @@ -1551,6 +1551,30 @@ TEST(crypto, hex_tools) return true; } + +TEST(crypto, calc_lsb_32) +{ + auto& local_calc_lsb = [](uint32_t v) { + uint8_t r = 0; + while (v != 0 && (v & 1) == 0) + { + v >>= 1; + ++r; + } + return r; + }; + + for (uint32_t x = 0; x < UINT32_MAX; ++x) + { + if (x % 10000000 == 0) + std::cout << x << ENDL; + ASSERT_EQ((int)local_calc_lsb(x), (int)calc_lsb_32(x)); + } + ASSERT_EQ((int)local_calc_lsb(UINT32_MAX), (int)calc_lsb_32(UINT32_MAX)); + + return true; +} + // // test's runner // From bb6dea509e97700689ff50e99545f1174ed5cdf9 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 7 Jun 2021 15:00:58 +0300 Subject: [PATCH 13/29] wallet resync-on-load issue fixed (the bug was in data storing on Boost > 69), also Zano made compatible with Boost 1.72 --- contrib/eos_portable_archive/eos/portable_oarchive.hpp | 2 +- src/pch/stdafx.h | 1 - src/wallet/wallet2.cpp | 5 +---- src/wallet/wallet2.h | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/contrib/eos_portable_archive/eos/portable_oarchive.hpp b/contrib/eos_portable_archive/eos/portable_oarchive.hpp index fce2bd26..5f390194 100644 --- a/contrib/eos_portable_archive/eos/portable_oarchive.hpp +++ b/contrib/eos_portable_archive/eos/portable_oarchive.hpp @@ -340,7 +340,7 @@ namespace eos { // we choose to use little endian because this way we just // save the first size bytes to the stream and skip the rest #if BOOST_VERSION >= 106900 - temp = endian::native_to_little(temp); + temp = endian::native_to_little(t); #else endian::store_little_endian(&temp, t); #endif diff --git a/src/pch/stdafx.h b/src/pch/stdafx.h index 7aec3431..a1aa51ed 100644 --- a/src/pch/stdafx.h +++ b/src/pch/stdafx.h @@ -67,7 +67,6 @@ POP_VS_WARNINGS #include #include #include -#include #include #include #include diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9c8c9c33..d0456a00 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2389,10 +2389,6 @@ bool wallet2::deinit() bool wallet2::clear() { reset_all(); - //currency::block b; - //currency::generate_genesis_block(b); - m_chain.clear(); - //m_blockchain.push_back(get_block_hash(b)); return true; } //---------------------------------------------------------------------------------------------------- @@ -2666,6 +2662,7 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password) bool need_to_resync = false; if (wbh.m_ver == 1000) { + // old WALLET_FILE_BINARY_HEADER_VERSION version means no encryption need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, data_file); } else diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index f1ab885e..6723795c 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -707,7 +707,7 @@ namespace tools if (ver < 149) { - WLT_LOG_MAGENTA("Wallet file truncated due to old version", LOG_LEVEL_0); + WLT_LOG_MAGENTA("Wallet file truncated due to old version: " << ver, LOG_LEVEL_0); return; } From d38c852ead86985646e639b1a3207d1dad4e31b4 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 8 Jun 2021 17:56:25 +0300 Subject: [PATCH 14/29] crypto_tests: minor fix --- tests/functional_tests/crypto_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/functional_tests/crypto_tests.cpp b/tests/functional_tests/crypto_tests.cpp index eaf5a5f3..b70c5390 100644 --- a/tests/functional_tests/crypto_tests.cpp +++ b/tests/functional_tests/crypto_tests.cpp @@ -14,6 +14,7 @@ #include "currency_core/difficulty.h" #include "crypto/crypto-sugar.h" +#include "crypto/range_proofs.h" using namespace crypto; From ca10d2de17037f710f921eae102bda8f0b147b6c Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 8 Jun 2021 18:07:53 +0300 Subject: [PATCH 15/29] Bulletproofs+: gcc compilation fix + minor improvements --- src/crypto/range_proofs.h | 7 ++++--- tests/functional_tests/crypto_tests.cpp | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/crypto/range_proofs.h b/src/crypto/range_proofs.h index 7478e64b..b3d04d68 100644 --- a/src/crypto/range_proofs.h +++ b/src/crypto/range_proofs.h @@ -9,6 +9,7 @@ // Namely, Bulletproofs+ https://eprint.iacr.org/2020/735.pdf // +#include "epee/include/misc_log_ex.h" #include "crypto-sugar.h" namespace crypto @@ -140,8 +141,8 @@ namespace crypto const size_t c_bpp_mn = c_bpp_m * c_bpp_n; const size_t c_bpp_log2_mn = c_bpp_log2_m + c_bpp_log2_n; - // TODO: multiply values and masks by c_scalar_1div8 - // in order to enforce that points in verify() after mul by 8 will be in the prime-order subgroup + // pre-multiply all output points by c_scalar_1div8 + // in order to enforce these points to be in the prime-order subgroup (after mul by 8 in bpp_verify()) // calc commitments vector as commitments[i] = 1/8 * values[i] * G + 1/8 * masks[i] * H commitments.resize(values.size()); @@ -778,7 +779,7 @@ namespace crypto DBG_PRINT("H_scalar: " << H_scalar); // uncommon generators' multiplicands - point_t summand_8 = c_point_0; // this summand to be multiplied by 8 and rwf before adding to the main summand + point_t summand_8 = c_point_0; // this summand to be multiplied by 8 before adding to the main summand // - rwf * e^2 * A0 summand_8 -= rwf * interm.e_final_sq * interm.A0; DBG_PRINT("A0_scalar: " << c_scalar_Lm1 * interm.e_final_sq * rwf); diff --git a/tests/functional_tests/crypto_tests.cpp b/tests/functional_tests/crypto_tests.cpp index b70c5390..f5ea3a8e 100644 --- a/tests/functional_tests/crypto_tests.cpp +++ b/tests/functional_tests/crypto_tests.cpp @@ -1555,7 +1555,7 @@ TEST(crypto, hex_tools) TEST(crypto, calc_lsb_32) { - auto& local_calc_lsb = [](uint32_t v) { + auto local_calc_lsb = [](uint32_t v) { uint8_t r = 0; while (v != 0 && (v & 1) == 0) { From 9a0382f1a77b1d3cf70e838b589b290b1a722f59 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 15 Jun 2021 14:21:10 +0300 Subject: [PATCH 16/29] MSVC 2019 configuration + Boost 1.76 support --- .../serialization/keyvalue_serialization_overloads.h | 1 + contrib/epee/include/storages/portable_storage.h | 1 + src/pch/stdafx.h | 1 - utils/configure_local_paths_msvs2019.cmd | 8 ++++++++ utils/configure_win64_msvs2019_gui_testnet.cmd | 7 +++++++ 5 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 utils/configure_local_paths_msvs2019.cmd create mode 100644 utils/configure_win64_msvs2019_gui_testnet.cmd diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index 05c235d8..01f9e257 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -26,6 +26,7 @@ #pragma once +#include #include namespace epee diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h index 92fbeece..4d36cc03 100644 --- a/contrib/epee/include/storages/portable_storage.h +++ b/contrib/epee/include/storages/portable_storage.h @@ -28,6 +28,7 @@ #pragma once +#include #include "misc_language.h" #include "portable_storage_base.h" #include "portable_storage_to_bin.h" diff --git a/src/pch/stdafx.h b/src/pch/stdafx.h index a1aa51ed..76afcc62 100644 --- a/src/pch/stdafx.h +++ b/src/pch/stdafx.h @@ -66,7 +66,6 @@ POP_VS_WARNINGS #include #include #include -#include #include #include #include diff --git a/utils/configure_local_paths_msvs2019.cmd b/utils/configure_local_paths_msvs2019.cmd new file mode 100644 index 00000000..742774bf --- /dev/null +++ b/utils/configure_local_paths_msvs2019.cmd @@ -0,0 +1,8 @@ +@echo off +rem +rem This file contains local path settings for your own personal dev environment. +rem Rename to configure_local_paths.cmd and do not commit. +rem + +set QT_PREFIX_PATH=C:\dev\_sdk\Qt5.15.2\5.15.2 +set BOOST_ROOT=C:\dev\_sdk\boost_1_76_0 diff --git a/utils/configure_win64_msvs2019_gui_testnet.cmd b/utils/configure_win64_msvs2019_gui_testnet.cmd new file mode 100644 index 00000000..0fd0d89d --- /dev/null +++ b/utils/configure_win64_msvs2019_gui_testnet.cmd @@ -0,0 +1,7 @@ +call configure_local_paths_msvs2019.cmd + +cd .. +@mkdir build_msvc2019_64_tn +cd build_msvc2019_64_tn + +cmake -D TESTNET=TRUE -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2019_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.2" -G "Visual Studio 16 2019" -A x64 -T host=x64 ".." From d0932f1ea4d19eba8a57ea58edd9ad65570d7fda Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 17 Jun 2021 01:47:35 +0200 Subject: [PATCH 17/29] added mixins into monitoring --- src/connectivity_tool/conn_tool.cpp | 1 + src/currency_core/blockchain_storage.cpp | 15 ++++--- src/currency_core/blockchain_storage.h | 50 ++++++++++++------------ src/rpc/core_rpc_server.cpp | 1 + src/rpc/core_rpc_server_commands_defs.h | 3 ++ utils/munin_plugins/tx_mixins_count | 17 ++++++++ 6 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 utils/munin_plugins/tx_mixins_count diff --git a/src/connectivity_tool/conn_tool.cpp b/src/connectivity_tool/conn_tool.cpp index ce3143e9..b14125ad 100644 --- a/src/connectivity_tool/conn_tool.cpp +++ b/src/connectivity_tool/conn_tool.cpp @@ -593,6 +593,7 @@ bool handle_get_daemon_info(po::variables_map& vm) PRINT_FIELD_NAME(res.performance_data, "", tx_append_time) PRINT_FIELD_NAME(res.performance_data, "", tx_append_rl_wait) PRINT_FIELD_NAME(res.performance_data, "", tx_append_is_expired) + PRINT_FIELD_NAME(res.performance_data, "", tx_mixin_count) PRINT_FIELD_NAME(res.performance_data, "", tx_check_inputs_prefix_hash) PRINT_FIELD_NAME(res.performance_data, "", tx_check_inputs_attachment_check) PRINT_FIELD_NAME(res.performance_data, "", tx_check_inputs_loop) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index e60e5b6f..fd2b4d3e 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3816,12 +3816,14 @@ namespace currency const crypto::hash& m_tx_id; const crypto::hash& m_bl_id; const uint64_t m_bl_height; - add_transaction_input_visitor(blockchain_storage& bcs, blockchain_storage::key_images_container& m_db_spent_keys, const crypto::hash& tx_id, const crypto::hash& bl_id, const uint64_t bl_height) : + uint64_t &m_mixins_count; + add_transaction_input_visitor(blockchain_storage& bcs, blockchain_storage::key_images_container& m_db_spent_keys, const crypto::hash& tx_id, const crypto::hash& bl_id, const uint64_t bl_height, uint64_t& mixins_count) : m_bcs(bcs), m_db_spent_keys(m_db_spent_keys), m_tx_id(tx_id), m_bl_id(bl_id), - m_bl_height(bl_height) + m_bl_height(bl_height), + m_mixins_count(mixins_count) {} bool operator()(const txin_to_key& in) const { @@ -3846,7 +3848,8 @@ namespace currency return false; } } - + if (m_mixins_count < in.key_offsets.size()) + m_mixins_count = in.key_offsets.size(); return true; } bool operator()(const txin_htlc& in) const @@ -3896,11 +3899,11 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const process_blockchain_tx_attachments(tx, bl_height, bl_id, timestamp); TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_process_attachment); - + uint64_t mixins_count = 0; TIME_MEASURE_START_PD(tx_process_inputs); for(const txin_v& in : tx.vin) { - if(!boost::apply_visitor(add_transaction_input_visitor(*this, m_db_spent_keys, tx_id, bl_id, bl_height), in)) + if(!boost::apply_visitor(add_transaction_input_visitor(*this, m_db_spent_keys, tx_id, bl_id, bl_height, mixins_count), in)) { LOG_ERROR("critical internal error: add_transaction_input_visitor failed. but key_images should be already checked"); purge_transaction_keyimages_from_blockchain(tx, false); @@ -3913,6 +3916,8 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const } } TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_process_inputs); + if(need_to_profile && mixins_count > 0) + m_performance_data.tx_mixin_count.push(mixins_count); //check if there is already transaction with this hash TIME_MEASURE_START_PD(tx_check_exist); diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 5c3b995f..7cb02c41 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -73,33 +73,35 @@ namespace currency epee::math_helper::average target_calculating_calc; //tx processing zone - epee::math_helper::average tx_check_inputs_time; - epee::math_helper::average tx_add_one_tx_time; - epee::math_helper::average tx_process_extra; - epee::math_helper::average tx_process_attachment; - epee::math_helper::average tx_process_inputs ; - epee::math_helper::average tx_push_global_index; - epee::math_helper::average tx_check_exist; - epee::math_helper::average tx_print_log; - epee::math_helper::average tx_prapare_append; + epee::math_helper::average tx_check_inputs_time; + epee::math_helper::average tx_add_one_tx_time; + epee::math_helper::average tx_process_extra; + epee::math_helper::average tx_process_attachment; + epee::math_helper::average tx_process_inputs ; + epee::math_helper::average tx_push_global_index; + epee::math_helper::average tx_check_exist; + epee::math_helper::average tx_print_log; + epee::math_helper::average tx_prapare_append; - epee::math_helper::average tx_append_time; - epee::math_helper::average tx_append_rl_wait; - epee::math_helper::average tx_append_is_expired; + epee::math_helper::average tx_append_time; + epee::math_helper::average tx_append_rl_wait; + epee::math_helper::average tx_append_is_expired; - epee::math_helper::average tx_store_db; + epee::math_helper::average tx_store_db; - epee::math_helper::average tx_check_inputs_prefix_hash; - epee::math_helper::average tx_check_inputs_attachment_check; - epee::math_helper::average tx_check_inputs_loop; - epee::math_helper::average tx_check_inputs_loop_kimage_check; - epee::math_helper::average tx_check_inputs_loop_ch_in_val_sig; - epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_get_item_size; - epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_relative_to_absolute; - epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_loop; - epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_loop_get_subitem; - epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_loop_find_tx; - epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_loop_handle_output; + epee::math_helper::average tx_check_inputs_prefix_hash; + epee::math_helper::average tx_check_inputs_attachment_check; + epee::math_helper::average tx_check_inputs_loop; + epee::math_helper::average tx_check_inputs_loop_kimage_check; + epee::math_helper::average tx_check_inputs_loop_ch_in_val_sig; + epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_get_item_size; + epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_relative_to_absolute; + epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_loop; + epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_loop_get_subitem; + epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_loop_find_tx; + epee::math_helper::average tx_check_inputs_loop_scan_outputkeys_loop_handle_output; + + epee::math_helper::average tx_mixin_count; //TODO: move this to suitable place or remove it all diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 6238bed6..2c287ed7 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -210,6 +210,7 @@ namespace currency res.performance_data.tx_append_time = pd.tx_append_time.get_avg(); res.performance_data.tx_append_rl_wait = pd.tx_append_rl_wait.get_avg(); res.performance_data.tx_append_is_expired = pd.tx_append_is_expired.get_avg(); + res.performance_data.tx_mixin_count = pd.tx_mixin_count.get_avg(); res.performance_data.tx_store_db = pd.tx_store_db.get_avg(); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 2ef811ac..531cbe74 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -500,6 +500,8 @@ namespace currency uint64_t tx_print_log; uint64_t tx_prapare_append; + uint64_t tx_mixin_count; + uint64_t tx_store_db; @@ -547,6 +549,7 @@ namespace currency KV_SERIALIZE(tx_store_db) KV_SERIALIZE(tx_print_log) KV_SERIALIZE(tx_prapare_append) + KV_SERIALIZE(tx_mixin_count) KV_SERIALIZE(tx_check_inputs_prefix_hash) KV_SERIALIZE(tx_check_inputs_attachment_check) diff --git a/utils/munin_plugins/tx_mixins_count b/utils/munin_plugins/tx_mixins_count new file mode 100644 index 00000000..434c5cb3 --- /dev/null +++ b/utils/munin_plugins/tx_mixins_count @@ -0,0 +1,17 @@ +#!/bin/bash + +case $1 in + config) + cat <<'EOM' +graph_args --alt-autoscale +graph_title mixins +graph_vlabel mixins +graph_category daemon +mixins.label mixins + +EOM + exit 0;; +esac + +printf "mixins.value " +connectivity_tool --ip=127.0.0.1 --rpc-port=$ZANO_RPC_PORT --timeout=1000 --rpc-get-daemon-info --getinfo-flags-hex="0x0000000000010000" | grep tx_mixin_count | cut -d ' ' -f2 From 96f04db9648ac0b73825d2b37cc8bb5ba2902172 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 17 Jun 2021 01:50:04 +0200 Subject: [PATCH 18/29] added executable attribute --- utils/munin_plugins/tx_mixins_count | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 utils/munin_plugins/tx_mixins_count diff --git a/utils/munin_plugins/tx_mixins_count b/utils/munin_plugins/tx_mixins_count old mode 100644 new mode 100755 From 584558b9f326c30fe774bf75b44aa467ea162334 Mon Sep 17 00:00:00 2001 From: "crypto.sowle" Date: Thu, 17 Jun 2021 13:38:16 +0300 Subject: [PATCH 19/29] update high versions in readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index be80f313..9a00405f 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ Be sure to clone the repository properly:\ | llvm/clang (Linux) | UNKNOWN | 7.0.1 | 8.0.0 | | [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2015 (14.0 update 1) | 2017 (15.9.0) | 2019 | | [XCode](https://developer.apple.com/downloads/) (macOS) | 9.2 | 12.3 | 12.3 | -| [CMake](https://cmake.org/download/) | 2.8.6 | 3.15.5 | 3.18.1 | -| [Boost](https://www.boost.org/users/download/) | 1.56 | 1.68 | 1.69 | -| [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.11.2 | 5.13.2 | +| [CMake](https://cmake.org/download/) | 2.8.6 | 3.15.5 | 3.20 | +| [Boost](https://www.boost.org/users/download/) | 1.56 | 1.68 | 1.76 | +| [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.11.2 | 5.15.2 | Note:\ [*server version*] denotes steps required for building command-line tools (daemon, simplewallet, etc.).\ From 5df4988e6e5e4fd02037b98fa5afce672dc3b07b Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 17 Jun 2021 15:53:22 +0200 Subject: [PATCH 20/29] updated munin plugins --- src/currency_core/blockchain_storage.cpp | 7 ++++++- utils/munin_plugins/performance_transaction | 2 +- utils/munin_plugins/performance_transaction_inp | 2 +- utils/munin_plugins/performance_transaction_inp_loop | 2 +- .../performance_transaction_inp_loop_scan_loop | 2 +- utils/munin_plugins/tx_mixins_count | 2 +- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index fd2b4d3e..b2bae2b9 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3916,8 +3916,13 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const } } TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_process_inputs); - if(need_to_profile && mixins_count > 0) + if (need_to_profile && mixins_count > 0) + { m_performance_data.tx_mixin_count.push(mixins_count); +#ifdef _DEBUG + LOG_PRINT_L0("[TX_MIXINS]: " << mixins_count); +#endif + } //check if there is already transaction with this hash TIME_MEASURE_START_PD(tx_check_exist); diff --git a/utils/munin_plugins/performance_transaction b/utils/munin_plugins/performance_transaction index 84748813..ff8f1c7d 100755 --- a/utils/munin_plugins/performance_transaction +++ b/utils/munin_plugins/performance_transaction @@ -5,7 +5,7 @@ case $1 in cat <<'EOM' graph_title performance_transactions graph_vlabel mcs -graph_category daemon +graph_category transactions tx_add_one_tx_time.label tx_add_one_tx_time tx_add_one_tx_time.draw LINE tx_append_time.label tx_append_time diff --git a/utils/munin_plugins/performance_transaction_inp b/utils/munin_plugins/performance_transaction_inp index 1feaf016..04da756e 100755 --- a/utils/munin_plugins/performance_transaction_inp +++ b/utils/munin_plugins/performance_transaction_inp @@ -5,7 +5,7 @@ case $1 in cat <<'EOM' graph_title performance_tranactions_inp graph_vlabel mcs -graph_category daemon.inp +graph_category transactions.inp tx_check_inputs_prefix_hash.label prefix_hash tx_check_inputs_prefix_hash.draw AREA tx_check_inputs_attachment_check.label attachment_check diff --git a/utils/munin_plugins/performance_transaction_inp_loop b/utils/munin_plugins/performance_transaction_inp_loop index e0b8f602..4cd5ebc8 100755 --- a/utils/munin_plugins/performance_transaction_inp_loop +++ b/utils/munin_plugins/performance_transaction_inp_loop @@ -5,7 +5,7 @@ case $1 in cat <<'EOM' graph_title performance_tranactions_inp.every_inp graph_vlabel mcs -graph_category daemon.inp +graph_category transactions.inp tx_check_inputs_loop_kimage_check.label kimage_check tx_check_inputs_loop_kimage_check.draw AREA tx_check_inputs_loop_ch_in_val_sig.label ch_in_val_sig diff --git a/utils/munin_plugins/performance_transaction_inp_loop_scan_loop b/utils/munin_plugins/performance_transaction_inp_loop_scan_loop index 9e95c2b1..537ccd18 100755 --- a/utils/munin_plugins/performance_transaction_inp_loop_scan_loop +++ b/utils/munin_plugins/performance_transaction_inp_loop_scan_loop @@ -5,7 +5,7 @@ case $1 in cat <<'EOM' graph_title performance_tranactions_inp.every_inp.every_key graph_vlabel mcs -graph_category daemon.inp +graph_category transactions.inp tx_check_inputs_loop_scan_outputkeys_loop_get_subitem.label get_subitem tx_check_inputs_loop_scan_outputkeys_loop_get_subitem.draw AREA tx_check_inputs_loop_scan_outputkeys_loop_find_tx.label find_tx diff --git a/utils/munin_plugins/tx_mixins_count b/utils/munin_plugins/tx_mixins_count index 434c5cb3..0bee5984 100755 --- a/utils/munin_plugins/tx_mixins_count +++ b/utils/munin_plugins/tx_mixins_count @@ -6,7 +6,7 @@ case $1 in graph_args --alt-autoscale graph_title mixins graph_vlabel mixins -graph_category daemon +graph_category transactions mixins.label mixins EOM From f738596a3cd969b146353443ebd5465bc3b6d84c Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 17 Jun 2021 23:02:57 +0200 Subject: [PATCH 21/29] Added try_catch with location --- contrib/epee/include/misc_language.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h index 1a02c7c8..276dfe02 100644 --- a/contrib/epee/include/misc_language.h +++ b/contrib/epee/include/misc_language.h @@ -65,6 +65,8 @@ namespace epee } +#define STD_TRY_CATCH_LOCATION(return_val) STD_TRY_CATCH(LOCATION_SS, return_val) + /* helper class, to make able get namespace via decltype()::*/ template class namespace_accessor: public base_class{}; From d591db9a91975cb7b3598837bc1742c1e2e49e58 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 22 Jun 2021 18:00:30 +0300 Subject: [PATCH 22/29] crypto: point_t::is_in_main_subgroup() added --- src/crypto/crypto-sugar.h | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index 1c1b1b9a..600fe914 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -433,6 +433,17 @@ namespace crypto }; // struct scalar_t + // + // Global constants + // + + extern const scalar_t c_scalar_1; + extern const scalar_t c_scalar_L; + extern const scalar_t c_scalar_Lm1; + extern const scalar_t c_scalar_P; + extern const scalar_t c_scalar_Pm1; + extern const scalar_t c_scalar_256m1; + extern const scalar_t c_scalar_1div8; // // @@ -486,6 +497,7 @@ namespace crypto zero(); } + // as we're using additive notation, zero means identity group element here and after void zero() { ge_p3_0(&m_p3); @@ -497,6 +509,11 @@ namespace crypto return fe_isnonzero(m_p3.X) * fe_cmp(m_p3.Y, m_p3.Z) == 0; } + bool is_in_main_subgroup() const + { + return (c_scalar_L * *this).is_zero(); + } + bool from_public_key(const crypto::public_key& pk) { return ge_frombytes_vartime(&m_p3, reinterpret_cast(&pk)) == 0; @@ -862,14 +879,6 @@ namespace crypto // extern const point_g_t c_point_G; - - extern const scalar_t c_scalar_1; - extern const scalar_t c_scalar_L; - extern const scalar_t c_scalar_Lm1; - extern const scalar_t c_scalar_P; - extern const scalar_t c_scalar_Pm1; - extern const scalar_t c_scalar_256m1; - extern const scalar_t c_scalar_1div8; extern const point_t c_point_H; extern const point_t c_point_0; From 1ac39d19f69de18b148a2d05a46b3555bff665a7 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 22 Jun 2021 18:05:23 +0300 Subject: [PATCH 23/29] crypto_tests: added crypto_neg_identity (against negative identity pub keys and key images) --- tests/functional_tests/crypto_tests.cpp | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/functional_tests/crypto_tests.cpp b/tests/functional_tests/crypto_tests.cpp index f5ea3a8e..86d00401 100644 --- a/tests/functional_tests/crypto_tests.cpp +++ b/tests/functional_tests/crypto_tests.cpp @@ -1097,6 +1097,52 @@ TEST(crypto, point_basics) return true; } +TEST(crypto, neg_identity) +{ + point_t z = c_point_0; // 0 group element (identity) + public_key z_pk = z.to_public_key(); // pub key, corresponding to 0 ge (pub key is not zero bitwise) + public_key z_neg_pk = z_pk; + ((unsigned char*)&z_neg_pk)[31] = 0x80; // set sign bit manually + std::cout << "-Identity = " << z_pk << ENDL; + point_t z_neg; + ASSERT_FALSE(z_neg.from_public_key(z_neg_pk)); // negative identity should not be loaded + + key_image z_ki; + memset(&z_ki, 0, sizeof(z_ki)); + ((unsigned char*)&z_ki)[00] = 0x01; // y = 1 + + ASSERT_TRUE(validate_key_image(z_ki)); + + key_image z_neg_ki = z_ki; + ((unsigned char*)&z_neg_ki)[31] = 0x80; // set sign bit manually + + ASSERT_FALSE(validate_key_image(z_neg_ki)); // negative identity should not be loaded + + + // also do zero-byte pub key / key image checks + + public_key zzz_pk; + memset(&zzz_pk, 0, sizeof public_key); + + ASSERT_TRUE(check_key(zzz_pk)); + + point_t zzz; + ASSERT_TRUE(zzz.from_public_key(zzz_pk)); + ASSERT_FALSE(zzz.is_in_main_subgroup()); + + key_image zzz_ki; + memset(&zzz_ki, 0, sizeof key_image); + + ASSERT_FALSE(validate_key_image(zzz_ki)); + + point_t zzz2; + ASSERT_TRUE(zzz2.from_key_image(zzz_ki)); + ASSERT_FALSE(zzz2.is_in_main_subgroup()); + ASSERT_EQ(zzz, zzz2); + + return true; +} + TEST(crypto, scalar_reciprocal) { int64_t test_nums[] = { 1, 2, 10 }; From 2fdcbd1554736f3bcfb3d55f274b71d9b8fd7e30 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 29 Jun 2021 18:16:11 +0300 Subject: [PATCH 24/29] build certification and notarization for macos --- src/CMakeLists.txt | 1 + utils/build_script_mac_osx.sh | 64 ++++++++++++++++++++++++++++++++-- utils/macos_entitlements.plist | 8 +++++ 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 utils/macos_entitlements.plist diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3f36b1d5..807d2a16 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -199,6 +199,7 @@ if(BUILD_GUI) if(APPLE) target_link_libraries(Zano ${COCOA_LIBRARY}) + set_property(TARGET Zano PROPERTY XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES) endif() if(MSVC) target_link_libraries(Zano shlwapi.lib) diff --git a/utils/build_script_mac_osx.sh b/utils/build_script_mac_osx.sh index b9b989db..832e9b90 100755 --- a/utils/build_script_mac_osx.sh +++ b/utils/build_script_mac_osx.sh @@ -1,4 +1,5 @@ -set -x #echo on +set -x # echo on +set +e # switch off exit on error curr_path=${BASH_SOURCE%/*} # check that all the required environment vars are set @@ -21,6 +22,8 @@ if [ "$testnet" == true ]; then ARCHIVE_NAME_PREFIX=${ARCHIVE_NAME_PREFIX}testnet- fi +# cd "$ZANO_BUILD_DIR/release/src" +# if false; then rm -rf $ZANO_BUILD_DIR; mkdir -p "$ZANO_BUILD_DIR/release"; cd "$ZANO_BUILD_DIR/release" @@ -101,12 +104,44 @@ if [ $? -ne 0 ]; then exit 1 fi -codesign -s "Zano" --deep -vv -f Zano.app +#fi + +codesign -s "Developer ID Application: Zano Limited" --timestamp --options runtime -f --entitlements ../../../utils/macos_entitlements.plist --deep ./Zano.app +#codesign -s "Zano" --deep -vv -f Zano.app if [ $? -ne 0 ]; then - echo "Failed to sign application" + echo "Failed to sign Zano.app" exit 1 fi + +rm -f Zano.zip + +# creating archive for notarizing +echo "Creating archive for notarizing" +/usr/bin/ditto -c -k --keepParent ./Zano.app ./Zano.zip + +#fi + +# notarization +echo "Notarizing..." +tmpfile="tmptmptmp" +xcrun altool --notarize-app --primary-bundle-id "org.zano.desktop" -u "andrey@zano.org" -p "@keychain:Developer-altool" --file ./Zano.zip > $tmpfile 2>&1 +NOTARIZE_RES=$? +NOTARIZE_OUTPUT=$( cat $tmpfile ) +rm $tmpfile +echo "NOTARIZE_OUTPUT=$NOTARIZE_OUTPUT" +if [ $NOTARIZE_RES -ne 0 ]; then + echo "Notarization failed" + exit 1 +fi + +GUID=$(echo "$NOTARIZE_OUTPUT" | egrep -Ewo '[[:xdigit:]]{8}(-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}') +if [ ${#GUID} -ne 36 ]; then + echo "Couldn't get correct GUID from the response, got only \"$GUID\"" + exit 1 +fi + + read version_str <<< $(DYLD_LIBRARY_PATH=$ZANO_BOOST_LIBS_PATH ./connectivity_tool --version | awk '/^Zano/ { print $2 }') version_str=${version_str} echo $version_str @@ -134,7 +169,30 @@ if [ $? -ne 0 ]; then exit 1 fi + +success=0 + +# check notarization status +for i in {1..10}; do + xcrun altool --notarization-info $GUID -u "andrey@zano.org" -p "@keychain:Developer-altool" > $tmpfile 2>&1 + NOTARIZE_OUTPUT=$( cat $tmpfile ) + rm $tmpfile + NOTARIZATION_LOG_URL=$(echo "$NOTARIZE_OUTPUT" | sed -n "s/.*LogFileURL\: \([[:graph:]]*\).*/\1/p") + if [ $(#NOTARIZATION_LOG_URL) -ge 30 ]; then + success=1 + curl -L $NOTARIZATION_LOG_URL + break + fi + sleep 60 +done + cd ../../.. + +if [ $success -ne 1 ]; then + echo "Build notarizaton failed" + exit 1 +fi + echo "Build success" echo "############### Uploading... ################" diff --git a/utils/macos_entitlements.plist b/utils/macos_entitlements.plist new file mode 100644 index 00000000..68015469 --- /dev/null +++ b/utils/macos_entitlements.plist @@ -0,0 +1,8 @@ + + + + + com.apple.security.cs.disable-executable-page-protection + + + From 7c01ea40521041c916ea99b004d1d0bbd31892d5 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 5 Jul 2021 12:34:08 +0300 Subject: [PATCH 25/29] build: macos script redisigned for Big Sur --- utils/build_script_mac_osx.sh | 121 ++++++++++++++++++---------------- utils/macosx_dmg_builder.sh | 1 + 2 files changed, 64 insertions(+), 58 deletions(-) diff --git a/utils/build_script_mac_osx.sh b/utils/build_script_mac_osx.sh index 832e9b90..d19e0ca1 100755 --- a/utils/build_script_mac_osx.sh +++ b/utils/build_script_mac_osx.sh @@ -22,8 +22,11 @@ if [ "$testnet" == true ]; then ARCHIVE_NAME_PREFIX=${ARCHIVE_NAME_PREFIX}testnet- fi -# cd "$ZANO_BUILD_DIR/release/src" -# if false; then +######### DEBUG ########## +#cd "$ZANO_BUILD_DIR/release/src" +#rm *.dmg +#if false; then +##### end of DEBUG ###### rm -rf $ZANO_BUILD_DIR; mkdir -p "$ZANO_BUILD_DIR/release"; cd "$ZANO_BUILD_DIR/release" @@ -104,44 +107,13 @@ if [ $? -ne 0 ]; then exit 1 fi -#fi - codesign -s "Developer ID Application: Zano Limited" --timestamp --options runtime -f --entitlements ../../../utils/macos_entitlements.plist --deep ./Zano.app -#codesign -s "Zano" --deep -vv -f Zano.app if [ $? -ne 0 ]; then echo "Failed to sign Zano.app" exit 1 fi -rm -f Zano.zip - -# creating archive for notarizing -echo "Creating archive for notarizing" -/usr/bin/ditto -c -k --keepParent ./Zano.app ./Zano.zip - -#fi - -# notarization -echo "Notarizing..." -tmpfile="tmptmptmp" -xcrun altool --notarize-app --primary-bundle-id "org.zano.desktop" -u "andrey@zano.org" -p "@keychain:Developer-altool" --file ./Zano.zip > $tmpfile 2>&1 -NOTARIZE_RES=$? -NOTARIZE_OUTPUT=$( cat $tmpfile ) -rm $tmpfile -echo "NOTARIZE_OUTPUT=$NOTARIZE_OUTPUT" -if [ $NOTARIZE_RES -ne 0 ]; then - echo "Notarization failed" - exit 1 -fi - -GUID=$(echo "$NOTARIZE_OUTPUT" | egrep -Ewo '[[:xdigit:]]{8}(-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}') -if [ ${#GUID} -ne 36 ]; then - echo "Couldn't get correct GUID from the response, got only \"$GUID\"" - exit 1 -fi - - read version_str <<< $(DYLD_LIBRARY_PATH=$ZANO_BOOST_LIBS_PATH ./connectivity_tool --version | awk '/^Zano/ { print $2 }') version_str=${version_str} echo $version_str @@ -160,6 +132,8 @@ if [ $? -ne 0 ]; then exit 1 fi +#fi + package_filename=${ARCHIVE_NAME_PREFIX}${version_str}.dmg source ../../../utils/macosx_dmg_builder.sh @@ -169,6 +143,60 @@ if [ $? -ne 0 ]; then exit 1 fi +echo "Build success" + +echo "############### Uploading... ################" + +package_filepath=$package_filename + +scp $package_filepath zano_build_server:/var/www/html/builds/ +if [ $? -ne 0 ]; then + echo "Failed to upload to remote server" + exit 1 +fi + + +read checksum <<< $( shasum -a 256 $package_filepath | awk '/^/ { print $1 }' ) + +mail_msg="New ${build_prefix_label}${testnet_label}build for macOS-x64:
+https://build.zano.org/builds/$package_filename
+sha256: $checksum" + +echo "$mail_msg" + +echo "$mail_msg" | mail -s "Zano macOS-x64 ${build_prefix_label}${testnet_label}build $version_str" ${emails} + + +###################### +# notarization +###################### + +cd package_folder + +echo "Notarizing..." + +# creating archive for notarizing +echo "Creating archive for notarizing" +rm -f Zano.zip +/usr/bin/ditto -c -k --keepParent ./Zano.app ./Zano.zip + +tmpfile="tmptmptmp" +xcrun altool --notarize-app --primary-bundle-id "org.zano.desktop" -u "andrey@zano.org" -p "@keychain:Developer-altool" --file ./Zano.zip > $tmpfile 2>&1 +NOTARIZE_RES=$? +NOTARIZE_OUTPUT=$( cat $tmpfile ) +rm $tmpfile +echo "NOTARIZE_OUTPUT=$NOTARIZE_OUTPUT" +if [ $NOTARIZE_RES -ne 0 ]; then + echo "Notarization failed" + exit 1 +fi + +GUID=$(echo "$NOTARIZE_OUTPUT" | egrep -Ewo '[[:xdigit:]]{8}(-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}') +if [ ${#GUID} -ne 36 ]; then + echo "Couldn't get correct GUID from the response, got only \"$GUID\"" + exit 1 +fi + success=0 @@ -186,32 +214,9 @@ for i in {1..10}; do sleep 60 done -cd ../../.. - if [ $success -ne 1 ]; then - echo "Build notarizaton failed" + echo "Build notarization failed" exit 1 fi -echo "Build success" - -echo "############### Uploading... ################" - -package_filepath=$ZANO_BUILD_DIR/release/src/$package_filename - -scp $package_filepath zano_build_server:/var/www/html/builds/ -if [ $? -ne 0 ]; then - echo "Failed to upload to remote server" - exit 1 -fi - - -read checksum <<< $( shasum -a 256 $package_filepath | awk '/^/ { print $1 }' ) - -mail_msg="New ${build_prefix_label}${testnet_label}build for macOS-x64:
-https://build.zano.org/builds/$package_filename
-sha256: $checksum" - -echo "$mail_msg" - -echo "$mail_msg" | mail -s "Zano macOS-x64 ${build_prefix_label}${testnet_label}build $version_str" ${emails} +echo "Notarization done" diff --git a/utils/macosx_dmg_builder.sh b/utils/macosx_dmg_builder.sh index 7defc9cc..4fb211f8 100644 --- a/utils/macosx_dmg_builder.sh +++ b/utils/macosx_dmg_builder.sh @@ -19,6 +19,7 @@ function build_fancy_dmg() # $1 - path to package folder, $2 - dmg output filena --icon Zano.app 112 115 \ --hide-extension Zano.app \ --app-drop-link 365 115 \ + --no-internet-enable \ $2 \ $1 From 5ad01ef2c92a481814be826e23088f6d3b122604 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 5 Jul 2021 16:18:48 +0300 Subject: [PATCH 26/29] build: macos script minor fix --- utils/build_script_mac_osx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/build_script_mac_osx.sh b/utils/build_script_mac_osx.sh index d19e0ca1..bb70d5fc 100755 --- a/utils/build_script_mac_osx.sh +++ b/utils/build_script_mac_osx.sh @@ -206,7 +206,7 @@ for i in {1..10}; do NOTARIZE_OUTPUT=$( cat $tmpfile ) rm $tmpfile NOTARIZATION_LOG_URL=$(echo "$NOTARIZE_OUTPUT" | sed -n "s/.*LogFileURL\: \([[:graph:]]*\).*/\1/p") - if [ $(#NOTARIZATION_LOG_URL) -ge 30 ]; then + if [ ${#NOTARIZATION_LOG_URL} -ge 30 ]; then success=1 curl -L $NOTARIZATION_LOG_URL break From 733a8d7510878a45f43ee266b6b7029c03d41e13 Mon Sep 17 00:00:00 2001 From: "crypto.sowle" Date: Sun, 18 Jul 2021 20:13:46 +0300 Subject: [PATCH 27/29] fixed a typo in README.MD --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a00405f..b85f3073 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Recommended OS version: Ubuntu 18.04 LTS. [*GUI version*] - sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen mesa-common-dev libglu1-mesa-dev` + sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen mesa-common-dev libglu1-mesa-dev 2. Download and build Boost From b09b6e39168a4b4c2bba82ec64f3d8cd8e0c4840 Mon Sep 17 00:00:00 2001 From: "crypto.sowle" Date: Thu, 29 Jul 2021 03:28:41 +0300 Subject: [PATCH 28/29] added a notice for building testnet --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b85f3073..189c88cf 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ For instance, by adding the following lines to `~/.bashrc` make -j1 daemon simplewallet **NOTICE**: If you are building on a machine with a relatively high amount of RAM or with the proper setting of virtual memory, then you can use `-j2` or `-j` option to speed up the building process. Use with caution. + + **NOTICE 2**: If you'd like to build binaries for the testnet, use `cmake -D TESTNET=TRUE ..` instead of `cmake ..` . 1. Building GUI: From 52beabc915607e66c0f81fb115f0b5752ea38a81 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 9 Aug 2021 14:35:13 +0300 Subject: [PATCH 29/29] predownload: don't exit when downloading fails unless force-predownload has been set --- src/common/pre_download.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/common/pre_download.h b/src/common/pre_download.h index e119d505..5feec36b 100644 --- a/src/common/pre_download.h +++ b/src/common/pre_download.h @@ -50,7 +50,8 @@ namespace tools boost::system::error_code ec; uint64_t sz = boost::filesystem::file_size(db_main_file_path, ec); - if (pre_download.unpacked_size == 0 || !(ec || (pre_download.unpacked_size > sz && pre_download.unpacked_size - sz > pre_download_min_size_difference) || command_line::has_arg(vm, command_line::arg_force_predownload)) ) + bool flag_force_predownload = command_line::has_arg(vm, command_line::arg_force_predownload); + if (pre_download.unpacked_size == 0 || !(ec || (pre_download.unpacked_size > sz && pre_download.unpacked_size - sz > pre_download_min_size_difference) || flag_force_predownload) ) { LOG_PRINT_MAGENTA("Pre-downloading not needed (db file size = " << sz << ")", LOG_LEVEL_0); return true; @@ -92,15 +93,15 @@ namespace tools r = cl.download_and_unzip(cb, downloading_file_path, url, 5000 /* timout */, "GET", std::string(), 30 /* fails count */); if (!r) { - LOG_PRINT_RED("Download failed", LOG_LEVEL_0); - return false; + LOG_PRINT_RED("Downloading failed", LOG_LEVEL_0); + return !flag_force_predownload; // fatal error only if force-predownload } crypto::hash data_hash = hash_stream.calculate_hash(); if (epee::string_tools::pod_to_hex(data_hash) != pre_download.hash) { LOG_ERROR("hash missmatch in downloaded file, got: " << epee::string_tools::pod_to_hex(data_hash) << ", expected: " << pre_download.hash); - return false; + return !flag_force_predownload; // fatal error only if force-predownload } LOG_PRINT_GREEN("Download succeeded, hash " << pre_download.hash << " is correct" , LOG_LEVEL_0);