Files
MP-SPDZ/Processor/Input.hpp

195 lines
4.3 KiB
C++

/*
* Input.cpp
*
*/
#include "Input.h"
#include "Processor.h"
#include "Auth/MAC_Check.h"
template<class T>
InputBase<T>::InputBase(ArithmeticProcessor* proc) :
values_input(0)
{
if (proc)
buffer.setup(&proc->private_input, -1, proc->private_input_filename);
}
template<class T>
Input<T>::Input(SubProcessor<T>& proc, MAC_Check& mc) :
InputBase<T>(&proc.Proc), proc(proc), MC(mc), shares(proc.P.num_players())
{
}
template<class T>
Input<T>::Input(SubProcessor<T>* proc, Player& P) :
InputBase<T>(&proc->Proc), proc(*proc), MC(proc->MC), shares(
P.num_players())
{
assert (proc != 0);
}
template<class T>
InputBase<T>::~InputBase()
{
#ifdef VERBOSE
if (timer.elapsed() > 0)
cerr << T::type_string() << " inputs: " << timer.elapsed() << endl;
#endif
}
template<class T>
void Input<T>::adjust_mac(T& share, const open_type& value)
{
typename T::mac_type tmp;
tmp.mul(MC.get_alphai(), value);
tmp.add(share.get_mac(),tmp);
share.set_mac(tmp);
}
template<class T>
void Input<T>::reset(int player)
{
shares[player].clear();
if (player == proc.P.my_num())
o.reset_write_head();
}
template<class T>
void Input<T>::add_mine(const clear& input)
{
int player = proc.P.my_num();
shares[player].push_back({});
T& share = shares[player].back();
proc.DataF.get_input(share, rr, player);
t.sub(input, rr);
t.pack(o);
xi.add(t, share.get_share());
share.set_share(xi);
adjust_mac(share, t);
this->values_input++;
}
template<class T>
void Input<T>::add_other(int player)
{
open_type t;
shares[player].push_back({});
proc.DataF.get_input(shares[player].back(), t, player);
}
template<class T>
void Input<T>::send_mine()
{
proc.P.send_all(o, true);
}
template<class T>
void Input<T>::start(int player, int n_inputs)
{
reset(player);
if (player == proc.P.my_num())
{
for (int i = 0; i < n_inputs; i++)
{
clear t;
try
{
this->buffer.input(t);
}
catch (not_enough_to_buffer& e)
{
throw runtime_error("Insufficient input data to buffer");
}
add_mine(t);
}
send_mine();
}
else
{
for (int i = 0; i < n_inputs; i++)
add_other(player);
}
}
template<class T>
void Input<T>::stop(int player, const vector<int>& targets)
{
if (proc.P.my_num() == player)
for (unsigned int i = 0; i < targets.size(); i++)
proc.get_S_ref(targets[i]) = finalize_mine();
else
{
octetStream o;
this->timer.start();
proc.P.receive_player(player, o, true);
this->timer.stop();
for (unsigned int i = 0; i < targets.size(); i++)
{
finalize_other(player, proc.get_S_ref(targets[i]), o);
}
}
}
template<class T>
T Input<T>::finalize_mine()
{
return shares[proc.P.my_num()].next();
}
template<class T>
void Input<T>::finalize_other(int player, T& target,
octetStream& o)
{
target = shares[player].next();
t.unpack(o);
adjust_mac(target, t);
}
template<class T>
void InputBase<T>::input(SubProcessor<T>& Proc,
const vector<int>& args)
{
auto& input = Proc.input;
for (int i = 0; i < Proc.P.num_players(); i++)
input.reset(i);
assert(args.size() % 2 == 0);
int n_from_me = 0;
if (Proc.Proc.opts.interactive and Proc.Proc.thread_num == 0)
{
for (size_t i = 1; i < args.size(); i += 2)
n_from_me += (args[i] == Proc.P.my_num());
if (n_from_me > 0)
cout << "Please input " << n_from_me << " numbers:" << endl;
}
for (size_t i = 0; i < args.size(); i += 2)
{
int n = args[i + 1];
if (n == Proc.P.my_num())
{
long x = Proc.Proc.get_input(n_from_me > 0);
input.add_mine(x);
}
else
{
input.add_other(n);
}
}
if (n_from_me > 0)
cout << "Thank you" << endl;
input.send_mine();
vector<vector<int>> regs(Proc.P.num_players());
for (size_t i = 0; i < args.size(); i += 2)
{
regs[args[i + 1]].push_back(args[i]);
}
for (int i = 0; i < Proc.P.num_players(); i++)
input.stop(i, regs[i]);
}