
import unittest

from transformers import is_torch_available
from transformers.testing_utils import require_torch, slow, torch_device

from ...generation.test_utils import GenerationTesterMixin
from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
   import torch

   from transformers import (
       OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST,
       OpenAIGPTConfig,
       OpenAIGPTDoubleHeadsModel,
       OpenAIGPTForSequenceClassification,
       OpenAIGPTLMHeadModel,
       OpenAIGPTModel,
   )







class   lowerCamelCase	:





     def __init__(self   :					Union[str, Any]       ,					_A   :					Optional[int]       ,					_A   :					List[str]=1_3       ,					_A   :					Union[str, Any]=7       ,					_A   :					Union[str, Any]=True       ,					_A   :					List[str]=True       ,					_A   :					str=True       ,					_A   :					List[str]=9_9       ,					_A   :					List[Any]=3_2       ,					_A   :					Dict=5       ,					_A   :					Tuple=4       ,					_A   :					int=3_7       ,					_A   :					str="gelu"       ,					_A   :					Optional[Any]=0.1       ,					_A   :					int=0.1       ,					_A   :					Union[str, Any]=5_1_2       ,					_A   :					int=1_6       ,					_A   :					List[Any]=2       ,					_A   :					List[Any]=0.02       ,					_A   :					Dict=3       ,					_A   :					List[str]=4       ,					_A   :					Dict=None       ,					)		->		List[str]:
         snake_case				  =      parent
         snake_case				  =      batch_size
         snake_case				  =      seq_length
         snake_case				  =      is_training
         snake_case				  =      use_token_type_ids
         snake_case				  =      use_labels
         snake_case				  =      vocab_size
         snake_case				  =      hidden_size
         snake_case				  =      num_hidden_layers
         snake_case				  =      num_attention_heads
         snake_case				  =      intermediate_size
         snake_case				  =      hidden_act
         snake_case				  =      hidden_dropout_prob
         snake_case				  =      attention_probs_dropout_prob
         snake_case				  =      max_position_embeddings
         snake_case				  =      type_vocab_size
         snake_case				  =      type_sequence_label_size
         snake_case				  =      initializer_range
         snake_case				  =      num_labels
         snake_case				  =      num_choices
         snake_case				  =      scope
         snake_case				  =      self.vocab_size - 1





     def 	UpperCAmelCase(self   :					Dict     )		->		Union[str, Any]:
         snake_case				  =      ids_tensor([self.batch_size, self.seq_length]       ,					self.vocab_size     )

         snake_case				  =      None
         if self.use_token_type_ids:
             snake_case				  =      ids_tensor([self.batch_size, self.seq_length]       ,					self.type_vocab_size     )

         snake_case				  =      None
         snake_case				  =      None
         snake_case				  =      None
         if self.use_labels:
             snake_case				  =      ids_tensor([self.batch_size]       ,					self.type_sequence_label_size     )
             snake_case				  =      ids_tensor([self.batch_size, self.seq_length]       ,					self.num_labels     )
             snake_case				  =      ids_tensor([self.batch_size]       ,					self.num_choices     )

         snake_case				  =      OpenAIGPTConfig(
             vocab_size=self.vocab_size       ,					n_embd=self.hidden_size       ,					n_layer=self.num_hidden_layers       ,					n_head=self.num_attention_heads       ,					n_positions=self.max_position_embeddings       ,					pad_token_id=self.pad_token_id       ,					)

         snake_case				  =      ids_tensor([self.num_hidden_layers, self.num_attention_heads]       ,					2     )

         return (
             config,
             input_ids,
             head_mask,
             token_type_ids,
             sequence_labels,
             token_labels,
             choice_labels,
         )





     def 	UpperCAmelCase(self   :					Dict       ,					_A   :					Optional[Any]       ,					_A   :					Tuple       ,					_A   :					int       ,					_A   :					List[str]       ,					*_A   :					Union[str, Any]     )		->		Optional[int]:
         snake_case				  =      OpenAIGPTModel(config=_A     )
         model.to(_A     )
         model.eval()

         snake_case				  =      model(_A       ,					token_type_ids=_A       ,					head_mask=_A     )
         snake_case				  =      model(_A       ,					token_type_ids=_A     )
         snake_case				  =      model(_A     )

         self.parent.assertEqual(result.last_hidden_state.shape       ,					(self.batch_size, self.seq_length, self.hidden_size)     )





     def 	UpperCAmelCase(self   :					Tuple       ,					_A   :					List[str]       ,					_A   :					Tuple       ,					_A   :					List[str]       ,					_A   :					List[str]       ,					*_A   :					Dict     )		->		List[Any]:
         snake_case				  =      OpenAIGPTLMHeadModel(_A     )
         model.to(_A     )
         model.eval()

         snake_case				  =      model(_A       ,					token_type_ids=_A       ,					labels=_A     )
         self.parent.assertEqual(result.loss.shape       ,					()     )
         self.parent.assertEqual(result.logits.shape       ,					(self.batch_size, self.seq_length, self.vocab_size)     )





     def 	UpperCAmelCase(self   :					int       ,					_A   :					str       ,					_A   :					str       ,					_A   :					Union[str, Any]       ,					_A   :					Union[str, Any]       ,					*_A   :					Tuple     )		->		int:
         snake_case				  =      OpenAIGPTDoubleHeadsModel(_A     )
         model.to(_A     )
         model.eval()

         snake_case				  =      model(_A       ,					token_type_ids=_A       ,					labels=_A     )
         self.parent.assertEqual(result.loss.shape       ,					()     )
         self.parent.assertEqual(result.logits.shape       ,					(self.batch_size, self.seq_length, self.vocab_size)     )





     def 	UpperCAmelCase(self   :					List[Any]       ,					_A   :					Tuple       ,					_A   :					Union[str, Any]       ,					_A   :					str       ,					_A   :					Dict       ,					*_A   :					Optional[int]     )		->		int:
         snake_case				  =      self.num_labels
         snake_case				  =      OpenAIGPTForSequenceClassification(_A     )
         model.to(_A     )
         model.eval()

         snake_case				  =      ids_tensor([self.batch_size]       ,					self.type_sequence_label_size     )
         snake_case				  =      model(_A       ,					token_type_ids=_A       ,					labels=_A     )
         self.parent.assertEqual(result.logits.shape       ,					(self.batch_size, self.num_labels)     )





     def 	UpperCAmelCase(self   :					Any     )		->		Tuple:
         snake_case				  =      self.prepare_config_and_inputs()
         (
             (
             snake_case
         )  ,							(
             snake_case
         )  ,							(
             snake_case
         )  ,							(
             snake_case
         )  ,							(
             snake_case
         )  ,							(
             snake_case
         )  ,							(
             snake_case
         )  ,							
         )				  =      config_and_inputs
         snake_case				  =      {
             "input_ids": input_ids,
             "token_type_ids": token_type_ids,
             "head_mask": head_mask,
         }

         return config, inputs_dict







@require_torch
class   lowerCamelCase	(						A_							,				A_							,				A_							,				unittest.TestCase						):
     UpperCAmelCase__       :							int     =	(
         (OpenAIGPTModel, OpenAIGPTLMHeadModel, OpenAIGPTDoubleHeadsModel, OpenAIGPTForSequenceClassification)
         if is_torch_available()
         else ()
     )
     UpperCAmelCase__       :							Tuple     =	(
         (OpenAIGPTLMHeadModel,) if is_torch_available() else ()
     )  # TODO (PVP): Add Double HeadsModel when generate() function is changed accordingly
     UpperCAmelCase__       :							Any     =	(
         {
             "feature-extraction": OpenAIGPTModel,
             "text-classification": OpenAIGPTForSequenceClassification,
             "text-generation": OpenAIGPTLMHeadModel,
             "zero-shot": OpenAIGPTForSequenceClassification,
         }
         if is_torch_available()
         else {}
     )





     def 	UpperCAmelCase(self   :					Union[str, Any]       ,					_A   :					Union[str, Any]       ,					_A   :					int       ,					_A   :					List[str]       ,					_A   :					Dict       ,					_A   :					Optional[int]     )		->		Dict:
         if pipeline_test_casse_name == "ZeroShotClassificationPipelineTests":
             # Get `tokenizer does not have a padding token` error for both fast/slow tokenizers.
             # `OpenAIGPTConfig` was never used in pipeline tests, either because of a missing checkpoint or because a
             # tiny config could not be created.
             return True

         return False





     def 	UpperCAmelCase(self   :					Optional[int]       ,					_A   :					Optional[int]       ,					_A   :					List[str]       ,					_A   :					List[str]=False     )		->		int:
         snake_case				  =      super()._prepare_for_class(_A       ,					_A       ,					return_labels=_A     )

         if return_labels:
             if model_class.__name__ == "OpenAIGPTDoubleHeadsModel":
                 snake_case				  =      torch.zeros(
                     (self.model_tester.batch_size, self.model_tester.num_choices, self.model_tester.seq_length)       ,					dtype=torch.long       ,					device=_A       ,					)
                 snake_case				  =      inputs_dict["labels"]
                 snake_case				  =      inputs_dict["labels"]
                 snake_case				  =      torch.zeros(
                     (self.model_tester.batch_size, self.model_tester.num_choices)       ,					dtype=torch.long       ,					device=_A       ,					)
                 snake_case				  =      torch.zeros(
                     self.model_tester.batch_size       ,					dtype=torch.long       ,					device=_A     )
         return inputs_dict





     def 	UpperCAmelCase(self   :					Optional[Any]     )		->		Any:
         snake_case				  =      OpenAIGPTModelTester(self     )
         snake_case				  =      ConfigTester(self       ,					config_class=_A       ,					n_embd=3_7     )





     def 	UpperCAmelCase(self   :					Union[str, Any]     )		->		Optional[int]:
         self.config_tester.run_common_tests()





     def 	UpperCAmelCase(self   :					Any     )		->		Union[str, Any]:
         snake_case				  =      self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_openai_gpt_model(*_A     )





     def 	UpperCAmelCase(self   :					int     )		->		Tuple:
         snake_case				  =      self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_lm_head_model(*_A     )





     def 	UpperCAmelCase(self   :					List[Any]     )		->		Optional[Any]:
         snake_case				  =      self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_double_lm_head_model(*_A     )





     def 	UpperCAmelCase(self   :					Tuple     )		->		Any:
         snake_case				  =      self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_openai_gpt_for_sequence_classification(*_A     )





     @slow
     def 	UpperCAmelCase(self   :					Optional[int]     )		->		List[Any]:
         for model_name in OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
             snake_case				  =      OpenAIGPTModel.from_pretrained(_A     )
             self.assertIsNotNone(_A     )







@require_torch
class   lowerCamelCase	(						unittest.TestCase						):





     @slow
     def 	UpperCAmelCase(self   :					str     )		->		int:
         snake_case				  =      OpenAIGPTLMHeadModel.from_pretrained("openai-gpt"     )
         model.to(_A     )
         snake_case				  =      torch.tensor([[4_8_1, 4_7_3_5, 5_4_4]]       ,					dtype=torch.long       ,					device=_A     )  # the president is
         snake_case				  =      [
             4_8_1,
             4_7_3_5,
             5_4_4,
             2_4_6,
             9_6_3,
             8_7_0,
             7_6_2,
             2_3_9,
             2_4_4,
             4_0_4_7_7,
             2_4_4,
             2_4_9,
             7_1_9,
             8_8_1,
             4_8_7,
             5_4_4,
             2_4_0,
             2_4_4,
             6_0_3,
             4_8_1,
         ]  # the president is a very good man. " \n " i\'m sure he is, " said the

         snake_case				  =      model.generate(_A       ,					do_sample=_A     )
         self.assertListEqual(output_ids[0].tolist()       ,					_A     )



from binascii import hexlify
from hashlib import shaaaa
from os import urandom

# RFC 3526 - More Modular Exponential (MODP) Diffie-Hellman groups for
# Internet Key Exchange (IKE) https://tools.ietf.org/html/rfc3526

_A						      =				{
    # 1536-bit
    5: {
        "prime": int(
            "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
            + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
            + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
            + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
            + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
            + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
            + "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
            + "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF",
            base=16,
        ),
        "generator": 2,
    },
    # 2048-bit
    14: {
        "prime": int(
            "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
            + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
            + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
            + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
            + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
            + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
            + "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
            + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
            + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
            + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
            + "15728E5A8AACAA68FFFFFFFFFFFFFFFF",
            base=16,
        ),
        "generator": 2,
    },
    # 3072-bit
    15: {
        "prime": int(
            "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
            + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
            + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
            + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
            + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
            + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
            + "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
            + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
            + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
            + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
            + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
            + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
            + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
            + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
            + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
            + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF",
            base=16,
        ),
        "generator": 2,
    },
    # 4096-bit
    16: {
        "prime": int(
            "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
            + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
            + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
            + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
            + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
            + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
            + "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
            + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
            + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
            + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
            + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
            + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
            + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
            + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
            + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
            + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
            + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
            + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
            + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
            + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
            + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"
            + "FFFFFFFFFFFFFFFF",
            base=16,
        ),
        "generator": 2,
    },
    # 6144-bit
    17: {
        "prime": int(
            "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
            + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
            + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
            + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
            + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
            + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
            + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
            + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
            + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
            + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
            + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
            + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
            + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC"
            + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26"
            + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB"
            + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2"
            + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127"
            + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
            + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406"
            + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918"
            + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151"
            + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03"
            + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F"
            + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
            + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B"
            + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632"
            + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E"
            + "6DCC4024FFFFFFFFFFFFFFFF",
            base=16,
        ),
        "generator": 2,
    },
    # 8192-bit
    18: {
        "prime": int(
            "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
            + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
            + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
            + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
            + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
            + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
            + "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
            + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
            + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
            + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
            + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
            + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
            + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
            + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
            + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
            + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
            + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
            + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
            + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
            + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
            + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
            + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
            + "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
            + "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
            + "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
            + "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
            + "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
            + "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
            + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
            + "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
            + "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
            + "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
            + "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
            + "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
            + "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
            + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
            + "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
            + "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
            + "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
            + "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
            + "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
            + "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
            + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF",
            base=16,
        ),
        "generator": 2,
    },
}







class   lowerCamelCase	:





     def __init__(self   :					Any       ,					_A   :					int = 1_4     )		->		None:
         if group not in primes:
             raise ValueError("Unsupported Group"     )
         snake_case				  =      primes[group]["prime"]
         snake_case				  =      primes[group]["generator"]

         snake_case				  =      int(hexlify(urandom(3_2     )     )       ,					base=1_6     )





     def 	UpperCAmelCase(self   :					Any     )		->		str:
         return hex(self.__private_key     )[2:]





     def 	UpperCAmelCase(self   :					Tuple     )		->		str:
         snake_case				  =      pow(self.generator       ,					self.__private_key       ,					self.prime     )
         return hex(_A     )[2:]





     def 	UpperCAmelCase(self   :					Optional[int]       ,					_A   :					int     )		->		bool:
         # check if the other public key is valid based on NIST SP800-56
         return (
             2 <= key <= self.prime - 2
             and pow(_A       ,					(self.prime - 1) // 2       ,					self.prime     ) == 1
         )





     def 	UpperCAmelCase(self   :					List[Any]       ,					_A   :					str     )		->		str:
         snake_case				  =      int(_A       ,					base=1_6     )
         if not self.is_valid_public_key(_A     ):
             raise ValueError("Invalid public key"     )
         snake_case				  =      pow(_A       ,					self.__private_key       ,					self.prime     )
         return shaaaa(str(_A     ).encode()     ).hexdigest()





     @staticmethod
     def 	UpperCAmelCase(_A   :					int       ,					_A   :					int     )		->		bool:
         # check if the other public key is valid based on NIST SP800-56
         return (
             2 <= remote_public_key_str <= prime - 2
             and pow(_A       ,					(prime - 1) // 2       ,					_A     ) == 1
         )





     @staticmethod
     def 	UpperCAmelCase(_A   :					str       ,					_A   :					str       ,					_A   :					int = 1_4     )		->		str:
         snake_case				  =      int(_A       ,					base=1_6     )
         snake_case				  =      int(_A       ,					base=1_6     )
         snake_case				  =      primes[group]["prime"]
         if not DiffieHellman.is_valid_public_key_static(_A       ,					_A     ):
             raise ValueError("Invalid public key"     )
         snake_case				  =      pow(_A       ,					_A       ,					_A     )
         return shaaaa(str(_A     ).encode()     ).hexdigest()


if __name__ == "__main__":
   import doctest

   doctest.testmod()

