/* * Input.cpp * */ #include "Input.h" #include "Processor.h" template InputBase::InputBase(ArithmeticProcessor* proc) : P(0), values_input(0) { if (proc) buffer.setup(&proc->private_input, -1, proc->private_input_filename); } template Input::Input(SubProcessor& proc, MAC_Check& mc) : InputBase(&proc.Proc), proc(proc), MC(mc), shares(proc.P.num_players()) { } template Input::Input(SubProcessor* proc, Player& P) : InputBase(&proc->Proc), proc(*proc), MC(proc->MC), shares( P.num_players()) { assert (proc != 0); } template InputBase::~InputBase() { #ifdef VERBOSE if (timer.elapsed() > 0) cerr << T::type_string() << " inputs: " << timer.elapsed() << endl; #endif } template void Input::reset(int player) { InputBase::reset(player); shares[player].clear(); } template void InputBase::reset(int player) { os.resize(max(os.size(), player + 1UL)); os[player].reset_write_head(); } template void InputBase::reset_all(Player& P) { this->P = &P; os.resize(P.num_players()); for (int i = 0; i < P.num_players(); i++) reset(i); } template void Input::add_mine(const open_type& 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(this->os[player]); share += T::constant(t, 0, MC.get_alphai()); this->values_input++; } template void Input::add_other(int player) { open_type t; shares[player].push_back({}); proc.DataF.get_input(shares[player].back(), t, player); } template void InputBase::add_from_all(const clear& input) { for (int i = 0; i < P->num_players(); i++) if (i == P->my_num()) add_mine(input); else add_other(i); } template void Input::send_mine() { proc.P.send_all(this->os[proc.P.my_num()], true); } template void InputBase::exchange() { for (int i = 0; i < P->num_players(); i++) if (i == P->my_num()) send_mine(); else P->receive_player(i, os[i], true); } template void Input::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 void Input::stop(int player, const vector& 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 T Input::finalize_mine() { return shares[proc.P.my_num()].next(); } template void Input::finalize_other(int player, T& target, octetStream& o) { target = shares[player].next(); t.unpack(o); target += T::constant(t, 1, MC.get_alphai()); } template T InputBase::finalize(int player) { if (player == P->my_num()) return finalize_mine(); else { T res; finalize_other(player, res, os[player]); return res; } } template void InputBase::input(SubProcessor& Proc, const vector& 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 << " number(s):" << 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> 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]); }