From 67c47c5491b022f74a0af8138b69ae614527bdba Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Sat, 17 Feb 2024 18:10:28 +0100 Subject: [PATCH] add signing functionality --- .env | 74 ++++++------ .github/workflows/linux.yml | 12 +- .gitignore | 14 ++- Makefile | 138 ++++++++++++++++++++++- README.md | 40 ++----- libbridge/src/main/cpp/wallet2_api_c.cpp | 15 +++ libbridge/src/main/cpp/wallet2_api_c.h | 2 + 7 files changed, 213 insertions(+), 82 deletions(-) diff --git a/.env b/.env index 28629a6..3ca46c9 100644 --- a/.env +++ b/.env @@ -1,40 +1,34 @@ - PREFIX=/opt/linux/prefix - NPROC=4 - PATH=/usr/cmake-3.14.6-Linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - - # CMake - CMAKE_VERSION='3.14.6' - CMAKE_HASH='82e08e50ba921035efa82b859c74c5fbe27d3e49a4003020e3c77618a4e912cd' - # Boost - BOOST_VERSION='1_70_0' - BOOST_VERSION_DOT='1.70.0' - BOOST_HASH='430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778' - # iconv - ICONV_VERSION='1.16' - ICONV_HASH='e6a1b1b589654277ee790cce3734f07876ac4ccfaecbee8afa0b649cf529cc04' - # zlib - ZLIB_VERSION='1.3.1' - ZLIB_HASH='9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23' - # OpenSSL - OPENSSL_VERSION='3.2.0' - OPENSSL_HASH='14c826f07c7e433706fb5c69fa9e25dab95684844b4c962a2cf1bf183eb4690e' - # ZMQ - ZMQ_VERSION='v4.3.2' - ZMQ_HASH='a84ffa12b2eb3569ced199660bac5ad128bff1f0' - # libsodium - SODIUM_VERSION='1.0.18' - SODIUM_HASH='4f5e89fa84ce1d178a6765b8b46f2b6f91216677' - # libexpat - LIBEXPAT_VERSION='R_2_4_8' - LIBEXPAT_HASH='3bab6c09bbe8bf42d84b81563ddbcf4cca4be838' - # libunbound - LIBUNBOUND_VERSION='branch-1.16.1' - LIBUNBOUND_HASH='903538c76e1d8eb30d0814bb55c3ef1ea28164e8' - # polyseed - POLYSEED_HASH='b7c35bb3c6b91e481ecb04fc235eaff69c507fa1' - # utf8proc - UTF8PROC_HASH='1cb28a66ca79a0845e99433fd1056257456cef8b' - # (finally) monero - MONERO_GIT_SOURCE_SIMPLE='git.mrcyjanek.net_mrcyjanek_monero' - MONERO_GIT_SOURCE=https://git.mrcyjanek.net/mrcyjanek/monero.git - MONERO_TAG='release-v0.18.3.1-anonero' \ No newline at end of file +NPROC=4 +# Boost +BOOST_VERSION=1_84_0 +BOOST_VERSION_DOT=1.84.0 +BOOST_HASH=cc4b893acf645c9d4b698e9a0f08ca8846aa5d6c68275c14c3e7949c24109454 +# iconv +ICONV_VERSION=1.16 +ICONV_HASH=e6a1b1b589654277ee790cce3734f07876ac4ccfaecbee8afa0b649cf529cc04 +# zlib +ZLIB_VERSION=1.3.1 +ZLIB_HASH=9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23 +# OpenSSL +OPENSSL_VERSION=3.2.0 +OPENSSL_HASH=14c826f07c7e433706fb5c69fa9e25dab95684844b4c962a2cf1bf183eb4690e +# ZMQ +ZMQ_VERSION=v4.3.2 +ZMQ_HASH=a84ffa12b2eb3569ced199660bac5ad128bff1f0 +# libsodium +SODIUM_VERSION=1.0.18 +SODIUM_HASH=4f5e89fa84ce1d178a6765b8b46f2b6f91216677 +# libexpat +LIBEXPAT_VERSION=R_2_4_8 +LIBEXPAT_HASH=3bab6c09bbe8bf42d84b81563ddbcf4cca4be838 +# libunbound +LIBUNBOUND_VERSION=branch-1.16.1 +LIBUNBOUND_HASH=903538c76e1d8eb30d0814bb55c3ef1ea28164e8 +# polyseed +POLYSEED_HASH=b7c35bb3c6b91e481ecb04fc235eaff69c507fa1 +# utf8proc +UTF8PROC_HASH=1cb28a66ca79a0845e99433fd1056257456cef8b +# (finally) monero +MONERO_GIT_SOURCE_SIMPLE=git.mrcyjanek.net_mrcyjanek_monero +MONERO_GIT_SOURCE=https://git.mrcyjanek.net/mrcyjanek/monero.git +MONERO_TAG=release-v0.18.3.1-anonero \ No newline at end of file diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index dfd1ea7..4c1252d 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -276,12 +276,12 @@ jobs: && sha256sum ${{ matrix.host_triplet }}_libwallet2_api_c.so > ${{ matrix.host_triplet }}_libwallet2_api_c.so.sha256 \ && xz -e ${{ matrix.host_triplet }}_libwallet2_api_c.so \ && sha256sum ${{ matrix.host_triplet }}_libwallet2_api_c.so.xz > ${{ matrix.host_triplet }}_libwallet2_api_c.so.xz.sha256 - - name: Publish .deb - run: | - cd ${{ github.workspace }} \ - && LD_PRELOAD=/usr/lib/checkinstall/installwatch.so checkinstall --type=debian --pkgname="libwallet2-api-c" --pkgversion="$(git describe --tags | sed 's/v//')" --nodoc --strip=no --stripso=no --maintainer=cyjan@mrcyjanek.net --install=no -y \ - ; ls -lah *.deb \ - ; curl --user mrcyjanek:$PAT_SECRET_PACKAGE --upload-file $(echo *.deb) https://git.mrcyjanek.net/api/packages/mrcyjanek/debian/pool/no-distro/main/upload + # - name: Publish .deb + # run: | + # cd ${{ github.workspace }} \ + # && LD_PRELOAD=/usr/lib/checkinstall/installwatch.so checkinstall --type=debian --pkgname="libwallet2-api-c" --pkgversion="$(git describe --tags | sed 's/v//')" --nodoc --strip=no --stripso=no --maintainer=cyjan@mrcyjanek.net --install=no -y \ + # ; ls -lah *.deb \ + # ; curl --user mrcyjanek:$PAT_SECRET_PACKAGE --upload-file $(echo *.deb) https://git.mrcyjanek.net/api/packages/mrcyjanek/debian/pool/no-distro/main/upload # - name: act - copy workspace to /opt/wspace # if: ${{ env.ACT }} # run: cp -a ${{ github.workspace }} /opt/wspace diff --git a/.gitignore b/.gitignore index 8553e3d..99b9ab8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,13 @@ -monero* \ No newline at end of file +monero* +boost_* +libexpat +libiconv-* +libsodium* +libzmq* +openssl-* +polyseed* +unbound* +utf8proc* +zlib* + +prefix \ No newline at end of file diff --git a/Makefile b/Makefile index fc98c16..b0e1a8c 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,136 @@ -install: - cp libbridge/build/libwallet2_api_c.so /usr/local/lib/libwallet2_api_c.so \ No newline at end of file +include .env +export $(shell sed 's/=.*//' .env) + +PREFIX := ${PWD}/prefix + +.PHONY: download +download: + rm -rf monero + # Monero + (git clone ${MONERO_GIT_SOURCE} --depth=1 --branch ${MONERO_TAG} monero && cd monero && git submodule init && git submodule update) + # Boost + curl -L -o boost_${BOOST_VERSION}.tar.bz2 https://archives.boost.io/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 + echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c + tar -xf boost_${BOOST_VERSION}.tar.bz2 + rm -f boost_${BOOST_VERSION}.tar.bz2 + # libiconv + curl -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz + echo "${ICONV_HASH} libiconv-${ICONV_VERSION}.tar.gz" | sha256sum -c + tar -xzf libiconv-${ICONV_VERSION}.tar.gz + rm -f libiconv-${ICONV_VERSION}.tar.gz + # zlib + curl -O https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz + echo "${ZLIB_HASH} zlib-${ZLIB_VERSION}.tar.gz" | sha256sum -c + tar -xzf zlib-${ZLIB_VERSION}.tar.gz + rm zlib-${ZLIB_VERSION}.tar.gz + mv zlib-${ZLIB_VERSION} zlib + openssl + curl -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz + echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c + tar -xzf openssl-${OPENSSL_VERSION}.tar.gz + rm openssl-${OPENSSL_VERSION}.tar.gz + # libzmq + git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} --depth=1 + (cd libzmq && test `git rev-parse HEAD` = ${ZMQ_HASH}) || exit 1 + # libsodium + git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} --depth=1 + (cd libsodium && test `git rev-parse HEAD` = ${SODIUM_HASH}) || exit 1 + # libexpat + git clone https://github.com/libexpat/libexpat.git -b ${LIBEXPAT_VERSION} --depth=1 + (cd libexpat && test `git rev-parse HEAD` = ${LIBEXPAT_HASH}) || exit 1 + # unbound + git clone https://github.com/NLnetLabs/unbound.git -b ${LIBUNBOUND_VERSION} --depth=1 + (cd unbound && test `git rev-parse HEAD` = ${LIBUNBOUND_HASH}) || exit 1 + # polyseed + git clone https://github.com/tevador/polyseed.git + (cd polyseed && git reset --hard ${POLYSEED_HASH}) || exit 1 + # utf8proc + git clone https://github.com/JuliaStrings/utf8proc -b v2.8.0 --depth=1 + (cd utf8proc && git reset --hard ${UTF8PROC_HASH}) + + +.PHONY: host_depends +host_depends: libiconv_host boost_host zlib_host openssl_host libzmq_host libsodium_host libsodium_host libexpat_host unbound_host polyseed_host utf8proc_host + cp -a ${PREFIX}/lib64/* ${PREFIX}/lib # fix linking issue + +.PHONY: libiconv_host +libiconv_host: + cd libiconv-${ICONV_VERSION} && ./configure --prefix=${PREFIX} --disable-rpath + cd libiconv-${ICONV_VERSION} && make -j${NPROC} + cd libiconv-${ICONV_VERSION} && make install + +.PHONY: boost_host +boost_host: + cd boost_${BOOST_VERSION} && ./bootstrap.sh --prefix=${PREFIX} + cd boost_${BOOST_VERSION} && echo '\n#undef PTHREAD_STACK_MIN\n#define PTHREAD_STACK_MIN 16384\n' | cat - ./boost/thread/pthread/thread_data.hpp > temp && mv temp ./boost/thread/pthread/thread_data.hpp + cd boost_${BOOST_VERSION} && ./b2 cxxflags=-fPIC cflags=-fPIC --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale --build-dir=linux --stagedir=linux toolset=gcc threading=multi threadapi=pthread -sICONV_PATH=${PREFIX} install -j${NPROC} + +.PHONY: zlib_host +zlib_host: + cd zlib && ./configure --static + cd zlib && make -j${NPROC} + +.PHONY: openssl_host +openssl_host: + cd openssl-${OPENSSL_VERSION} && ./Configure -static no-shared no-tests --with-zlib-include=${PREFIX}/zlib/include --with-zlib-lib=${PREFIX}/zlib/lib --prefix=${PREFIX} --openssldir=${PREFIX} -fpic + cd openssl-${OPENSSL_VERSION} && make -j${NPROC} + cd openssl-${OPENSSL_VERSION} && make install_sw + +.PHONY: libzmq_host +libzmq_host: + rm -rf libzmq/build || true + cd libzmq && ./autogen.sh + cd libzmq && mkdir build + cd libzmq/build && cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DBUILD_SHARED=OFF -DBUILD_TESTS=OFF .. + cd libzmq/build && make -j${NPROC} + cd libzmq/build && make install + +.PHONY: libsodium_host +libsodium_host: + cd libsodium && ./autogen.sh + cd libsodium && ./configure --prefix=${PREFIX} --enable-static --disable-shared --with-pic + cd libsodium && make -j${NPROC} + cd libsodium && make install + +.PHONY: libexpat_host +libexpat_host: + cd libexpat/expat && ./buildconf.sh + cd libexpat/expat && ./configure --prefix=${PREFIX} --enable-static --disable-shared + cd libexpat/expat && make -j${NPROC} + cd libexpat/expat && make install + +.PHONY: unbound_host +unbound_host: + cd unbound && ./configure -with-pic --prefix=${PREFIX} --enable-static --disable-shared --disable-flto --with-libexpat=${PREFIX} --with-ssl=${PREFIX} + cd unbound && make -j${NPROC} + cd unbound && make install + +.PHONY: polyseed_host +polyseed_host: + cd polyseed && cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} . + cd polyseed && make -j${NPROC} + cd polyseed && make install + +.PHONY: utf8proc_host +utf8proc_host: + cd utf8proc && rm -rf build || true + cd utf8proc && mkdir build + cd utf8proc/build && rm -rf ../CMakeCache.txt ../CMakeFiles/ || true + cd utf8proc/build && cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} .. + cd utf8proc/build && make -j${NPROC} + cd utf8proc/build && make install + +.PHONY: monero_linux_amd64 +monero_linux_amd64: + cd monero \ + && mkdir -p build/release \ + && cd build/release \ + && env CMAKE_INCLUDE_PATH="${PREFIX}/include" CMAKE_LIBRARY_PATH="${PREFIX}/lib" USE_SINGLE_BUILDDIR=1 cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH="x86-64" -D STATIC=ON -D BUILD_64="ON" -D CMAKE_BUILD_TYPE=release -D ANDROID=false -D BUILD_TAG="linux-x86_64" -D CMAKE_SYSTEM_NAME="Linux" ../.. + cd monero/build/release && make wallet_api -j${NPROC} + +.PHONY: moneroc_linux_amd64 +moneroc_linux_amd64: + rm -rf libbridge/build || true + mkdir -p libbridge/build + cd libbridge/build && env CC=gcc CXX=g++ cmake -DANDROID_ABI=linux-x86_64 .. + cd libbridge/build && make -j${NPROC} \ No newline at end of file diff --git a/README.md b/README.md index 29254da..25551fd 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,16 @@ # wallet2_api.h (but this time C compatible) -Wrapper around wallet2_api.h that can be called using C api. +> Wrapper around wallet2_api.h that can be called using C api. ## Contributing To contribute you can visit git.mrcyjanek.net/mrcyjanek/monero_c and open a PR, alternatively use any other code mirror or send patches directly. -## Building (android) - -Builds are provided in the [release tab](https://git.mrcyjanek.net/mrcyjanek/monero_c/releases), built using Gitea Runners. Building locally is possible as well, althought it is rather a heavy task which takes ~2 hours to finish (excluding enviroment setup and some downloads). - -Base image for the runner is `git.mrcyjanek.net/mrcyjanek/androidndk:r17c`, which contains preinstalled NDK. `Dockerfile` can be obtained from [mrcyjanek/CIimages](https://git.mrcyjanek.net/mrcyjanek/CIimages/src/branch/master/Dockerfile.androidndk-r17c) repository. - -Then to build `.github/workflows/*.yml` files are used. - -Local build? +**IMPORTANT** I don't have time to write better README, please check Makefile for build instructions, in general it comes down to: ```bash -$ act --pull=false -Pandroidndk-r17c=git.mrcyjanek.net/mrcyjanek/androidndk:r17c -``` - -For development? - -```bash -$ timeout 5 act --pull=false -Pandroidndk-r17c=git.mrcyjanek.net/mrcyjanek/androidndk:r17c # needed to clear cache. -$ act --pull=false -Pandroidndk-r17c=git.mrcyjanek.net/mrcyjanek/androidndk:r17c --reuse -$ docker ps -CONTAINER ID IMAGE ..................................... -d0626dcd8c5d git.mrcyjanek.net/mrcyjanek/androidndk:r17c .... -$ docker commit d0626dcd8c5d monero_c:dev -$ docker run --rm -it \ - -v $PWD/libbridge:/opt/wspace/libbridge_up \ - --entrypoint /bin/bash \ - monero_c:dev -[docker] $ export 'PATH=/usr/cmake-3.14.6-Linux-x86_64/bin:/opt/android/toolchain/aarch64-linux-android/bin:/opt/android/toolchain/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' \ - && cd /opt/wspace/libbridge_up \ - && rm -rf build && mkdir build && cd build \ - && env CC=clang CXX=clang++ cmake -DANDROID_ABI=-arm64-v8a .. \ - && make -# Resulting file will be available in the current directory. -``` +$ make download +$ make host_depends +$ make monero_linux_amd64 # or else, depending on your OS/arch +$ make moneroc_linux_amd64 # or else, depending on your OS/arch +``` \ No newline at end of file diff --git a/libbridge/src/main/cpp/wallet2_api_c.cpp b/libbridge/src/main/cpp/wallet2_api_c.cpp index 5659bb4..c7d1570 100644 --- a/libbridge/src/main/cpp/wallet2_api_c.cpp +++ b/libbridge/src/main/cpp/wallet2_api_c.cpp @@ -1317,6 +1317,21 @@ const char* MONERO_Wallet_getTxKey(void* wallet_ptr, const char* txid) { return buffer; } +const char* MONERO_Wallet_signMessage(void* wallet_ptr, const char* message, const char* address) { + Monero::Wallet *wallet = reinterpret_cast(wallet_ptr); + std::string str = wallet->signMessage(std::string(message), std::string(address)); + const std::string::size_type size = str.size(); + char *buffer = new char[size + 1]; //we need extra char for NUL + memcpy(buffer, str.c_str(), size + 1); + return buffer; +} + +bool MONERO_Wallet_verifySignedMessage(void* wallet_ptr, const char* message, const char* address, const char* signature) { + Monero::Wallet *wallet = reinterpret_cast(wallet_ptr); + bool v = wallet->verifySignedMessage(std::string(message), std::string(address), std::string(signature)); + return v; +} + bool MONERO_Wallet_rescanSpent(void* wallet_ptr) { Monero::Wallet *wallet = reinterpret_cast(wallet_ptr); return wallet->rescanSpent(); diff --git a/libbridge/src/main/cpp/wallet2_api_c.h b/libbridge/src/main/cpp/wallet2_api_c.h index 300d3ca..a600be7 100644 --- a/libbridge/src/main/cpp/wallet2_api_c.h +++ b/libbridge/src/main/cpp/wallet2_api_c.h @@ -757,7 +757,9 @@ const char* MONERO_Wallet_getTxKey(void* wallet_ptr, const char* txid); // virtual std::string getReserveProof(bool all, uint32_t account_index, uint64_t amount, const std::string &message) const = 0; // virtual bool checkReserveProof(const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &total, uint64_t &spent) const = 0; // virtual std::string signMessage(const std::string &message, const std::string &address = "") = 0; +const char* MONERO_Wallet_signMessage(void* wallet_ptr, const char* message, const char* address); // virtual bool verifySignedMessage(const std::string &message, const std::string &addres, const std::string &signature) const = 0; +bool MONERO_Wallet_verifySignedMessage(void* wallet_ptr, const char* message, const char* address, const char* signature); // virtual std::string signMultisigParticipant(const std::string &message) const = 0; // virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const = 0; // virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector &unknown_parameters, std::string &error) = 0;