"""simple docstring"""





import os
import random
import sys

from . import cryptomath_module as cryptomath
from . import rabin_miller

lowerCAmelCase_     =	3



def      lowerCamelCase_(__SCREAMING_SNAKE_CASE  )->    int:
							print("""Generating primitive root of p"""  )
							while True:
														_SCREAMING_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      lowerCamelCase_(__SCREAMING_SNAKE_CASE  )->    tuple[tuple[int, int, int, int], tuple[int, int]]:
							print("""Generating prime p..."""  )
							_SCREAMING_SNAKE_CASE		:						Union[str, Any]			  =    rabin_miller.generate_large_prime(__SCREAMING_SNAKE_CASE  )  # select large prime number.
							_SCREAMING_SNAKE_CASE		:						int			  =    primitive_root(__SCREAMING_SNAKE_CASE  )  # one primitive root on modulo p.
							_SCREAMING_SNAKE_CASE		:						Any			  =    random.randrange(3     ,	__SCREAMING_SNAKE_CASE  )  # private_key -> have to be greater than 2 for safety.
							_SCREAMING_SNAKE_CASE		:						List[str]			  =    cryptomath.find_mod_inverse(pow(__SCREAMING_SNAKE_CASE     ,	__SCREAMING_SNAKE_CASE     ,	__SCREAMING_SNAKE_CASE  )     ,	__SCREAMING_SNAKE_CASE  )

							_SCREAMING_SNAKE_CASE		:						Optional[int]			  =    (key_size, e_a, e_a, p)
							_SCREAMING_SNAKE_CASE		:						Dict			  =    (key_size, d)

							return public_key, private_key



def      lowerCamelCase_(__SCREAMING_SNAKE_CASE     ,	__SCREAMING_SNAKE_CASE  )->    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()

							_SCREAMING_SNAKE_CASE  ,				_SCREAMING_SNAKE_CASE		:						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      lowerCamelCase_()->    None:
							print("""Making key files..."""  )
							make_key_files("""elgamal"""     ,	2_048  )
							print("""Key files generation successful"""  )


if __name__ == "__main__":
			main()



"""simple docstring"""





from __future__ import annotations



def      lowerCamelCase_(__SCREAMING_SNAKE_CASE     ,	__SCREAMING_SNAKE_CASE     ,	__SCREAMING_SNAKE_CASE     ,	)->    tuple:
							if (electron_conc, hole_conc, intrinsic_conc).count(0  ) != 1:
														raise ValueError("""You cannot supply more or less than 2 values"""  )
							elif electron_conc < 0:
														raise ValueError("""Electron concentration cannot be negative in a semiconductor"""  )
							elif hole_conc < 0:
														raise ValueError("""Hole concentration cannot be negative in a semiconductor"""  )
							elif intrinsic_conc < 0:
														raise ValueError(
														    """Intrinsic concentration cannot be negative in a semiconductor"""  )
							elif electron_conc == 0:
														return (
														    "electron_conc",
														    intrinsic_conc**2 / hole_conc,
														)
							elif hole_conc == 0:
														return (
														    "hole_conc",
														    intrinsic_conc**2 / electron_conc,
														)
							elif intrinsic_conc == 0:
														return (
														    "intrinsic_conc",
														    (electron_conc * hole_conc) ** 0.5,
														)
							else:
														return (-1, -1)


if __name__ == "__main__":
			import doctest

			doctest.testmod()


