def test_open_does_not_mutate_share(self, runtime): """Test that opening a share does not change it.""" # The parties have shares 43, 44, 45 respectively. share = Share(runtime, self.Zp, self.Zp(42 + runtime.id)) opened = runtime.open(share) opened.addCallback(self.assertEquals, 42) share.addCallback(self.assertEquals, 42 + runtime.id) return opened
def test_open_does_not_mutate_share(self, runtime): """Test that opening a share does not change it.""" # The parties have shares 43, 44, 45 respectively. share = Share(runtime, self.Zp, self.Zp(42 + runtime.id)) opened = runtime.open(share) opened.addCallback(self.assertEquals, 42) share.addCallback(self.assertEquals, 42 + runtime.id) return opened
def exchange(share): # Send share to all receivers. for peer_id in receivers: if peer_id != self.id: pc = tuple(self.program_counter) self.protocols[peer_id].sendShare(pc, share) # Receive and recombine shares if this player is a receiver. if self.id in receivers: deferreds = [] for peer_id in self.players: if peer_id == self.id: d = Share(self, share.field, (share.field(peer_id), share)) else: d = self._expect_share(peer_id, share.field) d.addCallback(lambda s, peer_id: (s.field(peer_id), s), peer_id) deferreds.append(d) return recombine(deferreds)
def exchange(share): # Send share to all receivers. for peer_id in receivers: if peer_id != self.id: pc = tuple(self.program_counter) self.protocols[peer_id].sendShare(pc, share) # Receive and recombine shares if this player is a receiver. if self.id in receivers: deferreds = [] for peer_id in self.players: if peer_id == self.id: d = Share(self, share.field, (share.field(peer_id), share)) else: d = self._expect_share(peer_id, share.field) d.addCallback(lambda s, peer_id: (s.field(peer_id), s), peer_id) deferreds.append(d) return recombine(deferreds)
def open(self, a, receivers=None, threshold=None): """Open a secret sharing. The *receivers* are the players that will eventually obtain the opened result. The default is to let everybody know the result. Communication cost: every player sends one share to each receiving player. """ assert isinstance(a, Share) yield declareReturn(self, a.field) # all players receive result by default if receivers is None: receivers = self.players.keys() if threshold is None: threshold = self.threshold a = yield a # Send share to all receivers. for peer_id in receivers: if peer_id != self.id: self._send_share(peer_id, a) # Receive and recombine shares if this player is a receiver. if self.id in receivers: shares = [] for peer_id in self.players: field = type(a) if peer_id == self.id: s = Share(self, field, (field(peer_id), a)) else: s = self._expect_share(peer_id, field) s.addCallback(lambda s, peer_id: (field(peer_id), s), peer_id) # s.df.addCallback(lambda s, peer_id: (field(peer_id), s), peer_id) shares.append(s) shares = yield shares[:threshold + 1] #ToDo wait for t+1 shares only. returnValue(shamir.recombine(shares))
def finish_mul((a, b)): pc = tuple(self.program_counter) send_data = self.protocols[self.peer.id].sendData if hash(pc) % 2 == self.id: # We play the role of P1. a1, b1 = a, b enc_a1 = encrypt(a1.value, self.player.pubkey) enc_b1 = encrypt(b1.value, self.player.pubkey) send_data(pc, PAILLIER, str(enc_a1)) send_data(pc, PAILLIER, str(enc_b1)) enc_c1 = Share(self, field) self._expect_data(self.peer.id, PAILLIER, enc_c1) c1 = enc_c1.addCallback(decrypt, self.player.seckey) c1.addCallback(lambda c: long(c) + a1 * b1) return c1 else: # We play the role of P2. a2, b2 = a, b enc_a1 = Deferred() self._expect_data(self.peer.id, PAILLIER, enc_a1) enc_a1.addCallback(long) enc_b1 = Deferred() self._expect_data(self.peer.id, PAILLIER, enc_b1) enc_b1.addCallback(long) nsq = self.peer.pubkey['n']**2 # Calculate a1 * b2 and b1 * a2 inside the encryption. enc_a1_b2 = enc_a1.addCallback(pow, b2.value, nsq) enc_b1_a2 = enc_b1.addCallback(pow, a2.value, nsq) # Chose and encrypt r. r = rand.randint(0, 2 * field.modulus**2 + 2**k) enc_r = encrypt(r, self.peer.pubkey) c1 = gatherResults([enc_a1_b2, enc_b1_a2]) c1.addCallback(lambda (a, b): a * b * enc_r) c1.addCallback(lambda c: send_data(pc, PAILLIER, str(c))) c2 = a2 * b2 - r return Share(self, field, c2)
def finish_mul((a, b)): pc = tuple(self.program_counter) send_data = self.protocols[self.peer.id].sendData if hash(pc) % 2 == self.id: # We play the role of P1. a1, b1 = a, b enc_a1 = encrypt(a1.value, self.player.pubkey) enc_b1 = encrypt(b1.value, self.player.pubkey) send_data(pc, PAILLIER, str(enc_a1)) send_data(pc, PAILLIER, str(enc_b1)) enc_c1 = Share(self, field) self._expect_data(self.peer.id, PAILLIER, enc_c1) c1 = enc_c1.addCallback(decrypt, self.player.seckey) c1.addCallback(lambda c: long(c) + a1 * b1) return c1 else: # We play the role of P2. a2, b2 = a, b enc_a1 = Deferred() self._expect_data(self.peer.id, PAILLIER, enc_a1) enc_a1.addCallback(long) enc_b1 = Deferred() self._expect_data(self.peer.id, PAILLIER, enc_b1) enc_b1.addCallback(long) nsq = self.peer.pubkey['n']**2 # Calculate a1 * b2 and b1 * a2 inside the encryption. enc_a1_b2 = enc_a1.addCallback(pow, b2.value, nsq) enc_b1_a2 = enc_b1.addCallback(pow, a2.value, nsq) # Chose and encrypt r. r = rand.randint(0, 2 * field.modulus**2 + 2**k) enc_r = encrypt(r, self.peer.pubkey) c1 = gatherResults([enc_a1_b2, enc_b1_a2]) c1.addCallback(lambda (a,b): a * b * enc_r) c1.addCallback(lambda c: send_data(pc, PAILLIER, str(c))) c2 = a2 * b2 - r return Share(self, field, c2)
def prss_share(self, inputters, field, element=None): """Creates pseudo-random secret sharings. This protocol creates a secret sharing for each player in the subset of players specified in *inputters*. Each inputter provides an integer. The result is a list of shares, one for each inputter. The protocol uses the pseudo-random secret sharing technique described in the paper "Share Conversion, Pseudorandom Secret-Sharing and Applications to Secure Computation" by Ronald Cramer, Ivan Damgård, and Yuval Ishai in Proc. of TCC 2005, LNCS 3378. `Download <http://www.cs.technion.ac.il/~yuvali/pubs/CDI05.ps>`__ Communication cost: Each inputter does one broadcast. """ # Verifying parameters. if element is None: assert self.id not in inputters, "No element given." else: assert self.id in inputters, \ "Element given, but we are not sharing?" n = self.num_players # Key used for PRSS. key = self.prss_key() # The shares for which we have all the keys. all_shares = [] # Shares we calculate from doing PRSS with the other players. tmp_shares = {} prfs = self.players[self.id].dealer_prfs(field.modulus) # Compute and broadcast correction value. if self.id in inputters: for player in self.players: share = prss(n, player, field, prfs[self.id], key) all_shares.append((field(player), share)) shared = shamir.recombine(all_shares[:self.threshold + 1]) correction = element - shared # if this player is inputter then broadcast correction value # TODO: more efficient broadcast? pc = tuple(self.program_counter) for peer_id in self.players: if self.id != peer_id: self.protocols[peer_id].sendShare(pc, correction) # Receive correction value from inputters and compute share. result = [] for player in inputters: tmp_shares[player] = prss(n, self.id, field, prfs[player], key) if player == self.id: d = Share(self, field, correction) else: d = self._expect_share(player, field) d.addCallback(lambda c, s: s + c, tmp_shares[player]) result.append(d) # Unpack a singleton list. if len(result) == 1: return result[0] else: return result
def prss_share(self, inputters, field, element=None): """Creates pseudo-random secret sharings. This protocol creates a secret sharing for each player in the subset of players specified in *inputters*. Each inputter provides an integer. The result is a list of shares, one for each inputter. The protocol uses the pseudo-random secret sharing technique described in the paper "Share Conversion, Pseudorandom Secret-Sharing and Applications to Secure Computation" by Ronald Cramer, Ivan Damgård, and Yuval Ishai in Proc. of TCC 2005, LNCS 3378. `Download <http://www.cs.technion.ac.il/~yuvali/pubs/CDI05.ps>`__ Communication cost: Each inputter does one broadcast. """ # Verifying parameters. if element is None: assert self.id not in inputters, "No element given." else: assert self.id in inputters, \ "Element given, but we are not sharing?" n = self.num_players # Key used for PRSS. key = self.prss_key() # The shares for which we have all the keys. all_shares = [] # Shares we calculate from doing PRSS with the other players. tmp_shares = {} prfs = self.players[self.id].dealer_prfs(field.modulus) # Compute and broadcast correction value. if self.id in inputters: for player in self.players: share = prss(n, player, field, prfs[self.id], key) all_shares.append((field(player), share)) shared = shamir.recombine(all_shares[:self.threshold+1]) correction = element - shared # if this player is inputter then broadcast correction value # TODO: more efficient broadcast? pc = tuple(self.program_counter) for peer_id in self.players: if self.id != peer_id: self.protocols[peer_id].sendShare(pc, correction) # Receive correction value from inputters and compute share. result = [] for player in inputters: tmp_shares[player] = prss(n, self.id, field, prfs[player], key) if player == self.id: d = Share(self, field, correction) else: d = self._expect_share(player, field) d.addCallback(lambda c, s: s + c, tmp_shares[player]) result.append(d) # Unpack a singleton list. if len(result) == 1: return result[0] else: return result