Files
MP-SPDZ/Protocols/ReplicatedInput.hpp
2025-05-30 13:35:02 +10:00

161 lines
3.3 KiB
C++

/*
* ReplicatedInput.cpp
*
*/
#ifndef PROTOCOLS_REPLICATEDINPUT_HPP_
#define PROTOCOLS_REPLICATEDINPUT_HPP_
#include "ReplicatedInput.h"
#include "Processor/Processor.h"
#include "Processor/Input.hpp"
template<class T>
template<class U>
ReplicatedInput<T>::ReplicatedInput(SubProcessor<T>* proc,
const AstraPrepProtocol<U>& protocol) :
ReplicatedInput(proc, protocol.prng_protocol)
{
}
template<class T>
void ReplicatedInput<T>::reset(int player)
{
InputBase<T>::reset(player);
assert(P.num_players() == 3);
if (player == P.my_num())
{
this->shares.clear();
os.resize(2);
for (auto& o : os)
o.reset_write_head();
}
expect[player] = false;
to_send = 0;
}
template<class T>
inline void ReplicatedInput<T>::add_mine(const typename T::open_type& input, int n_bits)
{
auto& shares = this->shares;
T my_share;
if (T::clear::binary)
{
my_share[0].randomize(protocol.shared_prngs[0], n_bits);
my_share[1] = input - my_share[0];
my_share[1].pack(os[1], n_bits);
}
else
{
my_share[1] = input;
}
shares.push_back(my_share);
}
template<class T>
void ReplicatedInput<T>::add_other(int player, int)
{
expect[player] = true;
}
template<class T>
void ReplicatedInput<T>::send_mine()
{
for (auto& x : os)
x.append(0);
P.send_relative(os);
}
template<class T>
void ReplicatedInput<T>::prepare(size_t n_inputs)
{
os[1].reserve(n_inputs * T::clear::size());
to_send = &os[1];
}
template<class T>
void ReplicatedInput<T>::add_mine_prepared(T& share,
const typename T::open_type& input)
{
share[0].randomize(protocol.shared_prngs[0]);
share[1] = input;
share[1] -= share[0];
to_send->store_no_resize(share[1]);
}
template<class T>
void ReplicatedInput<T>::exchange()
{
CODE_LOCATION
if (not T::clear::binary and not to_send)
{
prepare(this->shares.size());
for (auto& share : this->shares)
{
add_mine_prepared(share, share[1]);
}
}
this->values_input += this->shares.size();
for (auto& x : os)
x.append(0);
bool receive = expect[P.get_player(1)];
bool send = not os[1].empty();
if (send)
if (receive)
P.pass_around(os[1], dest, -1);
else
P.send_to(P.get_player(-1), os[1]);
else
if (receive)
P.receive_player(P.get_player(1), dest);
this->shares.reset();
}
template<class T>
inline void ReplicatedInput<T>::finalize_other(int player, T& target,
octetStream&, int n_bits)
{
int offset = player - this->my_num;
if (offset == 1 or offset == -2)
{
typename T::value_type t;
t.unpack(dest, n_bits);
target[0] = t;
target[1] = 0;
}
else
{
target[0] = 0;
target[1].randomize(protocol.shared_prngs[1], n_bits);
}
}
template<class T>
T ReplicatedInput<T>::finalize_offset(int offset)
{
T res;
switch (offset)
{
case 0:
return this->finalize_mine();
case 1:
case -2:
res[0] = dest.get_no_check<typename T::value_type>();
break;
case 2:
case -1:
res[1].randomize(protocol.shared_prngs[1]);
}
return res;
}
template<class T>
T PrepLessInput<T>::finalize_mine()
{
return this->shares.next();
}
#endif