U +Mb!@sZdddgZddlmZddlmZmZmZddlmZddZ ddZ Gd dde Z d S) generate construct ElGamalKey)Random)generate_probable_safe_primetest_probable_prime COMPOSITEIntegercCst}t||d|_|jdd?}ttjd|j|dd|j|_|jdkrLq"|jd|jdkrbq"|j|j}|jd|dkrq"qq"tjd|jd|d|_t|j|j|j|_ |S)a Randomly generate a fresh, new ElGamal key. The key will be safe for use for both encryption and signature (although it should be used for **only one** purpose). Args: bits (int): Key length, or size (in bits) of the modulus *p*. The recommended value is 2048. randfunc (callable): Random number generation function; it should accept a single integer *N* and return a string of random *N* random bytes. Return: an :class:`ElGamalKey` object )Z exact_bitsrandfuncZ min_inclusiveZ max_exclusiver )r r r) rrppowr random_rangeginversexy)bitsr objqZginvr?/tmp/pip-target-t616c12r/lib/python/Crypto/PublicKey/ElGamal.pyr"s0 cCst}t|dkrtdtt|D]"}|j|}t||t||q&t|jt k}||j dkpn|j |jkO}|t |j |jd|jdkO}||j dkp|j |jkO}t|dkr||j dkp|j |jkO}|t |j |j |j|j kO}|rtd|S)aConstruct an ElGamal key from a tuple of valid ElGamal components. The modulus *p* must be a prime. The following conditions must apply: .. math:: \begin{align} &1 < g < p-1 \\ &g^{p-1} = 1 \text{ mod } 1 \\ &1 < x < p-1 \\ &g^x = y \text{ mod } p \end{align} Args: tup (tuple): A tuple with either 3 or 4 integers, in the following order: 1. Modulus (*p*). 2. Generator (*g*). 3. Public key (*y*). 4. Private key (*x*). Optional. Raises: ValueError: when the key being imported fails the most basic ElGamal validity checks. Returns: an :class:`ElGamalKey` object )z%argument for construct() wrong lengthr rzInvalid ElGamal key components)rlen ValueErrorrange_keydatasetattrr rrrrrrr)tuprifieldZ fmt_errorrrrr`s    c@seZdZdZddddgZd-ddZd d Zd d Zd dZddZ ddZ ddZ ddZ ddZ ddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,ZdS).raPClass defining an ElGamal key. Do not instantiate directly. Use :func:`generate` or :func:`construct` instead. :ivar p: Modulus :vartype d: integer :ivar g: Generator :vartype e: integer :ivar y: Public key component :vartype y: integer :ivar x: Private key component :vartype x: integer rrrrNcCs|dkrtj}||_dSN)rnewread _randfunc)selfr rrr__init__s zElGamalKey.__init__cCs:t|j||j}t|j||j||j}t|t|gSr%)rrrrint)r)MKabrrr_encryptszElGamalKey._encryptcCst|dstdtjd|jd|jd}t|j||j|d|j}t||j|j}| |j|d|j}|t|j ||j|j}t |S)Nr(Private key not available in this objectr r rr) hasattr TypeErrorr rrr(rrrrrr+)r)r,rZa_blindZaxZplaintext_blind plaintextrrr_decrypts zElGamalKey._decryptcCst|dstd|jd}t|}||dkr:tdt|j||j}t||j||}|dkrr||}q`|| ||}t |t |gS)Nrr1r zBad K value: GCD(K,p-1)!=1r) r2r3rr gcdrrrrrr+)r)r,r-p1r.tr/rrr_signs   zElGamalKey._signcCsdd|D}|ddks,|d|jdkr0dSt|j|d|j}|t|d|d|j|j}t|j||j}||krdSdS)NcSsg|] }t|qSrr ).0rrrr sz&ElGamalKey._verify..rr )rrrr)r)r,sigv1v2rrr_verifys zElGamalKey._verifycCst|drdSdSdS)z&Whether this is an ElGamal private keyrr rN)r2r)rrr has_privates zElGamalKey.has_privatecCsdSNTrrArrr can_encryptszElGamalKey.can_encryptcCsdSrCrrArrrcan_signszElGamalKey.can_signcCst|j|j|jfS)zfA matching ElGamal public key. Returns: a new :class:`ElGamalKey` object )rrrrrArrr publickeyszElGamalKey.publickeycCsPt|t|krdSd}|jD]$}|oHt|j|dt|j|dk}q&|S)NFT)boolrBr getattrkey)r)otherresultcomprrr__eq__s  zElGamalKey.__eq__cCs || Sr%)rM)r)rJrrr__ne__szElGamalKey.__ne__cCsddlm}|dS)Nr) PicklingError)picklerO)r)rOrrr __getstate__s zElGamalKey.__getstate__cCstdSr%NotImplementedError)r)r,r-rrrsign szElGamalKey.signcCstdSr%rR)r)r, signaturerrrverifyszElGamalKey.verifycCstdSr%rR)r)r5r-rrrencryptszElGamalKey.encryptcCstdSr%rR)r)Z ciphertextrrrdecryptszElGamalKey.decryptcCstdSr%rRr)r,BrrrblindszElGamalKey.blindcCstdSr%rRrYrrrunblindszElGamalKey.unblindcCstdSr%rRrArrrsizeszElGamalKey.size)N)__name__ __module__ __qualname____doc__r r*r0r6r:r@rBrDrErFrMrNrQrTrVrWrXr[r\r]rrrrrs*      N) __all__ZCryptorZCrypto.Math.PrimalityrrrZCrypto.Math.Numbersr rrobjectrrrrrs   >4