diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index a99c0d584..84c99584d 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -277,9 +277,8 @@ mkdir -p "$LOGDIR_BASE" RUST_DEPS_VERSION=0 RUST_DEPS_HASH="gg5izydrra2b1ywgskvlrfrh983gf6b4" RUST_DEPS_ARCHIVE="rust_deps-${RUST_DEPS_VERSION}.tar.gz" -#UNCOMMENT_IN_10359# RUST_DEPS_STORE_ITEM="/gnu/store/${RUST_DEPS_HASH}-${RUST_DEPS_ARCHIVE}" -#UNCOMMENT_IN_10359# if [ ! -f "${RUST_DEPS_STORE_ITEM}" ]; then -if false; then #REMOVE_IN_10359# +RUST_DEPS_STORE_ITEM="/gnu/store/${RUST_DEPS_HASH}-${RUST_DEPS_ARCHIVE}" +if [ ! -f "${RUST_DEPS_STORE_ITEM}" ]; then time-machine environment --manifest="${PWD}/contrib/guix/rust/cargo.scm" \ --container \ --pure \ diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index eb3b86454..31dabd67d 100644 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -373,7 +373,7 @@ mkdir -p "$DISTSRC" # Unpack rust dependencies mkdir -p /rust/vendor - #UNCOMMENT_IN_10359# tar xf /rust-deps -C /rust + tar xf /rust-deps -C /rust # "vendor" rust std for dir in "${RUST_STD}"/vendor/*/; do diff --git a/src/fcmp_pp/CMakeLists.txt b/src/fcmp_pp/CMakeLists.txt index d5eebdc3e..56989b087 100644 --- a/src/fcmp_pp/CMakeLists.txt +++ b/src/fcmp_pp/CMakeLists.txt @@ -29,18 +29,42 @@ set(fcmp_pp_sources curve_trees.cpp fcmp_pp_crypto.cpp - fcmp_pp_types.cpp) + fcmp_pp_types.cpp + tower_cycle.cpp) monero_find_all_headers(fcmp_pp_headers "${CMAKE_CURRENT_SOURCE_DIR}") add_subdirectory(fcmp_pp_rust) -monero_add_library(fcmp_pp - ${fcmp_pp_sources} - ${fcmp_pp_headers}) +monero_add_library_with_deps( + NAME fcmp_pp + DEPENDS fcmp_pp_rust + SOURCES + ${fcmp_pp_sources} + ${fcmp_pp_headers}) + +if(WIN32) + set(EXTRA_RUST_LIBRARIES ws2_32 ntdll userenv) +else() + set(EXTRA_RUST_LIBRARIES ) +endif() target_link_libraries(fcmp_pp PUBLIC cncrypto PRIVATE - ${EXTRA_LIBRARIES}) + ${CMAKE_CURRENT_BINARY_DIR}/fcmp_pp_rust/libfcmp_pp_rust.a + ${EXTRA_LIBRARIES} + ${EXTRA_RUST_LIBRARIES}) + +# Try compiling C file ffi_api_c_compat.c which includes fcmp++.h, and throw an error if C compilation fails +try_compile(FFI_API_C_COMPAT_RES + "${CMAKE_CURRENT_BINARY_DIR}/fcmp_ffi_c" + "${CMAKE_CURRENT_SOURCE_DIR}/ffi_api_c_compat.c" + CMAKE_FLAGS -DCMAKE_C_STANDARD=11 + COMPILE_DEFINITIONS -I"${CMAKE_CURRENT_SOURCE_DIR}/fcmp_pp_rust" + OUTPUT_VARIABLE FFI_API_C_COMPAT_OUTPUT) +if(NOT FFI_API_C_COMPAT_RES) + message(SEND_ERROR "Error compiling ffi_api_c_compat.c: ${FFI_API_C_COMPAT_OUTPUT}") + message(FATAL_ERROR "The FCMP++ FFI API header 'fcmp++.h' has broken compatibility with C") +endif() diff --git a/src/fcmp_pp/fcmp_pp_rust/.gitignore b/src/fcmp_pp/fcmp_pp_rust/.gitignore new file mode 100644 index 000000000..5a07b8927 --- /dev/null +++ b/src/fcmp_pp/fcmp_pp_rust/.gitignore @@ -0,0 +1,4 @@ +# If a developer runs cargo build inside this sub-directory to only work with +# the Rust side of things, they'll create this target directory which shouldn't +# be committed +target diff --git a/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt b/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt index bdad6f5b5..c63b61b05 100644 --- a/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt +++ b/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt @@ -25,3 +25,106 @@ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +if(ARCH_ID MATCHES "x86-64" OR ARCH_ID MATCHES "amd64") + set(RUST_ARCH "x86_64") +elseif(ARCH_ID MATCHES "(arm64|armv8a|armv8-a)") + set(RUST_ARCH "aarch64") +elseif(ARCH_ID MATCHES "armv7-a") + set(RUST_ARCH "armv7") +elseif(ARCH_ID MATCHES "i386") + set(RUST_ARCH "i686") +elseif(ARCH_ID MATCHES "riscv64") + set(RUST_ARCH "riscv64gc") +else() + set(RUST_ARCH "${ARCH_ID}") +endif() + +if(MINGW) + set(RUST_PLATFORM "pc-windows") + set(RUST_TOOLCHAIN "-gnu") +elseif(APPLE) + if(CMAKE_SYSTEM_NAME STREQUAL "iOS") + if(CMAKE_OSX_SYSROOT MATCHES "i[pP]hone[sS]imulator") + set(RUST_PLATFORM "apple-ios-sim") + else() + set(RUST_PLATFORM "apple-ios") + endif() + else() + set(RUST_PLATFORM "apple-darwin") + endif() + set(RUST_TOOLCHAIN "") +elseif(FREEBSD) + set(RUST_PLATFORM "unknown-freebsd") + set(RUST_TOOLCHAIN "") +elseif(OPENBSD) + set(RUST_PLATFORM "unknown-openbsd") + set(RUST_TOOLCHAIN "") +elseif(ANDROID) + set(RUST_PLATFORM "linux-android") + if(RUST_ARCH MATCHES "(arm|armv7)") + set(RUST_TOOLCHAIN "eabi") + else() + set(RUST_TOOLCHAIN "") + endif() +elseif(DRAGONFLY) + set(RUST_PLATFORM "unknown-dragonfly") + set(RUST_TOOLCHAIN "") +elseif(CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)") + if(RUST_ARCH MATCHES "x86_64") + set(RUST_PLATFORM "pc-solaris") + set(RUST_TOOLCHAIN "") + elseif(RUST_ARCH MATCHES "sparcv9") + set(RUST_PLATFORM "sun-solaris") + set(RUST_TOOLCHAIN "") + endif() +else() + set(RUST_PLATFORM "unknown-linux") + if(RUST_ARCH MATCHES "armv7") + # Rust does support non-HF, yet Monero assumes HF for armv7 + set(RUST_TOOLCHAIN "-gnueabihf") + else() + set(RUST_TOOLCHAIN "-gnu") + endif() +endif() + +set(RUST_TARGET "${RUST_ARCH}-${RUST_PLATFORM}${RUST_TOOLCHAIN}") +message(STATUS "Using Rust target ${RUST_TARGET}") + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + if(SANITIZE) + message(STATUS "Using Rust ASAN") + # Rust ASAN is an experimental feature included in nightly at time of writing + set(CARGO_CMD RUSTFLAGS=-Zsanitizer=address cargo +nightly build --target "${RUST_TARGET}" ${CARGO_OPTIONS}) + else() + set(CARGO_CMD cargo build --target "${RUST_TARGET}" ${CARGO_OPTIONS}) + endif() + set(TARGET_DIR "debug") +else () + set(CARGO_CMD cargo build --target "${RUST_TARGET}" --release ${CARGO_OPTIONS}) + set(TARGET_DIR "release") +endif () + +set(FCMP_PP_RUST_HEADER_DIR "${MONERO_GENERATED_HEADERS_DIR}/fcmp_pp_rust") +set(FCMP_PP_RUST_HEADER "${FCMP_PP_RUST_HEADER_DIR}/fcmp++.h") +set(FCMP_PP_RUST_LIB "${CMAKE_CURRENT_BINARY_DIR}/libfcmp_pp_rust.a") + +# Removing OUTPUT files makes sure custom command runs every time +file(REMOVE_RECURSE "${FCMP_PP_RUST_HEADER_DIR}") +file(MAKE_DIRECTORY "${FCMP_PP_RUST_HEADER_DIR}") + +file(REMOVE "${FCMP_PP_RUST_LIB}") + +add_custom_command( + COMMENT "Building fcmp++ rust lib" + OUTPUT ${FCMP_PP_RUST_HEADER} + OUTPUT ${FCMP_PP_RUST_LIB} + COMMAND ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} ${CARGO_CMD} + COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/fcmp++.h ${FCMP_PP_RUST_HEADER} + COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/${RUST_TARGET}/${TARGET_DIR}/libfcmp_pp_rust.a ${FCMP_PP_RUST_LIB} + COMMAND echo "Finished copying fcmp++ rust targets" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + VERBATIM +) + +add_custom_target(fcmp_pp_rust DEPENDS ${FCMP_PP_RUST_LIB}) diff --git a/src/fcmp_pp/fcmp_pp_rust/Cargo.lock b/src/fcmp_pp/fcmp_pp_rust/Cargo.lock new file mode 100644 index 000000000..b6d6aed68 --- /dev/null +++ b/src/fcmp_pp/fcmp_pp_rust/Cargo.lock @@ -0,0 +1,689 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "ciphersuite" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae44ce6224d75ced726e5597265b8f334b9bf4767b8b42e058f2304005d8475" +dependencies = [ + "dalek-ff-group 0.4.6", + "digest", + "elliptic-curve", + "ff", + "flexible-transcript", + "group", + "k256", + "minimal-ed448", + "p256", + "rand_core", + "sha2", + "sha3", + "std-shims", + "subtle", + "zeroize", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "git+https://github.com/kayabaNerve/crypto-bigint?branch=c-repr#78352771313f1e9b8e48abe5ce30d50d6bdd291d" +dependencies = [ + "generic-array 0.14.7", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "ff", + "fiat-crypto", + "group", + "rand_core", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dalek-ff-group" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "231684731518402967286b76bedadedfd6b0867f814e2cd41d4a82bedea2902a" +dependencies = [ + "crypto-bigint", + "curve25519-dalek", + "digest", + "ff", + "group", + "rand_core", + "rustversion", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "dalek-ff-group" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26103554e8f7857b6015a4a9ef551c6ce0669f6caa040785d4394bf52041ccaf" +dependencies = [ + "ciphersuite", + "crypto-bigint", + "curve25519-dalek", + "digest", + "ff", + "group", + "rand_core", + "rustversion", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "ec-divisors" +version = "0.1.0" +source = "git+https://github.com/monero-oxide/monero-oxide?rev=71da8f03a87f596db674258cda74553068a57bcd#71da8f03a87f596db674258cda74553068a57bcd" +dependencies = [ + "dalek-ff-group 0.5.0", + "ff", + "group", + "rand_core", + "std-shims", + "subtle", + "zeroize", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "elliptic-curve", + "signature", + "spki", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array 0.14.7", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "tap", + "zeroize", +] + +[[package]] +name = "fcmp_pp_rust" +version = "0.0.0" +dependencies = [ + "ciphersuite", + "dalek-ff-group 0.5.0", + "helioselene", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "flexible-transcript" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "329fdf3a39d36921c94b665764caa152fdf08f0ed631085ba4ee7e51899d93b4" +dependencies = [ + "blake2", + "digest", + "merlin", + "std-shims", + "subtle", + "zeroize", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "generic-array" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb8bc4c28d15ade99c7e90b219f30da4be5c88e586277e8cbe886beeb868ab2" +dependencies = [ + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] + +[[package]] +name = "helioselene" +version = "0.1.0" +source = "git+https://github.com/monero-oxide/monero-oxide?rev=71da8f03a87f596db674258cda74553068a57bcd#71da8f03a87f596db674258cda74553068a57bcd" +dependencies = [ + "blake2", + "ciphersuite", + "crypto-bigint", + "dalek-ff-group 0.5.0", + "ec-divisors", + "ff", + "group", + "rand_core", + "std-shims", + "subtle", + "zeroize", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core", + "zeroize", +] + +[[package]] +name = "minimal-ed448" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209ec7c2b5573660a3c5d0f64c90f8ff286171b15ad2234e7a3fbf8f26180be" +dependencies = [ + "crypto-bigint", + "ff", + "generic-array 1.1.1", + "group", + "rand_core", + "rustversion", + "subtle", + "zeroize", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array 0.14.7", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core", +] + +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "std-shims" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fbb9ed849fede2765386134c64bc8984081e8c8408bc9201b99c6e3143ec5e7" +dependencies = [ + "hashbrown", + "rustversion", + "spin", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/src/fcmp_pp/fcmp_pp_rust/Cargo.toml b/src/fcmp_pp/fcmp_pp_rust/Cargo.toml new file mode 100644 index 000000000..54c590992 --- /dev/null +++ b/src/fcmp_pp/fcmp_pp_rust/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "fcmp_pp_rust" +version = "0.0.0" +edition = "2021" + +[lib] +name = "fcmp_pp_rust" +crate-type = ["staticlib"] + +[dependencies] +ciphersuite = { version = "0.4.2", features = ["ed25519"] } +dalek-ff-group = "0.5.0" +helioselene = { git = "https://github.com/monero-oxide/monero-oxide", rev = "71da8f03a87f596db674258cda74553068a57bcd" } + +[patch.crates-io] +crypto-bigint = { git = "https://github.com/kayabaNerve/crypto-bigint", branch = "c-repr" } + +[profile.dev] +lto = "off" +panic = "abort" +overflow-checks = true + +[profile.release] +lto = "thin" +panic = "abort" +overflow-checks = true +codegen-units = 1 + +[profile.dev.package] +helioselene = { opt-level = 3 } diff --git a/src/fcmp_pp/fcmp_pp_rust/fcmp++.h b/src/fcmp_pp/fcmp_pp_rust/fcmp++.h index a4f2e9381..60da05095 100644 --- a/src/fcmp_pp/fcmp_pp_rust/fcmp++.h +++ b/src/fcmp_pp/fcmp_pp_rust/fcmp++.h @@ -28,12 +28,47 @@ #pragma once +// static assertions +#if defined(__cplusplus) || (__STDC_VERSION__ >= 202311L) +#define FFI_STATIC_ASSERT static_assert +#else +#include +#define FFI_STATIC_ASSERT _Static_assert +#endif + +#include #include +// ----- deps C bindings ----- + +/// A constant-time implementation of the Ed25519 field. +/// This type is expected to be opaque to the C/C++ side, meaning only the Rust side should read/write +/// its internal represenation. We're using a modified crypto-bigint crate for this type so that we +/// can work with points and scalars across the FFI without tons of byte repr conversions. +struct SeleneScalar { + uintptr_t _0[32 / sizeof(uintptr_t)]; +}; +FFI_STATIC_ASSERT(sizeof(struct SeleneScalar) == 32, "SeleneScalar FFI type unexpected size"); +FFI_STATIC_ASSERT(alignof(struct SeleneScalar) == sizeof(uintptr_t), "SeleneScalar FFI type unexpected alignment"); + struct OutputTuple { uint8_t O[32]; uint8_t I[32]; uint8_t C[32]; }; +FFI_STATIC_ASSERT(sizeof(struct OutputTuple) == 32*3, "OutputTuple FFI type unexpected size"); +FFI_STATIC_ASSERT(alignof(struct OutputTuple) == 1, "OutputTuple FFI type unexpected alignment"); + +// ----- End deps C bindings ----- + +#ifdef __cplusplus +extern "C" { +#endif + +int selene_scalar_from_bytes(const uint8_t *selene_scalar_bytes, struct SeleneScalar *selene_scalar_out); + +#ifdef __cplusplus +} //extern "C" +#endif diff --git a/src/fcmp_pp/fcmp_pp_rust/src/lib.rs b/src/fcmp_pp/fcmp_pp_rust/src/lib.rs new file mode 100644 index 000000000..80f768dfa --- /dev/null +++ b/src/fcmp_pp/fcmp_pp_rust/src/lib.rs @@ -0,0 +1,64 @@ +use ciphersuite::Ciphersuite; + +use helioselene::{Field25519 as SeleneScalar, Selene}; + +use std::{mem::{align_of, size_of}, os::raw::c_int}; + +#[allow(non_snake_case)] +#[repr(C)] +pub struct OutputTuple { + O: [u8; 32], + I: [u8; 32], + C: [u8; 32], +} + +// Static assertions +// WARNING: if any of these break, fcmp++.h needs to be modified also +macro_rules! static_assert_size_eq { + ($T:ty, $N:expr) => { + const _: [(); $N] = [(); size_of::<$T>()]; + }; +} + +macro_rules! static_assert_alignment { + ($T:ty, $N:expr) => { + const _: [(); $N] = [(); align_of::<$T>()]; + }; +} + +static_assert_size_eq!(SeleneScalar, 32); +static_assert_alignment!(SeleneScalar, size_of::()); + +static_assert_size_eq!(OutputTuple, 32*3); +static_assert_alignment!(OutputTuple, 1); + +macro_rules! ec_elem_from_bytes { + ($fn_name:ident, $Type:ty, $Curve:ty, $from_bytes:ident) => { + /// # Safety + /// + /// This function assumes 32 bytes allocated, and to be passed a raw pointer to + /// the expected type. + #[allow(clippy::not_unsafe_ptr_arg_deref)] + #[no_mangle] + pub unsafe extern "C" fn $fn_name(bytes: *const u8, ec_elem_out: *mut $Type) -> c_int { + if ec_elem_out.is_null() { + return -1; + } + let mut bytes = unsafe { core::slice::from_raw_parts(bytes, 32) }; + match <$Curve>::$from_bytes(&mut bytes) { + Ok(ec_elem) => { + *ec_elem_out = ec_elem; + 0 + } + Err(_) => -2, + } + } + }; +} + +ec_elem_from_bytes!(selene_scalar_from_bytes, SeleneScalar, Selene, read_F); + +// https://github.com/rust-lang/rust/issues/79609 +#[cfg(all(target_os = "windows", target_arch = "x86"))] +#[no_mangle] +pub extern "C" fn _Unwind_Resume() {} diff --git a/src/fcmp_pp/tower_cycle.cpp b/src/fcmp_pp/tower_cycle.cpp new file mode 100644 index 000000000..c1a89175b --- /dev/null +++ b/src/fcmp_pp/tower_cycle.cpp @@ -0,0 +1,55 @@ +// Copyright (c) 2024, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "tower_cycle.h" + +#include "misc_log_ex.h" + +namespace fcmp_pp +{ +namespace tower_cycle +{ +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +#define CHECK_FFI_RES \ + CHECK_AND_ASSERT_THROW_MES(r == 0, __func__ << " failed with error code " << r); +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +// Exposed helper functions +//---------------------------------------------------------------------------------------------------------------------- +SeleneScalar selene_scalar_from_bytes(const crypto::ec_coord &bytes) +{ + SeleneScalar selene_scalar; + int r = ::selene_scalar_from_bytes(to_bytes(bytes), &selene_scalar); + CHECK_FFI_RES; + return selene_scalar; +} +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +} //namespace tower_cycle +} //namespace fcmp_pp diff --git a/src/fcmp_pp/tower_cycle.h b/src/fcmp_pp/tower_cycle.h new file mode 100644 index 000000000..4e3e038f0 --- /dev/null +++ b/src/fcmp_pp/tower_cycle.h @@ -0,0 +1,45 @@ +// Copyright (c) 2024, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include "crypto/crypto.h" +#include "fcmp_pp_rust/fcmp++.h" + + +namespace fcmp_pp +{ +namespace tower_cycle +{ +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +SeleneScalar selene_scalar_from_bytes(const crypto::ec_coord &bytes); +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +}//namespace tower_cycle +}//namespace fcmp_pp