diff --git a/BMR/Party.cpp b/BMR/Party.cpp index 6cdbc83de..a7275c0de 100644 --- a/BMR/Party.cpp +++ b/BMR/Party.cpp @@ -31,7 +31,6 @@ #include "GC/Thread.hpp" #include "GC/ThreadMaster.hpp" #include "GC/Program.hpp" -#include "GC/Instruction.hpp" #include "Processor/Instruction.hpp" #include "Protocols/Share.hpp" diff --git a/BMR/RealProgramParty.hpp b/BMR/RealProgramParty.hpp index 7872ec526..ac5f17d22 100644 --- a/BMR/RealProgramParty.hpp +++ b/BMR/RealProgramParty.hpp @@ -17,7 +17,6 @@ #include "GC/Machine.hpp" #include "GC/Processor.hpp" #include "GC/Program.hpp" -#include "GC/Instruction.hpp" #include "GC/Secret.hpp" #include "GC/Thread.hpp" #include "GC/ThreadMaster.hpp" @@ -113,6 +112,7 @@ RealProgramParty::RealProgramParty(int argc, const char** argv) : garble_processor.reset(program); this->processor.open_input_file(N.my_num(), 0); + T::bit_type::mac_key_type::init_field(); GC::ShareThread share_thread(N, online_opts, *P, 0, usage); shared_proc = new SubProcessor(dummy_proc, *MC, *prep, *P); diff --git a/BMR/Register.hpp b/BMR/Register.hpp index fe9c44e61..e4f743cb1 100644 --- a/BMR/Register.hpp +++ b/BMR/Register.hpp @@ -56,7 +56,7 @@ void EvalRegister::store_clear_in_dynamic(GC::Memory& mem, T& dest = mem[access.address]; GC::Clear value = access.value; ProgramParty& party = ProgramParty::s(); - dest.assign(value.get(), party.get_id() - 1, party.get_mac_key().get()); + dest = T::constant(value.get(), party.get_id() - 1, party.get_mac_key().get()); #ifdef DEBUG_DYNAMIC cout << "store clear " << dest.share << " " << dest.mac << " " << value << endl; #endif @@ -105,7 +105,7 @@ void EvalRegister::store(GC::Memory& mem, U tmp; gf2n_long ext = (int)reg.get_external(); //cout << "ext:" << ext << "/" << (int)reg.get_external() << " " << endl; - tmp.add(spdz_wire.mask, ext, (int)party.get_id() - 1, party.get_mac_key()); + tmp = spdz_wire.mask + U::constant(ext, (int)party.get_id() - 1, party.get_mac_key()); S.push_back(tmp); tmp *= gf2n_long(1) << i; dest += tmp; diff --git a/BMR/TrustedParty.cpp b/BMR/TrustedParty.cpp index ae701549e..6bd1ba264 100644 --- a/BMR/TrustedParty.cpp +++ b/BMR/TrustedParty.cpp @@ -28,7 +28,6 @@ #include "GC/Thread.hpp" #include "GC/ThreadMaster.hpp" #include "GC/Program.hpp" -#include "GC/Instruction.hpp" #include "GC/ShareSecret.hpp" #include "Processor/Instruction.hpp" #include "Protocols/Share.hpp" diff --git a/CHANGELOG.md b/CHANGELOG.md index 78748b74a..6416d68d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ The changelog explains changes pulled through from the private development repository. Bug fixes and small enhancements are committed between releases and not documented here. +## 0.2.2 (Jan 21, 2020) + +- Infrastructure for random element generation +- Programs generating as much preprocessing data as required by a particular high-level program +- Smaller binaries +- Cleaning up code +- Removing unused virtual machine instructions +- Fixed security bug: wrong MAC check in SPDZ2k input tuple generation + ## 0.2.1 (Dec 11, 2020) - Virtual machines automatically use the modulus used during compilation @@ -14,9 +23,9 @@ The changelog explains changes pulled through from the private development repos - Training and inference for multi-class classification - Local share conversion for semi-honest protocols based on additive secret sharing modulo a power of two - edaBit generation based on local share conversion -- Optimize exponentation with local share conversion +- Optimize exponentiation with local share conversion - Optimize Shamir pseudo-random secret sharing using a hyper-invertible matrix -- Mathematical functions (exponentation, logarithm, square root, and trigonometric functions) with binary circuits +- Mathematical functions (exponentiation, logarithm, square root, and trigonometric functions) with binary circuits - Direct construction of fixed-point values from any type, breaking `sfix(x)` where `x` is the integer representation of a fixed-point number. Use `sfix._new(x)` instead. - Optimized dot product for `sfix` - Matrix multiplication via operator overloading uses VM-optimized multiplication. @@ -70,7 +79,7 @@ The changelog explains changes pulled through from the private development repos - Mixed circuit computation with secret sharing - Binary computation for dishonest majority using secret sharing as in [FKOS15](https://eprint.iacr.org/2015/901) - Fixed security bug: insufficient OT correlation check in SPDZ2k -- This version breaks bytecode compatibilty. +- This version breaks bytecode compatibility. ## 0.1.3 (Nov 21, 2019) @@ -133,7 +142,7 @@ The changelog explains changes pulled through from the private development repos ## 0.0.4 (Oct 11, 2018) - Added BMR, Yao's garbled circuits, and semi-honest 3-party replicated secret sharing for arithmetic and binary circuits. -- Use inline assembly instead of MPIR for arithmetic modulo primes up length upt to 128 bit. +- Use inline assembly instead of MPIR for arithmetic modulo primes up length up to 128 bit. - Added a secure multiplication instruction to the instruction set in order to accommodate protocols that don't use Beaver randomization. ## 0.0.3 (Mar 2, 2018) diff --git a/Compiler/allocator.py b/Compiler/allocator.py index 0ff79329e..ddaaecc3f 100644 --- a/Compiler/allocator.py +++ b/Compiler/allocator.py @@ -483,10 +483,6 @@ def keep_merged_order(instr, n, t): print("Processed dependency of %d/%d instructions at" % \ (n, len(block.instructions)), time.asctime()) - if len(open_nodes) > 1000 and self.block.parent.program.verbose: - print("Basic block has %d %s instructions" % - (len(open_nodes), merge_classes)) - def merge_nodes(self, i, j): """ Merge node j into i, removing node j """ G = self.G diff --git a/Compiler/floatingpoint.py b/Compiler/floatingpoint.py index c720ce914..570d54597 100644 --- a/Compiler/floatingpoint.py +++ b/Compiler/floatingpoint.py @@ -288,18 +288,8 @@ def BitDecFieldRaw(a, k, m, kappa, bits_to_compute=None): c = types.cint() r = [types.sint() for i in range(m)] comparison.PRandM(r_dprime, r_prime, r, k, m, kappa) - #assert(r_prime.value == sum(r[i].value*2**i for i in range(m)) % comparison.program.P) pow2 = two_power(k + kappa) asm_open(c, pow2 + two_power(k) + a - two_power(m)*r_dprime - r_prime) - #rval = 2**m*r_dprime.value + r_prime.value - #assert(rval % 2**m == r_prime.value) - #assert(rval == (2**m*r_dprime.value + sum(r[i].value*2**i for i in range(m)) % comparison.program.P )) - try: - pass#assert(c.value == (2**(k + kappa) + 2**k + (a.value%2**k) - rval) % comparison.program.P) - except AssertionError: - print('BitDec assertion failed') - print('a =', a.value) - print('a mod 2^%d =' % k, (a.value % 2**k)) res = r[0].bit_adder(r, list(r[0].bit_decompose_clear(c,m))) return res @@ -328,7 +318,6 @@ def B2U(a, l, kappa): return B2U_from_Pow2(pow2a, l, kappa), pow2a def B2U_from_Pow2(pow2a, l, kappa): - #assert(pow2a.value == 2**a.value) r = [types.sint() for i in range(l)] t = types.sint() c = types.cint() @@ -354,8 +343,10 @@ def B2U_from_Pow2(pow2a, l, kappa): #print ' '.join(str(b.value) for b in y) return [types.sint.conv(1 - y[i]) for i in range(l)] -def Trunc(a, l, m, kappa, compute_modulo=False, signed=False): +def Trunc(a, l, m, kappa=None, compute_modulo=False, signed=False): """ Oblivious truncation by secret m """ + prog = program.Program.prog + kappa = kappa or prog.security if util.is_constant(m) and not compute_modulo: # cheaper res = type(a)(size=a.size) @@ -376,28 +367,22 @@ def Trunc(a, l, m, kappa, compute_modulo=False, signed=False): ci = [types.cint() for i in range(l)] d = types.sint() x, pow2m = B2U(m, l, kappa) - #assert(pow2m.value == 2**m.value) - #assert(sum(b.value for b in x) == m.value) for i in range(l): bit(r[i]) t1 = two_power(i) * r[i] t2 = t1*x[i] r_prime += t2 r_dprime += t1 - t2 - #assert(r_prime.value == (sum(2**i*x[i].value*r[i].value for i in range(l)) % comparison.program.P)) if program.Program.prog.options.ring: n_shift = int(program.Program.prog.options.ring) - l c = ((a + r_dprime + r_prime) << n_shift).reveal() >> n_shift else: comparison.PRandInt(rk, kappa) r_dprime += two_power(l) * rk - #assert(r_dprime.value == (2**l * rk.value + sum(2**i*(1 - x[i].value)*r[i].value for i in range(l)) % comparison.program.P)) asm_open(c, a + r_dprime + r_prime) for i in range(1,l): ci[i] = c % two_power(i) - #assert(ci[i].value == c.value % 2**i) c_dprime = sum(ci[i]*(x[i-1] - x[i]) for i in range(1,l)) - #assert(c_dprime.value == (sum(ci[i].value*(x[i-1].value - x[i].value) for i in range(1,l)) % comparison.program.P)) lts(d, c_dprime, r_prime, l, kappa) if compute_modulo: b = c_dprime - r_prime + pow2m * d @@ -408,7 +393,6 @@ def Trunc(a, l, m, kappa, compute_modulo=False, signed=False): shifted = TruncInRing(to_shift, l, pow2m) else: pow2inv = Inv(pow2m) - #assert(pow2inv.value * pow2m.value % comparison.program.P == 1) shifted = to_shift * pow2inv b = shifted - d return b diff --git a/Compiler/instructions.py b/Compiler/instructions.py index b91b190b0..9a03069d4 100644 --- a/Compiler/instructions.py +++ b/Compiler/instructions.py @@ -256,27 +256,6 @@ class gstmsi(base.WriteMemoryInstruction, base.IndirectMemoryInstruction): arg_format = ['sg','ci'] direct = staticmethod(gstms) -@base.gf2n -@base.vectorize -class protectmems(base.Instruction): - r""" Protects secret memory range $[ci_i,ci_j)$. """ - code = base.opcodes['PROTECTMEMS'] - arg_format = ['ci','ci'] - -@base.gf2n -@base.vectorize -class protectmemc(base.Instruction): - r""" Protects clear memory range $[ci_i,ci_j)$. """ - code = base.opcodes['PROTECTMEMC'] - arg_format = ['ci','ci'] - -@base.gf2n -@base.vectorize -class protectmemint(base.Instruction): - r""" Protects integer memory range $[ci_i,ci_j)$. """ - code = base.opcodes['PROTECTMEMINT'] - arg_format = ['ci','ci'] - @base.gf2n @base.vectorize class movc(base.Instruction): @@ -1177,6 +1156,18 @@ class randoms(base.Instruction): arg_format = ['sw','int'] field_type = 'modp' +@base.vectorize +class randomfulls(base.Instruction): + """ Store share(s) of a fresh secret random element in secret + register (vectors). + + :param: destination (sint) + """ + __slots__ = [] + code = base.opcodes['RANDOMFULLS'] + arg_format = ['sw'] + field_type = 'modp' + @base.gf2n @base.vectorize class square(base.DataInstruction): @@ -1415,14 +1406,6 @@ def add_usage(self, req_node): req_node.increment((self.field_type, 'input', player), \ self.get_size()) -@base.gf2n -@base.vectorize -class print_mem(base.IOInstruction): - r""" Print value in clear memory \verb|C[ci]| to stdout. """ - __slots__ = [] - code = base.opcodes['PRINTMEM'] - arg_format = ['c'] - @base.gf2n @base.vectorize class print_reg(base.IOInstruction): @@ -1527,18 +1510,6 @@ class cond_print_str(base.IOInstruction): def __init__(self, cond, val): super(cond_print_str, self).__init__(cond, self.str_to_int(val)) -@base.vectorize -class print_char_regint(base.IOInstruction): - r""" Print register $ci_i$ as a single character to stdout. """ - code = base.opcodes['PRINTCHRINT'] - arg_format = ['ci'] - -@base.vectorize -class print_char4_regint(base.IOInstruction): - r""" Print register $ci_i$ as a four character string to stdout. """ - code = base.opcodes['PRINTSTRINT'] - arg_format = ['ci'] - @base.vectorize class pubinput(base.PublicFileIOInstruction): """ Store public input in clear integer register (vector). @@ -1717,6 +1688,11 @@ class startprivateoutput(base.Instruction): __slots__ = [] code = base.opcodes['STARTPRIVATEOUTPUT'] arg_format = ['sw','s','p'] + field_type = 'modp' + + def add_usage(self, req_node): + req_node.increment((self.field_type, 'input', self.args[2]), \ + self.get_size()) @base.gf2n @base.vectorize diff --git a/Compiler/instructions_base.py b/Compiler/instructions_base.py index b3f879b18..b5e071c7c 100644 --- a/Compiler/instructions_base.py +++ b/Compiler/instructions_base.py @@ -112,6 +112,7 @@ EDABIT = 0x59, SEDABIT = 0x5A, RANDOMS = 0x5B, + RANDOMFULLS = 0x5D, # Input INPUT = 0x60, INPUTFIX = 0xF0, diff --git a/Compiler/library.py b/Compiler/library.py index 4c9c7fcc7..806415b70 100644 --- a/Compiler/library.py +++ b/Compiler/library.py @@ -1511,7 +1511,7 @@ def break_point(name=''): # Fixed point ops from math import ceil, log -from .floatingpoint import PreOR, TruncPr, two_power, shift_two +from .floatingpoint import PreOR, TruncPr, two_power def approximate_reciprocal(divisor, k, f, theta): """ @@ -1599,7 +1599,6 @@ def sint_cint_division(a, b, k, f, kappa): B = absolute_b W = w0 - @for_range(1, theta) def block(i): A.link(TruncPr(A * W, 2*k, f, kappa)) diff --git a/Compiler/mpc_math.py b/Compiler/mpc_math.py index 3508b63b4..76df9f408 100644 --- a/Compiler/mpc_math.py +++ b/Compiler/mpc_math.py @@ -393,7 +393,7 @@ class my_fix(type(a)): @types.vectorize @instructions_base.sfix_cisc -def log2_fx(x, use_division=False): +def log2_fx(x, use_division=True): """ Returns the result of :math:`\log_2(x)` for any unbounded number. This is achieved by changing :py:obj:`x` into diff --git a/Compiler/types.py b/Compiler/types.py index ffdfee87c..cfe8b11e8 100644 --- a/Compiler/types.py +++ b/Compiler/types.py @@ -614,12 +614,6 @@ class _clear(_register): __slots__ = [] mov = staticmethod(movc) - @vectorized_classmethod - @set_instruction_type - def protect_memory(cls, start, end): - program.curr_tape.start_new_basicblock(name='protect-memory') - protectmemc(regint(start), regint(end)) - @set_instruction_type @vectorize def load_other(self, val): @@ -1140,11 +1134,6 @@ class regint(_register, _int): instruction_type = 'modp' mov = staticmethod(movint) - @classmethod - def protect_memory(cls, start, end): - program.curr_tape.start_new_basicblock(name='protect-memory') - protectmemint(regint(start), regint(end)) - @vectorized_classmethod def load_mem(cls, address, mem_type=None): """ Load from memory by public address. """ @@ -1530,12 +1519,6 @@ class _secret(_register): PreOR = staticmethod(lambda l: floatingpoint.PreORC(l)) PreOp = staticmethod(lambda op, l: floatingpoint.PreOpL(op, l)) - @vectorized_classmethod - @set_instruction_type - def protect_memory(cls, start, end): - program.curr_tape.start_new_basicblock(name='protect-memory') - protectmems(regint(start), regint(end)) - @vectorized_classmethod @set_instruction_type def get_input_from(cls, player): @@ -1831,6 +1814,13 @@ def get_random_int(cls, bits): comparison.PRandInt(res, bits) return res + @vectorized_classmethod + def get_random(cls): + """ Secret random ring element according to security model. """ + res = sint() + randomfulls(res) + return res + @vectorized_classmethod def get_input_from(cls, player): """ Secret input. @@ -3197,6 +3187,8 @@ class _single(_number, _structure): __slots__ = ['v'] kappa = None round_nearest = False + """ Whether to round deterministically to nearest instead of + probabilistically, e.g. after fixed-point multiplication. """ @classmethod def receive_from_client(cls, n, client_id, message_type=ClientMessageType.NoType): diff --git a/ECDSA/Fake-ECDSA.cpp b/ECDSA/Fake-ECDSA.cpp index c27c23e70..23f81b9ef 100644 --- a/ECDSA/Fake-ECDSA.cpp +++ b/ECDSA/Fake-ECDSA.cpp @@ -10,6 +10,7 @@ #include "Protocols/fake-stuff.hpp" #include "Protocols/Share.hpp" #include "Processor/Data_Files.hpp" +#include "Math/gfp.hpp" int main() { diff --git a/ECDSA/P256Element.cpp b/ECDSA/P256Element.cpp index 0d4f5cf1c..4a4c2e382 100644 --- a/ECDSA/P256Element.cpp +++ b/ECDSA/P256Element.cpp @@ -86,9 +86,7 @@ P256Element& P256Element::operator +=(const P256Element& other) P256Element& P256Element::operator /=(const Scalar& other) { - auto tmp = other; - tmp.invert(); - *this = *this * tmp; + *this = *this * other.invert(); return *this; } diff --git a/ECDSA/P256Element.h b/ECDSA/P256Element.h index 4c335b8b7..6263c49fb 100644 --- a/ECDSA/P256Element.h +++ b/ECDSA/P256Element.h @@ -27,6 +27,8 @@ class P256Element : public ValueInterface typedef void next; typedef void Square; + static const true_type invertible; + static int size() { return 0; } static string type_string() { return "P256"; } @@ -55,10 +57,6 @@ class P256Element : public ValueInterface void assign_zero() { *this = 0; } bool is_zero() { return *this == 0; } - void add(const P256Element& x, const P256Element& y) { *this = x + y; } - void sub(const P256Element& x, const P256Element& y) { *this = x - y; } - void mul(const P256Element& x, const Scalar& y) { *this = x * y; } - void mul(const Scalar& x, const P256Element& y) { *this = y * x; } void add(octetStream& os) { *this += os.get(); } void pack(octetStream& os) const; diff --git a/ECDSA/hm-ecdsa-party.hpp b/ECDSA/hm-ecdsa-party.hpp index c17a7ff12..d2648fe13 100644 --- a/ECDSA/hm-ecdsa-party.hpp +++ b/ECDSA/hm-ecdsa-party.hpp @@ -59,7 +59,7 @@ void run(int argc, const char** argv) OnlineOptions::singleton.batch_size = (1 + pShare::Protocol::uses_triples) * n_tuples; DataPositions usage; - auto& prep = *Preprocessing::get_live_prep(0, usage); + typename pShare::TriplePrep prep(0, usage); typename pShare::MAC_Check MCp; ArithmeticProcessor _({}, 0); SubProcessor proc(_, MCp, prep, P); @@ -69,6 +69,4 @@ void run(int argc, const char** argv) preprocessing(tuples, n_tuples, sk, proc, opts); // check(tuples, sk, {}, P); sign_benchmark(tuples, sk, MCp, P, opts, prep_mul ? 0 : &proc); - - delete &prep; } diff --git a/ECDSA/ot-ecdsa-party.hpp b/ECDSA/ot-ecdsa-party.hpp index 237b86500..9d86d589d 100644 --- a/ECDSA/ot-ecdsa-party.hpp +++ b/ECDSA/ot-ecdsa-party.hpp @@ -103,7 +103,7 @@ void run(int argc, const char** argv) OnlineOptions::singleton.batch_size = 1; typename pShare::Direct_MC MCp(keyp); ArithmeticProcessor _({}, 0); - typename pShare::LivePrep sk_prep(0, usage); + typename pShare::TriplePrep sk_prep(0, usage); GC::ShareThread thread(N, OnlineOptions::singleton, P, {}, usage); SubProcessor sk_proc(_, MCp, sk_prep, P); @@ -119,7 +119,7 @@ void run(int argc, const char** argv) (P.comm_stats - stats).print(true); OnlineOptions::singleton.batch_size = (1 + pShare::Protocol::uses_triples) * n_tuples; - typename pShare::LivePrep prep(0, usage); + typename pShare::TriplePrep prep(0, usage); prep.params.correlation_check &= not opt.isSet("-U"); prep.params.fewer_rounds = opt.isSet("-A"); prep.params.fiat_shamir = opt.isSet("-H"); diff --git a/ECDSA/preprocessing.hpp b/ECDSA/preprocessing.hpp index 4701e5882..fb9f6001c 100644 --- a/ECDSA/preprocessing.hpp +++ b/ECDSA/preprocessing.hpp @@ -121,8 +121,7 @@ void check(vector>& tuples, T sk, for (auto& tuple : tuples) { auto inv_k = MC.open(tuple.a, P); - auto k = inv_k; - k.invert(); + auto k = inv_k.invert(); assert(open_sk * inv_k == MC.open(tuple.b, P)); assert(tuple.R == k); } diff --git a/ECDSA/sign.hpp b/ECDSA/sign.hpp index 78d5322a2..10991276a 100644 --- a/ECDSA/sign.hpp +++ b/ECDSA/sign.hpp @@ -103,11 +103,9 @@ EcSignature sign(const unsigned char* message, size_t length, P256Element::Scala { EcSignature signature; auto k = SeededPRNG().get(); - auto inv_k = k; - inv_k.invert(); signature.R = k; auto rx = signature.R.x(); - signature.s = inv_k * (hash_to_scalar(message, length) + rx * sk); + signature.s = k.invert() * (hash_to_scalar(message, length) + rx * sk); return signature; } @@ -119,8 +117,7 @@ void check(EcSignature signature, const unsigned char* message, size_t length, timer.start(); signature.s.check(); signature.R.check(); - P256Element::Scalar w; - w.invert(signature.s); + auto w = signature.s.invert(); auto u1 = hash_to_scalar(message, length) * w; auto u2 = signature.R.x() * w; assert(P256Element(u1) + pk * u2 == signature.R); diff --git a/FHE/Ciphertext.cpp b/FHE/Ciphertext.cpp index d06194597..9afef83ce 100644 --- a/FHE/Ciphertext.cpp +++ b/FHE/Ciphertext.cpp @@ -1,7 +1,7 @@ #include "Ciphertext.h" #include "PPData.h" #include "P2Data.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Math/modp.hpp" diff --git a/FHE/FHE_Params.cpp b/FHE/FHE_Params.cpp index 59f548bc6..04b9299f7 100644 --- a/FHE/FHE_Params.cpp +++ b/FHE/FHE_Params.cpp @@ -1,7 +1,7 @@ #include "FHE_Params.h" #include "FHE/Ring_Element.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" void FHE_Params::set(const Ring& R, diff --git a/FHE/Matrix.cpp b/FHE/Matrix.cpp index 747cac3c9..c9c23aaba 100644 --- a/FHE/Matrix.cpp +++ b/FHE/Matrix.cpp @@ -1,6 +1,6 @@ #include "FHE/Matrix.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Math/modp.hpp" diff --git a/FHE/P2Data.cpp b/FHE/P2Data.cpp index 63f38b840..7d9a8ca47 100644 --- a/FHE/P2Data.cpp +++ b/FHE/P2Data.cpp @@ -42,7 +42,7 @@ void P2Data::backward(vector& ans,const vector& a) const int ii = i * n + n - 1 - j; y ^= (Ai[ii] & bv).parity(); } - ans[i].assign(y); + ans[i] = (y); } } diff --git a/FHE/Plaintext.cpp b/FHE/Plaintext.cpp index afdec58b3..81f4e0e2b 100644 --- a/FHE/Plaintext.cpp +++ b/FHE/Plaintext.cpp @@ -57,7 +57,7 @@ void Plaintext::from_poly() const if (type!=Polynomial) { return; } vector aa((*Field_Data).phi_m()); for (unsigned int i=0; i::generate_setup(int n_parties, int plaintext_length, int sec, template void PartSetup::fake(vector& sks, vector& alphais, - int nplayers, bool distributed) + int nplayers, bool distributed, bool check_security) { - insecure("global key generation"); + if (check_security) + insecure("global key generation"); if (distributed) cout << "Faking distributed key generation" << endl; else @@ -91,11 +92,11 @@ void PartSetup::fake(vector& sks, vector& alphais, template void PartSetup::fake(vector >& setups, int nplayers, - bool distributed) + bool distributed, bool check_security) { vector sks; vector alphais; - fake(sks, alphais, nplayers, distributed); + fake(sks, alphais, nplayers, distributed, check_security); setups.clear(); setups.resize(nplayers, *this); for (int i = 0; i < nplayers; i++) diff --git a/FHEOffline/DataSetup.h b/FHEOffline/DataSetup.h index 772ac2288..7b9a28457 100644 --- a/FHEOffline/DataSetup.h +++ b/FHEOffline/DataSetup.h @@ -38,8 +38,10 @@ class PartSetup void generate_setup(int n_parties, int plaintext_length, int sec, int slack, bool round_up); - void fake(vector& sks, vector& alphais, int nplayers, bool distributed = true); - void fake(vector >& setups, int nplayers, bool distributed = true); + void fake(vector& sks, vector& alphais, int nplayers, + bool distributed = true, bool check_security = true); + void fake(vector >& setups, int nplayers, + bool distributed = true, bool check_security = true); void insecure_debug_keys(vector >& setups, int nplayers, bool simple_pk); void pack(octetStream& os); diff --git a/FHEOffline/EncCommit.cpp b/FHEOffline/EncCommit.cpp index 208b2ceb9..ddd77d800 100644 --- a/FHEOffline/EncCommit.cpp +++ b/FHEOffline/EncCommit.cpp @@ -1,6 +1,6 @@ #include "Tools/Subroutines.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Tools/random.h" #include "EncCommit.h" diff --git a/FHEOffline/PairwiseSetup.cpp b/FHEOffline/PairwiseSetup.cpp index 649bd454a..b1eaad7ea 100644 --- a/FHEOffline/PairwiseSetup.cpp +++ b/FHEOffline/PairwiseSetup.cpp @@ -13,6 +13,9 @@ #include "Tools/Bundle.h" #include "Processor/OnlineOptions.h" +#include "Protocols/Share.hpp" +#include "Protocols/mac_key.hpp" + template void PairwiseSetup::init(const Player& P, int sec, int plaintext_length, int& extra_slack) @@ -21,7 +24,6 @@ void PairwiseSetup::init(const Player& P, int sec, int plaintext_length, << plaintext_length << endl; PRNG G; G.ReSeed(); - dirname = PREP_DIR; octetStream o; if (P.my_num() == 0) @@ -43,8 +45,8 @@ void PairwiseSetup::init(const Player& P, int sec, int plaintext_length, } alpha = FieldD; - alpha.randomize(G, Diagonal); - alphai = alpha.element(0); + alphai = read_or_generate_mac_key>(P); + alpha.assign_constant(alphai); } template diff --git a/FHEOffline/PairwiseSetup.h b/FHEOffline/PairwiseSetup.h index d8ec74ac3..61b4f20dc 100644 --- a/FHEOffline/PairwiseSetup.h +++ b/FHEOffline/PairwiseSetup.h @@ -27,7 +27,6 @@ class PairwiseSetup FD FieldD; typename FD::T alphai; Plaintext_ alpha; - string dirname; static string name() { diff --git a/FHEOffline/Producer.cpp b/FHEOffline/Producer.cpp index 362a42204..f573cc1c9 100644 --- a/FHEOffline/Producer.cpp +++ b/FHEOffline/Producer.cpp @@ -277,9 +277,7 @@ void InverseProducer::get(Share& a, Share& b) } TupleProducer::get(a, b); - T ab_inv; - ab_inv.invert(ab.element(i - 1)); - b.mul(b,ab_inv); + b /= ab.element(i - 1); } void gfpBitProducer::get(Share& a) @@ -394,9 +392,7 @@ void gfpBitProducer::run(const Player& P, const FHE_PK& pk, else { marks[i] = 0; - gfp temp; - temp.invert(s.element(i).sqrRoot()); - s.set_element(i, temp); + s.set_element(i, s.element(i).sqrRoot().invert()); } } Ciphertext cv(params); @@ -416,7 +412,7 @@ void gfpBitProducer::run(const Player& P, const FHE_PK& pk, gfp two_inv, zero; two_inv = bigint((dd.f.get_field().get_prime() + 1) / 2); zero.assign_zero(); - one.assign_one(); + auto shared_one = Share::constant(1, P.my_num(), alphai); bits.clear(); for (unsigned int i = 0; i < vi.num_slots(); i++) { @@ -425,7 +421,7 @@ void gfpBitProducer::run(const Player& P, const FHE_PK& pk, a.set_share(vi.element(i)); a.set_mac(gam_vi.element(i)); // Form (1/2)*a+1 - a.add(a, one, P.my_num(), alphai); + a += shared_one; a.mul(a, two_inv); bits.push_back(a); } diff --git a/FHEOffline/Sacrificing.cpp b/FHEOffline/Sacrificing.cpp index 3bd5cd255..dab3e507a 100644 --- a/FHEOffline/Sacrificing.cpp +++ b/FHEOffline/Sacrificing.cpp @@ -70,7 +70,7 @@ void Triple_Checking(const Player& P, MAC_Check& MC, int nm, temp.mul(b2[i],PO[2*i]); Sh_Tau[i].sub(Sh_Tau[i],temp); te = (PO[2*i] * PO[2*i+1]); - Sh_Tau[i].sub(Sh_Tau[i],te,P.my_num(),MC.get_alphai()); + Sh_Tau[i].sub(Sh_Tau[i], Share::constant(te,P.my_num(),MC.get_alphai())); } MC.POpen_Begin(Tau,Sh_Tau,P); MC.POpen_End(Tau,Sh_Tau,P); @@ -148,9 +148,11 @@ void Inverse_Checking(const Player& P, MAC_Check& MC, int nr, MC.POpen_Begin(PO,Sh_PO,P); MC.POpen_End(PO,Sh_PO,P); + auto t_shared = Share::constant(t, P.my_num(), MC.get_alphai()); + for (int i=0; i>(P); + Plaintext_ m(part_setup.FieldD); + m.assign_constant(part_setup.alphai); + vector C({part_setup.pk.encrypt(m)}); + TreeSum().run(C, P); + part_setup.calpha = C[0]; + if (output) part_setup.output(N); } diff --git a/GC/BitPrepFiles.h b/GC/BitPrepFiles.h new file mode 100644 index 000000000..0a406a461 --- /dev/null +++ b/GC/BitPrepFiles.h @@ -0,0 +1,38 @@ +/* + * BitPrepFiles.h + * + */ + +#ifndef GC_BITPREPFILES_H_ +#define GC_BITPREPFILES_H_ + +namespace GC +{ + +#include "ShiftableTripleBuffer.h" +#include "Processor/Data_Files.h" + +template +class BitPrepFiles : public ShiftableTripleBuffer, public Sub_Data_Files +{ +public: + BitPrepFiles(const Names& N, const string& prep_data_dir, + DataPositions& usage, int thread_num = -1) : + Sub_Data_Files(N, prep_data_dir, usage, thread_num) + { + } + + array get_triple_no_count(int n_bits) + { + return ShiftableTripleBuffer::get_triple_no_count(n_bits); + } + + void get(Dtype type, T* data) + { + Sub_Data_Files::get(type, data); + } +}; + +} + +#endif /* GC_BITPREPFILES_H_ */ diff --git a/GC/CcdPrep.h b/GC/CcdPrep.h index 194003eed..e38ad5f08 100644 --- a/GC/CcdPrep.h +++ b/GC/CcdPrep.h @@ -29,6 +29,11 @@ class CcdPrep : public BufferPrep { } + CcdPrep(SubProcessor*, DataPositions& usage) : + CcdPrep(usage, ShareThread::s()) + { + } + ~CcdPrep() { if (part_proc) diff --git a/GC/CcdSecret.h b/GC/CcdSecret.h index 21707a828..6d19b6685 100644 --- a/GC/CcdSecret.h +++ b/GC/CcdSecret.h @@ -51,7 +51,7 @@ class CcdSecret : public VectorSecret> { } - CcdSecret(const super& other) : + CcdSecret(const typename super::super& other) : super(other) { } diff --git a/GC/CcdShare.h b/GC/CcdShare.h index cd6c3618f..fcd16bff0 100644 --- a/GC/CcdShare.h +++ b/GC/CcdShare.h @@ -34,6 +34,11 @@ class CcdShare : public ShamirShare, public ShareSecret> static const int default_length = 1; + static DataFieldType field_type() + { + return DATA_GF2; + } + static string name() { return "CCD"; diff --git a/GC/FakeSecret.h b/GC/FakeSecret.h index 40dda61a0..9cdf97e8c 100644 --- a/GC/FakeSecret.h +++ b/GC/FakeSecret.h @@ -141,7 +141,7 @@ class FakeSecret : public ShareInterface, public BitVec void reveal(int n_bits, Clear& x) { (void) n_bits; x = a; } - void invert(FakeSecret) { throw not_implemented(); } + FakeSecret invert() const { throw not_implemented(); } void input(istream&, bool) { throw not_implemented(); } diff --git a/GC/Instruction.hpp b/GC/Instruction.cpp similarity index 98% rename from GC/Instruction.hpp rename to GC/Instruction.cpp index 256eb4fac..3fe0cc588 100644 --- a/GC/Instruction.hpp +++ b/GC/Instruction.cpp @@ -22,14 +22,12 @@ namespace GC { -inline Instruction::Instruction() : BaseInstruction() { size = 1; } -inline bool Instruction::get_offline_data_usage(int& usage) { switch (opcode) @@ -42,7 +40,6 @@ bool Instruction::get_offline_data_usage(int& usage) } } -inline unsigned Instruction::get_mem(RegType reg_type) const { unsigned m = n + 1; @@ -73,7 +70,6 @@ unsigned Instruction::get_mem(RegType reg_type) const return 0; } -inline void Instruction::parse(istream& s, int pos) { BaseInstruction::parse(s, pos); diff --git a/GC/Instruction.h b/GC/Instruction.h index a6b831294..b37091735 100644 --- a/GC/Instruction.h +++ b/GC/Instruction.h @@ -30,10 +30,6 @@ class Instruction : public ::BaseInstruction // Returns the memory size used if applicable and known unsigned get_mem(RegType reg_type) const; - - // Execute this instruction - template - bool execute(Processor& processor, U& dynamic_memory) const; }; } /* namespace GC */ diff --git a/GC/Instruction_inline.h b/GC/Instruction_inline.h index 61465c7dc..e6c6fb7a3 100644 --- a/GC/Instruction_inline.h +++ b/GC/Instruction_inline.h @@ -27,32 +27,6 @@ inline bool fallback_code(const Instruction& instruction, Processor& processo return true; } -template -MAYBE_INLINE bool Instruction::execute(Processor& processor, - U& dynamic_memory) const -{ -#ifdef DEBUG_OPS - cout << typeid(T).name() << " "; - cout << "pc " << processor.PC << " op " << hex << showbase << opcode << " " - << dec << noshowbase << r[0]; - if (CommonParty::singleton) - cout << ", " << CommonParty::s().get_reg_size() << " regs "; - if (ProgramParty::singleton) - ProgramParty::s().print_input_size(); - cout << endl; -#endif - const Instruction& instruction = *this; - auto& Ci = processor.I; - switch (opcode) - { -#define X(NAME, CODE) case NAME: CODE; return true; - INSTRUCTIONS -#undef X - default: - return fallback_code(*this, processor); - } -} - } /* namespace GC */ #endif /* GC_INSTRUCTION_INLINE_H_ */ diff --git a/GC/Machine.cpp b/GC/Machine.cpp deleted file mode 100644 index 55d011bda..000000000 --- a/GC/Machine.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Machine.cpp - * - */ - -#include "MaliciousRepSecret.h" -#include "Protocols/ReplicatedMC.h" -#include "Protocols/MaliciousRepMC.h" - -#include "Instruction.hpp" -#include "Machine.hpp" -#include "Processor.hpp" -#include "Program.hpp" -#include "Thread.hpp" -#include "ThreadMaster.hpp" - -#include "Processor/Machine.hpp" -#include "Processor/Instruction.hpp" -#include "Protocols/MaliciousRepMC.hpp" -#include "Protocols/MAC_Check_Base.hpp" -#include "Protocols/Beaver.hpp" - -namespace GC -{ - -#define GC_MACHINE(T) \ - template class Instruction; \ - template class Machine; \ - template class Processor; \ - template class Program; \ - template class Thread; \ - template class ThreadMaster; \ - -} /* namespace GC */ diff --git a/GC/Machine.h b/GC/Machine.h index d3f1b3020..ecf352cc6 100644 --- a/GC/Machine.h +++ b/GC/Machine.h @@ -46,8 +46,8 @@ class Machine : public ::BaseMachine, public Memories Machine(); ~Machine(); - void load_schedule(string progname); - void load_program(string threadname, string filename); + void load_schedule(const string& progname); + void load_program(const string& threadname, const string& filename); template void reset(const U& program); diff --git a/GC/Machine.hpp b/GC/Machine.hpp index c2934e8e6..f156628eb 100644 --- a/GC/Machine.hpp +++ b/GC/Machine.hpp @@ -35,7 +35,7 @@ Machine::~Machine() } template -void Machine::load_program(string threadname, string filename) +void Machine::load_program(const string& threadname, const string& filename) { (void)threadname; progs.push_back({}); @@ -44,7 +44,7 @@ void Machine::load_program(string threadname, string filename) } template -void Machine::load_schedule(string progname) +void Machine::load_schedule(const string& progname) { BaseMachine::load_schedule(progname); print_compiler(); diff --git a/GC/MaliciousCcdSecret.h b/GC/MaliciousCcdSecret.h index 3c82d5db6..eb450f082 100644 --- a/GC/MaliciousCcdSecret.h +++ b/GC/MaliciousCcdSecret.h @@ -48,7 +48,7 @@ class MaliciousCcdSecret : public VectorSecret> { } - MaliciousCcdSecret(const super& other) : + MaliciousCcdSecret(const typename super::super& other) : super(other) { } diff --git a/GC/MaliciousCcdShare.h b/GC/MaliciousCcdShare.h index 6f9410961..1c5841824 100644 --- a/GC/MaliciousCcdShare.h +++ b/GC/MaliciousCcdShare.h @@ -39,6 +39,11 @@ class MaliciousCcdShare: public MaliciousShamirShare, public ShareSecret< static const int default_length = 1; + static DataFieldType field_type() + { + return DATA_GF2; + } + static string name() { return "Malicious CCD"; diff --git a/GC/Memory.h b/GC/Memory.h index baa3aab6c..359677a20 100644 --- a/GC/Memory.h +++ b/GC/Memory.h @@ -12,7 +12,7 @@ #include using namespace std; -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Clear.h" #include "config.h" diff --git a/GC/NoShare.h b/GC/NoShare.h index c16a545cc..fed195e8b 100644 --- a/GC/NoShare.h +++ b/GC/NoShare.h @@ -24,6 +24,7 @@ class NoValue : public ValueInterface { public: typedef NoValue Scalar; + typedef NoValue next; const static int n_bits = 0; const static int MAX_N_BITS = 0; @@ -48,6 +49,11 @@ class NoValue : public ValueInterface return "no"; } + static string type_short() + { + return "no"; + } + static void fail() { throw runtime_error("VM does not support binary circuits"); @@ -70,6 +76,11 @@ class NoValue : public ValueInterface void randomize(PRNG&) { fail(); } void invert() { fail(); } + + void mask(int) { fail(); } + + void input(istream&, bool) { fail(); } + void output(ostream&, bool) { fail(); } }; inline ostream& operator<<(ostream& o, NoValue) @@ -176,12 +187,17 @@ class NoShare : public ShareInterface NoShare operator&(int) const { fail(); return {}; } NoShare operator>>(int) const { fail(); return {}; } + NoShare& operator+=(const NoShare&) { fail(); return *this; } + NoShare lsb() const { fail(); return {}; } NoShare get_bit(int) const { fail(); return {}; } void invert(int, NoShare) { fail(); } + NoShare mask(int) const { fail(); return {}; } + void input(istream&, bool) { fail(); } + void output(ostream&, bool) { fail(); } }; } /* namespace GC */ diff --git a/GC/PersonalPrep.hpp b/GC/PersonalPrep.hpp index 28b79ade5..dfeb77bc4 100644 --- a/GC/PersonalPrep.hpp +++ b/GC/PersonalPrep.hpp @@ -27,7 +27,7 @@ void PersonalPrep::buffer_personal_triples() template void PersonalPrep::buffer_personal_triples(size_t batch_size, ThreadQueues* queues) { - ShuffleSacrifice sacri; + TripleShuffleSacrifice sacri; batch_size = max(batch_size, (size_t)sacri.minimum_n_outputs()) + sacri.C; vector> triples(batch_size); diff --git a/GC/Processor.hpp b/GC/Processor.hpp index 9b8c190f5..8cf85e0cd 100644 --- a/GC/Processor.hpp +++ b/GC/Processor.hpp @@ -18,6 +18,7 @@ using namespace std; #include "GC/Machine.hpp" #include "Processor/ProcessorBase.hpp" +#include "Math/bigint.hpp" namespace GC { diff --git a/GC/Program.hpp b/GC/Program.hpp index e78a6a4c9..9815c0b84 100644 --- a/GC/Program.hpp +++ b/GC/Program.hpp @@ -7,13 +7,13 @@ #define GC_PROGRAM_HPP_ #include +#include "Instruction_inline.h" +#include "instructions.h" #include "config.h" #include "Tools/callgrind.h" -#include "Instruction.hpp" - namespace GC { @@ -82,7 +82,6 @@ void Program::parse(istream& s) } template -__attribute__((flatten)) BreakType Program::execute(Processor& Proc, U& dynamic_memory, int PC) const { @@ -95,6 +94,8 @@ BreakType Program::execute(Processor& Proc, U& dynamic_memory, unsigned int size = p.size(); size_t time = Proc.time; Proc.complexity = 0; + auto& Ci = Proc.I; + auto& processor = Proc; do { #ifdef DEBUG_EXE @@ -109,7 +110,15 @@ BreakType Program::execute(Processor& Proc, U& dynamic_memory, #ifdef COUNT_INSTRUCTIONS Proc.stats[p[Proc.PC].get_opcode()]++; #endif - p[Proc.PC++].execute(Proc, dynamic_memory); + auto& instruction = p[Proc.PC++]; + switch (instruction.get_opcode()) + { +#define X(NAME, CODE) case NAME: CODE; break; + INSTRUCTIONS +#undef X + default: + fallback_code(instruction, processor); + } time++; #ifdef DEBUG_COMPLEXITY cout << "complexity at " << time << ": " << Proc.complexity << endl; diff --git a/GC/RepPrep.h b/GC/RepPrep.h index 98025b865..34419de79 100644 --- a/GC/RepPrep.h +++ b/GC/RepPrep.h @@ -41,9 +41,9 @@ class RepPrep : public PersonalPrep, ShiftableTripleBuffer BufferPrep::get(type, data); } - array get_triple(int n_bits) + array get_triple_no_count(int n_bits) { - return ShiftableTripleBuffer::get_triple(n_bits); + return ShiftableTripleBuffer::get_triple_no_count(n_bits); } }; diff --git a/GC/Secret.h b/GC/Secret.h index a45f40bf1..4e687d23d 100644 --- a/GC/Secret.h +++ b/GC/Secret.h @@ -127,8 +127,8 @@ class Secret void load_clear(int n, const Integer& x); void operator=(const Integer& x) { load_clear(default_length, x); } - Secret operator<<(int i); - Secret operator>>(int i); + Secret operator<<(int i) const; + Secret operator>>(int i) const; template void bitcom(Memory& S, const vector& regs); diff --git a/GC/Secret.hpp b/GC/Secret.hpp index d2b169017..562cc32ca 100644 --- a/GC/Secret.hpp +++ b/GC/Secret.hpp @@ -183,7 +183,7 @@ void Secret::load(vector >& accesses, const U& mem) } template -Secret Secret::operator<<(int i) +Secret Secret::operator<<(int i) const { Secret res; for (int j = 0; j < i; j++) @@ -194,7 +194,7 @@ Secret Secret::operator<<(int i) } template -Secret Secret::operator>>(int i) +Secret Secret::operator>>(int i) const { Secret res; res.registers.insert(res.registers.end(), registers.begin() + i, registers.end()); @@ -219,10 +219,8 @@ template void Secret::bitdec(Memory& S, const vector& regs) const { if (regs.size() > registers.size()) - throw out_of_range( - "not enough bits for bit decomposition: " - + to_string(regs.size()) + " > " - + to_string(registers.size())); + throw overflow("not enough bits for bit decomposition", regs.size(), + registers.size()); for (unsigned int i = 0; i < regs.size(); i++) { Secret& secret = S[regs[i]]; diff --git a/GC/SemiPrep.h b/GC/SemiPrep.h index d45a12985..425cf6790 100644 --- a/GC/SemiPrep.h +++ b/GC/SemiPrep.h @@ -43,9 +43,9 @@ class SemiPrep : public BufferPrep, ShiftableTripleBuffer::get(type, data); } - array get_triple(int n_bits) + array get_triple_no_count(int n_bits) { - return ShiftableTripleBuffer::get_triple(n_bits); + return ShiftableTripleBuffer::get_triple_no_count(n_bits); } void buffer_personal_triples(vector>&, size_t, size_t) diff --git a/GC/ShareThread.hpp b/GC/ShareThread.hpp index f59793b72..80ad46527 100644 --- a/GC/ShareThread.hpp +++ b/GC/ShareThread.hpp @@ -8,6 +8,7 @@ #include #include "GC/ShareParty.h" +#include "BitPrepFiles.h" #include "Math/Setup.h" #include "Processor/Data_Files.hpp" @@ -27,7 +28,7 @@ ShareThread::ShareThread(const Names& N, OnlineOptions& opts, DataPositions& opts.live_prep ? *static_cast*>(new typename T::LivePrep( usage, *this)) : - *static_cast*>(new Sub_Data_Files(N, + *static_cast*>(new BitPrepFiles(N, get_prep_sub_dir(PREP_DIR, N.num_players()), usage))) { } diff --git a/GC/ShiftableTripleBuffer.h b/GC/ShiftableTripleBuffer.h index ed56dc3e5..af66cfb22 100644 --- a/GC/ShiftableTripleBuffer.h +++ b/GC/ShiftableTripleBuffer.h @@ -29,9 +29,9 @@ class ShiftableTripleBuffer virtual ~ShiftableTripleBuffer() {} - array get_triple(int n_bits) + array get_triple_no_count(int n_bits) { - int max_n_bits = T::N_BITS; + int max_n_bits = T::default_length; assert(n_bits <= max_n_bits); assert(n_bits > 0); array res; diff --git a/GC/Thread.hpp b/GC/Thread.hpp index 637873cf5..f53e02d74 100644 --- a/GC/Thread.hpp +++ b/GC/Thread.hpp @@ -10,6 +10,7 @@ #include "Program.h" #include "Networking/CryptoPlayer.h" +#include "Processor/Processor.h" #include "Processor.hpp" diff --git a/GC/ThreadMaster.hpp b/GC/ThreadMaster.hpp index 9a47e43a5..a0914389c 100644 --- a/GC/ThreadMaster.hpp +++ b/GC/ThreadMaster.hpp @@ -98,17 +98,8 @@ void ThreadMaster::run() delete P; - for (auto it : exe_stats) - switch (it.first) - { -#define X(NAME, CODE) case NAME: cerr << it.second << " " #NAME << endl; break; - INSTRUCTIONS -#undef X - } - - for (auto it = stats.begin(); it != stats.end(); it++) - if (it->second.data > 0) - cerr << it->first << " " << 1e-6 * it->second.data << " MB" << endl; + exe_stats.print(); + stats.print(); cerr << "Time = " << timer.elapsed() << " seconds" << endl; cerr << "Data sent = " << data_sent * 1e-6 << " MB" << endl; diff --git a/GC/TinierPrep.h b/GC/TinierPrep.h index 81e353c8e..be35f5a96 100644 --- a/GC/TinierPrep.h +++ b/GC/TinierPrep.h @@ -21,6 +21,11 @@ class TinierPrep : public TinyPrep { } + TinierPrep(SubProcessor*, DataPositions& usage) : + TinierPrep(usage, ShareThread::s()) + { + } + void buffer_inputs(int player) { this->buffer_inputs_(player, this->triple_generator); diff --git a/GC/TinierSharePrep.h b/GC/TinierSharePrep.h index 0cfceaa8d..7f292ac73 100644 --- a/GC/TinierSharePrep.h +++ b/GC/TinierSharePrep.h @@ -35,6 +35,7 @@ class TinierSharePrep : public PersonalPrep public: TinierSharePrep(DataPositions& usage, int input_player = PersonalPrep::SECURE); + TinierSharePrep(SubProcessor*, DataPositions& usage); ~TinierSharePrep(); void set_protocol(typename T::Protocol& protocol); diff --git a/GC/TinierSharePrep.hpp b/GC/TinierSharePrep.hpp index 801519d4c..02c7dd7a2 100644 --- a/GC/TinierSharePrep.hpp +++ b/GC/TinierSharePrep.hpp @@ -22,6 +22,12 @@ TinierSharePrep::TinierSharePrep(DataPositions& usage, int input_player) : { } +template +TinierSharePrep::TinierSharePrep(SubProcessor*, DataPositions& usage) : + TinierSharePrep(usage) +{ +} + template TinierSharePrep::~TinierSharePrep() { diff --git a/GC/TinyPrep.h b/GC/TinyPrep.h index a8e0cf69f..22d2b0bc3 100644 --- a/GC/TinyPrep.h +++ b/GC/TinyPrep.h @@ -10,13 +10,12 @@ #include "OT/MascotParams.h" #include "Protocols/Beaver.h" #include "Protocols/ReplicatedPrep.h" -#include "Protocols/RandomPrep.h" namespace GC { template -class TinyPrep : public BufferPrep, public RandomPrep +class TinyPrep : public BufferPrep { protected: ShareThread& thread; @@ -43,9 +42,7 @@ class TinyPrep : public BufferPrep, public RandomPrep get_triple(int n_bits); + array get_triple_no_count(int n_bits); size_t data_sent(); }; diff --git a/GC/TinyPrep.hpp b/GC/TinyPrep.hpp index 4de2446f6..b4c7c7b47 100644 --- a/GC/TinyPrep.hpp +++ b/GC/TinyPrep.hpp @@ -68,7 +68,6 @@ void TinyOnlyPrep::set_protocol(Beaver& protocol) OnlineOptions::singleton.batch_size, 1, this->params, this->thread.MC->get_alphai(), &protocol.P); input_generator->multi_threaded = false; - this->thread.MC->get_part_MC().set_prep(*this); } template @@ -78,7 +77,7 @@ void TinyPrep::buffer_triples() assert(triple_generator != 0); params.generateBits = false; vector> triples; - ShuffleSacrifice sacrifice; + TripleShuffleSacrifice sacrifice; size_t required; if (amplify) required = sacrifice.minimum_n_inputs_with_combining(); @@ -169,15 +168,7 @@ void TinyPrep::buffer_inputs_(int player, typename T::InputGenerator* input_g } template -typename T::part_type::super GC::TinyPrep::get_random() -{ - T tmp; - this->get_one(DATA_BIT, tmp); - return tmp.get_reg(0); -} - -template -array TinyPrep::get_triple(int n_bits) +array TinyPrep::get_triple_no_count(int n_bits) { assert(n_bits > 0); while ((unsigned)n_bits > triple_buffer.size()) diff --git a/GC/TinySecret.h b/GC/TinySecret.h index c7a804276..daa641ac2 100644 --- a/GC/TinySecret.h +++ b/GC/TinySecret.h @@ -60,9 +60,10 @@ class VectorSecret : public Secret return part_type::size() * default_length; } - template - static void generate_mac_key(mac_key_type&, const U&) + static void read_or_generate_mac_key(string directory, const Player& P, + mac_key_type& key) { + T::read_or_generate_mac_key(directory, P, key); } template @@ -218,7 +219,7 @@ class TinySecret : public VectorSecret> TinySecret() { } - TinySecret(const super& other) : + TinySecret(const typename super::super& other) : super(other) { } diff --git a/GC/VectorInput.h b/GC/VectorInput.h index f1e0da678..fe25beaa1 100644 --- a/GC/VectorInput.h +++ b/GC/VectorInput.h @@ -24,6 +24,11 @@ class VectorInput : public InputBase part_input.reset_all(P); } + VectorInput(SubProcessor& proc, typename T::MAC_Check&) : + VectorInput(proc.MC, proc.DataF, proc.P) + { + } + void reset(int player) { part_input.reset(player); diff --git a/GC/VectorProtocol.hpp b/GC/VectorProtocol.hpp index 79ab806aa..d95c3a24e 100644 --- a/GC/VectorProtocol.hpp +++ b/GC/VectorProtocol.hpp @@ -33,7 +33,7 @@ typename T::clear VectorProtocol::prepare_mul(const T& x, const T& y, int n) { for (int i = 0; i < n; i++) - part_protocol.prepare_mul(x.get_reg(i), y.get_reg(i)); + part_protocol.prepare_mul(x.get_reg(i), y.get_reg(i), 1); return {}; } @@ -49,7 +49,7 @@ T VectorProtocol::finalize_mul(int n) T res; res.resize_regs(n); for (int i = 0; i < n; i++) - res.get_reg(i) = part_protocol.finalize_mul(); + res.get_reg(i) = part_protocol.finalize_mul(1); return res; } diff --git a/License.txt b/License.txt index 82f1da0bd..3a9eb2ae0 100644 --- a/License.txt +++ b/License.txt @@ -1,5 +1,5 @@ CSIRO Open Source Software Licence Agreement (variation of the BSD / MIT License) -Copyright (c) 2020, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230. +Copyright (c) 2021, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230. All rights reserved. CSIRO is willing to grant you a licence to this MP-SPDZ sofware on the following terms, except where otherwise indicated for third party material. Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. diff --git a/Machines/OTMachine.cpp b/Machines/OTMachine.cpp index 880e3d3ec..f13701bef 100644 --- a/Machines/OTMachine.cpp +++ b/Machines/OTMachine.cpp @@ -1,7 +1,7 @@ #include "Networking/Player.h" #include "OT/OTExtension.h" #include "OT/OTExtensionWithMatrix.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Tools/time-func.h" #include diff --git a/Machines/TripleMachine.cpp b/Machines/TripleMachine.cpp index 4e89da6ba..f3020be81 100644 --- a/Machines/TripleMachine.cpp +++ b/Machines/TripleMachine.cpp @@ -13,8 +13,10 @@ #include "Math/Setup.h" #include "Protocols/fake-stuff.h" #include "Math/BitVec.h" +#include "GC/TinierSecret.h" #include "Protocols/fake-stuff.hpp" +#include "Protocols/MascotPrep.hpp" #include "Math/Z2k.hpp" #include "Math/gfp.hpp" #include "OT/NPartyTripleGenerator.hpp" diff --git a/Machines/cowgear-offline.cpp b/Machines/cowgear-offline.cpp new file mode 100644 index 000000000..ced5e0a41 --- /dev/null +++ b/Machines/cowgear-offline.cpp @@ -0,0 +1,20 @@ +/* + * cowgear-offline.cpp + * + */ + +#include "SPDZ.hpp" +#include "Math/gfp.hpp" +#include "Protocols/CowGearShare.h" +#include "Protocols/CowGearOptions.h" +#include "Protocols/CowGearPrep.hpp" +#include "Processor/FieldMachine.hpp" +#include "Processor/OfflineMachine.hpp" + +int main(int argc, const char** argv) +{ + ez::ezOptionParser opt; + CowGearOptions::singleton = CowGearOptions(opt, argc, argv); + DishonestMajorityFieldMachine>(argc, argv, opt); +} diff --git a/Machines/mal-shamir-offline.cpp b/Machines/mal-shamir-offline.cpp new file mode 100644 index 000000000..1f585f41a --- /dev/null +++ b/Machines/mal-shamir-offline.cpp @@ -0,0 +1,18 @@ +/* + * mal-shamir-offline.cpp + * + */ + +#include "ShamirMachine.hpp" +#include "MalRep.hpp" +#include "Processor/OfflineMachine.hpp" + +int main(int argc, const char** argv) +{ + auto& opts = ShamirOptions::singleton; + ez::ezOptionParser opt; + opts = {opt, argc, argv}; + HonestMajorityFieldMachine>(argc, argv, opt, + opts.nparties); +} diff --git a/Machines/malicious-rep-bin-party.cpp b/Machines/malicious-rep-bin-party.cpp index 8986b11fe..eb641e6dd 100644 --- a/Machines/malicious-rep-bin-party.cpp +++ b/Machines/malicious-rep-bin-party.cpp @@ -8,7 +8,6 @@ #include "GC/ShareSecret.hpp" #include "GC/MaliciousRepSecret.h" -#include "GC/Instruction.hpp" #include "GC/Machine.hpp" #include "GC/Processor.hpp" #include "GC/Program.hpp" diff --git a/Machines/mascot-offline.cpp b/Machines/mascot-offline.cpp new file mode 100644 index 000000000..975ae030b --- /dev/null +++ b/Machines/mascot-offline.cpp @@ -0,0 +1,18 @@ +/* + * mascot-offline.cpp + * + */ + +#include "GC/TinierSecret.h" + +#include "SPDZ.hpp" +#include "Math/gfp.hpp" +#include "Processor/FieldMachine.hpp" +#include "Processor/OfflineMachine.hpp" + +int main(int argc, const char** argv) +{ + ez::ezOptionParser opt; + DishonestMajorityFieldMachine>(argc, argv, opt); +} diff --git a/Machines/replicated-bin-party.cpp b/Machines/replicated-bin-party.cpp index 2043d7f22..7a7551703 100644 --- a/Machines/replicated-bin-party.cpp +++ b/Machines/replicated-bin-party.cpp @@ -7,7 +7,6 @@ #include "GC/ShareParty.hpp" #include "GC/ShareSecret.hpp" -#include "GC/Instruction.hpp" #include "GC/Machine.hpp" #include "GC/Processor.hpp" #include "GC/Program.hpp" diff --git a/Machines/semi-bin-party.cpp b/Machines/semi-bin-party.cpp index ba2c1f9a4..ee5d92d7d 100644 --- a/Machines/semi-bin-party.cpp +++ b/Machines/semi-bin-party.cpp @@ -11,7 +11,6 @@ #include "GC/Machine.hpp" #include "GC/Program.hpp" -#include "GC/Instruction.hpp" #include "GC/Thread.hpp" #include "GC/ThreadMaster.hpp" #include "GC/Processor.hpp" diff --git a/Machines/tinier-party.cpp b/Machines/tinier-party.cpp index dfc60ffcc..f4c0fbe9e 100644 --- a/Machines/tinier-party.cpp +++ b/Machines/tinier-party.cpp @@ -10,7 +10,6 @@ #include "GC/ShareParty.hpp" #include "GC/ShareSecret.hpp" -#include "GC/Instruction.hpp" #include "GC/Machine.hpp" #include "GC/Processor.hpp" #include "GC/Program.hpp" diff --git a/Machines/tiny-party.cpp b/Machines/tiny-party.cpp index 0ff368351..f96f5490d 100644 --- a/Machines/tiny-party.cpp +++ b/Machines/tiny-party.cpp @@ -10,7 +10,6 @@ #include "GC/ShareParty.hpp" #include "GC/ShareSecret.hpp" -#include "GC/Instruction.hpp" #include "GC/Machine.hpp" #include "GC/Processor.hpp" #include "GC/Program.hpp" diff --git a/Makefile b/Makefile index 017eb6a6a..d556856c3 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ COMMON = $(MATH) $(TOOLS) $(NETWORK) GC/square64.o Processor/OnlineOptions.o Pro COMPLETE = $(COMMON) $(PROCESSOR) $(FHEOFFLINE) $(TINYOTOFFLINE) $(GC) $(OT) YAO = $(patsubst %.cpp,%.o,$(wildcard Yao/*.cpp)) $(OT) BMR/Key.o BMR = $(patsubst %.cpp,%.o,$(wildcard BMR/*.cpp BMR/network/*.cpp)) -VM = $(PROCESSOR) $(COMMON) GC/square64.o OT/OTTripleSetup.o OT/BaseOT.o $(LIBSIMPLEOT) +VM = $(PROCESSOR) $(COMMON) GC/square64.o GC/Instruction.o OT/OTTripleSetup.o OT/BaseOT.o $(LIBSIMPLEOT) LIB = libSPDZ.a @@ -29,14 +29,14 @@ LIBRELEASE = librelease.a LIBSIMPLEOT = SimpleOT/libsimpleot.a # used for dependency generation -OBJS = $(BMR) $(FHEOFFLINE) $(TINYOTOFFLINE) $(YAO) $(COMPLETE) $(patsubst %.cpp,%.o,$(wildcard Machines/*.cpp)) +OBJS = $(BMR) $(FHEOFFLINE) $(TINYOTOFFLINE) $(YAO) $(COMPLETE) $(patsubst %.cpp,%.o,$(wildcard Machines/*.cpp Utils/*.cpp)) DEPS := $(wildcard */*.d */*/*.d) # never delete .SECONDARY: $(OBJS) -all: arithmetic binary gen_input online offline externalIO bmr doc +all: arithmetic binary gen_input online offline externalIO bmr ecdsa doc .PHONY: doc doc: @@ -59,7 +59,7 @@ include $(wildcard *.d static/*.d) online: Fake-Offline.x Server.x Player-Online.x Check-Offline.x emulate.x -offline: $(OT_EXE) Check-Offline.x +offline: $(OT_EXE) Check-Offline.x mascot-offline.x cowgear-offline.x mal-shamir-offline.x gen_input: gen_input_f2n.x gen_input_fp.x @@ -100,7 +100,7 @@ shamir: shamir-party.x malicious-shamir-party.x galois-degree.x sy: sy-rep-field-party.x sy-rep-ring-party.x sy-shamir-party.x -ecdsa: $(patsubst ECDSA/%.cpp,%.x,$(wildcard ECDSA/*-ecdsa-party.cpp)) +ecdsa: $(patsubst ECDSA/%.cpp,%.x,$(wildcard ECDSA/*-ecdsa-party.cpp)) Fake-ECDSA.x ecdsa-static: static-dir $(patsubst ECDSA/%.cpp,static/%.x,$(wildcard ECDSA/*-ecdsa-party.cpp)) $(LIBRELEASE): Protocols/MalRepRingOptions.o $(PROCESSOR) $(COMMON) $(OT) $(GC) @@ -115,9 +115,9 @@ static/%.x: ECDSA/%.o ECDSA/P256Element.o $(VM) $(OT) $(LIBSIMPLEOT) static-dir: @ mkdir static 2> /dev/null; true -static-release: static-dir $(patsubst Machines/%.cpp, static/%.x, $(wildcard Machines/*-party.cpp)) +static-release: static-dir $(patsubst Machines/%.cpp, static/%.x, $(wildcard Machines/*-party.cpp)) static/emulate.x -Fake-ECDSA.x: ECDSA/Fake-ECDSA.cpp ECDSA/P256Element.o $(COMMON) +Fake-ECDSA.x: ECDSA/Fake-ECDSA.cpp ECDSA/P256Element.o $(COMMON) Processor/PrepBase.o $(CXX) -o $@ $^ $(CFLAGS) $(LDLIBS) $(ECLIB) Check-Offline.x: $(PROCESSOR) @@ -127,7 +127,7 @@ ot.x: $(OT) $(COMMON) Machines/OText_main.o Machines/OTMachine.o $(LIBSIMPLEOT) ot-offline.x: $(OT) $(LIBSIMPLEOT) Machines/TripleMachine.o -gc-emulate.x: $(PROCESSOR) GC/FakeSecret.o GC/square64.o +gc-emulate.x: $(VM) GC/FakeSecret.o GC/square64.o bmr-%.x: $(BMR) $(VM) Machines/bmr-%.cpp $(LIBSIMPLEOT) $(CXX) -o $@ $(CFLAGS) $^ $(BOOST) $(LDLIBS) @@ -205,6 +205,9 @@ emulate.x: GC/FakeSecret.o semi-bmr-party.x: GC/SemiPrep.o GC/SemiSecret.o $(OT) real-bmr-party.x: $(OT) paper-example.x: $(VM) $(OT) $(FHEOFFLINE) +mascot-offline.x: $(VM) $(OT) +cowgear-offline.x: $(OT) $(FHEOFFLINE) +Fake-Offline.x: $(VM) static/rep-bmr-party.x: $(BMR) static/mal-rep-bmr-party.x: $(BMR) static/shamir-bmr-party.x: $(BMR) diff --git a/Math/BitVec.h b/Math/BitVec.h index fd867a092..c7f35fca5 100644 --- a/Math/BitVec.h +++ b/Math/BitVec.h @@ -24,6 +24,9 @@ class BitVec_ : public IntBase static const int n_bits = sizeof(T) * 8; + static const false_type invertible; + static const true_type characteristic_two; + static char type_char() { return 'B'; } static string type_short() { return "B"; } static DataFieldType field_type() { return DATA_GF2; } @@ -73,4 +76,9 @@ class BitVec_ : public IntBase typedef BitVec_ BitVec; +template +const false_type BitVec_::invertible; +template +const true_type BitVec_::characteristic_two; + #endif /* MATH_BITVEC_H_ */ diff --git a/Math/FixedVec.h b/Math/FixedVec.h index 63521f224..3e188513d 100644 --- a/Math/FixedVec.h +++ b/Math/FixedVec.h @@ -56,7 +56,7 @@ class FixedVec return res; } - FixedVec(const T& other = 0) + FixedVec(const T& other = {}) { for (auto& x : v) x = other; @@ -128,12 +128,7 @@ class FixedVec void mul(const FixedVec& x, const FixedVec& y) { for (int i = 0; i < L; i++) - v[i].mul(x.v[i], y.v[i]); - } - - void add(const FixedVec& x) - { - add(*this, x); + v[i] = (x.v[i] * y.v[i]); } void add(octetStream& os) @@ -225,7 +220,7 @@ class FixedVec FixedVec& operator+=(const FixedVec& other) { - add(other); + add(*this, other); return *this; } diff --git a/Math/Integer.h b/Math/Integer.h index f60ad0c99..057a952b9 100644 --- a/Math/Integer.h +++ b/Math/Integer.h @@ -150,9 +150,6 @@ class Integer : public IntBase void mul(const Integer& x) { *this = *this * x; } - void invert() { throw runtime_error("cannot invert integer"); } - void invert(const Integer& _) { (void)_; invert(); } - void AND(const Integer& x, const Integer& y) { *this = x & y; } void OR(const Integer& x, const Integer& y) { *this = x | y; } void XOR(const Integer& x, const Integer& y) { *this = x ^ y; } diff --git a/Math/Setup.cpp b/Math/Setup.cpp index 5fb838cdc..ea143c0a5 100644 --- a/Math/Setup.cpp +++ b/Math/Setup.cpp @@ -140,3 +140,24 @@ void write_online_setup(string dirname, const bigint& p) if (!outf.good()) throw file_error("cannot write to " + ss.str()); } + +void check_setup(string dir, bigint pr) +{ + bigint p; + string filename = dir + "Params-Data"; + ifstream(filename) >> p; + if (p != pr) + throw runtime_error("wrong modulus in " + dir); +} + +string get_prep_sub_dir(const string& prep_dir, int nparties, int log2mod, + const string& type_short) +{ + string res = prep_dir + "/" + to_string(nparties) + "-" + type_short; + if (log2mod > 1) + res += "-" + to_string(log2mod); + res += "/"; + if (mkdir_p(res.c_str()) < 0) + throw file_error(res); + return res; +} diff --git a/Math/Setup.h b/Math/Setup.h index 073b702f7..f8405ba3b 100644 --- a/Math/Setup.h +++ b/Math/Setup.h @@ -27,6 +27,7 @@ void generate_prime_setup(string dir, int lgp); template void generate_online_setup(string dirname, bigint& p, int lgp); void write_online_setup(string dirname, const bigint& p); +void check_setup(string dirname, bigint p); // Setup primes only // Chooses a p of at least lgp bits @@ -35,22 +36,19 @@ void SPDZ_Data_Setup_Primes(bigint& p,int lgp,int& idx,int& m); void generate_prime(bigint& p, int lgp, int m); bigint generate_prime(int lgp, int m); +string get_prep_sub_dir(const string& prep_dir, int nparties, int log2mod, + const string& type_short); + template -string get_prep_sub_dir(string prep_dir, int nparties, int log2mod) +string get_prep_sub_dir(const string& prep_dir, int nparties, int log2mod) { - string res = prep_dir + "/" + to_string(nparties) + "-" + T::type_short(); if (T::clear::length() > 1) log2mod = T::clear::length(); - if (log2mod > 1) - res += "-" + to_string(log2mod); - res += "/"; - if (mkdir_p(res.c_str()) < 0) - throw file_error(res); - return res; + return get_prep_sub_dir(prep_dir, nparties, log2mod, T::type_short()); } template -string get_prep_sub_dir(string prep_dir, int nparties) +string get_prep_sub_dir(const string& prep_dir, int nparties) { return get_prep_sub_dir(prep_dir, nparties, T::clear::length()); } diff --git a/Math/ValueInterface.h b/Math/ValueInterface.h index cf47f1eea..4bd36cd2a 100644 --- a/Math/ValueInterface.h +++ b/Math/ValueInterface.h @@ -6,7 +6,7 @@ #ifndef MATH_VALUEINTERFACE_H_ #define MATH_VALUEINTERFACE_H_ -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" class OnlineOptions; class bigint; @@ -19,6 +19,7 @@ class ValueInterface static const false_type characteristic_two; static const false_type prime_field; + static const false_type invertible; template static void init(bool mont = true) { (void) mont; } @@ -28,11 +29,13 @@ class ValueInterface static void read_or_generate_setup(const string&, const OnlineOptions&) {} template static void generate_setup(string, int, int) {} + template + static void write_setup(int) {} + static void write_setup(string) {} + static void check_setup(string) {} static bigint pr() { throw runtime_error("no prime modulus"); } - static int power_of_two(bool, int) { throw not_implemented(); } - void normalize() {} void randomize_part(PRNG&, int) { throw not_implemented(); } diff --git a/Math/Z2k.h b/Math/Z2k.h index 6e414b9a0..c22a2ad95 100644 --- a/Math/Z2k.h +++ b/Math/Z2k.h @@ -35,21 +35,8 @@ class Z2 : public ValueInterface public: - typedef void Inp; - typedef void PO; typedef void Square; - class DummyZ2kProtocol - { - public: - static void assign(Z2& _, const Z2& __, int& ___) - { - (void) _, (void) __, (void) ___; - throw not_implemented(); - } - }; - typedef DummyZ2kProtocol Protocol; - static const int N_BITS = K; static const int MAX_EDABITS = K; static const int N_BYTES = (K + 7) / 8; @@ -109,10 +96,6 @@ class Z2 : public ValueInterface const mp_limb_t* get() const { return a; } void convert_destroy(bigint& a) { *this = a; } - - void negate() { - throw not_implemented(); - } Z2 operator+(const Z2& other) const; Z2 operator-(const Z2& other) const; @@ -126,37 +109,30 @@ class Z2 : public ValueInterface Z2 operator/(const Z2& other) const { (void) other; throw division_by_zero(); } Z2 operator&(const Z2& other) const; + Z2 operator^(const Z2& other) const; + Z2 operator|(const Z2& other) const; Z2& operator+=(const Z2& other); Z2& operator-=(const Z2& other); + Z2& operator*=(const Z2& other); Z2& operator&=(const Z2& other); Z2& operator<<=(int other); Z2& operator>>=(int other); Z2 operator<<(int i) const; Z2 operator>>(int i) const; + Z2 operator<<(const Z2& i) const { return *this << i.a[0]; } + Z2 operator>>(const Z2& i) const { return *this >> i.a[0]; } bool operator==(const Z2& other) const; bool operator!=(const Z2& other) const { return not (*this == other); } - void add(const Z2& a, const Z2& b) { *this = a + b; } - void add(const Z2& a) { *this += a; } - void sub(const Z2& a, const Z2& b) { *this = a - b; } - - template - void mul(const Z2& a, const Z2& b) { *this = Z2::Mul(a, b); } - template - void mul(const Integer& a, const Z2& b) { *this = Z2::Mul(Z2<64>(a), b); } - - void mul(const Z2& a) { *this = Z2::Mul(*this, a); } - - void add(octetStream& os) { add(os.consume(size())); } + void add(octetStream& os) { *this += (os.consume(size())); } Z2 lazy_add(const Z2& x) const; Z2 lazy_mul(const Z2& x) const; - Z2& invert(); - void invert(const Z2& a) { *this = a; invert(); } + Z2 invert() const; Z2 sqrRoot(); @@ -164,16 +140,6 @@ class Z2 : public ValueInterface bool is_one() const { return *this == 1; } bool is_bit() const { return is_zero() or is_one(); } - void SHL(const Z2& a, const bigint& i) { *this = a << i.get_ui(); } - void SHR(const Z2& a, const bigint& i) { *this = a >> i.get_ui(); } - - void SHL(const Z2& a, int i) { *this = a << i; } - void SHR(const Z2& a, int i) { *this = a >> i; } - - void AND(const Z2& a, const Z2& b); - void OR(const Z2& a, const Z2& b); - void XOR(const Z2& a, const Z2& b); - void randomize(PRNG& G, int n = -1); void randomize_part(PRNG& G, int n); void almost_randomize(PRNG& G) { randomize(G); } @@ -321,6 +287,13 @@ Z2& Z2::operator-=(const Z2& other) return *this; } +template +Z2& Z2::operator*=(const Z2& other) +{ + *this = *this * other; + return *this; +} + template Z2& Z2::operator&=(const Z2& other) { diff --git a/Math/Z2k.hpp b/Math/Z2k.hpp index f5a468bc4..5df91806d 100644 --- a/Math/Z2k.hpp +++ b/Math/Z2k.hpp @@ -71,7 +71,23 @@ template Z2 Z2::operator&(const Z2& other) const { Z2 res; - res.AND(*this, other); + mpn_and_n(res.a, a, other.a, N_WORDS); + return res; +} + +template +Z2 Z2::operator^(const Z2& other) const +{ + Z2 res; + mpn_xor_n(res.a, a, other.a, N_WORDS); + return res; +} + +template +Z2 Z2::operator|(const Z2& other) const +{ + Z2 res; + mpn_ior_n(res.a, a, other.a, N_WORDS); return res; } @@ -86,7 +102,7 @@ bool Z2::operator==(const Z2& other) const } template -Z2& Z2::invert() +Z2 Z2::invert() const { if (get_bit(0) != 1) throw division_by_zero(); @@ -96,8 +112,7 @@ Z2& Z2::invert() { res += Z2((Z2(1) - Z2::Mul(*this, res)).get_bit(i)) << i; } - *this = res; - return *this; + return res; } template @@ -115,24 +130,6 @@ Z2 Z2::sqrRoot() return res; } -template -void Z2::AND(const Z2& x, const Z2& y) -{ - mpn_and_n(a, x.a, y.a, N_WORDS); -} - -template -void Z2::OR(const Z2& x, const Z2& y) -{ - mpn_ior_n(a, x.a, y.a, N_WORDS); -} - -template -void Z2::XOR(const Z2& x, const Z2& y) -{ - mpn_xor_n(a, x.a, y.a, N_WORDS); -} - template void Z2::input(istream& s, bool human) { diff --git a/Math/Zp_Data.cpp b/Math/Zp_Data.cpp index 6e7fc2a08..884d7ace4 100644 --- a/Math/Zp_Data.cpp +++ b/Math/Zp_Data.cpp @@ -60,18 +60,6 @@ void Zp_Data::init(const bigint& p,bool mont) } -__m128i Zp_Data::get_random128(PRNG& G) -{ - assert(t == 2); - while (true) - { - __m128i res = G.get_doubleword(); - if (__uint128_t(res) < __uint128_t(int128(prA[1], prA[0]).a)) - return res; - } -} - - #include void Zp_Data::Mont_Mult(mp_limb_t* z,const mp_limb_t* x,const mp_limb_t* y,int t) const diff --git a/Math/Zp_Data.h b/Math/Zp_Data.h index 26c8bf83b..e067b85f4 100644 --- a/Math/Zp_Data.h +++ b/Math/Zp_Data.h @@ -81,12 +81,10 @@ class Zp_Data void Sub(mp_limb_t* ans,const mp_limb_t* x,const mp_limb_t* y) const; void Sub(mp_limb_t* ans,const mp_limb_t* x,const mp_limb_t* y) const; - __m128i get_random128(PRNG& G); - bool operator!=(const Zp_Data& other) const; template friend void to_modp(modp_& ans,int x,const Zp_Data& ZpD); - template friend void to_modp(modp_& ans,const bigint& x,const Zp_Data& ZpD); + template friend void to_modp(modp_& ans,const mpz_class& x,const Zp_Data& ZpD); template friend void Add(modp_& ans,const modp_& x,const modp_& y,const Zp_Data& ZpD); template friend void Sub(modp_& ans,const modp_& x,const modp_& y,const Zp_Data& ZpD); @@ -263,6 +261,13 @@ inline void Zp_Data::Mont_Mult(mp_limb_t* z,const mp_limb_t* x,const mp_limb_t* CASE(4) CASE(5) #endif +#if MAX_MOD_SZ >= 10 + CASE(6) + CASE(7) + CASE(8) + CASE(9) + CASE(10) +#endif #undef CASE #endif default: diff --git a/Math/bigint.cpp b/Math/bigint.cpp index c02f3ec25..a12706481 100644 --- a/Math/bigint.cpp +++ b/Math/bigint.cpp @@ -6,7 +6,7 @@ #include "Z2k.h" #include "Z2k.hpp" #include "GC/Clear.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "bigint.hpp" @@ -152,6 +152,13 @@ bigint::bigint(const gfpvar& other) to_bigint(*this, other.get(), other.get_ZpD()); } +string to_string(const bigint& x) +{ + stringstream ss; + ss << x; + return ss.str(); +} + #ifdef REALLOC_POLICE void bigint::lottery() { diff --git a/Math/bigint.h b/Math/bigint.h index 69998c158..efb2c777d 100644 --- a/Math/bigint.h +++ b/Math/bigint.h @@ -7,7 +7,7 @@ using namespace std; #include #include -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Tools/int.h" #include "Tools/random.h" #include "Tools/octetStream.h" @@ -69,12 +69,14 @@ class bigint : public mpz_class bigint& operator=(word n); template bigint& operator=(const gfp_& other); + template + bigint& operator=(const Z2& x); + template + bigint& operator=(const SignedZ2& x); void allocate_slots(const bigint& x) { *this = x; } int get_min_alloc() { return get_mpz_t()->_mp_alloc; } - void negate() { mpz_neg(get_mpz_t(), get_mpz_t()); } - void mul(const bigint& x, const bigint& y) { *this = x * y; } #ifdef REALLOC_POLICE @@ -138,12 +140,25 @@ inline bigint& bigint::operator=(word n) template bigint::bigint(const Z2& x) +{ + *this = x; +} + +template +bigint& bigint::operator=(const Z2& x) { mpz_import(get_mpz_t(), Z2::N_WORDS, -1, sizeof(mp_limb_t), 0, 0, x.get_ptr()); + return *this; } template bigint::bigint(const SignedZ2& x) +{ + *this = x; +} + +template +bigint& bigint::operator=(const SignedZ2& x) { mpz_import(get_mpz_t(), Z2::N_WORDS, -1, sizeof(mp_limb_t), 0, 0, x.get_ptr()); if (x.negative()) @@ -152,6 +167,7 @@ bigint::bigint(const SignedZ2& x) bigint::tmp <<= K; *this -= bigint::tmp; } + return *this; } template @@ -167,6 +183,7 @@ bigint& bigint::operator=(const gfp_& x) return *this; } +string to_string(const bigint& x); /********************************** * Utility Functions * diff --git a/Math/gf2n.cpp b/Math/gf2n.cpp index 4e0de2160..ff2105d81 100644 --- a/Math/gf2n.cpp +++ b/Math/gf2n.cpp @@ -2,7 +2,7 @@ #include "Math/gf2n.h" #include "Math/Bit.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include #include @@ -58,7 +58,7 @@ void gf2n_short::init_field(int nn) { if (nn == 0) { - nn = default_length(); + nn = DEFAULT_LENGTH; #ifdef VERBOSE cerr << "Using GF(2^" << nn << ")" << endl; #endif @@ -139,19 +139,6 @@ inline word mul16(word x,word y) -/* Takes 16 bit x the 32 bit square */ -inline word sqr16(word x) -{ - word a1=x&(0xFF),a2=x>>8; - - word ans=gf2n_short_table[a2][a2]<<16; - ans^=gf2n_short_table[a1][a1]; - - return ans; -} - - - void gf2n_short::reduce_trinomial(word xh,word xl) { // Deal with xh first @@ -261,39 +248,9 @@ gf2n_short gf2n_short::operator*(const Bit& x) const } - - -inline void sqr32(word x,word& ans) -{ - word a1=x&(0xFFFF),a2=x>>16; - ans=sqr16(a1)^(sqr16(a2)<<32); -} - -void gf2n_short::square() -{ - word xh,xl; - sqr32(a&0xFFFFFFFF,xl); - sqr32(a>>32,xh); - reduce(xh,xl); -} - - -void gf2n_short::square(const gf2n_short& bb) +gf2n_short gf2n_short::invert() const { - word xh,xl; - sqr32(bb.a&0xFFFFFFFF,xl); - sqr32(bb.a>>32,xh); - reduce(xh,xl); -} - - - - - - -void gf2n_short::invert() -{ - if (is_one()) { return; } + if (is_one()) { return *this; } if (is_zero()) { throw division_by_zero(); } word u,v=a,B=0,D=1,mod=1; @@ -322,22 +279,7 @@ void gf2n_short::invert() else { v=v^u; D=D^B; } } - a=D; -} - - -void gf2n_short::power(long i) -{ - long n=i; - if (n<0) { invert(); n=-n; } - - gf2n_short T=*this; - assign_one(); - while (n!=0) - { if ((n&1)!=0) { mul(*this,T); } - n>>=1; - T.square(); - } + return D; } @@ -380,14 +322,14 @@ void gf2n_short::input(istream& s,bool human) void expand_byte(gf2n_short& a,int b) { gf2n_short x,xp; - x.assign(32+1); + x = (32+1); xp.assign_one(); a.assign_zero(); while (b!=0) { if ((b&1)==1) { a.add(a,xp); } - xp.mul(x); + xp *= (x); b>>=1; } } diff --git a/Math/gf2n.h b/Math/gf2n.h index afb7e21c9..4c51abc30 100644 --- a/Math/gf2n.h +++ b/Math/gf2n.h @@ -66,8 +66,7 @@ class gf2n_short : public ValueInterface static const int MAX_N_BITS = 64; static const int N_BYTES = sizeof(a); - - static const int N_BITS = -1; + static const int DEFAULT_LENGTH = 40; static void init_field(int nn = 0); static void reset() { n = 0; } @@ -88,10 +87,8 @@ class gf2n_short : public ValueInterface static int size() { return sizeof(a); } static int size_in_bits() { return sizeof(a) * 8; } - static int t() { return 0; } - static int default_length() { return 40; } - static int length() { return n == 0 ? default_length() : n; } + static int length() { return n == 0 ? DEFAULT_LENGTH : n; } static bool allows(Dtype type) { (void) type; return true; } @@ -107,17 +104,12 @@ class gf2n_short : public ValueInterface const void* get_ptr() const { return &a; } - void assign(const gf2n_short& g) { a=g.a; } - void assign_zero() { a=0; } void assign_one() { a=1; } void assign_x() { a=2; } - void assign(word aa) { a=aa&mask; } - void assign(long aa) { assign(word(aa)); } - void assign(int aa) { a=static_cast(aa)&mask; } void assign(const void* aa) { a = *(word*) aa & mask; } - void normalize() { assign(a); } + void normalize() { a &= mask; } int get_bit(int i) const { return (a>>i)&1; } @@ -129,37 +121,29 @@ class gf2n_short : public ValueInterface } gf2n_short() : a(0) {} - gf2n_short(word a) { assign(a); } - gf2n_short(long a) { assign(a); } - gf2n_short(int a) { assign(a); } - gf2n_short(bool a) { assign(a); } - gf2n_short(const char* a) { assign(a); } + gf2n_short(word a) : a(a & mask) {} + gf2n_short(long a) : gf2n_short(word(a)) {} + gf2n_short(int a) : gf2n_short(word(unsigned(a))) {} gf2n_short(const int128& a) { reduce(a.get_upper(), a.get_lower()); } template - gf2n_short(IntBase a) { assign(a.get()); } + gf2n_short(IntBase a) : a(a.get()) {} int is_zero() const { return (a==0); } int is_one() const { return (a==1); } - int equal(const gf2n_short& y) const { return (a==y.a); } bool operator==(const gf2n_short& y) const { return a==y.a; } bool operator!=(const gf2n_short& y) const { return a!=y.a; } // x+y void add(const gf2n_short& x,const gf2n_short& y) { a=x.a^y.a; } - void add(const gf2n_short& x) - { a^=x.a; } void add(octet* x) { a^=*(word*)(x); } void add(octetStream& os) { add(os.consume(size())); } void sub(const gf2n_short& x,const gf2n_short& y) { a=x.a^y.a; } - void sub(const gf2n_short& x) - { a^=x.a; } // = x * y void mul(const gf2n_short& x,const gf2n_short& y); - void mul(const gf2n_short& x) { mul(*this,x); } // x * y when one of x,y is a bit void mul_by_bit(const gf2n_short& x, const gf2n_short& y) { a = x.a * y.a; } @@ -168,40 +152,28 @@ class gf2n_short : public ValueInterface gf2n_short operator+(const gf2n_short& x) const { gf2n_short res; res.add(*this, x); return res; } gf2n_short operator*(const gf2n_short& x) const { gf2n_short res; res.mul(*this, x); return res; } - gf2n_short& operator+=(const gf2n_short& x) { add(x); return *this; } - gf2n_short& operator*=(const gf2n_short& x) { mul(x); return *this; } + gf2n_short& operator+=(const gf2n_short& x) { add(*this, x); return *this; } + gf2n_short& operator*=(const gf2n_short& x) { mul(*this, x); return *this; } gf2n_short operator-(const gf2n_short& x) const { gf2n_short res; res.add(*this, x); return res; } - gf2n_short& operator-=(const gf2n_short& x) { sub(x); return *this; } - gf2n_short operator/(const gf2n_short& x) const { gf2n_short tmp; tmp.invert(x); return *this * tmp; } + gf2n_short& operator-=(const gf2n_short& x) { sub(*this, x); return *this; } + gf2n_short operator/(const gf2n_short& x) const { return *this * x.invert(); } gf2n_short operator*(const Bit& x) const; - void square(); - void square(const gf2n_short& aa); - void invert(); - void invert(const gf2n_short& aa) - { *this=aa; invert(); } + gf2n_short invert() const; void negate() { return; } - void power(long i); /* Bitwise Ops */ - void AND(const gf2n_short& x,const gf2n_short& y) { a=x.a&y.a; } - void XOR(const gf2n_short& x,const gf2n_short& y) { a=x.a^y.a; } - void OR(const gf2n_short& x,const gf2n_short& y) { a=x.a|y.a; } - void NOT(const gf2n_short& x) { a=(~x.a)&mask; } - void SHL(const gf2n_short& x,int n) { a=(x.a<>n; } - - gf2n_short operator&(const gf2n_short& x) const { gf2n_short res; res.AND(*this, x); return res; } - gf2n_short operator^(const gf2n_short& x) const { gf2n_short res; res.XOR(*this, x); return res; } - gf2n_short operator|(const gf2n_short& x) const { gf2n_short res; res.OR(*this, x); return res; } - gf2n_short operator!() const { gf2n_short res; res.NOT(*this); return res; } - gf2n_short operator<<(int i) const { gf2n_short res; res.SHL(*this, i); return res; } - gf2n_short operator>>(int i) const { gf2n_short res; res.SHR(*this, i); return res; } - - gf2n_short& operator&=(const gf2n_short& x) { AND(*this, x); return *this; } - gf2n_short& operator>>=(int i) { SHR(*this, i); return *this; } - gf2n_short& operator<<=(int i) { SHL(*this, i); return *this; } + gf2n_short operator&(const gf2n_short& x) const { return a & x.a; } + gf2n_short operator^(const gf2n_short& x) const { return a ^ x.a; } + gf2n_short operator|(const gf2n_short& x) const { return a | x.a; } + gf2n_short operator~() const { return ~a; } + gf2n_short operator<<(int i) const { return a << i; } + gf2n_short operator>>(int i) const { return a >> i; } + + gf2n_short& operator&=(const gf2n_short& x) { *this = *this & x; return *this; } + gf2n_short& operator>>=(int i) { *this = *this >> i; return *this; } + gf2n_short& operator<<=(int i) { *this = *this << i; return *this; } /* Crap RNG */ void randomize(PRNG& G, int n = -1); diff --git a/Math/gf2nlong.cpp b/Math/gf2nlong.cpp index 7d401b5ac..f0d32baf8 100644 --- a/Math/gf2nlong.cpp +++ b/Math/gf2nlong.cpp @@ -6,7 +6,7 @@ #include "gf2nlong.h" #include "gf2n.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include #include @@ -66,7 +66,7 @@ void gf2n_long::init_field(int nn) { if (nn == 0) { - nn = default_length(); + nn = MAX_N_BITS; #ifdef VERBOSE cerr << "Using GF(2^" << nn << ")" << endl; #endif @@ -201,9 +201,9 @@ class int129 { s << a.msb << a.lower; return s; } }; -void gf2n_long::invert() +gf2n_long gf2n_long::invert() const { - if (is_one()) { return; } + if (is_one()) { return *this; } if (is_zero()) { throw division_by_zero(); } int129 u,v=a,B=0,D=1,mod=1; @@ -232,7 +232,7 @@ void gf2n_long::invert() else { v=v^u; D=D^B; } } - a=D.get_lower(); + return D.get_lower(); } diff --git a/Math/gf2nlong.h b/Math/gf2nlong.h index d5e16a869..03a0383ff 100644 --- a/Math/gf2nlong.h +++ b/Math/gf2nlong.h @@ -17,7 +17,6 @@ using namespace std; #include "Tools/random.h" #include "Math/field_types.h" #include "Math/bigint.h" -#include "Math/Bit.h" class int128 @@ -59,7 +58,6 @@ class int128 friend ostream& operator<<(ostream& s, const int128& a); - static int128 ones(int n); bool get_bit(int i) const; }; @@ -108,8 +106,6 @@ class gf2n_long : public ValueInterface const static int MAX_N_BITS = 128; const static int N_BYTES = sizeof(a); - static const int N_BITS = -1; - typedef gf2n_long Scalar; void reduce(int128 xh,int128 xl) @@ -139,9 +135,6 @@ class gf2n_long : public ValueInterface static int size() { return sizeof(a); } static int size_in_bits() { return sizeof(a) * 8; } - static int t() { return 0; } - - static int default_length() { return 128; } static bool allows(Dtype type) { (void) type; return true; } @@ -157,39 +150,19 @@ class gf2n_long : public ValueInterface const void* get_ptr() const { return &a.a; } - void assign(const gf2n_long& g) { a=g.a; } - void assign_zero() { a=_mm_setzero_si128(); } void assign_one() { a=int128(0,1); } void assign_x() { a=int128(0,2); } - void assign(int128 aa) { a=aa&mask; } - void assign(int aa) { a=int128(static_cast(aa))&mask; } void assign(const void* buffer) { a = _mm_loadu_si128((__m128i*)buffer); } - void normalize() {} - int get_bit(int i) const { return ((a>>i)&1).get_lower(); } - void set_bit(int i,unsigned int b) - { if (b==1) - { a |= (1UL< - gf2n_long(IntBase g) { assign(g.get()); } - gf2n_long(const char* buffer) { assign(buffer); } - gf2n_long(GC::NoValue); - - gf2n_long& operator=(const gf2n_long& g) - { if (&g!=this) { assign(g); } - return *this; - } + gf2n_long(IntBase g) : a(g.get()) {} int is_zero() const { return a==int128(0); } int is_one() const { return a==int128(1); } @@ -200,19 +173,14 @@ class gf2n_long : public ValueInterface // x+y void add(const gf2n_long& x,const gf2n_long& y) { a=x.a^y.a; } - void add(const gf2n_long& x) - { a^=x.a; } void add(octet* x) { a^=int128(_mm_loadu_si128((__m128i*)x)); } void add(octetStream& os) { add(os.consume(size())); } void sub(const gf2n_long& x,const gf2n_long& y) { a=x.a^y.a; } - void sub(const gf2n_long& x) - { a^=x.a; } // = x * y gf2n_long& mul(const gf2n_long& x,const gf2n_long& y); - void mul(const gf2n_long& x) { mul(*this,x); } // x * y when one of x,y is a bit void mul_by_bit(const gf2n_long& x, const gf2n_long& y) { a = x.a.a * y.a.a; } @@ -221,40 +189,27 @@ class gf2n_long : public ValueInterface gf2n_long operator+(const gf2n_long& x) const { gf2n_long res; res.add(*this, x); return res; } gf2n_long operator*(const gf2n_long& x) const { gf2n_long res; res.mul(*this, x); return res; } - gf2n_long& operator+=(const gf2n_long& x) { add(x); return *this; } - gf2n_long& operator*=(const gf2n_long& x) { mul(x); return *this; } + gf2n_long& operator+=(const gf2n_long& x) { add(*this, x); return *this; } + gf2n_long& operator*=(const gf2n_long& x) { mul(*this, x); return *this; } gf2n_long operator-(const gf2n_long& x) const { gf2n_long res; res.add(*this, x); return res; } - gf2n_long& operator-=(const gf2n_long& x) { sub(x); return *this; } - gf2n_long operator/(const gf2n_long& x) const { gf2n_long tmp; tmp.invert(x); return *this * tmp; } - - void square(); - void square(const gf2n_long& aa); - void invert(); - void invert(const gf2n_long& aa) - { *this=aa; invert(); } + gf2n_long& operator-=(const gf2n_long& x) { sub(*this, x); return *this; } + gf2n_long operator/(const gf2n_long& x) const { return *this * x.invert(); } + + gf2n_long invert() const; void negate() { return; } - void power(long i); /* Bitwise Ops */ - void AND(const gf2n_long& x,const gf2n_long& y) { a=x.a&y.a; } - void XOR(const gf2n_long& x,const gf2n_long& y) { a=x.a^y.a; } - void OR(const gf2n_long& x,const gf2n_long& y) { a=x.a|y.a; } - void NOT(const gf2n_long& x) { a=(~x.a)&mask; } - void SHL(const gf2n_long& x,int n) { a=(x.a<>n; } - - gf2n_long operator&(const gf2n_long& x) const { gf2n_long res; res.AND(*this, x); return res; } - gf2n_long operator^(const gf2n_long& x) const { gf2n_long res; res.XOR(*this, x); return res; } - gf2n_long operator|(const gf2n_long& x) const { gf2n_long res; res.OR(*this, x); return res; } - gf2n_long operator!() const { gf2n_long res; res.NOT(*this); return res; } - gf2n_long operator<<(int i) const { gf2n_long res; res.SHL(*this, i); return res; } - gf2n_long operator>>(int i) const { gf2n_long res; res.SHR(*this, i); return res; } - - gf2n_long& operator&=(const gf2n_long& x) { AND(*this, x); return *this; } - gf2n_long& operator>>=(int i) { SHR(*this, i); return *this; } - gf2n_long& operator<<=(int i) { SHL(*this, i); return *this; } - - bool operator<(gf2n_long) const { return false; } + gf2n_long operator&(const gf2n_long& x) const { return a & x.a; } + gf2n_long operator^(const gf2n_long& x) const { return a ^ x.a; } + gf2n_long operator|(const gf2n_long& x) const { return a | x.a; } + gf2n_long operator~() const { return ~a; } + gf2n_long operator<<(int i) const { return a << i; } + gf2n_long operator>>(int i) const { return a >> i; } + + gf2n_long& operator&=(const gf2n_long& x) { *this = *this & x; return *this; } + gf2n_long& operator^=(const gf2n_long& x) { *this = *this ^ x; return *this; } + gf2n_long& operator>>=(int i) { *this = *this >> i; return *this; } + gf2n_long& operator<<=(int i) { *this = *this << i; return *this; } /* Crap RNG */ void randomize(PRNG& G, int n = -1); @@ -263,9 +218,6 @@ class gf2n_long : public ValueInterface void force_to_bit() { a &= 1; } - template - T convert() const { return *this; } - void output(ostream& s,bool human) const; void input(istream& s,bool human); @@ -277,7 +229,10 @@ class gf2n_long : public ValueInterface { bigint tmp; s >> hex >> tmp >> dec; x.a = 0; - mpn_copyi((word*)&x.a.a, tmp.get_mpz_t()->_mp_d, tmp.get_mpz_t()->_mp_size); + auto size = tmp.get_mpz_t()->_mp_size; + assert(size >= 0); + assert(size <= 2); + mpn_copyi((mp_limb_t*)&x.a.a, tmp.get_mpz_t()->_mp_d, size); return s; } @@ -357,14 +312,6 @@ inline void mul128(__m128i a, __m128i b, __m128i *res1, __m128i *res2) *res2 = tmp6; } -inline int128 int128::ones(int n) -{ - if (n < 64) - return int128(0, (1ULL << n) - 1); - else - return int128((1ULL << (n - 64)) - 1, -1); -} - inline bool int128::get_bit(int i) const { if (i < 64) diff --git a/Math/gfp.h b/Math/gfp.h index 524cf6c2e..255815fa3 100644 --- a/Math/gfp.h +++ b/Math/gfp.h @@ -9,6 +9,7 @@ using namespace std; #include "Math/Zp_Data.h" #include "Math/field_types.h" #include "Math/Bit.h" +#include "Math/Setup.h" #include "Tools/random.h" #include "GC/NoShare.h" #include "Processor/OnlineOptions.h" @@ -78,8 +79,14 @@ class gfp_ : public ValueInterface template static void generate_setup(string dir, int nplayers, int lgp) { generate_prime_setup(dir, nplayers, lgp); } + template + static void write_setup(int nplayers) + { write_setup(get_prep_sub_dir(nplayers)); } + static void write_setup(string dir) + { write_online_setup(dir, pr()); } + static void check_setup(string dir); - static bigint pr() + static const bigint& pr() { return ZpD.pr; } static int t() { return L; } @@ -108,19 +115,9 @@ class gfp_ : public ValueInterface static gfp_ power_of_two(bool bit, int exp); - void assign(const gfp_& g) { a=g.a; } void assign_zero() { assignZero(a,ZpD); } void assign_one() { assignOne(a,ZpD); } - void assign(word aa) { bigint::tmp=aa; to_gfp(*this,bigint::tmp); } - void assign(long aa) - { - if (aa == 0) - assignZero(a, ZpD); - else - to_gfp(*this, bigint::tmp = aa); - } - void assign(int aa) { assign(long(aa)); } - void assign(const char* buffer) { a.assign(buffer, ZpD.get_t()); } + void assign(const void* buffer) { a.assign(buffer, ZpD.get_t()); } modp_type get() const { return a; } @@ -129,33 +126,20 @@ class gfp_ : public ValueInterface const void* get_ptr() const { return &a.x; } void* get_ptr() { return &a.x; } - // Assumes prD behind x is equal to ZpD - void assign(modp_& x) { a=x; } - gfp_() { assignZero(a,ZpD); } template gfp_(const modp_& g) { a=g; } - gfp_(const __m128i& x) { *this=x; } - gfp_(const int128& x) { *this=x.a; } - gfp_(const bigint& x) { to_modp(a, x, ZpD); } - gfp_(int x) { assign(x); } - gfp_(long x) { assign(x); } - gfp_(word x) { assign(x); } + gfp_(const mpz_class& x) { to_modp(a, x, ZpD); } + gfp_(int x) : gfp_(long(x)) {} + gfp_(long x); + gfp_(word x) : gfp_(bigint::tmp = x) {} template - gfp_(IntBase x) { assign(x.get()); } - gfp_(const void* buffer) { assign((char*)buffer); } + gfp_(IntBase x) : gfp_(x.get()) {} template gfp_(const gfp_& x); gfp_(const gfpvar& other); template gfp_(const SignedZ2& other); - gfp_(GC::NoValue) { GC::NoValue::fail(); } - - gfp_& operator=(const __m128i other) - { - memcpy(a.x, &other, sizeof(other)); - return *this; - } void zero_overhang(); void check(); @@ -172,19 +156,13 @@ class gfp_ : public ValueInterface { add(os.consume(size())); } void add(const gfp_& x,const gfp_& y) { ZpD.Add(a.x,x.a.x,y.a.x); } - void add(const gfp_& x) - { ZpD.Add(a.x,a.x,x.a.x); } void add(void* x) { ZpD.Add(a.x,a.x,(mp_limb_t*)x); } void sub(const gfp_& x,const gfp_& y) { Sub(a,x.a,y.a,ZpD); } - void sub(const gfp_& x) - { Sub(a,a,x.a,ZpD); } // = x * y void mul(const gfp_& x,const gfp_& y) { a.template mul(x.a,y.a,ZpD); } - void mul(const gfp_& x) - { a.template mul(a,x.a,ZpD); } gfp_ lazy_add(const gfp_& x) const { return *this + x; } gfp_ lazy_mul(const gfp_& x) const { return *this * x; } @@ -192,25 +170,16 @@ class gfp_ : public ValueInterface gfp_ operator+(const gfp_& x) const { gfp_ res; res.add(*this, x); return res; } gfp_ operator-(const gfp_& x) const { gfp_ res; res.sub(*this, x); return res; } gfp_ operator*(const gfp_& x) const { gfp_ res; res.mul(*this, x); return res; } - gfp_ operator/(const gfp_& x) const { gfp_ tmp; tmp.invert(x); return *this * tmp; } - gfp_& operator+=(const gfp_& x) { add(x); return *this; } - gfp_& operator-=(const gfp_& x) { sub(x); return *this; } - gfp_& operator*=(const gfp_& x) { mul(x); return *this; } + gfp_ operator/(const gfp_& x) const { return *this * x.invert(); } + gfp_& operator+=(const gfp_& x) { add(*this, x); return *this; } + gfp_& operator-=(const gfp_& x) { sub(*this, x); return *this; } + gfp_& operator*=(const gfp_& x) { mul(*this, x); return *this; } gfp_ operator-() { gfp_ res = *this; res.negate(); return res; } - void square(const gfp_& aa) - { Sqr(a,aa.a,ZpD); } - void square() - { Sqr(a,a,ZpD); } - void invert() - { Inv(a,a,ZpD); } - void invert(const gfp_& aa) - { Inv(a,aa.a,ZpD); } + gfp_ invert() const; void negate() { Negate(a,a,ZpD); } - void power(long i) - { Power(a,a,i,ZpD); } // deterministic square root gfp_ sqrRoot(); @@ -237,26 +206,17 @@ class gfp_ : public ValueInterface /* Bitwise Ops * - Converts gfp args to bigints and then converts answer back to gfp */ - void AND(const gfp_& x,const gfp_& y); - void XOR(const gfp_& x,const gfp_& y); - void OR(const gfp_& x,const gfp_& y); - void AND(const gfp_& x,const bigint& y); - void XOR(const gfp_& x,const bigint& y); - void OR(const gfp_& x,const bigint& y); - void SHL(const gfp_& x,int n); - void SHR(const gfp_& x,int n); - void SHL(const gfp_& x,const bigint& n); - void SHR(const gfp_& x,const bigint& n); - - gfp_ operator&(const gfp_& x) { gfp_ res; res.AND(*this, x); return res; } - gfp_ operator^(const gfp_& x) { gfp_ res; res.XOR(*this, x); return res; } - gfp_ operator|(const gfp_& x) { gfp_ res; res.OR(*this, x); return res; } - gfp_ operator<<(int i) const { gfp_ res; res.SHL(*this, i); return res; } - gfp_ operator>>(int i) const { gfp_ res; res.SHR(*this, i); return res; } - - gfp_& operator&=(const gfp_& x) { AND(*this, x); return *this; } - gfp_& operator<<=(int i) { SHL(*this, i); return *this; } - gfp_& operator>>=(int i) { SHR(*this, i); return *this; } + gfp_ operator&(const gfp_& x) { return (bigint::tmp = *this) &= bigint(x); } + gfp_ operator^(const gfp_& x) { return (bigint::tmp = *this) ^= bigint(x); } + gfp_ operator|(const gfp_& x) { return (bigint::tmp = *this) |= bigint(x); } + gfp_ operator<<(int i) const; + gfp_ operator>>(int i) const; + gfp_ operator<<(const gfp_& i) const; + gfp_ operator>>(const gfp_& i) const; + + gfp_& operator&=(const gfp_& x) { *this = *this & x; return *this; } + gfp_& operator<<=(int i) { *this << i; return *this; } + gfp_& operator>>=(int i) { *this >> i; return *this; } void force_to_bit() { throw runtime_error("impossible"); } @@ -285,6 +245,15 @@ Zp_Data gfp_::ZpD; template thread_local vector> gfp_::powers; +template +gfp_::gfp_(long x) +{ + if (x == 0) + assign_zero(); + else + *this = bigint::tmp = x; +} + template template gfp_::gfp_(const gfp_& x) diff --git a/Math/gfp.hpp b/Math/gfp.hpp index 3ebbe3cff..59d40ab6e 100644 --- a/Math/gfp.hpp +++ b/Math/gfp.hpp @@ -5,7 +5,7 @@ #include "Math/gfpvar.h" #include "Math/Setup.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Math/bigint.hpp" #include "Math/Setup.hpp" @@ -27,22 +27,26 @@ inline void gfp_::read_or_generate_setup(string dir, init_field(opts.prime); } +template +void gfp_::check_setup(string dir) +{ + ::check_setup(dir, pr()); +} + template void gfp_::init_field(const bigint& p, bool mont) { ZpD.init(p, mont); - string name = "gfp<" + to_string(X) + ", " + to_string(L) + ">"; + char name[100]; + snprintf(name, 100, "gfp_<%d, %d>", X, L); if (ZpD.get_t() > L) { - cout << "modulus is " << p << endl; - throw wrong_gfp_size(name + " too small for modulus. " - "Maybe change GFP_MOD_SZ to " + to_string(ZpD.get_t())); + throw wrong_gfp_size(name, p, "GFP_MOD_SZ", ZpD.get_t()); } if (ZpD.get_t() < L) { if (mont) - throw wrong_gfp_size(name + " too large for modulus. " - "Maybe change GFP_MOD_SZ to " + to_string(ZpD.get_t())); + throw wrong_gfp_size(name, p, "GFP_MOD_SZ", ZpD.get_t()); else cerr << name << " larger than necessary for modulus " << p << endl; } @@ -74,121 +78,69 @@ void gfp_::almost_randomize(PRNG& G) a.x[t()-1]&=ZpD.mask; } -template -void gfp_::AND(const gfp_& x,const gfp_& y) -{ - bigint bi1,bi2; - to_bigint(bi1,x); - to_bigint(bi2,y); - mpz_and(bi1.get_mpz_t(), bi1.get_mpz_t(), bi2.get_mpz_t()); - convert_destroy(bi1); -} - -template -void gfp_::OR(const gfp_& x,const gfp_& y) -{ - bigint bi1,bi2; - to_bigint(bi1,x); - to_bigint(bi2,y); - mpz_ior(bi1.get_mpz_t(), bi1.get_mpz_t(), bi2.get_mpz_t()); - convert_destroy(bi1); -} - -template -void gfp_::XOR(const gfp_& x,const gfp_& y) -{ - bigint bi1,bi2; - to_bigint(bi1,x); - to_bigint(bi2,y); - mpz_xor(bi1.get_mpz_t(), bi1.get_mpz_t(), bi2.get_mpz_t()); - convert_destroy(bi1); -} - -template -void gfp_::AND(const gfp_& x,const bigint& y) -{ - bigint bi; - to_bigint(bi,x); - mpz_and(bi.get_mpz_t(), bi.get_mpz_t(), y.get_mpz_t()); - convert_destroy(bi); -} - -template -void gfp_::OR(const gfp_& x,const bigint& y) -{ - bigint bi; - to_bigint(bi,x); - mpz_ior(bi.get_mpz_t(), bi.get_mpz_t(), y.get_mpz_t()); - convert_destroy(bi); -} - -template -void gfp_::XOR(const gfp_& x,const bigint& y) -{ - bigint bi; - to_bigint(bi,x); - mpz_xor(bi.get_mpz_t(), bi.get_mpz_t(), y.get_mpz_t()); - convert_destroy(bi); -} - template -void gfp_::SHL(const gfp_& x,int n) +gfp_ gfp_::operator<<(int n) const { - if (!x.is_zero()) + if (!is_zero()) { if (n != 0) { - *this = x * power_of_two(1, n); + return *this * power_of_two(1, n); } else - assign(x); + return *this; } else { - assign_zero(); + return {}; } } template -void gfp_::SHR(const gfp_& x,int n) +gfp_ gfp_::operator>>(int n) const { - if (!x.is_zero()) + if (!is_zero()) { if (n != 0) { - bigint& bi = bigint::tmp; - to_bigint(bi,x); - bi >>= n; - convert_destroy(bi); + return (bigint::tmp = *this) >>= n; } else - assign(x); + return *this; } else { - assign_zero(); + return {}; } } template -void gfp_::SHL(const gfp_& x,const bigint& n) +gfp_ gfp_::operator<<(const gfp_& i) const { - SHL(x,mpz_get_si(n.get_mpz_t())); + return *this << (bigint::tmp = i).get_ui(); } template -void gfp_::SHR(const gfp_& x,const bigint& n) +gfp_ gfp_::operator>>(const gfp_& i) const { - SHR(x,mpz_get_si(n.get_mpz_t())); + return *this >> (bigint::tmp = i).get_ui(); } +template +gfp_ gfp_::invert() const +{ + gfp_ res; + Inv(res.a, a, ZpD); + return res; +} + template gfp_ gfp_::sqrRoot() { diff --git a/Math/gfpvar.cpp b/Math/gfpvar.cpp index b4cd1a629..d4f8ac486 100644 --- a/Math/gfpvar.cpp +++ b/Math/gfpvar.cpp @@ -50,8 +50,7 @@ void gfpvar::init_field(bigint prime, bool montgomery) { ZpD.init(prime, montgomery); if (ZpD.get_t() > N_LIMBS) - throw wrong_gfp_size("gfpvar too small for modulus. " - "Maybe change MAX_MOD_SZ to " + to_string(ZpD.get_t() * 2)); + throw wrong_gfp_size("gfpvar", prime, "MAX_MOD_SZ", ZpD.get_t() * 2); } void gfpvar::init_default(int lgp, bool montgomery) @@ -76,6 +75,16 @@ void gfpvar::generate_setup>(string prep_data_prefix, generate_prime_setup>(prep_data_prefix, nplayers, lgp); } +void gfpvar::check_setup(string dir) +{ + ::check_setup(dir, pr()); +} + +void gfpvar::write_setup(string dir) +{ + write_online_setup(dir, pr()); +} + gfpvar::gfpvar() { } @@ -148,9 +157,7 @@ gfpvar gfpvar::operator *(const gfpvar& other) const gfpvar gfpvar::operator /(const gfpvar& other) const { - gfpvar tmp; - tmp.invert(other); - return *this * tmp; + return *this * other.invert(); } gfpvar& gfpvar::operator +=(const gfpvar& other) @@ -191,9 +198,11 @@ void gfpvar::negate() *this = gfpvar() - *this; } -void gfpvar::invert(const gfpvar& other) +gfpvar gfpvar::invert() const { - Inv(a, other.a, ZpD); + gfpvar res; + Inv(res.a, a, ZpD); + return res; } gfpvar gfpvar::sqrRoot() const diff --git a/Math/gfpvar.h b/Math/gfpvar.h index 3ea18ba01..319ee55e1 100644 --- a/Math/gfpvar.h +++ b/Math/gfpvar.h @@ -8,6 +8,7 @@ #include "modp.h" #include "Zp_Data.h" +#include "Setup.h" class FFT_Data; @@ -52,6 +53,13 @@ class gfpvar template static void generate_setup(string prep_data_prefix, int nplayers, int lgp); + static void check_setup(string dir); + static void write_setup(string dir); + template + static void write_setup(int nplayers) + { + write_setup(get_prep_sub_dir(nplayers)); + } gfpvar(); gfpvar(int other); @@ -91,7 +99,7 @@ class gfpvar void negate(); - void invert(const gfpvar& other); + gfpvar invert() const; gfpvar sqrRoot() const; diff --git a/Math/modp.h b/Math/modp.h index 42c8bf2d7..0f0bac88b 100644 --- a/Math/modp.h +++ b/Math/modp.h @@ -47,7 +47,7 @@ class modp_ const mp_limb_t* get() const { return x; } - void assign(const char* buffer, int t) { memcpy(x, buffer, t * sizeof(mp_limb_t)); } + void assign(const void* buffer, int t) { memcpy(x, buffer, t * sizeof(mp_limb_t)); } void convert(const mp_limb_t* source, mp_size_t size, const Zp_Data& ZpD, bool negative = false); @@ -84,7 +84,7 @@ class modp_ void mul(const modp_& x, const modp_& y, const Zp_Data& ZpD); template friend void to_modp(modp_& ans,int x,const Zp_Data& ZpD); - template friend void to_modp(modp_& ans,const bigint& x,const Zp_Data& ZpD); + template friend void to_modp(modp_& ans,const mpz_class& x,const Zp_Data& ZpD); friend void Add(modp_& ans,const modp_& x,const modp_& y,const Zp_Data& ZpD) { ZpD.Add(ans.x, x.x, y.x); } diff --git a/Math/modp.hpp b/Math/modp.hpp index 0ac6f91de..94cc4b398 100644 --- a/Math/modp.hpp +++ b/Math/modp.hpp @@ -2,7 +2,7 @@ #include "modp.h" #include "Z2k.hpp" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" /*********************************************************************** * The following functions remain the same in Real and Montgomery rep * @@ -161,7 +161,7 @@ void to_modp(modp_& ans,int x,const Zp_Data& ZpD) template -void to_modp(modp_& ans,const bigint& x,const Zp_Data& ZpD) +void to_modp(modp_& ans,const mpz_class& x,const Zp_Data& ZpD) { if (x == 0) { diff --git a/Math/mpn_fixed.h b/Math/mpn_fixed.h index 130571a02..99cc76b51 100644 --- a/Math/mpn_fixed.h +++ b/Math/mpn_fixed.h @@ -54,9 +54,6 @@ template <> inline void mpn_add_fixed_n<2>(mp_limb_t* res, const mp_limb_t* x, const mp_limb_t* y) { memcpy(res, y, 2 * sizeof(mp_limb_t)); - debug_print("x", x, 2); - debug_print("y", y, 2); - debug_print("res", res, 2); __asm__ ( "add %2, %0 \n" "adc %3, %1 \n" @@ -64,16 +61,12 @@ inline void mpn_add_fixed_n<2>(mp_limb_t* res, const mp_limb_t* x, const mp_limb : "rm"(x[0]), "rm"(x[1]) : "cc" ); - debug_print("res", res, 2); } template <> inline void mpn_add_fixed_n<3>(mp_limb_t* res, const mp_limb_t* x, const mp_limb_t* y) { memcpy(res, y, 3 * sizeof(mp_limb_t)); - debug_print("x", x, 3); - debug_print("y", y, 3); - debug_print("res", res, 3); __asm__ ( "add %3, %0 \n" "adc %4, %1 \n" @@ -82,7 +75,6 @@ inline void mpn_add_fixed_n<3>(mp_limb_t* res, const mp_limb_t* x, const mp_limb : "rm"(x[0]), "rm"(x[1]), "rm"(x[2]) : "cc" ); - debug_print("res", res, 3); } template <> @@ -100,6 +92,15 @@ inline void mpn_add_fixed_n<4>(mp_limb_t* res, const mp_limb_t* x, const mp_limb ); } +#ifdef __clang__ +inline char clang_add_carry(char carryin, unsigned long x, unsigned long y, unsigned long& res) +{ + unsigned long carryout; + res = __builtin_addcl(x, y, carryin, &carryout); + return carryout; +} +#endif + inline mp_limb_t mpn_add_n_with_carry(mp_limb_t* res, const mp_limb_t* x, const mp_limb_t* y, int n) { // This is complicated because we want to use adc(x) whenever possible. @@ -109,14 +110,10 @@ inline mp_limb_t mpn_add_n_with_carry(mp_limb_t* res, const mp_limb_t* x, const { char carry = 0; for (int i = 0; i < n; i++) -#if defined(__clang__) -#if __has_builtin(__builtin_ia32_addcarryx_u64) && defined(__ADX__) - carry = __builtin_ia32_addcarryx_u64(carry, x[i], y[i], (unsigned long long*)&res[i]); -#else - carry = __builtin_ia32_addcarry_u64(carry, x[i], y[i], (unsigned long long*)&res[i]); -#endif -#else +#if defined(__ADX__) carry = _addcarryx_u64(carry, x[i], y[i], (unsigned long long*)&res[i]); +#else + carry = clang_add_carry(carry, x[i], y[i], res[i]); #endif return carry; } @@ -267,16 +264,11 @@ inline void mpn_addmul_1_fixed__(mp_limb_t* res, const mp_limb_t* y, mp_limb_t x higher[L - 1] = 0; for (int j = 0; j < M; j++) lower[j] = _mulx_u64(x, y[j], (long long unsigned*)higher + j); - debug_print("lower", lower, L); - debug_print("higher", higher, L); - debug_print("before add", res, L + 1); if (ADD) mpn_add_fixed_n(res, lower, res); else inline_mpn_copyi(res, lower, L); - debug_print("first add", res, L + 1); mpn_add_fixed_n(res + 1, higher, res + 1); - debug_print("second add", res, L + 1); } template diff --git a/Math/operators.h b/Math/operators.h deleted file mode 100644 index 9e3800bbf..000000000 --- a/Math/operators.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * operations.h - * - */ - -#ifndef MATH_OPERATORS_H_ -#define MATH_OPERATORS_H_ - -//template -//T operator*(const bool& x, const T& y) { return x ? y : T(); } -//template -//T operator*(const T& y, const bool& x) { return x ? y : T(); } -template -T& operator*=(T& y, const bool& x) { y = x ? y : T(); return y; } - -//template -//T operator+(const T& x, const U& y) { T res; res.add(x, y); return res; } -//template -//T operator*(const T& x, const T& y) { T res; res.mul(x, y); return res; } -//template -//T operator-(const T& x, const U& y) { T res; res.sub(x, y); return res; } - -//template -//T& operator+=(T& x, const U& y) { x.add(y); return x; } -//template -//T& operator*=(T& x, const T& y) { x.mul(y); return x; } -//template -//T& operator-=(T& x, const U& y) { x.sub(y); return x; } - -//template -//T operator/(const T& x, const U& y) { U inv = y; inv.invert(); return x * inv; } -template -T& operator/=(const T& x, const U& y) { U inv = y; inv.invert(); return x *= inv; } - -#endif /* MATH_OPERATORS_H_ */ diff --git a/Networking/Player.cpp b/Networking/Player.cpp index b87dd73bc..67faf8b38 100644 --- a/Networking/Player.cpp +++ b/Networking/Player.cpp @@ -1,7 +1,7 @@ #include "Player.h" #include "ssl_sockets.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Tools/int.h" #include "Tools/NetworkOptions.h" #include "Networking/Server.h" diff --git a/Networking/Server.cpp b/Networking/Server.cpp index 7ccb4b195..25476114f 100644 --- a/Networking/Server.cpp +++ b/Networking/Server.cpp @@ -154,7 +154,6 @@ void Server::start() void* Server::start_in_thread(void* server) { ((Server*)server)->start(); - pthread_detach(pthread_self()); return 0; } @@ -168,12 +167,17 @@ Server* Server::start_networking(Names& N, int my_num, int nplayers, assert(my_num >= 0); assert(my_num < nplayers); Server* server = 0; + pthread_t thread; if (my_num == 0) { - pthread_t thread; pthread_create(&thread, 0, Server::start_in_thread, server = new Server(nplayers, portnum)); } N.init(my_num, portnum, Names::DEFAULT_PORT, hostname.c_str()); - return server; + if (my_num == 0) + { + pthread_join(thread, 0); + delete server; + } + return 0; } diff --git a/Networking/ServerSocket.cpp b/Networking/ServerSocket.cpp index 7d1808191..781ace0b8 100644 --- a/Networking/ServerSocket.cpp +++ b/Networking/ServerSocket.cpp @@ -5,7 +5,7 @@ #include #include -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include #include diff --git a/Networking/data.h b/Networking/data.h index bb34c0c09..60b8b0326 100644 --- a/Networking/data.h +++ b/Networking/data.h @@ -3,8 +3,9 @@ #include -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Tools/avx_memcpy.h" +#include "Tools/int.h" #ifdef __APPLE__ # include @@ -16,15 +17,6 @@ #include #endif -typedef unsigned char octet; - -// Assumes word is a 64 bit value -#ifdef WIN32 - typedef unsigned __int64 word; -#else - typedef unsigned long word; -#endif - inline void encode_length(octet *buff, size_t len, size_t n_bytes) { diff --git a/Networking/sockets.cpp b/Networking/sockets.cpp index eeb7ce43b..ab3a194aa 100644 --- a/Networking/sockets.cpp +++ b/Networking/sockets.cpp @@ -1,6 +1,6 @@ #include "sockets.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Tools/time-func.h" #include diff --git a/OT/NPartyTripleGenerator.hpp b/OT/NPartyTripleGenerator.hpp index 18867475a..08c2c7b65 100644 --- a/OT/NPartyTripleGenerator.hpp +++ b/OT/NPartyTripleGenerator.hpp @@ -5,7 +5,6 @@ #include "OT/OTExtensionWithMatrix.h" #include "OT/OTMultiplier.h" -#include "Math/operators.h" #include "Tools/Subroutines.h" #include "Protocols/MAC_Check.h" #include "GC/SemiSecret.h" @@ -322,7 +321,7 @@ void MascotTripleGenerator::generateBitsGf2n() r.randomize(G); check_sum += r * bits[j]; } - bits.resize(this->nTriplesPerLoop); + bits.resize(nTriplesPerLoop); to_open[0] = check_sum; MC.POpen_Begin(opened, to_open, globalPlayer); @@ -446,7 +445,7 @@ void Spdz2kTripleGenerator::generateTriples() // get piggy-backed random value Z2 r_share = b_padded_bits.get_ptr_to_byte(nTriplesPerLoop, Z2::N_BYTES); Z2 r_mac; - r_mac.mul(r_share, this->get_mac_key()); + r_mac = (r_share * this->get_mac_key()); for (int i = 0; i < this->nparties-1; i++) r_mac += (ot_multipliers[i])->macs.at(1).at(nTriplesPerLoop); Share> r; diff --git a/OT/OTExtension.h b/OT/OTExtension.h index ddc77478c..87a3d48e9 100644 --- a/OT/OTExtension.h +++ b/OT/OTExtension.h @@ -3,7 +3,7 @@ #include "OT/BaseOT.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Networking/Player.h" diff --git a/OT/Row.hpp b/OT/Row.hpp index 5e1869513..b43923244 100644 --- a/OT/Row.hpp +++ b/OT/Row.hpp @@ -1,5 +1,5 @@ #include "OT/Row.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" template bool Row::operator ==(const Row& other) const diff --git a/OT/Triple.hpp b/OT/Triple.hpp index 318082e9e..cf8591be4 100644 --- a/OT/Triple.hpp +++ b/OT/Triple.hpp @@ -142,7 +142,7 @@ class ShareTriple : public Triple { typename U::share_type value = triple.byIndex(l,j); typename U::mac_type mac; - mac.mul(value, generator.get_mac_key()); + mac = (value * generator.get_mac_key()); for (int i = 0; i < generator.nparties-1; i++) mac += generator.ot_multipliers[i]->macs.at(l).at(iTriple * repeat + j); U& share = this->byIndex(l,j); diff --git a/Processor/BaseMachine.cpp b/Processor/BaseMachine.cpp index 2bc94032b..1eea739a8 100644 --- a/Processor/BaseMachine.cpp +++ b/Processor/BaseMachine.cpp @@ -13,6 +13,12 @@ using namespace std; BaseMachine* BaseMachine::singleton = 0; thread_local int BaseMachine::thread_num; +void print_usage(ostream& o, const char* name, size_t capacity) +{ + if (capacity) + o << name << "=" << capacity << " "; +} + BaseMachine& BaseMachine::s() { if (singleton) @@ -29,7 +35,7 @@ BaseMachine::BaseMachine() : nthreads(0) singleton = this; } -void BaseMachine::load_schedule(string progname, bool load_bytecode) +void BaseMachine::load_schedule(const string& progname, bool load_bytecode) { this->progname = progname; string fname = "Programs/Schedules/" + progname + ".sch"; @@ -56,9 +62,10 @@ void BaseMachine::load_schedule(string progname, bool load_bytecode) string threadname; for (int i=0; i> threadname; + string filename = "Programs/Bytecode/" + threadname + ".bc"; + bc_filenames.push_back(filename); if (load_bytecode) { - string filename = "Programs/Bytecode/" + threadname + ".bc"; #ifdef DEBUG_FILES cerr << "Loading program " << i << " from " << filename << endl; #endif @@ -88,7 +95,7 @@ void BaseMachine::print_compiler() #endif } -void BaseMachine::load_program(string threadname, string filename) +void BaseMachine::load_program(const string& threadname, const string& filename) { (void)threadname; (void)filename; @@ -121,7 +128,7 @@ void BaseMachine::print_timers() cerr << "Time" << it->first << " = " << it->second.elapsed() << " seconds " << endl; } -string BaseMachine::memory_filename(string type_short, int my_number) +string BaseMachine::memory_filename(const string& type_short, int my_number) { return PREP_DIR "Memory-" + type_short + "-P" + to_string(my_number); } diff --git a/Processor/BaseMachine.h b/Processor/BaseMachine.h index 2e4f92ee3..9b80a001a 100644 --- a/Processor/BaseMachine.h +++ b/Processor/BaseMachine.h @@ -15,6 +15,8 @@ #include using namespace std; +void print_usage(ostream& o, const char* name, size_t capacity); + class BaseMachine { protected: @@ -27,7 +29,7 @@ class BaseMachine void print_timers(); - virtual void load_program(string threadname, string filename); + virtual void load_program(const string& threadname, const string& filename); public: static thread_local int thread_num; @@ -39,10 +41,12 @@ class BaseMachine ThreadQueues queues; + vector bc_filenames; + static BaseMachine& s(); static bool has_singleton() { return singleton != 0; } - static string memory_filename(string type_short, int my_number); + static string memory_filename(const string& type_short, int my_number); static string get_domain(string progname); static int ring_size_from_schedule(string progname); @@ -52,14 +56,14 @@ class BaseMachine BaseMachine(); virtual ~BaseMachine() {} - void load_schedule(string progname, bool load_bytecode = true); + void load_schedule(const string& progname, bool load_bytecode = true); void print_compiler(); void time(); void start(int n); void stop(int n); - virtual void reqbl(int n) { (void)n; throw runtime_error("not defined"); } + virtual void reqbl(int) {} OTTripleSetup fresh_ot_setup(); }; diff --git a/Processor/Binary_File_IO.h b/Processor/Binary_File_IO.h index b41fc7d00..11e05a23d 100644 --- a/Processor/Binary_File_IO.h +++ b/Processor/Binary_File_IO.h @@ -1,7 +1,7 @@ #ifndef _FILE_IO_HEADER #define _FILE_IO_HEADER -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include #include diff --git a/Processor/DataPositions.cpp b/Processor/DataPositions.cpp index 3e72cd1ba..fc8ebf185 100644 --- a/Processor/DataPositions.cpp +++ b/Processor/DataPositions.cpp @@ -12,12 +12,36 @@ const char* DataPositions::field_names[] = { "int", "gf2n", "bit" }; const int DataPositions::tuple_size[N_DTYPE] = { 3, 2, 1, 2, 3, 3 }; +DataPositions::DataPositions(int num_players) +{ + set_num_players(num_players); +} + +DataPositions::~DataPositions() +{ +} + +void DataPositions::reset() +{ + *this = DataPositions(num_players()); +} + void DataPositions::set_num_players(int num_players) { files = {}; inputs.resize(num_players, {}); } +void DataPositions::count(DataFieldType type, DataTag tag, int n) +{ + extended[type][tag] += n; +} + +void DataPositions::count_edabit(bool strict, int n_bits) +{ + edabits[{strict, n_bits}]++; +} + void DataPositions::increase(const DataPositions& delta) { inputs.resize(max(inputs.size(), delta.inputs.size()), {}); @@ -165,3 +189,35 @@ bool DataPositions::empty() const return true; } + +bool DataPositions::any_more(const DataPositions& other) const +{ + for (unsigned int field_type = 0; field_type < N_DATA_FIELD_TYPE; + field_type++) + { + for (unsigned int dtype = 0; dtype < N_DTYPE; dtype++) + if (files[field_type][dtype] > other.files[field_type][dtype]) + return true; + for (unsigned int j = 0; j < min(inputs.size(), other.inputs.size()); j++) + if (inputs[j][field_type] > other.inputs[j][field_type]) + return true; + + auto& ext = extended[field_type]; + auto& other_ext = other.extended[field_type]; + for (auto it = ext.begin(); it != ext.end(); it++) + { + auto x = other_ext.find(it->first); + if (x == other_ext.end() or it->second > x->second) + return true; + } + } + + for (auto it = edabits.begin(); it != edabits.end(); it++) + { + auto x = other.edabits.find(it->first); + if (x == other.edabits.end() or it->second > x->second) + return true; + } + + return false; +} diff --git a/Processor/Data_Files.h b/Processor/Data_Files.h index 791b2ca9d..770776dd8 100644 --- a/Processor/Data_Files.h +++ b/Processor/Data_Files.h @@ -11,6 +11,7 @@ #include "Tools/Lock.h" #include "Networking/Player.h" #include "Protocols/edabit.h" +#include "PrepBase.h" #include #include @@ -58,15 +59,22 @@ class DataPositions array, N_DATA_FIELD_TYPE> extended; map, long long> edabits; - DataPositions(int num_players = 0) { set_num_players(num_players); } - void reset() { *this = DataPositions(inputs.size()); } + DataPositions(int num_players = 0); + ~DataPositions(); + + void reset(); void set_num_players(int num_players); int num_players() { return inputs.size(); } + + void count(DataFieldType type, DataTag tag, int n = 1); + void count_edabit(bool strict, int n_bits); + void increase(const DataPositions& delta); DataPositions& operator-=(const DataPositions& delta); DataPositions operator-(const DataPositions& delta) const; void print_cost() const; bool empty() const; + bool any_more(const DataPositions& other) const; }; template class Processor; @@ -75,7 +83,7 @@ template class Machine; template class SubProcessor; template -class Preprocessing +class Preprocessing : public PrepBase { protected: DataPositions& usage; @@ -83,10 +91,20 @@ class Preprocessing map, vector>> edabits; map, edabitvec> my_edabits; - void count(Dtype dtype) { usage.files[T::field_type()][dtype]++; } - void count(DataTag tag, int n = 1) { usage.extended[T::field_type()][tag] += n; } - void count_input(int player) { usage.inputs[player][T::field_type()]++; } - void count_edabit(bool strict, int n_bits) { usage.edabits[{strict, n_bits}]++; } + bool do_count; + + void count(Dtype dtype, int n = 1) { usage.files[T::field_type()][dtype] += do_count * n; } + void count_input(int player) { usage.inputs[player][T::field_type()] += do_count; } + + template + void get_edabits(bool strict, size_t size, T* a, + vector& Sb, const vector& regs, false_type); + template + void get_edabits(bool, size_t, T*, vector&, + const vector&, true_type) + { throw not_implemented(); } + + T get_random_from_inputs(int nplayers); public: template @@ -95,7 +113,7 @@ class Preprocessing static Preprocessing* get_live_prep(SubProcessor* proc, DataPositions& usage); - Preprocessing(DataPositions& usage) : usage(usage) {} + Preprocessing(DataPositions& usage) : usage(usage), do_count(true) {} virtual ~Preprocessing() {} virtual void set_protocol(typename T::Protocol& protocol) = 0; @@ -123,12 +141,18 @@ class Preprocessing void get(vector& S, DataTag tag, const vector& regs, int vector_size); virtual array get_triple(int n_bits); + virtual array get_triple_no_count(int n_bits); virtual T get_bit(); + virtual T get_random(); virtual void get_dabit(T&, typename T::bit_type&); virtual void get_dabit_no_count(T&, typename T::bit_type&) { throw runtime_error("no daBit"); } virtual void get_edabits(bool strict, size_t size, T* a, - vector& Sb, const vector& regs); - virtual void get_edabit_no_count(bool, int n_bits, edabit& eb); + vector& Sb, const vector& regs) + { get_edabits<0>(strict, size, a, Sb, regs, T::clear::characteristic_two); } + template + void get_edabit_no_count(bool, int n_bits, edabit& eb); + template + edabitvec get_edabitvec(bool strict, int n_bits); virtual void buffer_edabits_with_queues(bool, int) { throw runtime_error("no edaBits"); } virtual void push_triples(const vector>&) @@ -145,9 +169,6 @@ class Sub_Data_Files : public Preprocessing { template friend class Sub_Data_Files; - static map tuple_lengths; - static Lock tuple_lengths_lock; - static int tuple_length(int dtype); BufferOwner buffers[N_DTYPE]; @@ -164,10 +185,20 @@ class Sub_Data_Files : public Preprocessing Sub_Data_Files* part; - void buffer_edabits_with_queues(bool stric, int n_bits); + void buffer_edabits_with_queues(bool strict, int n_bits) + { buffer_edabits_with_queues<0>(strict, n_bits, T::clear::characteristic_two); } + template + void buffer_edabits_with_queues(bool strict, int n_bits, false_type); + template + void buffer_edabits_with_queues(bool, int, true_type) + { throw not_implemented(); } public: - static string get_suffix(int thread_num); + static string get_filename(const Names& N, Dtype type, int thread_num = 0); + static string get_input_filename(const Names& N, int input_player, + int thread_num = 0); + static string get_edabit_filename(const Names& N, int n_bits, + int thread_num = 0); Sub_Data_Files(int my_num, int num_players, const string& prep_data_dir, DataPositions& usage, int thread_num = -1); @@ -298,7 +329,9 @@ inline void Preprocessing::get(Dtype dtype, T* a) template inline void Preprocessing::get_three(Dtype dtype, T& a, T& b, T& c) { - count(dtype); + // count bit triples in get_triple() + if (T::field_type() != DATA_GF2) + count(dtype); get_three_no_count(dtype, a, b, c); } @@ -327,14 +360,23 @@ template inline void Preprocessing::get(vector& S, DataTag tag, const vector& regs, int vector_size) { - count(tag, vector_size); + usage.count(T::field_type(), tag, vector_size); get_no_count(S, tag, regs, vector_size); } template array Preprocessing::get_triple(int n_bits) { - (void) n_bits; + if (T::field_type() == DATA_GF2) + count(DATA_TRIPLE, n_bits); + return get_triple_no_count(n_bits); +} + +template +array Preprocessing::get_triple_no_count(int n_bits) +{ + assert(T::field_type() != DATA_GF2 or T::default_length == 1 or + T::default_length == n_bits or not do_count); array res; get(DATA_TRIPLE, res.data()); return res; @@ -348,6 +390,12 @@ T Preprocessing::get_bit() return res; } +template +T Preprocessing::get_random() +{ + return get_random_from_inputs(usage.inputs.size()); +} + template inline void Data_Files::purge() { diff --git a/Processor/Data_Files.hpp b/Processor/Data_Files.hpp index ae28e8c4c..dca9a9079 100644 --- a/Processor/Data_Files.hpp +++ b/Processor/Data_Files.hpp @@ -6,10 +6,7 @@ #include "Protocols/dabit.h" #include "Math/Setup.h" -template -Lock Sub_Data_Files::tuple_lengths_lock; -template -map Sub_Data_Files::tuple_lengths; +#include "Protocols/MascotPrep.hpp" template Preprocessing* Preprocessing::get_live_prep(SubProcessor* proc, @@ -39,17 +36,28 @@ int Sub_Data_Files::tuple_length(int dtype) } template -string Sub_Data_Files::get_suffix(int thread_num) +string Sub_Data_Files::get_filename(const Names& N, Dtype type, + int thread_num) { -#ifdef INSECURE - (void) thread_num; - return ""; -#else - if (thread_num >= 0) - return "-T" + to_string(thread_num); - else - return ""; -#endif + return PrepBase::get_filename(get_prep_sub_dir(N.num_players()), + type, T::type_short(), N.my_num(), thread_num); +} + +template +string Sub_Data_Files::get_input_filename(const Names& N, int input_player, + int thread_num) +{ + return PrepBase::get_input_filename( + get_prep_sub_dir(N.num_players()), T::type_short(), input_player, + N.my_num(), thread_num); +} + +template +string Sub_Data_Files::get_edabit_filename(const Names& N, int n_bits, + int thread_num) +{ + return PrepBase::get_edabit_filename( + get_prep_sub_dir(N.num_players()), n_bits, N.my_num(), thread_num); } template @@ -62,35 +70,37 @@ Sub_Data_Files::Sub_Data_Files(int my_num, int num_players, #ifdef DEBUG_FILES cerr << "Setting up Data_Files in: " << prep_data_dir << endl; #endif - char filename[1024]; - string suffix = get_suffix(thread_num); + T::clear::check_setup(prep_data_dir); + string type_short = T::type_short(); + string type_string = T::type_string(); + for (int dtype = 0; dtype < N_DTYPE; dtype++) { if (T::clear::allows(Dtype(dtype))) { - sprintf(filename,(prep_data_dir + "%s-%s-P%d%s").c_str(),DataPositions::dtype_names[dtype], - (T::type_short()).c_str(),my_num,suffix.c_str()); - buffers[dtype].setup(filename, - tuple_length(dtype), DataPositions::dtype_names[dtype]); + buffers[dtype].setup( + PrepBase::get_filename(prep_data_dir, Dtype(dtype), type_short, + my_num, thread_num), tuple_length(dtype), type_string, + DataPositions::dtype_names[dtype]); } } - sprintf(filename, (prep_data_dir + "%s-%s-P%d%s").c_str(), - DataPositions::dtype_names[DATA_DABIT], (T::type_short()).c_str(), my_num, - suffix.c_str()); - dabit_buffer.setup(filename, 1, DataPositions::dtype_names[DATA_DABIT]); + dabit_buffer.setup( + PrepBase::get_filename(prep_data_dir, DATA_DABIT, + type_short, my_num, thread_num), 1, type_string, + DataPositions::dtype_names[DATA_DABIT]); input_buffers.resize(num_players); for (int i=0; i::~Data_Files() template Sub_Data_Files::~Sub_Data_Files() { - for (int i = 0; i < N_DTYPE; i++) - buffers[i].close(); - for (int i = 0; i < num_players; i++) - input_buffers[i].close(); - my_input_buffers.close(); - for (auto it = - extended.begin(); it != extended.end(); it++) - it->second.close(); - dabit_buffer.close(); for (auto& x: edabit_buffers) { - x.second->close(); delete x.second; } if (part != 0) @@ -216,31 +216,17 @@ void Sub_Data_Files::purge() template void Sub_Data_Files::setup_extended(const DataTag& tag, int tuple_size) { - BufferBase& buffer = extended[tag]; - tuple_lengths_lock.lock(); - int tuple_length = tuple_lengths[tag]; - int my_tuple_length = tuple_size * T::size(); - if (tuple_length > 0) - { - if (tuple_size > 0 && my_tuple_length != tuple_length) - { - stringstream ss; - ss << "Inconsistent size of " << T::type_string() << " " - << tag.get_string() << ": " << my_tuple_length << " vs " - << tuple_length; - throw Processor_Error(ss.str()); - } - } - else - tuple_lengths[tag] = my_tuple_length; - tuple_lengths_lock.unlock(); + auto& buffer = extended[tag]; + int tuple_length = tuple_size * T::size(); if (!buffer.is_up()) { stringstream ss; ss << prep_data_dir << tag.get_string() << "-" << T::type_short() << "-P" << my_num; - extended[tag].setup(ss.str(), tuple_length); + buffer.setup(ss.str(), tuple_length); } + + buffer.check_tuple_length(tuple_length); } template @@ -262,15 +248,17 @@ void Sub_Data_Files::get_dabit_no_count(T& a, typename T::bit_type& b) } template -void Sub_Data_Files::buffer_edabits_with_queues(bool strict, int n_bits) +template +void Sub_Data_Files::buffer_edabits_with_queues(bool strict, int n_bits, + false_type) { #ifndef INSECURE throw runtime_error("no secure implementation of reading edaBits from files"); #endif if (edabit_buffers.find(n_bits) == edabit_buffers.end()) { - string filename = prep_data_dir + "edaBits-" + to_string(n_bits) + "-P" - + to_string(my_num); + string filename = PrepBase::get_edabit_filename(prep_data_dir, + n_bits, my_num, thread_num); ifstream* f = new ifstream(filename); if (f->fail()) throw runtime_error("cannot open " + filename); diff --git a/Processor/DummyProtocol.h b/Processor/DummyProtocol.h index c6ac9b544..a1d9aacda 100644 --- a/Processor/DummyProtocol.h +++ b/Processor/DummyProtocol.h @@ -190,9 +190,9 @@ class NotImplementedInput NotImplementedInput(const T&, const U&, const W&) { } - NotImplementedInput(Player& P) + template + NotImplementedInput(const T&) { - (void) P; } void start(int n, vector regs) { @@ -241,6 +241,11 @@ class NotImplementedInput { throw not_implemented(); } + template + void add_from_all(U) + { + throw not_implemented(); + } void exchange() { throw not_implemented(); diff --git a/Processor/ExternalClients.cpp b/Processor/ExternalClients.cpp index c0236823f..974392181 100644 --- a/Processor/ExternalClients.cpp +++ b/Processor/ExternalClients.cpp @@ -40,7 +40,7 @@ int ExternalClients::get_client_connection(int portnum_base) if (it == client_connection_servers.end()) { cerr << "Thread " << this_thread::get_id() << " didn't find server." << endl; - return -1; + throw runtime_error("No connection on port " + to_string(portnum_base)); } cerr << "Thread " << this_thread::get_id() << " found server." << endl; int client_id, socket; diff --git a/Processor/ExternalClients.h b/Processor/ExternalClients.h index e6e50d8ea..1306f973c 100644 --- a/Processor/ExternalClients.h +++ b/Processor/ExternalClients.h @@ -3,7 +3,7 @@ #include "Networking/sockets.h" #include "Networking/ssl_sockets.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include #include #include diff --git a/Processor/FieldMachine.h b/Processor/FieldMachine.h index 4deb8cabf..c544fb96a 100644 --- a/Processor/FieldMachine.h +++ b/Processor/FieldMachine.h @@ -7,9 +7,10 @@ #define PROCESSOR_FIELDMACHINE_H_ #include "RingMachine.h" +#include "HonestMajorityMachine.h" #include "Tools/ezOptionParser.h" -template class U> +template class U, class V = HonestMajorityMachine> class HonestMajorityFieldMachine { public: @@ -26,7 +27,8 @@ class FieldMachine OnlineOptions& online_opts, int nplayers = 0); }; -template class T, template class V = T, class W = gf2n> +template class T, template class V = T, + class W = gf2n, class X = DishonestMajorityMachine> class DishonestMajorityFieldMachine { public: @@ -36,8 +38,7 @@ class DishonestMajorityFieldMachine OnlineOptions& online_opts = OnlineOptions::singleton; online_opts = {opt, argc, argv, 1000, live_prep_default, true}; - FieldMachine(argc, argv, opt, - online_opts); + FieldMachine(argc, argv, opt, online_opts); } }; diff --git a/Processor/FieldMachine.hpp b/Processor/FieldMachine.hpp index d0f357b8b..f93517d98 100644 --- a/Processor/FieldMachine.hpp +++ b/Processor/FieldMachine.hpp @@ -12,20 +12,20 @@ #include "OnlineMachine.hpp" -template class T> -HonestMajorityFieldMachine::HonestMajorityFieldMachine(int argc, +template class T, class V> +HonestMajorityFieldMachine::HonestMajorityFieldMachine(int argc, const char **argv) { ez::ezOptionParser opt; HonestMajorityFieldMachine(argc, argv, opt); } -template class T> -HonestMajorityFieldMachine::HonestMajorityFieldMachine(int argc, +template class T, class V> +HonestMajorityFieldMachine::HonestMajorityFieldMachine(int argc, const char **argv, ez::ezOptionParser& opt, int nplayers) { OnlineOptions online_opts(opt, argc, argv, 0, true, true); - FieldMachine(argc, argv, opt, online_opts, + FieldMachine(argc, argv, opt, online_opts, nplayers); } diff --git a/Processor/Input.hpp b/Processor/Input.hpp index fc7914e18..044872e72 100644 --- a/Processor/Input.hpp +++ b/Processor/Input.hpp @@ -327,7 +327,7 @@ void InputBase::input_mixed(SubProcessor& Proc, const vector& args, X(IntInput) X(FixInput) X(FloatInput) #undef X default: - throw runtime_error("unknown input type: " + to_string(type)); + throw unknown_input_type(type); } i += n_arg_tuple; last_type = type; @@ -351,7 +351,7 @@ void InputBase::input_mixed(SubProcessor& Proc, const vector& args, X(IntInput) X(FixInput) X(FloatInput) #undef X default: - throw runtime_error("unknown input type: " + to_string(type)); + throw unknown_input_type(type); } i += n_arg_tuple; } diff --git a/Processor/Instruction.cpp b/Processor/Instruction.cpp new file mode 100644 index 000000000..db03d6d06 --- /dev/null +++ b/Processor/Instruction.cpp @@ -0,0 +1,95 @@ +/* + * Instruction.cpp + * + */ + +#include "Instruction.h" +#include "instructions.h" +#include "Processor.h" +#include "Math/gf2n.h" + +#include + +template +void Instruction::execute_clear_gf2n(vector& registers, + vector& memory, ArithmeticProcessor& Proc) const +{ + auto& C2 = registers; + auto& M2C = memory; + switch (opcode) + { +#define X(NAME, PRE, CODE) \ + case NAME: { PRE; for (int i = 0; i < size; i++) { CODE; } } break; + CLEAR_GF2N_INSTRUCTIONS +#undef X + } +} + +template +void Instruction::gbitdec(vector& registers) const +{ + for (int j = 0; j < size; j++) + { + typename cgf2n::internal_type a = registers.at(r[0] + j).get(); + for (unsigned int i = 0; i < start.size(); i++) + { + registers.at(start[i] + j) = a & 1; + a >>= n; + } + } +} + +template +void Instruction::gbitcom(vector& registers) const +{ + for (int j = 0; j < size; j++) + { + typename cgf2n::internal_type a = 0; + for (unsigned int i = 0; i < start.size(); i++) + { + a ^= registers.at(start[i] + j).get() << (i * n); + } + registers.at(r[0] + j) = a; + } +} + +void Instruction::execute_regint(ArithmeticProcessor& Proc, vector& Mi) const +{ + (void) Mi; + auto& Ci = Proc.get_Ci(); + switch (opcode) + { +#define X(NAME, PRE, CODE) \ + case NAME: { PRE; for (int i = 0; i < size; i++) { CODE; } } break; + REGINT_INSTRUCTIONS +#undef X + } +} + +void Instruction::shuffle(ArithmeticProcessor& Proc) const +{ + for (int i = 0; i < size; i++) + Proc.write_Ci(r[0] + i, Proc.read_Ci(r[1] + i)); + for (int i = 0; i < size; i++) + { + int j = Proc.shared_prng.get_uint(size - i); + swap(Proc.get_Ci_ref(r[0] + i), Proc.get_Ci_ref(r[0] + i + j)); + } +} + +void Instruction::bitdecint(ArithmeticProcessor& Proc) const +{ + for (int j = 0; j < size; j++) + { + long a = Proc.read_Ci(r[0] + j); + for (unsigned int i = 0; i < start.size(); i++) + { + Proc.get_Ci_ref(start[i] + j) = (a >> i) & 1; + } + } +} + +template void Instruction::execute_clear_gf2n(vector& registers, + vector& memory, ArithmeticProcessor& Proc) const; +template void Instruction::execute_clear_gf2n(vector& registers, + vector& memory, ArithmeticProcessor& Proc) const; diff --git a/Processor/Instruction.h b/Processor/Instruction.h index bd8fdb97b..1a0508bc1 100644 --- a/Processor/Instruction.h +++ b/Processor/Instruction.h @@ -13,6 +13,7 @@ using namespace std; template class Machine; template class Processor; +class ArithmeticProcessor; /* * Opcode constants @@ -112,6 +113,7 @@ enum EDABIT = 0x59, SEDABIT = 0x5A, RANDOMS = 0x5B, + RANDOMFULLS = 0x5D, // Input INPUT = 0x60, INPUTFIX = 0xF0, @@ -311,19 +313,6 @@ struct TempVars { sint Sansp; bigint aa,aa2; typename sint::open_type rrp, xip; - // assign without allocation - void assign_ansp(unsigned int n) - { - ansp = int(n); - } - void assign_ansp(int n) - { - ansp = n; - } - void assign_ansp(long n) - { - ansp = n; - } }; @@ -378,6 +367,20 @@ class Instruction : public BaseInstruction // and streams pointing to the triples etc template void execute(Processor& Proc) const; + + template + void execute_clear_gf2n(vector& registers, vector& memory, + ArithmeticProcessor& Proc) const; + + template + void gbitdec(vector& registers) const; + template + void gbitcom(vector& registers) const; + + void execute_regint(ArithmeticProcessor& Proc, vector& Mi) const; + + void shuffle(ArithmeticProcessor& Proc) const; + void bitdecint(ArithmeticProcessor& Proc) const; }; #endif diff --git a/Processor/Instruction.hpp b/Processor/Instruction.hpp index 1e3ecf6b8..bc3f1c3d6 100644 --- a/Processor/Instruction.hpp +++ b/Processor/Instruction.hpp @@ -8,7 +8,7 @@ #include "Processor/FixInput.h" #include "Processor/FloatInput.h" #include "Processor/instructions.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Tools/time-func.h" #include "Tools/parse.h" #include "GC/Instruction.h" @@ -139,11 +139,6 @@ void BaseInstruction::parse_operands(istream& s, int pos, int file_pos) case LTZC: case EQZC: case RAND: - case PROTECTMEMS: - case PROTECTMEMC: - case GPROTECTMEMS: - case GPROTECTMEMC: - case PROTECTMEMINT: case DABIT: case SHUFFLE: r[0]=get_int(s); @@ -152,7 +147,7 @@ void BaseInstruction::parse_operands(istream& s, int pos, int file_pos) // instructions with 1 register operand case BIT: case BITB: - case PRINTMEM: + case RANDOMFULLS: case PRINTREGPLAIN: case PRINTREGPLAINB: case LDTN: @@ -160,7 +155,6 @@ void BaseInstruction::parse_operands(istream& s, int pos, int file_pos) case STARG: case JMPI: case GBIT: - case GPRINTMEM: case GPRINTREGPLAIN: case JOIN_TAPE: case PUSHINT: @@ -168,8 +162,6 @@ void BaseInstruction::parse_operands(istream& s, int pos, int file_pos) case PUBINPUT: case RAWOUTPUT: case GRAWOUTPUT: - case PRINTCHRINT: - case PRINTSTRINT: case PRINTINT: case NPLAYERS: case THRESHOLD: @@ -370,6 +362,18 @@ void BaseInstruction::parse_operands(istream& s, int pos, int file_pos) case STOPINPUT: case GSTOPINPUT: throw runtime_error("two-stage input not supported any more"); + case PRINTMEM: + case GPRINTMEM: + throw runtime_error("memory printing not supported any more"); + case PRINTCHRINT: + case PRINTSTRINT: + throw runtime_error("run-time printing not supported any more"); + case PROTECTMEMS: + case PROTECTMEMC: + case GPROTECTMEMS: + case GPROTECTMEMC: + case PROTECTMEMINT: + throw runtime_error("memory protection not supported any more"); case GBITDEC: case GBITCOM: num_var_args = get_int(s) - 2; @@ -797,9 +801,6 @@ ostream& operator<<(ostream& s,const Instruction& instr) template -#ifndef __clang__ -__attribute__((always_inline)) -#endif inline void Instruction::execute(Processor& Proc) const { auto& Procp = Proc.Procp; @@ -808,43 +809,6 @@ inline void Instruction::execute(Processor& Proc) const // optimize some instructions switch (opcode) { - case GADDC: - for (int i = 0; i < size; i++) - Proc.get_C2_ref(r[0] + i).add(Proc.read_C2(r[1] + i),Proc.read_C2(r[2] + i)); - return; - case GADDS: - for (int i = 0; i < size; i++) - Proc.get_S2_ref(r[0] + i).add(Proc.read_S2(r[1] + i),Proc.read_S2(r[2] + i)); - return; - case GMOVC: - for (int i = 0; i < size; i++) - Proc.write_C2(r[0] + i, Proc.read_C2(r[1] + i)); - return; - case GANDC: - for (int i = 0; i < size; i++) - Proc.get_C2_ref(r[0] + i).AND(Proc.read_C2(r[1] + i),Proc.read_C2(r[2] + i)); - return; - case GSHLCI: - for (int i = 0; i < size; i++) - Proc.get_C2_ref(r[0] + i).SHL(Proc.read_C2(r[1] + i),n); - return; - case GSHRCI: - for (int i = 0; i < size; i++) - Proc.get_C2_ref(r[0] + i).SHR(Proc.read_C2(r[1] + i),n); - return; - case GMULM: - for (int i = 0; i < size; i++) - Proc.get_S2_ref(r[0] + i).mul(Proc.read_S2(r[1] + i),Proc.read_C2(r[2] + i)); - return; - case SHUFFLE: - for (int i = 0; i < size; i++) - Proc.write_Ci(r[0] + i, Proc.read_Ci(r[1] + i)); - for (int i = 0; i < size; i++) - { - int j = Proc.shared_prng.get_uint(size - i); - swap(Proc.get_Ci_ref(r[0] + i), Proc.get_Ci_ref(r[0] + i + j)); - } - return; case CONVMODP: if (n == 0) { @@ -865,202 +829,33 @@ inline void Instruction::execute(Processor& Proc) const int n = this->n; for (int i = 0; i < size; i++) { switch (opcode) - { case LDI: - Proc.temp.assign_ansp(n); - Proc.write_Cp(r[0],Proc.temp.ansp); - break; - case GLDI: - Proc.temp.ans2.assign(n); - Proc.write_C2(r[0],Proc.temp.ans2); - break; - case LDSI: - Proc.get_Sp_ref(r[0]).assign(n, Proc.P.my_num(), Proc.MCp.get_alphai()); - break; - case GLDSI: - Proc.get_S2_ref(r[0]).assign(n, Proc.P.my_num(), Proc.MC2.get_alphai()); - break; + { case LDMC: Proc.write_Cp(r[0],Proc.machine.Mp.read_C(n)); n++; break; - case GLDMC: - Proc.write_C2(r[0],Proc.machine.M2.read_C(n)); - n++; - break; - case LDMS: - Proc.write_Sp(r[0],Proc.machine.Mp.read_S(n)); - n++; - break; - case GLDMS: - Proc.write_S2(r[0],Proc.machine.M2.read_S(n)); - n++; - break; - case LDMINT: - Proc.write_Ci(r[0],Proc.machine.Mi.read_C(n).get()); - n++; - break; case LDMCI: Proc.write_Cp(r[0], Proc.machine.Mp.read_C(Proc.read_Ci(r[1]))); break; - case GLDMCI: - Proc.write_C2(r[0], Proc.machine.M2.read_C(Proc.read_Ci(r[1]))); - break; - case LDMSI: - Proc.write_Sp(r[0], Proc.machine.Mp.read_S(Proc.read_Ci(r[1]))); - break; - case GLDMSI: - Proc.write_S2(r[0], Proc.machine.M2.read_S(Proc.read_Ci(r[1]))); - break; - case LDMINTI: - Proc.write_Ci(r[0], Proc.machine.Mi.read_C(Proc.read_Ci(r[1])).get()); - break; case STMC: - Proc.machine.Mp.write_C(n,Proc.read_Cp(r[0]),Proc.PC); - n++; - break; - case GSTMC: - Proc.machine.M2.write_C(n,Proc.read_C2(r[0]),Proc.PC); - n++; - break; - case STMS: - Proc.machine.Mp.write_S(n,Proc.read_Sp(r[0]),Proc.PC); - n++; - break; - case GSTMS: - Proc.machine.M2.write_S(n,Proc.read_S2(r[0]),Proc.PC); - n++; - break; - case STMINT: - Proc.machine.Mi.write_C(n,Integer(Proc.read_Ci(r[0])),Proc.PC); + Proc.machine.Mp.write_C(n,Proc.read_Cp(r[0])); n++; break; case STMCI: - Proc.machine.Mp.write_C(Proc.read_Ci(r[1]), Proc.read_Cp(r[0]),Proc.PC); - break; - case GSTMCI: - Proc.machine.M2.write_C(Proc.read_Ci(r[1]), Proc.read_C2(r[0]),Proc.PC); - break; - case STMSI: - Proc.machine.Mp.write_S(Proc.read_Ci(r[1]), Proc.read_Sp(r[0]),Proc.PC); - break; - case GSTMSI: - Proc.machine.M2.write_S(Proc.read_Ci(r[1]), Proc.read_S2(r[0]),Proc.PC); - break; - case STMINTI: - Proc.machine.Mi.write_C(Proc.read_Ci(r[1]), Integer(Proc.read_Ci(r[0])),Proc.PC); + Proc.machine.Mp.write_C(Proc.read_Ci(r[1]), Proc.read_Cp(r[0])); break; case MOVC: Proc.write_Cp(r[0],Proc.read_Cp(r[1])); break; - case GMOVC: - Proc.write_C2(r[0],Proc.read_C2(r[1])); - break; - case MOVS: - Proc.write_Sp(r[0],Proc.read_Sp(r[1])); - break; - case GMOVS: - Proc.write_S2(r[0],Proc.read_S2(r[1])); - break; - case MOVINT: - Proc.write_Ci(r[0],Proc.read_Ci(r[1])); - break; - case PROTECTMEMS: - Proc.machine.Mp.protect_s(Proc.read_Ci(r[0]), Proc.read_Ci(r[1])); - break; - case PROTECTMEMC: - Proc.machine.Mp.protect_c(Proc.read_Ci(r[0]), Proc.read_Ci(r[1])); - break; - case GPROTECTMEMS: - Proc.machine.M2.protect_s(Proc.read_Ci(r[0]), Proc.read_Ci(r[1])); - break; - case GPROTECTMEMC: - Proc.machine.M2.protect_c(Proc.read_Ci(r[0]), Proc.read_Ci(r[1])); - break; - case PROTECTMEMINT: - Proc.machine.Mi.protect_c(Proc.read_Ci(r[0]), Proc.read_Ci(r[1])); - break; - case PUSHINT: - Proc.pushi(Proc.read_Ci(r[0])); - break; - case POPINT: - Proc.popi(Proc.get_Ci_ref(r[0])); - break; - case LDTN: - Proc.write_Ci(r[0],Proc.get_thread_num()); - break; - case LDARG: - Proc.write_Ci(r[0],Proc.get_arg()); - break; - case STARG: - Proc.set_arg(Proc.read_Ci(r[0])); - break; - case ADDC: - Proc.get_Cp_ref(r[0]).add(Proc.read_Cp(r[1]),Proc.read_Cp(r[2])); - break; - case GADDC: - Proc.get_C2_ref(r[0]).add(Proc.read_C2(r[1]),Proc.read_C2(r[2])); - break; - case ADDS: - Proc.get_Sp_ref(r[0]).add(Proc.read_Sp(r[1]),Proc.read_Sp(r[2])); - break; - case GADDS: - Proc.get_S2_ref(r[0]).add(Proc.read_S2(r[1]),Proc.read_S2(r[2])); - break; - case ADDM: - Proc.get_Sp_ref(r[0]).add(Proc.read_Sp(r[1]),Proc.read_Cp(r[2]),Proc.P.my_num(),Proc.MCp.get_alphai()); - break; - case GADDM: - Proc.get_S2_ref(r[0]).add(Proc.read_S2(r[1]),Proc.read_C2(r[2]),Proc.P.my_num(),Proc.MC2.get_alphai()); - break; - case SUBC: - Proc.get_Cp_ref(r[0]).sub(Proc.read_Cp(r[1]),Proc.read_Cp(r[2])); - break; - case GSUBC: - Proc.get_C2_ref(r[0]).sub(Proc.read_C2(r[1]),Proc.read_C2(r[2])); - break; - case SUBS: - Proc.get_Sp_ref(r[0]).sub(Proc.read_Sp(r[1]),Proc.read_Sp(r[2])); - break; - case GSUBS: - Proc.get_S2_ref(r[0]).sub(Proc.read_S2(r[1]),Proc.read_S2(r[2])); - break; - case SUBML: - Proc.get_Sp_ref(r[0]).sub(Proc.read_Sp(r[1]),Proc.read_Cp(r[2]),Proc.P.my_num(),Proc.MCp.get_alphai()); - break; - case GSUBML: - Proc.get_S2_ref(r[0]).sub(Proc.read_S2(r[1]),Proc.read_C2(r[2]),Proc.P.my_num(),Proc.MC2.get_alphai()); - break; - case SUBMR: - Proc.get_Sp_ref(r[0]).sub(Proc.read_Cp(r[1]),Proc.read_Sp(r[2]),Proc.P.my_num(),Proc.MCp.get_alphai()); - break; - case GSUBMR: - Proc.get_S2_ref(r[0]).sub(Proc.read_C2(r[1]),Proc.read_S2(r[2]),Proc.P.my_num(),Proc.MC2.get_alphai()); - break; - case MULC: - Proc.get_Cp_ref(r[0]).mul(Proc.read_Cp(r[1]),Proc.read_Cp(r[2])); - break; - case GMULC: - Proc.get_C2_ref(r[0]).mul(Proc.read_C2(r[1]),Proc.read_C2(r[2])); - break; - case MULM: - Proc.get_Sp_ref(r[0]).mul(Proc.read_Sp(r[1]),Proc.read_Cp(r[2])); - break; - case GMULM: - Proc.get_S2_ref(r[0]).mul(Proc.read_S2(r[1]),Proc.read_C2(r[2])); - break; case DIVC: if (Proc.read_Cp(r[2]).is_zero()) throw Processor_Error("Division by zero from register"); - Proc.temp.ansp.invert(Proc.read_Cp(r[2])); - Proc.temp.ansp.mul(Proc.read_Cp(r[1])); - Proc.write_Cp(r[0],Proc.temp.ansp); + Proc.write_Cp(r[0], Proc.read_Cp(r[1]) / Proc.read_Cp(r[2])); break; case GDIVC: if (Proc.read_C2(r[2]).is_zero()) throw Processor_Error("Division by zero from register"); - Proc.temp.ans2.invert(Proc.read_C2(r[2])); - Proc.temp.ans2.mul(Proc.read_C2(r[1])); - Proc.write_C2(r[0],Proc.temp.ans2); + Proc.write_C2(r[0], Proc.read_C2(r[1]) / Proc.read_C2(r[2])); break; case MODC: to_bigint(Proc.temp.aa, Proc.read_Cp(r[1])); @@ -1090,27 +885,15 @@ inline void Instruction::execute(Processor& Proc) const case DIVCI: if (n == 0) throw Processor_Error("Division by immediate zero"); - bigint::tmp = n; - to_gfp(Proc.temp.ansp, bigint::tmp); - Proc.temp.ansp.invert(); - Proc.temp.ansp.mul(Proc.read_Cp(r[1])); - Proc.write_Cp(r[0],Proc.temp.ansp); + Proc.write_Cp(r[0], Proc.read_Cp(r[1]) / n); break; case GDIVCI: if (n == 0) throw Processor_Error("Division by immediate zero"); - Proc.temp.ans2.assign(n); - Proc.temp.ans2.invert(); - Proc.temp.ans2.mul(Proc.read_C2(r[1])); - Proc.write_C2(r[0],Proc.temp.ans2); + Proc.write_C2(r[0], Proc.read_C2(r[1]) / n); break; case INV2M: - if (Proc.inverses2m.find(n) == Proc.inverses2m.end()) - { - to_gfp(Proc.inverses2m[n], bigint(1) << n); - Proc.inverses2m[n].invert(); - } - Proc.write_Cp(r[0], Proc.inverses2m[n]); + Proc.write_Cp(r[0], Proc.get_inverse2(n)); break; case MODCI: to_bigint(Proc.temp.aa, Proc.read_Cp(r[1])); @@ -1123,76 +906,6 @@ inline void Instruction::execute(Processor& Proc) const case GMULBITM: Proc.get_S2_ref(r[0]).mul_by_bit(Proc.read_S2(r[1]),Proc.read_C2(r[2])); break; - case ADDCI: - Proc.temp.assign_ansp(n); - Proc.get_Cp_ref(r[0]).add(Proc.temp.ansp,Proc.read_Cp(r[1])); - break; - case GADDCI: - Proc.temp.ans2.assign(n); - Proc.get_C2_ref(r[0]).add(Proc.temp.ans2,Proc.read_C2(r[1])); - break; - case ADDSI: - Proc.temp.assign_ansp(n); - Proc.get_Sp_ref(r[0]).add(Proc.read_Sp(r[1]),Proc.temp.ansp,Proc.P.my_num(),Proc.MCp.get_alphai()); - break; - case GADDSI: - Proc.temp.ans2.assign(n); - Proc.get_S2_ref(r[0]).add(Proc.read_S2(r[1]),Proc.temp.ans2,Proc.P.my_num(),Proc.MC2.get_alphai()); - break; - case SUBCI: - Proc.temp.assign_ansp(n); - Proc.get_Cp_ref(r[0]).sub(Proc.read_Cp(r[1]),Proc.temp.ansp); - break; - case GSUBCI: - Proc.temp.ans2.assign(n); - Proc.get_C2_ref(r[0]).sub(Proc.read_C2(r[1]),Proc.temp.ans2); - break; - case SUBSI: - Proc.temp.assign_ansp(n); - Proc.get_Sp_ref(r[0]).sub(Proc.read_Sp(r[1]),Proc.temp.ansp,Proc.P.my_num(),Proc.MCp.get_alphai()); - break; - case GSUBSI: - Proc.temp.ans2.assign(n); - Proc.get_S2_ref(r[0]).sub(Proc.read_S2(r[1]),Proc.temp.ans2,Proc.P.my_num(),Proc.MC2.get_alphai()); - break; - case SUBCFI: - Proc.temp.assign_ansp(n); - Proc.get_Cp_ref(r[0]).sub(Proc.temp.ansp,Proc.read_Cp(r[1])); - break; - case GSUBCFI: - Proc.temp.ans2.assign(n); - Proc.get_C2_ref(r[0]).sub(Proc.temp.ans2,Proc.read_C2(r[1])); - break; - case SUBSFI: - Proc.temp.assign_ansp(n); - Proc.get_Sp_ref(r[0]).sub(Proc.temp.ansp,Proc.read_Sp(r[1]),Proc.P.my_num(),Proc.MCp.get_alphai()); - break; - case GSUBSFI: - Proc.temp.ans2.assign(n); - Proc.get_S2_ref(r[0]).sub(Proc.temp.ans2,Proc.read_S2(r[1]),Proc.P.my_num(),Proc.MC2.get_alphai()); - break; - case MULCI: - Proc.temp.assign_ansp(n); - Proc.get_Cp_ref(r[0]).mul(Proc.temp.ansp,Proc.read_Cp(r[1])); - break; - case GMULCI: - Proc.temp.ans2.assign(n); - Proc.get_C2_ref(r[0]).mul(Proc.temp.ans2,Proc.read_C2(r[1])); - break; - case MULSI: - Proc.temp.assign_ansp(n); - Proc.get_Sp_ref(r[0]).mul(Proc.read_Sp(r[1]),Proc.temp.ansp); - break; - case GMULSI: - Proc.temp.ans2.assign(n); - Proc.get_S2_ref(r[0]).mul(Proc.read_S2(r[1]),Proc.temp.ans2); - break; - case TRIPLE: - Procp.DataF.get_three(DATA_TRIPLE, Proc.get_Sp_ref(r[0]),Proc.get_Sp_ref(r[1]),Proc.get_Sp_ref(r[2])); - break; - case GTRIPLE: - Proc2.DataF.get_three(DATA_TRIPLE, Proc.get_S2_ref(r[0]),Proc.get_S2_ref(r[1]),Proc.get_S2_ref(r[2])); - break; case GBITTRIPLE: Proc2.DataF.get_three(DATA_BITTRIPLE, Proc.get_S2_ref(r[0]),Proc.get_S2_ref(r[1]),Proc.get_S2_ref(r[2])); break; @@ -1205,12 +918,6 @@ inline void Instruction::execute(Processor& Proc) const case GSQUARE: Proc2.DataF.get_two(DATA_SQUARE, Proc.get_S2_ref(r[0]),Proc.get_S2_ref(r[1])); break; - case BIT: - Procp.DataF.get_one(DATA_BIT, Proc.get_Sp_ref(r[0])); - break; - case GBIT: - Proc2.DataF.get_one(DATA_BIT, Proc.get_S2_ref(r[0])); - break; case INV: Procp.DataF.get_two(DATA_INVERSE, Proc.get_Sp_ref(r[0]),Proc.get_Sp_ref(r[1])); break; @@ -1258,48 +965,6 @@ inline void Instruction::execute(Processor& Proc) const case GRAWINPUT: Proc.Proc2.input.raw_input(Proc.Proc2, start, size); return; - case ANDC: - Proc.get_Cp_ref(r[0]).AND(Proc.read_Cp(r[1]),Proc.read_Cp(r[2])); - break; - case GANDC: - Proc.get_C2_ref(r[0]).AND(Proc.read_C2(r[1]),Proc.read_C2(r[2])); - break; - case XORC: - Proc.get_Cp_ref(r[0]).XOR(Proc.read_Cp(r[1]),Proc.read_Cp(r[2])); - break; - case GXORC: - Proc.get_C2_ref(r[0]).XOR(Proc.read_C2(r[1]),Proc.read_C2(r[2])); - break; - case ORC: - Proc.get_Cp_ref(r[0]).OR(Proc.read_Cp(r[1]),Proc.read_Cp(r[2])); - break; - case GORC: - Proc.get_C2_ref(r[0]).OR(Proc.read_C2(r[1]),Proc.read_C2(r[2])); - break; - case ANDCI: - Proc.temp.aa=n; - Proc.get_Cp_ref(r[0]).AND(Proc.read_Cp(r[1]),Proc.temp.aa); - break; - case GANDCI: - Proc.temp.ans2.assign(n); - Proc.get_C2_ref(r[0]).AND(Proc.temp.ans2,Proc.read_C2(r[1])); - break; - case XORCI: - Proc.temp.aa=n; - Proc.get_Cp_ref(r[0]).XOR(Proc.read_Cp(r[1]),Proc.temp.aa); - break; - case GXORCI: - Proc.temp.ans2.assign(n); - Proc.get_C2_ref(r[0]).XOR(Proc.temp.ans2,Proc.read_C2(r[1])); - break; - case ORCI: - Proc.temp.aa=n; - Proc.get_Cp_ref(r[0]).OR(Proc.read_Cp(r[1]),Proc.temp.aa); - break; - case GORCI: - Proc.temp.ans2.assign(n); - Proc.get_C2_ref(r[0]).OR(Proc.temp.ans2,Proc.read_C2(r[1])); - break; // Note: Fp version has different semantics for NOTC than GNOTC case NOTC: to_bigint(Proc.temp.aa, Proc.read_Cp(r[1])); @@ -1310,64 +975,9 @@ inline void Instruction::execute(Processor& Proc) const Proc.temp.ansp.convert_destroy(Proc.temp.aa); Proc.write_Cp(r[0],Proc.temp.ansp); break; - case GNOTC: - Proc.get_C2_ref(r[0]).NOT(Proc.read_C2(r[1])); - break; - case SHLC: - to_bigint(Proc.temp.aa,Proc.read_Cp(r[2])); - Proc.get_Cp_ref(r[0]).SHL(Proc.read_Cp(r[1]),Proc.temp.aa); - break; - case SHRC: - to_bigint(Proc.temp.aa,Proc.read_Cp(r[2])); - Proc.get_Cp_ref(r[0]).SHR(Proc.read_Cp(r[1]),Proc.temp.aa); - break; - case SHLCI: - Proc.get_Cp_ref(r[0]).SHL(Proc.read_Cp(r[1]),n); - break; - case GSHLCI: - Proc.get_C2_ref(r[0]).SHL(Proc.read_C2(r[1]),n); - break; - case SHRCI: - Proc.get_Cp_ref(r[0]).SHR(Proc.read_Cp(r[1]),n); - break; - case GSHRCI: - Proc.get_C2_ref(r[0]).SHR(Proc.read_C2(r[1]),n); - break; case SHRSI: sint::shrsi(Procp, *this); return; - case GBITDEC: - for (int j = 0; j < size; j++) - { - gf2n::internal_type a = Proc.read_C2(r[0] + j).get(); - for (unsigned int i = 0; i < start.size(); i++) - { - Proc.get_C2_ref(start[i] + j) = a & 1; - a >>= n; - } - } - return; - case GBITCOM: - for (int j = 0; j < size; j++) - { - gf2n::internal_type a = 0; - for (unsigned int i = 0; i < start.size(); i++) - { - a ^= Proc.read_C2(start[i] + j).get() << (i * n); - } - Proc.get_C2_ref(r[0] + j) = a; - } - return; - case BITDECINT: - for (int j = 0; j < size; j++) - { - long a = Proc.read_Ci(r[0] + j); - for (unsigned int i = 0; i < start.size(); i++) - { - Proc.get_Ci_ref(start[i] + j) = (a >> i) & 1; - } - } - return; case OPEN: Proc.Procp.POpen(start, Proc.P, size); return; @@ -1419,93 +1029,12 @@ inline void Instruction::execute(Processor& Proc) const if (Proc.read_Ci(r[0]) == 0) { Proc.PC += (signed int) n; } break; - case EQZC: - if (Proc.read_Ci(r[1]) == 0) - Proc.write_Ci(r[0], 1); - else - Proc.write_Ci(r[0], 0); - break; - case LTZC: - if (Proc.read_Ci(r[1]) < 0) - Proc.write_Ci(r[0], 1); - else - Proc.write_Ci(r[0], 0); - break; - case LTC: - if (Proc.read_Ci(r[1]) < Proc.read_Ci(r[2])) - Proc.write_Ci(r[0], 1); - else - Proc.write_Ci(r[0], 0); - break; - case GTC: - if (Proc.read_Ci(r[1]) > Proc.read_Ci(r[2])) - Proc.write_Ci(r[0], 1); - else - Proc.write_Ci(r[0], 0); - break; - case EQC: - if (Proc.read_Ci(r[1]) == Proc.read_Ci(r[2])) - Proc.write_Ci(r[0], 1); - else - Proc.write_Ci(r[0], 0); - break; - case LDINT: - Proc.write_Ci(r[0], n); - break; - case ADDINT: - Proc.get_Ci_ref(r[0]) = Proc.read_Ci(r[1]) + Proc.read_Ci(r[2]); - break; - case SUBINT: - Proc.get_Ci_ref(r[0]) = Proc.read_Ci(r[1]) - Proc.read_Ci(r[2]); - break; - case MULINT: - Proc.get_Ci_ref(r[0]) = Proc.read_Ci(r[1]) * Proc.read_Ci(r[2]); - break; - case DIVINT: - Proc.get_Ci_ref(r[0]) = Proc.read_Ci(r[1]) / Proc.read_Ci(r[2]); - break; - case CONVINT: - Proc.temp.assign_ansp(Proc.read_Ci(r[1])); - Proc.get_Cp_ref(r[0]) = Proc.temp.ansp; - break; - case GCONVINT: - Proc.get_C2_ref(r[0]).assign((word)Proc.read_Ci(r[1])); - break; - case CONVMODP: - if (n == 0) - { - Proc.write_Ci(r[0], - Integer::convert_unsigned(Proc.read_Cp(r[1])).get()); - } - else - { - if (n > 64) - throw Processor_Error(to_string(n) + "-bit conversion impossible; " - "integer registers only have 64 bits"); - Proc.write_Ci(r[0], Integer(Proc.read_Cp(r[1]), n).get()); - } - break; - case GCONVGF2N: - Proc.write_Ci(r[0], Proc.read_C2(r[1]).get_word()); - break; - case PRINTMEM: - { Proc.out << "Mem[" << r[0] << "] = " << Proc.machine.Mp.read_C(r[0]) << endl; } - break; - case GPRINTMEM: - { Proc.out << "Mem[" << r[0] << "] = " << Proc.machine.M2.read_C(r[0]) << endl; } - break; case PRINTREG: { Proc.out << "Reg[" << r[0] << "] = " << Proc.read_Cp(r[0]) << " # " << string((char*)&n,sizeof(n)) << endl; } break; - case GPRINTREG: - { - Proc.out << "Reg[" << r[0] << "] = " << Proc.read_C2(r[0]) - << " # " << string((char*)&n,sizeof(n)) << endl; - } - break; case PRINTREGPLAIN: { Proc.out << Proc.read_Cp(r[0]) << flush; @@ -1522,16 +1051,6 @@ inline void Instruction::execute(Processor& Proc) const Proc.out << bigint::get_float(v, p, {}, {}) << flush; } break; - case GPRINTREGPLAIN: - { - Proc.out << Proc.read_C2(r[0]) << flush; - } - break; - case PRINTINT: - { - Proc.out << Proc.read_Ci(r[0]) << flush; - } - break; case PRINTFLOATPLAIN: { auto nan = Proc.read_Cp(start[4]); @@ -1542,14 +1061,6 @@ inline void Instruction::execute(Processor& Proc) const bigint::output_float(Proc.out, bigint::get_float(v, p, z, s), nan); } break; - case PRINTFLOATPREC: - Proc.out << setprecision(n); - break; - case PRINTSTR: - { - Proc.out << string((char*)&n,sizeof(n)) << flush; - } - break; case CONDPRINTSTR: if (not Proc.read_Cp(r[0]).is_zero()) { @@ -1560,24 +1071,6 @@ inline void Instruction::execute(Processor& Proc) const Proc.out << str << flush; } break; - case PRINTCHR: - { - Proc.out << string((char*)&n,1) << flush; - } - break; - case PRINTCHRINT: - { - Proc.out << string((char*)&(Proc.read_Ci(r[0])),1) << flush; - } - break; - case PRINTSTRINT: - { - Proc.out << string((char*)&(Proc.read_Ci(r[0])),sizeof(int)) << flush; - } - break; - case RAND: - Proc.write_Ci(r[0], Proc.shared_prng.get_uint() % (1 << Proc.read_Ci(r[1]))); - break; case REQBL: case GREQBL: case USE: @@ -1632,12 +1125,6 @@ inline void Instruction::execute(Processor& Proc) const { // get client connection at port number n + my_num()) int client_handle = Proc.external_clients.get_client_connection(n); - if (client_handle == -1) - { - stringstream ss; - ss << "No connection on port " << r[0] << endl; - throw Processor_Error(ss.str()); - } if (Proc.P.my_num() == 0) { octetStream os; @@ -1696,9 +1183,6 @@ inline void Instruction::execute(Processor& Proc) const case RAWOUTPUT: Proc.read_Cp(r[0]).output(Proc.public_output, false); break; - case GRAWOUTPUT: - Proc.read_C2(r[0]).output(Proc.public_output, false); - break; case STARTPRIVATEOUTPUT: Proc.privateOutputp.start(n,r[0],r[1]); break; @@ -1719,11 +1203,21 @@ inline void Instruction::execute(Processor& Proc) const return; default: printf("Case of opcode=0x%x not implemented yet\n",opcode); - throw runtime_error("invalid opcode: " + to_string(opcode)); + throw invalid_opcode(opcode); break; -#define X(NAME, CODE) case NAME: throw runtime_error("wrong case statement"); return; +#define X(NAME, CODE) case NAME: COMBI_INSTRUCTIONS #undef X +#define X(NAME, PRE, CODE) case NAME: + ARITHMETIC_INSTRUCTIONS +#undef X +#define X(NAME, PRE, CODE) case NAME: + CLEAR_GF2N_INSTRUCTIONS +#undef X +#define X(NAME, PRE, CODE) case NAME: + REGINT_INSTRUCTIONS +#undef X + throw runtime_error("wrong case statement"); return; } if (size > 1) { @@ -1739,6 +1233,7 @@ void Program::execute(Processor& Proc) const Proc.PC=0; auto& Procp = Proc.Procp; + auto& Proc2 = Proc.Proc2; // binary instructions typedef typename sint::bit_type T; @@ -1752,6 +1247,7 @@ void Program::execute(Processor& Proc) const auto& n = instruction.n; auto& start = instruction.start; auto& size = instruction.size; + (void) start; #ifdef COUNT_INSTRUCTIONS Proc.stats[p[Proc.PC].get_opcode()]++; @@ -1765,6 +1261,14 @@ void Program::execute(Processor& Proc) const case NAME: { PRE; for (int i = 0; i < size; i++) { CODE; } } break; ARITHMETIC_INSTRUCTIONS #undef X +#define X(NAME, PRE, CODE) case NAME: + CLEAR_GF2N_INSTRUCTIONS + instruction.execute_clear_gf2n(Proc2.get_C(), Proc.machine.M2.MC, Proc); break; +#undef X +#define X(NAME, PRE, CODE) case NAME: + REGINT_INSTRUCTIONS + instruction.execute_regint(Proc, Proc.machine.Mi.MC); break; +#undef X #define X(NAME, CODE) case NAME: CODE; break; COMBI_INSTRUCTIONS #undef X diff --git a/Processor/Machine.h b/Processor/Machine.h index 40301b1c5..2c268a460 100644 --- a/Processor/Machine.h +++ b/Processor/Machine.h @@ -45,7 +45,7 @@ class Machine : public BaseMachine // Keep record of used offline data DataPositions pos; - void load_program(string threadname, string filename); + void load_program(const string& threadname, const string& filename); public: @@ -71,8 +71,8 @@ class Machine : public BaseMachine atomic data_sent; ExecutionStats stats; - Machine(int my_number, Names& playerNames, string progname, - string memtype, int lg2, bool direct, int opening_sum, + Machine(int my_number, Names& playerNames, const string& progname, + const string& memtype, int lg2, bool direct, int opening_sum, bool receive_threads, int max_broadcast, bool use_encryption, bool live_prep, OnlineOptions opts); diff --git a/Processor/Machine.hpp b/Processor/Machine.hpp index 6f98c0420..d5cc119e9 100644 --- a/Processor/Machine.hpp +++ b/Processor/Machine.hpp @@ -1,9 +1,12 @@ +#ifndef PROCESSOR_MACHINE_HPP_ +#define PROCESSOR_MACHINE_HPP_ + #include "Machine.h" #include "Memory.hpp" #include "Online-Thread.hpp" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include @@ -20,7 +23,8 @@ using namespace std; template Machine::Machine(int my_number, Names& playerNames, - string progname_str, string memtype, int lg2, bool direct, + const string& progname_str, const string& memtype, + int lg2, bool direct, int opening_sum, bool receive_threads, int max_broadcast, bool use_encryption, bool live_prep, OnlineOptions opts) : my_number(my_number), N(playerNames), @@ -128,14 +132,12 @@ Machine::Machine(int my_number, Names& playerNames, } template -void Machine::load_program(string threadname, string filename) +void Machine::load_program(const string& threadname, + const string& filename) { - ifstream pinp(filename); - if (pinp.fail()) { throw file_error(filename); } progs.push_back(N.num_players()); int i = progs.size() - 1; - progs[i].parse(pinp); - pinp.close(); + progs[i].parse(filename); M2.minimum_size(SGF2N, CGF2N, progs[i], threadname); Mp.minimum_size(SINT, CINT, progs[i], threadname); Mi.minimum_size(NONE, INT, progs[i], threadname); @@ -223,9 +225,9 @@ DataPositions Machine::run_tape(int thread_number, int tape_number, int arg) { if (size_t(thread_number) >= tinfo.size()) - throw Processor_Error("invalid thread number: " + to_string(thread_number) + "/" + to_string(tinfo.size())); + throw overflow("invalid thread number", thread_number, tinfo.size()); if (size_t(tape_number) >= progs.size()) - throw Processor_Error("invalid tape number: " + to_string(tape_number) + "/" + to_string(progs.size())); + throw overflow("invalid tape number", tape_number, progs.size()); queues[thread_number]->schedule({tape_number, arg, pos}); //printf("Send signal to run program %d in thread %d\n",tape_number,thread_number); @@ -325,7 +327,7 @@ void Machine::run() global += os.get_int(8); cerr << "Global data sent = " << global / 1e6 << " MB" << endl; -#ifdef VERBOSE +#ifdef VERBOSE_OPTIONS if (opening_sum < N.num_players() && !direct) cerr << "Summed at most " << opening_sum << " shares at once with indirect communication" << endl; else @@ -373,6 +375,10 @@ void Machine::run() pos.print_cost(); #endif + if (pos.any_more(progs[0].get_offline_data_used()) + and not progs[0].usage_unknown()) + throw runtime_error("computation used more preprocessing than expected"); + if (not stats.empty()) { stats.print(); @@ -413,3 +419,5 @@ void Machine::reqbl(int n) { sint::clear::reqbl(n); } + +#endif diff --git a/Processor/Memory.h b/Processor/Memory.h index 5cb3ed6ff..c628e8e5c 100644 --- a/Processor/Memory.h +++ b/Processor/Memory.h @@ -18,11 +18,6 @@ template istream& operator>>(istream& s,Memory& M); template class Memory { -#ifdef MEMPROTECT - set< pair > protected_s; - set< pair > protected_c; -#endif - public: CheckVector MS; @@ -43,38 +38,15 @@ class Memory const T& read_S(int i) const { return MS[i]; } - void write_C(unsigned int i,const typename T::clear& x,int PC=-1) + void write_C(unsigned int i,const typename T::clear& x) { MC[i]=x; - (void)PC; -#ifdef MEMPROTECT - if (is_protected_c(i)) - cerr << "Protected clear memory access of " << i << " by " << PC - 1 << endl; -#endif } - void write_S(unsigned int i,const T& x,int PC=-1) + void write_S(unsigned int i,const T& x) { MS[i]=x; - (void)PC; -#ifdef MEMPROTECT - if (is_protected_s(i)) - cerr << "Protected secret memory access of " << i << " by " << PC - 1 << endl; -#endif } - -#ifdef MEMPROTECT - void protect_s(unsigned int start, unsigned int end); - void protect_c(unsigned int start, unsigned int end); - bool is_protected_s(unsigned int index); - bool is_protected_c(unsigned int index); -#else - void protect_s(unsigned int start, unsigned int end) - { (void)start, (void)end; cerr << "Memory protection not activated" << endl; } - void protect_c(unsigned int start, unsigned int end) - { (void)start, (void)end; cerr << "Memory protection not activated" << endl; } -#endif - void minimum_size(RegType secret_type, RegType clear_type, - const Program& program, string threadname); + const Program& program, const string& threadname); friend ostream& operator<< <>(ostream& s,const Memory& M); friend istream& operator>> <>(istream& s,Memory& M); diff --git a/Processor/Memory.hpp b/Processor/Memory.hpp index bee3b40dd..44e7d3432 100644 --- a/Processor/Memory.hpp +++ b/Processor/Memory.hpp @@ -5,7 +5,7 @@ template void Memory::minimum_size(RegType secret_type, RegType clear_type, - const Program &program, string threadname) + const Program &program, const string& threadname) { (void) threadname; unsigned sizes[MAX_SECRECY_TYPE]; @@ -29,40 +29,6 @@ void Memory::minimum_size(RegType secret_type, RegType clear_type, } } -#ifdef MEMPROTECT -template -void Memory::protect_s(unsigned int start, unsigned int end) -{ - protected_s.insert(pair(start, end)); -} - -template -void Memory::protect_c(unsigned int start, unsigned int end) -{ - protected_c.insert(pair(start, end)); -} - -template -bool Memory::is_protected_s(unsigned int index) -{ - for (set< pair >::iterator it = protected_s.begin(); - it != protected_s.end(); it++) - if (it->first <= index and it->second > index) - return true; - return false; -} - -template -bool Memory::is_protected_c(unsigned int index) -{ - for (set< pair >::iterator it = protected_c.begin(); - it != protected_c.end(); it++) - if (it->first <= index and it->second > index) - return true; - return false; -} -#endif - template ostream& operator<<(ostream& s,const Memory& M) diff --git a/Processor/NoLivePrep.h b/Processor/NoLivePrep.h index fe1d5d118..514283535 100644 --- a/Processor/NoLivePrep.h +++ b/Processor/NoLivePrep.h @@ -6,7 +6,7 @@ #ifndef PROCESSOR_NOLIVEPREP_H_ #define PROCESSOR_NOLIVEPREP_H_ -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Data_Files.h" template class SubProcessor; diff --git a/Processor/OfflineMachine.h b/Processor/OfflineMachine.h new file mode 100644 index 000000000..792c5bdaa --- /dev/null +++ b/Processor/OfflineMachine.h @@ -0,0 +1,36 @@ +/* + * DishonestMajorityOfflineMachine.h + * + */ + +#ifndef PROCESSOR_OFFLINEMACHINE_H_ +#define PROCESSOR_OFFLINEMACHINE_H_ + +#include "OnlineMachine.h" +#include "Data_Files.h" +#include "BaseMachine.h" +#include "Networking/CryptoPlayer.h" + +template +class OfflineMachine : public W +{ + DataPositions usage; + BaseMachine machine; + Names& playerNames; + Player& P; + + template + void generate(); + +public: + template + OfflineMachine(int argc, const char** argv, + ez::ezOptionParser& opt, OnlineOptions& online_opts, V, + int nplayers = 0); + ~OfflineMachine(); + + template + int run(); +}; + +#endif /* PROCESSOR_OFFLINEMACHINE_H_ */ diff --git a/Processor/OfflineMachine.hpp b/Processor/OfflineMachine.hpp new file mode 100644 index 000000000..b065b75d1 --- /dev/null +++ b/Processor/OfflineMachine.hpp @@ -0,0 +1,150 @@ +/* + * DishonestMajorityOfflineMachine.hpp + * + */ + +#ifndef PROCESSOR_OFFLINEMACHINE_HPP_ +#define PROCESSOR_OFFLINEMACHINE_HPP_ + +#include "OfflineMachine.h" +#include "Protocols/mac_key.hpp" + +template +template +OfflineMachine::OfflineMachine(int argc, const char** argv, + ez::ezOptionParser& opt, OnlineOptions& online_opts, V, + int nplayers) : + W(argc, argv, opt, online_opts, V(), nplayers), playerNames( + W::playerNames), P(*this->new_player()) +{ + machine.load_schedule(online_opts.progname, false); + Program program(playerNames.num_players()); + program.parse(machine.bc_filenames[0]); + usage = program.get_offline_data_used(); + machine.ot_setups.push_back({P}); +} + +template +OfflineMachine::~OfflineMachine() +{ + delete &P; +} + +template +template +int OfflineMachine::run() +{ + T::bit_type::mac_key_type::init_field(); + auto binary_mac_key = read_generate_write_mac_key(P); + GC::ShareThread thread(playerNames, + OnlineOptions::singleton, P, binary_mac_key, usage); + + generate(); + generate(); + generate(); + + thread.MC->Check(P); + + return 0; +} + +template +template +void OfflineMachine::generate() +{ + T::clear::init_default(this->online_opts.prime_length()); + T::clear::next::template init(false); + T::clear::template write_setup(P.num_players()); + auto mac_key = read_generate_write_mac_key(P); + DataPositions generated; + generated.set_num_players(P.num_players()); + typename T::MAC_Check output(mac_key); + typename T::LivePrep preprocessing(0, generated); + SubProcessor processor(output, preprocessing, P); + + auto& domain_usage = usage.files[T::field_type()]; + for (unsigned i = 0; i < domain_usage.size(); i++) + { + auto my_usage = domain_usage[i]; + Dtype dtype = Dtype(i); + string filename = Sub_Data_Files::get_filename(playerNames, dtype); + if (my_usage > 0) + { + ofstream out(filename, iostream::out | iostream::binary); + if (i == DATA_DABIT) + { + for (long long j = 0; + j < DIV_CEIL(my_usage, BUFFER_SIZE) * BUFFER_SIZE; j++) + { + T a; + typename T::bit_type b; + preprocessing.get_dabit(a, b); + dabit(a, b).output(out, false); + } + } + else + { + vector tuple(DataPositions::tuple_size[i]); + for (long long j = 0; + j < DIV_CEIL(my_usage, BUFFER_SIZE) * BUFFER_SIZE; j++) + { + preprocessing.get(dtype, tuple.data()); + for (auto& x : tuple) + x.output(out, false); + } + } + } + else + remove(filename.c_str()); + } + + for (int i = 0; i < P.num_players(); i++) + { + auto n_inputs = usage.inputs[i][T::field_type()]; + string filename = Sub_Data_Files::get_input_filename(playerNames, i); + if (n_inputs > 0) + { + ofstream out(filename, iostream::out | iostream::binary); + InputTuple tuple; + for (long long j = 0; + j < DIV_CEIL(n_inputs, BUFFER_SIZE) * BUFFER_SIZE; j++) + { + preprocessing.get_input(tuple.share, tuple.value, i); + tuple.share.output(out, false); + if (i == P.my_num()) + tuple.value.output(out, false); + } + } + else + remove(filename.c_str()); + } + + if (T::field_type() == DATA_INT) + { + int max_n_bits = 0; + for (auto& x : usage.edabits) + max_n_bits = max(max_n_bits, x.first.second); + + for (int n_bits = 1; n_bits < max(100, max_n_bits); n_bits++) + { + int batch = edabitvec::MAX_SIZE; + int total = usage.edabits[{false, n_bits}] + + usage.edabits[{true, n_bits}]; + string filename = Sub_Data_Files::get_edabit_filename(playerNames, + n_bits, P.my_num()); + if (total > 0) + { + ofstream out(filename, ios::binary); + for (int i = 0; i < DIV_CEIL(total, batch) * batch; i++) + preprocessing.template get_edabitvec<0>(true, n_bits).output(n_bits, + out); + } + else + remove(filename.c_str()); + } + } + + output.Check(P); +} + +#endif /* PROCESSOR_OFFLINEMACHINE_HPP_ */ diff --git a/Processor/Online-Thread.h b/Processor/Online-Thread.h index 7fe6c7cd2..dc05c31be 100644 --- a/Processor/Online-Thread.h +++ b/Processor/Online-Thread.h @@ -29,7 +29,8 @@ class thread_info static void purge_preprocessing(Machine& machine); template - static void print_usage(ostream& o, const vector& regs, string name); + static void print_usage(ostream& o, const vector& regs, + const char* name); void Sub_Main_Func(); }; diff --git a/Processor/Online-Thread.hpp b/Processor/Online-Thread.hpp index 0cc27c0db..466d1b336 100644 --- a/Processor/Online-Thread.hpp +++ b/Processor/Online-Thread.hpp @@ -10,6 +10,7 @@ #include "Protocols/LimitedPrep.h" #include "Processor/Processor.hpp" +#include "Processor/Instruction.hpp" #include "Processor/Input.hpp" #include "Protocols/LimitedPrep.hpp" #include "GC/BitAdder.hpp" @@ -23,10 +24,9 @@ using namespace std; template template void thread_info::print_usage(ostream &o, - const vector& regs, string name) + const vector& regs, const char* name) { - if (regs.capacity()) - o << name << "=" << regs.capacity() << " "; + ::print_usage(o, name, regs.capacity()); } template @@ -50,21 +50,23 @@ void thread_info::Sub_Main_Func() Player* player; if (machine.use_encryption) { -#ifdef VERBOSE +#ifdef VERBOSE_OPTIONS cerr << "Using encrypted single-threaded communication" << endl; #endif player = new CryptoPlayer(*(tinfo->Nms), num << 16); } else if (!machine.receive_threads or machine.direct) { -#ifdef VERBOSE +#ifdef VERBOSE_OPTIONS cerr << "Using single-threaded receiving" << endl; #endif player = new PlainPlayer(*(tinfo->Nms), num << 16); } else { +#ifdef VERBOSE_OPTIONS cerr << "Using player-specific threads for receiving" << endl; +#endif player = new ThreadPlayer(*(tinfo->Nms), num << 16); } Player& P = *player; @@ -77,7 +79,7 @@ void thread_info::Sub_Main_Func() if (machine.direct) { -#ifdef VERBOSE +#ifdef VERBOSE_OPTIONS cerr << "Using direct communication." << endl; #endif MC2 = new typename sgf2n::Direct_MC(*(tinfo->alpha2i)); @@ -85,7 +87,7 @@ void thread_info::Sub_Main_Func() } else { -#ifdef VERBOSE +#ifdef VERBOSE_OPTIONS cerr << "Using indirect communication." << endl; #endif MC2 = new typename sgf2n::MAC_Check(*(tinfo->alpha2i), machine.opening_sum, machine.max_broadcast); @@ -154,7 +156,8 @@ void thread_info::Sub_Main_Func() } else if (job.type == DABIT_JOB) { - dynamic_cast&>(Proc.DataF.DataFp).buffer_dabits_without_check( + dynamic_cast&>(Proc.DataF.DataFp).template + buffer_dabits_without_check<0>( *(vector>*) job.output, job.begin, job.end, Proc.Procp.bit_prep); queues->finished(job); @@ -168,7 +171,8 @@ void thread_info::Sub_Main_Func() } else if (job.type == EDABIT_JOB) { - dynamic_cast&>(Proc.DataF.DataFp).buffer_edabits_without_check( + dynamic_cast&>(Proc.DataF.DataFp).template + buffer_edabits_without_check<0>( job.length, *(vector*) job.output, *(vector>*) job.output2, job.begin, job.end); queues->finished(job); @@ -178,7 +182,8 @@ void thread_info::Sub_Main_Func() auto &party = GC::ShareThread::s(); SubProcessor bit_proc(party.MC->get_part_MC(), Proc.Procp.bit_prep, P); - dynamic_cast&>(Proc.DataF.DataFp).buffer_personal_edabits_without_check( + dynamic_cast&>(Proc.DataF.DataFp).template + buffer_personal_edabits_without_check<0>( job.length, *(vector*) job.output, *(vector>*) job.output2, bit_proc, job.arg, job.begin, job.end); @@ -186,7 +191,8 @@ void thread_info::Sub_Main_Func() } else if (job.type == SANITIZE_JOB) { - dynamic_cast&>(Proc.DataF.DataFp).sanitize( + dynamic_cast&>(Proc.DataF.DataFp).template + sanitize<0>( *(vector>*) job.output, job.length, job.arg, job.begin, job.end); queues->finished(job); @@ -212,7 +218,7 @@ void thread_info::Sub_Main_Func() { typedef typename sint::bit_type B; auto &party = GC::ShareThread::s(); - ShuffleSacrifice().triple_sacrifice( + TripleShuffleSacrifice().triple_sacrifice( *(vector>*) job.output, *(vector>*) job.input, *party.P, *party.MC, job.begin, job.end); diff --git a/Processor/OnlineMachine.h b/Processor/OnlineMachine.h index 6b9f04c9a..352884a14 100644 --- a/Processor/OnlineMachine.h +++ b/Processor/OnlineMachine.h @@ -37,6 +37,8 @@ class OnlineMachine template int run(); + + Player* new_player(int id_base = 0); }; class DishonestMajorityMachine : public OnlineMachine diff --git a/Processor/OnlineMachine.hpp b/Processor/OnlineMachine.hpp index 4f412700f..4ade74df4 100644 --- a/Processor/OnlineMachine.hpp +++ b/Processor/OnlineMachine.hpp @@ -6,6 +6,7 @@ #include "Protocols/Share.h" #include "Tools/ezOptionParser.h" #include "Networking/Server.h" +#include "Networking/CryptoPlayer.h" #include #include #include @@ -212,6 +213,15 @@ void OnlineMachine::start_networking() } } +inline +Player* OnlineMachine::new_player(int id_base) +{ + if (use_encryption) + return new CryptoPlayer(playerNames, id_base); + else + return new PlainPlayer(playerNames, id_base); +} + template int OnlineMachine::run() { diff --git a/Processor/OnlineOptions.cpp b/Processor/OnlineOptions.cpp index cdb62a4f7..e71185e55 100644 --- a/Processor/OnlineOptions.cpp +++ b/Processor/OnlineOptions.cpp @@ -262,7 +262,8 @@ void OnlineOptions::finalize(ez::ezOptionParser& opt, int argc, << "' or compile with '--prime " << prime << "'." << endl; exit(1); } - prime = schedule_prime; + if (schedule_prime != 0) + prime = schedule_prime; } if (opt.get("-lgp") and not opt.isSet("-lgp")) diff --git a/Processor/PrepBase.cpp b/Processor/PrepBase.cpp new file mode 100644 index 000000000..b4fd58a99 --- /dev/null +++ b/Processor/PrepBase.cpp @@ -0,0 +1,61 @@ +/* + * SubDataFilesBase.cpp + * + */ + +#include "PrepBase.h" + +#include "Data_Files.h" + +string PrepBase::get_suffix(int thread_num) +{ +#ifdef INSECURE + (void) thread_num; + return ""; +#else + if (thread_num >= 0) + return "-T" + to_string(thread_num); + else + return ""; +#endif +} + +string PrepBase::get_filename(const string& prep_data_dir, + Dtype dtype, const string& type_short, int my_num, int thread_num) +{ + return prep_data_dir + DataPositions::dtype_names[dtype] + "-" + type_short + + "-P" + to_string(my_num) + get_suffix(thread_num); +} + +string PrepBase::get_input_filename(const string& prep_data_dir, + const string& type_short, int input_player, int my_num, int thread_num) +{ + return prep_data_dir + "Inputs-" + type_short + "-P" + to_string(my_num) + + "-" + to_string(input_player) + get_suffix(thread_num); +} + +string PrepBase::get_edabit_filename(const string& prep_data_dir, + int n_bits, int my_num, int thread_num) +{ + return prep_data_dir + "edaBits-" + to_string(n_bits) + "-P" + + to_string(my_num) + get_suffix(thread_num); +} + +void PrepBase::print_left(const char* name, size_t n, const string& type_string) +{ + if (n > 0) + cerr << "\t" << n << " " << name << " of " << type_string << " left" + << endl; +} + +void PrepBase::print_left_edabits(size_t n, size_t n_batch, bool strict, + int n_bits) +{ + if (n > 0) + { + cerr << "\t~" << n * n_batch; + if (not strict) + cerr << " loose"; + cerr << " edaBits of size " << n_bits << " left" << endl; + } +} diff --git a/Processor/PrepBase.h b/Processor/PrepBase.h new file mode 100644 index 000000000..bedba6299 --- /dev/null +++ b/Processor/PrepBase.h @@ -0,0 +1,31 @@ +/* + * SubDataFilesBase.h + * + */ + +#ifndef PROCESSOR_PREPBASE_H_ +#define PROCESSOR_PREPBASE_H_ + +#include +using namespace std; + +#include "Math/field_types.h" + +class PrepBase +{ +public: + static string get_suffix(int thread_num); + + static string get_filename(const string& prep_data_dir, Dtype type, + const string& type_short, int my_num, int thread_num = 0); + static string get_input_filename(const string& prep_data_dir, + const string& type_short, int input_player, int my_num, + int thread_num = 0); + static string get_edabit_filename(const string& prep_data_dir, int n_bits, + int my_num, int thread_num = 0); + + static void print_left(const char* name, size_t n, const string& type_string); + static void print_left_edabits(size_t n, size_t n_batch, bool strict, int n_bits); +}; + +#endif /* PROCESSOR_PREPBASE_H_ */ diff --git a/Processor/PrivateOutput.hpp b/Processor/PrivateOutput.hpp index 700363440..400d1c449 100644 --- a/Processor/PrivateOutput.hpp +++ b/Processor/PrivateOutput.hpp @@ -24,7 +24,7 @@ void PrivateOutput::stop(int player, int dest, int source) if (player == proc.P.my_num() and proc.Proc) { auto& value = proc.get_C_ref(dest); - value.sub(proc.get_C_ref(source), masks.front()); + value = (proc.get_C_ref(source) - masks.front()); value.output(proc.Proc->private_output, false); masks.pop_front(); } diff --git a/Processor/Processor.h b/Processor/Processor.h index e1b7b2848..137f54e2e 100644 --- a/Processor/Processor.h +++ b/Processor/Processor.h @@ -6,7 +6,7 @@ */ #include "Math/Integer.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Networking/Player.h" #include "Data_Files.h" #include "Input.h" @@ -100,6 +100,7 @@ class ArithmeticProcessor : public ProcessorBase int thread_num; PRNG secure_prng; + PRNG shared_prng; string private_input_filename; string public_input_filename; @@ -108,12 +109,13 @@ class ArithmeticProcessor : public ProcessorBase ifstream public_input; ofstream public_output; ofstream private_output; - ofstream stdout_redirect_file; int sent, rounds; OnlineOptions opts; + SwitchableOutput out; + ArithmeticProcessor() : ArithmeticProcessor(OnlineOptions::singleton, BaseMachine::thread_num) { @@ -126,6 +128,11 @@ class ArithmeticProcessor : public ProcessorBase return thread_num == 0 and opts.interactive; } + int get_thread_num() + { + return thread_num; + } + const long& read_Ci(int i) const { return Ci[i]; } long& get_Ci_ref(int i) @@ -134,16 +141,22 @@ class ArithmeticProcessor : public ProcessorBase { Ci[i]=x; } CheckVector& get_Ci() { return Ci; } + + void shuffle(const Instruction& instruction); + void bitdecint(const Instruction& instruction); }; template class Processor : public ArithmeticProcessor { - int reg_max2, reg_maxi; + typedef typename sint::clear cint; // Data structure used for reading/writing data to/from a socket (i.e. an external party to SPDZ) octetStream socket_stream; + // avoid re-computation of expensive division + vector inverses2m; + public: Data_Files DataF; Player& P; @@ -162,15 +175,8 @@ class Processor : public ArithmeticProcessor unsigned int PC; TempVars temp; - PRNG shared_prng; - ExternalClients external_clients; Binary_File_IO binary_file_io; - - // avoid re-computation of expensive division - map inverses2m; - - SwitchableOutput out; void reset(const Program& program,int arg); // Reset the state of the processor string get_filename(const char* basename, bool use_number); @@ -181,10 +187,6 @@ class Processor : public ArithmeticProcessor const Program& program); ~Processor(); - int get_thread_num() - { - return thread_num; - } const typename sgf2n::clear& read_C2(int i) const { return Proc2.C[i]; } const sgf2n& read_S2(int i) const @@ -232,6 +234,8 @@ class Processor : public ArithmeticProcessor void read_shares_from_file(int start_file_pos, int end_file_pos_register, const vector& data_registers); void write_shares_to_file(const vector& data_registers); + cint get_inverse2(unsigned m); + // Print the processor state template friend ostream& operator<<(ostream& s,const Processor& P); diff --git a/Processor/Processor.hpp b/Processor/Processor.hpp index 55e34b7b8..d36fdab79 100644 --- a/Processor/Processor.hpp +++ b/Processor/Processor.hpp @@ -29,6 +29,7 @@ SubProcessor::SubProcessor(typename T::MAC_Check& MC, { DataF.set_proc(this); DataF.set_protocol(protocol); + protocol.init_mul(this); bit_usage.set_num_players(P.num_players()); personal_bit_preps.resize(P.num_players()); for (int i = 0; i < P.num_players(); i++) @@ -134,12 +135,11 @@ string Processor::get_filename(const char* prefix, bool use_number) template void Processor::reset(const Program& program,int arg) { - reg_maxi = program.num_reg(INT); Proc2.get_S().resize(program.num_reg(SGF2N)); Proc2.get_C().resize(program.num_reg(CGF2N)); Procp.get_S().resize(program.num_reg(SINT)); Procp.get_C().resize(program.num_reg(CINT)); - Ci.resize(reg_maxi); + Ci.resize(program.num_reg(INT)); this->arg = arg; Procb.reset(program); } @@ -600,6 +600,14 @@ void SubProcessor::conv2ds(const Instruction& instruction) } } +template +typename sint::clear Processor::get_inverse2(unsigned m) +{ + for (unsigned i = inverses2m.size(); i <= m; i++) + inverses2m.push_back((cint(1) << i).invert()); + return inverses2m[m]; +} + template ostream& operator<<(ostream& s,const Processor& P) { diff --git a/Processor/ProcessorBase.cpp b/Processor/ProcessorBase.cpp index 3bde79b5f..f2d34bb97 100644 --- a/Processor/ProcessorBase.cpp +++ b/Processor/ProcessorBase.cpp @@ -5,6 +5,22 @@ #include "ProcessorBase.hpp" +string ProcessorBase::get_parameterized_filename(int my_num, int thread_num, const string& prefix) +{ + string filename = prefix + "-P" + to_string(my_num) + "-" + to_string(thread_num); + return filename; +} + +void ProcessorBase::open_input_file(int my_num, int thread_num, + const string& prefix) +{ + string tmp = prefix; + if (prefix.empty()) + tmp = "Player-Data/Input"; + + open_input_file(get_parameterized_filename(my_num, thread_num, tmp)); +} + void ProcessorBase::setup_redirection(int my_num, int thread_num, OnlineOptions& opts) { diff --git a/Processor/ProcessorBase.h b/Processor/ProcessorBase.h index 79cb7ea8f..3c7d71166 100644 --- a/Processor/ProcessorBase.h +++ b/Processor/ProcessorBase.h @@ -26,7 +26,8 @@ class ProcessorBase // Optional argument to tape int arg; - string get_parameterized_filename(int my_num, int thread_num, string prefix); + string get_parameterized_filename(int my_num, int thread_num, + const string& prefix); public: ExecutionStats stats; @@ -47,7 +48,7 @@ class ProcessorBase } void open_input_file(const string& name); - void open_input_file(int my_num, int thread_num, string prefix=""); + void open_input_file(int my_num, int thread_num, const string& prefix=""); template T get_input(bool interactive, const int* params); diff --git a/Processor/ProcessorBase.hpp b/Processor/ProcessorBase.hpp index 7dcab3fc2..06b26a996 100644 --- a/Processor/ProcessorBase.hpp +++ b/Processor/ProcessorBase.hpp @@ -10,7 +10,7 @@ #include "IntInput.h" #include "FixInput.h" #include "FloatInput.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include @@ -24,21 +24,6 @@ void ProcessorBase::open_input_file(const string& name) input_filename = name; } -inline -string ProcessorBase::get_parameterized_filename(int my_num, int thread_num, string prefix) -{ - string filename = prefix + "-P" + to_string(my_num) + "-" + to_string(thread_num); - return filename; -} -inline -void ProcessorBase::open_input_file(int my_num, int thread_num, string prefix) -{ - if (prefix.empty()) - prefix = "Player-Data/Input"; - - open_input_file(get_parameterized_filename(my_num, thread_num, prefix)); -} - template T ProcessorBase::get_input(bool interactive, const int* params) { @@ -57,12 +42,7 @@ T ProcessorBase::get_input(istream& input_file, const string& input_filename, co res.read(input_file, params); if (input_file.fail()) { - input_file.clear(); - string token; - input_file >> token; - throw IO_Error( - string() + "cannot read " + T::NAME + " from " + input_filename - + ", problem with '" + token + "'"); + throw input_error(T::NAME, input_filename, input_file); } return res; } diff --git a/Processor/Program.cpp b/Processor/Program.cpp index f0eef1434..0bb4c5bfa 100644 --- a/Processor/Program.cpp +++ b/Processor/Program.cpp @@ -26,6 +26,14 @@ void Program::compute_constants() } } +void Program::parse(string filename) +{ + ifstream pinp(filename); + if (pinp.fail()) + throw file_error(filename); + parse(pinp); +} + void Program::parse(istream& s) { p.resize(0); diff --git a/Processor/Program.h b/Processor/Program.h index 480791483..727f90709 100644 --- a/Processor/Program.h +++ b/Processor/Program.h @@ -35,6 +35,7 @@ class Program { compute_constants(); } // Read in a program + void parse(string filename); void parse(istream& s); DataPositions get_offline_data_used() const { return offline_data_used; } diff --git a/Processor/ThreadQueue.cpp b/Processor/ThreadQueue.cpp new file mode 100644 index 000000000..3f5b1c76d --- /dev/null +++ b/Processor/ThreadQueue.cpp @@ -0,0 +1,40 @@ +/* + * ThreadQueue.cpp + * + */ + + +#include "ThreadQueue.h" + +void ThreadQueue::schedule(const ThreadJob& job) +{ + lock.lock(); + left++; +#ifdef DEBUG_THREAD_QUEUE + cerr << this << ": " << left << " left" << endl; +#endif + lock.unlock(); + in.push(job); +} + +ThreadJob ThreadQueue::next() +{ + return in.pop(); +} + +void ThreadQueue::finished(const ThreadJob& job) +{ + out.push(job); +} + +ThreadJob ThreadQueue::result() +{ + auto res = out.pop(); + lock.lock(); + left--; +#ifdef DEBUG_THREAD_QUEUE + cerr << this << ": " << left << " left" << endl; +#endif + lock.unlock(); + return res; +} diff --git a/Processor/ThreadQueue.h b/Processor/ThreadQueue.h index 78d9e4512..2e994b3ad 100644 --- a/Processor/ThreadQueue.h +++ b/Processor/ThreadQueue.h @@ -6,6 +6,8 @@ #ifndef PROCESSOR_THREADQUEUE_H_ #define PROCESSOR_THREADQUEUE_H_ +#include "ThreadJob.h" + class ThreadQueue { WaitQueue in, out; @@ -23,38 +25,10 @@ class ThreadQueue return left == 0; } - void schedule(ThreadJob job) - { - lock.lock(); - left++; -#ifdef DEBUG_THREAD_QUEUE - cerr << this << ": " << left << " left" << endl; -#endif - lock.unlock(); - in.push(job); - } - - ThreadJob next() - { - return in.pop(); - } - - void finished(ThreadJob job) - { - out.push(job); - } - - ThreadJob result() - { - auto res = out.pop(); - lock.lock(); - left--; -#ifdef DEBUG_THREAD_QUEUE - cerr << this << ": " << left << " left" << endl; -#endif - lock.unlock(); - return res; - } + void schedule(const ThreadJob& job); + ThreadJob next(); + void finished(const ThreadJob& job); + ThreadJob result(); }; #endif /* PROCESSOR_THREADQUEUE_H_ */ diff --git a/Processor/instructions.h b/Processor/instructions.h index 4d1c768a5..a58f1df20 100644 --- a/Processor/instructions.h +++ b/Processor/instructions.h @@ -11,6 +11,9 @@ #define ARITHMETIC_INSTRUCTIONS \ X(LDI, auto dest = &Procp.get_C()[r[0]]; typename sint::clear tmp = int(n), \ *dest++ = tmp) \ + X(LDSI, auto dest = &Procp.get_S()[r[0]]; \ + auto tmp = sint::constant(int(n), Proc.P.my_num(), Procp.MC.get_alphai()), \ + *dest++ = tmp) \ X(LDMS, auto dest = &Procp.get_S()[r[0]]; auto source = &Proc.machine.Mp.MS[n], \ *dest++ = *source++) \ X(STMS, auto source = &Procp.get_S()[r[0]]; auto dest = &Proc.machine.Mp.MS[n], \ @@ -27,6 +30,8 @@ X(ADDM, auto dest = &Procp.get_S()[r[0]]; auto op1 = &Procp.get_S()[r[1]]; \ auto op2 = &Procp.get_C()[r[2]], \ *dest++ = *op1++ + sint::constant(*op2++, Proc.P.my_num(), Procp.MC.get_alphai())) \ + X(ADDSI, auto dest = &Procp.get_S()[r[0]]; auto op1 = &Procp.get_S()[r[1]], \ + *dest++ = *op1++ + sint::constant(int(n), Proc.P.my_num(), Procp.MC.get_alphai())) \ X(ADDC, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ auto op2 = &Procp.get_C()[r[2]], \ *dest++ = *op1++ + *op2++) \ @@ -36,6 +41,9 @@ X(SUBS, auto dest = &Procp.get_S()[r[0]]; auto op1 = &Procp.get_S()[r[1]]; \ auto op2 = &Procp.get_S()[r[2]], \ *dest++ = *op1++ - *op2++) \ + X(SUBSI, auto dest = &Procp.get_S()[r[0]]; auto op1 = &Procp.get_S()[r[1]]; \ + auto op2 = sint::constant(int(n), Proc.P.my_num(), Procp.MC.get_alphai()), \ + *dest++ = *op1++ - op2) \ X(SUBSFI, auto dest = &Procp.get_S()[r[0]]; auto op1 = &Procp.get_S()[r[1]]; \ auto op2 = sint::constant(int(n), Proc.P.my_num(), Procp.MC.get_alphai()), \ *dest++ = op2 - *op1++) \ @@ -48,6 +56,12 @@ X(SUBC, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ auto op2 = &Procp.get_C()[r[2]], \ *dest++ = *op1++ - *op2++) \ + X(SUBCI, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + typename sint::clear op2 = int(n), \ + *dest++ = *op1++ - op2) \ + X(SUBCFI, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + typename sint::clear op2 = int(n), \ + *dest++ = op2 - *op1++) \ X(MULM, auto dest = &Procp.get_S()[r[0]]; auto op1 = &Procp.get_S()[r[1]]; \ auto op2 = &Procp.get_C()[r[2]], \ *dest++ = *op1++ * *op2++) \ @@ -60,6 +74,32 @@ X(MULSI, auto dest = &Procp.get_S()[r[0]]; auto op1 = &Procp.get_S()[r[1]]; \ typename sint::clear op2 = int(n), \ *dest++ = *op1++ * op2) \ + X(ANDC, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + auto op2 = &Procp.get_C()[r[2]], \ + *dest++ = *op1++ & *op2++) \ + X(XORC, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + auto op2 = &Procp.get_C()[r[2]], \ + *dest++ = *op1++ ^ *op2++) \ + X(ORC, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + auto op2 = &Procp.get_C()[r[2]], \ + *dest++ = *op1++ | *op2++) \ + X(ANDCI, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + typename sint::clear op2 = int(n), \ + *dest++ = *op1++ & op2) \ + X(XORCI, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + typename sint::clear op2 = int(n), \ + *dest++ = *op1++ ^ op2) \ + X(ORCI, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + typename sint::clear op2 = int(n), \ + *dest++ = *op1++ | op2) \ + X(SHLC, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + auto op2 = &Procp.get_C()[r[2]], \ + *dest++ = *op1++ << *op2++) \ + X(SHRC, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]]; \ + auto op2 = &Procp.get_C()[r[2]], \ + *dest++ = *op1++ >> *op2++) \ + X(SHLCI, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]], \ + *dest++ = *op1++ << n) \ X(SHRCI, auto dest = &Procp.get_C()[r[0]]; auto op1 = &Procp.get_C()[r[1]], \ *dest++ = *op1++ >> n) \ X(TRIPLE, auto a = &Procp.get_S()[r[0]]; auto b = &Procp.get_S()[r[1]]; \ @@ -67,6 +107,76 @@ Procp.DataF.get_three(DATA_TRIPLE, *a++, *b++, *c++)) \ X(BIT, auto dest = &Procp.get_S()[r[0]], \ Procp.DataF.get_one(DATA_BIT, *dest++)) \ + X(RANDOMFULLS, auto dest = &Procp.get_S()[r[0]], \ + *dest++ = Procp.DataF.get_random()) \ + X(GLDSI, auto dest = &Proc2.get_S()[r[0]]; \ + auto tmp = sgf2n::constant(int(n), Proc.P.my_num(), Proc2.MC.get_alphai()), \ + *dest++ = tmp) \ + X(GLDMS, auto dest = &Proc2.get_S()[r[0]]; auto source = &Proc.machine.M2.MS[n], \ + *dest++ = *source++) \ + X(GSTMS, auto source = &Proc2.get_S()[r[0]]; auto dest = &Proc.machine.M2.MS[n], \ + *dest++ = *source++) \ + X(GLDMSI, auto dest = &Proc2.get_S()[r[0]]; auto source = &Proc.get_Ci()[r[1]], \ + *dest++ = Proc.machine.M2.read_S(*source++)) \ + X(GSTMSI, auto source = &Proc2.get_S()[r[0]]; auto dest = &Proc.get_Ci()[r[1]], \ + Proc.machine.M2.write_S(*dest++, *source++)) \ + X(GMOVS, auto dest = &Proc2.get_S()[r[0]]; auto source = &Proc2.get_S()[r[1]], \ + *dest++ = *source++) \ + X(GADDS, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_S()[r[1]]; \ + auto op2 = &Proc2.get_S()[r[2]], \ + *dest++ = *op1++ + *op2++) \ + X(GADDM, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_S()[r[1]]; \ + auto op2 = &Proc2.get_C()[r[2]], \ + *dest++ = *op1++ + sgf2n::constant(*op2++, Proc.P.my_num(), Proc2.MC.get_alphai())) \ + X(GADDSI, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_S()[r[1]], \ + *dest++ = *op1++ + sgf2n::constant(int(n), Proc.P.my_num(), Proc2.MC.get_alphai())) \ + X(GSUBS, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_S()[r[1]]; \ + auto op2 = &Proc2.get_S()[r[2]], \ + *dest++ = *op1++ - *op2++) \ + X(GSUBSI, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_S()[r[1]]; \ + auto op2 = sgf2n::constant(int(n), Proc.P.my_num(), Proc2.MC.get_alphai()), \ + *dest++ = *op1++ - op2) \ + X(GSUBSFI, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_S()[r[1]]; \ + auto op2 = sgf2n::constant(int(n), Proc.P.my_num(), Proc2.MC.get_alphai()), \ + *dest++ = op2 - *op1++) \ + X(GSUBML, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_S()[r[1]]; \ + auto op2 = &Proc2.get_C()[r[2]], \ + *dest++ = *op1++ - sgf2n::constant(*op2++, Proc.P.my_num(), Proc2.MC.get_alphai())) \ + X(GSUBMR, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_C()[r[1]]; \ + auto op2 = &Proc2.get_S()[r[2]], \ + *dest++ = sgf2n::constant(*op1++, Proc.P.my_num(), Proc2.MC.get_alphai()) - *op2++) \ + X(GMULM, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_S()[r[1]]; \ + auto op2 = &Proc2.get_C()[r[2]], \ + *dest++ = *op1++ * *op2++) \ + X(GMULSI, auto dest = &Proc2.get_S()[r[0]]; auto op1 = &Proc2.get_S()[r[1]]; \ + typename sgf2n::clear op2 = int(n), \ + *dest++ = *op1++ * op2) \ + X(GTRIPLE, auto a = &Proc2.get_S()[r[0]]; auto b = &Proc2.get_S()[r[1]]; \ + auto c = &Proc2.get_S()[r[2]], \ + Proc2.DataF.get_three(DATA_TRIPLE, *a++, *b++, *c++)) \ + X(GBIT, auto dest = &Proc2.get_S()[r[0]], \ + Proc2.DataF.get_one(DATA_BIT, *dest++)) \ + X(CONVINT, auto dest = &Procp.get_C()[r[0]]; auto source = &Proc.get_Ci()[r[1]], \ + *dest++ = *source++) \ + X(GCONVINT, auto dest = &Proc2.get_C()[r[0]]; auto source = &Proc.get_Ci()[r[1]], \ + *dest++ = *source++) \ + +#define REGINT_INSTRUCTIONS \ + X(LDMINT, auto dest = &Proc.get_Ci()[r[0]]; auto source = &Mi[n], \ + *dest++ = (*source).get(); source++) \ + X(STMINT, auto dest = &Mi[n]; auto source = &Proc.get_Ci()[r[0]], \ + *dest++ = *source++) \ + X(LDMINTI, auto dest = &Proc.get_Ci()[r[0]]; auto source = &Ci[r[1]], \ + *dest++ = Mi[*source].get(); source++) \ + X(STMINTI, auto dest = &Proc.get_Ci()[r[1]]; auto source = &Ci[r[0]], \ + Mi[*dest] = *source++; dest++) \ + X(MOVINT, auto dest = &Proc.get_Ci()[r[0]]; auto source = &Ci[r[1]], \ + *dest++ = *source++) \ + X(PUSHINT, Proc.pushi(Ci[r[0]]),) \ + X(POPINT, auto dest = &Ci[r[0]], Proc.popi(*dest++)) \ + X(LDTN, auto dest = &Ci[r[0]], *dest++ = Proc.get_thread_num()) \ + X(LDARG, auto dest = &Ci[r[0]], *dest++ = Proc.get_arg()) \ + X(STARG, Proc.set_arg(Ci[r[0]]),) \ X(LDINT, auto dest = &Proc.get_Ci()[r[0]], \ *dest++ = int(n)) \ X(ADDINT, auto dest = &Proc.get_Ci()[r[0]]; auto op1 = &Proc.get_Ci()[r[1]]; \ @@ -83,8 +193,91 @@ *dest++ = *op1++ / *op2++) \ X(INCINT, auto dest = &Proc.get_Ci()[r[0]]; auto base = Proc.get_Ci()[r[1]], \ int inc = (i / start[0]) % start[1]; *dest++ = base + inc * int(n)) \ - X(CONVINT, auto dest = &Procp.get_C()[r[0]]; auto source = &Proc.get_Ci()[r[1]], \ - *dest++ = *source++) \ + X(EQZC, auto dest = &Ci[r[0]]; auto source = &Ci[r[1]], *dest++ = *source++ == 0) \ + X(LTZC, auto dest = &Ci[r[0]]; auto source = &Ci[r[1]], *dest++ = *source++ < 0) \ + X(LTC, auto dest = &Ci[r[0]]; auto op1 = &Ci[r[1]]; auto op2 = &Ci[r[2]], \ + *dest++ = *op1++ < *op2++) \ + X(GTC, auto dest = &Ci[r[0]]; auto op1 = &Ci[r[1]]; auto op2 = &Ci[r[2]], \ + *dest++ = *op1++ > *op2++) \ + X(EQC, auto dest = &Ci[r[0]]; auto op1 = &Ci[r[1]]; auto op2 = &Ci[r[2]], \ + *dest++ = *op1++ == *op2++) \ + X(PRINTINT, Proc.out << Proc.read_Ci(r[0]) << flush,) \ + X(PRINTFLOATPREC, Proc.out << setprecision(n),) \ + X(PRINTSTR, Proc.out << string((char*)&n,sizeof(n)) << flush,) \ + X(PRINTCHR, Proc.out << string((char*)&n,1) << flush,) \ + X(SHUFFLE, shuffle(Proc),) \ + X(BITDECINT, bitdecint(Proc),) \ + X(RAND, auto dest = &Ci[r[0]]; auto source = &Ci[r[1]], \ + *dest++ = Proc.shared_prng.get_uint() % (1 << *source++)) \ +#define CLEAR_GF2N_INSTRUCTIONS \ + X(GLDI, auto dest = &C2[r[0]]; cgf2n tmp = int(n), \ + *dest++ = tmp) \ + X(GLDMC, auto dest = &C2[r[0]]; auto source = &M2C[n], \ + *dest++ = (*source).get(); source++) \ + X(GSTMC, auto dest = &M2C[n]; auto source = &C2[r[0]], \ + *dest++ = *source++) \ + X(GLDMCI, auto dest = &C2[r[0]]; auto source = &Proc.get_Ci()[r[1]], \ + *dest++ = M2C[*source++]) \ + X(GSTMCI, auto dest = &Proc.get_Ci()[r[1]]; auto source = &C2[r[0]], \ + M2C[*dest++] = *source++) \ + X(GMOVC, auto dest = &C2[r[0]]; auto source = &C2[r[1]], \ + *dest++ = *source++) \ + X(GADDC, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + auto op2 = &C2[r[2]], \ + *dest++ = *op1++ + *op2++) \ + X(GADDCI, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + cgf2n op2 = int(n), \ + *dest++ = *op1++ + op2) \ + X(GSUBC, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + auto op2 = &C2[r[2]], \ + *dest++ = *op1++ - *op2++) \ + X(GSUBCI, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + cgf2n op2 = int(n), \ + *dest++ = *op1++ - op2) \ + X(GSUBCFI, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + cgf2n op2 = int(n), \ + *dest++ = op2 - *op1++) \ + X(GMULC, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + auto op2 = &C2[r[2]], \ + *dest++ = *op1++ * *op2++) \ + X(GMULCI, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + cgf2n op2 = int(n), \ + *dest++ = *op1++ * op2) \ + X(GANDC, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + auto op2 = &C2[r[2]], \ + *dest++ = *op1++ & *op2++) \ + X(GXORC, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + auto op2 = &C2[r[2]], \ + *dest++ = *op1++ ^ *op2++) \ + X(GORC, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + auto op2 = &C2[r[2]], \ + *dest++ = *op1++ | *op2++) \ + X(GANDCI, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + cgf2n op2 = int(n), \ + *dest++ = *op1++ & op2) \ + X(GXORCI, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + cgf2n op2 = int(n), \ + *dest++ = *op1++ ^ op2) \ + X(GORCI, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]]; \ + cgf2n op2 = int(n), \ + *dest++ = *op1++ | op2) \ + X(GNOTC, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]], \ + *dest++ = ~*op1++) \ + X(GSHLCI, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]], \ + *dest++ = *op1++ << n) \ + X(GSHRCI, auto dest = &C2[r[0]]; auto op1 = &C2[r[1]], \ + *dest++ = *op1++ >> n) \ + X(GPRINTREG, auto source = &C2[r[0]], \ + Proc.out << "Reg[" << r[0] << "] = " << *source++ \ + << " # " << string((char*)&n,sizeof(n)) << endl) \ + X(GPRINTREGPLAIN, auto source = &C2[r[0]], \ + Proc.out << *source++ << flush) \ + X(GBITDEC, gbitdec(C2),) \ + X(GBITCOM, gbitcom(C2),) \ + X(GCONVGF2N, auto dest = &Proc.get_Ci()[r[0]]; auto source = &C2[r[1]], \ + *dest++ = source->get_word(); source++) \ + X(GRAWOUTPUT, auto source = &C2[r[0]], \ + (*source++).output(Proc.public_output, false)) \ #endif /* PROCESSOR_INSTRUCTIONS_H_ */ diff --git a/Protocols/ChaiGearPrep.h b/Protocols/ChaiGearPrep.h index 22f331cfa..12281e74a 100644 --- a/Protocols/ChaiGearPrep.h +++ b/Protocols/ChaiGearPrep.h @@ -40,7 +40,6 @@ class ChaiGearPrep : public MaliciousRingPrep void buffer_triples(); void buffer_squares(); - void buffer_inverses(); void buffer_bits(); void buffer_inputs(int player); }; diff --git a/Protocols/ChaiGearPrep.hpp b/Protocols/ChaiGearPrep.hpp index 264097358..988b3cdbb 100644 --- a/Protocols/ChaiGearPrep.hpp +++ b/Protocols/ChaiGearPrep.hpp @@ -145,13 +145,6 @@ void ChaiGearPrep::buffer_squares() this->squares.push_back({{square[0], square[1]}}); } -template -void ChaiGearPrep::buffer_inverses() -{ - assert(this->proc != 0); - ::buffer_inverses(this->inverses, *this, this->proc->MC, this->proc->P); -} - template void ChaiGearPrep::buffer_inputs(int player) { diff --git a/Protocols/CowGearPrep.h b/Protocols/CowGearPrep.h index eb0e64990..a62614247 100644 --- a/Protocols/CowGearPrep.h +++ b/Protocols/CowGearPrep.h @@ -40,7 +40,6 @@ class CowGearPrep : public MaliciousRingPrep ~CowGearPrep(); void buffer_triples(); - void buffer_inverses(); void buffer_bits(); void buffer_inputs(int player); }; diff --git a/Protocols/CowGearPrep.hpp b/Protocols/CowGearPrep.hpp index eb2110b18..e0cf6bfe8 100644 --- a/Protocols/CowGearPrep.hpp +++ b/Protocols/CowGearPrep.hpp @@ -132,13 +132,6 @@ void CowGearPrep::buffer_triples() #endif } -template -void CowGearPrep::buffer_inverses() -{ - assert(this->proc != 0); - ::buffer_inverses(this->inverses, *this, this->proc->MC, this->proc->P); -} - template void CowGearPrep::buffer_inputs(int player) { diff --git a/Protocols/FakePrep.h b/Protocols/FakePrep.h index 587274f7f..8597ffc4b 100644 --- a/Protocols/FakePrep.h +++ b/Protocols/FakePrep.h @@ -57,9 +57,7 @@ class FakePrep : public BufferPrep for (int i = 0; i < 1000; i++) { auto a = G.get(); - T aa; - aa.invert(a); - this->inverses.push_back({{a, aa}}); + this->inverses.push_back({{a, a.invert()}}); } } diff --git a/Protocols/FakeShare.h b/Protocols/FakeShare.h index 204b93890..e5e4fd8b9 100644 --- a/Protocols/FakeShare.h +++ b/Protocols/FakeShare.h @@ -58,11 +58,6 @@ class FakeShare : public T, public ShareInterface { } - void assign(T value, int = 0, T = 0) - { - *this = value; - } - void add(T a, T b, int = 0, T = {}) { *this = a + b; diff --git a/Protocols/HemiPrep.h b/Protocols/HemiPrep.h index b0092e331..bfa3e25bd 100644 --- a/Protocols/HemiPrep.h +++ b/Protocols/HemiPrep.h @@ -35,7 +35,6 @@ class HemiPrep : public SemiHonestRingPrep } void buffer_triples(); - void buffer_inverses(); }; #endif /* PROTOCOLS_HEMIPREP_H_ */ diff --git a/Protocols/HemiPrep.hpp b/Protocols/HemiPrep.hpp index d6d226410..af5909f2b 100644 --- a/Protocols/HemiPrep.hpp +++ b/Protocols/HemiPrep.hpp @@ -78,11 +78,4 @@ void HemiPrep::buffer_triples() {{ a.element(i), b.element(i), c.element(i) }}); } -template -void HemiPrep::buffer_inverses() -{ - assert(this->proc != 0); - ::buffer_inverses(this->inverses, *this, this->proc->MC, this->proc->P); -} - #endif diff --git a/Protocols/MAC_Check.h b/Protocols/MAC_Check.h index 68147a626..104a0b503 100644 --- a/Protocols/MAC_Check.h +++ b/Protocols/MAC_Check.h @@ -10,7 +10,6 @@ using namespace std; #include "Protocols/Share.h" #include "Networking/Player.h" #include "Protocols/MAC_Check_Base.h" -#include "Protocols/RandomPrep.h" #include "Tools/time-func.h" @@ -58,7 +57,7 @@ class TreeSum template -class MAC_Check_ : public TreeSum, public MAC_Check_Base +class Tree_MAC_Check : public TreeSum, public MAC_Check_Base { typedef typename U::open_type T; @@ -76,21 +75,32 @@ class MAC_Check_ : public TreeSum, public MAC_Check_Base< public: - MAC_Check_(const typename U::mac_key_type::Scalar& ai, int opening_sum = 10, + Tree_MAC_Check(const typename U::mac_key_type::Scalar& ai, int opening_sum = 10, int max_broadcast = 10, int send_player = 0); - virtual ~MAC_Check_(); + virtual ~Tree_MAC_Check(); virtual void init_open(const Player& P, int n = 0); virtual void prepare_open(const U& secret); virtual void exchange(const Player& P); virtual void AddToCheck(const U& share, const T& value, const Player& P); - virtual void Check(const Player& P); + virtual void Check(const Player& P) = 0; // compatibility void set_random_element(const U& random_element) { (void) random_element; } }; +template +class MAC_Check_ : public Tree_MAC_Check +{ +public: + MAC_Check_(const typename U::mac_key_type::Scalar& ai, int opening_sum = 10, + int max_broadcast = 10, int send_player = 0); + virtual ~MAC_Check_() {} + + virtual void Check(const Player& P); +}; + template using MAC_Check = MAC_Check_>; @@ -99,11 +109,11 @@ template class Spdz2kPrep; template class MascotPrep; template -class MAC_Check_Z2k : public MAC_Check_ +class MAC_Check_Z2k : public Tree_MAC_Check { protected: vector shares; - RandomPrep* prep; + Preprocessing* prep; W get_random_element(); @@ -118,7 +128,7 @@ class MAC_Check_Z2k : public MAC_Check_ virtual void Check(const Player& P); void set_random_element(const W& random_element); - void set_prep(RandomPrep& prep); + void set_prep(Preprocessing& prep); virtual ~MAC_Check_Z2k() {}; }; diff --git a/Protocols/MAC_Check.hpp b/Protocols/MAC_Check.hpp index 13603cf6b..5eee59bf4 100644 --- a/Protocols/MAC_Check.hpp +++ b/Protocols/MAC_Check.hpp @@ -3,7 +3,7 @@ #include "Protocols/MAC_Check.h" #include "Tools/Subroutines.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Tools/random.h" #include "Tools/time-func.h" @@ -31,6 +31,13 @@ const char* TreeSum::mc_timer_names[] = { template MAC_Check_::MAC_Check_(const typename U::mac_key_type::Scalar& ai, int opening_sum, + int max_broadcast, int send_player) : + Tree_MAC_Check(ai, opening_sum, max_broadcast, send_player) +{ +} + +template +Tree_MAC_Check::Tree_MAC_Check(const typename U::mac_key_type::Scalar& ai, int opening_sum, int max_broadcast, int send_player) : TreeSum(opening_sum, max_broadcast, send_player) { @@ -41,7 +48,7 @@ MAC_Check_::MAC_Check_(const typename U::mac_key_type::Scalar& ai, int openin } template -MAC_Check_::~MAC_Check_() +Tree_MAC_Check::~Tree_MAC_Check() { if (WaitingForCheck() > 0) { @@ -51,7 +58,7 @@ MAC_Check_::~MAC_Check_() } template -void MAC_Check_::init_open(const Player&, int n) +void Tree_MAC_Check::init_open(const Player&, int n) { macs.reserve(macs.size() + n); this->secrets.clear(); @@ -61,14 +68,14 @@ void MAC_Check_::init_open(const Player&, int n) } template -void MAC_Check_::prepare_open(const U& secret) +void Tree_MAC_Check::prepare_open(const U& secret) { this->values.push_back(secret.get_share()); macs.push_back(secret.get_mac()); } template -void MAC_Check_::exchange(const Player& P) +void Tree_MAC_Check::exchange(const Player& P) { this->run(this->values, P); @@ -86,14 +93,14 @@ void MAC_Check_::exchange(const Player& P) template -void MAC_Check_::AddToValues(vector& values) +void Tree_MAC_Check::AddToValues(vector& values) { vals.insert(vals.end(), values.begin(), values.end()); } template -void MAC_Check_::CheckIfNeeded(const Player& P) +void Tree_MAC_Check::CheckIfNeeded(const Player& P) { if (WaitingForCheck() >= POPEN_MAX) Check(P); @@ -101,7 +108,7 @@ void MAC_Check_::CheckIfNeeded(const Player& P) template -void MAC_Check_::AddToCheck(const U& share, const T& value, const Player& P) +void Tree_MAC_Check::AddToCheck(const U& share, const T& value, const Player& P) { macs.push_back(share.get_mac()); vals.push_back(value); @@ -114,11 +121,17 @@ void MAC_Check_::AddToCheck(const U& share, const T& value, const Player& P) template void MAC_Check_::Check(const Player& P) { - if (WaitingForCheck() == 0) + assert(U::mac_type::invertible); + + if (this->WaitingForCheck() == 0) return; //cerr << "In MAC Check : " << popen_cnt << endl; + auto& vals = this->vals; + auto& macs = this->macs; + auto& popen_cnt = this->popen_cnt; + if (popen_cnt < 10) { vector deltas; @@ -159,14 +172,14 @@ void MAC_Check_::Check(const Player& P) { h.almost_randomize(G); temp = vals[i] * h; - a.add(a,temp); + a = (a + temp); temp = h * macs[i]; - gami.add(gami,temp); + gami = (gami + temp); } temp = this->alphai * a; - tau[P.my_num()].sub(gami,temp); + tau[P.my_num()] = (gami - temp); //cerr << "\tCommit and Open" << endl; this->timers[COMMIT].start(); @@ -178,7 +191,7 @@ void MAC_Check_::Check(const Player& P) typename U::mac_type t; t.assign_zero(); for (int i=0; i::Check(const Player& P) template MAC_Check_Z2k::MAC_Check_Z2k(const T& ai, int opening_sum, int max_broadcast, int send_player) : - MAC_Check_(ai, opening_sum, max_broadcast, send_player), prep(0) + Tree_MAC_Check(ai, opening_sum, max_broadcast, send_player), prep(0) { } @@ -205,7 +218,7 @@ template void MAC_Check_Z2k::AddToCheck(const W& share, const T& value, const Player& P) { shares.push_back(share.get_share()); - MAC_Check_::AddToCheck(share, value, P); + Tree_MAC_Check::AddToCheck(share, value, P); } template @@ -242,7 +255,7 @@ void MAC_Check_Z2k::set_random_element(const W& random_element) { } template -void MAC_Check_Z2k::set_prep(RandomPrep& prep) +void MAC_Check_Z2k::set_prep(Preprocessing& prep) { this->prep = &prep; } diff --git a/Protocols/MalRepRingPrep.hpp b/Protocols/MalRepRingPrep.hpp index 790c45e99..4a784cdd5 100644 --- a/Protocols/MalRepRingPrep.hpp +++ b/Protocols/MalRepRingPrep.hpp @@ -99,7 +99,7 @@ void shuffle_triple_generation(vector>& triples, Player& P, typename T::MAC_Check& MC, int n_bits = -1, ThreadQueues* queues = 0) { RunningTimer timer; - ShuffleSacrifice sacrifice; + TripleShuffleSacrifice sacrifice; vector> check_triples; int buffer_size = sacrifice.minimum_n_inputs(OnlineOptions::singleton.batch_size); @@ -120,9 +120,8 @@ void shuffle_triple_generation(vector>& triples, Player& P, #endif } -template template -void ShuffleSacrifice::shuffle(vector& check_triples, Player& P) +void ShuffleSacrifice::shuffle(vector& check_triples, Player& P) { int buffer_size = check_triples.size(); assert(buffer_size >= minimum_n_inputs()); @@ -138,7 +137,7 @@ void ShuffleSacrifice::shuffle(vector& check_triples, Player& P) } template -void ShuffleSacrifice::triple_sacrifice(vector>& triples, +void TripleShuffleSacrifice::triple_sacrifice(vector>& triples, vector>& check_triples, Player& P, typename T::MAC_Check& MC, ThreadQueues* queues) { @@ -175,7 +174,7 @@ void ShuffleSacrifice::triple_sacrifice(vector>& triples, } template -void ShuffleSacrifice::triple_sacrifice(vector>& triples, +void TripleShuffleSacrifice::triple_sacrifice(vector>& triples, vector>& check_triples, Player& P, typename T::MAC_Check& MC, int begin, int end) { diff --git a/Protocols/MaliciousRepPrep.h b/Protocols/MaliciousRepPrep.h index 5e701b7f0..b9b744a0a 100644 --- a/Protocols/MaliciousRepPrep.h +++ b/Protocols/MaliciousRepPrep.h @@ -47,7 +47,6 @@ class MaliciousRepPrep : public MaliciousBitOnlyRepPrep protected: void buffer_triples(); void buffer_squares(); - void buffer_inverses(); void buffer_inputs(int player); public: diff --git a/Protocols/MaliciousRepPrep.hpp b/Protocols/MaliciousRepPrep.hpp index ce18d8826..f2bf9d984 100644 --- a/Protocols/MaliciousRepPrep.hpp +++ b/Protocols/MaliciousRepPrep.hpp @@ -162,13 +162,6 @@ void MaliciousRepPrep::buffer_squares() MC.CheckFor(0, checks, P); } -template -void MaliciousRepPrep::buffer_inverses() -{ - assert(this->honest_proc); - ::buffer_inverses(this->inverses, *this, this->MC, this->honest_proc->P); -} - template void MaliciousBitOnlyRepPrep::buffer_bits() { diff --git a/Protocols/MaliciousRingPrep.hpp b/Protocols/MaliciousRingPrep.hpp index 13ce21b80..4caf78fe1 100644 --- a/Protocols/MaliciousRingPrep.hpp +++ b/Protocols/MaliciousRingPrep.hpp @@ -13,6 +13,20 @@ template void MaliciousRingPrep::buffer_dabits(ThreadQueues* queues) +{ + buffer_dabits<0>(queues, T::clear::characteristic_two); +} + +template +template +void MaliciousRingPrep::buffer_dabits(ThreadQueues*, true_type) +{ + throw runtime_error("only implemented for integer-like domains"); +} + +template +template +void MaliciousRingPrep::buffer_dabits(ThreadQueues* queues, false_type) { assert(this->proc != 0); vector> check_dabits; diff --git a/Protocols/MaliciousShamirShare.h b/Protocols/MaliciousShamirShare.h index 56086fc78..47592981f 100644 --- a/Protocols/MaliciousShamirShare.h +++ b/Protocols/MaliciousShamirShare.h @@ -36,7 +36,9 @@ class MaliciousShamirShare : public ShamirShare typedef MaliciousRepPrep TriplePrep; typedef T random_type; +#ifndef NO_MIXED_CIRCUITS typedef GC::MaliciousCcdSecret bit_type; +#endif static string type_short() { diff --git a/Protocols/MamaPrep.h b/Protocols/MamaPrep.h index a1e774fe7..9c142edc7 100644 --- a/Protocols/MamaPrep.h +++ b/Protocols/MamaPrep.h @@ -9,7 +9,7 @@ #include "MascotPrep.h" template -class MamaPrep : public OTPrep +class MamaPrep : public OTPrep, public MaliciousRingPrep { public: static void basic_setup(Player&) {}; diff --git a/Protocols/MamaPrep.hpp b/Protocols/MamaPrep.hpp index 7a56e693b..ff91836a4 100644 --- a/Protocols/MamaPrep.hpp +++ b/Protocols/MamaPrep.hpp @@ -10,7 +10,8 @@ template MamaPrep::MamaPrep(SubProcessor* proc, DataPositions& usage) : BufferPrep(usage), BitPrep(proc, usage), - OTPrep(proc, usage) + RingPrep(proc, usage), OTPrep(proc, usage), + MaliciousRingPrep(proc, usage) { this->params.amplify = true; this->params.generateMACs = true; @@ -37,7 +38,7 @@ void MamaPrep::buffer_triples() assert(this->proc != 0); this->params.generateBits = false; vector> triples; - ShuffleSacrifice sacrifice; + TripleShuffleSacrifice sacrifice; size_t required = OnlineOptions::singleton.batch_size; // prefer shuffling if not loosing much security and bucket size is smaller diff --git a/Protocols/MamaShare.h b/Protocols/MamaShare.h index 71be6097c..b875bd42c 100644 --- a/Protocols/MamaShare.h +++ b/Protocols/MamaShare.h @@ -16,13 +16,35 @@ template class MamaMultiplier; template class SimpleMascotTripleGenerator; template -class MamaShare : public Share_, FixedVec, N>> +class MamaMac : public FixedVec, N> +{ + typedef FixedVec, N> super; + +public: + static const true_type invertible; + + MamaMac() + { + } + + template + MamaMac(const U& other) : + super(other) + { + } +}; + +template +const true_type MamaMac::invertible; + +template +class MamaShare : public Share_, MamaMac> { typedef MamaShare This; public: typedef FixedVec, N> mac_key_type; - typedef Share_, mac_key_type> super; + typedef Share_, MamaMac> super; typedef Beaver Protocol; typedef MAC_Check_ MAC_Check; diff --git a/Protocols/MascotPrep.h b/Protocols/MascotPrep.h index 990eaa33b..50d08735f 100644 --- a/Protocols/MascotPrep.h +++ b/Protocols/MascotPrep.h @@ -7,7 +7,6 @@ #define PROTOCOLS_MASCOTPREP_H_ #include "ReplicatedPrep.h" -#include "RandomPrep.h" #include "OT/MascotParams.h" template @@ -28,7 +27,7 @@ class OTPrep : public virtual BitPrep }; template -class MascotTriplePrep : public OTPrep, public RandomPrep +class MascotTriplePrep : public OTPrep { public: MascotTriplePrep(SubProcessor *proc, DataPositions &usage) : @@ -39,8 +38,6 @@ class MascotTriplePrep : public OTPrep, public RandomPrep void buffer_triples(); void buffer_inputs(int player); - - T get_random(); }; template @@ -60,14 +57,12 @@ class MascotPrep: public virtual MaliciousRingPrep, } void buffer_bits() { throw runtime_error("use subclass"); } - virtual void buffer_dabits(ThreadQueues* queues); void buffer_edabits(bool strict, int n_bits, ThreadQueues* queues); }; template class MascotFieldPrep : public MascotPrep { - void buffer_inverses(); void buffer_bits(); public: diff --git a/Protocols/MascotPrep.hpp b/Protocols/MascotPrep.hpp index 7cf956216..50d786405 100644 --- a/Protocols/MascotPrep.hpp +++ b/Protocols/MascotPrep.hpp @@ -65,13 +65,6 @@ void MascotTriplePrep::buffer_triples() {{ triple.a[0], triple.b, triple.c[0] }}); } -template -void MascotFieldPrep::buffer_inverses() -{ - assert(this->proc != 0); - ::buffer_inverses(this->inverses, *this, this->proc->MC, this->proc->P); -} - template void MascotFieldPrep::buffer_bits() { @@ -84,21 +77,6 @@ void MascotFieldPrep::buffer_bits() this->bits.push_back(bit); } -template -void MascotPrep::buffer_dabits(ThreadQueues* queues) -{ - assert(this->proc != 0); - DabitSacrifice dabit_sacrifice; - vector> check_dabits; -#ifdef VERBOSE_DABIT - cerr << "Generate daBits to sacrifice" << endl; -#endif - this->buffer_dabits_without_check(check_dabits, - dabit_sacrifice.minimum_n_inputs(), queues); - dabit_sacrifice.sacrifice_and_check_bits(this->dabits, check_dabits, - *this->proc, queues); -} - template void MascotTriplePrep::buffer_inputs(int player) { @@ -112,14 +90,7 @@ void MascotTriplePrep::buffer_inputs(int player) } template -T MascotTriplePrep::get_random() -{ - assert(this->proc); - return BufferPrep::get_random_from_inputs(this->proc->P.num_players()); -} - -template -T BufferPrep::get_random_from_inputs(int nplayers) +T Preprocessing::get_random_from_inputs(int nplayers) { T res; for (int j = 0; j < nplayers; j++) diff --git a/Protocols/RandomPrep.h b/Protocols/RandomPrep.h deleted file mode 100644 index ab13bf307..000000000 --- a/Protocols/RandomPrep.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * RandomPrep.h - * - */ - -#ifndef PROTOCOLS_RANDOMPREP_H_ -#define PROTOCOLS_RANDOMPREP_H_ - -template -class RandomPrep -{ -public: - virtual ~RandomPrep() {} - - virtual T get_random() = 0; -}; - -#endif /* PROTOCOLS_RANDOMPREP_H_ */ diff --git a/Protocols/Rep3Share.h b/Protocols/Rep3Share.h index 017901a70..dc367fd7c 100644 --- a/Protocols/Rep3Share.h +++ b/Protocols/Rep3Share.h @@ -46,37 +46,6 @@ class RepShare : public FixedVec, public ShareInterface { } - void add(const This& x, const This& y) - { - *this = x + y; - } - void sub(const This& x, const This& y) - { - *this = x - y; - } - - template - void add(const U& S, const clear aa, int my_num, - const T& alphai) - { - (void)alphai; - *this = S + S.constant(aa, my_num); - } - template - void sub(const U& S, const clear& aa, int my_num, - const T& alphai) - { - (void)alphai; - *this = S - S.constant(aa, my_num); - } - template - void sub(const clear& aa, const U& S, int my_num, - const T& alphai) - { - (void)alphai; - *this = S.constant(aa, my_num) - S; - } - void mul_by_bit(const This& x, const T& y) { (void) x, (void) y; @@ -156,12 +125,6 @@ class Rep3Share : public RepShare Replicated::assign(*this, value, my_num); } - // Share compatibility - void assign(clear other, int my_num, const T& alphai) - { - (void)alphai; - *this = Rep3Share(other, my_num); - } void assign(const char* buffer) { FixedVec::assign(buffer); diff --git a/Protocols/Rep4.h b/Protocols/Rep4.h index 2db2c660a..f9bfcd5a2 100644 --- a/Protocols/Rep4.h +++ b/Protocols/Rep4.h @@ -48,6 +48,13 @@ class Rep4 : public ProtocolBase int get_player(int offset); + template + void trunc_pr(const vector& regs, int size, SubProcessor& proc, + true_type); + template + void trunc_pr(const vector& regs, int size, SubProcessor& proc, + false_type); + public: array, 3> rep_prngs; Player& P; diff --git a/Protocols/Rep4.hpp b/Protocols/Rep4.hpp index 42bedb5cd..fe44c1ada 100644 --- a/Protocols/Rep4.hpp +++ b/Protocols/Rep4.hpp @@ -280,7 +280,22 @@ void Rep4::randoms(T& res, int n_bits) template void Rep4::trunc_pr(const vector& regs, int size, - SubProcessor& proc) + SubProcessor& proc) +{ + trunc_pr<0>(regs, size, proc, T::clear::characteristic_two); +} + +template +template +void Rep4::trunc_pr(const vector&, int, SubProcessor&, true_type) +{ + throw runtime_error("only implemented for integer-like domains"); +} + +template +template +void Rep4::trunc_pr(const vector& regs, int size, + SubProcessor& proc, false_type) { assert(regs.size() % 4 == 0); typedef typename T::open_type open_type; diff --git a/Protocols/Rep4Prep.h b/Protocols/Rep4Prep.h index 008614858..148e4285a 100644 --- a/Protocols/Rep4Prep.h +++ b/Protocols/Rep4Prep.h @@ -22,15 +22,6 @@ class Rep4RingPrep : public MaliciousRingPrep Rep4RingPrep(SubProcessor* proc, DataPositions& usage); }; -template -class Rep4Prep : public Rep4RingPrep -{ - void buffer_inverses(); - -public: - Rep4Prep(SubProcessor* proc, DataPositions& usage); -}; - template class Rep4RingOnlyPrep : public virtual Rep4RingPrep, public virtual RepRingOnlyEdabitPrep diff --git a/Protocols/Rep4Prep.hpp b/Protocols/Rep4Prep.hpp index 0ff8b609f..48b843e0c 100644 --- a/Protocols/Rep4Prep.hpp +++ b/Protocols/Rep4Prep.hpp @@ -15,13 +15,6 @@ Rep4RingPrep::Rep4RingPrep(SubProcessor* proc, DataPositions& usage) : { } -template -Rep4Prep::Rep4Prep(SubProcessor* proc, DataPositions& usage) : - BufferPrep(usage), BitPrep(proc, usage), - RingPrep(proc, usage), Rep4RingPrep(proc, usage) -{ -} - template Rep4RingOnlyPrep::Rep4RingOnlyPrep(SubProcessor* proc, DataPositions& usage) : @@ -107,11 +100,4 @@ void Rep4RingPrep::buffer_bits() a[i].res + b[i].res - two * protocol.finalize_mul()); } -template -void Rep4Prep::buffer_inverses() -{ - assert(this->proc != 0); - ::buffer_inverses(this->inverses, *this, this->proc->MC, this->proc->P); -} - #endif /* PROTOCOLS_REP4PREP_HPP_ */ diff --git a/Protocols/Rep4Share.h b/Protocols/Rep4Share.h index d9e6eccee..98aa54908 100644 --- a/Protocols/Rep4Share.h +++ b/Protocols/Rep4Share.h @@ -11,7 +11,7 @@ template class Rep4MC; template class Rep4; -template class Rep4Prep; +template class Rep4RingPrep; template class Rep4Input; namespace GC @@ -33,7 +33,7 @@ class Rep4Share : public RepShare typedef MAC_Check Direct_MC; typedef Rep4Input Input; typedef ::PrivateOutput PrivateOutput; - typedef Rep4Prep LivePrep; + typedef Rep4RingPrep LivePrep; typedef LivePrep SquarePrep; typedef GC::Rep4Secret bit_type; diff --git a/Protocols/Replicated.h b/Protocols/Replicated.h index 373ef4ee1..846a269b0 100644 --- a/Protocols/Replicated.h +++ b/Protocols/Replicated.h @@ -44,7 +44,7 @@ class ReplicatedBase template class ProtocolBase { - virtual void buffer_random() { not_implemented(); } + virtual void buffer_random() { throw not_implemented(); } protected: vector random; @@ -93,7 +93,7 @@ class ProtocolBase template class Replicated : public ReplicatedBase, public ProtocolBase { - vector os; + array os; PointerVector add_shares; typename T::clear dotprod_share; diff --git a/Protocols/Replicated.hpp b/Protocols/Replicated.hpp index 53b67d3d1..abc8c82a3 100644 --- a/Protocols/Replicated.hpp +++ b/Protocols/Replicated.hpp @@ -127,7 +127,10 @@ template T ProtocolBase::get_random() { if (random.empty()) + { buffer_random(); + assert(not random.empty()); + } auto res = random.back(); random.pop_back(); @@ -151,7 +154,6 @@ void Replicated::init_mul(Preprocessing& prep, typename T::MAC_Check& MC) template void Replicated::init_mul() { - os.resize(2); for (auto& o : os) o.reset_write_head(); add_shares.clear(); diff --git a/Protocols/ReplicatedPrep.h b/Protocols/ReplicatedPrep.h index 5b129a817..e49864985 100644 --- a/Protocols/ReplicatedPrep.h +++ b/Protocols/ReplicatedPrep.h @@ -17,10 +17,6 @@ #include -template -void buffer_inverses(vector>& inverses, Preprocessing& prep, - MAC_Check_Base& MC, Player& P); - template void bits_from_random(vector& bits, typename T::Protocol& protocol); @@ -29,6 +25,11 @@ class BufferPrep : public Preprocessing { template friend class Machine; + template + void buffer_inverses(true_type); + template + void buffer_inverses(false_type) { throw runtime_error("no inverses"); } + protected: vector> triples; vector> squares; @@ -44,7 +45,7 @@ class BufferPrep : public Preprocessing virtual void buffer_triples() { throw runtime_error("no triples"); } virtual void buffer_squares() { throw runtime_error("no squares"); } - virtual void buffer_inverses() { throw runtime_error("no inverses"); } + virtual void buffer_inverses(); virtual void buffer_bits() { throw runtime_error("no bits"); } virtual void buffer_inputs(int player); @@ -94,10 +95,10 @@ class BufferPrep : public Preprocessing void get_no_count(vector& S, DataTag tag, const vector& regs, int vector_size); - T get_random_from_inputs(int nplayers); - virtual void get_dabit_no_count(T& a, typename T::bit_type& b); + virtual T get_random(); + void push_triples(const vector>& triples) { this->triples.insert(this->triples.end(), triples.begin(), triples.end()); } void push_triple(const array& triple) @@ -141,49 +142,51 @@ class RingPrep : public virtual BitPrep protected: void buffer_dabits_without_check(vector>& dabits, int buffer_size = -1, ThreadQueues* queues = 0); + template void buffer_edabits_without_check(int n_bits, vector& sums, vector>& bits, int buffer_size, ThreadQueues* queues = 0); + template void buffer_edabits_without_check(int n_bits, vector>& edabits, int buffer_size); - void buffer_personal_edabits(int n_bits, vector& sums, - vector>& bits, SubProcessor& proc, int input_player, - bool strict, ThreadQueues* queues = 0); - - virtual void buffer_sedabits_from_edabits(int); + void buffer_sedabits_from_edabits(int n_bits) + { this->template buffer_sedabits_from_edabits<0>(n_bits, T::clear::characteristic_two); } + template + void buffer_sedabits_from_edabits(int n_bits, false_type); + template + void buffer_sedabits_from_edabits(int, true_type) + { throw not_implemented(); } + template void sanitize(vector>& edabits, int n_bits); public: - static void edabit_sacrifice_buckets(vector>& to_check, size_t n_bits, - bool strict, int player, SubProcessor& proc, int begin, int end, - const void* supply = 0) - { - ShuffleSacrifice().edabit_sacrifice_buckets(to_check, n_bits, strict, - player, proc, begin, end, supply); - } - RingPrep(SubProcessor* proc, DataPositions& usage); virtual ~RingPrep() {} vector& get_bits() { return this->bits; } + template void sanitize(vector>& edabits, int n_bits, int player = -1, ThreadQueues* queues = 0); + template void sanitize(vector>& edabits, int n_bits, int player, int begin, int end); void buffer_dabits_without_check(vector>& dabits, size_t begin, size_t end); + template void buffer_dabits_without_check(vector>& dabits, size_t begin, size_t end, Preprocessing& bit_prep); + template void buffer_edabits_without_check(int n_bits, vector& sums, vector>& bits, int begin, int end); + template void buffer_personal_edabits_without_check(int n_bits, vector& sums, vector >& bits, SubProcessor& proc, int input_player, int begin, int end); @@ -207,8 +210,15 @@ class SemiHonestRingPrep : public virtual RingPrep virtual void buffer_dabits(ThreadQueues*) { this->buffer_dabits_without_check(this->dabits); } virtual void buffer_edabits(int n_bits, ThreadQueues*) - { this->buffer_edabits_without_check(n_bits, this->edabits[{false, n_bits}], + { buffer_edabits<0>(n_bits, T::clear::characteristic_two); } + template + void buffer_edabits(int n_bits, false_type) + { this->template buffer_edabits_without_check<0>(n_bits, + this->edabits[{false, n_bits}], OnlineOptions::singleton.batch_size); } + template + void buffer_edabits(int, true_type) + { throw not_implemented(); } virtual void buffer_sedabits(int n_bits, ThreadQueues*) { this->buffer_sedabits_from_edabits(n_bits); } }; @@ -216,12 +226,40 @@ class SemiHonestRingPrep : public virtual RingPrep template class MaliciousRingPrep : public virtual RingPrep { + typedef typename T::bit_type::part_type BT; + protected: + void buffer_personal_edabits(int n_bits, vector& sums, + vector>& bits, SubProcessor& proc, int input_player, + bool strict, ThreadQueues* queues = 0); + void buffer_edabits_from_personal(bool strict, int n_bits, ThreadQueues* queues); + template + void buffer_edabits_from_personal(bool strict, int n_bits, + ThreadQueues* queues, true_type); + template + void buffer_edabits_from_personal(bool strict, int n_bits, + ThreadQueues* queues, false_type); + void buffer_personal_dabits(int input_player); + void buffer_personal_dabits(int input_player, true_type); + void buffer_personal_dabits(int input_player, false_type); + + template + void buffer_dabits(ThreadQueues* queues, true_type); + template + void buffer_dabits(ThreadQueues* queues, false_type); public: + static void edabit_sacrifice_buckets(vector>& to_check, size_t n_bits, + bool strict, int player, SubProcessor& proc, int begin, int end, + const void* supply = 0) + { + EdabitShuffleSacrifice().edabit_sacrifice_buckets(to_check, n_bits, strict, + player, proc, begin, end, supply); + } + MaliciousRingPrep(SubProcessor* proc, DataPositions& usage) : BufferPrep(usage), BitPrep(proc, usage), RingPrep(proc, usage) @@ -256,8 +294,6 @@ template class ReplicatedPrep : public virtual ReplicatedRingPrep, public virtual SemiHonestRingPrep { - void buffer_inverses(); - public: ReplicatedPrep(SubProcessor* proc, DataPositions& usage) : BufferPrep(usage), BitPrep(proc, usage), diff --git a/Protocols/ReplicatedPrep.hpp b/Protocols/ReplicatedPrep.hpp index 997e8f92c..e373aa6b9 100644 --- a/Protocols/ReplicatedPrep.hpp +++ b/Protocols/ReplicatedPrep.hpp @@ -19,6 +19,24 @@ #include "GC/ShareThread.hpp" #include "GC/BitAdder.hpp" +class InScope +{ + bool& variable; + bool backup; + +public: + InScope(bool& variable, bool value) : + variable(variable) + { + backup = variable; + variable = value; + } + ~InScope() + { + variable = backup; + } +}; + template BufferPrep::BufferPrep(DataPositions& usage) : Preprocessing(usage), n_bit_rounds(0), @@ -31,26 +49,20 @@ template BufferPrep::~BufferPrep() { #ifdef VERBOSE + string type_string = T::type_string(); if (n_bit_rounds > 0) - cerr << n_bit_rounds << " rounds of random " << T::type_string() + cerr << n_bit_rounds << " rounds of random " << type_string << " bit generation" << endl; #define X(KIND) \ - if (KIND.size()) \ - cerr << "\t" << KIND.size() << " " #KIND " of " << T::type_string() \ - << " left" << endl; + this->print_left(#KIND, KIND.size(), type_string); X(triples) X(squares) X(inverses) X(bits) X(dabits) #undef X for (auto& x : this->edabits) { - if (not x.second.empty()) - { - cerr << "\t~" << x.second.size() * x.second[0].size(); - if (not x.first.first) - cerr << " loose"; - cerr << " edaBits of size " << x.first.second << " left" << endl; - } + this->print_left_edabits(x.second.size(), x.second[0].size(), + x.first.first, x.first.second); } #endif } @@ -185,18 +197,19 @@ void generate_squares(vector>& squares, int n_squares, } template -void ReplicatedPrep::buffer_inverses() +void BufferPrep::buffer_inverses() { - auto protocol = this->protocol; - assert(protocol != 0); - typename T::MAC_Check MC; - ::buffer_inverses(this->inverses, *this, MC, protocol->P); + buffer_inverses<0>(T::clear::invertible); } template -void buffer_inverses(vector>& inverses, Preprocessing& prep, - MAC_Check_Base& MC, Player& P) +template +void BufferPrep::buffer_inverses(true_type) { + assert(proc != 0); + auto& P = proc->P; + auto& MC = proc->MC; + auto& prep = *this; int buffer_size = OnlineOptions::singleton.batch_size; vector> triples(buffer_size); vector c; @@ -316,6 +329,18 @@ void BitPrep::buffer_bits_without_check() template void MaliciousRingPrep::buffer_personal_dabits(int input_player) +{ + buffer_personal_dabits(input_player, T::clear::characteristic_two); +} + +template +void MaliciousRingPrep::buffer_personal_dabits(int, true_type) +{ + throw runtime_error("only implemented for integer-like domains"); +} + +template +void MaliciousRingPrep::buffer_personal_dabits(int input_player, false_type) { assert(this->proc != 0); auto& P = this->proc->P; @@ -360,6 +385,7 @@ void MaliciousRingPrep::buffer_personal_dabits(int input_player) template +template void RingPrep::buffer_personal_edabits_without_check(int n_bits, vector& sums, vector >& bits, SubProcessor& proc, int input_player, int begin, int end) @@ -417,7 +443,7 @@ void RingPrep::buffer_personal_edabits_without_check(int n_bits, } template -void RingPrep::buffer_personal_edabits(int n_bits, vector& wholes, +void MaliciousRingPrep::buffer_personal_edabits(int n_bits, vector& wholes, vector >& parts, SubProcessor& proc, int input_player, bool strict, ThreadQueues* queues) { @@ -427,7 +453,7 @@ void RingPrep::buffer_personal_edabits(int n_bits, vector& wholes, Timer timer; timer.start(); #endif - ShuffleSacrifice shuffle_sacrifice; + EdabitShuffleSacrifice shuffle_sacrifice; int buffer_size = shuffle_sacrifice.minimum_n_inputs(); vector sums(buffer_size); vector> bits(n_bits, vector(DIV_CEIL(buffer_size, BT::default_length))); @@ -435,13 +461,13 @@ void RingPrep::buffer_personal_edabits(int n_bits, vector& wholes, { ThreadJob job(n_bits, &sums, &bits, input_player); int start = queues->distribute(job, buffer_size, 0, BT::default_length); - buffer_personal_edabits_without_check(n_bits, sums, bits, proc, - input_player, start, buffer_size); + this->template buffer_personal_edabits_without_check<0>(n_bits, sums, + bits, proc, input_player, start, buffer_size); queues->wrap_up(job); } else - buffer_personal_edabits_without_check(n_bits, sums, bits, proc, - input_player, 0, buffer_size); + this->template buffer_personal_edabits_without_check<0>(n_bits, sums, + bits, proc, input_player, 0, buffer_size); #ifdef VERBOSE_EDA cerr << "Done with generating personal edaBits after " << timer.elapsed() << " seconds" << endl; @@ -560,10 +586,11 @@ void RingPrep::buffer_dabits_without_check(vector>& dabits, { auto proc = this->proc; assert(proc != 0); - buffer_dabits_without_check(dabits, begin, end, proc->bit_prep); + buffer_dabits_without_check<0>(dabits, begin, end, proc->bit_prep); } template +template void RingPrep::buffer_dabits_without_check(vector>& dabits, size_t begin, size_t end, Preprocessing& bit_prep) @@ -599,6 +626,7 @@ void RingPrep::buffer_dabits_without_check(vector>& dabits, } template +template void RingPrep::buffer_edabits_without_check(int n_bits, vector& sums, vector>& bits, int buffer_size, ThreadQueues* queues) @@ -612,11 +640,11 @@ void RingPrep::buffer_edabits_without_check(int n_bits, vector& sums, { ThreadJob job(n_bits, &sums, &bits); int start = queues->distribute(job, rounded, 0, dl); - buffer_edabits_without_check(n_bits, sums, bits, start, rounded); + buffer_edabits_without_check<0>(n_bits, sums, bits, start, rounded); queues->wrap_up(job); } else - buffer_edabits_without_check(n_bits, sums, bits, 0, rounded); + buffer_edabits_without_check<0>(n_bits, sums, bits, 0, rounded); sums.resize(buffer_size); #ifdef VERBOSE_EDA cerr << "Done with unchecked edaBit generation after " << timer.elapsed() @@ -625,6 +653,7 @@ void RingPrep::buffer_edabits_without_check(int n_bits, vector& sums, } template +template void RingPrep::buffer_edabits_without_check(int n_bits, vector& sums, vector>& bits, int begin, int end) @@ -645,7 +674,7 @@ void RingPrep::buffer_edabits_without_check(int n_bits, vector& sums, vector>> parts(n_relevant, vector>(n_bits, vector(buffer_size / dl))); for (int i = 0; i < n_relevant; i++) - buffer_personal_edabits_without_check(n_bits, player_ints[i], parts[i], + buffer_personal_edabits_without_check<0>(n_bits, player_ints[i], parts[i], bit_proc, i, 0, buffer_size); vector>> player_bits(n_bits, vector>(n_relevant)); @@ -664,6 +693,7 @@ void RingPrep::buffer_edabits_without_check(int n_bits, vector& sums, } template +template void RingPrep::buffer_edabits_without_check(int n_bits, vector>& edabits, int buffer_size) { @@ -671,7 +701,7 @@ void RingPrep::buffer_edabits_without_check(int n_bits, vector>& typedef typename T::bit_type::part_type bit_type; vector> bits; vector sums; - buffer_edabits_without_check(n_bits, sums, bits, buffer_size); + buffer_edabits_without_check<0>(n_bits, sums, bits, buffer_size); this->push_edabits(edabits, sums, bits, buffer_size); (void) stat; #ifdef VERBOSE_PREP @@ -696,14 +726,15 @@ void BufferPrep::push_edabits(vector>& edabits, } template -void RingPrep::buffer_sedabits_from_edabits(int n_bits) +template +void RingPrep::buffer_sedabits_from_edabits(int n_bits, false_type) { assert(this->proc != 0); size_t buffer_size = OnlineOptions::singleton.batch_size; auto& loose = this->edabits[{false, n_bits}]; while (loose.size() < size_t(DIV_CEIL(buffer_size, edabitvec::MAX_SIZE))) this->buffer_edabits(false, n_bits); - sanitize(loose, n_bits); + sanitize<0>(loose, n_bits); for (auto& x : loose) { this->edabits[{true, n_bits}].push_back(x); @@ -712,6 +743,7 @@ void RingPrep::buffer_sedabits_from_edabits(int n_bits) } template +template void RingPrep::sanitize(vector>& edabits, int n_bits, int player, ThreadQueues* queues) { @@ -719,14 +751,15 @@ void RingPrep::sanitize(vector>& edabits, int n_bits, { SanitizeJob job(&edabits, n_bits, player); int start = queues->distribute(job, edabits.size()); - sanitize(edabits, n_bits, player, start, edabits.size()); + sanitize<0>(edabits, n_bits, player, start, edabits.size()); queues->wrap_up(job); } else - sanitize(edabits, n_bits, player, 0, edabits.size()); + sanitize<0>(edabits, n_bits, player, 0, edabits.size()); } template +template void RingPrep::sanitize(vector>& edabits, int n_bits, int player, int begin, int end) { @@ -773,12 +806,14 @@ void RingPrep::sanitize(vector>& edabits, int n_bits, int player, - mask * typename T::clear(masked * 2); whole -= overflow << j; } + x.second.resize(n_bits); } MCB.Check(this->proc->P); delete &MCB; } template +template void RingPrep::sanitize(vector>& edabits, int n_bits) { vector dabits; @@ -822,6 +857,7 @@ void RingPrep::sanitize(vector>& edabits, int n_bits) x.a[i] -= overflow << j; } } + x.b.resize(n_bits); } MCB.Check(this->proc->P); delete &MCB; @@ -888,6 +924,7 @@ void BufferPrep::get_one_no_count(Dtype dtype, T& a) while (bits.empty()) { + InScope in_scope(this->do_count, false); buffer_bits(); n_bit_rounds++; } @@ -914,6 +951,7 @@ void BufferPrep::get_dabit_no_count(T& a, typename T::bit_type& b) { if (dabits.empty()) { + InScope in_scope(this->do_count, false); ThreadQueues* queues = 0; buffer_dabits(queues); } @@ -941,16 +979,28 @@ void Preprocessing::get_dabit(T& a, typename T::bit_type& b) } template -void Preprocessing::get_edabit_no_count(bool strict, int n_bits, edabit& a) +template +edabitvec Preprocessing::get_edabitvec(bool strict, int n_bits) { auto& buffer = this->edabits[{strict, n_bits}]; + if (buffer.empty()) + { + InScope in_scope(this->do_count, false); + buffer_edabits_with_queues(strict, n_bits); + } + auto res = buffer.back(); + buffer.pop_back(); + return res; +} + +template +template +void Preprocessing::get_edabit_no_count(bool strict, int n_bits, edabit& a) +{ auto& my_edabit = my_edabits[{strict, n_bits}]; if (my_edabit.empty()) { - if (buffer.empty()) - buffer_edabits_with_queues(strict, n_bits); - my_edabit = buffer.back(); - buffer.pop_back(); + my_edabit = this->template get_edabitvec<0>(strict, n_bits); } a = my_edabit.next(); } @@ -965,8 +1015,9 @@ void BufferPrep::buffer_edabits_with_queues(bool strict, int n_bits) } template +template void Preprocessing::get_edabits(bool strict, size_t size, T* a, - vector& Sb, const vector& regs) + vector& Sb, const vector& regs, false_type) { int n_bits = regs.size(); auto& buffer = edabits[{strict, n_bits}]; @@ -986,7 +1037,7 @@ void Preprocessing::get_edabits(bool strict, size_t size, T* a, { for (size_t i = k * unit; i < min(size, (k + 1) * unit); i++) { - this->get_edabit_no_count(strict, n_bits, eb); + this->template get_edabit_no_count<0>(strict, n_bits, eb); a[i] = eb.first; for (int j = 0; j < n_bits; j++) { @@ -1000,7 +1051,7 @@ void Preprocessing::get_edabits(bool strict, size_t size, T* a, } for (size_t i = 0; i < size; i++) - this->count_edabit(strict, n_bits); + this->usage.count_edabit(strict, n_bits); } template @@ -1068,4 +1119,20 @@ void BufferPrep::shrink_to_fit() triples.shrink_to_fit(); } +template +T BufferPrep::get_random() +{ + try + { + if (proc != 0) + return proc->protocol.get_random(); + else + throw not_implemented(); + } + catch (not_implemented&) + { + return Preprocessing::get_random(); + } +} + #endif diff --git a/Protocols/SemiPrep.h b/Protocols/SemiPrep.h index 9e61167ca..7148c8a9b 100644 --- a/Protocols/SemiPrep.h +++ b/Protocols/SemiPrep.h @@ -15,7 +15,6 @@ class SemiPrep : public virtual OTPrep, public virtual SemiHonestRingPrep SemiPrep(SubProcessor* proc, DataPositions& usage); void buffer_triples(); - void buffer_inverses(); }; #endif /* PROTOCOLS_SEMIPREP_H_ */ diff --git a/Protocols/SemiPrep.hpp b/Protocols/SemiPrep.hpp index a60f00a61..88b894911 100644 --- a/Protocols/SemiPrep.hpp +++ b/Protocols/SemiPrep.hpp @@ -29,10 +29,3 @@ void SemiPrep::buffer_triples() } this->triple_generator->unlock(); } - -template -void SemiPrep::buffer_inverses() -{ - assert(this->proc != 0); - ::buffer_inverses(this->inverses, *this, this->proc->MC, this->proc->P); -} diff --git a/Protocols/SemiShare.h b/Protocols/SemiShare.h index 1e1a8a1ee..96b77173c 100644 --- a/Protocols/SemiShare.h +++ b/Protocols/SemiShare.h @@ -81,46 +81,16 @@ class SemiShare : public T, public ShareInterface { } SemiShare(const clear& other, int my_num, const T& alphai = {}) - { - (void) alphai; - assign(other, my_num); - } - - void assign(const clear& other, int my_num, const T& alphai = {}) { (void) alphai; Protocol::assign(*this, other, my_num); } + void assign(const char* buffer) { super::assign(buffer); } - void add(const SemiShare& x, const SemiShare& y) - { - *this = x + y; - } - void sub(const SemiShare& x, const SemiShare& y) - { - *this = x - y; - } - - void add(const SemiShare& S, const clear aa, int my_num, const T& alphai) - { - (void) alphai; - *this = S + SemiShare(aa, my_num); - } - void sub(const SemiShare& S, const clear& aa, int my_num, const T& alphai) - { - (void) alphai; - *this = S - SemiShare(aa, my_num); - } - void sub(const clear& aa, const SemiShare& S, int my_num, const T& alphai) - { - (void) alphai; - *this = SemiShare(aa, my_num) - S; - } - void pack(octetStream& os, bool full = true) const { (void)full; diff --git a/Protocols/Shamir.h b/Protocols/Shamir.h index 0bfc52aab..b435d687d 100644 --- a/Protocols/Shamir.h +++ b/Protocols/Shamir.h @@ -31,8 +31,6 @@ class Shamir : public ProtocolBase SeededPRNG secure_prng; - vector random; - vector> hyper; typename T::open_type dotprod_share; @@ -86,8 +84,6 @@ class Shamir : public ProtocolBase void prepare_dotprod(const T& x, const T& y); void next_dotprod(); T finalize_dotprod(int length); - - T get_random(); }; #endif /* PROTOCOLS_SHAMIR_H_ */ diff --git a/Protocols/Shamir.hpp b/Protocols/Shamir.hpp index cb09ef5ee..b35d8151c 100644 --- a/Protocols/Shamir.hpp +++ b/Protocols/Shamir.hpp @@ -169,16 +169,6 @@ T Shamir::finalize_dotprod(int) return finalize_mul(); } -template -T Shamir::get_random() -{ - if (random.empty()) - buffer_random(); - auto res = random.back(); - random.pop_back(); - return res; -} - template void Shamir::buffer_random() { @@ -207,6 +197,7 @@ void Shamir::buffer_random() input.add_mine(secure_prng.get()); input.exchange(); vector inputs; + auto& random = this->random; for (int i = 0; i < buffer_size; i += hyper.size()) { inputs.clear(); diff --git a/Protocols/ShamirMC.hpp b/Protocols/ShamirMC.hpp index b223fe6bd..3b483542d 100644 --- a/Protocols/ShamirMC.hpp +++ b/Protocols/ShamirMC.hpp @@ -30,7 +30,7 @@ void ShamirMC::init_open(const Player& P, int n) int n_relevant_players = ShamirMachine::s().threshold + 1; if (reconstruction.empty()) { - reconstruction.resize(n_relevant_players, 1); + reconstruction.resize(n_relevant_players); for (int i = 0; i < n_relevant_players; i++) reconstruction[i] = Shamir::get_rec_factor(i, n_relevant_players); diff --git a/Protocols/ShamirShare.h b/Protocols/ShamirShare.h index 949234ec9..4728cbc0f 100644 --- a/Protocols/ShamirShare.h +++ b/Protocols/ShamirShare.h @@ -39,7 +39,9 @@ class ShamirShare : public T, public ShareInterface typedef ReplicatedRingPrep TriplePrep; typedef ShamirShare Honest; +#ifndef NO_MIXED_CIRCUITS typedef GC::CcdSecret bit_type; +#endif const static bool needs_ot = false; const static bool dishonest_majority = false; diff --git a/Protocols/Share.h b/Protocols/Share.h index 11bed562f..21fc63b58 100644 --- a/Protocols/Share.h +++ b/Protocols/Share.h @@ -41,7 +41,7 @@ class Share_ : public ShareInterface public: - typedef T part_type; + typedef GC::NoShare part_type; typedef V mac_key_type; typedef V mac_type; typedef T share_type; @@ -49,7 +49,9 @@ class Share_ : public ShareInterface typedef typename T::open_type open_type; typedef typename T::clear clear; +#ifndef NO_MIXED_CIRCUITS typedef GC::TinierSecret bit_type; +#endif const static bool needs_ot = T::needs_ot; const static bool dishonest_majority = T::dishonest_majority; @@ -100,18 +102,8 @@ class Share_ : public ShareInterface /* Arithmetic Routines */ void mul(const Share_& S,const clear& aa); void mul_by_bit(const Share_& S,const clear& aa); - void add(const Share_& S,const clear& aa,int my_num,const V& alphai); - void negate() { a.negate(); mac.negate(); } - void sub(const Share_& S,const clear& aa,int my_num,const V& alphai); - void sub(const clear& aa,const Share_& S,int my_num,const V& alphai); void add(const Share_& S1,const Share_& S2); void sub(const Share_& S1,const Share_& S2); - void add(const Share_& S1) { add(*this,S1); } - - // obsolete interface - void add(const Share_& S,const clear& aa,bool playerone,const T& alphai); - void sub(const Share_& S,const clear& aa,bool playerone,const T& alphai); - void sub(const clear& aa,const Share_& S,bool playerone,const T& alphai); Share_ operator+(const Share_& x) const { Share_ res; res.add(*this, x); return res; } @@ -123,10 +115,12 @@ class Share_ : public ShareInterface Share_ operator/(const T& x) const { Share_ res; res.set_share(a / x); res.set_mac(mac / x); return res; } - Share_& operator+=(const Share_& x) { add(x); return *this; } + Share_& operator+=(const Share_& x) { add(*this, x); return *this; } Share_& operator-=(const Share_& x) { sub(*this, x); return *this; } template Share_& operator*=(const U& x) { mul(*this, x); return *this; } + template + Share_& operator/=(const U& x) { *this = *this / x; return *this; } Share_ operator<<(int i) { return this->operator*(clear(1) << i); } Share_& operator<<=(int i) { return *this = *this << i; } @@ -160,6 +154,7 @@ class Share : public Share_, SemiShare> typedef Share_, SemiShare> super; typedef T mac_key_type; + typedef T mac_type; typedef Share prep_type; typedef Share input_check_type; @@ -204,15 +199,15 @@ Share_ operator*(const typename T::clear& y, const Share_& x) { Shar template inline void Share_::add(const Share_& S1,const Share_& S2) { - a.add(S1.a,S2.a); - mac.add(S1.mac,S2.mac); + a = (S1.a + S2.a); + mac = (S1.mac + S2.mac); } template void Share_::sub(const Share_& S1,const Share_& S2) { - a.sub(S1.a,S2.a); - mac.sub(S1.mac,S2.mac); + a = (S1.a - S2.a); + mac = (S1.mac - S2.mac); } template @@ -222,24 +217,6 @@ inline void Share_::mul(const Share_& S,const clear& aa) mac = aa * S.mac; } -template -inline void Share_::add(const Share_& S,const clear& aa,int my_num,const V& alphai) -{ - *this = S + Share_(aa, my_num, alphai); -} - -template -inline void Share_::sub(const Share_& S,const clear& aa,int my_num,const V& alphai) -{ - *this = S - Share_(aa, my_num, alphai); -} - -template -inline void Share_::sub(const clear& aa,const Share_& S,int my_num,const V& alphai) -{ - *this = Share_(aa, my_num, alphai) - S; -} - template inline void Share_::assign(const clear& aa, int my_num, const typename V::Scalar& alphai) diff --git a/Protocols/ShareInterface.h b/Protocols/ShareInterface.h index 9bb25c5d5..fcce6e0d6 100644 --- a/Protocols/ShareInterface.h +++ b/Protocols/ShareInterface.h @@ -26,6 +26,8 @@ class ShareInterface static const bool expensive = false; static const bool expensive_triples = false; + static const int default_length = 1; + static string type_short() { return "undef"; } template diff --git a/Protocols/ShuffleSacrifice.h b/Protocols/ShuffleSacrifice.h index ed54e2ec8..304091f39 100644 --- a/Protocols/ShuffleSacrifice.h +++ b/Protocols/ShuffleSacrifice.h @@ -18,11 +18,9 @@ class Player; template class LimitedPrep; -template class ShuffleSacrifice { - typedef typename T::bit_type::part_type BT; - +protected: const int B; public: @@ -52,7 +50,12 @@ class ShuffleSacrifice template void shuffle(vector& items, Player& P); +}; +template +class TripleShuffleSacrifice : public ShuffleSacrifice +{ +public: void triple_sacrifice(vector>& triples, vector>& check_triples, Player& P, typename T::MAC_Check& MC, ThreadQueues* queues = 0); @@ -63,7 +66,14 @@ class ShuffleSacrifice void triple_combine(vector>& triples, vector>& to_combine, Player& P, typename T::MAC_Check& MC); +}; +template +class EdabitShuffleSacrifice : public ShuffleSacrifice +{ + typedef typename T::bit_type::part_type BT; + +public: void edabit_sacrifice(vector>& output, vector& sums, vector>& bits, size_t n_bits, SubProcessor& proc, bool strict = false, int player = -1, diff --git a/Protocols/ShuffleSacrifice.hpp b/Protocols/ShuffleSacrifice.hpp index 00ee693eb..0808b7521 100644 --- a/Protocols/ShuffleSacrifice.hpp +++ b/Protocols/ShuffleSacrifice.hpp @@ -13,14 +13,14 @@ #include "MalRepRingPrep.hpp" #include "LimitedPrep.hpp" -template -ShuffleSacrifice::ShuffleSacrifice() : +inline +ShuffleSacrifice::ShuffleSacrifice() : B(OnlineOptions::singleton.bucket_size), C(this->B) { } template -inline void ShuffleSacrifice::triple_combine(vector >& triples, +void TripleShuffleSacrifice::triple_combine(vector >& triples, vector >& to_combine, Player& P, typename T::MAC_Check& MC) { @@ -62,7 +62,7 @@ inline void ShuffleSacrifice::triple_combine(vector >& triples, } template -void ShuffleSacrifice::edabit_sacrifice(vector >& output, +void EdabitShuffleSacrifice::edabit_sacrifice(vector >& output, vector& wholes, vector>& parts, size_t n_bits, SubProcessor& proc, bool strict, int player, ThreadQueues* queues) @@ -232,7 +232,7 @@ void ShuffleSacrifice::edabit_sacrifice(vector >& output, } template -void ShuffleSacrifice::edabit_sacrifice_buckets(vector>& to_check, +void EdabitShuffleSacrifice::edabit_sacrifice_buckets(vector>& to_check, size_t n_bits, bool strict, int player, SubProcessor& proc, int begin, int end, const void* supply) { @@ -242,7 +242,7 @@ void ShuffleSacrifice::edabit_sacrifice_buckets(vector>& to_check, } template -void ShuffleSacrifice::edabit_sacrifice_buckets(vector>& to_check, +void EdabitShuffleSacrifice::edabit_sacrifice_buckets(vector>& to_check, size_t n_bits, bool strict, int player, SubProcessor& proc, int begin, int end, LimitedPrep& personal_prep, const void* supply) { @@ -365,7 +365,8 @@ void ShuffleSacrifice::edabit_sacrifice_buckets(vector>& to_check, if (strict) { - (dynamic_cast*>(&proc.DataF))->sanitize(to_sanitize, + (dynamic_cast*>(&proc.DataF))->template + sanitize<0>(to_sanitize, n_bits, player, queues); shares.reserve((B - 1) * N); bit_shares.reserve((B - 1) * N * (n_bits + 2)); diff --git a/Protocols/SohoPrep.h b/Protocols/SohoPrep.h index 1f0c77d39..07bc7b9c4 100644 --- a/Protocols/SohoPrep.h +++ b/Protocols/SohoPrep.h @@ -27,7 +27,6 @@ class SohoPrep : public SemiHonestRingPrep void buffer_triples(); void buffer_squares(); - void buffer_inverses(); void buffer_bits(); }; diff --git a/Protocols/SohoPrep.hpp b/Protocols/SohoPrep.hpp index 91825aa5d..e2b1a2e30 100644 --- a/Protocols/SohoPrep.hpp +++ b/Protocols/SohoPrep.hpp @@ -110,13 +110,6 @@ void SohoPrep::buffer_squares() this->squares.push_back({{ai.element(i), ci.element(i)}}); } -template -void SohoPrep::buffer_inverses() -{ - assert(this->proc != 0); - ::buffer_inverses(this->inverses, *this, this->proc->MC, this->proc->P); -} - template void SohoPrep::buffer_bits() { diff --git a/Protocols/Spdz2kPrep.h b/Protocols/Spdz2kPrep.h index 71dbff234..3907512ee 100644 --- a/Protocols/Spdz2kPrep.h +++ b/Protocols/Spdz2kPrep.h @@ -21,7 +21,6 @@ class Spdz2kPrep : public virtual MascotPrep, public virtual RingOnlyPrep MascotTriplePrep* bit_prep; SubProcessor* bit_proc; typename BitShare::MAC_Check* bit_MC; - Sub_Data_Files* bit_DataF; typename BitShare::Protocol* bit_protocol; public: diff --git a/Protocols/Spdz2kPrep.hpp b/Protocols/Spdz2kPrep.hpp index 9aa5df481..4a2617b2e 100644 --- a/Protocols/Spdz2kPrep.hpp +++ b/Protocols/Spdz2kPrep.hpp @@ -23,7 +23,6 @@ Spdz2kPrep::Spdz2kPrep(SubProcessor* proc, DataPositions& usage) : { this->params.amplify = false; bit_MC = 0; - bit_DataF = 0; bit_proc = 0; bit_prep = 0; bit_protocol = 0; @@ -36,7 +35,6 @@ Spdz2kPrep::~Spdz2kPrep() { delete bit_prep; delete bit_proc; - delete bit_DataF; delete bit_MC; delete bit_protocol; } @@ -51,9 +49,8 @@ void Spdz2kPrep::set_protocol(typename T::Protocol& protocol) bit_MC = new typename BitShare::MAC_Check(proc->MC.get_alphai()); // just dummies bit_pos = DataPositions(proc->P.num_players()); - bit_DataF = new Sub_Data_Files(0, 0, "", bit_pos, 0); - bit_proc = new SubProcessor(*bit_MC, *bit_DataF, proc->P); bit_prep = new MascotTriplePrep(bit_proc, bit_pos); + bit_proc = new SubProcessor(*bit_MC, *bit_prep, proc->P); bit_prep->params.amplify = false; bit_protocol = new typename BitShare::Protocol(proc->P); bit_prep->set_protocol(*bit_protocol); @@ -157,6 +154,23 @@ void MascotPrep::buffer_edabits(bool strict, int n_bits, template void MaliciousRingPrep::buffer_edabits_from_personal(bool strict, int n_bits, ThreadQueues* queues) +{ + buffer_edabits_from_personal<0>(strict, n_bits, queues, + T::clear::characteristic_two); +} + +template +template +void MaliciousRingPrep::buffer_edabits_from_personal(bool, int, + ThreadQueues*, true_type) +{ + throw runtime_error("only implemented for integer-like domains"); +} + +template +template +void MaliciousRingPrep::buffer_edabits_from_personal(bool strict, int n_bits, + ThreadQueues* queues, false_type) { assert(this->proc != 0); typedef typename T::bit_type::part_type bit_type; @@ -209,7 +223,7 @@ void MaliciousRingPrep::buffer_edabits_from_personal(bool strict, int n_bits, bits.clear(); bits.shrink_to_fit(); if (strict) - this->sanitize(checked, n_bits, -1, queues); + this->template sanitize<0>(checked, n_bits, -1, queues); auto& output = this->edabits[{strict, n_bits}]; for (auto& x : checked) { diff --git a/Protocols/Spdz2kShare.h b/Protocols/Spdz2kShare.h index 4331f8ba9..d26cde4f2 100644 --- a/Protocols/Spdz2kShare.h +++ b/Protocols/Spdz2kShare.h @@ -31,7 +31,6 @@ class Spdz2kShare : public Share> typedef SignedZ2 clear; typedef Z2 mac_key_type; - typedef Z2 mac_type; typedef Z2 open_type; typedef Spdz2kShare prep_type; @@ -48,10 +47,12 @@ class Spdz2kShare : public Share> typedef SPDZ Protocol; typedef Spdz2kPrep LivePrep; +#ifndef NO_MIXED_CIRCUITS #ifdef SPDZ2K_BIT typedef GC::TinySecret bit_type; #else typedef GC::TinierSecret bit_type; +#endif #endif const static int k = K; diff --git a/Protocols/SpdzWisePrep.h b/Protocols/SpdzWisePrep.h index eff1f546a..ad2c2cd89 100644 --- a/Protocols/SpdzWisePrep.h +++ b/Protocols/SpdzWisePrep.h @@ -17,7 +17,6 @@ class SpdzWisePrep : public MaliciousRingPrep void buffer_triples(); void buffer_bits(); - void buffer_inverses(); void buffer_inputs(int player); diff --git a/Protocols/SpdzWisePrep.hpp b/Protocols/SpdzWisePrep.hpp index 09c42ae7d..f88e97d64 100644 --- a/Protocols/SpdzWisePrep.hpp +++ b/Protocols/SpdzWisePrep.hpp @@ -91,15 +91,6 @@ void SpdzWisePrep::buffer_bits(U) super::buffer_bits(); } -template -void SpdzWisePrep::buffer_inverses() -{ - auto protocol = this->protocol; - assert(protocol != 0); - assert(this->proc != 0); - ::buffer_inverses(this->inverses, *this, this->proc->MC, protocol->P); -} - template void SpdzWisePrep::buffer_inputs(int player) { diff --git a/Protocols/SpdzWiseShare.h b/Protocols/SpdzWiseShare.h index 39007597e..6386aa5be 100644 --- a/Protocols/SpdzWiseShare.h +++ b/Protocols/SpdzWiseShare.h @@ -28,6 +28,7 @@ class SpdzWiseShare : public Share_ typedef Share_ super; public: + typedef T part_type; typedef T open_part_type; typedef typename T::clear clear; typedef typename T::open_type open_type; diff --git a/Protocols/dabit.h b/Protocols/dabit.h index 1228a033d..c6a61fe00 100644 --- a/Protocols/dabit.h +++ b/Protocols/dabit.h @@ -41,6 +41,12 @@ class dabit : public pair this->first.assign(buffer); this->second.assign(buffer + T::size()); } + + void output(ostream& out, bool human) + { + this->first.output(out, human); + this->second.output(out, human); + } }; #endif /* PROTOCOLS_DABIT_H_ */ diff --git a/Protocols/edabit.h b/Protocols/edabit.h index 91a62dc1d..d893277ae 100644 --- a/Protocols/edabit.h +++ b/Protocols/edabit.h @@ -116,6 +116,15 @@ class edabitvec b.push_back(x); } } + + void output(int length, ofstream& s) + { + assert(size() == MAX_SIZE); + for (auto& x : a) + x.output(s, false); + for (int i = 0; i < length; i++) + b[i].output(s, false); + } }; #endif /* PROTOCOLS_EDABIT_H_ */ diff --git a/Protocols/fake-stuff.h b/Protocols/fake-stuff.h index b07c95ced..9add273fa 100644 --- a/Protocols/fake-stuff.h +++ b/Protocols/fake-stuff.h @@ -31,6 +31,10 @@ void read_mac_key(const string& directory, int player_num, int nplayers, U& key) template void read_mac_key(const string& directory, const Names& N, U& key); +template +typename T::mac_key_type read_generate_write_mac_key(const Player& P, + string directory = ""); + template class Files { diff --git a/Protocols/fake-stuff.hpp b/Protocols/fake-stuff.hpp index f0a83348c..1c9a3b229 100644 --- a/Protocols/fake-stuff.hpp +++ b/Protocols/fake-stuff.hpp @@ -267,6 +267,13 @@ void write_mac_key(const string& directory, int i, int nplayers, U key) outf.close(); } +template +void write_mac_key(const Names& N, typename T::mac_key_type key) +{ + write_mac_key(get_prep_sub_dir(N.num_players()), N.my_num(), + N.num_players(), key); +} + template void read_mac_key(const string& directory, const Names& N, T& key) { @@ -306,6 +313,27 @@ void read_mac_key(const string& directory, int player_num, int nplayers, U& key) inpf.close(); } +template +inline typename T::mac_key_type read_generate_write_mac_key(const Player& P, + string directory) +{ + if (directory == "") + directory = get_prep_sub_dir(P.num_players()); + typename T::mac_key_type res; + + try + { + read_mac_key(directory, P.my_num(), P.num_players(), res); + } + catch (mac_key_error&) + { + T::read_or_generate_mac_key(directory, P, res); + write_mac_key(directory, P.my_num(), P.num_players(), res); + } + + return res; +} + template void read_global_mac_key(const string& directory, int nparties, U& key) { @@ -451,6 +479,8 @@ template void make_mult_triples(const typename T::mac_type& key, int N, int ntrip, bool zero, string prep_data_prefix, int thread_num = -1) { + T::clear::write_setup(get_prep_sub_dir(prep_data_prefix, N)); + PRNG G; G.ReSeed(); @@ -459,12 +489,13 @@ void make_mult_triples(const typename T::mac_type& key, int N, int ntrip, vector Sa(N),Sb(N),Sc(N); /* Generate Triples */ for (int i=0; i(prep_data_prefix, N) << "Triples-" << T::type_short() << "-P" << i - << Sub_Data_Files::get_suffix(thread_num); - cout << "Opening " << filename.str() << endl; - outf[i].open(filename.str().c_str(),ios::out | ios::binary); - if (outf[i].fail()) { throw file_error(filename.str().c_str()); } + { + string filename = PrepBase::get_filename( + get_prep_sub_dir(prep_data_prefix, N), DATA_TRIPLE, + T::type_short(), i, thread_num); + cout << "Opening " << filename << endl; + outf[i].open(filename,ios::out | ios::binary); + if (outf[i].fail()) { throw file_error(filename); } } for (int i=0; i +typename T::mac_key_type read_or_generate_mac_key(const Player& P, + string directory = "") +{ + if (directory == "") + directory = get_prep_sub_dir(P.num_players()); + typename T::mac_key_type res; + T::read_or_generate_mac_key(directory, P, res); + return res; +} + +#endif /* PROTOCOLS_MAC_KEY_HPP_ */ diff --git a/README.md b/README.md index 054826947..61e01b040 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,9 @@ It will execute [the tutorial](Programs/Source/tutorial.mpc) with two parties and malicious security. +Note that this only works with a git clone but not with a binary +release. + ``` make -j 8 tldr ./compile.py tutorial @@ -148,7 +151,7 @@ phase outputs the amount of offline material required, which allows to compute the preprocessing time for a particular computation. #### Requirements - - GCC 5 or later (tested with up to 10) or LLVM/clang 5 or later (tested with up to 10). We recommend clang because it performs better. + - GCC 5 or later (tested with up to 10) or LLVM/clang 5 or later (tested with up to 11). We recommend clang because it performs better. - MPIR library, compiled with C++ support (use flag `--enable-cxx` when running configure). You can use `make -j8 tldr` to install it locally. - libsodium library, tested against 1.0.16 - OpenSSL, tested against 1.1.1 @@ -663,9 +666,13 @@ script, the inputs are read from `Player-Data/Input-P-0`. In this section we show how to benchmark purely the data-dependent (often called online) phase of some protocols. This requires to -generate the output of a previous phase insecurely. You will have to -(re)compile the software after adding `MY_CFLAGS = -DINSECURE` to -`CONFIG.mine` in order to run this insecure generation. +generate the output of a previous phase. There are two options to do +that: +1. For select protocols, you can run [preprocessing as + required](#preprocessing-as-required). +2. You can run insecure preprocessing. For this, you will have to + (re)compile the software after adding `MY_CFLAGS = -DINSECURE` to + `CONFIG.mine` in order to run this insecure generation. ### SPDZ @@ -787,6 +794,30 @@ compiler to remove dead code. This is useful for more complex programs such as this one. 3) Run `gc_oram` in the virtual machines as explained above. +## Preprocessing as required + +For select protocols, you can run all required preprocessing but not +the actual computation. First, compile the binary: + +`make -offline.x` + +At the time of writing the supported protocols are `mascot`, +`cowgear`, and `mal-shamir`. + +If you have not done so already, then compile your high-level program: + +`./compile.py ` + +Finally, run the parties as follows: + +`./-offline.x -p 0 & ./-offline.x -p 1 & ...` + +The options for the network setup are the same as for the complete +computation above. + +If you run the preprocessing on different hosts, make sure to use the +same player number in the preprocessing and the online phase. + ## Benchmarking offline phases #### SPDZ-2 offline phase diff --git a/Scripts/process-tf.py b/Scripts/process-tf.py index 46bbbde9e..5854a907c 100755 --- a/Scripts/process-tf.py +++ b/Scripts/process-tf.py @@ -58,9 +58,10 @@ def get_valid_padding(input_shape, window, strides): else: shape = None t = op.type - if t in ('VariableV2', 'Const'): - pass - elif t in ('Reshape', 'Squeeze'): + if t in ('VariableV2', 'Const', 'Assign', 'NoOp', 'Fill', 'VarHandleOp'): + source(op) + elif t in ('Reshape', 'Squeeze', 'Identity', 'VarIsInitializedOp', 'ReadVariableOp', + 'AssignVariableOp'): link(op, op.inputs[0].op) elif t == 'Placeholder': source(op) @@ -95,7 +96,7 @@ def get_valid_padding(input_shape, window, strides): 'inputs=[named["%s"]])' % \ (input_shape, tuple(window), (window[3],), output_shape, strides, repr(padding), op.inputs[0].op.name)) - elif t == 'Add' and op.inputs[1].op.type != 'VariableV2': + elif t in ('Add', 'AddV2') and op.inputs[1].op.type != 'VariableV2': output(op, 'ml.Add([%s])' % ','.join('named["%s"]' % x.op.name for x in op.inputs), False) elif t in ('Add', 'BiasAdd'): @@ -147,7 +148,7 @@ def get_valid_padding(input_shape, window, strides): output(op, 'ml.Concat([%s], %s)' % ( ','.join('named["%s"]' % x.name[:-2] for x in op.inputs[:2]), dim), prev_input=False) - elif t == 'FusedBatchNorm': + elif t in ('FusedBatchNorm', 'FusedBatchNormV3'): output(op, 'ml.FusedBatchNorm(%s, inputs=[named["%s"]])' % (get_shape(op.inputs[0].shape), op.inputs[0].op.name)) elif t == 'Pad': diff --git a/Scripts/sy-shamir.sh b/Scripts/sy-shamir.sh index 98ae80ce0..e35ea7741 100755 --- a/Scripts/sy-shamir.sh +++ b/Scripts/sy-shamir.sh @@ -3,7 +3,7 @@ HERE=$(cd `dirname $0`; pwd) SPDZROOT=$HERE/.. -export PLAYERS=3 +export PLAYERS=${PLAYERS:-3} . $HERE/run-common.sh diff --git a/Scripts/test_tutorial.sh b/Scripts/test_tutorial.sh index d5195bbac..90d74b9b8 100755 --- a/Scripts/test_tutorial.sh +++ b/Scripts/test_tutorial.sh @@ -25,8 +25,9 @@ function test_vm ulimit -c unlimited vm=$1 shift - if ! Scripts/$vm.sh tutorial $* | grep 'weighted average: 2.333'; then - for i in 0 1 2; do + if ! Scripts/$vm.sh tutorial $* > /dev/null || + ! grep 'weighted average: 2.333' logs/tutorial-0; then + for i in $(seq 4 -1 0); do echo == Party $i cat logs/tutorial-$i done @@ -69,7 +70,7 @@ if test $dabit != 0; then ./compile.py -R 64 -Z 4 tutorial test_vm rep4-ring $run_opts - ./compile.py -R 64 -Z 2 tutorial + ./compile.py -R 64 -Z ${PLAYERS:-2} tutorial test_vm semi2k $run_opts fi diff --git a/Tools/BitVector.h b/Tools/BitVector.h index 850de822e..98c2cccf3 100644 --- a/Tools/BitVector.h +++ b/Tools/BitVector.h @@ -10,7 +10,7 @@ using namespace std; #include #include -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Networking/data.h" // just for util functions #include "Math/gf2nlong.h" @@ -198,7 +198,7 @@ class BitVector void set_bit(int i,unsigned int a) { if ((size_t)i >= nbits) - throw overflow_error("BitVector " + to_string(i) + "/" + to_string(nbits)); + throw overflow("BitVector", i, nbits); int j = i/8, k = i&7; if (a==1) { bytes[j] |= (octet)(1UL< diff --git a/Tools/Buffer.cpp b/Tools/Buffer.cpp index 4bedf9c24..7eb7fcd64 100644 --- a/Tools/Buffer.cpp +++ b/Tools/Buffer.cpp @@ -10,8 +10,8 @@ bool BufferBase::rewind = false; -void BufferBase::setup(ifstream* f, int length, string filename, - const char* type, const char* field) +void BufferBase::setup(ifstream* f, int length, const string& filename, + const char* type, const string& field) { file = f; tuple_length = length; @@ -60,6 +60,8 @@ void BufferBase::prune() string tmp_name = filename + ".new"; ofstream tmp(tmp_name.c_str()); tmp << file->rdbuf(); + if (tmp.fail()) + throw runtime_error("problem writing to " + tmp_name); tmp.close(); file->close(); rename(tmp_name.c_str(), filename.c_str()); @@ -77,3 +79,9 @@ void BufferBase::purge() file = 0; } } + +void BufferBase::check_tuple_length(int tuple_length) +{ + if (tuple_length != this->tuple_length) + throw Processor_Error("inconsistent tuple length"); +} diff --git a/Tools/Buffer.h b/Tools/Buffer.h index 0cb6d5418..4bc6d7d6a 100644 --- a/Tools/Buffer.h +++ b/Tools/Buffer.h @@ -37,13 +37,14 @@ class BufferBase tuple_length(-1), eof(false) {} ~BufferBase() {} virtual ifstream* open() = 0; - void setup(ifstream* f, int length, string filename, const char* type = "", - const char* field = ""); + void setup(ifstream* f, int length, const string& filename, + const char* type = "", const string& field = {}); void seekg(int pos); bool is_up() { return file != 0; } void try_rewind(); void prune(); void purge(); + void check_tuple_length(int tuple_length); }; @@ -72,15 +73,29 @@ class BufferOwner : public Buffer { } + ~BufferOwner() + { + close(); + } + ifstream* open() { file = new ifstream(this->filename, ios::in | ios::binary); return file; } - void setup(string filename, int tuple_length, const char* data_type = "") + void setup(const string& filename, int tuple_length, + const char* data_type = "") + { + Buffer::setup(file, tuple_length, filename, data_type, + U::type_string()); + } + + void setup(const string& filename, int tuple_length, + const string& type_string, const char* data_type = "") { - Buffer::setup(file, tuple_length, filename, data_type, U::type_string().c_str()); + Buffer::setup(file, tuple_length, filename, data_type, + type_string); } void close() diff --git a/Tools/Exceptions.cpp b/Tools/Exceptions.cpp new file mode 100644 index 000000000..ee6722e28 --- /dev/null +++ b/Tools/Exceptions.cpp @@ -0,0 +1,61 @@ +/* + * Exceptions.cpp + * + */ + +#include "Exceptions.h" +#include "Math/bigint.h" + +IO_Error::IO_Error(const string& m) +{ + ans = "IO-Error : " + m; +} + +file_error::file_error(const string& m) +{ + ans = "File Error : " + m; +} + +Processor_Error::Processor_Error(const string& m) +{ + msg = "Processor-Error : " + m; +} + +Processor_Error::Processor_Error(const char* m) : + Processor_Error(string(m)) +{ +} + +wrong_gfp_size::wrong_gfp_size(const char* name, const bigint& p, + const char* symbol, int n_limbs) : + runtime_error( + string() + name + " wrong size for modulus " + to_string(p) + + ". Maybe change " + symbol + " to " + + to_string(n_limbs) + ".") +{ +} + +overflow::overflow(const char* name, size_t i, size_t n) : + runtime_error(string(name) + " overflow: " + to_string(i) + "/" + to_string(n)) +{ +} + +unknown_input_type::unknown_input_type(int type) : + runtime_error("unkown type: " + to_string(type)) +{ +} + +invalid_opcode::invalid_opcode(int opcode) : + runtime_error("invalid opcode: " + to_string(opcode)) +{ +} + +input_error::input_error(const char* name, const string& filename, + istream& input_file) +{ + input_file.clear(); + string token; + input_file >> token; + msg += string() + "cannot read " + name + " from " + filename + + ", problem with '" + token + "'"; +} diff --git a/Exceptions/Exceptions.h b/Tools/Exceptions.h similarity index 88% rename from Exceptions/Exceptions.h rename to Tools/Exceptions.h index 9534780a6..fd9820c26 100644 --- a/Exceptions/Exceptions.h +++ b/Tools/Exceptions.h @@ -49,12 +49,10 @@ class invalid_commitment: public exception { return "Invalid Commitment"; } }; class IO_Error: public exception - { string msg, ans; + { + string ans; public: - IO_Error(string m) : msg(m) - { ans="IO-Error : "; - ans+=msg; - } + IO_Error(const string& m); ~IO_Error()throw() { } virtual const char* what() const throw() { @@ -103,13 +101,10 @@ class invalid_program: public exception { return "Invalid Program"; } }; class file_error: public exception - { string filename, ans; + { + string ans; public: - file_error(string m) : filename(m) - { - ans="File Error : "; - ans+=filename; - } + file_error(const string& m); ~file_error()throw() { } virtual const char* what() const throw() { @@ -153,10 +148,8 @@ class file_missing: public exception class Processor_Error: public exception { string msg; public: - Processor_Error(string m) - { - msg = "Processor-Error : " + m; - } + Processor_Error(const string& m); + Processor_Error(const char* m); ~Processor_Error()throw() { } virtual const char* what() const throw() { @@ -230,13 +223,13 @@ class ran_out } }; +class bigint; + class wrong_gfp_size : public runtime_error { public: - wrong_gfp_size(string msg) : - runtime_error(msg) - { - } + wrong_gfp_size(const char* name, const bigint& p, const char* symbol, + int n_limbs); }; class mac_key_error: public runtime_error @@ -248,4 +241,36 @@ class mac_key_error: public runtime_error } }; +class overflow : public runtime_error +{ +public: + overflow(const char* name, size_t i, size_t n); +}; + +class unknown_input_type : public runtime_error +{ +public: + unknown_input_type(int type); +}; + +class invalid_opcode : public runtime_error +{ +public: + invalid_opcode(int opcode); +}; + +class input_error : public exception +{ + string msg; + +public: + input_error(const char* name, const string& filename, + istream& input_file); + + const char* what() const throw() + { + return msg.c_str(); + } +}; + #endif diff --git a/Tools/ExecutionStats.cpp b/Tools/ExecutionStats.cpp index 1b7aab602..bbc36dca6 100644 --- a/Tools/ExecutionStats.cpp +++ b/Tools/ExecutionStats.cpp @@ -11,6 +11,13 @@ #include #include +ExecutionStats& ExecutionStats::operator+=(const ExecutionStats& other) +{ + for (auto it : other) + (*this)[it.first] += it.second; + return *this; +} + void ExecutionStats::print() { cerr << "Instruction statistics:" << endl; diff --git a/Tools/ExecutionStats.h b/Tools/ExecutionStats.h index c795f7abb..a6d84caa1 100644 --- a/Tools/ExecutionStats.h +++ b/Tools/ExecutionStats.h @@ -12,12 +12,7 @@ using namespace std; class ExecutionStats : public map { public: - ExecutionStats& operator+=(const ExecutionStats& other) - { - for (auto it : other) - (*this)[it.first] += it.second; - return *this; - } + ExecutionStats& operator+=(const ExecutionStats& other); void print(); }; diff --git a/Tools/FixedVector.h b/Tools/FixedVector.h index 6946f0823..f070d69b5 100644 --- a/Tools/FixedVector.h +++ b/Tools/FixedVector.h @@ -34,7 +34,7 @@ class FixedVector : array void reserve(size_t size) { if (size > L) - throw runtime_error("too large: " + to_string(size)); + throw overflow("FixedVector", size, L); } void push_back(const T& x) diff --git a/Tools/Subroutines.cpp b/Tools/Subroutines.cpp index 57214f05c..1b6582eab 100644 --- a/Tools/Subroutines.cpp +++ b/Tools/Subroutines.cpp @@ -2,7 +2,7 @@ #include "Tools/Subroutines.h" #include "Tools/random.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Tools/Commit.h" #include "Math/Z2k.h" #include "Math/gfp.h" diff --git a/Tools/octetStream.cpp b/Tools/octetStream.cpp index 337e469aa..1522b506d 100644 --- a/Tools/octetStream.cpp +++ b/Tools/octetStream.cpp @@ -6,7 +6,7 @@ #include #include "Networking/sockets.h" #include "Networking/ssl_sockets.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "Networking/data.h" #include "Networking/Player.h" #include "Networking/Exchanger.h" diff --git a/Tools/random.cpp b/Tools/random.cpp index 8a1fe60f6..7acc91418 100644 --- a/Tools/random.cpp +++ b/Tools/random.cpp @@ -72,7 +72,7 @@ void PRNG::InitSeed() #else memcpy(state,seed,SEED_SIZE*sizeof(octet)); #endif - next(); + hash(); //cout << "SetSeed : "; print_state(); cout << endl; } diff --git a/Tools/time-func.cpp b/Tools/time-func.cpp index 37eb28321..52e28b8f1 100644 --- a/Tools/time-func.cpp +++ b/Tools/time-func.cpp @@ -1,6 +1,6 @@ #include "Tools/time-func.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include diff --git a/Tools/time-func.h b/Tools/time-func.h index 5bc702c36..e37fc6233 100644 --- a/Tools/time-func.h +++ b/Tools/time-func.h @@ -6,7 +6,7 @@ #include #include -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" long long timeval_diff(struct timeval *start_time, struct timeval *end_time); double timeval_diff_in_seconds(struct timeval *start_time, struct timeval *end_time); diff --git a/Utils/Check-Offline-Z2k.cpp b/Utils/Check-Offline-Z2k.cpp index edde3f71c..7994b08b6 100644 --- a/Utils/Check-Offline-Z2k.cpp +++ b/Utils/Check-Offline-Z2k.cpp @@ -53,7 +53,7 @@ void check_triples_Z2k(int n_players, string type_char = "") check_share(bs, b, mac, n_players, keyp); check_share(cs, c, mac, n_players, keyp); - prod.mul(a, b); + prod = (a * b); if (typename W::clear(prod) != c) { cout << j << ": " << c << " != " << prod << " = " << a << " * " << b << endl; diff --git a/Utils/Check-Offline.cpp b/Utils/Check-Offline.cpp index ff343022b..738a58916 100644 --- a/Utils/Check-Offline.cpp +++ b/Utils/Check-Offline.cpp @@ -10,7 +10,7 @@ #include "Protocols/MAC_Check.h" #include "Protocols/Rep3Share.h" #include "Tools/ezOptionParser.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "GC/MaliciousRepSecret.h" #include "GC/TinierSecret.h" #include "GC/TinyMC.h" diff --git a/Utils/Fake-Offline.cpp b/Utils/Fake-Offline.cpp index 1b4e2b01a..f164055be 100644 --- a/Utils/Fake-Offline.cpp +++ b/Utils/Fake-Offline.cpp @@ -14,7 +14,7 @@ #include "Protocols/SpdzWiseShare.h" #include "Protocols/Rep4Share2k.h" #include "Protocols/fake-stuff.h" -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "GC/MaliciousRepSecret.h" #include "GC/SemiSecret.h" #include "GC/TinySecret.h" @@ -96,12 +96,12 @@ void make_bit_triples(const gf2n& key,int N,int ntrip,Dtype dtype,bool zero) { if (!zero) a.randomize(G); - a.AND(a, one); + a &= one; make_share(Sa,a,N,key,G); if (!zero) b.randomize(G); if (dtype == DATA_BITTRIPLE) - b.AND(b, one); + b &= (one); make_share(Sb,b,N,key,G); c.mul(a,b); make_share(Sc,c,N,key,G); @@ -311,7 +311,7 @@ void make_PreMulC(const typename T::mac_type& key, int N, int ntrip, bool zero) a.randomize(G); while (a.is_zero()); files.output_shares(a); - b.invert(a); + b = a.invert(); files.output_shares(b); files.output_shares(a * c); c = b; diff --git a/Utils/gc-emulate.cpp b/Utils/gc-emulate.cpp index f90014733..e3cc8f8f0 100644 --- a/Utils/gc-emulate.cpp +++ b/Utils/gc-emulate.cpp @@ -12,7 +12,6 @@ #include "GC/Processor.hpp" #include "GC/Machine.hpp" #include "GC/Program.hpp" -#include "GC/Instruction.hpp" #include "GC/Thread.hpp" #include "GC/ThreadMaster.hpp" #include "Processor/Machine.hpp" diff --git a/Utils/gen_input_fp.cpp b/Utils/gen_input_fp.cpp index 173ae7770..5c689f16f 100644 --- a/Utils/gen_input_fp.cpp +++ b/Utils/gen_input_fp.cpp @@ -56,7 +56,26 @@ int main(int argc, const char** argv) { "-o", // Flag token. "--output" // Flag token. ); + + opt.add( + "", // Default. + 0, // Required? + 0, // Number of args expected. + 0, // Delimiter if expecting multiple args. + "This message.", // Help description. + "-h", // Flag token. + "--help" // Flag token. + ); + opt.parse(argc, argv); + if (opt.get("-h")->isSet) + { + string help; + opt.getUsage(help); + cerr << help; + exit(0); + } + int nparties, lgp, lg2; opt.get("-N")->getInt(nparties); opt.get("-lgp")->getInt(lgp); diff --git a/Utils/paper-example.cpp b/Utils/paper-example.cpp index 11c6b725f..f04d56673 100644 --- a/Utils/paper-example.cpp +++ b/Utils/paper-example.cpp @@ -5,8 +5,12 @@ * */ +#define NO_MIXED_CIRCUITS + #include "Math/gfp.hpp" #include "Machines/SPDZ.hpp" +#include "Machines/MalRep.hpp" +#include "Machines/ShamirMachine.hpp" #include "Protocols/CowGearShare.h" #include "Protocols/CowGearPrep.hpp" @@ -24,7 +28,7 @@ int main(int argc, char** argv) // need player number and number of players if (argc < 3) { - cerr << "Usage: " << argv[0] << " [protocol]" << endl; + cerr << "Usage: " << argv[0] << " [protocol [threshold]]" << endl; exit(1); } @@ -38,6 +42,21 @@ int main(int argc, char** argv) run>>(argv, prime_length); else if (protocol == "SPDZ2k") run>(argv, 0); + else if (protocol == "Shamir" or protocol == "MalShamir") + { + int nparties = (atoi(argv[2])); + int threshold = (nparties - 1) / 2; + if (argc > 4) + threshold = atoi(argv[4]); + assert(2 * threshold < nparties); + ShamirOptions::s().threshold = threshold; + ShamirOptions::s().nparties = nparties; + + if (protocol == "Shamir") + run>>(argv, prime_length); + else + run>>(argv, prime_length); + } else { cerr << "Unknown protocol: " << protocol << endl; @@ -66,19 +85,13 @@ void run(char** argv, int prime_length) // global OT setup BaseMachine machine; - machine.ot_setups.push_back({P}); + if (T::needs_ot) + machine.ot_setups.push_back({P}); // keeps tracks of preprocessing usage (triples etc) DataPositions usage; usage.set_num_players(P.num_players()); - // initialize binary computation - T::bit_type::mac_key_type::init_field(); - typename T::bit_type::mac_key_type binary_mac_key; - T::bit_type::part_type::read_or_generate_mac_key("", P, binary_mac_key); - GC::ShareThread thread(N, - OnlineOptions::singleton, P, binary_mac_key, usage); - // output protocol typename T::MAC_Check output(mac_key); @@ -120,4 +133,6 @@ void run(char** argv, int prime_length) cout << "result: " << result << endl; output.Check(P); + + T::LivePrep::teardown(); } diff --git a/Yao/YaoCommon.h b/Yao/YaoCommon.h index ab65c2407..2f0014b3c 100644 --- a/Yao/YaoCommon.h +++ b/Yao/YaoCommon.h @@ -11,7 +11,7 @@ #include #include -#include "Exceptions/Exceptions.h" +#include "Tools/Exceptions.h" #include "GC/RuntimeBranching.h" #include "GC/ThreadMaster.h" #include "YaoAndJob.h" diff --git a/Yao/YaoEvalMaster.cpp b/Yao/YaoEvalMaster.cpp index 558d2cfc3..e8a637372 100644 --- a/Yao/YaoEvalMaster.cpp +++ b/Yao/YaoEvalMaster.cpp @@ -6,7 +6,6 @@ #include "YaoEvalMaster.h" #include "YaoEvaluator.h" -#include "GC/Instruction.hpp" #include "GC/Machine.hpp" #include "GC/Program.hpp" #include "GC/Processor.hpp" diff --git a/Yao/YaoEvaluator.cpp b/Yao/YaoEvaluator.cpp index fd652a481..8653de0f1 100644 --- a/Yao/YaoEvaluator.cpp +++ b/Yao/YaoEvaluator.cpp @@ -5,7 +5,6 @@ #include "YaoEvaluator.h" -#include "GC/Instruction.hpp" #include "GC/Machine.hpp" #include "GC/Program.hpp" #include "GC/Processor.hpp" diff --git a/Yao/YaoGarbleMaster.cpp b/Yao/YaoGarbleMaster.cpp index e9fdb4373..9b6ea5fe6 100644 --- a/Yao/YaoGarbleMaster.cpp +++ b/Yao/YaoGarbleMaster.cpp @@ -6,7 +6,6 @@ #include "YaoGarbleMaster.h" #include "YaoGarbler.h" -#include "GC/Instruction.hpp" #include "GC/Machine.hpp" #include "GC/Program.hpp" #include "GC/Processor.hpp" diff --git a/Yao/YaoGarbler.cpp b/Yao/YaoGarbler.cpp index 3b0dc7094..2dc1b3fc7 100644 --- a/Yao/YaoGarbler.cpp +++ b/Yao/YaoGarbler.cpp @@ -7,7 +7,6 @@ #include "YaoGate.h" #include "GC/ThreadMaster.hpp" -#include "GC/Instruction.hpp" #include "GC/Processor.hpp" #include "GC/Program.hpp" #include "GC/Machine.hpp" diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1fb801bdc..bd144e7d1 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -11,7 +11,7 @@ pool: steps: - script: | - bash -c "sudo apt-get install libsodium-dev libntl-dev yasm texinfo libboost-dev libboost-thread-dev python3-gmpy2 libcrypto++-dev python-networkx python3-networkx python3-sphinx" + bash -c "sudo apt-get update && sudo apt-get install libsodium-dev libntl-dev yasm texinfo libboost-dev libboost-thread-dev python3-gmpy2 libcrypto++-dev python-networkx python3-networkx python3-sphinx" - script: | make mpir - script: diff --git a/doc/low-level.rst b/doc/low-level.rst index 259b8bbda..47bd3b483 100644 --- a/doc/low-level.rst +++ b/doc/low-level.rst @@ -115,7 +115,8 @@ or generates a fresh one otherwise. // global OT setup BaseMachine machine; - machine.ot_setups.push_back({P}); + if (T::needs_ot) + machine.ot_setups.push_back({P}); Many protocols for a dishonest majority use oblivious transfer. This block runs a few instances to seed the oblivious transfer @@ -143,8 +144,9 @@ variable that will store the usage. GC::ShareThread thread(N, OnlineOptions::singleton, P, binary_mac_key, usage); -While this example only uses arithmetic computation, we initialize the -binary computation as well because the code might not work without. +While this example only uses arithmetic computation, you need to +initialize binary computation as well unless you use the compile-time +option ``NO_MIXED_CIRCUITS``. .. code-block:: cpp @@ -246,3 +248,10 @@ separates dot products in the data preparation phase. The output protocol follows the same blueprint except that it is necessary to call the checking in order to verify the outputs. + +.. code-block:: cpp + + T::LivePrep::teardown(); + +This frees the memory used for global key material when using homomorphic +encryption. Otherwise, this does not do anything.