
from __future__ import annotations

from fractions import Fraction
from math import gcd, sqrt



def 		UpperCamelCase     (       _UpperCAmelCase  :   int  )   ->			bool:






						'''simple docstring'''

						_lowercase       :	int           =   int(number**0.5  )
						return number == sq * sq



def 		UpperCamelCase     (       _UpperCAmelCase  :   int ,			_UpperCAmelCase  :   int ,			_UpperCAmelCase  :   int ,			_UpperCAmelCase  :   int ,			_UpperCAmelCase  :   int ,			_UpperCAmelCase  :   int  )   ->			tuple[int, int]:






						'''simple docstring'''

						_lowercase       :	int           =   x_num * y_den * z_den + y_num * x_den * z_den + z_num * x_den * y_den
						_lowercase       :	int           =   x_den * y_den * z_den
						_lowercase       :	int           =   gcd(_UpperCAmelCase ,			_UpperCAmelCase  )
						top //= hcf
						bottom //= hcf
						return top, bottom



def 		UpperCamelCase     (       _UpperCAmelCase  :   int = 35  )   ->			int:






						'''simple docstring'''

						_lowercase       :	set           =   set()
						_lowercase       :	int
						_lowercase       :	Fraction           =   Fraction(0  )
						_lowercase       :	tuple[int, int]

						for x_num in range(1 ,			order + 1  ):
												for x_den in range(x_num + 1 ,			order + 1  ):
																		for y_num in range(1 ,			order + 1  ):
																								for y_den in range(y_num + 1 ,			order + 1  ):
																														# n=1
																														_lowercase       :	Dict           =   x_num * y_den + x_den * y_num
																														_lowercase       :	Union[str, Any]           =   x_den * y_den
																														_lowercase       :	List[str]           =   gcd(_UpperCAmelCase ,			_UpperCAmelCase  )
																														z_num //= hcf
																														z_den //= hcf
																														if 0 < z_num < z_den <= order:
																																				_lowercase       :	Any           =   add_three(
																																				    _UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase  )
																																				unique_s.add(_UpperCAmelCase  )

																														# n=2
																														_lowercase       :	Optional[int]           =   (
																														    x_num * x_num * y_den * y_den + x_den * x_den * y_num * y_num
																														)
																														_lowercase       :	Dict           =   x_den * x_den * y_den * y_den
																														if is_sq(_UpperCAmelCase  ) and is_sq(_UpperCAmelCase  ):
																																				_lowercase       :	Union[str, Any]           =   int(sqrt(_UpperCAmelCase  )  )
																																				_lowercase       :	Optional[Any]           =   int(sqrt(_UpperCAmelCase  )  )
																																				_lowercase       :	List[str]           =   gcd(_UpperCAmelCase ,			_UpperCAmelCase  )
																																				z_num //= hcf
																																				z_den //= hcf
																																				if 0 < z_num < z_den <= order:
																																										_lowercase       :	List[str]           =   add_three(
																																										    _UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase  )
																																										unique_s.add(_UpperCAmelCase  )

                    # n=-1
																														_lowercase       :	Union[str, Any]           =   x_num * y_num
																														_lowercase       :	List[str]           =   x_den * y_num + x_num * y_den
																														_lowercase       :	str           =   gcd(_UpperCAmelCase ,			_UpperCAmelCase  )
																														z_num //= hcf
																														z_den //= hcf
																														if 0 < z_num < z_den <= order:
																																				_lowercase       :	Dict           =   add_three(
																																				    _UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase  )
																																				unique_s.add(_UpperCAmelCase  )

																														# n=2
																														_lowercase       :	int           =   x_num * x_num * y_num * y_num
																														_lowercase       :	Optional[int]           =   (
																														    x_den * x_den * y_num * y_num + x_num * x_num * y_den * y_den
																														)
																														if is_sq(_UpperCAmelCase  ) and is_sq(_UpperCAmelCase  ):
																																				_lowercase       :	List[Any]           =   int(sqrt(_UpperCAmelCase  )  )
																																				_lowercase       :	Tuple           =   int(sqrt(_UpperCAmelCase  )  )
																																				_lowercase       :	List[Any]           =   gcd(_UpperCAmelCase ,			_UpperCAmelCase  )
																																				z_num //= hcf
																																				z_den //= hcf
																																				if 0 < z_num < z_den <= order:
																																										_lowercase       :	Optional[int]           =   add_three(
																																										    _UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase  )
																																										unique_s.add(_UpperCAmelCase  )

						for num, den in unique_s:
												total += Fraction(_UpperCAmelCase ,			_UpperCAmelCase  )

						return total.denominator + total.numerator


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






import os
import random
import sys

from . import cryptomath_module as cryptomath
from . import rabin_miller

UpperCamelCase_						:     List[Any]	       =							3



def 		UpperCamelCase     (       _UpperCAmelCase  :   int  )   ->			int:






						'''simple docstring'''

						print("Generating primitive root of p"  )
						while True:
												_lowercase       :	Any           =   random.randrange(3 ,			_UpperCAmelCase  )
												if pow(_UpperCAmelCase ,			2 ,			_UpperCAmelCase  ) == 1:
																		continue
												if pow(_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase  ) == 1:
																		continue
												return g



def 		UpperCamelCase     (       _UpperCAmelCase  :   int  )   ->			tuple[tuple[int, int, int, int], tuple[int, int]]:






						'''simple docstring'''

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

						_lowercase       :	List[Any]           =   (key_size, e_a, e_a, p)
						_lowercase       :	Union[str, Any]           =   (key_size, d)

						return public_key, private_key



def 		UpperCamelCase     (       _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       :	Optional[Any]           =   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()




