diff --git a/src/fcmp_pp/CMakeLists.txt b/src/fcmp_pp/CMakeLists.txt index 32ca1b4f2..d5eebdc3e 100644 --- a/src/fcmp_pp/CMakeLists.txt +++ b/src/fcmp_pp/CMakeLists.txt @@ -27,10 +27,14 @@ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. set(fcmp_pp_sources - fcmp_pp_crypto.cpp) + curve_trees.cpp + fcmp_pp_crypto.cpp + fcmp_pp_types.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}) diff --git a/src/fcmp_pp/curve_trees.cpp b/src/fcmp_pp/curve_trees.cpp new file mode 100644 index 000000000..49650cd12 --- /dev/null +++ b/src/fcmp_pp/curve_trees.cpp @@ -0,0 +1,158 @@ +// 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 "curve_trees.h" + +#include "crypto/crypto.h" +#include "fcmp_pp_crypto.h" +#include "fcmp_pp_types.h" +#include "profile_tools.h" + +namespace +{ + // Struct composed of ec elems needed to get a full-fledged leaf tuple + struct PreLeafTuple final + { + fcmp_pp::EdDerivatives O_derivatives; + fcmp_pp::EdDerivatives I_derivatives; + fcmp_pp::EdDerivatives C_derivatives; + }; +} + +namespace fcmp_pp +{ +namespace curve_trees +{ +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +// Public helper functions +//---------------------------------------------------------------------------------------------------------------------- +OutputTuple output_to_tuple(const OutputPair &output_pair) +{ + const crypto::public_key &output_pubkey = output_pubkey_cref(output_pair); + const crypto::ec_point &commitment = commitment_cref(output_pair); + + TIME_MEASURE_NS_START(derive_key_image_generator_ns); + + // Derive key image generator using the original output pubkey. + // CRITICAL: it's CRITICALLY important that we use the original output pubkey here, and not `O` calculated later. + // If we were to use `O`, then an output with torsion could be double spent before and after the FCMP++ fork, since + // it would have 1 key image before the fork (tied to the output pubkey) and a distinct key image (tied to torsion + // cleared `O`). + crypto::ec_point I; + crypto::derive_key_image_generator(output_pubkey, use_biased_hash_to_point(output_pair), I); + + TIME_MEASURE_NS_FINISH(derive_key_image_generator_ns); + + LOG_PRINT_L3("derive_key_image_generator_ns: " << derive_key_image_generator_ns); + + // Get O and C from output pubkey and commitment + crypto::ec_point O = output_pubkey; + crypto::ec_point C = commitment; + + // If the output has already been checked for torsion, then we don't need to clear torsion here + if (!output_checked_for_torsion(output_pair)) + { + TIME_MEASURE_NS_START(clear_torsion_ns); + + if (!fcmp_pp::get_valid_torsion_cleared_point_vartime(output_pubkey, O)) + throw std::runtime_error("O is invalid for insertion to tree"); + if (!fcmp_pp::get_valid_torsion_cleared_point_vartime(commitment, C)) + throw std::runtime_error("C is invalid for insertion to tree"); + + if (O != output_pubkey) + LOG_PRINT_L2("Output pubkey has torsion: " << output_pubkey); + if (C != commitment) + LOG_PRINT_L2("Commitment has torsion: " << commitment); + + TIME_MEASURE_NS_FINISH(clear_torsion_ns); + + LOG_PRINT_L3("clear_torsion_ns: " << clear_torsion_ns); + } + +#if !defined(NDEBUG) + { + // Debug build safety checks + crypto::ec_point O_debug; + crypto::ec_point C_debug; + assert(fcmp_pp::get_valid_torsion_cleared_point_vartime(output_pubkey, O_debug)); + assert(fcmp_pp::get_valid_torsion_cleared_point_vartime(commitment, C_debug)); + assert(O == O_debug); + assert(C == C_debug); + } +#endif + + // Redundant check for safety + if (O == fcmp_pp::EC_I) + throw std::runtime_error("O cannot equal identity"); + if (C == fcmp_pp::EC_I) + throw std::runtime_error("C cannot equal identity"); + + return output_tuple_from_bytes(O, I, C); +} +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +// Static functions +//---------------------------------------------------------------------------------------------------------------------- +static PreLeafTuple output_tuple_to_pre_leaf_tuple(const OutputTuple &o) +{ + TIME_MEASURE_NS_START(point_to_ed_derivatives_ns); + + const crypto::ec_point &O = (crypto::ec_point&) o.O; + const crypto::ec_point &I = (crypto::ec_point&) o.I; + const crypto::ec_point &C = (crypto::ec_point&) o.C; + + /* + TODO: investigate perf impact of the following extraneous ops: + - Decompressing O and C when checking points for torsion and again here. + - Compressing I in derive_key_image_generator and decompressing again here. + */ + PreLeafTuple plt; + if (!fcmp_pp::point_to_ed_derivatives(O, plt.O_derivatives)) + throw std::runtime_error("failed to get ed derivatives from O"); + if (!fcmp_pp::point_to_ed_derivatives(I, plt.I_derivatives)) + throw std::runtime_error("failed to get ed derivatives from I"); + if (!fcmp_pp::point_to_ed_derivatives(C, plt.C_derivatives)) + throw std::runtime_error("failed to get ed derivatives from C"); + + TIME_MEASURE_NS_FINISH(point_to_ed_derivatives_ns); + + LOG_PRINT_L3("point_to_ed_derivatives_ns: " << point_to_ed_derivatives_ns); + + return plt; +} +//---------------------------------------------------------------------------------------------------------------------- +static PreLeafTuple output_to_pre_leaf_tuple(const OutputPair &output_pair) +{ + const auto o = output_to_tuple(output_pair); + return output_tuple_to_pre_leaf_tuple(o); +} +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +} //namespace curve_trees +} //namespace fcmp_pp diff --git a/src/fcmp_pp/curve_trees.h b/src/fcmp_pp/curve_trees.h new file mode 100644 index 000000000..ceb62f354 --- /dev/null +++ b/src/fcmp_pp/curve_trees.h @@ -0,0 +1,46 @@ +// 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_types.h" +#include "misc_log_ex.h" + + +namespace fcmp_pp +{ +namespace curve_trees +{ +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +OutputTuple output_to_tuple(const OutputPair &output_pair); +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +} //namespace curve_trees +} //namespace fcmp_pp diff --git a/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt b/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt new file mode 100644 index 000000000..bdad6f5b5 --- /dev/null +++ b/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt @@ -0,0 +1,27 @@ +# 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. diff --git a/src/fcmp_pp/fcmp_pp_rust/fcmp++.h b/src/fcmp_pp/fcmp_pp_rust/fcmp++.h new file mode 100644 index 000000000..a4f2e9381 --- /dev/null +++ b/src/fcmp_pp/fcmp_pp_rust/fcmp++.h @@ -0,0 +1,39 @@ +// Copyright (c) 2025, 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 + + +struct OutputTuple +{ + uint8_t O[32]; + uint8_t I[32]; + uint8_t C[32]; +}; diff --git a/src/fcmp_pp/fcmp_pp_types.cpp b/src/fcmp_pp/fcmp_pp_types.cpp new file mode 100644 index 000000000..517f69f30 --- /dev/null +++ b/src/fcmp_pp/fcmp_pp_types.cpp @@ -0,0 +1,108 @@ +// 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 "fcmp_pp_types.h" + +#include "misc_log_ex.h" + +namespace fcmp_pp +{ +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +// Helpers +//---------------------------------------------------------------------------------------------------------------------- +OutputTuple output_tuple_from_bytes(const crypto::ec_point &O, const crypto::ec_point &I, const crypto::ec_point &C) +{ + OutputTuple output_tuple; + + static_assert(sizeof(output_tuple.O) == sizeof(O), "unexpected sizeof O"); + static_assert(sizeof(output_tuple.I) == sizeof(I), "unexpected sizeof I"); + static_assert(sizeof(output_tuple.C) == sizeof(C), "unexpected sizeof C"); + + memcpy(output_tuple.O, &O, sizeof(O)); + memcpy(output_tuple.I, &I, sizeof(I)); + memcpy(output_tuple.C, &C, sizeof(C)); + + return output_tuple; +} +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +const crypto::public_key &output_pubkey_cref(const OutputPair &output_pair) +{ + struct output_pair_visitor + { + const crypto::public_key &operator()(const LegacyOutputPair &o) const + { return o.output_pubkey; } + const crypto::public_key &operator()(const CarrotOutputPairV1 &o) const + { return o.output_pubkey; } + }; + + return std::visit(output_pair_visitor{}, output_pair); +} +//---------------------------------------------------------------------------------------------------------------------- +const crypto::ec_point &commitment_cref(const OutputPair &output_pair) +{ + struct output_pair_visitor + { + const crypto::ec_point &operator()(const LegacyOutputPair &o) const + { return o.commitment; } + const crypto::ec_point &operator()(const CarrotOutputPairV1 &o) const + { return o.commitment; } + }; + + return std::visit(output_pair_visitor{}, output_pair); +} +//---------------------------------------------------------------------------------------------------------------------- +bool output_checked_for_torsion(const OutputPair &output_pair) +{ + struct output_pair_visitor + { + bool operator()(const LegacyOutputPair&) const + { return false; } + bool operator()(const CarrotOutputPairV1&) const + { return true; } + }; + + return std::visit(output_pair_visitor{}, output_pair); +} +//---------------------------------------------------------------------------------------------------------------------- +bool use_biased_hash_to_point(const OutputPair &output_pair) +{ + struct output_pair_visitor + { + bool operator()(const LegacyOutputPair&) const + { return true; } + bool operator()(const CarrotOutputPairV1&) const + { return false; } + }; + + return std::visit(output_pair_visitor{}, output_pair); +} +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +}//namespace fcmp_pp diff --git a/src/fcmp_pp/fcmp_pp_types.h b/src/fcmp_pp/fcmp_pp_types.h new file mode 100644 index 000000000..80a783931 --- /dev/null +++ b/src/fcmp_pp/fcmp_pp_types.h @@ -0,0 +1,115 @@ +// 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 +#include +#include + +#include "crypto/crypto.h" +#include "fcmp_pp_rust/fcmp++.h" + + +namespace fcmp_pp +{ +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +// Rust types +//---------------------------------------------------------------------------------------------------------------------- +using OutputTuple = ::OutputTuple; +//---------------------------------------------------------------------------------------------------------------------- +OutputTuple output_tuple_from_bytes(const crypto::ec_point &O, const crypto::ec_point &I, const crypto::ec_point &C); +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +// C++ types +//---------------------------------------------------------------------------------------------------------------------- +// Curve trees types +//---------------------------------------------------------------------------------------------------------------------- +// Output pubkey and commitment, ready to be converted to a leaf tuple +// - From {output_pubkey,commitment} -> {O,C} -> {O,I,C} -> {O.x,O.y,I.x,I.y,C.x,C.y} +// - Output pairs do NOT necessarily have torsion cleared. We need the output pubkey as it exists in the chain in order +// to derive the correct I (when deriving {O.x,O.y,I.x,I.y,C.x,C.y}). Torsion clearing O before deriving I from O +// would enable spending a torsioned output once before FCMP++ fork and again with a different key image via FCMP++. +template +struct OutputPairTemplate +{ + crypto::public_key output_pubkey; + // Uses the ec_point type to avoid a circular dep to ringct/rctTypes.h, and to differentiate from output_pubkey + crypto::ec_point commitment; + + OutputPairTemplate(const crypto::public_key &_output_pubkey, const crypto::ec_point &_commitment): + output_pubkey(_output_pubkey), + commitment(_commitment) + {}; + + OutputPairTemplate(): + output_pubkey{}, + commitment{} + {}; + + // WARNING: not constant time + bool operator==(const OutputPairTemplate &other) const + { + return output_pubkey == other.output_pubkey + && commitment == other.commitment; + } +}; + +// May have torsion, use biased key image generator for I +struct LegacyOutputPair : public OutputPairTemplate{}; +// No torsion, use unbiased key image generator for I +struct CarrotOutputPairV1 : public OutputPairTemplate{}; + +static_assert(sizeof(LegacyOutputPair) == (32+32), "sizeof LegacyOutputPair unexpected"); +static_assert(sizeof(CarrotOutputPairV1) == (32+32), "sizeof CarrotOutputPairV1 unexpected"); + +static_assert(std::has_unique_object_representations_v); +static_assert(std::has_unique_object_representations_v); + +using OutputPair = std::variant; + +const crypto::public_key &output_pubkey_cref(const OutputPair &output_pair); +const crypto::ec_point &commitment_cref(const OutputPair &output_pair); + +bool output_checked_for_torsion(const OutputPair &output_pair); +bool use_biased_hash_to_point(const OutputPair &output_pair); +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +}//namespace fcmp_pp + +// WARNING: not constant time +inline bool operator==(const fcmp_pp::OutputTuple &a, const fcmp_pp::OutputTuple &b) +{ + static_assert(sizeof(fcmp_pp::OutputTuple) == (sizeof(a.O) + sizeof(a.I) + sizeof(a.C)), + "unexpected sizeof OutputTuple for == implementation"); + return + (memcmp(a.O, b.O, sizeof(a.O)) == 0) && + (memcmp(a.I, b.I, sizeof(a.I)) == 0) && + (memcmp(a.C, b.C, sizeof(a.C)) == 0); +} diff --git a/src/fcmp_pp/ffi_api_c_compat.c b/src/fcmp_pp/ffi_api_c_compat.c new file mode 100644 index 000000000..c92510ebd --- /dev/null +++ b/src/fcmp_pp/ffi_api_c_compat.c @@ -0,0 +1,3 @@ +#include "fcmp++.h" + +int main() { return 0; }