diff --git a/Compiler/instructions.py b/Compiler/instructions.py index e50bc9fd..c2aa7668 100644 --- a/Compiler/instructions.py +++ b/Compiler/instructions.py @@ -1204,7 +1204,7 @@ class randoms(base.Instruction): field_type = 'modp' @base.vectorize -class randomfulls(base.Instruction): +class randomfulls(base.DataInstruction): """ Store share(s) of a fresh secret random element in secret register (vectors). @@ -1214,6 +1214,10 @@ class randomfulls(base.Instruction): code = base.opcodes['RANDOMFULLS'] arg_format = ['sw'] field_type = 'modp' + data_type = 'random' + + def get_repeat(self): + return len(self.args) @base.gf2n @base.vectorize @@ -1511,8 +1515,8 @@ class inputpersonal(personal_base): code = base.opcodes['INPUTPERSONAL'] arg_format = tools.cycle(['int','p','sw','c']) -class privateoutput(personal_base): - """ Private input from cint. +class privateoutput(personal_base, base.DataInstruction): + """ Private output to cint. :param: vector size (int) :param: player (int) @@ -1523,6 +1527,14 @@ class privateoutput(personal_base): __slots__ = [] code = base.opcodes['PRIVATEOUTPUT'] arg_format = tools.cycle(['int','p','cw','s']) + data_type = 'open' + + def add_usage(self, req_node): + personal_base.add_usage(self, req_node) + base.DataInstruction.add_usage(self, req_node) + + def get_repeat(self): + return sum(self.args[::4]) class sendpersonal(base.Instruction, base.Mergeable): """ Private input from cint. @@ -2202,7 +2214,7 @@ class gconvgf2n(base.Instruction): # rename 'open' to avoid conflict with built-in open function @base.gf2n @base.vectorize -class asm_open(base.VarArgsInstruction): +class asm_open(base.VarArgsInstruction, base.DataInstruction): """ Reveal secret registers (vectors) to clear registers (vectors). :param: number of argument to follow (odd number) @@ -2214,6 +2226,10 @@ class asm_open(base.VarArgsInstruction): __slots__ = [] code = base.opcodes['OPEN'] arg_format = tools.chain(['int'], tools.cycle(['cw','s'])) + data_type = 'open' + + def get_repeat(self): + return (len(self.args) - 1) // 2 def merge(self, other): self.args[0] |= other.args[0] diff --git a/Compiler/program.py b/Compiler/program.py index 03232f18..9860053f 100644 --- a/Compiler/program.py +++ b/Compiler/program.py @@ -31,6 +31,8 @@ data_types = dict( inverse=3, dabit=4, mixed=5, + random=6, + open=7, ) field_types = dict( diff --git a/GC/ShareSecret.h b/GC/ShareSecret.h index bdf6c903..5114bdef 100644 --- a/GC/ShareSecret.h +++ b/GC/ShareSecret.h @@ -127,6 +127,7 @@ public: static const bool variable_players = false; static const bool needs_ot = false; static const bool has_mac = false; + static const bool randoms_for_opens = false; static string type_string() { return "replicated secret"; } static string phase_name() { return "Replicated computation"; } diff --git a/GC/TinySecret.h b/GC/TinySecret.h index 85098d18..b9c03776 100644 --- a/GC/TinySecret.h +++ b/GC/TinySecret.h @@ -51,6 +51,7 @@ public: static const bool needs_ot = T::needs_ot; static const bool has_mac = T::has_mac; static const bool expensive_triples = false; + static const bool randoms_for_opens = false; static const int default_length = 64; diff --git a/Math/field_types.h b/Math/field_types.h index 052cc40a..32c35989 100644 --- a/Math/field_types.h +++ b/Math/field_types.h @@ -17,6 +17,8 @@ enum Dtype DATA_INVERSE, DATA_DABIT, DATA_MIXED, + DATA_RANDOM, + DATA_OPEN, N_DTYPE, }; diff --git a/Math/gf2n.h b/Math/gf2n.h index c44f9c0e..5b7b06a4 100644 --- a/Math/gf2n.h +++ b/Math/gf2n.h @@ -84,7 +84,7 @@ protected: static int length() { return n == 0 ? MAX_N_BITS : n; } - static bool allows(Dtype type) { (void) type; return true; } + static bool allows(Dtype type) { return type <= DATA_INVERSE; } static string options(); diff --git a/Math/gfp.hpp b/Math/gfp.hpp index 33ea972c..3387f7ae 100644 --- a/Math/gfp.hpp +++ b/Math/gfp.hpp @@ -172,9 +172,9 @@ void gfp_::reqbl(int n) } template -bool gfp_::allows(Dtype) +bool gfp_::allows(Dtype type) { - return true; + return type <= DATA_INVERSE; } template diff --git a/Processor/Data_Files.h b/Processor/Data_Files.h index 6f6c5727..7f8a49bf 100644 --- a/Processor/Data_Files.h +++ b/Processor/Data_Files.h @@ -165,6 +165,8 @@ public: virtual T get_bit(); /// Get fresh random value in domain virtual T get_random(); + virtual T get_random_for_open(); + virtual T get_random_no_count(); /// Store fresh daBit in ``a`` (arithmetic part) and ``b`` (binary part) virtual void get_dabit(T& a, typename T::bit_type& b); virtual void get_dabit_no_count(T&, typename T::bit_type&) { throw runtime_error("no daBit"); } @@ -226,6 +228,8 @@ public: static string get_edabit_filename(const Names& N, int n_bits, int thread_num = -1); + static long additional_inputs(const DataPositions& usage); + Sub_Data_Files(int my_num, int num_players, const string& prep_data_dir, DataPositions& usage, int thread_num = -1); Sub_Data_Files(const Names& N, DataPositions& usage, int thread_num = -1); @@ -421,6 +425,21 @@ T Preprocessing::get_bit() template T Preprocessing::get_random() +{ + count(DATA_RANDOM); + return get_random_no_count(); +} + +template +T Preprocessing::get_random_for_open() +{ + assert(T::randoms_for_opens); + count(DATA_OPEN); + return get_random_no_count(); +} + +template +T Preprocessing::get_random_no_count() { assert(not usage.inputs.empty()); return get_random_from_inputs(usage.inputs.size()); diff --git a/Processor/Data_Files.hpp b/Processor/Data_Files.hpp index 5fe49f39..b42d2f76 100644 --- a/Processor/Data_Files.hpp +++ b/Processor/Data_Files.hpp @@ -187,6 +187,16 @@ Sub_Data_Files::~Sub_Data_Files() delete part; } +template +long Sub_Data_Files::additional_inputs(const DataPositions& usage) +{ + auto& domain_usage = usage.files[T::clear::field_type()]; + long add_to_inputs = domain_usage[DATA_RANDOM]; + if (T::randoms_for_opens) + add_to_inputs += domain_usage[DATA_OPEN]; + return add_to_inputs; +} + template void Sub_Data_Files::seekg(DataPositions& pos) { @@ -203,11 +213,15 @@ void Sub_Data_Files::seekg(DataPositions& pos) for (int dtype = 0; dtype < N_DTYPE; dtype++) if (T::clear::allows(Dtype(dtype))) buffers[dtype].seekg(pos.files[field_type][dtype]); + + long add_to_inputs = additional_inputs(pos); + for (int j = 0; j < num_players; j++) if (j == my_num) - my_input_buffers.seekg(pos.inputs[j][field_type]); + my_input_buffers.seekg(pos.inputs[j][field_type] + add_to_inputs); else - input_buffers[j].seekg(pos.inputs[j][field_type]); + input_buffers[j].seekg(pos.inputs[j][field_type] + add_to_inputs); + for (map::const_iterator it = pos.extended[field_type].begin(); it != pos.extended[field_type].end(); it++) { diff --git a/Processor/OfflineMachine.hpp b/Processor/OfflineMachine.hpp index a699a9d8..98359a49 100644 --- a/Processor/OfflineMachine.hpp +++ b/Processor/OfflineMachine.hpp @@ -111,7 +111,7 @@ void OfflineMachine::generate() dabit(a, b).output(out, false); } } - else + else if (not (i == DATA_RANDOM or i == DATA_OPEN)) { vector tuple(DataPositions::tuple_size[i]); for (long long j = 0; @@ -127,9 +127,12 @@ void OfflineMachine::generate() remove(filename.c_str()); } + long additional_inputs = Sub_Data_Files::additional_inputs(usage); + for (int i = 0; i < P.num_players(); i++) { - auto n_inputs = usage.inputs[i][T::clear::field_type()]; + auto n_inputs = usage.inputs[i][T::clear::field_type()] + + additional_inputs; string filename = Sub_Data_Files::get_input_filename(playerNames, i, 0); if (n_inputs > 0) { diff --git a/Protocols/MAC_Check.hpp b/Protocols/MAC_Check.hpp index fe6a0108..0866765f 100644 --- a/Protocols/MAC_Check.hpp +++ b/Protocols/MAC_Check.hpp @@ -265,7 +265,7 @@ W MAC_Check_Z2k::get_random_element() { else { if (prep) - return prep->get_random(); + return prep->get_random_for_open(); else { insecure("random dummy"); diff --git a/Protocols/ShareInterface.h b/Protocols/ShareInterface.h index c168a464..3182b1c0 100644 --- a/Protocols/ShareInterface.h +++ b/Protocols/ShareInterface.h @@ -48,6 +48,8 @@ public: static const bool is_real = true; + static const bool randoms_for_opens = false; + static const int default_length = 1; static string type_short() { throw runtime_error("shorthand undefined"); } diff --git a/Protocols/Spdz2kShare.h b/Protocols/Spdz2kShare.h index b6270a87..82be3c38 100644 --- a/Protocols/Spdz2kShare.h +++ b/Protocols/Spdz2kShare.h @@ -63,6 +63,8 @@ public: const static int k = K; const static int s = S; + const static bool randoms_for_opens = true; + static string type_string() { return "SPDZ2^(" + to_string(K) + "+" + to_string(S) + ")"; } static string type_short() { return "Z" + to_string(K) + "," + to_string(S); } diff --git a/Tools/names.cpp b/Tools/names.cpp index 220263c8..f81995c9 100644 --- a/Tools/names.cpp +++ b/Tools/names.cpp @@ -2,4 +2,4 @@ const char* DataPositions::dtype_names[N_DTYPE + 1] = { "Triples", "Squares", "Bits", "Inverses", - "daBits", "Mixed triples", "None" }; + "daBits", "Mixed triples", "Randoms", "Opens", "None" };