/* * PairwiseSetup.cpp * */ #include #include "FHE/NoiseBounds.h" #include "FHE/NTL-Subs.h" #include "Math/Setup.h" #include "FHEOffline/Proof.h" #include "FHEOffline/PairwiseMachine.h" #include "FHEOffline/TemiSetup.h" #include "Tools/Commit.h" #include "Tools/Bundle.h" #include "Processor/OnlineOptions.h" #include "Protocols/LowGearKeyGen.h" #include "Protocols/Share.hpp" #include "Protocols/mac_key.hpp" template void PairwiseSetup::init(const Player& P, int sec, int plaintext_length, int& extra_slack) { cout << "Finding parameters for security " << sec << " and field size ~2^" << plaintext_length << endl; PRNG G; G.ReSeed(); octetStream o; if (P.my_num() == 0) { extra_slack = generate_semi_setup(plaintext_length, sec, params, FieldD, true); params.pack(o); FieldD.pack(o); o.store(extra_slack); P.send_all(o); } else { P.receive_player(0, o); params.unpack(o); FieldD.unpack(o); FieldD.init_field(); o.get(extra_slack); } alpha = FieldD; alphai = read_or_generate_mac_key>(P); alpha.assign_constant(alphai); } template void PairwiseSetup::secure_init(Player& P, PairwiseMachine& machine, int plaintext_length, int sec) { ::secure_init(*this, P, machine, plaintext_length, sec, params); alpha = FieldD; machine.sk = FHE_SK(params, FieldD.get_prime()); for (auto& pk : machine.other_pks) pk = FHE_PK(params, FieldD.get_prime()); } template void secure_init(T& setup, Player& P, U& machine, int plaintext_length, int sec, FHE_Params& params) { assert(sec >= 0); machine.sec = sec; params.set_min_sec(sec); string filename = PREP_DIR + T::name() + "-" + to_string(plaintext_length) + "-" + to_string(sec) + "-" + to_string(params.secp()) + "-" + to_string(machine.comp_sec()) + "-" + to_string(params.get_matrix_dim()) + "-" + OnlineOptions::singleton.prime.get_str() + "-" + to_string(CowGearOptions::singleton.top_gear()) + "-P" + to_string(P.my_num()) + "-" + to_string(P.num_players()); string reason; auto base_setup = setup; try { octetStream os; os.input(filename); os.get(machine.extra_slack); setup.unpack(os); } catch (exception& e) { reason = e.what(); } try { setup.check(P, machine); } catch (mismatch_among_parties& e) { if (reason.empty()) reason = e.what(); } if (not reason.empty()) { if (OnlineOptions::singleton.has_option("expect_setup")) throw runtime_error("error in setup: " + reason); if (OnlineOptions::singleton.verbose) cerr << "Generating parameters for security " << sec << " and field size ~2^" << plaintext_length << " because no suitable material " "from a previous run was found (" << reason << ")" << endl; setup = base_setup; setup.generate(P, machine, plaintext_length, sec); setup.check(P, machine); octetStream os; os.store(machine.extra_slack); setup.pack(os); ofstream file(filename); os.output(file); } if (OnlineOptions::singleton.has_option("verbose_he")) { cerr << "Ciphertext length: " << params.p0().numBits(); for (size_t i = 1; i < params.FFTD().size(); i++) cerr << "+" << params.FFTD()[i].get_prime().numBits(); cerr << " (" << DIV_CEIL(params.p0().numBits(), 64); for (size_t i = 1; i < params.FFTD().size(); i++) cerr << "+" << DIV_CEIL(params.FFTD()[i].get_prime().numBits(), 64); cerr << " limbs)"; cerr << endl; cerr << "Number of slots: " << params.phi_m() << endl; } } template void PairwiseSetup::generate(Player&, MachineBase& machine, int plaintext_length, int sec) { machine.extra_slack = generate_semi_setup(plaintext_length, sec, params, FieldD, true); } template void PairwiseSetup::pack(octetStream& os) const { params.pack(os); FieldD.pack(os); alpha.pack(os); alphai.pack(os); } template void PairwiseSetup::unpack(octetStream& os) { params.unpack(os); FieldD.unpack(os); FieldD.init_field(); alpha.unpack(os); alphai.unpack(os); } template void PairwiseSetup::check(Player& P, PairwiseMachine& machine) { Bundle bundle(P); bundle.mine.store(machine.extra_slack); params.pack(bundle.mine); FieldD.hash(bundle.mine); bundle.compare(P); } template void PairwiseSetup::covert_key_generation(Player& P, PairwiseMachine& machine, int num_runs) { CODE_LOCATION vector G(num_runs); vector commits(num_runs, P); vector my_keys(num_runs, {params, FieldD.get_prime()}); Bundle pks(P); for (int i = 0; i < num_runs; i++) { my_keys[i].generate(G[i]); my_keys[i].pk.pack(pks.mine); commits[i].commit({SEED_SIZE, G[i].get_seed()}); } P.Broadcast_Receive(pks); int challenge = GlobalPRNG(P).get_uint(num_runs); machine.sk = my_keys[challenge].sk; machine.pk = my_keys[challenge].pk; for (int i = 0; i < num_runs; i++) if (i != challenge) commits[i].open({SEED_SIZE, G[i].get_seed()}); for (int i = 0; i < num_runs; i++) { for (int j = 0; j < P.num_players(); j++) if (j != P.my_num()) { FHE_PK pk(params); pk.unpack(pks[j]); if (i == challenge) machine.other_pks[j] = pk; else { FHE_KeyPair pair(params, FieldD.get_prime()); PRNG prng(commits[i].messages[j]); pair.generate(prng); if (pair.pk != pk) throw bad_keygen("covert pairwise key generation"); } } } } template void PairwiseSetup::covert_mac_generation(Player& P, PairwiseMachine& machine, int num_runs) { vector pks; for (auto& pk : machine.other_pks) pks.push_back(&pk); covert_generation(alpha, machine.enc_alphas, pks, &P, num_runs, Diagonal); alphai = alpha.element(0); } template void PairwiseSetup::key_and_mac_generation(Player& P, PairwiseMachine& machine, int num_runs, true_type) { covert_key_generation(P, machine, num_runs); covert_mac_generation(P, machine, num_runs); } template void PairwiseSetup::set_alphai(T alphai) { this->alphai = alphai; alpha.assign_constant(alphai); } template class PairwiseSetup; template class PairwiseSetup; template void secure_init(PartSetup&, Player&, MachineBase&, int, int, FHE_Params& params); template void secure_init(PartSetup&, Player&, MachineBase&, int, int, FHE_Params& params); template void secure_init(TemiSetup&, Player&, MachineBase&, int, int, FHE_Params& params); template void secure_init(TemiSetup&, Player&, MachineBase&, int, int, FHE_Params& params);