def vc_init(runtime=None, directory="data/", printeq=True): """ Initialize verifiable computation system, storing all intermediate files in the given directory. If no runtime is given, the VC system can only be used for secret-sharing input data. If printeq is True, print equations to a file (only needed for key generation). """ global vc_directory, my_suffix, vc_modulus, qap, qapo, qapv print "*** Initializing VC (data dir=" + directory + ")" vc_directory = directory if vc_directory[-1] != "/": vc_directory = vc_directory + "/" my_suffix = "" if runtime == None or runtime.__class__.__name__ == "LocalRuntime" else str( runtime.id) vc_modulus = 21888242871839275222246405745257275088548364400416034343698204186575808495617 if runtime: if printeq: qap = open(vc_directory + "geppeq" + my_suffix, "w") print >> qap, "# geppetri qap" qapo = open(vc_directory + "geppout" + my_suffix, "w") print >> qapo, "# geppetri qap outputs" qapv = open(vc_directory + "geppval" + my_suffix, "w") print >> qapv, "# geppetri qap values" runtime.vc_counter = [] runtime.Zp = GF(vc_modulus, runtime.res) if hasattr( runtime, "res") else GF(vc_modulus) return runtime
def synchronize(self): """Introduce a synchronization point. Returns a :class:`Deferred` which will trigger if and when all other players have made their calls to :meth:`synchronize`. By adding callbacks to the returned :class:`Deferred`, one can divide a protocol execution into disjoint phases. """ input_shares = [(GF(101)(player), GF(101)(0)) for player in self.players] yield DeferredList(self._exchange_shares(input_shares))
def eval_poly(runtime): print "Starting protocol" start_time = time() modulus = find_prime(2**65, blum=True) Zp = GF(modulus) # In this example we just let Player 1 share the input values. if runtime.id == 1: x = runtime.shamir_share([1], Zp, 17) a = runtime.shamir_share([1], Zp, 42) b = runtime.shamir_share([1], Zp, -5) c = runtime.shamir_share([1], Zp, 87) else: x = runtime.shamir_share([1], Zp) a = runtime.shamir_share([1], Zp) b = runtime.shamir_share([1], Zp) c = runtime.shamir_share([1], Zp) # Evaluate the polynomial. p = a * (x * x) + b * x + c sign = (p < 0) * -1 + (p > 0) * 1 output = runtime.open(sign) output.addCallback(done, start_time, runtime)
def __init__(self, runtime, security_parameter, p, random): assert p > 1 self.random = random # TODO: Generate Paillier cipher with N_i sufficiently larger than p self.runtime = runtime self.p = p self.Zp = GF(p) self.k = self._bit_length_of(p) self.security_parameter = security_parameter self.u_bound = 2**(self.security_parameter + 4 * self.k) self.zk_random = Random(self.random.getrandbits(128)) paillier_random = Random(self.random.getrandbits(128)) alpha_random = Random(self.random.getrandbits(128)) self.paillier = ModifiedPaillier(runtime, paillier_random) # Debug output. #print "n_%d**2:%d" % (runtime.id, self.paillier.pubkey['n_square']) #print "n_%d:%d" % (runtime.id, self.paillier.pubkey['n']) #print "n_%d bitlength: %d" % \ # (runtime.id, self._bit_length_of(self.paillier.pubkey['n'])) #self.Zp = GF(p) #self.Zn2 = GF(self.paillier.pubkey['n_square']) #self.alpha = self.Zp(self.random.randint(0, p - 1)) self.alpha = alpha_random.randint(0, p - 1) self.n2 = runtime.players[runtime.id].pubkey['n_square']
def protocol(rt): print "Starting protocol" Zp = GF(11) a, b, c = rt.prss_share([1, 2, 3], Zp, 0) x, y, z = rt.prss_share([1, 2, 3], Zp, 1) a_b = rt.open(rt.convert_bit_share(a, GF256)) b_b = rt.open(rt.convert_bit_share(b, GF256)) c_b = rt.open(rt.convert_bit_share(c, GF256)) x_b = rt.open(rt.convert_bit_share(x, GF256)) y_b = rt.open(rt.convert_bit_share(y, GF256)) z_b = rt.open(rt.convert_bit_share(z, GF256)) def check(result, variable, expected): if result == expected: print "%s: %s (correct)" % (variable, result) else: print "%s: %s (incorrect, expected %d)" \ % (variable, result, expected) a_b.addCallback(check, "a_b", GF256(0)) b_b.addCallback(check, "b_b", GF256(0)) c_b.addCallback(check, "c_b", GF256(0)) x_b.addCallback(check, "x_b", GF256(1)) y_b.addCallback(check, "y_b", GF256(1)) z_b.addCallback(check, "z_b", GF256(1)) rt.wait_for(a_b, b_b, c_b, x_b, y_b, z_b)
def test_share_protocol_multi(self, runtime): p, k = 17, 5 Zp = GF(p) random = Random(345453 + runtime.id) elms = [Zp(runtime.id), Zp(runtime.id * 3)] paillier_random = Random(random.getrandbits(128)) zk_random = Random(random.getrandbits(128)) paillier = ModifiedPaillier(runtime, paillier_random) partial_shares = generate_partial_share_contents( elms, runtime, paillier, k, zk_random) def decrypt(share_contents): self.assertEquals(2, len(share_contents)) decrypted_shares = [ paillier.decrypt(share_contents[i].enc_shares[runtime.id - 1]) for i in range(2) ] decrypted_shares = [ _convolute(runtime, decrypted_shares[i]) for i in range(2) ] def test_sum(vals, should_be): self.assertEquals([Zp(e) for e in should_be], vals) runtime.schedule_callback(decrypted_shares[0], test_sum, [1, 2, 3]) runtime.schedule_callback(decrypted_shares[1], test_sum, [3, 6, 9]) runtime.schedule_callback(partial_shares, decrypt) return partial_shares
def share_all(runtime): share_rounds = 0 # How many rounds to share all inputs for party in nodes_per_party: share_rounds = max(share_rounds, len(nodes_per_party[party])) # Share the inputs in rounds shares = {} # will contain the shares. l = runtime.options.bit_length k = runtime.options.security_parameter Zp = GF(find_prime(2**65, blum=True)) this_party_input = nodes_per_party[int(id)] for i in range(share_rounds): print "share round " + str(i) + "/" + str(share_rounds) value_to_share = 0 if i < len(this_party_input): value_to_share = values[this_party_input[i]] value_to_share = INFINITY if value_to_share == float( "inf") else value_to_share round_shares = runtime.shamir_share(parties_list, Zp, value_to_share) for index in range(len(round_shares)): party = parties_list[index] sharing_party_inputs = nodes_per_party[int(party)] if i < len(sharing_party_inputs): shares[sharing_party_inputs[i]] = round_shares[index] return shares
def test_mul_same_player_inputs_and_receives(self, runtime): p = 17 random = Random(283883) triple_generator = TripleGenerator(runtime, self.security_parameter, p, random) Zp = GF(p) ais = [Zp(6), Zp(6), Zp(6), Zp(6)] b2 = Zp(7) cs = [] for ai in ais: cs.append(triple_generator.paillier.encrypt(b2.value, 2)) n = len(ais) r1 = triple_generator._mul(2, 2, n, ais, cs) def check(shares): for share in shares: if runtime.id == 2: self.assertEquals(share.value, 8) return True r1.addCallback(check) return r1
def test_add_macs_produces_correct_sharing(self, runtime): # TODO: Here we use the open method of the BeDOZa runtime in # order to verify the macs of the generated full share. In # order to be more unit testish, this test should use its own # way of verifying these. p = 17 Zp = GF(p) secret = 6 random = Random(283883) paillier_random = Random(random.getrandbits(128)) paillier = ModifiedPaillier(runtime, random) add_macs_random = Random(random.getrandbits(128)) shares_random = Random(random.getrandbits(128)) shares = [] shares.append( partial_share(shares_random, runtime, Zp, secret, paillier=paillier)) shares.append( partial_share(shares_random, runtime, Zp, secret + 1, paillier=paillier)) shares.append( partial_share(shares_random, runtime, Zp, secret + 2, paillier=paillier)) shares.append( partial_share(shares_random, runtime, Zp, secret + 3, paillier=paillier)) bits_in_p = 5 u_bound = 2**(4 * bits_in_p) alpha = 15 zs = add_macs(runtime, Zp, u_bound, alpha, add_macs_random, paillier, shares) def verify(open_shares): inx = secret for open_share in open_shares: self.assertEquals(inx, open_share.value) inx += 1 opened_shares = [] for s in zs: opened_shares.append(runtime.open(s)) d = gather_shares(opened_shares) d.addCallback(verify) return d
def test_generate_triples_generates_correct_triples(self, runtime): p = 17 Zp = GF(p) random = Random(574566 + runtime.id) triple_generator = TripleGenerator(runtime, self.security_parameter, p, random) triples = triple_generator._generate_triples(10) def check((a, b, c)): self.assertEquals(c, a * b) def open(triple): d1 = runtime.open(triple.a) d2 = runtime.open(triple.b) d3 = runtime.open(triple.c) d = gatherResults([d1, d2, d3]) runtime.schedule_callback(d, check) return d for triple in triples: runtime.schedule_callback(triple, open) return gatherResults(triples)
def test_encrypted_random_real_shares_open_correctly(self, runtime): random = Random(3423993) modulus = 17 Zp = GF(modulus) bits_in_p = 5 u_bound = 2**(4 * bits_in_p) alpha = 15 paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128))) share_random = Random(random.getrandbits(128)) gen = TestShareGenerator(Zp, runtime, share_random, paillier, u_bound, alpha) shares = gen.generate_random_shares(7) expected_result = [9, 16, 7, 12, 3, 5, 6] results = [] for inx, share in enumerate(shares): def check(v, expected_result): self.assertEquals(expected_result, v) r = runtime.open(share) results.append(r) runtime.schedule_callback(r, check, expected_result[inx]) return gather_shares(results)
def setUp(self): RuntimeTestCase.setUp(self) self.Zp = GF(17) bits_in_p = 5 self.security_parameter = 32 self.u_bound = 2**(self.security_parameter + 4 * bits_in_p) self.alpha = 15
def test_send_two_senders_in_parallel(self, runtime): """Test of send a value.""" self.Zp = GF( 6277101735386680763835789423176059013767194773182842284081) def check(ls): for s, x in ls: self.assertEquals(int(x), 42) return ls value = 42 receivers = [2, 3] if 1 == runtime.id: d1 = runtime.broadcast([1], receivers, str(value)) else: d1 = runtime.broadcast([1], receivers) if 2 == runtime.id: d2 = runtime.broadcast([2], [3], str(value)) else: d2 = runtime.broadcast([2], [3]) ds = [d1] if [] != d2: ds.append(d2) dls = DeferredList(ds) dls.addCallback(check) return dls
def mpc_share_guess(self, guess): # For the comparison protocol to work, we need a field modulus # bigger than 2**(l+1) + 2**(l+k+1), where the bit length of # the input numbers is l and k is the security parameter. # Further more, the prime must be a Blum prime (a prime p such # that p % 4 == 3 holds). The find_prime function lets us find # a suitable prime. l = self.runtime.options.bit_length k = self.runtime.options.security_parameter Zp = GF(find_prime(2**(l + 1) + 2**(l + k + 1), blum=True)) # We must secret share our input with the other parties. They # will do the same and we end up with three variables # We can only share between the remaining player, don't wait # for a dead person's input. # TODO: only require the living players to respond. alive_player_array = self.alive_players() if not self.lives[self.runtime.id - 1] > 0: print "sorry you're dead ignoring your input %s " % self.runtime.id return self.runtime.shamir_share(alive_player_array, Zp, None) else: print "you're alive your player num %s " % self.runtime.id print "alive mcp %s " % alive_player_array if self.is_player: print "in 1,2 " g1, g2 = self.runtime.shamir_share([1, 2], Zp, guess) else: print "in 3" g1, g2 = self.runtime.shamir_share([1, 2], Zp) return [g1, g2]
def __init__(self, runtime): # Save the Runtime for later use self.runtime = runtime self.k = 256 self.b = 2 self.threshold = 1 self.matrix = [[0 for x in range(self.k + 1)] for y in range(self.k + 1)] self.openmatrix = [[0 for x in range(self.k + 1)] for y in range(self.k + 1)] self.prefix = 0 # This is the value we will use in the protocol. self.target = 3 Zp = GF(find_prime(2**64)) if runtime.id == 1: a = runtime.shamir_share([1], Zp, self.target) else: a = runtime.shamir_share([1], Zp) self.a = a ''' for i in range(self.k + 1): if runtime.id == 1: self.matrix[0][i] = self.runtime.shamir_share([1], Zp, self.b**i) else: self.matrix[0][i] = self.runtime.shamir_share([1], Zp) ''' #self.matrix[0][1] = TriplesHyperinvertibleMatricesMixin.single_share_random(1,self.threshold,Zp) if runtime.id == 1: self.matrix[0][0] = self.runtime.shamir_share([1], Zp, 0) self.matrix[0][1] = self.runtime.shamir_share([1], Zp, self.b) else: self.matrix[0][0] = self.runtime.shamir_share([1], Zp) self.matrix[0][1] = self.runtime.shamir_share([1], Zp) for i in range(2, self.k + 1): self.matrix[0][i] = self.matrix[0][i - 1] * self.matrix[0][1] #record_stop() for i in range(self.k + 1): self.openmatrix[0][i] = self.runtime.open(self.matrix[0][i]) self.matrix[1][0] = self.a self.matrix[1][1] = self.matrix[1][0] * self.matrix[0][1] self.prefix = self.runtime.open(a - self.matrix[0][1]) list1 = [self.prefix, a, self.matrix[1][1]] list1 = list1 + [self.matrix[0][i] for i in range(1, self.k + 1)] print len(list1) #results = list1 results = gather_shares(list1) results.addCallback(self.preprocess_ready)
def test_not_hyper(self): """Check a non-hyper-invertible matrix.""" Zp = GF(11) # This is an invertible matrix, but it is not hyper-invertible # since none of the three the upper 2x2 matrices are # invertible. m = Matrix([[Zp(2), Zp(3), Zp(4)], [Zp(4), Zp(6), Zp(9)], [Zp(3), Zp(5), Zp(8)]]) self.assertFalse(self.is_hyper(m))
def test_shares_have_correct_type(self, runtime): Zp = GF(23) share = partial_share(Random(23499), runtime, Zp, 7) def test(share): self.assertEquals(Zp, share.value.field) runtime.schedule_callback(share, test) return share
def test_convolute_field_element(self, runtime): Zp = GF(17) res = _convolute_gf_elm(runtime, Zp(runtime.id)) def verify(result): self.assertEquals(runtime.players.keys(), result) runtime.schedule_callback(res, verify) return res
def test_vec_mul_E_is_correct(self): s, prover_id, k, Zn = 5, 1, 0, GF(17) c = [None] * s y = [Zn(i) for i in range(1, 6)] zk = ZKProof(s, prover_id, k, RuntimeStub(), c) zk.e = [1, 0, 1, 1, 0] x = [1, 2, 0, 1, 0] x_mul_E = zk._vec_mul_E(x) self.assertEquals([v for v in [1, 2, 1, 4, 2, 1, 1, 0, 0]], x_mul_E)
def __init__(self, runtime): # Save the Runtime for later use self.runtime = runtime # This is the value we will use in the protocol. self.millions = rand.randint(1, 200) print "I am Millionaire %d and I am worth %d millions." \ % (runtime.id, self.millions) # For the comparison protocol to work, we need a field modulus # bigger than 2**(l+1) + 2**(l+k+1), where the bit length of # the input numbers is l and k is the security parameter. # Further more, the prime must be a Blum prime (a prime p such # that p % 4 == 3 holds). The find_prime function lets us find # a suitable prime. l = runtime.options.bit_length k = runtime.options.security_parameter Zp = GF(find_prime(2**(l + 1) + 2**(l + k + 1), blum=True)) # We must secret share our input with the other parties. They # will do the same and we end up with three variables m1, m2, m3 = runtime.shamir_share([1, 2, 3], Zp, self.millions) # Now that everybody has secret shared their inputs we can # compare them. We compare the worth of the first millionaire # with the two others, and compare those two millionaires with # each other. m1_ge_m2 = m1 >= m2 m1_ge_m3 = m1 >= m3 m2_ge_m3 = m2 >= m3 # The results are secret shared, so we must open them before # we can do anything usefull with them. open_m1_ge_m2 = runtime.open(m1_ge_m2) open_m1_ge_m3 = runtime.open(m1_ge_m3) open_m2_ge_m3 = runtime.open(m2_ge_m3) # We will now gather the results and call the # self.results_ready method when they have all been received. results = gather_shares([open_m1_ge_m2, open_m1_ge_m3, open_m2_ge_m3]) results.addCallback(self.results_ready) # We can add more callbacks to the callback chain in results. # These are called in sequence when self.results_ready is # finished. The first callback acts like a barrier and makes # all players wait on each other. # # The callbacks are always called with an argument equal to # the return value of the preceeding callback. We do not need # the argument (which is None since self.results_ready does # not return anything), so we throw it away using a lambda # expressions which ignores its first argument. runtime.schedule_callback(results, lambda _: runtime.synchronize()) # The next callback shuts the runtime down, killing the # connections between the players. runtime.schedule_callback(results, lambda _: runtime.shutdown())
def test_shares_are_additive(self, runtime): secret = 7 share = partial_share(Random(34993), runtime, GF(23), secret) def convolute(share): values = _convolute_gf_elm(runtime, share.value) def test_sum(vals): self.assertEquals(secret, sum(vals)) runtime.schedule_callback(values, test_sum) runtime.schedule_callback(share, convolute) return share
def test_mul_computes_correct_result(self, runtime): p = 17 random = Random(283883) triple_generator = TripleGenerator(runtime, 32, p, random) Zp = GF(p) ais = [Zp(6), Zp(6), Zp(6), Zp(6)] b2 = Zp(7) cs = [] for ai in ais: cs.append(triple_generator.paillier.encrypt(b2.value, 2)) n = len(ais) if runtime.id == 1: r1 = triple_generator._mul(1, 2, n, ais, cs) def check1(shares): for share in shares: pc = tuple(runtime.program_counter) runtime.protocols[2].sendData(pc, TEXT, str(share.value)) return True r1.addCallback(check1) return r1 else: r1 = triple_generator._mul(1, 2, n) def check(shares): deferreds = [] for share in shares: if runtime.id == 2: def check_additivity(zi, zj): self.assertEquals((Zp(long(zi)) + zj).value, 8) return None d = Deferred() d.addCallback(check_additivity, share.value) runtime._expect_data(1, TEXT, d) deferreds.append(d) else: self.assertEquals(share.value, 0) return gatherResults(deferreds) r1.addCallback(check) return r1
def test_fullmul_encrypted_values_are_the_same_as_the_share(self, runtime): p = 17 Zp = GF(p) random = Random(283883) triple_generator = TripleGenerator(runtime, self.security_parameter, p, random) paillier = triple_generator.paillier share_as = [] share_bs = [] share_as.append( partial_share(random, runtime, GF(p), 6, paillier=paillier)) share_bs.append( partial_share(random, runtime, GF(p), 7, paillier=paillier)) share_as.append( partial_share(random, runtime, GF(p), 5, paillier=paillier)) share_bs.append( partial_share(random, runtime, GF(p), 4, paillier=paillier)) share_as.append( partial_share(random, runtime, GF(p), 2, paillier=paillier)) share_bs.append( partial_share(random, runtime, GF(p), 3, paillier=paillier)) share_zs = triple_generator._full_mul(share_as, share_bs) def check(shares): all_enc_shares = [] for share in shares: def test_enc(enc_shares, value): all_the_same, zi_enc = reduce( lambda x, y: (x[0] and x[1] == y, y), enc_shares, (True, enc_shares[0])) zi_enc = triple_generator.paillier.decrypt(zi_enc) self.assertEquals(value, Zp(zi_enc)) return True for inx, enc_share in enumerate(share.enc_shares): d = _convolute(runtime, enc_share) if runtime.id == inx + 1: d.addCallback(test_enc, share.value) all_enc_shares.append(d) return gatherResults(all_enc_shares) d = gatherResults(share_zs) d.addCallback(check) return d
def main(runtime): global tv, Zp tv = runtime k = tv.options.security_parameter l = tv.options.bit_length ln = len(tv.players).bit_length() Zp = GF(find_prime(2**(l + k + ln + 1), blum=True)) yield declareReturn(tv, Zp) shareZp = lambda x: Share(tv, Zp, Zp(x)) t = 12 for i in xrange(t): a = secret_index(shareZp(i), t) a = yield map(tv.open, a) print i, map(lambda v: int(v.value), a) tv.shutdown()
def test_sender_in_receivers(self, runtime): """Test of send a value.""" self.Zp = GF( 6277101735386680763835789423176059013767194773182842284081) value = 42 if 1 == runtime.id: d = runtime.broadcast([1], [1, 2, 3], str(value)) else: d = runtime.broadcast([1], [1, 2, 3]) def check(x): self.assertEquals(int(x), 42) return x d.addCallback(check) return d
def setUp(self): """Configure and connect three Runtimes. .. warning:: Subclasses that override this method *must* remember to do a super-call to it. Otherwise the runtimes wont be connected and :meth:`tearDown` wont work. """ # Our standard 65 bit Blum prime self.Zp = GF(30916444023318367583) configs = self.generate_configs(self.num_players, self.threshold) self.protocols = {} # initialize the dictionary of random generators seed = rand.random() self.shared_rand = dict([(player_id, Random(seed)) for player_id in range(1, self.num_players + 1)]) # This will be a list of Deferreds which will trigger when the # virtual connections between the players are closed. self.close_sentinels = [] self.runtimes = [] for id in reversed(range(1, self.num_players+1)): _, players = load_config(configs[id]) self.create_loopback_runtime(id, players) if isinstance(reactor, ViffReactor): def set_loop_call(runtimes): self.i = 0 # This loop call should ensure the queues of the parties are # processed in a more or less fair manner. This is necessary # because we have only one reactor for all parties here. def loop_call(): i = self.i for j in range(len(runtimes)): self.i = (self.i + 1) % len(runtimes) runtimes[(i + j) % len(runtimes)].process_deferred_queue() reactor.setLoopCall(loop_call) gatherResults(self.runtimes).addCallback(set_loop_call)
def __init__(self, runtime, k): self.k = k self.runtime = runtime self.inputs = [0 for _ in range(self.k)] self.p = find_prime(2**256, blum=True) self.Zp = GF(self.p) self.open_value = [0 for _ in range(self.k)] self.precomputed_powers = [[0 for _ in range(self.k)] for _ in range(self.k)] # load -1/1 shares from file self.load_input_from_file(self.k, self.p) for i in range(self.k): self.open_value[i] = self.runtime.open(self.inputs[i]) #print self.open_value result = gather_shares(self.open_value) result.addCallback(self.create_output)
def test_fullmul_computes_the_correct_result(self, runtime): p = 17 Zp = GF(p) random = Random(283883) triple_generator = TripleGenerator(runtime, self.security_parameter, p, random) paillier = triple_generator.paillier share_as = [] share_bs = [] share_as.append( partial_share(random, runtime, GF(p), 6, paillier=paillier)) share_bs.append( partial_share(random, runtime, GF(p), 7, paillier=paillier)) share_as.append( partial_share(random, runtime, GF(p), 5, paillier=paillier)) share_bs.append( partial_share(random, runtime, GF(p), 4, paillier=paillier)) share_as.append( partial_share(random, runtime, GF(p), 2, paillier=paillier)) share_bs.append( partial_share(random, runtime, GF(p), 3, paillier=paillier)) share_zs = triple_generator._full_mul(share_as, share_bs) def check(shares): def test_sum(ls): self.assertEquals(8, Zp(sum(ls[0]))) self.assertEquals(3, Zp(sum(ls[1]))) self.assertEquals(6, Zp(sum(ls[2]))) values = [] for share in shares: value = _convolute(runtime, share.value.value) values.append(value) d = gatherResults(values) runtime.schedule_callback(d, test_sum) return d d = gatherResults(share_zs) d.addCallback(check) return d
def load_input_from_file(self, k, p): filename = "party" + str(self.runtime.id) + "-input" FD = open(filename, "r") line = FD.readline() if int(line) != k: print "k dismatch!! k in file is %d" % (int(line)) line = FD.readline() if int(line) != p: print "prime dismatch!! prime in file is %d" % (int(line)) self.Zp = GF(p) line = FD.readline() i = 0 while line and i < self.k: #print i self.inputs[i] = Share(self.runtime, self.Zp, self.Zp(int(line))) line = FD.readline() i = i + 1
def test_encrypted_real_share_open_correctly(self, runtime): random = Random(3423993) modulus = 17 Zp = GF(modulus) bits_in_p = 5 u_bound = 2**(4 * bits_in_p) alpha = 15 paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128))) share_random = Random(random.getrandbits(128)) gen = ShareGenerator(Zp, runtime, share_random, paillier, u_bound, alpha) share = gen.generate_share(7) def check(v): self.assertEquals(7, v) r = runtime.open(share) runtime.schedule_callback(r, check) return r