
    lg%                         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 dS )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          k    rt          d|d|          | dk     s| | dz
  z  rt          d| z            dS )	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      Y/var/www/html/nourish/venv/lib/python3.11/site-packages/passlib/crypto/scrypt/__init__.pyr   r   )   s     	1uu.23331uu.23331uv~~ j!!DEEE1uuQUu@1DEEE4       ?c                 \    |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   s:    " #'B!a%L;667F%  FMr   r   r   c                     t          |||           t          | d          } t          |d          }|dk     rt          d          |t          k    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   s    R Q1fH---FD'''Dzz4555
:ZGHHH64Aq&111r   c                  l    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.      sW     "rrsH 
#%-
./2/IK K K '&&&&&r   c                      	 ddl m}  | S # t          $ r Y nw xY w	 ddl }t          dt          j                   nB# t          $ r5}dt          |          vrt          dt          j                   Y d}~nd}~ww xY wdS )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	   r0   ImportErrorr   r   PasslibWarningstr)r0   r	   errs      r   _load_cffi_backendr5      s    
   
Z 	DcFXYYYY  % % %3s88## ]#% % %	% 4s!   
 
: 
A9+A44A9c                  D    	 ddl m n# t          $ r Y dS w xY wfd} | S )zf
    Attempt to load stdlib scrypt() implement and return wrapper.
    Returns None if not found.
    r   )r	   Nc           	      d    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   sL     A::$Q1--F}f41Qf$*, , , 	,r   )hashlibr	   r1   )r<   r;   s    @r   _load_stdlib_backendr>      s`    
3333333   tt, , , , ,$ ! s   
 
)stdlibr	   builtinFc                 `   | dk    rdS | dk    rFt           D ]*} 	 t          | |          c S # t          j        $ r Y 'w xY wt          j        d          t                              |           }|st          d|            |            }|st          j        d| z            |rdS | a|adS )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$   )namerE   loaderr0   s       r   rG   rG      s     u}}			" 	 	D#D888888*   %&DEEE!%%d++ 	E*TTCDDDvxx 	T)*Kd*RSSS 	Fs   ,>>rC   c                 V    	 t          | d           dS # t          j        $ r Y dS w xY w)NTrD   F)rG   r   rH   )rL   s    r   _has_backendrO     sD    T$''''t"   uus    (()r   )r   r   )F)!__doc__
__future__r   logging	getLogger__name__logwarningsr   passlibr   passlib.utilsr   passlib.utils.compatr   __all__r:   r#   r   r   r   r   r$   rK   r	   r.   r5   r>   rF   dictrI   rG   rO    r   r   <module>r]      s    ' & & & & & 'g'11             " " " " " " % % % % % % 
  "
 
  8    <  02 02 02 02f	  	  	   2! ! !B 1 4!      > Y       r   