A_      =      {0: [2, 3], 1: [0], 2: [1], 3: [4], 4: []}

A_      =      {0: [1, 2, 3], 1: [2], 2: [0], 3: [4], 4: [5], 5: [3]}






def        __UpperCAmelCase    (       UpperCAmelCase,		UpperCAmelCase,		UpperCAmelCase       )->       list[int]:



			"""simple docstring"""







			lowercase							=		True
			lowercase							=		[]

			for neighbour in graph[vert]:
						if not visited[neighbour]:
									order += topology_sort(UpperCAmelCase,		UpperCAmelCase,		UpperCAmelCase       )

			order.append(UpperCAmelCase       )

			return order






def        __UpperCAmelCase    (       UpperCAmelCase,		UpperCAmelCase,		UpperCAmelCase       )->       list[int]:



			"""simple docstring"""







			lowercase							=		True
			lowercase							=		[vert]

			for neighbour in reversed_graph[vert]:
						if not visited[neighbour]:
									component += find_components(UpperCAmelCase,		UpperCAmelCase,		UpperCAmelCase       )

			return component






def        __UpperCAmelCase    (       UpperCAmelCase       )->       list[list[int]]:



			"""simple docstring"""







			lowercase							=		len(UpperCAmelCase       ) * [False]
			lowercase							=		{vert: [] for vert in range(len(UpperCAmelCase       )       )}

			for vert, neighbours in graph.items():
						for neighbour in neighbours:
									reversed_graph[neighbour].append(UpperCAmelCase       )

			lowercase							=		[]
			for i, was_visited in enumerate(UpperCAmelCase       ):
						if not was_visited:
									order += topology_sort(UpperCAmelCase,		UpperCAmelCase,		UpperCAmelCase       )

			lowercase							=		[]
			lowercase							=		len(UpperCAmelCase       ) * [False]

			for i in range(len(UpperCAmelCase       )       ):
						lowercase							=		order[len(UpperCAmelCase       ) - i - 1]
						if not visited[vert]:
									lowercase							=		find_components(UpperCAmelCase,		UpperCAmelCase,		UpperCAmelCase       )
									components_list.append(UpperCAmelCase       )

			return components_list






import os
import random
import sys

from . import cryptomath_module as cryptomath
from . import rabin_miller

A_      =      3






def        __UpperCAmelCase    (       UpperCAmelCase       )->       int:



			"""simple docstring"""







			print('''Generating primitive root of p'''       )
			while True:
						lowercase							=		random.randrange(3,		UpperCAmelCase       )
						if pow(UpperCAmelCase,		2,		UpperCAmelCase       ) == 1:
									continue
						if pow(UpperCAmelCase,		UpperCAmelCase,		UpperCAmelCase       ) == 1:
									continue
						return g






def        __UpperCAmelCase    (       UpperCAmelCase       )->       tuple[tuple[int, int, int, int], tuple[int, int]]:



			"""simple docstring"""







			print('''Generating prime p...'''       )
			lowercase							=		rabin_miller.generate_large_prime(UpperCAmelCase       )  # select large prime number.
			lowercase							=		primitive_root(UpperCAmelCase       )  # one primitive root on modulo p.
			lowercase							=		random.randrange(3,		UpperCAmelCase       )  # private_key -> have to be greater than 2 for safety.
			lowercase							=		cryptomath.find_mod_inverse(pow(UpperCAmelCase,		UpperCAmelCase,		UpperCAmelCase       ),		UpperCAmelCase       )

			lowercase							=		(key_size, e_a, e_a, p)
			lowercase							=		(key_size, d)

			return public_key, private_key






def        __UpperCAmelCase    (       UpperCAmelCase,		UpperCAmelCase       )->       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 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        __UpperCAmelCase    (       )->       None:



			"""simple docstring"""







			print('''Making key files...'''       )
			make_key_files('''elgamal''',		2048       )
			print('''Key files generation successful'''       )


if __name__ == "__main__":
						main()





