o
    Þý°jk*  ã                   @   s‚   d dl mZ d dlmZ d dlmZmZmZmZm	Z	m
Z
mZmZmZ eddƒZdd„ ZG dd	„ d	eƒZd
d„ Zdd„ ZdZdZdS )é    )Úget_random_bytes)Ú_copy_bytes)	Úload_pycryptodome_raw_libÚcreate_string_bufferÚget_raw_bufferÚVoidPointerÚSmartPointerÚc_size_tÚc_uint8_ptrÚc_ulongÚis_writeable_bufferzCryptodome.Cipher._chacha20aè  
                    int chacha20_init(void **pState,
                                      const uint8_t *key,
                                      size_t keySize,
                                      const uint8_t *nonce,
                                      size_t nonceSize);

                    int chacha20_destroy(void *state);

                    int chacha20_encrypt(void *state,
                                         const uint8_t in[],
                                         uint8_t out[],
                                         size_t len);

                    int chacha20_seek(void *state,
                                      unsigned long block_high,
                                      unsigned long block_low,
                                      unsigned offset);

                    int hchacha20(  const uint8_t key[32],
                                    const uint8_t nonce16[16],
                                    uint8_t subkey[32]);
                    c                 C   sV   t | ƒdksJ ‚t |ƒdksJ ‚tdƒ}t t| ƒt|ƒt|ƒ¡}|r)td| ƒ‚|S )Né    é   z,Error %d when deriving subkey with HChaCha20)ÚlenÚ	bytearrayÚ_raw_chacha20_libÚ	hchacha20r
   Ú
ValueError)ÚkeyÚnonceÚsubkeyÚresult© r   ú�/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/Cryptodome/Cipher/ChaCha20.pyÚ
_HChaCha20C   s   ýr   c                   @   s@   e Zd ZdZdZdd„ Zddd„Zdd	„ Zdd
d„Zdd„ Z	dS )ÚChaCha20Cipherz¹ChaCha20 (or XChaCha20) cipher object.
    Do not create it directly. Use :py:func:`new` instead.

    :var nonce: The nonce with length 8, 12 or 24 bytes
    :vartype nonce: bytes
    é   c              	   C   s¸   t dd|ƒ| _t|ƒdkr"t||dd… ƒ}d|dd…  }d| _nd| _| j}d| _tƒ | _t 	| j 
¡ t|ƒtt|ƒƒ|tt|ƒƒ¡}|rPtd|| jf ƒ‚t| j ¡ tjƒ| _dS )	z\Initialize a ChaCha20/XChaCha20 cipher object

        See also `new()` at the module level.Né   r   ó       Ú	XChaCha20ÚChaCha20)ÚencryptÚdecryptz"Error %d instantiating a %s cipher)r   r   r   r   Ú_nameÚ_nextr   Ú_stater   Úchacha20_initÚ
address_ofr
   r	   r   r   ÚgetÚchacha20_destroy)Úselfr   r   r   r   r   r   Ú__init__]   s.   

ûÿ

ÿzChaCha20Cipher.__init__Nc                 C   s$   d| j vr	tdƒ‚d| _ |  ||¡S )a«  Encrypt a piece of data.

        Args:
          plaintext(bytes/bytearray/memoryview): The data to encrypt, of any size.
        Keyword Args:
          output(bytes/bytearray/memoryview): The location where the ciphertext
            is written to. If ``None``, the ciphertext is returned.
        Returns:
          If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
          Otherwise, ``None``.
        r!   z-Cipher object can only be used for decryption)r!   )r$   Ú	TypeErrorÚ_encrypt)r*   Ú	plaintextÚoutputr   r   r   r!   }   s   
zChaCha20Cipher.encryptc                 C   sš   |du rt t|ƒƒ}n|}t|ƒstdƒ‚t|ƒt|ƒkr%tdt|ƒ ƒ‚t | j ¡ t	|ƒt	|ƒt
t|ƒƒ¡}|rCtd|| jf ƒ‚|du rKt|ƒS dS )zEncrypt without FSM checksNz4output must be a bytearray or a writeable memoryviewz9output must have the same length as the input  (%d bytes)z!Error %d while encrypting with %s)r   r   r   r,   r   r   Úchacha20_encryptr%   r(   r
   r	   r#   r   )r*   r.   r/   Ú
ciphertextr   r   r   r   r-   �   s(   ÿ
üzChaCha20Cipher._encryptc              
   C   sT   d| j vr	tdƒ‚d| _ z|  ||¡W S  ty) } z
tt|ƒ dd¡ƒ‚d}~ww )a©  Decrypt a piece of data.

        Args:
          ciphertext(bytes/bytearray/memoryview): The data to decrypt, of any size.
        Keyword Args:
          output(bytes/bytearray/memoryview): The location where the plaintext
            is written to. If ``None``, the plaintext is returned.
        Returns:
          If ``output`` is ``None``, the plaintext is returned as ``bytes``.
          Otherwise, ``None``.
        r"   z-Cipher object can only be used for encryption)r"   ÚencÚdecN)r$   r,   r-   r   ÚstrÚreplace)r*   r1   r/   Úer   r   r   r"   «   s   
€ÿzChaCha20Cipher.decryptc                 C   sV   t |dƒ\}}|d@ }|d? }t | j ¡ t|ƒt|ƒ|¡}|r)td|| jf ƒ‚dS )a   Seek to a certain position in the key stream.

        If you want to seek to a certain block,
        use ``seek(block_number * 64)``.

        Args:
          position (integer):
            The absolute position within the key stream, in bytes.
        é@   l   ÿÿ r   zError %d while seeking with %sN)Údivmodr   Úchacha20_seekr%   r(   r   r   r#   )r*   ÚpositionÚblock_numberÚoffsetÚ	block_lowÚ
block_highr   r   r   r   ÚseekÁ   s   üÿzChaCha20Cipher.seek)N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú
block_sizer+   r!   r-   r"   r?   r   r   r   r   r   S   s    
 
r   c                 C   s†   t | ƒdkr
tdƒ‚|du rtdƒ }}nt |ƒdkr d| }nt |ƒdkr)|}ntdƒ‚t| |d� d	¡}|dd
… |d
d… |fS )zrDerive a tuple (r, s, nonce) for a Poly1305 MAC.

    If nonce is ``None``, a new 12-byte nonce is generated.
    r   z-Poly1305 with ChaCha20 requires a 32-byte keyNé   é   r   z6Poly1305 with ChaCha20 requires an 8- or 12-byte nonce)r   r   s                                    r   )r   r   r   Únewr!   )r   r   Úpadded_nonceÚrsr   r   r   Ú_derive_Poly1305_key_pairÚ   s   
rJ   c               
   K   s–   z|   d¡}W n ty } ztd| ƒ‚d}~ww |   dd¡}|du r(tdƒ}t|ƒdkr2tdƒ‚t|ƒdvr<td	ƒ‚| rFtd
t| ƒ ƒ‚t||ƒS )a�  Create a new ChaCha20 or XChaCha20 cipher

    Keyword Args:
        key (bytes/bytearray/memoryview): The secret key to use.
            It must be 32 bytes long.
        nonce (bytes/bytearray/memoryview): A mandatory value that
            must never be reused for any other encryption
            done with this key.

            For ChaCha20, it must be 8 or 12 bytes long.

            For XChaCha20, it must be 24 bytes long.

            If not provided, 8 bytes will be randomly generated
            (you can find them back in the ``nonce`` attribute).

    :Return: a :class:`Cryptodome.Cipher.ChaCha20.ChaCha20Cipher` object
    r   zMissing parameter %sNr   rF   r   z,ChaCha20/XChaCha20 key must be 32 bytes long)rF   rE   r   z:Nonce must be 8/12 bytes(ChaCha20) or 24 bytes (XChaCha20)zUnknown parameters: )ÚpopÚKeyErrorr,   r   r   r   r4   r   )Úkwargsr   r6   r   r   r   r   rG   ÷   s    €ÿ
rG   r   r   N)ÚCryptodome.Randomr   ÚCryptodome.Util.py3compatr   ÚCryptodome.Util._raw_apir   r   r   r   r   r	   r
   r   r   r   r   Úobjectr   rJ   rG   rD   Úkey_sizer   r   r   r   Ú<module>   s   ,ÿ )