
    XR_B7              
       N   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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                   d    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   Nc           	          t          t          |           j        di |}|Xt          |t          j                  rt          |          }|                    ||                    d                    |_	        	 t          j        d| j        z  | j	        | j                   n># t          $ r1}t          t          dt!          |          z                       d }~ww xY w|S )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        9/usr/lib/python3/dist-packages/passlib/handlers/scrypt.pyr    zscrypt.using   s    )vs##)11D11!*b&<== - __
 & 7 7
DHHU^L_L_ 7 ` `F	bQ#"44cncoVVVV 	b 	b 	b ,TWZ[^W_W_,_!`!`aaa	b s   =(B& &
C!0,CC!c                 8     | di |                      |          S )Nr   )parse)r,   hashs     r1   from_stringzscrypt.from_string   s"    s%%SYYt__%%%    c                     |                      |          \  }}t          | d|                    t                    z  d           }|r ||          S t          j                            |           )Nz_parse_%s_string)_parse_identgetattrstrip_UDOLLARr"   excInvalidHashError)r,   r4   r   suffixfuncs        r1   r3   zscrypt.parse   sh    ((..vs.X1F1FFMM 	/4<<&))#...r6   c                 8   |                     d          }t          |          dk    r|\  }}}n;t          |          dk    r|\  }}d }n t          j                            | d          |                     d          }t          |          dk    rL|\  }}}|                    d          sJ |                    d          sJ |                    d          sJ n t          j                            | d	          t          t          t          |dd                    t          |dd                    t          |dd                    t          |
                    d
                    |r"t          |
                    d
                    n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   s    S!!u::??#( FD&&ZZ1__ LFDFF&++C1ABBB S!!u::??$D$??5)))))??4(((((??4((((((&++C1KLLLtABBx==48}}DHT[[1122<BL[w!7!7888   	r6   c           
      f   |                     d                              d          }t          |          dk    r|\  }}n8t          |          dk    r|\  }d }nt          j                                        t          |          dk     r t          j                            | d          t          t          t          j	        |d d                   t          j
        |dd                   t          j
        |dd                   |dd          |rt          j        |          n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2u::??"NFFFZZ1__GFFF&++--- v;;&++C1IJJJ?6"1":..'qs44("6617AS%f---T
 
 
 	
r6   c                    | j         }|t          k    rWd| j        | j        | j        t          t          | j                            t          t          | j                            fz  S |t          k    sJ | j        }	 |
                    d           n*# t          $ r t          t          d                    w xY wt          d                    dt          j        | j                  t          j        | j                  t          j        | j                  | j        dt          j        | j                  g                    S )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455k$-88996   G####9DlG$$$$% l l l$%89i%j%jkkkl ,, 11 !122	 //+ " "   s   ?B 'B<c                      t          t          |           j        di | |&t          j        | | j        | j        d          sJ d S |                     |          | _        d S )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?DDY3?A A A A A A A A #33J??DOOOr6   Fc                 4    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                     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13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   anyc                 l    	 |                      |d           dS # t          j        j        $ r Y dS w xY w)NTdryrunF)set_backendr"   r<   MissingBackendError)r,   names     r1   has_backendzscrypt.has_backendX  sI    	OODO...4v) 	 	 	55	s    33c                 2    t          j        ||           d S )Nr|   )r'   _set_backend)r,   r   r}   s      r1   r~   zscrypt.set_backend`  s    T&11111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  sO    &111~fdiA4D $ 09KM M M 	Mr6   c                     | 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.
        Tr   )r   typer   r   _calc_needs_update)rf   r-   r0   s     r1   r   zscrypt._calc_needs_updatep  sC    
 ?d4jj33345uVT""5=====r6   rq   )F)rz   )rz   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   !   s'       > >N DXL M
 !M '*L
 M NJJK K J      [& & & [& / / [/&   [Z 
 
 [
:  <@ @ @ @ @ @ \ \ \ [\     & & ]&   [    [ 2 2 2 [2M M 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      sd   5 5 7 6 6 6 6 6 6 6 'g'11 - , , , , , ' ' ' ' ' ' ' ' > > > > > > > > > > A A A A A A A A A A - - - - - - # # # # # # # # #  q}}
!E((1S66
V> V> V> V> V>R ",r?PRTRbV> V> V> V> V>r6   