
     hB7              
       t   d Z ddlmZmZ ddlZ ej
                  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c mZ d	gZ ed
      Z ed      Z ed      Z G d d	ej>                  ej@                  ejB                  ejD                  ejF                  ejH                        Z	y)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                   (    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
	       Zed        Zed        Zed        Zed        Zd Zd fd	Zedd       Z fdZed        Zed        Zedd       Z edd       Z!d Z" fdZ# x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   c           	         t        t        | 
  di |}|Lt        |t        j
                        rt        |      }|j                  ||j                  d            |_	        	 t        j                  d| j                  z  | j                  | j                         |S # t        $ r%}t        t        dt!        |      z               d }~ww xY 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__s        Y/var/www/html/Resume-Scraper/venv/lib/python3.12/site-packages/passlib/handlers/scrypt.pyr    zscrypt.using   s    vs)1D1!*b&<&<= _
 & 7 7
DHHU^L_ 7 `F	bQ#"4"44cnncooV   	b ,TWZ[^W_,_!`aa	bs   $8B 	C' CCc                 0     | di | j                  |      S )Nr   )parse)r,   hashs     r1   from_stringzscrypt.from_string   s    %SYYt_%%    c                     | j                  |      \  }}t        | d|j                  t              z  d       }|r ||      S t        j
                  j                  |       )Nz_parse_%s_string)_parse_identgetattrstrip_UDOLLARr"   excInvalidHashError)r,   r4   r   suffixfuncs        r1   r3   zscrypt.parse   sU    ((.vs.X1FFM<&&))#..r6   c                    |j                  d      }t        |      dk(  r|\  }}}n6t        |      dk(  r|\  }}d }n t        j                  j	                  | d      |j                  d      }t        |      dk(  r?|\  }}}|j                  d      sJ |j                  d      sJ |j                  d      s"J t        j                  j	                  | d	      t        t        t        |dd        t        |dd        t        |dd        t        |j                  d
            |rt        |j                  d
                  S 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"   r<   MalformedHashError
startswithdictIDENT_SCRYPTr$   r   encode)	r,   r>   partsparamsr   digestnstrbstrpstrs	            r1   _parse_scrypt_stringzscrypt._parse_scrypt_string   s2    S!u:?#( FD&Z1_ LFDF&&++C1ABB S!u:?$D$??5))??4((??4((&&++C1KLLtABx=48}DHT[[12<B[w!78 	 IM 	r6   c           
         |j                  d      j                  d      }t        |      dk(  r|\  }}n3t        |      dk(  r|\  }d }nt        j                  j                         t        |      dk  r t        j                  j                  | d      t        t        t        j                  |d d       t        j                  |dd       t        j                  |dd       |dd  |rt        j                  |            S d       S )	NrD      $rB   r      zparams field too short   rE   )rM   rG   rH   r"   r<   rI   rK   IDENT_7r   decode_int6decode_int30decode_bytes)r,   r>   rN   rO   rP   s        r1   _parse_7_stringzscrypt._parse_7_string   s     g&,,T2u:?"NFFZ1_GFF&&++-- v;&&++C1IJJ??6"1:.''q4(("617S%%f-
 	
 >B
 	
r6   c                    | j                   }|t        k(  r`d| j                  | j                  | j                  t        t        | j                              t        t        | j                              fz  S |t        k(  sJ | j                  }	 |j                  d       t        dj                  dt        j                   | j                        t        j"                  | j                        t        j"                  | j                        | j                  dt        j$                  | j                        g            S # t        $ r t        t        d            w xY w)Nz$scrypt$ln=%d,r=%d,p=%d$%s$%srD   z.scrypt $7$ hashes dont support non-ascii saltsr6   s   $7$rV   )r   rL   r   r   r   r   r	   r   rF   rY   decodeUnicodeDecodeErrorr   NotImplementedErrorjoinr   encode_int6encode_int30encode_bytes)selfr   r   s      r1   	to_stringzscrypt.to_string  s   

L 2  k$))45k$--896   G##99DlG$ !,  1  !1!12		  /+ "   & l$%89i%jkkls   D> >Ec                     t        t        | 
  di | |0t        j                  | | j
                  | j                  d      sJ y | j                  |      | _        y )Nr   paramr   )r   r   __init__r"   validate_default_valuer   r%   )rf   r   r-   r0   s      r1   rk   zscrypt.__init__1  s_    fd$,t, ,,T4??DDYDY3?A A A #33J?DOr6   c                 6    t        j                  | |dd|      S )Nr   r   )minrj   r   )r"   norm_integer)r,   r   r   s      r1   r%   zscrypt._norm_block_size>  s    sJA\SZ[[r6   c                 h    t         t        |          }| j                  t        k(  rt        |      }|S N)r   r   _generate_saltr   rY   r	   )rf   r   r0   s     r1   rr   zscrypt._generate_saltB  s/    VT13::  t$Dr6   c                 "    t         j                  S rq   )r'   backend_valuesr,   s    r1   backendszscrypt.backendsP  s    %%%r6   c                 "    t         j                  S rq   )r'   backendru   s    r1   get_backendzscrypt.get_backendT  s    r6   c                 r    	 | j                  |d       y# t        j                  j                  $ r Y yw xY w)NTdryrunF)set_backendr"   r<   MissingBackendError)r,   names     r1   has_backendzscrypt.has_backendX  s6    	OODO.vv)) 		s    66c                 2    t        j                  ||       y )Nr{   )r'   _set_backend)r,   r   r|   s      r1   r}   zscrypt.set_backend`  s    T&1r6   c                     t        |d      }t        j                  || j                  d| j                  z  | j
                  | j                  | j                        S )Nsecretri   r   )nrpkeylen)r   r'   r   r   r   r   r   checksum_size)rf   r   s     r1   _calc_checksumzscrypt._calc_checksumg  sK    &1~~fdiiA4D $ 0 09K9KM 	Mr6   c                 p    | j                   t        |       j                   k7  ryt        t        |   di |S )zR
        mark hash as needing update if rounds is outside desired bounds.
        Tr   )r   typer   r   _calc_needs_update)rf   r-   r0   s     r1   r   zscrypt._calc_needs_updatep  s3    
 ??d4j333VT5===r6   rq   )F)any)r   F)%__name__
__module____qualname____doc__r   setting_kwdsr   rL   default_identrY   ident_valuesdefault_salt_sizemax_salt_sizer)   
min_rounds
max_roundsrounds_costr   r   classmethodr    r5   r3   rT   r]   rg   rk   r%   rr   r   rv   ry   r   r}   r   r   __classcell__)r0   s   @r1   r   r   !   sI   >N DXL M
 !M '*L
 M NJJK K J  & & & / /&  Z 
 
:<@ \ \ & &     2 2M> >r6   )%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__rL   rY   r;   ParallelismMixin	HasRounds
HasRawSaltHasRawChecksumHasManyIdentsGenericHandlerr   r6   r1   <module>r      s    5 7 'g''1 - ' > > A A - # #  }
E(S6
V>R  ",,r?P?PRTRbRbV>r6   