def generate_configs(n, t, addresses=None, prefix=None): """Generate player configurations. Generates *n* configuration objects with a threshold of *t*. The *addresses* is an optional list of ``(host, port)`` pairs and *prefix* is a filename prefix. One can avoid generating keys for PRSS by setting *skip_prss* to True. This is useful when the number of players is large. The configurations are returned as :class:`ConfigObj` instances and can be saved to disk if desired. Returns a mapping from player ID to player configuration. """ players = frozenset(range(1, n+1)) def generate_key(): # TODO: is a 40 byte hex string as good as a 20 byte binary # string when it is used for SHA1 hashing? It ought to be # since they contain the same entropy. # A SHA1 hash is 160 bit return hex(rand.randint(0, 2**160)) def s_str(subset): """Convert a subset to a string.""" return " ".join(map(str, subset)) def p_str(player): """Convert a player ID to a string.""" return "Player " + str(player) configs = {} for p in players: config = ConfigObj(indent_type=' ') config.filename = "%s-%d.ini" % (prefix, p) config.initial_comment = ['VIFF config file for Player %d' % p] config.final_comment = ['', 'End of config', ''] configs[p] = config for p in players: if addresses is None: host, port = 'no-host', 0 else: host, port = addresses[p-1] for player, config in configs.iteritems(): config[p_str(p)] = dict(host=host, port=port) if player == p: # Prepare the config file for the keys config[p_str(p)]['prss_keys'] = {} max_unqualified_subsets = generate_subsets(players, n-t) for subset in max_unqualified_subsets: key = generate_key() for player in subset: config = configs[player] config[p_str(player)]['prss_keys'][s_str(subset)] = key return configs
def is_hyper(self, mat): """Checks if a square matrix is hyper-invertible. @param mat: A square matrix. @return: True if the matrix is hyper-invertible, otherwise False. """ n = len(mat.rows) for size in range(1, n + 1): subsets = generate_subsets(frozenset(range(n)), size) for rows in subsets: for columns in subsets: sub = Matrix([[mat[r, c] for r in rows] for c in columns]) if sub.determinant() == 0: return False return True
def is_hyper(self, mat): """Checks if a square matrix is hyper-invertible. @param mat: A square matrix. @return: True if the matrix is hyper-invertible, otherwise False. """ n = len(mat.rows) for size in range(1, n+1): subsets = generate_subsets(frozenset(range(n)), size) for rows in subsets: for columns in subsets: sub = Matrix([[mat[r, c] for r in rows] for c in columns]) if sub.determinant() == 0: return False return True
def test_generate_subsets(self): """Test subset generation. All possible subsets of all possible sizes are generated and it is verified that they have the correct size and that they can be combined to yield the original set. """ def binom(n, k): """Binomial coefficient.""" def fac(n): """Factorial.""" if n > 1: return n * fac(n-1) else: return 1 return fac(n) // (fac(k) * fac(n-k)) # Maximum size of sets to test. The running time grows quite # rapidly, so this should not be too big. max_size = 6 for size in range(max_size): set = frozenset(range(size)) for sub_size in range(max_size): subsets = generate_subsets(set, sub_size) if sub_size > size: self.assertEquals(len(subsets), 0) else: self.assertEquals(len(subsets), binom(len(set), sub_size)) union = reduce(lambda a, b: a | b, subsets) if sub_size == 0: self.assertEquals(frozenset([]), union) else: self.assertEquals(set, union)
def generate_configs(n, t, paillier=ViffPaillier(1024), addresses=None, prefix=None, skip_prss=False): """Generate player configurations. Generates *n* configuration objects with a threshold of *t*. The *addresses* is an optional list of ``(host, port)`` pairs and *prefix* is a filename prefix. One can avoid generating keys for PRSS by setting *skip_prss* to True. This is useful when the number of players is large. The configurations are returned as :class:`ConfigObj` instances and can be saved to disk if desired. Returns a mapping from player ID to player configuration. """ players = frozenset(range(1, n + 1)) def generate_key(): # TODO: is a 40 byte hex string as good as a 20 byte binary # string when it is used for SHA1 hashing? It ought to be # since they contain the same entropy. # A SHA1 hash is 160 bit return hex(rand.randint(0, 2**160)) def s_str(subset): """Convert a subset to a string.""" return " ".join(map(str, subset)) def p_str(player): """Convert a player ID to a string.""" return "Player " + str(player) def d_str(dealer): """Convert a dealer ID to a string.""" return "Dealer " + str(dealer) key_pairs = dict([(p, paillier.generate_keys()) for p in players]) configs = {} for p in players: config = ConfigObj(indent_type=' ') config.filename = "%s-%d.ini" % (prefix, p) config.initial_comment = ['VIFF config file for Player %d' % p] config.final_comment = ['', 'End of config', ''] configs[p] = config for p in players: if addresses is None: host, port = 'no-host', 0 else: host, port = addresses[p - 1] for player, config in configs.iteritems(): config[p_str(p)] = dict(host=host, port=port) # Attaching an empty string as a comment will result in a newline # in the configuration file, making it slightly easier to read config.comments[p_str(p)] = [''] config[p_str(p)]['paillier'] = {} config[p_str(p)]['paillier']['type'] = paillier.type config[p_str(p)]['paillier']['pubkey'] = key_pairs[p][0] if player == p: config[p_str(p)]['paillier']['seckey'] = key_pairs[p][1] # Prepare the config file for the keys config[p_str(p)]['prss_keys'] = {} config[p_str(p)]['prss_dealer_keys'] = {} for d in players: config[p_str(p)]['prss_dealer_keys'][d_str(d)] = {} if not skip_prss: max_unqualified_subsets = generate_subsets(players, n - t) for subset in max_unqualified_subsets: key = generate_key() for player in subset: config = configs[player] config[p_str(player)]['prss_keys'][s_str(subset)] = key for dealer in players: d = d_str(dealer) for subset in max_unqualified_subsets: s = s_str(subset) key = generate_key() for player in (subset | set([dealer])): p = p_str(player) configs[player][p]['prss_dealer_keys'][d][s] = key return configs
def generate_configs(n, t, paillier=ViffPaillier(1024), addresses=None, prefix=None, skip_prss=False): """Generate player configurations. Generates *n* configuration objects with a threshold of *t*. The *addresses* is an optional list of ``(host, port)`` pairs and *prefix* is a filename prefix. One can avoid generating keys for PRSS by setting *skip_prss* to True. This is useful when the number of players is large. The configurations are returned as :class:`ConfigObj` instances and can be saved to disk if desired. Returns a mapping from player ID to player configuration. """ players = frozenset(range(1, n+1)) def generate_key(): # TODO: is a 40 byte hex string as good as a 20 byte binary # string when it is used for SHA1 hashing? It ought to be # since they contain the same entropy. # A SHA1 hash is 160 bit return hex(rand.randint(0, 2**160)) def s_str(subset): """Convert a subset to a string.""" return " ".join(map(str, subset)) def p_str(player): """Convert a player ID to a string.""" return "Player " + str(player) def d_str(dealer): """Convert a dealer ID to a string.""" return "Dealer " + str(dealer) key_pairs = dict([(p, paillier.generate_keys()) for p in players]) configs = {} for p in players: config = ConfigObj(indent_type=' ') config.filename = "%s-%d.ini" % (prefix, p) config.initial_comment = ['VIFF config file for Player %d' % p] config.final_comment = ['', 'End of config', ''] configs[p] = config for p in players: if addresses is None: host, port = 'no-host', 0 else: host, port = addresses[p-1] for player, config in configs.iteritems(): config[p_str(p)] = dict(host=host, port=port) # Attaching an empty string as a comment will result in a newline # in the configuration file, making it slightly easier to read config.comments[p_str(p)] = [''] config[p_str(p)]['paillier'] = {} config[p_str(p)]['paillier']['type'] = paillier.type config[p_str(p)]['paillier']['pubkey'] = key_pairs[p][0] if player == p: config[p_str(p)]['paillier']['seckey'] = key_pairs[p][1] # Prepare the config file for the keys config[p_str(p)]['prss_keys'] = {} config[p_str(p)]['prss_dealer_keys'] = {} for d in players: config[p_str(p)]['prss_dealer_keys'][d_str(d)] = {} if not skip_prss: max_unqualified_subsets = generate_subsets(players, n-t) for subset in max_unqualified_subsets: key = generate_key() for player in subset: config = configs[player] config[p_str(player)]['prss_keys'][s_str(subset)] = key for dealer in players: d = d_str(dealer) for subset in max_unqualified_subsets: s = s_str(subset) key = generate_key() for player in (subset | set([dealer])): p = p_str(player) configs[player][p]['prss_dealer_keys'][d][s] = key return configs