Skip to content

Commit

Permalink
Multinode computation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkskeller committed Dec 14, 2023
1 parent 1f8f784 commit cf4426f
Show file tree
Hide file tree
Showing 130 changed files with 2,505 additions and 799 deletions.
1 change: 1 addition & 0 deletions BMR/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <cstring>
#include <string>
#include <vector>
#include <stdint.h>
using namespace std;

#include "Tools/CheckVector.h"
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
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.3.8 (December 14, 2023)

- Functionality for multiple nodes per party
- Functionality to use disk space for high-level data structures
- True division is always fixed-point division (similar to Python 3)
- Compiler option to optimize for specific protocol
- Cleartext permutation
- Faster compilation and lower bytecode size
- Functionality to output secret shares from high-level code
- Run-time command-line arguments accessible from high-level code
- Client connection setup specifies cleartext domain
- Compile-time parameter for connection timeout
- Prevent connections from timing out (@ParallelogramPal)
- More ECDSA examples
- More flexible multiplication instruction
- Dot product instruction supports several operations at once
- Example-based virtual machine explanation

## 0.3.7 (August 14, 2023)

- Path Oblivious Heap (@tskovlund)
Expand Down
1 change: 1 addition & 0 deletions CONFIG
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ LDLIBS = -lgmpxx -lgmp -lsodium $(MY_LDLIBS)
LDLIBS += $(BREW_LDLIBS)
LDLIBS += -Wl,-rpath -Wl,$(CURDIR)/local/lib -L$(CURDIR)/local/lib
LDLIBS += -lboost_system -lssl -lcrypto
LDLIBS += -lboost_filesystem -lboost_iostreams

CFLAGS += -I./local/include

Expand Down
27 changes: 14 additions & 13 deletions Compiler/GC/instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,17 @@ class ClearBitsAF(base.RegisterArgFormat):
CONVCBITVEC = 0x231,
)

class BinaryVectorInstruction(base.Instruction):
is_vec = lambda self: True
class BinaryCiscable(base.Ciscable):
pass

def copy(self, size, subs):
return type(self)(*self.get_new_args(size, subs))
class BinaryVectorInstruction(BinaryCiscable):
is_vec = lambda self: True

class NonVectorInstruction(base.Instruction):
is_vec = lambda self: False

def __init__(self, *args, **kwargs):
assert(args[0].n <= args[0].unit)
assert(args[0].n is None or args[0].n <= args[0].unit)
super(NonVectorInstruction, self).__init__(*args, **kwargs)

class NonVectorInstruction1(base.Instruction):
Expand Down Expand Up @@ -163,7 +163,7 @@ def add_usage(self, req_node):
sum(int(math.ceil(x / 64)) for x in self.args[::4]))

class andrsvec(base.VarArgsInstruction, base.Mergeable,
base.DynFormatInstruction):
base.DynFormatInstruction, BinaryCiscable):
""" Constant-vector AND of secret bit registers (vectorized version).
:param: total number of arguments to follow (int)
Expand Down Expand Up @@ -206,6 +206,9 @@ def add_usage(self, req_node):
req_node.increment(('bit', 'triple'), size * (n - 3) // 2)
req_node.increment(('bit', 'mixed'), size)

def copy(self, size, subs):
return type(self)(*self.get_new_args(size, subs))

class ands(BinaryVectorInstruction):
""" Bitwise AND of secret bit register vector.
Expand Down Expand Up @@ -306,7 +309,7 @@ class bitcoms(NonVectorInstruction, base.VarArgsInstruction):
arg_format = tools.chain(['sbw'], itertools.repeat('sb'))

class bitdecc(NonVectorInstruction, base.VarArgsInstruction):
""" Secret bit register decomposition.
""" Clear bit register decomposition.
:param: number of arguments to follow / number of bits plus one (int)
:param: source (sbit)
Expand Down Expand Up @@ -513,8 +516,8 @@ class convcbitvec(BinaryVectorInstruction):
"""
code = opcodes['CONVCBITVEC']
arg_format = ['int','ciw','cb']
def __init__(self, *args):
super(convcbitvec, self).__init__(*args)
def __init__(self, *args, **kwargs):
super(convcbitvec, self).__init__(*args, **kwargs)
assert(args[2].n == args[0])
args[1].set_size(args[0])

Expand Down Expand Up @@ -546,14 +549,14 @@ def __init__(self, *args, **kwargs):
super(split_class, self).__init__(*args, **kwargs)
assert (len(args) - 2) % args[0] == 0

class movsb(NonVectorInstruction):
class movsb(BinaryVectorInstruction):
""" Copy secret bit register.
:param: destination (sbit)
:param: source (sbit)
"""
code = opcodes['MOVSB']
arg_format = ['sbw','sb']
arg_format = ['int', 'sbw','sb']

class trans(base.VarArgsInstruction, base.DynFormatInstruction):
""" Secret bit register vector transpose. The first destination vector
Expand All @@ -568,8 +571,6 @@ class trans(base.VarArgsInstruction, base.DynFormatInstruction):
"""
code = opcodes['TRANS']
is_vec = lambda self: True
def __init__(self, *args):
super(trans, self).__init__(*args)

@classmethod
def dynamic_arg_format(cls, args):
Expand Down
53 changes: 46 additions & 7 deletions Compiler/GC/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ def bit_decompose_clear(a, n_bits):
cbits.conv_cint_vec(a, *res)
return res
@classmethod
def malloc(cls, size, creator_tape=None):
return Program.prog.malloc(size, cls, creator_tape=creator_tape)
def malloc(cls, size, creator_tape=None, **kwargs):
return Program.prog.malloc(size, cls, creator_tape=creator_tape,
**kwargs)
@staticmethod
def n_elements():
return 1
Expand Down Expand Up @@ -254,6 +255,18 @@ def expand(self, length):
return self.get_type(length).bit_compose([self] * length)
else:
raise CompilerError('cannot expand from %s to %s' % (self.n, length))
@classmethod
def new_vector(cls, size):
return cls.get_type(size)()
@classmethod
def concat(cls, parts):
return cls.bit_compose(
sum([part.bit_decompose() for part in parts], []))
def copy_from_part(self, source, base, size):
self.mov(self,
self.bit_compose(source.bit_decompose()[base:base + size]))
def vector_size(self):
return self.n

class cbits(bits):
""" Clear bits register. Helper type with limited functionality. """
Expand Down Expand Up @@ -425,7 +438,7 @@ def conv_regint_by_bit(cls, n, res, other):
tmp = cbits.get_type(n)()
tmp.conv_regint_by_bit(n, tmp, other)
res.load_other(tmp)
mov = inst.movsb
mov = staticmethod(lambda x, y: inst.movsb(x.n, x, y))
types = {}
def __init__(self, *args, **kwargs):
bits.__init__(self, *args, **kwargs)
Expand Down Expand Up @@ -1048,6 +1061,9 @@ def f(res):

class sbit(bit, sbits):
""" Single secret bit. """
@classmethod
def get_type(cls, length):
return sbits.get_type(length)
def if_else(self, x, y):
""" Non-vectorized oblivious selection::
Expand Down Expand Up @@ -1301,6 +1317,7 @@ class sbitintvec(sbitvec, _bitint, _number, _sbitintbase):
"""
bit_extend = staticmethod(_complement_two_extend)
mul_functions = {}
@classmethod
def popcnt_bits(cls, bits):
return sbitvec.from_vec(bits).popcnt()
Expand All @@ -1326,20 +1343,42 @@ def __mul__(self, other):
elif isinstance(other, sbitfixvec):
return NotImplemented
my_bits, other_bits = self.expand(other, False)
matrix = []
m = float('inf')
uniform = True
for x in itertools.chain(my_bits, other_bits):
try:
uniform &= type(x) == type(my_bits[0]) and x.n == my_bits[0].n
m = min(m, x.n)
except:
pass
if uniform and Program.prog.options.cisc:
bl = len(my_bits)
key = bl, len(other_bits)
if key not in self.mul_functions:
def instruction(*args):
res = self.binary_mul(args[bl:2 * bl], args[2 * bl:],
args[0].n)
for x, y in zip(res, args):
x.mov(y, x)
instruction.__name__ = 'binary_mul%sx%s' % (bl, len(other_bits))
self.mul_functions[key] = instructions_base.cisc(instruction,
bl)
res = [sbits.get_type(m)() for i in range(bl)]
self.mul_functions[key](*(res + my_bits + other_bits))
return self.from_vec(res)
else:
return self.binary_mul(my_bits, other_bits, m)
@classmethod
def binary_mul(cls, my_bits, other_bits, m):
matrix = []
for i, b in enumerate(other_bits):
if m == 1:
matrix.append([x * b for x in my_bits[:len(self.v)-i]])
matrix.append([x * b for x in my_bits[:len(my_bits)-i]])
else:
matrix.append((sbitvec.from_vec(my_bits[:len(self.v)-i]) * b).v)
matrix.append((
sbitvec.from_vec(my_bits[:len(my_bits)-i]) * b).v)
v = sbitint.wallace_tree_from_matrix(matrix)
return self.from_vec(v[:len(self.v)])
return cls.from_vec(v[:len(my_bits)])
__rmul__ = __mul__
reduce_after_mul = lambda x: x
def TruncMul(self, other, k, m, kappa=None, nearest=False):
Expand Down
Loading

0 comments on commit cf4426f

Please sign in to comment.