diff --git a/.gitignore b/.gitignore index 2fc767cca..9f62575e5 100644 --- a/.gitignore +++ b/.gitignore @@ -120,5 +120,3 @@ nbproject __pycache__/ *.pyc *.log - -Cargo.lock diff --git a/.gitmodules b/.gitmodules index 95bee114a..721cce3b4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,6 +14,3 @@ path = external/supercop url = https://github.com/monero-project/supercop branch = monero -[submodule "external/fcmp-plus-plus"] - path = external/fcmp-plus-plus - url = https://github.com/kayabaNerve/fcmp-plus-plus.git diff --git a/src/fcmp/CMakeLists.txt b/src/fcmp/CMakeLists.txt index 4db451d68..b7aca03fb 100644 --- a/src/fcmp/CMakeLists.txt +++ b/src/fcmp/CMakeLists.txt @@ -36,7 +36,7 @@ add_subdirectory(fcmp_rust) monero_add_library_with_deps( NAME fcmp - DEPENDS rust_cxx + DEPENDS fcmp_rust SOURCES ${fcmp_sources} ${fcmp_headers}) @@ -46,5 +46,5 @@ target_link_libraries(fcmp crypto epee PRIVATE - fcmp_rust + ${CMAKE_CURRENT_BINARY_DIR}/fcmp_rust/libfcmp_rust.a ${EXTRA_LIBRARIES}) diff --git a/src/fcmp/curve_trees.cpp b/src/fcmp/curve_trees.cpp index 6801475bc..f210022ef 100644 --- a/src/fcmp/curve_trees.cpp +++ b/src/fcmp/curve_trees.cpp @@ -1,21 +1,21 @@ // 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 @@ -46,7 +46,7 @@ typename C::Point get_new_parent(const C &curve, const typename C::Chunk &new_ch { // New parent means no prior children, fill priors with 0 std::vector prior_children; - tower_cycle::extend_zeroes(curve, new_children.size(), prior_children); + tower_cycle::extend_zeroes(curve, new_children.len, prior_children); return curve.hash_grow( curve.m_hash_init_point, @@ -76,17 +76,17 @@ static typename C::Point get_first_parent(const C &curve, if (child_layer_last_hash_updated) { // If the last chunk has updated children in it, then we need to get the delta to the old children - prior_children.emplace_back(curve.clone(last_chunk_ptr->last_child)); + prior_children.emplace_back(last_chunk_ptr->last_child); // Extend prior children by zeroes for any additional new children, since they must be new - if (new_children.size() > 1) - tower_cycle::extend_zeroes(curve, new_children.size() - 1, prior_children); + if (new_children.len > 1) + tower_cycle::extend_zeroes(curve, new_children.len - 1, prior_children); } else if (offset > 0) { // If we're updating the parent hash and no children were updated, then we're just adding new children // to the existing last chunk and can fill priors with 0 - tower_cycle::extend_zeroes(curve, new_children.size(), prior_children); + tower_cycle::extend_zeroes(curve, new_children.len, prior_children); } else { @@ -190,8 +190,9 @@ static void hash_layer(const C &curve, const auto chunk_start = child_scalars.data() + chunk_start_idx; const typename C::Chunk chunk{chunk_start, chunk_size}; - for (const auto &c : chunk) - MDEBUG("Hashing " << curve.to_string(c)); + for (uint c = 0; c < chunk_size; ++c) { + MDEBUG("Hashing " << curve.to_string(chunk_start[c])); + } // Hash the chunk of children typename C::Point chunk_hash = chunk_start_idx == 0 @@ -264,9 +265,9 @@ typename CurveTrees::TreeExtension CurveTrees::get_tree_extensio for (const auto &leaf : new_leaf_tuples) { tree_extension.leaves.tuples.emplace_back(LeafTuple{ - .O_x = m_c2.clone(leaf.O_x), - .I_x = m_c2.clone(leaf.I_x), - .C_x = m_c2.clone(leaf.C_x) + .O_x = leaf.O_x, + .I_x = leaf.I_x, + .C_x = leaf.C_x }); } @@ -378,9 +379,9 @@ std::vector CurveTrees::flatten_leaves(const std::v for (const auto &l : leaves) { // TODO: implement without cloning - flattened_leaves.emplace_back(m_c2.clone(l.O_x)); - flattened_leaves.emplace_back(m_c2.clone(l.I_x)); - flattened_leaves.emplace_back(m_c2.clone(l.C_x)); + flattened_leaves.emplace_back(l.O_x); + flattened_leaves.emplace_back(l.I_x); + flattened_leaves.emplace_back(l.C_x); } return flattened_leaves; diff --git a/src/fcmp/fcmp_rust/.gitignore b/src/fcmp/fcmp_rust/.gitignore new file mode 100644 index 000000000..5a07b8927 --- /dev/null +++ b/src/fcmp/fcmp_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/fcmp_rust/CMakeLists.txt b/src/fcmp/fcmp_rust/CMakeLists.txt index e14564be0..cb25b3378 100644 --- a/src/fcmp/fcmp_rust/CMakeLists.txt +++ b/src/fcmp/fcmp_rust/CMakeLists.txt @@ -34,37 +34,28 @@ else () set(TARGET_DIR "release") endif () -set(FCMP_RUST_CXX "${CMAKE_CURRENT_BINARY_DIR}/fcmp_rust.cc") set(FCMP_RUST_HEADER_DIR "${MONERO_GENERATED_HEADERS_DIR}/fcmp_rust") -set(FCMP_RUST_HEADER "${FCMP_RUST_HEADER_DIR}/fcmp_rust.h") -set(CXX_HEADER "${FCMP_RUST_HEADER_DIR}/cxx.h") +set(FCMP_RUST_HEADER "${FCMP_RUST_HEADER_DIR}/fcmp++.h") +set(FCMP_RUST_LIB "${CMAKE_CURRENT_BINARY_DIR}/libfcmp_rust.a") # Removing OUTPUT files makes sure custom command runs every time -file(REMOVE_RECURSE "${FCMP_RUST_CXX}") file(REMOVE_RECURSE "${FCMP_RUST_HEADER_DIR}") file(MAKE_DIRECTORY "${FCMP_RUST_HEADER_DIR}") +file(REMOVE "${FCMP_RUST_LIB}") + add_custom_command( COMMENT "Building rust fcmp lib" - OUTPUT ${FCMP_RUST_CXX} ${FCMP_RUST_HEADER} ${CXX_HEADER} + OUTPUT ${FCMP_RUST_HEADER} + OUTPUT ${FCMP_RUST_LIB} COMMAND CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} ${CARGO_CMD} - COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/cxxbridge/fcmp_rust/src/lib.rs.cc ${FCMP_RUST_CXX} - COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/cxxbridge/fcmp_rust/src/lib.rs.h ${FCMP_RUST_HEADER} - COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/cxxbridge/rust/cxx.h ${CXX_HEADER} + COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/fcmp++.h ${FCMP_RUST_HEADER} + COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_DIR}/libfcmp_rust.a ${FCMP_RUST_LIB} COMMAND echo "Finished copying fcmp rust targets" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} VERBATIM ) -add_custom_target(rust_cxx ALL DEPENDS ${CXX_HEADER}) - -set(fcmp_rust_sources ${FCMP_RUST_CXX}) - -monero_find_all_headers(fcmp_rust_headers "${FCMP_RUST_HEAfDER_DIR}") - -monero_add_library(fcmp_rust - ${fcmp_rust_sources} - ${fcmp_rust_headers}) - -set(FCMP_RUST_LIB "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_DIR}/libfcmp_rust.a") -target_link_libraries(fcmp_rust dl ${FCMP_RUST_LIB}) +#monero_find_all_headers(fcmp_rust_headers "${FCMP_RUST_HEADER_DIR}") +add_custom_target(fcmp_rust DEPENDS ${FCMP_RUST_LIB}) +#target_link_libraries(fcmp ${FCMP_RUST_LIB}) diff --git a/src/fcmp/fcmp_rust/Cargo.lock b/src/fcmp/fcmp_rust/Cargo.lock new file mode 100644 index 000000000..a8bd846a1 --- /dev/null +++ b/src/fcmp/fcmp_rust/Cargo.lock @@ -0,0 +1,716 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ciphersuite" +version = "0.4.1" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "blake2", + "dalek-ff-group", + "digest", + "elliptic-curve", + "ff", + "flexible-transcript", + "group", + "helioselene", + "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.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "group", + "platforms", + "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.1" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "crypto-bigint", + "curve25519-dalek", + "digest", + "ff", + "group", + "rand_core", + "rustversion", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +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/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "dalek-ff-group", + "group", + "hex", + "rand_core", + "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_rust" +version = "0.0.0" +dependencies = [ + "ciphersuite", + "ec-divisors", + "flexible-transcript", + "full-chain-membership-proofs", + "generalized-bulletproofs", + "helioselene", + "rand_core", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +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.2" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "blake2", + "digest", + "merlin", + "rustversion", + "subtle", + "zeroize", +] + +[[package]] +name = "full-chain-membership-proofs" +version = "0.1.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "ciphersuite", + "ec-divisors", + "flexible-transcript", + "generalized-bulletproofs", + "multiexp", + "rand_core", + "zeroize", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generalized-bulletproofs" +version = "0.1.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "ciphersuite", + "flexible-transcript", + "multiexp", + "rand_core", + "zeroize", +] + +[[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.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe739944a5406424e080edccb6add95685130b9f160d5407c639c7df0c5836b0" +dependencies = [ + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +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/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "crypto-bigint", + "dalek-ff-group", + "ec-divisors", + "ff", + "group", + "rand_core", + "rustversion", + "subtle", + "zeroize", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +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.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[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.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "crypto-bigint", + "ff", + "generic-array 1.0.0", + "group", + "rand_core", + "rustversion", + "subtle", + "zeroize", +] + +[[package]] +name = "multiexp" +version = "0.4.0" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "ff", + "group", + "rand_core", + "rustversion", + "std-shims", + "zeroize", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[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 = "platforms" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" + +[[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.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[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.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +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.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[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.1" +source = "git+https://github.com/kayabaNerve/fcmp-plus-plus#a17500708f5c6d79ec9cc33d53c771149db152c3" +dependencies = [ + "hashbrown", + "spin", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "2.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +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.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[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.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +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/fcmp_rust/Cargo.toml b/src/fcmp/fcmp_rust/Cargo.toml index d5052aac7..b6ac65d6c 100644 --- a/src/fcmp/fcmp_rust/Cargo.toml +++ b/src/fcmp/fcmp_rust/Cargo.toml @@ -8,14 +8,16 @@ name = "fcmp_rust" crate-type = ["staticlib"] [dependencies] -cxx = "1.0" -full-chain-membership-proofs = { path = "../../../external/fcmp-plus-plus/crypto/fcmps" } -ciphersuite = { path = "../../../external/fcmp-plus-plus/crypto/ciphersuite", features = ["helioselene", "ed25519"] } - -ec-divisors = { path = "../../../external/fcmp-plus-plus/crypto/divisors", features = ["ed25519"] } rand_core = { version = "0.6", features = ["getrandom"] } -transcript = { package = "flexible-transcript", path = "../../../external/fcmp-plus-plus/crypto/transcript", features = ["recommended"] } -generalized-bulletproofs = { path = "../../../external/fcmp-plus-plus/crypto/generalized-bulletproofs", features = ["tests"] } -[build-dependencies] -cxx-build = "1.0" \ No newline at end of file +transcript = { package = "flexible-transcript", git = "https://github.com/kayabaNerve/fcmp-plus-plus", features = ["recommended"] } +helioselene = { git = "https://github.com/kayabaNerve/fcmp-plus-plus" } +ciphersuite = { git = "https://github.com/kayabaNerve/fcmp-plus-plus", features = ["ed25519", "helioselene"] } + +generalized-bulletproofs = { git = "https://github.com/kayabaNerve/fcmp-plus-plus", features = ["tests"] } + +ec-divisors = { git = "https://github.com/kayabaNerve/fcmp-plus-plus", features = ["ed25519"] } +full-chain-membership-proofs = { git = "https://github.com/kayabaNerve/fcmp-plus-plus" } + +[patch.crates-io] +crypto-bigint = { git = "https://github.com/kayabaNerve/crypto-bigint", branch = "c-repr" } diff --git a/src/fcmp/fcmp_rust/build.rs b/src/fcmp/fcmp_rust/build.rs deleted file mode 100644 index 0b216f6d3..000000000 --- a/src/fcmp/fcmp_rust/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let _ = cxx_build::bridge("src/lib.rs"); - - println!("cargo:rerun-if-changed=src/lib.rs"); -} \ No newline at end of file diff --git a/src/fcmp/fcmp_rust/fcmp++.h b/src/fcmp/fcmp_rust/fcmp++.h new file mode 100644 index 000000000..590f2000a --- /dev/null +++ b/src/fcmp/fcmp_rust/fcmp++.h @@ -0,0 +1,144 @@ +namespace fcmp_rust { +#include +#include +#include +#include +#include + +// ----- deps C bindings ----- + +/// Inner integer type that the [`Limb`] newtype wraps. +// TODO: This is only valid for 64-bit platforms +using Word = uint64_t; + +/// Big integers are represented as an array of smaller CPU word-size integers +/// called "limbs". +using Limb = Word; + + +/// Stack-allocated big unsigned integer. +/// +/// Generic over the given number of `LIMBS` +/// +/// # Encoding support +/// This type supports many different types of encodings, either via the +/// [`Encoding`][`crate::Encoding`] trait or various `const fn` decoding and +/// encoding functions that can be used with [`Uint`] constants. +/// +/// Optional crate features for encoding (off-by-default): +/// - `generic-array`: enables [`ArrayEncoding`][`crate::ArrayEncoding`] trait which can be used to +/// [`Uint`] as `GenericArray` and a [`ArrayDecoding`][`crate::ArrayDecoding`] trait which +/// can be used to `GenericArray` as [`Uint`]. +/// - `rlp`: support for [Recursive Length Prefix (RLP)][RLP] encoding. +/// +/// [RLP]: https://eth.wiki/fundamentals/rlp +template +struct Uint { + /// Inner limb array. Stored from least significant to most significant. + Limb limbs[LIMBS]; +}; + + +/// A residue mod `MOD`, represented using `LIMBS` limbs. The modulus of this residue is constant, so it cannot be set at runtime. +/// Internally, the value is stored in Montgomery form (multiplied by MOD::R) until it is retrieved. +template +struct Residue { + Uint montgomery_form; +}; + + +/// A constant-time implementation of the Ed25519 field. +struct SeleneScalar { + Residue<4> _0; +}; + + +/// The field novel to Helios/Selene. +struct HeliosScalar { + Residue<4> _0; +}; + +struct HeliosPoint { + SeleneScalar x; + SeleneScalar y; + SeleneScalar z; +}; + +struct SelenePoint { + HeliosScalar x; + HeliosScalar y; + HeliosScalar z; +}; + +// ----- End deps C bindings ----- + +template +struct Box; + +struct HeliosGenerators { + void* generators; +}; + +struct SeleneGenerators { + void* generators; +}; + +template +struct CResult { + T value; + void* err; +}; + +template +struct Slice { + const T *buf; + uintptr_t len; +}; + +using HeliosScalarSlice = Slice; + +using SeleneScalarSlice = Slice; + +extern "C" { + +HeliosGenerators random_helios_generators(uintptr_t n); + +SeleneGenerators random_selene_generators(uintptr_t n); + +HeliosPoint random_helios_hash_init_point(); + +SelenePoint random_selene_hash_init_point(); + +uint8_t *helios_scalar_to_bytes(HeliosScalar helios_scalar); + +uint8_t *selene_scalar_to_bytes(SeleneScalar selene_scalar); + +uint8_t *helios_point_to_bytes(HeliosPoint helios_point); + +uint8_t *selene_point_to_bytes(SelenePoint selene_point); + +SeleneScalar ed25519_point_to_selene_scalar(const uint8_t *ed25519_point); + +HeliosScalar selene_point_to_helios_scalar(SelenePoint selene_point); + +SeleneScalar helios_point_to_selene_scalar(HeliosPoint helios_point); + +HeliosScalar helios_zero_scalar(); + +SeleneScalar selene_zero_scalar(); + +CResult hash_grow_helios(const HeliosGenerators *helios_generators, + HeliosPoint existing_hash, + uintptr_t offset, + HeliosScalarSlice prior_children, + HeliosScalarSlice new_children); + +CResult hash_grow_selene(const SeleneGenerators *selene_generators, + SelenePoint existing_hash, + uintptr_t offset, + SeleneScalarSlice prior_children, + SeleneScalarSlice new_children); + +} // extern "C" + +} diff --git a/src/fcmp/fcmp_rust/src/lib.rs b/src/fcmp/fcmp_rust/src/lib.rs index 8270e726c..9ae55f929 100644 --- a/src/fcmp/fcmp_rust/src/lib.rs +++ b/src/fcmp/fcmp_rust/src/lib.rs @@ -1,226 +1,186 @@ -use rand_core::OsRng; - use std::io; -use full_chain_membership_proofs::tree::hash_grow; +use rand_core::OsRng; use transcript::RecommendedTranscript; - +use helioselene::{HeliosPoint, SelenePoint, HelioseleneField as HeliosScalar, Field25519 as SeleneScalar}; use ciphersuite::{group::{Group, GroupEncoding, ff::{PrimeField, Field}}, Ciphersuite, Ed25519, Selene, Helios}; -use ec_divisors::DivisorCurve; - use generalized_bulletproofs::Generators; -// TODO: lint -#[cxx::bridge] -mod ffi { - // Rust types and signatures exposed to C++. - #[namespace = "fcmp_rust"] - extern "Rust" { - // TODO: Separate Helios and Selene namespaces - type HeliosGenerators; - type HeliosPoint; - type HeliosScalar; - - type SeleneGenerators; - type SelenePoint; - type SeleneScalar; - - fn random_helios_generators(n: usize) -> Box; - fn random_helios_hash_init_point() -> Box; - - fn random_selene_generators(n: usize) -> Box; - fn random_selene_hash_init_point() -> Box; - - fn clone_helios_scalar(helios_scalar: &Box) -> Box; - fn clone_selene_scalar(selene_scalar: &Box) -> Box; - fn clone_helios_point(helios_point: &Box) -> Box; - fn clone_selene_point(selene_point: &Box) -> Box; - - fn helios_scalar_to_bytes(helios_scalar: &Box) -> [u8; 32]; - fn selene_scalar_to_bytes(selene_scalar: &Box) -> [u8; 32]; - fn helios_point_to_bytes(helios_point: &Box) -> [u8; 32]; - fn selene_point_to_bytes(selene_point: &Box) -> [u8; 32]; - - fn ed25519_point_to_selene_scalar(ed25519_point: &[u8; 32]) -> Box; - fn selene_point_to_helios_scalar(selene_point: &Box) -> Box; - fn helios_point_to_selene_scalar(helios_point: &Box) -> Box; - - fn helios_zero_scalar() -> Box; - fn selene_zero_scalar() -> Box; - - pub fn hash_grow_helios( - helios_generators: &Box, - existing_hash: &Box, - offset: usize, - prior_children: &[Box], - new_children: &[Box] - ) -> Result>; - - pub fn hash_grow_selene( - selene_generators: &Box, - existing_hash: &Box, - offset: usize, - prior_children: &[Box], - new_children: &[Box] - ) -> Result>; - } -} +use ec_divisors::DivisorCurve; +use full_chain_membership_proofs::tree::hash_grow; // TODO: cleaner const usage of generators // TODO: try to get closer to underlying types // TODO: maybe don't do both tuple and Box? Just make these all boxes -pub struct HeliosGenerators(Generators); -pub struct HeliosPoint(::G); -pub struct HeliosScalar(::F); +#[repr(C)] +pub struct HeliosGenerators { + generators: Box> +} +#[repr(C)] +pub struct SeleneGenerators { + generators: Box> +} -pub struct SeleneGenerators(Generators); -pub struct SelenePoint(::G); -pub struct SeleneScalar(::F); - -#[allow(non_snake_case)] -pub fn random_helios_generators(n: usize) -> Box { +#[no_mangle] +pub extern "C" fn random_helios_generators(n: usize) -> HeliosGenerators { let helios_generators = generalized_bulletproofs::tests::generators::(n); - Box::new(HeliosGenerators(helios_generators)) + HeliosGenerators { generators: Box::new(helios_generators) } } -#[allow(non_snake_case)] -pub fn random_selene_generators(n: usize) -> Box { +#[no_mangle] +pub extern "C" fn random_selene_generators(n: usize) -> SeleneGenerators { let selene_generators = generalized_bulletproofs::tests::generators::(n); - Box::new(SeleneGenerators(selene_generators)) + SeleneGenerators { generators: Box::new(selene_generators) } } -#[allow(non_snake_case)] -pub fn random_helios_hash_init_point() -> Box { - let helios_hash_init_point = ::G::random(&mut OsRng); - dbg!(&helios_hash_init_point); - Box::new(HeliosPoint(helios_hash_init_point)) +#[no_mangle] +pub extern "C" fn random_helios_hash_init_point() -> HeliosPoint { + HeliosPoint::random(&mut OsRng) } -#[allow(non_snake_case)] -pub fn random_selene_hash_init_point() -> Box { - let selene_hash_init_point = ::G::random(&mut OsRng); - dbg!(&selene_hash_init_point); - Box::new(SelenePoint(selene_hash_init_point)) +#[no_mangle] +pub extern "C" fn random_selene_hash_init_point() -> SelenePoint { + SelenePoint::random(&mut OsRng) } -// TODO: should be able to use generics -// TODO: shorter names -pub fn clone_helios_scalar(helios_scalar: &Box) -> Box { - Box::new(HeliosScalar(helios_scalar.0)) +fn c_u8_32(bytes: [u8; 32]) -> *const u8 { + let arr_ptr = Box::into_raw(Box::new(bytes)); + arr_ptr as *const u8 } -pub fn clone_selene_scalar(selene_scalar: &Box) -> Box { - Box::new(SeleneScalar(selene_scalar.0)) +#[no_mangle] +pub extern "C" fn helios_scalar_to_bytes(helios_scalar: HeliosScalar) -> *const u8 { + c_u8_32(helios_scalar.to_repr()) } -pub fn clone_helios_point(helios_point: &Box) -> Box { - Box::new(HeliosPoint(helios_point.0)) +#[no_mangle] +pub extern "C" fn selene_scalar_to_bytes(selene_scalar: SeleneScalar) -> *const u8 { + c_u8_32(selene_scalar.to_repr()) } -pub fn clone_selene_point(selene_point: &Box) -> Box { - Box::new(SelenePoint(selene_point.0)) +#[no_mangle] +pub extern "C" fn helios_point_to_bytes(helios_point: HeliosPoint) -> *const u8 { + c_u8_32(helios_point.to_bytes()) } -// TODO: generics -pub fn helios_scalar_to_bytes(helios_scalar: &Box) -> [u8; 32] { - helios_scalar.0.to_repr() -} - -pub fn selene_scalar_to_bytes(selene_scalar: &Box) -> [u8; 32] { - selene_scalar.0.to_repr() -} - -pub fn helios_point_to_bytes(helios_point: &Box) -> [u8; 32] { - helios_point.0.to_bytes() -} - -pub fn selene_point_to_bytes(selene_point: &Box) -> [u8; 32] { - selene_point.0.to_bytes() +#[no_mangle] +pub extern "C" fn selene_point_to_bytes(selene_point: SelenePoint) -> *const u8 { + c_u8_32(selene_point.to_bytes()) } // Get the x coordinate of the ed25519 point // TODO: use generics for below logic -pub fn ed25519_point_to_selene_scalar(ed25519_point: &[u8; 32]) -> Box { +#[no_mangle] +pub extern "C" fn ed25519_point_to_selene_scalar(ed25519_point: *const u8) -> SeleneScalar { // TODO: unwrap or else error - let ed25519_point = ::read_G(&mut ed25519_point.as_slice()).unwrap(); + let mut ed25519_point = unsafe { core::slice::from_raw_parts(ed25519_point, 32) }; + let ed25519_point = ::read_G(&mut ed25519_point).unwrap(); let xy_coords = ::G::to_xy(ed25519_point); - let x: ::F = xy_coords.0; - Box::new(SeleneScalar(x)) + let x: SeleneScalar = xy_coords.0; + x } // TODO: use generics for below logic -pub fn selene_point_to_helios_scalar(selene_point: &Box) -> Box { - let xy_coords = ::G::to_xy(selene_point.0); - let x: ::F = xy_coords.0; - Box::new(HeliosScalar(x)) +#[no_mangle] +pub extern "C" fn selene_point_to_helios_scalar(selene_point: SelenePoint) -> HeliosScalar { + let xy_coords = SelenePoint::to_xy(selene_point); + let x: HeliosScalar = xy_coords.0; + x } // TODO: use generics for below logic -pub fn helios_point_to_selene_scalar(helios_point: &Box) -> Box { - let xy_coords = ::G::to_xy(helios_point.0); - let x: ::F = xy_coords.0; - Box::new(SeleneScalar(x)) +#[no_mangle] +pub extern "C" fn helios_point_to_selene_scalar(helios_point: HeliosPoint) -> SeleneScalar { + let xy_coords = HeliosPoint::to_xy(helios_point); + let x: SeleneScalar = xy_coords.0; + x } -pub fn helios_zero_scalar() -> Box { - Box::new(HeliosScalar(::F::ZERO)) +#[no_mangle] +pub extern "C" fn helios_zero_scalar() -> HeliosScalar { + HeliosScalar::ZERO } -pub fn selene_zero_scalar() -> Box { - Box::new(SeleneScalar(::F::ZERO)) +#[no_mangle] +pub extern "C" fn selene_zero_scalar() -> SeleneScalar { + SeleneScalar::ZERO } -// TODO: use generics for curves -pub fn hash_grow_helios( - helios_generators: &Box, - existing_hash: &Box, - offset: usize, - prior_children: &[Box], - new_children: &[Box] -) -> Result, io::Error> { - let prior_children = prior_children.iter().map(|c| c.0).collect::>(); - let new_children = new_children.iter().map(|c| c.0).collect::>(); +#[repr(C)] +pub struct Slice { + buf: *const T, + len: usize, +} +pub type HeliosScalarSlice = Slice; +pub type SeleneScalarSlice = Slice; +impl<'a, T> Into<&'a [T]> for Slice { + fn into(self) -> &'a [T] { + unsafe { core::slice::from_raw_parts(self.buf, self.len) } + } +} - let hash = hash_grow( - &helios_generators.0, - existing_hash.0, - offset, - &prior_children, - &new_children - ); - - if let Some(hash) = hash { - Ok(Box::new(HeliosPoint(hash))) - } else { - Err(io::Error::new(io::ErrorKind::Other, "failed to grow hash")) +#[repr(C)] +pub struct CResult { + value: T, + err: *const E, +} +impl CResult { + fn ok(value: T) -> Self { + CResult { value, err: core::ptr::null() } + } + fn err(default: T, err: E) -> Self { + CResult { value: default, err: Box::into_raw(Box::new(err)) } } } // TODO: use generics for curves -pub fn hash_grow_selene( - selene_generators: &Box, - existing_hash: &Box, +#[no_mangle] +pub extern "C" fn hash_grow_helios( + helios_generators: &HeliosGenerators, + existing_hash: HeliosPoint, offset: usize, - prior_children: &[Box], - new_children: &[Box] -) -> Result, io::Error> { - let prior_children = prior_children.iter().map(|c| c.0).collect::>(); - let new_children = new_children.iter().map(|c| c.0).collect::>(); - + prior_children: HeliosScalarSlice, + new_children: HeliosScalarSlice +) -> CResult { let hash = hash_grow( - &selene_generators.0, - existing_hash.0, + &helios_generators.generators, + existing_hash, offset, - &prior_children, - &new_children + prior_children.into(), + new_children.into(), ); if let Some(hash) = hash { - Ok(Box::new(SelenePoint(hash))) + CResult::ok(hash) } else { - Err(io::Error::new(io::ErrorKind::Other, "failed to grow hash")) + CResult::err(HeliosPoint::identity(), io::Error::new(io::ErrorKind::Other, "failed to grow hash")) } } + +// TODO: use generics for curves +#[no_mangle] +pub extern "C" fn hash_grow_selene( + selene_generators: &SeleneGenerators, + existing_hash: SelenePoint, + offset: usize, + prior_children: SeleneScalarSlice, + new_children: SeleneScalarSlice +) -> CResult { + let hash = hash_grow( + &selene_generators.generators, + existing_hash, + offset, + prior_children.into(), + new_children.into(), + ); + + if let Some(hash) = hash { + CResult::ok(hash) + } else { + CResult::err(SelenePoint::identity(), io::Error::new(io::ErrorKind::Other, "failed to grow hash")) + } + +} diff --git a/src/fcmp/tower_cycle.cpp b/src/fcmp/tower_cycle.cpp index 96fa5fe09..8ad64b4be 100644 --- a/src/fcmp/tower_cycle.cpp +++ b/src/fcmp/tower_cycle.cpp @@ -1,21 +1,21 @@ // 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 @@ -51,12 +51,16 @@ Helios::Point Helios::hash_grow( const Helios::Chunk &prior_children, const Helios::Chunk &new_children) const { - return fcmp_rust::hash_grow_helios( - m_generators, + auto res = fcmp_rust::hash_grow_helios( + &m_generators, existing_hash, offset, prior_children, new_children); + if (res.err != 0) { + throw std::runtime_error("failed to hash grow"); + } + return res.value; } //---------------------------------------------------------------------------------------------------------------------- Selene::Point Selene::hash_grow( @@ -65,32 +69,16 @@ Selene::Point Selene::hash_grow( const Selene::Chunk &prior_children, const Selene::Chunk &new_children) const { - return fcmp_rust::hash_grow_selene( - m_generators, + auto res = fcmp_rust::hash_grow_selene( + &m_generators, existing_hash, offset, prior_children, new_children); -} -//---------------------------------------------------------------------------------------------------------------------- -Helios::Scalar Helios::clone(const Helios::Scalar &scalar) const -{ - return fcmp_rust::clone_helios_scalar(scalar); -} -//---------------------------------------------------------------------------------------------------------------------- -Selene::Scalar Selene::clone(const Selene::Scalar &scalar) const -{ - return fcmp_rust::clone_selene_scalar(scalar); -} -//---------------------------------------------------------------------------------------------------------------------- -Helios::Point Helios::clone(const Helios::Point &point) const -{ - return fcmp_rust::clone_helios_point(point); -} -//---------------------------------------------------------------------------------------------------------------------- -Selene::Point Selene::clone(const Selene::Point &point) const -{ - return fcmp_rust::clone_selene_point(point); + if (res.err != 0) { + throw std::runtime_error("failed to hash grow"); + } + return res.value; } //---------------------------------------------------------------------------------------------------------------------- Helios::Scalar Helios::zero_scalar() const @@ -105,22 +93,38 @@ Selene::Scalar Selene::zero_scalar() const //---------------------------------------------------------------------------------------------------------------------- std::array Helios::to_bytes(const Helios::Scalar &scalar) const { - return fcmp_rust::helios_scalar_to_bytes(scalar); + auto bytes = fcmp_rust::helios_scalar_to_bytes(scalar); + std::array res; + memcpy(&res, bytes, 32); + free(bytes); + return res; } //---------------------------------------------------------------------------------------------------------------------- std::array Selene::to_bytes(const Selene::Scalar &scalar) const { - return fcmp_rust::selene_scalar_to_bytes(scalar); + auto bytes = fcmp_rust::selene_scalar_to_bytes(scalar); + std::array res; + memcpy(&res, bytes, 32); + free(bytes); + return res; } //---------------------------------------------------------------------------------------------------------------------- std::array Helios::to_bytes(const Helios::Point &point) const { - return fcmp_rust::helios_point_to_bytes(point); + auto bytes = fcmp_rust::helios_point_to_bytes(point); + std::array res; + memcpy(&res, bytes, 32); + free(bytes); + return res; } //---------------------------------------------------------------------------------------------------------------------- std::array Selene::to_bytes(const Selene::Point &point) const { - return fcmp_rust::selene_point_to_bytes(point); + auto bytes = fcmp_rust::selene_point_to_bytes(point); + std::array res; + memcpy(&res, bytes, 32); + free(bytes); + return res; } //---------------------------------------------------------------------------------------------------------------------- std::string Helios::to_string(const typename Helios::Scalar &scalar) const @@ -148,13 +152,7 @@ std::string Selene::to_string(const typename Selene::Point &point) const //---------------------------------------------------------------------------------------------------------------------- SeleneScalar ed_25519_point_to_scalar(const crypto::ec_point &point) { - static_assert(sizeof(RustEd25519Point) == sizeof(crypto::ec_point), - "expected same size ed25519 point to rust representation"); - - // TODO: implement reading just the x coordinate of ed25519 point in C/C++ - fcmp::tower_cycle::RustEd25519Point rust_point; - memcpy(&rust_point, &point, sizeof(fcmp::tower_cycle::RustEd25519Point)); - return fcmp_rust::ed25519_point_to_selene_scalar(rust_point); + return fcmp_rust::ed25519_point_to_selene_scalar((uint8_t*) &point.data); } //---------------------------------------------------------------------------------------------------------------------- template diff --git a/src/fcmp/tower_cycle.h b/src/fcmp/tower_cycle.h index f63cac5ff..0f61bc08b 100644 --- a/src/fcmp/tower_cycle.h +++ b/src/fcmp/tower_cycle.h @@ -1,21 +1,21 @@ // 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 @@ -29,8 +29,7 @@ #pragma once #include "crypto/crypto.h" -#include "fcmp_rust/cxx.h" -#include "fcmp_rust/fcmp_rust.h" +#include "fcmp_rust/fcmp++.h" #include @@ -45,24 +44,24 @@ namespace tower_cycle using RustEd25519Point = std::array; // Need to forward declare Scalar types for point_to_cycle_scalar below -using SeleneScalar = rust::Box; -using HeliosScalar = rust::Box; +using SeleneScalar = fcmp_rust::SeleneScalar; +using HeliosScalar = fcmp_rust::HeliosScalar; //---------------------------------------------------------------------------------------------------------------------- struct HeliosT final { - using Generators = rust::Box; + using Generators = fcmp_rust::HeliosGenerators; using Scalar = HeliosScalar; - using Point = rust::Box; - using Chunk = rust::Slice; + using Point = fcmp_rust::HeliosPoint; + using Chunk = fcmp_rust::HeliosScalarSlice; using CycleScalar = SeleneScalar; }; //---------------------------------------------------------------------------------------------------------------------- struct SeleneT final { - using Generators = rust::Box; + using Generators = fcmp_rust::SeleneGenerators; using Scalar = SeleneScalar; - using Point = rust::Box; - using Chunk = rust::Slice; + using Point = fcmp_rust::SelenePoint; + using Chunk = fcmp_rust::SeleneScalarSlice; using CycleScalar = HeliosScalar; }; //---------------------------------------------------------------------------------------------------------------------- @@ -89,9 +88,6 @@ public: const typename C::Chunk &prior_children, const typename C::Chunk &new_children) const = 0; - virtual typename C::Scalar clone(const typename C::Scalar &scalar) const = 0; - virtual typename C::Point clone(const typename C::Point &point) const = 0; - virtual typename C::Scalar zero_scalar() const = 0; virtual std::array to_bytes(const typename C::Scalar &scalar) const = 0; @@ -133,9 +129,6 @@ public: const Chunk &prior_children, const Chunk &new_children) const override; - Scalar clone(const Scalar &scalar) const override; - Point clone(const Point &point) const override; - Scalar zero_scalar() const override; std::array to_bytes(const Scalar &scalar) const override; @@ -171,9 +164,6 @@ public: const Chunk &prior_children, const Chunk &new_children) const override; - Scalar clone(const Scalar &scalar) const override; - Point clone(const Point &point) const override; - Scalar zero_scalar() const override; std::array to_bytes(const Scalar &scalar) const override; diff --git a/tests/unit_tests/curve_trees.cpp b/tests/unit_tests/curve_trees.cpp index e2a588c44..d29e78249 100644 --- a/tests/unit_tests/curve_trees.cpp +++ b/tests/unit_tests/curve_trees.cpp @@ -1,21 +1,21 @@ // Copyright (c) 2014, 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 @@ -49,8 +49,8 @@ static fcmp::curve_trees::LastChunkData get_last_child_layer_chunk(const C &c return fcmp::curve_trees::LastChunkData{ .child_offset = child_offset, - .last_child = curve.clone(last_child), - .last_parent = curve.clone(last_parent), + .last_child = last_child, + .last_parent = last_parent, .child_layer_size = child_layer_size, .parent_layer_size = parent_layer_size }; @@ -204,9 +204,9 @@ void CurveTreesUnitTest::extend_tree(const CurveTreesV1::TreeExtension &tree_ext for (const auto &leaf : tree_extension.leaves.tuples) { tree_inout.leaves.emplace_back(CurveTreesV1::LeafTuple{ - .O_x = m_curve_trees.m_c2.clone(leaf.O_x), - .I_x = m_curve_trees.m_c2.clone(leaf.I_x), - .C_x = m_curve_trees.m_c2.clone(leaf.C_x) + .O_x = leaf.O_x, + .I_x = leaf.I_x, + .C_x = leaf.C_x }); } @@ -240,10 +240,10 @@ void CurveTreesUnitTest::extend_tree(const CurveTreesV1::TreeExtension &tree_ext // We updated the last hash if (started_at_tip) - c2_inout.back() = m_curve_trees.m_c2.clone(c2_ext.hashes.front()); + c2_inout.back() = c2_ext.hashes.front(); for (std::size_t i = started_at_tip ? 1 : 0; i < c2_ext.hashes.size(); ++i) - c2_inout.emplace_back(m_curve_trees.m_c2.clone(c2_ext.hashes[i])); + c2_inout.emplace_back(c2_ext.hashes[i]); ++c2_idx; } @@ -266,10 +266,10 @@ void CurveTreesUnitTest::extend_tree(const CurveTreesV1::TreeExtension &tree_ext // We updated the last hash if (started_at_tip) - c1_inout.back() = m_curve_trees.m_c1.clone(c1_ext.hashes.front()); + c1_inout.back() = c1_ext.hashes.front(); for (std::size_t i = started_at_tip ? 1 : 0; i < c1_ext.hashes.size(); ++i) - c1_inout.emplace_back(m_curve_trees.m_c1.clone(c1_ext.hashes[i])); + c1_inout.emplace_back(c1_ext.hashes[i]); ++c1_idx; }