




import os
import random
import sys

from . import cryptomath_module as cryptomath
from . import rabin_miller

lowerCamelCase       :       Dict        =    3




def 						SCREAMING_SNAKE_CASE__					(    lowercase     )  ->   int:
   print("""Generating primitive root of p"""     )
   while True:
      snake_case      :				Any				=       random.randrange(3						,__SCREAMING_SNAKE_CASE     )
      if pow(__SCREAMING_SNAKE_CASE						,2						,__SCREAMING_SNAKE_CASE     ) == 1:
         continue
      if pow(__SCREAMING_SNAKE_CASE						,__SCREAMING_SNAKE_CASE						,__SCREAMING_SNAKE_CASE     ) == 1:
         continue
      return g




def 						SCREAMING_SNAKE_CASE__					(    lowercase     )  ->   tuple[tuple[int, int, int, int], tuple[int, int]]:
   print("""Generating prime p..."""     )
   snake_case      :				str				=       rabin_miller.generate_large_prime(__SCREAMING_SNAKE_CASE     )  # select large prime number.
   snake_case      :				Union[str, Any]				=       primitive_root(__SCREAMING_SNAKE_CASE     )  # one primitive root on modulo p.
   snake_case      :				Union[str, Any]				=       random.randrange(3						,__SCREAMING_SNAKE_CASE     )  # private_key -> have to be greater than 2 for safety.
   snake_case      :				Tuple				=       cryptomath.find_mod_inverse(pow(__SCREAMING_SNAKE_CASE						,__SCREAMING_SNAKE_CASE						,__SCREAMING_SNAKE_CASE     )						,__SCREAMING_SNAKE_CASE     )

   snake_case      :				Any				=       (key_size, e_a, e_a, p)
   snake_case      :				str				=       (key_size, d)

   return public_key, private_key




def 						SCREAMING_SNAKE_CASE__					(    lowercase						,lowercase     )  ->   None:
   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()

   snake_case      :				Union[str, Any]				=       generate_key(__SCREAMING_SNAKE_CASE     )
   print(f"""\nWriting public key to file {name}_pubkey.txt..."""     )
   with open(f"""{name}_pubkey.txt"""						,"""w"""     ) as fo:
      fo.write(f"""{public_key[0]},{public_key[1]},{public_key[2]},{public_key[3]}"""     )

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




def 						SCREAMING_SNAKE_CASE__					(    )  ->   None:
   print("""Making key files..."""     )
   make_key_files("""elgamal"""						,2048     )
   print("""Key files generation successful"""     )


if __name__ == "__main__":
       main()








"""simple docstring"""


from __future__ import annotations






def     a__    (    __SCREAMING_SNAKE_CASE )	->	bool:
		__lowerCAmelCase:       Tuple          =			str(__SCREAMING_SNAKE_CASE )
		return len(__SCREAMING_SNAKE_CASE ) == 9 and set(__SCREAMING_SNAKE_CASE ) == set("123456789" )






def     a__    (    )	->	int | None:
		for base_num in range(9_9_9_9					, 4_9_9_9					, -1 ):
				__lowerCAmelCase:       Tuple          =			1_0_0_0_0_2 * base_num
				if is_9_pandigital(__SCREAMING_SNAKE_CASE ):
						return candidate

		for base_num in range(3_3_3					, 9_9					, -1 ):
				__lowerCAmelCase:       int          =			1_0_0_2_0_0_3 * base_num
				if is_9_pandigital(__SCREAMING_SNAKE_CASE ):
						return candidate

		return None


if __name__ == "__main__":
			print(F'''{solution() = }''')


