def __init__(self, ports, key=None, debug=False): """Initializes the sender object with a list of sockets containing one socket for each port in the ports list. Args: ports: A list of integer port number values for the sender. key: A base64 format string key to be used for MAC tag generation. Default value = None. debug: A boolean value indicating debug mode. Raises: TypeError: Error when key is not a string value, or when ports is not a list of integers. """ try: if type(ports) != list: raise TypeError("invalid ports: list expected") elif key != None and type(key) != str: raise TypeError("invalid key: str expected") self.host, self.ports = mysocket.gethostname(), ports self.sock = [] self.key = key self.debug = debug for port in ports: self.sock.append(mysocket()) self.sock[-1].bind((self.host, port)) print "Sender socket (%s, %d) initiated" % (self.host, port) except: if debug == True: raise else: secureFail() sys.exit()
def __init__(self, ports, key=None, debug=False): """Initializes the receiver object with a list of sockets containing one socket for each port in the ports list. Args: ports: A list of integer port number values for the receiver. key: A base64 format string key to be used for MAC tag generation. Default value = None. debug: A boolean value indicating debug mode. Raises: TypeError: Error when key is not a string value, or when ports is not a list of integers. """ try: if type(ports) != list: raise TypeError("invalid ports: list expected") elif key != None and type(key) != str: raise TypeError("invalid key: str expected") self.host, self.ports = mysocket.gethostname(), ports self.sock = [] self.key = key self.debug = debug for port in ports: self.sock.append(mysocket()) self.sock[-1].bind((self.host, port)) print "Receiver socket (%s, %d) initiated" % (self.host, port) except: if debug == True: raise else: secureFail() sys.exit()
def __init__(self, port, debug=False): """Initializes the node object with a socket object using the port number specified by the argument port. Args: port: An integer port number for the node. debug: A boolean value indicating debug mode. Raises: TypeError: Error when port is not an integer. """ try: if type(port) not in [int, long]: raise TypeError("invalid port: int or long expected") self.host, self.port = mysocket.gethostname(), port self.sock = mysocket() self.sock.bind((self.host, self.port)) self.share = None self.debug = debug print "Node (%s, %d) initiated" % (self.host, self.port) except: if debug == True: raise else: secureFail() sys.exit()
def sendShares(self, msg, n, k, prime, nodes, mode=NO_VERIFICATION): """Generates n shares for the msg such that any k shares can be used for reconstruction of the msg. According to the specified mode, the verification information is added to each share and they are sent to the given list of nodes. The value prime is used for as the order of modulo operations. Args: msg: A string message for which the shares are to be sent. n: An integer number representing the number of shares to be generated. k: An integer number representing the number of shares required for reconstruction. prime: An integer value to be used as the order of modulo operations. nodes: A list of (host, port) tuples for the intermediate nodes. mode: An integer value representing the verification mode as per options defined in the message.py module. Returns: A list of string value shares sent to the given nodes. Raises: TypeError: Error when msg is not a string, or when either n, k, prime or mode is not an integer, or when nodes is not a list. ValueError: Error when msg is longer than 159 characters, or when the mode is invalid. """ try: if type(msg) != str: raise TypeError("invalid msg: str expected") elif len(msg) > 159: raise ValueError("invalid msg: expected 159 characters or less") elif type(n) not in [int, long]: raise TypeError("invalid n: int or long expected") elif type(k) not in [int, long]: raise TypeError("invalid k: int or long expected") elif type(prime) not in [int, long]: raise TypeError("invalid prime: int or long expected") elif type(nodes) != list: raise TypeError("invalid nodes: list expected") elif type(mode) != type(NO_VERIFICATION): raise TypeError("invalid mode: int or long expected") elif mode not in [NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION]: modeRange = "%d, %d or %d" % (NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION) raise ValueError("invalid mode: " + modeRange + " expected") print "Secret message:", msg genStartTime = time() shares = secretSharing.generateShares(msg, n, k, prime) sharesToSend = [] if mode == NO_VERIFICATION: sharesToSend = self.getSharesNoVrfy(shares) elif mode == MAC_VERIFICATION: sharesToSend = self.getSharesWithMac(shares) elif mode == AUX_INFO_VERIFICATION: sharesToSend = self.getSharesWithAuxInfo(shares, prime) genEndTime = time() for i in range(0, len(nodes)): self.sendShareToNode(sharesToSend[i], nodes[i], i) msgSize = sys.getsizeof(msg) shareSize = sys.getsizeof(sharesToSend[0]) totalSharesSize = shareSize * n print "-" * 50 print "Secret Message:", msg print "Message Size: %d bytes" % msgSize print "Share Size: %d bytes" % shareSize print "Total Shares Size: %d bytes" % totalSharesSize print "-" * 50 return [sharesToSend, genEndTime - genStartTime] except: if self.debug == True: raise else: secureFail() sys.exit()
dictStr = fp.read() fp.close() senderDict = message.strToList(dictStr) ports = senderDict["ports"] msg = senderDict["msg"] n = senderDict["n"] k = senderDict["k"] prime = senderDict["prime"] key = senderDict["key"] mode = senderDict["mode"] nodePorts = senderDict["nodes"] addr = mysocket.gethostname() nodes = [(addr, portNum) for portNum in nodePorts] s = sender(ports, key, args.debug) shares, genTime = s.sendShares(msg, n, k, prime, nodes, mode) print "Time taken to generate shares:", genTime print "-" * 50 except SystemExit: pass except: if args.debug == True: raise else: secureFail() ##################### End of Code ###########################
def reconstructSecret(self, nodes, buffer, k, t, prime, mode=NO_VERIFICATION): """Reconstruct the secret message and calculate the set of faulty nodes based on the shares received from the nodes using the input buffer size specified by buffer argument. It uses the following steps: 1. Connect to each node in nodes and receive corresponding shares using the input buffer size specified by buffer. 2. Based on the mode argument, verify the validity of each share. 3. Use k valid shares to reconstruct the secret message. 4. Use the list of invalid shares to calculate the list of faulty nodes. Args: nodes: A list of tuples (host, port) where host is the host name and port is the port number of the corresponding node. buffer: An integer value specifying the input buffer size. k: An integer value representing the number of shares required for reconstructing the secret message. t: An integer value representing the maximum number of faulty nodes. prime: An integer value specifying the prime field for modulo operations. mode: An integer value representing the mode of verification as defined in the module message.py Returns: A list containing the secret message string and a list of port numbers of faulty nodes. Raises: TypeError: Error when any of k, t, prime, buffer or mode is not an integer, or when nodes is not a list. ValueError: Error when the mode is invalid. """ try: if type(nodes) != list: raise TypeError("invalid nodes: list expected") elif type(buffer) not in [int, long]: raise TypeError("invalid buffer: int or long expected") elif type(k) not in [int, long]: raise TypeError("invalid k: int or long expected") elif type(t) not in [int, long]: raise TypeError("invalid t: int or long expected") elif type(prime) not in [int, long]: raise TypeError("invalid prime: int or long expected") elif type(mode) not in [int, long]: raise TypeError("invalid mode: int or long expected") elif mode not in [ NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION ]: modeRange = "%d, %d or %d" % ( NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION) raise ValueError("invalid mode: " + modeRange + " expected") shares = self.getShares(nodes, buffer) reconStartTime = time() sharesForRecon = [] honestNodes = [] if mode == NO_VERIFICATION: sharesForRecon = self.getReconSharesNoVrfy(shares, k) elif mode == MAC_VERIFICATION: sList, macList = self.unpackSharesMacMode(shares) honestNodes = self.verifyMac(sList, macList) sharesForRecon = self.getReconSharesMacMode( sList, honestNodes, k) elif mode == AUX_INFO_VERIFICATION: sList, yList, bList, cList = self.unpackSharesAuxMode(shares) honestNodes = self.verifyAuxInfo(sList, yList, bList, cList, t, prime) sharesForRecon = self.getReconSharesAuxMode( sList, honestNodes, k) print "-" * 50 print "Reconstructing Secret from Shares", sharesForRecon secretNum = secretSharing.reconstructSecret( sharesForRecon, k, prime) try: secret = message.numToStr(secretNum) except TypeError: secret = None faultyNodes = self.getFaultyNodes(nodes, honestNodes) reconEndTime = time() return [secret, faultyNodes, reconEndTime - reconStartTime] except: if self.debug == True: raise else: secureFail() sys.exit()
prime = recvrDict['prime'] key = recvrDict['key'] mode = recvrDict['mode'] buf = recvrDict['buffer'] nodePorts = recvrDict['nodes'] addr = mysocket.gethostname() nodes = [(addr, portNum) for portNum in nodePorts] r = receiver(ports, key, args.debug) secret, faultyNodes, reconTime = r.reconstructSecret( nodes, buf, k, t, prime, mode) if len(faultyNodes) == 0: faultyNodes = None endTime = time() print "-" * 50 print "Reconstructed message:", secret print "Faulty nodes:", faultyNodes print "-" * 50 print "Time taken to reconstruct secret :", reconTime print "-" * 50 except SystemExit: pass except: if args.debug == True: raise else: secureFail() ##################### End of Code ###########################
def sendShares(self, msg, n, k, prime, nodes, mode=NO_VERIFICATION): """Generates n shares for the msg such that any k shares can be used for reconstruction of the msg. According to the specified mode, the verification information is added to each share and they are sent to the given list of nodes. The value prime is used for as the order of modulo operations. Args: msg: A string message for which the shares are to be sent. n: An integer number representing the number of shares to be generated. k: An integer number representing the number of shares required for reconstruction. prime: An integer value to be used as the order of modulo operations. nodes: A list of (host, port) tuples for the intermediate nodes. mode: An integer value representing the verification mode as per options defined in the message.py module. Returns: A list of string value shares sent to the given nodes. Raises: TypeError: Error when msg is not a string, or when either n, k, prime or mode is not an integer, or when nodes is not a list. ValueError: Error when msg is longer than 159 characters, or when the mode is invalid. """ try: if type(msg) != str: raise TypeError("invalid msg: str expected") elif len(msg) > 159: raise ValueError( "invalid msg: expected 159 characters or less") elif type(n) not in [int, long]: raise TypeError("invalid n: int or long expected") elif type(k) not in [int, long]: raise TypeError("invalid k: int or long expected") elif type(prime) not in [int, long]: raise TypeError("invalid prime: int or long expected") elif type(nodes) != list: raise TypeError("invalid nodes: list expected") elif type(mode) != type(NO_VERIFICATION): raise TypeError("invalid mode: int or long expected") elif mode not in [ NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION ]: modeRange = "%d, %d or %d" % ( NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION) raise ValueError("invalid mode: " + modeRange + " expected") print "Secret message:", msg genStartTime = time() shares = secretSharing.generateShares(msg, n, k, prime) sharesToSend = [] if mode == NO_VERIFICATION: sharesToSend = self.getSharesNoVrfy(shares) elif mode == MAC_VERIFICATION: sharesToSend = self.getSharesWithMac(shares) elif mode == AUX_INFO_VERIFICATION: sharesToSend = self.getSharesWithAuxInfo(shares, prime) genEndTime = time() for i in range(0, len(nodes)): self.sendShareToNode(sharesToSend[i], nodes[i], i) msgSize = sys.getsizeof(msg) shareSize = sys.getsizeof(sharesToSend[0]) totalSharesSize = shareSize * n print "-" * 50 print "Secret Message:", msg print "Message Size: %d bytes" % msgSize print "Share Size: %d bytes" % shareSize print "Total Shares Size: %d bytes" % totalSharesSize print "-" * 50 return [sharesToSend, genEndTime - genStartTime] except: if self.debug == True: raise else: secureFail() sys.exit()
def reconstructSecret(self, nodes, buffer, k, t, prime, mode=NO_VERIFICATION): """Reconstruct the secret message and calculate the set of faulty nodes based on the shares received from the nodes using the input buffer size specified by buffer argument. It uses the following steps: 1. Connect to each node in nodes and receive corresponding shares using the input buffer size specified by buffer. 2. Based on the mode argument, verify the validity of each share. 3. Use k valid shares to reconstruct the secret message. 4. Use the list of invalid shares to calculate the list of faulty nodes. Args: nodes: A list of tuples (host, port) where host is the host name and port is the port number of the corresponding node. buffer: An integer value specifying the input buffer size. k: An integer value representing the number of shares required for reconstructing the secret message. t: An integer value representing the maximum number of faulty nodes. prime: An integer value specifying the prime field for modulo operations. mode: An integer value representing the mode of verification as defined in the module message.py Returns: A list containing the secret message string and a list of port numbers of faulty nodes. Raises: TypeError: Error when any of k, t, prime, buffer or mode is not an integer, or when nodes is not a list. ValueError: Error when the mode is invalid. """ try: if type(nodes) != list: raise TypeError("invalid nodes: list expected") elif type(buffer) not in [int, long]: raise TypeError("invalid buffer: int or long expected") elif type(k) not in [int, long]: raise TypeError("invalid k: int or long expected") elif type(t) not in [int, long]: raise TypeError("invalid t: int or long expected") elif type(prime) not in [int, long]: raise TypeError("invalid prime: int or long expected") elif type(mode) not in [int, long]: raise TypeError("invalid mode: int or long expected") elif mode not in [NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION]: modeRange = "%d, %d or %d" % (NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION) raise ValueError("invalid mode: " + modeRange + " expected") shares = self.getShares(nodes, buffer) reconStartTime = time() sharesForRecon = [] honestNodes = [] if mode == NO_VERIFICATION: sharesForRecon = self.getReconSharesNoVrfy(shares, k) elif mode == MAC_VERIFICATION: sList, macList = self.unpackSharesMacMode(shares) honestNodes = self.verifyMac(sList, macList) sharesForRecon = self.getReconSharesMacMode(sList, honestNodes, k) elif mode == AUX_INFO_VERIFICATION: sList, yList, bList, cList = self.unpackSharesAuxMode(shares) honestNodes = self.verifyAuxInfo(sList, yList, bList, cList, t, prime) sharesForRecon = self.getReconSharesAuxMode(sList, honestNodes, k) print "-" * 50 print "Reconstructing Secret from Shares", sharesForRecon secretNum = secretSharing.reconstructSecret(sharesForRecon, k, prime) try: secret = message.numToStr(secretNum) except TypeError: secret = None faultyNodes = self.getFaultyNodes(nodes, honestNodes) reconEndTime = time() return [secret, faultyNodes, reconEndTime-reconStartTime] except: if self.debug == True: raise else: secureFail() sys.exit()
def run(self, senderPorts, receiverPorts, buf, mode=NO_VERIFICATION, honest=True): """Listens to incoming connections, accepts connections from sender and receiver nodes specified by lists of port numbers in senderPorts and receiverPorts respectively, receives the share from the sender, manipulates the share if it is a dishonest node (honest=False) and sends the share to the receiver node. If the receiver is connected before the node has received the share from the sender, then the node waits for the share to be received before initiating the sending of share to the receiver node. Args: senderPorts: A list of integer values representing port numbers used by the sender node. receiverPorts: A list of integer values representing port numbers used by the receiver node. buf: An integer value specifying the input buffer size. mode: An integer value representing the mode of verification as defined in the module message.py honest: A boolean value specifying whether the node is honest or faulty. Raises: TypeError: Error when either buf or mode is not an integer, or when either senderPorts or receiverPorts is not a list, or when honest is not a boolean. ValueError: Error when the mode is invalid. """ try: if type(senderPorts) != list: raise TypeError("invalid senderPorts: list expected") elif type(receiverPorts) != list: raise TypeError("invalid receiverPorts: list expected") elif type(buf) not in [int, long]: raise TypeError("invalid buf: int or long expected") elif type(mode) not in [int, long]: raise TypeError("invalid mode: int or long expected") elif type(honest) != bool: raise TypeError("invalid honest: bool expected") elif mode not in [NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION]: modeRange = "%d, %d or %d" % (NO_VERIFICATION, MAC_VERIFICATION, AUX_INFO_VERIFICATION) raise ValueError("invalid mode: " + modeRange + " expected") self.sock.listen(5) clients = [None, None] tasksDone = [False, False] while tasksDone.count(True) != 2: if clients.count(None) > 0: c, addr = self.sock.accept() port = addr[1] if port in senderPorts: clients[0] = c print "Sender (Port=%d) connected" % port elif port in receiverPorts: clients[1] = c print "Receiver (Port=%d) connected" % port else: print "Unknown node %s connected. Dropping connection!" % addr c.close() if clients[0] != None and tasksDone[0] != True: self.receiveShare(clients[0], buf) clients[0].close() print "Share received:", self.share, "\n" if honest == False: self.manipulateShare(mode) print "Share manipulated:", self.share, "\n" tasksDone[0] = True print "-" * 50 if clients[1] != None and tasksDone[0] == True and self.isShareReceived(): self.sendShare(clients[1]) clients[1].close() print "Sent:", self.share, "\n" tasksDone[1] = True self.sock.close() except: if self.debug == True: raise else: secureFail() sys.exit()