
    g%                         S r SSKJr  SSKr\R                  " \5      rSSKJr  SSK	J
r
  SSKJr  SSKJr  SS	/rS
rSrSrS rSrSS jrSqSqSS jrS rS rS rSr\" \\\S9rSS jr\" S5        S r g)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                     US:  a  [        SU-  5      eUS:  a  [        SU-  5      eX-  [        :  a  [        SU< SU< 35      eU S:  d  X S-
  -  (       a  [        SU -  5      eg)	a-  
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      W/home/matz/Project1/venv/lib/python3.13/site-packages/passlib/crypto/scrypt/__init__.pyr   r   )   sr     	1u.2331u.233uv~ !DEE1uU@1DEE       c                 P    USU-  SU S-   -  [         -  -   -  n[        XC-  5      nU$ )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   s5    " #'B!a%L;667F FMr   c                     [        X#U5        [        U SS9n [        USS9nUS:  a  [        S5      eU[        :  a  [        S[        -  5      e[	        XX#XE5      $ )a  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   sb    R Q1fH-FD'Dz455
:ZGHH6q11r   c                  ~    [         (       a  SOSn [        SU -  [        R                  5        SSKJn  UR                  $ )z<
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?     TrsH 
#%-
./2/I/IK 'r   c                       SSK Jn   U $ ! [         a     Of = f SSK n[        S[        R
                  5        g! [         a3  nS[        U5      ;  a  [        S[        R
                  5         SnAgSnAff = f)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!   
 
: 
A7)A22A7c                  B   ^  SSK Jm  U4S jn U $ ! [         a     gf = f)zZ
Attempt to load stdlib scrypt() implement and return wrapper.
Returns None if not found.
r   )r	   Nc           
      F   > [         nUS:  a  [        X#U5      nT" XX#XEUS9$ )Nr   )passwordr!   r   r   r   dklenr   )SCRYPT_MAXMEMr   )r   r!   r   r   r   r$   r   stdlib_scrypts          r   stdlib_scrypt_wrapper3_load_stdlib_backend.<locals>.stdlib_scrypt_wrapper   s3     A:$Q1-Ff1Q$*, 	,r   )hashlibr	   r0   )r;   r:   s    @r   _load_stdlib_backendr>      s,    
3,$ ! +  s    
)stdlibr	   builtinc                 j   U S:X  a  gU S:X  a-  [          H  n  [        XS9s  $    [        R                  " S5      e[        R                  U 5      nU(       d  [        SU < 35      eU" 5       nU(       d  [        R                  " SU -  5      eU(       a  gU qUqg! [        R                   a     M  f = f)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   loaderr/   s       r   rG   rG      s     u}		"D#D88 #
 %%&DEE!%%d+TCDDx))*Kd*RSS ** s   BB21B2rC   c                 N     [        U SS9  g! [        R                   a     gf = f)NTrD   F)rG   r   rH   )rL   s    r   _has_backendrO     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#   rK   r	   r-   r4   r>   rF   dictrI   rG   rO    r   r   <module>r]      s    ' g''1   " % 
  "
 
8 <  02f	 2!B 1 ! > Y r   