From 11bb860b9d3d92e78057fd3b80036470938c9508 Mon Sep 17 00:00:00 2001 From: Marcel Keller Date: Wed, 25 Mar 2020 19:41:30 +1100 Subject: [PATCH] Semi-honest computation based on somewhat homomorphic encryption. --- FHEOffline/DataSetup.cpp | 23 +++++------ FHEOffline/DataSetup.h | 9 ++--- FHEOffline/PairwiseSetup.cpp | 2 +- Machines/soho-party.cpp | 33 +++++++++++++++ Makefile | 3 +- Protocols/SohoPrep.h | 31 ++++++++++++++ Protocols/SohoPrep.hpp | 78 ++++++++++++++++++++++++++++++++++++ Protocols/SohoShare.h | 40 ++++++++++++++++++ README.md | 10 +++-- Scripts/soho.sh | 8 ++++ Scripts/test_tutorial.sh | 2 +- 11 files changed, 213 insertions(+), 26 deletions(-) create mode 100644 Machines/soho-party.cpp create mode 100644 Protocols/SohoPrep.h create mode 100644 Protocols/SohoPrep.hpp create mode 100644 Protocols/SohoShare.h create mode 100755 Scripts/soho.sh diff --git a/FHEOffline/DataSetup.cpp b/FHEOffline/DataSetup.cpp index dd2715bf1..3102d7eb4 100644 --- a/FHEOffline/DataSetup.cpp +++ b/FHEOffline/DataSetup.cpp @@ -346,31 +346,28 @@ void PartSetup::check(Player& P, MachineBase& machine) } template -void PartSetup::covert_key_generation(Player& P, - MultiplicativeMachine& machine, int num_runs) +void PartSetup::covert_key_generation(Player& P, int num_runs) { - auto& setup = machine.setup.part(); - Run_Gen_Protocol(setup.pk, setup.sk, P, num_runs, false); + Run_Gen_Protocol(pk, sk, P, num_runs, false); } template -void PartSetup::covert_mac_generation(Player& P, - MultiplicativeMachine& machine, int num_runs) +void PartSetup::covert_mac_generation(Player& P, int num_runs) { - auto& setup = machine.setup.part(); - generate_mac_key(setup.alphai, setup.calpha, setup.FieldD, setup.pk, P, + generate_mac_key(alphai, calpha, FieldD, pk, P, num_runs); } template -void PartSetup::covert_secrets_generation(Player& P, - MultiplicativeMachine& machine, int num_runs) +void PartSetup::covert_secrets_generation(Player& P, MachineBase& machine, + int num_runs) { octetStream os; params.pack(os); FieldD.pack(os); string filename = PREP_DIR "ChaiGear-Secrets-" + to_string(num_runs) + "-" - + os.check_sum(20).get_str(16) + "-P" + to_string(P.my_num()); + + os.check_sum(20).get_str(16) + "-P" + to_string(P.my_num()) + "-" + + to_string(P.num_players()); string error; @@ -397,8 +394,8 @@ void PartSetup::covert_secrets_generation(Player& P, if (not error.empty()) { cerr << "Running secrets generation because " << error << endl; - covert_key_generation(P, machine, num_runs); - covert_mac_generation(P, machine, num_runs); + covert_key_generation(P, num_runs); + covert_mac_generation(P, num_runs); ofstream output(filename); octetStream os; pack(os); diff --git a/FHEOffline/DataSetup.h b/FHEOffline/DataSetup.h index 561d11508..da1b185b9 100644 --- a/FHEOffline/DataSetup.h +++ b/FHEOffline/DataSetup.h @@ -56,12 +56,9 @@ class PartSetup int sec); void check(Player& P, MachineBase& machine); - void covert_key_generation(Player& P, MultiplicativeMachine& machine, - int num_runs); - void covert_mac_generation(Player& P, MultiplicativeMachine& machine, - int num_runs); - void covert_secrets_generation(Player& P, MultiplicativeMachine& machine, - int num_runs); + void covert_key_generation(Player& P, int num_runs); + void covert_mac_generation(Player& P, int num_runs); + void covert_secrets_generation(Player& P, MachineBase& machine, int num_runs); }; class DataSetup diff --git a/FHEOffline/PairwiseSetup.cpp b/FHEOffline/PairwiseSetup.cpp index 3da7d8bcf..80563e227 100644 --- a/FHEOffline/PairwiseSetup.cpp +++ b/FHEOffline/PairwiseSetup.cpp @@ -63,7 +63,7 @@ void secure_init(T& setup, Player& P, MachineBase& machine, string filename = PREP_DIR + T::name() + "-" + to_string(plaintext_length) + "-" + to_string(sec) + "-" + to_string(CowGearOptions::singleton.top_gear()) + "-P" - + to_string(P.my_num()); + + to_string(P.my_num()) + "-" + to_string(P.num_players()); try { ifstream file(filename); diff --git a/Machines/soho-party.cpp b/Machines/soho-party.cpp new file mode 100644 index 000000000..19ec6c4ec --- /dev/null +++ b/Machines/soho-party.cpp @@ -0,0 +1,33 @@ +/* + * soho-party.cpp + * + */ + +#include "Protocols/SohoShare.h" +#include "Math/gfp.h" +#include "Math/gf2n.h" +#include "FHE/P2Data.h" +#include "Tools/ezOptionParser.h" +#include "GC/SemiSecret.h" +#include "GC/SemiPrep.h" + +#include "Player-Online.hpp" +#include "Protocols/HemiPrep.hpp" +#include "Processor/Data_Files.hpp" +#include "Processor/Instruction.hpp" +#include "Processor/Machine.hpp" +#include "Protocols/SohoPrep.hpp" +#include "Protocols/SemiInput.hpp" +#include "Protocols/MAC_Check_Base.hpp" +#include "Protocols/MAC_Check.hpp" +#include "Protocols/fake-stuff.hpp" +#include "Protocols/SemiMC.hpp" +#include "Protocols/Beaver.hpp" +#include "GC/ShareSecret.hpp" +#include "GC/SemiHonestRepPrep.h" + +int main(int argc, const char** argv) +{ + ez::ezOptionParser opt; + spdz_main, SohoShare>(argc, argv, opt); +} diff --git a/Makefile b/Makefile index 1eb40b6b8..2f0bc4379 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ binary: rep-bin yao semi-bin-party.x tinier-party.x tiny-party.x ccd-party.x mal ifeq ($(USE_NTL),1) all: overdrive she-offline gear: cowgear-party.x chaigear-party.x -arithmetic: hemi-party.x gear +arithmetic: hemi-party.x soho-party.x gear endif -include $(DEPS) @@ -175,6 +175,7 @@ static/spdz2k-party.x: $(patsubst %.cpp,%.o,$(wildcard Machines/SPDZ2*.cpp)) semi-party.x: $(OT) GC/SemiSecret.o GC/SemiPrep.o GC/square64.o semi2k-party.x: $(OT) GC/SemiSecret.o GC/SemiPrep.o GC/square64.o hemi-party.x: $(FHEOFFLINE) $(GC_SEMI) $(OT) +soho-party.x: $(FHEOFFLINE) $(GC_SEMI) $(OT) cowgear-party.x: $(FHEOFFLINE) Protocols/CowGearOptions.o $(OT) chaigear-party.x: $(FHEOFFLINE) Protocols/CowGearOptions.o $(OT) mascot-party.x: Machines/SPDZ.o $(OT) diff --git a/Protocols/SohoPrep.h b/Protocols/SohoPrep.h new file mode 100644 index 000000000..bd5ecc67a --- /dev/null +++ b/Protocols/SohoPrep.h @@ -0,0 +1,31 @@ +/* + * SohoPrep.h + * + */ + +#ifndef PROTOCOLS_SOHOPREP_H_ +#define PROTOCOLS_SOHOPREP_H_ + +template +class SohoPrep : public SemiHonestRingPrep +{ + typedef typename T::clear::FD FD; + + static PartSetup* setup; + static Lock lock; + +public: + static void basic_setup(Player& P); + static void teardown(); + + SohoPrep(SubProcessor* proc, DataPositions& usage) : + BufferPrep(usage), + RingPrep(proc, usage), SemiHonestRingPrep(proc, usage) + { + } + + void buffer_triples(); + void buffer_inverses(); +}; + +#endif /* PROTOCOLS_SOHOPREP_H_ */ diff --git a/Protocols/SohoPrep.hpp b/Protocols/SohoPrep.hpp new file mode 100644 index 000000000..81ef780e6 --- /dev/null +++ b/Protocols/SohoPrep.hpp @@ -0,0 +1,78 @@ +/* + * SohoPrep.cpp + * + */ + +#include "SohoPrep.h" +#include "FHEOffline/DataSetup.h" + +template +PartSetup::FD>* SohoPrep::setup = 0; + +template +Lock SohoPrep::lock; + +template +void SohoPrep::basic_setup(Player& P) +{ + assert(not setup); + setup = new PartSetup; + MachineBase machine; + setup->secure_init(P, machine, T::clear::length(), 0); + setup->covert_secrets_generation(P, machine, 1); +} + +template +void SohoPrep::teardown() +{ + if (setup) + delete setup; +} + +template +void SohoPrep::buffer_triples() +{ + auto& proc = this->proc; + assert(proc != 0); + lock.lock(); + if (not setup) + { + PlainPlayer P(proc->P.N, T::clear::type_char()); + basic_setup(P); + } + lock.unlock(); + + Plaintext_ ai(setup->FieldD), bi(setup->FieldD); + SeededPRNG G; + ai.randomize(G); + bi.randomize(G); + Ciphertext Ca = setup->pk.encrypt(ai); + Ciphertext Cb = setup->pk.encrypt(bi); + octetStream os; + Ca.pack(os); + Cb.pack(os); + + for (int i = 1; i < proc->P.num_players(); i++) + { + proc->P.pass_around(os); + Ca.add<0>(os); + Cb.add<0>(os); + } + + Ciphertext Cc = Ca.mul(setup->pk, Cb); + Plaintext_ ci(setup->FieldD); + SimpleDistDecrypt dd(proc->P, *setup); + EncCommitBase_ EC; + dd.reshare(ci, Cc, EC); + + for (unsigned i = 0; i < ai.num_slots(); i++) + this->triples.push_back({{ai.element(i), bi.element(i), + ci.element(i)}}); +} + +template +void SohoPrep::buffer_inverses() +{ + assert(this->proc != 0); + ::buffer_inverses(this->inverses, *this, this->proc->MC, this->proc->P); +} diff --git a/Protocols/SohoShare.h b/Protocols/SohoShare.h new file mode 100644 index 000000000..7525c97c5 --- /dev/null +++ b/Protocols/SohoShare.h @@ -0,0 +1,40 @@ +/* + * SohoShare.h + * + */ + +#ifndef PROTOCOLS_SOHOSHARE_H_ +#define PROTOCOLS_SOHOSHARE_H_ + +#include "SemiShare.h" + +template class SohoPrep; + +template +class SohoShare : public SemiShare +{ + typedef SohoShare This; + typedef SemiShare super; + +public: + typedef SemiMC MAC_Check; + typedef DirectSemiMC Direct_MC; + typedef SemiInput Input; + typedef ::PrivateOutput PrivateOutput; + typedef SPDZ Protocol; + typedef SohoPrep LivePrep; + + static const bool needs_ot = false; + + SohoShare() + { + } + + template + SohoShare(const U& other) : + super(other) + { + } +}; + +#endif /* PROTOCOLS_SOHOSHARE_H_ */ diff --git a/README.md b/README.md index eccd793c0..72e2632be 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ The following table lists all protocols that are fully supported. | --- | --- | --- | --- | --- | | Malicious, dishonest majority | [MASCOT](#secret-sharing) | [SPDZ2k](#secret-sharing) | [Tiny / Tinier](#secret-sharing) | [BMR](#bmr) | | Covert, dishonest majority | [CowGear / ChaiGear](#secret-sharing) | N/A | N/A | N/A | -| Semi-honest, dishonest majority | [Semi / Hemi](#secret-sharing) | [Semi2k](#secret-sharing) | [SemiBin](#secret-sharing) | [Yao's GC](#yaos-garbled-circuits) / [BMR](#bmr) | +| Semi-honest, dishonest majority | [Semi / Hemi / Soho](#secret-sharing) | [Semi2k](#secret-sharing) | [SemiBin](#secret-sharing) | [Yao's GC](#yaos-garbled-circuits) / [BMR](#bmr) | | Malicious, honest majority | [Shamir / Rep3 / PS](#honest-majority) | [Brain / Rep3 / PS](#honest-majority) | [Rep3 / CCD](#honest-majority) | [BMR](#bmr) | | Semi-honest, honest majority | [Shamir / Rep3](#honest-majority) | [Rep3](#honest-majority) | [Rep3 / CCD](#honest-majority) | [BMR](#bmr) | @@ -136,7 +136,7 @@ compute the preprocessing time for a particular computation. - Boost.Thread for BMR (`libboost-thread-dev` on Ubuntu), tested against 1.65 - 64-bit CPU - Python 3.5 or later - - NTL library for CowGear, ChaiGear, and the SPDZ-2 and Overdrive offline phases (optional; tested with NTL 10.5) + - NTL library for homomorphic encryption (optional; tested with NTL 10.5) - If using macOS, Sierra or later #### Compilation @@ -149,7 +149,7 @@ compute the preprocessing time for a particular computation. extensions in the `ARCH` variable. - To benchmark online-only protocols or Overdrive, add the following line at the top: `MY_CFLAGS = -DINSECURE` - `PREP_DIR` should point to should be a local, unversioned directory to store preprocessing data (default is `Player-Data` in the current directory). - - For CowGear, ChaiGear, and the SPDZ-2 and Overdrive offline phases, set `USE_NTL = 1`. + - For homomorphic encryption, set `USE_NTL = 1`. 2) Run make to compile all the software (use the flag -j for faster compilation multiple threads). See below on how to compile specific @@ -278,6 +278,7 @@ The following table shows all programs for dishonest-majority computation using | `cowgear-party.x` | Adapted [LowGear](https://eprint.iacr.org/2017/1230) | Mod prime | Covert | `cowgear.sh` | | `chaigear-party.x` | Adapted [HighGear](https://eprint.iacr.org/2017/1230) | Mod prime | Covert | `chaigear.sh` | | `hemi-party.x` | Semi-homomorphic encryption | Mod prime | Semi-honest | `hemi.sh` | +| `soho-party.x` | Somewhat homomorphic encryption | Mod prime | Semi-honest | `soho.sh` | | `semi-bin-party.x` | OT-based | Binary | Semi-honest | `semi-bin.sh` | | `tiny-party.x` | Adapted SPDZ2k | Binary | Malicious | `tiny.sh` | | `tinier-party.x` | [FKOS15](https://eprint.iacr.org/2015/901) | Binary | Malicious | `tinier.sh` | @@ -304,7 +305,8 @@ an adapted version of HighGear. Option `-T` activates [TopGear](https://eprint.iacr.org/2019/035) zero-knowledge proofs in both. -Hemi denotes the stripped version version of LowGear for semi-honest +Hemi and Soho denote the stripped version version of LowGear and +HighGear, respectively, for semi-honest security similar to Semi, that is, generating additively shared Beaver triples using semi-homomorphic encryption. diff --git a/Scripts/soho.sh b/Scripts/soho.sh new file mode 100755 index 000000000..82bc96330 --- /dev/null +++ b/Scripts/soho.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +HERE=$(cd `dirname $0`; pwd) +SPDZROOT=$HERE/.. + +. $HERE/run-common.sh + +run_player soho-party.x $* || exit 1 diff --git a/Scripts/test_tutorial.sh b/Scripts/test_tutorial.sh index 90aa21fe5..8d78cb5aa 100755 --- a/Scripts/test_tutorial.sh +++ b/Scripts/test_tutorial.sh @@ -68,7 +68,7 @@ for dabit in ${dabit:-0 1 2}; do done fi - for i in hemi semi; do + for i in hemi semi soho; do test_vm $i done