

"""simple docstring"""





class  _lowerCAmelCase  :







 """simple docstring"""







 def __init__(      self							:      Optional[Any], UpperCAmelCase__							:      int, UpperCAmelCase__							:      Optional[Any]=None, UpperCAmelCase__							:      Optional[Any]=None     ):
    __lowercase								=						data
    __lowercase								=						previous
    __lowercase								=						next_node


 def __str__(      self							:      Tuple     ):
    return F"""{self.data}"""


 def  _lowercase			(      self							:      str     ):
    return self.data


 def  _lowercase			(      self							:      Any     ):
    return self.next



 def  _lowercase			(      self							:      List[str]     ):
    return self.previous







class  _lowerCAmelCase  :







 """simple docstring"""







 def __init__(      self							:      str, UpperCAmelCase__							:      Any     ):
    __lowercase								=						head


 def __iter__(      self							:      Union[str, Any]     ):
    return self



 def  _lowercase			(      self							:      Tuple     ):
    if not self.current:
       raise StopIteration
    else:
       __lowercase								=						self.current.get_data()
       __lowercase								=						self.current.get_next()
       return value







class  _lowerCAmelCase  :







 """simple docstring"""







 def __init__(      self							:      int     ):
    __lowercase								=						None  # First node in list
    __lowercase								=						None  # Last node in list


 def __str__(      self							:      int     ):
    __lowercase								=						self.head
    __lowercase								=						[]
    while current is not None:
       nodes.append(current.get_data()     )
       __lowercase								=						current.get_next()
    return " ".join(str(UpperCAmelCase__     ) for node in nodes     )


 def __contains__(      self							:      Optional[int], UpperCAmelCase__							:      int     ):
    __lowercase								=						self.head
    while current:
       if current.get_data() == value:
          return True
       __lowercase								=						current.get_next()
    return False


 def __iter__(      self							:      Any     ):
    return LinkedListIterator(self.head     )


 def  _lowercase			(      self							:      Tuple     ):
    if self.head:
       return self.head.get_data()
    return None


 def  _lowercase			(      self							:      Union[str, Any]     ):
    if self.tail:
       return self.tail.get_data()
    return None


 def  _lowercase			(      self							:      Optional[int], UpperCAmelCase__							:      Node     ):
    if self.head is None:
       __lowercase								=						node
       __lowercase								=						node
    else:
       self.insert_before_node(self.head, UpperCAmelCase__     )


 def  _lowercase			(      self							:      List[Any], UpperCAmelCase__							:      Node     ):
    if self.head is None:
       self.set_head(UpperCAmelCase__     )
    else:
       self.insert_after_node(self.tail, UpperCAmelCase__     )


 def  _lowercase			(      self							:      Optional[int], UpperCAmelCase__							:      int     ):
    __lowercase								=						Node(UpperCAmelCase__     )
    if self.head is None:
       self.set_head(UpperCAmelCase__     )
    else:
       self.set_tail(UpperCAmelCase__     )


 def  _lowercase			(      self							:      List[Any], UpperCAmelCase__							:      Node, UpperCAmelCase__							:      Node     ):
    __lowercase								=						node
    __lowercase								=						node.previous

    if node.get_previous() is None:
       __lowercase								=						node_to_insert
    else:
       __lowercase								=						node_to_insert

    __lowercase								=						node_to_insert


 def  _lowercase			(      self							:      Dict, UpperCAmelCase__							:      Node, UpperCAmelCase__							:      Node     ):
    __lowercase								=						node
    __lowercase								=						node.next

    if node.get_next() is None:
       __lowercase								=						node_to_insert
    else:
       __lowercase								=						node_to_insert

    __lowercase								=						node_to_insert


 def  _lowercase			(      self							:      Optional[Any], UpperCAmelCase__							:      int, UpperCAmelCase__							:      int     ):
    __lowercase								=						1
    __lowercase								=						Node(UpperCAmelCase__     )
    __lowercase								=						self.head
    while node:
       if current_position == position:
          self.insert_before_node(UpperCAmelCase__, UpperCAmelCase__     )
          return
       current_position += 1
       __lowercase								=						node.next
    self.insert_after_node(self.tail, UpperCAmelCase__     )


 def  _lowercase			(      self							:      Tuple, UpperCAmelCase__							:      int     ):
    __lowercase								=						self.head
    while node:
       if node.get_data() == item:
          return node
       __lowercase								=						node.get_next()
    raise Exception("Node not found"     )


 def  _lowercase			(      self							:      Tuple, UpperCAmelCase__							:      Optional[int]     ):
    if (node := self.get_node(UpperCAmelCase__     )) is not None:
       if node == self.head:
          __lowercase								=						self.head.get_next()

       if node == self.tail:
          __lowercase								=						self.tail.get_previous()

       self.remove_node_pointers(UpperCAmelCase__     )


 @staticmethod
 def  _lowercase			(      UpperCAmelCase__							:      Node     ):
    if node.get_next():
       __lowercase								=						node.previous

    if node.get_previous():
       __lowercase								=						node.next

    __lowercase								=						None
    __lowercase								=						None



 def  _lowercase			(      self							:      Optional[Any]     ):
    return self.head is None







def   _A  (  )     ->						None:
   '''simple docstring'''




if __name__ == "__main__":
   import doctest

   doctest.testmod()







"""simple docstring"""





import os
import random
import sys

from . import cryptomath_module as cryptoMath  # noqa: N812
from . import rabin_miller as rabinMiller  # noqa: N812




def   _A  (  )     ->						None:
   '''simple docstring'''


   print("Making key files...")
   make_key_files("rsa",      1024)
   print("Key files generation successful.")




def   _A  (  UpperCamelCase_					:	int)     ->						tuple[tuple[int, int], tuple[int, int]]:
   '''simple docstring'''


   print("Generating prime p...")
   __lowercase								=						rabinMiller.generate_large_prime(UpperCamelCase_)
   print("Generating prime q...")
   __lowercase								=						rabinMiller.generate_large_prime(UpperCamelCase_)
   __lowercase								=						p * q

   print("Generating e that is relatively prime to (p - 1) * (q - 1)...")
   while True:
      __lowercase								=						random.randrange(2 ** (key_size - 1),      2 ** (key_size))
      if cryptoMath.gcd(UpperCamelCase_,      (p - 1) * (q - 1)) == 1:
         break

   print("Calculating d that is mod inverse of e...")
   __lowercase								=						cryptoMath.find_mod_inverse(UpperCamelCase_,      (p - 1) * (q - 1))

   __lowercase								=						(n, e)
   __lowercase								=						(n, d)
   return (public_key, private_key)




def   _A  (  UpperCamelCase_					:	str,      UpperCamelCase_					:	int)     ->						None:
   '''simple docstring'''


   if os.path.exists(F"""{name}_pubkey.txt""") or os.path.exists(F"""{name}_privkey.txt"""):
      print("\nWARNING:")
      print(
          F"""\"{name}_pubkey.txt\" or \"{name}_privkey.txt\" already exists. \n"""
          "Use a different name or delete these files and re-run this program.")
      sys.exit()

   __lowercase		,__lowercase								=						generate_key(UpperCamelCase_)
   print(F"""\nWriting public key to file {name}_pubkey.txt...""")
   with open(F"""{name}_pubkey.txt""",      "w") as out_file:
      out_file.write(F"""{key_size},{public_key[0]},{public_key[1]}""")

   print(F"""Writing private key to file {name}_privkey.txt...""")
   with open(F"""{name}_privkey.txt""",      "w") as out_file:
      out_file.write(F"""{key_size},{private_key[0]},{private_key[1]}""")


if __name__ == "__main__":
   main()




