



import os
import random
import sys

from . import cryptomath_module as cryptomath
from . import rabin_miller

lowerCAmelCase__					  =  3


def  __lowerCamelCase (       lowerCamelCase__						):

				"""simple docstring"""


				print("Generating primitive root of p"						)
				while True:
								lowercase__					:   List[str]													=					random.randrange(3					,			lowerCamelCase__						)
								if pow(lowerCamelCase__					,			2					,			lowerCamelCase__						) == 1:
												continue
								if pow(lowerCamelCase__					,			lowerCamelCase__					,			lowerCamelCase__						) == 1:
												continue
								return g


def  __lowerCamelCase (       lowerCamelCase__						):

				"""simple docstring"""


				print("Generating prime p..."						)
				lowercase__					:   List[Any]													=					rabin_miller.generate_large_prime(lowerCamelCase__						)  # select large prime number.
				lowercase__					:   str													=					primitive_root(lowerCamelCase__						)  # one primitive root on modulo p.
				lowercase__					:   List[str]													=					random.randrange(3					,			lowerCamelCase__						)  # private_key -> have to be greater than 2 for safety.
				lowercase__					:   Dict													=					cryptomath.find_mod_inverse(pow(lowerCamelCase__					,			lowerCamelCase__					,			lowerCamelCase__						)					,			lowerCamelCase__						)

				lowercase__					:   List[Any]													=					(key_size, e_a, e_a, p)
				lowercase__					:   List[Any]													=					(key_size, d)

				return public_key, private_key


def  __lowerCamelCase (       lowerCamelCase__					,			lowerCamelCase__						):

				"""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__					:   Optional[int]													=					generate_key(lowerCamelCase__						)
				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  __lowerCamelCase (       ):

				"""simple docstring"""


				print("Making key files..."						)
				make_key_files("elgamal"					,			2_048						)
				print("Key files generation successful"						)


if __name__ == "__main__":
				main()









from collections import Counter
from timeit import timeit


def  __lowerCamelCase (       lowerCamelCase__ = ""					,			):

				"""simple docstring"""


				return sum(c % 2 for c in Counter(input_str.replace(" "					,			""						).lower()						).values()						) < 2


def  __lowerCamelCase (       lowerCamelCase__ = ""						):

				"""simple docstring"""


				if len(lowerCamelCase__						) == 0:
								return True
				lowercase__					:   str													=					input_str.replace(" "					,			""						).lower()
				# character_freq_dict: Stores the frequency of every character in the input string
				lowercase__					:   dict[str, int]													=					{}

				for character in lower_case_input_str:
								lowercase__					:   List[Any]													=					character_freq_dict.get(lowerCamelCase__					,			0						) + 1
				lowercase__					:   List[Any]													=					0

				for character_count in character_freq_dict.values():
								if character_count % 2:
												odd_char += 1
				if odd_char > 1:
								return False
				return True


def  __lowerCamelCase (       lowerCamelCase__ = ""						):

				"""simple docstring"""


				print("\nFor string = "					,			lowerCamelCase__					,			":"						)
				print(
				    "> can_string_be_rearranged_as_palindrome_counter()"					,			"\tans ="					,			can_string_be_rearranged_as_palindrome_counter(lowerCamelCase__						)					,			"\ttime ="					,			timeit(
				        "z.can_string_be_rearranged_as_palindrome_counter(z.check_str)"					,			setup="import __main__ as z"					,			)					,			"seconds"					,			)
				print(
				    "> can_string_be_rearranged_as_palindrome()"					,			"\tans ="					,			can_string_be_rearranged_as_palindrome(lowerCamelCase__						)					,			"\ttime ="					,			timeit(
				        "z.can_string_be_rearranged_as_palindrome(z.check_str)"					,			setup="import __main__ as z"					,			)					,			"seconds"					,			)


if __name__ == "__main__":
				lowerCAmelCase__					  =  input(
				    '''Enter string to determine if it can be rearranged as a palindrome or not: '''
				).strip()
				benchmark(check_str)
				lowerCAmelCase__					  =  can_string_be_rearranged_as_palindrome_counter(check_str)
				print(f'''{check_str} can {"" if status else "not "}be rearranged as a palindrome''')




