Mixed computation, binary computation with XOR-based MACs.

This commit is contained in:
Marcel Keller
2019-12-23 18:42:12 +01:00
parent 12773c4d24
commit 6fa65c3141
171 changed files with 2872 additions and 1115 deletions

View File

@@ -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");

View File

@@ -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; }

View File

@@ -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

View File

@@ -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):

View File

@@ -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)

View File

@@ -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

View File

@@ -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]

View File

@@ -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()

View File

@@ -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):

View File

@@ -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))

View File

@@ -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

View File

@@ -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) - \

View File

@@ -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):

View File

@@ -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):

View File

@@ -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 = {}

View File

@@ -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>

View File

@@ -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>

View File

@@ -3,6 +3,9 @@
*
*/
#include "GC/SemiSecret.h"
#include "GC/SemiPrep.h"
#include "Protocols/SemiMC.hpp"
#include "Protocols/SemiPrep.hpp"
#include "Protocols/SemiInput.hpp"

View File

@@ -212,4 +212,13 @@ class closed_connection
}
};
class no_singleton : runtime_error
{
public:
no_singleton(string msg) :
runtime_error(msg)
{
}
};
#endif

View File

@@ -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"; }

View File

@@ -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_ */

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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
View 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_ */

View File

@@ -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>

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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(); }

View File

@@ -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

View File

@@ -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)
{
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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

View File

@@ -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;

View File

@@ -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();

View File

@@ -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 */

View File

@@ -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

View File

@@ -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
View 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
View 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
View 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
View 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
View 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;
}
}

View File

@@ -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) :

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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()

View File

@@ -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_ */

View File

@@ -5,6 +5,7 @@
#include "Processor/config.h"
#include "Protocols/Share.h"
#include "GC/TinierSecret.h"
#include "Player-Online.hpp"

View File

@@ -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.

View File

@@ -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
View File

@@ -0,0 +1,2 @@
#include "Rep.hpp"
#include "Protocols/Spdz2kPrep.hpp"

View File

@@ -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>>;

View File

@@ -4,6 +4,7 @@
*/
#include "Protocols/Spdz2kShare.h"
#include "Protocols/Spdz2kPrep.h"
#include "Processor/Data_Files.hpp"
#include "Processor/Instruction.hpp"

View File

@@ -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)
{

View File

@@ -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"

View File

@@ -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)
{

View File

@@ -3,6 +3,8 @@
*
*/
#include "Protocols/MaliciousRep3Share.h"
#include "Machines/Rep.hpp"
#include "BMR/RealProgramParty.hpp"

View File

@@ -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)
{

View File

@@ -1,6 +1,7 @@
#include "Player-Online.hpp"
#include "Math/gfp.h"
#include "GC/TinierSecret.h"
int main(int argc, const char** argv)
{

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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
View 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);
}

View File

@@ -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
View 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_ */

View File

@@ -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_ */

View File

@@ -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>;

View File

@@ -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

View File

@@ -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_ */

View File

@@ -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
{

View File

@@ -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);

View File

@@ -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;

View File

@@ -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()
{

View File

@@ -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);

View File

@@ -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_ */

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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; }

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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; }

View File

@@ -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>

View File

@@ -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

View File

@@ -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)

View File

@@ -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);

View File

@@ -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