o
    ‰¡e•  ã                   @   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r5| ||dd …  ¡| _n"t|ƒ| j d krK|| _| |¡d d… }nt	d| j | j d f ƒ‚| | _
| _|j||jf| j| j  d … | j d dœ|¤Ž| _d S )NFó    é   )ÚIVÚsegment_sizeéþÿÿÿé   z4Length of IV must be %d or %d bytes for MODE_OPENPGP)Ú
block_sizeÚ_done_first_blockÚnewÚMODE_CFBr   ÚlenÚencryptÚ_encrypted_IVÚdecryptÚ
ValueErrorÚivr   Ú_cipher)ÚselfÚfactoryÚkeyr   Úcipher_paramsÚ	IV_cipher© r   úA/usr/lib/python3/dist-packages/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   Ú
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ur$|dur#tdƒ‚n|}z|  d¡}W n tyA } ztdt|ƒ ƒ‚d}~ww 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__ÚCryptodome.Util.py3compatr   ÚCryptodome.Randomr   Úobjectr   r+   r   r   r   r   Ú<module>   s    