o
    _6dB7                  	   @   s   d Z ddlmZmZ ddlZeeZddlm	Z
 ddlmZmZ ddlmZmZmZ ddlmZmZmZ ddlmZ ddlm  mZ d	gZed
ZedZedZG dd	 d	ejej ej!ej"ej#ej$Z	dS )z/passlib.handlers.scrypt -- scrypt password hash    )with_statementabsolute_importN)scrypt)h64to_bytes)r   b64s_decodeb64s_encode)ubascii_to_strsuppress_cause)classpropertyr   z$scrypt$z$7$$c                       s  e Zd ZdZd ZdZdZeZee	fZ
dZdZdZdZdZdZdZd	Zed+ fdd	Zedd Zedd Zedd Zedd Zdd Zd+ fdd	Zed,ddZ fddZedd Zed d! Zed-d#d$Z ed.d%d&Z!d'd( Z" fd)d*Z#  Z$S )/r   a	  This class implements an SCrypt-based password [#scrypt-home]_ hash, and follows the :ref:`password-hash-api`.

    It supports a variable-length salt, a variable number of rounds,
    as well as some custom tuning parameters unique to scrypt (see below).

    The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords:

    :type salt: str
    :param salt:
        Optional salt string.
        If specified, the length must be between 0-1024 bytes.
        If not specified, one will be auto-generated (this is recommended).

    :type salt_size: int
    :param salt_size:
        Optional number of bytes to use when autogenerating new salts.
        Defaults to 16 bytes, but can be any value between 0 and 1024.

    :type rounds: int
    :param rounds:
        Optional number of rounds to use.
        Defaults to 16, but must be within ``range(1,32)``.

        .. warning::

            Unlike many hash algorithms, increasing the rounds value
            will increase both the time *and memory* required to hash a password.

    :type block_size: int
    :param block_size:
        Optional block size to pass to scrypt hash function (the ``r`` parameter).
        Useful for tuning scrypt to optimal performance for your CPU architecture.
        Defaults to 8.

    :type parallelism: int
    :param parallelism:
        Optional parallelism to pass to scrypt hash function (the ``p`` parameter).
        Defaults to 1.

    :type relaxed: bool
    :param relaxed:
        By default, providing an invalid value for one of the other
        keywords will result in a :exc:`ValueError`. If ``relaxed=True``,
        and the error can be corrected, a :exc:`~passlib.exc.PasslibHashWarning`
        will be issued instead. Correctable errors include ``rounds``
        that are too small or too large, and ``salt`` strings that are too long.

    .. note::

        The underlying scrypt hash function has a number of limitations
        on it's parameter values, which forbids certain combinations of settings.
        The requirements are:

        * ``linear_rounds = 2**<some positive integer>``
        * ``linear_rounds < 2**(16 * block_size)``
        * ``block_size * parallelism <= 2**30-1``

    .. todo::

        This class currently does not support configuring default values
        for ``block_size`` or ``parallelism`` via a :class:`~passlib.context.CryptContext`
        configuration.
    )identsaltZ	salt_sizerounds
block_sizeparallelism       i         log2   Nc              
      s   t t| jdi |}|d ur$t|tjrt|}|j||dd|_	zt
d| j> | j	| j W |S  tyI } z
ttdt| d }~ww )Nrelaxed)r   r   z&scrypt: invalid settings combination:  )superr   using
isinstanceuhZnative_string_typesint_norm_block_sizegetr   _scryptvalidatedefault_roundsr   
ValueErrorr   str)clsr   kwdssubclserr	__class__r   nC:\Users\jesus\OneDrive\Desktop\erpjis_fastapi\backend\jisbackend\Lib\site-packages\passlib/handlers/scrypt.pyr      s   zscrypt.usingc                 C   s   | di |  |S )Nr   )parse)r'   hashr   r   r-   from_string      zscrypt.from_stringc                 C   s<   |  |\}}t| d|t d }|r||S tj| )Nz_parse_%s_string)Z_parse_identgetattrstrip_UDOLLARr   excZInvalidHashError)r'   r/   r   suffixfuncr   r   r-   r.      s
   zscrypt.parsec           	   
   C   s   | d}t|dkr|\}}}nt|dkr|\}}d }ntj| d| d}t|dkrK|\}}}|ds<J |dsCJ |dsJJ ntj| d	ttt|dd  t|dd  t|dd  t	|
d
|rzt	|
d
dS d dS )Nr         zmalformed hash,zln=zr=zp=zmalformed settings fieldasciir   r   r   r   r   checksum)splitlenr   r5   MalformedHashError
startswithdictIDENT_SCRYPTr   r   encode)	r'   r6   partsparamsr   digestZnstrZbstrpstrr   r   r-   _parse_scrypt_string   s0   


zscrypt._parse_scrypt_stringc              	   C   s   | dd}t|dkr|\}}nt|dkr|\}d }ntj t|dk r1tj| dttt	|d d t
|dd t
|dd |dd  |rYt|dS d dS )	Nr;      $r9   r      zparams field too short   r<   )rD   r>   r?   r   r5   r@   rB   IDENT_7r   Zdecode_int6Zdecode_int30Zdecode_bytes)r'   r6   rE   rF   rG   r   r   r-   _parse_7_string   s&   


zscrypt._parse_7_stringc                 C   s   | j }|tkrd| j| j| jtt| jtt| jf S |t	ks#J | j}z|
d W n ty:   ttdw tddt| jt| jt| j| jdt| jgS )Nz$scrypt$ln=%d,r=%d,p=%d$%s$%sr;   z.scrypt $7$ hashes dont support non-ascii salts    s   $7$rJ   )r   rC   r   r   r   r
   r   r   r=   rM   decodeUnicodeDecodeErrorr   NotImplementedErrorjoinr   Zencode_int6Zencode_int30Zencode_bytes)selfr   r   r   r   r-   	to_string  s2   



zscrypt.to_stringc                    sL   t t| jdi | |d u rtj| | j| jddsJ d S | || _d S )Nr   paramr   )r   r   __init__r   Zvalidate_default_valuer   r    )rT   r   r(   r+   r   r-   rX   1  s   zscrypt.__init__Fc                 C   s   t j| |dd|dS )Nr   r   )minrW   r   )r   Znorm_integer)r'   r   r   r   r   r-   r    >  r1   zscrypt._norm_block_sizec                    s$   t t|  }| jtkrt|}|S N)r   r   _generate_saltr   rM   r   )rT   r   r+   r   r-   r[   B  s   
zscrypt._generate_saltc                 C      t jS rZ   )r"   Zbackend_valuesr'   r   r   r-   backendsP     zscrypt.backendsc                 C   r\   rZ   )r"   backendr]   r   r   r-   get_backendT  r_   zscrypt.get_backendanyc                 C   s.   z
| j |dd W dS  tjjy   Y dS w )NTdryrunF)set_backendr   r5   ZMissingBackendError)r'   namer   r   r-   has_backendX  s   zscrypt.has_backendc                 C   s   t j||d d S )Nrc   )r"   Z_set_backend)r'   rf   rd   r   r   r-   re   `  s   zscrypt.set_backendc                 C   s0   t |dd}tj|| jd| j> | j| j| jdS )NsecretrV   r   )nrpZkeylen)r   r"   r   r   r   r   r   checksum_size)rT   rh   r   r   r-   _calc_checksumg  s   zscrypt._calc_checksumc                    s*   | j t| j kr
dS tt| jdi |S )zR
        mark hash as needing update if rounds is outside desired bounds.
        TNr   )r   typer   r   _calc_needs_update)rT   r(   r+   r   r-   ro   p  s   zscrypt._calc_needs_updaterZ   )F)rb   )rb   F)%__name__
__module____qualname____doc__rf   Zsetting_kwdsrl   rC   Zdefault_identrM   Zident_valuesZdefault_salt_sizeZmax_salt_sizer$   Z
min_rounds
max_roundsZrounds_costr   r   classmethodr   r0   r.   rI   rN   rU   rX   r    r[   r   r^   ra   rg   re   rm   ro   __classcell__r   r   r+   r-   r   !   sP    G		


-


	)%rs   
__future__r   r   logging	getLoggerrp   logZpasslib.cryptor   r"   Zpasslib.utilsr   r   Zpasslib.utils.binaryr   r   Zpasslib.utils.compatr	   r
   r   Zpasslib.utils.decorr   Zpasslib.utils.handlersutilshandlersr   __all__rC   rM   r4   ZParallelismMixinZ	HasRoundsZ
HasRawSaltZHasRawChecksumZHasManyIdentsZGenericHandlerr   r   r   r-   <module>   s"    