mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-09 13:37:58 -05:00
Mixed computation, binary computation with XOR-based MACs.
This commit is contained in:
@@ -58,7 +58,7 @@ void GarbleJob<T>::middle_round(RealProgramParty<T>& party, Protocol& second_pro
|
||||
{
|
||||
second_protocol.prepare_mul(party.shared_delta(j),
|
||||
lambda_uv + lambda_v * alpha + lambda_u * beta
|
||||
+ T(alpha * beta, me, party.MC->get_alphai())
|
||||
+ T::constant(alpha * beta, me, party.MC->get_alphai())
|
||||
+ lambda_w);
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ void RealGarbleWire<T>::input(party_id_t from, char input)
|
||||
assert(party.MC != 0);
|
||||
auto& protocol = party.shared_proc->protocol;
|
||||
protocol.init_mul(party.shared_proc);
|
||||
protocol.prepare_mul(mask, T(1, party.P->my_num(), party.mac_key) - mask);
|
||||
protocol.prepare_mul(mask, T::constant(1, party.P->my_num(), party.mac_key) - mask);
|
||||
protocol.exchange();
|
||||
if (party.MC->open(protocol.finalize_mul(), *party.P) != 0)
|
||||
throw runtime_error("input mask not a bit");
|
||||
|
||||
@@ -195,6 +195,7 @@ public:
|
||||
template <typename T>
|
||||
BlackHole& operator<<(T) { return *this; }
|
||||
BlackHole& operator<<(BlackHole& (*__pf)(BlackHole&)) { (void)__pf; return *this; }
|
||||
void activate(bool) {}
|
||||
};
|
||||
inline BlackHole& endl(BlackHole& b) { return b; }
|
||||
inline BlackHole& flush(BlackHole& b) { return b; }
|
||||
@@ -205,7 +206,7 @@ public:
|
||||
typedef NoMemory DynamicMemory;
|
||||
|
||||
typedef BlackHole out_type;
|
||||
static const BlackHole out;
|
||||
static BlackHole out;
|
||||
|
||||
static void check(const int128& value, word share, int128 mac)
|
||||
{ (void)value; (void)share; (void)mac; }
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
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.1.4 (Dec 23, 2019)
|
||||
|
||||
- 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.
|
||||
|
||||
## 0.1.3 (Nov 21, 2019)
|
||||
|
||||
- Python 3
|
||||
|
||||
@@ -28,13 +28,32 @@ opcodes = dict(
|
||||
LDBITS = 0x20a,
|
||||
ANDS = 0x20b,
|
||||
TRANS = 0x20c,
|
||||
XORCI = 0x210,
|
||||
BITB = 0x20d,
|
||||
ANDM = 0x20e,
|
||||
LDMSB = 0x240,
|
||||
STMSB = 0x241,
|
||||
LDMSBI = 0x242,
|
||||
STMSBI = 0x243,
|
||||
MOVSB = 0x244,
|
||||
INPUTB = 0x246,
|
||||
XORCBI = 0x210,
|
||||
BITDECC = 0x211,
|
||||
CONVCINT = 0x213,
|
||||
REVEAL = 0x214,
|
||||
STMSDCI = 0x215,
|
||||
INPUTB = 0x216,
|
||||
LDMCB = 0x217,
|
||||
STMCB = 0x218,
|
||||
XORCB = 0x219,
|
||||
ADDCB = 0x21a,
|
||||
ADDCBI = 0x21b,
|
||||
MULCBI = 0x21c,
|
||||
SHRCBI = 0x21d,
|
||||
SHLCBI = 0x21e,
|
||||
PRINTREGSIGNED = 0x220,
|
||||
PRINTREGB = 0x221,
|
||||
PRINTREGPLAINB = 0x222,
|
||||
PRINTFLOATPLAINB = 0x223,
|
||||
CONDPRINTSTRB = 0x224,
|
||||
CONVCBIT = 0x230,
|
||||
)
|
||||
|
||||
@@ -46,12 +65,12 @@ class xorm(base.Instruction):
|
||||
code = opcodes['XORM']
|
||||
arg_format = ['int','sbw','sb','cb']
|
||||
|
||||
class xorc(base.Instruction):
|
||||
code = base.opcodes['XORC']
|
||||
class xorcb(base.Instruction):
|
||||
code = opcodes['XORCB']
|
||||
arg_format = ['cbw','cb','cb']
|
||||
|
||||
class xorci(base.Instruction):
|
||||
code = opcodes['XORCI']
|
||||
class xorcbi(base.Instruction):
|
||||
code = opcodes['XORCBI']
|
||||
arg_format = ['cbw','cb','int']
|
||||
|
||||
class andrs(base.Instruction):
|
||||
@@ -62,16 +81,20 @@ class ands(base.Instruction):
|
||||
code = opcodes['ANDS']
|
||||
arg_format = tools.cycle(['int','sbw','sb','sb'])
|
||||
|
||||
class addc(base.Instruction):
|
||||
code = base.opcodes['ADDC']
|
||||
class andm(base.Instruction):
|
||||
code = opcodes['ANDM']
|
||||
arg_format = ['int','sbw','sb','cb']
|
||||
|
||||
class addcb(base.Instruction):
|
||||
code = opcodes['ADDCB']
|
||||
arg_format = ['cbw','cb','cb']
|
||||
|
||||
class addci(base.Instruction):
|
||||
code = base.opcodes['ADDCI']
|
||||
class addcbi(base.Instruction):
|
||||
code = opcodes['ADDCBI']
|
||||
arg_format = ['cbw','cb','int']
|
||||
|
||||
class mulci(base.Instruction):
|
||||
code = base.opcodes['MULCI']
|
||||
class mulcbi(base.Instruction):
|
||||
code = opcodes['MULCBI']
|
||||
arg_format = ['cbw','cb','int']
|
||||
|
||||
class bitdecs(base.VarArgsInstruction):
|
||||
@@ -86,44 +109,44 @@ class bitdecc(base.VarArgsInstruction):
|
||||
code = opcodes['BITDECC']
|
||||
arg_format = tools.chain(['cb'], itertools.repeat('cbw'))
|
||||
|
||||
class shrci(base.Instruction):
|
||||
code = base.opcodes['SHRCI']
|
||||
class shrcbi(base.Instruction):
|
||||
code = opcodes['SHRCBI']
|
||||
arg_format = ['cbw','cb','int']
|
||||
|
||||
class shlci(base.Instruction):
|
||||
code = base.opcodes['SHLCI']
|
||||
class shlcbi(base.Instruction):
|
||||
code = opcodes['SHLCBI']
|
||||
arg_format = ['cbw','cb','int']
|
||||
|
||||
class ldbits(base.Instruction):
|
||||
code = opcodes['LDBITS']
|
||||
arg_format = ['sbw','i','i']
|
||||
|
||||
class ldms(base.DirectMemoryInstruction, base.ReadMemoryInstruction):
|
||||
code = base.opcodes['LDMS']
|
||||
class ldmsb(base.DirectMemoryInstruction, base.ReadMemoryInstruction):
|
||||
code = opcodes['LDMSB']
|
||||
arg_format = ['sbw','int']
|
||||
|
||||
class stms(base.DirectMemoryWriteInstruction):
|
||||
code = base.opcodes['STMS']
|
||||
class stmsb(base.DirectMemoryWriteInstruction):
|
||||
code = opcodes['STMSB']
|
||||
arg_format = ['sb','int']
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# super(type(self), self).__init__(*args, **kwargs)
|
||||
# import inspect
|
||||
# self.caller = [frame[1:] for frame in inspect.stack()[1:]]
|
||||
|
||||
class ldmc(base.DirectMemoryInstruction, base.ReadMemoryInstruction):
|
||||
code = base.opcodes['LDMC']
|
||||
class ldmcb(base.DirectMemoryInstruction, base.ReadMemoryInstruction):
|
||||
code = opcodes['LDMCB']
|
||||
arg_format = ['cbw','int']
|
||||
|
||||
class stmc(base.DirectMemoryWriteInstruction):
|
||||
code = base.opcodes['STMC']
|
||||
class stmcb(base.DirectMemoryWriteInstruction):
|
||||
code = opcodes['STMCB']
|
||||
arg_format = ['cb','int']
|
||||
|
||||
class ldmsi(base.ReadMemoryInstruction):
|
||||
code = base.opcodes['LDMSI']
|
||||
class ldmsbi(base.ReadMemoryInstruction):
|
||||
code = opcodes['LDMSBI']
|
||||
arg_format = ['sbw','ci']
|
||||
|
||||
class stmsi(base.WriteMemoryInstruction):
|
||||
code = base.opcodes['STMSI']
|
||||
class stmsbi(base.WriteMemoryInstruction):
|
||||
code = opcodes['STMSBI']
|
||||
arg_format = ['sb','ci']
|
||||
|
||||
class ldmsdi(base.ReadMemoryInstruction):
|
||||
@@ -158,8 +181,8 @@ class convcbit(base.Instruction):
|
||||
code = opcodes['CONVCBIT']
|
||||
arg_format = ['ciw','cb']
|
||||
|
||||
class movs(base.Instruction):
|
||||
code = base.opcodes['MOVS']
|
||||
class movsb(base.Instruction):
|
||||
code = opcodes['MOVSB']
|
||||
arg_format = ['sbw','sb']
|
||||
|
||||
class trans(base.VarArgsInstruction):
|
||||
@@ -169,8 +192,8 @@ class trans(base.VarArgsInstruction):
|
||||
['sb'] * (len(args) - 1 - args[0])
|
||||
super(trans, self).__init__(*args)
|
||||
|
||||
class bit(base.Instruction):
|
||||
code = base.opcodes['BIT']
|
||||
class bitb(base.Instruction):
|
||||
code = opcodes['BITB']
|
||||
arg_format = ['sbw']
|
||||
|
||||
class reveal(base.Instruction):
|
||||
@@ -182,28 +205,28 @@ class inputb(base.DoNotEliminateInstruction, base.VarArgsInstruction):
|
||||
code = opcodes['INPUTB']
|
||||
arg_format = tools.cycle(['p','int','int','sbw'])
|
||||
|
||||
class print_reg(base.IOInstruction):
|
||||
code = base.opcodes['PRINTREG']
|
||||
class print_regb(base.IOInstruction):
|
||||
code = opcodes['PRINTREGB']
|
||||
arg_format = ['cb','i']
|
||||
def __init__(self, reg, comment=''):
|
||||
super(print_reg, self).__init__(reg, self.str_to_int(comment))
|
||||
super(print_regb, self).__init__(reg, self.str_to_int(comment))
|
||||
|
||||
class print_reg_plain(base.IOInstruction):
|
||||
code = base.opcodes['PRINTREGPLAIN']
|
||||
class print_reg_plainb(base.IOInstruction):
|
||||
code = opcodes['PRINTREGPLAINB']
|
||||
arg_format = ['cb']
|
||||
|
||||
class print_reg_signed(base.IOInstruction):
|
||||
code = opcodes['PRINTREGSIGNED']
|
||||
arg_format = ['int','cb']
|
||||
|
||||
class print_float_plain(base.IOInstruction):
|
||||
class print_float_plainb(base.IOInstruction):
|
||||
__slots__ = []
|
||||
code = base.opcodes['PRINTFLOATPLAIN']
|
||||
code = opcodes['PRINTFLOATPLAINB']
|
||||
arg_format = ['cb', 'cb', 'cb', 'cb']
|
||||
|
||||
class cond_print_str(base.IOInstruction):
|
||||
class cond_print_strb(base.IOInstruction):
|
||||
r""" Print a 4 character string. """
|
||||
code = base.opcodes['CONDPRINTSTR']
|
||||
code = opcodes['CONDPRINTSTRB']
|
||||
arg_format = ['cb', 'int']
|
||||
|
||||
def __init__(self, cond, val):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from Compiler.types import MemValue, read_mem_value, regint, Array
|
||||
from Compiler.types import _bitint, _number, _fix, _structure
|
||||
from Compiler.types import MemValue, read_mem_value, regint, Array, cint
|
||||
from Compiler.types import _bitint, _number, _fix, _structure, _bit
|
||||
from Compiler.program import Tape, Program
|
||||
from Compiler.exceptions import *
|
||||
from Compiler import util, oram, floatingpoint, library
|
||||
@@ -7,7 +7,7 @@ import Compiler.GC.instructions as inst
|
||||
import operator
|
||||
from functools import reduce
|
||||
|
||||
class bits(Tape.Register, _structure):
|
||||
class bits(Tape.Register, _structure, _bit):
|
||||
n = 40
|
||||
size = 1
|
||||
PreOp = staticmethod(floatingpoint.PreOpN)
|
||||
@@ -97,10 +97,15 @@ class bits(Tape.Register, _structure):
|
||||
raise Exception('too long: %d' % n)
|
||||
self.n = n
|
||||
def load_other(self, other):
|
||||
if isinstance(other, cint):
|
||||
size = other.size
|
||||
other = sum(x << i for i, x in enumerate(other))
|
||||
other = other.to_regint(size)
|
||||
if isinstance(other, int):
|
||||
self.set_length(self.n or util.int_len(other))
|
||||
self.load_int(other)
|
||||
elif isinstance(other, regint):
|
||||
assert(other.size == 1)
|
||||
self.conv_regint(self.n, self, other)
|
||||
elif isinstance(self, type(other)) or isinstance(other, type(self)):
|
||||
self.mov(self, other)
|
||||
@@ -122,8 +127,8 @@ class cbits(bits):
|
||||
max_length = 64
|
||||
reg_type = 'cb'
|
||||
is_clear = True
|
||||
load_inst = (None, inst.ldmc)
|
||||
store_inst = (None, inst.stmc)
|
||||
load_inst = (None, inst.ldmcb)
|
||||
store_inst = (None, inst.stmcb)
|
||||
bitdec = inst.bitdecc
|
||||
conv_regint = staticmethod(lambda n, x, y: inst.convcint(x, y))
|
||||
types = {}
|
||||
@@ -146,9 +151,9 @@ class cbits(bits):
|
||||
else:
|
||||
return op(self, cbits(other))
|
||||
__add__ = lambda self, other: \
|
||||
self.clear_op(other, inst.addc, inst.addci, operator.add)
|
||||
self.clear_op(other, inst.addcb, inst.addcbi, operator.add)
|
||||
__xor__ = lambda self, other: \
|
||||
self.clear_op(other, inst.xorc, inst.xorci, operator.xor)
|
||||
self.clear_op(other, inst.xorcb, inst.xorcbi, operator.xor)
|
||||
__radd__ = __add__
|
||||
__rxor__ = __xor__
|
||||
def __mul__(self, other):
|
||||
@@ -157,25 +162,25 @@ class cbits(bits):
|
||||
else:
|
||||
try:
|
||||
res = cbits(n=min(self.max_length, self.n+util.int_len(other)))
|
||||
inst.mulci(res, self, other)
|
||||
inst.mulcbi(res, self, other)
|
||||
return res
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
def __rshift__(self, other):
|
||||
res = cbits(n=self.n-other)
|
||||
inst.shrci(res, self, other)
|
||||
inst.shrcbi(res, self, other)
|
||||
return res
|
||||
def __lshift__(self, other):
|
||||
res = cbits(n=self.n+other)
|
||||
inst.shlci(res, self, other)
|
||||
inst.shlcbi(res, self, other)
|
||||
return res
|
||||
def print_reg(self, desc=''):
|
||||
inst.print_reg(self, desc)
|
||||
inst.print_regb(self, desc)
|
||||
def print_reg_plain(self):
|
||||
inst.print_reg_signed(self.n, self)
|
||||
output = print_reg_plain
|
||||
def print_if(self, string):
|
||||
inst.cond_print_str(self, string)
|
||||
inst.cond_print_strb(self, string)
|
||||
def reveal(self):
|
||||
return self
|
||||
def to_regint(self, dest):
|
||||
@@ -189,12 +194,12 @@ class sbits(bits):
|
||||
is_clear = False
|
||||
clear_type = cbits
|
||||
default_type = cbits
|
||||
load_inst = (inst.ldmsi, inst.ldms)
|
||||
store_inst = (inst.stmsi, inst.stms)
|
||||
load_inst = (inst.ldmsbi, inst.ldmsb)
|
||||
store_inst = (inst.stmsbi, inst.stmsb)
|
||||
bitdec = inst.bitdecs
|
||||
bitcom = inst.bitcoms
|
||||
conv_regint = inst.convsint
|
||||
mov = inst.movs
|
||||
mov = inst.movsb
|
||||
types = {}
|
||||
def __init__(self, *args, **kwargs):
|
||||
bits.__init__(self, *args, **kwargs)
|
||||
@@ -207,7 +212,7 @@ class sbits(bits):
|
||||
@staticmethod
|
||||
def get_random_bit():
|
||||
res = sbit()
|
||||
inst.bit(res)
|
||||
inst.bitb(res)
|
||||
return res
|
||||
@classmethod
|
||||
def get_input_from(cls, player, n_bits=None):
|
||||
@@ -238,7 +243,7 @@ class sbits(bits):
|
||||
if self.n <= 32:
|
||||
inst.ldbits(self, self.n, value)
|
||||
elif self.n <= 64:
|
||||
self.load_other(regint(value))
|
||||
self.load_other(regint(value, size=1))
|
||||
elif self.n <= 128:
|
||||
lower = sbits.get_type(64)(value % 2**64)
|
||||
upper = sbits.get_type(self.n - 64)(value >> 64)
|
||||
@@ -251,7 +256,7 @@ class sbits(bits):
|
||||
return self.xor_int(other)
|
||||
else:
|
||||
if not isinstance(other, sbits):
|
||||
other = sbits(other)
|
||||
other = self.conv(other)
|
||||
n = min(self.n, other.n)
|
||||
res = self.new(n=n)
|
||||
inst.xors(n, res, self, other)
|
||||
@@ -300,13 +305,20 @@ class sbits(bits):
|
||||
return 0
|
||||
elif util.is_all_ones(other, self.n):
|
||||
return self
|
||||
assert(self.n == other.n)
|
||||
res = self.new(n=self.n)
|
||||
if not isinstance(other, sbits):
|
||||
other = cbits.get_type(self.n).conv(other)
|
||||
inst.andm(self.n, res, self, other)
|
||||
return res
|
||||
other = self.conv(other)
|
||||
assert(self.n == other.n)
|
||||
inst.ands(self.n, res, self, other)
|
||||
return res
|
||||
def xor_int(self, other):
|
||||
if other == 0:
|
||||
return self
|
||||
elif other == self.long_one():
|
||||
return ~self
|
||||
self_bits = self.bit_decompose()
|
||||
other_bits = util.bit_decompose(other, max(self.n, util.int_len(other)))
|
||||
extra_bits = [self.new(b, n=1) for b in other_bits[self.n:]]
|
||||
@@ -332,9 +344,8 @@ class sbits(bits):
|
||||
# res = type(self)(n=self.n)
|
||||
# inst.nots(res, self)
|
||||
# return res
|
||||
one = self.new(value=1, n=1)
|
||||
bits = [one + bit for bit in self.bit_decompose()]
|
||||
return self.bit_compose(bits)
|
||||
one = self.new(value=self.long_one(), n=self.n)
|
||||
return self + one
|
||||
def __neg__(self):
|
||||
return self
|
||||
def reveal(self):
|
||||
@@ -381,6 +392,9 @@ class sbits(bits):
|
||||
def if_else(self, x, y):
|
||||
# vectorized if/else
|
||||
return result_conv(x, y)(self & (x ^ y) ^ y)
|
||||
@staticmethod
|
||||
def bit_adder(*args, **kwargs):
|
||||
return sbitint.bit_adder(*args, **kwargs)
|
||||
|
||||
class sbitvec(object):
|
||||
@classmethod
|
||||
@@ -634,7 +648,7 @@ class cbitfix(object):
|
||||
bits = self.v.bit_decompose(self.k)
|
||||
sign = bits[-1]
|
||||
v = self.v + (sign << (self.k)) * -1
|
||||
inst.print_float_plain(v, cbits(-self.f, n=32), cbits(0), cbits(0))
|
||||
inst.print_float_plainb(v, cbits(-self.f, n=32), cbits(0), cbits(0))
|
||||
|
||||
class sbitfix(_fix):
|
||||
float_type = type(None)
|
||||
|
||||
@@ -41,16 +41,16 @@ class StraightlineAllocator:
|
||||
raise RegisterOverflowError()
|
||||
self.alloc[base] = res
|
||||
|
||||
if base.vector:
|
||||
for i,r in enumerate(base.vector):
|
||||
r.i = self.alloc[base] + i
|
||||
base.i = self.alloc[base]
|
||||
|
||||
def dealloc_reg(self, reg, inst, free):
|
||||
self.dealloc.add(reg)
|
||||
if reg.vector:
|
||||
self.dealloc |= reg.vector
|
||||
else:
|
||||
self.dealloc.add(reg)
|
||||
base = reg.vectorbase
|
||||
|
||||
if base.vector and not inst.is_vec():
|
||||
if base.vector:
|
||||
for i in base.vector:
|
||||
if i not in self.dealloc:
|
||||
# not all vector elements ready for deallocation
|
||||
|
||||
@@ -139,8 +139,12 @@ def TruncLeakyInRing(a, k, m, signed):
|
||||
from .types import sint, intbitint, cint, cgf2n
|
||||
n_bits = k - m
|
||||
n_shift = int(program.options.ring) - n_bits
|
||||
r_bits = [sint.get_random_bit() for i in range(n_bits)]
|
||||
r = sint.bit_compose(r_bits)
|
||||
if program.use_dabit and n_bits > 1:
|
||||
r, r_bits = zip(*(sint.get_dabit() for i in range(n_bits)))
|
||||
r = sint.bit_compose(r)
|
||||
else:
|
||||
r_bits = [sint.get_random_bit() for i in range(n_bits)]
|
||||
r = sint.bit_compose(r_bits)
|
||||
if signed:
|
||||
a += (1 << (k - 1))
|
||||
shifted = ((a << (n_shift - m)) + (r << n_shift)).reveal()
|
||||
@@ -195,21 +199,26 @@ def Mod2mRing(a_prime, a, k, m, signed):
|
||||
assert(int(program.options.ring) >= k)
|
||||
from Compiler.types import sint, intbitint, cint
|
||||
shift = int(program.options.ring) - m
|
||||
r = [sint.get_random_bit() for i in range(m)]
|
||||
if program.use_dabit:
|
||||
r, r_bin = zip(*(sint.get_dabit() for i in range(m)))
|
||||
else:
|
||||
r = [sint.get_random_bit() for i in range(m)]
|
||||
r_bin = r
|
||||
r_prime = sint.bit_compose(r)
|
||||
tmp = a + r_prime
|
||||
c_prime = (tmp << shift).reveal() >> shift
|
||||
u = sint()
|
||||
BitLTL(u, c_prime, r, 0)
|
||||
BitLTL(u, c_prime, r_bin, 0)
|
||||
res = (u << m) + c_prime - r_prime
|
||||
if a_prime is not None:
|
||||
movs(a_prime, res)
|
||||
return res
|
||||
|
||||
def Mod2mField(a_prime, a, k, m, kappa, signed):
|
||||
from .types import sint
|
||||
r_dprime = program.curr_block.new_reg('s')
|
||||
r_prime = program.curr_block.new_reg('s')
|
||||
r = [program.curr_block.new_reg('s') for i in range(m)]
|
||||
r = [sint() for i in range(m)]
|
||||
c = program.curr_block.new_reg('c')
|
||||
c_prime = program.curr_block.new_reg('c')
|
||||
v = program.curr_block.new_reg('s')
|
||||
@@ -238,7 +247,7 @@ def Mod2mField(a_prime, a, k, m, kappa, signed):
|
||||
adds(a_prime, t[5], t[4])
|
||||
return r_dprime, r_prime, c, c_prime, u, t, c2k1
|
||||
|
||||
def PRandM(r_dprime, r_prime, b, k, m, kappa):
|
||||
def PRandM(r_dprime, r_prime, b, k, m, kappa, use_dabit=True):
|
||||
"""
|
||||
r_dprime = random secret integer in range [0, 2^(k + kappa - m) - 1]
|
||||
r_prime = random secret integer in range [0, 2^m - 1]
|
||||
@@ -249,6 +258,12 @@ def PRandM(r_dprime, r_prime, b, k, m, kappa):
|
||||
PRandInt(r_dprime, k + kappa - m)
|
||||
# r_dprime is always multiplied by 2^m
|
||||
program.curr_tape.require_bit_length(k + kappa)
|
||||
if use_dabit and program.use_dabit and m > 1:
|
||||
from .types import sint
|
||||
r, b[:] = zip(*(sint.get_dabit() for i in range(m)))
|
||||
r = sint.bit_compose(r)
|
||||
movs(r_prime, r)
|
||||
return
|
||||
bit(b[-1])
|
||||
for i in range(1,m):
|
||||
adds(t[i][0], t[i-1][1], t[i-1][1])
|
||||
@@ -345,14 +360,13 @@ def carry(b, a, compute_p):
|
||||
return a
|
||||
t = [program.curr_block.new_reg('s') for i in range(3)]
|
||||
if compute_p:
|
||||
muls(t[0], a[0], b[0])
|
||||
muls(t[1], a[0], b[1])
|
||||
adds(t[2], a[1], t[1])
|
||||
t[0] = a[0].bit_and(b[0])
|
||||
t[2] = a[0].bit_and(b[1]) + a[1]
|
||||
return t[0], t[2]
|
||||
|
||||
# from WP9 report
|
||||
# length of a is even
|
||||
def CarryOutAux(d, a, kappa):
|
||||
def CarryOutAux(a, kappa):
|
||||
k = len(a)
|
||||
if k > 1 and k % 2 == 1:
|
||||
a.append(None)
|
||||
@@ -362,9 +376,9 @@ def CarryOutAux(d, a, kappa):
|
||||
if k > 1:
|
||||
for i in range(k//2):
|
||||
u[i] = carry(a[2*i+1], a[2*i], i != k//2-1)
|
||||
CarryOutAux(d, u[:k//2][::-1], kappa)
|
||||
return CarryOutAux(u[:k//2][::-1], kappa)
|
||||
else:
|
||||
movs(d, a[0][1])
|
||||
return a[0][1]
|
||||
|
||||
# carry out with carry-in bit c
|
||||
def CarryOut(res, a, b, c=0, kappa=None):
|
||||
@@ -378,19 +392,14 @@ def CarryOut(res, a, b, c=0, kappa=None):
|
||||
k = len(a)
|
||||
from . import types
|
||||
d = [program.curr_block.new_reg('s') for i in range(k)]
|
||||
t = [[types.sint() for i in range(k)] for i in range(4)]
|
||||
s = [program.curr_block.new_reg('s') for i in range(3)]
|
||||
for i in range(k):
|
||||
mulm(t[0][i], b[i], a[i])
|
||||
mulsi(t[1][i], t[0][i], 2)
|
||||
addm(t[2][i], b[i], a[i])
|
||||
subs(t[3][i], t[2][i], t[1][i])
|
||||
d[i] = [t[3][i], t[0][i]]
|
||||
d[i] = list(b[i].half_adder(a[i]))
|
||||
s[0] = d[-1][0] * c
|
||||
s[1] = d[-1][1] + s[0]
|
||||
d[-1][1] = s[1]
|
||||
|
||||
CarryOutAux(res, d[::-1], kappa)
|
||||
movs(res, types.sint.conv(CarryOutAux(d[::-1], kappa)))
|
||||
|
||||
def CarryOutLE(a, b, c=0):
|
||||
""" Little-endian version """
|
||||
@@ -412,7 +421,7 @@ def BitLTL(res, a, b, kappa):
|
||||
s = [[program.curr_block.new_reg('s') for i in range(k)] for j in range(2)]
|
||||
t = [program.curr_block.new_reg('s') for i in range(1)]
|
||||
for i in range(len(b)):
|
||||
subsfi(s[0][i], b[i], 1)
|
||||
s[0][i] = b[0].long_one() - b[i]
|
||||
CarryOut(t[0], a_bits[::-1], s[0][::-1], 1, kappa)
|
||||
subsfi(res, t[0], 1)
|
||||
return a_bits, s[0]
|
||||
|
||||
@@ -32,8 +32,12 @@ def shift_two(n, pos):
|
||||
|
||||
def maskRing(a, k):
|
||||
shift = int(program.Program.prog.options.ring) - k
|
||||
r = [types.sint.get_random_bit() for i in range(k)]
|
||||
r_prime = types.sint.bit_compose(r)
|
||||
if program.Program.prog.use_dabit:
|
||||
rr, r = zip(*(types.sint.get_dabit() for i in range(k)))
|
||||
r_prime = types.sint.bit_compose(rr)
|
||||
else:
|
||||
r = [types.sint.get_random_bit() for i in range(k)]
|
||||
r_prime = types.sint.bit_compose(r)
|
||||
c = ((a + r_prime) << shift).reveal() >> shift
|
||||
return c, r
|
||||
|
||||
@@ -53,8 +57,8 @@ def EQZ(a, k, kappa):
|
||||
c, r = maskField(a, k, kappa)
|
||||
d = [None]*k
|
||||
for i,b in enumerate(bits(c, k)):
|
||||
d[i] = b + r[i] - 2*b*r[i]
|
||||
return 1 - KOR(d, kappa)
|
||||
d[i] = r[i].bit_xor(b)
|
||||
return 1 - types.sint.conv(KOR(d, kappa))
|
||||
|
||||
def bits(a,m):
|
||||
""" Get the bits of an int """
|
||||
@@ -82,10 +86,10 @@ def carry(b, a, compute_p=True):
|
||||
(p,g) = (p_2, g_2)o(p_1, g_1) -> (p_1 & p_2, g_2 | (p_2 & g_1))
|
||||
"""
|
||||
if compute_p:
|
||||
t1 = a[0]*b[0]
|
||||
t1 = a[0].bit_and(b[0])
|
||||
else:
|
||||
t1 = None
|
||||
t2 = a[1] + a[0]*b[1]
|
||||
t2 = a[1] + a[0].bit_and(b[1])
|
||||
return (t1, t2)
|
||||
|
||||
def or_op(a, b, void=None):
|
||||
@@ -197,7 +201,7 @@ def KORL(a, kappa):
|
||||
else:
|
||||
t1 = KORL(a[:k//2], kappa)
|
||||
t2 = KORL(a[k//2:], kappa)
|
||||
return t1 + t2 - t1*t2
|
||||
return t1 + t2 - t1.bit_and(t2)
|
||||
|
||||
def KORC(a, kappa):
|
||||
return PreORC(a, kappa, 1)[0]
|
||||
@@ -295,11 +299,16 @@ def BitDec(a, k, m, kappa, bits_to_compute=None):
|
||||
|
||||
def BitDecRing(a, k, m):
|
||||
n_shift = int(program.Program.prog.options.ring) - m
|
||||
r_bits = [types.sint.get_random_bit() for i in range(m)]
|
||||
r = types.sint.bit_compose(r_bits)
|
||||
if program.Program.prog.use_dabit:
|
||||
r, r_bits = zip(*(types.sint.get_dabit() for i in range(m)))
|
||||
r = types.sint.bit_compose(r)
|
||||
else:
|
||||
r_bits = [types.sint.get_random_bit() for i in range(m)]
|
||||
r = types.sint.bit_compose(r_bits)
|
||||
shifted = ((a - r) << n_shift).reveal()
|
||||
masked = shifted >> n_shift
|
||||
return types.intbitint.bit_adder(r_bits, masked.bit_decompose(m))
|
||||
bits = r_bits[0].bit_adder(r_bits, masked.bit_decompose(m))
|
||||
return [types.sint.conv(bit) for bit in bits]
|
||||
|
||||
def BitDecField(a, k, m, kappa, bits_to_compute=None):
|
||||
r_dprime = types.sint()
|
||||
@@ -319,7 +328,8 @@ def BitDecField(a, k, m, kappa, bits_to_compute=None):
|
||||
print('BitDec assertion failed')
|
||||
print('a =', a.value)
|
||||
print('a mod 2^%d =' % k, (a.value % 2**k))
|
||||
return types.intbitint.bit_adder(list(bits(c,m)), r)
|
||||
res = r[0].bit_adder(r, list(bits(c,m)))
|
||||
return [types.sint.conv(bit) for bit in res]
|
||||
|
||||
|
||||
def Pow2(a, l, kappa):
|
||||
@@ -345,17 +355,21 @@ def B2U_from_Pow2(pow2a, l, kappa):
|
||||
r = [types.sint() for i in range(l)]
|
||||
t = types.sint()
|
||||
c = types.cint()
|
||||
for i in range(l):
|
||||
bit(r[i])
|
||||
if program.Program.prog.use_dabit:
|
||||
r, r_bits = zip(*(types.sint.get_dabit() for i in range(l)))
|
||||
else:
|
||||
for i in range(l):
|
||||
bit(r[i])
|
||||
r_bits = r
|
||||
comparison.PRandInt(t, kappa)
|
||||
asm_open(c, pow2a + two_power(l) * t + sum(two_power(i)*r[i] for i in range(l)))
|
||||
comparison.program.curr_tape.require_bit_length(l + kappa)
|
||||
c = list(bits(c, l))
|
||||
x = [c[i] + r[i] - 2*c[i]*r[i] for i in range(l)]
|
||||
x = [r_bits[i].bit_xor(c[i]) for i in range(l)]
|
||||
#print ' '.join(str(b.value) for b in x)
|
||||
y = PreOR(x, kappa)
|
||||
#print ' '.join(str(b.value) for b in y)
|
||||
return [1 - y[i] for i in range(l)]
|
||||
return [types.sint.conv(1 - y[i]) for i in range(l)]
|
||||
|
||||
def Trunc(a, l, m, kappa, compute_modulo=False, signed=False):
|
||||
""" Oblivious truncation by secret m """
|
||||
@@ -532,7 +546,7 @@ def TruncPrField(a, k, m, kappa=None):
|
||||
b = two_power(k-1) + a
|
||||
r_prime, r_dprime = types.sint(), types.sint()
|
||||
comparison.PRandM(r_dprime, r_prime, [types.sint() for i in range(m)],
|
||||
k, m, kappa)
|
||||
k, m, kappa, use_dabit=False)
|
||||
two_to_m = two_power(m)
|
||||
r = two_to_m * r_dprime + r_prime
|
||||
c = (b + r).reveal()
|
||||
|
||||
@@ -801,6 +801,15 @@ class bit(base.DataInstruction):
|
||||
def execute(self):
|
||||
self.args[0].value = randint(0,1)
|
||||
|
||||
@base.vectorize
|
||||
class dabit(base.DataInstruction):
|
||||
""" daBit """
|
||||
__slots__ = []
|
||||
code = base.opcodes['DABIT']
|
||||
arg_format = ['sw', 'sbw']
|
||||
field_type = 'modp'
|
||||
data_type = 'bit'
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class square(base.DataInstruction):
|
||||
|
||||
@@ -102,6 +102,7 @@ opcodes = dict(
|
||||
GBITGF2NTRIPLE = 0x155,
|
||||
INPUTMASK = 0x56,
|
||||
PREP = 0x57,
|
||||
DABIT = 0x58,
|
||||
# Input
|
||||
INPUT = 0x60,
|
||||
INPUTFIX = 0xF0,
|
||||
@@ -237,11 +238,11 @@ def vectorize(instruction, global_dict=None):
|
||||
if issubclass(ArgFormats[f], RegisterArgFormat):
|
||||
arg.set_size(size)
|
||||
def get_code(self):
|
||||
return (self.size << 9) + self.code
|
||||
return (self.size << 10) + self.code
|
||||
def get_pre_arg(self):
|
||||
return "%d, " % self.size
|
||||
def is_vec(self):
|
||||
return self.size > 1
|
||||
return True
|
||||
def get_size(self):
|
||||
return self.size
|
||||
def expand(self):
|
||||
@@ -547,8 +548,8 @@ class Instruction(object):
|
||||
try:
|
||||
ArgFormats[f].check(arg)
|
||||
except ArgumentError as e:
|
||||
raise CompilerError('Invalid argument "%s" to instruction: %s'
|
||||
% (e.arg, self) + '\n' + e.msg)
|
||||
raise CompilerError('Invalid argument %d "%s" to instruction: %s'
|
||||
% (n, e.arg, self) + '\n' + e.msg)
|
||||
except KeyError as e:
|
||||
raise CompilerError('Unknown argument %s for instruction %s' % (f, self))
|
||||
|
||||
|
||||
@@ -909,6 +909,7 @@ def map_reduce_single(n_parallel, n_loops, initializer=lambda *x: [],
|
||||
for block in blocks[-n_to_merge + 1:]:
|
||||
merged.instructions += block.instructions
|
||||
exit_elimination(block)
|
||||
block.purge()
|
||||
del blocks[-n_to_merge + 1:]
|
||||
del get_tape().req_node.children[-1]
|
||||
merged.children = []
|
||||
@@ -956,8 +957,6 @@ def multithread(n_threads, n_items):
|
||||
Distribute the computation of n_items to n_threads threads,
|
||||
but leave the in-thread repetition up to the user
|
||||
"""
|
||||
if n_threads == 1 or n_items == 1:
|
||||
return lambda loop_body: loop_body(0, n_items)
|
||||
return map_reduce(n_threads, None, n_items, initializer=lambda: [],
|
||||
reducer=None, looping=False)
|
||||
|
||||
@@ -977,13 +976,6 @@ def map_reduce(n_threads, n_parallel, n_loops, initializer, reducer, \
|
||||
return new_body
|
||||
new_dec = map_reduce(n_threads, n_parallel, n_loops, initializer, reducer, thread_mem_req)
|
||||
return lambda loop_body: new_dec(decorator(loop_body))
|
||||
if n_threads == 1 or n_loops == 1:
|
||||
dec = map_reduce_single(n_parallel, n_loops, initializer, reducer)
|
||||
if thread_mem_req:
|
||||
thread_mem = Array(thread_mem_req[regint], regint)
|
||||
return lambda loop_body: dec(lambda i: loop_body(i, thread_mem))
|
||||
else:
|
||||
return dec
|
||||
def decorator(loop_body):
|
||||
thread_rounds = n_loops // n_threads
|
||||
remainder = n_loops % n_threads
|
||||
|
||||
@@ -1404,7 +1404,7 @@ class PackedIndexStructure(object):
|
||||
self.value_type = value_type
|
||||
for demux_bits in range(max_demux_bits + 1):
|
||||
self.log_entries_per_element = min(log2(size), \
|
||||
int(math.floor(math.log(float(get_value_size(value_type)) // \
|
||||
int(math.floor(math.log(float(get_value_size(value_type)) / \
|
||||
sum(self.entry_size), 2))))
|
||||
self.log_elements_per_block = \
|
||||
max(0, min(demux_bits, log2(size) - \
|
||||
|
||||
@@ -94,6 +94,7 @@ class Program(object):
|
||||
self.to_merge += [gc.ldmsdi, gc.stmsdi, gc.ldmsd, gc.stmsd, \
|
||||
gc.stmsdci, gc.xors, gc.andrs, gc.ands, gc.inputb]
|
||||
self.use_trunc_pr = False
|
||||
self.use_dabit = options.mixed
|
||||
Program.prog = self
|
||||
|
||||
self.reset_values()
|
||||
@@ -462,6 +463,7 @@ class Tape:
|
||||
self.purged = False
|
||||
self.n_rounds = 0
|
||||
self.n_to_merge = 0
|
||||
self.defined_registers = None
|
||||
|
||||
def __len__(self):
|
||||
return len(self.instructions)
|
||||
@@ -502,9 +504,14 @@ class Tape:
|
||||
#print 'Basic block %d jumps to %d (%d)' % (next_block_index, jump_index, offset)
|
||||
|
||||
def purge(self):
|
||||
relevant = lambda inst: inst.add_usage is not \
|
||||
Compiler.instructions_base.Instruction.add_usage
|
||||
def relevant(inst):
|
||||
req_node = Tape.ReqNode('')
|
||||
req_node.num = Tape.ReqNum()
|
||||
inst.add_usage(req_node)
|
||||
return req_node.num != {}
|
||||
self.usage_instructions = list(filter(relevant, self.instructions))
|
||||
if len(self.usage_instructions) > 1000:
|
||||
print('Retaining %d instructions' % len(self.usage_instructions))
|
||||
del self.instructions
|
||||
del self.defined_registers
|
||||
self.purged = True
|
||||
@@ -899,7 +906,7 @@ class Tape:
|
||||
|
||||
The 'value' property is for emulation.
|
||||
"""
|
||||
__slots__ = ["reg_type", "program", "i", "_is_active", \
|
||||
__slots__ = ["reg_type", "program", "absolute_i", "relative_i", \
|
||||
"size", "vector", "vectorbase", "caller", \
|
||||
"can_eliminate"]
|
||||
|
||||
@@ -916,16 +923,16 @@ class Tape:
|
||||
if size is None:
|
||||
size = Compiler.instructions_base.get_global_vector_size()
|
||||
self.size = size
|
||||
self.vectorbase = self
|
||||
self.relative_i = 0
|
||||
if i is not None:
|
||||
self.i = i
|
||||
else:
|
||||
self.i = program.reg_counter[reg_type]
|
||||
program.reg_counter[reg_type] += size
|
||||
self.vector = []
|
||||
self.vectorbase = self
|
||||
if value is not None:
|
||||
self.value = value
|
||||
self._is_active = False
|
||||
self.can_eliminate = True
|
||||
if Program.prog.DEBUG:
|
||||
self.caller = [frame[1:] for frame in inspect.stack()[1:]]
|
||||
@@ -934,9 +941,19 @@ class Tape:
|
||||
if self.i % 1000000 == 0 and self.i > 0:
|
||||
print("Initialized %d registers at" % self.i, time.asctime())
|
||||
|
||||
@property
|
||||
def i(self):
|
||||
return self.vectorbase.absolute_i + self.relative_i
|
||||
|
||||
@i.setter
|
||||
def i(self, value):
|
||||
self.vectorbase.absolute_i = value - self.relative_i
|
||||
|
||||
def set_size(self, size):
|
||||
if self.size == size:
|
||||
return
|
||||
elif not self.program.options.assemblymode:
|
||||
raise CompilerError('Mismatch of instruction and register size')
|
||||
elif self.size == 1 and self.vectorbase is self:
|
||||
if '%s%d' % (self.reg_type, self.i) in compilerLib.VARS:
|
||||
# create vector register in assembly mode
|
||||
@@ -955,10 +972,18 @@ class Tape:
|
||||
if self.vectorbase is not self:
|
||||
raise CompilerError('Cannot assign one register' \
|
||||
'to several vectors')
|
||||
self.relative_i = self.i - vectorbase.i
|
||||
self.vectorbase = vectorbase
|
||||
|
||||
def _new_by_number(self, i):
|
||||
return Tape.Register(self.reg_type, self.program, size=1, i=i)
|
||||
def _new_by_number(self, i, size=1):
|
||||
return Tape.Register(self.reg_type, self.program, size=size, i=i)
|
||||
|
||||
def get_vector(self, base, size):
|
||||
res = self._new_by_number(self.i + base, size=size)
|
||||
res.set_vectorbase(self)
|
||||
self.create_vector_elements()
|
||||
res.vector = self.vector[base:base+size]
|
||||
return res
|
||||
|
||||
def create_vector_elements(self):
|
||||
if self.vector:
|
||||
@@ -983,14 +1008,6 @@ class Tape:
|
||||
def __len__(self):
|
||||
return self.size
|
||||
|
||||
def activate(self):
|
||||
""" Activating a register signals that it will at some point be used
|
||||
in the program.
|
||||
|
||||
Inactive registers are reserved for temporaries for CISC instructions. """
|
||||
if not self._is_active:
|
||||
self._is_active = True
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self.program.reg_values[self.reg_type][self.i]
|
||||
@@ -1000,10 +1017,6 @@ class Tape:
|
||||
while (len(self.program.reg_values[self.reg_type]) <= self.i):
|
||||
self.program.reg_values[self.reg_type] += [0] * INIT_REG_MAX
|
||||
self.program.reg_values[self.reg_type][self.i] = val
|
||||
|
||||
@property
|
||||
def is_active(self):
|
||||
return self._is_active
|
||||
|
||||
@property
|
||||
def is_gf2n(self):
|
||||
|
||||
@@ -175,6 +175,10 @@ class _number(object):
|
||||
return (self < other).if_else(other, self)
|
||||
|
||||
class _int(object):
|
||||
@staticmethod
|
||||
def bit_adder(*args, **kwargs):
|
||||
return intbitint.bit_adder(*args, **kwargs)
|
||||
|
||||
def if_else(self, a, b):
|
||||
if hasattr(a, 'for_mux'):
|
||||
f, a, b = a.for_mux(b)
|
||||
@@ -189,7 +193,24 @@ class _int(object):
|
||||
def bit_xor(self, other):
|
||||
return self + other - 2 * self * other
|
||||
|
||||
class _gf2n(object):
|
||||
def bit_and(self, other):
|
||||
return self * other
|
||||
|
||||
def half_adder(self, other):
|
||||
carry = self * other
|
||||
return self + other - 2 * carry, carry
|
||||
|
||||
class _bit(object):
|
||||
def bit_xor(self, other):
|
||||
return self ^ other
|
||||
|
||||
def bit_and(self, other):
|
||||
return self & other
|
||||
|
||||
def half_adder(self, other):
|
||||
return self ^ other, self & other
|
||||
|
||||
class _gf2n(_bit):
|
||||
def if_else(self, a, b):
|
||||
return b ^ self * self.hard_conv(a ^ b)
|
||||
|
||||
@@ -310,6 +331,12 @@ class _register(Tape.Register, _number, _structure):
|
||||
elif val is not None:
|
||||
self.load_other(val)
|
||||
|
||||
def _new_by_number(self, i, size=1):
|
||||
res = type(self)(size=size)
|
||||
res.i = i
|
||||
res.program = self.program
|
||||
return res
|
||||
|
||||
def sizeof(self):
|
||||
return self.size
|
||||
|
||||
@@ -509,6 +536,7 @@ class cint(_clear, _int):
|
||||
elif chunk:
|
||||
sum += sign * chunk
|
||||
|
||||
@vectorize
|
||||
def to_regint(self, n_bits=None, dest=None):
|
||||
dest = regint() if dest is None else dest
|
||||
convmodp(dest, self, bitlength=n_bits)
|
||||
@@ -599,6 +627,7 @@ class cint(_clear, _int):
|
||||
def greater_than(self, other, bit_length=None):
|
||||
return self > other
|
||||
|
||||
@vectorize
|
||||
def bit_decompose(self, bit_length=None):
|
||||
if bit_length == 0:
|
||||
return []
|
||||
@@ -1065,19 +1094,20 @@ class _secret(_register):
|
||||
@read_mem_value
|
||||
@vectorize
|
||||
def load_other(self, val):
|
||||
from Compiler.GC.types import sbits
|
||||
if isinstance(val, self.clear_type):
|
||||
self.load_clear(val)
|
||||
elif isinstance(val, type(self)):
|
||||
movs(self, val)
|
||||
elif isinstance(val, sbits):
|
||||
assert(val.n == self.size)
|
||||
r = self.get_dabit()
|
||||
v = regint()
|
||||
bitdecint_class(regint((r[1] ^ val).reveal()), *v)
|
||||
movs(self, r[0].bit_xor(v))
|
||||
else:
|
||||
self.load_clear(self.clear_type(val))
|
||||
|
||||
def _new_by_number(self, i):
|
||||
res = type(self)(size=1)
|
||||
res.i = i
|
||||
res.program = self.program
|
||||
return res
|
||||
|
||||
@set_instruction_type
|
||||
@read_mem_value
|
||||
@vectorize
|
||||
@@ -1179,6 +1209,18 @@ class sint(_secret, _int):
|
||||
inputmixed('int', res, player)
|
||||
return res
|
||||
|
||||
@vectorized_classmethod
|
||||
def get_dabit(cls):
|
||||
""" Bit in arithmetic and binary circuit according to security model """
|
||||
from Compiler.GC.types import sbits
|
||||
res = cls(), sbits.get_type(get_global_vector_size())()
|
||||
dabit(*res)
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
def long_one():
|
||||
return 1
|
||||
|
||||
@classmethod
|
||||
def get_raw_input_from(cls, player):
|
||||
res = cls()
|
||||
@@ -1354,6 +1396,7 @@ class sint(_secret, _int):
|
||||
def __rrshift__(self, other):
|
||||
return floatingpoint.Trunc(other, program.bit_length, self, program.security)
|
||||
|
||||
@vectorize
|
||||
def bit_decompose(self, bit_length=None, security=None):
|
||||
if bit_length == 0:
|
||||
return []
|
||||
@@ -1519,6 +1562,10 @@ class _bitint(object):
|
||||
log_rounds = False
|
||||
linear_rounds = False
|
||||
|
||||
@staticmethod
|
||||
def half_adder(a, b):
|
||||
return a.half_adder(b)
|
||||
|
||||
@classmethod
|
||||
def bit_adder(cls, a, b, carry_in=0, get_carry=False):
|
||||
a, b = list(a), list(b)
|
||||
@@ -1618,10 +1665,6 @@ class _bitint(object):
|
||||
s = a + b
|
||||
return s + carry, util.if_else(s, carry, a)
|
||||
|
||||
@staticmethod
|
||||
def half_adder(a, b):
|
||||
return a + b, a & b
|
||||
|
||||
@staticmethod
|
||||
def bit_comparator(a, b):
|
||||
long_one = util.long_one(a + b)
|
||||
@@ -1814,11 +1857,6 @@ class intbitint(_bitint, sint):
|
||||
s = a.bit_xor(b)
|
||||
return s.bit_xor(carry), util.if_else(s, carry, a)
|
||||
|
||||
@staticmethod
|
||||
def half_adder(a, b):
|
||||
carry = a * b
|
||||
return a + b - 2 * carry, carry
|
||||
|
||||
@staticmethod
|
||||
def sum_from_carries(a, b, carries):
|
||||
return [a[i] + b[i] + carries[i] - 2 * carries[i + 1] \
|
||||
@@ -3284,6 +3322,7 @@ class Array(object):
|
||||
if conv:
|
||||
value = self.value_type.conv(value)
|
||||
mem_value = MemValue(value)
|
||||
self.address = MemValue(self.address)
|
||||
n_threads = 8 if use_threads and len(self) > 2**20 else 1
|
||||
@library.for_range_multithread(n_threads, 1024, len(self))
|
||||
def f(i):
|
||||
|
||||
@@ -197,6 +197,11 @@ class set_by_id(object):
|
||||
def add(self, value):
|
||||
self.content[id(value)] = value
|
||||
|
||||
def __ior__(self, values):
|
||||
for value in values:
|
||||
self.add(value)
|
||||
return self
|
||||
|
||||
class dict_by_id(object):
|
||||
def __init__(self):
|
||||
self.content = {}
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
#include "Processor/Input.hpp"
|
||||
#include "Processor/Processor.hpp"
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/RepPrep.hpp"
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
@@ -3,8 +3,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "GC/TinierSecret.h"
|
||||
#include "GC/TinyMC.h"
|
||||
|
||||
#include "Protocols/Share.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/TinierSharePrep.hpp"
|
||||
#include "ot-ecdsa-party.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "GC/SemiSecret.h"
|
||||
#include "GC/SemiPrep.h"
|
||||
|
||||
#include "Protocols/SemiMC.hpp"
|
||||
#include "Protocols/SemiPrep.hpp"
|
||||
#include "Protocols/SemiInput.hpp"
|
||||
|
||||
@@ -212,4 +212,13 @@ class closed_connection
|
||||
}
|
||||
};
|
||||
|
||||
class no_singleton : runtime_error
|
||||
{
|
||||
public:
|
||||
no_singleton(string msg) :
|
||||
runtime_error(msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,12 +34,6 @@ public:
|
||||
typedef FakeSecret DynamicType;
|
||||
typedef Memory<FakeSecret> DynamicMemory;
|
||||
|
||||
// dummy
|
||||
typedef DummyMC MC;
|
||||
typedef DummyProtocol Protocol;
|
||||
|
||||
static MC* new_mc(Machine<FakeSecret>& _) { (void) _; return new MC; }
|
||||
|
||||
static string type_string() { return "fake secret"; }
|
||||
static string phase_name() { return "Faking"; }
|
||||
|
||||
|
||||
@@ -15,50 +15,29 @@ using namespace std;
|
||||
namespace GC
|
||||
{
|
||||
|
||||
// Register types
|
||||
enum RegType {
|
||||
SBIT,
|
||||
CBIT,
|
||||
INT,
|
||||
DYN_SBIT,
|
||||
MAX_REG_TYPE,
|
||||
NONE
|
||||
};
|
||||
|
||||
template<class T> class Processor;
|
||||
|
||||
template <class T>
|
||||
class Instruction : public ::BaseInstruction
|
||||
{
|
||||
bool (*code)(const Instruction<T>& instruction, Processor<T>& processor);
|
||||
public:
|
||||
Instruction();
|
||||
|
||||
int get_r(int i) const { return r[i]; }
|
||||
unsigned int get_n() const { return n; }
|
||||
const vector<int>& get_start() const { return start; }
|
||||
int get_opcode() const { return opcode; }
|
||||
|
||||
// Reads a single instruction from the istream
|
||||
void parse(istream& s, int pos);
|
||||
|
||||
// Return whether usage is known
|
||||
bool get_offline_data_usage(int& usage);
|
||||
|
||||
int get_reg_type() const;
|
||||
|
||||
// Returns the maximal register used
|
||||
unsigned get_max_reg(int reg_type) const;
|
||||
|
||||
// Returns the memory size used if applicable and known
|
||||
unsigned get_mem(RegType reg_type) const;
|
||||
|
||||
// Execute this instruction
|
||||
bool exe(Processor<T>& processor) const { return code(*this, processor); }
|
||||
template<class U>
|
||||
template<class T, class U>
|
||||
bool execute(Processor<T>& processor, U& dynamic_memory) const;
|
||||
};
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
enum
|
||||
{
|
||||
// GC specific
|
||||
@@ -77,20 +56,37 @@ enum
|
||||
LDBITS = 0x20a,
|
||||
ANDS = 0x20b,
|
||||
TRANS = 0x20c,
|
||||
BITB = 0x20d,
|
||||
ANDM = 0x20e,
|
||||
LDMSB = 0x240,
|
||||
STMSB = 0x241,
|
||||
LDMSBI = 0x242,
|
||||
STMSBI = 0x243,
|
||||
MOVSB = 0x244,
|
||||
INPUTB = 0x246,
|
||||
// write to clear
|
||||
CLEAR_WRITE = 0x210,
|
||||
XORCI = 0x210,
|
||||
XORCBI = 0x210,
|
||||
BITDECC = 0x211,
|
||||
CONVCINT = 0x213,
|
||||
REVEAL = 0x214,
|
||||
STMSDCI = 0x215,
|
||||
INPUTB = 0x216,
|
||||
LDMCB = 0x217,
|
||||
STMCB = 0x218,
|
||||
XORCB = 0x219,
|
||||
ADDCB = 0x21a,
|
||||
ADDCBI = 0x21b,
|
||||
MULCBI = 0x21c,
|
||||
SHRCBI = 0x21d,
|
||||
SHLCBI = 0x21e,
|
||||
// don't write
|
||||
PRINTREGSIGNED = 0x220,
|
||||
PRINTREGB = 0x221,
|
||||
PRINTREGPLAINB = 0x222,
|
||||
PRINTFLOATPLAINB = 0x223,
|
||||
CONDPRINTSTRB = 0x224,
|
||||
// write to regint
|
||||
CONVCBIT = 0x230,
|
||||
};
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif /* PROCESSOR_GC_INSTRUCTION_H_ */
|
||||
|
||||
@@ -17,16 +17,15 @@
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template <class T>
|
||||
Instruction<T>::Instruction() :
|
||||
inline
|
||||
Instruction::Instruction() :
|
||||
BaseInstruction()
|
||||
{
|
||||
code = fallback_code;
|
||||
size = 1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool Instruction<T>::get_offline_data_usage(int& usage)
|
||||
inline
|
||||
bool Instruction::get_offline_data_usage(int& usage)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
@@ -38,79 +37,8 @@ bool Instruction<T>::get_offline_data_usage(int& usage)
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int Instruction<T>::get_reg_type() const
|
||||
{
|
||||
switch (opcode & 0x2F0)
|
||||
{
|
||||
case SECRET_WRITE:
|
||||
return SBIT;
|
||||
case CLEAR_WRITE:
|
||||
return CBIT;
|
||||
default:
|
||||
switch (::BaseInstruction::get_reg_type())
|
||||
{
|
||||
case ::INT:
|
||||
return INT;
|
||||
case ::MODP:
|
||||
switch (opcode)
|
||||
{
|
||||
case LDMC:
|
||||
case STMC:
|
||||
case XORC:
|
||||
case ADDC:
|
||||
case ADDCI:
|
||||
case MULCI:
|
||||
case SHRCI:
|
||||
case SHLCI:
|
||||
return CBIT;
|
||||
}
|
||||
return SBIT;
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
unsigned GC::Instruction<T>::get_max_reg(int reg_type) const
|
||||
{
|
||||
int skip;
|
||||
int offset = 0;
|
||||
switch (opcode)
|
||||
{
|
||||
case LDMSD:
|
||||
case LDMSDI:
|
||||
skip = 3;
|
||||
break;
|
||||
case STMSD:
|
||||
case STMSDI:
|
||||
skip = 2;
|
||||
break;
|
||||
case ANDRS:
|
||||
case XORS:
|
||||
case ANDS:
|
||||
skip = 4;
|
||||
offset = 1;
|
||||
break;
|
||||
case INPUTB:
|
||||
skip = 4;
|
||||
offset = 3;
|
||||
break;
|
||||
case CONVCBIT:
|
||||
return BaseInstruction::get_max_reg(INT);
|
||||
default:
|
||||
return BaseInstruction::get_max_reg(reg_type);
|
||||
}
|
||||
|
||||
unsigned m = 0;
|
||||
if (reg_type == SBIT)
|
||||
for (size_t i = offset; i < start.size(); i += skip)
|
||||
m = max(m, (unsigned)start[i] + 1);
|
||||
return m;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
unsigned Instruction<T>::get_mem(RegType reg_type) const
|
||||
inline
|
||||
unsigned Instruction::get_mem(RegType reg_type) const
|
||||
{
|
||||
unsigned m = n + 1;
|
||||
switch (opcode)
|
||||
@@ -133,27 +61,15 @@ unsigned Instruction<T>::get_mem(RegType reg_type) const
|
||||
return m;
|
||||
}
|
||||
break;
|
||||
case LDMS:
|
||||
case STMS:
|
||||
if (reg_type == SBIT)
|
||||
return m;
|
||||
break;
|
||||
case LDMC:
|
||||
case STMC:
|
||||
if (reg_type == CBIT)
|
||||
return m;
|
||||
break;
|
||||
case LDMINT:
|
||||
case STMINT:
|
||||
if (reg_type == INT)
|
||||
return m;
|
||||
break;
|
||||
default:
|
||||
return BaseInstruction::get_mem(reg_type, MAX_SECRECY_TYPE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Instruction<T>::parse(istream& s, int pos)
|
||||
inline
|
||||
void Instruction::parse(istream& s, int pos)
|
||||
{
|
||||
n = 0;
|
||||
start.resize(0);
|
||||
@@ -162,67 +78,7 @@ void Instruction<T>::parse(istream& s, int pos)
|
||||
int file_pos = s.tellg();
|
||||
opcode = ::get_int(s);
|
||||
|
||||
try {
|
||||
parse_operands(s, pos);
|
||||
}
|
||||
catch (Invalid_Instruction& e)
|
||||
{
|
||||
int m;
|
||||
switch (opcode)
|
||||
{
|
||||
case XORM:
|
||||
n = get_int(s);
|
||||
get_ints(r, s, 3);
|
||||
break;
|
||||
case XORCI:
|
||||
case MULCI:
|
||||
case LDBITS:
|
||||
get_ints(r, s, 2);
|
||||
n = get_int(s);
|
||||
break;
|
||||
case BITDECS:
|
||||
case BITCOMS:
|
||||
case BITDECC:
|
||||
m = get_int(s) - 1;
|
||||
get_ints(r, s, 1);
|
||||
get_vector(m, start, s);
|
||||
break;
|
||||
case CONVCINT:
|
||||
case CONVCBIT:
|
||||
get_ints(r, s, 2);
|
||||
break;
|
||||
case REVEAL:
|
||||
case CONVSINT:
|
||||
n = get_int(s);
|
||||
get_ints(r, s, 2);
|
||||
break;
|
||||
case LDMSDI:
|
||||
case STMSDI:
|
||||
case LDMSD:
|
||||
case STMSD:
|
||||
case STMSDCI:
|
||||
case XORS:
|
||||
case ANDRS:
|
||||
case ANDS:
|
||||
case INPUTB:
|
||||
get_vector(get_int(s), start, s);
|
||||
break;
|
||||
case PRINTREGSIGNED:
|
||||
n = get_int(s);
|
||||
get_ints(r, s, 1);
|
||||
break;
|
||||
case TRANS:
|
||||
m = get_int(s) - 1;
|
||||
n = get_int(s);
|
||||
get_vector(m, start, s);
|
||||
break;
|
||||
default:
|
||||
ostringstream os;
|
||||
os << "Invalid instruction " << showbase << hex << opcode
|
||||
<< " at " << dec << pos << "/" << hex << file_pos << dec;
|
||||
throw Invalid_Instruction(os.str());
|
||||
}
|
||||
}
|
||||
parse_operands(s, pos, file_pos);
|
||||
|
||||
switch(opcode)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace GC {
|
||||
#include "instructions.h"
|
||||
|
||||
template <class T>
|
||||
inline bool fallback_code(const Instruction<T>& instruction, Processor<T>& processor)
|
||||
inline bool fallback_code(const Instruction& instruction, Processor<T>& processor)
|
||||
{
|
||||
(void)processor;
|
||||
cout << "Undefined instruction " << showbase << hex
|
||||
@@ -27,9 +27,8 @@ inline bool fallback_code(const Instruction<T>& instruction, Processor<T>& proce
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class U>
|
||||
MAYBE_INLINE bool Instruction<T>::execute(Processor<T>& processor,
|
||||
template <class T, class U>
|
||||
MAYBE_INLINE bool Instruction::execute(Processor<T>& processor,
|
||||
U& dynamic_memory) const
|
||||
{
|
||||
#ifdef DEBUG_OPS
|
||||
|
||||
15
GC/Machine.h
15
GC/Machine.h
@@ -21,11 +21,22 @@ namespace GC
|
||||
template <class T> class Program;
|
||||
|
||||
template <class T>
|
||||
class Machine : public ::BaseMachine
|
||||
class Memories
|
||||
{
|
||||
public:
|
||||
Memory<T> MS;
|
||||
Memory<Clear> MC;
|
||||
|
||||
template<class U>
|
||||
void reset(const U& program);
|
||||
|
||||
void write_memory(int my_num);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class Machine : public ::BaseMachine, public Memories<T>
|
||||
{
|
||||
public:
|
||||
Memory<Integer> MI;
|
||||
|
||||
vector<Program<T> > progs;
|
||||
@@ -50,8 +61,6 @@ public:
|
||||
|
||||
void run_tape(int thread_number, int tape_number, int arg);
|
||||
void join_tape(int thread_numer);
|
||||
|
||||
void write_memory(int my_num);
|
||||
};
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_MACHINE_HPP_
|
||||
#define GC_MACHINE_HPP_
|
||||
|
||||
#include <GC/Machine.h>
|
||||
|
||||
#include "GC/Program.h"
|
||||
@@ -52,13 +55,20 @@ void Machine<T>::load_schedule(string progname)
|
||||
print_compiler();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class U>
|
||||
void Memories<T>::reset(const U& program)
|
||||
{
|
||||
MS.resize_min(*program.direct_mem(SBIT), "memory");
|
||||
MC.resize_min(*program.direct_mem(CBIT), "memory");
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class U>
|
||||
void Machine<T>::reset(const U& program)
|
||||
{
|
||||
MS.resize_min(program.direct_mem(SBIT), "memory");
|
||||
MC.resize_min(program.direct_mem(CBIT), "memory");
|
||||
MI.resize_min(program.direct_mem(INT), "memory");
|
||||
Memories<T>::reset(program);
|
||||
MI.resize_min(*program.direct_mem(INT), "memory");
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -66,7 +76,7 @@ template <class U, class V>
|
||||
void Machine<T>::reset(const U& program, V& MD)
|
||||
{
|
||||
reset(program);
|
||||
MD.resize_min(program.direct_mem(DYN_SBIT), "dynamic memory");
|
||||
MD.resize_min(*program.direct_mem(DYN_SBIT), "dynamic memory");
|
||||
#ifdef DEBUG_MEMORY
|
||||
cerr << "reset dynamic mem to " << program.direct_mem(DYN_SBIT) << endl;
|
||||
#endif
|
||||
@@ -85,12 +95,14 @@ void Machine<T>::join_tape(int thread_number)
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void GC::Machine<T>::write_memory(int my_num)
|
||||
void Memories<T>::write_memory(int my_num)
|
||||
{
|
||||
ofstream outf(memory_filename("B", my_num));
|
||||
ofstream outf(BaseMachine::memory_filename("B", my_num));
|
||||
outf << 0 << endl;
|
||||
outf << MC.size() << endl << MC;
|
||||
outf << 0 << endl << 0 << endl << 0 << endl << 0 << endl;
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "ShareSecret.h"
|
||||
#include "Machine.h"
|
||||
#include "ThreadMaster.h"
|
||||
#include "Protocols/Beaver.h"
|
||||
#include "Protocols/MaliciousRepMC.h"
|
||||
#include "Processor/DummyProtocol.h"
|
||||
@@ -34,12 +35,19 @@ public:
|
||||
typedef ReplicatedInput<MaliciousRepSecret> Input;
|
||||
typedef RepPrep<MaliciousRepSecret> LivePrep;
|
||||
|
||||
static MC* new_mc(Machine<MaliciousRepSecret>& machine)
|
||||
typedef MaliciousRepSecret part_type;
|
||||
|
||||
static MC* new_mc(mac_key_type)
|
||||
{
|
||||
if (machine.more_comm_less_comp)
|
||||
return new CommMaliciousRepMC<MaliciousRepSecret>;
|
||||
else
|
||||
return new HashMaliciousRepMC<MaliciousRepSecret>;
|
||||
try
|
||||
{
|
||||
if (ThreadMaster<MaliciousRepSecret>::s().machine.more_comm_less_comp)
|
||||
return new CommMaliciousRepMC<MaliciousRepSecret>;
|
||||
}
|
||||
catch(no_singleton& e)
|
||||
{
|
||||
}
|
||||
return new HashMaliciousRepMC<MaliciousRepSecret>;
|
||||
}
|
||||
|
||||
static MaliciousRepSecret constant(const BitVec& other, int my_num, const BitVec& alphai)
|
||||
|
||||
122
GC/NoShare.h
Normal file
122
GC/NoShare.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* NoShare.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_NOSHARE_H_
|
||||
#define GC_NOSHARE_H_
|
||||
|
||||
#include "BMR/Register.h"
|
||||
#include "Processor/DummyProtocol.h"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
class NoValue
|
||||
{
|
||||
public:
|
||||
const static int n_bits = 0;
|
||||
|
||||
static bool allows(Dtype)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static int size()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fail()
|
||||
{
|
||||
throw runtime_error("VM does not support binary circuits");
|
||||
}
|
||||
|
||||
void assign(const char*) { fail(); }
|
||||
|
||||
int get() const { fail(); return 0; }
|
||||
};
|
||||
|
||||
class NoShare : public Phase
|
||||
{
|
||||
public:
|
||||
typedef DummyMC<NoShare> MC;
|
||||
typedef DummyProtocol Protocol;
|
||||
typedef NotImplementedInput<NoShare> Input;
|
||||
typedef DummyLivePrep<NoShare> LivePrep;
|
||||
typedef DummyMC<NoShare> MAC_Check;
|
||||
|
||||
typedef NoValue open_type;
|
||||
typedef NoValue clear;
|
||||
typedef NoValue mac_key_type;
|
||||
|
||||
typedef NoShare bit_type;
|
||||
typedef NoShare part_type;
|
||||
|
||||
static const bool needs_ot = false;
|
||||
|
||||
static MC* new_mc(mac_key_type)
|
||||
{
|
||||
return new MC;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void generate_mac_key(mac_key_type, T)
|
||||
{
|
||||
}
|
||||
|
||||
static DataFieldType field_type()
|
||||
{
|
||||
throw not_implemented();
|
||||
}
|
||||
|
||||
static string type_short()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
static string type_string()
|
||||
{
|
||||
return "no";
|
||||
}
|
||||
|
||||
static int size()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fail()
|
||||
{
|
||||
NoValue::fail();
|
||||
}
|
||||
|
||||
static void inputb(Processor<NoShare>&, const vector<int>&) { fail(); }
|
||||
|
||||
static void input(Processor<NoShare>&, InputArgs&) { fail(); }
|
||||
static void trans(Processor<NoShare>&, Integer, const vector<int>&) { fail(); }
|
||||
|
||||
NoShare() {}
|
||||
|
||||
NoShare(int) { fail(); }
|
||||
|
||||
void load_clear(Integer, Integer) { fail(); }
|
||||
void random_bit() { fail(); }
|
||||
void and_(int, NoShare&, NoShare&, bool) { fail(); }
|
||||
void xor_(int, NoShare&, NoShare&) { fail(); }
|
||||
void bitdec(vector<NoShare>&, const vector<int>&) const { fail(); }
|
||||
void bitcom(vector<NoShare>&, const vector<int>&) const { fail(); }
|
||||
void reveal(Integer, Integer) { fail(); }
|
||||
|
||||
void assign(const char*) { fail(); }
|
||||
|
||||
NoShare operator&(const Clear&) const { fail(); return {}; }
|
||||
|
||||
NoShare operator<<(int) const { fail(); return {}; }
|
||||
void operator^=(NoShare) { fail(); }
|
||||
|
||||
NoShare operator+(const NoShare&) const { fail(); return {}; }
|
||||
};
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif /* GC_NOSHARE_H_ */
|
||||
@@ -39,7 +39,8 @@ public:
|
||||
|
||||
static void check_input(bigint in, int n_bits);
|
||||
|
||||
Machine<T>& machine;
|
||||
Machine<T>* machine;
|
||||
Memories<T>& memories;
|
||||
|
||||
unsigned int PC;
|
||||
unsigned int time;
|
||||
@@ -54,6 +55,7 @@ public:
|
||||
ExecutionStats stats;
|
||||
|
||||
Processor(Machine<T>& machine);
|
||||
Processor(Memories<T>& memories, Machine<T>* machine = 0);
|
||||
~Processor();
|
||||
|
||||
template<class U>
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_PROCESSOR_HPP_
|
||||
#define GC_PROCESSOR_HPP_
|
||||
|
||||
#include <GC/Processor.h>
|
||||
|
||||
#include <iostream>
|
||||
@@ -13,6 +16,7 @@ using namespace std;
|
||||
#include "Access.h"
|
||||
#include "Processor/FixInput.h"
|
||||
|
||||
#include "GC/Machine.hpp"
|
||||
#include "Processor/ProcessorBase.hpp"
|
||||
|
||||
namespace GC
|
||||
@@ -20,7 +24,13 @@ namespace GC
|
||||
|
||||
template <class T>
|
||||
Processor<T>::Processor(Machine<T>& machine) :
|
||||
machine(machine), PC(0), time(0),
|
||||
Processor<T>(machine, &machine)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Processor<T>::Processor(Memories<T>& memories, Machine<T>* machine) :
|
||||
machine(machine), memories(memories), PC(0), time(0),
|
||||
complexity(0)
|
||||
{
|
||||
}
|
||||
@@ -49,7 +59,9 @@ template <class U>
|
||||
void Processor<T>::reset(const U& program)
|
||||
{
|
||||
reset(program, 0);
|
||||
machine.reset(program);
|
||||
if (machine)
|
||||
machine->reset(program);
|
||||
memories.reset(program);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -248,3 +260,5 @@ void Processor<T>::print_float_prec(int n)
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define GC_PROGRAM_H_
|
||||
|
||||
#include "GC/Instruction.h"
|
||||
#include "Processor/Program.h"
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
@@ -26,7 +27,7 @@ template <class T> class Processor;
|
||||
template <class T>
|
||||
class Program
|
||||
{
|
||||
vector< Instruction<T> > p;
|
||||
vector<Instruction> p;
|
||||
int offline_data_used;
|
||||
|
||||
// Maximal register used
|
||||
@@ -57,8 +58,8 @@ class Program
|
||||
unsigned num_reg(RegType reg_type) const
|
||||
{ return max_reg[reg_type]; }
|
||||
|
||||
unsigned direct_mem(RegType reg_type) const
|
||||
{ return max_mem[reg_type]; }
|
||||
const unsigned* direct_mem(RegType reg_type) const
|
||||
{ return &max_mem[reg_type]; }
|
||||
|
||||
template<class U>
|
||||
BreakType execute(Processor<T>& Proc, U& dynamic_memory, int PC = -1) const;
|
||||
|
||||
@@ -61,7 +61,7 @@ template <class T>
|
||||
void Program<T>::parse(istream& s)
|
||||
{
|
||||
p.resize(0);
|
||||
Instruction<T> instr;
|
||||
Instruction instr;
|
||||
s.peek();
|
||||
int pos = 0;
|
||||
CALLGRIND_STOP_INSTRUMENTATION;
|
||||
|
||||
@@ -13,13 +13,16 @@
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T> class ShareThread;
|
||||
|
||||
template<class T>
|
||||
class RepPrep : public BufferPrep<T>, ShiftableTripleBuffer<T>
|
||||
{
|
||||
ReplicatedBase* protocol;
|
||||
|
||||
public:
|
||||
RepPrep(DataPositions& usage, Thread<T>& thread);
|
||||
RepPrep(DataPositions& usage, ShareThread<T>& thread);
|
||||
RepPrep(DataPositions& usage);
|
||||
~RepPrep();
|
||||
|
||||
void set_protocol(typename T::Protocol& protocol);
|
||||
|
||||
@@ -16,12 +16,18 @@ namespace GC
|
||||
{
|
||||
|
||||
template<class T>
|
||||
RepPrep<T>::RepPrep(DataPositions& usage, Thread<T>& thread) :
|
||||
BufferPrep<T>(usage), protocol(0)
|
||||
RepPrep<T>::RepPrep(DataPositions& usage, ShareThread<T>& thread) :
|
||||
RepPrep<T>(usage)
|
||||
{
|
||||
(void) thread;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
RepPrep<T>::RepPrep(DataPositions& usage) :
|
||||
BufferPrep<T>(usage), protocol(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
RepPrep<T>::~RepPrep()
|
||||
{
|
||||
@@ -39,7 +45,7 @@ template<class T>
|
||||
void RepPrep<T>::buffer_triples()
|
||||
{
|
||||
assert(protocol != 0);
|
||||
auto MC = ShareThread<T>::s().new_mc();
|
||||
auto MC = ShareThread<T>::s().new_mc({});
|
||||
shuffle_triple_generation(this->triples, protocol->P, *MC, 64);
|
||||
delete MC;
|
||||
}
|
||||
|
||||
@@ -70,11 +70,7 @@ class Secret
|
||||
public:
|
||||
typedef typename T::DynamicMemory DynamicMemory;
|
||||
|
||||
// dummy
|
||||
typedef DummyMC MC;
|
||||
typedef DummyProtocol Protocol;
|
||||
|
||||
static MC* new_mc(Machine<Secret>& _) { (void) _; return new MC; }
|
||||
typedef NoShare bit_type;
|
||||
|
||||
static string type_string() { return "evaluation secret"; }
|
||||
static string phase_name() { return T::name(); }
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_SECRET_HPP_
|
||||
#define GC_SECRET_HPP_
|
||||
|
||||
#include "Secret.h"
|
||||
#include "Secret_inline.h"
|
||||
|
||||
@@ -336,3 +339,5 @@ void Secret<T>::reveal(size_t n_bits, U& x)
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,8 +15,12 @@ namespace GC
|
||||
class SemiHonestRepPrep : public RepPrep<SemiHonestRepSecret>
|
||||
{
|
||||
public:
|
||||
SemiHonestRepPrep(DataPositions& usage, Thread<SemiHonestRepSecret>& thread) :
|
||||
RepPrep<SemiHonestRepSecret>(usage, thread)
|
||||
SemiHonestRepPrep(DataPositions& usage, ShareThread<SemiHonestRepSecret>&) :
|
||||
RepPrep<SemiHonestRepSecret>(usage)
|
||||
{
|
||||
}
|
||||
SemiHonestRepPrep(DataPositions& usage) :
|
||||
RepPrep<SemiHonestRepSecret>(usage)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,13 @@
|
||||
namespace GC
|
||||
{
|
||||
|
||||
SemiPrep::SemiPrep(DataPositions& usage, Thread<SemiSecret>& thread) :
|
||||
BufferPrep<SemiSecret>(usage), thread(thread), triple_generator(0)
|
||||
SemiPrep::SemiPrep(DataPositions& usage, ShareThread<SemiSecret>&) :
|
||||
SemiPrep(usage)
|
||||
{
|
||||
}
|
||||
|
||||
SemiPrep::SemiPrep(DataPositions& usage) :
|
||||
BufferPrep<SemiSecret>(usage), triple_generator(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,9 +30,9 @@ void SemiPrep::set_protocol(Beaver<SemiSecret>& protocol)
|
||||
(void) protocol;
|
||||
params.set_passive();
|
||||
triple_generator = new SemiSecret::TripleGenerator(
|
||||
thread.processor.machine.ot_setups.at(thread.thread_num).get_fresh(),
|
||||
thread.master.N, thread.thread_num, thread.master.opts.batch_size,
|
||||
1, params, {}, thread.P);
|
||||
BaseMachine::s().fresh_ot_setup(),
|
||||
protocol.P.N, -1, OnlineOptions::singleton.batch_size,
|
||||
1, params, {}, &protocol.P);
|
||||
triple_generator->multi_threaded = false;
|
||||
}
|
||||
|
||||
@@ -50,6 +55,7 @@ SemiPrep::~SemiPrep()
|
||||
|
||||
void SemiPrep::buffer_bits()
|
||||
{
|
||||
auto& thread = Thread<SemiSecret>::s();
|
||||
word r = thread.secure_prng.get_word();
|
||||
for (size_t i = 0; i < sizeof(word) * 8; i++)
|
||||
this->bits.push_back((r >> i) & 1);
|
||||
|
||||
@@ -16,15 +16,16 @@ template<class T> class Beaver;
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T> class ShareThread;
|
||||
|
||||
class SemiPrep : public BufferPrep<SemiSecret>, ShiftableTripleBuffer<SemiSecret>
|
||||
{
|
||||
Thread<SemiSecret>& thread;
|
||||
|
||||
SemiSecret::TripleGenerator* triple_generator;
|
||||
MascotParams params;
|
||||
|
||||
public:
|
||||
SemiPrep(DataPositions& usage, Thread<SemiSecret>& thread);
|
||||
SemiPrep(DataPositions& usage, ShareThread<SemiSecret>& thread);
|
||||
SemiPrep(DataPositions& usage);
|
||||
~SemiPrep();
|
||||
|
||||
void set_protocol(Beaver<SemiSecret>& protocol);
|
||||
|
||||
@@ -26,7 +26,7 @@ void SemiSecret::trans(Processor<SemiSecret>& processor, int n_outputs,
|
||||
void SemiSecret::load_clear(int n, const Integer& x)
|
||||
{
|
||||
check_length(n, x);
|
||||
*this = constant(x, Thread<SemiSecret>::s().P->my_num());
|
||||
*this = constant(x, ShareThread<SemiSecret>::s().P->my_num());
|
||||
}
|
||||
|
||||
void SemiSecret::bitcom(Memory<SemiSecret>& S, const vector<int>& regs)
|
||||
@@ -45,7 +45,7 @@ void SemiSecret::bitdec(Memory<SemiSecret>& S,
|
||||
|
||||
void SemiSecret::reveal(size_t n_bits, Clear& x)
|
||||
{
|
||||
auto& thread = Thread<SemiSecret>::s();
|
||||
auto& thread = ShareThread<SemiSecret>::s();
|
||||
x = thread.MC->POpen(*this, *thread.P).mask(n_bits);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,12 +29,19 @@ public:
|
||||
typedef SemiPrep LivePrep;
|
||||
typedef SemiInput<SemiSecret> Input;
|
||||
|
||||
typedef SemiSecret part_type;
|
||||
|
||||
static const int default_length = sizeof(BitVec) * 8;
|
||||
|
||||
static string type_string() { return "binary secret"; }
|
||||
static string phase_name() { return "Binary computation"; }
|
||||
|
||||
static MC* new_mc(Machine<SemiSecret>& _) { (void) _; return new MC; }
|
||||
static MC* new_mc(mac_key_type) { return new MC; }
|
||||
|
||||
template<class T>
|
||||
static void generate_mac_key(mac_key_type, T)
|
||||
{
|
||||
}
|
||||
|
||||
static void trans(Processor<SemiSecret>& processor, int n_outputs,
|
||||
const vector<int>& args);
|
||||
@@ -50,6 +57,11 @@ public:
|
||||
SemiShare<BitVec>(other)
|
||||
{
|
||||
}
|
||||
template<int K>
|
||||
SemiSecret(const Z2<K>& other) :
|
||||
SemiShare<BitVec>(other)
|
||||
{
|
||||
}
|
||||
|
||||
void load_clear(int n, const Integer& x);
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ ShareParty<T>::ShareParty(int argc, const char** argv, int default_batch_size) :
|
||||
"--communication" // Flag token.
|
||||
);
|
||||
online_opts.finalize(opt, argc, argv);
|
||||
OnlineOptions::singleton = online_opts;
|
||||
this->progname = online_opts.progname;
|
||||
int my_num = online_opts.playerno;
|
||||
|
||||
@@ -122,7 +123,7 @@ ShareParty<T>::ShareParty(int argc, const char** argv, int default_batch_size) :
|
||||
template<class T>
|
||||
Thread<T>* ShareParty<T>::new_thread(int i)
|
||||
{
|
||||
return new ShareThread<T>(i, *this);
|
||||
return new StandaloneShareThread<T>(i, *this);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -130,7 +131,7 @@ void ShareParty<T>::post_run()
|
||||
{
|
||||
DataPositions usage;
|
||||
for (auto thread : this->threads)
|
||||
usage.increase(dynamic_cast<ShareThread<T>*>(thread)->usage);
|
||||
usage.increase(dynamic_cast<StandaloneShareThread<T>*>(thread)->usage);
|
||||
usage.print_cost();
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ using namespace std;
|
||||
#include "GC/Clear.h"
|
||||
#include "GC/Access.h"
|
||||
#include "GC/ArgTuples.h"
|
||||
#include "GC/NoShare.h"
|
||||
#include "Math/FixedVec.h"
|
||||
#include "Math/BitVec.h"
|
||||
#include "Tools/SwitchableOutput.h"
|
||||
@@ -73,6 +74,8 @@ public:
|
||||
|
||||
typedef ReplicatedBase Protocol;
|
||||
|
||||
typedef NoShare bit_type;
|
||||
|
||||
static const int N_BITS = clear::N_BITS;
|
||||
|
||||
static const bool dishonest_majority = false;
|
||||
@@ -83,9 +86,19 @@ public:
|
||||
|
||||
static int default_length;
|
||||
|
||||
static int threshold(int)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void trans(Processor<U>& processor, int n_outputs,
|
||||
const vector<int>& args);
|
||||
|
||||
template<class T>
|
||||
static void generate_mac_key(mac_key_type, T)
|
||||
{
|
||||
}
|
||||
|
||||
ReplicatedSecret() {}
|
||||
template <class T>
|
||||
ReplicatedSecret(const T& other) : super(other) {}
|
||||
@@ -101,6 +114,9 @@ public:
|
||||
{ *this = x ^ y; (void)n; }
|
||||
|
||||
void reveal(size_t n_bits, Clear& x);
|
||||
|
||||
ReplicatedSecret operator&(const Clear& other)
|
||||
{ return super::operator&(BitVec(other)); }
|
||||
};
|
||||
|
||||
class SemiHonestRepPrep;
|
||||
@@ -118,7 +134,9 @@ public:
|
||||
typedef SemiHonestRepPrep LivePrep;
|
||||
typedef ReplicatedInput<SemiHonestRepSecret> Input;
|
||||
|
||||
static MC* new_mc(Machine<SemiHonestRepSecret>& _) { (void) _; return new MC; }
|
||||
typedef SemiHonestRepSecret part_type;
|
||||
|
||||
static MC* new_mc(mac_key_type) { return new MC; }
|
||||
|
||||
SemiHonestRepSecret() {}
|
||||
template<class T>
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_SHARESECRET_HPP
|
||||
#define GC_SHARESECRET_HPP
|
||||
|
||||
#include "ShareSecret.h"
|
||||
|
||||
#include "MaliciousRepSecret.h"
|
||||
@@ -17,6 +20,7 @@
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "ShareParty.h"
|
||||
#include "ShareThread.hpp"
|
||||
#include "Thread.hpp"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
@@ -30,8 +34,11 @@ SwitchableOutput ShareSecret<U>::out;
|
||||
template<class U>
|
||||
void ShareSecret<U>::check_length(int n, const Integer& x)
|
||||
{
|
||||
if ((size_t)n < 8 * sizeof(x) and abs(x.get()) >= (1LL << n))
|
||||
throw out_of_range("public value too long");
|
||||
if ((size_t) n < 8 * sizeof(x)
|
||||
and (unsigned long long) abs(x.get()) >= (1ULL << n))
|
||||
throw out_of_range(
|
||||
"public value too long for " + to_string(n) + " bits: "
|
||||
+ to_string(x.get()) + "/" + to_string(1ULL << n));
|
||||
}
|
||||
|
||||
template<class U>
|
||||
@@ -89,7 +96,7 @@ void ShareSecret<U>::inputb(Processor<U>& processor,
|
||||
input.reset_all(*party.P);
|
||||
|
||||
InputArgList a(args);
|
||||
bool interactive = party.n_interactive_inputs_from_me(a) > 0;
|
||||
bool interactive = Thread<U>::s().n_interactive_inputs_from_me(a) > 0;
|
||||
|
||||
for (auto x : a)
|
||||
{
|
||||
@@ -153,7 +160,7 @@ void ReplicatedSecret<U>::reveal(size_t n_bits, Clear& x)
|
||||
vector<BitVec> opened;
|
||||
auto& party = ShareThread<U>::s();
|
||||
party.MC->POpen(opened, {share}, *party.P);
|
||||
x = IntBase(opened[0]);
|
||||
x = BitVec::super(opened[0]);
|
||||
}
|
||||
|
||||
template<class U>
|
||||
@@ -165,3 +172,5 @@ void ShareSecret<U>::random_bit()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,25 +19,42 @@ namespace GC
|
||||
{
|
||||
|
||||
template<class T>
|
||||
class ShareThread : public Thread<T>
|
||||
class ShareThread
|
||||
{
|
||||
static thread_local ShareThread<T>* singleton;
|
||||
|
||||
public:
|
||||
static ShareThread& s();
|
||||
|
||||
Player* P;
|
||||
typename T::MC* MC;
|
||||
typename T::Protocol* protocol;
|
||||
|
||||
DataPositions usage;
|
||||
Preprocessing<T>& DataF;
|
||||
|
||||
ShareThread(int i, ThreadMaster<T>& master);
|
||||
ShareThread(const Names& N, OnlineOptions& opts);
|
||||
virtual ~ShareThread();
|
||||
|
||||
void pre_run();
|
||||
virtual typename T::MC* new_mc(typename T::mac_key_type mac_key)
|
||||
{ return T::new_mc(mac_key); }
|
||||
|
||||
void pre_run(Player& P, typename T::mac_key_type mac_key);
|
||||
void post_run();
|
||||
|
||||
void and_(Processor<T>& processor, const vector<int>& args, bool repeat);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class StandaloneShareThread : public ShareThread<T>, public Thread<T>
|
||||
{
|
||||
public:
|
||||
StandaloneShareThread(int i, ThreadMaster<T>& master);
|
||||
|
||||
void pre_run();
|
||||
void post_run() { ShareThread<T>::post_run(); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
thread_local ShareThread<T>* ShareThread<T>::singleton = 0;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define GC_SHARETHREAD_HPP_
|
||||
|
||||
#include <GC/ShareThread.h>
|
||||
#include "GC/ShareParty.h"
|
||||
#include "Protocols/MaliciousRepMC.h"
|
||||
#include "Math/Setup.h"
|
||||
|
||||
@@ -16,15 +17,19 @@ namespace GC
|
||||
{
|
||||
|
||||
template<class T>
|
||||
ShareThread<T>::ShareThread(int i,
|
||||
ThreadMaster<T>& master) :
|
||||
Thread<T>(i, master), usage(master.N.num_players()), DataF(
|
||||
master.opts.live_prep ?
|
||||
*(Preprocessing<T>*) new typename T::LivePrep(usage,
|
||||
*this) :
|
||||
*(Preprocessing<T>*) new Sub_Data_Files<T>(master.N,
|
||||
get_prep_dir(master.N.num_players(), 128, 128),
|
||||
usage))
|
||||
StandaloneShareThread<T>::StandaloneShareThread(int i, ThreadMaster<T>& master) :
|
||||
ShareThread<T>(master.N, master.opts), Thread<T>(i, master)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ShareThread<T>::ShareThread(const Names& N, OnlineOptions& opts) :
|
||||
P(0), MC(0), protocol(0), usage(N.num_players()), DataF(
|
||||
opts.live_prep ?
|
||||
*static_cast<Preprocessing<T>*>(new typename T::LivePrep(
|
||||
usage, *this)) :
|
||||
*static_cast<Preprocessing<T>*>(new Sub_Data_Files<T>(N,
|
||||
get_prep_dir(N.num_players(), 128, 128), usage)))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -32,21 +37,34 @@ template<class T>
|
||||
ShareThread<T>::~ShareThread()
|
||||
{
|
||||
delete &DataF;
|
||||
if (MC)
|
||||
delete MC;
|
||||
if (protocol)
|
||||
delete protocol;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ShareThread<T>::pre_run()
|
||||
void ShareThread<T>::pre_run(Player& P, typename T::mac_key_type mac_key)
|
||||
{
|
||||
this->P = &P;
|
||||
if (singleton)
|
||||
throw runtime_error("there can only be one");
|
||||
singleton = this;
|
||||
assert(this->protocol != 0);
|
||||
protocol = new typename T::Protocol(*this->P);
|
||||
MC = this->new_mc(mac_key);
|
||||
DataF.set_protocol(*this->protocol);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void StandaloneShareThread<T>::pre_run()
|
||||
{
|
||||
ShareThread<T>::pre_run(*Thread<T>::P, ShareParty<T>::s().mac_key);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ShareThread<T>::post_run()
|
||||
{
|
||||
MC->Check(*this->P);
|
||||
#ifndef INSECURE
|
||||
cerr << "Removing used pre-processed data" << endl;
|
||||
DataF.prune();
|
||||
|
||||
@@ -34,8 +34,6 @@ public:
|
||||
ThreadMaster<T>& master;
|
||||
Machine<T>& machine;
|
||||
Processor<T> processor;
|
||||
typename T::MC* MC;
|
||||
typename T::Protocol* protocol;
|
||||
Names& N;
|
||||
Player* P;
|
||||
PRNG secure_prng;
|
||||
@@ -50,8 +48,6 @@ public:
|
||||
Thread(int thread_num, ThreadMaster<T>& master);
|
||||
virtual ~Thread();
|
||||
|
||||
virtual typename T::MC* new_mc() { return T::new_mc(machine); }
|
||||
|
||||
void run();
|
||||
virtual void pre_run() {}
|
||||
virtual void run(Program<T>& program);
|
||||
@@ -72,7 +68,8 @@ Thread<T>& Thread<T>::s()
|
||||
if (singleton)
|
||||
return *singleton;
|
||||
else
|
||||
throw runtime_error("no singleton");
|
||||
throw runtime_error(
|
||||
"no singleton / not implemented with arithmetic VMs");
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_THREAD_HPP_
|
||||
#define GC_THREAD_HPP_
|
||||
|
||||
#include "Thread.h"
|
||||
#include "Program.h"
|
||||
|
||||
@@ -24,7 +27,7 @@ void* Thread<T>::run_thread(void* thread)
|
||||
template<class T>
|
||||
Thread<T>::Thread(int thread_num, ThreadMaster<T>& master) :
|
||||
master(master), machine(master.machine), processor(machine),
|
||||
protocol(0), N(master.N), P(0),
|
||||
N(master.N), P(0),
|
||||
thread_num(thread_num)
|
||||
{
|
||||
pthread_create(&thread, 0, run_thread, this);
|
||||
@@ -33,12 +36,8 @@ Thread<T>::Thread(int thread_num, ThreadMaster<T>& master) :
|
||||
template<class T>
|
||||
Thread<T>::~Thread()
|
||||
{
|
||||
if (MC)
|
||||
delete MC;
|
||||
if (P)
|
||||
delete P;
|
||||
if (protocol)
|
||||
delete protocol;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -47,13 +46,12 @@ void Thread<T>::run()
|
||||
if (singleton)
|
||||
throw runtime_error("there can only be one");
|
||||
singleton = this;
|
||||
BaseMachine::s().thread_num = thread_num;
|
||||
secure_prng.ReSeed();
|
||||
if (machine.use_encryption)
|
||||
P = new CryptoPlayer(N, thread_num << 16);
|
||||
else
|
||||
P = new PlainPlayer(N, thread_num << 16);
|
||||
protocol = new typename T::Protocol(*P);
|
||||
MC = this->new_mc();
|
||||
processor.open_input_file(N.my_num(), thread_num);
|
||||
done.push(0);
|
||||
pre_run();
|
||||
@@ -67,7 +65,6 @@ void Thread<T>::run()
|
||||
}
|
||||
|
||||
post_run();
|
||||
MC->Check(*P);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -104,3 +101,5 @@ int GC::Thread<T>::n_interactive_inputs_from_me(InputArgList& args)
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_THREADMASTER_HPP_
|
||||
#define GC_THREADMASTER_HPP_
|
||||
|
||||
#include "ThreadMaster.h"
|
||||
#include "Program.h"
|
||||
|
||||
@@ -20,7 +23,7 @@ ThreadMaster<T>& ThreadMaster<T>::s()
|
||||
if (singleton)
|
||||
return *singleton;
|
||||
else
|
||||
throw runtime_error("no singleton, maybe threads not supported");
|
||||
throw no_singleton("no singleton, maybe threads not supported");
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -107,3 +110,5 @@ void ThreadMaster<T>::run()
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif
|
||||
|
||||
31
GC/TinierPrep.h
Normal file
31
GC/TinierPrep.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* TinierPrep.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_TINIERPREP_H_
|
||||
#define GC_TINIERPREP_H_
|
||||
|
||||
#include "TinyPrep.h"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T>
|
||||
class TinierPrep : public TinyPrep<T>
|
||||
{
|
||||
public:
|
||||
TinierPrep(DataPositions& usage, ShareThread<T>& thread) :
|
||||
TinyPrep<T>(usage, thread)
|
||||
{
|
||||
}
|
||||
|
||||
void buffer_inputs(int player)
|
||||
{
|
||||
this->buffer_inputs_(player, this->triple_generator);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* GC_TINIERPREP_H_ */
|
||||
95
GC/TinierSecret.h
Normal file
95
GC/TinierSecret.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* TinierSecret.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_TINIERSECRET_H_
|
||||
#define GC_TINIERSECRET_H_
|
||||
|
||||
#include "TinySecret.h"
|
||||
#include "TinierShare.h"
|
||||
|
||||
template<class T> class TinierMultiplier;
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T> class TinierPrep;
|
||||
|
||||
template<class T>
|
||||
class TinierSecret : public VectorSecret<TinierShare<T>>
|
||||
{
|
||||
typedef VectorSecret<TinierShare<T>> super;
|
||||
typedef TinierSecret This;
|
||||
|
||||
public:
|
||||
typedef TinyMC<This> MC;
|
||||
typedef MC MAC_Check;
|
||||
typedef Beaver<This> Protocol;
|
||||
typedef ::Input<This> Input;
|
||||
typedef TinierPrep<This> LivePrep;
|
||||
typedef Memory<This> DynamicMemory;
|
||||
|
||||
typedef NPartyTripleGenerator<This> TripleGenerator;
|
||||
typedef NPartyTripleGenerator<This> InputGenerator;
|
||||
typedef TinierMultiplier<This> Multiplier;
|
||||
|
||||
typedef typename super::part_type check_type;
|
||||
typedef Share<T> input_check_type;
|
||||
typedef check_type input_type;
|
||||
|
||||
static string type_short()
|
||||
{
|
||||
return "TT";
|
||||
}
|
||||
|
||||
static MC* new_mc(typename super::mac_key_type mac_key)
|
||||
{
|
||||
return new MC(mac_key);
|
||||
}
|
||||
|
||||
template<class U>
|
||||
static void generate_mac_key(typename super::mac_key_type& dest, const U&)
|
||||
{
|
||||
SeededPRNG G;
|
||||
dest.randomize(G);
|
||||
}
|
||||
|
||||
static void store_clear_in_dynamic(Memory<This>& mem,
|
||||
const vector<ClearWriteAccess>& accesses)
|
||||
{
|
||||
auto& party = ShareThread<This>::s();
|
||||
for (auto access : accesses)
|
||||
mem[access.address] = super::constant(access.value,
|
||||
party.P->my_num(), {});
|
||||
}
|
||||
|
||||
|
||||
TinierSecret()
|
||||
{
|
||||
}
|
||||
TinierSecret(const super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
TinierSecret(const typename super::super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
TinierSecret(const typename super::part_type& other)
|
||||
{
|
||||
this->get_regs().push_back(other);
|
||||
}
|
||||
|
||||
void reveal(size_t n_bits, Clear& x)
|
||||
{
|
||||
auto& to_open = *this;
|
||||
to_open.resize_regs(n_bits);
|
||||
auto& party = ShareThread<This>::s();
|
||||
x = party.MC->POpen(to_open, *party.P);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif /* GC_TINIERSECRET_H_ */
|
||||
107
GC/TinierShare.h
Normal file
107
GC/TinierShare.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* TinierShare.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_TINIERSHARE_H_
|
||||
#define GC_TINIERSHARE_H_
|
||||
|
||||
#include "Processor/DummyProtocol.h"
|
||||
#include "Protocols/Share.h"
|
||||
#include "Math/Bit.h"
|
||||
#include "TinierSharePrep.h"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T> class TinierSecret;
|
||||
|
||||
template<class T>
|
||||
class TinierShare: public Share_<SemiShare<Bit>, SemiShare<T>>,
|
||||
public ShareSecret<TinierSecret<T>>
|
||||
{
|
||||
typedef TinierShare This;
|
||||
|
||||
public:
|
||||
typedef Share_<SemiShare<Bit>, SemiShare<T>> super;
|
||||
|
||||
typedef T mac_key_type;
|
||||
typedef T mac_type;
|
||||
typedef T sacri_type;
|
||||
typedef Share<T> input_check_type;
|
||||
|
||||
typedef MAC_Check_<This> MAC_Check;
|
||||
typedef TinierSharePrep<This> LivePrep;
|
||||
typedef ::Input<This> Input;
|
||||
typedef Beaver<This> Protocol;
|
||||
typedef NPartyTripleGenerator<TinierSecret<T>> TripleGenerator;
|
||||
|
||||
typedef void DynamicMemory;
|
||||
typedef SwitchableOutput out_type;
|
||||
|
||||
static string name()
|
||||
{
|
||||
return "tinier share";
|
||||
}
|
||||
|
||||
static string type_string()
|
||||
{
|
||||
return "Tinier";
|
||||
}
|
||||
|
||||
static ShareThread<TinierSecret<T>>& get_party()
|
||||
{
|
||||
return ShareThread<TinierSecret<T>>::s();
|
||||
}
|
||||
|
||||
static MAC_Check* new_mc(mac_key_type mac_key)
|
||||
{
|
||||
return new MAC_Check(mac_key);
|
||||
}
|
||||
|
||||
static This new_reg()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
TinierShare()
|
||||
{
|
||||
}
|
||||
TinierShare(const super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
TinierShare(const typename super::share_type& share, const typename super::mac_type& mac) :
|
||||
super(share, mac)
|
||||
{
|
||||
}
|
||||
|
||||
void XOR(const This& a, const This& b)
|
||||
{
|
||||
*this = a + b;
|
||||
}
|
||||
|
||||
This& operator^=(const This& other)
|
||||
{
|
||||
*this += other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void public_input(bool input)
|
||||
{
|
||||
auto& party = get_party();
|
||||
*this = super::constant(input, party.P->my_num(),
|
||||
party.MC->get_alphai());
|
||||
}
|
||||
|
||||
void random()
|
||||
{
|
||||
TinierSecret<T> tmp;
|
||||
get_party().DataF.get_one(DATA_BIT, tmp);
|
||||
*this = tmp.get_reg(0);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif /* GC_TINIERSHARE_H_ */
|
||||
40
GC/TinierSharePrep.h
Normal file
40
GC/TinierSharePrep.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* TinierSharePrep.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_TINIERSHAREPREP_H_
|
||||
#define GC_TINIERSHAREPREP_H_
|
||||
|
||||
#include "Protocols/ReplicatedPrep.h"
|
||||
#include "OT/NPartyTripleGenerator.h"
|
||||
#include "ShareThread.h"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T>
|
||||
class TinierSharePrep : public BufferPrep<T>
|
||||
{
|
||||
typename T::TripleGenerator* triple_generator;
|
||||
MascotParams params;
|
||||
|
||||
void buffer_triples() { throw not_implemented(); }
|
||||
void buffer_squares() { throw not_implemented(); }
|
||||
void buffer_bits() { throw not_implemented(); }
|
||||
void buffer_inverses() { throw not_implemented(); }
|
||||
|
||||
void buffer_inputs(int player);
|
||||
|
||||
public:
|
||||
TinierSharePrep(DataPositions& usage);
|
||||
~TinierSharePrep();
|
||||
|
||||
void set_protocol(typename T::Protocol& protocol);
|
||||
|
||||
size_t data_sent();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* GC_TINIERSHAREPREP_H_ */
|
||||
59
GC/TinierSharePrep.hpp
Normal file
59
GC/TinierSharePrep.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* TinierSharePrep.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "TinierSharePrep.h"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T>
|
||||
TinierSharePrep<T>::TinierSharePrep(DataPositions& usage) :
|
||||
BufferPrep<T>(usage), triple_generator(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
TinierSharePrep<T>::~TinierSharePrep()
|
||||
{
|
||||
if (triple_generator)
|
||||
delete triple_generator;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void TinierSharePrep<T>::set_protocol(typename T::Protocol& protocol)
|
||||
{
|
||||
params.generateMACs = true;
|
||||
params.amplify = false;
|
||||
params.check = false;
|
||||
auto& thread = ShareThread<TinierSecret<typename T::mac_key_type>>::s();
|
||||
triple_generator = new typename T::TripleGenerator(
|
||||
BaseMachine::s().fresh_ot_setup(), protocol.P.N, -1,
|
||||
OnlineOptions::singleton.batch_size
|
||||
* TinierSecret<typename T::mac_key_type>::default_length, 1,
|
||||
params, thread.MC->get_alphai(), &protocol.P);
|
||||
triple_generator->multi_threaded = false;
|
||||
this->inputs.resize(thread.P->num_players());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void TinierSharePrep<T>::buffer_inputs(int player)
|
||||
{
|
||||
auto& inputs = this->inputs;
|
||||
assert(triple_generator);
|
||||
triple_generator->generateInputs(player);
|
||||
for (auto& x : triple_generator->inputs)
|
||||
inputs.at(player).push_back(x);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
size_t TinierSharePrep<T>::data_sent()
|
||||
{
|
||||
if (triple_generator)
|
||||
return triple_generator->data_sent();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,9 +14,9 @@ namespace GC
|
||||
template<class T>
|
||||
class TinyMC : public MAC_Check_Base<T>
|
||||
{
|
||||
typename T::part_type::MAC_Check part_MC;
|
||||
typename T::check_type::MAC_Check part_MC;
|
||||
vector<typename T::part_type::open_type> part_values;
|
||||
vector<typename T::part_type::super> part_shares;
|
||||
vector<typename T::check_type> part_shares;
|
||||
|
||||
public:
|
||||
TinyMC(typename T::mac_key_type mac_key) :
|
||||
|
||||
@@ -18,18 +18,16 @@ namespace GC
|
||||
template<class T>
|
||||
class TinyPrep : public BufferPrep<T>, public RandomPrep<typename T::part_type::super>
|
||||
{
|
||||
typedef Share<Z2<1 + T::part_type::s>> res_type;
|
||||
|
||||
Thread<T>& thread;
|
||||
protected:
|
||||
ShareThread<T>& thread;
|
||||
|
||||
typename T::TripleGenerator* triple_generator;
|
||||
typename T::part_type::TripleGenerator* input_generator;
|
||||
MascotParams params;
|
||||
|
||||
vector<array<typename T::part_type, 3>> triple_buffer;
|
||||
|
||||
public:
|
||||
TinyPrep(DataPositions& usage, Thread<T>& thread);
|
||||
TinyPrep(DataPositions& usage, ShareThread<T>& thread);
|
||||
~TinyPrep();
|
||||
|
||||
void set_protocol(Beaver<T>& protocol);
|
||||
@@ -37,14 +35,35 @@ public:
|
||||
void buffer_triples();
|
||||
void buffer_bits();
|
||||
|
||||
void buffer_inputs(int player);
|
||||
|
||||
void buffer_squares() { throw not_implemented(); }
|
||||
void buffer_inverses() { throw not_implemented(); }
|
||||
|
||||
void buffer_inputs_(int player, typename T::InputGenerator* input_generator);
|
||||
|
||||
typename T::part_type::super get_random();
|
||||
|
||||
array<T, 3> get_triple(int n_bits);
|
||||
|
||||
size_t data_sent();
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class TinyOnlyPrep : public TinyPrep<T>
|
||||
{
|
||||
typename T::part_type::TripleGenerator* input_generator;
|
||||
|
||||
public:
|
||||
TinyOnlyPrep(DataPositions& usage, ShareThread<T>& thread);
|
||||
~TinyOnlyPrep();
|
||||
|
||||
void set_protocol(Beaver<T>& protocol);
|
||||
|
||||
void buffer_inputs(int player)
|
||||
{
|
||||
this->buffer_inputs_(player, input_generator);
|
||||
}
|
||||
|
||||
size_t data_sent();
|
||||
};
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
@@ -5,13 +5,21 @@
|
||||
|
||||
#include "TinyPrep.h"
|
||||
|
||||
#include "Protocols/MascotPrep.hpp"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T>
|
||||
TinyPrep<T>::TinyPrep(DataPositions& usage, Thread<T>& thread) :
|
||||
BufferPrep<T>(usage), thread(thread), triple_generator(0),
|
||||
input_generator(0)
|
||||
TinyPrep<T>::TinyPrep(DataPositions& usage, ShareThread<T>& thread) :
|
||||
BufferPrep<T>(usage), thread(thread), triple_generator(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
TinyOnlyPrep<T>::TinyOnlyPrep(DataPositions& usage, ShareThread<T>& thread) :
|
||||
TinyPrep<T>(usage, thread), input_generator(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -20,6 +28,11 @@ TinyPrep<T>::~TinyPrep()
|
||||
{
|
||||
if (triple_generator)
|
||||
delete triple_generator;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
TinyOnlyPrep<T>::~TinyOnlyPrep()
|
||||
{
|
||||
if (input_generator)
|
||||
delete input_generator;
|
||||
}
|
||||
@@ -31,19 +44,24 @@ void TinyPrep<T>::set_protocol(Beaver<T>& protocol)
|
||||
params.generateMACs = true;
|
||||
params.amplify = false;
|
||||
params.check = false;
|
||||
auto& thread = ShareThread<T>::s();
|
||||
triple_generator = new typename T::TripleGenerator(
|
||||
thread.processor.machine.ot_setups.at(thread.thread_num).get_fresh(),
|
||||
thread.master.N, thread.thread_num,
|
||||
thread.master.opts.batch_size,
|
||||
1, params, thread.MC->get_alphai(), thread.P);
|
||||
BaseMachine::s().fresh_ot_setup(), protocol.P.N, -1,
|
||||
OnlineOptions::singleton.batch_size, 1, params,
|
||||
thread.MC->get_alphai(), &protocol.P);
|
||||
triple_generator->multi_threaded = false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void TinyOnlyPrep<T>::set_protocol(Beaver<T>& protocol)
|
||||
{
|
||||
TinyPrep<T>::set_protocol(protocol);
|
||||
input_generator = new typename T::part_type::TripleGenerator(
|
||||
thread.processor.machine.ot_setups.at(thread.thread_num).get_fresh(),
|
||||
thread.master.N, thread.thread_num,
|
||||
thread.master.opts.batch_size,
|
||||
1, params, thread.MC->get_alphai(), thread.P);
|
||||
BaseMachine::s().fresh_ot_setup(), protocol.P.N, -1,
|
||||
OnlineOptions::singleton.batch_size, 1, this->params,
|
||||
this->thread.MC->get_alphai(), &protocol.P);
|
||||
input_generator->multi_threaded = false;
|
||||
thread.MC->get_part_MC().set_prep(*this);
|
||||
this->thread.MC->get_part_MC().set_prep(*this);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -51,9 +69,9 @@ void TinyPrep<T>::buffer_triples()
|
||||
{
|
||||
auto& triple_generator = this->triple_generator;
|
||||
params.generateBits = false;
|
||||
vector<array<typename T::part_type::super, 3>> triples;
|
||||
ShuffleSacrifice<typename T::part_type::super> sacrifice;
|
||||
while (int(triples.size()) < sacrifice.minimum_n_inputs())
|
||||
vector<array<typename T::check_type, 3>> triples;
|
||||
ShuffleSacrifice<typename T::check_type> sacrifice;
|
||||
while (int(triples.size()) < sacrifice.minimum_n_inputs_with_combining())
|
||||
{
|
||||
triple_generator->generatePlainTriples();
|
||||
triple_generator->unlock();
|
||||
@@ -84,6 +102,8 @@ void TinyPrep<T>::buffer_triples()
|
||||
}
|
||||
sacrifice.triple_sacrifice(triples, triples,
|
||||
*thread.P, thread.MC->get_part_MC());
|
||||
sacrifice.triple_combine(triples, triples, *thread.P,
|
||||
thread.MC->get_part_MC());
|
||||
for (size_t i = 0; i < triples.size() / T::default_length; i++)
|
||||
{
|
||||
this->triples.push_back({});
|
||||
@@ -112,21 +132,22 @@ void TinyPrep<T>::buffer_bits()
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void TinyPrep<T>::buffer_inputs(int player)
|
||||
void TinyPrep<T>::buffer_inputs_(int player, typename T::InputGenerator* input_generator)
|
||||
{
|
||||
auto& inputs = this->inputs;
|
||||
inputs.resize(thread.P->num_players());
|
||||
assert(this->input_generator);
|
||||
this->input_generator->generateInputs(player);
|
||||
for (size_t i = 0; i < this->input_generator->inputs.size() / T::default_length; i++)
|
||||
inputs.resize(this->thread.P->num_players());
|
||||
assert(input_generator);
|
||||
input_generator->generateInputs(player);
|
||||
assert(input_generator->inputs.size() >= T::default_length);
|
||||
for (size_t i = 0; i < input_generator->inputs.size() / T::default_length; i++)
|
||||
{
|
||||
inputs[player].push_back({});
|
||||
inputs[player].back().share.resize_regs(T::default_length);
|
||||
for (int j = 0; j < T::default_length; j++)
|
||||
{
|
||||
auto& source_input = this->input_generator->inputs[j
|
||||
auto& source_input = input_generator->inputs[j
|
||||
+ i * T::default_length];
|
||||
inputs[player].back().share.get_reg(j) = res_type(source_input.share);
|
||||
inputs[player].back().share.get_reg(j) = source_input.share;
|
||||
inputs[player].back().value ^= typename T::open_type(
|
||||
source_input.value.get_bit(0)) << j;
|
||||
}
|
||||
@@ -170,4 +191,22 @@ array<T, 3> TinyPrep<T>::get_triple(int n_bits)
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
size_t TinyPrep<T>::data_sent()
|
||||
{
|
||||
size_t res = 0;
|
||||
if (triple_generator)
|
||||
res += triple_generator->data_sent();
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
size_t TinyOnlyPrep<T>::data_sent()
|
||||
{
|
||||
auto res = TinyPrep<T>::data_sent();
|
||||
if (input_generator)
|
||||
res += input_generator->data_sent();
|
||||
return res;
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
127
GC/TinySecret.h
127
GC/TinySecret.h
@@ -19,16 +19,16 @@ template<class T> class TinyMultiplier;
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T> class TinyPrep;
|
||||
template<class T> class TinyOnlyPrep;
|
||||
template<class T> class TinyMC;
|
||||
|
||||
template<int S>
|
||||
class TinySecret : public Secret<TinyShare<S>>
|
||||
template<class T>
|
||||
class VectorSecret : public Secret<T>
|
||||
{
|
||||
typedef TinySecret This;
|
||||
typedef VectorSecret This;
|
||||
|
||||
public:
|
||||
typedef TinyShare<S> part_type;
|
||||
typedef T part_type;
|
||||
typedef Secret<part_type> super;
|
||||
|
||||
typedef typename part_type::mac_key_type mac_key_type;
|
||||
@@ -36,29 +36,17 @@ public:
|
||||
typedef BitVec open_type;
|
||||
typedef BitVec clear;
|
||||
|
||||
typedef TinyMC<This> MC;
|
||||
typedef MC MAC_Check;
|
||||
typedef Beaver<This> Protocol;
|
||||
typedef ::Input<This> Input;
|
||||
typedef TinyPrep<This> LivePrep;
|
||||
typedef Memory<This> DynamicMemory;
|
||||
|
||||
typedef OTTripleGenerator<This> TripleGenerator;
|
||||
typedef TinyMultiplier<This> Multiplier;
|
||||
typedef typename part_type::sacri_type sacri_type;
|
||||
typedef typename part_type::mac_type mac_type;
|
||||
typedef BitDiagonal Rectangle;
|
||||
|
||||
typedef typename T::super check_type;
|
||||
|
||||
static const bool dishonest_majority = true;
|
||||
static const bool needs_ot = true;
|
||||
|
||||
static const int default_length = 64;
|
||||
|
||||
static string type_short()
|
||||
{
|
||||
return "T";
|
||||
}
|
||||
|
||||
static DataFieldType field_type()
|
||||
{
|
||||
return BitVec::field_type();
|
||||
@@ -69,19 +57,9 @@ public:
|
||||
return part_type::size() * default_length;
|
||||
}
|
||||
|
||||
static MC* new_mc(Machine<This>& machine)
|
||||
static void generate_mac_key(mac_key_type& dest, const mac_key_type& source)
|
||||
{
|
||||
(void) machine;
|
||||
return new MC(ShareParty<This>::s().mac_key);
|
||||
}
|
||||
|
||||
static void store_clear_in_dynamic(Memory<This>& mem,
|
||||
const vector<ClearWriteAccess>& accesses)
|
||||
{
|
||||
auto& party = ShareThread<This>::s();
|
||||
for (auto access : accesses)
|
||||
mem[access.address] = constant(access.value, party.P->my_num(),
|
||||
{});
|
||||
dest = source;
|
||||
}
|
||||
|
||||
static This constant(BitVec other, int my_num, mac_key_type alphai)
|
||||
@@ -93,13 +71,17 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
TinySecret()
|
||||
VectorSecret()
|
||||
{
|
||||
}
|
||||
TinySecret(const super& other) :
|
||||
VectorSecret(const super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
VectorSecret(const part_type& other)
|
||||
{
|
||||
this->get_regs().push_back(other);
|
||||
}
|
||||
|
||||
void assign(const char* buffer)
|
||||
{
|
||||
@@ -113,6 +95,11 @@ public:
|
||||
return *this + other;
|
||||
}
|
||||
|
||||
This& operator^=(const This& other)
|
||||
{
|
||||
return *this = *this + other;
|
||||
}
|
||||
|
||||
This operator*(const BitVec& other) const
|
||||
{
|
||||
This res = *this;
|
||||
@@ -122,6 +109,11 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
This operator&(const BitVec::super& other) const
|
||||
{
|
||||
return *this * BitVec(other);
|
||||
}
|
||||
|
||||
This extend_bit() const
|
||||
{
|
||||
This res;
|
||||
@@ -136,14 +128,6 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
void reveal(size_t n_bits, Clear& x)
|
||||
{
|
||||
auto& to_open = *this;
|
||||
to_open.resize_regs(n_bits);
|
||||
auto& party = ShareThread<This>::s();
|
||||
x = party.MC->POpen(to_open, *party.P);
|
||||
}
|
||||
|
||||
void output(ostream& s, bool human = true) const
|
||||
{
|
||||
assert(this->get_regs().size() == default_length);
|
||||
@@ -153,7 +137,66 @@ public:
|
||||
};
|
||||
|
||||
template<int S>
|
||||
inline TinySecret<S> operator*(const BitVec& clear, const TinySecret<S>& share)
|
||||
class TinySecret : public VectorSecret<TinyShare<S>>
|
||||
{
|
||||
typedef VectorSecret<TinyShare<S>> super;
|
||||
typedef TinySecret This;
|
||||
|
||||
public:
|
||||
typedef TinyMC<This> MC;
|
||||
typedef MC MAC_Check;
|
||||
typedef Beaver<This> Protocol;
|
||||
typedef ::Input<This> Input;
|
||||
typedef TinyOnlyPrep<This> LivePrep;
|
||||
typedef Memory<This> DynamicMemory;
|
||||
|
||||
typedef OTTripleGenerator<This> TripleGenerator;
|
||||
typedef typename super::part_type::TripleGenerator InputGenerator;
|
||||
|
||||
typedef TinyMultiplier<This> Multiplier;
|
||||
|
||||
static string type_short()
|
||||
{
|
||||
return "T";
|
||||
}
|
||||
|
||||
static MC* new_mc(typename super::mac_key_type mac_key)
|
||||
{
|
||||
return new MC(mac_key);
|
||||
}
|
||||
|
||||
static void store_clear_in_dynamic(Memory<This>& mem,
|
||||
const vector<ClearWriteAccess>& accesses)
|
||||
{
|
||||
auto& party = ShareThread<This>::s();
|
||||
for (auto access : accesses)
|
||||
mem[access.address] = super::constant(access.value,
|
||||
party.P->my_num(), {});
|
||||
}
|
||||
|
||||
TinySecret()
|
||||
{
|
||||
}
|
||||
TinySecret(const super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
TinySecret(const typename super::part_type& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
|
||||
void reveal(size_t n_bits, Clear& x)
|
||||
{
|
||||
auto& to_open = *this;
|
||||
to_open.resize_regs(n_bits);
|
||||
auto& party = ShareThread<This>::s();
|
||||
x = party.MC->POpen(to_open, *party.P);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline VectorSecret<T> operator*(const BitVec& clear, const VectorSecret<T>& share)
|
||||
{
|
||||
return share * clear;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,11 @@ public:
|
||||
TinyShare()
|
||||
{
|
||||
}
|
||||
TinyShare(const typename super::super& other) :
|
||||
TinyShare(const typename super::super::super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
TinyShare(const super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
@@ -64,7 +68,7 @@ public:
|
||||
{
|
||||
auto& party = get_party();
|
||||
*this = super::constant(input, party.P->my_num(),
|
||||
ShareParty < TinySecret < S >> ::s().mac_key);
|
||||
party.MC->get_alphai());
|
||||
}
|
||||
|
||||
void random()
|
||||
|
||||
@@ -14,87 +14,96 @@
|
||||
#define MD dynamic_memory
|
||||
|
||||
#define R0 instruction.get_r(0)
|
||||
#define R1 instruction.get_r(1)
|
||||
#define R2 instruction.get_r(2)
|
||||
#define REG1 instruction.get_r(1)
|
||||
|
||||
#define S0 processor.S[instruction.get_r(0)]
|
||||
#define PS1 processor.S[instruction.get_r(1)]
|
||||
#define PS2 processor.S[instruction.get_r(2)]
|
||||
|
||||
#define C0 processor.C[instruction.get_r(0)]
|
||||
#define C1 processor.C[instruction.get_r(1)]
|
||||
#define C2 processor.C[instruction.get_r(2)]
|
||||
#define PC1 processor.C[instruction.get_r(1)]
|
||||
#define PC2 processor.C[instruction.get_r(2)]
|
||||
|
||||
#define I0 processor.I[instruction.get_r(0)]
|
||||
#define I1 processor.I[instruction.get_r(1)]
|
||||
#define I2 processor.I[instruction.get_r(2)]
|
||||
#define PI1 processor.I[instruction.get_r(1)]
|
||||
#define PI2 processor.I[instruction.get_r(2)]
|
||||
|
||||
#define IMM instruction.get_n()
|
||||
#define EXTRA instruction.get_start()
|
||||
|
||||
#define MSD MACH.MS[IMM]
|
||||
#define MMC MACH.MC[IMM]
|
||||
#define MID MACH.MI[IMM]
|
||||
#define MSD processor.memories.MS[IMM]
|
||||
#define MMC processor.memories.MC[IMM]
|
||||
#define MID MACH->MI[IMM]
|
||||
|
||||
#define MSI MACH.MS[I1.get()]
|
||||
#define MII MACH.MI[I1.get()]
|
||||
#define MSI processor.memories.MS[PI1.get()]
|
||||
#define MII MACH->MI[PI1.get()]
|
||||
|
||||
#define INSTRUCTIONS \
|
||||
#define BIT_INSTRUCTIONS \
|
||||
X(XORS, PROC.xors(EXTRA)) \
|
||||
X(XORC, C0.xor_(C1, C2)) \
|
||||
X(XORCI, C0.xor_(C1, IMM)) \
|
||||
X(XORCB, C0.xor_(PC1, PC2)) \
|
||||
X(XORCBI, C0.xor_(PC1, IMM)) \
|
||||
X(ANDRS, T::andrs(PROC, EXTRA)) \
|
||||
X(ANDS, T::ands(PROC, EXTRA)) \
|
||||
X(INPUTB, T::inputb(PROC, EXTRA)) \
|
||||
X(ADDC, C0 = C1 + C2) \
|
||||
X(ADDCI, C0 = C1 + IMM) \
|
||||
X(MULCI, C0 = C1 * IMM) \
|
||||
X(ADDCB, C0 = PC1 + PC2) \
|
||||
X(ADDCBI, C0 = PC1 + IMM) \
|
||||
X(MULCBI, C0 = PC1 * IMM) \
|
||||
X(BITDECS, PROC.bitdecs(EXTRA, S0)) \
|
||||
X(BITCOMS, PROC.bitcoms(S0, EXTRA)) \
|
||||
X(BITDECC, PROC.bitdecc(EXTRA, C0)) \
|
||||
X(BITDECINT, PROC.bitdecint(EXTRA, I0)) \
|
||||
X(SHRCI, C0 = C1 >> IMM) \
|
||||
X(SHLCI, C0 = C1 << IMM) \
|
||||
X(LDBITS, S0.load_clear(R1, IMM)) \
|
||||
X(LDMS, S0 = MSD) \
|
||||
X(STMS, MSD = S0) \
|
||||
X(LDMSI, S0 = MSI) \
|
||||
X(STMSI, MSI = S0) \
|
||||
X(LDMC, C0 = MMC) \
|
||||
X(STMC, MMC = C0) \
|
||||
X(SHRCBI, C0 = PC1 >> IMM) \
|
||||
X(SHLCBI, C0 = PC1 << IMM) \
|
||||
X(LDBITS, S0.load_clear(REG1, IMM)) \
|
||||
X(LDMSB, S0 = MSD) \
|
||||
X(STMSB, MSD = S0) \
|
||||
X(LDMCB, C0 = MMC) \
|
||||
X(STMCB, MMC = C0) \
|
||||
X(MOVSB, S0 = PS1) \
|
||||
X(TRANS, T::trans(PROC, IMM, EXTRA)) \
|
||||
X(BITB, PROC.random_bit(S0)) \
|
||||
X(REVEAL, PS1.reveal(IMM, C0)) \
|
||||
X(PRINTREGSIGNED, PROC.print_reg_signed(IMM, C0)) \
|
||||
X(PRINTREGB, PROC.print_reg(R0, IMM)) \
|
||||
X(PRINTREGPLAINB, PROC.print_reg_plain(C0)) \
|
||||
X(PRINTFLOATPLAINB, PROC.print_float(EXTRA)) \
|
||||
X(CONDPRINTSTRB, if(C0.get()) PROC.print_str(IMM)) \
|
||||
|
||||
#define COMBI_INSTRUCTIONS BIT_INSTRUCTIONS \
|
||||
X(ANDM, S0 = PS1 & PC2) \
|
||||
X(LDMSBI, S0 = processor.memories.MS[Proc.read_Ci(REG1)]) \
|
||||
X(STMSBI, processor.memories.MS[Proc.read_Ci(REG1)] = S0) \
|
||||
X(CONVSINT, S0.load_clear(IMM, Proc.read_Ci(REG1))) \
|
||||
X(CONVCINT, C0 = Proc.read_Ci(REG1)) \
|
||||
X(CONVCBIT, Proc.write_Ci(R0, PC1.get())) \
|
||||
X(DABIT, Proc.dabit(INST)) \
|
||||
|
||||
#define GC_INSTRUCTIONS \
|
||||
X(LDMSBI, S0 = MSI) \
|
||||
X(STMSBI, MSI = S0) \
|
||||
X(LDMSD, PROC.load_dynamic_direct(EXTRA, MD)) \
|
||||
X(STMSD, PROC.store_dynamic_direct(EXTRA, MD)) \
|
||||
X(LDMSDI, PROC.load_dynamic_indirect(EXTRA, MD)) \
|
||||
X(STMSDI, PROC.store_dynamic_indirect(EXTRA, MD)) \
|
||||
X(STMSDCI, PROC.store_clear_in_dynamic(EXTRA, MD)) \
|
||||
X(CONVSINT, S0.load_clear(IMM, I1)) \
|
||||
X(CONVCINT, C0 = I1) \
|
||||
X(CONVCBIT, T::convcbit(I0, C1)) \
|
||||
X(MOVS, S0 = PS1) \
|
||||
X(TRANS, T::trans(PROC, IMM, EXTRA)) \
|
||||
X(BIT, PROC.random_bit(S0)) \
|
||||
X(REVEAL, PS1.reveal(IMM, C0)) \
|
||||
X(PRINTREG, PROC.print_reg(R0, IMM)) \
|
||||
X(PRINTREGPLAIN, PROC.print_reg_plain(C0)) \
|
||||
X(PRINTREGSIGNED, PROC.print_reg_signed(IMM, C0)) \
|
||||
X(CONVSINT, S0.load_clear(IMM, PI1)) \
|
||||
X(CONVCINT, C0 = PI1) \
|
||||
X(CONVCBIT, T::convcbit(I0, PC1)) \
|
||||
X(PRINTCHR, PROC.print_chr(IMM)) \
|
||||
X(PRINTSTR, PROC.print_str(IMM)) \
|
||||
X(PRINTFLOATPLAIN, PROC.print_float(EXTRA)) \
|
||||
X(PRINTFLOATPREC, PROC.print_float_prec(IMM)) \
|
||||
X(CONDPRINTSTR, if(C0.get()) PROC.print_str(IMM)) \
|
||||
X(LDINT, I0 = int(IMM)) \
|
||||
X(ADDINT, I0 = I1 + I2) \
|
||||
X(SUBINT, I0 = I1 - I2) \
|
||||
X(MULINT, I0 = I1 * I2) \
|
||||
X(DIVINT, I0 = I1 / I2) \
|
||||
X(ADDINT, I0 = PI1 + PI2) \
|
||||
X(SUBINT, I0 = PI1 - PI2) \
|
||||
X(MULINT, I0 = PI1 * PI2) \
|
||||
X(DIVINT, I0 = PI1 / PI2) \
|
||||
X(JMP, PROC.PC += IMM) \
|
||||
X(JMPNZ, if (I0 != 0) PROC.PC += IMM) \
|
||||
X(JMPEQZ, if (I0 == 0) PROC.PC += IMM) \
|
||||
X(EQZC, I0 = I1 == 0) \
|
||||
X(LTZC, I0 = I1 < 0) \
|
||||
X(LTC, I0 = I1 < I2) \
|
||||
X(GTC, I0 = I1 > I2) \
|
||||
X(EQC, I0 = I1 == I2) \
|
||||
X(EQZC, I0 = PI1 == 0) \
|
||||
X(LTZC, I0 = PI1 < 0) \
|
||||
X(LTC, I0 = PI1 < PI2) \
|
||||
X(GTC, I0 = PI1 > PI2) \
|
||||
X(EQC, I0 = PI1 == PI2) \
|
||||
X(JMPI, PROC.PC += I0) \
|
||||
X(LDMINT, I0 = MID) \
|
||||
X(STMINT, MID = I0) \
|
||||
@@ -102,18 +111,23 @@
|
||||
X(STMINTI, MII = I0) \
|
||||
X(PUSHINT, PROC.pushi(I0.get())) \
|
||||
X(POPINT, long x; PROC.popi(x); I0 = x) \
|
||||
X(MOVINT, I0 = I1) \
|
||||
X(MOVINT, I0 = PI1) \
|
||||
X(BITDECINT, PROC.bitdecint(EXTRA, I0)) \
|
||||
X(LDARG, I0 = PROC.get_arg()) \
|
||||
X(STARG, PROC.set_arg(I0.get())) \
|
||||
X(TIME, MACH.time()) \
|
||||
X(START, MACH.start(IMM)) \
|
||||
X(STOP, MACH.stop(IMM)) \
|
||||
X(TIME, MACH->time()) \
|
||||
X(START, MACH->start(IMM)) \
|
||||
X(STOP, MACH->stop(IMM)) \
|
||||
X(GLDMS, ) \
|
||||
X(GLDMC, ) \
|
||||
X(LDMS, ) \
|
||||
X(LDMC, ) \
|
||||
X(PRINTINT, S0.out << I0) \
|
||||
X(STARTGRIND, CALLGRIND_START_INSTRUMENTATION) \
|
||||
X(STOPGRIND, CALLGRIND_STOP_INSTRUMENTATION) \
|
||||
X(RUN_TAPE, MACH.run_tape(R0, IMM, R1)) \
|
||||
X(JOIN_TAPE, MACH.join_tape(R0)) \
|
||||
X(RUN_TAPE, MACH->run_tape(R0, IMM, REG1)) \
|
||||
X(JOIN_TAPE, MACH->join_tape(R0)) \
|
||||
|
||||
#define INSTRUCTIONS BIT_INSTRUCTIONS GC_INSTRUCTIONS
|
||||
|
||||
#endif /* GC_INSTRUCTIONS_H_ */
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "Processor/config.h"
|
||||
#include "Protocols/Share.h"
|
||||
#include "GC/TinierSecret.h"
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ int spdz_main(int argc, const char** argv, ez::ezOptionParser& opt, bool live_pr
|
||||
OnlineOptions& online_opts = OnlineOptions::singleton;
|
||||
online_opts = {opt, argc, argv, 1000, live_prep_default};
|
||||
|
||||
opt.example = "./Player-Online.x -lgp 64 -lg2 128 -m new 0 sample-prog\n./Player-Online.x -pn 13000 -h localhost 1 sample-prog\n";
|
||||
opt.example = string() + argv[0] + " -p 0 -N 2 sample-prog\n" + argv[0]
|
||||
+ " -h localhost -p 1 -N 2 sample-prog\n";
|
||||
|
||||
opt.add(
|
||||
to_string(U::clear::default_degree()).c_str(), // Default.
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Protocols/MaliciousRep3Share.h"
|
||||
#include "Protocols/MalRepRingShare.h"
|
||||
#include "Protocols/BrainShare.h"
|
||||
#include "Protocols/BrainPrep.h"
|
||||
#include "Protocols/MalRepRingPrep.h"
|
||||
|
||||
@@ -15,12 +12,14 @@
|
||||
#include "Protocols/BrainPrep.hpp"
|
||||
#include "Protocols/MalRepRingPrep.hpp"
|
||||
#include "Protocols/MaliciousRepPrep.hpp"
|
||||
#include "Protocols/Spdz2kPrep.hpp"
|
||||
#include "Protocols/MAC_Check_Base.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/MaliciousRepMC.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/RepPrep.hpp"
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
|
||||
template<>
|
||||
Preprocessing<Rep3Share<gf2n>>* Preprocessing<Rep3Share<gf2n>>::get_live_prep(
|
||||
|
||||
2
Machines/RepRing.hpp
Normal file
2
Machines/RepRing.hpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "Rep.hpp"
|
||||
#include "Protocols/Spdz2kPrep.hpp"
|
||||
@@ -8,4 +8,14 @@
|
||||
|
||||
#include "Protocols/MascotPrep.hpp"
|
||||
|
||||
#include "GC/TinierSecret.h"
|
||||
#include "GC/TinyMC.h"
|
||||
#include "GC/TinierPrep.h"
|
||||
|
||||
#include "GC/ShareParty.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/TinyPrep.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/TinierSharePrep.hpp"
|
||||
|
||||
template class Machine<Share<gfp>, Share<gf2n>>;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "Protocols/Spdz2kShare.h"
|
||||
#include "Protocols/Spdz2kPrep.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "Processor/RingOptions.h"
|
||||
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
#include "Machines/Rep.hpp"
|
||||
#include "Machines/RepRing.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#include "FHE/FFT_Data.h"
|
||||
#include "FHE/NTL-Subs.h"
|
||||
|
||||
#include "GC/TinierSecret.h"
|
||||
#include "GC/TinierPrep.h"
|
||||
#include "GC/TinyMC.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
@@ -18,6 +22,11 @@
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/TinyPrep.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/TinierSharePrep.hpp"
|
||||
#include "OT/NPartyTripleGenerator.hpp"
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "Math/gf2n.h"
|
||||
#include "FHE/P2Data.h"
|
||||
#include "Tools/ezOptionParser.h"
|
||||
#include "GC/SemiSecret.h"
|
||||
#include "GC/SemiPrep.h"
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
#include "Protocols/HemiPrep.hpp"
|
||||
@@ -21,6 +23,8 @@
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/SemiMC.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/SemiHonestRepPrep.h"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Protocols/MaliciousRep3Share.h"
|
||||
|
||||
#include "Machines/Rep.hpp"
|
||||
|
||||
#include "BMR/RealProgramParty.hpp"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "Protocols/MalRepRingOptions.h"
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
#include "Processor/RingOptions.h"
|
||||
#include "Machines/Rep.hpp"
|
||||
#include "Machines/RepRing.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
#include "Math/gfp.h"
|
||||
#include "GC/TinierSecret.h"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "Protocols/PostSacriRepFieldShare.h"
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
#include "Processor/RingOptions.h"
|
||||
#include "Machines/Rep.hpp"
|
||||
#include "Machines/RepRing.hpp"
|
||||
#include "Protocols/PostSacrifice.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
*/
|
||||
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
#include "Protocols/Rep3Share2k.h"
|
||||
#include "Protocols/ReplicatedPrep2k.h"
|
||||
#include "Processor/RingOptions.h"
|
||||
#include "Math/Integer.h"
|
||||
#include "Machines/Rep.hpp"
|
||||
#include "Machines/RepRing.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
@@ -15,11 +17,11 @@ int main(int argc, const char** argv)
|
||||
switch (opts.R)
|
||||
{
|
||||
case 64:
|
||||
ReplicatedMachine<Rep3Share<SignedZ2<64>>, Rep3Share<gf2n>>(argc, argv,
|
||||
ReplicatedMachine<Rep3Share2<64>, Rep3Share<gf2n>>(argc, argv,
|
||||
"replicated-ring", opt);
|
||||
break;
|
||||
case 72:
|
||||
ReplicatedMachine<Rep3Share<SignedZ2<72>>, Rep3Share<gf2n>>(argc, argv,
|
||||
ReplicatedMachine<Rep3Share2<72>, Rep3Share<gf2n>>(argc, argv,
|
||||
"replicated-ring", opt);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
|
||||
#include "Math/gfp.h"
|
||||
#include "Protocols/SemiShare.h"
|
||||
#include "Tools/SwitchableOutput.h"
|
||||
#include "GC/SemiPrep.h"
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
#include "Semi.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
@@ -4,11 +4,14 @@
|
||||
*/
|
||||
|
||||
#include "Protocols/Semi2kShare.h"
|
||||
#include "Protocols/SemiPrep2k.h"
|
||||
#include "Math/gf2n.h"
|
||||
#include "Processor/RingOptions.h"
|
||||
#include "GC/SemiPrep.h"
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
#include "Semi.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "GC/TinySecret.h"
|
||||
#include "GC/TinyMC.h"
|
||||
#include "GC/TinyPrep.h"
|
||||
#include "GC/TinierSecret.h"
|
||||
#include "Processor/Machine.h"
|
||||
#include "Processor/RingOptions.h"
|
||||
#include "Protocols/Spdz2kShare.h"
|
||||
@@ -11,6 +15,11 @@
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
#include "SPDZ2k.hpp"
|
||||
#include "GC/ShareParty.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/TinyPrep.hpp"
|
||||
#include "GC/TinierSharePrep.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
33
Machines/tinier-party.cpp
Normal file
33
Machines/tinier-party.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* tinier-party.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "GC/TinierSecret.h"
|
||||
#include "GC/TinierPrep.h"
|
||||
#include "GC/ShareParty.h"
|
||||
#include "GC/TinyMC.h"
|
||||
|
||||
#include "GC/ShareParty.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "GC/Machine.hpp"
|
||||
#include "GC/Processor.hpp"
|
||||
#include "GC/Program.hpp"
|
||||
#include "GC/Thread.hpp"
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/TinyPrep.hpp"
|
||||
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
#include "Protocols/MAC_Check_Base.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Protocols/MascotPrep.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
gf2n_short::init_field(40);
|
||||
GC::ShareParty<GC::TinierSecret<gf2n_short>>(argc, argv, 1000);
|
||||
}
|
||||
25
Makefile
25
Makefile
@@ -12,6 +12,7 @@ PROCESSOR = $(patsubst %.cpp,%.o,$(wildcard Processor/*.cpp))
|
||||
FHEOFFLINE = $(patsubst %.cpp,%.o,$(wildcard FHEOffline/*.cpp FHE/*.cpp))
|
||||
|
||||
GC = $(patsubst %.cpp,%.o,$(wildcard GC/*.cpp)) $(PROCESSOR)
|
||||
GC_SEMI = GC/SemiSecret.o GC/SemiPrep.o GC/square64.o
|
||||
|
||||
OT = $(patsubst %.cpp,%.o,$(filter-out OT/OText_main.cpp,$(wildcard OT/*.cpp)))
|
||||
OT_EXE = ot.x ot-offline.x
|
||||
@@ -20,7 +21,7 @@ COMMON = $(MATH) $(TOOLS) $(NETWORK)
|
||||
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)) $(COMMON) $(PROCESSOR) $(OT)
|
||||
VM = $(PROCESSOR) $(COMMON)
|
||||
VM = $(PROCESSOR) $(COMMON) GC/square64.o
|
||||
|
||||
|
||||
LIB = libSPDZ.a
|
||||
@@ -35,10 +36,14 @@ DEPS := $(wildcard */*.d)
|
||||
.SECONDARY: $(OBJS)
|
||||
|
||||
|
||||
all: gen_input online offline externalIO bmr yao replicated shamir real-bmr spdz2k-party.x brain-party.x semi-party.x semi2k-party.x semi-bin-party.x mascot-party.x tiny-party.x
|
||||
all: arithmetic binary gen_input online offline externalIO bmr
|
||||
|
||||
arithmetic: rep-ring rep-field shamir semi2k-party.x semi-party.x spdz2k-party.x mascot-party.x
|
||||
binary: rep-bin yao semi-bin-party.x tinier-party.x tiny-party.x real-bmr
|
||||
|
||||
ifeq ($(USE_NTL),1)
|
||||
all: overdrive she-offline cowgear-party.x hemi-party.x
|
||||
all: overdrive she-offline
|
||||
arithmetic: hemi-party.x cowgear-party.x
|
||||
endif
|
||||
|
||||
-include $(DEPS)
|
||||
@@ -157,23 +162,27 @@ default-prime-length.x: Utils/default-prime-length.cpp
|
||||
$(CXX) -o $@ $(CFLAGS) $^ $(LDLIBS) $(ECLIB)
|
||||
|
||||
replicated-bin-party.x: GC/square64.o
|
||||
replicated-ring-party.x: GC/square64.o
|
||||
replicated-field-party.x: GC/square64.o
|
||||
brain-party.x: GC/square64.o
|
||||
malicious-rep-bin-party.x: GC/square64.o
|
||||
semi-bin-party.x: $(VM) $(OT) GC/SemiSecret.o GC/SemiPrep.o GC/square64.o
|
||||
tiny-party.x: $(OT)
|
||||
tinier-party.x: $(OT)
|
||||
shamir-party.x: Machines/ShamirMachine.o
|
||||
malicious-shamir-party.x: Machines/ShamirMachine.o
|
||||
spdz2k-party.x: $(OT)
|
||||
semi-party.x: $(OT)
|
||||
semi2k-party.x: $(OT)
|
||||
hemi-party.x: $(FHEOFFLINE)
|
||||
cowgear-party.x: $(FHEOFFLINE) Protocols/CowGearOptions.o
|
||||
semi-party.x: $(OT) GC/SemiSecret.o GC/SemiPrep.o GC/square64.o
|
||||
semi2k-party.x: $(OT) GC/SemiSecret.o GC/SemiPrep.o GC/square64.o
|
||||
hemi-party.x: $(FHEOFFLINE) $(GC_SEMI) $(OT)
|
||||
cowgear-party.x: $(FHEOFFLINE) Protocols/CowGearOptions.o $(OT)
|
||||
mascot-party.x: Machines/SPDZ.o $(OT)
|
||||
Player-Online.x: Machines/SPDZ.o $(OT)
|
||||
ps-rep-ring-party.x: Protocols/MalRepRingOptions.o
|
||||
malicious-rep-ring-party.x: Protocols/MalRepRingOptions.o
|
||||
mal-shamir-ecdsa-party.x: Machines/ShamirMachine.o
|
||||
shamir-ecdsa-party.x: Machines/ShamirMachine.o
|
||||
semi-ecdsa-party.x: $(OT) $(LIBSIMPLEOT)
|
||||
semi-ecdsa-party.x: $(OT) $(LIBSIMPLEOT) GC/SemiPrep.o
|
||||
mascot-ecdsa-party.x: $(OT) $(LIBSIMPLEOT)
|
||||
|
||||
$(LIBSIMPLEOT): SimpleOT/Makefile
|
||||
|
||||
54
Math/Bit.h
Normal file
54
Math/Bit.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Bit.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MATH_BIT_H_
|
||||
#define MATH_BIT_H_
|
||||
|
||||
#include "BitVec.h"
|
||||
|
||||
class Bit : public BitVec_<bool>
|
||||
{
|
||||
typedef BitVec_<bool> super;
|
||||
|
||||
public:
|
||||
static int size_in_bits()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Bit()
|
||||
{
|
||||
}
|
||||
Bit(bool other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
Bit(const super::super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
|
||||
Bit operator*(const Bit& other) const
|
||||
{
|
||||
return super::operator*(other);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T operator*(const T& other) const
|
||||
{
|
||||
return other * *this;
|
||||
}
|
||||
|
||||
void pack(octetStream& os, int = -1) const
|
||||
{
|
||||
super::pack(os, 1);
|
||||
}
|
||||
void unpack(octetStream& os, int = -1)
|
||||
{
|
||||
super::unpack(os, 1);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* MATH_BIT_H_ */
|
||||
@@ -8,57 +8,63 @@
|
||||
|
||||
#include "Integer.h"
|
||||
#include "field_types.h"
|
||||
#include "Square.h"
|
||||
|
||||
class BitDiagonal;
|
||||
|
||||
class BitVec : public IntBase
|
||||
template<class T>
|
||||
class BitVec_ : public IntBase<T>
|
||||
{
|
||||
public:
|
||||
typedef BitVec Scalar;
|
||||
typedef IntBase<T> super;
|
||||
|
||||
typedef BitVec next;
|
||||
typedef BitVec_ Scalar;
|
||||
|
||||
typedef BitVec_ next;
|
||||
typedef BitDiagonal Square;
|
||||
|
||||
static const int n_bits = sizeof(a) * 8;
|
||||
static const int n_bits = sizeof(T) * 8;
|
||||
|
||||
static char type_char() { return 'B'; }
|
||||
static DataFieldType field_type() { return DATA_GF2; }
|
||||
|
||||
static bool allows(Dtype dtype) { return dtype == DATA_TRIPLE or dtype == DATA_BIT; }
|
||||
|
||||
BitVec() {}
|
||||
BitVec(long a) : IntBase(a) {}
|
||||
BitVec(const IntBase& a) : IntBase(a) {}
|
||||
BitVec_() {}
|
||||
BitVec_(long a) : super(a) {}
|
||||
BitVec_(const super& a) : super(a) {}
|
||||
template<int K>
|
||||
BitVec_(const Z2<K>& a) : super(a.get_limb(0)) {}
|
||||
|
||||
BitVec operator+(const BitVec& other) const { return a ^ other.a; }
|
||||
BitVec operator-(const BitVec& other) const { return a ^ other.a; }
|
||||
BitVec operator*(const BitVec& other) const { return a & other.a; }
|
||||
BitVec_ operator+(const BitVec_& other) const { return *this ^ other; }
|
||||
BitVec_ operator-(const BitVec_& other) const { return *this ^ other; }
|
||||
BitVec_ operator*(const BitVec_& other) const { return *this & other; }
|
||||
|
||||
BitVec operator/(const BitVec& other) const { (void) other; throw not_implemented(); }
|
||||
BitVec_ operator/(const BitVec_& other) const { (void) other; throw not_implemented(); }
|
||||
|
||||
BitVec& operator+=(const BitVec& other) { *this ^= other; return *this; }
|
||||
BitVec& operator-=(const BitVec& other) { *this ^= other; return *this; }
|
||||
BitVec_& operator+=(const BitVec_& other) { *this ^= other; return *this; }
|
||||
BitVec_& operator-=(const BitVec_& other) { *this ^= other; return *this; }
|
||||
|
||||
BitVec extend_bit() const { return -(a & 1); }
|
||||
BitVec mask(int n) const { return n < n_bits ? *this & ((1L << n) - 1) : *this; }
|
||||
BitVec_ extend_bit() const { return -(this->a & 1); }
|
||||
BitVec_ mask(int n) const { return n < n_bits ? *this & ((1L << n) - 1) : *this; }
|
||||
|
||||
template<int t>
|
||||
void add(octetStream& os) { *this += os.get<BitVec>(); }
|
||||
void add(octetStream& os) { *this += os.get<BitVec_>(); }
|
||||
|
||||
void mul(const BitVec& a, const BitVec& b) { *this = a * b; }
|
||||
void mul(const BitVec_& a, const BitVec_& b) { *this = a * b; }
|
||||
|
||||
void randomize(PRNG& G, int n = n_bits) { IntBase::randomize(G); *this = mask(n); }
|
||||
void randomize(PRNG& G, int n = n_bits) { super::randomize(G); *this = mask(n); }
|
||||
|
||||
void pack(octetStream& os, int n = n_bits) const { os.store_int(a, DIV_CEIL(n, 8)); }
|
||||
void unpack(octetStream& os, int n = n_bits) { a = os.get_int(DIV_CEIL(n, 8)); }
|
||||
void pack(octetStream& os, int n = n_bits) const { os.store_int(this->a, DIV_CEIL(n, 8)); }
|
||||
void unpack(octetStream& os, int n = n_bits) { this->a = os.get_int(DIV_CEIL(n, 8)); }
|
||||
|
||||
static BitVec unpack_new(octetStream& os, int n = n_bits)
|
||||
static BitVec_ unpack_new(octetStream& os, int n = n_bits)
|
||||
{
|
||||
BitVec res;
|
||||
BitVec_ res;
|
||||
res.unpack(os, n);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
typedef BitVec_<long> BitVec;
|
||||
|
||||
#endif /* MATH_BITVEC_H_ */
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
#include "Integer.h"
|
||||
|
||||
void IntBase::output(ostream& s,bool human) const
|
||||
template<class T>
|
||||
void IntBase<T>::output(ostream& s,bool human) const
|
||||
{
|
||||
if (human)
|
||||
s << a;
|
||||
@@ -13,7 +14,8 @@ void IntBase::output(ostream& s,bool human) const
|
||||
s.write((char*)&a, sizeof(a));
|
||||
}
|
||||
|
||||
void IntBase::input(istream& s,bool human)
|
||||
template<class T>
|
||||
void IntBase<T>::input(istream& s,bool human)
|
||||
{
|
||||
if (human)
|
||||
s >> a;
|
||||
@@ -35,3 +37,14 @@ void Integer::reqbl(int n)
|
||||
throw Processor_Error("Program compiled for fields not rings");
|
||||
}
|
||||
}
|
||||
|
||||
Integer::Integer(const Integer& x, int n_bits)
|
||||
{
|
||||
a = abs(x.get());
|
||||
a &= ~(uint64_t(-1) << (n_bits - 1) << 1);
|
||||
if (x < 0)
|
||||
a = -a;
|
||||
}
|
||||
|
||||
template class IntBase<long>;
|
||||
template class IntBase<bool>;
|
||||
|
||||
@@ -18,10 +18,11 @@ using namespace std;
|
||||
|
||||
|
||||
// Functionality shared between integers and bit vectors
|
||||
template<class T>
|
||||
class IntBase : public ValueInterface
|
||||
{
|
||||
protected:
|
||||
long a;
|
||||
T a;
|
||||
|
||||
public:
|
||||
static const int N_BYTES = sizeof(a);
|
||||
@@ -37,9 +38,9 @@ public:
|
||||
static bool allows(Dtype type) { return type <= DATA_BIT; }
|
||||
|
||||
IntBase() { a = 0; }
|
||||
IntBase(long a) : a(a) {}
|
||||
IntBase(T a) : a(a) {}
|
||||
|
||||
long get() const { return a; }
|
||||
T get() const { return a; }
|
||||
bool get_bit(int i) const { return (a >> i) & 1; }
|
||||
|
||||
char* get_ptr() const { return (char*)&a; }
|
||||
@@ -55,17 +56,17 @@ public:
|
||||
bool is_one() const { return a == 1; }
|
||||
bool is_bit() const { return is_zero() or is_one(); }
|
||||
|
||||
long operator>>(const IntBase& other) const
|
||||
long operator>>(const IntBase<long>& other) const
|
||||
{
|
||||
if (other.a < N_BITS)
|
||||
return (unsigned long) a >> other.a;
|
||||
if (other.get() < N_BITS)
|
||||
return (unsigned long) a >> other.get();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
long operator<<(const IntBase& other) const
|
||||
long operator<<(const IntBase<long>& other) const
|
||||
{
|
||||
if (other.a < N_BITS)
|
||||
return a << other.a;
|
||||
if (other.get() < N_BITS)
|
||||
return a << other.get();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@@ -79,8 +80,8 @@ public:
|
||||
|
||||
bool equal(const IntBase& other) const { return *this == other; }
|
||||
|
||||
long operator^=(const IntBase& other) { return a ^= other.a; }
|
||||
long operator&=(const IntBase& other) { return a &= other.a; }
|
||||
T& operator^=(const IntBase& other) { return a ^= other.a; }
|
||||
T& operator&=(const IntBase& other) { return a &= other.a; }
|
||||
|
||||
friend ostream& operator<<(ostream& s, const IntBase& x) { x.output(s, true); return s; }
|
||||
|
||||
@@ -95,7 +96,7 @@ public:
|
||||
};
|
||||
|
||||
// Wrapper class for integer
|
||||
class Integer : public IntBase
|
||||
class Integer : public IntBase<long>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -114,6 +115,10 @@ class Integer : public IntBase
|
||||
Integer(const bigint& x) { *this = (x > 0) ? x.get_ui() : -x.get_ui(); }
|
||||
template<int K>
|
||||
Integer(const Z2<K>& x) : Integer(x.get_limb(0)) {}
|
||||
template<int X, int L>
|
||||
Integer(const gfp_<X, L>& x);
|
||||
|
||||
Integer(const Integer& x, int n_bits);
|
||||
|
||||
void convert_destroy(bigint& other) { *this = other.get_si(); }
|
||||
|
||||
@@ -150,19 +155,23 @@ class Integer : public IntBase
|
||||
void SHR(const Integer& x, const Integer& y) { *this = (unsigned long)x.a >> y.a; }
|
||||
};
|
||||
|
||||
inline void IntBase::randomize(PRNG& G)
|
||||
template<>
|
||||
inline void IntBase<long>::randomize(PRNG& G)
|
||||
{
|
||||
a = G.get_word();
|
||||
}
|
||||
|
||||
inline void to_bigint(bigint& res, const Integer& x)
|
||||
template<>
|
||||
inline void IntBase<bool>::randomize(PRNG& G)
|
||||
{
|
||||
res = (unsigned long)x.get();
|
||||
a = G.get_bit();
|
||||
}
|
||||
|
||||
inline void to_signed_bigint(bigint& res, const Integer& x)
|
||||
template<int X, int L>
|
||||
Integer::Integer(const gfp_<X, L>& x)
|
||||
{
|
||||
res = x.get();
|
||||
to_signed_bigint(bigint::tmp, x);
|
||||
*this = bigint::tmp;
|
||||
}
|
||||
|
||||
// slight misnomer
|
||||
|
||||
11
Math/Z2k.h
11
Math/Z2k.h
@@ -53,6 +53,7 @@ public:
|
||||
|
||||
static int size() { return N_BYTES; }
|
||||
static int size_in_limbs() { return N_WORDS; }
|
||||
static int size_in_bits() { return size() * 8; }
|
||||
static int t() { return 0; }
|
||||
|
||||
static char type_char() { return 'R'; }
|
||||
@@ -113,6 +114,8 @@ public:
|
||||
|
||||
Z2<K> operator/(const Z2& other) const { (void) other; throw not_implemented(); }
|
||||
|
||||
Z2<K> operator&(const Z2& other) const;
|
||||
|
||||
Z2<K>& operator+=(const Z2<K>& other);
|
||||
Z2<K>& operator-=(const Z2<K>& other);
|
||||
|
||||
@@ -148,6 +151,9 @@ public:
|
||||
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);
|
||||
@@ -348,10 +354,9 @@ ostream& operator<<(ostream& o, const SignedZ2<K>& x)
|
||||
}
|
||||
|
||||
template<int K>
|
||||
inline void to_signed_bigint(bigint& res, const SignedZ2<K>& x, int n)
|
||||
void to_bigint(bigint& res, const SignedZ2<K>& a)
|
||||
{
|
||||
bigint tmp = x;
|
||||
to_signed_bigint(res, tmp, n);
|
||||
res = a;
|
||||
}
|
||||
|
||||
#endif /* MATH_Z2K_H_ */
|
||||
|
||||
@@ -58,6 +58,14 @@ bool Z2<K>::get_bit(int i) const
|
||||
return 1 & (a[i / N_LIMB_BITS] >> (i % N_LIMB_BITS));
|
||||
}
|
||||
|
||||
template<int K>
|
||||
Z2<K> Z2<K>::operator&(const Z2<K>& other) const
|
||||
{
|
||||
Z2<K> res;
|
||||
res.AND(*this, other);
|
||||
return res;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
bool Z2<K>::operator==(const Z2<K>& other) const
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ void Zp_Data::init(const bigint& p,bool mont)
|
||||
#endif
|
||||
|
||||
pr=p;
|
||||
pr_half = p / 2;
|
||||
mask=static_cast<mp_limb_t>(1ULL<<((mpz_sizeinbase(pr.get_mpz_t(),2)-1)%(8*sizeof(mp_limb_t))))-1;
|
||||
pr_byte_length = numBytes(pr);
|
||||
pr_bit_length = numBits(pr);
|
||||
|
||||
@@ -47,6 +47,7 @@ class Zp_Data
|
||||
public:
|
||||
|
||||
bigint pr;
|
||||
bigint pr_half;
|
||||
mp_limb_t mask;
|
||||
size_t pr_byte_length;
|
||||
size_t pr_bit_length;
|
||||
|
||||
@@ -146,17 +146,6 @@ bigint::bigint(const GC::Clear& x) : bigint(SignedZ2<64>(x))
|
||||
{
|
||||
}
|
||||
|
||||
void to_signed_bigint(bigint& res, const bigint& x, int n)
|
||||
{
|
||||
res = abs(x);
|
||||
bigint& tmp = bigint::tmp = 1;
|
||||
tmp <<= n;
|
||||
tmp -= 1;
|
||||
res &= tmp;
|
||||
if (x < 0)
|
||||
res.negate();
|
||||
}
|
||||
|
||||
#ifdef REALLOC_POLICE
|
||||
void bigint::lottery()
|
||||
{
|
||||
|
||||
@@ -105,8 +105,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
void to_signed_bigint(bigint& res, const bigint& x, int n);
|
||||
|
||||
void inline_mpn_zero(mp_limb_t* x, mp_size_t size);
|
||||
void inline_mpn_copyi(mp_limb_t* dest, const mp_limb_t* src, mp_size_t size);
|
||||
|
||||
|
||||
@@ -9,6 +9,16 @@
|
||||
|
||||
enum DataFieldType { DATA_INT, DATA_GF2N, DATA_GF2, N_DATA_FIELD_TYPE };
|
||||
|
||||
enum Dtype { DATA_TRIPLE, DATA_SQUARE, DATA_BIT, DATA_INVERSE, DATA_BITTRIPLE, DATA_BITGF2NTRIPLE, N_DTYPE };
|
||||
enum Dtype
|
||||
{
|
||||
DATA_TRIPLE,
|
||||
DATA_SQUARE,
|
||||
DATA_BIT,
|
||||
DATA_INVERSE,
|
||||
DATA_BITTRIPLE,
|
||||
DATA_BITGF2NTRIPLE,
|
||||
DATA_DABIT,
|
||||
N_DTYPE
|
||||
};
|
||||
|
||||
#endif /* MATH_FIELD_TYPES_H_ */
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
#include "Math/gf2n.h"
|
||||
#include "Math/Bit.h"
|
||||
|
||||
#include "Exceptions/Exceptions.h"
|
||||
|
||||
@@ -249,6 +250,11 @@ void gf2n_short::mul(const gf2n_short& x,const gf2n_short& y)
|
||||
reduce(hi,lo);
|
||||
}
|
||||
|
||||
gf2n_short gf2n_short::operator*(const Bit& x) const
|
||||
{
|
||||
return x.get() * a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ using namespace std;
|
||||
|
||||
class gf2n_short;
|
||||
class P2Data;
|
||||
class Bit;
|
||||
template<class T> class Square;
|
||||
typedef Square<gf2n_short> gf2n_short_square;
|
||||
|
||||
@@ -82,6 +83,7 @@ class gf2n_short
|
||||
static string type_string() { return "gf2n"; }
|
||||
|
||||
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; }
|
||||
@@ -166,6 +168,8 @@ class gf2n_short
|
||||
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 Bit& x) const;
|
||||
|
||||
void square();
|
||||
void square(const gf2n_short& aa);
|
||||
void invert();
|
||||
|
||||
@@ -129,6 +129,7 @@ class gf2n_long
|
||||
static string type_string() { return "gf2n_long"; }
|
||||
|
||||
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; }
|
||||
|
||||
@@ -209,8 +209,7 @@ void to_signed_bigint(bigint& ans, const gfp& x)
|
||||
{
|
||||
to_bigint(ans, x);
|
||||
// get sign and abs(x)
|
||||
bigint& p_half = bigint::tmp = (gfp::pr()-1)/2;
|
||||
if (mpz_cmp(ans.get_mpz_t(), p_half.get_mpz_t()) > 0)
|
||||
if (mpz_cmp(ans.get_mpz_t(), gfp::get_ZpD().pr_half.get_mpz_t()) > 0)
|
||||
ans -= gfp::pr();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ class gfp_
|
||||
static string type_string() { return "gfp"; }
|
||||
|
||||
static int size() { return t() * sizeof(mp_limb_t); }
|
||||
static int size_in_bits() { return 8 * size(); }
|
||||
static int length() { return ZpD.pr_bit_length; }
|
||||
|
||||
static void reqbl(int n);
|
||||
|
||||
@@ -22,8 +22,8 @@ T& operator*=(const T& y, const bool& x) { y = x ? y : T(); return y; }
|
||||
|
||||
//template <class T, class U>
|
||||
//T& operator+=(T& x, const U& y) { x.add(y); return x; }
|
||||
template <class T>
|
||||
T& operator*=(T& x, const T& y) { x.mul(y); return x; }
|
||||
//template <class T>
|
||||
//T& operator*=(T& x, const T& y) { x.mul(y); return x; }
|
||||
//template <class T, class U>
|
||||
//T& operator-=(T& x, const U& y) { x.sub(y); return x; }
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Tools/int.h"
|
||||
#include "Tools/NetworkOptions.h"
|
||||
#include "Networking/Server.h"
|
||||
#include "Networking/ServerSocket.h"
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <utility>
|
||||
|
||||
@@ -17,7 +17,6 @@ using namespace std;
|
||||
#include "Tools/octetStream.h"
|
||||
#include "Tools/FlexBuffer.h"
|
||||
#include "Networking/sockets.h"
|
||||
#include "Networking/ServerSocket.h"
|
||||
#include "Tools/sha1.h"
|
||||
#include "Tools/int.h"
|
||||
#include "Networking/Receiver.h"
|
||||
@@ -26,6 +25,7 @@ using namespace std;
|
||||
|
||||
template<class T> class MultiPlayer;
|
||||
class Server;
|
||||
class ServerSocket;
|
||||
|
||||
/* Class to get the names off the server */
|
||||
class Names
|
||||
|
||||
@@ -458,9 +458,10 @@ void BitMatrix::resize(int length)
|
||||
squares.resize(length / 128);
|
||||
}
|
||||
|
||||
int BitMatrix::size()
|
||||
template <class U>
|
||||
size_t Matrix<U>::vertical_size()
|
||||
{
|
||||
return squares.size() * 128;
|
||||
return squares.size() * U::N_ROWS;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -681,6 +682,8 @@ Y(72, 48)
|
||||
Y(74, 48)
|
||||
Y(72, 64)
|
||||
Y(74, 64)
|
||||
Y(1, 48)
|
||||
Y(1, 64)
|
||||
|
||||
template class Matrix<square128>;
|
||||
|
||||
@@ -697,6 +700,7 @@ BMS
|
||||
|
||||
#define XXXX(BM, GF) \
|
||||
template class Slice<BM>; \
|
||||
template size_t BM::vertical_size(); \
|
||||
XX(BM, GF)
|
||||
|
||||
XXXX(Matrix<gf2n_short_square>, gf2n_short)
|
||||
|
||||
@@ -120,6 +120,8 @@ public:
|
||||
|
||||
vector< U, aligned_allocator<U, 32> > squares;
|
||||
|
||||
size_t vertical_size();
|
||||
|
||||
void resize_vertical(int length) { squares.resize(DIV_CEIL(length, U::N_ROWS)); }
|
||||
|
||||
bool operator==(Matrix<U>& other);
|
||||
@@ -145,7 +147,6 @@ public:
|
||||
__m128i& operator[](int i) { return squares[i / 128].rows[i % 128]; }
|
||||
|
||||
void resize(int length);
|
||||
int size();
|
||||
|
||||
void transpose();
|
||||
void check_transpose(BitMatrix& dual);
|
||||
|
||||
@@ -131,12 +131,12 @@ class NPartyTripleGenerator : public OTTripleGenerator<T>
|
||||
typedef typename T::mac_key_type mac_key_type;
|
||||
typedef typename T::sacri_type sacri_type;
|
||||
|
||||
virtual void generateTriples() = 0;
|
||||
virtual void generateBits() = 0;
|
||||
virtual void generateTriples() { throw not_implemented(); }
|
||||
virtual void generateBits() { throw not_implemented(); }
|
||||
|
||||
public:
|
||||
vector< ShareTriple_<sacri_type, mac_key_type, 2> > uncheckedTriples;
|
||||
vector<InputTuple<Share<sacri_type>>> inputs;
|
||||
vector<InputTuple<typename T::input_type>> inputs;
|
||||
|
||||
NPartyTripleGenerator(const OTTripleSetup& setup, const Names& names,
|
||||
int thread_num, int nTriples, int nloops, MascotParams& machine,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user