def Return_Fastest_Node(): x = Configuration() Node_Dictionary = Tools().Read_From_Json(directory=x.UserFolder + "/" + x.NodeFolder + "/" + x.NodeFile) Send_initial = 999.0 Receive_initial = 999.0 Fastest_Combination = {} for Node, Stats in Node_Dictionary.items(): try: Send = Stats["Send"] Receive = Stats["Receive"] float except TypeError: Send = 999.0 Receive = 999.0 if Send_initial > Send: Send_initial = Send Fastest_Combination["Send"] = Node if Receive_initial > Receive: Receive_initial = Receive Fastest_Combination["Receive"] = Node return Fastest_Combination
def Ping_Function(self): #Define directory and read the file Ping_Dir = str(self.UserFolder+"/"+self.PathFolder+"/"+self.Trajectory_Ping) Tools().Build_DB(File = Ping_Dir) Ping_Dictionary = Tools().Read_From_Json(directory = Ping_Dir) #Generate information about the client Current_Block = Dynamic_Public_Ledger().Calculate_Block().Block Client_Public_Address = self.PrivateIOTA.Generate_Address(Index = Current_Block) Client_Public_Key = self.PublicKey #Here we generate a random number used to identify the ping to a trajectory. Random = str(Key_Generation().Secret_Key).encode("hex")[:self.Default_Size-20] Data = self.Send_Message(Message = Random, ReceiverAddress = Client_Public_Address, PublicKey = Client_Public_Key, Ping_Function = True) #Here we record the messaage as plaintext as a label and the trajectory as a string. for i in Data: Fragment = i[0] Path_Taken = i[1] Path_Taken.reverse() Trajectory_As_String = str(Current_Block) for x in i[1]: if x[0] == '0'*81: Address = "X" elif x[0] == Client_Public_Address: Address = "LOCALCLIENT" else: Address = x[0] Trajectory_As_String = str(Trajectory_As_String + "-->" + Address) Ping_Dictionary = Tools().Add_To_Dictionary(Input_Dictionary = Ping_Dictionary, Entry_Label = Fragment, Entry_Value = Trajectory_As_String) Tools().Write_To_Json(directory = Ping_Dir, Dictionary = Ping_Dictionary) return self
def __init__(self): Configuration.__init__(self) Tools.__init__(self) #Core directory objects self.Contact_Folder_Dir = str(self.UserFolder + "/" + self.Contacts_Folder) self.Contacts_File_Dir = str(self.Contact_Folder_Dir + "/" + self.Contacts_File)
def Decompose(self): KeyList = Tools().ReadLine(directory=self.PEMFile) KeyString = Tools().List_To_String(List=KeyList) KeyEncoded = Tools().String_To_Base64(String=KeyString) Private_Seed = User_Profile().Private_Seed Combined = str(KeyEncoded + Configuration().Identifier + Private_Seed) KeyCipher = Encryption().SymmetricEncryption( PlainText=Combined, SecretKey=self.SuperSecretKey1) KeyCipher = Encryption().SymmetricEncryption( PlainText=KeyCipher, SecretKey=self.SuperSecretKey2) return KeyCipher
def __init__(self): Initialization.__init__(self) Continue = self.Build_Application() if Continue == True: self.Account() Keys = Key_Generation().PrivateKey_Import() Private_Seed_Encrypted = Tools().List_To_String(List = Tools().ReadLine(directory = str(self.UserFolder+"/"+self.SeedFolder+"/"+self.PrivateSeed))) self.PrivateKey = Keys.PrivateKey self.PublicKey = Keys.PublicKey self.Private_Seed = Decryption().AsymmetricDecryption(CipherText = Private_Seed_Encrypted, PrivateKey = self.PrivateKey) else: print("Permission Error")
def __init__(self): Initialization.__init__(self) Tools.__init__(self) Configuration.__init__(self) self.Received_Dir = str( self.InboxGenerator(Output_Directory=True).ReceivedMessages + "/" + Configuration().ReceivedMessages + ".txt") self.Relayed_Dir = str( self.InboxGenerator(Output_Directory=True).RelayedMessages + "/" + Configuration().RelayedMessage + ".txt") self.NotRelayed_Dir = str( self.InboxGenerator(Output_Directory=True).OutstandingRelay + "/" + Configuration().NotRelayedMessage + ".txt") self.Message_Inbox = self.UserFolder + "/" + self.MessageFolder + "/" + Configuration( ).ReceivedMessages + "/" + self.Inbox + ".txt"
def First_Usage(): if Tools().Check_File(File=str(Configuration().UserFolder + "/" + Configuration().KeysFolder + "/" + Configuration().PrivateKey)) == False: #First time this program was executed while True: Password = getpass.getpass(prompt="Enter a password: "******"Enter the passsword again: ") if Password == Password2: config.Password = Password break else: print("") print("Passwords do not match!") print("") try: HayStack().Build_All_Directories() except: print("No IRI instance running on device.") else: while True: #Turn this on later Password = getpass.getpass(prompt="Enter the HayStack password: "******"The password was incorrect. Please try again.")
def Collection(temp, Node_Dictionary, node, PoW, Action, Read_Write): Kill() temp[Action] = Speed_Tx(Node=node, PoW=PoW, Read_Write=Read_Write) Node_Dictionary[node] = temp Tools().JSON_Manipulation(File_Directory=x.Node, Dictionary=Node_Dictionary) return Node_Dictionary, temp
def TangleTime(self): Node_Data = self.IOTA_Api.get_node_info() self.Current_Time = Node_Data["time"] Output = Tools().Epoch_To_Block(Epoch_Time = float(self.Current_Time)) self.Block_Remainder = Output[1] self.CurrentBlock = Output[0] return self
def PrivateKey_Import(self): PrivateCipher = Tools().ReadLine(directory=str(self.UserFolder + "/" + self.KeysFolder + "/" + self.PrivateKey)) Keys = RSA.importKey(PrivateCipher, passphrase=self.Password) self.PublicKey = Keys.publickey().exportKey(format='PEM') self.PrivateKey = Keys return self
def Build_Directory(self): Tools().Build_Directory(directory=str(self.RootNode)) Tools().Build_DB(File=self.NodeFile_Dir) Node_List = [ "http://localhost:14265", "https://mama.iota.family:14267", "http://node05.iotatoken.nl:16265", "https://nodes.iota.cafe:443", "https://we-did-it.org:14265", "https://node.iri.host:443", "https://node.iota-tangle.io:14265", "https://node04.iotatoken.nl:443", "https://node02.iotatoken.nl:443", "https://pool.trytes.eu", "https://nutzdoch.einfachiota.de", "https://pow.iota.community:443", "https://papa.iota.family:14267", "https://piota-node.com:443", "https://v22018036012963637.bestsrv.de:14267", "https://trinity.iota-tangle.io:14265", "https://dyn.tangle-nodes.com:443", "https://perma.iota.partners:443", "https://gewirr.com:14267", "https://node01.iotatoken.nl:443", "https://node01.iotatoken.nl:443", "https://www.iotaqubic.us:443", "https://community.tanglebay.org", "https://node.deviceproof.org:443", "https://nodes.thetangle.org:443", "https://wallet1.iota.town:443", "https://wallet2.iota.town:443", "https://iota.chain.garden:443", "https://nodes.thetangle.org:443", "https://node.trustingiot.com:443", "https://power.benderiota.com:14267", "https://www.iotaqubic.us:443", "https://stirrlink.dyndns.org:14267", "https://iota1.chain.garden:443", "https://nod3.theshock.de:443", "https://wallet1.iota.town:443", "https://node00.gubiota.ch:443", "https://node01.gubiota.ch:443", "https://node02.gubiota.ch:443", "https://iotanow.nl:443" ] Node_Dictionary = {} for i in Node_List: Node_Dictionary = Tools().Add_To_Dictionary( Input_Dictionary=Node_Dictionary, Entry_Label=i, Entry_Value="") Tools().Write_To_Json(directory=self.NodeFile_Dir, Dictionary=Node_Dictionary) return self
def Restore_FileDirectory(self): Outcome = self.DownloadDB() HayStackPW = config.Password Found = False if isinstance(Outcome, list) == True: PEM_Directory = self.Conf.UserFolder + "/" + self.Conf.KeysFolder + "/" + self.Conf.PrivateKey Seed_Directory = self.Conf.UserFolder + "/" + self.Conf.SeedFolder + "/" + self.Conf.PrivateSeed for i in range(10): try: if Tools().Check_File(File=PEM_Directory) == False: Decoded_Private = Tools().Base64_To_String( Encoded=Outcome[0]) Tools().Write(directory=PEM_Directory, data=Decoded_Private) if Tools().Check_File(File=Seed_Directory) == False: try: Import = Key_Generation().PrivateKey_Import( Password=HayStackPW) Data = Encryption().AsymmetricEncryption( PlainText=Outcome[1], PublicKey=Import.PublicKey) Tools().Write(directory=Seed_Directory, data=Data) Found = True config.Password = HayStackPW except ValueError: print( "Please enter the password for your old HayStack account: \n" ) Password = getpass.getpass() HayStackPW = Password except IOError: Initialization().Build_Application() if Found != False: #Make sure that the block number is being set to 3 Tools().Build_Directory(directory=str(self.Conf.UserFolder + "/" + self.Conf.PathFolder)) Tools().Build_DB(File=str(self.Conf.UserFolder + "/" + self.Conf.PathFolder + "/" + self.Conf.Last_Block)) Block_Number = Tools().Add_To_Dictionary(Input_Dictionary={}, Entry_Label="Block", Entry_Value=3) Tools().Write_To_Json(directory=str(self.Conf.UserFolder + "/" + self.Conf.PathFolder + "/" + self.Conf.Last_Block), Dictionary=Block_Number) return Found
def Message_Decrypter(self, Cipher): #Break the message cipher into two parts: if Cipher[0] == Cipher[len(Cipher)-1] == "'": Pieces = Cipher[1:len(Cipher)-1].split(self.Identifier) else: Pieces = Cipher.split(self.Identifier) Runtime = True counter = 0 Next_Address = '0'*81 while Runtime == True: if len(Pieces) != 2: Decrypted = False else: #This will be the asymmetric part: Decrypted = self.AsymmetricDecryption(b64decode(Pieces[1]), Key_Generation().PrivateKey_Import().PrivateKey) if Decrypted != False: Next_Address = Decrypted[len(Decrypted)-81:] SymKey = Decrypted[:len(Decrypted)-81] #Now we try to decrypt the symmetric part To_Relay = b64decode(self.SymmetricDecryption(CipherText = Pieces[0], SecretKey = SymKey)) if self.MessageIdentifier in To_Relay: Contains_Message = To_Relay.split(self.MessageIdentifier) To_Relay = Contains_Message[0] Message_Fragment = Contains_Message[1:] if isinstance(Message_Fragment, list) == True: Message_As_String = str(self.MessageIdentifier + Tools().List_To_String(List = Message_Fragment) + self.MessageIdentifier) self.Addressed_To_Client(Message_As_String, SymKey) #Enforce that this has been decrypted properly if self.Identifier in To_Relay and Next_Address != '0'*81: counter = counter +1 for i in Dynamic_Public_Ledger().Check_User_In_Ledger(ScanAll = True).All_Accounts: if i[0] == Next_Address: NextAddress_PublicKey = i[1] #Terminate the while condition once a non dummy address was found. Runtime = False elif '0'*81 == Next_Address: counter = counter +1 Pieces = To_Relay.split(self.Identifier) if Runtime == False: #Replace the stripped layers by re-encrypting the (counter) layers. for i in range(counter+1): To_Relay = self.Layering_Encryption(PlainText = To_Relay, PublicKey = NextAddress_PublicKey, Address = '0'*81) return [To_Relay, Next_Address] if config.RunTime == False: break else: Runtime = False return [Cipher, Next_Address]
def __init__(self): Tools.__init__(self) Configuration.__init__(self) User_Profile.__init__(self) self.Ledger_Accounts_Dir = str(self.UserFolder + "/" + self.PathFolder + "/" + self.Ledger_Accounts_File) self.Last_Block_Dir = str(self.UserFolder + "/" + self.PathFolder + "/" + self.Last_Block) self.Ping_Dir = str(self.UserFolder + "/" + self.PathFolder + "/" + self.Trajectory_Ping) self.Incoming_Shrapnells = str(self.UserFolder + "/" + self.MessageFolder + "/" + Configuration().ReceivedMessages + "/" + Configuration().ReceivedMessages + ".txt") self.TrustedNodes_Dir = str(self.UserFolder + "/" + self.PathFolder + "/" + self.Trusted_Nodes) self.Current_Block = Dynamic_Public_Ledger().Calculate_Block().Block self.PrivateIOTA = IOTA_Module(Seed=self.Private_Seed)
def Test_Node(node): def Speed_Tx(Node, Read_Write, PoW=False): start = time.time() iota = IOTA(Seed=Configuration().PublicSeed, Node=node, PoW=PoW) if Read_Write == "w": Address = iota.Generate_Address(Index=0) Confirmation = iota.Send(Receiver_Address=Address, Message="Test") else: Confirmation = iota.Receive(Start=1, Stop=2) stop = time.time() if Confirmation == False: return "Error" else: return stop - start def Kill(): if config.RunTime == False: exit() def Collection(temp, Node_Dictionary, node, PoW, Action, Read_Write): Kill() temp[Action] = Speed_Tx(Node=node, PoW=PoW, Read_Write=Read_Write) Node_Dictionary[node] = temp Tools().JSON_Manipulation(File_Directory=x.Node, Dictionary=Node_Dictionary) return Node_Dictionary, temp x = UserProfile() Node_Dictionary = Tools().JSON_Manipulation(File_Directory=x.Node) temp = {} Output = Collection(temp=temp, Node_Dictionary=Node_Dictionary, node=node, PoW=False, Action="Send_No_PoW", Read_Write="w") Output = Collection(temp=Output[1], Node_Dictionary=Output[0], node=node, PoW=False, Action="Send_PoW", Read_Write="w") Output = Collection(temp=Output[1], Node_Dictionary=Output[0], node=node, PoW=False, Action="Read", Read_Write="r")
def Test_Nodes(self): try: Node_Dictionary = Tools().Read_From_Json( directory=self.NodeFile_Dir) except: self.Build_Directory() Node_Dictionary = Tools().Read_From_Json( directory=self.NodeFile_Dir) for Node, Value in Node_Dictionary.items(): if config.RunTime == False: break config.Node = Node IOTA = Iota(Node, self.PublicSeed) IOTA_Instance = IOTA_Module(Seed=self.PublicSeed, IOTA_Instance=IOTA) Burner_Address = IOTA_Instance.Generate_Address() Temp_Dictionary = {} try: start = time.time() Hash = IOTA_Instance.Send(ReceiverAddress=Burner_Address, Message="Test", Test_Node=True) end = time.time() delta_Send = end - start except: delta_Send = "Error" Temp_Dictionary["Send"] = delta_Send if config.RunTime == False: break try: start = time.time() Output = IOTA_Instance.Receive(Start=1, Test_Node=True) end = time.time() delta_Receive = end - start except: delta_Receive = "Error" Temp_Dictionary["Receive"] = delta_Receive Node_Dictionary[Node] = Temp_Dictionary Tools().Write_To_Json(directory=self.NodeFile_Dir, Dictionary=Node_Dictionary) if config.RunTime == False: break return self
def Return_Optimal_Node(): def Return_Rank(Ranked, Plain): Ranking = {} z = 1 for i in Ranked: for x in Plain: if i == x[0]: if len(x) == 3: temp = {} temp["Node"] = x[2] temp["PoW"] = x[1] Ranking[z] = temp else: temp = {} temp["Node"] = x[1] temp["PoW"] = False Ranking[z] = temp z = z + 1 return Ranking Node_Dictionary = Tools().JSON_Manipulation( File_Directory=UserProfile().Node) Node_Send = [] Node_Read = [] Temp_Send = [] Temp_Read = [] for node, measurements in Node_Dictionary.items(): try: PoW = measurements["Send_PoW"] except KeyError: Pow = "Error" try: No_PoW = measurements["Send_No_PoW"] except KeyError: No_PoW = "Error" try: Read = measurements["Read"] except KeyError: Read = "Error" #Checking Dead Nodes if PoW == "Error": PoW = 9999 if No_PoW == "Error": No_PoW = 9999 if Read == "Error": Read = 9999 # PoW vs Non PoW if PoW < No_PoW: Use_PoW = True Comparison = PoW elif PoW > No_PoW: Use_PoW = False Comparison = No_PoW else: Comparison = 9999 PoW = False if Comparison != 9999: Node_Send.append([Comparison, Use_PoW, node]) Temp_Send.append(Comparison) if Read != 9999: Node_Read.append([Read, node]) Temp_Read.append(Read) Temp_Send.sort() Temp_Read.sort() Ranked_Sending = Return_Rank(Temp_Send, Node_Send) Ranked_Receiving = Return_Rank(Temp_Read, Node_Read) return [Ranked_Sending, Ranked_Receiving]
def __init__(self): Configuration.__init__(self) Tools.__init__(self)
def First_Usage(): if Tools().Check_File(File=str(Configuration().UserFolder + "/" + Configuration().KeysFolder + "/" + Configuration().PrivateKey)) == False: print("Searching for working IOTA nodes.. please wait 30 seconds...") try: for i in range(30): sleep(1) #First time this program was executed print("Please enter a password for HayStack.") while True: Password = getpass.getpass(prompt="Enter a password: "******"Enter the passsword again: ") if Password == Password2 != "": config.Password = Password break else: print("") print("Passwords do not match!") print("") except KeyboardInterrupt: Node_Finder.Terminate() exit() try: while True: print("Would you like to restore from backup? (y/n)") Choice = raw_input(">>> ") if Choice == "y": print("Checking connectivity. Please wait.") for i in range(60): sleep(1) Dictionary = HayStack().Fastest_Node() try: x = Dictionary["Receive"] y = Dictionary["Send"] if x != "Error" and y != "Error": break except: pass Recovery = True print( "You have chosen to recover your keys. Please enter your two passwords in the correct order." ) print("Type in password 1") SuperSecretKey1 = raw_input(">>> ") print("Type in password 2") SuperSecretKey2 = raw_input(">>> ") print("Password 1: " + SuperSecretKey1 + " Password 2: " + SuperSecretKey2) answer = raw_input("Are these correct? (y/n/b) ") if answer == "y": break elif answer == "b": break elif answer == "n": pass elif Choice == "n": Recovery = False break else: print("Not a valid choice...") except KeyboardInterrupt: Node_Finder.Terminate() exit() if Recovery == True: outcome = Restore(SuperSecretKey1, SuperSecretKey2).Restore_FileDirectory() if outcome == False: print("Failed to restore keys.") HayStack().Build_All_Directories() else: print("Found your house keys!") else: for i in range(30): try: HayStack().Build_All_Directories() break except KeyboardInterrupt: Node_Finder.Terminate() exit() except: print( "Your connection is unstable. All nodes are now being tested." ) Dictionary = HayStack().Fastest_Node() x = Dictionary("Receive") y = Dictionary("Send") if x != "Error" and y != "Error": print("Nodes found!") else: while True: Password = getpass.getpass(prompt="Enter the HayStack password: "******"The password was incorrect. Please try again.")
def Check_Current_Ledger(self): def User_Submission(): IOTA_Send_Private = Verify_Node(Dictionary=self.Send_Node, Seed=Keys.PrivateSeed)[0] String_To_Sign = Encoding().To_Base64( IOTA_Send_Private.Generate_Address(Index=Current_Block) + c.Identifier + Encoding().To_Base64(Input=Keys.PublicKey)) Signature = Encryption().Sign_Message(ToSign=String_To_Sign, PrivateKey=Keys.PrivateKey, Password=config.Password) Ready_To_Submit = Encoding().To_Base64(String_To_Sign + c.Identifier + Signature) DPL_Address = IOTA_Receive[0].Generate_Address(Index=Current_Block) Verify = Force_Alternate_Node(Dictionary=self.Send_Node, Seed=Keys.PrivateSeed, Address=DPL_Address, Message=str(Ready_To_Submit, "utf-8")) return Verify c = Configuration() u = UserProfile() Keys = u.Get_Keys(Password=config.Password) IOTA_Receive = Verify_Node(Dictionary=self.Receive_Node, Seed=c.PublicSeed) Current_Block = IOTA_Receive[1].CurrentBlock Current_Time = IOTA_Receive[1].Current_Time print(IOTA_Receive[1].Block_Remainder) Entries = Force_Alternate_Node(Dictionary=self.Receive_Node, Seed=c.PublicSeed, Start_Block=Current_Block, End_Block=Current_Block + 1) if Entries == {}: return User_Submission() elif Entries != False: Current_Ledger = {} Ledger_Accounts = Tools().JSON_Manipulation( File_Directory=u.LedgerAccounts) for Bundle, Dic in Entries.items(): Temp = {} try: User_Entry = Dic["Message"] Submission_Block = Tools().Epoch_To_Block( Epoch_Time=Dic["Timestamp"])[0] Decoded = Encoding().From_Base64(Input=User_Entry).split( c.Identifier) Address_PublicKey = Encoding().From_Base64( Input=Decoded[0]).split(c.Identifier) User_Address = Address_PublicKey[0] User_PublicKey = Encoding().From_Base64( Address_PublicKey[1]) if Decryption().Signature_Verification( ToVerify=Decoded[0], PublicKey=User_PublicKey, Signature=Decoded[1] ) == True: # and Submission_Block >= Current_Block-c.Offset: Current_Ledger[str(Address_PublicKey[1], "utf-8")] = str( User_Address, "utf-8") Temp[User_Address.decode("utf-8")] = Current_Block try: Ledger_Accounts[Address_PublicKey[1].decode( "utf-8")].update(Temp) except KeyError: Ledger_Accounts[Address_PublicKey[1].decode( "utf-8")] = {} Ledger_Accounts[Address_PublicKey[1].decode( "utf-8")].update(Temp) except: print(sys.exc_info()[1]) Tools().JSON_Manipulation(File_Directory=u.CurrentLedger, Dictionary=Current_Ledger) Tools().JSON_Manipulation(File_Directory=u.LedgerAccounts, Dictionary=Ledger_Accounts) Client_Address = str( Verify_Node(Dictionary=self.Send_Node, Seed=Keys.PrivateSeed)[0].Generate_Address( Index=Current_Block), "utf-8") if Client_Address not in Current_Ledger.values(): return User_Submission() else: return False