mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 11:32:46 +01:00
Squashed 'src/dashbls/' changes from 9329803969..795660db76
795660db76 chore: bump version to 1.3.0 (#84) e8743b0139 Merge pull request #83 from UdjinM6/bp_370_371 72f0ad2d37 fix: add missing destructor for CoreMPL and final for nested classes (#371) 2f05059c60 Fix a typo in class PrivateKey testcase. (#370) 851c2c8f68 fix: reading unitialized memory from Util::HasOnlyZeros in G2Element deserialization (#77) 4dd28e9016 fix: js bindings build (#82) 3697c51521 fix: dash is no more pretending being a 'libdashbls' (#76) 37c53141d3 feat: implement memory-copy only of G1Element and G2Element (#74) 97ac99e8e6 build(bls-dash-sys): ignore wasm32 target arch (#70) 2d494d351e Merge pull request #71 from dashpay/feat/threshold_bindings 67fb70d40b chore: revert permission changes in bcce0b214876c0d9e668baaa30a48542b496cda2 5a58fce0ea fix: resolve rust-bindings compilation failure 8604e03761 build: fix cmake build error c25957edf0 Merge remote-tracking branch 'dash/develop' into feat/threshold_bindings2 198e246f07 added a helper for verifying a message a4b8a5dd6e added a helper for verifying a message 2d783c985e added a helper for signing from the private key 16f7873d6a changed to using a slice for recovery a23d9708c0 feat: clone 0cf8a8eb96 feat: serde 47829e3e75 threshold_recovery functions a5589e6fc8 fix: bls extended private key size 1ceaab56e3 [add cpp targts] 86eb28e2d7 [fix linker path for cpp] 85debcab29 [include 'src' into build] f956c66b90 [switch into cc] 9ecb59bf9b [test linker] 3651a0fd79 [linker change] d8564679eb [fix: iossim] c829d4b6f1 [fix: aarch64-apple-darwin trigger] fc3509e901 [chore: silence warning] 79ce6ded50 [feat: apple build for single platform+arch] e580cb76db [feat: build for apple target] 17b2168955 feat: verifySecure method for BasicSchemeMPL in js bindings (#69) 4613425b60 chore: silence rust warnings 136d762607 [fix: target_arch] 0d8c8e9d41 [try to use ios.toolchain] bd441623df [back] 8137f48897 [change relic src] bdcba81d41 test: check patched relic 32b7f56d94 Merge pull request #1 from dashevo/rust-bindings-enhancement 6d359c6201 chore: test for extended private key from short seed 1cbeffe159 chore: add binding dace793a1a fix: same as previous: BIP32ExtendedPrivateKeyFromSeed with len 65c84d063c fix: ok now add second blank line 24b25bac2d fix: now try from typing import Union fe16287182 fix: try Union[Fq2, None] 3ffc96d409 fix: None 2d669a2cf8 chore: up version fbb5a43b19 fix: pass length PrivateKeyFromSeedBIP32 5822076d1a chore: cargo:fmt a8d3a7e956 test: add keys multiplication test 4b85f08937 fix: exchange keys when multiply 0bcefc68cb chore: add imports 7380332123 [chore: add binding for G1ElementMul] 881e6d7676 patch relic to be compatible with wasm bcce0b2148 chore: fix mode 02801cf973 add deeper checks to example project 6d25c60ee5 compilation fixes a4cebb4025 refactor: remove "C" prefix 995ef3796f refactor: bip32 feature 7ea0c34938 style: remove `get` prefix from getters e316c00f7b add VerifySecure da5536e1c5 feat: introduce PrivateKey::from_bip32_seed 4f03a1a1ae export legacy scheme 5c19e314d4 add extended private key cc081c0956 feat: add G1 element's fingerprint and generate methods f3e85b46d0 refactor: move back re-exports e8155b4bdb refactor: move legacy code to submodule f6e173242e add extendedpublickey 4f823249fb feat: legacy serialize and deserialize methods 90fd9f9c2c fix: comparison int with size_t 57237e5e87 Merge branch 'rust-bindings' of github.com:dashevo/bls-signatures into rust-bindings a1f862480b refactor: implement Deref trait for SecureBox 0b6f94e41f add LegacySchemeMPL aa19a77a40 refactor: small refactoring dae8b31042 make schemes public 827d1ed162 add hdkeys 7b4ffae5ec improve agg sig test 18057687be add basic scheme 3e4fdda2bd aggregates 61a4d791c9 elements ser/de 8b5b6301f3 wip 126b7becea wip c49514176e chore: remove autocxx variant 477c014bb7 refactor: increase `c_err_to_result` readability 5d52d0e59d Merge remote-tracking branch 'dashevo/rust-bindings' into rust-bindings 31724b39d1 chore: add example crate c04c2941db safe wrappers for simple case 844779cd81 chore: remove cdylib from bls-signatures d622625de4 chore: move all rust stuff into one 0d3c51106a Merge remote-tracking branch 'dashevo/rust-bindings' into rust-bindings ecf0271950 revert: bring back necessary c binding files :) 20e1cfe37b wip 654fc5e6a6 chore: remove unnecessary files from c binding 92ffd63c28 refactor: cargo build script 1d4d76fb05 chore: remove wrapper.h 20cc668708 qfix abb38804c7 Merge remote-tracking branch 'dashevo/rust-bindings' into rust-bindings 760a267ab7 build: fix mac related issues 8b083794a4 add destructors to bls-dash-sys basic test 6c54f0a01a Merge remote-tracking branch 'dashevo/rust-bindings' into rust-bindings fd526ab0db build: pass gmp lib path to build.rs a8aaccb510 rust-bindings sign and verify test simple 8447c1c112 wip bindings test 9390162e3c wip add rust-bindings tests 26ab7216c0 revert: bls header path db55e40cb0 rename to sys 96188a6d52 build qfix 965ac58df4 build: automate build process part 2 05636207a0 build: automate build process part 1 73b146a961 experiment cross compiling with autocxx and bindgen 969e5e2102 experiment cross compiling with autocxx and bindgen 88ee9d0519 chore: WIP 525b4d49d9 feat: rust bindings git-subtree-dir: src/dashbls git-subtree-split: 795660db76636c92bea3bfccfee621f1aba371a3
This commit is contained in:
parent
c1992c149e
commit
730efde109
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,6 +15,7 @@ blspy.*.so
|
||||
.mypy_cache/
|
||||
.pytest_chache/
|
||||
.eggs/
|
||||
cmake-build-debug/
|
||||
|
||||
js_build
|
||||
node_modules
|
||||
@ -67,6 +68,8 @@ yarn-error.log
|
||||
.vs/
|
||||
out/
|
||||
|
||||
target
|
||||
|
||||
Makefile.in
|
||||
/ar-lib
|
||||
/mdate-sh
|
||||
|
@ -14,6 +14,7 @@ endif()
|
||||
|
||||
project(BLS)
|
||||
|
||||
set(BUILD_BLS_JS_BINDINGS "1" CACHE STRING "")
|
||||
set(BUILD_BLS_PYTHON_BINDINGS "1" CACHE STRING "")
|
||||
set(BUILD_BLS_TESTS "1" CACHE STRING "")
|
||||
set(BUILD_BLS_BENCHMARKS "1" CACHE STRING "")
|
||||
@ -110,10 +111,36 @@ set(MI_OVERRIDE "off" CACHE STRING "")
|
||||
add_subdirectory(depends/relic)
|
||||
add_subdirectory(depends/mimalloc)
|
||||
|
||||
#message(STATUS "Patching Relic to make setjmp.h inclusion conditional")
|
||||
#
|
||||
#execute_process(
|
||||
# COMMAND bash -c "git apply ${CMAKE_SOURCE_DIR}/setjmp_patch.diff"
|
||||
# WORKING_DIRECTORY ${RELIC_SRC}
|
||||
#)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
|
||||
# Write include paths for rust binding
|
||||
if(EMSCRIPTEN)
|
||||
add_subdirectory(js-bindings)
|
||||
file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/include_paths.txt" "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}/c++/v1/;")
|
||||
endif()
|
||||
|
||||
file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/include_paths.txt" "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES};")
|
||||
|
||||
if(GMP_INCLUDES)
|
||||
file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/include_paths.txt" "${GMP_INCLUDES};")
|
||||
endif()
|
||||
|
||||
# Write gmp library path for rust binding
|
||||
if(GMP_LIBRARIES)
|
||||
file(APPEND "${CMAKE_CURRENT_LIST_DIR}/build/gmp_libraries.txt" "${GMP_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
if(EMSCRIPTEN)
|
||||
if(BUILD_BLS_JS_BINDINGS)
|
||||
add_subdirectory(js-bindings)
|
||||
endif()
|
||||
else()
|
||||
# emscripten can't build python bindings, it produces only javascript
|
||||
# add_subdirectory(contrib/pybind11)
|
||||
|
373
apple.rust.deps.sh
Executable file
373
apple.rust.deps.sh
Executable file
@ -0,0 +1,373 @@
|
||||
#!/bin/sh
|
||||
set -x
|
||||
# "x86_64-apple-ios"
|
||||
# "aarch64-apple-ios"
|
||||
# "aarch64-apple-ios-sim"
|
||||
# "x86_64-apple-darwin"
|
||||
# "aarch64-apple-darwin"
|
||||
# TODO: it's probably needs to be optimized in order to increase better build velocity
|
||||
# TODO: so we need to combine multiple targets
|
||||
TARGET=$1
|
||||
git submodule update --init
|
||||
MIN_IOS="13.0"
|
||||
MIN_WATCHOS="5.0"
|
||||
MIN_TVOS=$MIN_IOS
|
||||
MIN_MACOS="10.15"
|
||||
|
||||
IPHONEOS=iphoneos
|
||||
IPHONESIMULATOR=iphonesimulator
|
||||
WATCHOS=watchos
|
||||
WATCHSIMULATOR=watchsimulator
|
||||
TVOS=appletvos
|
||||
TVSIMULATOR=appletvsimulator
|
||||
MACOS=macosx
|
||||
|
||||
LOGICALCPU_MAX=$(sysctl -n hw.logicalcpu_max)
|
||||
BUILD=build
|
||||
|
||||
version_min_flag() {
|
||||
PLATFORM=$1
|
||||
FLAG=""
|
||||
# shellcheck disable=SC2039
|
||||
# shellcheck disable=SC2053
|
||||
if [[ $PLATFORM = $IPHONEOS ]]; then
|
||||
FLAG="-miphoneos-version-min=${MIN_IOS}"
|
||||
elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then
|
||||
FLAG="-mios-simulator-version-min=${MIN_IOS}"
|
||||
elif [[ $PLATFORM = $WATCHOS ]]; then
|
||||
FLAG="-mwatchos-version-min=${MIN_WATCHOS}"
|
||||
elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then
|
||||
FLAG="-mwatchos-simulator-version-min=${MIN_WATCHOS}"
|
||||
elif [[ $PLATFORM = $TVOS ]]; then
|
||||
FLAG="-mtvos-version-min=${MIN_TVOS}"
|
||||
elif [[ $PLATFORM = $TVSIMULATOR ]]; then
|
||||
FLAG="-mtvos-simulator-version-min=${MIN_TVOS}"
|
||||
elif [[ $PLATFORM = $MACOS ]]; then
|
||||
FLAG="-mmacosx-version-min=${MIN_MACOS}"
|
||||
fi
|
||||
echo $FLAG
|
||||
}
|
||||
|
||||
|
||||
prepare() {
|
||||
download_gmp() {
|
||||
GMP_VERSION="6.2.1"
|
||||
CURRENT_DIR=$(pwd)
|
||||
echo "$CURRENT_DIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd ${BUILD}
|
||||
mkdir -p "contrib"
|
||||
if [ ! -s "contrib/gmp-${GMP_VERSION}.tar.bz2" ]; then
|
||||
curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.bz2
|
||||
fi
|
||||
rm -rf "contrib/gmp"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd contrib
|
||||
tar xfj "gmp-${GMP_VERSION}.tar.bz2"
|
||||
mv gmp-${GMP_VERSION} gmp
|
||||
rm gmp/compat.c && cp ../../contrib/gmp-patch-6.2.1/compat.c gmp/compat.c
|
||||
rm gmp/longlong.h && cp ../../contrib/gmp-patch-6.2.1/longlong.h gmp/longlong.h
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #contrib
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #build
|
||||
}
|
||||
|
||||
download_cmake_toolchain() {
|
||||
if [ ! -s "${BUILD}/ios.toolchain.cmake" ]; then
|
||||
SHA256_HASH="d02857ff6bd64f1d7109ca59c3e4f3b2f89d0663c412146e6977c679801b3243"
|
||||
curl -o "${BUILD}/ios.toolchain.cmake" https://raw.githubusercontent.com/leetal/ios-cmake/c55677a4445b138c9ef2650d3c21f22cc78c2357/ios.toolchain.cmake
|
||||
DOWNLOADED_HASH=$(shasum -a 256 ${BUILD}/ios.toolchain.cmake | cut -f 1 -d " ")
|
||||
if [ $SHA256_HASH != "$DOWNLOADED_HASH" ]; then
|
||||
echo "Error: sha256 checksum of ios.toolchain.cmake mismatch" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
download_relic() {
|
||||
CURRENT_DIR=$(pwd)
|
||||
echo "$CURRENT_DIR"
|
||||
mkdir -p "${CURRENT_DIR}/${BUILD}/contrib"
|
||||
if [ ! -s "${CURRENT_DIR}/${BUILD}/contrib/relic" ]; then
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd "${CURRENT_DIR}/${BUILD}/contrib"
|
||||
git clone --depth 1 --branch "feat/ios-support" https://github.com/pankcuf/relic
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd relic
|
||||
git fetch --depth 1 origin 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae
|
||||
git checkout 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #relic
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #contrib
|
||||
fi
|
||||
}
|
||||
rm -rf ${BUILD}
|
||||
mkdir -p ${BUILD}
|
||||
download_relic
|
||||
download_gmp
|
||||
download_cmake_toolchain
|
||||
}
|
||||
|
||||
build_gmp_arch() {
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
PFX=${PLATFORM}-${ARCH}
|
||||
# why this works with this host only?
|
||||
HOST=arm-apple-darwin
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd ${BUILD}
|
||||
SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path)
|
||||
PLATFORM_PATH=$(xcrun --sdk "$PLATFORM" --show-sdk-platform-path)
|
||||
CLANG=$(xcrun --sdk "$PLATFORM" --find clang)
|
||||
DEVELOPER=$(xcode-select --print-path)
|
||||
CURRENT_DIR=$(pwd)
|
||||
export PATH="${PLATFORM_PATH}/Developer/usr/bin:${DEVELOPER}/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin"
|
||||
mkdir gmplib-"${PLATFORM}"-"${ARCH}"
|
||||
CFLAGS="-Wno-unused-value -fembed-bitcode -arch ${ARCH} --sysroot=${SDK} $(version_min_flag "$PLATFORM")"
|
||||
CONFIGURESCRIPT="gmp_configure_script.sh"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd contrib
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd gmp
|
||||
make clean || true
|
||||
make distclean || true
|
||||
echo "HOST: $HOST"
|
||||
echo "PREFIX: ${CURRENT_DIR}/gmplib-${PFX}"
|
||||
|
||||
cat >"$CONFIGURESCRIPT" << EOF
|
||||
#!/bin/sh
|
||||
./configure \
|
||||
CC="$CLANG" CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" \
|
||||
--host=${HOST} --prefix="${CURRENT_DIR}/gmplib-${PFX}" \
|
||||
--disable-shared --enable-static --disable-assembly -v
|
||||
EOF
|
||||
|
||||
chmod a+x "$CONFIGURESCRIPT"
|
||||
sh "$CONFIGURESCRIPT"
|
||||
rm "$CONFIGURESCRIPT"
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
mkdir -p "${CURRENT_DIR}/log"
|
||||
# shellcheck disable=SC2039
|
||||
make -j "$LOGICALCPU_MAX" &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-build.log
|
||||
# shellcheck disable=SC2039
|
||||
make install &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-install.log
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # gmp
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # contrib
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # build
|
||||
}
|
||||
|
||||
build_relic_arch() {
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
PFX=${PLATFORM}-${ARCH}
|
||||
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd ${BUILD}
|
||||
|
||||
SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path)
|
||||
|
||||
BUILDDIR=relic-"${PFX}"
|
||||
TOOLCHAIN=$(pwd)/ios.toolchain.cmake
|
||||
GMP_PFX=$(pwd)/gmplib-${PFX}
|
||||
rm -rf "$BUILDDIR"
|
||||
mkdir "$BUILDDIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd "$BUILDDIR"
|
||||
|
||||
unset CC
|
||||
# shellcheck disable=SC2155
|
||||
export CC=$(xcrun --sdk "${PLATFORM}" --find clang)
|
||||
|
||||
WSIZE=0
|
||||
IOS_PLATFORM=""
|
||||
OPTIMIZATIONFLAGS=""
|
||||
DEPLOYMENT_TARGET=""
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
# shellcheck disable=SC2053
|
||||
if [[ $PLATFORM = $IPHONEOS ]]; then
|
||||
if [[ $ARCH = "arm64" ]] || [[ $ARCH = "arm64e" ]]; then
|
||||
IOS_PLATFORM=OS64
|
||||
DEPLOYMENT_TARGET=$MIN_IOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
else
|
||||
IOS_PLATFORM=OS
|
||||
WSIZE=32
|
||||
fi
|
||||
elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then
|
||||
if [[ $ARCH = "x86_64" ]]; then
|
||||
IOS_PLATFORM=SIMULATOR64
|
||||
DEPLOYMENT_TARGET=$MIN_IOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
elif [[ $ARCH = "arm64" ]]; then
|
||||
IOS_PLATFORM=SIMULATORARM64
|
||||
DEPLOYMENT_TARGET=$MIN_IOS
|
||||
WSIZE=64
|
||||
else
|
||||
IOS_PLATFORM=SIMULATOR
|
||||
WSIZE=32
|
||||
fi
|
||||
elif [[ $PLATFORM = $WATCHOS ]]; then
|
||||
IOS_PLATFORM=WATCHOS
|
||||
DEPLOYMENT_TARGET=$MIN_WATCHOS
|
||||
WSIZE=32
|
||||
elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then
|
||||
IOS_PLATFORM=SIMULATOR_WATCHOS
|
||||
DEPLOYMENT_TARGET=$MIN_WATCHOS
|
||||
WSIZE=32
|
||||
elif [[ $PLATFORM = $TVOS ]]; then
|
||||
IOS_PLATFORM=TVOS
|
||||
DEPLOYMENT_TARGET=$MIN_TVOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
elif [[ $PLATFORM = $TVSIMULATOR ]]; then
|
||||
IOS_PLATFORM=SIMULATOR_TVOS
|
||||
#TODO
|
||||
if [[ $ARCH = "arm64" ]]
|
||||
then
|
||||
IOS_PLATFORM=OS64
|
||||
fi
|
||||
DEPLOYMENT_TARGET=$MIN_TVOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
elif [[ $PLATFORM = $MACOS ]]; then
|
||||
WSIZE=64
|
||||
IOS_PLATFORM=MAC
|
||||
if [[ $ARCH = "arm64" ]]
|
||||
then
|
||||
IOS_PLATFORM=MAC_ARM64
|
||||
fi
|
||||
DEPLOYMENT_TARGET=$MIN_MACOS
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
fi
|
||||
|
||||
COMPILER_ARGS="$(version_min_flag "$PLATFORM") -Wno-unused-functions"
|
||||
|
||||
EXTRA_ARGS="-DOPSYS=NONE -DPLATFORM=$IOS_PLATFORM -DDEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN"
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
if [[ $ARCH = "i386" ]]; then
|
||||
EXTRA_ARGS+=" -DARCH=X86"
|
||||
elif [[ $ARCH = "x86_64" ]]; then
|
||||
EXTRA_ARGS+=" -DARCH=X64"
|
||||
else
|
||||
EXTRA_ARGS+=" -DARCH=ARM"
|
||||
if [[ $ARCH = "armv7s" ]]; then
|
||||
EXTRA_ARGS+=" -DIOS_ARCH=armv7s"
|
||||
elif [[ $ARCH = "armv7k" ]]; then
|
||||
EXTRA_ARGS+=" -DIOS_ARCH=armv7k"
|
||||
elif [[ $ARCH = "arm64_32" ]]; then
|
||||
EXTRA_ARGS+=" -DIOS_ARCH=arm64_32"
|
||||
fi
|
||||
fi
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
cmake -DCMAKE_PREFIX_PATH:PATH="${GMP_PFX}" -DTESTS=0 -DBENCH=0 -DBUILD_BLS_JS_BINDINGS=0 -DBUILD_BLS_PYTHON_BINDINGS=0 \
|
||||
-DBUILD_BLS_BENCHMARKS=0 -DBUILD_BLS_TESTS=0 -DCHECK=off -DARITH=gmp -DTIMER=HPROC -DFP_PRIME=381 -DMULTI=PTHREAD \
|
||||
-DFP_QNRES=on -DFP_METHD="INTEG;INTEG;INTEG;MONTY;EXGCD;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" \
|
||||
-DCOMP_FLAGS="-pipe -std=c99 -O3 -funroll-loops $OPTIMIZATIONFLAGS -isysroot $SDK -arch $ARCH -fembed-bitcode ${COMPILER_ARGS}" \
|
||||
-DWSIZE=$WSIZE -DVERBS=off -DSHLIB=off -DALLOC="AUTO" -DEP_PLAIN=off -DEP_SUPER=off -DPP_EXT="LAZYR" \
|
||||
-DWITH="DV;BN;MD;FP;EP;FPX;EPX;PP;PC;CP" -DBN_METHD="COMBA;COMBA;MONTY;SLIDE;STEIN;BASIC" ${EXTRA_ARGS} ../../
|
||||
|
||||
make -j "$LOGICALCPU_MAX"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # "$BUILDDIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # contrib/relic
|
||||
}
|
||||
|
||||
build_bls_arch() {
|
||||
# shellcheck disable=SC2039
|
||||
BLS_FILES=( "bls" "chaincode" "elements" "extendedprivatekey" "extendedpublickey" "legacy" "privatekey" "schemes" "threshold" )
|
||||
# shellcheck disable=SC2039
|
||||
ALL_BLS_OBJ_FILES=$(printf "%s.o " "${BLS_FILES[@]}")
|
||||
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
PFX=${PLATFORM}-${ARCH}
|
||||
SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path)
|
||||
|
||||
BUILDDIR=${BUILD}/bls-"${PFX}"
|
||||
rm -rf "$BUILDDIR"
|
||||
mkdir "$BUILDDIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd "$BUILDDIR"
|
||||
|
||||
EXTRA_ARGS="$(version_min_flag "$PLATFORM")"
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
for F in "${BLS_FILES[@]}"
|
||||
do
|
||||
clang -I"../contrib/relic/include" \
|
||||
-I"../../depends/relic/include" \
|
||||
-I"../../include/dashbls" \
|
||||
-I"../relic-${PFX}/_deps/relic-build/include" \
|
||||
-I"../../src/" \
|
||||
-I"../gmplib-${PFX}/include" \
|
||||
-x c++ -std=c++14 -stdlib=libc++ -fembed-bitcode -arch "${ARCH}" -isysroot "${SDK}" "${EXTRA_ARGS}" \
|
||||
-c "../../src/${F}.cpp" -o "${F}.o"
|
||||
done
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
xcrun -sdk "$PLATFORM" ar -cvq libbls.a $ALL_BLS_OBJ_FILES
|
||||
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # "$BUILDDIR"
|
||||
}
|
||||
|
||||
build_all_arch() {
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
build_gmp_arch "$PLATFORM" "$ARCH"
|
||||
build_relic_arch "$PLATFORM" "$ARCH"
|
||||
build_bls_arch "$PLATFORM" "$ARCH"
|
||||
}
|
||||
|
||||
build_target() {
|
||||
BUILD_IN=$1
|
||||
echo "Build target: $BUILD_IN"
|
||||
ARCH=""
|
||||
PLATFORM=""
|
||||
# shellcheck disable=SC2039
|
||||
if [[ $BUILD_IN = "x86_64-apple-ios" ]]; then
|
||||
ARCH=x86_64
|
||||
PLATFORM=$IPHONESIMULATOR
|
||||
elif [[ $BUILD_IN = "aarch64-apple-ios" ]]; then
|
||||
ARCH=arm64
|
||||
PLATFORM=$IPHONEOS
|
||||
elif [[ $BUILD_IN = "aarch64-apple-ios-sim" ]]; then
|
||||
ARCH=arm64
|
||||
PLATFORM=$IPHONESIMULATOR
|
||||
elif [[ $BUILD_IN = "x86_64-apple-darwin" ]]; then
|
||||
ARCH=x86_64
|
||||
PLATFORM=$MACOS
|
||||
elif [[ $BUILD_IN = "aarch64-apple-darwin" ]]; then
|
||||
ARCH=arm64
|
||||
PLATFORM=$MACOS
|
||||
fi
|
||||
build_all_arch "$PLATFORM" "$ARCH"
|
||||
PFX="${PLATFORM}"-"${ARCH}"
|
||||
rm -rf "build/artefacts/${BUILD_IN}"
|
||||
mkdir -p "build/artefacts/${BUILD_IN}"
|
||||
cp "build/gmplib-${PFX}/lib/libgmp.a" "build/artefacts/${BUILD_IN}"
|
||||
cp "build/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" "build/artefacts/${BUILD_IN}"
|
||||
cp "build/relic-${PFX}/_deps/sodium-build/libsodium.a" "build/artefacts/${BUILD_IN}"
|
||||
cp "build/bls-${PFX}/libbls.a" "build/artefacts/${BUILD_IN}"
|
||||
# cp -rf build/bls-"${PFX}"/*.o build/artefacts/"${BUILD_IN}"/include
|
||||
# cp -rf src/*.hpp build/artefacts/"${BUILD_IN}"/include
|
||||
# cp -rf build/gmplib-"${PFX}"/include/gmp.h build/artefacts/"${BUILD_IN}"/include
|
||||
# cp -rf build/relic-"${PFX}"/_deps/relic-build/include/*.h build/artefacts/"${BUILD_IN}"/include
|
||||
}
|
||||
|
||||
prepare
|
||||
build_target "$TARGET"
|
458
apple.rust.sh
Executable file
458
apple.rust.sh
Executable file
@ -0,0 +1,458 @@
|
||||
#!/bin/sh
|
||||
set -x
|
||||
|
||||
git submodule update --init
|
||||
|
||||
MIN_IOS="13.0"
|
||||
MIN_WATCHOS="5.0"
|
||||
MIN_TVOS=$MIN_IOS
|
||||
MIN_MACOS="10.15"
|
||||
|
||||
IPHONEOS=iphoneos
|
||||
IPHONESIMULATOR=iphonesimulator
|
||||
WATCHOS=watchos
|
||||
WATCHSIMULATOR=watchsimulator
|
||||
TVOS=appletvos
|
||||
TVSIMULATOR=appletvsimulator
|
||||
MACOS=macosx
|
||||
|
||||
LOGICALCPU_MAX=$(sysctl -n hw.logicalcpu_max)
|
||||
BUILD=build
|
||||
|
||||
version_min_flag() {
|
||||
PLATFORM=$1
|
||||
FLAG=""
|
||||
# shellcheck disable=SC2039
|
||||
# shellcheck disable=SC2053
|
||||
if [[ $PLATFORM = $IPHONEOS ]]; then
|
||||
FLAG="-miphoneos-version-min=${MIN_IOS}"
|
||||
elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then
|
||||
FLAG="-mios-simulator-version-min=${MIN_IOS}"
|
||||
elif [[ $PLATFORM = $WATCHOS ]]; then
|
||||
FLAG="-mwatchos-version-min=${MIN_WATCHOS}"
|
||||
elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then
|
||||
FLAG="-mwatchos-simulator-version-min=${MIN_WATCHOS}"
|
||||
elif [[ $PLATFORM = $TVOS ]]; then
|
||||
FLAG="-mtvos-version-min=${MIN_TVOS}"
|
||||
elif [[ $PLATFORM = $TVSIMULATOR ]]; then
|
||||
FLAG="-mtvos-simulator-version-min=${MIN_TVOS}"
|
||||
elif [[ $PLATFORM = $MACOS ]]; then
|
||||
FLAG="-mmacosx-version-min=${MIN_MACOS}"
|
||||
fi
|
||||
echo $FLAG
|
||||
}
|
||||
|
||||
|
||||
prepare() {
|
||||
download_gmp() {
|
||||
GMP_VERSION="6.2.1"
|
||||
CURRENT_DIR=$(pwd)
|
||||
echo "$CURRENT_DIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd ${BUILD}
|
||||
mkdir -p "contrib"
|
||||
if [ ! -s "contrib/gmp-${GMP_VERSION}.tar.bz2" ]; then
|
||||
curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.bz2
|
||||
fi
|
||||
rm -rf "contrib/gmp"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd contrib
|
||||
tar xfj "gmp-${GMP_VERSION}.tar.bz2"
|
||||
mv gmp-${GMP_VERSION} gmp
|
||||
rm gmp/compat.c && cp ../../contrib/gmp-patch-6.2.1/compat.c gmp/compat.c
|
||||
rm gmp/longlong.h && cp ../../contrib/gmp-patch-6.2.1/longlong.h gmp/longlong.h
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #contrib
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #build
|
||||
}
|
||||
|
||||
download_cmake_toolchain() {
|
||||
if [ ! -s "${BUILD}/ios.toolchain.cmake" ]; then
|
||||
SHA256_HASH="d02857ff6bd64f1d7109ca59c3e4f3b2f89d0663c412146e6977c679801b3243"
|
||||
curl -o "${BUILD}/ios.toolchain.cmake" https://raw.githubusercontent.com/leetal/ios-cmake/c55677a4445b138c9ef2650d3c21f22cc78c2357/ios.toolchain.cmake
|
||||
DOWNLOADED_HASH=$(shasum -a 256 ${BUILD}/ios.toolchain.cmake | cut -f 1 -d " ")
|
||||
if [ $SHA256_HASH != "$DOWNLOADED_HASH" ]; then
|
||||
echo "Error: sha256 checksum of ios.toolchain.cmake mismatch" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
download_relic() {
|
||||
CURRENT_DIR=$(pwd)
|
||||
echo "$CURRENT_DIR"
|
||||
mkdir -p "${CURRENT_DIR}/${BUILD}/contrib"
|
||||
if [ ! -s "${CURRENT_DIR}/${BUILD}/contrib/relic" ]; then
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd "${CURRENT_DIR}/${BUILD}/contrib"
|
||||
git clone --depth 1 --branch "feat/ios-support" https://github.com/pankcuf/relic
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd relic
|
||||
git fetch --depth 1 origin 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae
|
||||
git checkout 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #relic
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #contrib
|
||||
fi
|
||||
}
|
||||
rm -rf ${BUILD}
|
||||
mkdir -p ${BUILD}
|
||||
download_relic
|
||||
download_gmp
|
||||
download_cmake_toolchain
|
||||
mkdir -p ${BUILD}/artefacts/include
|
||||
}
|
||||
|
||||
build_gmp_arch() {
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
PFX=${PLATFORM}-${ARCH}
|
||||
# why this works with this host only?
|
||||
HOST=arm-apple-darwin
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd ${BUILD}
|
||||
SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path)
|
||||
PLATFORM_PATH=$(xcrun --sdk "$PLATFORM" --show-sdk-platform-path)
|
||||
CLANG=$(xcrun --sdk "$PLATFORM" --find clang)
|
||||
DEVELOPER=$(xcode-select --print-path)
|
||||
CURRENT_DIR=$(pwd)
|
||||
export PATH="${PLATFORM_PATH}/Developer/usr/bin:${DEVELOPER}/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin"
|
||||
mkdir gmplib-"${PLATFORM}"-"${ARCH}"
|
||||
CFLAGS="-Wno-unused-value -fembed-bitcode -arch ${ARCH} --sysroot=${SDK} $(version_min_flag "$PLATFORM")"
|
||||
CONFIGURESCRIPT="gmp_configure_script.sh"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd contrib
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd gmp
|
||||
make clean || true
|
||||
make distclean || true
|
||||
echo "HOST: $HOST"
|
||||
echo "PREFIX: ${CURRENT_DIR}/gmplib-${PFX}"
|
||||
|
||||
cat >"$CONFIGURESCRIPT" << EOF
|
||||
#!/bin/sh
|
||||
./configure \
|
||||
CC="$CLANG" CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" \
|
||||
--host=${HOST} --prefix="${CURRENT_DIR}/gmplib-${PFX}" \
|
||||
--disable-shared --enable-static --disable-assembly -v
|
||||
EOF
|
||||
|
||||
chmod a+x "$CONFIGURESCRIPT"
|
||||
sh "$CONFIGURESCRIPT"
|
||||
rm "$CONFIGURESCRIPT"
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
mkdir -p "${CURRENT_DIR}/log"
|
||||
# shellcheck disable=SC2039
|
||||
make -j "$LOGICALCPU_MAX" &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-build.log
|
||||
# shellcheck disable=SC2039
|
||||
make install &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-install.log
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # gmp
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # contrib
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # build
|
||||
}
|
||||
|
||||
build_relic_arch() {
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
PFX=${PLATFORM}-${ARCH}
|
||||
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd ${BUILD}
|
||||
|
||||
SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path)
|
||||
|
||||
BUILDDIR=relic-"${PFX}"
|
||||
TOOLCHAIN=$(pwd)/ios.toolchain.cmake
|
||||
GMP_PFX=$(pwd)/gmplib-${PFX}
|
||||
rm -rf "$BUILDDIR"
|
||||
mkdir "$BUILDDIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd "$BUILDDIR"
|
||||
|
||||
unset CC
|
||||
# shellcheck disable=SC2155
|
||||
export CC=$(xcrun --sdk "${PLATFORM}" --find clang)
|
||||
|
||||
WSIZE=0
|
||||
IOS_PLATFORM=""
|
||||
OPTIMIZATIONFLAGS=""
|
||||
DEPLOYMENT_TARGET=""
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
# shellcheck disable=SC2053
|
||||
if [[ $PLATFORM = $IPHONEOS ]]; then
|
||||
if [[ $ARCH = "arm64" ]] || [[ $ARCH = "arm64e" ]]; then
|
||||
IOS_PLATFORM=OS64
|
||||
DEPLOYMENT_TARGET=$MIN_IOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
else
|
||||
IOS_PLATFORM=OS
|
||||
WSIZE=32
|
||||
fi
|
||||
elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then
|
||||
if [[ $ARCH = "x86_64" ]]; then
|
||||
IOS_PLATFORM=SIMULATOR64
|
||||
DEPLOYMENT_TARGET=$MIN_IOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
elif [[ $ARCH = "arm64" ]]; then
|
||||
IOS_PLATFORM=SIMULATORARM64
|
||||
DEPLOYMENT_TARGET=$MIN_IOS
|
||||
WSIZE=64
|
||||
else
|
||||
IOS_PLATFORM=SIMULATOR
|
||||
WSIZE=32
|
||||
fi
|
||||
elif [[ $PLATFORM = $WATCHOS ]]; then
|
||||
IOS_PLATFORM=WATCHOS
|
||||
DEPLOYMENT_TARGET=$MIN_WATCHOS
|
||||
WSIZE=32
|
||||
elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then
|
||||
IOS_PLATFORM=SIMULATOR_WATCHOS
|
||||
DEPLOYMENT_TARGET=$MIN_WATCHOS
|
||||
WSIZE=32
|
||||
elif [[ $PLATFORM = $TVOS ]]; then
|
||||
IOS_PLATFORM=TVOS
|
||||
DEPLOYMENT_TARGET=$MIN_TVOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
elif [[ $PLATFORM = $TVSIMULATOR ]]; then
|
||||
IOS_PLATFORM=SIMULATOR_TVOS
|
||||
#TODO
|
||||
if [[ $ARCH = "arm64" ]]
|
||||
then
|
||||
IOS_PLATFORM=OS64
|
||||
fi
|
||||
DEPLOYMENT_TARGET=$MIN_TVOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
elif [[ $PLATFORM = $MACOS ]]; then
|
||||
WSIZE=64
|
||||
IOS_PLATFORM=MAC
|
||||
if [[ $ARCH = "arm64" ]]
|
||||
then
|
||||
IOS_PLATFORM=MAC_ARM64
|
||||
fi
|
||||
DEPLOYMENT_TARGET=$MIN_MACOS
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
fi
|
||||
|
||||
COMPILER_ARGS="$(version_min_flag "$PLATFORM") -Wno-unused-functions"
|
||||
|
||||
EXTRA_ARGS="-DOPSYS=NONE -DPLATFORM=$IOS_PLATFORM -DDEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN"
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
if [[ $ARCH = "i386" ]]; then
|
||||
EXTRA_ARGS+=" -DARCH=X86"
|
||||
elif [[ $ARCH = "x86_64" ]]; then
|
||||
EXTRA_ARGS+=" -DARCH=X64"
|
||||
else
|
||||
EXTRA_ARGS+=" -DARCH=ARM"
|
||||
if [[ $ARCH = "armv7s" ]]; then
|
||||
EXTRA_ARGS+=" -DIOS_ARCH=armv7s"
|
||||
elif [[ $ARCH = "armv7k" ]]; then
|
||||
EXTRA_ARGS+=" -DIOS_ARCH=armv7k"
|
||||
elif [[ $ARCH = "arm64_32" ]]; then
|
||||
EXTRA_ARGS+=" -DIOS_ARCH=arm64_32"
|
||||
fi
|
||||
fi
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
cmake -DCMAKE_PREFIX_PATH:PATH="${GMP_PFX}" -DTESTS=0 -DBENCH=0 -DBUILD_BLS_JS_BINDINGS=0 -DBUILD_BLS_PYTHON_BINDINGS=0 \
|
||||
-DBUILD_BLS_BENCHMARKS=0 -DBUILD_BLS_TESTS=0 -DCHECK=off -DARITH=gmp -DTIMER=HPROC -DFP_PRIME=381 -DMULTI=PTHREAD \
|
||||
-DFP_QNRES=on -DFP_METHD="INTEG;INTEG;INTEG;MONTY;EXGCD;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" \
|
||||
-DCOMP_FLAGS="-pipe -std=c99 -O3 -funroll-loops $OPTIMIZATIONFLAGS -isysroot $SDK -arch $ARCH -fembed-bitcode ${COMPILER_ARGS}" \
|
||||
-DWSIZE=$WSIZE -DVERBS=off -DSHLIB=off -DALLOC="AUTO" -DEP_PLAIN=off -DEP_SUPER=off -DPP_EXT="LAZYR" \
|
||||
-DWITH="DV;BN;MD;FP;EP;FPX;EPX;PP;PC;CP" -DBN_METHD="COMBA;COMBA;MONTY;SLIDE;STEIN;BASIC" ${EXTRA_ARGS} ../../
|
||||
|
||||
make -j "$LOGICALCPU_MAX"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # "$BUILDDIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # contrib/relic
|
||||
}
|
||||
|
||||
build_bls_arch() {
|
||||
# shellcheck disable=SC2039
|
||||
BLS_FILES=( "bls" "chaincode" "elements" "extendedprivatekey" "extendedpublickey" "legacy" "privatekey" "schemes" "threshold" )
|
||||
# shellcheck disable=SC2039
|
||||
ALL_BLS_OBJ_FILES=$(printf "%s.o " "${BLS_FILES[@]}")
|
||||
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
PFX=${PLATFORM}-${ARCH}
|
||||
SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path)
|
||||
|
||||
BUILDDIR=${BUILD}/bls-"${PFX}"
|
||||
rm -rf "$BUILDDIR"
|
||||
mkdir "$BUILDDIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd "$BUILDDIR"
|
||||
|
||||
EXTRA_ARGS="$(version_min_flag "$PLATFORM")"
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
for F in "${BLS_FILES[@]}"
|
||||
do
|
||||
clang -I"../contrib/relic/include" \
|
||||
-I"../relic-${PFX}/_deps/relic-build/include" \
|
||||
-I"../../src/" \
|
||||
-I"../gmplib-${PFX}/include" \
|
||||
-x c++ -std=c++14 -stdlib=libc++ -fembed-bitcode -arch "${ARCH}" -isysroot "${SDK}" "${EXTRA_ARGS}" \
|
||||
-c "../../src/${F}.cpp" -o "${F}.o"
|
||||
done
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
xcrun -sdk "$PLATFORM" ar -cvq libbls.a $ALL_BLS_OBJ_FILES
|
||||
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # "$BUILDDIR"
|
||||
}
|
||||
|
||||
build_all_arch() {
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
build_gmp_arch "$PLATFORM" "$ARCH"
|
||||
build_relic_arch "$PLATFORM" "$ARCH"
|
||||
build_bls_arch "$PLATFORM" "$ARCH"
|
||||
}
|
||||
|
||||
build_all() {
|
||||
BUILD_IN=$1
|
||||
TARGET_DIR=build/artefacts
|
||||
# shellcheck disable=SC2039
|
||||
IFS='|' read -ra BUILD_PAIRS <<< "$BUILD_IN"
|
||||
# shellcheck disable=SC2039
|
||||
for BUILD_PAIR in "${BUILD_PAIRS[@]}"
|
||||
do
|
||||
# shellcheck disable=SC2039
|
||||
IFS=';' read -ra PARSED_PAIR <<< "$BUILD_PAIR"
|
||||
# shellcheck disable=SC2039
|
||||
PLATFORM=${PARSED_PAIR[0]}
|
||||
# shellcheck disable=SC2039
|
||||
ARCH=${PARSED_PAIR[1]}
|
||||
|
||||
GMP_LIPOARGS=""
|
||||
RELIC_LIPOARGS=""
|
||||
BLS_LIPOARGS=""
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
local NEED_LIPO=0
|
||||
# shellcheck disable=SC2039
|
||||
IFS='+' read -ra ARCHS <<< "$ARCH"
|
||||
# shellcheck disable=SC2039
|
||||
for i in "${!ARCHS[@]}"
|
||||
do
|
||||
# shellcheck disable=SC2039
|
||||
local SINGLEARCH=${ARCHS[i]}
|
||||
|
||||
# build for every platform+arch
|
||||
build_all_arch "$PLATFORM" "$SINGLEARCH"
|
||||
|
||||
PFX="${PLATFORM}"-"${SINGLEARCH}"
|
||||
ARCH_TARGET_DIR=${TARGET_DIR}/${PFX}
|
||||
rm -rf "${ARCH_TARGET_DIR}"
|
||||
mkdir -p "${ARCH_TARGET_DIR}"
|
||||
#mv "${BUILD}/gmplib-${PFX}/lib/libgmp.a" "${ARCH_TARGET_DIR}/libgmp.a"
|
||||
#mv "${BUILD}/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" "${ARCH_TARGET_DIR}/librelic.a"
|
||||
#mv "${BUILD}/bls-${PFX}/libbls.a" "${ARCH_TARGET_DIR}/libbls.a"
|
||||
|
||||
libtool -static -o "${ARCH_TARGET_DIR}/libbls.a" \
|
||||
"${BUILD}/gmplib-${PFX}/lib/libgmp.a" \
|
||||
"${BUILD}/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" \
|
||||
"${BUILD}/bls-${PFX}/libbls.a"
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
GMP_LIPOARGS+="${ARCH_TARGET_DIR}/libgmp.a "
|
||||
# shellcheck disable=SC2039
|
||||
RELIC_LIPOARGS+="${ARCH_TARGET_DIR}/librelic.a "
|
||||
# shellcheck disable=SC2039
|
||||
BLS_LIPOARGS+="${ARCH_TARGET_DIR}/libbls.a "
|
||||
|
||||
NEED_LIPO=i
|
||||
done
|
||||
|
||||
# Do lipo if we need https://developer.apple.com/forums/thread/666335?answerId=645963022#645963022
|
||||
# if [[ $NEED_LIPO -gt 0 ]]
|
||||
# then
|
||||
# FAT_TARGET_DIR=${TARGET_DIR}/${PLATFORM}-fat
|
||||
# rm -rf "${FAT_TARGET_DIR}"
|
||||
# mkdir -p "${FAT_TARGET_DIR}"
|
||||
# # shellcheck disable=SC2086
|
||||
# xcrun lipo $GMP_LIPOARGS -create -output "${FAT_TARGET_DIR}/libgmp.a"
|
||||
# # shellcheck disable=SC2086
|
||||
# xcrun lipo $RELIC_LIPOARGS -create -output "${FAT_TARGET_DIR}/librelic.a"
|
||||
# # shellcheck disable=SC2086
|
||||
# xcrun lipo $BLS_LIPOARGS -create -output "${FAT_TARGET_DIR}/libbls.a"
|
||||
# libtool -static -o "${FAT_TARGET_DIR}/libbls_combined.a" "${FAT_TARGET_DIR}/libgmp.a" "${FAT_TARGET_DIR}/librelic.a" "${FAT_TARGET_DIR}/libbls.a"
|
||||
# rm "${FAT_TARGET_DIR}/libgmp.a"
|
||||
# rm "${FAT_TARGET_DIR}/librelic.a"
|
||||
# rm "${FAT_TARGET_DIR}/libbls.a"
|
||||
# mv "${FAT_TARGET_DIR}/libbls_combined.a" "${FAT_TARGET_DIR}/libbls.a"
|
||||
# # clean up
|
||||
# # shellcheck disable=SC2039
|
||||
# for i in "${!ARCHS[@]}"
|
||||
# do
|
||||
# local SINGLEARCH=${ARCHS[i]}
|
||||
# rm -rf "${TARGET_DIR}-${SINGLEARCH}"
|
||||
# done
|
||||
# fi
|
||||
done
|
||||
}
|
||||
|
||||
#make_relic_headers_universal() {
|
||||
# RELIC_TARGET_DIR=relic-iphoneos-arm64
|
||||
# perl -p -e 's/#define WSIZE.*/#ifdef __LP64__\n#define WSIZE 64\n#else\n#define WSIZE 32\n#endif/' \
|
||||
# "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" \
|
||||
# > "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new"
|
||||
#
|
||||
# rm "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h"
|
||||
# mv "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h"
|
||||
#}
|
||||
|
||||
#copy_headers() {
|
||||
# mkdir build/artefacts/include
|
||||
# # Copy all headers we will need
|
||||
# cp -rf src/*.hpp build/artefacts/include
|
||||
# cp -rf build/gmp/include/gmp.h build/artefacts/include
|
||||
# cp -rf build/contrib/relic/include/*.h build/artefacts/include
|
||||
# cp -rf build/contrib/relic/include/low/*.h build/artefacts/include
|
||||
# cp -rf build/contrib/relic/relic-iphoneos-arm64/include/*.h build/artefacts/include
|
||||
# rm -rf build/artefacts/include/test-utils.hpp
|
||||
#}
|
||||
|
||||
#function make_fat_binary()
|
||||
#{
|
||||
# pushd artefacts
|
||||
#
|
||||
# XCFRAMEWORK_ARGS=""
|
||||
#
|
||||
# for dir in */; do
|
||||
# if [ -d "$dir" ]; then
|
||||
# if [[ "$dir" != "include/" ]]; then
|
||||
# libtool -static -o "${dir}libbls_combined.a" "${dir}libgmp.a" "${dir}librelic.a" "${dir}libbls.a"
|
||||
#
|
||||
# XCFRAMEWORK_ARGS+="-library ${dir}libbls_combined.a -headers include "
|
||||
# fi
|
||||
# fi
|
||||
# done
|
||||
#
|
||||
# #xcodebuild -create-xcframework $XCFRAMEWORK_ARGS -output "libbls.xcframework"
|
||||
#}
|
||||
|
||||
prepare
|
||||
build_all "${MACOS};x86_64+arm64"
|
||||
build_all "${IPHONEOS};arm64|${IPHONESIMULATOR};arm64+x86_64"
|
||||
|
||||
#make_relic_headers_universal
|
||||
#copy_headers
|
||||
#make_fat_binary
|
404
apple.rust.single.sh
Executable file
404
apple.rust.single.sh
Executable file
@ -0,0 +1,404 @@
|
||||
#!/bin/sh
|
||||
set -x
|
||||
# "x86_64-apple-ios"
|
||||
# "x86_64-apple-ios-sim"
|
||||
# "aarch64-apple-ios"
|
||||
# "aarch64-apple-ios-sim"
|
||||
# "x86_64-apple-darwin"
|
||||
# "aarch64-apple-darwin"
|
||||
# TODO: it's probably needs to be optimized in order to increase better build velocity
|
||||
# TODO: so we need to combine multiple targets
|
||||
TARGET=$1
|
||||
git submodule update --init
|
||||
MIN_IOS="13.0"
|
||||
MIN_WATCHOS="5.0"
|
||||
MIN_TVOS=$MIN_IOS
|
||||
MIN_MACOS="10.15"
|
||||
|
||||
IPHONEOS=iphoneos
|
||||
IPHONESIMULATOR=iphonesimulator
|
||||
WATCHOS=watchos
|
||||
WATCHSIMULATOR=watchsimulator
|
||||
TVOS=appletvos
|
||||
TVSIMULATOR=appletvsimulator
|
||||
MACOS=macosx
|
||||
|
||||
LOGICALCPU_MAX=$(sysctl -n hw.logicalcpu_max)
|
||||
BUILD=build
|
||||
|
||||
version_min_flag() {
|
||||
PLATFORM=$1
|
||||
FLAG=""
|
||||
# shellcheck disable=SC2039
|
||||
# shellcheck disable=SC2053
|
||||
if [[ $PLATFORM = $IPHONEOS ]]; then
|
||||
FLAG="-miphoneos-version-min=${MIN_IOS}"
|
||||
elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then
|
||||
FLAG="-mios-simulator-version-min=${MIN_IOS}"
|
||||
elif [[ $PLATFORM = $WATCHOS ]]; then
|
||||
FLAG="-mwatchos-version-min=${MIN_WATCHOS}"
|
||||
elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then
|
||||
FLAG="-mwatchos-simulator-version-min=${MIN_WATCHOS}"
|
||||
elif [[ $PLATFORM = $TVOS ]]; then
|
||||
FLAG="-mtvos-version-min=${MIN_TVOS}"
|
||||
elif [[ $PLATFORM = $TVSIMULATOR ]]; then
|
||||
FLAG="-mtvos-simulator-version-min=${MIN_TVOS}"
|
||||
elif [[ $PLATFORM = $MACOS ]]; then
|
||||
FLAG="-mmacosx-version-min=${MIN_MACOS}"
|
||||
fi
|
||||
echo $FLAG
|
||||
}
|
||||
|
||||
|
||||
prepare() {
|
||||
download_gmp() {
|
||||
GMP_VERSION="6.2.1"
|
||||
CURRENT_DIR=$(pwd)
|
||||
echo "$CURRENT_DIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd ${BUILD}
|
||||
mkdir -p "contrib"
|
||||
if [ ! -s "contrib/gmp-${GMP_VERSION}.tar.bz2" ]; then
|
||||
curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.bz2
|
||||
fi
|
||||
rm -rf "contrib/gmp"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd contrib
|
||||
tar xfj "gmp-${GMP_VERSION}.tar.bz2"
|
||||
mv gmp-${GMP_VERSION} gmp
|
||||
rm gmp/compat.c && cp ../../contrib/gmp-patch-6.2.1/compat.c gmp/compat.c
|
||||
rm gmp/longlong.h && cp ../../contrib/gmp-patch-6.2.1/longlong.h gmp/longlong.h
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #contrib
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #build
|
||||
}
|
||||
|
||||
download_cmake_toolchain() {
|
||||
if [ ! -s "${BUILD}/ios.toolchain.cmake" ]; then
|
||||
SHA256_HASH="d02857ff6bd64f1d7109ca59c3e4f3b2f89d0663c412146e6977c679801b3243"
|
||||
curl -o "${BUILD}/ios.toolchain.cmake" https://raw.githubusercontent.com/leetal/ios-cmake/c55677a4445b138c9ef2650d3c21f22cc78c2357/ios.toolchain.cmake
|
||||
DOWNLOADED_HASH=$(shasum -a 256 ${BUILD}/ios.toolchain.cmake | cut -f 1 -d " ")
|
||||
if [ $SHA256_HASH != "$DOWNLOADED_HASH" ]; then
|
||||
echo "Error: sha256 checksum of ios.toolchain.cmake mismatch" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
download_relic() {
|
||||
CURRENT_DIR=$(pwd)
|
||||
echo "$CURRENT_DIR"
|
||||
mkdir -p "${CURRENT_DIR}/${BUILD}/contrib"
|
||||
if [ ! -s "${CURRENT_DIR}/${BUILD}/contrib/relic" ]; then
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd "${CURRENT_DIR}/${BUILD}/contrib"
|
||||
git clone --depth 1 --branch "feat/ios-support" https://github.com/pankcuf/relic
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd relic
|
||||
git fetch --depth 1 origin 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae
|
||||
git checkout 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #relic
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd #contrib
|
||||
fi
|
||||
}
|
||||
rm -rf ${BUILD}
|
||||
mkdir -p ${BUILD}
|
||||
download_relic
|
||||
download_gmp
|
||||
download_cmake_toolchain
|
||||
}
|
||||
|
||||
build_gmp_arch() {
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
PFX=${PLATFORM}-${ARCH}
|
||||
# why this works with this host only?
|
||||
HOST=arm-apple-darwin
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd ${BUILD}
|
||||
SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path)
|
||||
PLATFORM_PATH=$(xcrun --sdk "$PLATFORM" --show-sdk-platform-path)
|
||||
CLANG=$(xcrun --sdk "$PLATFORM" --find clang)
|
||||
DEVELOPER=$(xcode-select --print-path)
|
||||
CURRENT_DIR=$(pwd)
|
||||
export PATH="${PLATFORM_PATH}/Developer/usr/bin:${DEVELOPER}/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin"
|
||||
mkdir gmplib-"${PLATFORM}"-"${ARCH}"
|
||||
CFLAGS="-Wno-unused-value -fembed-bitcode -arch ${ARCH} --sysroot=${SDK} $(version_min_flag "$PLATFORM")"
|
||||
CONFIGURESCRIPT="gmp_configure_script.sh"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd contrib
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd gmp
|
||||
make clean || true
|
||||
make distclean || true
|
||||
echo "HOST: $HOST"
|
||||
echo "PREFIX: ${CURRENT_DIR}/gmplib-${PFX}"
|
||||
|
||||
cat >"$CONFIGURESCRIPT" << EOF
|
||||
#!/bin/sh
|
||||
./configure \
|
||||
CC="$CLANG" CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" \
|
||||
--host=${HOST} --prefix="${CURRENT_DIR}/gmplib-${PFX}" \
|
||||
--disable-shared --enable-static --disable-assembly -v
|
||||
EOF
|
||||
|
||||
chmod a+x "$CONFIGURESCRIPT"
|
||||
sh "$CONFIGURESCRIPT"
|
||||
rm "$CONFIGURESCRIPT"
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
mkdir -p "${CURRENT_DIR}/log"
|
||||
# shellcheck disable=SC2039
|
||||
make -j "$LOGICALCPU_MAX" &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-build.log
|
||||
# shellcheck disable=SC2039
|
||||
make install &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-install.log
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # gmp
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # contrib
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # build
|
||||
}
|
||||
|
||||
build_relic_arch() {
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
PFX=${PLATFORM}-${ARCH}
|
||||
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd ${BUILD}
|
||||
|
||||
SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path)
|
||||
|
||||
BUILDDIR=relic-"${PFX}"
|
||||
TOOLCHAIN=$(pwd)/ios.toolchain.cmake
|
||||
GMP_PFX=$(pwd)/gmplib-${PFX}
|
||||
rm -rf "$BUILDDIR"
|
||||
mkdir "$BUILDDIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd "$BUILDDIR"
|
||||
|
||||
unset CC
|
||||
# shellcheck disable=SC2155
|
||||
export CC=$(xcrun --sdk "${PLATFORM}" --find clang)
|
||||
|
||||
WSIZE=0
|
||||
IOS_PLATFORM=""
|
||||
OPTIMIZATIONFLAGS=""
|
||||
DEPLOYMENT_TARGET=""
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
# shellcheck disable=SC2053
|
||||
if [[ $PLATFORM = $IPHONEOS ]]; then
|
||||
if [[ $ARCH = "arm64" ]] || [[ $ARCH = "arm64e" ]]; then
|
||||
IOS_PLATFORM=OS64
|
||||
DEPLOYMENT_TARGET=$MIN_IOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
else
|
||||
IOS_PLATFORM=OS
|
||||
WSIZE=32
|
||||
fi
|
||||
elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then
|
||||
if [[ $ARCH = "x86_64" ]]; then
|
||||
IOS_PLATFORM=SIMULATOR64
|
||||
DEPLOYMENT_TARGET=$MIN_IOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
elif [[ $ARCH = "arm64" ]]; then
|
||||
IOS_PLATFORM=SIMULATORARM64
|
||||
DEPLOYMENT_TARGET=$MIN_IOS
|
||||
WSIZE=64
|
||||
else
|
||||
IOS_PLATFORM=SIMULATOR
|
||||
WSIZE=32
|
||||
fi
|
||||
elif [[ $PLATFORM = $WATCHOS ]]; then
|
||||
IOS_PLATFORM=WATCHOS
|
||||
DEPLOYMENT_TARGET=$MIN_WATCHOS
|
||||
WSIZE=32
|
||||
elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then
|
||||
IOS_PLATFORM=SIMULATOR_WATCHOS
|
||||
DEPLOYMENT_TARGET=$MIN_WATCHOS
|
||||
WSIZE=32
|
||||
elif [[ $PLATFORM = $TVOS ]]; then
|
||||
IOS_PLATFORM=TVOS
|
||||
DEPLOYMENT_TARGET=$MIN_TVOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
elif [[ $PLATFORM = $TVSIMULATOR ]]; then
|
||||
IOS_PLATFORM=SIMULATOR_TVOS
|
||||
#TODO
|
||||
if [[ $ARCH = "arm64" ]]
|
||||
then
|
||||
IOS_PLATFORM=OS64
|
||||
fi
|
||||
DEPLOYMENT_TARGET=$MIN_TVOS
|
||||
WSIZE=64
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
elif [[ $PLATFORM = $MACOS ]]; then
|
||||
WSIZE=64
|
||||
IOS_PLATFORM=MAC
|
||||
if [[ $ARCH = "arm64" ]]
|
||||
then
|
||||
IOS_PLATFORM=MAC_ARM64
|
||||
fi
|
||||
DEPLOYMENT_TARGET=$MIN_MACOS
|
||||
OPTIMIZATIONFLAGS=-fomit-frame-pointer
|
||||
fi
|
||||
|
||||
COMPILER_ARGS="$(version_min_flag "$PLATFORM") -Wno-unused-functions"
|
||||
|
||||
EXTRA_ARGS="-DOPSYS=NONE -DPLATFORM=$IOS_PLATFORM -DDEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN"
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
if [[ $ARCH = "i386" ]]; then
|
||||
EXTRA_ARGS+=" -DARCH=X86"
|
||||
elif [[ $ARCH = "x86_64" ]]; then
|
||||
EXTRA_ARGS+=" -DARCH=X64"
|
||||
else
|
||||
EXTRA_ARGS+=" -DARCH=ARM"
|
||||
if [[ $ARCH = "armv7s" ]]; then
|
||||
EXTRA_ARGS+=" -DIOS_ARCH=armv7s"
|
||||
elif [[ $ARCH = "armv7k" ]]; then
|
||||
EXTRA_ARGS+=" -DIOS_ARCH=armv7k"
|
||||
elif [[ $ARCH = "arm64_32" ]]; then
|
||||
EXTRA_ARGS+=" -DIOS_ARCH=arm64_32"
|
||||
fi
|
||||
fi
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
cmake -DCMAKE_PREFIX_PATH:PATH="${GMP_PFX}" -DTESTS=0 -DBENCH=0 -DBUILD_BLS_JS_BINDINGS=0 -DBUILD_BLS_PYTHON_BINDINGS=0 \
|
||||
-DBUILD_BLS_BENCHMARKS=0 -DBUILD_BLS_TESTS=0 -DCHECK=off -DARITH=gmp -DTIMER=HPROC -DFP_PRIME=381 -DMULTI=PTHREAD \
|
||||
-DFP_QNRES=on -DFP_METHD="INTEG;INTEG;INTEG;MONTY;EXGCD;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" \
|
||||
-DCOMP_FLAGS="-pipe -std=c99 -O3 -funroll-loops $OPTIMIZATIONFLAGS -isysroot $SDK -arch $ARCH -fembed-bitcode ${COMPILER_ARGS}" \
|
||||
-DWSIZE=$WSIZE -DVERBS=off -DSHLIB=off -DALLOC="AUTO" -DEP_PLAIN=off -DEP_SUPER=off -DPP_EXT="LAZYR" \
|
||||
-DWITH="DV;BN;MD;FP;EP;FPX;EPX;PP;PC;CP" -DBN_METHD="COMBA;COMBA;MONTY;SLIDE;STEIN;BASIC" ${EXTRA_ARGS} ../../
|
||||
|
||||
make -j "$LOGICALCPU_MAX"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # "$BUILDDIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # contrib/relic
|
||||
}
|
||||
|
||||
build_bls_arch() {
|
||||
# shellcheck disable=SC2039
|
||||
BLS_FILES=( "bls" "chaincode" "elements" "extendedprivatekey" "extendedpublickey" "legacy" "privatekey" "schemes" "threshold" )
|
||||
# shellcheck disable=SC2039
|
||||
ALL_BLS_OBJ_FILES=$(printf "%s.o " "${BLS_FILES[@]}")
|
||||
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
PFX=${PLATFORM}-${ARCH}
|
||||
SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path)
|
||||
|
||||
BUILDDIR=${BUILD}/bls-"${PFX}"
|
||||
rm -rf "$BUILDDIR"
|
||||
mkdir "$BUILDDIR"
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
pushd "$BUILDDIR"
|
||||
|
||||
EXTRA_ARGS="$(version_min_flag "$PLATFORM")"
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
for F in "${BLS_FILES[@]}"
|
||||
do
|
||||
clang -I"../contrib/relic/include" \
|
||||
-I"../relic-${PFX}/_deps/relic-build/include" \
|
||||
-I"../../src/" \
|
||||
-I"../gmplib-${PFX}/include" \
|
||||
-x c++ -std=c++14 -stdlib=libc++ -fembed-bitcode -arch "${ARCH}" -isysroot "${SDK}" "${EXTRA_ARGS}" \
|
||||
-c "../../src/${F}.cpp" -o "${F}.o"
|
||||
done
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
xcrun -sdk "$PLATFORM" ar -cvq libbls.a $ALL_BLS_OBJ_FILES
|
||||
|
||||
# shellcheck disable=SC2039,SC2164
|
||||
popd # "$BUILDDIR"
|
||||
}
|
||||
|
||||
build_all_arch() {
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
build_gmp_arch "$PLATFORM" "$ARCH"
|
||||
build_relic_arch "$PLATFORM" "$ARCH"
|
||||
build_bls_arch "$PLATFORM" "$ARCH"
|
||||
}
|
||||
|
||||
build_target() {
|
||||
BUILD_IN=$1
|
||||
echo "Build target: $BUILD_IN"
|
||||
ARCH=""
|
||||
PLATFORM=""
|
||||
# shellcheck disable=SC2039
|
||||
if [[ $BUILD_IN = "x86_64-apple-ios" ]]; then
|
||||
ARCH=x86_64
|
||||
PLATFORM=$IPHONESIMULATOR
|
||||
elif [[ $BUILD_IN = "aarch64-apple-ios" ]]; then
|
||||
ARCH=arm64
|
||||
PLATFORM=$IPHONEOS
|
||||
elif [[ $BUILD_IN = "aarch64-apple-ios-sim" ]]; then
|
||||
ARCH=arm64
|
||||
PLATFORM=$IPHONESIMULATOR
|
||||
elif [[ $BUILD_IN = "x86_64-apple-darwin" ]]; then
|
||||
ARCH=x86_64
|
||||
PLATFORM=$MACOS
|
||||
elif [[ $BUILD_IN = "aarch64-apple-darwin" ]]; then
|
||||
ARCH=arm64
|
||||
PLATFORM=$MACOS
|
||||
fi
|
||||
build_all_arch "$PLATFORM" "$ARCH"
|
||||
PFX="${PLATFORM}"-"${ARCH}"
|
||||
rm -rf "build/artefacts/${BUILD_IN}"
|
||||
mkdir -p "build/artefacts/${BUILD_IN}/include"
|
||||
# libtool -static -o "build/artefacts/${BUILD_IN}/libbls.a" \
|
||||
# "build/gmplib-${PFX}/lib/libgmp.a" \
|
||||
# "build/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" \
|
||||
# "build/bls-${PFX}/libbls.a"
|
||||
cp "build/gmplib-${PFX}/lib/libgmp.a" "build/artefacts/${BUILD_IN}"
|
||||
cp "build/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" "build/artefacts/${BUILD_IN}"
|
||||
cp "build/relic-${PFX}/_deps/sodium-build/libsodium.a" "build/artefacts/${BUILD_IN}"
|
||||
cp "build/bls-${PFX}/libbls.a" "build/artefacts/${BUILD_IN}"
|
||||
cp -rf build/bls-"${PFX}"/*.o build/artefacts/"${BUILD_IN}"/include
|
||||
cp -rf src/*.hpp build/artefacts/"${BUILD_IN}"/include
|
||||
cp -rf build/gmplib-"${PFX}"/include/gmp.h build/artefacts/"${BUILD_IN}"/include
|
||||
cp -rf build/relic-"${PFX}"/_deps/relic-build/include/*.h build/artefacts/"${BUILD_IN}"/include
|
||||
}
|
||||
|
||||
#make_relic_headers_universal() {
|
||||
# RELIC_TARGET_DIR=relic-iphoneos-arm64
|
||||
# perl -p -e 's/#define WSIZE.*/#ifdef __LP64__\n#define WSIZE 64\n#else\n#define WSIZE 32\n#endif/' \
|
||||
# "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" \
|
||||
# > "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new"
|
||||
#
|
||||
# rm "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h"
|
||||
# mv "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h"
|
||||
#}
|
||||
#
|
||||
#copy_headers() {
|
||||
## mkdir build/artefacts/include
|
||||
# # Copy all headers we will need
|
||||
# cp -rf src/*.hpp ${BUILD}/artefacts/include
|
||||
# cp -rf ${BUILD}/contrib/gmp/include/gmp.h ${BUILD}/artefacts/include
|
||||
# cp -rf ${BUILD}/contrib/relic/include/*.h ${BUILD}/artefacts/include
|
||||
# cp -rf ${BUILD}/contrib/relic/include/low/*.h ${BUILD}/artefacts/include
|
||||
# #cp -rf ${BUILD}/contrib/relic/relic-iphoneos-arm64/include/*.h ${BUILD}/artefacts/include
|
||||
# rm -rf ${BUILD}/artefacts/include/test-utils.hpp
|
||||
#}
|
||||
|
||||
prepare
|
||||
build_target "$TARGET"
|
||||
#copy_headers
|
||||
#build_all "${MACOS};x86_64+arm64"
|
||||
#build_all "${IPHONEOS};arm64|${IPHONESIMULATOR};arm64+x86_64"
|
||||
|
||||
#make_relic_headers_universal
|
||||
#copy_headers
|
||||
#make_fat_binary
|
@ -1,5 +1,5 @@
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([libdashbls],[1.2.4])
|
||||
AC_INIT([libdashbls],[1.3.0])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([build-aux/m4])
|
||||
|
||||
@ -783,3 +783,4 @@ AC_OUTPUT
|
||||
|
||||
dnl Peplace conflict-prone PACKAGE-prefixed macros with DASHBLS
|
||||
sed -i.old 's/PACKAGE/DASHBLS/g' depends/relic/include/relic_conf.h
|
||||
sed -i.old 's/PACKAGE/DASHBLS/g' config.status
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
GTElement Pair(const G2Element &b) const;
|
||||
uint32_t GetFingerprint(bool fLegacy = false) const;
|
||||
std::vector<uint8_t> Serialize(bool fLegacy = false) const;
|
||||
G1Element Copy();
|
||||
|
||||
friend bool operator==(const G1Element &a, const G1Element &b);
|
||||
friend bool operator!=(const G1Element &a, const G1Element &b);
|
||||
@ -101,6 +102,7 @@ public:
|
||||
G2Element Negate() const;
|
||||
GTElement Pair(const G1Element &a) const;
|
||||
std::vector<uint8_t> Serialize(bool fLegacy = false) const;
|
||||
G2Element Copy();
|
||||
|
||||
friend bool operator==(G2Element const &a, G2Element const &b);
|
||||
friend bool operator!=(G2Element const &a, G2Element const &b);
|
||||
|
@ -39,6 +39,7 @@ class CoreMPL {
|
||||
public:
|
||||
CoreMPL() = delete;
|
||||
CoreMPL(const std::string& strId) : strCiphersuiteId(strId) {}
|
||||
virtual ~CoreMPL() {}
|
||||
// Generates a private key from a seed, similar to HD key generation
|
||||
// (hashes the seed), and reduces it mod the group order
|
||||
virtual PrivateKey KeyGen(const vector<uint8_t>& seed);
|
||||
@ -112,7 +113,7 @@ protected:
|
||||
bool fLegacy);
|
||||
};
|
||||
|
||||
class BasicSchemeMPL : public CoreMPL {
|
||||
class BasicSchemeMPL final : public CoreMPL {
|
||||
public:
|
||||
static const std::string CIPHERSUITE_ID;
|
||||
BasicSchemeMPL() : CoreMPL(BasicSchemeMPL::CIPHERSUITE_ID) {}
|
||||
@ -133,7 +134,7 @@ public:
|
||||
const G2Element& signature) override;
|
||||
};
|
||||
|
||||
class AugSchemeMPL : public CoreMPL {
|
||||
class AugSchemeMPL final : public CoreMPL {
|
||||
|
||||
public:
|
||||
static const std::string CIPHERSUITE_ID;
|
||||
@ -186,7 +187,7 @@ public:
|
||||
const G2Element& signature) override;
|
||||
};
|
||||
|
||||
class PopSchemeMPL : public CoreMPL {
|
||||
class PopSchemeMPL final : public CoreMPL {
|
||||
|
||||
public:
|
||||
static const std::string CIPHERSUITE_ID;
|
||||
@ -221,7 +222,7 @@ public:
|
||||
/**
|
||||
* This scheme reflects the Sign/Verify behaviour of older bls-signatures library versions (<0.1.29).
|
||||
*/
|
||||
class LegacySchemeMPL : public CoreMPL {
|
||||
class LegacySchemeMPL final : public CoreMPL {
|
||||
|
||||
public:
|
||||
LegacySchemeMPL() : CoreMPL(std::string{}) {}
|
||||
|
@ -34,5 +34,5 @@ foreach(file ${JS_BINDINGS_TESTS})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tests/${file} tests/${file} COPYONLY)
|
||||
endforeach()
|
||||
|
||||
set_target_properties(blsjstmp PROPERTIES LINK_FLAGS "--bind -Oz --closure 1 -s MODULARIZE=1 -s NODEJS_CATCH_EXIT=1 -s NODEJS_CATCH_REJECTION=1")
|
||||
set_target_properties(blsjstmp PROPERTIES LINK_FLAGS "--bind -Oz --closure 1 -s MODULARIZE=1")
|
||||
add_custom_command(TARGET blsjstmp POST_BUILD COMMAND npm run build:web)
|
||||
|
1
js-bindings/blsjs.d.ts
vendored
1
js-bindings/blsjs.d.ts
vendored
@ -21,6 +21,7 @@ export declare class BasicSchemeMPL {
|
||||
static deriveChildSk(sk: PrivateKey, index: number): PrivateKey;
|
||||
static deriveChildSkUnhardened(sk: PrivateKey, index: number): PrivateKey;
|
||||
static deriveChildPkUnhardened(pk: G1Element, index: number): G1Element;
|
||||
static verifySecure(pk: G1Element, sig: G2Element, msg: Uint8Array): boolean;
|
||||
}
|
||||
|
||||
export declare class PopSchemeMPL {
|
||||
|
@ -42,7 +42,8 @@ EMSCRIPTEN_BINDINGS(blsjs) {
|
||||
.class_function("aggregateVerify", &SchemeMPLWrapper<BasicSchemeMPL>::AggregateVerify)
|
||||
.class_function("deriveChildSk", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildSk)
|
||||
.class_function("deriveChildSkUnhardened", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildSkUnhardened)
|
||||
.class_function("deriveChildPkUnhardened", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildPkUnhardened);
|
||||
.class_function("deriveChildPkUnhardened", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildPkUnhardened)
|
||||
.class_function("verifySecure", &SchemeMPLWrapper<BasicSchemeMPL>::VerifySecure);
|
||||
|
||||
class_<PopSchemeMPLWrapper>("PopSchemeMPL")
|
||||
.class_function("skToG1", &PopSchemeMPLWrapper::SkToG1)
|
||||
|
@ -81,6 +81,15 @@ template <typename SchemeMPL> class SchemeMPLWrapper : public JSWrapper<SchemeMP
|
||||
return G1ElementWrapper(mpl.DeriveChildPkUnhardened(pk.GetWrappedInstance(), index));
|
||||
}
|
||||
|
||||
static bool VerifySecure(val pubkeyArray, const G2ElementWrapper &signature, val messageVal) {
|
||||
std::vector<G1Element> pubkeys = G1ElementWrapper::Unwrap
|
||||
(helpers::toVectorFromJSArray<G1ElementWrapper>(pubkeyArray));
|
||||
|
||||
std::vector <uint8_t> message = helpers::toVector(messageVal);
|
||||
|
||||
return mpl.VerifySecure(pubkeys, signature.GetWrappedInstance(), message);
|
||||
}
|
||||
|
||||
protected:
|
||||
static inline SchemeMPL mpl;
|
||||
};
|
||||
|
@ -21,6 +21,7 @@ from bls12381 import h_eff, q
|
||||
from ec import JacobianPoint, default_ec_twist, eval_iso
|
||||
from fields import Fq, Fq2, roots_of_unity
|
||||
from hash_to_field import Hp2
|
||||
from typing import Union
|
||||
|
||||
|
||||
def sgn0(x: Fq2) -> int:
|
||||
@ -198,7 +199,7 @@ def iso3(P):
|
||||
#
|
||||
# map from Fq2 element(s) to point in G2 subgroup of Ell2
|
||||
#
|
||||
def opt_swu2_map(t: Fq2, t2: Fq2 = None) -> JacobianPoint:
|
||||
def opt_swu2_map(t: Fq2, t2: Union[Fq2, None] = None) -> JacobianPoint:
|
||||
Pp = iso3(osswu2_help(t))
|
||||
if t2 is not None:
|
||||
Pp2 = iso3(osswu2_help(t2))
|
||||
|
2
rust-bindings/.gitignore
vendored
Normal file
2
rust-bindings/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
Cargo.lock
|
||||
target
|
17
rust-bindings/bls-dash-sys/.rustfmt.toml
Normal file
17
rust-bindings/bls-dash-sys/.rustfmt.toml
Normal file
@ -0,0 +1,17 @@
|
||||
unstable_features = true
|
||||
|
||||
blank_lines_lower_bound = 0
|
||||
condense_wildcard_suffixes = true
|
||||
error_on_line_overflow = true
|
||||
error_on_unformatted = true
|
||||
format_code_in_doc_comments = true
|
||||
format_macro_matchers = true
|
||||
format_strings = true
|
||||
imports_granularity = "Crate"
|
||||
normalize_comments = true
|
||||
normalize_doc_attributes = true
|
||||
reorder_impl_items = true
|
||||
group_imports = "StdExternalCrate"
|
||||
use_field_init_shorthand = true
|
||||
use_try_shorthand = true
|
||||
wrap_comments = true
|
15
rust-bindings/bls-dash-sys/Cargo.toml
Normal file
15
rust-bindings/bls-dash-sys/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "bls-dash-sys"
|
||||
description = ""
|
||||
version = "1.2.5"
|
||||
build = "build.rs"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
apple = []
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
bindgen = "0.65.1"
|
||||
glob ="0.3"
|
435
rust-bindings/bls-dash-sys/bindings.rs
Normal file
435
rust-bindings/bls-dash-sys/bindings.rs
Normal file
@ -0,0 +1,435 @@
|
||||
pub type G1Element = *mut ::std::os::raw::c_void;
|
||||
pub type G2Element = *mut ::std::os::raw::c_void;
|
||||
pub type PrivateKey = *mut ::std::os::raw::c_void;
|
||||
pub type CoreMPL = *mut ::std::os::raw::c_void;
|
||||
pub type BasicSchemeMPL = CoreMPL;
|
||||
pub type AugSchemeMPL = CoreMPL;
|
||||
pub type PopSchemeMPL = CoreMPL;
|
||||
pub type LegacySchemeMPL = CoreMPL;
|
||||
pub type BIP32ExtendedPrivateKey = *mut ::std::os::raw::c_void;
|
||||
pub type BIP32ExtendedPublicKey = *mut ::std::os::raw::c_void;
|
||||
pub type BIP32ChainCode = *mut ::std::os::raw::c_void;
|
||||
|
||||
extern "C" {
|
||||
pub fn G1ElementSize() -> ::std::os::raw::c_int;
|
||||
|
||||
pub fn G1ElementFromBytes(
|
||||
data: *const ::std::os::raw::c_void,
|
||||
legacy: bool,
|
||||
didErr: *mut bool,
|
||||
) -> G1Element;
|
||||
|
||||
pub fn G1ElementGenerator() -> G1Element;
|
||||
|
||||
pub fn G1ElementIsValid(el: G1Element) -> bool;
|
||||
|
||||
pub fn G1ElementGetFingerprint(el: G1Element, legacy: bool) -> u32;
|
||||
|
||||
pub fn G1ElementIsEqual(el1: G1Element, el2: G1Element) -> bool;
|
||||
|
||||
pub fn G1ElementAdd(el1: G1Element, el2: G1Element) -> G1Element;
|
||||
|
||||
pub fn G1ElementMul(el: G1Element, sk: PrivateKey) -> G1Element;
|
||||
|
||||
pub fn G1ElementNegate(el: G1Element) -> G1Element;
|
||||
|
||||
pub fn G1ElementCopy(el: G1Element) -> G1Element;
|
||||
|
||||
pub fn G1ElementSerialize(el: G1Element, legacy: bool) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn G1ElementFree(el: G1Element);
|
||||
|
||||
pub fn G2ElementSize() -> ::std::os::raw::c_int;
|
||||
|
||||
pub fn G2ElementFromBytes(
|
||||
data: *const ::std::os::raw::c_void,
|
||||
legacy: bool,
|
||||
didErr: *mut bool,
|
||||
) -> G2Element;
|
||||
|
||||
pub fn G2ElementGenerator() -> G2Element;
|
||||
|
||||
pub fn G2ElementIsValid(el: G2Element) -> bool;
|
||||
|
||||
pub fn G2ElementIsEqual(el1: G2Element, el2: G2Element) -> bool;
|
||||
|
||||
pub fn G2ElementAdd(el1: G2Element, el2: G2Element) -> G2Element;
|
||||
|
||||
pub fn G2ElementMul(el: G2Element, sk: PrivateKey) -> G2Element;
|
||||
|
||||
pub fn G2ElementNegate(el: G2Element) -> G2Element;
|
||||
|
||||
pub fn G2ElementCopy(el: G2Element) -> G2Element;
|
||||
|
||||
pub fn G2ElementSerialize(el: G2Element, legacy: bool) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn G2ElementFree(el: G2Element);
|
||||
|
||||
pub fn PrivateKeyFromBytes(
|
||||
data: *const ::std::os::raw::c_void,
|
||||
modOrder: bool,
|
||||
didErr: *mut bool,
|
||||
) -> PrivateKey;
|
||||
|
||||
pub fn PrivateKeyFromSeedBIP32(data: *const ::std::os::raw::c_void, len: usize) -> PrivateKey;
|
||||
|
||||
pub fn PrivateKeyAggregate(sks: *mut *mut ::std::os::raw::c_void, len: usize) -> PrivateKey;
|
||||
|
||||
pub fn PrivateKeyGetG1Element(sk: PrivateKey, didErr: *mut bool) -> G1Element;
|
||||
|
||||
pub fn PrivateKeyGetG2Element(sk: PrivateKey, didErr: *mut bool) -> G2Element;
|
||||
|
||||
pub fn PrivateKeyGetG2Power(sk: PrivateKey, el: G2Element) -> G2Element;
|
||||
|
||||
pub fn PrivateKeyIsEqual(sk1: PrivateKey, sk2: PrivateKey) -> bool;
|
||||
|
||||
pub fn PrivateKeySerialize(sk: PrivateKey) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn PrivateKeyFree(sk: PrivateKey);
|
||||
|
||||
pub fn PrivateKeySizeBytes() -> usize;
|
||||
|
||||
pub fn SecFree(p: *mut ::std::os::raw::c_void);
|
||||
|
||||
pub fn AllocPtrArray(len: usize) -> *mut *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn SetPtrArray(
|
||||
arrPtr: *mut *mut ::std::os::raw::c_void,
|
||||
elemPtr: *mut ::std::os::raw::c_void,
|
||||
index: ::std::os::raw::c_int,
|
||||
);
|
||||
|
||||
pub fn FreePtrArray(inPtr: *mut *mut ::std::os::raw::c_void);
|
||||
|
||||
pub fn GetPtrAtIndex(
|
||||
arrPtr: *mut *mut ::std::os::raw::c_void,
|
||||
index: ::std::os::raw::c_int,
|
||||
) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn SecAllocBytes(len: usize) -> *mut u8;
|
||||
|
||||
pub fn GetAddressAtIndex(
|
||||
ptr: *mut u8,
|
||||
index: ::std::os::raw::c_int,
|
||||
) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn GetLastErrorMsg() -> *const ::std::os::raw::c_char;
|
||||
|
||||
pub fn CoreMPLKeyGen(
|
||||
scheme: CoreMPL,
|
||||
seed: *const ::std::os::raw::c_void,
|
||||
seedLen: usize,
|
||||
didErr: *mut bool,
|
||||
) -> PrivateKey;
|
||||
|
||||
pub fn CoreMPLSkToG1(scheme: CoreMPL, sk: PrivateKey) -> G1Element;
|
||||
|
||||
pub fn CoreMPLSign(
|
||||
scheme: CoreMPL,
|
||||
sk: PrivateKey,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
) -> G2Element;
|
||||
|
||||
pub fn CoreMPLVerify(
|
||||
scheme: BasicSchemeMPL,
|
||||
pk: G1Element,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
sig: G2Element,
|
||||
) -> bool;
|
||||
|
||||
pub fn CoreMPLVerifySecure(
|
||||
scheme: CoreMPL,
|
||||
pks: *mut *mut ::std::os::raw::c_void,
|
||||
pksLen: usize,
|
||||
sig: G2Element,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
) -> bool;
|
||||
|
||||
pub fn CoreMPLAggregatePubKeys(
|
||||
scheme: CoreMPL,
|
||||
pubKeys: *mut *mut ::std::os::raw::c_void,
|
||||
pkLen: usize,
|
||||
) -> G1Element;
|
||||
|
||||
pub fn CoreMPLAggregateSigs(
|
||||
scheme: CoreMPL,
|
||||
sigs: *mut *mut ::std::os::raw::c_void,
|
||||
sigLen: usize,
|
||||
) -> G2Element;
|
||||
|
||||
pub fn CoreMPLDeriveChildSk(scheme: CoreMPL, sk: PrivateKey, index: u32) -> PrivateKey;
|
||||
|
||||
pub fn CoreMPLDeriveChildSkUnhardened(
|
||||
scheme: CoreMPL,
|
||||
sk: PrivateKey,
|
||||
index: u32,
|
||||
) -> PrivateKey;
|
||||
|
||||
pub fn CoreMPLDeriveChildPkUnhardened(scheme: CoreMPL, sk: G1Element, index: u32) -> G1Element;
|
||||
|
||||
pub fn CoreMPLAggregateVerify(
|
||||
scheme: CoreMPL,
|
||||
pks: *mut *mut ::std::os::raw::c_void,
|
||||
pkLen: usize,
|
||||
msgs: *mut *mut ::std::os::raw::c_void,
|
||||
msgLens: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
sig: G2Element,
|
||||
) -> bool;
|
||||
|
||||
pub fn NewBasicSchemeMPL() -> BasicSchemeMPL;
|
||||
|
||||
pub fn BasicSchemeMPLAggregateVerify(
|
||||
scheme: BasicSchemeMPL,
|
||||
pks: *mut *mut ::std::os::raw::c_void,
|
||||
pksLen: usize,
|
||||
msgs: *mut *mut ::std::os::raw::c_void,
|
||||
msgsLens: *const ::std::os::raw::c_void,
|
||||
msgsLen: usize,
|
||||
sig: G2Element,
|
||||
) -> bool;
|
||||
|
||||
pub fn BasicSchemeMPLFree(scheme: BasicSchemeMPL);
|
||||
|
||||
pub fn NewAugSchemeMPL() -> AugSchemeMPL;
|
||||
|
||||
pub fn AugSchemeMPLSign(
|
||||
scheme: AugSchemeMPL,
|
||||
sk: PrivateKey,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
) -> G2Element;
|
||||
|
||||
pub fn AugSchemeMPLSignPrepend(
|
||||
scheme: AugSchemeMPL,
|
||||
sk: PrivateKey,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
prepPk: G1Element,
|
||||
) -> G2Element;
|
||||
|
||||
pub fn AugSchemeMPLVerify(
|
||||
scheme: AugSchemeMPL,
|
||||
pk: G1Element,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
sig: G2Element,
|
||||
) -> bool;
|
||||
|
||||
pub fn AugSchemeMPLAggregateVerify(
|
||||
scheme: AugSchemeMPL,
|
||||
pks: *mut *mut ::std::os::raw::c_void,
|
||||
pksLen: usize,
|
||||
msgs: *mut *mut ::std::os::raw::c_void,
|
||||
msgsLens: *const ::std::os::raw::c_void,
|
||||
msgsLen: usize,
|
||||
sig: G2Element,
|
||||
) -> bool;
|
||||
|
||||
pub fn AugSchemeMPLFree(scheme: AugSchemeMPL);
|
||||
|
||||
pub fn NewPopSchemeMPL() -> PopSchemeMPL;
|
||||
|
||||
pub fn PopSchemeMPLPopProve(scheme: PopSchemeMPL, sk: PrivateKey) -> G2Element;
|
||||
|
||||
pub fn PopSchemeMPLPopVerify(scheme: PopSchemeMPL, pk: G1Element, sig: G2Element) -> bool;
|
||||
|
||||
pub fn PopSchemeMPLFastAggregateVerify(
|
||||
scheme: PopSchemeMPL,
|
||||
pks: *mut *mut ::std::os::raw::c_void,
|
||||
pksLen: usize,
|
||||
msgs: *const ::std::os::raw::c_void,
|
||||
msgsLen: usize,
|
||||
sig: G2Element,
|
||||
) -> bool;
|
||||
|
||||
pub fn PopSchemeMPLFree(scheme: PopSchemeMPL);
|
||||
|
||||
pub fn NewLegacySchemeMPL() -> LegacySchemeMPL;
|
||||
|
||||
pub fn LegacySchemeMPLSign(
|
||||
scheme: LegacySchemeMPL,
|
||||
sk: PrivateKey,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
) -> G2Element;
|
||||
|
||||
pub fn LegacySchemeMPLSignPrepend(
|
||||
scheme: LegacySchemeMPL,
|
||||
sk: PrivateKey,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
prepPk: G1Element,
|
||||
) -> G2Element;
|
||||
|
||||
pub fn LegacySchemeMPLVerify(
|
||||
scheme: LegacySchemeMPL,
|
||||
pk: G1Element,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
sig: G2Element,
|
||||
) -> bool;
|
||||
|
||||
pub fn LegacySchemeMPLVerifySecure(
|
||||
scheme: LegacySchemeMPL,
|
||||
pks: *mut *mut ::std::os::raw::c_void,
|
||||
pksLen: usize,
|
||||
sig: G2Element,
|
||||
msg: *const ::std::os::raw::c_void,
|
||||
msgLen: usize,
|
||||
) -> bool;
|
||||
|
||||
pub fn LegacySchemeMPLAggregateVerify(
|
||||
scheme: LegacySchemeMPL,
|
||||
pks: *mut *mut ::std::os::raw::c_void,
|
||||
pksLen: usize,
|
||||
msgs: *mut *mut ::std::os::raw::c_void,
|
||||
msgsLens: *const ::std::os::raw::c_void,
|
||||
msgsLen: usize,
|
||||
sig: G2Element,
|
||||
) -> bool;
|
||||
|
||||
pub fn LegacySchemeMPLFree(scheme: LegacySchemeMPL);
|
||||
|
||||
pub fn ThresholdPrivateKeyShare(
|
||||
sks: *mut *mut ::std::os::raw::c_void,
|
||||
sksLen: usize,
|
||||
hash: *const ::std::os::raw::c_void,
|
||||
didErr: *mut bool,
|
||||
) -> PrivateKey;
|
||||
|
||||
pub fn ThresholdPrivateKeyRecover(
|
||||
sks: *mut *mut ::std::os::raw::c_void,
|
||||
sksLen: usize,
|
||||
hashes: *mut *mut ::std::os::raw::c_void,
|
||||
hashesLen: usize,
|
||||
didErr: *mut bool,
|
||||
) -> PrivateKey;
|
||||
|
||||
pub fn ThresholdPublicKeyShare(
|
||||
pks: *mut *mut ::std::os::raw::c_void,
|
||||
pksLen: usize,
|
||||
hash: *const ::std::os::raw::c_void,
|
||||
didErr: *mut bool,
|
||||
) -> G1Element;
|
||||
|
||||
pub fn ThresholdPublicKeyRecover(
|
||||
pks: *mut *mut ::std::os::raw::c_void,
|
||||
pksLen: usize,
|
||||
hashes: *mut *mut ::std::os::raw::c_void,
|
||||
hashesLen: usize,
|
||||
didErr: *mut bool,
|
||||
) -> G1Element;
|
||||
|
||||
pub fn ThresholdSignatureShare(
|
||||
sigs: *mut *mut ::std::os::raw::c_void,
|
||||
sigsLen: usize,
|
||||
hash: *const ::std::os::raw::c_void,
|
||||
didErr: *mut bool,
|
||||
) -> G2Element;
|
||||
|
||||
pub fn ThresholdSignatureRecover(
|
||||
sigs: *mut *mut ::std::os::raw::c_void,
|
||||
sigsLen: usize,
|
||||
hashes: *mut *mut ::std::os::raw::c_void,
|
||||
hashesLen: usize,
|
||||
didErr: *mut bool,
|
||||
) -> G2Element;
|
||||
|
||||
pub fn ThresholdSign(sk: PrivateKey, hash: *const ::std::os::raw::c_void) -> G2Element;
|
||||
|
||||
pub fn ThresholdVerify(
|
||||
pk: G1Element,
|
||||
hash: *const ::std::os::raw::c_void,
|
||||
sig: G2Element,
|
||||
) -> bool;
|
||||
|
||||
pub fn BIP32ChainCodeSerialize(cc: BIP32ChainCode) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn BIP32ChainCodeIsEqual(cc1: BIP32ChainCode, cc2: BIP32ChainCode) -> bool;
|
||||
|
||||
pub fn BIP32ChainCodeFree(cc: BIP32ChainCode);
|
||||
|
||||
pub fn BIP32ExtendedPublicKeyFromBytes(
|
||||
data: *const ::std::os::raw::c_void,
|
||||
legacy: bool,
|
||||
didErr: *mut bool,
|
||||
) -> BIP32ExtendedPublicKey;
|
||||
|
||||
pub fn BIP32ExtendedPublicKeyPublicChild(
|
||||
pk: BIP32ExtendedPublicKey,
|
||||
index: u32,
|
||||
legacy: bool,
|
||||
) -> BIP32ExtendedPublicKey;
|
||||
|
||||
pub fn BIP32ExtendedPublicKeyGetChainCode(pk: BIP32ExtendedPublicKey) -> BIP32ChainCode;
|
||||
|
||||
pub fn BIP32ExtendedPublicKeySerialize(
|
||||
pk: BIP32ExtendedPublicKey,
|
||||
legacy: bool,
|
||||
) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn BIP32ExtendedPublicKeyIsEqual(
|
||||
pk1: BIP32ExtendedPublicKey,
|
||||
pk2: BIP32ExtendedPublicKey,
|
||||
) -> bool;
|
||||
|
||||
pub fn BIP32ExtendedPublicKeyGetPublicKey(
|
||||
pk: BIP32ExtendedPublicKey,
|
||||
) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn BIP32ExtendedPublicKeyFree(pk: BIP32ExtendedPublicKey);
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyFromBytes(
|
||||
data: *const ::std::os::raw::c_void,
|
||||
didErr: *mut bool,
|
||||
) -> BIP32ExtendedPrivateKey;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyFromSeed(
|
||||
data: *const ::std::os::raw::c_void,
|
||||
len: usize,
|
||||
didErr: *mut bool,
|
||||
) -> BIP32ExtendedPrivateKey;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyPrivateChild(
|
||||
sk: BIP32ExtendedPrivateKey,
|
||||
index: u32,
|
||||
legacy: bool,
|
||||
) -> BIP32ExtendedPrivateKey;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyPublicChild(
|
||||
sk: BIP32ExtendedPrivateKey,
|
||||
index: u32,
|
||||
) -> BIP32ExtendedPublicKey;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyGetChainCode(sk: BIP32ExtendedPrivateKey) -> BIP32ChainCode;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeySerialize(
|
||||
sk: BIP32ExtendedPrivateKey,
|
||||
) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyIsEqual(
|
||||
sk1: BIP32ExtendedPrivateKey,
|
||||
sk2: BIP32ExtendedPrivateKey,
|
||||
) -> bool;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyGetPrivateKey(
|
||||
sk: BIP32ExtendedPrivateKey,
|
||||
) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyGetExtendedPublicKey(
|
||||
sk: BIP32ExtendedPrivateKey,
|
||||
legacy: bool,
|
||||
didErr: *mut bool,
|
||||
) -> BIP32ExtendedPublicKey;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyGetPublicKey(
|
||||
sk: BIP32ExtendedPrivateKey,
|
||||
didErr: *mut bool,
|
||||
) -> *mut ::std::os::raw::c_void;
|
||||
|
||||
pub fn BIP32ExtendedPrivateKeyFree(sk: BIP32ExtendedPrivateKey);
|
||||
}
|
374
rust-bindings/bls-dash-sys/build.rs
Normal file
374
rust-bindings/bls-dash-sys/build.rs
Normal file
@ -0,0 +1,374 @@
|
||||
use std::{env, fs, io, io::Write, path::{Path, PathBuf}, process::{Command, Output}};
|
||||
|
||||
#[cfg(not(feature = "apple"))]
|
||||
fn create_cross_cmake_command() -> Command {
|
||||
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
|
||||
let mut command = if target_arch.eq("wasm32") {
|
||||
Command::new("emcmake")
|
||||
} else {
|
||||
Command::new("cmake")
|
||||
};
|
||||
|
||||
if target_arch.eq("wasm32") {
|
||||
command.arg("cmake");
|
||||
}
|
||||
|
||||
command
|
||||
}
|
||||
|
||||
fn handle_command_output(output: Output) {
|
||||
io::stdout()
|
||||
.write_all(&output.stdout)
|
||||
.expect("should write output");
|
||||
|
||||
io::stderr()
|
||||
.write_all(&output.stderr)
|
||||
.expect("should write output");
|
||||
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "apple"))]
|
||||
fn main() {
|
||||
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
|
||||
// TODO: fix build for wasm32 on MacOS
|
||||
// errors with `error: linking with `rust-lld` failed: exit status: 1`
|
||||
if target_arch.eq("wasm32") {
|
||||
println!("Build for wasm32 is not fully supported");
|
||||
return;
|
||||
}
|
||||
|
||||
let root_path = Path::new("../..")
|
||||
.canonicalize()
|
||||
.expect("can't get abs path");
|
||||
|
||||
let bls_dash_build_path = root_path.join("build");
|
||||
let bls_dash_src_path = root_path.join("src");
|
||||
let c_bindings_path = root_path.join("rust-bindings/bls-dash-sys/c-bindings");
|
||||
|
||||
println!("root {}", root_path.display());
|
||||
println!("bls_dash_build_path {}", bls_dash_build_path.display());
|
||||
println!("bls_dash_src_path {}", bls_dash_src_path.display());
|
||||
// println!("c_bindings_path {}", c_bindings_path.display());
|
||||
|
||||
// Run cmake
|
||||
|
||||
println!("Run cmake:");
|
||||
|
||||
if bls_dash_build_path.exists() {
|
||||
fs::remove_dir_all(&bls_dash_build_path).expect("can't clean build directory");
|
||||
}
|
||||
|
||||
fs::create_dir_all(&bls_dash_build_path).expect("can't create build directory");
|
||||
|
||||
let cmake_output = create_cross_cmake_command()
|
||||
.current_dir(&bls_dash_build_path)
|
||||
.arg("-DBUILD_BLS_PYTHON_BINDINGS=0")
|
||||
.arg("-DBUILD_BLS_TESTS=0")
|
||||
.arg("-DBUILD_BLS_BENCHMARKS=0")
|
||||
.arg("-DBUILD_BLS_JS_BINDINGS=0")
|
||||
.arg("..")
|
||||
.output()
|
||||
.expect("can't run cmake");
|
||||
|
||||
handle_command_output(cmake_output);
|
||||
|
||||
// Build deps for bls-signatures
|
||||
|
||||
println!("Build dependencies:");
|
||||
|
||||
let build_output = Command::new("cmake")
|
||||
.args(["--build", ".", "--", "-j", "6"])
|
||||
.current_dir(&bls_dash_build_path)
|
||||
.output()
|
||||
.expect("can't build bls-signatures deps");
|
||||
|
||||
handle_command_output(build_output);
|
||||
|
||||
// Collect include paths
|
||||
let include_paths_file_path = bls_dash_build_path.join("include_paths.txt");
|
||||
|
||||
let include_paths =
|
||||
fs::read_to_string(include_paths_file_path).expect("should read include paths from file");
|
||||
|
||||
let mut include_paths: Vec<_> = include_paths
|
||||
.split(';')
|
||||
.filter(|path| !path.is_empty())
|
||||
.map(|path| PathBuf::from(path))
|
||||
.collect();
|
||||
|
||||
include_paths.extend([
|
||||
bls_dash_build_path.join("_deps/relic-src/include"),
|
||||
bls_dash_build_path.join("_deps/relic-build/include"),
|
||||
bls_dash_build_path.join("src"),
|
||||
root_path.join("include/dashbls"),
|
||||
bls_dash_build_path.join("depends/relic/include"),
|
||||
bls_dash_build_path.join("depends/mimalloc/include"),
|
||||
root_path.join("depends/relic/include"),
|
||||
root_path.join("depends/mimalloc/include"),
|
||||
bls_dash_src_path.clone(),
|
||||
]);
|
||||
|
||||
// Build c binding
|
||||
|
||||
println!("Build C binding:");
|
||||
|
||||
let mut cc = cc::Build::new();
|
||||
|
||||
let cpp_files_mask = c_bindings_path.join("**/*.cpp");
|
||||
|
||||
let cpp_files: Vec<_> = glob::glob(cpp_files_mask.to_str().unwrap())
|
||||
.expect("can't get list of cpp files")
|
||||
.filter_map(Result::ok)
|
||||
.collect();
|
||||
|
||||
cc.files(cpp_files)
|
||||
.includes(&include_paths)
|
||||
.cpp(true)
|
||||
.flag_if_supported("-std=c++14");
|
||||
|
||||
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
|
||||
// Fix homebrew LLVM installation issue
|
||||
if env::consts::OS == "macos" && target_arch == "wasm32" {
|
||||
cc.archiver("llvm-ar");
|
||||
}
|
||||
|
||||
if target_arch.eq("wasm32") {
|
||||
cc.flag_if_supported("-ffreestanding")
|
||||
.define("_LIBCPP_HAS_NO_THREADS", Some("1"));
|
||||
}
|
||||
|
||||
if !cfg!(debug_assertions) {
|
||||
cc.opt_level(2);
|
||||
}
|
||||
|
||||
cc.compile("bls-dash-sys");
|
||||
|
||||
// // Link dependencies
|
||||
// println!(
|
||||
// "cargo:rustc-link-search={}",
|
||||
// bls_dash_build_path.join("_deps/sodium-build").display()
|
||||
// );
|
||||
|
||||
// println!("cargo:rustc-link-lib=static=sodium");
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search={}",
|
||||
root_path.join("build/depends/relic/lib").display()
|
||||
);
|
||||
|
||||
println!("cargo:rustc-link-lib=static=relic_s");
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search={}",
|
||||
root_path.join("build/depends/mimalloc").display()
|
||||
);
|
||||
|
||||
println!("cargo:rustc-link-lib=static=mimalloc-secure");
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search={}",
|
||||
bls_dash_build_path.join("src").display()
|
||||
);
|
||||
|
||||
println!("cargo:rustc-link-lib=static=dashbls");
|
||||
|
||||
// Link GMP if exists
|
||||
let gmp_libraries_file_path = bls_dash_build_path.join("gmp_libraries.txt");
|
||||
|
||||
if gmp_libraries_file_path.exists() {
|
||||
let gmp_libraries_path = PathBuf::from(
|
||||
fs::read_to_string(gmp_libraries_file_path)
|
||||
.expect("should read gmp includes from file"),
|
||||
);
|
||||
|
||||
let gmp_libraries_parent_path = gmp_libraries_path
|
||||
.parent()
|
||||
.expect("can't get gmp libraries parent dir");
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search={}",
|
||||
gmp_libraries_parent_path.display()
|
||||
);
|
||||
|
||||
println!("cargo:rustc-link-lib=static=gmp");
|
||||
}
|
||||
|
||||
// Generate rust code for c binding to src/lib.rs
|
||||
// println!("Generate C binding for rust:");
|
||||
|
||||
// let mut builder = bindgen::Builder::default()
|
||||
// // .trust_clang_mangling(true)
|
||||
// // .wasm_import_module_name()
|
||||
// .size_t_is_usize(true)
|
||||
// .parse_callbacks(Box::new(bindgen::CargoCallbacks));
|
||||
|
||||
// let headers_to_process = [
|
||||
// "blschia.h",
|
||||
// "elements.h",
|
||||
// "privatekey.h",
|
||||
// "schemes.h",
|
||||
// "threshold.h",
|
||||
// "bip32/chaincode.h",
|
||||
// "bip32/extendedprivatekey.h",
|
||||
// "bip32/extendedpublickey.h",
|
||||
// ];
|
||||
|
||||
// for header in headers_to_process {
|
||||
// builder = builder.header(c_bindings_path.join(header).to_str().unwrap())
|
||||
// }
|
||||
|
||||
// if target_arch == "wasm32" {
|
||||
// builder = builder.clang_args(
|
||||
// include_paths
|
||||
// .iter()
|
||||
// .map(|path| format!("-I{}", path.display())),
|
||||
// );
|
||||
// }
|
||||
|
||||
// let bindings = builder.generate().expect("Unable to generate bindings");
|
||||
|
||||
// let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
|
||||
// bindings
|
||||
// .write_to_file(out_path.join("bindings.rs"))
|
||||
// .expect("couldn't write bindings");
|
||||
|
||||
// // Rerun build if files changed
|
||||
// println!("cargo:rerun-if-changed={}", c_bindings_path.display());
|
||||
println!("cargo:rerun-if-changed={}", bls_dash_src_path.display());
|
||||
}
|
||||
|
||||
// fn main() {
|
||||
// let target = env::var("TARGET").unwrap();
|
||||
// println!("Building bls-signatures for apple target: {}", target);
|
||||
// let root_path = Path::new("../..")
|
||||
// .canonicalize()
|
||||
// .expect("can't get abs path");
|
||||
// let bls_dash_build_path = root_path.join("build");
|
||||
// let bls_dash_src_path = root_path.join("src");
|
||||
// let artefacts_path = bls_dash_build_path.join("artefacts");
|
||||
// let target_path = artefacts_path.join(&target);
|
||||
// let script = root_path.join("apple.rust.single.sh");
|
||||
// if bls_dash_build_path.exists() {
|
||||
// fs::remove_dir_all(&bls_dash_build_path).expect("can't clean build directory");
|
||||
// }
|
||||
// fs::create_dir_all(&bls_dash_build_path).expect("can't create build directory");
|
||||
// let output = Command::new("sh")
|
||||
// .current_dir(&root_path)
|
||||
// .arg(script)
|
||||
// .arg(target)
|
||||
// .output()
|
||||
// .expect("Failed to execute the shell script");
|
||||
// handle_command_output(output);
|
||||
// let library_path = target_path.join("libbls.a");
|
||||
// if !fs::metadata(&library_path).is_ok() {
|
||||
// panic!("Library file not found: {}", library_path.display());
|
||||
// }
|
||||
// println!("cargo:rustc-link-search={}", target_path.display());
|
||||
// println!("cargo:rustc-link-lib=static=gmp");
|
||||
// println!("cargo:rustc-link-lib=static=sodium");
|
||||
// println!("cargo:rustc-link-lib=static=relic_s");
|
||||
// println!("cargo:rustc-link-search={}", bls_dash_build_path.join("src").display());
|
||||
// println!("cargo:rustc-link-lib=static=bls");
|
||||
// println!("cargo:rerun-if-changed={}", bls_dash_src_path.display());
|
||||
// }
|
||||
|
||||
#[cfg(feature = "apple")]
|
||||
fn main() {
|
||||
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
|
||||
// TODO: fix build for wasm32 on MacOS
|
||||
// errors with `error: linking with `rust-lld` failed: exit status: 1`
|
||||
if target_arch.eq("wasm32") {
|
||||
println!("Build for wasm32 is not fully supported");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let target = env::var("TARGET").unwrap();
|
||||
println!("Building bls-signatures for apple target: {}", target);
|
||||
let root_path = Path::new("../..")
|
||||
.canonicalize()
|
||||
.expect("can't get abs path");
|
||||
let bls_dash_build_path = root_path.join("build");
|
||||
let bls_dash_src_path = root_path.join("src");
|
||||
let bls_dash_src_include_path = root_path.join("include/dashbls");
|
||||
let c_bindings_path = root_path.join("rust-bindings/bls-dash-sys/c-bindings");
|
||||
let artefacts_path = bls_dash_build_path.join("artefacts");
|
||||
let target_path = artefacts_path.join(&target);
|
||||
let script = root_path.join("apple.rust.deps.sh");
|
||||
if bls_dash_build_path.exists() {
|
||||
fs::remove_dir_all(&bls_dash_build_path).expect("can't clean build directory");
|
||||
}
|
||||
fs::create_dir_all(&bls_dash_build_path).expect("can't create build directory");
|
||||
let output = Command::new("sh")
|
||||
.current_dir(&root_path)
|
||||
.arg(script)
|
||||
.arg(target.as_str())
|
||||
.output()
|
||||
.expect("Failed to execute the shell script");
|
||||
handle_command_output(output);
|
||||
let (arch, platform) = match target.as_str() {
|
||||
"x86_64-apple-ios" => ("x86_64", "iphonesimulator"),
|
||||
"aarch64-apple-ios" => ("arm64", "iphoneos"),
|
||||
"aarch64-apple-ios-sim" => ("arm64", "iphonesimulator"),
|
||||
"x86_64-apple-darwin" => ("x86_64", "macosx"),
|
||||
"aarch64-apple-darwin" => ("arm64", "macosx"),
|
||||
_ => panic!("Target {} not supported", target.as_str())
|
||||
};
|
||||
env::set_var("IPHONEOS_DEPLOYMENT_TARGET", "13.0");
|
||||
|
||||
// Collect include paths
|
||||
let include_paths_file_path = bls_dash_build_path.join("include_paths.txt");
|
||||
|
||||
let include_paths =
|
||||
fs::read_to_string(include_paths_file_path).expect("should read include paths from file");
|
||||
|
||||
let mut include_paths: Vec<_> = include_paths
|
||||
.split(';')
|
||||
.filter(|path| !path.is_empty())
|
||||
.map(|path| PathBuf::from(path))
|
||||
.collect();
|
||||
|
||||
include_paths.extend([
|
||||
bls_dash_build_path.join(format!("relic-{}-{}/_deps/relic-src/include", platform, arch)),
|
||||
bls_dash_build_path.join(format!("relic-{}-{}/_deps/relic-build/include", platform, arch)),
|
||||
bls_dash_build_path.join("contrib/relic/src"),
|
||||
root_path.join("src"),
|
||||
root_path.join("include/dashbls"),
|
||||
root_path.join("depends/relic/include"),
|
||||
root_path.join("depends/mimalloc/include"),
|
||||
root_path.join("depends/catch2/include"),
|
||||
bls_dash_src_path.clone(),
|
||||
bls_dash_src_include_path.clone()
|
||||
]);
|
||||
|
||||
let cpp_files: Vec<_> = glob::glob(c_bindings_path.join("**/*.cpp").to_str().unwrap())
|
||||
.expect("can't get list of cpp files")
|
||||
.filter_map(Result::ok)
|
||||
.collect();
|
||||
|
||||
let mut cc = cc::Build::new();
|
||||
cc.files(cpp_files)
|
||||
.includes(&include_paths)
|
||||
.cpp(true)
|
||||
.flag("-Wno-unused-parameter")
|
||||
.flag("-Wno-sign-compare")
|
||||
.flag("-Wno-delete-non-abstract-non-virtual-dtor")
|
||||
.flag("-std=c++14");
|
||||
|
||||
cc.compile("dashbls");
|
||||
|
||||
println!("cargo:rustc-link-search={}", target_path.display());
|
||||
println!("cargo:rustc-link-lib=static=gmp");
|
||||
// println!("cargo:rustc-link-lib=static=sodium");
|
||||
// println!("cargo:rustc-link-lib=static=relic_s");
|
||||
println!("cargo:rustc-link-lib=static=bls");
|
||||
println!("cargo:rustc-link-search={}", bls_dash_src_path.display());
|
||||
println!("cargo:rustc-link-lib=static=dashbls");
|
||||
println!("cargo:rerun-if-changed={}", bls_dash_src_path.display());
|
||||
}
|
25
rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.cpp
Normal file
25
rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include <vector>
|
||||
#include "bls.hpp"
|
||||
#include "chaincode.h"
|
||||
|
||||
void* BIP32ChainCodeSerialize(const BIP32ChainCode cc)
|
||||
{
|
||||
const bls::ChainCode* ccPtr = (bls::ChainCode*)cc;
|
||||
const std::vector<uint8_t> serialized = ccPtr->Serialize();
|
||||
uint8_t* buffer = (uint8_t*)malloc(bls::ChainCode::SIZE);
|
||||
memcpy(buffer, serialized.data(), bls::ChainCode::SIZE);
|
||||
return (void*)buffer;
|
||||
}
|
||||
|
||||
bool BIP32ChainCodeIsEqual(const BIP32ChainCode cc1, const BIP32ChainCode cc2)
|
||||
{
|
||||
const bls::ChainCode* cc1Ptr = (bls::ChainCode*)cc1;
|
||||
const bls::ChainCode* cc2Ptr = (bls::ChainCode*)cc2;
|
||||
return *cc1Ptr == *cc2Ptr;
|
||||
}
|
||||
|
||||
void BIP32ChainCodeFree(const BIP32ChainCode cc)
|
||||
{
|
||||
const bls::ChainCode* ccPtr = (bls::ChainCode*)cc;
|
||||
delete ccPtr;
|
||||
}
|
21
rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.h
Normal file
21
rust-bindings/bls-dash-sys/c-bindings/bip32/chaincode.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef BIP32CHAINCODE_H_
|
||||
#define BIP32CHAINCODE_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* BIP32ChainCode;
|
||||
|
||||
void* BIP32ChainCodeSerialize(const BIP32ChainCode cc);
|
||||
bool BIP32ChainCodeIsEqual(const BIP32ChainCode cc1, const BIP32ChainCode cc2);
|
||||
void BIP32ChainCodeFree(const BIP32ChainCode cc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // BIP32CHAINCODE_H_
|
@ -0,0 +1,128 @@
|
||||
#include "extendedprivatekey.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../blschia.h"
|
||||
#include "../error.h"
|
||||
#include "bls.hpp"
|
||||
|
||||
BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyFromBytes(const void* data, bool* didErr)
|
||||
{
|
||||
bls::ExtendedPrivateKey* el = nullptr;
|
||||
try {
|
||||
el = new bls::ExtendedPrivateKey(bls::ExtendedPrivateKey::FromBytes(
|
||||
bls::Bytes((uint8_t*)(data), bls::ExtendedPrivateKey::SIZE)));
|
||||
} catch (const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return el;
|
||||
}
|
||||
|
||||
BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyFromSeed(const void* data, const size_t len, bool* didErr)
|
||||
{
|
||||
bls::ExtendedPrivateKey* el = nullptr;
|
||||
try {
|
||||
el = new bls::ExtendedPrivateKey(bls::ExtendedPrivateKey::FromSeed(
|
||||
bls::Bytes((uint8_t*)(data), len)));
|
||||
} catch (const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return el;
|
||||
}
|
||||
|
||||
BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyPrivateChild(
|
||||
const BIP32ExtendedPrivateKey sk,
|
||||
const uint32_t index,
|
||||
const bool legacy)
|
||||
{
|
||||
const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk;
|
||||
return new bls::ExtendedPrivateKey(skPtr->PrivateChild(index, legacy));
|
||||
}
|
||||
|
||||
BIP32ExtendedPublicKey BIP32ExtendedPrivateKeyPublicChild(
|
||||
const BIP32ExtendedPrivateKey sk,
|
||||
const uint32_t index)
|
||||
{
|
||||
const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk;
|
||||
return new bls::ExtendedPublicKey(skPtr->PublicChild(index));
|
||||
}
|
||||
|
||||
BIP32ChainCode BIP32ExtendedPrivateKeyGetChainCode(const BIP32ExtendedPrivateKey sk)
|
||||
{
|
||||
const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk;
|
||||
return new bls::ChainCode(skPtr->GetChainCode());
|
||||
}
|
||||
|
||||
void* BIP32ExtendedPrivateKeySerialize(const BIP32ExtendedPrivateKey sk)
|
||||
{
|
||||
const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk;
|
||||
uint8_t* buffer =
|
||||
bls::Util::SecAlloc<uint8_t>(bls::ExtendedPrivateKey::SIZE);
|
||||
skPtr->Serialize(buffer);
|
||||
|
||||
return (void*)buffer;
|
||||
}
|
||||
|
||||
bool BIP32ExtendedPrivateKeyIsEqual(
|
||||
const BIP32ExtendedPrivateKey sk1,
|
||||
const BIP32ExtendedPrivateKey sk2)
|
||||
{
|
||||
const bls::ExtendedPrivateKey* sk1Ptr = (bls::ExtendedPrivateKey*)sk1;
|
||||
const bls::ExtendedPrivateKey* sk2Ptr = (bls::ExtendedPrivateKey*)sk2;
|
||||
return *sk1Ptr == *sk2Ptr;
|
||||
}
|
||||
|
||||
void* BIP32ExtendedPrivateKeyGetPrivateKey(const BIP32ExtendedPrivateKey sk)
|
||||
{
|
||||
bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk;
|
||||
return new bls::PrivateKey(skPtr->GetPrivateKey());
|
||||
}
|
||||
|
||||
void* BIP32ExtendedPrivateKeyGetPublicKey(
|
||||
const BIP32ExtendedPrivateKey sk,
|
||||
bool* didErr)
|
||||
{
|
||||
bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk;
|
||||
bls::G1Element* el = nullptr;
|
||||
try {
|
||||
el = new bls::G1Element(skPtr->GetPublicKey());
|
||||
*didErr = false;
|
||||
} catch (const std::exception& ex) {
|
||||
// set err
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
BIP32ExtendedPublicKey BIP32ExtendedPrivateKeyGetExtendedPublicKey(
|
||||
const BIP32ExtendedPrivateKey sk,
|
||||
const bool legacy,
|
||||
bool* didErr)
|
||||
{
|
||||
bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk;
|
||||
bls::ExtendedPublicKey* pk = nullptr;
|
||||
try {
|
||||
pk = new bls::ExtendedPublicKey(skPtr->GetExtendedPublicKey(legacy));
|
||||
*didErr = false;
|
||||
} catch (const std::exception& ex) {
|
||||
// set err
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
return pk;
|
||||
}
|
||||
|
||||
void BIP32ExtendedPrivateKeyFree(const BIP32ExtendedPrivateKey sk)
|
||||
{
|
||||
const bls::ExtendedPrivateKey* skPtr = (bls::ExtendedPrivateKey*)sk;
|
||||
delete skPtr;
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
#ifndef BIP32EXTENDEDPRIVATEKEY_H_
|
||||
#define BIP32EXTENDEDPRIVATEKEY_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "extendedpublickey.h"
|
||||
#include "chaincode.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* BIP32ExtendedPrivateKey;
|
||||
|
||||
// ExtendedPrivateKey
|
||||
BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyFromBytes(
|
||||
const void* data,
|
||||
bool* didErr);
|
||||
BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyFromSeed(const void* data, const size_t len, bool* didErr);
|
||||
BIP32ExtendedPrivateKey BIP32ExtendedPrivateKeyPrivateChild(
|
||||
const BIP32ExtendedPrivateKey sk,
|
||||
const uint32_t index,
|
||||
const bool legacy);
|
||||
BIP32ExtendedPublicKey BIP32ExtendedPrivateKeyPublicChild(
|
||||
const BIP32ExtendedPrivateKey sk,
|
||||
const uint32_t index);
|
||||
BIP32ChainCode BIP32ExtendedPrivateKeyGetChainCode(const BIP32ExtendedPrivateKey sk);
|
||||
void* BIP32ExtendedPrivateKeySerialize(const BIP32ExtendedPrivateKey sk);
|
||||
bool BIP32ExtendedPrivateKeyIsEqual(
|
||||
const BIP32ExtendedPrivateKey sk1,
|
||||
const BIP32ExtendedPrivateKey sk2);
|
||||
void* BIP32ExtendedPrivateKeyGetPrivateKey(const BIP32ExtendedPrivateKey sk);
|
||||
BIP32ExtendedPublicKey BIP32ExtendedPrivateKeyGetExtendedPublicKey(
|
||||
const BIP32ExtendedPrivateKey sk,
|
||||
const bool legacy,
|
||||
bool* didErr);
|
||||
void* BIP32ExtendedPrivateKeyGetPublicKey(
|
||||
const BIP32ExtendedPrivateKey sk,
|
||||
bool* didErr);
|
||||
void BIP32ExtendedPrivateKeyFree(const BIP32ExtendedPrivateKey sk);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // BIP32EXTENDEDPRIVATEKEY_H_
|
@ -0,0 +1,72 @@
|
||||
#include "extendedpublickey.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../blschia.h"
|
||||
#include "../error.h"
|
||||
#include "bls.hpp"
|
||||
|
||||
BIP32ExtendedPublicKey BIP32ExtendedPublicKeyFromBytes(
|
||||
const void* data,
|
||||
const bool legacy,
|
||||
bool* didErr)
|
||||
{
|
||||
bls::ExtendedPublicKey* el = nullptr;
|
||||
try {
|
||||
el = new bls::ExtendedPublicKey(bls::ExtendedPublicKey::FromBytes(
|
||||
bls::Bytes((uint8_t*)(data), bls::ExtendedPublicKey::SIZE),
|
||||
legacy));
|
||||
} catch (const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return el;
|
||||
}
|
||||
|
||||
BIP32ExtendedPublicKey BIP32ExtendedPublicKeyPublicChild(
|
||||
const BIP32ExtendedPublicKey pk,
|
||||
const uint32_t index,
|
||||
const bool legacy)
|
||||
{
|
||||
const bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk;
|
||||
return new bls::ExtendedPublicKey(pkPtr->PublicChild(index, legacy));
|
||||
}
|
||||
|
||||
BIP32ChainCode BIP32ExtendedPublicKeyGetChainCode(const BIP32ExtendedPublicKey pk)
|
||||
{
|
||||
const bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk;
|
||||
return new bls::ChainCode(pkPtr->GetChainCode());
|
||||
}
|
||||
|
||||
void* BIP32ExtendedPublicKeyGetPublicKey(const BIP32ExtendedPublicKey pk) {
|
||||
bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk;
|
||||
return new bls::G1Element(pkPtr->GetPublicKey());
|
||||
}
|
||||
|
||||
void* BIP32ExtendedPublicKeySerialize(
|
||||
const BIP32ExtendedPublicKey pk,
|
||||
const bool legacy)
|
||||
{
|
||||
const bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk;
|
||||
const std::vector<uint8_t> serialized = pkPtr->Serialize(legacy);
|
||||
uint8_t* buffer = (uint8_t*)malloc(bls::ExtendedPublicKey::SIZE);
|
||||
memcpy(buffer, serialized.data(), bls::ExtendedPublicKey::SIZE);
|
||||
return (void*)buffer;
|
||||
}
|
||||
|
||||
bool BIP32ExtendedPublicKeyIsEqual(
|
||||
const BIP32ExtendedPublicKey pk1,
|
||||
const BIP32ExtendedPublicKey pk2)
|
||||
{
|
||||
const bls::ExtendedPublicKey* pk1Ptr = (bls::ExtendedPublicKey*)pk1;
|
||||
const bls::ExtendedPublicKey* pk2Ptr = (bls::ExtendedPublicKey*)pk2;
|
||||
return *pk1Ptr == *pk2Ptr;
|
||||
}
|
||||
|
||||
void BIP32ExtendedPublicKeyFree(const BIP32ExtendedPublicKey pk)
|
||||
{
|
||||
const bls::ExtendedPublicKey* pkPtr = (bls::ExtendedPublicKey*)pk;
|
||||
delete pkPtr;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#ifndef BIP32EXTENDEDPUBLICKEY_H_
|
||||
#define BIP32EXTENDEDPUBLICKEY_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "chaincode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* BIP32ExtendedPublicKey;
|
||||
|
||||
// ExtendedPublicKey
|
||||
BIP32ExtendedPublicKey BIP32ExtendedPublicKeyFromBytes(
|
||||
const void* data,
|
||||
const bool legacy,
|
||||
bool* didErr);
|
||||
BIP32ExtendedPublicKey BIP32ExtendedPublicKeyPublicChild(
|
||||
const BIP32ExtendedPublicKey pk,
|
||||
const uint32_t index,
|
||||
const bool legacy);
|
||||
BIP32ChainCode BIP32ExtendedPublicKeyGetChainCode(const BIP32ExtendedPublicKey pk);
|
||||
void* BIP32ExtendedPublicKeyGetPublicKey(const BIP32ExtendedPublicKey pk);
|
||||
void* BIP32ExtendedPublicKeySerialize(
|
||||
const BIP32ExtendedPublicKey pk,
|
||||
const bool legacy);
|
||||
bool BIP32ExtendedPublicKeyIsEqual(
|
||||
const BIP32ExtendedPublicKey pk1,
|
||||
const BIP32ExtendedPublicKey pk2);
|
||||
void BIP32ExtendedPublicKeyFree(const BIP32ExtendedPublicKey pk);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // BIP32EXTENDEDPUBLICKEY_H_
|
56
rust-bindings/bls-dash-sys/c-bindings/blschia.cpp
Normal file
56
rust-bindings/bls-dash-sys/c-bindings/blschia.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include "bls.hpp"
|
||||
#include "error.h"
|
||||
#include "blschia.h"
|
||||
|
||||
// TODO: Revisit
|
||||
|
||||
std::string gErrMsg;
|
||||
|
||||
void SecFree(void *p) {
|
||||
bls::Util::SecFree(p);
|
||||
}
|
||||
|
||||
void** AllocPtrArray(size_t len) {
|
||||
// caller to free
|
||||
return (void**)bls::Util::SecAlloc<uint8_t>(sizeof(void*) * len);
|
||||
}
|
||||
|
||||
void SetPtrArray(void** arrPtr, void* elemPtr, int index) {
|
||||
arrPtr[index] = elemPtr;
|
||||
}
|
||||
|
||||
void FreePtrArray(void** inPtr) {
|
||||
bls::Util::SecFree(inPtr);
|
||||
}
|
||||
|
||||
void* GetPtrAtIndex(void** arrPtr, int index) {
|
||||
return arrPtr[index];
|
||||
}
|
||||
|
||||
uint8_t* SecAllocBytes(size_t len) {
|
||||
return (uint8_t*)bls::Util::SecAlloc<uint8_t>(sizeof(uint8_t) * len);
|
||||
}
|
||||
|
||||
void* GetAddressAtIndex(uint8_t* ptr, int index) {
|
||||
return (void*)&ptr[index];
|
||||
}
|
||||
|
||||
const char* GetLastErrorMsg() {
|
||||
return gErrMsg.c_str();
|
||||
}
|
46
rust-bindings/bls-dash-sys/c-bindings/blschia.h
Normal file
46
rust-bindings/bls-dash-sys/c-bindings/blschia.h
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef BLSCHIA_H_
|
||||
#define BLSCHIA_H_
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "privatekey.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Export the BLS SecFree method
|
||||
void SecFree(void *p);
|
||||
|
||||
typedef void** carr;
|
||||
|
||||
// Additional C++ helper funcs for allocations
|
||||
void** AllocPtrArray(size_t len);
|
||||
void SetPtrArray(void **arrPtr, void *elemPtr, int index);
|
||||
void FreePtrArray(void **inPtr);
|
||||
void* GetPtrAtIndex(void **arrPtr, int index);
|
||||
|
||||
// Allocates an array of bytes with size of passed in len argument
|
||||
uint8_t* SecAllocBytes(size_t len);
|
||||
|
||||
void* GetAddressAtIndex(uint8_t *ptr, int index);
|
||||
|
||||
const char* GetLastErrorMsg();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // BLSCHIA_H_
|
162
rust-bindings/bls-dash-sys/c-bindings/elements.cpp
Normal file
162
rust-bindings/bls-dash-sys/c-bindings/elements.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <vector>
|
||||
#include "bls.hpp"
|
||||
#include "blschia.h"
|
||||
#include "error.h"
|
||||
#include "elements.h"
|
||||
|
||||
// G1Element
|
||||
int G1ElementSize() {
|
||||
return bls::G1Element::SIZE;
|
||||
}
|
||||
|
||||
G1Element G1ElementFromBytes(const void* data, bool legacy, bool* didErr) {
|
||||
bls::G1Element* el = nullptr;
|
||||
try {
|
||||
el = new bls::G1Element(
|
||||
bls::G1Element::FromBytes(bls::Bytes((uint8_t*)(data), bls::G1Element::SIZE), legacy)
|
||||
);
|
||||
} catch(const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return el;
|
||||
}
|
||||
|
||||
G1Element G1ElementGenerator() {
|
||||
return new bls::G1Element(bls::G1Element::Generator());
|
||||
}
|
||||
|
||||
bool G1ElementIsValid(const G1Element el) {
|
||||
const bls::G1Element* elPtr = (bls::G1Element*)el;
|
||||
return elPtr->IsValid();
|
||||
}
|
||||
|
||||
uint32_t G1ElementGetFingerprint(const G1Element el, const bool legacy) {
|
||||
const bls::G1Element* elPtr = (bls::G1Element*)el;
|
||||
return elPtr->GetFingerprint(legacy);
|
||||
}
|
||||
|
||||
void* G1ElementSerialize(const G1Element el, const bool legacy) {
|
||||
const bls::G1Element* elPtr = (bls::G1Element*)el;
|
||||
const std::vector<uint8_t> serialized = elPtr->Serialize(legacy);
|
||||
uint8_t* buffer = (uint8_t*)malloc(bls::G1Element::SIZE);
|
||||
memcpy(buffer, serialized.data(), bls::G1Element::SIZE);
|
||||
return (void*)buffer;
|
||||
}
|
||||
|
||||
bool G1ElementIsEqual(const G1Element el1, const G1Element el2) {
|
||||
const bls::G1Element* el1Ptr = (bls::G1Element*)el1;
|
||||
const bls::G1Element* el2Ptr = (bls::G1Element*)el2;
|
||||
return *el1Ptr == *el2Ptr;
|
||||
}
|
||||
|
||||
G1Element G1ElementAdd(const G1Element el1, const G1Element el2) {
|
||||
const bls::G1Element* el1Ptr = (bls::G1Element*)el1;
|
||||
const bls::G1Element* el2Ptr = (bls::G1Element*)el2;
|
||||
return new bls::G1Element((*el1Ptr) + (*el2Ptr));
|
||||
}
|
||||
|
||||
G1Element G1ElementMul(const G1Element el, const PrivateKey sk) {
|
||||
const bls::G1Element* elPtr = (bls::G1Element*)el;
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::G1Element(*elPtr * *skPtr);
|
||||
}
|
||||
|
||||
G1Element G1ElementNegate(const G1Element el) {
|
||||
const bls::G1Element* elPtr = (bls::G1Element*)el;
|
||||
return new bls::G1Element(elPtr->Negate());
|
||||
}
|
||||
|
||||
G1Element G1ElementCopy(const G1Element el) {
|
||||
return new bls::G1Element(((bls::G1Element*)el)->Copy());
|
||||
}
|
||||
|
||||
void G1ElementFree(const G1Element el) {
|
||||
const bls::G1Element* elPtr = (bls::G1Element*)el;
|
||||
delete elPtr;
|
||||
}
|
||||
|
||||
// G2Element
|
||||
int G2ElementSize() {
|
||||
return bls::G2Element::SIZE;
|
||||
}
|
||||
|
||||
G2Element G2ElementFromBytes(const void* data, const bool legacy, bool* didErr) {
|
||||
bls::G2Element* el = nullptr;
|
||||
try {
|
||||
el = new bls::G2Element(
|
||||
bls::G2Element::FromBytes(bls::Bytes((uint8_t*)data, bls::G2Element::SIZE), legacy)
|
||||
);
|
||||
*didErr = false;
|
||||
} catch(const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
G2Element G2ElementGenerator() {
|
||||
return new bls::G2Element(bls::G2Element::Generator());
|
||||
}
|
||||
|
||||
bool G2ElementIsValid(const G2Element el) {
|
||||
const bls::G2Element* elPtr = (bls::G2Element*)el;
|
||||
return elPtr->IsValid();
|
||||
}
|
||||
|
||||
void* G2ElementSerialize(const G2Element el, const bool legacy) {
|
||||
const bls::G2Element* elPtr = (bls::G2Element*)el;
|
||||
const std::vector<uint8_t> serialized = elPtr->Serialize(legacy);
|
||||
uint8_t* buffer = (uint8_t*)malloc(bls::G2Element::SIZE);
|
||||
memcpy(buffer, serialized.data(), bls::G2Element::SIZE);
|
||||
return (void*)buffer;
|
||||
}
|
||||
|
||||
bool G2ElementIsEqual(const G2Element el1, const G2Element el2) {
|
||||
const bls::G2Element* el1Ptr = (bls::G2Element*)el1;
|
||||
const bls::G2Element* el2Ptr = (bls::G2Element*)el2;
|
||||
return *el1Ptr == *el2Ptr;
|
||||
}
|
||||
|
||||
G2Element G2ElementAdd(const G2Element el1, const G2Element el2) {
|
||||
bls::G2Element* el1Ptr = (bls::G2Element*)el1;
|
||||
bls::G2Element* el2Ptr = (bls::G2Element*)el2;
|
||||
return new bls::G2Element(*el1Ptr + *el2Ptr);
|
||||
}
|
||||
|
||||
G2Element G2ElementMul(const G2Element el, const PrivateKey sk) {
|
||||
const bls::G2Element* elPtr = (bls::G2Element*)el;
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::G2Element(*elPtr * *skPtr);
|
||||
}
|
||||
|
||||
G2Element G2ElementNegate(const G2Element el) {
|
||||
const bls::G2Element* elPtr = (bls::G2Element*)el;
|
||||
return new bls::G2Element(elPtr->Negate());
|
||||
}
|
||||
|
||||
G2Element G2ElementCopy(const G1Element el) {
|
||||
return new bls::G2Element(((bls::G2Element*)el)->Copy());
|
||||
}
|
||||
|
||||
void G2ElementFree(const G2Element el) {
|
||||
bls::G2Element* elPtr = (bls::G2Element*)el;
|
||||
delete elPtr;
|
||||
}
|
58
rust-bindings/bls-dash-sys/c-bindings/elements.h
Normal file
58
rust-bindings/bls-dash-sys/c-bindings/elements.h
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ELEMENTS_H_
|
||||
#define ELEMENTS_H_
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* G1Element;
|
||||
typedef void* G2Element;
|
||||
typedef void* PrivateKey;
|
||||
|
||||
// G1Element
|
||||
int G1ElementSize();
|
||||
G1Element G1ElementFromBytes(const void* data, const bool legacy, bool* didErr);
|
||||
G1Element G1ElementGenerator();
|
||||
bool G1ElementIsValid(const G1Element el);
|
||||
uint32_t G1ElementGetFingerprint(const G1Element el, const bool legacy);
|
||||
bool G1ElementIsEqual(const G1Element el1, const G1Element el2);
|
||||
G1Element G1ElementAdd(const G1Element el1, const G1Element el2);
|
||||
G1Element G1ElementMul(const G1Element el, const PrivateKey sk);
|
||||
G1Element G1ElementNegate(const G1Element el);
|
||||
G1Element G1ElementCopy(const G1Element el);
|
||||
void* G1ElementSerialize(const G1Element el, const bool legacy);
|
||||
void G1ElementFree(const G1Element el);
|
||||
|
||||
// G2Element
|
||||
int G2ElementSize();
|
||||
G2Element G2ElementFromBytes(const void* data, const bool legacy, bool* didErr);
|
||||
G2Element G2ElementGenerator();
|
||||
bool G2ElementIsValid(const G2Element el);
|
||||
bool G2ElementIsEqual(const G2Element el1, const G2Element el2);
|
||||
G2Element G2ElementAdd(const G2Element el1, const G2Element el2);
|
||||
G2Element G2ElementMul(const G2Element el, const PrivateKey sk);
|
||||
G2Element G2ElementNegate(const G2Element el);
|
||||
G2Element G2ElementCopy(const G2Element el);
|
||||
void* G2ElementSerialize(const G2Element el, const bool legacy);
|
||||
void G2ElementFree(const G2Element el);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // ELEMENTS_H_
|
21
rust-bindings/bls-dash-sys/c-bindings/error.h
Normal file
21
rust-bindings/bls-dash-sys/c-bindings/error.h
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2020 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ERROR_H_
|
||||
#define ERROR_H_
|
||||
#include <string>
|
||||
|
||||
extern std::string gErrMsg;
|
||||
|
||||
#endif // ERROR_H_
|
120
rust-bindings/bls-dash-sys/c-bindings/privatekey.cpp
Normal file
120
rust-bindings/bls-dash-sys/c-bindings/privatekey.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <vector>
|
||||
#include "bls.hpp"
|
||||
#include "privatekey.h"
|
||||
#include "blschia.h"
|
||||
#include "error.h"
|
||||
#include "utils.hpp"
|
||||
|
||||
// private key bindings implementation
|
||||
PrivateKey PrivateKeyFromBytes(const void* data, const bool modOrder, bool* didErr) {
|
||||
bls::PrivateKey* skPtr = nullptr;
|
||||
try {
|
||||
skPtr = new bls::PrivateKey(
|
||||
bls::PrivateKey::FromBytes(
|
||||
bls::Bytes((uint8_t*)data, bls::PrivateKey::PRIVATE_KEY_SIZE),
|
||||
modOrder
|
||||
)
|
||||
);
|
||||
} catch (const std::exception& ex) {
|
||||
// set err
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return skPtr;
|
||||
}
|
||||
|
||||
PrivateKey PrivateKeyFromSeedBIP32(const void* data, const size_t len) {
|
||||
return new bls::PrivateKey(
|
||||
bls::PrivateKey::FromSeedBIP32(bls::Bytes((uint8_t*)data, len))
|
||||
);
|
||||
}
|
||||
|
||||
PrivateKey PrivateKeyAggregate(void** sks, const size_t len) {
|
||||
return new bls::PrivateKey(
|
||||
bls::PrivateKey::Aggregate(toBLSVector<bls::PrivateKey>(sks, len))
|
||||
);
|
||||
}
|
||||
|
||||
void* PrivateKeySerialize(const PrivateKey sk) {
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
uint8_t* buffer = bls::Util::SecAlloc<uint8_t>(bls::PrivateKey::PRIVATE_KEY_SIZE);
|
||||
skPtr->Serialize(buffer);
|
||||
|
||||
return (void*)buffer;
|
||||
}
|
||||
|
||||
size_t PrivateKeySizeBytes() {
|
||||
return bls::PrivateKey::PRIVATE_KEY_SIZE;
|
||||
}
|
||||
|
||||
bool PrivateKeyIsEqual(const PrivateKey sk1, const PrivateKey sk2) {
|
||||
const bls::PrivateKey* sk1Ptr = (bls::PrivateKey*)sk1;
|
||||
const bls::PrivateKey* sk2Ptr = (bls::PrivateKey*)sk2;
|
||||
return *sk1Ptr == *sk2Ptr;
|
||||
}
|
||||
|
||||
G1Element PrivateKeyGetG1Element(const PrivateKey sk, bool* didErr) {
|
||||
bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
bls::G1Element* el = nullptr;
|
||||
try {
|
||||
el = new bls::G1Element(skPtr->GetG1Element());
|
||||
*didErr = false;
|
||||
} catch (const std::exception& ex) {
|
||||
// set err
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
G2Element PrivateKeyGetG2Element(const PrivateKey sk, bool* didErr) {
|
||||
bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
bls::G2Element* el = nullptr;
|
||||
try {
|
||||
el = new bls::G2Element(skPtr->GetG2Element());
|
||||
*didErr = false;
|
||||
} catch (const std::exception& ex) {
|
||||
// set err
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
G2Element PrivateKeyGetG2Power(const PrivateKey sk, const G2Element el) {
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
const bls::G2Element* elPtr = (bls::G2Element*)el;
|
||||
return new bls::G2Element(skPtr->GetG2Power(*elPtr));
|
||||
}
|
||||
|
||||
G2Element PrivateKeySignG2(const PrivateKey sk,
|
||||
uint8_t* msg,
|
||||
const size_t len,
|
||||
const uint8_t* dst,
|
||||
const size_t dstLen) {
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::G2Element(skPtr->SignG2(msg, len, dst, dstLen));
|
||||
}
|
||||
|
||||
void PrivateKeyFree(PrivateKey sk) {
|
||||
bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
delete skPtr;
|
||||
}
|
40
rust-bindings/bls-dash-sys/c-bindings/privatekey.h
Normal file
40
rust-bindings/bls-dash-sys/c-bindings/privatekey.h
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PRIVATEKEY_H_
|
||||
#define PRIVATEKEY_H_
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "elements.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* PrivateKey;
|
||||
|
||||
PrivateKey PrivateKeyFromBytes(const void* data, const bool modOrder, bool* didErr);
|
||||
PrivateKey PrivateKeyFromSeedBIP32(const void* data, const size_t len);
|
||||
PrivateKey PrivateKeyAggregate(void** sks, const size_t len);
|
||||
G1Element PrivateKeyGetG1Element(const PrivateKey sk, bool* didErr);
|
||||
G2Element PrivateKeyGetG2Element(const PrivateKey sk, bool* didErr);
|
||||
G2Element PrivateKeyGetG2Power(const PrivateKey sk, const G2Element el);
|
||||
bool PrivateKeyIsEqual(const PrivateKey sk1, const PrivateKey sk2);
|
||||
void* PrivateKeySerialize(const PrivateKey sk);
|
||||
void PrivateKeyFree(const PrivateKey sk);
|
||||
size_t PrivateKeySizeBytes();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // PRIVATEKEY_H_
|
388
rust-bindings/bls-dash-sys/c-bindings/schemes.cpp
Normal file
388
rust-bindings/bls-dash-sys/c-bindings/schemes.cpp
Normal file
@ -0,0 +1,388 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "schemes.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "bls.hpp"
|
||||
#include "blschia.h"
|
||||
#include "elements.h"
|
||||
#include "error.h"
|
||||
#include "privatekey.h"
|
||||
#include "utils.hpp"
|
||||
|
||||
// Implementation of bindings for CoreMPL class
|
||||
|
||||
PrivateKey CoreMPLKeyGen(
|
||||
const CoreMPL scheme,
|
||||
const void* seed,
|
||||
const size_t seedLen,
|
||||
bool* didErr)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
bls::PrivateKey* sk = nullptr;
|
||||
try {
|
||||
sk = new bls::PrivateKey(
|
||||
schemePtr->KeyGen(bls::Bytes((uint8_t*)seed, seedLen)));
|
||||
} catch (const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return sk;
|
||||
}
|
||||
|
||||
G1Element CoreMPLSkToG1(const CoreMPL scheme, const PrivateKey sk)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::G1Element(schemePtr->SkToG1(*skPtr));
|
||||
}
|
||||
|
||||
G2Element CoreMPLSign(
|
||||
CoreMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const void* msg,
|
||||
const size_t msgLen)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::G2Element(
|
||||
schemePtr->Sign(*skPtr, bls::Bytes((uint8_t*)msg, msgLen)));
|
||||
}
|
||||
|
||||
bool CoreMPLVerify(
|
||||
const CoreMPL scheme,
|
||||
const G1Element pk,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G2Element sig)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
const bls::G1Element* pkPtr = (bls::G1Element*)pk;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
return schemePtr->Verify(
|
||||
*pkPtr, bls::Bytes((uint8_t*)msg, msgLen), *sigPtr);
|
||||
}
|
||||
|
||||
bool CoreMPLVerifySecure(
|
||||
const CoreMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
const G2Element sig,
|
||||
const void* msg,
|
||||
const size_t msgLen)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
const std::vector<bls::G1Element> vecPubKeys =
|
||||
toBLSVector<bls::G1Element>(pks, pksLen);
|
||||
const uint8_t* msgPtr = (uint8_t*)msg;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
return schemePtr->VerifySecure(
|
||||
vecPubKeys, *sigPtr, bls::Bytes(msgPtr, msgLen));
|
||||
}
|
||||
|
||||
G1Element CoreMPLAggregatePubKeys(
|
||||
const CoreMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
return new bls::G1Element(
|
||||
schemePtr->Aggregate(toBLSVector<bls::G1Element>(pks, pksLen)));
|
||||
}
|
||||
|
||||
G2Element CoreMPLAggregateSigs(
|
||||
const CoreMPL scheme,
|
||||
void** sigs,
|
||||
const size_t sigsLen)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
return new bls::G2Element(
|
||||
schemePtr->Aggregate(toBLSVector<bls::G2Element>(sigs, sigsLen)));
|
||||
}
|
||||
|
||||
PrivateKey CoreMPLDeriveChildSk(
|
||||
const CoreMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const uint32_t index)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::PrivateKey(schemePtr->DeriveChildSk(*skPtr, index));
|
||||
}
|
||||
|
||||
PrivateKey CoreMPLDeriveChildSkUnhardened(
|
||||
CoreMPL scheme,
|
||||
PrivateKey sk,
|
||||
uint32_t index)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::PrivateKey(
|
||||
schemePtr->DeriveChildSkUnhardened(*skPtr, index));
|
||||
}
|
||||
|
||||
G1Element CoreMPLDeriveChildPkUnhardened(
|
||||
CoreMPL scheme,
|
||||
G1Element el,
|
||||
uint32_t index)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
bls::G1Element* elPtr = (bls::G1Element*)el;
|
||||
return new bls::G1Element(
|
||||
schemePtr->DeriveChildPkUnhardened(*elPtr, index));
|
||||
}
|
||||
|
||||
bool CoreMPLAggregateVerify(
|
||||
const CoreMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
void** msgs,
|
||||
const void* msgsLens,
|
||||
const size_t msgsLen,
|
||||
const G2Element sig)
|
||||
{
|
||||
bls::CoreMPL* schemePtr = (bls::CoreMPL*)scheme;
|
||||
const size_t* msgLensPtr = (size_t*)msgsLens;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
const std::vector<bls::G1Element> vecPubKeys =
|
||||
toBLSVector<bls::G1Element>(pks, pksLen);
|
||||
const std::vector<size_t> vecMsgsLens =
|
||||
std::vector<size_t>(msgLensPtr, msgLensPtr + msgsLen);
|
||||
const std::vector<bls::Bytes> vecMsgs =
|
||||
toVectorBytes(msgs, msgsLen, vecMsgsLens);
|
||||
return schemePtr->AggregateVerify(vecPubKeys, vecMsgs, *sigPtr);
|
||||
}
|
||||
|
||||
// BasicSchemeMPL
|
||||
BasicSchemeMPL NewBasicSchemeMPL() { return new bls::BasicSchemeMPL(); }
|
||||
|
||||
bool BasicSchemeMPLAggregateVerify(
|
||||
BasicSchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
void** msgs,
|
||||
const void* msgsLens,
|
||||
const size_t msgsLen,
|
||||
const G2Element sig)
|
||||
{
|
||||
bls::BasicSchemeMPL* schemePtr = (bls::BasicSchemeMPL*)scheme;
|
||||
const size_t* msgLensPtr = (size_t*)msgsLens;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
const std::vector<bls::G1Element> vecPubKeys =
|
||||
toBLSVector<bls::G1Element>(pks, pksLen);
|
||||
const std::vector<size_t> vecMsgsLens =
|
||||
std::vector<size_t>(msgLensPtr, msgLensPtr + msgsLen);
|
||||
const std::vector<bls::Bytes> vecMsgs =
|
||||
toVectorBytes(msgs, msgsLen, vecMsgsLens);
|
||||
return schemePtr->AggregateVerify(vecPubKeys, vecMsgs, *sigPtr);
|
||||
}
|
||||
|
||||
void BasicSchemeMPLFree(BasicSchemeMPL scheme)
|
||||
{
|
||||
bls::BasicSchemeMPL* schemePtr = (bls::BasicSchemeMPL*)scheme;
|
||||
delete schemePtr;
|
||||
}
|
||||
|
||||
// AugSchemeMPL
|
||||
AugSchemeMPL NewAugSchemeMPL() { return new bls::AugSchemeMPL(); }
|
||||
|
||||
G2Element AugSchemeMPLSign(
|
||||
const AugSchemeMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const void* msg,
|
||||
const size_t msgLen)
|
||||
{
|
||||
bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme;
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::G2Element(
|
||||
schemePtr->Sign(*skPtr, bls::Bytes((uint8_t*)msg, msgLen)));
|
||||
}
|
||||
|
||||
G2Element AugSchemeMPLSignPrepend(
|
||||
const AugSchemeMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G1Element prepPk)
|
||||
{
|
||||
bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme;
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
const bls::G1Element* prepPkPtr = (bls::G1Element*)prepPk;
|
||||
return new bls::G2Element(
|
||||
schemePtr->Sign(*skPtr, bls::Bytes((uint8_t*)msg, msgLen), *prepPkPtr));
|
||||
}
|
||||
|
||||
bool AugSchemeMPLVerify(
|
||||
const AugSchemeMPL scheme,
|
||||
const G1Element pk,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G2Element sig)
|
||||
{
|
||||
bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme;
|
||||
const bls::G1Element* pkPtr = (bls::G1Element*)pk;
|
||||
const uint8_t* msgPtr = (uint8_t*)msg;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
return schemePtr->Verify(*pkPtr, bls::Bytes(msgPtr, msgLen), *sigPtr);
|
||||
}
|
||||
|
||||
bool AugSchemeMPLAggregateVerify(
|
||||
const AugSchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
void** msgs,
|
||||
const void* msgsLens,
|
||||
const size_t msgsLen,
|
||||
const G2Element sig)
|
||||
{
|
||||
bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme;
|
||||
const size_t* msgLensPtr = (size_t*)msgsLens;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
const std::vector<bls::G1Element> vecPubKeys =
|
||||
toBLSVector<bls::G1Element>(pks, pksLen);
|
||||
const std::vector<size_t> vecMsgsLens =
|
||||
std::vector<size_t>(msgLensPtr, msgLensPtr + msgsLen);
|
||||
const std::vector<bls::Bytes> vecMsgs =
|
||||
toVectorBytes(msgs, msgsLen, vecMsgsLens);
|
||||
return schemePtr->AggregateVerify(vecPubKeys, vecMsgs, *sigPtr);
|
||||
}
|
||||
|
||||
void AugSchemeMPLFree(AugSchemeMPL scheme)
|
||||
{
|
||||
bls::AugSchemeMPL* schemePtr = (bls::AugSchemeMPL*)scheme;
|
||||
delete schemePtr;
|
||||
}
|
||||
|
||||
// PopSchemeMPL
|
||||
PopSchemeMPL NewPopSchemeMPL() { return new bls::PopSchemeMPL(); }
|
||||
|
||||
G2Element PopSchemeMPLPopProve(
|
||||
const PopSchemeMPL scheme,
|
||||
const PrivateKey sk)
|
||||
{
|
||||
bls::PopSchemeMPL* schemePtr = (bls::PopSchemeMPL*)scheme;
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::G2Element(schemePtr->PopProve(*skPtr));
|
||||
}
|
||||
|
||||
bool PopSchemeMPLPopVerify(
|
||||
const PopSchemeMPL scheme,
|
||||
const G1Element pk,
|
||||
const G2Element sig)
|
||||
{
|
||||
bls::PopSchemeMPL* schemePtr = (bls::PopSchemeMPL*)scheme;
|
||||
const bls::G1Element* pkPtr = (bls::G1Element*)pk;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
return schemePtr->PopVerify(*pkPtr, *sigPtr);
|
||||
}
|
||||
|
||||
bool PopSchemeMPLFastAggregateVerify(
|
||||
const PopSchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G2Element sig)
|
||||
{
|
||||
bls::PopSchemeMPL* schemePtr = (bls::PopSchemeMPL*)scheme;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
const std::vector<bls::G1Element> vecPubKeys =
|
||||
toBLSVector<bls::G1Element>(pks, pksLen);
|
||||
return schemePtr->FastAggregateVerify(
|
||||
vecPubKeys, bls::Bytes((uint8_t*)msg, msgLen), *sigPtr);
|
||||
}
|
||||
|
||||
void PopSchemeMPLFree(PopSchemeMPL scheme)
|
||||
{
|
||||
bls::PopSchemeMPL* schemePtr = (bls::PopSchemeMPL*)scheme;
|
||||
delete schemePtr;
|
||||
}
|
||||
|
||||
// LegacySchemeMPL
|
||||
LegacySchemeMPL NewLegacySchemeMPL() { return new bls::LegacySchemeMPL(); }
|
||||
|
||||
G2Element LegacySchemeMPLSign(
|
||||
const LegacySchemeMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const void* msg,
|
||||
const size_t msgLen)
|
||||
{
|
||||
bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme;
|
||||
const bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::G2Element(
|
||||
schemePtr->Sign(*skPtr, bls::Bytes((uint8_t*)msg, msgLen)));
|
||||
}
|
||||
|
||||
bool LegacySchemeMPLVerify(
|
||||
const LegacySchemeMPL scheme,
|
||||
const G1Element pk,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G2Element sig)
|
||||
{
|
||||
bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme;
|
||||
const bls::G1Element* pkPtr = (bls::G1Element*)pk;
|
||||
const uint8_t* msgPtr = (uint8_t*)msg;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
return schemePtr->Verify(*pkPtr, bls::Bytes(msgPtr, msgLen), *sigPtr);
|
||||
}
|
||||
|
||||
bool LegacySchemeMPLVerifySecure(
|
||||
const LegacySchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
const G2Element sig,
|
||||
const void* msg,
|
||||
const size_t msgLen)
|
||||
{
|
||||
bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme;
|
||||
const std::vector<bls::G1Element> vecPubKeys =
|
||||
toBLSVector<bls::G1Element>(pks, pksLen);
|
||||
const uint8_t* msgPtr = (uint8_t*)msg;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
// Because of scheme pointer it will call CoreMPL::VerifySecure with 'legacy' flag variant
|
||||
return schemePtr->VerifySecure(
|
||||
vecPubKeys, *sigPtr, bls::Bytes(msgPtr, msgLen));
|
||||
}
|
||||
|
||||
bool LegacySchemeMPLAggregateVerify(
|
||||
const LegacySchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
void** msgs,
|
||||
const void* msgsLens,
|
||||
const size_t msgsLen,
|
||||
const G2Element sig)
|
||||
{
|
||||
bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme;
|
||||
const size_t* msgLensPtr = (size_t*)msgsLens;
|
||||
const bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
const std::vector<bls::G1Element> vecPubKeys =
|
||||
toBLSVector<bls::G1Element>(pks, pksLen);
|
||||
const std::vector<size_t> vecMsgsLens =
|
||||
std::vector<size_t>(msgLensPtr, msgLensPtr + msgsLen);
|
||||
const std::vector<bls::Bytes> vecMsgs =
|
||||
toVectorBytes(msgs, msgsLen, vecMsgsLens);
|
||||
return schemePtr->AggregateVerify(vecPubKeys, vecMsgs, *sigPtr);
|
||||
}
|
||||
|
||||
void LegacySchemeMPLFree(LegacySchemeMPL scheme)
|
||||
{
|
||||
bls::LegacySchemeMPL* schemePtr = (bls::LegacySchemeMPL*)scheme;
|
||||
delete schemePtr;
|
||||
}
|
184
rust-bindings/bls-dash-sys/c-bindings/schemes.h
Normal file
184
rust-bindings/bls-dash-sys/c-bindings/schemes.h
Normal file
@ -0,0 +1,184 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SCHEMES_H_
|
||||
#define SCHEMES_H_
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "elements.h"
|
||||
#include "privatekey.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* CoreMPL;
|
||||
typedef CoreMPL BasicSchemeMPL;
|
||||
typedef CoreMPL AugSchemeMPL;
|
||||
typedef CoreMPL PopSchemeMPL;
|
||||
typedef CoreMPL LegacySchemeMPL;
|
||||
|
||||
// CoreMPL
|
||||
PrivateKey CoreMPLKeyGen(
|
||||
const CoreMPL scheme,
|
||||
const void* seed,
|
||||
const size_t seedLen,
|
||||
bool* didErr);
|
||||
G1Element CoreMPLSkToG1(const CoreMPL scheme, const PrivateKey sk);
|
||||
G2Element CoreMPLSign(
|
||||
const CoreMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const void* msg,
|
||||
const size_t msgLen);
|
||||
bool CoreMPLVerify(
|
||||
const BasicSchemeMPL scheme,
|
||||
const G1Element pk,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G2Element sig);
|
||||
bool CoreMPLVerifySecure(
|
||||
const CoreMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
const G2Element sig,
|
||||
const void* msg,
|
||||
const size_t msgLen);
|
||||
G1Element CoreMPLAggregatePubKeys(
|
||||
const CoreMPL scheme,
|
||||
void** pubKeys,
|
||||
const size_t pkLen);
|
||||
G2Element CoreMPLAggregateSigs(
|
||||
const CoreMPL scheme,
|
||||
void** sigs,
|
||||
const size_t sigLen);
|
||||
PrivateKey CoreMPLDeriveChildSk(
|
||||
const CoreMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const uint32_t index);
|
||||
PrivateKey CoreMPLDeriveChildSkUnhardened(
|
||||
const CoreMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const uint32_t index);
|
||||
G1Element CoreMPLDeriveChildPkUnhardened(
|
||||
const CoreMPL scheme,
|
||||
const G1Element sk,
|
||||
const uint32_t index);
|
||||
bool CoreMPLAggregateVerify(
|
||||
const CoreMPL scheme,
|
||||
void** pks,
|
||||
const size_t pkLen,
|
||||
void** msgs,
|
||||
const void* msgLens,
|
||||
const size_t msgLen,
|
||||
const G2Element sig);
|
||||
|
||||
// BasicSchemeMPL
|
||||
BasicSchemeMPL NewBasicSchemeMPL();
|
||||
bool BasicSchemeMPLAggregateVerify(
|
||||
BasicSchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
void** msgs,
|
||||
const void* msgsLens,
|
||||
const size_t msgsLen,
|
||||
const G2Element sig);
|
||||
void BasicSchemeMPLFree(BasicSchemeMPL scheme);
|
||||
|
||||
// AugSchemeMPL
|
||||
AugSchemeMPL NewAugSchemeMPL();
|
||||
G2Element AugSchemeMPLSign(
|
||||
const AugSchemeMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const void* msg,
|
||||
const size_t msgLen);
|
||||
G2Element AugSchemeMPLSignPrepend(
|
||||
const AugSchemeMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G1Element prepPk);
|
||||
bool AugSchemeMPLVerify(
|
||||
const AugSchemeMPL scheme,
|
||||
const G1Element pk,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G2Element sig);
|
||||
bool AugSchemeMPLAggregateVerify(
|
||||
const AugSchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
void** msgs,
|
||||
const void* msgsLens,
|
||||
const size_t msgsLen,
|
||||
const G2Element sig);
|
||||
void AugSchemeMPLFree(AugSchemeMPL scheme);
|
||||
|
||||
// PopSchemeMPL
|
||||
PopSchemeMPL NewPopSchemeMPL();
|
||||
G2Element PopSchemeMPLPopProve(
|
||||
const PopSchemeMPL scheme,
|
||||
const PrivateKey sk);
|
||||
bool PopSchemeMPLPopVerify(
|
||||
const PopSchemeMPL scheme,
|
||||
const G1Element pk,
|
||||
const G2Element sig);
|
||||
bool PopSchemeMPLFastAggregateVerify(
|
||||
const PopSchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
const void* msgs,
|
||||
const size_t msgsLen,
|
||||
const G2Element sig);
|
||||
void PopSchemeMPLFree(PopSchemeMPL scheme);
|
||||
|
||||
// LegacySchemeMPL
|
||||
LegacySchemeMPL NewLegacySchemeMPL();
|
||||
G2Element LegacySchemeMPLSign(
|
||||
const LegacySchemeMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const void* msg,
|
||||
const size_t msgLen);
|
||||
G2Element LegacySchemeMPLSignPrepend(
|
||||
const LegacySchemeMPL scheme,
|
||||
const PrivateKey sk,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G1Element prepPk);
|
||||
bool LegacySchemeMPLVerify(
|
||||
const LegacySchemeMPL scheme,
|
||||
const G1Element pk,
|
||||
const void* msg,
|
||||
const size_t msgLen,
|
||||
const G2Element sig);
|
||||
bool LegacySchemeMPLVerifySecure(
|
||||
const LegacySchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
const G2Element sig,
|
||||
const void* msg,
|
||||
const size_t msgLen);
|
||||
bool LegacySchemeMPLAggregateVerify(
|
||||
const LegacySchemeMPL scheme,
|
||||
void** pks,
|
||||
const size_t pksLen,
|
||||
void** msgs,
|
||||
const void* msgsLens,
|
||||
const size_t msgsLen,
|
||||
const G2Element sig);
|
||||
void LegacySchemeMPLFree(LegacySchemeMPL scheme);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // SCHEMES_H_
|
168
rust-bindings/bls-dash-sys/c-bindings/threshold.cpp
Normal file
168
rust-bindings/bls-dash-sys/c-bindings/threshold.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include "bls.hpp"
|
||||
#include "privatekey.h"
|
||||
#include "elements.h"
|
||||
#include "blschia.h"
|
||||
#include "threshold.h"
|
||||
#include "utils.hpp"
|
||||
#include "error.h"
|
||||
|
||||
std::vector<bls::Bytes> toVectorHashes(void** elems, const size_t len) {
|
||||
std::vector<bls::Bytes> vec;
|
||||
vec.reserve(len);
|
||||
for (int i = 0 ; i < len; ++i) {
|
||||
vec.push_back(
|
||||
bls::Bytes((uint8_t*)elems[i], HashSize)
|
||||
);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
PrivateKey ThresholdPrivateKeyShare(void** sks, const size_t sksLen, const void* hash, bool* didErr) {
|
||||
bls::PrivateKey* sk = nullptr;
|
||||
try {
|
||||
sk = new bls::PrivateKey(
|
||||
bls::Threshold::PrivateKeyShare(
|
||||
toBLSVector<bls::PrivateKey>(sks, sksLen),
|
||||
bls::Bytes((uint8_t*)hash, HashSize)
|
||||
)
|
||||
);
|
||||
} catch(const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return sk;
|
||||
}
|
||||
|
||||
PrivateKey ThresholdPrivateKeyRecover(void** sks,
|
||||
const size_t sksLen,
|
||||
void** hashes,
|
||||
const size_t hashesLen,
|
||||
bool* didErr) {
|
||||
bls::PrivateKey* sk = nullptr;
|
||||
std::vector<bls::Bytes> pop = toVectorHashes(hashes, hashesLen);
|
||||
try {
|
||||
sk = new bls::PrivateKey(
|
||||
bls::Threshold::PrivateKeyRecover(
|
||||
toBLSVector<bls::PrivateKey>(sks, sksLen),
|
||||
toVectorHashes(hashes, hashesLen)
|
||||
)
|
||||
);
|
||||
} catch(const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return sk;
|
||||
}
|
||||
|
||||
G1Element ThresholdPublicKeyShare(void** pks, const size_t pksLen, const void* hash, bool* didErr) {
|
||||
bls::G1Element* el = nullptr;
|
||||
try {
|
||||
el = new bls::G1Element(
|
||||
bls::Threshold::PublicKeyShare(
|
||||
toBLSVector<bls::G1Element>(pks, pksLen),
|
||||
bls::Bytes((uint8_t*)hash, HashSize)
|
||||
)
|
||||
);
|
||||
} catch(const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return el;
|
||||
}
|
||||
|
||||
G1Element ThresholdPublicKeyRecover(void** pks,
|
||||
const size_t pksLen,
|
||||
void** hashes,
|
||||
const size_t hashesLen,
|
||||
bool* didErr) {
|
||||
bls::G1Element* el = nullptr;
|
||||
try {
|
||||
el = new bls::G1Element(
|
||||
bls::Threshold::PublicKeyRecover(
|
||||
toBLSVector<bls::G1Element>(pks, pksLen),
|
||||
toVectorHashes(hashes, hashesLen)
|
||||
)
|
||||
);
|
||||
} catch(const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return el;
|
||||
}
|
||||
|
||||
G2Element ThresholdSignatureShare(void** sigs, const size_t sigsLen, const void* hash, bool* didErr) {
|
||||
bls::G2Element* el = nullptr;
|
||||
try {
|
||||
el = new bls::G2Element(
|
||||
bls::Threshold::SignatureShare(
|
||||
toBLSVector<bls::G2Element>(sigs, sigsLen),
|
||||
bls::Bytes((uint8_t*)hash, HashSize)
|
||||
)
|
||||
);
|
||||
} catch(const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return el;
|
||||
}
|
||||
|
||||
G2Element ThresholdSignatureRecover(void** sigs,
|
||||
const size_t sigsLen,
|
||||
void** hashes,
|
||||
const size_t hashesLen,
|
||||
bool* didErr) {
|
||||
bls::G2Element* el = nullptr;
|
||||
try {
|
||||
el = new bls::G2Element(
|
||||
bls::Threshold::SignatureRecover(
|
||||
toBLSVector<bls::G2Element>(sigs, sigsLen),
|
||||
toVectorHashes(hashes, hashesLen)
|
||||
)
|
||||
);
|
||||
} catch(const std::exception& ex) {
|
||||
gErrMsg = ex.what();
|
||||
*didErr = true;
|
||||
return nullptr;
|
||||
}
|
||||
*didErr = false;
|
||||
return el;
|
||||
}
|
||||
|
||||
G2Element ThresholdSign(const PrivateKey sk, const void* hash) {
|
||||
bls::PrivateKey* skPtr = (bls::PrivateKey*)sk;
|
||||
return new bls::G2Element(
|
||||
bls::Threshold::Sign(*skPtr, bls::Bytes((uint8_t*)hash, HashSize))
|
||||
);
|
||||
}
|
||||
|
||||
bool ThresholdVerify(const G1Element pk, const void* hash, const G2Element sig) {
|
||||
bls::G1Element* pkPtr = (bls::G1Element*)pk;
|
||||
bls::G2Element* sigPtr = (bls::G2Element*)sig;
|
||||
return bls::Threshold::Verify(*pkPtr, bls::Bytes((uint8_t*)hash, HashSize), *sigPtr);
|
||||
}
|
55
rust-bindings/bls-dash-sys/c-bindings/threshold.h
Normal file
55
rust-bindings/bls-dash-sys/c-bindings/threshold.h
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THRESHOLD_H_
|
||||
#define THRESHOLD_H_
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "privatekey.h"
|
||||
#include "elements.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const int HashSize = 32;
|
||||
|
||||
PrivateKey ThresholdPrivateKeyShare(void** sks, const size_t sksLen, const void* hash, bool* didErr);
|
||||
PrivateKey ThresholdPrivateKeyRecover(void** sks,
|
||||
const size_t sksLen,
|
||||
void** hashes,
|
||||
const size_t hashesLen,
|
||||
bool* didErr);
|
||||
|
||||
G1Element ThresholdPublicKeyShare(void** pks, const size_t pksLen, const void* hash, bool* didErr);
|
||||
G1Element ThresholdPublicKeyRecover(void** pks,
|
||||
const size_t pksLen,
|
||||
void** hashes,
|
||||
const size_t hashesLen,
|
||||
bool* didErr);
|
||||
|
||||
G2Element ThresholdSignatureShare(void** sigs, const size_t sigsLen, const void* hash, bool* didErr);
|
||||
G2Element ThresholdSignatureRecover(void** sigs,
|
||||
const size_t sigsLen,
|
||||
void** hashes,
|
||||
const size_t hashesLen,
|
||||
bool* didErr);
|
||||
|
||||
G2Element ThresholdSign(const PrivateKey sk, const void* hash);
|
||||
bool ThresholdVerify(const G1Element pk, const void* hash, const G2Element sig);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // THRESHOLD_H_
|
40
rust-bindings/bls-dash-sys/c-bindings/utils.cpp
Normal file
40
rust-bindings/bls-dash-sys/c-bindings/utils.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <vector>
|
||||
#include "bls.hpp"
|
||||
#include "privatekey.h"
|
||||
#include "elements.h"
|
||||
|
||||
// helper functions
|
||||
template <class T>
|
||||
std::vector<T> toBLSVector(void** elems, const size_t len) {
|
||||
std::vector<T> vec;
|
||||
vec.reserve(len);
|
||||
for (int i = 0 ; i < len; ++i) {
|
||||
T* el = (T*)elems[i];
|
||||
vec.push_back(*el);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::vector<bls::Bytes> toVectorBytes(void** elems, const size_t len, const std::vector<size_t> vecElemsLens) {
|
||||
std::vector<bls::Bytes> vec;
|
||||
vec.reserve(len);
|
||||
for (int i = 0 ; i < len; ++i) {
|
||||
uint8_t* elPtr = (uint8_t*)elems[i];
|
||||
vec.push_back(bls::Bytes(elPtr, vecElemsLens[i]));
|
||||
}
|
||||
return vec;
|
||||
}
|
34
rust-bindings/bls-dash-sys/c-bindings/utils.hpp
Normal file
34
rust-bindings/bls-dash-sys/c-bindings/utils.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2021 The Dash Core developers
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "bls.hpp"
|
||||
#include "privatekey.h"
|
||||
#include "elements.h"
|
||||
|
||||
// helper functions
|
||||
template <class T>
|
||||
std::vector<T> toBLSVector(void** elems, const size_t len) {
|
||||
std::vector<T> vec;
|
||||
vec.reserve(len);
|
||||
for (int i = 0 ; i < (int)len; ++i) {
|
||||
const T* el = (T*)elems[i];
|
||||
vec.push_back(*el);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::vector<bls::Bytes> toVectorBytes(void** elems, const size_t len, const std::vector<size_t> vecElemsLens);
|
8
rust-bindings/bls-dash-sys/include.h
Normal file
8
rust-bindings/bls-dash-sys/include.h
Normal file
@ -0,0 +1,8 @@
|
||||
#include "c-bindings/blschia.h"
|
||||
#include "c-bindings/elements.h"
|
||||
#include "c-bindings/privatekey.h"
|
||||
#include "c-bindings/schemes.h"
|
||||
#include "c-bindings/threshold.h"
|
||||
#include "c-bindings/bip32/chaincode.h"
|
||||
#include "c-bindings/bip32/extendedprivatekey.h"
|
||||
#include "c-bindings/bip32/extendedpublickey.h"
|
6
rust-bindings/bls-dash-sys/src/lib.rs
Normal file
6
rust-bindings/bls-dash-sys/src/lib.rs
Normal file
@ -0,0 +1,6 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
// include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
include!("../bindings.rs");
|
79
rust-bindings/bls-dash-sys/tests/sign_and_verify.rs
Normal file
79
rust-bindings/bls-dash-sys/tests/sign_and_verify.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use bls_dash_sys as sys;
|
||||
|
||||
#[test]
|
||||
fn sign_and_verify() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let bad_seed = b"weedseedweedseedweedseedweedseed";
|
||||
|
||||
unsafe {
|
||||
let scheme = sys::NewAugSchemeMPL();
|
||||
let mut did_err = false;
|
||||
|
||||
let sk = sys::CoreMPLKeyGen(
|
||||
scheme,
|
||||
seed.as_ptr() as *const _,
|
||||
seed.len(),
|
||||
&mut did_err as *mut _,
|
||||
);
|
||||
assert!(!did_err);
|
||||
|
||||
let pk = sys::PrivateKeyGetG1Element(sk, &mut did_err as *mut _);
|
||||
assert!(!did_err);
|
||||
|
||||
let sk2 = sys::CoreMPLKeyGen(
|
||||
scheme,
|
||||
bad_seed.as_ptr() as *const _,
|
||||
bad_seed.len(),
|
||||
&mut did_err as *mut _,
|
||||
);
|
||||
assert!(!did_err);
|
||||
|
||||
let pk2 = sys::PrivateKeyGetG1Element(sk2, &mut did_err as *mut _);
|
||||
assert!(!did_err);
|
||||
|
||||
let message = b"Evgeny owns 1337 dash no cap";
|
||||
let sig = sys::CoreMPLSign(scheme, sk, message.as_ptr() as *const _, message.len());
|
||||
|
||||
let verify =
|
||||
sys::CoreMPLVerify(scheme, pk, message.as_ptr() as *const _, message.len(), sig);
|
||||
assert!(verify);
|
||||
|
||||
let verify_bad = sys::CoreMPLVerify(
|
||||
scheme,
|
||||
pk2,
|
||||
message.as_ptr() as *const _,
|
||||
message.len(),
|
||||
sig,
|
||||
);
|
||||
assert!(!verify_bad);
|
||||
|
||||
sys::G2ElementFree(sig);
|
||||
sys::G1ElementFree(pk2);
|
||||
sys::PrivateKeyFree(sk2);
|
||||
sys::G1ElementFree(pk);
|
||||
sys::PrivateKeyFree(sk);
|
||||
sys::AugSchemeMPLFree(scheme);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_private_key_from_bip32() {
|
||||
use std::slice;
|
||||
let long_seed: [u8; 32] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2];
|
||||
let long_private_key_test_data: [u8; 32] = [50, 67, 148, 112, 207, 6, 210, 118, 137, 125, 27, 144, 105, 189, 214, 228, 68, 83, 144, 205, 80, 105, 133, 222, 14, 26, 28, 136, 167, 111, 241, 118];
|
||||
let short_seed: [u8; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
let short_private_key_test_data: [u8; 32] = [70, 137, 28, 44, 236, 73, 89, 60, 129, 146, 30, 71, 61, 183, 72, 0, 41, 224, 252, 30, 185, 51, 198, 185, 61, 129, 245, 55, 14, 177, 159, 189];
|
||||
unsafe {
|
||||
let c_private_key = sys::PrivateKeyFromSeedBIP32(long_seed.as_ptr() as *const _, long_seed.len());
|
||||
let serialized = sys::PrivateKeySerialize(c_private_key) as *const u8;
|
||||
let data = slice::from_raw_parts(serialized, sys::PrivateKeySizeBytes());
|
||||
assert_eq!(data, &long_private_key_test_data);
|
||||
sys::PrivateKeyFree(c_private_key);
|
||||
|
||||
let c_private_key = sys::PrivateKeyFromSeedBIP32(short_seed.as_ptr() as *const _, short_seed.len());
|
||||
let serialized = sys::PrivateKeySerialize(c_private_key) as *const u8;
|
||||
let data = slice::from_raw_parts(serialized, sys::PrivateKeySizeBytes());
|
||||
assert_eq!(data, &short_private_key_test_data);
|
||||
sys::PrivateKeyFree(c_private_key);
|
||||
}
|
||||
}
|
17
rust-bindings/bls-signatures/.rustfmt.toml
Normal file
17
rust-bindings/bls-signatures/.rustfmt.toml
Normal file
@ -0,0 +1,17 @@
|
||||
unstable_features = true
|
||||
|
||||
blank_lines_lower_bound = 0
|
||||
condense_wildcard_suffixes = true
|
||||
error_on_line_overflow = true
|
||||
error_on_unformatted = true
|
||||
format_code_in_doc_comments = true
|
||||
format_macro_matchers = true
|
||||
format_strings = true
|
||||
imports_granularity = "Crate"
|
||||
normalize_comments = true
|
||||
normalize_doc_attributes = true
|
||||
reorder_impl_items = true
|
||||
group_imports = "StdExternalCrate"
|
||||
use_field_init_shorthand = true
|
||||
use_try_shorthand = true
|
||||
wrap_comments = true
|
18
rust-bindings/bls-signatures/Cargo.toml
Normal file
18
rust-bindings/bls-signatures/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "bls-signatures"
|
||||
description = ""
|
||||
version = "1.2.5"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
legacy = []
|
||||
bip32 = []
|
||||
use_serde = ["serde"]
|
||||
dash_helpers = ["rand"]
|
||||
default = [ "legacy", "bip32", "dash_helpers", "use_serde"]
|
||||
apple = ["bls-dash-sys/apple"]
|
||||
|
||||
[dependencies]
|
||||
bls-dash-sys = { path = "../bls-dash-sys" }
|
||||
serde = { version= "1.0.160", features = ["derive"], optional = true}
|
||||
rand = { version= "0.8.5", optional = true}
|
33
rust-bindings/bls-signatures/src/bip32/chain_code.rs
Normal file
33
rust-bindings/bls-signatures/src/bip32/chain_code.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use std::ffi::c_void;
|
||||
|
||||
use bls_dash_sys::{BIP32ChainCodeFree, BIP32ChainCodeIsEqual, BIP32ChainCodeSerialize};
|
||||
|
||||
pub const BIP32_CHAIN_CODE_SIZE: usize = 32;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ChainCode {
|
||||
pub(crate) c_chain_code: *mut c_void,
|
||||
}
|
||||
|
||||
impl ChainCode {
|
||||
pub fn serialize(&self) -> Box<[u8; BIP32_CHAIN_CODE_SIZE]> {
|
||||
unsafe {
|
||||
let malloc_ptr = BIP32ChainCodeSerialize(self.c_chain_code);
|
||||
Box::from_raw(malloc_ptr as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ChainCode {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
unsafe { BIP32ChainCodeIsEqual(self.c_chain_code, other.c_chain_code) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for ChainCode {}
|
||||
|
||||
impl Drop for ChainCode {
|
||||
fn drop(&mut self) {
|
||||
unsafe { BIP32ChainCodeFree(self.c_chain_code) }
|
||||
}
|
||||
}
|
7
rust-bindings/bls-signatures/src/bip32/mod.rs
Normal file
7
rust-bindings/bls-signatures/src/bip32/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
mod chain_code;
|
||||
mod private_key;
|
||||
mod public_key;
|
||||
|
||||
pub use chain_code::*;
|
||||
pub use private_key::*;
|
||||
pub use public_key::*;
|
205
rust-bindings/bls-signatures/src/bip32/private_key.rs
Normal file
205
rust-bindings/bls-signatures/src/bip32/private_key.rs
Normal file
@ -0,0 +1,205 @@
|
||||
use std::ffi::c_void;
|
||||
|
||||
use bls_dash_sys::{
|
||||
BIP32ExtendedPrivateKeyFree, BIP32ExtendedPrivateKeyFromBytes, BIP32ExtendedPrivateKeyFromSeed,
|
||||
BIP32ExtendedPrivateKeyGetChainCode, BIP32ExtendedPrivateKeyGetExtendedPublicKey,
|
||||
BIP32ExtendedPrivateKeyGetPrivateKey, BIP32ExtendedPrivateKeyGetPublicKey,
|
||||
BIP32ExtendedPrivateKeyIsEqual, BIP32ExtendedPrivateKeyPrivateChild,
|
||||
BIP32ExtendedPrivateKeyPublicChild, BIP32ExtendedPrivateKeySerialize,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
bip32::{chain_code::ChainCode, ExtendedPublicKey},
|
||||
utils::{c_err_to_result, SecureBox},
|
||||
BlsError, G1Element, PrivateKey,
|
||||
};
|
||||
|
||||
pub const BIP32_EXTENDED_PRIVATE_KEY_SIZE: usize = 77;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExtendedPrivateKey {
|
||||
c_extended_private_key: *mut c_void,
|
||||
}
|
||||
|
||||
impl PartialEq for ExtendedPrivateKey {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
unsafe {
|
||||
BIP32ExtendedPrivateKeyIsEqual(
|
||||
self.c_extended_private_key,
|
||||
other.c_extended_private_key,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for ExtendedPrivateKey {}
|
||||
|
||||
impl ExtendedPrivateKey {
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, BlsError> {
|
||||
if bytes.len() != BIP32_EXTENDED_PRIVATE_KEY_SIZE {
|
||||
return Err(BlsError {
|
||||
msg: format!(
|
||||
"Extended Private Key size must be {}, got {}",
|
||||
BIP32_EXTENDED_PRIVATE_KEY_SIZE,
|
||||
bytes.len()
|
||||
),
|
||||
});
|
||||
}
|
||||
Ok(ExtendedPrivateKey {
|
||||
c_extended_private_key: c_err_to_result(|did_err| unsafe {
|
||||
BIP32ExtendedPrivateKeyFromBytes(bytes.as_ptr() as *const _, did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_seed(bytes: &[u8]) -> Result<Self, BlsError> {
|
||||
Ok(ExtendedPrivateKey {
|
||||
c_extended_private_key: c_err_to_result(|did_err| unsafe {
|
||||
BIP32ExtendedPrivateKeyFromSeed(bytes.as_ptr() as *const _, bytes.len(), did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn private_child_with_legacy_flag(&self, index: u32, legacy: bool) -> Self {
|
||||
ExtendedPrivateKey {
|
||||
c_extended_private_key: unsafe {
|
||||
BIP32ExtendedPrivateKeyPrivateChild(self.c_extended_private_key, index, legacy)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn private_child(&self, index: u32) -> Self {
|
||||
self.private_child_with_legacy_flag(index, false)
|
||||
}
|
||||
|
||||
pub fn public_child(&self, index: u32) -> ExtendedPublicKey {
|
||||
ExtendedPublicKey {
|
||||
c_extended_public_key: unsafe {
|
||||
BIP32ExtendedPrivateKeyPublicChild(self.c_extended_private_key, index)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn extended_public_key_with_legacy_flag(
|
||||
&self,
|
||||
legacy: bool,
|
||||
) -> Result<ExtendedPublicKey, BlsError> {
|
||||
Ok(ExtendedPublicKey {
|
||||
c_extended_public_key: c_err_to_result(|did_err| unsafe {
|
||||
BIP32ExtendedPrivateKeyGetExtendedPublicKey(
|
||||
self.c_extended_private_key,
|
||||
legacy,
|
||||
did_err,
|
||||
)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn extended_public_key(&self) -> Result<ExtendedPublicKey, BlsError> {
|
||||
self.extended_public_key_with_legacy_flag(false)
|
||||
}
|
||||
|
||||
pub fn public_key(&self) -> Result<G1Element, BlsError> {
|
||||
Ok(G1Element {
|
||||
c_element: c_err_to_result(|did_err| unsafe {
|
||||
BIP32ExtendedPrivateKeyGetPublicKey(self.c_extended_private_key, did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn private_key(&self) -> PrivateKey {
|
||||
PrivateKey {
|
||||
c_private_key: unsafe {
|
||||
BIP32ExtendedPrivateKeyGetPrivateKey(self.c_extended_private_key)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn serialize(&self) -> SecureBox {
|
||||
unsafe {
|
||||
let secalloc_ptr = BIP32ExtendedPrivateKeySerialize(self.c_extended_private_key);
|
||||
SecureBox::from_ptr(secalloc_ptr as *mut u8, BIP32_EXTENDED_PRIVATE_KEY_SIZE)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn chain_code(&self) -> ChainCode {
|
||||
ChainCode {
|
||||
c_chain_code: unsafe {
|
||||
BIP32ExtendedPrivateKeyGetChainCode(self.c_extended_private_key)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ExtendedPrivateKey {
|
||||
fn drop(&mut self) {
|
||||
unsafe { BIP32ExtendedPrivateKeyFree(self.c_extended_private_key) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialize_deserialize() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let private_key =
|
||||
ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key");
|
||||
|
||||
let private_key_bytes = private_key.serialize();
|
||||
let private_key_2 = ExtendedPrivateKey::from_bytes(private_key_bytes.as_ref())
|
||||
.expect("cannot deserialize extended private key");
|
||||
|
||||
assert_eq!(private_key, private_key_2);
|
||||
assert_eq!(private_key.private_key(), private_key_2.private_key());
|
||||
assert_eq!(private_key.public_key(), private_key_2.public_key());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hierarchical_deterministic_keys() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let private_key =
|
||||
ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key");
|
||||
let public_key = private_key
|
||||
.extended_public_key()
|
||||
.expect("cannot get extended public key");
|
||||
|
||||
let private_child = private_key.private_child(1337);
|
||||
let private_grandchild = private_child.private_child(420);
|
||||
|
||||
let public_child = public_key.public_child(1337);
|
||||
let public_grandchild = public_child.public_child(420);
|
||||
|
||||
assert_eq!(
|
||||
public_grandchild,
|
||||
private_grandchild
|
||||
.extended_public_key()
|
||||
.expect("cannot get extended public key")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_keys_match() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let private_key =
|
||||
ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key");
|
||||
let public_key = private_key
|
||||
.extended_public_key()
|
||||
.expect("cannot get extended public key");
|
||||
|
||||
assert_eq!(private_key.public_key(), Ok(public_key.public_key()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fingerprint_for_short_bip32_seed() {
|
||||
assert_eq!(
|
||||
ExtendedPrivateKey::from_seed(&[1u8, 50, 6, 244, 24, 199, 1, 25])
|
||||
.expect("cannot generate extended private key")
|
||||
.public_key()
|
||||
.expect("cannot get public key from extended private key")
|
||||
.fingerprint_legacy(),
|
||||
0xa4700b27
|
||||
);
|
||||
}
|
||||
}
|
119
rust-bindings/bls-signatures/src/bip32/public_key.rs
Normal file
119
rust-bindings/bls-signatures/src/bip32/public_key.rs
Normal file
@ -0,0 +1,119 @@
|
||||
use std::ffi::c_void;
|
||||
|
||||
use bls_dash_sys::{
|
||||
BIP32ExtendedPublicKeyFree, BIP32ExtendedPublicKeyFromBytes,
|
||||
BIP32ExtendedPublicKeyGetChainCode, BIP32ExtendedPublicKeyGetPublicKey,
|
||||
BIP32ExtendedPublicKeyIsEqual, BIP32ExtendedPublicKeyPublicChild,
|
||||
BIP32ExtendedPublicKeySerialize,
|
||||
};
|
||||
|
||||
use crate::{bip32::chain_code::ChainCode, utils::c_err_to_result, BlsError, G1Element};
|
||||
|
||||
pub const BIP32_EXTENDED_PUBLIC_KEY_SIZE: usize = 93;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExtendedPublicKey {
|
||||
pub(crate) c_extended_public_key: *mut c_void,
|
||||
}
|
||||
|
||||
impl PartialEq for ExtendedPublicKey {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
unsafe {
|
||||
BIP32ExtendedPublicKeyIsEqual(self.c_extended_public_key, other.c_extended_public_key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for ExtendedPublicKey {}
|
||||
|
||||
impl ExtendedPublicKey {
|
||||
pub(crate) fn from_bytes_with_legacy_flag(
|
||||
bytes: &[u8],
|
||||
legacy: bool,
|
||||
) -> Result<Self, BlsError> {
|
||||
if bytes.len() != BIP32_EXTENDED_PUBLIC_KEY_SIZE {
|
||||
return Err(BlsError {
|
||||
msg: format!(
|
||||
"Extended Public Key size must be {}, got {}",
|
||||
BIP32_EXTENDED_PUBLIC_KEY_SIZE,
|
||||
bytes.len()
|
||||
),
|
||||
});
|
||||
}
|
||||
Ok(ExtendedPublicKey {
|
||||
c_extended_public_key: c_err_to_result(|did_err| unsafe {
|
||||
BIP32ExtendedPublicKeyFromBytes(bytes.as_ptr() as *const _, legacy, did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, BlsError> {
|
||||
Self::from_bytes_with_legacy_flag(bytes, false)
|
||||
}
|
||||
|
||||
pub(crate) fn public_child_with_legacy_flag(&self, index: u32, legacy: bool) -> Self {
|
||||
ExtendedPublicKey {
|
||||
c_extended_public_key: unsafe {
|
||||
BIP32ExtendedPublicKeyPublicChild(self.c_extended_public_key, index, legacy)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn public_child(&self, index: u32) -> Self {
|
||||
self.public_child_with_legacy_flag(index, false)
|
||||
}
|
||||
|
||||
pub(crate) fn serialize_with_legacy_flag(
|
||||
&self,
|
||||
legacy: bool,
|
||||
) -> Box<[u8; BIP32_EXTENDED_PUBLIC_KEY_SIZE]> {
|
||||
unsafe {
|
||||
let malloc_ptr = BIP32ExtendedPublicKeySerialize(self.c_extended_public_key, legacy);
|
||||
Box::from_raw(malloc_ptr as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn serialize(&self) -> Box<[u8; BIP32_EXTENDED_PUBLIC_KEY_SIZE]> {
|
||||
self.serialize_with_legacy_flag(false)
|
||||
}
|
||||
|
||||
pub fn chain_code(&self) -> ChainCode {
|
||||
ChainCode {
|
||||
c_chain_code: unsafe { BIP32ExtendedPublicKeyGetChainCode(self.c_extended_public_key) },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn public_key(&self) -> G1Element {
|
||||
G1Element {
|
||||
c_element: unsafe { BIP32ExtendedPublicKeyGetPublicKey(self.c_extended_public_key) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ExtendedPublicKey {
|
||||
fn drop(&mut self) {
|
||||
unsafe { BIP32ExtendedPublicKeyFree(self.c_extended_public_key) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::bip32::ExtendedPrivateKey;
|
||||
|
||||
#[test]
|
||||
fn serialize_deserialize() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let private_key =
|
||||
ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key");
|
||||
let public_key = private_key
|
||||
.extended_public_key()
|
||||
.expect("cannot get extended public key");
|
||||
|
||||
let public_key_bytes = public_key.serialize();
|
||||
let public_key_2 = ExtendedPublicKey::from_bytes(public_key_bytes.as_ref())
|
||||
.expect("cannot deserialize extended public key");
|
||||
|
||||
assert_eq!(public_key, public_key_2);
|
||||
}
|
||||
}
|
368
rust-bindings/bls-signatures/src/elements.rs
Normal file
368
rust-bindings/bls-signatures/src/elements.rs
Normal file
@ -0,0 +1,368 @@
|
||||
use std::ffi::c_void;
|
||||
|
||||
use bls_dash_sys::{CoreMPLDeriveChildPkUnhardened, G1ElementFree, G1ElementFromBytes, G1ElementGenerator, G1ElementGetFingerprint, G1ElementIsEqual, G1ElementSerialize, G1ElementCopy, G2ElementCopy, G2ElementFree, G2ElementFromBytes, G2ElementIsEqual, G2ElementSerialize, ThresholdPublicKeyRecover, ThresholdSignatureRecover};
|
||||
#[cfg(feature = "use_serde")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::{schemes::Scheme, utils::c_err_to_result, BlsError, BasicSchemeMPL};
|
||||
|
||||
// TODO Split into modules
|
||||
|
||||
pub const G1_ELEMENT_SIZE: usize = 48; // TODO somehow extract it from bls library
|
||||
pub const G2_ELEMENT_SIZE: usize = 96; // TODO somehow extract it from bls library
|
||||
|
||||
#[cfg(feature = "dash_helpers")]
|
||||
pub type PublicKey = G1Element;
|
||||
|
||||
#[cfg(feature = "dash_helpers")]
|
||||
pub type Signature = G2Element;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct G1Element {
|
||||
pub(crate) c_element: *mut c_void,
|
||||
}
|
||||
|
||||
impl PartialEq for G1Element {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
unsafe { G1ElementIsEqual(self.c_element, other.c_element) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for G1Element {}
|
||||
|
||||
impl G1Element {
|
||||
pub fn generate() -> Self {
|
||||
let c_element = unsafe { G1ElementGenerator() };
|
||||
|
||||
G1Element { c_element }
|
||||
}
|
||||
|
||||
#[cfg(feature = "dash_helpers")]
|
||||
pub fn verify(&self, signature: &G2Element, message: &[u8]) -> bool {
|
||||
self.verify_basic(signature, message)
|
||||
}
|
||||
|
||||
pub fn verify_basic(&self, signature: &G2Element, message: &[u8]) -> bool {
|
||||
let basic_scheme = BasicSchemeMPL::new();
|
||||
basic_scheme.verify(self, message, signature)
|
||||
}
|
||||
|
||||
pub(crate) fn from_bytes_with_legacy_flag(
|
||||
bytes: &[u8],
|
||||
legacy: bool,
|
||||
) -> Result<Self, BlsError> {
|
||||
if bytes.len() != G1_ELEMENT_SIZE {
|
||||
return Err(BlsError {
|
||||
msg: format!(
|
||||
"G1 Element size must be {}, got {}",
|
||||
G1_ELEMENT_SIZE,
|
||||
bytes.len()
|
||||
),
|
||||
});
|
||||
}
|
||||
Ok(G1Element {
|
||||
c_element: c_err_to_result(|did_err| unsafe {
|
||||
G1ElementFromBytes(bytes.as_ptr() as *const _, legacy, did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, BlsError> {
|
||||
Self::from_bytes_with_legacy_flag(bytes, false)
|
||||
}
|
||||
|
||||
pub(crate) fn to_bytes_with_legacy_flag(&self, legacy: bool) -> Box<[u8; G1_ELEMENT_SIZE]> {
|
||||
unsafe {
|
||||
let malloc_ptr = G1ElementSerialize(self.c_element, legacy);
|
||||
Box::from_raw(malloc_ptr as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Box<[u8; G1_ELEMENT_SIZE]> {
|
||||
self.to_bytes_with_legacy_flag(false)
|
||||
}
|
||||
|
||||
pub fn derive_child_public_key_unhardened(
|
||||
&self,
|
||||
scheme: &impl Scheme,
|
||||
index: u32,
|
||||
) -> G1Element {
|
||||
G1Element {
|
||||
c_element: unsafe {
|
||||
CoreMPLDeriveChildPkUnhardened(scheme.as_mut_ptr(), self.c_element, index)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn fingerprint_with_legacy_flag(&self, legacy: bool) -> u32 {
|
||||
unsafe { G1ElementGetFingerprint(self.c_element, legacy) }
|
||||
}
|
||||
|
||||
pub fn fingerprint(&self) -> u32 {
|
||||
self.fingerprint_with_legacy_flag(false)
|
||||
}
|
||||
|
||||
pub fn threshold_recover(
|
||||
bls_ids_with_elements: &[(Vec<u8>, G1Element)],
|
||||
) -> Result<Self, BlsError> {
|
||||
unsafe {
|
||||
let len = bls_ids_with_elements.len();
|
||||
let (c_hashes, c_elements): (Vec<_>, Vec<_>) = bls_ids_with_elements
|
||||
.iter()
|
||||
.map(|(hash, element)| {
|
||||
(
|
||||
hash.as_ptr() as *mut c_void,
|
||||
element.c_element as *mut c_void,
|
||||
)
|
||||
})
|
||||
.unzip();
|
||||
let c_hashes_ptr = c_hashes.as_ptr() as *mut *mut c_void;
|
||||
let c_elements_ptr = c_elements.as_ptr() as *mut *mut c_void;
|
||||
Ok(G1Element {
|
||||
c_element: c_err_to_result(|did_err| {
|
||||
ThresholdPublicKeyRecover(c_elements_ptr, len, c_hashes_ptr, len, did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for G1Element {
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
G1Element{c_element: G1ElementCopy(self.c_element)}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
// Implement Serialize trait for G1Element
|
||||
impl Serialize for G1Element {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let bytes = *self.to_bytes();
|
||||
serializer.serialize_bytes(&bytes)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
// Implement Deserialize trait for G1Element
|
||||
impl<'de> Deserialize<'de> for G1Element {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct G1ElementVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for G1ElementVisitor {
|
||||
type Value = G1Element;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a byte array representing a G1Element")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
G1Element::from_bytes(bytes).map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_bytes(G1ElementVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for G1Element {
|
||||
fn drop(&mut self) {
|
||||
unsafe { G1ElementFree(self.c_element) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct G2Element {
|
||||
pub(crate) c_element: *mut c_void,
|
||||
}
|
||||
|
||||
impl PartialEq for G2Element {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
unsafe { G2ElementIsEqual(self.c_element, other.c_element) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for G2Element {}
|
||||
|
||||
impl G2Element {
|
||||
pub(crate) fn from_bytes_with_legacy_flag(
|
||||
bytes: &[u8],
|
||||
legacy: bool,
|
||||
) -> Result<Self, BlsError> {
|
||||
if bytes.len() != G2_ELEMENT_SIZE {
|
||||
return Err(BlsError {
|
||||
msg: format!(
|
||||
"G2 Element size must be {}, got {}",
|
||||
G2_ELEMENT_SIZE,
|
||||
bytes.len()
|
||||
),
|
||||
});
|
||||
}
|
||||
Ok(G2Element {
|
||||
c_element: c_err_to_result(|did_err| unsafe {
|
||||
G2ElementFromBytes(bytes.as_ptr() as *const _, legacy, did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, BlsError> {
|
||||
Self::from_bytes_with_legacy_flag(bytes, false)
|
||||
}
|
||||
|
||||
pub(crate) fn to_bytes_with_legacy_flag(&self, legacy: bool) -> Box<[u8; G2_ELEMENT_SIZE]> {
|
||||
unsafe {
|
||||
let malloc_ptr = G2ElementSerialize(self.c_element, legacy);
|
||||
Box::from_raw(malloc_ptr as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Box<[u8; G2_ELEMENT_SIZE]> {
|
||||
self.to_bytes_with_legacy_flag(false)
|
||||
}
|
||||
|
||||
pub fn threshold_recover(
|
||||
bls_ids_with_elements: &[(Vec<u8>, G2Element)],
|
||||
) -> Result<Self, BlsError> {
|
||||
unsafe {
|
||||
let len = bls_ids_with_elements.len();
|
||||
let (c_hashes, c_elements): (Vec<_>, Vec<_>) = bls_ids_with_elements
|
||||
.iter()
|
||||
.map(|(hash, element)| {
|
||||
(
|
||||
hash.as_ptr() as *mut c_void,
|
||||
element.c_element as *mut c_void,
|
||||
)
|
||||
})
|
||||
.unzip();
|
||||
let c_hashes_ptr = c_hashes.as_ptr() as *mut *mut c_void;
|
||||
let c_elements_ptr = c_elements.as_ptr() as *mut *mut c_void;
|
||||
Ok(G2Element {
|
||||
c_element: c_err_to_result(|did_err| {
|
||||
ThresholdSignatureRecover(c_elements_ptr, len, c_hashes_ptr, len, did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for G2Element {
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
G2Element{c_element: G2ElementCopy(self.c_element)}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
// Implement Serialize trait for G1Element
|
||||
impl Serialize for G2Element {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let bytes = *self.to_bytes();
|
||||
serializer.serialize_bytes(&bytes)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
// Implement Deserialize trait for G1Element
|
||||
impl<'de> Deserialize<'de> for G2Element {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct G2ElementVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for G2ElementVisitor {
|
||||
type Value = G2Element;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a byte array representing a G2Element")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
G2Element::from_bytes(bytes).map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_bytes(G2ElementVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for G2Element {
|
||||
fn drop(&mut self) {
|
||||
unsafe { G2ElementFree(self.c_element) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
schemes::{AugSchemeMPL, Scheme},
|
||||
PrivateKey,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn g1_serialize_deserialize() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let scheme = AugSchemeMPL::new();
|
||||
let sk = PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key");
|
||||
|
||||
let g1 = sk.g1_element().expect("cannot get G1 element");
|
||||
let g1_bytes = g1.to_bytes();
|
||||
let g1_2 =
|
||||
G1Element::from_bytes(g1_bytes.as_ref()).expect("cannot build G1 element from bytes");
|
||||
|
||||
assert_eq!(g1, g1_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn g2_serialize_deserialize() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let scheme = AugSchemeMPL::new();
|
||||
let sk = PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key");
|
||||
|
||||
let g2 = scheme.sign(&sk, b"ayy");
|
||||
let g2_bytes = g2.to_bytes();
|
||||
let g2_2 =
|
||||
G2Element::from_bytes(g2_bytes.as_ref()).expect("cannot build G2 element from bytes");
|
||||
|
||||
assert_eq!(g2, g2_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_generate_new_g1_element() {
|
||||
let g1_element = G1Element::generate();
|
||||
|
||||
assert_eq!(g1_element.to_bytes().len(), 48);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_fingerprint() {
|
||||
let bytes = [
|
||||
151, 241, 211, 167, 49, 151, 215, 148, 38, 149, 99, 140, 79, 169, 172, 15, 195, 104,
|
||||
140, 79, 151, 116, 185, 5, 161, 78, 58, 63, 23, 27, 172, 88, 108, 85, 232, 63, 249,
|
||||
122, 26, 239, 251, 58, 240, 10, 219, 34, 198, 187,
|
||||
];
|
||||
|
||||
let g1_element =
|
||||
G1Element::from_bytes(&bytes).expect("should create g1 element from bytes");
|
||||
|
||||
assert_eq!(g1_element.fingerprint(), 2093959050);
|
||||
}
|
||||
}
|
2
rust-bindings/bls-signatures/src/legacy/bip32/mod.rs
Normal file
2
rust-bindings/bls-signatures/src/legacy/bip32/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod private_key;
|
||||
mod public_key;
|
58
rust-bindings/bls-signatures/src/legacy/bip32/private_key.rs
Normal file
58
rust-bindings/bls-signatures/src/legacy/bip32/private_key.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use crate::{
|
||||
bip32::{ExtendedPrivateKey, ExtendedPublicKey},
|
||||
BlsError,
|
||||
};
|
||||
|
||||
impl ExtendedPrivateKey {
|
||||
pub fn private_child_legacy(&self, index: u32) -> Self {
|
||||
self.private_child_with_legacy_flag(index, true)
|
||||
}
|
||||
|
||||
pub fn extended_public_key_legacy(&self) -> Result<ExtendedPublicKey, BlsError> {
|
||||
self.extended_public_key_with_legacy_flag(true)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialize_deserialize_legacy() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let private_key =
|
||||
ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key");
|
||||
let public_key = private_key
|
||||
.extended_public_key_legacy()
|
||||
.expect("cannot get extended public key");
|
||||
|
||||
let public_key_bytes = public_key.serialize_legacy();
|
||||
let public_key_2 = ExtendedPublicKey::from_bytes_legacy(public_key_bytes.as_ref())
|
||||
.expect("cannot deserialize extended public key");
|
||||
|
||||
assert_eq!(public_key, public_key_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hierarchical_deterministic_keys_legacy() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let private_key =
|
||||
ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key");
|
||||
let public_key = private_key
|
||||
.extended_public_key_legacy()
|
||||
.expect("cannot get extended public key");
|
||||
|
||||
let private_child = private_key.private_child_legacy(1337);
|
||||
let private_grandchild = private_child.private_child_legacy(420);
|
||||
|
||||
let public_child = public_key.public_child_legacy(1337);
|
||||
let public_grandchild = public_child.public_child_legacy(420);
|
||||
|
||||
assert_eq!(
|
||||
public_grandchild,
|
||||
private_grandchild
|
||||
.extended_public_key_legacy()
|
||||
.expect("cannot get extended public key")
|
||||
);
|
||||
}
|
||||
}
|
40
rust-bindings/bls-signatures/src/legacy/bip32/public_key.rs
Normal file
40
rust-bindings/bls-signatures/src/legacy/bip32/public_key.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use crate::{
|
||||
bip32::{ExtendedPublicKey, BIP32_EXTENDED_PUBLIC_KEY_SIZE},
|
||||
BlsError,
|
||||
};
|
||||
|
||||
impl ExtendedPublicKey {
|
||||
pub fn from_bytes_legacy(bytes: &[u8]) -> Result<Self, BlsError> {
|
||||
Self::from_bytes_with_legacy_flag(bytes, true)
|
||||
}
|
||||
|
||||
pub fn public_child_legacy(&self, index: u32) -> Self {
|
||||
self.public_child_with_legacy_flag(index, true)
|
||||
}
|
||||
|
||||
pub fn serialize_legacy(&self) -> Box<[u8; BIP32_EXTENDED_PUBLIC_KEY_SIZE]> {
|
||||
self.serialize_with_legacy_flag(true)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::bip32::ExtendedPrivateKey;
|
||||
|
||||
#[test]
|
||||
fn serialize_deserialize_legacy() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let private_key =
|
||||
ExtendedPrivateKey::from_seed(seed).expect("cannot generate extended private key");
|
||||
let public_key = private_key
|
||||
.extended_public_key_legacy()
|
||||
.expect("cannot get extended public key");
|
||||
|
||||
let public_key_bytes = public_key.serialize_legacy();
|
||||
let public_key_2 = ExtendedPublicKey::from_bytes_legacy(public_key_bytes.as_ref())
|
||||
.expect("cannot deserialize extended public key");
|
||||
|
||||
assert_eq!(public_key, public_key_2);
|
||||
}
|
||||
}
|
25
rust-bindings/bls-signatures/src/legacy/elements.rs
Normal file
25
rust-bindings/bls-signatures/src/legacy/elements.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use crate::{BlsError, G1Element, G2Element, G1_ELEMENT_SIZE, G2_ELEMENT_SIZE};
|
||||
|
||||
impl G1Element {
|
||||
pub fn serialize_legacy(&self) -> Box<[u8; G1_ELEMENT_SIZE]> {
|
||||
self.to_bytes_with_legacy_flag(true)
|
||||
}
|
||||
|
||||
pub fn from_bytes_legacy(bytes: &[u8]) -> Result<Self, BlsError> {
|
||||
Self::from_bytes_with_legacy_flag(bytes, true)
|
||||
}
|
||||
|
||||
pub fn fingerprint_legacy(&self) -> u32 {
|
||||
self.fingerprint_with_legacy_flag(true)
|
||||
}
|
||||
}
|
||||
|
||||
impl G2Element {
|
||||
pub fn from_bytes_legacy(bytes: &[u8]) -> Result<Self, BlsError> {
|
||||
Self::from_bytes_with_legacy_flag(bytes, true)
|
||||
}
|
||||
|
||||
pub fn serialize_legacy(&self) -> Box<[u8; G2_ELEMENT_SIZE]> {
|
||||
self.to_bytes_with_legacy_flag(true)
|
||||
}
|
||||
}
|
2
rust-bindings/bls-signatures/src/legacy/mod.rs
Normal file
2
rust-bindings/bls-signatures/src/legacy/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod bip32;
|
||||
mod elements;
|
104
rust-bindings/bls-signatures/src/lib.rs
Normal file
104
rust-bindings/bls-signatures/src/lib.rs
Normal file
@ -0,0 +1,104 @@
|
||||
mod elements;
|
||||
mod private_key;
|
||||
mod schemes;
|
||||
mod utils;
|
||||
|
||||
#[cfg(feature = "legacy")]
|
||||
mod legacy;
|
||||
|
||||
#[cfg(feature = "bip32")]
|
||||
pub mod bip32;
|
||||
|
||||
use std::{error::Error, fmt::Display};
|
||||
|
||||
pub use elements::{G1Element, G2Element, G1_ELEMENT_SIZE, G2_ELEMENT_SIZE};
|
||||
#[cfg(feature = "dash_helpers")]
|
||||
pub use elements::{PublicKey, Signature};
|
||||
pub use private_key::{PrivateKey, PRIVATE_KEY_SIZE};
|
||||
pub use schemes::{AugSchemeMPL, BasicSchemeMPL, LegacySchemeMPL, Scheme};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct BlsError {
|
||||
// Need to use owned version as each time BLS has an error its binding glue overwrites error
|
||||
// message variable.
|
||||
msg: String,
|
||||
}
|
||||
|
||||
impl Display for BlsError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for BlsError {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::schemes::{AugSchemeMPL, Scheme};
|
||||
|
||||
#[test]
|
||||
fn basic_sign() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let bad_seed = b"weedseedweedseedweedseedweedseed";
|
||||
|
||||
let scheme = AugSchemeMPL::new();
|
||||
|
||||
let private_key_before =
|
||||
PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key");
|
||||
|
||||
// Also test private key serialization
|
||||
let private_key_bytes = private_key_before.to_bytes();
|
||||
let private_key = PrivateKey::from_bytes(private_key_bytes.as_slice(), false)
|
||||
.expect("cannot build private key from bytes");
|
||||
drop(private_key_bytes);
|
||||
|
||||
let public_key = private_key.g1_element().expect("unable to get public key");
|
||||
|
||||
let private_key_bad =
|
||||
PrivateKey::key_gen(&scheme, bad_seed).expect("unable to generate private key");
|
||||
let public_key_bad = private_key_bad
|
||||
.g1_element()
|
||||
.expect("unable to get public key");
|
||||
|
||||
let message = b"Evgeny owns 1337 dash no cap";
|
||||
|
||||
let signature = scheme.sign(&private_key, message);
|
||||
let verify = scheme.verify(&public_key, message, &signature);
|
||||
assert!(verify);
|
||||
let verify_bad = scheme.verify(&public_key_bad, message, &signature);
|
||||
assert!(!verify_bad);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_seed() {
|
||||
let seed = b"lol";
|
||||
let scheme = AugSchemeMPL::new();
|
||||
let private_key = PrivateKey::key_gen(&scheme, seed);
|
||||
|
||||
assert!(matches!(
|
||||
private_key,
|
||||
Err(BlsError { msg }) if msg == "Seed size must be at least 32 bytes"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hd_keys_deterministic() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let scheme = AugSchemeMPL::new();
|
||||
|
||||
let master_sk = PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key");
|
||||
let master_pk = master_sk.g1_element().expect("unable to get public key");
|
||||
|
||||
let child_sk_u = master_sk.derive_child_private_key_unhardened(&scheme, 22);
|
||||
let grandchild_sk_u = child_sk_u.derive_child_private_key_unhardened(&scheme, 0);
|
||||
|
||||
let child_pk_u = master_pk.derive_child_public_key_unhardened(&scheme, 22);
|
||||
let grandchild_pk_u = child_pk_u.derive_child_public_key_unhardened(&scheme, 0);
|
||||
|
||||
assert_eq!(
|
||||
grandchild_pk_u,
|
||||
grandchild_sk_u.g1_element().expect("cannot get public key")
|
||||
);
|
||||
}
|
||||
}
|
315
rust-bindings/bls-signatures/src/private_key.rs
Executable file
315
rust-bindings/bls-signatures/src/private_key.rs
Executable file
@ -0,0 +1,315 @@
|
||||
use std::{ffi::c_void, ops::Mul};
|
||||
|
||||
use bls_dash_sys::{
|
||||
CoreMPLDeriveChildSk, CoreMPLDeriveChildSkUnhardened, CoreMPLKeyGen, G1ElementMul,
|
||||
PrivateKeyFree, PrivateKeyFromBytes, PrivateKeyFromSeedBIP32, PrivateKeyGetG1Element,
|
||||
PrivateKeyIsEqual, PrivateKeySerialize, ThresholdPrivateKeyRecover,
|
||||
};
|
||||
use rand::{prelude::StdRng, Rng};
|
||||
#[cfg(feature = "use_serde")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::{schemes::Scheme, utils::{c_err_to_result, SecureBox}, BasicSchemeMPL, BlsError, G1Element, G2Element};
|
||||
|
||||
pub const PRIVATE_KEY_SIZE: usize = 32; // TODO somehow extract it from bls library
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrivateKey {
|
||||
pub(crate) c_private_key: *mut c_void,
|
||||
}
|
||||
|
||||
impl PartialEq for PrivateKey {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
unsafe { PrivateKeyIsEqual(self.c_private_key, other.c_private_key) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for PrivateKey {}
|
||||
|
||||
impl Mul<G1Element> for PrivateKey {
|
||||
type Output = Result<G1Element, BlsError>;
|
||||
|
||||
fn mul(self, rhs: G1Element) -> Self::Output {
|
||||
Ok(G1Element {
|
||||
c_element: c_err_to_result(|_| unsafe {
|
||||
G1ElementMul(rhs.c_element, self.c_private_key)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<PrivateKey> for G1Element {
|
||||
type Output = Result<G1Element, BlsError>;
|
||||
|
||||
fn mul(self, rhs: PrivateKey) -> Self::Output {
|
||||
rhs * self
|
||||
}
|
||||
}
|
||||
|
||||
impl PrivateKey {
|
||||
pub(crate) fn as_mut_ptr(&self) -> *mut c_void {
|
||||
self.c_private_key
|
||||
}
|
||||
|
||||
// TODO Rename to from_seed
|
||||
pub fn key_gen(scheme: &impl Scheme, seed: &[u8]) -> Result<Self, BlsError> {
|
||||
Ok(PrivateKey {
|
||||
c_private_key: c_err_to_result(|did_err| unsafe {
|
||||
CoreMPLKeyGen(
|
||||
scheme.as_mut_ptr(),
|
||||
seed.as_ptr() as *const _,
|
||||
seed.len(),
|
||||
did_err,
|
||||
)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "dash_helpers")]
|
||||
pub fn generate_dash(rng: &mut StdRng) -> Result<Self, BlsError> {
|
||||
let seed = rng.gen::<[u8; 32]>();
|
||||
let scheme = BasicSchemeMPL::new();
|
||||
Ok(PrivateKey {
|
||||
c_private_key: c_err_to_result(|did_err| unsafe {
|
||||
CoreMPLKeyGen(
|
||||
scheme.as_mut_ptr(),
|
||||
seed.as_ptr() as *const _,
|
||||
seed.len(),
|
||||
did_err,
|
||||
)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "dash_helpers")]
|
||||
pub fn sign(&self, message: &[u8]) -> G2Element {
|
||||
self.sign_basic(message)
|
||||
}
|
||||
|
||||
pub fn sign_basic(&self, message: &[u8]) -> G2Element {
|
||||
let scheme = BasicSchemeMPL::new();
|
||||
scheme.sign(self, message)
|
||||
}
|
||||
|
||||
#[cfg(feature = "dash_helpers")]
|
||||
pub fn generate_dash_many(count: usize, rng: &mut StdRng) -> Result<Vec<Self>, BlsError> {
|
||||
(0..count)
|
||||
.into_iter()
|
||||
.map(|_| Self::generate_dash(rng))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn g1_element(&self) -> Result<G1Element, BlsError> {
|
||||
Ok(G1Element {
|
||||
c_element: c_err_to_result(|did_err| unsafe {
|
||||
PrivateKeyGetG1Element(self.c_private_key, did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> SecureBox {
|
||||
// `PrivateKeySerialize` internally securely allocates memory which we have to
|
||||
// wrap safely
|
||||
unsafe {
|
||||
SecureBox::from_ptr(
|
||||
PrivateKeySerialize(self.c_private_key) as *mut u8,
|
||||
PRIVATE_KEY_SIZE,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8], mod_order: bool) -> Result<Self, BlsError> {
|
||||
if bytes.len() != PRIVATE_KEY_SIZE {
|
||||
return Err(BlsError {
|
||||
msg: format!(
|
||||
"Private key size must be {}, got {}",
|
||||
PRIVATE_KEY_SIZE,
|
||||
bytes.len()
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
let c_private_key = c_err_to_result(|did_err| unsafe {
|
||||
PrivateKeyFromBytes(bytes.as_ptr() as *const c_void, mod_order, did_err)
|
||||
})?;
|
||||
|
||||
Ok(PrivateKey { c_private_key })
|
||||
}
|
||||
|
||||
pub fn from_bip32_seed(bytes: &[u8]) -> Self {
|
||||
let c_private_key =
|
||||
unsafe { PrivateKeyFromSeedBIP32(bytes.as_ptr() as *const c_void, bytes.len()) };
|
||||
|
||||
PrivateKey { c_private_key }
|
||||
}
|
||||
|
||||
pub fn derive_child_private_key(&self, scheme: &impl Scheme, index: u32) -> PrivateKey {
|
||||
PrivateKey {
|
||||
c_private_key: unsafe {
|
||||
CoreMPLDeriveChildSk(scheme.as_mut_ptr(), self.c_private_key, index)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn derive_child_private_key_unhardened(
|
||||
&self,
|
||||
scheme: &impl Scheme,
|
||||
index: u32,
|
||||
) -> PrivateKey {
|
||||
PrivateKey {
|
||||
c_private_key: unsafe {
|
||||
CoreMPLDeriveChildSkUnhardened(scheme.as_mut_ptr(), self.c_private_key, index)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn threshold_recover(
|
||||
bls_ids_with_private_keys: &[(Vec<u8>, PrivateKey)],
|
||||
) -> Result<Self, BlsError> {
|
||||
unsafe {
|
||||
let len = bls_ids_with_private_keys.len();
|
||||
let (c_hashes, c_elements): (Vec<_>, Vec<_>) = bls_ids_with_private_keys
|
||||
.iter()
|
||||
.map(|(hash, element)| (hash.as_ptr() as *mut c_void, element.c_private_key))
|
||||
.unzip();
|
||||
let c_hashes_ptr = c_hashes.as_ptr() as *mut *mut c_void;
|
||||
let c_elements_ptr = c_elements.as_ptr() as *mut *mut c_void;
|
||||
Ok(PrivateKey {
|
||||
c_private_key: c_err_to_result(|did_err| {
|
||||
ThresholdPrivateKeyRecover(c_elements_ptr, len, c_hashes_ptr, len, did_err)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for PrivateKey {
|
||||
fn clone(&self) -> Self {
|
||||
// Serialize the element
|
||||
let bytes = self.to_bytes();
|
||||
// We can panic
|
||||
PrivateKey::from_bytes(bytes.as_slice(), false).expect("expected bytes to be valid")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
// Implement Serialize trait for G1Element
|
||||
impl Serialize for PrivateKey {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_bytes(self.to_bytes().as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
// Implement Deserialize trait for G1Element
|
||||
impl<'de> Deserialize<'de> for PrivateKey {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct PrivateKeyElementVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for PrivateKeyElementVisitor {
|
||||
type Value = PrivateKey;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a byte array representing a Private Key")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
PrivateKey::from_bytes(bytes, false).map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_bytes(PrivateKeyElementVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PrivateKey {
|
||||
fn drop(&mut self) {
|
||||
unsafe { PrivateKeyFree(self.c_private_key) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::schemes::AugSchemeMPL;
|
||||
|
||||
#[test]
|
||||
fn serialize_deserialize() {
|
||||
let seed = b"seedweedseedweedseedweedseedweed";
|
||||
let scheme = AugSchemeMPL::new();
|
||||
let sk1 = PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key");
|
||||
let sk1_bytes = sk1.to_bytes();
|
||||
let sk2 = PrivateKey::from_bytes(sk1_bytes.as_slice(), false)
|
||||
.expect("cannot build private key from bytes");
|
||||
|
||||
assert_eq!(sk1, sk2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_private_key_from_bip32_bytes() {
|
||||
let long_seed = [
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 1, 2,
|
||||
];
|
||||
let long_private_key_test_data = [
|
||||
50, 67, 148, 112, 207, 6, 210, 118, 137, 125, 27, 144, 105, 189, 214, 228, 68, 83, 144,
|
||||
205, 80, 105, 133, 222, 14, 26, 28, 136, 167, 111, 241, 118,
|
||||
];
|
||||
let long_private_key = PrivateKey::from_bip32_seed(&long_seed);
|
||||
assert_eq!(*long_private_key.to_bytes(), long_private_key_test_data);
|
||||
|
||||
// Previously didn't work with seed with length != 32
|
||||
let short_seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
let short_private_key_test_data = [
|
||||
70, 137, 28, 44, 236, 73, 89, 60, 129, 146, 30, 71, 61, 183, 72, 0, 41, 224, 252, 30,
|
||||
185, 51, 198, 185, 61, 129, 245, 55, 14, 177, 159, 189,
|
||||
];
|
||||
let short_private_key = PrivateKey::from_bip32_seed(&short_seed);
|
||||
assert_eq!(*short_private_key.to_bytes(), short_private_key_test_data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_multiplication() {
|
||||
// 46891c2cec49593c81921e473db7480029e0fc1eb933c6b93d81f5370eb19fbd
|
||||
let private_key_data = [
|
||||
70, 137, 28, 44, 236, 73, 89, 60, 129, 146, 30, 71, 61, 183, 72, 0, 41, 224, 252, 30,
|
||||
185, 51, 198, 185, 61, 129, 245, 55, 14, 177, 159, 189,
|
||||
];
|
||||
// 0e2f9055c17eb13221d8b41833468ab49f7d4e874ddf4b217f5126392a608fd48ccab3510548f1da4f397c1ad4f8e01a
|
||||
let public_key_data = [
|
||||
14, 47, 144, 85, 193, 126, 177, 50, 33, 216, 180, 24, 51, 70, 138, 180, 159, 125, 78,
|
||||
135, 77, 223, 75, 33, 127, 81, 38, 57, 42, 96, 143, 212, 140, 202, 179, 81, 5, 72, 241,
|
||||
218, 79, 57, 124, 26, 212, 248, 224, 26,
|
||||
];
|
||||
// 03fd387c4d4c66ec9dcdb31ef0c08ad881090dcda13d4b2c9cbc5ef264ff4dc7
|
||||
let expected_data = [
|
||||
3, 253, 56, 124, 77, 76, 102, 236, 157, 205, 179, 30, 240, 192, 138, 216, 129, 9, 13,
|
||||
205, 161, 61, 75, 44, 156, 188, 94, 242, 100, 255, 77, 199,
|
||||
];
|
||||
let private_key = PrivateKey::from_bytes(&private_key_data, false).unwrap();
|
||||
let public_key = G1Element::from_bytes_legacy(&public_key_data).unwrap();
|
||||
let result = (private_key * public_key).unwrap();
|
||||
assert_eq!(
|
||||
&result.serialize_legacy()[..32],
|
||||
&expected_data,
|
||||
"should match"
|
||||
);
|
||||
let private_key = PrivateKey::from_bytes(&private_key_data, false).unwrap();
|
||||
let public_key = G1Element::from_bytes_legacy(&public_key_data).unwrap();
|
||||
let result = (public_key * private_key).unwrap();
|
||||
assert_eq!(
|
||||
&result.serialize_legacy()[..32],
|
||||
&expected_data,
|
||||
"should match"
|
||||
);
|
||||
}
|
||||
}
|
434
rust-bindings/bls-signatures/src/schemes.rs
Normal file
434
rust-bindings/bls-signatures/src/schemes.rs
Normal file
@ -0,0 +1,434 @@
|
||||
use std::ffi::c_void;
|
||||
|
||||
use bls_dash_sys::{
|
||||
AugSchemeMPLAggregateVerify, AugSchemeMPLFree, AugSchemeMPLSign, AugSchemeMPLVerify,
|
||||
BasicSchemeMPLAggregateVerify, BasicSchemeMPLFree, CoreMPLAggregatePubKeys,
|
||||
CoreMPLAggregateSigs, CoreMPLSign, CoreMPLVerify, CoreMPLVerifySecure,
|
||||
LegacySchemeMPLAggregateVerify, LegacySchemeMPLSign, LegacySchemeMPLVerify,
|
||||
LegacySchemeMPLVerifySecure, NewAugSchemeMPL, NewBasicSchemeMPL, NewLegacySchemeMPL,
|
||||
};
|
||||
|
||||
// TODO Split into modules
|
||||
use crate::{private_key::PrivateKey, G1Element, G2Element};
|
||||
|
||||
pub trait Scheme {
|
||||
fn as_mut_ptr(&self) -> *mut c_void;
|
||||
|
||||
fn sign(&self, private_key: &PrivateKey, message: &[u8]) -> G2Element;
|
||||
|
||||
fn verify(&self, public_key: &G1Element, message: &[u8], signature: &G2Element) -> bool;
|
||||
|
||||
fn verify_secure<'a>(
|
||||
&self,
|
||||
public_keys: impl IntoIterator<Item = &'a G1Element>,
|
||||
message: &[u8],
|
||||
signature: &G2Element,
|
||||
) -> bool {
|
||||
let mut g1_pointers = public_keys
|
||||
.into_iter()
|
||||
.map(|g1| g1.c_element)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
unsafe {
|
||||
CoreMPLVerifySecure(
|
||||
self.as_mut_ptr(),
|
||||
g1_pointers.as_mut_ptr(),
|
||||
g1_pointers.len(),
|
||||
signature.c_element,
|
||||
message.as_ptr() as *const _,
|
||||
message.len(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn aggregate_public_keys<'a>(
|
||||
&self,
|
||||
public_keys: impl IntoIterator<Item = &'a G1Element>,
|
||||
) -> G1Element {
|
||||
let mut g1_pointers = public_keys
|
||||
.into_iter()
|
||||
.map(|g1| g1.c_element)
|
||||
.collect::<Vec<_>>();
|
||||
G1Element {
|
||||
c_element: unsafe {
|
||||
CoreMPLAggregatePubKeys(
|
||||
self.as_mut_ptr(),
|
||||
g1_pointers.as_mut_ptr(),
|
||||
g1_pointers.len(),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn aggregate_sigs<'a>(&self, sigs: impl IntoIterator<Item = &'a G2Element>) -> G2Element {
|
||||
let mut g2_pointers = sigs.into_iter().map(|g2| g2.c_element).collect::<Vec<_>>();
|
||||
G2Element {
|
||||
c_element: unsafe {
|
||||
CoreMPLAggregateSigs(
|
||||
self.as_mut_ptr(),
|
||||
g2_pointers.as_mut_ptr(),
|
||||
g2_pointers.len(),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn aggregate_verify<'a>(
|
||||
&self,
|
||||
public_keys: impl IntoIterator<Item = &'a G1Element>,
|
||||
messages: impl IntoIterator<Item = &'a [u8]>,
|
||||
signature: &G2Element,
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
struct AggregateVerifyArgs {
|
||||
g1_pointers: Vec<*mut c_void>,
|
||||
messages_pointers: Vec<*const u8>,
|
||||
messages_lengths: Vec<usize>,
|
||||
}
|
||||
|
||||
// TODO put constructor inside struct?
|
||||
fn prepare_aggregate_verify_args<'a>(
|
||||
public_keys: impl IntoIterator<Item = &'a G1Element>,
|
||||
messages: impl IntoIterator<Item = &'a [u8]>,
|
||||
) -> AggregateVerifyArgs {
|
||||
let g1_pointers = public_keys
|
||||
.into_iter()
|
||||
.map(|g1| g1.c_element)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut messages_pointers = Vec::new();
|
||||
let mut messages_lengths = Vec::new();
|
||||
|
||||
for m in messages.into_iter() {
|
||||
messages_pointers.push(m.as_ptr());
|
||||
messages_lengths.push(m.len());
|
||||
}
|
||||
|
||||
AggregateVerifyArgs {
|
||||
g1_pointers,
|
||||
messages_pointers,
|
||||
messages_lengths,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BasicSchemeMPL {
|
||||
scheme: *mut c_void,
|
||||
}
|
||||
|
||||
impl BasicSchemeMPL {
|
||||
pub fn new() -> Self {
|
||||
BasicSchemeMPL {
|
||||
scheme: unsafe { NewBasicSchemeMPL() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for BasicSchemeMPL {
|
||||
fn as_mut_ptr(&self) -> *mut c_void {
|
||||
self.scheme
|
||||
}
|
||||
|
||||
fn sign(&self, private_key: &PrivateKey, message: &[u8]) -> G2Element {
|
||||
G2Element {
|
||||
c_element: unsafe {
|
||||
CoreMPLSign(
|
||||
self.scheme,
|
||||
private_key.as_mut_ptr(),
|
||||
message.as_ptr() as *const _,
|
||||
message.len(),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn verify(&self, public_key: &G1Element, message: &[u8], signature: &G2Element) -> bool {
|
||||
unsafe {
|
||||
CoreMPLVerify(
|
||||
self.scheme,
|
||||
public_key.c_element,
|
||||
message.as_ptr() as *const _,
|
||||
message.len(),
|
||||
signature.c_element,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn aggregate_verify<'a>(
|
||||
&self,
|
||||
public_keys: impl IntoIterator<Item = &'a G1Element>,
|
||||
messages: impl IntoIterator<Item = &'a [u8]>,
|
||||
signature: &G2Element,
|
||||
) -> bool {
|
||||
let AggregateVerifyArgs {
|
||||
mut g1_pointers,
|
||||
mut messages_pointers,
|
||||
messages_lengths: mut messages_lengthes,
|
||||
} = prepare_aggregate_verify_args(public_keys, messages);
|
||||
|
||||
unsafe {
|
||||
BasicSchemeMPLAggregateVerify(
|
||||
self.as_mut_ptr(),
|
||||
g1_pointers.as_mut_ptr(),
|
||||
g1_pointers.len(),
|
||||
messages_pointers.as_mut_ptr() as *mut _,
|
||||
messages_lengthes.as_mut_ptr() as *mut _,
|
||||
messages_pointers.len(),
|
||||
signature.c_element,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LegacySchemeMPL {
|
||||
scheme: *mut c_void,
|
||||
}
|
||||
|
||||
impl LegacySchemeMPL {
|
||||
pub fn new() -> Self {
|
||||
LegacySchemeMPL {
|
||||
scheme: unsafe { NewLegacySchemeMPL() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for LegacySchemeMPL {
|
||||
fn as_mut_ptr(&self) -> *mut c_void {
|
||||
self.scheme
|
||||
}
|
||||
|
||||
fn sign(&self, private_key: &PrivateKey, message: &[u8]) -> G2Element {
|
||||
G2Element {
|
||||
c_element: unsafe {
|
||||
LegacySchemeMPLSign(
|
||||
self.scheme,
|
||||
private_key.as_mut_ptr(),
|
||||
message.as_ptr() as *const _,
|
||||
message.len(),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn verify(&self, public_key: &G1Element, message: &[u8], signature: &G2Element) -> bool {
|
||||
unsafe {
|
||||
LegacySchemeMPLVerify(
|
||||
self.scheme,
|
||||
public_key.c_element,
|
||||
message.as_ptr() as *const _,
|
||||
message.len(),
|
||||
signature.c_element,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_secure<'a>(
|
||||
&self,
|
||||
public_keys: impl IntoIterator<Item = &'a G1Element>,
|
||||
message: &[u8],
|
||||
signature: &G2Element,
|
||||
) -> bool {
|
||||
let mut g1_pointers = public_keys
|
||||
.into_iter()
|
||||
.map(|g1| g1.c_element)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
unsafe {
|
||||
LegacySchemeMPLVerifySecure(
|
||||
self.as_mut_ptr(),
|
||||
g1_pointers.as_mut_ptr(),
|
||||
g1_pointers.len(),
|
||||
signature.c_element,
|
||||
message.as_ptr() as *const _,
|
||||
message.len(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn aggregate_verify<'a>(
|
||||
&self,
|
||||
public_keys: impl IntoIterator<Item = &'a G1Element>,
|
||||
messages: impl IntoIterator<Item = &'a [u8]>,
|
||||
signature: &G2Element,
|
||||
) -> bool {
|
||||
let AggregateVerifyArgs {
|
||||
mut g1_pointers,
|
||||
mut messages_pointers,
|
||||
messages_lengths: mut messages_lengthes,
|
||||
} = prepare_aggregate_verify_args(public_keys, messages);
|
||||
|
||||
unsafe {
|
||||
LegacySchemeMPLAggregateVerify(
|
||||
self.as_mut_ptr(),
|
||||
g1_pointers.as_mut_ptr(),
|
||||
g1_pointers.len(),
|
||||
messages_pointers.as_mut_ptr() as *mut _,
|
||||
messages_lengthes.as_mut_ptr() as *mut _,
|
||||
messages_pointers.len(),
|
||||
signature.c_element,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for BasicSchemeMPL {
|
||||
fn drop(&mut self) {
|
||||
unsafe { BasicSchemeMPLFree(self.scheme) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AugSchemeMPL {
|
||||
scheme: *mut c_void,
|
||||
}
|
||||
|
||||
impl AugSchemeMPL {
|
||||
pub fn new() -> Self {
|
||||
AugSchemeMPL {
|
||||
scheme: unsafe { NewAugSchemeMPL() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for AugSchemeMPL {
|
||||
fn as_mut_ptr(&self) -> *mut c_void {
|
||||
self.scheme
|
||||
}
|
||||
|
||||
fn sign(&self, private_key: &PrivateKey, message: &[u8]) -> G2Element {
|
||||
G2Element {
|
||||
c_element: unsafe {
|
||||
AugSchemeMPLSign(
|
||||
self.scheme,
|
||||
private_key.as_mut_ptr(),
|
||||
message.as_ptr() as *const _,
|
||||
message.len(),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn verify(&self, public_key: &G1Element, message: &[u8], signature: &G2Element) -> bool {
|
||||
unsafe {
|
||||
AugSchemeMPLVerify(
|
||||
self.scheme,
|
||||
public_key.c_element,
|
||||
message.as_ptr() as *const _,
|
||||
message.len(),
|
||||
signature.c_element,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn aggregate_verify<'a>(
|
||||
&self,
|
||||
public_keys: impl IntoIterator<Item = &'a G1Element>,
|
||||
messages: impl IntoIterator<Item = &'a [u8]>,
|
||||
signature: &G2Element,
|
||||
) -> bool {
|
||||
let AggregateVerifyArgs {
|
||||
mut g1_pointers,
|
||||
mut messages_pointers,
|
||||
mut messages_lengths,
|
||||
} = prepare_aggregate_verify_args(public_keys, messages);
|
||||
|
||||
unsafe {
|
||||
AugSchemeMPLAggregateVerify(
|
||||
self.as_mut_ptr(),
|
||||
g1_pointers.as_mut_ptr(),
|
||||
g1_pointers.len(),
|
||||
messages_pointers.as_mut_ptr() as *mut _,
|
||||
messages_lengths.as_mut_ptr() as *mut _,
|
||||
messages_pointers.len(),
|
||||
signature.c_element,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AugSchemeMPL {
|
||||
fn drop(&mut self) {
|
||||
unsafe { AugSchemeMPLFree(self.scheme) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn verify_aggregate(scheme: impl Scheme) {
|
||||
let seed1 = b"seedweedseedweedseedweedseedweed";
|
||||
let seed2 = b"weedseedweedseedweedseedweedseed";
|
||||
let seed3 = b"seedseedseedseedweedweedweedweed";
|
||||
let seed4 = b"weedweedweedweedweedweedweedweed";
|
||||
|
||||
let private_key_1 =
|
||||
PrivateKey::key_gen(&scheme, seed1).expect("unable to generate private key");
|
||||
let private_key_2 =
|
||||
PrivateKey::key_gen(&scheme, seed2).expect("unable to generate private key");
|
||||
let private_key_3 =
|
||||
PrivateKey::key_gen(&scheme, seed3).expect("unable to generate private key");
|
||||
let private_key_4 =
|
||||
PrivateKey::key_gen(&scheme, seed4).expect("unable to generate private key");
|
||||
|
||||
let public_key_1 = private_key_1
|
||||
.g1_element()
|
||||
.expect("unable to get public key");
|
||||
let public_key_2 = private_key_2
|
||||
.g1_element()
|
||||
.expect("unable to get public key");
|
||||
let public_key_3 = private_key_3
|
||||
.g1_element()
|
||||
.expect("unable to get public key");
|
||||
let public_key_4 = private_key_4
|
||||
.g1_element()
|
||||
.expect("unable to get public key");
|
||||
|
||||
let message_1 = b"ayya";
|
||||
let message_2 = b"ayyb";
|
||||
let message_3 = b"ayyc";
|
||||
let message_4 = b"ayyd";
|
||||
|
||||
let signature_1 = scheme.sign(&private_key_1, message_1);
|
||||
let signature_2 = scheme.sign(&private_key_2, message_2);
|
||||
let signature_3 = scheme.sign(&private_key_3, message_3);
|
||||
let signature_4 = scheme.sign(&private_key_4, message_4);
|
||||
|
||||
let signature_agg = scheme.aggregate_sigs([&signature_1, &signature_2, &signature_3]);
|
||||
|
||||
let verify = scheme.aggregate_verify(
|
||||
[&public_key_1, &public_key_2, &public_key_3],
|
||||
[message_1.as_ref(), message_2.as_ref(), message_3.as_ref()],
|
||||
&signature_agg,
|
||||
);
|
||||
assert!(verify);
|
||||
|
||||
// Arbitrary trees of aggregates
|
||||
let signature_agg_final = scheme.aggregate_sigs([&signature_agg, &signature_4]);
|
||||
let verify_final = scheme.aggregate_verify(
|
||||
[&public_key_1, &public_key_2, &public_key_3, &public_key_4],
|
||||
[
|
||||
message_1.as_ref(),
|
||||
message_2.as_ref(),
|
||||
message_3.as_ref(),
|
||||
message_4.as_ref(),
|
||||
],
|
||||
&signature_agg_final,
|
||||
);
|
||||
assert!(verify_final);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_aggregate_aug() {
|
||||
verify_aggregate(AugSchemeMPL::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_aggregate_basic() {
|
||||
verify_aggregate(BasicSchemeMPL::new());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_aggregate_legacy() {
|
||||
verify_aggregate(LegacySchemeMPL::new());
|
||||
}
|
||||
}
|
71
rust-bindings/bls-signatures/src/utils.rs
Normal file
71
rust-bindings/bls-signatures/src/utils.rs
Normal file
@ -0,0 +1,71 @@
|
||||
use core::slice;
|
||||
use std::{
|
||||
ffi::{c_void, CStr},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
use bls_dash_sys::{GetLastErrorMsg, SecAllocBytes, SecFree};
|
||||
|
||||
use crate::BlsError;
|
||||
|
||||
pub(crate) fn c_err_to_result<T, F>(f: F) -> Result<T, BlsError>
|
||||
where
|
||||
F: FnOnce(&mut bool) -> T,
|
||||
{
|
||||
let mut did_error = false;
|
||||
let result = f(&mut did_error);
|
||||
|
||||
if did_error {
|
||||
let error_message = unsafe { CStr::from_ptr(GetLastErrorMsg()) };
|
||||
Err(BlsError {
|
||||
msg: String::from_utf8_lossy(error_message.to_bytes()).into_owned(),
|
||||
})
|
||||
} else {
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SecureBox {
|
||||
c_sec_alloc: *mut u8,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl SecureBox {
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn new(len: usize) -> Self {
|
||||
SecureBox {
|
||||
c_sec_alloc: unsafe { SecAllocBytes(len) },
|
||||
len,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn from_ptr(ptr: *mut u8, len: usize) -> Self {
|
||||
SecureBox {
|
||||
c_sec_alloc: ptr,
|
||||
len,
|
||||
}
|
||||
}
|
||||
|
||||
// Somewhere it returns *mut c_void
|
||||
pub(crate) fn as_mut_ptr(&mut self) -> *mut c_void {
|
||||
self.c_sec_alloc as *mut c_void
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(self.c_sec_alloc, self.len) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for SecureBox {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SecureBox {
|
||||
fn drop(&mut self) {
|
||||
unsafe { SecFree(self.as_mut_ptr()) }
|
||||
}
|
||||
}
|
7
rust-bindings/example/Cargo.toml
Normal file
7
rust-bindings/example/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "example"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bls-signatures = { path = "../bls-signatures" }
|
51
rust-bindings/example/src/main.rs
Normal file
51
rust-bindings/example/src/main.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use bls_signatures::{bip32::ExtendedPrivateKey, LegacySchemeMPL, Scheme};
|
||||
|
||||
const SEED: &'static [u8] = b"seedweedseedweedseedweedseedweed";
|
||||
|
||||
fn check_bip32_hd_keys() {
|
||||
println!("Check BIP32 hierarchical deterministic keys work");
|
||||
|
||||
let private_key =
|
||||
ExtendedPrivateKey::from_seed(SEED).expect("cannot generate extended private key");
|
||||
let public_key = private_key
|
||||
.extended_public_key()
|
||||
.expect("cannot get extended public key");
|
||||
|
||||
let private_child = private_key.private_child(1337);
|
||||
let private_grandchild = private_child.private_child(420);
|
||||
|
||||
let public_child = public_key.public_child(1337);
|
||||
let public_grandchild = public_child.public_child(420);
|
||||
|
||||
assert_eq!(
|
||||
public_grandchild,
|
||||
private_grandchild
|
||||
.extended_public_key()
|
||||
.expect("cannot get extended public key")
|
||||
);
|
||||
}
|
||||
|
||||
fn check_bip32_legacy_scheme() {
|
||||
println!("Check BIP32 signing works");
|
||||
|
||||
let private_key =
|
||||
ExtendedPrivateKey::from_seed(SEED).expect("cannot generate extended private key");
|
||||
let public_key = private_key
|
||||
.extended_public_key()
|
||||
.expect("cannot get extended public key");
|
||||
|
||||
let scheme = LegacySchemeMPL::new();
|
||||
let message = b"dash is og";
|
||||
let signature = scheme.sign(&private_key.private_key(), message);
|
||||
|
||||
assert!(scheme.verify(&public_key.public_key(), message, &signature));
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Run some checks to see if everything is linked up to original BLS library:");
|
||||
|
||||
check_bip32_hd_keys();
|
||||
check_bip32_legacy_scheme();
|
||||
|
||||
println!("All checks passed!");
|
||||
}
|
41
setjmp_patch.diff
Normal file
41
setjmp_patch.diff
Normal file
@ -0,0 +1,41 @@
|
||||
diff --git a/include/relic_err.h b/include/relic_err.h
|
||||
index e16f71fe..a4adb107 100644
|
||||
--- a/include/relic_err.h
|
||||
+++ b/include/relic_err.h
|
||||
@@ -33,7 +33,6 @@
|
||||
#define RLC_ERR_H
|
||||
|
||||
#include <stdint.h>
|
||||
-#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -43,6 +42,10 @@
|
||||
#include "relic_util.h"
|
||||
#include "relic_label.h"
|
||||
|
||||
+#ifdef CHECK
|
||||
+#include <setjmp.h>
|
||||
+#endif
|
||||
+
|
||||
/*============================================================================*/
|
||||
/* Constant definitions */
|
||||
/*============================================================================*/
|
||||
@@ -94,6 +97,8 @@ enum errors {
|
||||
*/
|
||||
typedef int err_t;
|
||||
|
||||
+#ifdef CHECK
|
||||
+
|
||||
/**
|
||||
* Type that describes an error status, including the error code and the program
|
||||
* location where the error occurred.
|
||||
@@ -107,6 +112,8 @@ typedef struct _sts_t {
|
||||
int block;
|
||||
} sts_t;
|
||||
|
||||
+#endif
|
||||
+
|
||||
/*============================================================================*/
|
||||
/* Macro definitions */
|
||||
/*============================================================================*/
|
@ -11,8 +11,7 @@ add_library(dashbls
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/extendedpublickey.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/legacy.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/schemes.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/threshold.cpp
|
||||
)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/threshold.cpp)
|
||||
|
||||
target_include_directories(dashbls
|
||||
PUBLIC
|
||||
|
@ -98,6 +98,14 @@ G1Element G1Element::FromNative(const g1_t element)
|
||||
return ele;
|
||||
}
|
||||
|
||||
G1Element G1Element::Copy() {
|
||||
G1Element ele;
|
||||
g1_copy(ele.p, this->p);
|
||||
|
||||
return ele;
|
||||
}
|
||||
|
||||
|
||||
G1Element G1Element::FromMessage(const std::vector<uint8_t>& message,
|
||||
const uint8_t* dst,
|
||||
int dst_len)
|
||||
@ -246,6 +254,7 @@ G2Element G2Element::FromBytesUnchecked(Bytes const bytes, const bool fLegacy)
|
||||
|
||||
if (fLegacy) {
|
||||
std::memcpy(buffer + 1, bytes.begin(), G2Element::SIZE);
|
||||
buffer[0] = 0x00;
|
||||
} else {
|
||||
std::memcpy(buffer + 1, bytes.begin() + G2Element::SIZE / 2, G2Element::SIZE / 2);
|
||||
std::memcpy(buffer + 1 + G2Element::SIZE / 2, bytes.begin(), G2Element::SIZE / 2);
|
||||
@ -358,6 +367,14 @@ void G2Element::ToNative(g2_t output) const {
|
||||
g2_copy(output, (g2_st*)q);
|
||||
}
|
||||
|
||||
G2Element G2Element::Copy() {
|
||||
G2Element ele;
|
||||
g2_copy(ele.q, this->q);
|
||||
|
||||
return ele;
|
||||
}
|
||||
|
||||
|
||||
G2Element G2Element::Negate() const
|
||||
{
|
||||
G2Element ans;
|
||||
|
@ -56,7 +56,7 @@ void TestHKDF(string ikm_hex, string salt_hex, string info_hex, string prk_expec
|
||||
|
||||
TEST_CASE("class PrivateKey") {
|
||||
uint8_t buffer[PrivateKey::PRIVATE_KEY_SIZE];
|
||||
memcmp(buffer, getRandomSeed().data(), PrivateKey::PRIVATE_KEY_SIZE);
|
||||
memcpy(buffer, getRandomSeed().data(), PrivateKey::PRIVATE_KEY_SIZE);
|
||||
SECTION("Copy {constructor|assignment operator}") {
|
||||
PrivateKey pk1 = PrivateKey::RandomPrivateKey();
|
||||
PrivateKey pk2 = PrivateKey::RandomPrivateKey();
|
||||
|
Loading…
Reference in New Issue
Block a user