libdpf/include/dpf/bit_inject.hpp

78 lines
2.5 KiB
C++
Raw Permalink Normal View History

/// @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 <cstddef>
#include <cstdint>
#include <utility>
#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 <typename Ring>
HEDLEY_WARN_UNUSED_RESULT
beavers::wire<Ring> inject2(beavers::session<Ring> & s,
beavers::wire<Ring> bit_wire, beavers::wire<Ring> 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 <typename T>
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 <typename T>
HEDLEY_WARN_UNUSED_RESULT
std::pair<T, T> rss_refresh(T y_own, T y_from_next)
{
return {y_own, y_from_next};
}
/// @brief Cleartext identity: `(b0⊕b1) * (x0+x1)`.
template <typename Ring>
HEDLEY_WARN_UNUSED_RESULT
Ring inject_clear(std::uint8_t b0, std::uint8_t b1, Ring x0, Ring x1)
{
const Ring b = static_cast<Ring>((b0 ^ b1) & 1u);
return static_cast<Ring>(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<std::uint8_t>(
(a_own & b_own) ^ (a_own & b_next) ^ (a_next & b_own));
const std::uint8_t mask = static_cast<std::uint8_t>(
rss::zero_share<std::uint8_t>(seeds, index) & 1u);
return static_cast<std::uint8_t>(cross ^ mask);
}
} // namespace bit_inject
} // namespace dpf
#endif // LIBDPF_INCLUDE_DPF_BIT_INJECT_HPP__