U
    ÈZj§!  ã                   @   sZ   d ddgZ ddlmZ ddlmZmZmZ ddlmZ dd „ Z	dd„ Z
G d	d„ deƒZd
S )ÚgenerateÚ	constructÚ
ElGamalKeyé    )ÚRandom)Úgenerate_probable_safe_primeÚtest_probable_primeÚ	COMPOSITE©ÚIntegerc                 C   s¸   t ƒ }t| |d�|_|jd d? }ttjd|j|d�d|jƒ|_|jdkrLq"|jd |j dkrbq"|j |j¡}|jd | dkrˆq"qˆq"tjd|jd |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_bitsÚrandfuncé   é   ©Zmin_inclusiveZmax_exclusiver   )r   r   r   )
r   r   ÚpÚpowr
   Úrandom_rangeÚgÚinverseÚxÚy)Úbitsr   ÚobjÚqZginv© r   ú[/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/Crypto/PublicKey/ElGamal.pyr   "   s0    þ þ
þc                 C   sü   t ƒ }t| ƒdkrtdƒ‚tt| ƒƒD ]"}|j| }t||t| | ƒƒ q&t|jƒt	k}||j
dkpn|j
|jkO }|t|j
|jd |jƒdkO }||jdk p¦|j|jkO }t| ƒdkrì||jdkpÌ|j|jkO }|t|j
|j|jƒ|jkO }|røtdƒ‚|S )aÍ  Construct 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   r   zInvalid ElGamal key components)r   ÚlenÚ
ValueErrorÚrangeÚ_keydataÚsetattrr
   r   r   r   r   r   r   r   )Útupr   ÚiÚfieldZ	fmt_errorr   r   r   r   `   s      
c                   @   s¶   e Zd ZdZddddgZd-dd„Zd	d
„ Zdd„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ ZdS ).r   aP  Class 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
    r   r   r   r   Nc                 C   s   |d krt  ¡ j}|| _d S ©N)r   ÚnewÚreadÚ	_randfunc)Úselfr   r   r   r   Ú__init__³   s    
zElGamalKey.__init__c                 C   s:   t | j|| jƒ}t | j|| jƒ| | j }t|ƒt|ƒgS r%   )r   r   r   r   Úint)r)   ÚMÚKÚaÚbr   r   r   Ú_encrypt¸   s    zElGamalKey._encryptc                 C   s”   t | dƒstdƒ‚tjd| jd | jd�}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   r   r   )ÚhasattrÚ	TypeErrorr
   r   r   r(   r   r   r   r   r   r+   )r)   r,   ÚrZa_blindZaxZplaintext_blindÚ	plaintextr   r   r   Ú_decrypt½   s    
þzElGamalKey._decryptc                 C   s”   t | dƒstdƒ‚| jd }t|ƒ}| |¡dkr:tdƒ‚t| j|| jƒ}t|ƒ| j|  | }|dk rr|| }q`|| 	|¡ | }t
|ƒt
|ƒgS )Nr   r1   r   zBad K value: GCD(K,p-1)!=1r   )r2   r3   r   r
   Úgcdr   r   r   r   r   r+   )r)   r,   r-   Úp1r.   Útr/   r   r   r   Ú_signÉ   s    

 
zElGamalKey._signc                 C   s„   dd„ |D ƒ}|d dk s,|d | j d kr0dS t| j|d | j ƒ}|t|d |d | j ƒ | j  }t| j|| j ƒ}||kr€dS dS )Nc                 S   s   g | ]}t |ƒ‘qS r   r	   )Ú.0r   r   r   r   Ú
<listcomp>×   s     z&ElGamalKey._verify.<locals>.<listcomp>r   r   )r   r   r   r   )r)   r,   ÚsigZv1Zv2r   r   r   Ú_verifyÖ   s     zElGamalKey._verifyc                 C   s   t | dƒrdS dS dS )z&Whether this is an ElGamal private keyr   r   r   N)r2   ©r)   r   r   r   Úhas_privateá   s    
zElGamalKey.has_privatec                 C   s   dS ©NTr   r?   r   r   r   Úcan_encrypté   s    zElGamalKey.can_encryptc                 C   s   dS rA   r   r?   r   r   r   Úcan_signì   s    zElGamalKey.can_signc                 C   s   t | j| j| jfƒS )zfA matching ElGamal public key.

        Returns:
            a new :class:`ElGamalKey` object
        )r   r   r   r   r?   r   r   r   Ú	publickeyï   s    zElGamalKey.publickeyc                 C   sP   t |  ¡ ƒt | ¡ ƒkrdS d}| jD ]$}|oHt| j|d ƒt|j|d ƒk}q&|S )NFT)Úboolr@   r    ÚgetattrÚkey)r)   ÚotherÚresultÚcompr   r   r   Ú__eq__÷   s    
ÿzElGamalKey.__eq__c                 C   s   |   |¡ S r%   )rK   )r)   rH   r   r   r   Ú__ne__  s    zElGamalKey.__ne__c                 C   s   ddl m} |‚d S )Nr   )ÚPicklingError)ÚpicklerM   )r)   rM   r   r   r   Ú__getstate__  s    zElGamalKey.__getstate__c                 C   s   t ‚d S r%   ©ÚNotImplementedError)r)   r,   r-   r   r   r   Úsign  s    zElGamalKey.signc                 C   s   t ‚d S r%   rP   )r)   r,   Ú	signaturer   r   r   Úverify  s    zElGamalKey.verifyc                 C   s   t ‚d S r%   rP   )r)   r5   r-   r   r   r   Úencrypt  s    zElGamalKey.encryptc                 C   s   t ‚d S r%   rP   )r)   Z
ciphertextr   r   r   Údecrypt  s    zElGamalKey.decryptc                 C   s   t ‚d S r%   rP   ©r)   r,   ÚBr   r   r   Úblind  s    zElGamalKey.blindc                 C   s   t ‚d S r%   rP   rW   r   r   r   Úunblind  s    zElGamalKey.unblindc                 C   s   t ‚d S r%   rP   r?   r   r   r   Úsize  s    zElGamalKey.size)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    r*   r0   r6   r:   r>   r@   rB   rC   rD   rK   rL   rO   rR   rT   rU   rV   rY   rZ   r[   r   r   r   r   r   ”   s*   

N)Ú__all__ZCryptor   ZCrypto.Math.Primalityr   r   r   ZCrypto.Math.Numbersr
   r   r   Úobjectr   r   r   r   r   Ú<module>   s   
>4