def runtime_assert_mat_equals(expected, actual, test_name): if isinstance(actual[0][0], sint): actual = reveal_mat(actual) if len(expected) != len(actual): print_ln("%s in %s dimensions wrong.", MPC_ERROR_FLAG, test_name) for expected_row, actual_row in zip(expected, actual): runtime_assert_arr_equals(expected_row, actual_row, test_name)
def runtime_assert_arr_equals(expected, actual, test_name): if isinstance(actual[0], sint): actual = [v.reveal() for v in actual] if len(expected) != len(actual): print_ln("%s in %s dimensions wrong", MPC_ERROR_FLAG, test_name) for expected_val, actual_val in zip(expected, actual): runtime_assert_equals(expected_val, actual_val, test_name)
def match(self, n_loops=None): if n_loops is None or n_loops > self.N * self.M: loop = do_while init_rounds = self.N else: loop = for_range(n_loops) init_rounds = n_loops / self.M self.wives = \ self.oram_type(self.N, entry_size=log2(self.N), \ init_rounds=0, value_type=self.basic_type) self.husbands = \ self.oram_type(self.N, entry_size=log2(self.N), \ init_rounds=0, value_type=self.basic_type) propose = \ self.oram_type(self.N, entry_size=log2(self.N), \ init_rounds=0, value_type=self.basic_type) self.unengaged = OStack(self.N, oram_type=self.oram_type, \ int_type=self.int_type) @for_range(init_rounds) def f(i): self.unengaged.append(i) rounds = types.MemValue(types.regint(0)) @loop def f(i=None): rounds.iadd(1) time() man = self.unengaged.pop() #self.husbands.ram[0].x[0].reveal().print_reg('j') pref = self.int_type(propose[man]) if self.M < self.N and n_loops is None: @if_((pref == self.M).reveal()) def f(): print_ln('run out of acceptable women') crash() #self.husbands.ram[0].x[0].reveal().print_reg('k') propose[man] = pref + 1 #self.husbands.ram[0].x[0].reveal().print_reg('l') self.propose(man, self.m_prefs[man][pref], True) print_ln('man: %s, pref: %s, left: %s', \ *(x.reveal() for x in (man, pref, self.unengaged.size))) # self.wives[man].reveal().print_reg('wife') return types.regint((self.unengaged.size > 0).reveal()) print_ln('%s rounds', rounds) @for_range(init_rounds) def f(i): types.cint(i).print_reg('wife') self.husbands[i].reveal().print_reg('husb')
def f(i=None): rounds.iadd(1) time() man = self.unengaged.pop() #self.husbands.ram[0].x[0].reveal().print_reg('j') pref = self.int_type(propose[man]) if self.M < self.N and n_loops is None: @if_((pref == self.M).reveal()) def f(): print_ln('run out of acceptable women') crash() #self.husbands.ram[0].x[0].reveal().print_reg('k') propose[man] = pref + 1 #self.husbands.ram[0].x[0].reveal().print_reg('l') self.propose(man, self.m_prefs[man][pref], True) print_ln('man: %s, pref: %s, left: %s', \ *(x.reveal() for x in (man, pref, self.unengaged.size))) # self.wives[man].reveal().print_reg('wife') return types.regint((self.unengaged.size > 0).reveal())
def propose(self, man, woman, for_real): (fiance,), free = self.husbands.read(woman) #self.husbands.ram[0].x[0].reveal().print_reg('f') engaged = 1 - free rank_man = self.f_ranks[woman][man] #self.husbands.ram[0].x[0].reveal().print_reg('g') (rank_fiance,), worst_fiance = self.f_ranks[woman].read(engaged*fiance) #self.husbands.ram[0].x[0].reveal().print_reg('h') leaving = self.int_type(rank_man) < self.int_type(rank_fiance) if self.M < self.N: leaving = 1 - (1 - leaving) * (1 - worst_fiance) print_str('woman: %s, man: %s, fiance: %s, worst fiance: %s, ', \ *(x.reveal() for x in (woman, man, fiance, worst_fiance))) print_ln('rank man: %s, rank fiance: %s, engaged: %s, leaving: %s', \ *(x.reveal() for x in \ (rank_man, rank_fiance, engaged, leaving))) self.dump(fiance, woman, engaged * leaving * for_real) self.engage(man, woman, (1 - (engaged * (1 - leaving))) * for_real) self.unengaged.append(man, engaged * (1 - leaving) * for_real)
def runtime_assert_node_equals(expected, actual, test_name): if isinstance(expected, LN): runtime_assert_equals(1, actual.is_leaf, test_name) if expected.is_dummy: # dummy case runtime_assert_equals(1, actual.is_dummy, test_name) # don't test class because this is a dummy node else: runtime_assert_equals(0, actual.is_dummy, test_name) runtime_assert_equals(expected.node_class, actual.node_class, test_name) elif isinstance(expected, DN): runtime_assert_equals(0, actual.is_leaf, test_name) runtime_assert_equals(expected.attr_idx, actual.attr_idx, test_name) runtime_assert_equals(expected.threshold, actual.threshold, test_name) else: print_ln("%s incorrect expected tree, must only hold nodes", MPC_ERROR_FLAG)
def runtime_assert_tree_equals(expected, actual, test_name): # TODO how should dummy nodes be handled? actual = actual.reveal() expected_num_nodes = expected.num_nodes() actual_num_nodes = actual.num_nodes() if expected_num_nodes != actual_num_nodes: print_ln("%s Expected tree has %s nodes but actual has %s", MPC_ERROR_FLAG, expected_num_nodes, actual_num_nodes) queue = deque([(expected.root, actual.root)]) while queue: expected_next_node, actual_next_node = queue.popleft() if expected_next_node: if not actual_next_node: print_ln("%s trees have different topology", MPC_ERROR_FLAG) runtime_assert_node_equals(expected_next_node, actual_next_node, test_name) queue.append((expected_next_node.left, actual_next_node.left)) queue.append( (expected_next_node.right, actual_next_node.right)) else: if actual_next_node: print_ln("%s trees have different topology", MPC_ERROR_FLAG)
def f(): print_ln('run out of acceptable women') crash()
def _(): print_ln("%s in %s.Expected %s but was %s", MPC_ERROR_FLAG, test_name, expected, actual)
def _(): print_ln("%s passed.", test_name)