├── .gitignore ├── .gitmodules ├── Auth ├── MAC_Check.cpp ├── MAC_Check.h ├── Subroutines.cpp ├── Subroutines.h ├── Summer.cpp ├── Summer.h ├── fake-stuff.cpp └── fake-stuff.h ├── CHANGELOG.md ├── CONFIG ├── Check-Offline.cpp ├── Compiler ├── __init__.py ├── allocator.py ├── comparison.py ├── compilerLib.py ├── config.py ├── dijkstra.py ├── exceptions.py ├── floatingpoint.py ├── graph.py ├── gs.py ├── instructions.py ├── instructions_base.py ├── library.py ├── oram.py ├── path_oram.py ├── permutation.py ├── program.py ├── tools.py ├── types.py └── util.py ├── Exceptions └── Exceptions.h ├── ExternalIO ├── README.md ├── bankers-bonus-client.cpp └── bankers-bonus-commsec-client.cpp ├── FHE ├── AddableVector.h ├── Ciphertext.cpp ├── Ciphertext.h ├── DiscreteGauss.cpp ├── DiscreteGauss.h ├── FFT.cpp ├── FFT.h ├── FFT_Data.cpp ├── FFT_Data.h ├── FHE_Keys.cpp ├── FHE_Keys.h ├── FHE_Params.cpp ├── FHE_Params.h ├── Generator.h ├── Matrix.cpp ├── Matrix.h ├── NTL-Subs.cpp ├── NTL-Subs.h ├── NoiseBounds.cpp ├── NoiseBounds.h ├── P2Data.cpp ├── P2Data.h ├── PPData.cpp ├── PPData.h ├── Plaintext.cpp ├── Plaintext.h ├── QGroup.cpp ├── QGroup.h ├── Random_Coins.cpp ├── Random_Coins.h ├── Ring.cpp ├── Ring.h ├── Ring_Element.cpp ├── Ring_Element.h ├── Rq_Element.cpp ├── Rq_Element.h └── tools.h ├── FHEOffline ├── CutAndChooseMachine.cpp ├── CutAndChooseMachine.h ├── DataSetup.cpp ├── DataSetup.h ├── DistDecrypt.cpp ├── DistDecrypt.h ├── DistKeyGen.cpp ├── DistKeyGen.h ├── EncCommit.cpp ├── EncCommit.h ├── FHE-Subroutines.cpp ├── FullSetup.cpp ├── FullSetup.h ├── Multiplier.cpp ├── Multiplier.h ├── PairwiseGenerator.cpp ├── PairwiseGenerator.h ├── PairwiseMachine.cpp ├── PairwiseMachine.h ├── PairwiseSetup.cpp ├── PairwiseSetup.h ├── Player-Offline.h ├── Producer.cpp ├── Producer.h ├── Proof.cpp ├── Proof.h ├── Prover.cpp ├── Prover.h ├── Reshare.cpp ├── Reshare.h ├── Sacrificing.cpp ├── Sacrificing.h ├── SimpleDistDecrypt.cpp ├── SimpleDistDecrypt.h ├── SimpleEncCommit.cpp ├── SimpleEncCommit.h ├── SimpleGenerator.cpp ├── SimpleGenerator.h ├── SimpleMachine.cpp ├── SimpleMachine.h ├── Verifier.cpp ├── Verifier.h └── config.h ├── Fake-Offline.cpp ├── HOSTS.example ├── License.txt ├── Makefile ├── Math ├── Integer.cpp ├── Integer.h ├── Setup.cpp ├── Setup.h ├── Share.cpp ├── Share.h ├── Subroutines.cpp ├── Subroutines.h ├── Zp_Data.cpp ├── Zp_Data.h ├── bigint.cpp ├── bigint.h ├── field_types.h ├── gf2n.cpp ├── gf2n.h ├── gf2nlong.cpp ├── gf2nlong.h ├── gfp.cpp ├── gfp.h ├── modp.cpp ├── modp.h └── operators.h ├── Networking ├── Player.cpp ├── Player.h ├── Receiver.cpp ├── Receiver.h ├── STS.cpp ├── STS.h ├── Sender.cpp ├── Sender.h ├── Server.cpp ├── Server.h ├── ServerSocket.cpp ├── ServerSocket.h ├── data.h ├── sockets.cpp └── sockets.h ├── OT ├── BaseOT.cpp ├── BaseOT.h ├── BitMatrix.cpp ├── BitMatrix.h ├── BitVector.cpp ├── BitVector.h ├── NPartyTripleGenerator.cpp ├── NPartyTripleGenerator.h ├── OTExtension.cpp ├── OTExtension.h ├── OTExtensionWithMatrix.cpp ├── OTExtensionWithMatrix.h ├── OTMachine.cpp ├── OTMachine.h ├── OTMultiplier.cpp ├── OTMultiplier.h ├── OTTripleSetup.cpp ├── OTTripleSetup.h ├── OText_main.cpp ├── OutputCheck.h ├── Tools.cpp ├── Tools.h ├── TripleMachine.cpp └── TripleMachine.h ├── Player-Online.cpp ├── Processor ├── Binary_File_IO.cpp ├── Binary_File_IO.h ├── Buffer.cpp ├── Buffer.h ├── Data_Files.cpp ├── Data_Files.h ├── ExternalClients.cpp ├── ExternalClients.h ├── Input.cpp ├── Input.h ├── InputTuple.h ├── Instruction.cpp ├── Instruction.h ├── Machine.cpp ├── Machine.h ├── Memory.cpp ├── Memory.h ├── Online-Thread.cpp ├── Online-Thread.h ├── PrivateOutput.cpp ├── PrivateOutput.h ├── Processor.cpp ├── Processor.h ├── Program.cpp └── Program.h ├── Programs └── Source │ ├── aes.mpc │ ├── bankers_bonus.mpc │ ├── bankers_bonus_commsec.mpc │ ├── dijkstra_tutorial.mpc │ ├── fixed_point_tutorial.mpc │ ├── gale-shapley_tutorial.mpc │ ├── htmac.mpc │ ├── oram_tutorial.mpc │ ├── prf_leg.mpc │ ├── prf_mimc.mpc │ ├── tpmpc_tutorial.mpc │ ├── tutorial.mpc │ └── vickrey.mpc ├── README.md ├── Scripts ├── gen_input_f2n.cpp ├── gen_input_fp.cpp ├── run-common.sh ├── run-online.sh └── setup-online.sh ├── Server.cpp ├── Tools ├── Commit.cpp ├── Commit.h ├── Config.cpp ├── Config.h ├── Lock.cpp ├── Lock.h ├── MMO.cpp ├── MMO.h ├── MemoryUsage.h ├── OfflineMachineBase.cpp ├── OfflineMachineBase.h ├── Signal.cpp ├── Signal.h ├── WaitQueue.h ├── aes-ni.cpp ├── aes.cpp ├── aes.h ├── avx_memcpy.h ├── benchmarking.h ├── ezOptionParser-MIT-LICENSE ├── ezOptionParser.h ├── int.h ├── mkpath.cpp ├── mkpath.h ├── names.cpp ├── octetStream.cpp ├── octetStream.h ├── parse.h ├── pprint.h ├── random.cpp ├── random.h ├── sha1.cpp ├── sha1.h ├── time-func.cpp └── time-func.h ├── check-passive.cpp ├── client-setup.cpp ├── cnc-offline.cpp ├── compile.py ├── ot-offline.cpp ├── pairwise-offline.cpp ├── simple-offline.cpp ├── spdz2-offline.cpp └── tutorial.md /.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 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "SimpleOT"] 2 | path = SimpleOT 3 | url = git@github.com:pascholl/SimpleOT.git 4 | -------------------------------------------------------------------------------- /Auth/Summer.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Summer.cpp 5 | * 6 | */ 7 | 8 | #include "Auth/Summer.h" 9 | #include "Auth/MAC_Check.h" 10 | #include "Tools/int.h" 11 | 12 | template 13 | Summer::Summer(int sum_players, int last_sum_players, int next_sum_players, 14 | Player* send_player, Player* receive_player, Parallel_MAC_Check& MC) : 15 | sum_players(sum_players), last_sum_players(last_sum_players), next_sum_players(next_sum_players), 16 | base_player(0), MC(MC),send_player(send_player), receive_player(receive_player), 17 | thread(0), stop(false), size(0) 18 | { 19 | cout << "Setting up summation by " << sum_players << " players" << endl; 20 | } 21 | 22 | template 23 | Summer::~Summer() 24 | { 25 | delete send_player; 26 | if (timer.elapsed()) 27 | cout << T::type_string() << " summation by " << sum_players << " players: " 28 | << timer.elapsed() << endl; 29 | } 30 | 31 | template 32 | void Summer::run() 33 | { 34 | octetStream os; 35 | 36 | while (true) 37 | { 38 | int size = 0; 39 | if (!input_queue.pop(size)) 40 | break; 41 | 42 | int my_relative_num = positive_modulo(send_player->my_num() - base_player, send_player->num_players()); 43 | if (my_relative_num < sum_players) 44 | { 45 | // first summer takes inputs from queue 46 | if (last_sum_players == send_player->num_players()) 47 | share_queue.pop(values); 48 | else 49 | { 50 | values.resize(size); 51 | receive_player->receive_player(receive_player->my_num(),os,true); 52 | for (int i = 0; i < size; i++) 53 | values[i].unpack(os); 54 | } 55 | 56 | timer.start(); 57 | if (T::t() == 2) 58 | add_openings(values, *receive_player, sum_players, 59 | last_sum_players, base_player, MC); 60 | else 61 | add_openings(values, *receive_player, sum_players, 62 | last_sum_players, base_player, MC); 63 | timer.stop(); 64 | 65 | os.reset_write_head(); 66 | for (int i = 0; i < size; i++) 67 | values[i].pack(os); 68 | 69 | if (sum_players > 1) 70 | { 71 | int receiver = positive_modulo(base_player + my_relative_num % next_sum_players, 72 | send_player->num_players()); 73 | send_player->send_to(receiver, os, true); 74 | } 75 | else 76 | { 77 | send_player->send_all(os); 78 | MC.value_queue.push(values); 79 | } 80 | } 81 | 82 | if (sum_players == 1) 83 | output_queue.push(size); 84 | 85 | base_player = (base_player + 1) % send_player->num_players(); 86 | } 87 | } 88 | 89 | template class Summer; 90 | template class Summer; 91 | 92 | #ifdef USE_GF2N_LONG 93 | template class Summer; 94 | #endif 95 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Compiler/compilerLib.py: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | from Compiler.program import Program 4 | from Compiler.config import * 5 | from Compiler.exceptions import * 6 | import instructions, instructions_base, types, comparison, library 7 | 8 | import random 9 | import time 10 | import sys 11 | 12 | 13 | def run(args, options, param=-1, merge_opens=True, emulate=True, \ 14 | reallocate=True, assemblymode=False, debug=False): 15 | """ Compile a file and output a Program object. 16 | 17 | If merge_opens is set to True, will attempt to merge any parallelisable open 18 | instructions. """ 19 | 20 | prog = Program(args, options, param, assemblymode) 21 | instructions.program = prog 22 | instructions_base.program = prog 23 | types.program = prog 24 | comparison.program = prog 25 | prog.EMULATE = emulate 26 | prog.DEBUG = debug 27 | VARS['program'] = prog 28 | comparison.set_variant(options) 29 | 30 | print 'Compiling file', prog.infile 31 | 32 | # no longer needed, but may want to support assembly in future (?) 33 | if assemblymode: 34 | prog.restart_main_thread() 35 | for i in xrange(INIT_REG_MAX): 36 | VARS['c%d'%i] = prog.curr_block.new_reg('c') 37 | VARS['s%d'%i] = prog.curr_block.new_reg('s') 38 | VARS['cg%d'%i] = prog.curr_block.new_reg('cg') 39 | VARS['sg%d'%i] = prog.curr_block.new_reg('sg') 40 | if i % 10000000 == 0 and i > 0: 41 | print "Initialized %d register variables at" % i, time.asctime() 42 | 43 | # first pass determines how many assembler registers are used 44 | prog.FIRST_PASS = True 45 | execfile(prog.infile, VARS) 46 | 47 | if instructions_base.Instruction.count != 0: 48 | print 'instructions count', instructions_base.Instruction.count 49 | instructions_base.Instruction.count = 0 50 | prog.FIRST_PASS = False 51 | prog.reset_values() 52 | # make compiler modules directly accessible 53 | sys.path.insert(0, 'Compiler') 54 | # create the tapes 55 | execfile(prog.infile, VARS) 56 | 57 | # optimize the tapes 58 | for tape in prog.tapes: 59 | tape.optimize(options) 60 | 61 | # check program still does the same thing after optimizations 62 | if emulate: 63 | clearmem = list(prog.mem_c) 64 | sharedmem = list(prog.mem_s) 65 | prog.emulate() 66 | if prog.mem_c != clearmem or prog.mem_s != sharedmem: 67 | print 'Warning: emulated memory values changed after compiler optimization' 68 | # raise CompilerError('Compiler optimization caused incorrect memory write.') 69 | 70 | if prog.main_thread_running: 71 | prog.update_req(prog.curr_tape) 72 | print 'Program requires:', repr(prog.req_num) 73 | print 'Cost:', prog.req_num.cost() 74 | print 'Memory size:', prog.allocated_mem 75 | 76 | # finalize the memory 77 | prog.finalize_memory() 78 | 79 | return prog 80 | -------------------------------------------------------------------------------- /Compiler/config.py: -------------------------------------------------------------------------------- 1 | # (C) 2018 University of Bristol. See License.txt 2 | 3 | from collections import defaultdict 4 | 5 | #INIT_REG_MAX = 655360 6 | INIT_REG_MAX = 1310720 7 | REG_MAX = 2 ** 32 8 | USER_MEM = 8192 9 | TMP_MEM = 8192 10 | TMP_MEM_BASE = USER_MEM 11 | TMP_REG = 3 12 | TMP_REG_BASE = REG_MAX - TMP_REG 13 | 14 | P_VALUES = { -1: 2147483713, \ 15 | 32: 2147565569, \ 16 | 64: 9223372036855103489, \ 17 | 128: 172035116406933162231178957667602464769, \ 18 | 256: 57896044624266469032429686755131815517604980759976795324963608525438406557697, \ 19 | 512: 6703903964971298549787012499123814115273848577471136527425966013026501536706464354255445443244279389455058889493431223951165286470575994074291745908195329 } 20 | 21 | BIT_LENGTHS = { -1: 32, 22 | 32: 16, 23 | 64: 16, 24 | 128: 64, 25 | 256: 64, 26 | 512: 64 } 27 | 28 | STAT_SEC = { -1: 6, 29 | 32: 6, 30 | 64: 30, 31 | 128: 40, 32 | 256: 40, 33 | 512: 40 } 34 | 35 | 36 | COST = { 'modp': defaultdict(lambda: 0, 37 | { 'triple': 0.00020652622883106154, 38 | 'square': 0.00020652622883106154, 39 | 'bit': 0.00020652622883106154, 40 | 'inverse': 0.00020652622883106154, 41 | 'PreMulC': 2 * 0.00020652622883106154, 42 | }), 43 | 'gf2n': defaultdict(lambda: 0, 44 | { 'triple': 0.00020716801325875284, 45 | 'square': 0.00020716801325875284, 46 | 'inverse': 0.00020716801325875284, 47 | 'bit': 1.4492753623188405e-07, 48 | 'bittriple': 0.00004828818388140422, 49 | 'bitgf2ntriple': 0.00020716801325875284, 50 | 'PreMulC': 2 * 0.00020716801325875284, 51 | }) 52 | } 53 | 54 | 55 | try: 56 | from config_mine import * 57 | except: 58 | pass 59 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /FHE/DiscreteGauss.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include "DiscreteGauss.h" 5 | #include "math.h" 6 | 7 | void DiscreteGauss::set(double RR) 8 | { 9 | R=RR; 10 | e=exp(1); e1=exp(0.25); e2=exp(-1.35); 11 | } 12 | 13 | 14 | 15 | /* Return a value distributed normaly with std dev R */ 16 | int DiscreteGauss::sample(PRNG& G, int stretch) const 17 | { 18 | /* Uses the ratio method from Wikipedia to get a 19 | Normal(0,1) variable X 20 | Then multiplies X by R 21 | */ 22 | double U,V,X,R1,R2,R3,X2; 23 | int ans; 24 | while (true) 25 | { U=G.get_double(); 26 | V=G.get_double(); 27 | R1=5-4*e1*U; 28 | R2=4*e2/U+1.4; 29 | R3=-4/log(U); 30 | X=sqrt(8/e)*(V-0.5)/U; 31 | X2=X*X; 32 | if (X2<=R1 || (X2 RandomVectors::sample_Gauss(PRNG& G, int stretch) const 51 | { 52 | vector ans(n); 53 | for (int i=0; i RandomVectors::sample_Hwt(PRNG& G) const 60 | { 61 | if (h>n/2) { return sample_Gauss(G); } 62 | vector ans(n); 63 | for (int i=0; i RandomVectors::sample_Half(PRNG& G) const 98 | { 99 | vector ans(n); 100 | for (int i=0; i RandomVectors::sample_Uniform(PRNG& G,const bigint& B) const 107 | { 108 | vector ans(n); 109 | bigint v; 110 | for (int i=0; i 15 | 16 | #include "FHE/FFT_Data.h" 17 | 18 | /* This is the basic 2^n - FFT routine, it works in an recursive 19 | * manner. The FFT_Iter routine below does the same thing but in 20 | * an iterative manner, and is therefore more efficient. 21 | */ 22 | void FFT(vector& a,int N,const modp& theta,const Zp_Data& PrD); 23 | 24 | /* This uses a different root of unity and is used for going 25 | * forward when doing 2^n FFT's. This avoids the need for padding 26 | * out to a vector of size 2*n. Going backwards you still need to 27 | * use FFT, but some other post-processing. Again the iterative 28 | * version is given by FFT_Iter2 below, and this is usually faster 29 | */ 30 | void FFT2(vector& a,int N,const modp& theta,const Zp_Data& PrD); 31 | 32 | template 33 | void FFT_Iter(vector& a,int N,const T& theta,const P& PrD); 34 | 35 | void FFT_Iter2(vector& a,int N,const modp& theta,const Zp_Data& PrD); 36 | 37 | 38 | /* BFFT perform FFT and inverse FFT mod PrD for non power of two cyclotomics. 39 | * The modulus in PrD (contained in FFT_Data) must be set up 40 | * correctly in particular 41 | * m divides pr-1 <- Otherwise FFT not defined over base field 42 | * 2^k divides pr-1 <- Where 2^k is the smallest power of two 43 | * greater than m. This means we can do the 44 | * trick of extension and the convolution using 45 | * the 2-power FFT to do the main work 46 | * forward=true => FFT 47 | * forward=false => inverse FFT 48 | * 49 | * a on input is assumed to have size less than FFTD.n (it is then zero padded) 50 | * ans is assumed to have size FFTD.n 51 | */ 52 | 53 | void BFFT(vector& ans,const vector& a,const FFT_Data& FFTD,bool forward=true); 54 | 55 | 56 | /* Computes the FFT via Horner's Rule 57 | theta is assumed to be an Nth root of unity 58 | This works for any value of N 59 | */ 60 | void NaiveFFT(vector& ans,vector& a,int N,const modp& theta,const Zp_Data& PrD); 61 | 62 | 63 | #endif 64 | 65 | -------------------------------------------------------------------------------- /FHE/FFT_Data.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _FFT_Data 4 | #define _FFT_Data 5 | 6 | #include "Math/modp.h" 7 | #include "Math/Zp_Data.h" 8 | #include "Math/gfp.h" 9 | #include "FHE/Ring.h" 10 | 11 | /* Class for holding modular arithmetic data wrt the ring 12 | * 13 | * It also holds the ring 14 | */ 15 | 16 | 17 | class FFT_Data 18 | { 19 | Ring R; 20 | Zp_Data prData; 21 | 22 | vector root; // 2m'th Root of Unity mod pr and it's inverse 23 | 24 | // When twop is equal to zero, m is a power of two 25 | // When twop is positive it is equal to 2^e where 2^e>2*m and 2^e divides p-1 26 | // - In this case we can use FFTs over the base field 27 | int twop; 28 | 29 | // Stuff for arithmetic when 2^e > 2*m and 2^e divides p-1 (i.e. twop positive) 30 | vector two_root; // twop'th Root of Unity mod pr where twop = 2^e > 2*m 31 | // - And inverse 32 | vector< vector > b; 33 | 34 | // Stuff for arithmetic when m is a power of 2 (in which case twop=0) 35 | modp iphi; // 1/phi_m mod pr 36 | vector< vector > powers,powers_i; 37 | 38 | public: 39 | typedef gfp T; 40 | typedef bigint S; 41 | 42 | void init(const Ring& Rg,const Zp_Data& PrD); 43 | 44 | void init_field() const { gfp::init_field(prData.pr); } 45 | 46 | void pack(octetStream& o) const; 47 | void unpack(octetStream& o); 48 | 49 | void assign(const FFT_Data& FFTD); 50 | 51 | FFT_Data() { ; } 52 | FFT_Data(const FFT_Data& FFTD) 53 | { assign(FFTD); } 54 | FFT_Data(const Ring& Rg,const Zp_Data& PrD) 55 | { init(Rg,PrD); } 56 | FFT_Data& operator=(const FFT_Data& FFTD) 57 | { if (this!=&FFTD) { assign(FFTD); } 58 | return *this; 59 | } 60 | 61 | const Zp_Data& get_prD() const { return prData; } 62 | const bigint& get_prime() const { return prData.pr; } 63 | int phi_m() const { return R.phi_m(); } 64 | int m() const { return R.m(); } 65 | int num_slots() const { return R.phi_m(); } 66 | 67 | int p(int i) const { return R.p(i); } 68 | int p_inv(int i) const { return R.p_inv(i); } 69 | const vector& Phi() const { return R.Phi(); } 70 | 71 | int get_twop() const { return twop; } 72 | modp get_root(int i) const { return root[i]; } 73 | modp get_iphi() const { return iphi; } 74 | 75 | const Ring& get_R() const { return R; } 76 | 77 | bool operator==(const FFT_Data& other) const { return not (*this != other); } 78 | bool operator!=(const FFT_Data& other) const; 79 | 80 | friend ostream& operator<<(ostream& s,const FFT_Data& FFTD); 81 | friend istream& operator>>(istream& s,FFT_Data& FFTD); 82 | 83 | friend void BFFT(vector& ans,const vector& a,const FFT_Data& FFTD,bool forward); 84 | }; 85 | 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /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< FFTData; 24 | 25 | // Random generator for Multivariate Gaussian Distribution etc 26 | RandomVectors Chi; 27 | 28 | // Data for distributed decryption 29 | int sec_p; 30 | bigint Bval; 31 | 32 | public: 33 | 34 | FHE_Params(int n_mults = 1) : FFTData(n_mults + 1), sec_p(-1) {} 35 | 36 | int n_mults() const { return FFTData.size() - 1; } 37 | 38 | // Rely on default copy assignment/constructor (not that they should 39 | // ever be needed) 40 | 41 | void set(const Ring& R,const vector& primes,double r=3.2,int hwt=64); 42 | void set_sec(int sec); 43 | 44 | vector sampleGaussian(PRNG& G, int noise_boost = 1) const 45 | { return Chi.sample_Gauss(G, noise_boost); } 46 | vector sampleHwt(PRNG& G) const 47 | { return Chi.sample_Hwt(G); } 48 | vector sampleHalf(PRNG& G) const 49 | { return Chi.sample_Half(G); } 50 | vector sampleUniform(PRNG& G,const bigint& Bd) const 51 | { return Chi.sample_Uniform(G,Bd); } 52 | 53 | const vector& FFTD() const { return FFTData; } 54 | 55 | const bigint& p0() const { return FFTData[0].get_prime(); } 56 | const bigint& p1() const { return FFTData[1].get_prime(); } 57 | bigint Q() const; 58 | 59 | int secp() const { return sec_p; } 60 | const bigint& B() const { return Bval; } 61 | double get_R() const { return Chi.get_R(); } 62 | DiscreteGauss get_DG() const { return Chi.get_DG(); } 63 | 64 | int phi_m() const { return FFTData[0].phi_m(); } 65 | const Ring& get_ring() { return FFTData[0].get_R(); } 66 | 67 | void pack(octetStream& o) const; 68 | void unpack(octetStream& o); 69 | 70 | bool operator!=(const FHE_Params& other) const; 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /FHE/NTL-Subs.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _NTL_Subs 4 | #define _NTL_Subs 5 | 6 | /* All these routines use NTL on the inside */ 7 | 8 | #include "FHE/Ring.h" 9 | #include "FHE/FFT_Data.h" 10 | #include "FHE/P2Data.h" 11 | #include "FHE/PPData.h" 12 | #include "FHE/FHE_Params.h" 13 | 14 | 15 | /* Routines to set up key sizes given the number of players n 16 | * - And size lgp of plaintext modulus p for the char p case 17 | */ 18 | 19 | // Main setup routine (need NTL if online_only is false) 20 | void generate_setup(int nparties, int lgp, int lg2, 21 | int sec, bool skip_2 = false, int slack = 0, bool round_up = false); 22 | 23 | template 24 | void generate_setup(int n_parties, int plaintext_length, int sec, 25 | FHE_Params& params, FD& FTD, int slack, bool round_up); 26 | 27 | // semi-homomorphic, includes slack 28 | template 29 | int generate_semi_setup(int plaintext_length, int sec, 30 | FHE_Params& params, FD& FieldD, bool round_up); 31 | 32 | // field-independent semi-homomorphic setup 33 | int common_semi_setup(FHE_Params& params, int m, bigint p, int lgp0, int lgp1, 34 | bool round_up); 35 | 36 | // Everything else needs NTL 37 | void init(Ring& Rg,int m); 38 | void init(P2Data& P2D,const Ring& Rg); 39 | 40 | // For use when we only care about p being of a certain size 41 | void SPDZ_Data_Setup_Char_p(Ring& R, FFT_Data& FTD, bigint& pr0, bigint& pr1, 42 | int n, int lgp, int sec, int slack = 0, bool round_up = false); 43 | 44 | // For use when we want p to be a specific value 45 | void SPDZ_Data_Setup_Char_p_General(Ring& R, PPData& PPD, bigint& pr0, 46 | bigint& pr1, int n, int sec, bigint& p); 47 | 48 | // generate moduli according to lengths and other parameters 49 | void generate_moduli(bigint& pr0, bigint& pr1, const int m, 50 | const bigint p, const int lg2p0, const int lg2p1); 51 | 52 | void generate_modulus(bigint& pr, const int m, const bigint p, const int lg2pr, 53 | const string& i = "0", const bigint& pr0 = 0); 54 | 55 | // pre-generated dimensions for characteristic 2 56 | void char_2_dimension(int& m, int& lg2); 57 | 58 | void SPDZ_Data_Setup_Char_2(Ring& R, P2Data& P2D, bigint& pr0, bigint& pr1, 59 | int n, int lg2, int sec = -1, int slacke = 0, bool round_up = false); 60 | 61 | // try to avoid expensive generation by loading from disk if possible 62 | void load_or_generate(P2Data& P2D, const Ring& Rg); 63 | 64 | int phi_N(int N); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /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/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/PPData.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #include "Math/Subroutines.h" 4 | #include "FHE/PPData.h" 5 | #include "FHE/FFT.h" 6 | #include "FHE/Matrix.h" 7 | 8 | 9 | 10 | void PPData::assign(const PPData& PPD) 11 | { 12 | R=PPD.R; 13 | prData=PPD.prData; 14 | root=PPD.root; 15 | } 16 | 17 | 18 | void PPData::init(const Ring& Rg,const Zp_Data& PrD) 19 | { 20 | R=Rg; 21 | prData=PrD; 22 | 23 | root=Find_Primitive_Root_m(Rg.m(),Rg.Phi(),PrD); 24 | } 25 | 26 | 27 | ostream& operator<<(ostream& s,const PPData& PPD) 28 | { 29 | bigint ans; 30 | s << PPD.prData << endl; 31 | s << PPD.R << endl; 32 | to_bigint(ans,PPD.root,PPD.prData); s << ans << " "; 33 | 34 | return s; 35 | } 36 | 37 | 38 | istream& operator>>(istream& s,PPData& PPD) 39 | { 40 | bigint ans; 41 | s >> PPD.prData >> PPD.R; 42 | s >> ans; to_modp(PPD.root,ans,PPD.prData); 43 | return s; 44 | } 45 | 46 | 47 | 48 | void PPData::to_eval(vector& elem) const 49 | { 50 | if (elem.size()!= (unsigned) R.phi_m()) 51 | { throw params_mismatch(); } 52 | 53 | throw not_implemented(); 54 | 55 | /* 56 | vector ans; 57 | ans.resize(R.phi_m()); 58 | modp x=root; 59 | for (int i=0; i& elem) const 72 | { 73 | // avoid warning 74 | elem.empty(); 75 | throw not_implemented(); 76 | 77 | /* 78 | modp_matrix A; 79 | int n=phi_m(); 80 | A.resize(n, vector(n+1) ); 81 | modp x=root; 82 | for (int i=0; i& mess) const 113 | { 114 | // Uses Horner's rule 115 | gfp ans; 116 | to_gfp(ans,mess[mess.size()-1]); 117 | gfp coeff; 118 | for (int j=mess.size()-2; j>=0; j--) 119 | { ans.mul(thetaPow); 120 | to_gfp(coeff,mess[j]); 121 | ans.add(coeff); 122 | } 123 | return ans; 124 | } 125 | 126 | 127 | -------------------------------------------------------------------------------- /FHE/PPData.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _PPData 4 | #define _PPData 5 | 6 | #include "Math/modp.h" 7 | #include "Math/Zp_Data.h" 8 | #include "Math/gfp.h" 9 | #include "FHE/Ring.h" 10 | 11 | /* Class for holding modular arithmetic data wrt the ring 12 | * 13 | * It also holds the ring 14 | */ 15 | 16 | class PPData 17 | { 18 | public: 19 | typedef gf2n_short T; 20 | typedef bigint S; 21 | 22 | Ring R; 23 | Zp_Data prData; 24 | 25 | modp root; // m'th Root of Unity mod pr 26 | 27 | void init(const Ring& Rg,const Zp_Data& PrD); 28 | 29 | void assign(const PPData& PPD); 30 | 31 | PPData() { ; } 32 | PPData(const PPData& PPD) 33 | { assign(PPD); } 34 | PPData(const Ring& Rg,const Zp_Data& PrD) 35 | { init(Rg,PrD); } 36 | PPData& operator=(const PPData& PPD) 37 | { if (this!=&PPD) { assign(PPD); } 38 | return *this; 39 | } 40 | 41 | const Zp_Data& get_prD() const { return prData; } 42 | const bigint& get_prime() const { return prData.pr; } 43 | int phi_m() const { return R.phi_m(); } 44 | int m() const { return R.m(); } 45 | int num_slots() const { return R.phi_m(); } 46 | 47 | 48 | int p(int i) const { return R.p(i); } 49 | int p_inv(int i) const { return R.p_inv(i); } 50 | const vector& Phi() const { return R.Phi(); } 51 | 52 | friend ostream& operator<<(ostream& s,const PPData& PPD); 53 | friend istream& operator>>(istream& s,PPData& PPD); 54 | 55 | // Convert input vector from poly to evaluation representation 56 | // - Uses naive method and not FFT, we only use this rarely in any case 57 | void to_eval(vector& elem) const; 58 | void from_eval(vector& elem) const; 59 | 60 | // Following are used to iteratively get slots, as we use PPData when 61 | // we do not have an efficient FFT algorithm 62 | gfp thetaPow,theta; 63 | int pow; 64 | void reset_iteration(); 65 | void next_iteration(); 66 | gfp get_evaluation(const vector& mess) const; 67 | 68 | }; 69 | 70 | #endif 71 | 72 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /FHE/Random_Coins.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | #ifndef _Random_Coins 4 | #define _Random_Coins 5 | 6 | /* Randomness used to encrypt */ 7 | 8 | #include "FHE/FHE_Params.h" 9 | #include "FHE/Rq_Element.h" 10 | #include "FHE/AddableVector.h" 11 | 12 | class FHE_PK; 13 | 14 | class Int_Random_Coins : public AddableMatrix 15 | { 16 | const FHE_Params* params; 17 | public: 18 | Int_Random_Coins(const FHE_Params& params) : params(¶ms) 19 | { resize(3, params.phi_m()); } 20 | 21 | Int_Random_Coins(const FHE_PK& pk); 22 | 23 | void sample(PRNG& G) 24 | { 25 | (*this)[0].from(HalfGenerator(G)); 26 | for (int i = 1; i < 3; i++) 27 | (*this)[i].from(GaussianGenerator(params->get_DG(), G)); 28 | } 29 | }; 30 | 31 | class Random_Coins 32 | { 33 | Rq_Element uu,vv,ww; 34 | const FHE_Params *params; 35 | 36 | public: 37 | 38 | const FHE_Params& get_params() const { return *params; } 39 | 40 | Random_Coins(const FHE_Params& p) 41 | : uu(p.FFTD(),evaluation,evaluation), 42 | vv(p.FFTD(),evaluation,evaluation), 43 | ww(p.FFTD(),polynomial,polynomial) 44 | { params=&p; } 45 | 46 | Random_Coins(const FHE_PK& pk); 47 | 48 | ~Random_Coins() { ; } 49 | 50 | // Rely on default copy assignment/constructor 51 | 52 | const Rq_Element& u() const { return uu; } 53 | const Rq_Element& v() const { return vv; } 54 | const Rq_Element& w() const { return ww; } 55 | 56 | void assign(const Rq_Element& u,const Rq_Element& v,const Rq_Element& w) 57 | { uu=u; vv=v; ww=w; } 58 | 59 | template 60 | void assign(const vector& u,const vector& v,const vector& w) 61 | { uu.from_vec(u); vv.from_vec(v); ww.from_vec(w); } 62 | 63 | void assign(const Int_Random_Coins& rc) 64 | { uu.from_vec(rc[0]); vv.from_vec(rc[1]); ww.from_vec(rc[2]); } 65 | 66 | /* Generate a standard distribution */ 67 | void generate(PRNG& G) 68 | { uu.from(HalfGenerator(G)); 69 | vv.from(GaussianGenerator(params->get_DG(), G)); 70 | ww.from(GaussianGenerator(params->get_DG(), G)); 71 | } 72 | 73 | // Generate all from Uniform in range (-B,...B) 74 | void generateUniform(PRNG& G,const bigint& B1,const bigint& B2,const bigint& B3) 75 | { 76 | if (B1 == 0) 77 | uu.assign_zero(); 78 | else 79 | uu.from(UniformGenerator(G,numBits(B1))); 80 | vv.from(UniformGenerator(G,numBits(B2))); 81 | ww.from(UniformGenerator(G,numBits(B3))); 82 | } 83 | 84 | 85 | // ans,x and y must have same params otherwise error 86 | friend void add(Random_Coins& ans, 87 | const Random_Coins& x,const Random_Coins& y); 88 | 89 | // Don't bother outputing params, assumes these are implicitly known 90 | friend ostream& operator<<(ostream& s,const Random_Coins& rc) 91 | { s << rc.uu << " " << rc.vv << " " << rc.ww; 92 | return s; 93 | } 94 | 95 | void pack(octetStream& o) const { uu.pack(o); vv.pack(o); ww.pack(o); } 96 | 97 | size_t report_size(ReportType type) 98 | { return uu.report_size(type) + vv.report_size(type) + ww.report_size(type); } 99 | }; 100 | 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /FHEOffline/DataSetup.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * DataSetup.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_DATASETUP_H_ 9 | #define FHEOFFLINE_DATASETUP_H_ 10 | 11 | #include "Networking/Player.h" 12 | #include "FHE/FHE_Keys.h" 13 | #include "FHEOffline/FullSetup.h" 14 | #include "Math/Setup.h" 15 | 16 | class DataSetup; 17 | 18 | template 19 | class PartSetup 20 | { 21 | public: 22 | typedef typename FD::T T; 23 | 24 | FHE_Params params; 25 | FD FieldD; 26 | FHE_PK pk; 27 | FHE_SK sk; 28 | Ciphertext calpha; 29 | typename FD::T alphai; 30 | 31 | PartSetup(); 32 | void generate_setup(int n_parties, int plaintext_length, int sec, int slack, 33 | bool round_up); 34 | void output_setup(ostream& s) const; 35 | 36 | void fake(vector& sks, vector& alphais, int nplayers, bool distributed = true); 37 | void fake(vector >& setups, int nplayers, bool distributed = true); 38 | void insecure_debug_keys(vector >& setups, int nplayers, bool simple_pk); 39 | 40 | void pack(octetStream& os); 41 | void unpack(octetStream& os); 42 | 43 | void init_field(); 44 | 45 | void check(int sec) const; 46 | bool operator!=(const PartSetup& other); 47 | }; 48 | 49 | class DataSetup 50 | { 51 | public: 52 | PartSetup setup_p; 53 | PartSetup setup_2; 54 | 55 | FHE_Params ¶ms_p,¶ms_2; 56 | FFT_Data& FTD; 57 | P2Data& P2D; 58 | 59 | FHE_PK& pk_p; 60 | FHE_SK& sk_p; 61 | 62 | FHE_PK& pk_2; 63 | FHE_SK& sk_2; 64 | 65 | Ciphertext& calphap; 66 | Ciphertext& calpha2; 67 | 68 | gfp& alphapi; 69 | gf2n_short& alpha2i; 70 | 71 | DataSetup(); 72 | DataSetup(Names & N, bool skip_2 = false); 73 | DataSetup(const DataSetup& other) : DataSetup() { *this = other; } 74 | DataSetup& operator=(const DataSetup& other); 75 | 76 | void write_setup(string dir, bool skip_2); 77 | void write_setup(bool skip_2); 78 | void write_setup(const Names& N, bool skip_2); 79 | string get_prep_dir(int n_parties) const; 80 | void read_setup(bool skip_2, string dir = PREP_DIR); 81 | void read(Names& N, bool skip_2 = false, string dir = PREP_DIR); 82 | void output(int my_number, int nn, bool specific_dir = false); 83 | template 84 | PartSetup& part(); 85 | }; 86 | 87 | template<> inline PartSetup& DataSetup::part() { return setup_p; } 88 | template<> inline PartSetup& DataSetup::part() { return setup_2; } 89 | 90 | #endif /* FHEOFFLINE_DATASETUP_H_ */ 91 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/FHE-Subroutines.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include "Auth/Subroutines.h" 5 | #include "FHE/Rq_Element.h" 6 | #include "FHE/Ciphertext.h" 7 | #include "Tools/Commit.h" 8 | 9 | /* This runs the Commit and Open Protocol for data[i][j] of type T 10 | * 0 <= i < num_runs 11 | * 0 <= j < num_players 12 | * On input data[i][j] is only defined for j=my_number 13 | */ 14 | template 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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /FHEOffline/PairwiseMachine.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * PairwiseMachine.cpp 5 | * 6 | */ 7 | 8 | #include "FHEOffline/PairwiseMachine.h" 9 | #include "Tools/benchmarking.h" 10 | #include "Auth/fake-stuff.h" 11 | 12 | PairwiseMachine::PairwiseMachine(int argc, const char** argv) : 13 | MachineBase(argc, argv), P(N, 0xffff << 16), 14 | other_pks(N.num_players(), {setup_p.params, 0}), 15 | pk(other_pks[N.my_num()]), sk(pk) 16 | { 17 | if (use_gf2n) 18 | { 19 | field_size = 40; 20 | gf2n::init_field(field_size); 21 | setup_keys(); 22 | } 23 | else 24 | { 25 | setup_keys(); 26 | bigint p = setup_p.FieldD.get_prime(); 27 | gfp::init_field(p); 28 | ofstream outf; 29 | if (output) 30 | write_online_setup(outf, PREP_DIR, p, 40); 31 | } 32 | 33 | for (int i = 0; i < nthreads; i++) 34 | if (use_gf2n) 35 | generators.push_back(new PairwiseGenerator(i, *this)); 36 | else 37 | generators.push_back(new PairwiseGenerator(i, *this)); 38 | } 39 | 40 | template <> 41 | PairwiseSetup& PairwiseMachine::setup() 42 | { 43 | return setup_p; 44 | } 45 | 46 | template <> 47 | PairwiseSetup& PairwiseMachine::setup() 48 | { 49 | return setup_2; 50 | } 51 | 52 | template 53 | void PairwiseMachine::setup_keys() 54 | { 55 | PairwiseSetup& s = setup(); 56 | s.init(P, sec, field_size, extra_slack); 57 | if (output) 58 | write_mac_keys(PREP_DIR, P.my_num(), P.num_players(), setup_p.alphai, 59 | setup_2.alphai); 60 | for (auto& x : other_pks) 61 | x = FHE_PK(s.params, s.FieldD.get_prime()); 62 | sk = FHE_SK(pk); 63 | PRNG G; 64 | G.ReSeed(); 65 | insecure("local key generation"); 66 | KeyGen(pk, sk, G); 67 | vector os(N.num_players()); 68 | pk.pack(os[N.my_num()]); 69 | P.Broadcast_Receive(os); 70 | for (int i = 0; i < N.num_players(); i++) 71 | if (i != N.my_num()) 72 | other_pks[i].unpack(os[i]); 73 | 74 | insecure("MAC key generation"); 75 | Ciphertext enc_alpha = pk.encrypt(s.alpha); 76 | os.clear(); 77 | os.resize(N.num_players()); 78 | enc_alphas.resize(N.num_players(), pk); 79 | enc_alpha.pack(os[N.my_num()]); 80 | P.Broadcast_Receive(os); 81 | for (int i = 0; i < N.num_players(); i++) 82 | if (i != N.my_num()) 83 | enc_alphas[i].unpack(os[i]); 84 | for (int i = 0; i < N.num_players(); i++) 85 | cout << "Player " << i << " has pk " 86 | << other_pks[i].a().get(0).get_constant().get_limb(0) << " ..." 87 | << endl; 88 | } 89 | 90 | template void PairwiseMachine::setup_keys(); 91 | template void PairwiseMachine::setup_keys(); 92 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /FHEOffline/Reshare.cpp: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | 4 | #include "FHEOffline/Reshare.h" 5 | #include "FHEOffline/DistDecrypt.h" 6 | #include "Tools/random.h" 7 | 8 | template 9 | void Reshare(Plaintext& m,Ciphertext& cc, 10 | const Ciphertext& cm,bool NewCiphertext, 11 | const Player& P,EncCommitBase& EC, 12 | const FHE_PK& pk,const FHE_SK& share) 13 | { 14 | DistDecrypt dd(P, share, pk, m.get_field()); 15 | Reshare(m, cc, cm, NewCiphertext, P, EC, pk, dd); 16 | } 17 | 18 | template 19 | void Reshare(Plaintext& m,Ciphertext& cc, 20 | const Ciphertext& cm,bool NewCiphertext, 21 | const Player& P,EncCommitBase& EC, 22 | const FHE_PK& pk,DistDecrypt& dd) 23 | { 24 | const FHE_Params& params=pk.get_params(); 25 | 26 | // Step 1 27 | Ciphertext cf(params); 28 | Plaintext_& f = dd.f; 29 | EC.next(f,cf); 30 | 31 | // Step 2 32 | // We could be resharing a level 0 ciphertext so adjust if we are 33 | if (cm.level()==0) { cf.Scale(m.get_field().get_prime()); } 34 | Ciphertext cmf(params); 35 | add(cmf,cf,cm); 36 | 37 | // Step 3 38 | Plaintext_& mf = dd.mf; 39 | dd.run(cmf, NewCiphertext); 40 | 41 | // Step 4 42 | if (P.my_num()==0) 43 | { sub(m,mf,f); } 44 | else 45 | { m=f; m.negate(); } 46 | 47 | // Step 5 48 | if (NewCiphertext) 49 | { unsigned char sd[SEED_SIZE] = { 0 }; 50 | PRNG G; 51 | G.SetSeed(sd); 52 | Random_Coins rc(params); 53 | rc.generate(G); 54 | pk.encrypt(cc,mf,rc); 55 | // And again 56 | if (cf.level()==0) { cc.Scale(m.get_field().get_prime()); } 57 | sub(cc,cc,cf); 58 | } 59 | } 60 | 61 | 62 | 63 | 64 | template void Reshare(Plaintext& m,Ciphertext& cc, 65 | const Ciphertext& cm,bool NewCiphertext, 66 | const Player& P,EncCommitBase& EC, 67 | const FHE_PK& pk,DistDecrypt& dd); 68 | 69 | template void Reshare(Plaintext& m,Ciphertext& cc, 70 | const Ciphertext& cm,bool NewCiphertext, 71 | const Player& P,EncCommitBase& EC, 72 | const FHE_PK& pk,DistDecrypt& dd); 73 | 74 | 75 | template void Reshare(Plaintext& m,Ciphertext& cc, 76 | const Ciphertext& cm,bool NewCiphertext, 77 | const Player& P,EncCommitBase& EC, 78 | const FHE_PK& pk,const FHE_SK& share); 79 | 80 | template void Reshare(Plaintext& m,Ciphertext& cc, 81 | const Ciphertext& cm,bool NewCiphertext, 82 | const Player& P,EncCommitBase& EC, 83 | const FHE_PK& pk,const FHE_SK& share); 84 | 85 | 86 | -------------------------------------------------------------------------------- /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/Sacrificing.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * Checking.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_CHECKING_H_ 9 | #define FHEOFFLINE_CHECKING_H_ 10 | 11 | #include "Networking/Player.h" 12 | #include "Auth/MAC_Check.h" 13 | #include "Math/Setup.h" 14 | 15 | template 16 | class TripleSacriFactory 17 | { 18 | public: 19 | virtual ~TripleSacriFactory() {} 20 | virtual void get(T& a, T& b, T& c) = 0; 21 | }; 22 | 23 | template 24 | class TupleSacriFactory 25 | { 26 | public: 27 | virtual ~TupleSacriFactory() {} 28 | virtual void get(T& a, T& b) = 0; 29 | }; 30 | 31 | template 32 | class SingleSacriFactory 33 | { 34 | public: 35 | virtual ~SingleSacriFactory() {} 36 | virtual void get(T& a) = 0; 37 | }; 38 | 39 | template 40 | class FileSacriFactory : public TripleSacriFactory, 41 | public TupleSacriFactory, public SingleSacriFactory 42 | { 43 | ifstream inpf; 44 | 45 | public: 46 | FileSacriFactory(const char* type, const Player& P, int output_thread); 47 | void get(T& a, T& b, T& c); 48 | void get(T& a, T& b); 49 | void get(T& a); 50 | }; 51 | 52 | void Triple_Inverse_Checking(const Player& P, MAC_Check& MC, int nm, 53 | int nr, int output_thread = 0); 54 | template 55 | void Triple_Checking(const Player& P, MAC_Check& MC, int nm, 56 | int output_thread, TripleSacriFactory >& factory, 57 | bool write_output = true, bool clear = true, string dir = PREP_DIR); 58 | template 59 | void Inverse_Checking(const Player& P, MAC_Check& MC, int nr, 60 | int output_thread, TripleSacriFactory >& triple_factory, 61 | TupleSacriFactory >& inverse_factor, 62 | bool write_output = true, bool clear = true, string dir = PREP_DIR); 63 | void Triple_Checking(const Player& P,MAC_Check& MC,int nm); 64 | void Square_Bit_Checking(const Player& P,MAC_Check& MC,int ns,int nb); 65 | template 66 | void Square_Checking(const Player& P, MAC_Check& MC, int ns, 67 | int output_thread, TupleSacriFactory >& factory, 68 | bool write_output = true, bool clear = true, string dir = PREP_DIR); 69 | void Bit_Checking(const Player& P, MAC_Check& MC, int nb, 70 | int output_thread, TupleSacriFactory >& square_factory, 71 | SingleSacriFactory >& bit_factory, bool write_output = true, 72 | bool clear = true, string dir = PREP_DIR); 73 | void Square_Checking(const Player& P,MAC_Check& MC,int ns); 74 | 75 | template 76 | inline string file_completion(const T& dummy = {}) 77 | { 78 | (void)dummy; 79 | return { T::type_char() }; 80 | } 81 | 82 | #endif /* FHEOFFLINE_CHECKING_H_ */ 83 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /FHEOffline/SimpleGenerator.h: -------------------------------------------------------------------------------- 1 | // (C) 2018 University of Bristol. See License.txt 2 | 3 | /* 4 | * SimpleThread.h 5 | * 6 | */ 7 | 8 | #ifndef FHEOFFLINE_SIMPLEGENERATOR_H_ 9 | #define FHEOFFLINE_SIMPLEGENERATOR_H_ 10 | 11 | #include "Networking/Player.h" 12 | #include "FHEOffline/SimpleEncCommit.h" 13 | #include "FHEOffline/DataSetup.h" 14 | #include "FHEOffline/Producer.h" 15 | #include "FHEOffline/SimpleDistDecrypt.h" 16 | #include "Processor/Data_Files.h" 17 | 18 | class SimpleMachine; 19 | class MultiplicativeMachine; 20 | 21 | class GeneratorBase 22 | { 23 | protected: 24 | int thread_num; 25 | 26 | public: 27 | Player P; 28 | pthread_t thread; 29 | long long total; 30 | 31 | map timers; 32 | 33 | GeneratorBase(int thread_num, const Names& N) : 34 | thread_num(thread_num), P(N, thread_num << 16), thread(0), total(0) {} 35 | virtual ~GeneratorBase() {} 36 | virtual void run() = 0; 37 | virtual size_t report_size(ReportType type) = 0; 38 | virtual void report_size(ReportType type, MemoryUsage& res) = 0; 39 | virtual size_t report_sent() = 0; 40 | 41 | int get_thread_num() const { return thread_num; } 42 | }; 43 | 44 | template