diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 58f1cc7e..25ccccb7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -25,7 +25,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.13' - uses: actions/setup-node@v1 with: @@ -98,6 +98,23 @@ jobs: cd .. cp build_em/threshold_encryption/encrypt.* node/ + - name: Build t-encrypt Python native library + env: + OPENSSL_GIT_REF: openssl-3.0.15 + run: | + export CC=gcc-11 + export CXX=g++-11 + export TARGET=all + export CMAKE_BUILD_TYPE=Release + cd deps + ./clean.sh + ./build.sh + cd .. + mkdir -p build_t_encrypt_python + cd build_t_encrypt_python + cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo + make -j$(nproc) t_encrypt_python + - name: Calculate version run: | export BRANCH=${GITHUB_REF##*/} @@ -114,7 +131,7 @@ jobs: - name: Resolve t-encrypt version and library path run: | - lib_path="${PWD}/build/threshold_encryption/libt_encrypt_python.so" + lib_path="${PWD}/build_t_encrypt_python/threshold_encryption/libt_encrypt_python.so" echo "T_ENCRYPT_LIB_PATH=${lib_path}" >> "$GITHUB_ENV" # Calculate Python package version @@ -137,10 +154,19 @@ jobs: T_ENCRYPT_LIB_PATH: ${{ env.T_ENCRYPT_LIB_PATH }} run: | python -m pip install --upgrade pip - python -m pip install --upgrade setuptools wheel twine + python -m pip install --upgrade setuptools wheel twine auditwheel CURRENT_VERSION="$(python setup_t_encrypt.py --version)" sed -i "s/${CURRENT_VERSION}/${PACKAGE_VERSION}/g" setup_t_encrypt.py python setup_t_encrypt.py sdist bdist_wheel + wheel="$(ls -t dist/*.whl | head -n1)" + [[ "${wheel}" != *-py3-none-any.whl ]] || \ + { echo "Wheel bundling libencrypt.so must be platform-tagged: ${wheel}" >&2; exit 1; } + auditwheel show "${wheel}" + python -m zipfile -e "${wheel}" wheel-check + shared_library="wheel-check/t_encrypt/libencrypt.so" + [[ -f "${shared_library}" ]] || { echo "libencrypt.so was not found in ${wheel}" >&2; exit 1; } + ! readelf -d "${shared_library}" | grep -Eq 'lib(ssl|crypto)\.so\.1\.1' || \ + { echo "${shared_library} depends on OpenSSL 1.1" >&2; exit 1; } python -m twine check dist/* - name: Publish t-encrypt to PyPI diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4f29a3dc..f995aa77 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -196,6 +196,69 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.info + build_t_encrypt_wheel: + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.13' + - name: Build and check t-encrypt wheel + env: + CC: gcc-11 + CXX: g++-11 + OPENSSL_GIT_REF: openssl-3.0.15 + TARGET: all + run: | + sudo apt-get update + sudo apt-get install -y gcc-11 g++-11 cmake gawk sed shtool \ + libffi-dev yasm texinfo libgnutls28-dev gcc-multilib git + python -m pip install --upgrade pip setuptools wheel auditwheel + cd deps + ./build.sh + cd .. + mkdir -p build + cd build + cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo + make -j$(nproc) t_encrypt_python + cd ../python + export T_ENCRYPT_LIB_PATH="${GITHUB_WORKSPACE}/build/threshold_encryption/libt_encrypt_python.so" + python setup_t_encrypt.py bdist_wheel + wheel="$(ls -t dist/*.whl | head -n1)" + [[ "${wheel}" != *-py3-none-any.whl ]] || { echo "Wheel must be platform-tagged: ${wheel}" >&2; exit 1; } + auditwheel show "${wheel}" + python -m zipfile -e "${wheel}" wheel-check + shared_library="wheel-check/t_encrypt/libencrypt.so" + [[ -f "${shared_library}" ]] + ! readelf -d "${shared_library}" | grep -Eq 'lib(ssl|crypto)\.so\.1\.1' + - name: Upload t-encrypt wheel + uses: actions/upload-artifact@v4 + with: + name: t-encrypt-wheel + path: python/dist/*.whl + validate_t_encrypt_wheel: + needs: build_t_encrypt_wheel + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-22.04, ubuntu-24.04] + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.13' + - name: Download t-encrypt wheel + uses: actions/download-artifact@v4 + with: + name: t-encrypt-wheel + path: dist + - name: Install and import t-encrypt wheel + run: | + python -m pip install --upgrade pip + python -m pip install dist/*.whl + python -c "import t_encrypt" osx_build_and_test: runs-on: macos-15-intel steps: @@ -312,7 +375,7 @@ jobs: export LIBRARIES_ROOT=../deps/deps_inst/wasm32-emscripten/lib - emcmake cmake -DEMSCRIPTEN=ON -DBUILD_TESTS=OFF -DGMP_LIBRARY="$LIBRARIES_ROOT"/libgmp.a -DCRYPTOPP_LIBRARY="$LIBRARIES_ROOT"/libcrypto.a -DGMPXX_LIBRARY="$LIBRARIES_ROOT"/libgmpxx.a .. + emcmake cmake -DEMSCRIPTEN=ON -DBUILD_TESTS=OFF -DGMP_LIBRARY="$LIBRARIES_ROOT"/libgmp.a -DCRYPTOPP_LIBRARY="$LIBRARIES_ROOT"/libcrypto.a -DGMPXX_LIBRARY="$LIBRARIES_ROOT"/libgmpxx.a .. emmake make -j$(nproc) diff --git a/deps/build.sh b/deps/build.sh index 9ee0e0b8..55af6659 100755 --- a/deps/build.sh +++ b/deps/build.sh @@ -212,6 +212,7 @@ CXX_STANDARD=20 export CFLAGS="$CFLAGS -fPIC" export CXXFLAGS="$CXXFLAGS -fPIC" WITH_OPENSSL="yes" +OPENSSL_GIT_REF="${OPENSSL_GIT_REF:-OpenSSL_1_1_1n}" WITH_BOOST="yes" WITH_ZLIB="yes" @@ -310,7 +311,7 @@ then fi if [ -z "$ISA_NO" ]; - then + then ISA_NO="-mno-avx512f -mno-adx -mno-fma" fi fi @@ -326,7 +327,7 @@ then export CONF_CROSSCOMPILING_OPTS_VPX="" export CONF_CROSSCOMPILING_OPTS_X264="" export CONF_CROSSCOMPILING_OPTS_FFMPEG="" - + if [ "$USE_LLVM" = "1" ]; then export CC=$(which clang) @@ -595,19 +596,19 @@ then eval ./emsdk install latest eval ./emsdk activate latest source ./emsdk_env.sh - cd .. + cd .. fi if [ "$WITH_BOOST" = "yes" ]; then echo -e "${COLOR_SEPARATOR}==================== ${COLOR_PROJECT_NAME}BOOST${COLOR_SEPARATOR} ========================================${COLOR_RESET}" - + # Define Boost libraries based on build mode BOOST_LIBS_EMSCRIPTEN="program_options" BOOST_LIBS_NORMAL="system thread filesystem regex atomic context" BOOST_LIBS_SKALED="iostreams fiber log chrono date_time" - + # Build the full library list based on mode if [[ "${WITH_EMSCRIPTEN}" -eq 1 ]]; then BOOST_LIBS_TO_CHECK="$BOOST_LIBS_EMSCRIPTEN" @@ -617,7 +618,7 @@ then BOOST_LIBS_TO_CHECK="$BOOST_LIBS_TO_CHECK $BOOST_LIBS_SKALED" fi fi - + # Check if all required Boost libraries exist before skipping BOOST_CHECK_FAILED=0 for lib in $BOOST_LIBS_TO_CHECK; do @@ -626,7 +627,7 @@ then break fi done - + if [ "$BOOST_CHECK_FAILED" = "1" ]; then env_restore @@ -650,7 +651,7 @@ then fi cd ${BOOST_NAME} echo -e "${COLOR_INFO}configuring and building it${COLOR_DOTS}...${COLOR_RESET}" - + # Build BOOST_LIBRARIES string with commas for bootstrap.sh if [[ "${WITH_EMSCRIPTEN}" -eq 1 ]]; then @@ -662,7 +663,7 @@ then BOOST_LIBRARIES="${BOOST_LIBRARIES},${BOOST_LIBS_SKALED// /,}" fi fi - + eval ./bootstrap.sh --prefix="$INSTALL_ROOT" --with-libraries="$BOOST_LIBRARIES" if [ "$DEBUG" = "1" ]; then @@ -718,7 +719,7 @@ then echo -e "${COLOR_INFO}configuring it${COLOR_DOTS}...${COLOR_RESET}" cd openssl eval git fetch - eval git checkout OpenSSL_1_1_1n + git checkout --detach "$OPENSSL_GIT_REF" if [[ "$ARCH" = "x86_or_x64" || "$ARCH" = "wasm32-emscripten" ]]; then if [ "$UNIX_SYSTEM_NAME" = "Darwin" ]; @@ -929,12 +930,12 @@ if [ "$WITH_MCL" = "yes" ]; then if [ ! -f "$INSTALL_ROOT/lib/libmcl_sgx.a" ]; then echo -e "${COLOR_INFO}Building MCL for SGX...${COLOR_RESET}" cd "$SOURCES_ROOT/mcl" - + # Clean previous build artifacts "$MAKE" clean || true rm -rf "${SGX_OBJ_DIR}" "${SGX_LIB_DIR}" mkdir -p "${SGX_OBJ_DIR}" "${SGX_LIB_DIR}" - + "$MAKE" \ DEBUG=0 \ ARCH=x86_64 \ @@ -957,7 +958,7 @@ if [ "$WITH_MCL" = "yes" ]; then -Wa,--noexecstack" \ ${PARALLEL_MAKE_OPTIONS} \ "${SGX_LIB_DIR}/libmcl.a" - + cp "${SGX_LIB_DIR}/libmcl.a" "$INSTALL_ROOT/lib/libmcl_sgx.a" cd "$SOURCES_ROOT" else diff --git a/python/setup_t_encrypt.py b/python/setup_t_encrypt.py index c20525e1..da5e425b 100755 --- a/python/setup_t_encrypt.py +++ b/python/setup_t_encrypt.py @@ -5,6 +5,7 @@ import shutil from setuptools import setup, find_packages from setuptools.command.build_py import build_py +from setuptools.dist import Distribution # Configuration PACKAGE_NAME = 't_encrypt' @@ -39,9 +40,14 @@ def run(self): super().run() + +class BinaryDistribution(Distribution): + def has_ext_modules(self): + return True + setup( name='t-encrypt', - version='0.0.1', + version='0.0.2', description='Python bindings for SKALE Threshold Encryption', author='SKALE Network', packages=find_packages(), @@ -52,6 +58,7 @@ def run(self): cmdclass={ 'build_py': CustomBuildPy, }, + distclass=BinaryDistribution, classifiers=[ 'Programming Language :: Python :: 3', 'Operating System :: POSIX :: Linux',