mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-09 13:37:58 -05:00
Functionality to call high-level code from C++.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -49,6 +49,7 @@ callgrind.out.*
|
||||
Programs/Bytecode/*
|
||||
Programs/Schedules/*
|
||||
Programs/Public-Input/*
|
||||
Programs/Functions
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -13,3 +13,6 @@
|
||||
[submodule "deps/SimplestOT_C"]
|
||||
path = deps/SimplestOT_C
|
||||
url = https://github.com/mkskeller/SimplestOT_C
|
||||
[submodule "deps/sse2neon"]
|
||||
path = deps/sse2neon
|
||||
url = https://github.com/DLTcollab/sse2neon
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
The changelog explains changes pulled through from the private development repository. Bug fixes and small enhancements are committed between releases and not documented here.
|
||||
|
||||
## 0.4.0 (November 21, 2024)
|
||||
|
||||
- Functionality to call high-level code from C++
|
||||
- Matrix triples from file for all appropriate protocols
|
||||
- Exit with message on errors instead of uncaught exceptions
|
||||
- Reduce memory usage for binary memory
|
||||
- Optimized cint-regint conversion in Dealer protocol
|
||||
- Fixed security bug: missing MAC check in probabilistic truncation
|
||||
|
||||
## 0.3.9 (July 9, 2024)
|
||||
|
||||
- Inference with non-sequential PyTorch networks
|
||||
|
||||
2
CONFIG
2
CONFIG
@@ -71,6 +71,8 @@ CXX = clang++
|
||||
# use CONFIG.mine to overwrite DIR settings
|
||||
-include CONFIG.mine
|
||||
|
||||
AVX_SIMPLEOT := $(AVX_OT)
|
||||
|
||||
ifeq ($(USE_GF2N_LONG),1)
|
||||
GF2N_LONG = -DUSE_GF2N_LONG
|
||||
endif
|
||||
|
||||
@@ -540,8 +540,8 @@ class split(base.Instruction):
|
||||
|
||||
:param: number of arguments to follow (number of bits times number of additive shares plus one)
|
||||
:param: source (sint)
|
||||
:param: first share of least significant bit
|
||||
:param: second share of least significant bit
|
||||
:param: first share of least significant bit (sbit)
|
||||
:param: second share of least significant bit (sbit)
|
||||
:param: (remaining share of least significant bit)...
|
||||
:param: (repeat from first share for bit one step higher)...
|
||||
"""
|
||||
|
||||
@@ -737,6 +737,7 @@ class sbitvec(_vec, _bit, _binary):
|
||||
:py:obj:`v` and the columns by calling :py:obj:`elements`.
|
||||
"""
|
||||
class sbitvecn(cls, _structure):
|
||||
n_bits = n
|
||||
@staticmethod
|
||||
def get_type(n):
|
||||
return cls.get_type(n)
|
||||
@@ -757,17 +758,19 @@ class sbitvec(_vec, _bit, _binary):
|
||||
|
||||
:param: player (int)
|
||||
"""
|
||||
v = [0] * n
|
||||
sbits._check_input_player(player)
|
||||
instructions_base.check_vector_size(size)
|
||||
for i in range(size):
|
||||
vv = [sbit() for i in range(n)]
|
||||
inst.inputbvec(n + 3, f, player, *vv)
|
||||
for j in range(n):
|
||||
tmp = vv[j] << i
|
||||
v[j] = tmp ^ v[j]
|
||||
sbits._check_input_player(player)
|
||||
return cls.from_vec(v)
|
||||
if size == 1:
|
||||
res = cls.from_vec(sbit() for i in range(n))
|
||||
inst.inputbvec(n + 3, f, player, *res.v)
|
||||
return res
|
||||
else:
|
||||
elements = []
|
||||
for i in range(size):
|
||||
v = sbits.get_type(n)()
|
||||
inst.inputb(player, n, f, v)
|
||||
elements.append(v)
|
||||
return cls(elements)
|
||||
get_raw_input_from = get_input_from
|
||||
@classmethod
|
||||
def from_vec(cls, vector):
|
||||
|
||||
@@ -178,6 +178,8 @@ class StraightlineAllocator:
|
||||
dup = dup.vectorbase
|
||||
self.alloc[dup] = self.alloc[base]
|
||||
dup.i = self.alloc[base]
|
||||
if not dup.dup_count:
|
||||
dup.dup_count = len(base.duplicates)
|
||||
|
||||
def dealloc_reg(self, reg, inst, free):
|
||||
if reg.vector:
|
||||
@@ -275,8 +277,9 @@ class StraightlineAllocator:
|
||||
for reg in self.alloc:
|
||||
for x in reg.get_all():
|
||||
if x not in self.dealloc and reg not in self.dealloc \
|
||||
and len(x.duplicates) == 0:
|
||||
print('Warning: read before write at register', x)
|
||||
and len(x.duplicates) == x.dup_count:
|
||||
print('Warning: read before write at register %s/%x' %
|
||||
(x, id(x)))
|
||||
print('\tregister trace: %s' % format_trace(x.caller,
|
||||
'\t\t'))
|
||||
if options.stop:
|
||||
@@ -750,6 +753,8 @@ class Merger:
|
||||
G.remove_node(i)
|
||||
merge_nodes.discard(i)
|
||||
stats[type(instructions[i]).__name__] += 1
|
||||
for reg in instructions[i].get_def():
|
||||
self.block.parent.program.base_addresses.pop(reg)
|
||||
instructions[i] = None
|
||||
if unused_result:
|
||||
eliminate(i)
|
||||
|
||||
@@ -13,8 +13,18 @@ from .program import Program, defaults
|
||||
|
||||
|
||||
class Compiler:
|
||||
singleton = None
|
||||
|
||||
def __init__(self, custom_args=None, usage=None, execute=False,
|
||||
split_args=False):
|
||||
if Compiler.singleton:
|
||||
raise CompilerError(
|
||||
"Cannot have more than one compiler instance. "
|
||||
"It's not possible to run direct compilation programs with "
|
||||
"compile.py or compile-run.py.")
|
||||
else:
|
||||
Compiler.singleton = self
|
||||
|
||||
if usage:
|
||||
self.usage = usage
|
||||
else:
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
""" This module implements `Dijkstra's algorithm
|
||||
<https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm>`_ based on
|
||||
oblivious RAM. """
|
||||
|
||||
|
||||
from Compiler.oram import *
|
||||
|
||||
from Compiler.program import Program
|
||||
@@ -222,7 +227,21 @@ class HeapQ(object):
|
||||
print_ln()
|
||||
print_ln()
|
||||
|
||||
def dijkstra(source, edges, e_index, oram_type, n_loops=None, int_type=None):
|
||||
def dijkstra(source, edges, e_index, oram_type, n_loops=None, int_type=None,
|
||||
debug=False):
|
||||
""" Securely compute Dijstra's algorithm on a secret graph. See
|
||||
:download:`../Programs/Source/dijkstra_example.mpc` for an
|
||||
explanation of the required inputs.
|
||||
|
||||
:param source: source node (secret or clear-text integer)
|
||||
:param edges: ORAM representation of edges
|
||||
:param e_index: ORAM representation of vertices
|
||||
:param oram_type: ORAM type to use internally (default:
|
||||
:py:func:`~Compiler.oram.OptimalORAM`)
|
||||
:param n_loops: when to stop (default: number of edges)
|
||||
:param int_type: secret integer type (default: sint)
|
||||
|
||||
"""
|
||||
vert_loops = n_loops * e_index.size // edges.size \
|
||||
if n_loops else -1
|
||||
dist = oram_type(e_index.size, entry_size=(32,log2(e_index.size)), \
|
||||
@@ -267,27 +286,46 @@ def dijkstra(source, edges, e_index, oram_type, n_loops=None, int_type=None):
|
||||
dist.access(v, (basic_type(alt), u), is_shorter)
|
||||
#previous.access(v, u, is_shorter)
|
||||
Q.update(v, basic_type(alt), is_shorter)
|
||||
print_ln('u: %s, v: %s, alt: %s, dv: %s, first visit: %s', \
|
||||
u.reveal(), v.reveal(), alt.reveal(), dv[0].reveal(), \
|
||||
not_visited.reveal())
|
||||
if debug:
|
||||
print_ln('u: %s, v: %s, alt: %s, dv: %s, first visit: %s, '
|
||||
'shorter: %s, running: %s, queue size: %s, last edge: %s',
|
||||
u.reveal(), v.reveal(), alt.reveal(), dv[0].reveal(),
|
||||
not_visited.reveal(), is_shorter.reveal(),
|
||||
running.reveal(), Q.size.reveal(), last_edge.reveal())
|
||||
return dist
|
||||
|
||||
def convert_graph(G):
|
||||
edges = [None] * (2 * G.size())
|
||||
e_index = [None] * (len(G))
|
||||
i = 0
|
||||
for v in G:
|
||||
e_index[v] = i
|
||||
for u in G[v]:
|
||||
edges[i] = [u, G[v][u]['weight'], 0]
|
||||
i += 1
|
||||
edges[i-1][-1] = 1
|
||||
return edges, e_index
|
||||
|
||||
def test_dijkstra(G, source, oram_type=ORAM, n_loops=None, int_type=sint):
|
||||
""" Convert a `NetworkX directed graph
|
||||
<https://networkx.org/documentation/stable/reference/classes/digraph.html>`_
|
||||
to the cleartext representation of what :py:func:`dijkstra` expects. """
|
||||
G = G.copy()
|
||||
for u in G:
|
||||
for v in G[u]:
|
||||
G[u][v].setdefault('weight', 1)
|
||||
edges = [None] * (2 * G.size())
|
||||
e_index = [None] * (len(G))
|
||||
i = 0
|
||||
for v in sorted(G):
|
||||
e_index[v] = i
|
||||
for u in sorted(G[v]):
|
||||
edges[i] = [u, G[v][u]['weight'], 0]
|
||||
i += 1
|
||||
if not G[v]:
|
||||
edges[i] = [v, 0, 0]
|
||||
i += 1
|
||||
edges[i-1][-1] = 1
|
||||
return list(filter(lambda x: x, edges)), e_index
|
||||
|
||||
def test_dijkstra(G, source, oram_type=ORAM, n_loops=None,
|
||||
int_type=sint):
|
||||
""" Securely compute Dijstra's algorithm on a cleartext graph.
|
||||
|
||||
:param G: directed graph with NetworkX interface
|
||||
:param source: source node (secret or clear-text integer)
|
||||
:param n_loops: when to stop (default: number of edges)
|
||||
:param int_type: secret integer type (default: sint)
|
||||
|
||||
"""
|
||||
edges_list, e_index_list = convert_graph(G)
|
||||
edges = oram_type(len(edges_list), \
|
||||
entry_size=(log2(len(G)), log2(len(G)), 1), \
|
||||
|
||||
@@ -399,7 +399,7 @@ class stop(base.Instruction):
|
||||
arg_format = ['i']
|
||||
|
||||
class use(base.Instruction):
|
||||
""" Offline data usage. Necessary to avoid reusage while using
|
||||
r""" Offline data usage. Necessary to avoid reusage while using
|
||||
preprocessing from files. Also used to multithreading for expensive
|
||||
preprocessing.
|
||||
|
||||
@@ -419,7 +419,7 @@ class use(base.Instruction):
|
||||
args[2].i}
|
||||
|
||||
class use_inp(base.Instruction):
|
||||
""" Input usage. Necessary to avoid reusage while using
|
||||
r""" Input usage. Necessary to avoid reusage while using
|
||||
preprocessing from files.
|
||||
|
||||
:param: domain (0: integer, 1: :math:`\mathrm{GF}(2^n)`, 2: bit)
|
||||
@@ -1738,7 +1738,7 @@ class print_reg_plains(base.IOInstruction):
|
||||
arg_format = ['s']
|
||||
|
||||
class cond_print_plain(base.IOInstruction):
|
||||
""" Conditionally output clear register (with precision).
|
||||
r""" Conditionally output clear register (with precision).
|
||||
Outputs :math:`x \cdot 2^p` where :math:`p` is the precision.
|
||||
|
||||
:param: condition (cint, no output if zero)
|
||||
@@ -1989,7 +1989,7 @@ class closeclientconnection(base.IOInstruction):
|
||||
code = base.opcodes['CLOSECLIENTCONNECTION']
|
||||
arg_format = ['ci']
|
||||
|
||||
class writesharestofile(base.IOInstruction):
|
||||
class writesharestofile(base.VectorInstruction, base.IOInstruction):
|
||||
""" Write shares to ``Persistence/Transactions-P<playerno>.data``
|
||||
(appending at the end).
|
||||
|
||||
@@ -2002,11 +2002,12 @@ class writesharestofile(base.IOInstruction):
|
||||
__slots__ = []
|
||||
code = base.opcodes['WRITEFILESHARE']
|
||||
arg_format = tools.chain(['ci'], itertools.repeat('s'))
|
||||
vector_index = 1
|
||||
|
||||
def has_var_args(self):
|
||||
return True
|
||||
|
||||
class readsharesfromfile(base.IOInstruction):
|
||||
class readsharesfromfile(base.VectorInstruction, base.IOInstruction):
|
||||
""" Read shares from ``Persistence/Transactions-P<playerno>.data``.
|
||||
|
||||
:param: number of arguments to follow / number of shares plus two (int)
|
||||
@@ -2018,6 +2019,7 @@ class readsharesfromfile(base.IOInstruction):
|
||||
__slots__ = []
|
||||
code = base.opcodes['READFILESHARE']
|
||||
arg_format = tools.chain(['ci', 'ciw'], itertools.repeat('sw'))
|
||||
vector_index = 2
|
||||
|
||||
def has_var_args(self):
|
||||
return True
|
||||
@@ -2341,7 +2343,7 @@ class convint(base.Instruction):
|
||||
|
||||
@base.vectorize
|
||||
class convmodp(base.Instruction):
|
||||
""" Convert clear integer register (vector) to clear register
|
||||
r""" Convert clear integer register (vector) to clear register
|
||||
(vector). If the bit length is zero, the unsigned conversion is
|
||||
used, otherwise signed conversion is used. This makes a difference
|
||||
when computing modulo a prime :math:`p`. Signed conversion of
|
||||
@@ -2814,13 +2816,11 @@ class check(base.Instruction):
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class sqrs(base.CISC):
|
||||
""" Secret squaring $s_i = s_j \cdot s_j$. """
|
||||
r""" Secret squaring $s_i = s_j \cdot s_j$. """
|
||||
__slots__ = []
|
||||
arg_format = ['sw', 's']
|
||||
|
||||
def expand(self):
|
||||
if program.options.ring:
|
||||
return muls(self.args[0], self.args[1], self.args[1])
|
||||
s = [program.curr_block.new_reg('s') for i in range(6)]
|
||||
c = [program.curr_block.new_reg('c') for i in range(2)]
|
||||
square(s[0], s[1])
|
||||
|
||||
@@ -1200,9 +1200,11 @@ class VarArgsInstruction(Instruction):
|
||||
class VectorInstruction(Instruction):
|
||||
__slots__ = []
|
||||
is_vec = lambda self: True
|
||||
vector_index = 0
|
||||
|
||||
def get_code(self):
|
||||
return super(VectorInstruction, self).get_code(len(self.args[0]))
|
||||
return super(VectorInstruction, self).get_code(
|
||||
len(self.args[self.vector_index]))
|
||||
|
||||
class Ciscable(Instruction):
|
||||
def copy(self, size, subs):
|
||||
|
||||
@@ -402,7 +402,8 @@ class FunctionCallTape(FunctionTape):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(FunctionTape, self).__init__(*args, **kwargs)
|
||||
self.instances = {}
|
||||
def __call__(self, *args, **kwargs):
|
||||
@staticmethod
|
||||
def get_key(args, kwargs):
|
||||
key = (get_program(),)
|
||||
def process_for_key(arg):
|
||||
nonlocal key
|
||||
@@ -419,6 +420,9 @@ class FunctionCallTape(FunctionTape):
|
||||
for name, arg in sorted(kwargs.items()):
|
||||
key += (name, 'kw')
|
||||
process_for_key(arg)
|
||||
return key
|
||||
def __call__(self, *args, **kwargs):
|
||||
key = self.get_key(args, kwargs)
|
||||
if key not in self.instances:
|
||||
my_args = []
|
||||
def wrapped_function():
|
||||
@@ -502,6 +506,60 @@ class FunctionCallTape(FunctionTape):
|
||||
break_point('call-%s' % self.name)
|
||||
return untuplify(tuple(out_result))
|
||||
|
||||
class ExportFunction(FunctionCallTape):
|
||||
def __init__(self, function):
|
||||
super(ExportFunction, self).__init__(function)
|
||||
self.done = set()
|
||||
def __call__(self, *args, **kwargs):
|
||||
if kwargs:
|
||||
raise CompilerError('keyword arguments not supported')
|
||||
def arg_signature(arg):
|
||||
if isinstance(arg, types._structure):
|
||||
return '%s:%d' % (arg.arg_type(), arg.size)
|
||||
elif isinstance(arg, types._vectorizable):
|
||||
from .GC.types import sbitvec
|
||||
if issubclass(arg.value_type, sbitvec):
|
||||
return 'sbv:[%dx%d]' % (arg.total_size(),
|
||||
arg.value_type.n_bits)
|
||||
else:
|
||||
return '%s:[%d]' % (arg.value_type.arg_type(),
|
||||
arg.total_size())
|
||||
else:
|
||||
raise CompilerError('argument not supported: %s' % arg)
|
||||
signature = []
|
||||
for arg in args:
|
||||
signature.append(arg_signature(arg))
|
||||
signature = tuple(signature)
|
||||
key = self.get_key(args, kwargs)
|
||||
if key in self.instances and signature not in self.done:
|
||||
raise CompilerError('signature conflict')
|
||||
super(ExportFunction, self).__call__(*args, **kwargs)
|
||||
if signature not in self.done:
|
||||
filename = '%s/%s/%s-%s' % (get_program().programs_dir, 'Functions',
|
||||
self.name, '-'.join(signature))
|
||||
print('Writing to', filename)
|
||||
out = open(filename, 'w')
|
||||
print(get_program().name, file=out)
|
||||
print(self.instances[key][0], file=out)
|
||||
result = self.instances[key][1]
|
||||
try:
|
||||
if result is not None:
|
||||
result = untuplify(result)
|
||||
print(arg_signature(result), result.i, file=out)
|
||||
else:
|
||||
print('- 0', file=out)
|
||||
except CompilerError:
|
||||
raise CompilerError('return type not supported: %s' % result)
|
||||
for arg in self.instances[key][2]:
|
||||
if isinstance(arg, types._structure):
|
||||
print(arg.i, end=' ', file=out)
|
||||
elif isinstance(arg, types._vectorizable):
|
||||
print(arg.address, end=' ', file=out)
|
||||
else:
|
||||
CompilerError('argument not supported: %s', arg)
|
||||
print(file=out)
|
||||
self.done.add(signature)
|
||||
|
||||
def function_tape(function):
|
||||
return FunctionTape(function)
|
||||
|
||||
@@ -589,6 +647,9 @@ def function(function):
|
||||
"""
|
||||
return FunctionCallTape(function)
|
||||
|
||||
def export(function):
|
||||
return ExportFunction(function)
|
||||
|
||||
def memorize(x, write=True):
|
||||
if isinstance(x, (tuple, list)):
|
||||
return tuple(memorize(i, write=write) for i in x)
|
||||
@@ -898,8 +959,10 @@ def for_range(start, stop=None, step=None):
|
||||
|
||||
"""
|
||||
def decorator(loop_body):
|
||||
get_tape().unused_decorators.pop(decorator)
|
||||
range_loop(loop_body, start, stop, step)
|
||||
return loop_body
|
||||
get_tape().unused_decorators[decorator] = 'for_range'
|
||||
return decorator
|
||||
|
||||
def for_range_parallel(n_parallel, n_loops):
|
||||
@@ -948,7 +1011,7 @@ def for_range_opt(start, stop=None, step=None, budget=None):
|
||||
:param start/stop/step: int/regint/cint (used as in :py:func:`range`)
|
||||
or :py:obj:`start` only as list/tuple of int (see below)
|
||||
:param budget: number of instructions after which to start optimization
|
||||
(default is 100,000)
|
||||
(default is 1000 or as given with ``--budget``)
|
||||
|
||||
Example:
|
||||
|
||||
@@ -1487,7 +1550,7 @@ def while_do(condition, *args):
|
||||
return loop_body
|
||||
return decorator
|
||||
|
||||
def _run_and_link(function, g=None, lock_lists=True):
|
||||
def _run_and_link(function, g=None, lock_lists=True, allow_return=False):
|
||||
if g is None:
|
||||
g = function.__globals__
|
||||
if lock_lists:
|
||||
@@ -1504,6 +1567,9 @@ def _run_and_link(function, g=None, lock_lists=True):
|
||||
g[x] = A(g[x])
|
||||
pre = copy.copy(g)
|
||||
res = function()
|
||||
if res is not None and not allow_return:
|
||||
raise CompilerError('Conditional blocks cannot return values. '
|
||||
'Use if_else instead: https://mp-spdz.readthedocs.io/en/latest/Compiler.html#Compiler.types.regint.if_else')
|
||||
_link(pre, g)
|
||||
return res
|
||||
|
||||
@@ -1536,7 +1602,7 @@ def do_while(loop_fn, g=None):
|
||||
name='begin-loop')
|
||||
get_tape().loop_breaks.append([])
|
||||
loop_block = instructions.program.curr_block
|
||||
condition = _run_and_link(loop_fn, g)
|
||||
condition = _run_and_link(loop_fn, g, allow_return=True)
|
||||
if callable(condition):
|
||||
condition = condition()
|
||||
branch = instructions.jmpnz(regint.conv(condition), 0, add_to_prog=False)
|
||||
@@ -1558,7 +1624,9 @@ def if_then(condition):
|
||||
condition = condition()
|
||||
try:
|
||||
if not condition.is_clear:
|
||||
raise CompilerError('cannot branch on secret values')
|
||||
raise CompilerError(
|
||||
'cannot branch on secret values, use if_else instead: '
|
||||
'https://mp-spdz.readthedocs.io/en/latest/Compiler.html#Compiler.types.sint.if_else')
|
||||
except AttributeError:
|
||||
pass
|
||||
state.condition = regint.conv(condition)
|
||||
|
||||
@@ -849,7 +849,7 @@ class Dense(DenseBase):
|
||||
prod = MultiArray([N, self.d, self.d_out], sfix)
|
||||
else:
|
||||
prod = self.f_input
|
||||
max_size = get_program().budget // self.d_out
|
||||
max_size = get_program().budget
|
||||
@multithread(self.n_threads, N, max_size)
|
||||
def _(base, size):
|
||||
X_sub = sfix.Matrix(self.N, self.d_in, address=self.X.address)
|
||||
@@ -1316,12 +1316,12 @@ class Add(NoVariableLayer):
|
||||
self.inputs = inputs
|
||||
|
||||
def _forward(self, batch=[0]):
|
||||
assert len(batch) == 1
|
||||
@multithread(self.n_threads, self.Y[0].total_size())
|
||||
def _(base, size):
|
||||
tmp = sum(inp.Y[batch[0]].get_vector(base, size)
|
||||
for inp in self.inputs)
|
||||
self.Y[batch[0]].assign_vector(tmp, base)
|
||||
for bb in batch:
|
||||
tmp = sum(inp.Y[bb].get_vector(base, size)
|
||||
for inp in self.inputs)
|
||||
self.Y[bb].assign_vector(tmp, base)
|
||||
|
||||
class FusedBatchNorm(Layer):
|
||||
""" Fixed-point fused batch normalization layer (inference only).
|
||||
@@ -1400,11 +1400,11 @@ class BatchNorm(Layer):
|
||||
|
||||
def _output(self, batch, mu, var):
|
||||
factor = sfix.Array(len(mu))
|
||||
factor[:] = self.InvertSqrt(var[:] + self.epsilon)
|
||||
factor[:] = self.InvertSqrt(var[:] + self.epsilon) * self.weights[:]
|
||||
@for_range_opt_multithread(self.n_threads,
|
||||
[len(batch), self.X.sizes[1]])
|
||||
def _(i, j):
|
||||
tmp = self.weights[:] * (self.X[i][j][:] - mu[:]) * factor[:]
|
||||
tmp = (self.X[i][j][:] - mu[:]) * factor[:]
|
||||
self.my_Y[i][j][:] = self.bias[:] + tmp
|
||||
|
||||
@_layer_method_call_tape
|
||||
@@ -2233,7 +2233,7 @@ class Optimizer:
|
||||
res.output_stats = 'output_stats' in program.args
|
||||
return res
|
||||
|
||||
def __init__(self, layers=[], report_loss=None):
|
||||
def __init__(self, layers=[], report_loss=None, time_layers=False):
|
||||
if get_program().options.binary:
|
||||
raise CompilerError(
|
||||
'machine learning code not compatible with binary circuits')
|
||||
@@ -2248,6 +2248,10 @@ class Optimizer:
|
||||
self.stopped_on_loss = MemValue(0)
|
||||
self.stopped_on_low_loss = MemValue(0)
|
||||
self.layers = layers
|
||||
self.time_layers = time_layers
|
||||
if time_layers:
|
||||
for i, layer in enumerate(layers):
|
||||
print('Timer %d: %s' % (100 + i, repr(layer)))
|
||||
|
||||
@property
|
||||
def layers(self):
|
||||
@@ -2667,8 +2671,12 @@ class Optimizer:
|
||||
if model_input:
|
||||
for layer in self.layers:
|
||||
layer.input_from(0)
|
||||
elif reset:
|
||||
elif reset and not 'no_reset' in program.args:
|
||||
self.reset()
|
||||
else:
|
||||
for layer in self.layers:
|
||||
for theta in layer.thetas():
|
||||
theta.alloc()
|
||||
if 'one_iter' in program.args:
|
||||
print_float_prec(16)
|
||||
self.output_weights()
|
||||
@@ -2689,6 +2697,8 @@ class Optimizer:
|
||||
if 'bench10' in program.args or 'bench1' in program.args:
|
||||
n = 1 if 'bench1' in program.args else 10
|
||||
print('benchmarking %s iterations' % n)
|
||||
# force allocatoin
|
||||
self.layers[0].X, self.layers[-1].Y
|
||||
@for_range(n)
|
||||
def _(i):
|
||||
batch = Array.create_from(regint.inc(batch_size))
|
||||
|
||||
@@ -422,7 +422,7 @@ def mux_exp(x, y, block_size=8):
|
||||
@types.vectorize
|
||||
@instructions_base.sfix_cisc
|
||||
def log2_fx(x, use_division=True):
|
||||
"""
|
||||
r"""
|
||||
Returns the result of :math:`\log_2(x)` for any unbounded
|
||||
number. This is achieved by changing :py:obj:`x` into
|
||||
:math:`f \cdot 2^n` where f is bounded by :math:`[0.5, 1]`. Then the
|
||||
@@ -463,7 +463,7 @@ def log2_fx(x, use_division=True):
|
||||
|
||||
|
||||
def pow_fx(x, y, zero_output=False):
|
||||
"""
|
||||
r"""
|
||||
Returns the value of the expression :math:`x^y` where both inputs
|
||||
are secret shared. It uses :py:func:`log2_fx` together with
|
||||
:py:func:`exp2_fx` to calculate the expression :math:`2^{y \log_2(x)}`.
|
||||
@@ -487,7 +487,7 @@ def pow_fx(x, y, zero_output=False):
|
||||
|
||||
|
||||
def log_fx(x, b):
|
||||
"""
|
||||
r"""
|
||||
Returns the value of the expression :math:`\log_b(x)` where
|
||||
:py:obj:`x` is secret shared. It uses :py:func:`log2_fx` to
|
||||
calculate the expression :math:`\log_b(2) \cdot \log_2(x)`.
|
||||
@@ -859,7 +859,7 @@ def atan(x):
|
||||
|
||||
|
||||
def asin(x):
|
||||
"""
|
||||
r"""
|
||||
Returns the arcsine (sfix) of any given fractional value.
|
||||
|
||||
:param x: fractional input (sfix). valid interval is :math:`-1 \le x \le 1`
|
||||
@@ -875,7 +875,7 @@ def asin(x):
|
||||
|
||||
|
||||
def acos(x):
|
||||
"""
|
||||
r"""
|
||||
Returns the arccosine (sfix) of any given fractional value.
|
||||
|
||||
:param x: fractional input (sfix). :math:`-1 \le x \le 1`
|
||||
@@ -887,7 +887,7 @@ def acos(x):
|
||||
|
||||
|
||||
def tanh(x):
|
||||
"""
|
||||
r"""
|
||||
Hyperbolic tangent. For efficiency, accuracy is diminished
|
||||
around :math:`\pm \log(k - f - 2) / 2` where :math:`k` and
|
||||
:math:`f` denote the fixed-point parameters.
|
||||
|
||||
@@ -9,6 +9,11 @@ secret index::
|
||||
i = sint.get_input_from(0)
|
||||
a[i] = sint.get_input_from(1)
|
||||
|
||||
`The introductory book by Evans et
|
||||
al. <https://securecomputation.org>`_ contains `a chapter dedicated to
|
||||
oblivious RAM
|
||||
<https://securecomputation.org/docs/ch5-obliviousdata.pdf>`_.
|
||||
|
||||
"""
|
||||
|
||||
import random
|
||||
@@ -41,6 +46,7 @@ debug_online = False
|
||||
crash_on_overflow = False
|
||||
use_insecure_randomness = False
|
||||
debug_ram_size = False
|
||||
single_thread = False
|
||||
|
||||
def maybe_start_timer(n):
|
||||
if detailed_timing:
|
||||
@@ -844,7 +850,7 @@ class TrivialORAM(RefTrivialORAM, AbstractORAM):
|
||||
start_timer()
|
||||
|
||||
def get_n_threads(n_loops):
|
||||
if n_threads is None:
|
||||
if n_threads is None and not single_thread:
|
||||
if n_loops > 2048:
|
||||
return 8
|
||||
else:
|
||||
@@ -1038,7 +1044,7 @@ class LocalIndexStructure(List):
|
||||
__getitem__ = lambda self,index: List.__getitem__(self, index)[0]
|
||||
|
||||
def get_n_threads_for_tree(size):
|
||||
if n_threads_for_tree is None:
|
||||
if n_threads_for_tree is None and not single_thread:
|
||||
if size >= 2**13:
|
||||
return 8
|
||||
else:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""This module contains an implementation of the "Path Oblivious Heap"
|
||||
r"""This module contains an implementation of the "Path Oblivious Heap"
|
||||
oblivious priority queue as proposed by
|
||||
`Shi <https://eprint.iacr.org/2019/274.pdf>`_.
|
||||
|
||||
|
||||
@@ -260,7 +260,7 @@ class Program(object):
|
||||
os.mkdir(dirname)
|
||||
|
||||
# create extra directories if needed
|
||||
for dirname in ["Public-Input", "Bytecode", "Schedules"]:
|
||||
for dirname in ["Public-Input", "Bytecode", "Schedules", "Functions"]:
|
||||
if not os.path.exists(self.programs_dir + "/" + dirname):
|
||||
os.mkdir(self.programs_dir + "/" + dirname)
|
||||
|
||||
@@ -859,6 +859,7 @@ class Tape:
|
||||
self.warned_about_mem = False
|
||||
self.return_values = []
|
||||
self.ran_threads = False
|
||||
self.unused_decorators = {}
|
||||
|
||||
class BasicBlock(object):
|
||||
def __init__(self, parent, name, scope, exit_condition=None,
|
||||
@@ -1054,6 +1055,10 @@ class Tape:
|
||||
print()
|
||||
raise CompilerError("Unclosed if/else blocks, see tracebacks above")
|
||||
|
||||
if self.unused_decorators:
|
||||
raise CompilerError("Unused branching decorators, make sure to write " + ",".join(
|
||||
"'@%s' instead of '%s'" % (x, x) for x in set(self.unused_decorators.values())))
|
||||
|
||||
if self.program.verbose:
|
||||
print(
|
||||
"Processing tape", self.name, "with %d blocks" % len(self.basicblocks)
|
||||
@@ -1561,10 +1566,7 @@ class Tape:
|
||||
def __bool__(self):
|
||||
raise CompilerError(
|
||||
"Cannot derive truth value from register. "
|
||||
"This is a catch-all error appearing if you try to use a "
|
||||
"run-time value where the compiler expects a compile-time "
|
||||
"value, most likely a Python integer. "
|
||||
"In some cases, you can fix this by using 'compile.py -l'."
|
||||
"See https://mp-spdz.readthedocs.io/en/latest/troubleshooting.html#cannot-derive-truth-value-from-register"
|
||||
)
|
||||
|
||||
def __int__(self):
|
||||
@@ -1599,6 +1601,7 @@ class Tape:
|
||||
"caller",
|
||||
"can_eliminate",
|
||||
"duplicates",
|
||||
"dup_count",
|
||||
"block",
|
||||
]
|
||||
maximum_size = 2 ** (64 - inst_base.Instruction.code_length) - 1
|
||||
@@ -1631,6 +1634,7 @@ class Tape:
|
||||
self.vector = []
|
||||
self.can_eliminate = True
|
||||
self.duplicates = util.set_by_id([self])
|
||||
self.dup_count = None
|
||||
if Program.prog.DEBUG:
|
||||
self.caller = [frame[1:] for frame in inspect.stack()[1:]]
|
||||
else:
|
||||
|
||||
@@ -11,7 +11,7 @@ def dest_comp(B):
|
||||
return sum(Tt) - 1
|
||||
|
||||
def reveal_sort(k, D, reverse=False):
|
||||
""" Sort in place according to "perfect" key. The name hints at the fact
|
||||
r""" Sort in place according to "perfect" key. The name hints at the fact
|
||||
that a random order of the keys is revealed.
|
||||
|
||||
:param k: vector or Array of sint containing exactly :math:`0,\dots,n-1`
|
||||
|
||||
@@ -428,7 +428,7 @@ class _int(Tape._no_truth):
|
||||
:return: type depends on inputs (secret if any of them is) """
|
||||
if util.is_constant(other):
|
||||
if other:
|
||||
return self
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
return self + other - self * other
|
||||
@@ -502,14 +502,14 @@ class _bit(Tape._no_truth):
|
||||
return a ^ prod, b ^ prod
|
||||
|
||||
class _gf2n(_bit):
|
||||
""" :math:`\mathrm{GF}(2^n)` functionality. """
|
||||
r""" :math:`\mathrm{GF}(2^n)` functionality. """
|
||||
|
||||
def if_else(self, a, b):
|
||||
""" MUX in :math:`\mathrm{GF}(2^n)` circuits. Similar to :py:meth:`_int.if_else`. """
|
||||
r""" MUX in :math:`\mathrm{GF}(2^n)` circuits. Similar to :py:meth:`_int.if_else`. """
|
||||
return b ^ self * self.hard_conv(a ^ b)
|
||||
|
||||
def cond_swap(self, a, b, t=None):
|
||||
""" Swapping in :math:`\mathrm{GF}(2^n)`. Similar to :py:meth:`_int.if_else`. """
|
||||
r""" Swapping in :math:`\mathrm{GF}(2^n)`. Similar to :py:meth:`_int.if_else`. """
|
||||
prod = self * self.hard_conv(a ^ b)
|
||||
res = a ^ prod, b ^ prod
|
||||
if t is None:
|
||||
@@ -518,7 +518,7 @@ class _gf2n(_bit):
|
||||
return tuple(t.conv(r) for r in res)
|
||||
|
||||
def bit_xor(self, other):
|
||||
""" XOR in :math:`\mathrm{GF}(2^n)` circuits.
|
||||
r""" XOR in :math:`\mathrm{GF}(2^n)` circuits.
|
||||
|
||||
:param self/other: 0 or 1 (any compatible type)
|
||||
:rtype: depending on inputs (secret if any of them is) """
|
||||
@@ -583,6 +583,14 @@ class _structure(Tape._no_truth):
|
||||
def size_for_mem(self):
|
||||
return self.size
|
||||
|
||||
@classmethod
|
||||
def arg_type(cls):
|
||||
if issubclass(cls, _register):
|
||||
return cls.reg_type
|
||||
if issubclass(cls, (cfix, sfix)):
|
||||
return cls.int_type.reg_type
|
||||
raise CompilerError('type not supported as argument: %s' % cls)
|
||||
|
||||
class _secret_structure(_structure):
|
||||
@classmethod
|
||||
def input_tensor_from(cls, player, shape):
|
||||
@@ -1362,7 +1370,7 @@ class cint(_clear, _int):
|
||||
|
||||
|
||||
class cgf2n(_clear, _gf2n):
|
||||
"""
|
||||
r"""
|
||||
Clear :math:`\mathrm{GF}(2^n)` value. n is chosen at runtime. A
|
||||
number operators are supported (``+, -, *, /, **, ^, &, |, ~, ==,
|
||||
!=, <<, >>``), returning either :py:class:`cgf2n` if the other
|
||||
@@ -1381,7 +1389,7 @@ class cgf2n(_clear, _gf2n):
|
||||
|
||||
@classmethod
|
||||
def bit_compose(cls, bits, step=None):
|
||||
""" Clear :math:`\mathrm{GF}(2^n)` bit composition.
|
||||
r""" Clear :math:`\mathrm{GF}(2^n)` bit composition.
|
||||
|
||||
:param bits: list of cgf2n
|
||||
:param step: set every :py:obj:`step`-th bit in output (defaults to 1) """
|
||||
@@ -1478,7 +1486,7 @@ class cgf2n(_clear, _gf2n):
|
||||
|
||||
@vectorize
|
||||
def bit_decompose(self, bit_length=None, step=None):
|
||||
""" Clear bit decomposition.
|
||||
r""" Clear bit decomposition.
|
||||
|
||||
:param bit_length: number of bits (defaults to global :math:`\mathrm{GF}(2^n)` bit length)
|
||||
:param step: extract every :py:obj:`step`-th bit (defaults to 1) """
|
||||
@@ -2685,19 +2693,23 @@ class sint(_secret, _int):
|
||||
writesocketshare(client_id, message_type, values[0].size, *values)
|
||||
|
||||
@classmethod
|
||||
def read_from_file(cls, start, n_items):
|
||||
def read_from_file(cls, start, n_items=1, crash_if_missing=True, size=1):
|
||||
""" Read shares from
|
||||
``Persistence/Transactions-P<playerno>.data``. See :ref:`this
|
||||
section <persistence>` for details on the data format.
|
||||
|
||||
:param start: starting position in number of shares from beginning (int/regint/cint)
|
||||
:param n_items: number of items (int)
|
||||
:param crash_if_missing: crash if file not found (default)
|
||||
:param size: vector size (int)
|
||||
:returns: destination for final position, -1 for eof reached, or -2 for file not found (regint)
|
||||
:returns: list of shares
|
||||
"""
|
||||
shares = [cls(size=1) for i in range(n_items)]
|
||||
shares = [cls(size=size) for i in range(n_items)]
|
||||
stop = regint()
|
||||
readsharesfromfile(regint.conv(start), stop, *shares)
|
||||
if crash_if_missing:
|
||||
library.runtime_error_if(stop == -2, 'Persistence not found')
|
||||
return stop, shares
|
||||
|
||||
@staticmethod
|
||||
@@ -2710,9 +2722,11 @@ class sint(_secret, _int):
|
||||
:param position: start position (int/regint/cint),
|
||||
defaults to end of file
|
||||
"""
|
||||
if isinstance(shares, sint):
|
||||
shares = [shares]
|
||||
for share in shares:
|
||||
assert isinstance(share, sint)
|
||||
assert share.size == 1
|
||||
assert share.size == shares[0].size
|
||||
if position is None:
|
||||
position = -1
|
||||
writesharestofile(regint.conv(position), *shares)
|
||||
@@ -3246,7 +3260,7 @@ class sintbit(sint):
|
||||
__ror__ = __or__
|
||||
|
||||
class sgf2n(_secret, _gf2n):
|
||||
"""
|
||||
r"""
|
||||
Secret :math:`\mathrm{GF}(2^n)` value. n is chosen at runtime. A
|
||||
number operators are supported (``+, -, *, /, **, ^, ~, ==, !=,
|
||||
<<``), :py:class:`sgf2n`. Operators generally work with
|
||||
@@ -3271,7 +3285,7 @@ class sgf2n(_secret, _gf2n):
|
||||
return res
|
||||
|
||||
def add(self, other):
|
||||
""" Secret :math:`\mathrm{GF}(2^n)` addition (XOR).
|
||||
r""" Secret :math:`\mathrm{GF}(2^n)` addition (XOR).
|
||||
|
||||
:param other: sg2fn/cgf2n/regint/int """
|
||||
if isinstance(other, sgf2nint):
|
||||
@@ -3280,7 +3294,7 @@ class sgf2n(_secret, _gf2n):
|
||||
return super(sgf2n, self).add(other)
|
||||
|
||||
def mul(self, other):
|
||||
""" Secret :math:`\mathrm{GF}(2^n)` multiplication.
|
||||
r""" Secret :math:`\mathrm{GF}(2^n)` multiplication.
|
||||
|
||||
:param other: sg2fn/cgf2n/regint/int """
|
||||
if isinstance(other, (sgf2nint)):
|
||||
@@ -3349,7 +3363,7 @@ class sgf2n(_secret, _gf2n):
|
||||
|
||||
@vectorize
|
||||
def right_shift(self, other, bit_length=None):
|
||||
""" Secret right shift by public value:
|
||||
r""" Secret right shift by public value:
|
||||
|
||||
:param other: compile-time (int)
|
||||
:param bit_length: number of bits of :py:obj:`self` (defaults to :math:`\mathrm{GF}(2^n)` bit length) """
|
||||
@@ -4458,6 +4472,7 @@ class _single(_number, _secret_structure):
|
||||
:param start: starting position in number of shares from beginning
|
||||
(int/regint/cint)
|
||||
:param n_items: number of items (int)
|
||||
:param crash_if_missing: crash if file not found (default)
|
||||
:returns: destination for final position, -1 for eof reached,
|
||||
or -2 for file not found (regint)
|
||||
:returns: list of shares
|
||||
@@ -4980,11 +4995,21 @@ class sfix(_fix):
|
||||
return cfix._new(cint.conv(v, size=size), k, f)
|
||||
|
||||
def dot(self, other):
|
||||
""" Dot product with :py:class:`sint`. """
|
||||
""" Dot product with any vector or iterable. """
|
||||
if isinstance(other, sint):
|
||||
return self._new(sint.dot_product(self.v, other), k=self.k, f=self.f)
|
||||
elif isinstance(other, sfix):
|
||||
assert self.k == other.k
|
||||
assert self.f == other.f
|
||||
return self._new(sint.dot_product(self.v, other.v).round(
|
||||
self.k + other.f, self.f, nearest=self.round_nearest,
|
||||
signed=True), k=self.k, f=self.f)
|
||||
elif isinstance(other, (_int, cfix)):
|
||||
return (self * other).sum()
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
other = list(other)
|
||||
assert len(self) == len(other)
|
||||
return sum(a * b for a, b in zip(self, other))
|
||||
|
||||
def reveal_to(self, player):
|
||||
""" Reveal secret value to :py:obj:`player`.
|
||||
@@ -5280,7 +5305,7 @@ class squant_params(object):
|
||||
return squant._new(shifted, params=self)
|
||||
|
||||
class sfloat(_number, _secret_structure):
|
||||
"""
|
||||
r"""
|
||||
Secret floating-point number.
|
||||
Represents :math:`(1 - 2s) \cdot (1 - z)\cdot v \cdot 2^p`.
|
||||
|
||||
@@ -5769,6 +5794,23 @@ def _get_type(t):
|
||||
return t
|
||||
|
||||
class _vectorizable:
|
||||
@classmethod
|
||||
def check(cls, index, length, sizes):
|
||||
if isinstance(index, _clear):
|
||||
index = regint.conv(index)
|
||||
if length is not None:
|
||||
from .GC.types import cbits
|
||||
if isinstance(index, int):
|
||||
index += length * (index < 0)
|
||||
if index >= length or index < 0:
|
||||
raise IndexError('index %s, length %s' % \
|
||||
(str(index), str(length)))
|
||||
elif cls.check_indices and not isinstance(index, cbits):
|
||||
library.runtime_error_if(
|
||||
(index >= length).bit_or(index < 0),
|
||||
'overflow: %s/%s', index, sizes)
|
||||
return index
|
||||
|
||||
def reveal_to_clients(self, clients):
|
||||
""" Reveal contents to list of clients.
|
||||
|
||||
@@ -5807,11 +5849,11 @@ class Array(_vectorizable):
|
||||
|
||||
@classmethod
|
||||
def create_from(cls, l):
|
||||
""" Convert Python iterator or vector to array. Basic type will be taken
|
||||
from first element, further elements must to be convertible to
|
||||
that.
|
||||
""" Convert Python iterator or vector to array or copy another array.
|
||||
Basic type will be taken from first element, further elements
|
||||
must to be convertible to that.
|
||||
|
||||
:param l: Python iterable or register vector
|
||||
:param l: Python iterable, register vector, or array
|
||||
:returns: :py:class:`Array` of appropriate type containing the contents
|
||||
of :py:obj:`l`
|
||||
|
||||
@@ -5871,19 +5913,7 @@ class Array(_vectorizable):
|
||||
if isinstance(index, (_secret, _single)):
|
||||
raise CompilerError('need cleartext index')
|
||||
key = str(index), size or 1
|
||||
if isinstance(index, _clear):
|
||||
index = regint.conv(index)
|
||||
if self.length is not None:
|
||||
from .GC.types import cbits
|
||||
if isinstance(index, int):
|
||||
index += self.length * (index < 0)
|
||||
if index >= self.length or index < 0:
|
||||
raise IndexError('index %s, length %s' % \
|
||||
(str(index), str(self.length)))
|
||||
elif self.check_indices and not isinstance(index, cbits):
|
||||
library.runtime_error_if(
|
||||
(index >= self.length).bit_or(index < 0),
|
||||
'overflow: %s/%s', index, self.length)
|
||||
index = self.check(index, self.length, self.length)
|
||||
if (program.curr_block, key) not in self.address_cache:
|
||||
n = self.value_type.n_elements()
|
||||
length = self.length
|
||||
@@ -6178,13 +6208,14 @@ class Array(_vectorizable):
|
||||
def _(i):
|
||||
self[i] = input_from(player, **kwargs)
|
||||
|
||||
def read_from_file(self, start):
|
||||
def read_from_file(self, start, *args, **kwargs):
|
||||
""" Read content from ``Persistence/Transactions-P<playerno>.data``.
|
||||
Precision must be the same as when storing if applicable. See
|
||||
:ref:`this section <persistence>` for details on the data format.
|
||||
|
||||
:param start: starting position in number of shares from beginning
|
||||
(int/regint/cint)
|
||||
:param crash_if_missing: crash if file not found (default)
|
||||
:returns: destination for final position, -1 for eof reached,
|
||||
or -2 for file not found (regint)
|
||||
"""
|
||||
@@ -6192,8 +6223,9 @@ class Array(_vectorizable):
|
||||
res = MemValue(0)
|
||||
@library.multithread(None, len(self), max_size=program.budget)
|
||||
def _(base, size):
|
||||
stop, shares = self.value_type.read_from_file(start, size)
|
||||
self.assign(shares, base=base)
|
||||
stop, shares = self.value_type.read_from_file(
|
||||
start, *args, size=size, **kwargs)
|
||||
self.assign(shares[0], base=base)
|
||||
start.iadd(size)
|
||||
res.write(stop)
|
||||
return res
|
||||
@@ -6402,7 +6434,7 @@ class Array(_vectorizable):
|
||||
return personal(player, self.create_from(self[:].reveal_to(player)._v))
|
||||
|
||||
def sort(self, n_threads=None, batcher=False, n_bits=None):
|
||||
"""
|
||||
r"""
|
||||
Sort in place using `radix sort
|
||||
<https://eprint.iacr.org/2014/121>`_ with complexity
|
||||
:math:`O(n \log n)` for :py:class:`sint` and :py:class:`sfix`,
|
||||
@@ -6495,13 +6527,7 @@ class SubMultiArray(_vectorizable):
|
||||
key = program.curr_tape, tuple(
|
||||
(x, x.has_else) for x in program.curr_tape.if_states), str(index)
|
||||
if key not in self.sub_cache:
|
||||
if util.is_constant(index) and \
|
||||
(index >= self.sizes[0] or index < 0):
|
||||
raise CompilerError('index out of range')
|
||||
elif self.check_indices:
|
||||
library.runtime_error_if(index >= self.sizes[0],
|
||||
'overflow: %s/%s',
|
||||
index, self.sizes)
|
||||
index = self.check(index, self.sizes[0], self.sizes)
|
||||
if len(self.sizes) == 2:
|
||||
self.sub_cache[key] = \
|
||||
Array(self.sizes[1], self.value_type, \
|
||||
@@ -6769,20 +6795,21 @@ class SubMultiArray(_vectorizable):
|
||||
my_pos = position + i * self[i].total_size()
|
||||
self[i].write_to_file(my_pos)
|
||||
|
||||
def read_from_file(self, start):
|
||||
def read_from_file(self, start, *args, **kwargs):
|
||||
""" Read content from ``Persistence/Transactions-P<playerno>.data``.
|
||||
Precision must be the same as when storing if applicable. See
|
||||
:ref:`this section <persistence>` for details on the data format.
|
||||
|
||||
:param start: starting position in number of shares from beginning
|
||||
(int/regint/cint)
|
||||
:param crash_if_missing: crash if file not found (default)
|
||||
:returns: destination for final position, -1 for eof reached,
|
||||
or -2 for file not found (regint)
|
||||
"""
|
||||
start = MemValue(start)
|
||||
@library.for_range(len(self))
|
||||
def _(i):
|
||||
start.write(self[i].read_from_file(start))
|
||||
start.write(self[i].read_from_file(start, *args, **kwargs))
|
||||
return start
|
||||
|
||||
def write_to_socket(self, socket, debug=False):
|
||||
|
||||
@@ -292,6 +292,9 @@ class dict_by_id(object):
|
||||
def __iter__(self):
|
||||
return self.keys()
|
||||
|
||||
def pop(self, key):
|
||||
return self.content.pop(id(key), None)
|
||||
|
||||
class defaultdict_by_id(dict_by_id):
|
||||
def __init__(self, default):
|
||||
dict_by_id.__init__(self)
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
#include "Math/gfp.h"
|
||||
#include "ECDSA/P256Element.h"
|
||||
#include "GC/VectorInput.h"
|
||||
#include "Protocols/SPDZ.h"
|
||||
|
||||
#include "ECDSA/preprocessing.hpp"
|
||||
#include "ECDSA/sign.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Protocols/Hemi.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "GC/RepPrep.hpp"
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "Machines/ShamirMachine.hpp"
|
||||
#include "Machines/Shamir.hpp"
|
||||
#include "Machines/MalRep.hpp"
|
||||
#include "Machines/Rep.hpp"
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "Math/gfp.h"
|
||||
#include "ECDSA/P256Element.h"
|
||||
#include "Protocols/SemiShare.h"
|
||||
#include "Protocols/SPDZ.h"
|
||||
#include "Processor/BaseMachine.h"
|
||||
|
||||
#include "ECDSA/preprocessing.hpp"
|
||||
@@ -15,6 +16,7 @@
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/MascotPrep.hpp"
|
||||
#include "Protocols/Hemi.hpp"
|
||||
#include "Processor/Processor.hpp"
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Input.hpp"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "GC/SemiSecret.h"
|
||||
#include "GC/SemiPrep.h"
|
||||
|
||||
#include "Protocols/Hemi.hpp"
|
||||
#include "Protocols/SemiMC.hpp"
|
||||
#include "Protocols/SemiPrep.hpp"
|
||||
#include "Protocols/SemiInput.hpp"
|
||||
|
||||
@@ -17,11 +17,10 @@
|
||||
* - share of winning unique id * random value [w]
|
||||
* winning unique id is valid if ∑ [y] * ∑ [r] = ∑ [w]
|
||||
*
|
||||
* To run with 2 parties / SPDZ engines:
|
||||
* ./Scripts/setup-online.sh to create triple shares for each party (spdz engine).
|
||||
* To run:
|
||||
* ./Scripts/setup-clients.sh to create SSL keys and certificates for clients
|
||||
* ./compile.py bankers_bonus
|
||||
* ./Scripts/run-online.sh bankers_bonus to run the engines.
|
||||
* ./Scripts/compile-run.py <protocol> bankers_bonus to compile and run the engines.
|
||||
* (See https://github.com/data61/MP-SPDZ/?tab=readme-ov-file#protocols for options.)
|
||||
*
|
||||
* ./bankers-bonus-client.x 0 2 100 0
|
||||
* ./bankers-bonus-client.x 1 2 200 0
|
||||
|
||||
@@ -16,14 +16,14 @@ template<class T>
|
||||
class AddableVector: public vector<T>
|
||||
{
|
||||
public:
|
||||
AddableVector<T>() {}
|
||||
AddableVector<T>(size_t n, const T& x = T()) : vector<T>(n, x) {}
|
||||
AddableVector() {}
|
||||
AddableVector(size_t n, const T& x = T()) : vector<T>(n, x) {}
|
||||
template <class U, class FD, class S>
|
||||
AddableVector<T>(const Plaintext<U,FD,S>& other) :
|
||||
AddableVector<T>(other.get_poly()) {}
|
||||
AddableVector(const Plaintext<U,FD,S>& other) :
|
||||
AddableVector(other.get_poly()) {}
|
||||
|
||||
template <class U>
|
||||
AddableVector<T>(const vector<U>& other)
|
||||
AddableVector(const vector<U>& other)
|
||||
{
|
||||
this->assign(other.begin(), other.end());
|
||||
}
|
||||
@@ -129,29 +129,41 @@ public:
|
||||
(*this)[i].pack(os);
|
||||
}
|
||||
|
||||
void unpack_size(octetStream& os, const T& init = T())
|
||||
size_t unpack_size(octetStream& os)
|
||||
{
|
||||
unsigned int size;
|
||||
os.get(size);
|
||||
this->resize(size, init);
|
||||
this->reserve(size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void unpack(octetStream& os, const T& init = T())
|
||||
{
|
||||
unpack_size(os, init);
|
||||
for (unsigned int i = 0; i < this->size(); i++)
|
||||
(*this)[i].unpack(os);
|
||||
size_t new_size = unpack_size(os);
|
||||
this->clear();
|
||||
for (unsigned int i = 0; i < new_size; i++)
|
||||
{
|
||||
this->push_back(init);
|
||||
this->back().unpack(os);
|
||||
}
|
||||
}
|
||||
|
||||
void add(octetStream& os, T& tmp)
|
||||
{
|
||||
unpack_size(os, tmp);
|
||||
size_t new_size = unpack_size(os);
|
||||
T init = tmp;
|
||||
T& item = tmp;
|
||||
for (unsigned int i = 0; i < this->size(); i++)
|
||||
{
|
||||
item.unpack(os);
|
||||
(*this)[i] += item;
|
||||
}
|
||||
for (size_t i = this->size(); i < new_size; i++)
|
||||
{
|
||||
item.unpack(os);
|
||||
this->push_back(init);
|
||||
this->back() += item;
|
||||
}
|
||||
}
|
||||
|
||||
T infinity_norm() const
|
||||
|
||||
@@ -61,9 +61,7 @@ bigint FHE_Params::Q() const
|
||||
|
||||
void FHE_Params::pack(octetStream& o) const
|
||||
{
|
||||
o.store(FFTData.size());
|
||||
for(auto& fd: FFTData)
|
||||
fd.pack(o);
|
||||
o.store(FFTData);
|
||||
Chi.pack(o);
|
||||
Bval.pack(o);
|
||||
o.store(sec_p);
|
||||
@@ -73,11 +71,7 @@ void FHE_Params::pack(octetStream& o) const
|
||||
|
||||
void FHE_Params::unpack(octetStream& o)
|
||||
{
|
||||
size_t size;
|
||||
o.get(size);
|
||||
FFTData.resize(size);
|
||||
for (auto& fd : FFTData)
|
||||
fd.unpack(o);
|
||||
o.get(FFTData);
|
||||
Chi.unpack(o);
|
||||
Bval.unpack(o);
|
||||
o.get(sec_p);
|
||||
|
||||
@@ -311,22 +311,18 @@ void imatrix::hash(octetStream& o) const
|
||||
|
||||
void imatrix::pack(octetStream& o) const
|
||||
{
|
||||
o.store(size());
|
||||
for (auto& x : *this)
|
||||
{
|
||||
assert(x.size() == size());
|
||||
x.pack(o);
|
||||
}
|
||||
o.store(static_cast<const super&>(*this));
|
||||
}
|
||||
|
||||
void imatrix::unpack(octetStream& o)
|
||||
{
|
||||
size_t size;
|
||||
o.get(size);
|
||||
resize(size);
|
||||
o.get(static_cast<super&>(*this));
|
||||
for (auto& x : *this)
|
||||
{
|
||||
x.resize(size);
|
||||
x.unpack(o);
|
||||
assert(x.size() == size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ typedef vector< vector<bigint> > matrix;
|
||||
|
||||
class imatrix : public vector< BitVector >
|
||||
{
|
||||
typedef vector<BitVector> super;
|
||||
|
||||
public:
|
||||
bool operator!=(const imatrix& other) const;
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
#include "FHEOffline/Proof.h"
|
||||
|
||||
#include "Processor/OnlineOptions.h"
|
||||
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
|
||||
@@ -735,9 +737,9 @@ void load_or_generate(P2Data& P2D, const Ring& R)
|
||||
{
|
||||
P2D.load(R);
|
||||
}
|
||||
catch (...)
|
||||
catch (exception& e)
|
||||
{
|
||||
cout << "Loading failed" << endl;
|
||||
cerr << "Loading parameters failed, generating (" << e.what() << ")" << endl;
|
||||
init(P2D,R);
|
||||
P2D.store(R);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "FHE/P2Data.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "Math/fixint.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
#include <fstream>
|
||||
|
||||
|
||||
@@ -74,7 +75,6 @@ bool P2Data::operator!=(const P2Data& other) const
|
||||
|
||||
void P2Data::hash(octetStream& o) const
|
||||
{
|
||||
check_dimensions();
|
||||
o.store(gf2n_short::degree());
|
||||
o.store(slots);
|
||||
A.hash(o);
|
||||
@@ -113,17 +113,18 @@ string get_filename(const Ring& Rg)
|
||||
void P2Data::load(const Ring& Rg)
|
||||
{
|
||||
string filename = get_filename(Rg);
|
||||
cout << "Loading from " << filename << endl;
|
||||
ifstream s(filename);
|
||||
if (OnlineOptions::singleton.verbose)
|
||||
cerr << "Loading from " << filename << endl;
|
||||
octetStream os;
|
||||
os.input(s);
|
||||
os.input(filename);
|
||||
unpack(os);
|
||||
}
|
||||
|
||||
void P2Data::store(const Ring& Rg) const
|
||||
{
|
||||
string filename = get_filename(Rg);
|
||||
cout << "Storing in " << filename << endl;
|
||||
if (OnlineOptions::singleton.verbose)
|
||||
cerr << "Storing in " << filename << endl;
|
||||
ofstream s(filename);
|
||||
octetStream os;
|
||||
pack(os);
|
||||
|
||||
@@ -562,22 +562,17 @@ template <class T,class FD,class S>
|
||||
void Plaintext<T,FD,S>::pack(octetStream& o) const
|
||||
{
|
||||
to_poly();
|
||||
o.store((unsigned int)b.size());
|
||||
for (unsigned int i = 0; i < b.size(); i++)
|
||||
o.store(b[i]);
|
||||
o.store(b);
|
||||
}
|
||||
|
||||
template <class T,class FD,class S>
|
||||
void Plaintext<T,FD,S>::unpack(octetStream& o)
|
||||
{
|
||||
type = Polynomial;
|
||||
unsigned int size;
|
||||
o.get(size);
|
||||
allocate();
|
||||
o.get(b);
|
||||
auto size = b.size();
|
||||
allocate(Polynomial);
|
||||
if (size != b.size() and size != 0)
|
||||
throw length_error("unexpected length received");
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
b[i] = o.get<S>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -512,9 +512,7 @@ modp Ring_Element::get_constant() const
|
||||
void store(octetStream& o,const vector<modp>& v,const Zp_Data& ZpD)
|
||||
{
|
||||
ZpD.pack(o);
|
||||
o.store((int)v.size());
|
||||
for (unsigned int i=0; i<v.size(); i++)
|
||||
{ v[i].pack(o,ZpD); }
|
||||
o.store(v);
|
||||
}
|
||||
|
||||
|
||||
@@ -526,16 +524,7 @@ void get(octetStream& o,vector<modp>& v,const Zp_Data& ZpD)
|
||||
throw runtime_error(
|
||||
"mismatch: " + to_string(check_Zpd.pr_bit_length) + "/"
|
||||
+ to_string(ZpD.pr_bit_length));
|
||||
unsigned int length;
|
||||
o.get(length);
|
||||
v.clear();
|
||||
v.reserve(length);
|
||||
modp tmp;
|
||||
for (unsigned int i=0; i<length; i++)
|
||||
{
|
||||
tmp.unpack(o,ZpD);
|
||||
v.push_back(tmp);
|
||||
}
|
||||
o.get(v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _Subroutines
|
||||
#define _Subroutines
|
||||
#ifndef FHE_SUBROUTINES_H_
|
||||
#define FHE_SUBROUTINES_H_
|
||||
|
||||
|
||||
#include "Math/Zp_Data.h"
|
||||
|
||||
@@ -27,8 +27,7 @@ void read_or_generate_secrets(T& setup, Player& P, U& machine,
|
||||
|
||||
try
|
||||
{
|
||||
ifstream input(filename);
|
||||
os.input(input);
|
||||
os.input(filename);
|
||||
setup.unpack(os);
|
||||
machine.unpack(os);
|
||||
}
|
||||
@@ -44,11 +43,15 @@ void read_or_generate_secrets(T& setup, Player& P, U& machine,
|
||||
}
|
||||
catch (mismatch_among_parties& e)
|
||||
{
|
||||
error = e.what();
|
||||
if (error.empty())
|
||||
error = e.what();
|
||||
}
|
||||
|
||||
if (not error.empty())
|
||||
{
|
||||
if (OnlineOptions::singleton.has_option("expect_setup"))
|
||||
throw runtime_error("error in setup: " + error);
|
||||
|
||||
cerr << "Running secrets generation because no suitable material "
|
||||
"from a previous run was found (" << error << ")" << endl;
|
||||
setup.key_and_mac_generation(P, machine, num_runs, V());
|
||||
|
||||
@@ -80,9 +80,8 @@ void secure_init(T& setup, Player& P, U& machine,
|
||||
|
||||
try
|
||||
{
|
||||
ifstream file(filename);
|
||||
octetStream os;
|
||||
os.input(file);
|
||||
os.input(filename);
|
||||
os.get(machine.extra_slack);
|
||||
setup.unpack(os);
|
||||
}
|
||||
@@ -95,13 +94,17 @@ void secure_init(T& setup, Player& P, U& machine,
|
||||
{
|
||||
setup.check(P, machine);
|
||||
}
|
||||
catch (exception& e)
|
||||
catch (mismatch_among_parties& e)
|
||||
{
|
||||
reason = e.what();
|
||||
if (reason.empty())
|
||||
reason = e.what();
|
||||
}
|
||||
|
||||
if (not reason.empty())
|
||||
{
|
||||
if (OnlineOptions::singleton.has_option("expect_setup"))
|
||||
throw runtime_error("error in setup: " + reason);
|
||||
|
||||
if (OnlineOptions::singleton.verbose)
|
||||
cerr << "Generating parameters for security " << sec
|
||||
<< " and field size ~2^" << plaintext_length
|
||||
|
||||
@@ -82,9 +82,23 @@ void Instruction::parse(istream& s, int pos)
|
||||
#undef X
|
||||
default:
|
||||
ostringstream os;
|
||||
os << "Code not defined for instruction " << showbase << hex << opcode << dec << endl;
|
||||
os << "This virtual machine executes binary circuits only." << endl;
|
||||
os << "Use 'compile.py -B'.";
|
||||
os << "Code not defined for instruction ";
|
||||
bool known = true;
|
||||
switch (opcode)
|
||||
{
|
||||
#define X(NAME, PRE, CODE) case NAME: os << #NAME; break;
|
||||
ALL_INSTRUCTIONS
|
||||
#undef X
|
||||
default:
|
||||
known = false;
|
||||
os << showbase << hex << opcode << dec;
|
||||
}
|
||||
os << endl;
|
||||
if (known)
|
||||
{
|
||||
os << "This virtual machine executes binary circuits only. ";
|
||||
os << "Use 'compile.py -B'.";
|
||||
}
|
||||
exit_error(os.str());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
|
||||
typedef MaliciousRepMC<U> MC;
|
||||
typedef MC MAC_Check;
|
||||
typedef HashMaliciousRepMC<U> DefaultMC;
|
||||
|
||||
typedef ReplicatedInput<U> Input;
|
||||
typedef RepPrep<U> LivePrep;
|
||||
|
||||
@@ -71,9 +71,9 @@ void Program::parse(istream& s)
|
||||
CALLGRIND_STOP_INSTRUMENTATION;
|
||||
while (!s.eof())
|
||||
{
|
||||
instr.parse(s, pos);
|
||||
if (s.bad() or s.fail())
|
||||
throw runtime_error("error reading program");
|
||||
instr.parse(s, pos);
|
||||
p.push_back(instr);
|
||||
//cerr << "\t" << instr << endl;
|
||||
s.peek();
|
||||
|
||||
@@ -65,6 +65,8 @@ public:
|
||||
|
||||
typedef typename T::out_type out_type;
|
||||
|
||||
typedef void DefaultMC;
|
||||
|
||||
static string type_string() { return "evaluation secret"; }
|
||||
static string phase_name() { return T::name(); }
|
||||
|
||||
@@ -179,6 +181,7 @@ public:
|
||||
void finalize_input(U& inputter, int from, int n_bits);
|
||||
|
||||
int size() const { return registers.size(); }
|
||||
size_t maximum_size() const { return registers.size(); }
|
||||
RegVector& get_regs() { return registers; }
|
||||
const RegVector& get_regs() const { return registers; }
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ namespace GC
|
||||
void Semi::prepare_mult(const SemiSecret& x, const SemiSecret& y, int n,
|
||||
bool repeat)
|
||||
{
|
||||
if (repeat and OnlineOptions::singleton.live_prep and (n < 0 or n > 1))
|
||||
if (repeat and OnlineOptions::singleton.live_prep and (n < 0 or n > 1)
|
||||
and P.num_players() == 2)
|
||||
{
|
||||
this->triples.push_back({{}});
|
||||
auto& triple = this->triples.back();
|
||||
|
||||
@@ -51,6 +51,11 @@ public:
|
||||
static void trans(Processor<T>& processor, int n_outputs,
|
||||
const vector<int>& args);
|
||||
|
||||
static size_t maximum_size()
|
||||
{
|
||||
return default_length;
|
||||
}
|
||||
|
||||
SemiSecretBase()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_SEMISECRET_HPP_
|
||||
#define GC_SEMISECRET_HPP_
|
||||
|
||||
#include "GC/ShareParty.h"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "Protocols/MAC_Check_Base.hpp"
|
||||
@@ -161,3 +164,5 @@ void SemiSecretBase<T, V>::reveal(size_t n_bits, Clear& x)
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,7 +42,7 @@ inline ShareParty<T>& ShareParty<T>::s()
|
||||
if (singleton)
|
||||
return *singleton;
|
||||
else
|
||||
throw runtime_error("no singleton");
|
||||
throw runtime_error("no ShareParty singleton");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -125,6 +125,8 @@ public:
|
||||
|
||||
typedef NoShare bit_type;
|
||||
|
||||
typedef void DefaultMC;
|
||||
|
||||
static const int N_BITS = clear::N_BITS;
|
||||
|
||||
static const bool dishonest_majority = false;
|
||||
@@ -166,6 +168,11 @@ public:
|
||||
return T::fake_opts();
|
||||
}
|
||||
|
||||
static size_t maximum_size()
|
||||
{
|
||||
return default_length;
|
||||
}
|
||||
|
||||
RepSecretBase()
|
||||
{
|
||||
}
|
||||
@@ -203,7 +210,7 @@ public:
|
||||
typedef ReplicatedBase Protocol;
|
||||
|
||||
static ReplicatedSecret constant(const typename super::clear& value,
|
||||
int my_num, typename super::mac_key_type, int = -1)
|
||||
int my_num, typename super::mac_key_type = {}, int = -1)
|
||||
{
|
||||
ReplicatedSecret res;
|
||||
if (my_num < 2)
|
||||
|
||||
@@ -67,7 +67,7 @@ inline ShareThread<T>& ShareThread<T>::s()
|
||||
if (singleton and T::is_real)
|
||||
return *singleton;
|
||||
else
|
||||
throw runtime_error("no singleton");
|
||||
throw runtime_error("no ShareThread singleton");
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
@@ -144,6 +144,9 @@ void ShareThread<T>::and_(Processor<T>& processor,
|
||||
res.mask(res, n);
|
||||
}
|
||||
}
|
||||
|
||||
if (OnlineOptions::singleton.has_option("always_check"))
|
||||
protocol->check();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -195,6 +198,9 @@ void ShareThread<T>::andrsvec(Processor<T>& processor, const vector<int>& args)
|
||||
}
|
||||
it += 2 * n_args + 1;
|
||||
}
|
||||
|
||||
if (OnlineOptions::singleton.has_option("always_check"))
|
||||
protocol->check();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
Thread(int thread_num, ThreadMaster<T>& master);
|
||||
virtual ~Thread();
|
||||
|
||||
void start();
|
||||
void run();
|
||||
virtual void pre_run() {}
|
||||
virtual void run(Program& program);
|
||||
|
||||
@@ -31,7 +31,12 @@ template<class T>
|
||||
Thread<T>::Thread(int thread_num, ThreadMaster<T>& master) :
|
||||
master(master), machine(master.machine), processor(machine),
|
||||
N(master.N), P(0),
|
||||
thread_num(thread_num)
|
||||
thread_num(thread_num), thread(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Thread<T>::start()
|
||||
{
|
||||
pthread_create(&thread, 0, run_thread, this);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
virtual Thread<T>* new_thread(int i);
|
||||
|
||||
void run();
|
||||
void run_with_error();
|
||||
|
||||
virtual void post_run() {}
|
||||
};
|
||||
|
||||
@@ -59,6 +59,25 @@ Thread<T>* ThreadMaster<T>::new_thread(int i)
|
||||
|
||||
template<class T>
|
||||
void ThreadMaster<T>::run()
|
||||
{
|
||||
if (opts.has_option("throw_exceptions"))
|
||||
run_with_error();
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
run_with_error();
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
cerr << "Fatal error: " << e.what() << endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ThreadMaster<T>::run_with_error()
|
||||
{
|
||||
if (not opts.live_prep)
|
||||
{
|
||||
@@ -72,6 +91,9 @@ void ThreadMaster<T>::run()
|
||||
|
||||
for (int i = 0; i < machine.nthreads; i++)
|
||||
threads.push_back(new_thread(i));
|
||||
// must start after constructor due to virtual functions
|
||||
for (auto thread : threads)
|
||||
thread->start();
|
||||
for (auto thread : threads)
|
||||
thread->join_tape();
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
return *part_MC;
|
||||
}
|
||||
|
||||
void init_open(const Player& P, int n)
|
||||
void init_open(const Player& P, int n = 0)
|
||||
{
|
||||
part_MC->init_open(P);
|
||||
sizes.clear();
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
#include "Protocols/AtlasPrep.h"
|
||||
#include "GC/AtlasSecret.h"
|
||||
|
||||
#include "ShamirMachine.hpp"
|
||||
#include "Protocols/Atlas.hpp"
|
||||
|
||||
#include "Shamir.hpp"
|
||||
|
||||
#endif /* MACHINES_ATLAS_HPP_ */
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "BMR/RealProgramParty.hpp"
|
||||
#include "Machines/ShamirMachine.hpp"
|
||||
#include "Machines/Shamir.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
#include "Machines/MalRep.hpp"
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "BMR/RealProgramParty.hpp"
|
||||
#include "Machines/ShamirMachine.hpp"
|
||||
#include "Machines/Shamir.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
|
||||
@@ -5,3 +5,5 @@
|
||||
#include "Math/gfp.hpp"
|
||||
|
||||
template class FieldMachine<Share, Share, DishonestMajorityMachine>;
|
||||
|
||||
template class Machine<Share<gfp_<0, 2>>, Share<gf2n>>;
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#ifndef MACHINES_SPDZ_HPP_
|
||||
#define MACHINES_SPDZ_HPP_
|
||||
|
||||
#include "Protocols/MAC_Check.h"
|
||||
#include "Protocols/SPDZ.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
|
||||
50
Machines/Shamir.hpp
Normal file
50
Machines/Shamir.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* ShamirMachine.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MACHINE_SHAMIR_HPP_
|
||||
#define MACHINE_SHAMIR_HPP_
|
||||
|
||||
#include "Protocols/ShamirOptions.h"
|
||||
#include "Protocols/ShamirShare.h"
|
||||
#include "Protocols/MaliciousShamirShare.h"
|
||||
#include "Math/gfp.h"
|
||||
#include "Math/gf2n.h"
|
||||
#include "GC/VectorProtocol.h"
|
||||
#include "GC/CcdPrep.h"
|
||||
#include "GC/TinyMC.h"
|
||||
#include "GC/MaliciousCcdSecret.h"
|
||||
#include "GC/VectorInput.h"
|
||||
|
||||
#include "Processor/FieldMachine.hpp"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Protocols/ShamirInput.hpp"
|
||||
#include "Protocols/Shamir.hpp"
|
||||
#include "Protocols/ShamirMC.hpp"
|
||||
#include "Protocols/MaliciousShamirMC.hpp"
|
||||
#include "Protocols/MaliciousShamirPO.hpp"
|
||||
#include "Protocols/MAC_Check_Base.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Protocols/Spdz2kPrep.hpp"
|
||||
#include "Protocols/ReplicatedPrep.hpp"
|
||||
#include "Protocols/MalRepRingPrep.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/VectorProtocol.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/CcdPrep.hpp"
|
||||
#include "Math/gfp.hpp"
|
||||
|
||||
template<template<class U> class T>
|
||||
ShamirMachineSpec<T>::ShamirMachineSpec(int argc, const char** argv)
|
||||
{
|
||||
auto& opts = ShamirOptions::singleton;
|
||||
ez::ezOptionParser opt;
|
||||
opts = {opt, argc, argv};
|
||||
HonestMajorityFieldMachine<T>(argc, argv, opt, opts.nparties);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/CcdPrep.hpp"
|
||||
#include "Machines/ShamirMachine.hpp"
|
||||
#include "Machines/Shamir.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
8
Machines/export-atlas.cpp
Normal file
8
Machines/export-atlas.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* export-vm.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "maximal.hpp"
|
||||
|
||||
template class Machine<AtlasShare<gfp_<0, 2>>>;
|
||||
8
Machines/export-cowgear.cpp
Normal file
8
Machines/export-cowgear.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* export-vm.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "maximal.hpp"
|
||||
|
||||
template class Machine<CowGearShare<gfp_<0, 2>>>;
|
||||
8
Machines/export-dealer.cpp
Normal file
8
Machines/export-dealer.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* export-vm.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "maximal.hpp"
|
||||
|
||||
template class Machine<DealerShare<SignedZ2<64>>>;
|
||||
8
Machines/export-hemi.cpp
Normal file
8
Machines/export-hemi.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* export-vm.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "maximal.hpp"
|
||||
|
||||
template class Machine<HemiShare<gfp_<0, 2>>>;
|
||||
8
Machines/export-rep4-ring.cpp
Normal file
8
Machines/export-rep4-ring.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* export-vm.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "maximal.hpp"
|
||||
|
||||
template class Machine<Rep4Share2<64>>;
|
||||
8
Machines/export-ring.cpp
Normal file
8
Machines/export-ring.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* export-vm.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "maximal.hpp"
|
||||
|
||||
template class Machine<Rep3Share2<64>>;
|
||||
8
Machines/export-semi2k.cpp
Normal file
8
Machines/export-semi2k.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* export-vm.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "maximal.hpp"
|
||||
|
||||
template class Machine<Semi2kShare<64>>;
|
||||
8
Machines/export-sy-rep-ring.cpp
Normal file
8
Machines/export-sy-rep-ring.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* export-vm.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "maximal.hpp"
|
||||
|
||||
template class Machine<SpdzWiseRingShare<64, 40>>;
|
||||
377
Machines/h-files.h
Normal file
377
Machines/h-files.h
Normal file
@@ -0,0 +1,377 @@
|
||||
#include "BMR/AndJob.h"
|
||||
#include "BMR/BooleanCircuit.h"
|
||||
#include "BMR/common.h"
|
||||
#include "BMR/CommonParty.h"
|
||||
#include "BMR/config.h"
|
||||
#include "BMR/GarbledGate.h"
|
||||
#include "BMR/Gate.h"
|
||||
#include "BMR/Key.h"
|
||||
#include "BMR/msg_types.h"
|
||||
#include "BMR/Party.h"
|
||||
#include "BMR/prf.h"
|
||||
#include "BMR/proto_utils.h"
|
||||
#include "BMR/RealGarbleWire.h"
|
||||
#include "BMR/RealProgramParty.h"
|
||||
#include "BMR/Register.h"
|
||||
#include "BMR/Register_inline.h"
|
||||
#include "BMR/SpdzWire.h"
|
||||
#include "BMR/TrustedParty.h"
|
||||
#include "BMR/Wire.h"
|
||||
#include "ECDSA/CurveElement.h"
|
||||
#include "ECDSA/EcdsaOptions.h"
|
||||
#include "ECDSA/P256Element.h"
|
||||
#include "ExternalIO/Client.h"
|
||||
#include "FHE/AddableVector.h"
|
||||
#include "FHE/Ciphertext.h"
|
||||
#include "FHE/Diagonalizer.h"
|
||||
#include "FHE/DiscreteGauss.h"
|
||||
#include "FHE/FFT_Data.h"
|
||||
#include "FHE/FFT.h"
|
||||
#include "FHE/FHE_Keys.h"
|
||||
#include "FHE/FHE_Params.h"
|
||||
#include "FHE/Generator.h"
|
||||
#include "FHE/Matrix.h"
|
||||
#include "FHE/NoiseBounds.h"
|
||||
#include "FHE/NTL-Subs.h"
|
||||
#include "FHEOffline/config.h"
|
||||
#include "FHEOffline/CutAndChooseMachine.h"
|
||||
#include "FHEOffline/DataSetup.h"
|
||||
#include "FHEOffline/DistDecrypt.h"
|
||||
#include "FHEOffline/DistKeyGen.h"
|
||||
#include "FHEOffline/EncCommit.h"
|
||||
#include "FHEOffline/Multiplier.h"
|
||||
#include "FHEOffline/PairwiseGenerator.h"
|
||||
#include "FHEOffline/PairwiseMachine.h"
|
||||
#include "FHEOffline/PairwiseSetup.h"
|
||||
#include "FHEOffline/Producer.h"
|
||||
#include "FHEOffline/Proof.h"
|
||||
#include "FHEOffline/Prover.h"
|
||||
#include "FHEOffline/Reshare.h"
|
||||
#include "FHEOffline/Sacrificing.h"
|
||||
#include "FHEOffline/SimpleDistDecrypt.h"
|
||||
#include "FHEOffline/SimpleEncCommit.h"
|
||||
#include "FHEOffline/SimpleGenerator.h"
|
||||
#include "FHEOffline/SimpleMachine.h"
|
||||
#include "FHEOffline/TemiSetup.h"
|
||||
#include "FHEOffline/Verifier.h"
|
||||
#include "FHE/P2Data.h"
|
||||
#include "FHE/Plaintext.h"
|
||||
#include "FHE/QGroup.h"
|
||||
#include "FHE/Random_Coins.h"
|
||||
#include "FHE/Ring_Element.h"
|
||||
#include "FHE/Ring.h"
|
||||
#include "FHE/Rq_Element.h"
|
||||
#include "FHE/Subroutines.h"
|
||||
#include "FHE/tools.h"
|
||||
#include "GC/Access.h"
|
||||
#include "GC/ArgTuples.h"
|
||||
#include "GC/AtlasSecret.h"
|
||||
#include "GC/AtlasShare.h"
|
||||
#include "GC/BitAdder.h"
|
||||
#include "GC/BitPrepFiles.h"
|
||||
#include "GC/CcdPrep.h"
|
||||
#include "GC/CcdSecret.h"
|
||||
#include "GC/CcdShare.h"
|
||||
#include "GC/Clear.h"
|
||||
#include "GC/config.h"
|
||||
#include "GC/DealerPrep.h"
|
||||
#include "GC/FakeSecret.h"
|
||||
#include "GC/Instruction.h"
|
||||
#include "GC/Instruction_inline.h"
|
||||
#include "GC/instructions.h"
|
||||
#include "GC/Machine.h"
|
||||
#include "GC/MaliciousCcdSecret.h"
|
||||
#include "GC/MaliciousCcdShare.h"
|
||||
#include "GC/MaliciousRepSecret.h"
|
||||
#include "GC/Memory.h"
|
||||
#include "GC/NoShare.h"
|
||||
#include "GC/PersonalPrep.h"
|
||||
#include "GC/PostSacriBin.h"
|
||||
#include "GC/PostSacriSecret.h"
|
||||
#include "GC/Processor.h"
|
||||
#include "GC/Program.h"
|
||||
#include "GC/Rep4Prep.h"
|
||||
#include "GC/Rep4Secret.h"
|
||||
#include "GC/RepPrep.h"
|
||||
#include "GC/RuntimeBranching.h"
|
||||
#include "GC/Secret.h"
|
||||
#include "GC/Secret_inline.h"
|
||||
#include "GC/Semi.h"
|
||||
#include "GC/SemiHonestRepPrep.h"
|
||||
#include "GC/SemiPrep.h"
|
||||
#include "GC/SemiSecret.h"
|
||||
#include "GC/ShareParty.h"
|
||||
#include "GC/ShareSecret.h"
|
||||
#include "GC/ShareThread.h"
|
||||
#include "GC/ShiftableTripleBuffer.h"
|
||||
#include "GC/square64.h"
|
||||
#include "GC/Thread.h"
|
||||
#include "GC/ThreadMaster.h"
|
||||
#include "GC/TinierSecret.h"
|
||||
#include "GC/TinierShare.h"
|
||||
#include "GC/TinierSharePrep.h"
|
||||
#include "GC/TinyMC.h"
|
||||
#include "GC/TinySecret.h"
|
||||
#include "GC/TinyShare.h"
|
||||
#include "GC/VectorInput.h"
|
||||
#include "GC/VectorProtocol.h"
|
||||
#include "Machines/OTMachine.h"
|
||||
#include "Machines/OutputCheck.h"
|
||||
#include "Math/bigint.h"
|
||||
#include "Math/Bit.h"
|
||||
#include "Math/BitVec.h"
|
||||
#include "Math/config.h"
|
||||
#include "Math/field_types.h"
|
||||
#include "Math/FixedVec.h"
|
||||
#include "Math/fixint.h"
|
||||
#include "Math/gf2n.h"
|
||||
#include "Math/gf2nlong.h"
|
||||
#include "Math/gfp.h"
|
||||
#include "Math/gfpvar.h"
|
||||
#include "Math/Integer.h"
|
||||
#include "Math/modp.h"
|
||||
#include "Math/mpn_fixed.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "Math/Square.h"
|
||||
#include "Math/ValueInterface.h"
|
||||
#include "Math/Z2k.h"
|
||||
#include "Math/Zp_Data.h"
|
||||
#include "Networking/AllButLastPlayer.h"
|
||||
#include "Networking/CryptoPlayer.h"
|
||||
#include "Networking/data.h"
|
||||
#include "Networking/Exchanger.h"
|
||||
#include "Networking/PlayerBuffer.h"
|
||||
#include "Networking/PlayerCtSocket.h"
|
||||
#include "Networking/Player.h"
|
||||
#include "Networking/Receiver.h"
|
||||
#include "Networking/Sender.h"
|
||||
#include "Networking/Server.h"
|
||||
#include "Networking/ServerSocket.h"
|
||||
#include "Networking/sockets.h"
|
||||
#include "Networking/ssl_sockets.h"
|
||||
#include "OT/BaseOT.h"
|
||||
#include "OT/BitDiagonal.h"
|
||||
#include "OT/BitMatrix.h"
|
||||
#include "OT/config.h"
|
||||
#include "OT/MamaRectangle.h"
|
||||
#include "OT/MascotParams.h"
|
||||
#include "OT/NPartyTripleGenerator.h"
|
||||
#include "OT/OTExtension.h"
|
||||
#include "OT/OTExtensionWithMatrix.h"
|
||||
#include "OT/OTMultiplier.h"
|
||||
#include "OT/OTTripleSetup.h"
|
||||
#include "OT/OTVole.h"
|
||||
#include "OT/Rectangle.h"
|
||||
#include "OT/Row.h"
|
||||
#include "OT/Tools.h"
|
||||
#include "OT/TripleMachine.h"
|
||||
#include "Processor/BaseMachine.h"
|
||||
#include "Processor/Binary_File_IO.h"
|
||||
#include "Processor/config.h"
|
||||
#include "Processor/Conv2dTuple.h"
|
||||
#include "Processor/Data_Files.h"
|
||||
#include "Processor/DummyProtocol.h"
|
||||
#include "Processor/EdabitBuffer.h"
|
||||
#include "Processor/ExternalClients.h"
|
||||
#include "Processor/FieldMachine.h"
|
||||
#include "Processor/FixInput.h"
|
||||
#include "Processor/FloatInput.h"
|
||||
#include "Processor/FunctionArgument.h"
|
||||
#include "Processor/HonestMajorityMachine.h"
|
||||
#include "Processor/Input.h"
|
||||
#include "Processor/InputTuple.h"
|
||||
#include "Processor/Instruction.h"
|
||||
#include "Processor/instructions.h"
|
||||
#include "Processor/IntInput.h"
|
||||
#include "Processor/Machine.h"
|
||||
#include "Processor/Memory.h"
|
||||
#include "Processor/NoFilePrep.h"
|
||||
#include "Processor/OfflineMachine.h"
|
||||
#include "Processor/OnlineMachine.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
#include "Processor/Online-Thread.h"
|
||||
#include "Processor/PrepBase.h"
|
||||
#include "Processor/PrepBuffer.h"
|
||||
#include "Processor/PrivateOutput.h"
|
||||
#include "Processor/ProcessorBase.h"
|
||||
#include "Processor/Processor.h"
|
||||
#include "Processor/Program.h"
|
||||
#include "Processor/RingMachine.h"
|
||||
#include "Processor/RingOptions.h"
|
||||
#include "Processor/SpecificPrivateOutput.h"
|
||||
#include "Processor/ThreadJob.h"
|
||||
#include "Processor/ThreadQueue.h"
|
||||
#include "Processor/ThreadQueues.h"
|
||||
#include "Processor/TruncPrTuple.h"
|
||||
#include "Protocols/Atlas.h"
|
||||
#include "Protocols/AtlasPrep.h"
|
||||
#include "Protocols/AtlasShare.h"
|
||||
#include "Protocols/Beaver.h"
|
||||
#include "Protocols/BrainPrep.h"
|
||||
#include "Protocols/BrainShare.h"
|
||||
#include "Protocols/BufferScope.h"
|
||||
#include "Protocols/ChaiGearPrep.h"
|
||||
#include "Protocols/ChaiGearShare.h"
|
||||
#include "Protocols/config.h"
|
||||
#include "Protocols/CowGearOptions.h"
|
||||
#include "Protocols/CowGearPrep.h"
|
||||
#include "Protocols/CowGearShare.h"
|
||||
#include "Protocols/dabit.h"
|
||||
#include "Protocols/DabitSacrifice.h"
|
||||
#include "Protocols/Dealer.h"
|
||||
#include "Protocols/DealerInput.h"
|
||||
#include "Protocols/DealerMatrixPrep.h"
|
||||
#include "Protocols/DealerMC.h"
|
||||
#include "Protocols/DealerPrep.h"
|
||||
#include "Protocols/DealerShare.h"
|
||||
#include "Protocols/DummyMatrixPrep.h"
|
||||
#include "Protocols/edabit.h"
|
||||
#include "Protocols/FakeInput.h"
|
||||
#include "Protocols/FakeMC.h"
|
||||
#include "Protocols/FakePrep.h"
|
||||
#include "Protocols/FakeProtocol.h"
|
||||
#include "Protocols/FakeShare.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
#include "Protocols/Hemi.h"
|
||||
#include "Protocols/HemiMatrixPrep.h"
|
||||
#include "Protocols/HemiOptions.h"
|
||||
#include "Protocols/HemiPrep.h"
|
||||
#include "Protocols/HemiShare.h"
|
||||
#include "Protocols/HighGearKeyGen.h"
|
||||
#include "Protocols/HighGearShare.h"
|
||||
#include "Protocols/LimitedPrep.h"
|
||||
#include "Protocols/LowGearKeyGen.h"
|
||||
#include "Protocols/LowGearShare.h"
|
||||
#include "Protocols/MAC_Check_Base.h"
|
||||
#include "Protocols/MAC_Check.h"
|
||||
#include "Protocols/MaliciousRep3Share.h"
|
||||
#include "Protocols/MaliciousRepMC.h"
|
||||
#include "Protocols/MaliciousRepPO.h"
|
||||
#include "Protocols/MaliciousRepPrep.h"
|
||||
#include "Protocols/MaliciousShamirMC.h"
|
||||
#include "Protocols/MaliciousShamirPO.h"
|
||||
#include "Protocols/MaliciousShamirShare.h"
|
||||
#include "Protocols/MalRepRingOptions.h"
|
||||
#include "Protocols/MalRepRingPrep.h"
|
||||
#include "Protocols/MalRepRingShare.h"
|
||||
#include "Protocols/MamaPrep.h"
|
||||
#include "Protocols/MamaShare.h"
|
||||
#include "Protocols/MascotPrep.h"
|
||||
#include "Protocols/MatrixFile.h"
|
||||
#include "Protocols/NoLivePrep.h"
|
||||
#include "Protocols/NoProtocol.h"
|
||||
#include "Protocols/NoShare.h"
|
||||
#include "Protocols/Opener.h"
|
||||
#include "Protocols/PostSacrifice.h"
|
||||
#include "Protocols/PostSacriRepFieldShare.h"
|
||||
#include "Protocols/PostSacriRepRingShare.h"
|
||||
#include "Protocols/ProtocolSet.h"
|
||||
#include "Protocols/ProtocolSetup.h"
|
||||
#include "Protocols/Rep3Share2k.h"
|
||||
#include "Protocols/Rep3Share.h"
|
||||
#include "Protocols/Rep3Shuffler.h"
|
||||
#include "Protocols/Rep4.h"
|
||||
#include "Protocols/Rep4Input.h"
|
||||
#include "Protocols/Rep4MC.h"
|
||||
#include "Protocols/Rep4Prep.h"
|
||||
#include "Protocols/Rep4Share2k.h"
|
||||
#include "Protocols/Rep4Share.h"
|
||||
#include "Protocols/Replicated.h"
|
||||
#include "Protocols/ReplicatedInput.h"
|
||||
#include "Protocols/ReplicatedMC.h"
|
||||
#include "Protocols/ReplicatedPO.h"
|
||||
#include "Protocols/ReplicatedPrep.h"
|
||||
#include "Protocols/RepRingOnlyEdabitPrep.h"
|
||||
#include "Protocols/RingOnlyPrep.h"
|
||||
#include "Protocols/SecureShuffle.h"
|
||||
#include "Protocols/Semi2kShare.h"
|
||||
#include "Protocols/Semi.h"
|
||||
#include "Protocols/SemiInput.h"
|
||||
#include "Protocols/SemiMC.h"
|
||||
#include "Protocols/SemiPrep2k.h"
|
||||
#include "Protocols/SemiPrep.h"
|
||||
#include "Protocols/SemiRep3Prep.h"
|
||||
#include "Protocols/SemiShare.h"
|
||||
#include "Protocols/Shamir.h"
|
||||
#include "Protocols/ShamirInput.h"
|
||||
#include "Protocols/ShamirMC.h"
|
||||
#include "Protocols/ShamirOptions.h"
|
||||
#include "Protocols/ShamirShare.h"
|
||||
#include "Protocols/Share.h"
|
||||
#include "Protocols/ShareInterface.h"
|
||||
#include "Protocols/ShareMatrix.h"
|
||||
#include "Protocols/ShareVector.h"
|
||||
#include "Protocols/ShuffleSacrifice.h"
|
||||
#include "Protocols/SohoPrep.h"
|
||||
#include "Protocols/SohoShare.h"
|
||||
#include "Protocols/SPDZ2k.h"
|
||||
#include "Protocols/Spdz2kPrep.h"
|
||||
#include "Protocols/Spdz2kShare.h"
|
||||
#include "Protocols/SPDZ.h"
|
||||
#include "Protocols/SpdzWise.h"
|
||||
#include "Protocols/SpdzWiseInput.h"
|
||||
#include "Protocols/SpdzWiseMC.h"
|
||||
#include "Protocols/SpdzWisePrep.h"
|
||||
#include "Protocols/SpdzWiseRep3Shuffler.h"
|
||||
#include "Protocols/SpdzWiseRing.h"
|
||||
#include "Protocols/SpdzWiseRingPrep.h"
|
||||
#include "Protocols/SpdzWiseRingShare.h"
|
||||
#include "Protocols/SpdzWiseShare.h"
|
||||
#include "Protocols/SquarePrep.h"
|
||||
#include "Protocols/TemiPrep.h"
|
||||
#include "Protocols/TemiShare.h"
|
||||
#include "Tools/aes.h"
|
||||
#include "Tools/avx_memcpy.h"
|
||||
#include "Tools/benchmarking.h"
|
||||
#include "Tools/BitVector.h"
|
||||
#include "Tools/Buffer.h"
|
||||
#include "Tools/Bundle.h"
|
||||
#include "Tools/callgrind.h"
|
||||
#include "Tools/CheckVector.h"
|
||||
#include "Tools/Commit.h"
|
||||
#include "Tools/Coordinator.h"
|
||||
#include "Tools/cpu_support.h"
|
||||
#include "Tools/DiskVector.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
#include "Tools/ExecutionStats.h"
|
||||
#include "Tools/FixedVector.h"
|
||||
#include "Tools/FlexBuffer.h"
|
||||
#include "Tools/Hash.h"
|
||||
#include "Tools/int.h"
|
||||
#include "Tools/intrinsics.h"
|
||||
#include "Tools/Lock.h"
|
||||
#include "Tools/MemoryUsage.h"
|
||||
#include "Tools/mkpath.h"
|
||||
#include "Tools/MMO.h"
|
||||
#include "Tools/NamedStats.h"
|
||||
#include "Tools/NetworkOptions.h"
|
||||
#include "Tools/octetStream.h"
|
||||
#include "Tools/oct.h"
|
||||
#include "Tools/OfflineMachineBase.h"
|
||||
#include "Tools/parse.h"
|
||||
#include "Tools/PointerVector.h"
|
||||
#include "Tools/pprint.h"
|
||||
#include "Tools/random.h"
|
||||
#include "Tools/Signal.h"
|
||||
#include "Tools/Subroutines.h"
|
||||
#include "Tools/SwitchableOutput.h"
|
||||
#include "Tools/time-func.h"
|
||||
#include "Tools/TimerWithComm.h"
|
||||
#include "Tools/WaitQueue.h"
|
||||
#include "Tools/Waksman.h"
|
||||
#include "Tools/Worker.h"
|
||||
#include "Yao/config.h"
|
||||
#include "Yao/YaoAndJob.h"
|
||||
#include "Yao/YaoCommon.h"
|
||||
#include "Yao/YaoEvalInput.h"
|
||||
#include "Yao/YaoEvalMaster.h"
|
||||
#include "Yao/YaoEvaluator.h"
|
||||
#include "Yao/YaoEvalWire.h"
|
||||
#include "Yao/YaoGarbleInput.h"
|
||||
#include "Yao/YaoGarbleMaster.h"
|
||||
#include "Yao/YaoGarbler.h"
|
||||
#include "Yao/YaoGarbleWire.h"
|
||||
#include "Yao/YaoGate.h"
|
||||
#include "Yao/YaoHalfGate.h"
|
||||
#include "Yao/YaoPlayer.h"
|
||||
#include "Yao/YaoWire.h"
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ShamirMachine.hpp"
|
||||
#include <Machines/Shamir.hpp>
|
||||
#include "MalRep.hpp"
|
||||
#include "Processor/OfflineMachine.hpp"
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/CcdPrep.hpp"
|
||||
#include "Machines/ShamirMachine.hpp"
|
||||
#include "Machines/Shamir.hpp"
|
||||
#include "Machines/MalRep.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Machines/ShamirMachine.h"
|
||||
#include "Protocols/MaliciousShamirShare.h"
|
||||
#include "Protocols/ShamirOptions.h"
|
||||
#include "Machines/MalRep.hpp"
|
||||
|
||||
#include "ShamirMachine.hpp"
|
||||
#include "Shamir.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
37
Machines/maximal.hpp
Normal file
37
Machines/maximal.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* maximal.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MACHINES_MAXIMAL_HPP_
|
||||
#define MACHINES_MAXIMAL_HPP_
|
||||
|
||||
#include "minimal.hpp"
|
||||
|
||||
#include "Atlas.hpp"
|
||||
#include "MalRep.hpp"
|
||||
#include "Rep4.hpp"
|
||||
#include "Rep.hpp"
|
||||
#include "RepRing.hpp"
|
||||
#include "Semi2k.hpp"
|
||||
#include "SPDZ2k.hpp"
|
||||
#include "SPDZ.hpp"
|
||||
|
||||
#include "GC/CcdPrep.hpp"
|
||||
#include "GC/TinierSharePrep.hpp"
|
||||
#include "GC/TinyPrep.hpp"
|
||||
#include "Protocols/ChaiGearPrep.hpp"
|
||||
#include "Protocols/CowGearPrep.hpp"
|
||||
#include "Protocols/DealerPrep.hpp"
|
||||
#include "Protocols/DealerInput.hpp"
|
||||
#include "Protocols/DealerMC.hpp"
|
||||
#include "Protocols/DealerMatrixPrep.hpp"
|
||||
#include "Protocols/SpdzWise.hpp"
|
||||
#include "Protocols/SpdzWiseRing.hpp"
|
||||
#include "Protocols/SpdzWiseInput.hpp"
|
||||
#include "Protocols/SpdzWisePrep.hpp"
|
||||
#include "Protocols/SpdzWiseShare.hpp"
|
||||
#include "Protocols/SpdzWiseRep3Shuffler.hpp"
|
||||
#include "Protocols/TemiPrep.hpp"
|
||||
|
||||
#endif /* MACHINES_MAXIMAL_HPP_ */
|
||||
26
Machines/minimal.hpp
Normal file
26
Machines/minimal.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* minimal.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
// minimal header file to make all C++ code compile
|
||||
// but not produce all templated code in binary
|
||||
// use maximal.hpp for that
|
||||
|
||||
// please report if otherwise
|
||||
|
||||
#ifndef MACHINES_MINIMAL_HPP_
|
||||
#define MACHINES_MINIMAL_HPP_
|
||||
|
||||
#include "h-files.h"
|
||||
|
||||
// some h files depend on hpp files
|
||||
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/SemiSecret.hpp"
|
||||
#include "Protocols/DealerMC.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
#include "Protocols/MaliciousRepMC.hpp"
|
||||
#include "Protocols/ShamirMC.hpp"
|
||||
|
||||
#endif /* MACHINES_MINIMAL_HPP_ */
|
||||
@@ -3,10 +3,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Machines/ShamirMachine.h"
|
||||
#include "Protocols/ShamirOptions.h"
|
||||
#include "Protocols/ShamirShare.h"
|
||||
|
||||
#include "ShamirMachine.hpp"
|
||||
#include "Shamir.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "Protocols/SohoShare.h"
|
||||
#include "Protocols/SPDZ.h"
|
||||
#include "Math/gfp.h"
|
||||
#include "Math/gf2n.h"
|
||||
#include "FHE/P2Data.h"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ShamirMachine.h"
|
||||
#include "Protocols/SpdzWiseShare.h"
|
||||
#include "Protocols/MaliciousShamirShare.h"
|
||||
#include "Protocols/SpdzWiseMC.h"
|
||||
@@ -19,7 +18,7 @@
|
||||
#include "Protocols/SpdzWisePrep.hpp"
|
||||
#include "Protocols/SpdzWiseInput.hpp"
|
||||
#include "Protocols/SpdzWiseShare.hpp"
|
||||
#include "Machines/ShamirMachine.hpp"
|
||||
#include "Machines/Shamir.hpp"
|
||||
#include "Machines/MalRep.hpp"
|
||||
|
||||
template<class T>
|
||||
|
||||
21
Makefile
21
Makefile
@@ -7,7 +7,7 @@ TOOLS = $(patsubst %.cpp,%.o,$(wildcard Tools/*.cpp))
|
||||
|
||||
NETWORK = $(patsubst %.cpp,%.o,$(wildcard Networking/*.cpp))
|
||||
|
||||
PROCESSOR = $(patsubst %.cpp,%.o,$(wildcard Processor/*.cpp))
|
||||
PROCESSOR = $(patsubst %.cpp,%.o,$(wildcard Processor/*.cpp)) Protocols/ShamirOptions.o
|
||||
|
||||
FHEOBJS = $(patsubst %.cpp,%.o,$(wildcard FHEOffline/*.cpp FHE/*.cpp)) Protocols/CowGearOptions.o
|
||||
|
||||
@@ -59,7 +59,7 @@ DEPS := $(wildcard */*.d */*/*.d)
|
||||
.SECONDARY: $(OBJS)
|
||||
|
||||
|
||||
all: arithmetic binary gen_input online offline externalIO bmr ecdsa
|
||||
all: arithmetic binary gen_input online offline externalIO bmr ecdsa export
|
||||
vm: arithmetic binary
|
||||
|
||||
.PHONY: doc
|
||||
@@ -124,7 +124,7 @@ tldr: setup
|
||||
mkdir Player-Data 2> /dev/null; true
|
||||
|
||||
ifeq ($(ARM), 1)
|
||||
$(patsubst %.cpp,%.o,$(wildcard */*.cpp)): deps/simde/simde
|
||||
$(patsubst %.cpp,%.o,$(wildcard */*.cpp */*/*.cpp)): deps/simde/simde deps/sse2neon/sse2neon.h
|
||||
endif
|
||||
|
||||
shamir: shamir-party.x malicious-shamir-party.x atlas-party.x galois-degree.x
|
||||
@@ -162,6 +162,16 @@ static-dir:
|
||||
|
||||
static-release: static-dir $(patsubst Machines/%.cpp, static/%.x, $(wildcard Machines/*-party.cpp)) $(patsubst Machines/BMR/%.cpp, static/%.x, $(wildcard Machines/BMR/*-party.cpp)) static/emulate.x
|
||||
|
||||
EXPORT_VM = $(patsubst %.cpp, %.o, $(wildcard Machines/export-*.cpp))
|
||||
.SECONDARY: $(EXPORT_VM)
|
||||
|
||||
export-trunc.x: Machines/export-ring.o
|
||||
export-sort.x: Machines/export-ring.o
|
||||
export-a2b.x: GC/AtlasSecret.o Machines/SPDZ.o Machines/SPDZ2^64+64.o $(GC_SEMI) $(TINIER) $(EXPORT_VM) GC/Rep4Secret.o GC/Rep4Prep.o $(FHEOFFLINE)
|
||||
export-b2a.x: Machines/export-ring.o
|
||||
|
||||
export: $(patsubst Utils/%.cpp, %.x, $(wildcard Utils/export*.cpp))
|
||||
|
||||
Fake-ECDSA.x: ECDSA/Fake-ECDSA.cpp ECDSA/P256Element.o $(COMMON) Processor/PrepBase.o
|
||||
$(CXX) -o $@ $^ $(CFLAGS) $(LDLIBS)
|
||||
|
||||
@@ -367,8 +377,11 @@ mac-machine-setup:
|
||||
deps/simde/simde:
|
||||
git submodule update --init deps/simde || git clone https://github.com/simd-everywhere/simde deps/simde
|
||||
|
||||
deps/sse2neon/sse2neon.h:
|
||||
git submodule update --init deps/sse2neon || git clone https://github.com/DLTcollab/sse2neon deps/sse2neon
|
||||
|
||||
clean-deps:
|
||||
-rm -rf local/lib/liblibOTe.* deps/libOTe/out deps/SimplestOT_C
|
||||
-rm -rf local/lib/liblibOTe.* deps/libOTe/out deps/SimplestOT_C deps/SimpleOT
|
||||
|
||||
clean: clean-deps
|
||||
-rm -f */*.o *.o */*.d *.d *.x core.* *.a gmon.out */*/*.o static/*.x *.so
|
||||
|
||||
@@ -63,25 +63,25 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
FixedVec<T, L>(const T& other = {})
|
||||
FixedVec(const T& other = {})
|
||||
{
|
||||
for (auto& x : v)
|
||||
x = other;
|
||||
}
|
||||
|
||||
FixedVec<T, L>(long other) :
|
||||
FixedVec<T, L>(T(other))
|
||||
FixedVec(long other) :
|
||||
FixedVec(T(other))
|
||||
{
|
||||
}
|
||||
|
||||
template<class U>
|
||||
FixedVec<T, L>(const FixedVec<U, L>& other)
|
||||
FixedVec(const FixedVec<U, L>& other)
|
||||
{
|
||||
for (int i = 0; i < L; i++)
|
||||
v[i] = other[i];
|
||||
}
|
||||
|
||||
FixedVec<T, L>(const array<T, L>& other)
|
||||
FixedVec(const array<T, L>& other)
|
||||
{
|
||||
v = other;
|
||||
}
|
||||
|
||||
@@ -71,14 +71,14 @@ int default_m(int& lgp, int& idx)
|
||||
return m;
|
||||
}
|
||||
|
||||
bigint generate_prime(int lgp, int m)
|
||||
bigint generate_prime(int lgp, int m, bool force_degree)
|
||||
{
|
||||
bigint p;
|
||||
generate_prime(p, lgp, m);
|
||||
generate_prime(p, lgp, m, force_degree);
|
||||
return p;
|
||||
}
|
||||
|
||||
void generate_prime(bigint& p, int lgp, int m)
|
||||
void generate_prime(bigint& p, int lgp, int m, bool force_degree)
|
||||
{
|
||||
if (OnlineOptions::singleton.prime > 0)
|
||||
{
|
||||
@@ -100,7 +100,8 @@ void generate_prime(bigint& p, int lgp, int m)
|
||||
}
|
||||
|
||||
int idx;
|
||||
m = max(m, default_m(lgp, idx));
|
||||
if (not force_degree)
|
||||
m = max(m, default_m(lgp, idx));
|
||||
|
||||
bigint u;
|
||||
int ex;
|
||||
|
||||
@@ -33,8 +33,8 @@ void check_setup(string dirname, bigint p);
|
||||
// Chooses a p of at least lgp bits
|
||||
bigint SPDZ_Data_Setup_Primes(int lgp);
|
||||
void SPDZ_Data_Setup_Primes(bigint& p,int lgp,int& idx,int& m);
|
||||
void generate_prime(bigint& p, int lgp, int m);
|
||||
bigint generate_prime(int lgp, int m);
|
||||
void generate_prime(bigint& p, int lgp, int m, bool force_degree = false);
|
||||
bigint generate_prime(int lgp, int m, bool force_degree = false);
|
||||
int default_m(int& lgp, int& idx);
|
||||
|
||||
string get_prep_sub_dir(const string& prep_dir, int nparties, int log2mod,
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
word get_upper() const { return _mm_cvtsi128_si64(_mm_unpackhi_epi64(a, a)); }
|
||||
word get_half(bool upper) const { return upper ? get_upper() : get_lower(); }
|
||||
|
||||
#ifdef __SSE41__
|
||||
#ifdef __SSE4_1__
|
||||
bool operator==(const int128& other) const { return _mm_test_all_zeros(a ^ other.a, a ^ other.a); }
|
||||
#else
|
||||
bool operator==(const int128& other) const { return get_lower() == other.get_lower() and get_upper() == other.get_upper(); }
|
||||
@@ -152,6 +152,8 @@ class gf2n_long : public gf2n_<int128>
|
||||
gf2n_long(const super& g) : super(g) {}
|
||||
gf2n_long(const int128& g) : super(g) {}
|
||||
gf2n_long(int g) : gf2n_long(int128(unsigned(g))) {}
|
||||
gf2n_long(long g) : gf2n_long(int128(g)) {}
|
||||
gf2n_long(word g) : gf2n_long(int128(g)) {}
|
||||
template<class T>
|
||||
gf2n_long(IntBase<T> g) : super(g.get()) {}
|
||||
template<class T>
|
||||
|
||||
@@ -311,6 +311,11 @@ typedef gfp_<1, GFP_MOD_SZ> gfp1;
|
||||
|
||||
template<int X, int L>
|
||||
Zp_Data gfp_<X, L>::ZpD;
|
||||
template<int X, int L>
|
||||
gfp_<X, L> gfp_<X, L>::two;
|
||||
|
||||
template<int X, int L>
|
||||
const true_type gfp_<X, L>::prime_field;
|
||||
|
||||
template<int X, int L>
|
||||
thread_local vector<gfp_<X, L>> gfp_<X, L>::powers;
|
||||
|
||||
@@ -13,11 +13,7 @@
|
||||
template<int X, int L>
|
||||
const true_type gfp_<X, L>::invertible;
|
||||
template<int X, int L>
|
||||
const true_type gfp_<X, L>::prime_field;
|
||||
template<int X, int L>
|
||||
const int gfp_<X, L>::MAX_N_BITS;
|
||||
template<int X, int L>
|
||||
gfp_<X, L> gfp_<X, L>::two;
|
||||
|
||||
template<int X, int L>
|
||||
inline void gfp_<X, L>::read_or_generate_setup(string dir,
|
||||
|
||||
@@ -95,8 +95,10 @@ CryptoPlayer::CryptoPlayer(const Names& Nms, const string& id_base) :
|
||||
continue;
|
||||
}
|
||||
|
||||
senders[i] = new Sender<ssl_socket*>(i < my_num() ? sockets[i] : other_sockets[i]);
|
||||
receivers[i] = new Receiver<ssl_socket*>(i < my_num() ? other_sockets[i] : sockets[i]);
|
||||
senders[i] = new Sender<ssl_socket*>(
|
||||
i < my_num() ? sockets[i] : other_sockets[i], i);
|
||||
receivers[i] = new Receiver<ssl_socket*>(
|
||||
i < my_num() ? other_sockets[i] : sockets[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,14 @@ void Names::init(int player, int pnb, const string& filename, int nplayers_wante
|
||||
}
|
||||
if (nplayers_wanted > 0 and nplayers_wanted != nplayers)
|
||||
exit_error("not enough hosts in " + filename);
|
||||
#ifdef DEBUG_NETWORKING
|
||||
cerr << "Got list of " << nplayers << " players from file: " << endl;
|
||||
for (unsigned int i = 0; i < names.size(); i++)
|
||||
cerr << " " << names[i] << ":" << ports[i] << endl;
|
||||
#endif
|
||||
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
{
|
||||
cerr << "Got list of " << nplayers << " players from file: " << endl;
|
||||
for (unsigned int i = 0; i < names.size(); i++)
|
||||
cerr << " " << names[i] << ":" << ports[i] << endl;
|
||||
}
|
||||
|
||||
setup_server();
|
||||
}
|
||||
|
||||
@@ -140,9 +143,9 @@ void Names::setup_names(const char *servername, int my_port)
|
||||
}
|
||||
|
||||
octetStream("P" + to_string(player_no)).Send(socket_num);
|
||||
#ifdef DEBUG_NETWORKING
|
||||
cerr << "Sent " << player_no << " to " << servername << ":" << pn << endl;
|
||||
#endif
|
||||
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
cerr << "Sent " << player_no << " to " << servername << ":" << pn << endl;
|
||||
|
||||
// Send my name
|
||||
sockaddr_in address;
|
||||
@@ -151,10 +154,12 @@ void Names::setup_names(const char *servername, int my_port)
|
||||
char* my_name = inet_ntoa(address.sin_addr);
|
||||
octetStream(my_name).Send(socket_num);
|
||||
send(socket_num,(octet*)&my_port,4);
|
||||
#ifdef DEBUG_NETWORKING
|
||||
fprintf(stderr, "My Name = %s\n",my_name);
|
||||
cerr << "My number = " << player_no << endl;
|
||||
#endif
|
||||
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
{
|
||||
fprintf(stderr, "My Name = %s\n",my_name);
|
||||
cerr << "My number = " << player_no << endl;
|
||||
}
|
||||
|
||||
// Now get the set of names
|
||||
try
|
||||
@@ -172,10 +177,12 @@ void Names::setup_names(const char *servername, int my_port)
|
||||
if (names.size() != ports.size())
|
||||
exit_error("invalid network setup");
|
||||
nplayers = names.size();
|
||||
#ifdef VERBOSE
|
||||
for (int i = 0; i < nplayers; i++)
|
||||
cerr << "Player " << i << " is running on machine " << names[i] << endl;
|
||||
#endif
|
||||
|
||||
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
for (int i = 0; i < nplayers; i++)
|
||||
cerr << "Player " << i << " is running on machine " << names[i] << endl;
|
||||
|
||||
close_client_socket(socket_num);
|
||||
}
|
||||
|
||||
@@ -640,8 +647,8 @@ ThreadPlayer::ThreadPlayer(const Names& Nms, const string& id_base) :
|
||||
{
|
||||
for (int i = 0; i < Nms.num_players(); i++)
|
||||
{
|
||||
receivers.push_back(new Receiver<int>(sockets[i]));
|
||||
senders.push_back(new Sender<int>(socket_to_send(i)));
|
||||
receivers.push_back(new Receiver<int>(sockets[i], i));
|
||||
senders.push_back(new Sender<int>(socket_to_send(i), i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,10 +852,15 @@ Timer& CommStatsWithName::add_length_only(size_t length)
|
||||
}
|
||||
|
||||
Timer& CommStatsWithName::add(const octetStream& os)
|
||||
{
|
||||
return add(os.get_length());
|
||||
}
|
||||
|
||||
Timer& CommStatsWithName::add(size_t length)
|
||||
{
|
||||
if (OnlineOptions::singleton.has_option("verbose_comm"))
|
||||
fprintf(stderr, "%s %zu bytes\n", name.c_str(), os.get_length());
|
||||
return stats.add(os);
|
||||
fprintf(stderr, "%s %zu bytes\n", name.c_str(), length);
|
||||
return stats.add(length);
|
||||
}
|
||||
|
||||
void Player::reset_stats()
|
||||
|
||||
@@ -160,6 +160,7 @@ public:
|
||||
|
||||
Timer& add_length_only(size_t length);
|
||||
Timer& add(const octetStream& os);
|
||||
Timer& add(size_t length);
|
||||
void add(const octetStream& os, const TimeScope& scope) { add(os) += scope; }
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "Receiver.h"
|
||||
#include "ssl_sockets.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
@@ -19,8 +20,14 @@ void* Receiver<T>::run_thread(void* receiver)
|
||||
return 0;
|
||||
}
|
||||
|
||||
CommunicationThread::CommunicationThread(int other) :
|
||||
other(other)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Receiver<T>::Receiver(T socket) : socket(socket), thread(0)
|
||||
Receiver<T>::Receiver(T socket, int other) :
|
||||
CommunicationThread(other), socket(socket), thread(0)
|
||||
{
|
||||
start();
|
||||
}
|
||||
@@ -44,8 +51,28 @@ void Receiver<T>::stop()
|
||||
pthread_join(thread, 0);
|
||||
}
|
||||
|
||||
void CommunicationThread::run()
|
||||
{
|
||||
if (OnlineOptions::singleton.has_option("throw_exceptions"))
|
||||
run_with_error();
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
run_with_error();
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
cerr << "Fatal error in communication: " << e.what() << endl;
|
||||
cerr << "This is probably because party " << other
|
||||
<< " encountered a problem." << endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Receiver<T>::run()
|
||||
void Receiver<T>::run_with_error()
|
||||
{
|
||||
octetStream* os = 0;
|
||||
while (in.pop(os))
|
||||
|
||||
@@ -12,8 +12,20 @@
|
||||
#include "Tools/WaitQueue.h"
|
||||
#include "Tools/time-func.h"
|
||||
|
||||
class CommunicationThread
|
||||
{
|
||||
int other;
|
||||
|
||||
protected:
|
||||
CommunicationThread(int other);
|
||||
virtual ~CommunicationThread() {}
|
||||
|
||||
void run();
|
||||
virtual void run_with_error() = 0;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class Receiver
|
||||
class Receiver : CommunicationThread
|
||||
{
|
||||
T socket;
|
||||
WaitQueue<octetStream*> in;
|
||||
@@ -27,12 +39,12 @@ class Receiver
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void run();
|
||||
void run_with_error();
|
||||
|
||||
public:
|
||||
Timer timer;
|
||||
|
||||
Receiver(T socket);
|
||||
Receiver(T socket, int other);
|
||||
~Receiver();
|
||||
|
||||
T get_socket()
|
||||
|
||||
@@ -17,7 +17,8 @@ void* Sender<T>::run_thread(void* sender)
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Sender<T>::Sender(T socket) : socket(socket), thread(0)
|
||||
Sender<T>::Sender(T socket, int other) :
|
||||
CommunicationThread(other), socket(socket), thread(0)
|
||||
{
|
||||
start();
|
||||
}
|
||||
@@ -42,7 +43,7 @@ void Sender<T>::stop()
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Sender<T>::run()
|
||||
void Sender<T>::run_with_error()
|
||||
{
|
||||
const octetStream* os = 0;
|
||||
while (in.pop(os))
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "Receiver.h"
|
||||
|
||||
#include "Tools/octetStream.h"
|
||||
#include "Tools/WaitQueue.h"
|
||||
#include "Tools/time-func.h"
|
||||
|
||||
template<class T>
|
||||
class Sender
|
||||
class Sender : CommunicationThread
|
||||
{
|
||||
T socket;
|
||||
WaitQueue<const octetStream*> in;
|
||||
@@ -27,12 +29,12 @@ class Sender
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void run();
|
||||
void run_with_error();
|
||||
|
||||
public:
|
||||
Timer timer;
|
||||
|
||||
Sender(T socket);
|
||||
Sender(T socket, int other);
|
||||
~Sender();
|
||||
|
||||
T get_socket()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Networking/sockets.h"
|
||||
#include "Networking/ServerSocket.h"
|
||||
#include "Networking/Server.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <pthread.h>
|
||||
@@ -30,26 +31,23 @@ void Server::get_ip(int num)
|
||||
|
||||
names[num] = ipstr;
|
||||
|
||||
#ifdef DEBUG_NETWORKING
|
||||
cerr << "Client IP address: " << names[num] << endl;
|
||||
#endif
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
cerr << "IP address of party " << num << ": " << names[num] << endl;
|
||||
}
|
||||
|
||||
|
||||
void Server::get_name(int num)
|
||||
{
|
||||
#ifdef DEBUG_NETWORKING
|
||||
cerr << "Player " << num << " started." << endl;
|
||||
#endif
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
cerr << "Player " << num << " started." << endl;
|
||||
|
||||
// Receive name sent by client (legacy) - not used here
|
||||
octetStream os;
|
||||
os.Receive(socket_num[num]);
|
||||
receive(socket_num[num],(octet*)&ports[num],4);
|
||||
#ifdef DEBUG_NETWORKING
|
||||
cerr << "Player " << num << " sent (IP for info only) " << os.str() << ":"
|
||||
<< ports[num] << endl;
|
||||
#endif
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
cerr << "Player " << num << " listening on " << os.str() << ":"
|
||||
<< ports[num] << endl;
|
||||
|
||||
// Get client IP
|
||||
get_ip(num);
|
||||
@@ -121,13 +119,13 @@ void Server::start()
|
||||
// set up connections
|
||||
for (i=0; i<nmachines; i++)
|
||||
{
|
||||
#ifdef DEBUG_NETWORKING
|
||||
cerr << "Waiting for player " << i << endl;
|
||||
#endif
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
cerr << "Waiting for player " << i << endl;
|
||||
|
||||
socket_num[i] = server.get_connection_socket("P" + to_string(i));
|
||||
#ifdef DEBUG_NETWORKING
|
||||
cerr << "Connected to player " << i << endl;
|
||||
#endif
|
||||
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
cerr << "Connected to player " << i << endl;
|
||||
}
|
||||
|
||||
// get names
|
||||
@@ -164,10 +162,10 @@ void* Server::start_in_thread(void* server)
|
||||
Server* Server::start_networking(Names& N, int my_num, int nplayers,
|
||||
string hostname, int portnum, int my_port)
|
||||
{
|
||||
#ifdef DEBUG_NETWORKING
|
||||
cerr << "Starting networking for " << my_num << "/" << nplayers
|
||||
<< " with server on " << hostname << ":" << (portnum) << endl;
|
||||
#endif
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
cerr << "Starting networking for " << my_num << "/" << nplayers
|
||||
<< " with server on " << hostname << ":" << (portnum) << endl;
|
||||
|
||||
if (my_num < 0 or my_num >= nplayers)
|
||||
{
|
||||
cerr << "Player number " << my_num << " outside range: 0-"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "Tools/Exceptions.h"
|
||||
#include "Tools/time-func.h"
|
||||
#include "Tools/octetStream.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
@@ -60,10 +61,9 @@ ServerSocket::ServerSocket(int Portnum) : portnum(Portnum), thread(0)
|
||||
<< "), trying again in a second ..." << endl;
|
||||
sleep(1);
|
||||
}
|
||||
#ifdef DEBUG_NETWORKING
|
||||
else
|
||||
{ cerr << "ServerSocket is bound on port " << Portnum << endl; }
|
||||
#endif
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
cerr << "ServerSocket is bound on port " << Portnum << endl;
|
||||
}
|
||||
if (fl<0) { error("set_up_socket:bind"); }
|
||||
|
||||
@@ -121,11 +121,12 @@ void ServerSocket::wait_for_client_id(int socket, struct sockaddr dest)
|
||||
}
|
||||
catch (closed_connection&)
|
||||
{
|
||||
#ifdef DEBUG_NETWORKING
|
||||
auto& conn = *(sockaddr_in*) &dest;
|
||||
fprintf(stderr, "client on %s:%d left without identification\n",
|
||||
inet_ntoa(conn.sin_addr), ntohs(conn.sin_port));
|
||||
#endif
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
{
|
||||
auto& conn = *(sockaddr_in*) &dest;
|
||||
fprintf(stderr, "client on %s:%d left without identification\n",
|
||||
inet_ntoa(conn.sin_addr), ntohs(conn.sin_port));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,19 +2,23 @@
|
||||
#include "sockets.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
#include "Tools/time-func.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fcntl.h>
|
||||
using namespace std;
|
||||
|
||||
void error(const char *str)
|
||||
void error(const char *str, bool interrupted)
|
||||
{
|
||||
int old_errno = errno;
|
||||
char err[1000];
|
||||
gethostname(err,1000);
|
||||
strcat(err," : ");
|
||||
strcat(err,str);
|
||||
exit_error(string() + err + " : " + strerror(old_errno));
|
||||
gethostname(err, 1000);
|
||||
err[999] = 0;
|
||||
string message = string() + "Fatal communication error on " + err + ": "
|
||||
+ str + " (" + strerror(old_errno) + ")";
|
||||
if (interrupted)
|
||||
message += "\nThis is probably because another party encountered a problem.";
|
||||
exit_error(message);
|
||||
}
|
||||
|
||||
void set_up_client_socket(int& mysocket,const char* hostname,int Portnum)
|
||||
@@ -91,12 +95,13 @@ void set_up_client_socket(int& mysocket,const char* hostname,int Portnum)
|
||||
{
|
||||
close(mysocket);
|
||||
usleep(wait < 1000 ? wait *= 2 : wait);
|
||||
#ifdef DEBUG_NETWORKING
|
||||
string msg = "Connecting to " + string(hostname) + ":" +
|
||||
to_string(Portnum) + " failed";
|
||||
errno = connect_errno;
|
||||
perror(msg.c_str());
|
||||
#endif
|
||||
if (OnlineOptions::singleton.has_option("debug_networking"))
|
||||
{
|
||||
string msg = "Connecting to " + string(hostname) + ":"
|
||||
+ to_string(Portnum) + " failed";
|
||||
errno = connect_errno;
|
||||
perror(msg.c_str());
|
||||
}
|
||||
}
|
||||
errno = connect_errno;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ using namespace std;
|
||||
#define CONNECTION_TIMEOUT 60
|
||||
#endif
|
||||
|
||||
void error(const char *str);
|
||||
void error(const char *str, bool interrupted = false);
|
||||
|
||||
void set_up_client_socket(int& mysocket,const char* hostname,int Portnum);
|
||||
void close_client_socket(int socket);
|
||||
@@ -51,7 +51,7 @@ inline size_t send_non_blocking(int socket, octet* msg, size_t len)
|
||||
{
|
||||
if (errno != EINTR and errno != EAGAIN and errno != EWOULDBLOCK and
|
||||
errno != ENOBUFS)
|
||||
{ error("Send error - 1 "); }
|
||||
{ error("Sending error", true); }
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@@ -103,14 +103,14 @@ inline void receive(int socket,octet *msg,size_t len)
|
||||
if (errno == EAGAIN or errno == EINTR)
|
||||
{
|
||||
if (++fail > 25)
|
||||
error("Unavailable too many times");
|
||||
error("Unavailable too many times", true);
|
||||
else
|
||||
{
|
||||
usleep(wait *= 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ error("Receiving error - 1"); }
|
||||
{ error("Receiving error", true); }
|
||||
}
|
||||
else
|
||||
throw closed_connection();
|
||||
@@ -130,7 +130,7 @@ inline ssize_t check_non_blocking_result(ssize_t res)
|
||||
if (res < 0)
|
||||
{
|
||||
if (errno != EWOULDBLOCK)
|
||||
error("Non-blocking receiving error");
|
||||
error("Non-blocking receiving error", true);
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
@@ -149,7 +149,7 @@ inline ssize_t receive_all_or_nothing(int socket, octet *msg, ssize_t len)
|
||||
if (res == len)
|
||||
{
|
||||
if (recv(socket, msg, len, 0) != len)
|
||||
error("All or nothing receiving error");
|
||||
error("All or nothing receiving error", true);
|
||||
return len;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -111,6 +111,16 @@ void receiver_keygen(ref10_RECEIVER* r, unsigned char (*keys)[HASHBYTES])
|
||||
ref10_receiver_keygen(r, keys);
|
||||
}
|
||||
|
||||
void BaseOT::allocate()
|
||||
{
|
||||
for (int i = 0; i < nOT; i++)
|
||||
{
|
||||
sender_inputs[i][0] = BitVector(8 * AES_BLK_SIZE);
|
||||
sender_inputs[i][1] = BitVector(8 * AES_BLK_SIZE);
|
||||
receiver_outputs[i] = BitVector(8 * AES_BLK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
int BaseOT::avx = -1;
|
||||
|
||||
bool BaseOT::use_avx()
|
||||
@@ -186,6 +196,7 @@ void BaseOT::exec_base(bool new_receiver_inputs)
|
||||
}
|
||||
|
||||
os[0].reset_write_head();
|
||||
allocate();
|
||||
|
||||
for (i = 0; i < nOT; i += 4)
|
||||
{
|
||||
@@ -409,6 +420,8 @@ void FakeOT::exec_base(bool new_receiver_inputs)
|
||||
vector<octetStream> os(2);
|
||||
vector<BitVector> bv(2, 128);
|
||||
|
||||
allocate();
|
||||
|
||||
if ((ot_role & RECEIVER) && new_receiver_inputs)
|
||||
{
|
||||
for (int i = 0; i < nOT; i++)
|
||||
|
||||
@@ -61,13 +61,6 @@ public:
|
||||
receiver_outputs.resize(nOT);
|
||||
G_sender.resize(nOT);
|
||||
G_receiver.resize(nOT);
|
||||
|
||||
for (int i = 0; i < nOT; i++)
|
||||
{
|
||||
sender_inputs[i][0] = BitVector(8 * AES_BLK_SIZE);
|
||||
sender_inputs[i][1] = BitVector(8 * AES_BLK_SIZE);
|
||||
receiver_outputs[i] = BitVector(8 * AES_BLK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
BaseOT(TwoPartyPlayer* player, OT_ROLE role) :
|
||||
@@ -118,6 +111,8 @@ protected:
|
||||
bool is_sender() { return (bool) (ot_role & SENDER); }
|
||||
bool is_receiver() { return (bool) (ot_role & RECEIVER); }
|
||||
|
||||
void allocate();
|
||||
|
||||
bool use_avx();
|
||||
|
||||
/// CPU-specific instantiation of Simplest OT using Curve25519
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Protocols/MAC_Check.h"
|
||||
#include "GC/SemiSecret.h"
|
||||
#include "GC/SemiPrep.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
|
||||
#include "OT/Triple.hpp"
|
||||
#include "OT/OTMultiplier.hpp"
|
||||
@@ -25,7 +26,21 @@ template<class T>
|
||||
void* run_ot_thread(void* ptr)
|
||||
{
|
||||
bigint::init_thread();
|
||||
((OTMultiplierBase*)ptr)->multiply();
|
||||
auto multiplier = (OTMultiplierBase*) ptr;
|
||||
if (OnlineOptions::singleton.has_option("throw_exceptions"))
|
||||
multiplier->multiply();
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
multiplier->multiply();
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
cerr << "Fatal error in OT thread: " << e.what() << endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
11
OT/Row.hpp
11
OT/Row.hpp
@@ -110,20 +110,13 @@ void DeferredPlus<T, U>::pack(octetStream& o) const
|
||||
template<class T>
|
||||
void Row<T>::pack(octetStream& o) const
|
||||
{
|
||||
o.store(this->size());
|
||||
for (size_t i = 0; i < this->size(); i++)
|
||||
rows[i].pack(o);
|
||||
o.store(rows);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Row<T>::unpack(octetStream& o)
|
||||
{
|
||||
size_t size;
|
||||
o.get(size);
|
||||
rows.clear();
|
||||
rows.reserve(size);
|
||||
for (size_t i = 0; i < size; i++)
|
||||
rows.push_back(o.get<T>());
|
||||
o.get(rows);
|
||||
}
|
||||
|
||||
template <class V>
|
||||
|
||||
@@ -30,7 +30,7 @@ BaseMachine& BaseMachine::s()
|
||||
if (singleton)
|
||||
return *singleton;
|
||||
else
|
||||
throw runtime_error("no singleton");
|
||||
throw runtime_error("no BaseMachine singleton");
|
||||
}
|
||||
|
||||
bool BaseMachine::has_program()
|
||||
@@ -72,7 +72,8 @@ int BaseMachine::bucket_size(size_t usage)
|
||||
|
||||
int BaseMachine::matrix_batch_size(int n_rows, int n_inner, int n_cols)
|
||||
{
|
||||
unsigned res = min(100, OnlineOptions::singleton.batch_size);
|
||||
int limit = max(1., 1e6 / (max(n_rows * n_inner, n_inner * n_cols)));
|
||||
unsigned res = min(limit, OnlineOptions::singleton.batch_size);
|
||||
if (has_program())
|
||||
res = min(res, (unsigned) matrix_requirement(n_rows, n_inner, n_cols));
|
||||
return res;
|
||||
@@ -93,7 +94,8 @@ int BaseMachine::matrix_requirement(int n_rows, int n_inner, int n_cols)
|
||||
return -1;
|
||||
}
|
||||
|
||||
BaseMachine::BaseMachine() : nthreads(0)
|
||||
BaseMachine::BaseMachine() :
|
||||
nthreads(0), multithread(false)
|
||||
{
|
||||
if (sodium_init() == -1)
|
||||
throw runtime_error("couldn't initialize libsodium");
|
||||
@@ -147,7 +149,12 @@ void BaseMachine::load_schedule(const string& progname, bool load_bytecode)
|
||||
#endif
|
||||
long size = load_program(threadname, filename);
|
||||
if (expected >= 0 and expected != size)
|
||||
throw runtime_error("broken bytecode file");
|
||||
{
|
||||
stringstream os;
|
||||
os << "broken bytecode file, found " << size
|
||||
<< " instructions, expected " << expected;
|
||||
throw runtime_error(os.str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ class Binary_File_IO
|
||||
* Throws file_error.
|
||||
*/
|
||||
template <class T>
|
||||
void read_from_file(const string filename, vector< T >& buffer, const int start_posn, int &end_posn);
|
||||
void read_from_file(const string filename, vector<T>& buffer,
|
||||
const long start_posn, long& end_posn);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user