/// @file dpf/bit_inject.hpp /// @brief Boolean bit × arithmetic value (2PC bit_mul and 3PC RSS injection). #ifndef LIBDPF_INCLUDE_DPF_BIT_INJECT_HPP__ #define LIBDPF_INCLUDE_DPF_BIT_INJECT_HPP__ #include #include #include #include "hedley/hedley.h" #include "dpf/beaver.hpp" #include "dpf/rss_seed.hpp" #include "dpf/secret_share.hpp" namespace dpf { namespace bit_inject { /// @brief 2PC: `b * x` via a beaver bit_mul on an existing session. template HEDLEY_WARN_UNUSED_RESULT beavers::wire inject2(beavers::session & s, beavers::wire bit_wire, beavers::wire arith_wire) { return s.bit_mul(bit_wire, arith_wire); } /// @brief Local y-factor of RSS bit injection before ring send. /// @details Party holds RSS bit `(b_own, b_next)` and arithmetic `(x_own, x_next)`. /// Local contribution mirrors RSS mul with the bit as a 0/1 factor. template HEDLEY_WARN_UNUSED_RESULT T rss_inject_local(const rss::party_seeds & seeds, T b_own, T b_next, T x_own, T x_next, std::uint64_t index) { // Treat bit components as ring elements in {0,1}. return rss::rss_mul_local(seeds, b_own, b_next, x_own, x_next, index); } /// @brief After ring refresh: party receives `y_prev` and forms RSS `(y_own, y_prev)` /// wait — standard RSS refresh: send y_own to next, receive from prev, /// store `(y_own, y_from_prev)`? Actually ABY3: party i holds y_i after /// local mul; sends y_i to party i-1; ends with (y_i, y_{i+1}). template HEDLEY_WARN_UNUSED_RESULT std::pair rss_refresh(T y_own, T y_from_next) { return {y_own, y_from_next}; } /// @brief Cleartext identity: `(b0⊕b1) * (x0+x1)`. template HEDLEY_WARN_UNUSED_RESULT Ring inject_clear(std::uint8_t b0, std::uint8_t b1, Ring x0, Ring x1) { const Ring b = static_cast((b0 ^ b1) & 1u); return static_cast(b * (x0 + x1)); } /// @brief Boolean RSS AND local factor (GF(2)). inline std::uint8_t rss_and_local(const rss::party_seeds & seeds, std::uint8_t a_own, std::uint8_t a_next, std::uint8_t b_own, std::uint8_t b_next, std::uint64_t index) { const std::uint8_t cross = static_cast( (a_own & b_own) ^ (a_own & b_next) ^ (a_next & b_own)); const std::uint8_t mask = static_cast( rss::zero_share(seeds, index) & 1u); return static_cast(cross ^ mask); } } // namespace bit_inject } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_BIT_INJECT_HPP__