U
    Š¾úg•  ã                   @   s>   d Z dgZddlmZ ddlmZ G dd„ deƒZdd„ ZdS )	z
OpenPGP mode.
ÚOpenPgpModeé    )Ú_copy_bytes)Úget_random_bytesc                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r   az  OpenPGP mode.

    This mode is a variant of CFB, and it is only used in PGP and
    OpenPGP_ applications. If in doubt, use another mode.

    An Initialization Vector (*IV*) is required.

    Unlike CFB, the *encrypted* IV (not the IV itself) is
    transmitted to the receiver.

    The IV is a random data block. For legacy reasons, two of its bytes are
    duplicated to act as a checksum for the correctness of the key, which is now
    known to be insecure and is ignored. The encrypted IV is therefore 2 bytes
    longer than the clean IV.

    .. _OpenPGP: http://tools.ietf.org/html/rfc4880

    :undocumented: __init__
    c                 C   sð   |j | _ d| _|j||jfd| j  | j d dœ|—Ž}td d |ƒ}t|ƒ| j krj| ||dd …  ¡| _nDt|ƒ| j d kr–|| _| |¡d d… }nt	d| j | j d f ƒ‚| | _
| _|j||jf| j| j  d … | j d dœ|—Ž| _d S )NFó    é   )ÚIVZsegment_sizeéþÿÿÿé   z4Length of IV must be %d or %d bytes for MODE_OPENPGP)Ú
block_sizeÚ_done_first_blockÚnewZMODE_CFBr   ÚlenÚencryptÚ_encrypted_IVÚdecryptÚ
ValueErrorÚivr   Ú_cipher)ÚselfÚfactoryÚkeyr   Zcipher_paramsZ	IV_cipher© r   úC/tmp/pip-unpacked-wheel-_q8s9isk/Cryptodome/Cipher/_mode_openpgp.pyÚ__init__=   s<    þüûþþüûzOpenPgpMode.__init__c                 C   s&   | j  |¡}| js"| j| }d| _|S )a›  Encrypt data with the key and the parameters set at initialization.

        A cipher object is stateful: once you have encrypted a message
        you cannot encrypt (or decrypt) another message using the same
        object.

        The data to encrypt can be broken up in two or
        more pieces and `encrypt` can be called multiple times.

        That is, the statement:

            >>> c.encrypt(a) + c.encrypt(b)

        is equivalent to:

             >>> c.encrypt(a+b)

        This function does not add any padding to the plaintext.

        :Parameters:
          plaintext : bytes/bytearray/memoryview
            The piece of data to encrypt.

        :Return:
            the encrypted data, as a byte string.
            It is as long as *plaintext* with one exception:
            when encrypting the first message chunk,
            the encypted IV is prepended to the returned ciphertext.
        T)r   r   r   r   )r   Ú	plaintextÚresr   r   r   r   g   s
    
zOpenPgpMode.encryptc                 C   s   | j  |¡S )aÙ  Decrypt data with the key and the parameters set at initialization.

        A cipher object is stateful: once you have decrypted a message
        you cannot decrypt (or encrypt) another message with the same
        object.

        The data to decrypt can be broken up in two or
        more pieces and `decrypt` can be called multiple times.

        That is, the statement:

            >>> c.decrypt(a) + c.decrypt(b)

        is equivalent to:

             >>> c.decrypt(a+b)

        This function does not remove any padding from the plaintext.

        :Parameters:
          ciphertext : bytes/bytearray/memoryview
            The piece of data to decrypt.

        :Return: the decrypted data (byte string).
        )r   r   )r   Z
ciphertextr   r   r   r   Œ   s    zOpenPgpMode.decryptN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   r   (   s   *%c              
   K   sœ   |  dd¡}|  dd¡}d||fkr.t| jƒ}|dk	rH|dk	rLtdƒ‚n|}z|  d¡}W n2 tk
rŒ } ztdt|ƒ ƒ‚W 5 d}~X Y nX t| |||ƒS )a#  Create a new block cipher, configured in OpenPGP mode.

    :Parameters:
      factory : module
        The module.

    :Keywords:
      key : bytes/bytearray/memoryview
        The secret key to use in the symmetric cipher.

      IV : bytes/bytearray/memoryview
        The initialization vector to use for encryption or decryption.

        For encryption, the IV must be as long as the cipher block size.

        For decryption, it must be 2 bytes longer (it is actually the
        *encrypted* IV which was prefixed to the ciphertext).
    r   Nr   )NNz*You must either use 'iv' or 'IV', not bothr   zMissing component: )Úpopr   r
   Ú	TypeErrorÚKeyErrorÚstrr   )r   Úkwargsr   r   r   Úer   r   r   Ú_create_openpgp_cipherª   s    

"r&   N)	r   Ú__all__ZCryptodome.Util.py3compatr   ZCryptodome.Randomr   Úobjectr   r&   r   r   r   r   Ú<module>   s    