o
    5hB7                  	   @   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salt	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uhnative_string_typesint_norm_block_sizegetr   _scryptvalidatedefault_roundsr   
ValueErrorr   str)clsr   kwdssubclserr	__class__r   k/var/www/html/construction_image-detection-poc/venv/lib/python3.10/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)_parse_identgetattrstrip_UDOLLARr   excInvalidHashError)r)   r1   r   suffixfuncr   r   r/   r0      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   r8   MalformedHashError
startswithdictIDENT_SCRYPTr!   r   encode)	r)   r:   partsparamsr   digestnstr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?      $r=   r      zparams field too short   r@   )rH   rB   rC   r   r8   rD   rF   IDENT_7r   decode_int6decode_int30decode_bytes)r)   r:   rI   rJ   rK   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$rP   )r   rG   r   r   r   r
   r   r   rA   rS   decodeUnicodeDecodeErrorr   NotImplementedErrorjoinr   encode_int6encode_int30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   validate_default_valuer   r"   )r`   r   r*   r-   r   r/   rd   1  s   zscrypt.__init__Fc                 C   s   t j| |dd|dS )Nr   r   )minrc   r   )r   norm_integer)r)   r   r   r   r   r/   r"   >  r3   zscrypt._norm_block_sizec                    s$   t t|  }| jtkrt|}|S N)r   r   _generate_saltr   rS   r   )r`   r   r-   r   r/   ri   B  s   
zscrypt._generate_saltc                 C      t jS rh   )r$   backend_valuesr)   r   r   r/   backendsP     zscrypt.backendsc                 C   rj   rh   )r$   backendrl   r   r   r/   get_backendT  rn   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   r8   MissingBackendError)r)   namer   r   r/   has_backendX  s   zscrypt.has_backendc                 C   s   t j||d d S )Nrr   )r$   _set_backend)r)   rv   rs   r   r   r/   rt   `  s   zscrypt.set_backendc                 C   s0   t |dd}tj|| jd| j> | j| j| jdS )Nsecretrb   r   )nrpkeylen)r   r$   r   r   r   r   r   checksum_size)r`   ry   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)r`   r*   r-   r   r/   r   p  s   zscrypt._calc_needs_updaterh   )F)rq   )rq   F)%__name__
__module____qualname____doc__rv   setting_kwdsr~   rG   default_identrS   ident_valuesdefault_salt_sizemax_salt_sizer&   
min_rounds
max_roundsrounds_costr   r   classmethodr   r2   r0   rO   rW   ra   rd   r"   ri   r   rm   rp   rw   rt   r   r   __classcell__r   r   r-   r/   r   !   sP    G		


-


	)%r   
__future__r   r   logging	getLoggerr   logpasslib.cryptor   r$   passlib.utilsr   r   passlib.utils.binaryr   r   passlib.utils.compatr	   r
   r   passlib.utils.decorr   passlib.utils.handlersutilshandlersr   __all__rG   rS   r7   ParallelismMixin	HasRounds
HasRawSaltHasRawChecksumHasManyIdentsGenericHandlerr   r   r   r/   <module>   s"    