o
    Ìn~bQ#  ã                   @   s~   d dl mZmZmZmZmZmZmZ d dlm	Z	 d dl
mZ ddlmZ dd„ ZdZdZd	Zd
ZG dd„ deƒZddd„ZdS )é    )ÚVoidPointerÚSmartPointerÚcreate_string_bufferÚget_raw_bufferÚc_size_tÚc_uint8_ptrÚc_ubyte)Úlong_to_bytes)Úbchré   )Ú_raw_keccak_libc                 C   s$   | dkrdS t | ƒ}|tt|ƒƒ S )Nr   ó    )r	   r
   Úlen)ÚxÚS© r   úI/usr/local/lib/python3.10/dist-packages/Cryptodome/Hash/KangarooTwelve.pyÚ_length_encode*   s   r   é   é   é   c                   @   sR   e Zd Z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d„ZdS )ÚK12_XOFzeA KangarooTwelve hash object.
    Do not instantiate directly.
    Use the :func:`new` function.
    c                 C   sb   |d krd}|t t|ƒƒ | _t| _d | _|  ¡ | _d| _d | _	d| _
d| _|r/|  |¡ d S d S )Nó    r   )r   r   Ú_customÚ	SHORT_MSGÚ_stateÚ_paddingÚ_create_keccakÚ_hash1Ú_length1Ú_hash2Ú_length2Ú_ctrÚupdate©ÚselfÚdataÚcustomr   r   r   Ú__init__?   s   
ÿzK12_XOF.__init__c                 C   s@   t ƒ }t | ¡ tdƒtdƒ¡}|rtd| ƒ‚t| ¡ tj	ƒS )Né    é   z+Error %d while instantiating KangarooTwelve)
r   r   Zkeccak_initZ
address_ofr   r   Ú
ValueErrorr   ÚgetZkeccak_destroy)r%   ÚstateÚresultr   r   r   r   V   s   
þÿzK12_XOF._create_keccakc                 C   s2   t  | ¡ t|ƒtt|ƒƒ¡}|rtd| ƒ‚d S )Nz,Error %d while updating KangarooTwelve state)r   Zkeccak_absorbr,   r   r   r   r+   )r%   r&   Úhash_objr.   r   r   r   Ú_update`   s   

þÿÿzK12_XOF._updatec                 C   s<   t |ƒ}t | ¡ |t|ƒt|ƒ¡}|rtd| ƒ‚t|ƒS )Nz-Error %d while extracting from KangarooTwelve)r   r   Zkeccak_squeezer,   r   r   r+   r   )r%   r/   ÚlengthÚpaddingZbfrr.   r   r   r   Ú_squeezeh   s   
ýÿzK12_XOF._squeezec                 C   s"   t  | ¡ ¡}|rtd| ƒ‚d S )Nz-Error %d while resetting KangarooTwelve state)r   Zkeccak_resetr,   r+   )r%   r/   r.   r   r   r   Ú_resett   s   ÿÿzK12_XOF._resetc           
      C   sè  | j tkr	tdƒ‚| j tkr-| jt|ƒ }|t| jƒ dkr*|| _|  || j¡ | S t	| _ | j t	krŽt
|ƒ}| jdk s=J ‚tt|ƒd| j ƒ}|  |d|… | j¡ |  j|7  _| jdk r`| S | jdksgJ ‚d}|  || j¡ |  jd7  _|  ¡ | _d| _d| _t| _ |  ||d… ¡S | j tks•J ‚d}t|ƒ}t
|ƒ}||k ròt|d | j |ƒ}|  |||… | j¡ |  j|| 7  _|}| jdkrî|  | jdd	¡}	|  |	| j¡ |  jd7  _|  | j¡ d| _|  jd7  _||k s£| S )
a  Hash the next piece of data.

        .. note::
            For better performance, submit chunks with a length multiple of 8192 bytes.

        Args:
            data (byte string/byte array/memoryview): The next chunk of the
            message to hash.
        z/You cannot call 'update' after the first 'read'i    Ns          é   r   r   r)   é   )r   Ú	SQUEEZINGÚ	TypeErrorr   r   r   r   r0   r   ÚLONG_MSG_S0Ú
memoryviewÚminr   r    r!   r"   ÚLONG_MSG_SXr#   r3   r4   )
r%   r&   Znext_lengthZdata_memZdtcÚdividerÚindexZlen_dataZ	new_indexÚcv_ir   r   r   r#   z   sX   





ózK12_XOF.updatec                 C   s   d}| j tkr|  | j| j¡ d| _t| _ | j tkr)|  | j¡ d}| j t	ks)J ‚| j t	krw|s6|  | j¡ | j
dkra|  | jdd¡}|  || j¡ |  jd7  _|  | j¡ d| _
|  jd7  _t| jd ƒd }|  || j¡ d	| _t| _ |  | j|| j¡S )
ad  
        Produce more bytes of the digest.

        .. note::
            You cannot use :meth:`update` anymore after the first call to
            :meth:`read`.

        Args:
            length (integer): the amount of bytes this method must return

        :return: the next piece of XOF output (of the given length)
        :rtype: byte string
        Fé   Tr   r)   r6   r   s   ÿÿé   )r   r   r0   r   r   r   r7   r9   r#   r<   r!   r3   r    r   r4   r"   r   )r%   r1   Zcustom_was_consumedr?   Útrailerr   r   r   ÚreadÃ   s0   



zK12_XOF.readNr   c                 C   s   t | ƒ||ƒS )N)Útyper$   r   r   r   Únewó   s   zK12_XOF.new)Nr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r(   r   r0   r3   r4   r#   rC   rE   r   r   r   r   r   9   s    
I0r   Nc                 C   s
   t | |ƒS )ag  Return a fresh instance of a KangarooTwelve object.

    Args:
       data (bytes/bytearray/memoryview):
        Optional.
        The very first chunk of the message to hash.
        It is equivalent to an early call to :meth:`update`.
       custom (bytes):
        Optional.
        A customization byte string.

    :Return: A :class:`K12_XOF` object
    )r   )r&   r'   r   r   r   rE   ÷   s   
rE   )NN)ZCryptodome.Util._raw_apir   r   r   r   r   r   r   ZCryptodome.Util.numberr	   ZCryptodome.Util.py3compatr
   Zkeccakr   r   r   r9   r<   r7   Úobjectr   rE   r   r   r   r   Ú<module>   s   $	 ?