o
    n~b*                     @   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_libZ	hchacha20r
   
ValueError)keynoncesubkeyresult r   E/usr/local/lib/python3.10/dist-packages/Cryptodome/Cipher/ChaCha20.py
_HChaCha20B   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 )ChaCha20CipherzChaCha20 (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}| j| jf| _t | _	t
| j	 t|tt||tt|}|rTt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          Z	XChaCha20ZChaCha20z"Error %d instantiating a %s cipher)r   r   r   r   _nameencryptdecrypt_nextr   _stater   Zchacha20_initZ
address_ofr
   r	   r   r   getZchacha20_destroy)selfr   r   r   r   r   r   __init__\   s.   



zChaCha20Cipher.__init__Nc                 C   s*   | j | jvr
td| j f| _| ||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``.
        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   Zchacha20_encryptr"   r#   r
   r	   r   r   )r$   r(   r)   
ciphertextr   r   r   r   r'      s(   
zChaCha20Cipher._encryptc              
   C   sZ   | j | jvr
td| j f| _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``.
        z-Cipher object can only be used for encryptionencdecN)r    r!   r&   r'   r   strreplace)r$   r*   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 )zSeek to a certain position in the key stream.

        Args:
          position (integer):
            The absolute position within the key stream, in bytes.
        @   l    r   zError %d while seeking with %sN)divmodr   Zchacha20_seekr"   r#   r   r   r   )r$   positionoffsetZ	block_lowZ
block_highr   r   r   r   seek   s   zChaCha20Cipher.seek)N)
__name__
__module____qualname____doc__
block_sizer%   r   r'   r    r4   r   r   r   r   r   R   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   Zpadded_noncersr   r   r   _derive_Poly1305_key_pair   s   
r>   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   r;   r   z,ChaCha20/XChaCha20 key must be 32 bytes long)r;   r:   r   z:Nonce must be 8/12 bytes(ChaCha20) or 24 bytes (XChaCha20)zUnknown parameters: )popKeyErrorr&   r   r   r   r-   r   )kwargsr   r/   r   r   r   r   r<      s    
r<   r   r   N)ZCryptodome.Randomr   ZCryptodome.Util.py3compatr   ZCryptodome.Util._raw_apir   r   r   r   r   r	   r
   r   r   r   r   objectr   r>   r<   r9   Zkey_sizer   r   r   r   <module>   s   , )