Skip to content

Commit cf4426f

Browse files
committed
Multinode computation.
1 parent 1f8f784 commit cf4426f

File tree

130 files changed

+2505
-799
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+2505
-799
lines changed

BMR/common.h

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <cstring>
1111
#include <string>
1212
#include <vector>
13+
#include <stdint.h>
1314
using namespace std;
1415

1516
#include "Tools/CheckVector.h"

CHANGELOG.md

+18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
The changelog explains changes pulled through from the private development repository. Bug fixes and small enhancements are committed between releases and not documented here.
22

3+
## 0.3.8 (December 14, 2023)
4+
5+
- Functionality for multiple nodes per party
6+
- Functionality to use disk space for high-level data structures
7+
- True division is always fixed-point division (similar to Python 3)
8+
- Compiler option to optimize for specific protocol
9+
- Cleartext permutation
10+
- Faster compilation and lower bytecode size
11+
- Functionality to output secret shares from high-level code
12+
- Run-time command-line arguments accessible from high-level code
13+
- Client connection setup specifies cleartext domain
14+
- Compile-time parameter for connection timeout
15+
- Prevent connections from timing out (@ParallelogramPal)
16+
- More ECDSA examples
17+
- More flexible multiplication instruction
18+
- Dot product instruction supports several operations at once
19+
- Example-based virtual machine explanation
20+
321
## 0.3.7 (August 14, 2023)
422

523
- Path Oblivious Heap (@tskovlund)

CONFIG

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ LDLIBS = -lgmpxx -lgmp -lsodium $(MY_LDLIBS)
8787
LDLIBS += $(BREW_LDLIBS)
8888
LDLIBS += -Wl,-rpath -Wl,$(CURDIR)/local/lib -L$(CURDIR)/local/lib
8989
LDLIBS += -lboost_system -lssl -lcrypto
90+
LDLIBS += -lboost_filesystem -lboost_iostreams
9091

9192
CFLAGS += -I./local/include
9293

Compiler/GC/instructions.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,17 @@ class ClearBitsAF(base.RegisterArgFormat):
8080
CONVCBITVEC = 0x231,
8181
)
8282

83-
class BinaryVectorInstruction(base.Instruction):
84-
is_vec = lambda self: True
83+
class BinaryCiscable(base.Ciscable):
84+
pass
8585

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

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

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

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

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

209+
def copy(self, size, subs):
210+
return type(self)(*self.get_new_args(size, subs))
211+
209212
class ands(BinaryVectorInstruction):
210213
""" Bitwise AND of secret bit register vector.
211214
@@ -306,7 +309,7 @@ class bitcoms(NonVectorInstruction, base.VarArgsInstruction):
306309
arg_format = tools.chain(['sbw'], itertools.repeat('sb'))
307310

308311
class bitdecc(NonVectorInstruction, base.VarArgsInstruction):
309-
""" Secret bit register decomposition.
312+
""" Clear bit register decomposition.
310313
311314
:param: number of arguments to follow / number of bits plus one (int)
312315
:param: source (sbit)
@@ -513,8 +516,8 @@ class convcbitvec(BinaryVectorInstruction):
513516
"""
514517
code = opcodes['CONVCBITVEC']
515518
arg_format = ['int','ciw','cb']
516-
def __init__(self, *args):
517-
super(convcbitvec, self).__init__(*args)
519+
def __init__(self, *args, **kwargs):
520+
super(convcbitvec, self).__init__(*args, **kwargs)
518521
assert(args[2].n == args[0])
519522
args[1].set_size(args[0])
520523

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

549-
class movsb(NonVectorInstruction):
552+
class movsb(BinaryVectorInstruction):
550553
""" Copy secret bit register.
551554
552555
:param: destination (sbit)
553556
:param: source (sbit)
554557
"""
555558
code = opcodes['MOVSB']
556-
arg_format = ['sbw','sb']
559+
arg_format = ['int', 'sbw','sb']
557560

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

574575
@classmethod
575576
def dynamic_arg_format(cls, args):

Compiler/GC/types.py

+46-7
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ def bit_decompose_clear(a, n_bits):
9797
cbits.conv_cint_vec(a, *res)
9898
return res
9999
@classmethod
100-
def malloc(cls, size, creator_tape=None):
101-
return Program.prog.malloc(size, cls, creator_tape=creator_tape)
100+
def malloc(cls, size, creator_tape=None, **kwargs):
101+
return Program.prog.malloc(size, cls, creator_tape=creator_tape,
102+
**kwargs)
102103
@staticmethod
103104
def n_elements():
104105
return 1
@@ -254,6 +255,18 @@ def expand(self, length):
254255
return self.get_type(length).bit_compose([self] * length)
255256
else:
256257
raise CompilerError('cannot expand from %s to %s' % (self.n, length))
258+
@classmethod
259+
def new_vector(cls, size):
260+
return cls.get_type(size)()
261+
@classmethod
262+
def concat(cls, parts):
263+
return cls.bit_compose(
264+
sum([part.bit_decompose() for part in parts], []))
265+
def copy_from_part(self, source, base, size):
266+
self.mov(self,
267+
self.bit_compose(source.bit_decompose()[base:base + size]))
268+
def vector_size(self):
269+
return self.n
257270

258271
class cbits(bits):
259272
""" Clear bits register. Helper type with limited functionality. """
@@ -425,7 +438,7 @@ def conv_regint_by_bit(cls, n, res, other):
425438
tmp = cbits.get_type(n)()
426439
tmp.conv_regint_by_bit(n, tmp, other)
427440
res.load_other(tmp)
428-
mov = inst.movsb
441+
mov = staticmethod(lambda x, y: inst.movsb(x.n, x, y))
429442
types = {}
430443
def __init__(self, *args, **kwargs):
431444
bits.__init__(self, *args, **kwargs)
@@ -1048,6 +1061,9 @@ def f(res):
10481061

10491062
class sbit(bit, sbits):
10501063
""" Single secret bit. """
1064+
@classmethod
1065+
def get_type(cls, length):
1066+
return sbits.get_type(length)
10511067
def if_else(self, x, y):
10521068
""" Non-vectorized oblivious selection::
10531069
@@ -1301,6 +1317,7 @@ class sbitintvec(sbitvec, _bitint, _number, _sbitintbase):
13011317
13021318
"""
13031319
bit_extend = staticmethod(_complement_two_extend)
1320+
mul_functions = {}
13041321
@classmethod
13051322
def popcnt_bits(cls, bits):
13061323
return sbitvec.from_vec(bits).popcnt()
@@ -1326,20 +1343,42 @@ def __mul__(self, other):
13261343
elif isinstance(other, sbitfixvec):
13271344
return NotImplemented
13281345
my_bits, other_bits = self.expand(other, False)
1329-
matrix = []
13301346
m = float('inf')
1347+
uniform = True
13311348
for x in itertools.chain(my_bits, other_bits):
13321349
try:
1350+
uniform &= type(x) == type(my_bits[0]) and x.n == my_bits[0].n
13331351
m = min(m, x.n)
13341352
except:
13351353
pass
1354+
if uniform and Program.prog.options.cisc:
1355+
bl = len(my_bits)
1356+
key = bl, len(other_bits)
1357+
if key not in self.mul_functions:
1358+
def instruction(*args):
1359+
res = self.binary_mul(args[bl:2 * bl], args[2 * bl:],
1360+
args[0].n)
1361+
for x, y in zip(res, args):
1362+
x.mov(y, x)
1363+
instruction.__name__ = 'binary_mul%sx%s' % (bl, len(other_bits))
1364+
self.mul_functions[key] = instructions_base.cisc(instruction,
1365+
bl)
1366+
res = [sbits.get_type(m)() for i in range(bl)]
1367+
self.mul_functions[key](*(res + my_bits + other_bits))
1368+
return self.from_vec(res)
1369+
else:
1370+
return self.binary_mul(my_bits, other_bits, m)
1371+
@classmethod
1372+
def binary_mul(cls, my_bits, other_bits, m):
1373+
matrix = []
13361374
for i, b in enumerate(other_bits):
13371375
if m == 1:
1338-
matrix.append([x * b for x in my_bits[:len(self.v)-i]])
1376+
matrix.append([x * b for x in my_bits[:len(my_bits)-i]])
13391377
else:
1340-
matrix.append((sbitvec.from_vec(my_bits[:len(self.v)-i]) * b).v)
1378+
matrix.append((
1379+
sbitvec.from_vec(my_bits[:len(my_bits)-i]) * b).v)
13411380
v = sbitint.wallace_tree_from_matrix(matrix)
1342-
return self.from_vec(v[:len(self.v)])
1381+
return cls.from_vec(v[:len(my_bits)])
13431382
__rmul__ = __mul__
13441383
reduce_after_mul = lambda x: x
13451384
def TruncMul(self, other, k, m, kappa=None, nearest=False):

0 commit comments

Comments
 (0)