def recv_interest_voucher(self, data): msg, key = marshal.loads(data) (nonce, leader_ip, leader_gui_port, leader_com_port) = marshal.loads(msg) self.DEBUG( "Start round voucher from %s:%s, communicating at port %s" % (leader_ip, leader_gui_port, leader_com_port) ) # get the path to the file you want to share self.emit(SIGNAL("getSharedFilename()")) verified = self.verify(leader_ip, leader_gui_port, data) """ generate temporary keys for this round so leader can aggregate """ self.gen_temp_keys() temp1_str = AnonCrypto.pub_key_to_str(self.pubgenkey1) temp2_str = AnonCrypto.pub_key_to_str(self.pubgenkey2) """ default to random file of 128 bytes if you don't have anything to share """ if verified: if os.path.exists(self.shared_filename): self.DEBUG("You are sharing file %s" % (self.shared_filename)) else: self.DEBUG("Not a valid file path, continuing without sharing...") # respond with your interest self.DEBUG("Verified leader, participating as %s:%s at port %s" % (self.ip, self.gui_port, self.com_port)) response = marshal.dumps((nonce, self.ip, self.gui_port, self.com_port, temp1_str, temp2_str)) cipher = AnonCrypto.sign_with_key(self.privKey, response) AnonNet.send_to_addr(leader_ip, int(leader_gui_port), marshal.dumps(("interested", cipher))) else: self.DEBUG("Unkown leader, opting out...")
def unpickle_pub_keys(self, msgs): """ Leader uses this method to unpack keys from other nodes """ addrs = [] key_dict = {} key_dict[self.id] = (self.key_from_file(1), AnonCrypto.sign(self.id, self.key1, self.key2.get_pubkey())) for data in msgs: (rem_id, rem_round, rem_ip, rem_port, rem_key1, rem_key2) = marshal.loads(data) self.debug("Unpickled msg from node %d" % (rem_id)) if rem_round != self.round_id: raise RuntimeError, "Mismatched round numbers! (mine: %d, other: %d)" % ( self.round_id, rem_round) self.debug("Before reading verification key") k1 = AnonCrypto.vk_key_from_str(rem_key1) self.pub_keys[rem_id] = (k1, k1) self.debug("Before reading public key") k2 = AnonCrypto.pub_key_from_str( AnonCrypto.verify(self.pub_keys, rem_key2)) self.pub_keys[rem_id] = (k1, k2) addrs.append((rem_ip, rem_port)) key_dict[rem_id] = (rem_key1, rem_key2) self.debug("After handling the keys") return (marshal.dumps((self.round_id, key_dict)), addrs)
def unpickle_pub_keys(self, msgs): """ Leader uses this method to unpack keys from other nodes """ addrs = [] key_dict = {} key_dict[self.id] = ( self.key_from_file(1), AnonCrypto.sign(self.id, self.key1, self.key_from_file(2))) for data in msgs: (rem_id, rem_round, rem_ip, rem_port, rem_key1, rem_key2) = marshal.loads(data) self.debug("Unpickled msg from node %d" % (rem_id)) if rem_round != self.round_id: raise RuntimeError, "Mismatched round numbers! (mine: %d, other: %d)" % ( self.round_id, rem_round) k1 = AnonCrypto.pub_key_from_str(rem_key1) self.pub_keys[rem_id] = (k1, k1) k2 = AnonCrypto.pub_key_from_str(AnonCrypto.verify(self.pub_keys, rem_key2)) self.pub_keys[rem_id] = (k1, k2) addrs.append((rem_ip, rem_port)) key_dict[rem_id] = (rem_key1, rem_key2) return (marshal.dumps((self.round_id, key_dict)), addrs)
def recv_interest_voucher(self, data): msg, key = marshal.loads(data) (nonce, leader_ip, leader_gui_port, leader_com_port) = marshal.loads(msg) self.DEBUG("Start round voucher from %s:%s, communicating at port %s" % (leader_ip, leader_gui_port, leader_com_port)) # get the path to the file you want to share self.emit(SIGNAL("getSharedFilename()")) verified = self.verify(leader_ip, leader_gui_port, data) """ generate temporary keys for this round so leader can aggregate """ self.gen_temp_keys() temp1_str = AnonCrypto.pub_key_to_str(self.pubgenkey1) temp2_str = AnonCrypto.pub_key_to_str(self.pubgenkey2) """ default to random file of 128 bytes if you don't have anything to share """ if verified: if os.path.exists(self.shared_filename): self.DEBUG("You are sharing file %s" % (self.shared_filename)) else: self.DEBUG("Not a valid file path, continuing without sharing...") # respond with your interest self.DEBUG("Verified leader, participating as %s:%s at port %s" % (self.ip, self.gui_port, self.com_port)) response = marshal.dumps((nonce,self.ip,self.gui_port,self.com_port,temp1_str,temp2_str)) cipher = AnonCrypto.sign_with_key(self.privKey, response) AnonNet.send_to_addr(leader_ip, int(leader_gui_port), marshal.dumps(("interested", cipher))) else: self.DEBUG("Unkown leader, opting out...")
def phase0b_msg(self): """ Message the leader sends to all other nodes. """ newdict = {} for i in xrange(0, self.n_nodes): k1, k2 = self.pub_keys[i] newdict[i] = (AnonCrypto.pub_key_to_str(k1), AnonCrypto.pub_key_to_str(k2)) return marshal.dumps((self.round_id, newdict))
def initialize_keys(self): self.advance_phase() for index, participant in enumerate(self.participants_vector): msg, key = marshal.loads(participant[0]) (nonce, interest_ip, interest_gui_port, interest_com_port, pubkey1_str, pubkey2_str) = marshal.loads(msg) k1 = AnonCrypto.pub_key_from_str(pubkey1_str) k2 = AnonCrypto.pub_key_from_str(pubkey2_str) self.pub_keys[index] = (k1, k2) self.info('Unpickled public keys')
def generate_keys(self): info("Generating keypair, please wait...") self.key1 = AnonCrypto.random_key(self.key_len) self.key2 = AnonCrypto.random_key(self.key_len) self.save_pub_key(self.key1, 1) self.save_pub_key(self.key2, 2) self.pub_keys[self.id] = ( M2Crypto.RSA.load_pub_key(self.key_filename(1)), M2Crypto.RSA.load_pub_key(self.key_filename(2)))
def phase1_msg(self): """ Message that non-leader nodes send to the leader. """ #ToDo: Generate the hash of the encryption keys and send it instead of the keys themselves # for the equivocation check. return marshal.dumps( (self.id, self.round_id, self.ip, self.port, self.key_from_file(1), AnonCrypto.sign(self.id, self.key1, AnonCrypto.pub_key_to_str(self.key2)))) return marshal.dumps((self.round_id, newdict))
def phase0b_msg(self): """ Message the leader sends to all other nodes. """ newdict = {} for i in xrange(0, self.n_nodes): k1,k2 = self.pub_keys[i] newdict[i] = ( AnonCrypto.pub_key_to_str(k1), AnonCrypto.pub_key_to_str(k2)) return marshal.dumps((self.round_id, newdict))
def generate_keys(self): info("Generating sining key pair, please wait...") self.key1 = AnonCrypto.random_signing_key() info("Generating encryption key pair, please wait...") self.key2 = AnonCrypto.random_key(self.key_len) info("Keys generated") self.save_pub_key(self.key1, 1) #self.save_pub_key(self.key2, 2) self.pub_keys[self.id] = (M2Crypto.EC.load_pub_key( self.key_filename(1)), self.key2)
def run_phase4(self): self.advance_phase() if self.am_leader(): self.debug("Leader broadcasting ciphers to all nodes") self.broadcast_to_all_nodes(marshal.dumps(self.final_ciphers)) self.debug("Cipher set len %d" % (len(self.final_ciphers))) else: """ Get C' ciphertexts from leader. """ self.final_ciphers = marshal.loads(self.recv_from_leader()) """ self.final_ciphers holds an array of pickled (round_id, cipher_prime) tuples """ my_cipher_str = marshal.dumps((self.round_id, self.cipher_prime)) go = False if my_cipher_str in self.final_ciphers: self.info("Found my ciphertext in set") go = True else: self.critical("ABORT! My ciphertext is not in set!") self.debug(self.final_ciphers) go = False raise RuntimeError, "Protocol violation: My ciphertext is missing!" hashval = AnonCrypto.hash_list(self.final_ciphers) go_msg = marshal.dumps(( self.id, self.round_id, go, hashval)) go_data = '' if self.am_leader(): """ Collect go msgs """ data = self.recv_from_all(False) """ Add leader's signed GO message to set """ data.append(AnonCrypto.sign(self.id, self.key1, go_msg)) go_data = marshal.dumps((data)) self.broadcast_to_all_nodes(go_data) else: """ Send go msg to leader """ self.send_to_leader(go_msg) go_data = self.recv_from_leader() self.check_go_data(hashval, go_data) self.info("All nodes report GO") return
def gen_temp_keys(self): key1 = AnonCrypto.random_key(KEY_LENGTH) key2 = AnonCrypto.random_key(KEY_LENGTH) key1.save_key('config/temp1.priv', None) key1.save_pub_key('config/temp1.pub') key2.save_key('config/temp2.priv', None) key2.save_pub_key('config/temp2.pub') self.privgenkey1 = M2Crypto.RSA.load_key('config/temp1.priv') self.pubgenkey1 = M2Crypto.RSA.load_pub_key('config/temp1.pub') self.privgenkey2 = M2Crypto.RSA.load_key('config/temp2.priv') self.pubgenkey2 = M2Crypto.RSA.load_pub_key('config/temp2.pub')
def gen_temp_keys(self): key1 = AnonCrypto.random_key(KEY_LENGTH) key2 = AnonCrypto.random_key(KEY_LENGTH) key1.save_key("config/temp1.priv", None) key1.save_pub_key("config/temp1.pub") key2.save_key("config/temp2.priv", None) key2.save_pub_key("config/temp2.pub") self.privgenkey1 = M2Crypto.RSA.load_key("config/temp1.priv") self.pubgenkey1 = M2Crypto.RSA.load_pub_key("config/temp1.pub") self.privgenkey2 = M2Crypto.RSA.load_key("config/temp2.priv") self.pubgenkey2 = M2Crypto.RSA.load_pub_key("config/temp2.pub")
def phase1_msg(self): """ Message that non-leader nodes send to the leader. """ return marshal.dumps( (self.id, self.round_id, self.ip, self.port, self.key_from_file(1), AnonCrypto.sign(self.id, self.key1, self.key_from_file(2)))) return marshal.dumps((self.round_id, newdict))
def __main__(argv): min_key_len = 1024 if(len(argv) != 16): raise ValueError, "Usage: %s id key_len round_id n_nodes my_ip my_port leader_ip leader_port dnstr_ip dnstr_port upstr_ip upstr_port msg_len max_len mode" % (argv[0]) logger = logging.getLogger() logger.setLevel(logging.DEBUG) id = int(argv[1]) key_len = int(argv[2]) round_id = int(argv[3]) n_nodes = int(argv[4]) my_addr = (argv[5], int(argv[6])) leader_addr = (argv[7], int(argv[8])) up_addr = (argv[9], int(argv[10])) dn_addr = (argv[11], int(argv[12])) msg_len = int(argv[13]) max_len = int(argv[14]) mode = int (argv[15]) msg_file = AnonCrypto.random_file(msg_len) node = shuffle_node.shuffle_node(id, key_len, round_id, n_nodes, my_addr, leader_addr, up_addr, dn_addr, msg_file, max_len) #cProfile.runctx('node.run_protocol()', {}, {'node': node}) node.run_bad_protocol(mode) fnames = node.output_filenames() print "--------------------------------------------------------------------" # for i in xrange(0, len(fnames)): # copyfile(fnames[i], "data/node%04d-%04d.out" % (id, i)) return
def __main__(argv): min_key_len = 1024 if (len(argv) != 14): raise ValueError, "Usage: %s id key_len round_id n_nodes my_ip my_port leader_ip leader_port dnstr_ip dnstr_port upstr_ip upstr_port msg_len" % ( argv[0]) logger = logging.getLogger() logger.setLevel(logging.DEBUG) debug("Starting node") id = int(argv[1]) key_len = int(argv[2]) round_id = int(argv[3]) n_nodes = int(argv[4]) my_addr = (argv[5], int(argv[6])) leader_addr = (argv[7], int(argv[8])) up_addr = (argv[9], int(argv[10])) dn_addr = (argv[11], int(argv[12])) msg_len = int(argv[13]) msg_file = AnonCrypto.random_file(msg_len) node = bulk_node.bulk_node(id, key_len, round_id, n_nodes, my_addr, leader_addr, up_addr, dn_addr, msg_file) cProfile.runctx('mynode.run_protocol()', {'mynode': node}, {}) #node.run_protocol() fnames = node.output_filenames() for i in xrange(0, len(fnames)): copyfile(fnames[i], "data/node%04d-%04d.out" % (id, i)) return
def accept_phase(self, ip, port, nonce): # package and encrypt data response = marshal.dumps((nonce, self.ip, self.gui_port)) cipher = AnonCrypto.sign_with_key(self.privKey, response) # respond with ((ip, port), encrypted_data) AnonNet.send_to_addr(ip, int(port), marshal.dumps(("accept", cipher)))
def accept_phase(self, ip, port, nonce): # package and encrypt data response = marshal.dumps((nonce,self.ip,self.gui_port)) cipher = AnonCrypto.sign_with_key(self.privKey, response) # respond with ((ip, port), encrypted_data) AnonNet.send_to_addr(ip, int(port), marshal.dumps(("accept", cipher)))
def __main__(argv): min_key_len = 1024 if(len(argv) != 14): raise ValueError, "Usage: %s id key_len round_id n_nodes my_ip my_port leader_ip leader_port dnstr_ip dnstr_port upstr_ip upstr_port msg_len" % (argv[0]) logger = logging.getLogger() logger.setLevel(logging.DEBUG) debug("Starting node") id = int(argv[1]) key_len = int(argv[2]) round_id = int(argv[3]) n_nodes = int(argv[4]) my_addr = (argv[5], int(argv[6])) leader_addr = (argv[7], int(argv[8])) up_addr = (argv[9], int(argv[10])) dn_addr = (argv[11], int(argv[12])) msg_len = int(argv[13]) msg_file = AnonCrypto.random_file(msg_len) node = bulk_node.bulk_node(id, key_len, round_id, n_nodes, my_addr, leader_addr, up_addr, dn_addr, msg_file) cProfile.runctx('mynode.run_protocol()', {'mynode': node}, {}) #node.run_protocol() fnames = node.output_filenames() for i in xrange(0, len(fnames)): copyfile(fnames[i], "data/node%04d-%04d.out" % (id, i)) return
def start_node(self, down_index, up_index, participants_vector, my_id): n_nodes = len(participants_vector) leader_addr = (participants_vector[0][1], int(participants_vector[0][3])) my_addr = (participants_vector[my_id][1], int(participants_vector[my_id][3])) dn_addr = (participants_vector[down_index][1], int(participants_vector[down_index][3])) up_addr = (participants_vector[up_index][1], int(participants_vector[up_index][3])) round_id = 1 key_len = KEY_LENGTH """ if distrusted peer is participating, then don't share file (if one is chosen) """ self.DEBUG("Distrusted peers: %s" % self.distrusted_peers) msg_file = None trusted = True if os.path.exists(self.shared_filename): for peer in participants_vector: for distrusted_peer in self.distrusted_peers: (d_ip, d_port) = distrusted_peer (p_ip, p_port) = peer[1], peer[2] if d_ip == p_ip and str(d_port) == str(p_port): self.DEBUG("Not sharing my file because peer %s:%s is participating" % (p_ip, p_port)) trusted = False break if not trusted: break # create random file if none has been shared if trusted and os.path.exists(self.shared_filename): msg_file = self.shared_filename else: msg_file = AnonCrypto.random_file(DEFAULT_LENGTH) # initialize node self.node = bulk_node.bulk_node(my_id, key_len, round_id, n_nodes, \ my_addr, leader_addr, dn_addr, up_addr, msg_file, participants_vector, self.privgenkey1, self.privgenkey2) self.DEBUG("round_id: %s id: %s n_nodes: %s my_addr: %s leader_addr: %s dn_addr: %s up_addr: %s msg_file: %s" % \ (round_id, my_id, n_nodes, my_addr, leader_addr, dn_addr, up_addr, msg_file))
def __main__(argv): min_key_len = 1024 if (len(argv) != 16): raise ValueError, "Usage: %s id key_len round_id n_nodes my_ip my_port leader_ip leader_port dnstr_ip dnstr_port upstr_ip upstr_port msg_len max_len mode" % ( argv[0]) logger = logging.getLogger() logger.setLevel(logging.DEBUG) id = int(argv[1]) key_len = int(argv[2]) round_id = int(argv[3]) n_nodes = int(argv[4]) my_addr = (argv[5], int(argv[6])) leader_addr = (argv[7], int(argv[8])) up_addr = (argv[9], int(argv[10])) dn_addr = (argv[11], int(argv[12])) msg_len = int(argv[13]) max_len = int(argv[14]) mode = int(argv[15]) msg_file = AnonCrypto.random_file(msg_len) node = shuffle_node.shuffle_node(id, key_len, round_id, n_nodes, my_addr, leader_addr, up_addr, dn_addr, msg_file, max_len) #cProfile.runctx('node.run_protocol()', {}, {'node': node}) node.run_bad_protocol(mode) fnames = node.output_filenames() print "--------------------------------------------------------------------" # for i in xrange(0, len(fnames)): # copyfile(fnames[i], "data/node%04d-%04d.out" % (id, i)) return
def prepare_round(self): # can't start round without 3 or more peers if len(self.participants) < 3: self.DEBUG("Not enough peers to start round!") return prepare_voucher = marshal.dumps( (int(PREPARE_WAIT), int(1), copy.copy(self.participants), self.ip, self.gui_port, self.com_port) ) cipher = AnonCrypto.sign_with_key(self.privKey, prepare_voucher) for index, participant in enumerate(self.participants): down_index = (index - 1) % len(self.participants) up_index = (index + 1) % len(self.participants) if (self.ip, self.gui_port, self.com_port) != (participant[1], participant[2], participant[3]): AnonNet.send_to_addr( participant[1], participant[2], marshal.dumps(("prepare:%s:%s:%s" % (index, down_index, up_index), cipher)), ) self.DEBUG( "Sending prepare to peer %s:%s at port %s" % (participant[1], participant[2], participant[3]) ) # after informing the participants, create your node dn_idx = -1 % len(self.participants) up_idx = 1 self.start_node(dn_idx, up_idx, self.participants, 0) # start round after PREPARE_WAIT minutes DelayTimer(PREPARE_WAIT, self.run_protocol).start()
def create_cipher_string(self): self.cipher_prime = self.datum_string() """ Encrypt with all secondary keys from N ... 1 """ self.debug("Orig len: %d" % len(self.cipher_prime)) for i in xrange(self.n_nodes - 1, -1, -1): k1, k2 = self.pub_keys[i] self.cipher_prime = AnonCrypto.encrypt_with_rsa( k2, self.cipher_prime) self.debug("Cipher-prim len: %d" % len(self.cipher_prime)) self.cipher = self.cipher_prime """ Encrypt with all primary keys from N ... 1 """ for i in xrange(self.n_nodes - 1, -1, -1): k1, k2 = self.pub_keys[i] self.cipher = AnonCrypto.encrypt_with_rsa(k1, self.cipher) self.debug("Cipher len: %d" % len(self.cipher))
def create_cipher_string(self): self.cipher_prime = self.datum_string() """ Encrypt with all secondary keys from N ... 1 """ self.debug("Orig len: %d" % len(self.cipher_prime)) for i in xrange(self.n_nodes - 1, -1, -1): k1, k2 = self.pub_keys[i] self.cipher_prime = AnonCrypto.encrypt_with_rsa(k2, self.cipher_prime) self.debug("Cipher-prim len: %d" % len(self.cipher_prime)) self.cipher = self.cipher_prime """ Encrypt with all primary keys from N ... 1 """ for i in xrange(self.n_nodes-1, -1, -1): k1, k2 = self.pub_keys[i] self.cipher = AnonCrypto.encrypt_with_rsa(k1, self.cipher) self.debug("Cipher len: %d" % len(self.cipher))
def broadcast_to_all_nodes(self, msg, signed = True): if not self.am_leader(): raise RuntimeError, 'Only leader can broadcast' if signed: outmsg = AnonCrypto.sign(self.id, self.key1, msg) else: outmsg = msg AnonNet.broadcast_using(self.sockets, AnonNet.send_to_socket, outmsg)
def broadcast_to_all_nodes(self, msg, signed=True): if not self.am_leader(): raise RuntimeError, 'Only leader can broadcast' if signed: outmsg = AnonCrypto.sign(self.id, self.key1, msg) else: outmsg = msg AnonNet.broadcast_using(self.sockets, AnonNet.send_to_socket, outmsg)
def run_phase4(self): self.advance_phase() if self.am_leader(): self.debug("Leader broadcasting ciphers to all nodes") self.broadcast_to_all_nodes(marshal.dumps(self.final_ciphers)) self.debug("Cipher set len %d" % (len(self.final_ciphers))) else: """ Get C' ciphertexts from leader. """ self.final_ciphers = marshal.loads(self.recv_from_leader()) """ self.final_ciphers holds an array of pickled (round_id, cipher_prime) tuples """ my_cipher_str = marshal.dumps((self.round_id, self.cipher_prime)) go = False if my_cipher_str in self.final_ciphers: self.info("Found my ciphertext in set") go = True else: self.critical("ABORT! My ciphertext is not in set!") self.debug(self.final_ciphers) go = False raise RuntimeError, "Protocol violation: My ciphertext is missing!" hashval = AnonCrypto.hash_list(self.final_ciphers) go_msg = marshal.dumps((self.id, self.round_id, go, hashval)) go_data = '' if self.am_leader(): """ Collect go msgs """ data = self.recv_from_all(False) """ Add leader's signed GO message to set """ data.append(AnonCrypto.sign(self.id, self.key1, go_msg)) go_data = marshal.dumps((data)) self.broadcast_to_all_nodes(go_data) else: """ Send go msg to leader """ self.send_to_leader(go_msg) go_data = self.recv_from_leader() self.check_go_data(hashval, go_data) self.info("All nodes report GO") return
def run_phase4(self): self.advance_phase() self.info('Starting phase 4') self.data_filenames = self.unpack_msg_tar(self.message_tar) for i in xrange(0, len(self.data_filenames)): if AnonCrypto.hash_file(self.data_filenames[i]) != self.msg_data[i][3]: #raise RuntimeError, "Mismatched hash in slot %d" % i self.critical("Mismatched hashes")
def run_phase4(self): self.advance_phase() self.info("Starting phase 4") self.data_filenames = self.unpack_msg_tar(self.message_tar) for i in xrange(0, len(self.data_filenames)): if AnonCrypto.hash_file(self.data_filenames[i]) != self.msg_data[i][3]: # raise RuntimeError, "Mismatched hash in slot %d" % i self.critical("Mismatched hashes")
def unpickle_keyset(self, keys): """ Non-leader nodes use this to decode leader's key msg """ (rem_round_id, keydict) = marshal.loads(keys) if rem_round_id != self.round_id: raise RuntimeError, "Mismatched round ids" for i in keydict: s1, s2 = keydict[i] k1 = AnonCrypto.vk_key_from_str(s1) #k1.check_key() self.pub_keys[i] = (k1, k1) k2 = AnonCrypto.pub_key_from_str( AnonCrypto.verify(self.pub_keys, s2)) #k2.check_key() self.pub_keys[i] = (k1, k2) self.info('Unpickled public keys')
def unpickle_keyset(self, keys): """ Non-leader nodes use this to decode leader's key msg """ (rem_round_id, keydict) = marshal.loads(keys) if rem_round_id != self.round_id: raise RuntimeError, "Mismatched round ids" for i in keydict: s1,s2 = keydict[i] k1 = AnonCrypto.pub_key_from_str(s1) k1.check_key() self.pub_keys[i] = (k1, k1) k2 = AnonCrypto.pub_key_from_str(AnonCrypto.verify(self.pub_keys, s2)) k2.check_key() self.pub_keys[i] = (k1, k2) self.info('Unpickled public keys')
def unpickle_keyset(self, keys): """ Method that non-leader nodes use to unpack all public keys from the leader's message. """ (rem_round_id, keydict) = marshal.loads(keys) if rem_round_id != self.round_id: raise RuntimeError, "Mismatched round ids" for i in keydict: s1, s2 = keydict[i] k1 = AnonCrypto.pub_key_from_str(s1) k2 = AnonCrypto.pub_key_from_str(s2) k1.check_key() k2.check_key() self.pub_keys[i] = (k1, k2) self.info("Unpickled public keys")
def decrypt_ciphers(self, keyset): priv_keys = {} for item in keyset: """ Verify signature on each key """ item_str = AnonCrypto.verify(self.pub_keys, item) (r_id, r_roundid, r_keystr) = marshal.loads(item_str) if r_roundid != self.round_id: raise RuntimeError, 'Mismatched round numbers' priv_keys[r_id] = AnonCrypto.priv_key_from_str(r_keystr) plaintexts = [] for cipher in self.final_ciphers: (r_round, cipher_prime) = marshal.loads(cipher) if r_round != self.round_id: raise RuntimeError, 'Mismatched round ids' for i in xrange(0, self.n_nodes): cipher_prime = AnonCrypto.decrypt_with_rsa(priv_keys[i], cipher_prime) plaintexts.append(self.unpackage_msg(cipher_prime)) self.anon_data = plaintexts
def unpickle_pub_keys(self, msgs): """ Method that the leader uses to unpack public keys from other nodes. """ addrs = [] for data in msgs: (rem_id, rem_round, rem_ip, rem_port, rem_key1, rem_key2) = marshal.loads(data) self.debug("Unpickled msg from node %d" % (rem_id)) if rem_round != self.round_id: raise RuntimeError, "Mismatched round numbers!\ (mine: %d, other: %d)" % ( self.round_id, rem_round, ) self.pub_keys[rem_id] = (AnonCrypto.pub_key_from_str(rem_key1), AnonCrypto.pub_key_from_str(rem_key2)) addrs.append((rem_ip, rem_port)) return addrs
def unpickle_keyset(self, keys): """ Method that non-leader nodes use to unpack all public keys from the leader's message. """ (rem_round_id, keydict) = marshal.loads(keys) if rem_round_id != self.round_id: raise RuntimeError, "Mismatched round ids" for i in keydict: s1,s2 = keydict[i] k1 = AnonCrypto.pub_key_from_str(s1) k2 = AnonCrypto.pub_key_from_str(s2) k1.check_key() k2.check_key() self.pub_keys[i] = (k1, k2) self.info('Unpickled public keys')
def unpickle_pub_keys(self, msgs): """ Method that the leader uses to unpack public keys from other nodes. """ addrs = [] for data in msgs: (rem_id, rem_round, rem_ip, rem_port, rem_key1, rem_key2) = marshal.loads(data) self.debug("Unpickled msg from node %d" % (rem_id)) if rem_round != self.round_id: raise RuntimeError, "Mismatched round numbers!\ (mine: %d, other: %d)" % ( self.round_id, rem_round) self.pub_keys[rem_id] = ( AnonCrypto.pub_key_from_str(rem_key1), AnonCrypto.pub_key_from_str(rem_key2)) addrs.append((rem_ip, rem_port)) return addrs
def recv_from_all(self, verify=True): if not self.am_leader(): raise RuntimeError, "Only leader can broadcast" indata = AnonNet.recv_from_n(self.sockets) if verify: outdata = [] for d in indata: outdata.append(AnonCrypto.verify(self.pub_keys, d)) return outdata else: return indata
def shuffle_and_decrypt(self): random.shuffle(self.data_in) self.debug("Shuffling len = %d" % len(self.data_in)) self.data_out = [] for ctuple in self.data_in: (rem_round, ctext) = marshal.loads(ctuple) if rem_round != self.round_id: raise RuntimeError, "Mismatched round numbers (mine:%d, other:%d)" % (self.round_id, rem_round) new_ctext = AnonCrypto.decrypt_with_rsa(self.key1, ctext) pickled = marshal.dumps((self.round_id, new_ctext)) self.data_out.append(pickled)
def decrypt_ciphers(self, keyset): priv_keys = {} for item in keyset: """ Verify signature on each key """ item_str = AnonCrypto.verify(self.pub_keys, item) (r_id, r_roundid, r_keystr) = marshal.loads(item_str) if r_roundid != self.round_id: raise RuntimeError, 'Mismatched round numbers' priv_keys[r_id] = AnonCrypto.priv_key_from_str(r_keystr) plaintexts = [] for cipher in self.final_ciphers: (r_round, cipher_prime) = marshal.loads(cipher) if r_round != self.round_id: raise RuntimeError, 'Mismatched round ids' for i in xrange(0, self.n_nodes): cipher_prime = AnonCrypto.decrypt_with_rsa( priv_keys[i], cipher_prime) plaintexts.append(self.unpackage_msg(cipher_prime)) self.anon_data = plaintexts
def recv_from_all(self, verify=True): if not self.am_leader(): raise RuntimeError, 'Only leader can broadcast' indata = AnonNet.recv_from_n(self.sockets) if verify: outdata = [] for d in indata: outdata.append(AnonCrypto.verify(self.pub_keys, d)) return outdata else: return indata
def establish_keys(self): if not os.path.exists('config'): os.mkdir('config') try: # load them into instance vars if they already exist self.load_keys() except: # generate new keys, save them to config/priv # and config/pub -- then load them into instance vars self.DEBUG("keys don't exist/valid") newKey = AnonCrypto.random_key(KEY_LENGTH) self.save_keys(newKey) self.load_keys()
def establish_keys(self): if not os.path.exists("config"): os.mkdir("config") try: # load them into instance vars if they already exist self.load_keys() except: # generate new keys, save them to config/priv # and config/pub -- then load them into instance vars self.DEBUG("keys don't exist/valid") newKey = AnonCrypto.random_key(KEY_LENGTH) self.save_keys(newKey) self.load_keys()
def check_go_data(self, hashval, pickled_list): go_lst = marshal.loads(pickled_list) for item in go_lst: """ Verify signature on "GO" message """ item_str = AnonCrypto.verify(self.pub_keys, item) (r_id, r_round, r_go, r_hash) = marshal.loads(item_str) if r_round != self.round_id: raise RuntimeError, "Mismatched round numbers" if not r_go: raise RuntimeError, "Node %d reports failure!" % (r_id) if r_hash != hashval: raise RuntimeError, "Node %d produced bad hash!" % (r_id) return True
def shuffle_and_decrypt(self): random.shuffle(self.data_in) self.debug("Shuffling len = %d" % len(self.data_in)) self.data_out = [] for ctuple in self.data_in: (rem_round, ctext) = marshal.loads(ctuple) if rem_round != self.round_id: raise RuntimeError, "Mismatched round numbers (mine:%d, other:%d)" % ( self.round_id, rem_round) new_ctext = AnonCrypto.decrypt_with_rsa(self.key2, ctext) pickled = marshal.dumps((self.round_id, new_ctext)) self.data_out.append(pickled)
def run_phase5(self): self.advance_phase() mykeystr = AnonCrypto.sign( self.id, self.key1, marshal.dumps((self.id, self.round_id, AnonCrypto.priv_key_to_str(self.key2)))) if self.am_leader(): data = self.recv_from_all() """ Add leader's signed key to set """ data.append(mykeystr) self.debug("Key data... len = %d" % len(data)) self.broadcast_to_all_nodes(marshal.dumps(data)) else: self.info('Sending key to leader') self.send_to_leader(mykeystr) data = marshal.loads(self.recv_from_leader()) self.info("Got key set from leader, len = %d" % len(data)) self.decrypt_ciphers(data) self.info('Decrypted ciphertexts')
def start_node(self, down_index, up_index, participants_vector, my_id): n_nodes = len(participants_vector) leader_addr = (participants_vector[0][1], int(participants_vector[0][3])) my_addr = (participants_vector[my_id][1], int(participants_vector[my_id][3])) dn_addr = (participants_vector[down_index][1], int(participants_vector[down_index][3])) up_addr = (participants_vector[up_index][1], int(participants_vector[up_index][3])) round_id = 1 key_len = KEY_LENGTH """ if distrusted peer is participating, then don't share file (if one is chosen) """ self.DEBUG("Distrusted peers: %s" % self.distrusted_peers) msg_file = None trusted = True if os.path.exists(self.shared_filename): for peer in participants_vector: for distrusted_peer in self.distrusted_peers: (d_ip, d_port) = distrusted_peer (p_ip, p_port) = peer[1], peer[2] if d_ip == p_ip and str(d_port) == str(p_port): self.DEBUG("Not sharing my file because peer %s:%s is participating" % (p_ip, p_port)) trusted = False break if not trusted: break # create random file if none has been shared if trusted and os.path.exists(self.shared_filename): msg_file = self.shared_filename else: msg_file = AnonCrypto.random_file(DEFAULT_LENGTH) # initialize node self.node = bulk_node.bulk_node( my_id, key_len, round_id, n_nodes, my_addr, leader_addr, dn_addr, up_addr, msg_file, participants_vector, self.privgenkey1, self.privgenkey2, ) self.DEBUG( "round_id: %s id: %s n_nodes: %s my_addr: %s leader_addr: %s dn_addr: %s up_addr: %s msg_file: %s" % (round_id, my_id, n_nodes, my_addr, leader_addr, dn_addr, up_addr, msg_file) )
def run_phase5(self): self.advance_phase() mykeystr = AnonCrypto.sign(self.id, self.key1, marshal.dumps(( self.id, self.round_id, AnonCrypto.priv_key_to_str(self.key2)))) if self.am_leader(): data = self.recv_from_all() """ Add leader's signed key to set """ data.append(mykeystr) self.debug("Key data... len = %d" % len(data)) self.broadcast_to_all_nodes(marshal.dumps(data)) else: self.info('Sending key to leader') self.send_to_leader(mykeystr) data = marshal.loads(self.recv_from_leader()) self.info("Got key set from leader, len = %d" % len(data)) self.decrypt_ciphers(data) self.info('Decrypted ciphertexts')
def drop_out(self): self.DEBUG("Dropping out of the clique") # create dropout voucher (IP, PORT, PUBKEY) dropout_voucher = marshal.dumps((self.ip, self.gui_port, self.public_key_string())) # sign it cipher = AnonCrypto.sign_with_key(self.privKey, dropout_voucher) # give all peers signed voucher of your voluntary quitting self.broadcast_to_all_peers(marshal.dumps(("quit", cipher))) # empty peerlist and exit self.nodes = [] self.update_peerlist()
def initiate_round(self): self.DEBUG("I initiated a dissent round! Finding collaborators...") # get the path to the file you want to share self.emit(SIGNAL("getSharedFilename()")) nonce = int(1) self.participants = [] self.distrusted_peers = [] """ generate temporary keys for this round, add to participants """ self.gen_temp_keys() temp1_str = AnonCrypto.pub_key_to_str(self.pubgenkey1) temp2_str = AnonCrypto.pub_key_to_str(self.pubgenkey2) """ initiate round with a signed voucher containing relevant information """ my_voucher = marshal.dumps((nonce,self.ip,self.gui_port,self.com_port,temp1_str,temp2_str)) cipher = AnonCrypto.sign_with_key(self.privKey, my_voucher) """ make sure you have something to share first """ if os.path.exists(self.shared_filename): self.DEBUG("You are sharing file %s" % (self.shared_filename)) else: self.DEBUG("Not a valid file path, share something to start a round!") return # add yourself as leader in the participants list (entry 0) self.participants.append((cipher, self.ip, self.gui_port, self.com_port)) self.emit(SIGNAL("getDistrustedPeers()")) # ask if peers are interested interest_voucher = marshal.dumps((nonce, self.ip, self.gui_port, self.com_port)) cipher = AnonCrypto.sign_with_key(self.privKey, interest_voucher) self.broadcast_to_all_peers(marshal.dumps(("interested?",cipher))) # allow one minute to receive all replies, then initiate round with those peers DelayTimer(INTEREST_WAIT, self.prepare_round).start()
def initiate_round(self): self.DEBUG("I initiated a dissent round! Finding collaborators...") # get the path to the file you want to share self.emit(SIGNAL("getSharedFilename()")) nonce = int(1) self.participants = [] self.distrusted_peers = [] """ generate temporary keys for this round, add to participants """ self.gen_temp_keys() temp1_str = AnonCrypto.pub_key_to_str(self.pubgenkey1) temp2_str = AnonCrypto.pub_key_to_str(self.pubgenkey2) """ initiate round with a signed voucher containing relevant information """ my_voucher = marshal.dumps((nonce, self.ip, self.gui_port, self.com_port, temp1_str, temp2_str)) cipher = AnonCrypto.sign_with_key(self.privKey, my_voucher) """ make sure you have something to share first """ if os.path.exists(self.shared_filename): self.DEBUG("You are sharing file %s" % (self.shared_filename)) else: self.DEBUG("Not a valid file path, share something to start a round!") return # add yourself as leader in the participants list (entry 0) self.participants.append((cipher, self.ip, self.gui_port, self.com_port)) self.emit(SIGNAL("getDistrustedPeers()")) # ask if peers are interested interest_voucher = marshal.dumps((nonce, self.ip, self.gui_port, self.com_port)) cipher = AnonCrypto.sign_with_key(self.privKey, interest_voucher) self.broadcast_to_all_peers(marshal.dumps(("interested?", cipher))) # allow one minute to receive all replies, then initiate round with those peers DelayTimer(INTEREST_WAIT, self.prepare_round).start()
def run_phase5(self): self.advance_phase() self.info("Starting phase 5") #Create list of outputs and individual signature addresses=self.get_list_outputs() self.my_sign = AnonCrypto.sign(self.id, self.key1, marshal.dumps((self.id, addresses))) #Everybody sends her own signature to the leader. if self.am_leader(): all_sign = self.recv_from_all() self.debug("Received all signatures from participants") else: self.send_to_leader(marshal.dumps((self.round_id, self.my_sign))) self.debug("Sent signature to leader") #The leader broadcast the list of signatures and every participant checks if her signature # is included if self.am_leader(): self.broadcast_to_all_nodes(marshal.dumps(marshal.dumps((self.id, all_sign)))) self.debug("All signatures sent to participants") self.debug("Sign = TRUE") else: all_sign = marshal.loads(self.recv_from_socket(self.leader_socket)) self.debug("Received signature list") check_sig = marshal.dumps((self.round_id, self.my_sign)) if check_sig in all_sign: self.info("Found my signature in set") self.debug("Sign = TRUE") self.critical("Sign = TRUE") self.send_to_leader(marshal.dumps((self.id, "input address"))) else: self.critical("ABORT! My signature is not in set!") self.debug(self.final_ciphers) self.critical("Sign = FALSE") raise RuntimeError, "Protocol violation: My signature is missing!" #The leader waits for ack of every participant before creating the Bitcoin transaction if self.am_leader(): """ Leader waits for ciphers from member N. """ self.final_acks = self.recv_from_all() self.debug("Got acks from other nodes") self.critical("Leader: Bitcoin transaction finished")
def expel_peer(self, ip, port): self.DEBUG("IP/PORT to expel: %s:%s" % (ip, port)) # create voucher for peers to save expel_voucher = marshal.dumps((self.ip, self.gui_port, ip, port, self.peer_public_key_string(ip, port))) cipher = AnonCrypto.sign_with_key(self.privKey, expel_voucher) self.broadcast_to_all_peers(marshal.dumps(("expel", cipher))) # remove from peerlist index = self.nodes.index((ip, int(port), self.peer_public_key_string(ip, port))) self.nodes.pop(index) self.update_peerlist() self.DEBUG("Expelled!") # save the voucher you sent out self.save_voucher(self.ip, self.gui_port, cipher, "expelvoucher")
def expel_peer(self, ip, port): self.DEBUG("IP/PORT to expel: %s:%s" % (ip, port)) # create voucher for peers to save expel_voucher = marshal.dumps((self.ip, self.gui_port, ip, port, self.peer_public_key_string(ip,port))) cipher = AnonCrypto.sign_with_key(self.privKey, expel_voucher) self.broadcast_to_all_peers(marshal.dumps(("expel",cipher))) # remove from peerlist index = self.nodes.index((ip, int(port), self.peer_public_key_string(ip,port))) self.nodes.pop(index) self.update_peerlist() self.DEBUG("Expelled!") # save the voucher you sent out self.save_voucher(self.ip,self.gui_port,cipher,"expelvoucher")
def run_phase5(self): self.advance_phase() self.info("Starting phase 5") #Create list of outputs and individual signature addresses = self.get_list_outputs() self.my_sign = AnonCrypto.sign(self.id, self.key1, marshal.dumps((self.id, addresses))) #Everybody sends her own signature to the leader. if self.am_leader(): all_sign = self.recv_from_all() self.debug("Received all signatures from participants") else: self.send_to_leader(marshal.dumps((self.round_id, self.my_sign))) self.debug("Sent signature to leader") #The leader broadcast the list of signatures and every participant checks if her signature # is included if self.am_leader(): self.broadcast_to_all_nodes( marshal.dumps(marshal.dumps((self.id, all_sign)))) self.debug("All signatures sent to participants") self.debug("Sign = TRUE") else: all_sign = marshal.loads(self.recv_from_socket(self.leader_socket)) self.debug("Received signature list") check_sig = marshal.dumps((self.round_id, self.my_sign)) if check_sig in all_sign: self.info("Found my signature in set") self.debug("Sign = TRUE") self.critical("Sign = TRUE") self.send_to_leader(marshal.dumps((self.id, "input address"))) else: self.critical("ABORT! My signature is not in set!") self.debug(self.final_ciphers) self.critical("Sign = FALSE") raise RuntimeError, "Protocol violation: My signature is missing!" #The leader waits for ack of every participant before creating the Bitcoin transaction if self.am_leader(): """ Leader waits for ciphers from member N. """ self.final_acks = self.recv_from_all() self.debug("Got acks from other nodes") self.critical("Leader: Bitcoin transaction finished")
def invite_phase(self, ip, port, pubkey): # create nonce, # peers, vector containing (ip, port, pubkey) of all peers nonce = 1 num_peers = len(self.nodes) + 1 peer_vector = [(self.ip, self.gui_port, self.public_key_string())] for node in self.nodes: hashkey = self.hash_peer(node[0], node[1]) if hashkey != self.hashkey: peer_vector.append(node) # package the text up into (nonce, N, [array of peer data]) invite = marshal.dumps((nonce, num_peers, peer_vector)) # sign it cipher = AnonCrypto.sign_with_key(self.privKey, invite) # send to invitee packaged with who it's coming from ((ip:port), signed(text)) AnonNet.send_to_addr(ip, int(port), marshal.dumps(("invite", cipher)))