
    gB7              
       t   S r SSKJrJr  SSKr\R
                  " \5      rSSKJ	r
  SSKJrJr  SSKJrJrJr  SSKJrJrJr  SSKJr  SSKJs  Jr  S	/r\" S
5      r\" S5      r\" S5      r " S S	\R>                  \R@                  \RB                  \RD                  \RF                  \RH                  5      r	g)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                   B  ^  \ rS rSrSrS rSrSr\r	\\
4rSrSrSrSrSrS	rSrS
r\SU 4S jj5       r\S 5       r\S 5       r\S 5       r\S 5       rS rSU 4S jjr\SS j5       rU 4S jr\S 5       r\S 5       r \SS j5       r!\SS j5       r"S r#U 4S jr$Sr%U =r&$ )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           	        > [         [        U ]
  " S0 UD6nUbM  [        U[        R
                  5      (       a  [        U5      nUR                  XR                  S5      S9Ul	         [        R                  " SU R                  -  U R                  U R                  5        U$ ! [         a%  n[        [        S[!        U5      -   5      5      eS nAff = f)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        P/home/matz/Project1/venv/lib/python3.13/site-packages/passlib/handlers/scrypt.pyr!   scrypt.using   s    vs)1D1!*b&<&<== _
 & 7 7
HHU^L_ 7 `F	bQ#"4"44cnncooV   	b ,TWZ[^W_,_!`aa	bs   '9B" "
C, CCc                 0    U " S0 U R                  U5      D6$ )Nr   )parse)r-   hashs     r2   from_stringscrypt.from_string   s    %SYYt_%%    c                     U R                  U5      u  p#[        U SUR                  [        5      -  S 5      nU(       a  U" U5      $ [        R
                  R                  U 5      e)Nz_parse_%s_string)_parse_identgetattrstrip_UDOLLARr#   excInvalidHashError)r-   r6   r   suffixfuncs        r2   r5   scrypt.parse   sS    ((.s.X1FFM<&&))#..r9   c                    UR                  S5      n[        U5      S:X  a  Uu  p4nO6[        U5      S:X  a  Uu  p4S nO [        R                  R	                  U S5      eUR                  S5      n[        U5      S:X  aN  Uu  pgnUR                  S5      (       d   eUR                  S5      (       d   eUR                  S5      (       d   eO [        R                  R	                  U S	5      e[        [        [        USS  5      [        USS  5      [        USS  5      [        UR                  S
5      5      U(       a  [        UR                  S
5      5      S9$ S S9$ )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-   rA   partsparamsr   digestnstrbstrpstrs	            r2   _parse_scrypt_stringscrypt._parse_scrypt_string   s>    S!u:?#( F&Z1_ LF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 	r9   c           
      "   UR                  S5      R                  S5      n[        U5      S:X  a  Uu  p4O4[        U5      S:X  a  Uu  nS nO[        R                  R                  5       e[        U5      S:  a   [        R                  R                  U S5      e[        [        [        R                  " US S 5      [        R                  " USS 5      [        R                  " USS 5      USS  U(       a  [        R                  " U5      S9$ S S9$ )	NrH      $rF   r      zparams field too short   rI   )rQ   rK   rL   r#   r?   rM   rO   IDENT_7r   decode_int6decode_int30decode_bytes)r-   rA   rR   rS   rT   s        r2   _parse_7_string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
 	
r9   c                    U R                   nU[        :X  a`  SU R                  U R                  U R                  [        [        U R                  5      5      [        [        U R                  5      5      4-  $ U[        :X  d   eU R                  n UR                  S5        [        SR                  S[        R                   " U R                  5      [        R"                  " U R                  5      [        R"                  " U R                  5      U R                  S[        R$                  " U R                  5      /5      5      $ ! [         a    [        [        S5      5      ef = f)Nz$scrypt$ln=%d,r=%d,p=%d$%s$%srH   z.scrypt $7$ hashes dont support non-ascii saltsr9   s   $7$r[   )r   rP   r   r   r   r   r	   r   rJ   r^   decodeUnicodeDecodeErrorr   NotImplementedErrorjoinr   encode_int6encode_int30encode_bytes)selfr   r   s      r2   	to_string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   E E#c                    > [         [        U ]
  " S0 UD6  Uc2  [        R                  " X R
                  U R                  SS9(       d   eg U R                  U5      U l        g )Nr   paramr   )r    r   __init__r#   validate_default_valuer   r&   )rl   r   r.   r1   s      r2   rr   scrypt.__init__1  s]    fd$,t, ,,T??DDYDY3?A A A #33J?DOr9   c                 0    [         R                  " XSSUS9$ )Nr   r   )minrq   r   )r#   norm_integer)r-   r   r   s      r2   r&   scrypt._norm_block_size>  s    sA\SZ[[r9   c                 j   > [         [        U ]  5       nU R                  [        :X  a  [        U5      nU$ N)r    r   _generate_saltr   r^   r	   )rl   r   r1   s     r2   r{   scrypt._generate_saltB  s/    VT13::  t$Dr9   c                 "    [         R                  $ rz   )r(   backend_valuesr-   s    r2   backendsscrypt.backendsP  s    %%%r9   c                 "    [         R                  $ rz   )r(   backendr   s    r2   get_backendscrypt.get_backendT  s    r9   c                 n     U R                  USS9  g! [        R                  R                   a     gf = f)NTdryrunF)set_backendr#   r?   MissingBackendError)r-   names     r2   has_backendscrypt.has_backendX  s6    	OODO.vv)) 		s    44c                 ,    [         R                  " XS9  g )Nr   )r(   _set_backend)r-   r   r   s      r2   r   scrypt.set_backend`  s    T1r9   c           	          [        USS9n[        R                  " XR                  SU R                  -  U R
                  U R                  U R                  S9$ )Nsecretrp   r   )nrpkeylen)r   r(   r   r   r   r   r   checksum_size)rl   r   s     r2   _calc_checksumscrypt._calc_checksumg  sI    &1~~fiiA4D $ 0 09K9KM 	Mr9   c                 t   > U R                   [        U 5      R                   :w  a  g[        [        U ]  " S0 UD6$ )zB
mark hash as needing update if rounds is outside desired bounds.
Tr   )r   typer    r   _calc_needs_update)rl   r.   r1   s     r2   r   scrypt._calc_needs_updatep  s3    
 ??d4j333VT5===r9   )r   rz   )F)any)r   F)'__name__
__module____qualname____firstlineno____doc__r   setting_kwdsr   rP   default_identr^   ident_valuesdefault_salt_sizemax_salt_sizer*   
min_rounds
max_roundsrounds_costr   r   classmethodr!   r7   r5   rX   rb   rm   rr   r&   r{   r   r   r   r   r   r   r   __static_attributes____classcell__)r1   s   @r2   r   r   !   sI   >N DXL M
 !M '*L
 M NJJK K J  & & & / /&  Z 
 
:<@ \ \ & &     2 2M> >r9   )%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__rP   r^   r>   ParallelismMixin	HasRounds
HasRawSaltHasRawChecksumHasManyIdentsGenericHandlerr   r9   r2   <module>r      s    5 7 g''1 - ' > > A A - # #  }
E(S6
V>R  ",,r?P?PRTRbRbV>r9   