
     h%                         d Z ddlmZ ddlZ ej                  e      ZddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	gZd
ZdZdZd ZdZddZdadaddZd Zd Zd ZdZ eeee      ZddZ ed       d Z y)zg
passlib.utils.scrypt -- scrypt hash frontend and help utilities

XXX: add this module to public docs?
    )absolute_importN)warn)exc)to_bytes)PYPYvalidatescryptl    i?c                     |dk  rt        d|z        |dk  rt        d|z        ||z  t        kD  rt        d|d|      | dk  s| | dz
  z  rt        d| z        y)	aI  
    helper which validates a set of scrypt config parameters.
    scrypt will take ``O(n * r * p)`` time and ``O(n * r)`` memory.
    limitations are that ``n = 2**<positive integer>``, ``n < 2**(16*r)``, ``r * p < 2 ** 30``.

    :param n: scrypt rounds
    :param r: scrypt block size
    :param p: scrypt parallel factor
       zr must be > 0: r=%rzp must be > 0: p=%rzr * p must be < 2**30: r=z, p=   z%n must be > 1, and a power of 2: n=%rT)
ValueErrorMAX_RP)nrps      `/var/www/html/Resume-Scraper/venv/lib/python3.12/site-packages/passlib/crypto/scrypt/__init__.pyr   r   )   sv     	1u.2331u.2331uv~ !DEE1uQU@1DEE       c                 R    |d|z  d| dz   z  t         z  z   z  }t        ||z        }|S )a?  
    calculate memory required for parameter combination.
    assumes parameters have already been validated.

    .. warning::
        this is derived from OpenSSL's scrypt maxmem formula;
        and may not be correct for other implementations
        (additional buffers, different parallelism tradeoffs, etc).
           r   )UINT32_SIZEint)r   r   r   fudgemaxmems        r   estimate_maxmemr   H   s7    " #'B!a%L;667F% FMr   c                     t        |||       t        | d      } t        |d      }|dk  rt        d      |t        kD  rt        dt        z        t	        | |||||      S )a4  run SCrypt key derivation function using specified parameters.

    :arg secret:
        passphrase string (unicode is encoded to bytes using utf-8).

    :arg salt:
        salt string (unicode is encoded to bytes using utf-8).

    :arg n:
        integer 'N' parameter

    :arg r:
        integer 'r' parameter

    :arg p:
        integer 'p' parameter

    :arg keylen:
        number of bytes of key to generate.
        defaults to 32 (the internal block size).

    :returns:
        a *keylen*-sized bytes instance

    SCrypt imposes a number of constraints on it's input parameters:

    * ``r * p < 2**30`` -- due to a limitation of PBKDF2-HMAC-SHA256.
    * ``keylen < (2**32 - 1) * 32`` -- due to a limitation of PBKDF2-HMAC-SHA256.
    * ``n`` must a be a power of 2, and > 1 -- internal limitation of scrypt() implementation

    :raises ValueError: if the provided parameters are invalid (see constraints above).

    .. warning::

        Unless the third-party ``scrypt <https://pypi.python.org/pypi/scrypt/>``_ package
        is installed, passlib will use a builtin pure-python implementation of scrypt,
        which is *considerably* slower (and thus requires a much lower / less secure
        ``n`` value in order to be usuable). Installing the :mod:`!scrypt` package
        is strongly recommended.
    secret)paramsaltr   zkeylen must be at least 1zkeylen too large, must be <= %d)r   r   r   
MAX_KEYLEN_scrypt)r   r!   r   r   r   keylens         r   r	   r	   k   sj    R Q1fH-FD'Dz455
:ZGHH64Aq&11r   c                  t    t         rdnd} t        d| z  t        j                         ddlm} |j                  S )zD
    Load pure-python scrypt implementation built into passlib.
    
   d   zUsing builtin scrypt backend, which is %dx slower than is required for adequate security. Installing scrypt support (via 'pip install scrypt') is strongly recommendedr   )ScryptEngine)r   r   r   PasslibSecurityWarning_builtinr(   execute)slowdownr(   s     r   _load_builtin_backendr-      s=     rsH 
#%-
./2/I/IK 'r   c                      	 ddl m}  | S # t        $ r Y nw xY w	 ddl }t        dt        j
                         y# t        $ r1}dt        |      vrt        dt        j
                         Y d}~yd}~ww xY w)z
    Try to import the ctypes-based scrypt hash function provided by the
    ``scrypt <https://pypi.python.org/pypi/scrypt/>``_ package.
    r   )hashNz5'scrypt' package is too old (lacks ``hash()`` method)r	   zJ'scrypt' package failed to import correctly (possible installation issue?))r	   r/   ImportErrorr   r   PasslibWarningstr)r/   r	   errs      r   _load_cffi_backendr4      sz    
 
Z 	DcFXFXY  %3s8# ]##%
 %s!   
 	9 	A3'A..A3c                  >    	 ddl m fd} | S # t        $ r Y yw xY w)zf
    Attempt to load stdlib scrypt() implement and return wrapper.
    Returns None if not found.
    r   )r	   Nc           	      R    t         }|dk  rt        |||      } | ||||||      S )Nr   )passwordr!   r   r   r   dklenr   )SCRYPT_MAXMEMr   )r   r!   r   r   r   r$   r   stdlib_scrypts          r   stdlib_scrypt_wrapperz3_load_stdlib_backend.<locals>.stdlib_scrypt_wrapper   s;     A:$Q1-Ff41Qf$*, 	,r   )hashlibr	   r0   )r;   r:   s    @r   _load_stdlib_backendr=      s,    
3,$ ! +  s    	)stdlibr	   builtinc                 D   | dk(  ry| dk(  r/t         D ]  } 	 t        | |      c S  t        j                  d      t        j                  |       }|st        d|        |       }|st        j                  d| z        |ry| a|ay# t        j                  $ r Y w xY w)z
    set backend for scrypt(). if name not specified, loads first available.

    :raises ~passlib.exc.MissingBackendError: if backend can't be found

    .. note:: mainly intended to be called by unittests, and scrypt hash handler
    anyNdefaultdryrunzno scrypt backends availablezunknown scrypt backend: zscrypt backend %r not available)	backend_values_set_backendr   MissingBackendError_backend_loadersgetr   backendr#   )namerD   loaderr/   s       r   rF   rF      s     u}		" 	D#D88	
 %%&DEE!%%d+TCDDx))*Kd*RSS ** s   B		BBrB   c                 R    	 t        | d       y# t        j                  $ r Y yw xY w)NTrC   F)rF   r   rG   )rK   s    r   _has_backendrN     s,    T$'"" s    &&)g?)r   r   )F)!__doc__
__future__r   logging	getLogger__name__logwarningsr   passlibr   passlib.utilsr   passlib.utils.compatr   __all__r9   r"   r   r   r   r   r#   rJ   r	   r-   r4   r=   rE   dictrH   rF   rN    r   r   <module>r\      s    ' 'g''1   " % 
  "
 
8 <  02f	 2!B 1 ! > Y r   