




# This model implementation is heavily based on:

import gc
import random
import tempfile
import unittest

import numpy as np
import torch
from PIL import Image
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer

from diffusers import (
    AutoencoderKL,
    ControlNetModel,
    DDIMScheduler,
    StableDiffusionControlNetInpaintPipeline,
    UNetaDConditionModel,
)
from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion_controlnet import MultiControlNetModel
from diffusers.utils import floats_tensor, load_image, load_numpy, randn_tensor, slow, torch_device
from diffusers.utils.import_utils import is_xformers_available
from diffusers.utils.testing_utils import enable_full_determinism, require_torch_gpu

from ..pipeline_params import (
    TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS,
    TEXT_GUIDED_IMAGE_INPAINTING_PARAMS,
    TEXT_TO_IMAGE_IMAGE_PARAMS,
)
from ..test_pipelines_common import (
    PipelineKarrasSchedulerTesterMixin,
    PipelineLatentTesterMixin,
    PipelineTesterMixin,
)


enable_full_determinism()


class 				__UpperCamelCase      (			__UpperCAmelCase  ,       __UpperCAmelCase  ,       __UpperCAmelCase  ,       unittest.TestCase	):





				'''simple docstring'''



				__a				:			Dict					    =StableDiffusionControlNetInpaintPipeline
				__a				:			List[str]					    =TEXT_GUIDED_IMAGE_INPAINTING_PARAMS
				__a				:			Any					    =TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS
				__a				:			Optional[Any]					    =frozenset({"""control_image"""}	)  # skip `image` and `mask` for now, only test for control_image
				__a				:			Dict					    =TEXT_TO_IMAGE_IMAGE_PARAMS



				def    __snake_case		(			self    ):
											torch.manual_seed(0    )
											lowerCAmelCase =		UNetaDConditionModel(
											    block_out_channels=(32, 64)							,			layers_per_block=2							,			sample_size=32							,			in_channels=9							,			out_channels=4							,			down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')							,			up_block_types=('''CrossAttnUpBlock2D''', '''UpBlock2D''')							,			cross_attention_dim=32							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		ControlNetModel(
											    block_out_channels=(32, 64)							,			layers_per_block=2							,			in_channels=4							,			down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')							,			cross_attention_dim=32							,			conditioning_embedding_out_channels=(16, 32)							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		DDIMScheduler(
											    beta_start=0.00085							,			beta_end=0.012							,			beta_schedule='''scaled_linear'''							,			clip_sample=UpperCAmelCase_							,			set_alpha_to_one=UpperCAmelCase_							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		AutoencoderKL(
											    block_out_channels=[32, 64]							,			in_channels=3							,			out_channels=3							,			down_block_types=['''DownEncoderBlock2D''', '''DownEncoderBlock2D''']							,			up_block_types=['''UpDecoderBlock2D''', '''UpDecoderBlock2D''']							,			latent_channels=4							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		CLIPTextConfig(
											    bos_token_id=0							,			eos_token_id=2							,			hidden_size=32							,			intermediate_size=37							,			layer_norm_eps=1E-0_5							,			num_attention_heads=4							,			num_hidden_layers=5							,			pad_token_id=1							,			vocab_size=10_00							,			)
											lowerCAmelCase =		CLIPTextModel(UpperCAmelCase_    )
											lowerCAmelCase =		CLIPTokenizer.from_pretrained('''hf-internal-testing/tiny-random-clip'''    )

											lowerCAmelCase =		{
											    '''unet''': unet,
											    '''controlnet''': controlnet,
											    '''scheduler''': scheduler,
											    '''vae''': vae,
											    '''text_encoder''': text_encoder,
											    '''tokenizer''': tokenizer,
											    '''safety_checker''': None,
											    '''feature_extractor''': None,
											}
											return components



				def    __snake_case		(			self							,			UpperCAmelCase_							,			UpperCAmelCase_=0    ):
											if str(UpperCAmelCase_    ).startswith('''mps'''    ):
																		lowerCAmelCase =		torch.manual_seed(UpperCAmelCase_    )
											else:
																		lowerCAmelCase =		torch.Generator(device=UpperCAmelCase_    ).manual_seed(UpperCAmelCase_    )

											lowerCAmelCase =		2
											lowerCAmelCase =		randn_tensor(
											    (1, 3, 32 * controlnet_embedder_scale_factor, 32 * controlnet_embedder_scale_factor)							,			generator=UpperCAmelCase_							,			device=torch.device(UpperCAmelCase_    )							,			)
											lowerCAmelCase =		floats_tensor((1, 3, 32, 32)							,			rng=random.Random(UpperCAmelCase_    )    ).to(UpperCAmelCase_    )
											lowerCAmelCase =		init_image.cpu().permute(0							,			2							,			3							,			1    )[0]

											lowerCAmelCase =		Image.fromarray(np.uinta(UpperCAmelCase_    )    ).convert('''RGB'''    ).resize((64, 64)    )
											lowerCAmelCase =		Image.fromarray(np.uinta(init_image + 4    )    ).convert('''RGB'''    ).resize((64, 64)    )

											lowerCAmelCase =		{
											    '''prompt''': '''A painting of a squirrel eating a burger''',
											    '''generator''': generator,
											    '''num_inference_steps''': 2,
											    '''guidance_scale''': 6.0,
											    '''output_type''': '''numpy''',
											    '''image''': image,
											    '''mask_image''': mask_image,
											    '''control_image''': control_image,
											}

											return inputs



				def    __snake_case		(			self    ):
											return self._test_attention_slicing_forward_pass(expected_max_diff=2E-3    )



				@unittest.skipIf(
				    torch_device != '''cuda''' or not is_xformers_available()							,			reason='''XFormers attention is only available with CUDA and `xformers` installed'''							,			)
				def    __snake_case		(			self    ):
											self._test_xformers_attention_forwardGenerator_pass(expected_max_diff=2E-3    )






				def    __snake_case		(			self    ):
											self._test_inference_batch_single_identical(expected_max_diff=2E-3    )




class 				__UpperCamelCase      (			__UpperCAmelCase	):





				'''simple docstring'''



				__a				:			List[str]					    =StableDiffusionControlNetInpaintPipeline
				__a				:			Optional[Any]					    =TEXT_GUIDED_IMAGE_INPAINTING_PARAMS
				__a				:			Union[str, Any]					    =TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS
				__a				:			Dict					    =frozenset([]	)



				def    __snake_case		(			self    ):
											torch.manual_seed(0    )
											lowerCAmelCase =		UNetaDConditionModel(
											    block_out_channels=(32, 64)							,			layers_per_block=2							,			sample_size=32							,			in_channels=4							,			out_channels=4							,			down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')							,			up_block_types=('''CrossAttnUpBlock2D''', '''UpBlock2D''')							,			cross_attention_dim=32							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		ControlNetModel(
											    block_out_channels=(32, 64)							,			layers_per_block=2							,			in_channels=4							,			down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')							,			cross_attention_dim=32							,			conditioning_embedding_out_channels=(16, 32)							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		DDIMScheduler(
											    beta_start=0.00085							,			beta_end=0.012							,			beta_schedule='''scaled_linear'''							,			clip_sample=UpperCAmelCase_							,			set_alpha_to_one=UpperCAmelCase_							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		AutoencoderKL(
											    block_out_channels=[32, 64]							,			in_channels=3							,			out_channels=3							,			down_block_types=['''DownEncoderBlock2D''', '''DownEncoderBlock2D''']							,			up_block_types=['''UpDecoderBlock2D''', '''UpDecoderBlock2D''']							,			latent_channels=4							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		CLIPTextConfig(
											    bos_token_id=0							,			eos_token_id=2							,			hidden_size=32							,			intermediate_size=37							,			layer_norm_eps=1E-0_5							,			num_attention_heads=4							,			num_hidden_layers=5							,			pad_token_id=1							,			vocab_size=10_00							,			)
											lowerCAmelCase =		CLIPTextModel(UpperCAmelCase_    )
											lowerCAmelCase =		CLIPTokenizer.from_pretrained('''hf-internal-testing/tiny-random-clip'''    )

											lowerCAmelCase =		{
											    '''unet''': unet,
											    '''controlnet''': controlnet,
											    '''scheduler''': scheduler,
											    '''vae''': vae,
											    '''text_encoder''': text_encoder,
											    '''tokenizer''': tokenizer,
											    '''safety_checker''': None,
											    '''feature_extractor''': None,
											}
											return components




class 				__UpperCamelCase      (			__UpperCAmelCase  ,       __UpperCAmelCase  ,       unittest.TestCase	):





				'''simple docstring'''



				__a				:			int					    =StableDiffusionControlNetInpaintPipeline
				__a				:			str					    =TEXT_GUIDED_IMAGE_INPAINTING_PARAMS
				__a				:			Optional[Any]					    =TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS



				def    __snake_case		(			self    ):
											torch.manual_seed(0    )
											lowerCAmelCase =		UNetaDConditionModel(
											    block_out_channels=(32, 64)							,			layers_per_block=2							,			sample_size=32							,			in_channels=9							,			out_channels=4							,			down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')							,			up_block_types=('''CrossAttnUpBlock2D''', '''UpBlock2D''')							,			cross_attention_dim=32							,			)
											torch.manual_seed(0    )

											def init_weights(UpperCAmelCase_    ):
																		if isinstance(UpperCAmelCase_							,			torch.nn.Convad    ):
																									torch.nn.init.normal(m.weight    )
																									m.bias.data.fill_(1.0    )

											lowerCAmelCase =		ControlNetModel(
											    block_out_channels=(32, 64)							,			layers_per_block=2							,			in_channels=4							,			down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')							,			cross_attention_dim=32							,			conditioning_embedding_out_channels=(16, 32)							,			)
											controlneta.controlnet_down_blocks.apply(UpperCAmelCase_    )

											torch.manual_seed(0    )
											lowerCAmelCase =		ControlNetModel(
											    block_out_channels=(32, 64)							,			layers_per_block=2							,			in_channels=4							,			down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')							,			cross_attention_dim=32							,			conditioning_embedding_out_channels=(16, 32)							,			)
											controlneta.controlnet_down_blocks.apply(UpperCAmelCase_    )

											torch.manual_seed(0    )
											lowerCAmelCase =		DDIMScheduler(
											    beta_start=0.00085							,			beta_end=0.012							,			beta_schedule='''scaled_linear'''							,			clip_sample=UpperCAmelCase_							,			set_alpha_to_one=UpperCAmelCase_							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		AutoencoderKL(
											    block_out_channels=[32, 64]							,			in_channels=3							,			out_channels=3							,			down_block_types=['''DownEncoderBlock2D''', '''DownEncoderBlock2D''']							,			up_block_types=['''UpDecoderBlock2D''', '''UpDecoderBlock2D''']							,			latent_channels=4							,			)
											torch.manual_seed(0    )
											lowerCAmelCase =		CLIPTextConfig(
											    bos_token_id=0							,			eos_token_id=2							,			hidden_size=32							,			intermediate_size=37							,			layer_norm_eps=1E-0_5							,			num_attention_heads=4							,			num_hidden_layers=5							,			pad_token_id=1							,			vocab_size=10_00							,			)
											lowerCAmelCase =		CLIPTextModel(UpperCAmelCase_    )
											lowerCAmelCase =		CLIPTokenizer.from_pretrained('''hf-internal-testing/tiny-random-clip'''    )

											lowerCAmelCase =		MultiControlNetModel([controlneta, controlneta]    )

											lowerCAmelCase =		{
											    '''unet''': unet,
											    '''controlnet''': controlnet,
											    '''scheduler''': scheduler,
											    '''vae''': vae,
											    '''text_encoder''': text_encoder,
											    '''tokenizer''': tokenizer,
											    '''safety_checker''': None,
											    '''feature_extractor''': None,
											}
											return components



				def    __snake_case		(			self							,			UpperCAmelCase_							,			UpperCAmelCase_=0    ):
											if str(UpperCAmelCase_    ).startswith('''mps'''    ):
																		lowerCAmelCase =		torch.manual_seed(UpperCAmelCase_    )
											else:
																		lowerCAmelCase =		torch.Generator(device=UpperCAmelCase_    ).manual_seed(UpperCAmelCase_    )

											lowerCAmelCase =		2

											lowerCAmelCase =		[
											    randn_tensor(
											        (1, 3, 32 * controlnet_embedder_scale_factor, 32 * controlnet_embedder_scale_factor)							,			generator=UpperCAmelCase_							,			device=torch.device(UpperCAmelCase_    )							,			),
											    randn_tensor(
											        (1, 3, 32 * controlnet_embedder_scale_factor, 32 * controlnet_embedder_scale_factor)							,			generator=UpperCAmelCase_							,			device=torch.device(UpperCAmelCase_    )							,			),
											]
											lowerCAmelCase =		floats_tensor((1, 3, 32, 32)							,			rng=random.Random(UpperCAmelCase_    )    ).to(UpperCAmelCase_    )
											lowerCAmelCase =		init_image.cpu().permute(0							,			2							,			3							,			1    )[0]

											lowerCAmelCase =		Image.fromarray(np.uinta(UpperCAmelCase_    )    ).convert('''RGB'''    ).resize((64, 64)    )
											lowerCAmelCase =		Image.fromarray(np.uinta(init_image + 4    )    ).convert('''RGB'''    ).resize((64, 64)    )

											lowerCAmelCase =		{
											    '''prompt''': '''A painting of a squirrel eating a burger''',
											    '''generator''': generator,
											    '''num_inference_steps''': 2,
											    '''guidance_scale''': 6.0,
											    '''output_type''': '''numpy''',
											    '''image''': image,
											    '''mask_image''': mask_image,
											    '''control_image''': control_image,
											}

											return inputs



				def    __snake_case		(			self    ):
											lowerCAmelCase =		self.get_dummy_components()
											lowerCAmelCase =		self.pipeline_class(**UpperCAmelCase_    )
											pipe.to(UpperCAmelCase_    )

											lowerCAmelCase =		10.0
											lowerCAmelCase =		4

											lowerCAmelCase =		self.get_dummy_inputs(UpperCAmelCase_    )
											lowerCAmelCase =		steps
											lowerCAmelCase =		scale
											lowerCAmelCase =		pipe(**UpperCAmelCase_    )[0]

											lowerCAmelCase =		self.get_dummy_inputs(UpperCAmelCase_    )
											lowerCAmelCase =		steps
											lowerCAmelCase =		scale
											lowerCAmelCase =		pipe(**UpperCAmelCase_							,			control_guidance_start=0.1							,			control_guidance_end=0.2    )[0]

											lowerCAmelCase =		self.get_dummy_inputs(UpperCAmelCase_    )
											lowerCAmelCase =		steps
											lowerCAmelCase =		scale
											lowerCAmelCase =		pipe(**UpperCAmelCase_							,			control_guidance_start=[0.1, 0.3]							,			control_guidance_end=[0.2, 0.7]    )[0]

											lowerCAmelCase =		self.get_dummy_inputs(UpperCAmelCase_    )
											lowerCAmelCase =		steps
											lowerCAmelCase =		scale
											lowerCAmelCase =		pipe(**UpperCAmelCase_							,			control_guidance_start=0.4							,			control_guidance_end=[0.5, 0.8]    )[0]

											# make sure that all outputs are different
											assert np.sum(np.abs(output_a - output_a    )    ) > 1E-3
											assert np.sum(np.abs(output_a - output_a    )    ) > 1E-3
											assert np.sum(np.abs(output_a - output_a    )    ) > 1E-3



				def    __snake_case		(			self    ):
											return self._test_attention_slicing_forward_pass(expected_max_diff=2E-3    )



				@unittest.skipIf(
				    torch_device != '''cuda''' or not is_xformers_available()							,			reason='''XFormers attention is only available with CUDA and `xformers` installed'''							,			)
				def    __snake_case		(			self    ):
											self._test_xformers_attention_forwardGenerator_pass(expected_max_diff=2E-3    )



				def    __snake_case		(			self    ):
											self._test_inference_batch_single_identical(expected_max_diff=2E-3    )






				def    __snake_case		(			self    ):
											lowerCAmelCase =		self.get_dummy_components()
											lowerCAmelCase =		self.pipeline_class(**UpperCAmelCase_    )
											pipe.to(UpperCAmelCase_    )
											pipe.set_progress_bar_config(disable=UpperCAmelCase_    )
											with tempfile.TemporaryDirectory() as tmpdir:
																		try:
																									# save_pretrained is not implemented for Multi-ControlNet
																									pipe.save_pretrained(UpperCAmelCase_    )
																		except NotImplementedError:
																									pass




@slow
@require_torch_gpu
class 				__UpperCamelCase      (			unittest.TestCase	):





				'''simple docstring'''



				def    __snake_case		(			self    ):
											super().tearDown()
											gc.collect()
											torch.cuda.empty_cache()



				def    __snake_case		(			self    ):
											lowerCAmelCase =		ControlNetModel.from_pretrained('''lllyasviel/sd-controlnet-canny'''    )

											lowerCAmelCase =		StableDiffusionControlNetInpaintPipeline.from_pretrained(
											    '''runwayml/stable-diffusion-inpainting'''							,			safety_checker=UpperCAmelCase_							,			controlnet=UpperCAmelCase_    )
											pipe.enable_model_cpu_offload()
											pipe.set_progress_bar_config(disable=UpperCAmelCase_    )

											lowerCAmelCase =		torch.Generator(device='''cpu'''    ).manual_seed(0    )
											lowerCAmelCase =		load_image(
											    '''https://huggingface.co/lllyasviel/sd-controlnet-canny/resolve/main/images/bird.png'''    ).resize((5_12, 5_12)    )

											lowerCAmelCase =		load_image(
											    '''https://huggingface.co/datasets/diffusers/test-arrays/resolve/main'''
											    '''/stable_diffusion_inpaint/input_bench_mask.png'''    ).resize((5_12, 5_12)    )

											lowerCAmelCase =		'''pitch black hole'''

											lowerCAmelCase =		load_image(
											    '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/sd_controlnet/bird_canny.png'''    ).resize((5_12, 5_12)    )

											lowerCAmelCase =		pipe(
											    UpperCAmelCase_							,			image=UpperCAmelCase_							,			mask_image=UpperCAmelCase_							,			control_image=UpperCAmelCase_							,			generator=UpperCAmelCase_							,			output_type='''np'''							,			num_inference_steps=3							,			)

											lowerCAmelCase =		output.images[0]

											assert image.shape == (5_12, 5_12, 3)

											lowerCAmelCase =		load_numpy(
											    '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/sd_controlnet/inpaint.npy'''    )

											assert np.abs(expected_image - image    ).max() < 9E-2






				def    __snake_case		(			self    ):
											lowerCAmelCase =		ControlNetModel.from_pretrained('''lllyasviel/control_v11p_sd15_inpaint'''    )

											lowerCAmelCase =		StableDiffusionControlNetInpaintPipeline.from_pretrained(
											    '''runwayml/stable-diffusion-v1-5'''							,			safety_checker=UpperCAmelCase_							,			controlnet=UpperCAmelCase_    )
											lowerCAmelCase =		DDIMScheduler.from_config(pipe.scheduler.config    )
											pipe.enable_model_cpu_offload()
											pipe.set_progress_bar_config(disable=UpperCAmelCase_    )

											lowerCAmelCase =		torch.Generator(device='''cpu'''    ).manual_seed(33    )

											lowerCAmelCase =		load_image(
											    '''https://huggingface.co/datasets/diffusers/test-arrays/resolve/main/stable_diffusion_inpaint/boy.png'''    )
											lowerCAmelCase =		init_image.resize((5_12, 5_12)    )

											lowerCAmelCase =		load_image(
											    '''https://huggingface.co/datasets/diffusers/test-arrays/resolve/main/stable_diffusion_inpaint/boy_mask.png'''    )
											lowerCAmelCase =		mask_image.resize((5_12, 5_12)    )

											lowerCAmelCase =		'''a handsome man with ray-ban sunglasses'''

											def make_inpaint_condition(UpperCAmelCase_							,			UpperCAmelCase_    ):
																		lowerCAmelCase =		np.array(image.convert('''RGB'''    )    ).astype(np.floataa    ) / 255.0
																		lowerCAmelCase =		np.array(image_mask.convert('''L'''    )    ).astype(np.floataa    ) / 255.0

																		assert image.shape[0:1] == image_mask.shape[0:1], "image and image_mask must have the same image size"
																		lowerCAmelCase =		-1.0  # set as masked pixel
																		lowerCAmelCase =		np.expand_dims(UpperCAmelCase_							,			0    ).transpose(0							,			3							,			1							,			2    )
																		lowerCAmelCase =		torch.from_numpy(UpperCAmelCase_    )
																		return image

											lowerCAmelCase =		make_inpaint_condition(UpperCAmelCase_							,			UpperCAmelCase_    )

											lowerCAmelCase =		pipe(
											    UpperCAmelCase_							,			image=UpperCAmelCase_							,			mask_image=UpperCAmelCase_							,			control_image=UpperCAmelCase_							,			guidance_scale=9.0							,			eta=1.0							,			generator=UpperCAmelCase_							,			num_inference_steps=20							,			output_type='''np'''							,			)
											lowerCAmelCase =		output.images[0]

											assert image.shape == (5_12, 5_12, 3)

											lowerCAmelCase =		load_numpy(
											    '''https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/sd_controlnet/boy_ray_ban.npy'''    )

											assert np.abs(expected_image - image    ).max() < 9E-2









import os
import sys

from . import rsa_key_generator as rkg

UpperCAmelCase_    =128
UpperCAmelCase_    =256



def    UpperCAmelCase							(  _snake_case    ,			_snake_case = DEFAULT_BLOCK_SIZE				):
							lowerCAmelCase =		message.encode('''ascii'''				)

							lowerCAmelCase =		[]
							for block_start in range(0    ,			len(_snake_case				)    ,			_snake_case				):
														lowerCAmelCase =		0
														for i in range(_snake_case    ,			min(block_start + block_size    ,			len(_snake_case				)				)				):
																					block_int += message_bytes[i] * (BYTE_SIZE ** (i % block_size))
														block_ints.append(_snake_case				)
							return block_ints



def    UpperCAmelCase							(  _snake_case    ,			_snake_case    ,			_snake_case = DEFAULT_BLOCK_SIZE				):
							lowerCAmelCase =		[]
							for block_int in block_ints:
														lowerCAmelCase =		[]
														for i in range(block_size - 1    ,			-1    ,			-1				):
																					if len(_snake_case				) + i < message_length:
																												lowerCAmelCase =		block_int // (BYTE_SIZE**i)
																												lowerCAmelCase =		block_int % (BYTE_SIZE**i)
																												block_message.insert(0    ,			chr(_snake_case				)				)
														message.extend(_snake_case				)
							return "".join(_snake_case				)



def    UpperCAmelCase							(  _snake_case    ,			_snake_case    ,			_snake_case = DEFAULT_BLOCK_SIZE				):
							lowerCAmelCase =		[]
							lowerCAmelCase ,  lowerCAmelCase =		key

							for block in get_blocks_from_text(_snake_case    ,			_snake_case				):
														encrypted_blocks.append(pow(_snake_case    ,			_snake_case    ,			_snake_case				)				)
							return encrypted_blocks



def    UpperCAmelCase							(  _snake_case    ,			_snake_case    ,			_snake_case    ,			_snake_case = DEFAULT_BLOCK_SIZE    ,			):
							lowerCAmelCase =		[]
							lowerCAmelCase ,  lowerCAmelCase =		key
							for block in encrypted_blocks:
														decrypted_blocks.append(pow(_snake_case    ,			_snake_case    ,			_snake_case				)				)
							return get_text_from_blocks(_snake_case    ,			_snake_case    ,			_snake_case				)



def    UpperCAmelCase							(  _snake_case				):
							with open(_snake_case				) as fo:
														lowerCAmelCase =		fo.read()
							lowerCAmelCase ,  lowerCAmelCase ,  lowerCAmelCase =		content.split(''','''				)
							return (int(_snake_case				), int(_snake_case				), int(_snake_case				))



def    UpperCAmelCase							(  _snake_case    ,			_snake_case    ,			_snake_case    ,			_snake_case = DEFAULT_BLOCK_SIZE    ,			):
							lowerCAmelCase ,  lowerCAmelCase ,  lowerCAmelCase =		read_key_file(_snake_case				)
							if key_size < block_size * 8:
														sys.exit(
														    '''ERROR: Block size is {} bits and key size is {} bits. The RSA cipher '''
														    '''requires the block size to be equal to or greater than the key size. '''
														    '''Either decrease the block size or use different keys.'''.format(
														        block_size * 8    ,			_snake_case				)				)

							lowerCAmelCase =		[str(_snake_case				) for i in encrypt_message(_snake_case    ,			(n, e)    ,			_snake_case				)]

							lowerCAmelCase =		''','''.join(_snake_case				)
							lowerCAmelCase =		F"""{len(_snake_case				)}_{block_size}_{encrypted_content}"""
							with open(_snake_case    ,			'''w'''				) as fo:
														fo.write(_snake_case				)
							return encrypted_content



def    UpperCAmelCase							(  _snake_case    ,			_snake_case				):
							lowerCAmelCase ,  lowerCAmelCase ,  lowerCAmelCase =		read_key_file(_snake_case				)
							with open(_snake_case				) as fo:
														lowerCAmelCase =		fo.read()
							lowerCAmelCase ,  lowerCAmelCase ,  lowerCAmelCase =		content.split('''_'''				)
							lowerCAmelCase =		int(_snake_case				)
							lowerCAmelCase =		int(_snake_case				)

							if key_size < block_size * 8:
														sys.exit(
														    '''ERROR: Block size is {} bits and key size is {} bits. The RSA cipher '''
														    '''requires the block size to be equal to or greater than the key size. '''
														    '''Did you specify the correct key file and encrypted file?'''.format(
														        block_size * 8    ,			_snake_case				)				)

							lowerCAmelCase =		[]
							for block in encrypted_message.split(''','''				):
														encrypted_blocks.append(int(_snake_case				)				)

							return decrypt_message(_snake_case    ,			_snake_case    ,			(n, d)    ,			_snake_case				)



def    UpperCAmelCase							(  ):
							lowerCAmelCase =		'''encrypted_file.txt'''
							lowerCAmelCase =		input(R'''Encrypt\Decrypt [e\d]: '''				)

							if response.lower().startswith('''e'''				):
														lowerCAmelCase =		'''encrypt'''
							elif response.lower().startswith('''d'''				):
														lowerCAmelCase =		'''decrypt'''

							if mode == "encrypt":
														if not os.path.exists('''rsa_pubkey.txt'''				):
																					rkg.make_key_files('''rsa'''    ,			1024				)

														lowerCAmelCase =		input('''\nEnter message: '''				)
														lowerCAmelCase =		'''rsa_pubkey.txt'''
														print(F"""Encrypting and writing to {filename}..."""				)
														lowerCAmelCase =		encrypt_and_write_to_file(_snake_case    ,			_snake_case    ,			_snake_case				)

														print('''\nEncrypted text:'''				)
														print(_snake_case				)

							elif mode == "decrypt":
														lowerCAmelCase =		'''rsa_privkey.txt'''
														print(F"""Reading from {filename} and decrypting..."""				)
														lowerCAmelCase =		read_from_file_and_decrypt(_snake_case    ,			_snake_case				)
														print('''writing decryption to rsa_decryption.txt...'''				)
														with open('''rsa_decryption.txt'''    ,			'''w'''				) as dec:
																					dec.write(_snake_case				)

														print('''\nDecryption:'''				)
														print(_snake_case				)


if __name__ == "__main__":
		main()



