Skip to content

Commit

Permalink
Python 3, semi-honest computation using semi-homomorphic encryption.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkskeller committed Nov 21, 2019
1 parent 3bf45eb commit 470b075
Show file tree
Hide file tree
Showing 138 changed files with 1,931 additions and 1,021 deletions.
4 changes: 2 additions & 2 deletions BMR/RealGarbleWire.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void RealGarbleWire<T>::input(party_id_t from, char input)
protocol.init_mul(party.shared_proc);
protocol.prepare_mul(mask, T(1, party.P->my_num(), party.mac_key) - mask);
protocol.exchange();
if (party.MC->POpen(protocol.finalize_mul(), *party.P) != 0)
if (party.MC->open(protocol.finalize_mul(), *party.P) != 0)
throw runtime_error("input mask not a bit");
}
#ifdef DEBUG_MASK
Expand Down Expand Up @@ -168,7 +168,7 @@ void RealGarbleWire<T>::output()
auto& party = RealProgramParty<T>::s();
assert(party.MC != 0);
assert(party.P != 0);
auto m = party.MC->POpen(mask, *party.P);
auto m = party.MC->open(mask, *party.P);
party.output_masks.push_back(m.get_bit(0));
party.taint();
#ifdef DEBUG_MASK
Expand Down
2 changes: 1 addition & 1 deletion BMR/RealProgramParty.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ RealProgramParty<T>::RealProgramParty(int argc, const char** argv) :
{
mac_key.randomize(prng);
if (T::needs_ot)
BaseMachine::s().ot_setups.push_back({{{*P, true}}});
BaseMachine::s().ot_setups.push_back({*P, true});
prep = Preprocessing<T>::get_live_prep(0, usage);
}
else
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,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.

## 0.1.3 (Nov 21, 2019)

- Python 3
- Semi-honest computation based on semi-homomorphic encryption
- Access to player information in high-level language

## 0.1.2 (Oct 11, 2019)

- Machine learning capabilities used for [MobileNets inference](https://eprint.iacr.org/2019/131) and the iDASH submission
Expand Down
2 changes: 1 addition & 1 deletion Compiler/GC/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ def __init__(self, progname):
types.program = self
instructions.program = self
self.curr_tape = None
execfile(progname)
exec(compile(open(progname).read(), progname, 'exec'))
def malloc(self, *args):
pass
22 changes: 15 additions & 7 deletions Compiler/GC/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from Compiler import util, oram, floatingpoint, library
import Compiler.GC.instructions as inst
import operator
from functools import reduce

class bits(Tape.Register, _structure):
n = 40
Expand Down Expand Up @@ -82,7 +83,7 @@ def load_mem(cls, address, mem_type=None, size=None):
cls.load_inst[util.is_constant(address)](res, address)
return res
def store_in_mem(self, address):
self.store_inst[isinstance(address, (int, long))](self, address)
self.store_inst[isinstance(address, int)](self, address)
def __init__(self, value=None, n=None, size=None):
if size != 1 and size is not None:
raise Exception('invalid size for bit type: %s' % size)
Expand All @@ -92,11 +93,11 @@ def __init__(self, value=None, n=None, size=None):
self.load_other(value)
def set_length(self, n):
if n > self.max_length:
print self.max_length
print(self.max_length)
raise Exception('too long: %d' % n)
self.n = n
def load_other(self, other):
if isinstance(other, (int, long)):
if isinstance(other, int):
self.set_length(self.n or util.int_len(other))
self.load_int(other)
elif isinstance(other, regint):
Expand All @@ -115,6 +116,7 @@ def long_one(self):
def __repr__(self):
return '%s(%d/%d)' % \
(super(bits, self).__repr__(), self.n, type(self).n)
__str__ = __repr__

class cbits(bits):
max_length = 64
Expand Down Expand Up @@ -219,13 +221,13 @@ def get_input_from(cls, player, n_bits=None):
@classmethod
def load_dynamic_mem(cls, address):
res = cls()
if isinstance(address, (long, int)):
if isinstance(address, int):
inst.ldmsd(res, address, cls.n)
else:
inst.ldmsdi(res, address, cls.n)
return res
def store_in_dynamic_mem(self, address):
if isinstance(address, (long, int)):
if isinstance(address, int):
inst.stmsd(self, address)
else:
inst.stmsdi(self, cbits.conv(address))
Expand Down Expand Up @@ -322,7 +324,7 @@ def mul_int(self, other):
mul_bits = [self if b else zero for b in bits]
return self.bit_compose(mul_bits)
else:
print self.n, other
print(self.n, other)
return NotImplemented
def __lshift__(self, i):
return self.bit_compose([sbit(0)] * i + self.bit_decompose()[:self.max_length-i])
Expand Down Expand Up @@ -478,7 +480,7 @@ def __init__(self, value, start, lengths, entries_per_block):
self.start_demux = oram.demux_list(self.start_bits)
self.entries = [sbits.bit_compose(self.value_bits[i*length:][:length]) \
for i in range(entries_per_block)]
self.mul_entries = map(operator.mul, self.start_demux, self.entries)
self.mul_entries = list(map(operator.mul, self.start_demux, self.entries))
self.bits = sum(self.mul_entries).bit_decompose()
self.mul_value = sbits.compose(self.mul_entries, sum(self.lengths))
self.anti_value = self.mul_value + self.value
Expand Down Expand Up @@ -662,6 +664,12 @@ def __mul__(self, other):
return super(sbitfix, self).__mul__(other)
__rxor__ = __xor__
__rmul__ = __mul__
@staticmethod
def multipliable(other, k, f):
class cls(_fix):
int_type = sbitint.get_type(k)
cls.set_precision(f, k)
return cls._new(cls.int_type(other), k, f)

sbitfix.set_precision(20, 41)

Expand Down
10 changes: 5 additions & 5 deletions Compiler/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import compilerLib, program, instructions, types, library, floatingpoint
import GC.types
from . import compilerLib, program, instructions, types, library, floatingpoint
from .GC import types as GC_types
import inspect
from config import *
from compilerLib import run
from .config import *
from .compilerLib import run


# add all instructions to the program VARS dictionary
compilerLib.VARS = {}
instr_classes = [t[1] for t in inspect.getmembers(instructions, inspect.isclass)]

for mod in (types, GC.types):
for mod in (types, GC_types):
instr_classes += [t[1] for t in inspect.getmembers(mod, inspect.isclass)\
if t[1].__module__ == mod.__name__]

Expand Down
Loading

0 comments on commit 470b075

Please sign in to comment.