├── HOSTS.example ├── .gitmodules ├── Programs └── Source │ ├── oram_tutorial.mpc │ ├── gale-shapley_tutorial.mpc │ ├── dijkstra_tutorial.mpc │ ├── tutorial.mpc │ ├── fixed_point_tutorial.mpc │ ├── vickrey.mpc │ └── tpmpc_tutorial.mpc ├── Tools ├── names.cpp ├── mkpath.h ├── Lock.h ├── pprint.h ├── Lock.cpp ├── Signal.h ├── OfflineMachineBase.h ├── benchmarking.h ├── Signal.cpp ├── MMO.h ├── parse.h ├── MemoryUsage.h ├── ezOptionParser-MIT-LICENSE ├── avx_memcpy.h ├── mkpath.cpp ├── Config.h ├── int.h ├── sha1.h ├── Commit.h ├── time-func.cpp ├── WaitQueue.h ├── time-func.h ├── Commit.cpp ├── random.h └── OfflineMachineBase.cpp ├── Server.cpp ├── OT ├── OText_main.cpp ├── OutputCheck.h ├── OTMachine.h ├── TripleMachine.h ├── OTMultiplier.h ├── OTTripleSetup.cpp ├── Tools.h ├── NPartyTripleGenerator.h ├── BitVector.cpp ├── OTExtensionWithMatrix.h ├── OTTripleSetup.h ├── BaseOT.h └── Tools.cpp ├── Compiler ├── tools.py ├── exceptions.py ├── __init__.py ├── config.py └── compilerLib.py ├── ot-offline.cpp ├── cnc-offline.cpp ├── FHEOffline ├── config.h ├── FullSetup.h ├── CutAndChooseMachine.h ├── PairwiseSetup.h ├── Player-Offline.h ├── SimpleDistDecrypt.h ├── PairwiseMachine.h ├── Reshare.h ├── SimpleDistDecrypt.cpp ├── Verifier.h ├── DistDecrypt.h ├── PairwiseGenerator.h ├── PairwiseSetup.cpp ├── Prover.h ├── DistKeyGen.h ├── Multiplier.h ├── CutAndChooseMachine.cpp ├── DistDecrypt.cpp ├── FHE-Subroutines.cpp ├── FullSetup.cpp ├── SimpleMachine.h ├── SimpleGenerator.h ├── DataSetup.h ├── Sacrificing.h ├── PairwiseMachine.cpp └── Reshare.cpp ├── Math ├── field_types.h ├── Integer.cpp ├── Subroutines.h ├── Setup.h ├── operators.h ├── Integer.h ├── gfp.cpp └── Share.cpp ├── Scripts ├── run-online.sh ├── gen_input_f2n.cpp ├── setup-online.sh └── run-common.sh ├── pairwise-offline.cpp ├── simple-offline.cpp ├── FHE ├── tools.h ├── Random_Coins.cpp ├── Ring.h ├── Ring.cpp ├── Matrix.h ├── P2Data.h ├── NoiseBounds.h ├── QGroup.h ├── Generator.h ├── FHE_Params.cpp ├── PPData.h ├── NTL-Subs.h ├── FFT.h ├── FHE_Params.h ├── PPData.cpp ├── FFT_Data.h ├── DiscreteGauss.cpp └── Random_Coins.h ├── Processor ├── PrivateOutput.h ├── Online-Thread.h ├── Input.h ├── InputTuple.h ├── PrivateOutput.cpp ├── Binary_File_IO.h ├── Program.h ├── Buffer.h ├── Program.cpp ├── Machine.h ├── ExternalClients.h ├── Binary_File_IO.cpp ├── Input.cpp └── Memory.h ├── Networking ├── Receiver.h ├── Sender.h ├── Server.h ├── Sender.cpp ├── data.h ├── Receiver.cpp ├── ServerSocket.h ├── sockets.h └── STS.h ├── Auth ├── Summer.h ├── fake-stuff.h └── Summer.cpp ├── CONFIG ├── .gitignore ├── CHANGELOG.md ├── License.txt └── check-passive.cpp /HOSTS.example: -------------------------------------------------------------------------------- 1 | 192.168.0.1 2 | 192.168.0.2 3 | 192.168.0.3 4 | 192.168.0.4 5 | 192.168.0.5 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "SimpleOT"] 2 | path = SimpleOT 3 | url = git@github.com:pascholl/SimpleOT.git 4 | -------------------------------------------------------------------------------- /Programs/Source/oram_tutorial.mpc: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | from path_oram import OptimalORAM 4 | 5 | array = OptimalORAM(10000) 6 | array[1] = 1 7 | print_ln('%s', array[1].reveal()) 8 | -------------------------------------------------------------------------------- /Tools/names.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #include "Processor/Data_Files.h" 4 | 5 | const char* Data_Files::dtype_names[N_DTYPE] = { "Triples", "Squares", "Bits", "Inverses", "BitTriples", "BitGF2NTriples" }; 6 | -------------------------------------------------------------------------------- /Server.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Server.cpp 5 | * 6 | */ 7 | 8 | #include "Networking/Server.h" 9 | 10 | int main(int argc, char** argv) 11 | { 12 | Server(argc, argv).start(); 13 | } 14 | -------------------------------------------------------------------------------- /OT/OText_main.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * OText_main.cpp 5 | * 6 | */ 7 | 8 | #include "OTMachine.h" 9 | 10 | int main(int argc, const char** argv) 11 | { 12 | OTMachine(argc, argv).run(); 13 | } 14 | -------------------------------------------------------------------------------- /Programs/Source/gale-shapley_tutorial.mpc: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | from Compiler import gs 4 | from Compiler.path_oram import OptimalORAM 5 | 6 | mm = gs.Matchmaker(50, oram_type=OptimalORAM) 7 | mm.init_hard() 8 | mm.match() 9 | -------------------------------------------------------------------------------- /Compiler/tools.py: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | import itertools 4 | 5 | class chain(object): 6 | def __init__(self, *args): 7 | self.args = args 8 | def __iter__(self): 9 | return itertools.chain(*self.args) 10 | -------------------------------------------------------------------------------- /ot-offline.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * OT-Offline.cpp 5 | * 6 | */ 7 | 8 | #include "OT/NPartyTripleGenerator.h" 9 | 10 | int main(int argc, const char** argv) 11 | { 12 | TripleMachine(argc, argv).run(); 13 | } 14 | -------------------------------------------------------------------------------- /cnc-offline.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * cnc-offline.cpp 5 | * 6 | */ 7 | 8 | #include "FHEOffline/CutAndChooseMachine.h" 9 | 10 | int main(int argc, const char** argv) 11 | { 12 | CutAndChooseMachine(argc, argv).run(); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Tools/mkpath.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef TOOLS_MKPATH_H_ 4 | #define TOOLS_MKPATH_H_ 5 | 6 | // mkdir -p, from https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950 7 | int mkdir_p(const char *path); 8 | 9 | #endif /* TOOLS_MKPATH_H_ */ 10 | -------------------------------------------------------------------------------- /FHEOffline/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * config.h 3 | * 4 | * Created on: 2 Oct. 2018 5 | * Author: kel323 6 | */ 7 | 8 | #ifndef FHEOFFLINE_CONFIG_H_ 9 | #define FHEOFFLINE_CONFIG_H_ 10 | 11 | #ifndef LESS_MEM_MORE_ALLOC 12 | #define LESS_ALLOC_MORE_MEM 13 | #endif 14 | 15 | #endif /* FHEOFFLINE_CONFIG_H_ */ 16 | -------------------------------------------------------------------------------- /Math/field_types.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * types.h 5 | * 6 | */ 7 | 8 | #ifndef MATH_FIELD_TYPES_H_ 9 | #define MATH_FIELD_TYPES_H_ 10 | 11 | 12 | enum DataFieldType { DATA_MODP, DATA_GF2N, N_DATA_FIELD_TYPE }; 13 | 14 | 15 | #endif /* MATH_FIELD_TYPES_H_ */ 16 | -------------------------------------------------------------------------------- /Programs/Source/dijkstra_tutorial.mpc: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | import dijkstra 4 | from path_oram import OptimalORAM 5 | 6 | n = 1000 7 | 8 | dist = dijkstra.test_dijkstra_on_cycle(n, OptimalORAM) 9 | 10 | for i in range(n): 11 | print_ln('%s: %s', i, dist[i][0].reveal()) 12 | -------------------------------------------------------------------------------- /Scripts/run-online.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # (C) 2018 University of Bristol. See License.txt 4 | 5 | HERE=$(cd `dirname $0`; pwd) 6 | SPDZROOT=$HERE/.. 7 | 8 | bits=${2:-128} 9 | g=${3:-0} 10 | mem=${4:-empty} 11 | 12 | . $HERE/run-common.sh 13 | 14 | run_player Player-Online.x ${1:-test_all} -lgp ${bits} -lg2 ${g} -m ${mem} || exit 1 15 | -------------------------------------------------------------------------------- /pairwise-offline.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #include "FHEOffline/PairwiseMachine.h" 4 | #include 5 | 6 | int main(int argc, const char** argv) 7 | { 8 | CALLGRIND_STOP_INSTRUMENTATION; 9 | PairwiseMachine machine(argc, argv); 10 | CALLGRIND_START_INSTRUMENTATION; 11 | machine.run(); 12 | } 13 | -------------------------------------------------------------------------------- /Tools/Lock.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Lock.h 5 | * 6 | */ 7 | 8 | #ifndef TOOLS_LOCK_H_ 9 | #define TOOLS_LOCK_H_ 10 | 11 | #include 12 | 13 | class Lock 14 | { 15 | pthread_mutex_t mutex; 16 | public: 17 | Lock(); 18 | virtual ~Lock(); 19 | 20 | void lock(); 21 | void unlock(); 22 | }; 23 | 24 | #endif /* TOOLS_LOCK_H_ */ 25 | -------------------------------------------------------------------------------- /simple-offline.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * simple-offline.cpp 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | int main(int argc, const char** argv) 12 | { 13 | CALLGRIND_STOP_INSTRUMENTATION; 14 | SimpleMachine machine(argc, argv); 15 | CALLGRIND_START_INSTRUMENTATION; 16 | machine.run(); 17 | } 18 | -------------------------------------------------------------------------------- /Tools/pprint.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | inline void pprint_bytes(const char *label, unsigned char *bytes, int len) 10 | { 11 | cout << label << ": "; 12 | for (int j = 0; j < len; j++) 13 | cout << setfill('0') << setw(2) << hex << (int) bytes[j]; 14 | cout << dec << endl; 15 | } 16 | -------------------------------------------------------------------------------- /OT/OutputCheck.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * check.h 5 | * 6 | */ 7 | 8 | #ifndef OT_OUTPUTCHECK_H_ 9 | #define OT_OUTPUTCHECK_H_ 10 | 11 | #include "Math/Setup.h" 12 | 13 | #define RECEIVER_INPUT PREP_DIR "OT-receiver%d-input" 14 | #define RECEIVER_OUTPUT PREP_DIR "OT-receiver%d-output" 15 | #define SENDER_OUTPUT PREP_DIR "OT-sender%d-output%d" 16 | 17 | #endif /* OT_OUTPUTCHECK_H_ */ 18 | -------------------------------------------------------------------------------- /Math/Integer.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Integer.cpp 5 | * 6 | */ 7 | 8 | #include "Integer.h" 9 | 10 | void Integer::output(ostream& s,bool human) const 11 | { 12 | if (human) 13 | s << a; 14 | else 15 | s.write((char*)&a, sizeof(a)); 16 | } 17 | 18 | void Integer::input(istream& s,bool human) 19 | { 20 | if (human) 21 | s >> a; 22 | else 23 | s.read((char*)&a, sizeof(a)); 24 | } 25 | -------------------------------------------------------------------------------- /Tools/Lock.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Lock.cpp 5 | * 6 | */ 7 | 8 | #include 9 | 10 | Lock::Lock() 11 | { 12 | pthread_mutex_init(&mutex, 0); 13 | } 14 | 15 | Lock::~Lock() 16 | { 17 | pthread_mutex_destroy(&mutex); 18 | } 19 | 20 | void Lock::lock() 21 | { 22 | pthread_mutex_lock(&mutex); 23 | } 24 | 25 | void Lock::unlock() 26 | { 27 | pthread_mutex_unlock(&mutex); 28 | } 29 | -------------------------------------------------------------------------------- /FHE/tools.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * tools.h 5 | * 6 | */ 7 | 8 | #ifndef FHE_TOOLS_H_ 9 | #define FHE_TOOLS_H_ 10 | 11 | #include 12 | using namespace std; 13 | 14 | template 15 | T sum(const vector& summands) 16 | { 17 | T res = summands[0]; 18 | for (size_t i = 1; i < summands.size(); i++) 19 | res += summands[i]; 20 | return res; 21 | } 22 | 23 | #endif /* FHE_TOOLS_H_ */ 24 | -------------------------------------------------------------------------------- /FHEOffline/FullSetup.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _FullSetup 4 | #define _FullSetup 5 | 6 | /* Reads in the data created by the setup program */ 7 | 8 | #include "FHE/FHE_Params.h" 9 | #include "FHE/P2Data.h" 10 | #include "Math/Setup.h" 11 | 12 | void get_setup(FHE_Params& params_p,FFT_Data& FTD, 13 | FHE_Params& params_2,P2Data& P2D,string dir, 14 | bool skip_2=false); 15 | 16 | #endif 17 | 18 | 19 | -------------------------------------------------------------------------------- /Compiler/exceptions.py: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | class CompilerError(Exception): 4 | """Base class for compiler exceptions.""" 5 | pass 6 | 7 | class RegisterOverflowError(CompilerError): 8 | pass 9 | 10 | class MemoryOverflowError(CompilerError): 11 | pass 12 | 13 | class ArgumentError(CompilerError): 14 | """ Exception raised for errors in instruction argument parsing. """ 15 | def __init__(self, arg, msg): 16 | self.arg = arg 17 | self.msg = msg -------------------------------------------------------------------------------- /Tools/Signal.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Signal.h 5 | * 6 | */ 7 | 8 | #ifndef TOOLS_SIGNAL_H_ 9 | #define TOOLS_SIGNAL_H_ 10 | 11 | #include 12 | 13 | class Signal 14 | { 15 | pthread_mutex_t mutex; 16 | pthread_cond_t cond; 17 | 18 | public: 19 | Signal(); 20 | virtual ~Signal(); 21 | void lock(); 22 | void unlock(); 23 | void wait(); 24 | int wait(int seconds); 25 | void broadcast(); 26 | }; 27 | 28 | #endif /* TOOLS_SIGNAL_H_ */ 29 | -------------------------------------------------------------------------------- /FHEOffline/CutAndChooseMachine.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * CutAndChooseMachine.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_CUTANDCHOOSEMACHINE_H_ 9 | #define FHEOFFLINE_CUTANDCHOOSEMACHINE_H_ 10 | 11 | #include "FHEOffline/SimpleMachine.h" 12 | 13 | class CutAndChooseMachine : public MultiplicativeMachine 14 | { 15 | bool covert; 16 | 17 | template 18 | GeneratorBase* new_generator(int i); 19 | 20 | public: 21 | CutAndChooseMachine(int argc, const char** argv); 22 | 23 | int get_covert() const { return sec; } 24 | }; 25 | 26 | #endif /* FHEOFFLINE_CUTANDCHOOSEMACHINE_H_ */ 27 | -------------------------------------------------------------------------------- /Processor/PrivateOutput.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * PrivateOutput.h 5 | * 6 | */ 7 | 8 | #ifndef PROCESSOR_PRIVATEOUTPUT_H_ 9 | #define PROCESSOR_PRIVATEOUTPUT_H_ 10 | 11 | #include 12 | using namespace std; 13 | 14 | #include "Math/Share.h" 15 | 16 | class Processor; 17 | 18 | template 19 | class PrivateOutput 20 | { 21 | Processor& proc; 22 | deque masks; 23 | 24 | public: 25 | PrivateOutput(Processor& proc) : proc(proc) { }; 26 | 27 | void start(int player, int target, int source); 28 | void stop(int player, int source); 29 | }; 30 | 31 | #endif /* PROCESSOR_PRIVATEOUTPUT_H_ */ 32 | -------------------------------------------------------------------------------- /FHE/Random_Coins.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include "Random_Coins.h" 5 | #include "FHE_Keys.h" 6 | 7 | Int_Random_Coins::Int_Random_Coins(const FHE_PK& pk) : 8 | Int_Random_Coins(pk.get_params()) 9 | { 10 | } 11 | 12 | Random_Coins::Random_Coins(const FHE_PK& pk) : 13 | Random_Coins(pk.get_params()) 14 | { 15 | } 16 | 17 | void add(Random_Coins& ans,const Random_Coins& x,const Random_Coins& y) 18 | { 19 | if (x.params!=y.params) { throw params_mismatch(); } 20 | if (ans.params!=y.params) { throw params_mismatch(); } 21 | 22 | add(ans.uu,x.uu,y.uu); 23 | add(ans.vv,x.vv,y.vv); 24 | add(ans.ww,x.ww,y.ww); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /OT/OTMachine.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * OTMachine.h 5 | * 6 | */ 7 | 8 | #ifndef OT_OTMACHINE_H_ 9 | #define OT_OTMACHINE_H_ 10 | 11 | #include "OT/OTExtension.h" 12 | #include "Tools/ezOptionParser.h" 13 | 14 | class OTMachine 15 | { 16 | ez::ezOptionParser opt; 17 | OT_ROLE ot_role; 18 | 19 | public: 20 | int my_num, portnum_base, nthreads, nloops, nsubloops, nbase; 21 | long nOTs; 22 | bool passive; 23 | TwoPartyPlayer* P; 24 | BitVector baseReceiverInput; 25 | BaseOT* bot_; 26 | vector N; 27 | 28 | OTMachine(int argc, const char** argv); 29 | ~OTMachine(); 30 | void run(); 31 | }; 32 | 33 | #endif /* OT_OTMACHINE_H_ */ 34 | -------------------------------------------------------------------------------- /FHEOffline/PairwiseSetup.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * PairwiseSetup.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_PAIRWISESETUP_H_ 9 | #define FHEOFFLINE_PAIRWISESETUP_H_ 10 | 11 | #include "FHE/FHE_Params.h" 12 | #include "FHE/Plaintext.h" 13 | #include "Networking/Player.h" 14 | 15 | template 16 | class PairwiseSetup 17 | { 18 | public: 19 | FHE_Params params; 20 | FD FieldD; 21 | typename FD::T alphai; 22 | Plaintext_ alpha; 23 | string dirname; 24 | 25 | PairwiseSetup() : params(0), alpha(FieldD) {} 26 | 27 | void init(const Player& P, int sec, int plaintext_length, int& extra_slack); 28 | }; 29 | 30 | #endif /* FHEOFFLINE_PAIRWISESETUP_H_ */ 31 | -------------------------------------------------------------------------------- /FHEOffline/Player-Offline.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Player-Offline.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_PLAYER_OFFLINE_H_ 9 | #define FHEOFFLINE_PLAYER_OFFLINE_H_ 10 | 11 | class thread_info 12 | { 13 | public: 14 | 15 | int thread_num; 16 | int covert; 17 | Names* Nms; 18 | FHE_PK* pk_p; 19 | FHE_PK* pk_2; 20 | FHE_SK* sk_p; 21 | FHE_SK* sk_2; 22 | Ciphertext *calphap; 23 | Ciphertext *calpha2; 24 | gfp *alphapi; 25 | gf2n_short *alpha2i; 26 | 27 | FFT_Data *FTD; 28 | P2Data *P2D; 29 | 30 | int nm2,nmp,nb2,nbp,ni2,nip,ns2,nsp,nvp; 31 | bool skip_2() { return nm2 + ni2 + nb2 + ns2 == 0; } 32 | }; 33 | 34 | #endif /* FHEOFFLINE_PLAYER_OFFLINE_H_ */ 35 | -------------------------------------------------------------------------------- /Scripts/gen_input_f2n.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #include 4 | #include 5 | #include "Math/gf2n.h" 6 | #include "Processor/Buffer.h" 7 | 8 | using namespace std; 9 | 10 | int main() { 11 | ifstream cin("gf2n_vals.in"); 12 | ofstream cout("gf2n_vals.out"); 13 | 14 | gf2n::init_field(40); 15 | 16 | int n; cin >> n; 17 | for (int i = 0; i < n; ++i) { 18 | gf2n_short x; cin >> x; 19 | cerr << "value is: " << x << "\n"; 20 | x.output(cout,false); 21 | } 22 | n = -(n % BUFFER_SIZE) + BUFFER_SIZE; 23 | cerr << "Adding " << n << " zeros to match buffer size" << endl; 24 | for (int i = 0; i < n; i++) 25 | gf2n(0).output(cout, false); 26 | 27 | cin.close(); 28 | cout.close(); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /FHEOffline/SimpleDistDecrypt.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * SimpleDistDecrypt.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_SIMPLEDISTDECRYPT_H_ 9 | #define FHEOFFLINE_SIMPLEDISTDECRYPT_H_ 10 | 11 | #include "FHEOffline/DistDecrypt.h" 12 | #include "FHEOffline/DataSetup.h" 13 | 14 | template 15 | class SimpleDistDecrypt : public DistDecrypt 16 | { 17 | public: 18 | SimpleDistDecrypt(const Player& P, const PartSetup& setup) : 19 | DistDecrypt(P, setup.sk, setup.pk, setup.FieldD) {} 20 | 21 | void intermediate_step(); 22 | void reshare(Plaintext& m, 23 | const Ciphertext& cm, 24 | EncCommitBase& EC); 25 | }; 26 | 27 | #endif /* FHEOFFLINE_SIMPLEDISTDECRYPT_H_ */ 28 | -------------------------------------------------------------------------------- /Networking/Receiver.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Receiver.h 5 | * 6 | */ 7 | 8 | #ifndef NETWORKING_RECEIVER_H_ 9 | #define NETWORKING_RECEIVER_H_ 10 | 11 | #include 12 | 13 | #include "Tools/octetStream.h" 14 | #include "Tools/WaitQueue.h" 15 | #include "Tools/time-func.h" 16 | 17 | class Receiver 18 | { 19 | int socket; 20 | WaitQueue in; 21 | WaitQueue out; 22 | pthread_t thread; 23 | 24 | // prevent copying 25 | Receiver(const Receiver& other); 26 | 27 | public: 28 | Timer timer; 29 | 30 | Receiver(int socket); 31 | 32 | void start(); 33 | void stop(); 34 | void run(); 35 | 36 | void request(octetStream& os); 37 | void wait(octetStream& os); 38 | }; 39 | 40 | #endif /* NETWORKING_RECEIVER_H_ */ 41 | -------------------------------------------------------------------------------- /Networking/Sender.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Sender.h 5 | * 6 | */ 7 | 8 | #ifndef NETWORKING_SENDER_H_ 9 | #define NETWORKING_SENDER_H_ 10 | 11 | #include 12 | 13 | #include "Tools/octetStream.h" 14 | #include "Tools/WaitQueue.h" 15 | #include "Tools/time-func.h" 16 | 17 | class Sender 18 | { 19 | int socket; 20 | WaitQueue in; 21 | WaitQueue out; 22 | pthread_t thread; 23 | 24 | // prevent copying 25 | Sender(const Sender& other); 26 | 27 | public: 28 | Timer timer; 29 | 30 | Sender(int socket); 31 | 32 | void start(); 33 | void stop(); 34 | void run(); 35 | 36 | void request(const octetStream& os); 37 | void wait(const octetStream& os); 38 | }; 39 | 40 | #endif /* NETWORKING_SENDER_H_ */ 41 | -------------------------------------------------------------------------------- /OT/TripleMachine.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * TripleMachine.h 5 | * 6 | */ 7 | 8 | #ifndef OT_TRIPLEMACHINE_H_ 9 | #define OT_TRIPLEMACHINE_H_ 10 | 11 | #include "Math/gf2n.h" 12 | #include "Math/gfp.h" 13 | #include "Tools/OfflineMachineBase.h" 14 | 15 | class TripleMachine : public OfflineMachineBase 16 | { 17 | gf2n mac_key2; 18 | gfp mac_keyp; 19 | 20 | public: 21 | int nloops; 22 | string prep_data_dir; 23 | bool generateMACs; 24 | bool amplify; 25 | bool check; 26 | bool primeField; 27 | bool bonding; 28 | bool generateBits; 29 | struct timeval start, stop; 30 | 31 | TripleMachine(int argc, const char** argv); 32 | void run(); 33 | 34 | template 35 | T get_mac_key(); 36 | void output_mac_keys(); 37 | }; 38 | 39 | #endif /* OT_TRIPLEMACHINE_H_ */ 40 | -------------------------------------------------------------------------------- /Tools/OfflineMachineBase.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * OfflineMachineBase.h 5 | * 6 | */ 7 | 8 | #ifndef TOOLS_OFFLINEMACHINEBASE_H_ 9 | #define TOOLS_OFFLINEMACHINEBASE_H_ 10 | 11 | #include "Tools/ezOptionParser.h" 12 | #include "Networking/Server.h" 13 | #include "Networking/Player.h" 14 | 15 | class OfflineMachineBase 16 | { 17 | protected: 18 | ez::ezOptionParser opt; 19 | Server* server; 20 | 21 | public: 22 | Names N; 23 | int my_num, nplayers, nthreads; 24 | long long ntriples, nTriplesPerThread; 25 | bool output; 26 | 27 | OfflineMachineBase(); 28 | ~OfflineMachineBase(); 29 | 30 | void parse_options(int argc, const char** argv); 31 | void start_networking_with_server(string hostname = "localhost", int portnum = 5000); 32 | }; 33 | 34 | #endif /* TOOLS_OFFLINEMACHINEBASE_H_ */ 35 | -------------------------------------------------------------------------------- /Tools/benchmarking.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * benchmarking.h 5 | * 6 | */ 7 | 8 | #ifndef TOOLS_BENCHMARKING_H_ 9 | #define TOOLS_BENCHMARKING_H_ 10 | 11 | #include 12 | 13 | // call before insecure benchmarking functionality 14 | inline void insecure(string message, bool warning = true) 15 | { 16 | #ifdef INSECURE 17 | if (warning) 18 | cerr << "WARNING: insecure " << message << endl; 19 | #else 20 | (void)warning; 21 | string msg = "You are trying to use insecure benchmarking functionality for " 22 | + message + ".\nYou can activate this at compile time " 23 | "by adding -DINSECURE to the compiler options.\n" 24 | "Make sure to run make clean as well."; 25 | throw runtime_error(msg); 26 | #endif 27 | } 28 | 29 | #endif /* TOOLS_BENCHMARKING_H_ */ 30 | -------------------------------------------------------------------------------- /FHEOffline/PairwiseMachine.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * PairwiseMachine.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_PAIRWISEMACHINE_H_ 9 | #define FHEOFFLINE_PAIRWISEMACHINE_H_ 10 | 11 | #include "FHEOffline/PairwiseGenerator.h" 12 | #include "FHEOffline/SimpleMachine.h" 13 | #include "FHEOffline/PairwiseSetup.h" 14 | 15 | class PairwiseMachine : public MachineBase 16 | { 17 | public: 18 | PairwiseSetup setup_p; 19 | PairwiseSetup setup_2; 20 | Player P; 21 | 22 | vector other_pks; 23 | FHE_PK& pk; 24 | FHE_SK sk; 25 | vector enc_alphas; 26 | 27 | PairwiseMachine(int argc, const char** argv); 28 | 29 | template 30 | void setup_keys(); 31 | 32 | template 33 | PairwiseSetup& setup(); 34 | }; 35 | 36 | #endif /* FHEOFFLINE_PAIRWISEMACHINE_H_ */ 37 | -------------------------------------------------------------------------------- /Processor/Online-Thread.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Online_Thread 4 | #define _Online_Thread 5 | 6 | #include "Networking/Player.h" 7 | #include "Math/gf2n.h" 8 | #include "Math/gfp.h" 9 | #include "Math/Integer.h" 10 | #include "Processor/Data_Files.h" 11 | 12 | #include 13 | using namespace std; 14 | 15 | class Machine; 16 | 17 | class thread_info 18 | { 19 | public: 20 | 21 | int thread_num; 22 | int covert; 23 | Names* Nms; 24 | gf2n *alpha2i; 25 | gfp *alphapi; 26 | int prognum; 27 | bool finished; 28 | bool ready; 29 | 30 | // rownums for triples, bits, squares, and inverses etc 31 | DataPositions pos; 32 | // Integer arg (optional) 33 | int arg; 34 | 35 | Machine* machine; 36 | }; 37 | 38 | void* Main_Func(void *ptr); 39 | 40 | void purge_preprocessing(Names& N, string prep_dir); 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /Processor/Input.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Input.h 5 | * 6 | */ 7 | 8 | #ifndef PROCESSOR_INPUT_H_ 9 | #define PROCESSOR_INPUT_H_ 10 | 11 | #include 12 | using namespace std; 13 | 14 | #include "Math/Share.h" 15 | #include "Auth/MAC_Check.h" 16 | #include "Processor/Buffer.h" 17 | #include "Tools/time-func.h" 18 | 19 | class Processor; 20 | 21 | template 22 | class Input 23 | { 24 | Processor& proc; 25 | MAC_Check& MC; 26 | vector< vector< Share > > shares; 27 | Buffer buffer; 28 | Timer timer; 29 | 30 | void adjust_mac(Share& share, T& value); 31 | 32 | public: 33 | int values_input; 34 | 35 | Input(Processor& proc, MAC_Check& mc); 36 | ~Input(); 37 | 38 | void start(int player, int n_inputs); 39 | void stop(int player, vector targets); 40 | 41 | }; 42 | 43 | #endif /* PROCESSOR_INPUT_H_ */ 44 | -------------------------------------------------------------------------------- /Tools/Signal.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Signal.cpp 5 | * 6 | */ 7 | 8 | #include "Signal.h" 9 | 10 | Signal::Signal() 11 | { 12 | pthread_mutex_init(&mutex, 0); 13 | pthread_cond_init(&cond, 0); 14 | } 15 | 16 | Signal::~Signal() 17 | { 18 | pthread_mutex_destroy(&mutex); 19 | pthread_cond_destroy(&cond); 20 | } 21 | 22 | void Signal::lock() 23 | { 24 | pthread_mutex_lock(&mutex); 25 | } 26 | 27 | void Signal::unlock() 28 | { 29 | pthread_mutex_unlock(&mutex); 30 | } 31 | 32 | void Signal::wait() 33 | { 34 | pthread_cond_wait(&cond, &mutex); 35 | } 36 | 37 | int Signal::wait(int seconds) 38 | { 39 | timespec ts; 40 | clock_gettime(CLOCK_REALTIME, &ts); 41 | ts.tv_sec += seconds; 42 | return pthread_cond_timedwait(&cond, &mutex, &ts); 43 | } 44 | 45 | void Signal::broadcast() 46 | { 47 | pthread_cond_broadcast(&cond); 48 | } 49 | -------------------------------------------------------------------------------- /Processor/InputTuple.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * InputTuple.h 5 | * 6 | */ 7 | 8 | #ifndef PROCESSOR_INPUTTUPLE_H_ 9 | #define PROCESSOR_INPUTTUPLE_H_ 10 | 11 | 12 | template 13 | struct InputTuple 14 | { 15 | Share share; 16 | T value; 17 | 18 | static int size() 19 | { return Share::size() + T::size(); } 20 | 21 | static string type_string() 22 | { return T::type_string(); } 23 | 24 | void assign(const char* buffer) 25 | { 26 | share.assign(buffer); 27 | value.assign(buffer + Share::size()); 28 | } 29 | }; 30 | 31 | 32 | template 33 | struct RefInputTuple 34 | { 35 | Share& share; 36 | T& value; 37 | RefInputTuple(Share& share, T& value) : share(share), value(value) {} 38 | void operator=(InputTuple& other) { share = other.share; value = other.value; } 39 | }; 40 | 41 | 42 | #endif /* PROCESSOR_INPUTTUPLE_H_ */ 43 | -------------------------------------------------------------------------------- /Processor/PrivateOutput.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * PrivateOutput.cpp 5 | * 6 | */ 7 | 8 | #include "PrivateOutput.h" 9 | #include "Processor.h" 10 | 11 | template 12 | void PrivateOutput::start(int player, int target, int source) 13 | { 14 | T mask; 15 | proc.DataF.get_input(proc.get_S_ref(target), mask, player); 16 | proc.get_S_ref(target).add(proc.get_S_ref(source)); 17 | 18 | if (player == proc.P.my_num()) 19 | masks.push_back(mask); 20 | } 21 | 22 | template 23 | void PrivateOutput::stop(int player, int source) 24 | { 25 | if (player == proc.P.my_num()) 26 | { 27 | T value; 28 | value.sub(proc.get_C_ref(source), masks.front()); 29 | value.output(proc.private_output, false); 30 | masks.pop_front(); 31 | } 32 | } 33 | 34 | template class PrivateOutput; 35 | template class PrivateOutput; 36 | -------------------------------------------------------------------------------- /Networking/Server.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Server.h 5 | */ 6 | 7 | #ifndef NETWORKING_SERVER_H_ 8 | #define NETWORKING_SERVER_H_ 9 | 10 | #include "Networking/data.h" 11 | #include "Networking/Player.h" 12 | 13 | #include 14 | using namespace std; 15 | 16 | class Server 17 | { 18 | vector socket_num; 19 | vector names; 20 | vector ports; 21 | int nmachines; 22 | int PortnumBase; 23 | 24 | void get_ip(int num); 25 | void get_name(int num); 26 | void send_names(int num); 27 | 28 | public: 29 | static void* start_in_thread(void* server); 30 | static Server* start_networking(Names& N, int my_num, int nplayers, 31 | string hostname = "localhost", int portnum = 9000); 32 | 33 | Server(int argc, char** argv); 34 | Server(int nmachines, int PortnumBase); 35 | void start(); 36 | }; 37 | 38 | #endif /* NETWORKING_SERVER_H_ */ 39 | -------------------------------------------------------------------------------- /Tools/MMO.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * MMO.h 5 | * 6 | */ 7 | 8 | #ifndef TOOLS_MMO_H_ 9 | #define TOOLS_MMO_H_ 10 | 11 | #include "Tools/aes.h" 12 | 13 | // Matyas-Meyer-Oseas hashing 14 | class MMO 15 | { 16 | octet IV[176] __attribute__((aligned (16))); 17 | 18 | template 19 | static void encrypt_and_xor(void* output, const void* input, 20 | const octet* key); 21 | template 22 | static void encrypt_and_xor(void* output, const void* input, 23 | const octet* key, const int* indices); 24 | 25 | public: 26 | MMO() { zeroIV(); } 27 | void zeroIV(); 28 | void setIV(octet key[AES_BLK_SIZE]); 29 | template 30 | void hashOneBlock(octet* output, octet* input); 31 | template 32 | void hashBlockWise(octet* output, octet* input); 33 | template 34 | void outputOneBlock(octet* output); 35 | }; 36 | 37 | #endif /* TOOLS_MMO_H_ */ 38 | -------------------------------------------------------------------------------- /Tools/parse.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * parse.h 5 | * 6 | */ 7 | 8 | #ifndef TOOLS_PARSE_H_ 9 | #define TOOLS_PARSE_H_ 10 | 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | // Read a byte 16 | inline int get_val(istream& s) 17 | { 18 | char cc; 19 | s.get(cc); 20 | int a=cc; 21 | if (a<0) { a+=256; } 22 | return a; 23 | } 24 | 25 | // Read a 4-byte integer 26 | inline int get_int(istream& s) 27 | { 28 | int n = 0; 29 | for (int i=0; i<4; i++) 30 | { n<<=8; 31 | int t=get_val(s); 32 | n+=t; 33 | } 34 | return n; 35 | } 36 | 37 | // Read several integers 38 | inline void get_ints(int* res, istream& s, int count) 39 | { 40 | for (int i = 0; i < count; i++) 41 | res[i] = get_int(s); 42 | } 43 | 44 | inline void get_vector(int m, vector& start, istream& s) 45 | { 46 | start.resize(m); 47 | for (int i = 0; i < m; i++) 48 | start[i] = get_int(s); 49 | } 50 | 51 | #endif /* TOOLS_PARSE_H_ */ 52 | -------------------------------------------------------------------------------- /FHEOffline/Reshare.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Reshare 4 | #define _Reshare 5 | 6 | /* The procedure for the Reshare protocol 7 | * Input is a ciphertext cm and a flag NewCiphertext 8 | * Output is a Ring_Element and possibly a ciphertext cc 9 | */ 10 | 11 | #include "FHE/Ciphertext.h" 12 | #include "Networking/Player.h" 13 | #include "FHEOffline/EncCommit.h" 14 | 15 | template class DistDecrypt; 16 | 17 | template 18 | void Reshare(Plaintext& m,Ciphertext& cc, 19 | const Ciphertext& cm,bool NewCiphertext, 20 | const Player& P,EncCommitBase& EC, 21 | const FHE_PK& pk,const FHE_SK& share); 22 | 23 | template 24 | void Reshare(Plaintext& m,Ciphertext& cc, 25 | const Ciphertext& cm,bool NewCiphertext, 26 | const Player& P,EncCommitBase& EC, 27 | const FHE_PK& pk,DistDecrypt& dd); 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /FHEOffline/SimpleDistDecrypt.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * SimpleDistDecrypt.cpp 5 | * 6 | */ 7 | 8 | #include 9 | 10 | template 11 | void SimpleDistDecrypt::intermediate_step() 12 | { 13 | for (unsigned int i = 0; i < this->vv.size(); i++) 14 | this->vv[i] += this->f.coeff(i); 15 | } 16 | 17 | template 18 | void SimpleDistDecrypt::reshare(Plaintext& m, 19 | const Ciphertext& cm, 20 | EncCommitBase& EC) 21 | { 22 | (void)EC; 23 | 24 | PRNG G; 25 | G.ReSeed(); 26 | this->f.randomize(G, Full); 27 | 28 | // Step 3 29 | this->run(cm); 30 | 31 | // Step 4 32 | if (this->P.my_num()==0) 33 | { sub(m,this->mf,this->f); } 34 | else 35 | { m=this->f; m.negate(); } 36 | } 37 | 38 | 39 | template class SimpleDistDecrypt; 40 | template class SimpleDistDecrypt; 41 | -------------------------------------------------------------------------------- /FHEOffline/Verifier.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Verifier 4 | #define _Verifier 5 | 6 | #include "Proof.h" 7 | 8 | /* Defines the Verifier */ 9 | template 10 | class Verifier 11 | { 12 | AddableVector z; 13 | AddableMatrix t; 14 | 15 | const Proof& P; 16 | 17 | public: 18 | Verifier(const Proof& proof); 19 | 20 | void Stage_2(const vector& e, 21 | AddableVector& c, octetStream& ciphertexts, 22 | octetStream& cleartexts,const FHE_PK& pk,bool Diag,bool binary=false); 23 | 24 | /* This is the non-interactive version using the ROM 25 | - Creates space for all output values 26 | - Diag flag mirrors that in Prover 27 | */ 28 | void NIZKPoK(AddableVector& c,octetStream& ciphertexts,octetStream& cleartexts, 29 | const FHE_PK& pk,bool Diag,bool binary=false); 30 | 31 | size_t report_size(ReportType type) { return z.report_size(type) + t.report_size(type); } 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /OT/OTMultiplier.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * OTMultiplier.h 5 | * 6 | */ 7 | 8 | #ifndef OT_OTMULTIPLIER_H_ 9 | #define OT_OTMULTIPLIER_H_ 10 | 11 | #include 12 | using namespace std; 13 | 14 | #include "OT/OTExtensionWithMatrix.h" 15 | #include "Tools/random.h" 16 | 17 | class NPartyTripleGenerator; 18 | 19 | template 20 | class OTMultiplier 21 | { 22 | void multiplyForTriples(OTExtensionWithMatrix& auth_ot_ext); 23 | void multiplyForBits(OTExtensionWithMatrix& auth_ot_ext); 24 | public: 25 | NPartyTripleGenerator& generator; 26 | int thread_num; 27 | OTExtensionWithMatrix rot_ext; 28 | //OTExtensionWithMatrix* auth_ot_ext; 29 | vector c_output; 30 | vector< vector > macs; 31 | 32 | pthread_t thread; 33 | pthread_mutex_t mutex; 34 | pthread_cond_t ready; 35 | 36 | OTMultiplier(NPartyTripleGenerator& generator, int thread_num); 37 | ~OTMultiplier(); 38 | void multiply(); 39 | }; 40 | 41 | #endif /* OT_OTMULTIPLIER_H_ */ 42 | -------------------------------------------------------------------------------- /Networking/Sender.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Sender.cpp 5 | * 6 | */ 7 | 8 | #include "Sender.h" 9 | 10 | void* run_sender_thread(void* sender) 11 | { 12 | ((Sender*)sender)->run(); 13 | return 0; 14 | } 15 | 16 | Sender::Sender(int socket) : socket(socket), thread(0) 17 | { 18 | } 19 | 20 | void Sender::start() 21 | { 22 | pthread_create(&thread, 0, run_sender_thread, this); 23 | } 24 | 25 | void Sender::stop() 26 | { 27 | in.stop(); 28 | pthread_join(thread, 0); 29 | } 30 | 31 | void Sender::run() 32 | { 33 | const octetStream* os = 0; 34 | while (in.pop(os)) 35 | { 36 | // timer.start(); 37 | os->Send(socket); 38 | // timer.stop(); 39 | out.push(os); 40 | } 41 | } 42 | 43 | void Sender::request(const octetStream& os) 44 | { 45 | in.push(&os); 46 | } 47 | 48 | void Sender::wait(const octetStream& os) 49 | { 50 | const octetStream* queued = 0; 51 | out.pop(queued); 52 | if (queued != &os) 53 | throw not_implemented(); 54 | } 55 | -------------------------------------------------------------------------------- /Scripts/setup-online.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # (C) 2018 University of Bristol. See License.txt 4 | 5 | HERE=$(cd `dirname $0`; pwd) 6 | SPDZROOT=$HERE/.. 7 | 8 | # number of players 9 | players=${1:-2} 10 | # prime field bit length 11 | bits=${2:-128} 12 | # binary field bit length, default by binary 13 | g=${3:-0} 14 | # default number of triples etc. to create 15 | default=${4:-10000} 16 | 17 | die () { 18 | echo >&2 "$@" 19 | echo >&2 "Usage: 20 | setup-online.sh [nplayers] [prime_bitlength] [gf2n_bitlength] [num_prep] 21 | Defaults: 22 | nplayers=2, prime_bitlength=128, gf2n_bitlength=40/128 (as compiled), num_prep=10000" 23 | exit 1 24 | } 25 | 26 | [ "$#" -le 4 ] || die "More than 4 arguments provided" 27 | 28 | for arg in "$@" 29 | do 30 | echo "$arg" | grep -E -q '^[0-9]+$' || die "Integer argument required, $arg provided" 31 | done 32 | 33 | $SPDZROOT/Fake-Offline.x ${players} -lgp ${bits} -lg2 ${g} --default ${default} 34 | 35 | for i in $(seq 0 $[players-1]) ; do 36 | dd if=/dev/zero of=Player-Data/Private-Input-$i bs=10000 count=1 37 | done 38 | -------------------------------------------------------------------------------- /Tools/MemoryUsage.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * MemoryUsage.h 5 | * 6 | */ 7 | 8 | #ifndef TOOLS_MEMORYUSAGE_H_ 9 | #define TOOLS_MEMORYUSAGE_H_ 10 | 11 | #include 12 | using namespace std; 13 | 14 | class MemoryUsage 15 | { 16 | map usage; 17 | 18 | public: 19 | MemoryUsage& operator+=(const MemoryUsage& other) 20 | { 21 | for (auto& it : other.usage) 22 | usage[it.first] += it.second; 23 | return *this; 24 | } 25 | 26 | void update(const string& tag, size_t size) 27 | { 28 | usage[tag] = max(size, usage[tag]); 29 | } 30 | 31 | void add(const string& tag, size_t size) 32 | { 33 | usage[tag] += size; 34 | } 35 | 36 | size_t get(const string& tag) 37 | { 38 | return usage[tag]; 39 | } 40 | 41 | void print() 42 | { 43 | for (auto& it : usage) 44 | cout << it.first << " required: " << 1e-9 * it.second << " (GB)" << endl; 45 | } 46 | }; 47 | 48 | #endif /* TOOLS_MEMORYUSAGE_H_ */ 49 | -------------------------------------------------------------------------------- /Tools/ezOptionParser-MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2011,2012 Remik Ziemlinski 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Math/Subroutines.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Subroutines 4 | #define _Subroutines 5 | 6 | 7 | #include "Math/Zp_Data.h" 8 | 9 | void Subs(modp& ans,const vector& poly,const modp& x,const Zp_Data& ZpD); 10 | 11 | 12 | /* Find an m'th primitive root moduli the current prime 13 | * This is deterministic so all players have the same root of unity 14 | * poly is Phi_m(X) 15 | */ 16 | modp Find_Primitive_Root_m(int m,const vector& poly,const Zp_Data& ZpD); 17 | 18 | 19 | /* Find a (2m)'th primitive root moduli the current prime 20 | * This is deterministic so all players have the same root of unity 21 | * poly is Phi_m(X) 22 | */ 23 | modp Find_Primitive_Root_2m(int m,const vector& poly,const Zp_Data& ZpD); 24 | 25 | 26 | /* Find an mth primitive root moduli the current prime 27 | * This is deterministic so all players have the same root of unity 28 | * This assumes m is a power of two and so the cyclotomic polynomial 29 | * is F=X^{m/2}+1 30 | */ 31 | modp Find_Primitive_Root_2power(int m,const Zp_Data& ZpD); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /Auth/Summer.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Summer.h 5 | * 6 | */ 7 | 8 | #ifndef OFFLINE_SUMMER_H_ 9 | #define OFFLINE_SUMMER_H_ 10 | 11 | #include "Networking/Player.h" 12 | #include "Tools/WaitQueue.h" 13 | #include "Tools/time-func.h" 14 | 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | template 20 | class Parallel_MAC_Check; 21 | 22 | template 23 | class Summer 24 | { 25 | int sum_players, last_sum_players, next_sum_players; 26 | int base_player; 27 | Parallel_MAC_Check& MC; 28 | Player* send_player; 29 | Player* receive_player; 30 | Timer timer; 31 | 32 | public: 33 | vector values; 34 | 35 | pthread_t thread; 36 | WaitQueue input_queue, output_queue; 37 | bool stop; 38 | int size; 39 | WaitQueue< vector > share_queue; 40 | 41 | Summer(int sum_players, int last_sum_players, int next_sum_players, 42 | Player* send_player, Player* receive_player, Parallel_MAC_Check& MC); 43 | ~Summer(); 44 | void run(); 45 | }; 46 | 47 | #endif /* OFFLINE_SUMMER_H_ */ 48 | -------------------------------------------------------------------------------- /Tools/avx_memcpy.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * memcpy.h 5 | * 6 | */ 7 | 8 | #ifndef TOOLS_AVX_MEMCPY_H_ 9 | #define TOOLS_AVX_MEMCPY_H_ 10 | 11 | #include 12 | #include 13 | 14 | inline void avx_memcpy(void* dest, const void* source, size_t length) 15 | { 16 | __m256i* d = (__m256i*)dest, *s = (__m256i*)source; 17 | #ifdef __AVX__ 18 | while (length >= 32) 19 | { 20 | _mm256_storeu_si256(d++, _mm256_loadu_si256(s++)); 21 | length -= 32; 22 | } 23 | #endif 24 | __m128i* d2 = (__m128i*)d; 25 | __m128i* s2 = (__m128i*)s; 26 | while (length >= 16) 27 | { 28 | _mm_storeu_si128(d2++, _mm_loadu_si128(s2++)); 29 | length -= 16; 30 | } 31 | if (length) 32 | memcpy(d2, s2, length); 33 | } 34 | 35 | inline void avx_memzero(void* dest, size_t length) 36 | { 37 | __m256i* d = (__m256i*)dest; 38 | #ifdef __AVX__ 39 | __m256i s = _mm256_setzero_si256(); 40 | while (length >= 32) 41 | { 42 | _mm256_storeu_si256(d++, s); 43 | length -= 32; 44 | } 45 | #endif 46 | if (length) 47 | memset((void*)d, 0, length); 48 | } 49 | 50 | #endif /* TOOLS_AVX_MEMCPY_H_ */ 51 | -------------------------------------------------------------------------------- /Math/Setup.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Setup.h 5 | * 6 | */ 7 | 8 | #ifndef MATH_SETUP_H_ 9 | #define MATH_SETUP_H_ 10 | 11 | #include "Math/bigint.h" 12 | 13 | #include 14 | using namespace std; 15 | 16 | #ifndef PREP_DIR 17 | #define PREP_DIR "Player-Data/" 18 | #endif 19 | 20 | /* 21 | * Routines to create and read setup files for the finite fields 22 | */ 23 | 24 | // Create setup file for gfp and gf2n 25 | void generate_online_setup(ofstream& outf, string dirname, bigint& p, int lgp, int lg2); 26 | void write_online_setup(ofstream& outf, string dirname, const bigint& p, int lg2); 27 | 28 | // Setup primes only 29 | // Chooses a p of at least lgp bits 30 | void SPDZ_Data_Setup_Primes(bigint& p,int lgp,int& idx,int& m); 31 | void generate_prime(bigint& p, int lgp, int m); 32 | 33 | // get main directory for prep. data 34 | string get_prep_dir(int nparties, int lg2p, int gf2ndegree); 35 | 36 | // Read online setup file for gfp and gf2n 37 | void read_setup(const string& dir_prefix); 38 | void read_setup(int nparties, int lg2p, int gf2ndegree); 39 | 40 | 41 | #endif /* MATH_SETUP_H_ */ 42 | -------------------------------------------------------------------------------- /Programs/Source/tutorial.mpc: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | def test(actual, expected): 4 | if isinstance(actual, (sint, sgf2n)): 5 | actual = actual.reveal() 6 | print_ln('expected %s, got %s', expected, actual) 7 | 8 | # cint: clear integers modulo p 9 | # sint: secret integers modulo p 10 | 11 | a = sint(1) 12 | b = cint(2) 13 | 14 | test(a + b, 3) 15 | test(a + a, 2) 16 | test(a * b, 2) 17 | test(a * a, 1) 18 | test(a - b, -1) 19 | test(a < b, 1) 20 | test(a <= b, 1) 21 | test(a >= b, 0) 22 | test(a > b, 0) 23 | test(a == b, 0) 24 | test(a != b, 1) 25 | 26 | clear_a = a.reveal() 27 | 28 | # sgfn2/cgf2n: secret/clear elements of GF(2^n) 29 | 30 | a = sgf2n(1) 31 | b = cgf2n(2) 32 | 33 | test(a + b, 3) 34 | test(a + a, 0) 35 | test(a * b, 2) 36 | test(a * a, 1) 37 | test(a == b, 0) 38 | test(a != b, 1) 39 | 40 | # arrays and loops 41 | 42 | a = Array(100, sint) 43 | 44 | @for_range(100) 45 | def f(i): 46 | a[i] = sint(i)**2 47 | 48 | test(a[99], 99**2) 49 | 50 | # conditional 51 | 52 | if_then(cint(0)) 53 | a[0] = 123 54 | else_then() 55 | a[0] = 789 56 | end_if() 57 | 58 | test(a[0], 789) 59 | -------------------------------------------------------------------------------- /Networking/data.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Data 4 | #define _Data 5 | 6 | #include 7 | 8 | #include "Exceptions/Exceptions.h" 9 | 10 | 11 | typedef unsigned char octet; 12 | 13 | // Assumes word is a 64 bit value 14 | #ifdef WIN32 15 | typedef unsigned __int64 word; 16 | #else 17 | typedef unsigned long word; 18 | #endif 19 | 20 | #define BROADCAST 0 21 | #define ROUTE 1 22 | #define TERMINATE 2 23 | #define GO 3 24 | 25 | 26 | inline void encode_length(octet *buff, size_t len, size_t n_bytes) 27 | { 28 | if (n_bytes > 8) 29 | throw invalid_length("length field cannot be more than 64 bits"); 30 | if (n_bytes < 8 && (len > (1ULL << (8 * n_bytes)))) 31 | throw invalid_length("length too large for length field"); 32 | for (size_t i = 0; i < n_bytes; i++) 33 | buff[i] = len >> (8 * i); 34 | } 35 | 36 | inline size_t decode_length(octet *buff, size_t n_bytes) 37 | { 38 | size_t len = 0; 39 | for (size_t i = 0; i < n_bytes; i++) 40 | { 41 | len += (size_t) buff[i] << (8 * i); 42 | } 43 | return len; 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /Networking/Receiver.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Receiver.cpp 5 | * 6 | */ 7 | 8 | #include "Receiver.h" 9 | 10 | #include 11 | using namespace std; 12 | 13 | void* run_receiver_thread(void* receiver) 14 | { 15 | ((Receiver*)receiver)->run(); 16 | return 0; 17 | } 18 | 19 | Receiver::Receiver(int socket) : socket(socket), thread(0) 20 | { 21 | } 22 | 23 | void Receiver::start() 24 | { 25 | pthread_create(&thread, 0, run_receiver_thread, this); 26 | } 27 | 28 | void Receiver::stop() 29 | { 30 | in.stop(); 31 | pthread_join(thread, 0); 32 | } 33 | 34 | void Receiver::run() 35 | { 36 | octetStream* os = 0; 37 | while (in.pop(os)) 38 | { 39 | os->reset_write_head(); 40 | timer.start(); 41 | os->Receive(socket); 42 | timer.stop(); 43 | out.push(os); 44 | } 45 | } 46 | 47 | void Receiver::request(octetStream& os) 48 | { 49 | in.push(&os); 50 | } 51 | 52 | void Receiver::wait(octetStream& os) 53 | { 54 | octetStream* queued = 0; 55 | out.pop(queued); 56 | if (queued != &os) 57 | throw not_implemented(); 58 | } 59 | -------------------------------------------------------------------------------- /OT/OTTripleSetup.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #include "OTTripleSetup.h" 4 | 5 | void OTTripleSetup::setup() 6 | { 7 | timeval baseOTstart, baseOTend; 8 | gettimeofday(&baseOTstart, NULL); 9 | 10 | G.ReSeed(); 11 | for (int i = 0; i < nbase; i++) 12 | { 13 | base_receiver_inputs[i] = G.get_uchar() & 1; 14 | } 15 | //baseReceiverInput.randomize(G); 16 | 17 | for (int i = 0; i < nparties - 1; i++) 18 | { 19 | baseOTs[i]->set_receiver_inputs(base_receiver_inputs); 20 | baseOTs[i]->exec_base(false); 21 | } 22 | gettimeofday(&baseOTend, NULL); 23 | double basetime = timeval_diff(&baseOTstart, &baseOTend); 24 | cout << "\t\tBaseTime: " << basetime/1000000 << endl << flush; 25 | 26 | // Receiver send something to force synchronization 27 | // (since Sender finishes baseOTs before Receiver) 28 | } 29 | 30 | void OTTripleSetup::close_connections() 31 | { 32 | for (size_t i = 0; i < players.size(); i++) 33 | { 34 | delete players[i]; 35 | } 36 | } 37 | 38 | OTTripleSetup::~OTTripleSetup() 39 | { 40 | for (size_t i = 0; i < baseOTs.size(); i++) 41 | { 42 | delete baseOTs[i]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /FHE/Ring.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Ring 4 | #define _Ring 5 | 6 | /* Class to define the basic ring we are working with 7 | * and any associated data 8 | */ 9 | 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | #include "Tools/octetStream.h" 15 | 16 | class Ring 17 | { 18 | int mm,phim; 19 | vector pi; 20 | vector pi_inv; 21 | vector poly; 22 | 23 | public: 24 | 25 | 26 | Ring() : mm(0), phim(0) { ; } 27 | ~Ring() { ; } 28 | 29 | // Rely on default copy assignment/constructor 30 | 31 | int phi_m() const { return phim; } 32 | int m() const { return mm; } 33 | 34 | int p(int i) const { return pi.at(i); } 35 | int p_inv(int i) const { return pi_inv.at(i); } 36 | const vector& Phi() const { return poly; } 37 | 38 | friend ostream& operator<<(ostream& s,const Ring& R); 39 | friend istream& operator>>(istream& s,Ring& R); 40 | 41 | friend void init(Ring& Rg,int m); 42 | 43 | void pack(octetStream& o) const; 44 | void unpack(octetStream& o); 45 | 46 | bool operator!=(const Ring& other) const; 47 | }; 48 | 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /Compiler/__init__.py: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | import compilerLib, program, instructions, types, library, floatingpoint 4 | import inspect 5 | from config import * 6 | from compilerLib import run 7 | 8 | 9 | # add all instructions to the program VARS dictionary 10 | compilerLib.VARS = {} 11 | instr_classes = [t[1] for t in inspect.getmembers(instructions, inspect.isclass)] 12 | 13 | instr_classes += [t[1] for t in inspect.getmembers(types, inspect.isclass)\ 14 | if t[1].__module__ == types.__name__] 15 | 16 | instr_classes += [t[1] for t in inspect.getmembers(library, inspect.isfunction)\ 17 | if t[1].__module__ == library.__name__] 18 | 19 | for op in instr_classes: 20 | compilerLib.VARS[op.__name__] = op 21 | 22 | # add open and input separately due to name conflict 23 | compilerLib.VARS['open'] = instructions.asm_open 24 | compilerLib.VARS['vopen'] = instructions.vasm_open 25 | compilerLib.VARS['gopen'] = instructions.gasm_open 26 | compilerLib.VARS['vgopen'] = instructions.vgasm_open 27 | compilerLib.VARS['input'] = instructions.asm_input 28 | compilerLib.VARS['ginput'] = instructions.gasm_input 29 | 30 | compilerLib.VARS['comparison'] = comparison 31 | compilerLib.VARS['floatingpoint'] = floatingpoint 32 | -------------------------------------------------------------------------------- /FHEOffline/DistDecrypt.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _DistDecrypt 4 | #define _DistDecrypt 5 | 6 | /* 7 | * This is the Distributed Decryption Protocol 8 | * 9 | */ 10 | 11 | #include "FHE/Ciphertext.h" 12 | #include "Networking/Player.h" 13 | #include "FHEOffline/Reshare.h" 14 | 15 | template 16 | class DistDecrypt 17 | { 18 | protected: 19 | const Player& P; 20 | const FHE_SK& share; 21 | const FHE_PK& pk; 22 | AddableVector vv, vv1; 23 | 24 | public: 25 | Plaintext_ mf, f; 26 | 27 | DistDecrypt(const Player& P, const FHE_SK& share, const FHE_PK& pk, 28 | const FD& fd); 29 | virtual ~DistDecrypt() {} 30 | 31 | Plaintext_& run(const Ciphertext& ctx, bool NewCiphertext = false); 32 | virtual void intermediate_step() {} 33 | 34 | virtual void reshare(Plaintext& m, 35 | const Ciphertext& cm, 36 | EncCommitBase& EC) 37 | { Ciphertext dummy(pk.get_params()); Reshare(m, dummy, cm, false, P, EC, pk, *this); } 38 | 39 | size_t report_size(ReportType type) 40 | { return vv.report_size(type) + vv1.report_size(type) + mf.report_size(type) + f.report_size(type); } 41 | }; 42 | 43 | #endif 44 | 45 | -------------------------------------------------------------------------------- /Processor/Binary_File_IO.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _FILE_IO_HEADER 4 | #define _FILE_IO_HEADER 5 | 6 | #include "Exceptions/Exceptions.h" 7 | #include "Math/Share.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | /* 17 | * Provides generalised file read and write methods for arrays of numeric data types. 18 | * Stateless and not optimised for multiple reads from file. 19 | * Intended for MPC application specific file IO. 20 | */ 21 | 22 | class Binary_File_IO 23 | { 24 | public: 25 | 26 | /* 27 | * Append the buffer values as binary to the filename. 28 | * Throws file_error. 29 | */ 30 | template 31 | void write_to_file(const string filename, const vector< Share >& buffer); 32 | 33 | /* 34 | * Read from posn in the filename the binary values until the buffer is full. 35 | * Assumes file holds binary that maps into the type passed in. 36 | * Returns the current posn in the file or -1 if at eof. 37 | * Throws file_error. 38 | */ 39 | template 40 | void read_from_file(const string filename, vector< Share >& buffer, const int start_posn, int &end_posn); 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /Programs/Source/fixed_point_tutorial.mpc: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | program.bit_length = 80 4 | print "program.bit_length: ", program.bit_length 5 | program.security = 40 6 | 7 | n = 10 8 | m = 5 9 | 10 | # array of fixed points 11 | A = sfixArray(n) 12 | 13 | for i in range(n): 14 | A[i] = sfix(i) 15 | 16 | print_ln('array of fixed points') 17 | for i in range(n): 18 | print_ln('%s', A[i].reveal()) 19 | 20 | # matrix of fixed points 21 | M = sfixMatrix(n, m) 22 | 23 | for i in range(n): 24 | for j in range(m): 25 | M[i][j] = sfix(i*j) 26 | 27 | print_ln('matrix of fixed points') 28 | for i in range(n): 29 | for j in range(m): 30 | print_str('%s ', M[i][j].reveal()) 31 | print_ln(' ') 32 | 33 | 34 | # assign scalar to sfix 35 | A[5] = sfix(1.12345) 36 | print_ln('%s', A[5].reveal()) 37 | 38 | AC = Array(n, cfix) 39 | 40 | for i in range(n): 41 | AC[i] = cfix(1.5 * i) 42 | 43 | for i in range(n): 44 | print_ln('%s', AC[i]) 45 | 46 | # assign sint to sfix 47 | s = sint(10) 48 | sa = sfix(); sa.load_int(s) 49 | print_ln('successfully assigned sint to sfix %s', sa.reveal()) 50 | 51 | # division between fixed points 52 | sb = sfix(2.5) 53 | print_ln('division between %s %s = %s', sa.reveal(), sb.reveal(), (sa/sb).reveal()) 54 | 55 | 56 | -------------------------------------------------------------------------------- /Tools/mkpath.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #include "Tools/mkpath.h" 4 | #include 5 | #include /* PATH_MAX */ 6 | #include /* mkdir(2) */ 7 | #include 8 | 9 | // mkdir -p, from https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950 10 | int mkdir_p(const char *path) 11 | { 12 | /* Adapted from http://stackoverflow.com/a/2336245/119527 */ 13 | const size_t len = strlen(path); 14 | char _path[PATH_MAX]; 15 | char *p; 16 | 17 | errno = 0; 18 | 19 | /* Copy string so its mutable */ 20 | if (len > sizeof(_path)-1) { 21 | errno = ENAMETOOLONG; 22 | return -1; 23 | } 24 | strcpy(_path, path); 25 | 26 | /* Iterate the string */ 27 | for (p = _path + 1; *p; p++) { 28 | if (*p == '/') { 29 | /* Temporarily truncate */ 30 | *p = '\0'; 31 | 32 | if (mkdir(_path, S_IRWXU) != 0) { 33 | if (errno != EEXIST) 34 | return -1; 35 | } 36 | 37 | *p = '/'; 38 | } 39 | } 40 | 41 | if (mkdir(_path, S_IRWXU) != 0) { 42 | if (errno != EEXIST) 43 | return -1; 44 | } 45 | 46 | return 0; 47 | } -------------------------------------------------------------------------------- /CONFIG: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | ROOT = . 4 | 5 | OPTIM= -O3 6 | #PROF = -pg 7 | #DEBUG = -DDEBUG 8 | #MEMPROTECT = -DMEMPROTECT 9 | 10 | # set this to your preferred local storage directory 11 | PREP_DIR = '-DPREP_DIR="Player-Data/"' 12 | 13 | # set for 128-bit GF(2^n) and/or OT preprocessing 14 | USE_GF2N_LONG = 0 15 | 16 | # set to -march= for optimization 17 | # AVX2 support (Haswell or later) changes the bit matrix transpose 18 | ARCH = -mtune=native -mavx 19 | 20 | #use CONFIG.mine to overwrite DIR settings 21 | -include CONFIG.mine 22 | 23 | ifeq ($(USE_GF2N_LONG),1) 24 | GF2N_LONG = -DUSE_GF2N_LONG 25 | endif 26 | 27 | # MAX_MOD_SZ must be at least ceil(len(p)/len(word)) 28 | # Default is 2, which suffices for 128-bit p 29 | # MOD = -DMAX_MOD_SZ=2 30 | 31 | LDLIBS = -lmpirxx -lmpir -lsodium $(MY_LDLIBS) -lm -lpthread 32 | 33 | ifeq ($(USE_NTL),1) 34 | LDLIBS := -lntl $(LDLIBS) 35 | endif 36 | 37 | OS := $(shell uname -s) 38 | ifeq ($(OS), Linux) 39 | LDLIBS += -lrt 40 | endif 41 | 42 | CXX = g++ 43 | CFLAGS = $(ARCH) $(MY_CFLAGS) -g -Wextra -Wall $(OPTIM) -I$(ROOT) -pthread $(PROF) $(DEBUG) $(MOD) $(MEMPROTECT) $(GF2N_LONG) $(PREP_DIR) -maes -mpclmul -msse4.1 --std=c++11 -Werror 44 | CPPFLAGS = $(CFLAGS) 45 | LD = g++ 46 | 47 | -------------------------------------------------------------------------------- /FHEOffline/PairwiseGenerator.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * PairwiseGenerator.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_PAIRWISEGENERATOR_H_ 9 | #define FHEOFFLINE_PAIRWISEGENERATOR_H_ 10 | 11 | #include 12 | using namespace std; 13 | 14 | #include "FHEOffline/Multiplier.h" 15 | #include "FHEOffline/SimpleGenerator.h" 16 | 17 | class PairwiseMachine; 18 | 19 | template 20 | class PairwiseGenerator : public GeneratorBase 21 | { 22 | friend MultiEncCommit; 23 | 24 | PlaintextVector a, b, c; 25 | AddableVector b_mod_q; 26 | vector*> multipliers; 27 | TripleProducer_ producer; 28 | MultiEncCommit EC; 29 | 30 | // temporary data 31 | AddableVector C; 32 | octetStream ciphertexts, cleartexts; 33 | 34 | size_t volatile_memory; 35 | 36 | public: 37 | PairwiseMachine& machine; 38 | Player global_player; 39 | 40 | PairwiseGenerator(int thread_num, PairwiseMachine& machine); 41 | ~PairwiseGenerator(); 42 | 43 | void run(); 44 | size_t report_size(ReportType type); 45 | void report_size(ReportType type, MemoryUsage& res); 46 | size_t report_sent(); 47 | }; 48 | 49 | #endif /* FHEOFFLINE_PAIRWISEGENERATOR_H_ */ 50 | -------------------------------------------------------------------------------- /Scripts/run-common.sh: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | run_player() { 5 | port=$((RANDOM%10000+10000)) 6 | bin=$1 7 | shift 8 | if ! test -e $SPDZROOT/logs; then 9 | mkdir $SPDZROOT/logs 10 | fi 11 | if test $bin = Player-Online.x; then 12 | params="$* -pn $port -h localhost" 13 | else 14 | params="$port localhost $*" 15 | fi 16 | if test $bin = Player-KeyGen.x -a ! -e Player-Data/Params-Data; then 17 | ./Setup.x $players $size 40 18 | fi 19 | >&2 echo Running $SPDZROOT/Server.x $players $port 20 | $SPDZROOT/Server.x $players $port & 21 | rem=$(($players - 2)) 22 | for i in $(seq 0 $rem); do 23 | echo "trying with player $i" 24 | >&2 echo Running $prefix $SPDZROOT/$bin $i $params 25 | $prefix $SPDZROOT/$bin $i $params 2>&1 | tee $SPDZROOT/logs/$i & 26 | done 27 | last_player=$(($players - 1)) 28 | >&2 echo Running $prefix $SPDZROOT/$bin $last_player $params 29 | $prefix $SPDZROOT/$bin $last_player $params > $SPDZROOT/logs/$last_player 2>&1 || return 1 30 | } 31 | 32 | killall Player-Online.x Server.x 33 | sleep 0.5 34 | 35 | #mkdir /dev/shm/Player-Data 36 | 37 | players=${PLAYERS:-2} 38 | 39 | SPDZROOT=${SPDZROOT:-.} 40 | 41 | #. Scripts/setup.sh 42 | 43 | mkdir logs 44 | -------------------------------------------------------------------------------- /Tools/Config.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #include "Tools/octetStream.h" 4 | #include "Networking/Player.h" 5 | #include 6 | namespace Config { 7 | typedef vector public_key; 8 | typedef vector public_signing_key; 9 | typedef vector secret_key; 10 | typedef vector secret_signing_key; 11 | void read_player_config(string cfgdir,int my_number,vector pubkeys,secret_signing_key mysecretkey, public_signing_key mypubkey); 12 | void write_player_config_file(string config_dir 13 | ,int player_number, public_key my_pub, secret_key my_priv 14 | , public_signing_key my_signing_pub, secret_signing_key my_signing_priv 15 | , vector client_pubs, vector client_signing_pubs 16 | , vector player_pubs, vector player_signing_pubs); 17 | uint64_t getW64le(ifstream &infile); 18 | void putW64le(ofstream &outf, uint64_t nr); 19 | extern const string default_player_config_file_prefix; 20 | string player_config_file(int player_number); 21 | void print_vector(const vector &vec); 22 | } 23 | -------------------------------------------------------------------------------- /Tools/int.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * int.h 5 | * 6 | */ 7 | 8 | #ifndef TOOLS_INT_H_ 9 | #define TOOLS_INT_H_ 10 | 11 | 12 | typedef unsigned char octet; 13 | 14 | // Assumes word is a 64 bit value 15 | #ifdef WIN32 16 | typedef unsigned __int64 word; 17 | #else 18 | typedef unsigned long word; 19 | #endif 20 | 21 | 22 | inline int CEIL_LOG2(int x) 23 | { 24 | int result = 0; 25 | x--; 26 | while (x > 0) 27 | { 28 | result++; 29 | x >>= 1; 30 | } 31 | return result; 32 | } 33 | 34 | inline int FLOOR_LOG2(int x) 35 | { 36 | int result = 0; 37 | while (x > 1) 38 | { 39 | result++; 40 | x >>= 1; 41 | } 42 | return result; 43 | } 44 | 45 | // ceil(n / k) 46 | inline long long DIV_CEIL(long long n, long long k) 47 | { 48 | return (n + k - 1)/k; 49 | } 50 | 51 | inline void INT_TO_BYTES(octet *buff, int x) 52 | { 53 | buff[0] = x&255; 54 | buff[1] = (x>>8)&255; 55 | buff[2] = (x>>16)&255; 56 | buff[3] = (x>>24)&255; 57 | } 58 | 59 | inline int BYTES_TO_INT(octet *buff) 60 | { 61 | return buff[0] + 256*buff[1] + 65536*buff[2] + 16777216*buff[3]; 62 | } 63 | 64 | inline int positive_modulo(int i, int n) { 65 | return (i % n + n) % n; 66 | } 67 | 68 | #endif /* TOOLS_INT_H_ */ 69 | -------------------------------------------------------------------------------- /Math/operators.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * operations.h 5 | * 6 | */ 7 | 8 | #ifndef MATH_OPERATORS_H_ 9 | #define MATH_OPERATORS_H_ 10 | 11 | template 12 | T operator*(const bool& x, const T& y) { return x ? y : T(); } 13 | template 14 | T operator*(const T& y, const bool& x) { return x ? y : T(); } 15 | template 16 | T& operator*=(const T& y, const bool& x) { y = x ? y : T(); return y; } 17 | 18 | template 19 | T operator+(const T& x, const U& y) { T res; res.add(x, y); return res; } 20 | template 21 | T operator*(const T& x, const T& y) { T res; res.mul(x, y); return res; } 22 | template 23 | T operator-(const T& x, const U& y) { T res; res.sub(x, y); return res; } 24 | 25 | template 26 | T& operator+=(T& x, const U& y) { x.add(y); return x; } 27 | template 28 | T& operator*=(T& x, const T& y) { x.mul(y); return x; } 29 | template 30 | T& operator-=(T& x, const U& y) { x.sub(y); return x; } 31 | 32 | template 33 | T operator/(const T& x, const U& y) { U inv = y; inv.invert(); return x * inv; } 34 | template 35 | T& operator/=(const T& x, const U& y) { U inv = y; inv.invert(); return x *= inv; } 36 | 37 | #endif /* MATH_OPERATORS_H_ */ 38 | -------------------------------------------------------------------------------- /FHEOffline/PairwiseSetup.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * PairwiseSetup.cpp 5 | * 6 | */ 7 | 8 | #include 9 | #include "FHE/NoiseBounds.h" 10 | #include "FHE/NTL-Subs.h" 11 | #include "Math/Setup.h" 12 | #include "FHEOffline/Proof.h" 13 | 14 | template 15 | void PairwiseSetup::init(const Player& P, int sec, int plaintext_length, 16 | int& extra_slack) 17 | { 18 | sec = max(sec, 40); 19 | cout << "Finding parameters for security " << sec << " and field size ~2^" 20 | << plaintext_length << endl; 21 | PRNG G; 22 | G.ReSeed(); 23 | dirname = PREP_DIR; 24 | 25 | octetStream o; 26 | if (P.my_num() == 0) 27 | { 28 | extra_slack = 29 | generate_semi_setup(plaintext_length, sec, params, FieldD, true); 30 | params.pack(o); 31 | FieldD.pack(o); 32 | o.store(extra_slack); 33 | P.send_all(o); 34 | } 35 | else 36 | { 37 | P.receive_player(0, o); 38 | params.unpack(o); 39 | FieldD.unpack(o); 40 | FieldD.init_field(); 41 | o.get(extra_slack); 42 | } 43 | 44 | alpha = FieldD; 45 | alpha.randomize(G, Diagonal); 46 | alphai = alpha.element(0); 47 | } 48 | 49 | template class PairwiseSetup; 50 | template class PairwiseSetup; 51 | -------------------------------------------------------------------------------- /Tools/sha1.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _SHA1 4 | #define _SHA1 5 | 6 | /* 7 | * SHA1 routine optimized to do word accesses rather than byte accesses, 8 | * and to avoid unnecessary copies into the context array. 9 | * 10 | * This was initially based on the Mozilla SHA1 implementation, although 11 | * none of the original Mozilla code remains. 12 | */ 13 | 14 | #define HASH_SIZE 20 15 | 16 | typedef struct { 17 | unsigned long long size; 18 | unsigned int H[5]; 19 | unsigned int W[16]; 20 | } blk_SHA_CTX; 21 | 22 | void blk_SHA1_Init(blk_SHA_CTX *ctx); 23 | void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len); 24 | void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx); 25 | 26 | class octetStream; 27 | 28 | class SHA1 : public blk_SHA_CTX 29 | { 30 | public: 31 | static const int hash_length = 20; 32 | 33 | SHA1() 34 | { blk_SHA1_Init(this); } 35 | void update(const void *dataIn, unsigned long len) 36 | { blk_SHA1_Update(this, dataIn, len); } 37 | void update(const octetStream& os); 38 | void final(unsigned char hashout[hash_length]) 39 | { blk_SHA1_Final(hashout, this); } 40 | void final(octetStream& os); 41 | }; 42 | 43 | #define git_SHA_CTX blk_SHA_CTX 44 | #define git_SHA1_Init blk_SHA1_Init 45 | #define git_SHA1_Update blk_SHA1_Update 46 | #define git_SHA1_Final blk_SHA1_Final 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /OT/Tools.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _OTTOOLS 4 | #define _OTTOOLS 5 | 6 | #include "Networking/Player.h" 7 | #include "Tools/Commit.h" 8 | #include "Tools/random.h" 9 | 10 | #define SEED_SIZE_BYTES SEED_SIZE 11 | 12 | /* 13 | * Generate a secure, random seed between 2 parties via commitment 14 | */ 15 | void random_seed_commit(octet* seed, TwoPartyPlayer& player, int len); 16 | 17 | /* 18 | * GF(2^128) multiplication using Intel instructions 19 | * (should this go in gf2n class???) 20 | */ 21 | void gfmul128(__m128i a, __m128i b, __m128i *res); 22 | void gfred128(__m128i a1, __m128i a2, __m128i *res); 23 | 24 | //#if defined(__SSE2__) 25 | /* 26 | * Convert __m128i to string of type T 27 | */ 28 | template 29 | string __m128i_toString(const __m128i var) { 30 | stringstream sstr; 31 | sstr << hex; 32 | const T* values = (const T*) &var; 33 | if (sizeof(T) == 1) { 34 | for (unsigned int i = 0; i < sizeof(__m128i); i++) { 35 | sstr << (int) values[i] << " "; 36 | } 37 | } else { 38 | for (unsigned int i = 0; i < sizeof(__m128i) / sizeof(T); i++) { 39 | sstr << values[i] << " "; 40 | } 41 | } 42 | return sstr.str(); 43 | } 44 | //#endif 45 | 46 | string word_to_bytes(const word w); 47 | 48 | void shiftl128(word x1, word x2, word& res1, word& res2, size_t k); 49 | 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /FHE/Ring.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include "Ring.h" 5 | #include "Exceptions/Exceptions.h" 6 | 7 | ostream& operator<<(ostream& s,const Ring& R) 8 | { 9 | s << R.mm << " " << R.phim << endl; 10 | for (int i=0; i>(istream& s,Ring& R) 20 | { 21 | s >> R.mm >> R.phim; 22 | if (s.fail()) 23 | throw IO_Error("can't read ring"); 24 | R.pi.resize(R.phim); R.pi_inv.resize(R.mm); R.poly.resize(R.phim+1); 25 | for (int i=0; i> R.pi[i]; } 26 | for (int i=0; i> R.pi_inv[i]; } 27 | for (int i=0; i<=R.phim; i++) { s >> R.poly[i]; } 28 | return s; 29 | } 30 | 31 | void Ring::pack(octetStream& o) const 32 | { 33 | o.store(mm); 34 | o.store(phim); 35 | o.store(pi); 36 | o.store(pi_inv); 37 | o.store(poly); 38 | } 39 | 40 | void Ring::unpack(octetStream& o) 41 | { 42 | o.get(mm); 43 | o.get(phim); 44 | o.get(pi); 45 | o.get(pi_inv); 46 | o.get(poly); 47 | } 48 | 49 | bool Ring::operator !=(const Ring& other) const 50 | { 51 | if (mm != other.mm or phim != other.phim or pi != other.pi 52 | or pi_inv != other.pi_inv or poly != other.poly) 53 | return true; 54 | else 55 | return false; 56 | } 57 | -------------------------------------------------------------------------------- /Tools/Commit.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Commit 4 | #define _Commit 5 | 6 | /* Define the hash based commitment scheme */ 7 | 8 | #include "Tools/octetStream.h" 9 | #include "Networking/Player.h" 10 | 11 | /* 12 | * Commit using comm = hash(send_player || message || r) 13 | * where r is SEED_SIZE random bytes 14 | */ 15 | void Commit(octetStream& comm, octetStream& open, const octetStream& message, int send_player); 16 | 17 | bool Open(octetStream& message, const octetStream& comm, const octetStream& open, int send_player); 18 | 19 | // same as above using less memory 20 | class Commitment 21 | { 22 | int send_player; 23 | 24 | public: 25 | // open only contains the randomness 26 | octetStream comm, open; 27 | 28 | Commitment(int send_player) : send_player(send_player) {} 29 | void commit(const octetStream& message); 30 | void commit(const octetStream& message, const octetStream& open); 31 | void check(const octetStream& message, const octetStream& comm, 32 | const octetStream& open); 33 | }; 34 | 35 | class AllCommitments 36 | { 37 | const Player& P; 38 | vector comms, opens; 39 | 40 | public: 41 | AllCommitments(const Player& P) : P(P), comms(P.num_players()), opens(P.num_players()) {} 42 | // no checks yet 43 | void commit_and_open(const octetStream& message); 44 | void check(int player, const octetStream& message); 45 | void check_relative(int diff, const octetStream& message); 46 | }; 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /FHEOffline/Prover.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Prover 4 | #define _Prover 5 | 6 | #include "Proof.h" 7 | #include "Tools/MemoryUsage.h" 8 | 9 | /* Class for the prover */ 10 | 11 | template 12 | class Prover 13 | { 14 | /* Provers state */ 15 | Proof::Randomness s; 16 | AddableVector< Plaintext_ > y; 17 | 18 | #ifdef LESS_ALLOC_MORE_MEM 19 | AddableVector z; 20 | AddableMatrix t; 21 | #endif 22 | 23 | public: 24 | size_t volatile_memory; 25 | 26 | Prover(Proof& proof, const FD& FieldD); 27 | 28 | void Stage_1(const Proof& P, octetStream& ciphertexts, const AddableVector& c, 29 | const FHE_PK& pk, bool Diag, 30 | bool binary = false); 31 | 32 | bool Stage_2(Proof& P, octetStream& cleartexts, 33 | const vector& x, 34 | const Proof::Randomness& r, 35 | const vector& e); 36 | 37 | /* Only has a non-interactive version using the ROM 38 | - If Diag is true then the plaintexts x are assumed to be 39 | diagonal elements, i.e. x=(x_1,x_1,...,x_1) 40 | */ 41 | size_t NIZKPoK(Proof& P, octetStream& ciphertexts, octetStream& cleartexts, 42 | const FHE_PK& pk, 43 | const AddableVector& c, 44 | const vector& x, 45 | const Proof::Randomness& r, 46 | bool Diag,bool binary=false); 47 | 48 | size_t report_size(ReportType type); 49 | void report_size(ReportType type, MemoryUsage& res); 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /FHE/Matrix.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #ifndef _myHNF 5 | #define _myHNF 6 | 7 | #include 8 | using namespace std; 9 | 10 | #include "Math/bigint.h" 11 | #include "Math/modp.h" 12 | 13 | typedef vector< vector > matrix; 14 | typedef vector< vector > modp_matrix; 15 | 16 | class imatrix : public vector< vector > 17 | { 18 | public: 19 | bool operator!=(const imatrix& other) const; 20 | 21 | void pack(octetStream& o) const; 22 | void unpack(octetStream& o); 23 | }; 24 | 25 | /* Uses Algorithm 2.7 from Pohst-Zassenhaus to compute H and U st 26 | H = HNF(A) = A*U 27 | */ 28 | void HNF(matrix& H,matrix& U,const matrix& A); 29 | 30 | /* S = U*A*V 31 | We dont care about U though 32 | */ 33 | void SNF(matrix& S,const matrix& A,matrix& V); 34 | 35 | void print(const matrix& S); 36 | void print(const imatrix& S); 37 | 38 | // Special inverse routine, assumes A is unimodular and only 39 | // requires column operations to create the inverse 40 | matrix inv(const matrix& A); 41 | 42 | // Another special routine for modp matrices. 43 | // Solves 44 | // Ax=b 45 | // Assumes A is unimodular, square and only requires row operations to 46 | // create the inverse. In put is C=(A||b) and the routines alters A 47 | vector solve(modp_matrix& C,const Zp_Data& PrD); 48 | 49 | // Finds a pseudo-inverse of a matrix A modulo 2 50 | // - Input matrix is assumed to have more rows than columns 51 | void pinv(imatrix& Ai,const imatrix& A); 52 | 53 | ostream& operator<<(ostream& s,const imatrix& A); 54 | istream& operator>>(istream& s,imatrix& A); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /Tools/time-func.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include "Tools/time-func.h" 5 | #include "Exceptions/Exceptions.h" 6 | 7 | 8 | long long timeval_diff(struct timeval *start_time, struct timeval *end_time) 9 | { struct timeval temp_diff; 10 | struct timeval *difference; 11 | difference=&temp_diff; 12 | difference->tv_sec =end_time->tv_sec -start_time->tv_sec ; 13 | difference->tv_usec=end_time->tv_usec-start_time->tv_usec; 14 | while(difference->tv_usec<0) 15 | { difference->tv_usec+=1000000; 16 | difference->tv_sec -=1; 17 | } 18 | return 1000000LL*difference->tv_sec+difference->tv_usec; 19 | } 20 | 21 | double timeval_diff_in_seconds(struct timeval *start_time, struct timeval *end_time) 22 | { 23 | return double(timeval_diff(start_time, end_time)) / 1e6; 24 | } 25 | 26 | 27 | long long timespec_diff(struct timespec *start_time, struct timespec *end_time) 28 | { 29 | long long sec =end_time->tv_sec -start_time->tv_sec ; 30 | long long nsec=end_time->tv_nsec-start_time->tv_nsec; 31 | while(nsec<0) 32 | { nsec+=1000000000; 33 | sec -=1; 34 | } 35 | return 1000000000*sec+nsec; 36 | } 37 | 38 | 39 | double convert_ns_to_seconds(long long x) 40 | { 41 | return double(x) / 1e9; 42 | } 43 | 44 | 45 | double Timer::elapsed() 46 | { 47 | long long res = elapsed_time; 48 | if (running) 49 | res += elapsed_since_last_start(); 50 | return convert_ns_to_seconds(res); 51 | } 52 | 53 | double Timer::idle() 54 | { 55 | if (running) 56 | throw Processor_Error("Timer running."); 57 | else 58 | return convert_ns_to_seconds(elapsed_since_last_start()); 59 | } 60 | -------------------------------------------------------------------------------- /FHEOffline/DistKeyGen.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * DistKeyGen.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_DISTKEYGEN_H_ 9 | #define FHEOFFLINE_DISTKEYGEN_H_ 10 | 11 | #include "FHE/Random_Coins.h" 12 | #include "FHE/Rq_Element.h" 13 | #include "FHE/FHE_Params.h" 14 | #include "FHE/FHE_Keys.h" 15 | #include "Networking/Player.h" 16 | 17 | void Encrypt_Rq_Element(Ciphertext& c, const Rq_Element& mess, 18 | const Random_Coins& rc, const FHE_PK& pk); 19 | 20 | void Run_Gen_Protocol(FHE_PK& pk, FHE_SK& sk, const Player& P, int num_runs, 21 | bool commit); 22 | 23 | 24 | class DistKeyGen 25 | { 26 | const FHE_Params& params; 27 | 28 | public: 29 | Random_Coins rc1, rc2; 30 | Rq_Element secret; 31 | Rq_Element a; 32 | Rq_Element e; 33 | Rq_Element b; 34 | FHE_PK pk; 35 | Ciphertext enc_dash; 36 | Ciphertext enc; 37 | bigint p; 38 | 39 | static void fake(FHE_PK& pk, vector& sks, const bigint& p, int nparties); 40 | 41 | DistKeyGen(const FHE_Params& params, const bigint& p); 42 | void Gen_Random_Data(PRNG& G); 43 | DistKeyGen& operator+=(const DistKeyGen& other); 44 | void sum_a(const vector& as); 45 | void compute_b(); 46 | void compute_enc_dash(const vector& bs); 47 | void compute_enc_dash(); 48 | void compute_enc(const vector& enc_dashs); 49 | void compute_enc(); 50 | void sum_enc(const vector& enc); 51 | void finalize(FHE_PK& pk, FHE_SK& sk); 52 | void check_equality(const DistKeyGen other); 53 | }; 54 | 55 | #endif /* FHEOFFLINE_DISTKEYGEN_H_ */ 56 | -------------------------------------------------------------------------------- /FHEOffline/Multiplier.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Multiplier.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_MULTIPLIER_H_ 9 | #define FHEOFFLINE_MULTIPLIER_H_ 10 | 11 | #include "FHEOffline/SimpleEncCommit.h" 12 | #include "FHE/AddableVector.h" 13 | #include "Tools/MemoryUsage.h" 14 | 15 | template 16 | using PlaintextVector = AddableVector< Plaintext_ >; 17 | 18 | template 19 | class PairwiseGenerator; 20 | class PairwiseMachine; 21 | 22 | template 23 | class Multiplier 24 | { 25 | PairwiseGenerator& generator; 26 | PairwiseMachine& machine; 27 | OffsetPlayer P; 28 | int num_players, my_num; 29 | const FHE_PK& other_pk; 30 | const Ciphertext& other_enc_alpha; 31 | map& timers; 32 | 33 | // temporary 34 | Ciphertext C, mask; 35 | Plaintext_ product_share; 36 | Random_Coins rc; 37 | 38 | size_t volatile_capacity; 39 | MemoryUsage memory_usage; 40 | 41 | public: 42 | Multiplier(int offset, PairwiseGenerator& generator); 43 | void multiply_and_add(Plaintext_& res, const Ciphertext& C, 44 | const Plaintext_& b); 45 | void multiply_and_add(Plaintext_& res, const Ciphertext& C, 46 | const Rq_Element& b); 47 | void multiply_alpha_and_add(Plaintext_& res, const Rq_Element& b); 48 | int get_offset() { return P.get_offset(); } 49 | size_t report_size(ReportType type); 50 | void report_size(ReportType type, MemoryUsage& res); 51 | size_t report_volatile() { return volatile_capacity; } 52 | }; 53 | 54 | #endif /* FHEOFFLINE_MULTIPLIER_H_ */ 55 | -------------------------------------------------------------------------------- /FHE/P2Data.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _P2Data 4 | #define _P2Data 5 | 6 | /* This class defines all the data needed for representing 7 | * plaintexts modulo 2 8 | */ 9 | 10 | #include "FHE/Ring.h" 11 | #include "FHE/Matrix.h" 12 | #include "Math/gf2n.h" 13 | 14 | class P2Data 15 | { 16 | int slots; 17 | // Data for the forward mapping (phi_m by (slots*gf2n:deg)) 18 | imatrix A; 19 | // Data for the backward mapping (phi_m by phi_m) 20 | imatrix Ai; 21 | 22 | public: 23 | typedef gf2n_short T; 24 | typedef int S; 25 | 26 | int num_slots() const { return slots; } 27 | int degree() const { return A.size() ? A[0].size() : 0; } 28 | int phi_m() const { return A.size(); } 29 | 30 | void check_dimensions() const; 31 | 32 | // Despite only dealing with bits, we still use bigint's so 33 | // we can easily dovetail into the FHE code 34 | void forward(vector& ans,const vector& a) const; 35 | void backward(vector& ans,const vector& a) const; 36 | 37 | int get_prime() const { return 2; } 38 | 39 | bool operator!=(const P2Data& other) const; 40 | 41 | // no op because we require field to be initalized first 42 | void init_field() const {} 43 | 44 | void pack(octetStream& o) const; 45 | void unpack(octetStream& o); 46 | 47 | void load(const Ring& Rg); 48 | void store(const Ring& Rg) const; 49 | 50 | void load_or_generate(const Ring& Rg); 51 | 52 | friend ostream& operator<<(ostream& s,const P2Data& P2D); 53 | friend istream& operator>>(istream& s,P2Data& P2D); 54 | 55 | friend void init(P2Data& P2D,const Ring& Rg); 56 | }; 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /FHE/NoiseBounds.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * NoiseBound.h 5 | * 6 | */ 7 | 8 | #ifndef FHE_NOISEBOUNDS_H_ 9 | #define FHE_NOISEBOUNDS_H_ 10 | 11 | #include "Math/bigint.h" 12 | 13 | int phi_N(int N); 14 | 15 | class SemiHomomorphicNoiseBounds 16 | { 17 | protected: 18 | const bigint p; 19 | const int phi_m; 20 | const int n; 21 | const int sec; 22 | int slack; 23 | const double sigma; 24 | const int h; 25 | 26 | bigint B_clean; 27 | bigint B_scale; 28 | bigint drown; 29 | 30 | public: 31 | SemiHomomorphicNoiseBounds(const bigint& p, int phi_m, int n, int sec, 32 | int slack, bool extra_h = false, double sigma = 3.2, int h = 64); 33 | // with scaling 34 | bigint min_p0(const bigint& p1); 35 | // without scaling 36 | bigint min_p0(); 37 | bigint min_p0(bool scale, const bigint& p1) { return scale ? min_p0(p1) : min_p0(); } 38 | static double min_phi_m(int log_q); 39 | }; 40 | 41 | // as per ePrint 2012:642 for slack = 0 42 | class NoiseBounds : public SemiHomomorphicNoiseBounds 43 | { 44 | bigint B_KS; 45 | 46 | public: 47 | NoiseBounds(const bigint& p, int phi_m, int n, int sec, int slack, 48 | double sigma = 3.2, int h = 64); 49 | bigint U1(const bigint& p0, const bigint& p1); 50 | bigint U2(const bigint& p0, const bigint& p1); 51 | bigint min_p0(const bigint& p0, const bigint& p1); 52 | bigint min_p0(const bigint& p1); 53 | bigint min_p1(); 54 | bigint opt_p1(); 55 | bigint opt_p0() { return min_p0(opt_p1()); } 56 | double optimize(int& lg2p0, int& lg2p1); 57 | }; 58 | 59 | #endif /* FHE_NOISEBOUNDS_H_ */ 60 | -------------------------------------------------------------------------------- /FHE/QGroup.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _QGroup 4 | #define _QGroup 5 | 6 | /* This class holds the data needed to represent 7 | Gal/G_2 8 | where G_2 is the decomposition group at 2 and Gal=(Z/mZ)^* 9 | 10 | We hold it as a set of generators g[i] and orders d[i] 11 | 12 | The group is created using a Hafner-McCurley style 13 | generator/relation algorithm, then we apply the SNF. 14 | The key thing is that we impose the relation 2=1 so 15 | as to get the quotient group above 16 | */ 17 | 18 | #include 19 | #include 20 | using namespace std; 21 | 22 | class QGroup 23 | { 24 | int m; // the integer m defines the group (Z/mZ)^*/<2> 25 | vector g; // g is an array of generators 26 | vector d; /* d is an array of group orders, such that 27 | * (Z/mZ)^* = C_d0 \times C_d1 \times ... 28 | * and gi generates an order-di group 29 | *******************************************/ 30 | int ngen; // the number of generators 31 | int Gord; 32 | mutable vector elems; 33 | 34 | public: 35 | 36 | void assign(int mm,int seed); // initialize this instance for m=mm 37 | 38 | QGroup() { ; } 39 | ~QGroup() { ; } 40 | 41 | int num_gen() const { return ngen; } 42 | int gen(int i) const { return g[i]; } 43 | int gord(int i) const { return d[i]; } 44 | int order() const { return Gord; } 45 | 46 | friend ostream& operator<<(ostream& s,const QGroup& QGrp); 47 | friend istream& operator>>(istream& s,QGroup& QGrp); 48 | 49 | // For 0 <= n < ord returns the nth element 50 | int nth_element(int n) const; 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /Processor/Program.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Program 4 | #define _Program 5 | 6 | #include "Processor/Instruction.h" 7 | #include "Processor/Data_Files.h" 8 | 9 | class Machine; 10 | 11 | /* A program is a vector of instructions */ 12 | 13 | class Program 14 | { 15 | vector p; 16 | // Here we note the number of bits, squares and triples and input 17 | // data needed 18 | // - This is computed for a whole program sequence to enable 19 | // the run time to be able to determine which ones to pass to it 20 | DataPositions offline_data_used; 21 | 22 | // Maximal register used 23 | int max_reg[MAX_REG_TYPE]; 24 | 25 | // Memory size used directly 26 | int max_mem[MAX_REG_TYPE][MAX_SECRECY_TYPE]; 27 | 28 | // True if program contains variable-sized loop 29 | bool unknown_usage; 30 | 31 | void compute_constants(); 32 | 33 | public: 34 | 35 | Program(int nplayers) : offline_data_used(nplayers), 36 | unknown_usage(false) 37 | { compute_constants(); } 38 | 39 | // Read in a program 40 | void parse(istream& s); 41 | 42 | DataPositions get_offline_data_used() const { return offline_data_used; } 43 | void print_offline_cost() const; 44 | 45 | bool usage_unknown() const { return unknown_usage; } 46 | 47 | int num_reg(RegType reg_type) const 48 | { return max_reg[reg_type]; } 49 | 50 | const int* direct_mem(RegType reg_type) const 51 | { return max_mem[reg_type]; } 52 | 53 | friend ostream& operator<<(ostream& s,const Program& P); 54 | 55 | // Execute this program, updateing the processor and memory 56 | // and streams pointing to the triples etc 57 | void execute(Processor& Proc) const; 58 | 59 | }; 60 | 61 | #endif 62 | 63 | -------------------------------------------------------------------------------- /FHE/Generator.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Generator.h 5 | * 6 | */ 7 | 8 | #ifndef FHE_GENERATOR_H_ 9 | #define FHE_GENERATOR_H_ 10 | 11 | #include 12 | using namespace std; 13 | 14 | #include "Math/bigint.h" 15 | #include "Math/modp.h" 16 | 17 | template 18 | class Generator 19 | { 20 | public: 21 | virtual ~Generator() {} 22 | virtual Generator* clone() const = 0; 23 | virtual void get(T& x) const = 0; 24 | }; 25 | 26 | template 27 | class Iterator : public Generator 28 | { 29 | const vector& v; 30 | mutable size_t i; 31 | 32 | public: 33 | Iterator(const vector& v) : v(v), i(0) {} 34 | Generator* clone() const { return new Iterator(*this); } 35 | void get(T& x) const { x = v[i]; i++; } 36 | }; 37 | 38 | class ConversionIterator : public Generator 39 | { 40 | const vector& v; 41 | const Zp_Data& ZpD; 42 | mutable size_t i; 43 | 44 | public: 45 | ConversionIterator(const vector& v, const Zp_Data& ZpD) : v(v), ZpD(ZpD), i(0) {} 46 | Generator* clone() const { return new ConversionIterator(*this); } 47 | void get(bigint& x) const { to_bigint(x, v[i], ZpD); i++; } 48 | }; 49 | 50 | class WriteConversionIterator : public Generator 51 | { 52 | vector& v; 53 | const Zp_Data& ZpD; 54 | mutable size_t i; 55 | mutable bigint tmp; 56 | 57 | public: 58 | WriteConversionIterator(vector& v, const Zp_Data& ZpD) : v(v), ZpD(ZpD), i(0) {} 59 | Generator* clone() const { return new WriteConversionIterator(*this); } 60 | void get(bigint& x) const { tmp = x; v[i].convert_destroy(tmp, ZpD); i++; } 61 | }; 62 | 63 | #endif /* FHE_GENERATOR_H_ */ 64 | -------------------------------------------------------------------------------- /FHEOffline/CutAndChooseMachine.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * CutAndChooseMachine.cpp 5 | * 6 | */ 7 | 8 | #include "FHEOffline/CutAndChooseMachine.h" 9 | #include "FHEOffline/SimpleGenerator.h" 10 | 11 | CutAndChooseMachine::CutAndChooseMachine(int argc, const char** argv) 12 | { 13 | opt.add( 14 | "", // Default. 15 | 0, // Required? 16 | 0, // Number of args expected. 17 | 0, // Delimiter if expecting multiple args. 18 | "Use covert security (default: active; use -s for parameter)", // Help description. 19 | "-c", // Flag token. 20 | "--covert" // Flag token. 21 | ); 22 | parse_options(argc, argv); 23 | covert = opt.isSet("--covert"); 24 | if (not covert and sec != 40) 25 | throw runtime_error("active cut-and-choose only implemented for 40-bit security"); 26 | if (covert) 27 | generate_setup(COVERT_SPDZ2_SLACK); 28 | else 29 | generate_setup(ACTIVE_SPDZ2_SLACK); 30 | for (int i = 0; i < nthreads; i++) 31 | { 32 | if (use_gf2n) 33 | generators.push_back(new_generator(i)); 34 | else 35 | generators.push_back(new_generator(i)); 36 | } 37 | } 38 | 39 | template 40 | GeneratorBase* CutAndChooseMachine::new_generator(int i) 41 | { 42 | SimpleGenerator* generator = 43 | new SimpleGenerator(N, setup.part(), *this, i, data_type); 44 | if (covert) 45 | generator->EC.init(generator->P, setup.part().pk, sec, Full); 46 | else 47 | generator->EC.init(generator->P, setup.part().pk, Full, setup.part().FieldD, i); 48 | return generator; 49 | } 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Offline data, runtime logs # 2 | ############################## 3 | Player-Data 4 | Player-Data/* 5 | Prep-Data/* 6 | logs/* 7 | Language-Definition/main.pdf 8 | keys/* 9 | 10 | # Personal CONFIG file # 11 | ############################## 12 | CONFIG.mine 13 | config_mine.py 14 | 15 | # Temporary files # 16 | ################### 17 | *.bak 18 | *.orig 19 | *.rej 20 | *.tmp 21 | callgrind.out.* 22 | 23 | # Vim 24 | .*.swp 25 | tags 26 | 27 | # Eclipse # 28 | ########### 29 | .project 30 | .cproject 31 | .settings 32 | 33 | # VS Code IDE # 34 | ############### 35 | .vscode/** 36 | 37 | # Temporary files # 38 | ################### 39 | *.bak 40 | *.orig 41 | *.rej 42 | *.tmp 43 | callgrind.out.* 44 | 45 | # Compiled source # 46 | ################### 47 | Programs/Bytecode/* 48 | Programs/Schedules/* 49 | Programs/Public-Input/* 50 | *.com 51 | *.class 52 | *.dll 53 | *.exe 54 | *.x 55 | *.o 56 | *.so 57 | *.pyc 58 | *.bc 59 | *.sch 60 | *.a 61 | *.static 62 | *.d 63 | 64 | # Packages # 65 | ############ 66 | # it's better to unpack these files and commit the raw source 67 | # git has its own built in compression methods 68 | *.7z 69 | *.dmg 70 | *.gz 71 | *.iso 72 | *.jar 73 | *.rar 74 | *.tar 75 | *.zip 76 | 77 | # Latex # 78 | ######### 79 | *.aux 80 | *.lof 81 | *.log 82 | *.lot 83 | *.fls 84 | *.out 85 | *.toc 86 | *.fmt 87 | *.bbl 88 | *.bcf 89 | *.blg 90 | 91 | 92 | # Logs and databases # 93 | ###################### 94 | *.log 95 | *.sql 96 | *.sqlite 97 | *.data 98 | Persistence/* 99 | 100 | # OS generated files # 101 | ###################### 102 | *~ 103 | .DS_Store 104 | .DS_Store? 105 | ._* 106 | .Spotlight-V100 107 | .Trashes 108 | ehthumbs.db 109 | Thumbs.db 110 | **/*.x.dSYM/** 111 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | The changelog explains changes pulled through from the private development repository. Bug fixes and small enchancements are committed between releases and not documented here. 2 | 3 | ## 0.0.3 (Mar 2, 2018) 4 | 5 | - Added offline phases based on homomorphic encryption, used in the [SPDZ-2 paper](https://eprint.iacr.org/2012/642) and the [Overdrive paper](https://eprint.iacr.org/2017/1230). 6 | - On macOS, the minimum requirement is now Sierra. 7 | - Compilation with LLVM/clang is now possible (tested with 3.8). 8 | 9 | ## 0.0.2 (Sep 13, 2017) 10 | 11 | ### Support sockets based external client input and output to a SPDZ MPC program. 12 | 13 | See the [ExternalIO directory](./ExternalIO/README.md) for more details and examples. 14 | 15 | Note that [libsodium](https://download.libsodium.org/doc/) is now a dependency on the SPDZ build. 16 | 17 | Added compiler instructions: 18 | 19 | * LISTEN 20 | * ACCEPTCLIENTCONNECTION 21 | * CONNECTIPV4 22 | * WRITESOCKETSHARE 23 | * WRITESOCKETINT 24 | 25 | Removed instructions: 26 | 27 | * OPENSOCKET 28 | * CLOSESOCKET 29 | 30 | Modified instructions: 31 | 32 | * READSOCKETC 33 | * READSOCKETS 34 | * READSOCKETINT 35 | * WRITESOCKETC 36 | * WRITESOCKETS 37 | 38 | Support secure external client input and output with new instructions: 39 | 40 | * READCLIENTPUBLICKEY 41 | * INITSECURESOCKET 42 | * RESPSECURESOCKET 43 | 44 | ### Read/Write secret shares to disk to support persistence in a SPDZ MPC program. 45 | 46 | Added compiler instructions: 47 | 48 | * READFILESHARE 49 | * WRITEFILESHARE 50 | 51 | ### Other instructions 52 | 53 | Added compiler instructions: 54 | 55 | * DIGESTC - Clear truncated hash computation 56 | * PRINTINT - Print register value 57 | 58 | ## 0.0.1 (Sep 2, 2016) 59 | 60 | ### Initial Release 61 | 62 | * See `README.md` and `tutorial.md`. 63 | -------------------------------------------------------------------------------- /FHEOffline/DistDecrypt.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include "DistDecrypt.h" 5 | 6 | template 7 | DistDecrypt::DistDecrypt(const Player& P, const FHE_SK& share, 8 | const FHE_PK& pk, const FD& FTD) : 9 | P(P), share(share), pk(pk), mf(FTD), f(FTD) 10 | { 11 | vv.resize(pk.get_params().phi_m()); 12 | vv1.resize(pk.get_params().phi_m()); 13 | // extra limb for operations 14 | bigint limit = pk.get_params().Q() << 64; 15 | vv.allocate_slots(limit); 16 | vv1.allocate_slots(limit); 17 | mf.allocate_slots(pk.get_params().p0() << 64); 18 | } 19 | 20 | template 21 | Plaintext_& DistDecrypt::run(const Ciphertext& ctx, bool NewCiphertext) 22 | { 23 | const FHE_Params& params=ctx.get_params(); 24 | 25 | share.dist_decrypt_1(vv, ctx,P.my_num(),P.num_players()); 26 | 27 | if (not NewCiphertext) 28 | intermediate_step(); 29 | 30 | // Now pack into an octetStream for broadcasting 31 | vector os(P.num_players()); 32 | 33 | if ((int)vv.size() != params.phi_m()) 34 | throw length_error("wrong length of ring element"); 35 | for (int i=0; i; 59 | template class DistDecrypt; 60 | 61 | 62 | -------------------------------------------------------------------------------- /Auth/fake-stuff.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #ifndef _fake_stuff 5 | #define _fake_stuff 6 | 7 | #include "Math/gf2n.h" 8 | #include "Math/gfp.h" 9 | #include "Math/Share.h" 10 | 11 | #include 12 | using namespace std; 13 | 14 | template 15 | void make_share(vector >& Sa,const T& a,int N,const T& key,PRNG& G); 16 | 17 | template 18 | void check_share(vector >& Sa,T& value,T& mac,int N,const T& key); 19 | 20 | void expand_byte(gf2n_short& a,int b); 21 | void collapse_byte(int& b,const gf2n_short& a); 22 | 23 | // Generate MAC key shares 24 | void generate_keys(const string& directory, int nplayers); 25 | 26 | template 27 | void write_mac_keys(const string& directory, int player_num, int nplayers, gfp keyp, T key2); 28 | 29 | // Read MAC key shares and compute keys 30 | void read_keys(const string& directory, gfp& keyp, gf2n& key2, int nplayers); 31 | 32 | template 33 | class Files 34 | { 35 | public: 36 | ofstream* outf; 37 | int N; 38 | T key; 39 | PRNG G; 40 | Files(int N, const T& key, const string& prefix) : N(N), key(key) 41 | { 42 | outf = new ofstream[N]; 43 | for (int i=0; i > Sa(N); 61 | make_share(Sa,a,N,key,G); 62 | for (int j=0; j 12 | #include 13 | using namespace std; 14 | 15 | template 16 | class WaitQueue 17 | { 18 | pthread_mutex_t mutex; 19 | pthread_cond_t cond; 20 | 21 | deque queue; 22 | bool running; 23 | 24 | // prevent copying 25 | WaitQueue(const WaitQueue& other); 26 | 27 | public: 28 | WaitQueue() : running(true) 29 | { 30 | pthread_mutex_init(&mutex, 0); 31 | pthread_cond_init(&cond, 0); 32 | } 33 | 34 | ~WaitQueue() 35 | { 36 | pthread_mutex_destroy(&mutex); 37 | pthread_cond_destroy(&cond); 38 | } 39 | 40 | void lock() 41 | { 42 | pthread_mutex_lock(&mutex); 43 | } 44 | 45 | void unlock() 46 | { 47 | pthread_mutex_unlock(&mutex); 48 | } 49 | 50 | void wait() 51 | { 52 | pthread_cond_wait(&cond, &mutex); 53 | } 54 | 55 | void signal() 56 | { 57 | pthread_cond_signal(&cond); 58 | } 59 | 60 | void push(const T& value) 61 | { 62 | lock(); 63 | queue.push_back(value); 64 | signal(); 65 | unlock(); 66 | } 67 | 68 | bool pop(T& value) 69 | { 70 | lock(); 71 | if (running and queue.size() == 0) 72 | wait(); 73 | if (running) 74 | { 75 | value = queue.front(); 76 | queue.pop_front(); 77 | } 78 | unlock(); 79 | return running; 80 | } 81 | 82 | void stop() 83 | { 84 | lock(); 85 | running = false; 86 | signal(); 87 | unlock(); 88 | } 89 | }; 90 | 91 | #endif /* TOOLS_WAITQUEUE_H_ */ 92 | -------------------------------------------------------------------------------- /FHE/FHE_Params.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include "FHE_Params.h" 5 | #include "FHE/Ring_Element.h" 6 | #include "Math/gfp.h" 7 | #include "Exceptions/Exceptions.h" 8 | 9 | 10 | void FHE_Params::set(const Ring& R, 11 | const vector& primes,double r,int hwt) 12 | { 13 | if (primes.size() != FFTData.size()) 14 | throw runtime_error("wrong number of primes"); 15 | 16 | for (size_t i = 0; i < FFTData.size(); i++) 17 | FFTData[i].init(R,primes[i]); 18 | 19 | Chi.set(R.phi_m(),hwt,r); 20 | 21 | set_sec(40); 22 | } 23 | 24 | void FHE_Params::set_sec(int sec) 25 | { 26 | sec_p=sec; 27 | Bval=1; Bval=Bval< 15 | void Commit_And_Open(vector< vector >& data,const Player& P,int num_runs) 16 | { 17 | int num_players=P.num_players(); 18 | vector< vector > Comm_data(num_runs, vector(num_players)); 19 | vector Open_data(num_runs); 20 | Commit(Comm_data,Open_data,data,P,num_runs); 21 | Open(data,Comm_data,Open_data,P,num_runs); 22 | } 23 | 24 | 25 | 26 | /* Just transmit data[i][j] of type T 27 | * 0 <= i < num_runs 28 | * 0 <= j < num_players 29 | * On output data[i][j] contains all the data 30 | */ 31 | template 32 | void Transmit_Data(vector< vector >& data,const Player& P,int num_runs) 33 | { 34 | int my_number=P.my_num(); 35 | int num_players=P.num_players(); 36 | for (int i=0; i t_data(num_players); 39 | data[i][my_number].pack(t_data[my_number]); 40 | P.Broadcast_Receive(t_data); 41 | for (int j=0; j >& data,const Player& P,int num_runs); 50 | template void Commit_And_Open(vector< vector >& data,const Player& P,int num_runs); 51 | 52 | template void Transmit_Data(vector< vector >& data,const Player& P,int num_runs); 53 | template void Transmit_Data(vector< vector >& data,const Player& P,int num_runs); 54 | 55 | -------------------------------------------------------------------------------- /FHEOffline/FullSetup.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include "FHEOffline/FullSetup.h" 5 | #include "Math/gfp.h" 6 | 7 | #include "FHE/FHE_Params.h" 8 | #include "FHE/NTL-Subs.h" 9 | 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | 16 | // Read data for SHE offline 17 | void get_setup(FHE_Params& params_p,FFT_Data& FTD, 18 | FHE_Params& params_2,P2Data& P2D,string dir, 19 | bool skip_2) 20 | { 21 | int lg2; 22 | Ring R2,Rp; 23 | bigint p02,p12,p0p,p1p,p; 24 | 25 | // legacy 26 | if (dir == "") 27 | dir = PREP_DIR; 28 | 29 | string filename=dir+"/Params-Data"; 30 | 31 | ifstream inpf(filename.c_str()); 32 | if (inpf.fail()) { throw file_error(filename); } 33 | inpf >> p; 34 | inpf >> lg2; 35 | inpf >> Rp; 36 | inpf >> FTD; 37 | inpf >> p0p >> p1p; 38 | 39 | if (p != FTD.get_prime()) 40 | throw runtime_error("inconsistent p in Params-Data"); 41 | 42 | if (!skip_2) 43 | { 44 | // initialize before reading P2D for consistency check 45 | gf2n::init_field(lg2); 46 | inpf >> R2; 47 | inpf >> P2D; 48 | if (R2.phi_m() != P2D.phi_m()) 49 | throw runtime_error("phi(m) mismatch between ring and plaintext representation"); 50 | inpf >> p02 >> p12; 51 | } 52 | 53 | if (inpf.fail()) 54 | throw file_error("incomplete parameters"); 55 | 56 | inpf.close(); 57 | 58 | gfp::init_field(FTD.get_prime()); 59 | params_p.set(Rp,{p0p,p1p}); 60 | cout << "log(p) = " << numBits(FTD.get_prime()) << ", log(p0) = " 61 | << numBits(p0p) << ", " << "log(p1) = " << numBits(p1p) << endl; 62 | 63 | if (!skip_2) 64 | { 65 | params_2.set(R2,{p02,p12}); 66 | cout << "GF(2^" << lg2 << "): log(p0) = " << numBits(p02) 67 | << ", log(p1) = " << numBits(p12) << endl; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /FHEOffline/SimpleMachine.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * SimpleMachine.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_SIMPLEMACHINE_H_ 9 | #define FHEOFFLINE_SIMPLEMACHINE_H_ 10 | 11 | #include "FHE/FHE_Keys.h" 12 | #include "FHEOffline/DataSetup.h" 13 | #include "Networking/Player.h" 14 | #include "FHEOffline/SimpleGenerator.h" 15 | #include "Tools/OfflineMachineBase.h" 16 | 17 | class MachineBase : public OfflineMachineBase 18 | { 19 | protected: 20 | vector generators; 21 | string hostname; 22 | Timer timer; 23 | pthread_t throughput_loop_thread; 24 | int portnum_base; 25 | Dtype data_type; 26 | 27 | public: 28 | int sec; 29 | int field_size; 30 | int extra_slack; 31 | bool produce_inputs; 32 | bool use_gf2n; 33 | 34 | MachineBase(); 35 | MachineBase(int argc, const char** argv); 36 | void run(); 37 | 38 | void parse_options(int argc, const char** argv); 39 | 40 | string item_type(); 41 | 42 | void throughput_loop(); 43 | static void* run_throughput_loop(void* machine); 44 | 45 | size_t report_size(ReportType type); 46 | 47 | string tradeoff(); 48 | 49 | void mult_performance(); 50 | }; 51 | 52 | class MultiplicativeMachine : public MachineBase 53 | { 54 | protected: 55 | DataSetup setup; 56 | 57 | void parse_options(int argc, const char** argv); 58 | 59 | void generate_setup(int slack); 60 | template 61 | void fake_keys(int slack); 62 | 63 | public: 64 | virtual ~MultiplicativeMachine() {} 65 | 66 | virtual int get_covert() const { return 0; } 67 | }; 68 | 69 | class SimpleMachine : public MultiplicativeMachine 70 | { 71 | template