o
    Œõ±j²  ã                   @   s(  d dl mZmZmZmZ d dlZd dlZd dlmZ ddlm	Z	 ddl
mZ ddlmZmZmZ ddlmZ dd	lmZmZ e	ƒ Zed
krNddlmZmZ n!edksVedkrgddlmZmZ ddlmZmZ nddlmZmZ g d¢Zejdkr�dd„ Z dd„ Z!ndd„ Z dd„ Z!ddd„Z"dd„ Z#dS )é    )Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionN)Údatetimeé   )Úbackend)Ú
rand_bytes)Ú	type_nameÚbyte_clsÚ	int_types)Úpretty_message)ÚnewÚderefÚmac)Úpbkdf2Ú
pkcs12_kdfÚwinÚ	winlegacy)Úkernel32Úhandle_error)Úpbkdf1r   Úpbkdf2_iteration_calculatorr   Úwin32c                  C   s$   t tdƒ} t | ¡}t|ƒ t| ƒS )NzLARGE_INTEGER *)r   r   ÚQueryPerformanceCounterr   r   )ÚnumberÚres© r   ú/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/oscrypto/kdf.pyÚ
_get_start$   s   

r   c                 C   s   t ƒ |  }t|d ƒS )Ng     @�@)r   Úint)ÚstartÚlengthr   r   r   Ú_get_elapsed*   s   
r#   c                   C   s   t  ¡ S )N)r   Únowr   r   r   r   r   /   s   c                 C   s:   t  ¡ |  }|j|jd d  }|jd }t||d  ƒS )Né   i  iè  )r   r$   ÚsecondsÚdaysÚmicrosecondsr    )r!   r"   r&   Úmillisecondsr   r   r   r#   2   s   
éd   Fc                    s(  ˆ t g d¢ƒvrttdtˆ ƒƒƒ‚tˆtƒsttdtˆƒƒƒ‚ˆdk r,ttdtˆƒƒƒ‚tˆtƒs:ttdtˆƒƒƒ‚ˆdk rGttdtˆƒƒƒ‚tj	rPt
tdƒƒ‚d	‰d
 d¡‰tˆƒ‰‡ ‡‡‡‡‡‡fdd„}|ƒ }tˆ| d ƒ‰|ƒ }ˆ| ‰ˆdk rdnd}ttˆ|ƒƒ}|dkr’|d d }|S )aß  
    Runs pbkdf2() twice to determine the approximate number of iterations to
    use to hit a desired time per run. Use this on a production machine to
    dynamically adjust the number of iterations as high as you can.

    :param hash_algorithm:
        The string name of the hash algorithm to use: "md5", "sha1", "sha224",
        "sha256", "sha384", "sha512"

    :param key_length:
        The length of the desired key in bytes

    :param target_ms:
        The number of milliseconds the derivation should take

    :param quiet:
        If no output should be printed as attempts are made

    :return:
        An integer number of iterations of PBKDF2 using the specified hash
        that will take at least target_ms
    )Úsha1Úsha224Úsha256Úsha384Úsha512zz
            hash_algorithm must be one of "sha1", "sha224", "sha256", "sha384",
            "sha512", not %s
            ú?
            key_length must be an integer, not %s
            r   úC
            key_length must be greater than 0 - is %s
            z>
            target_ms must be an integer, not %s
            zB
            target_ms must be greater than 0 - is %s
            z€
            Only a very slow, pure-python version of PBKDF2 is available,
            making this function useless
            i'  zthis is a testzutf-8c                     s>   t ƒ } tˆ ˆˆˆˆƒ t| ƒ}ˆstdˆ|f ƒ dˆ | S )Nz%s iterations in %smsg      ð?)r   r   r#   Úprint)r!   Úobserved_ms©Úhash_algorithmÚ
iterationsÚ
key_lengthÚpasswordÚquietÚsaltÚ	target_msr   r   Ú_measure†   s   z-pbkdf2_iteration_calculator.<locals>._measureg       @i † éýÿÿÿéüÿÿÿi N  iˆ  )ÚsetÚ
ValueErrorr   ÚreprÚ
isinstancer   Ú	TypeErrorr
   r   Úpure_pythonÚOSErrorÚencoder	   r    Úround)r5   r7   r;   r9   r<   ÚfractionÚround_factorÚresultr   r4   r   r   9   sT   û
üü
üüÿ

r   c                 C   s\  t |tƒsttdt|ƒƒƒ‚t |tƒsttdt|ƒƒƒ‚t |tƒs*ttdt|ƒƒƒ‚|dk r7ttdt|ƒƒƒ‚t |tƒsEttdt|ƒƒƒ‚|dk rRttdt|ƒƒƒ‚| tg d¢ƒvrcttd	t| ƒƒƒ‚|d
krz| tddgƒv rzttd| t|ƒfƒƒ‚|dkr‹| dkr‹ttdt|ƒƒƒ‚t	t
| ƒ}||| ƒ ¡ }td|d ƒD ]}||ƒ ¡ }qŸ|d|… S )aF  
    An implementation of PBKDF1 - should only be used for interop with legacy
    systems, not new architectures

    :param hash_algorithm:
        The string name of the hash algorithm to use: "md2", "md5", "sha1"

    :param password:
        A byte string of the password to use an input to the KDF

    :param salt:
        A cryptographic random byte string

    :param iterations:
        The numbers of iterations to use when deriving the key

    :param key_length:
        The length of the desired key in bytes

    :return:
        The derived key as a byte string
    z@
            password must be a byte string, not %s
            z<
            salt must be a byte string, not %s
            z?
            iterations must be an integer, not %s
            r   zC
            iterations must be greater than 0 - is %s
            r0   r1   )Úmd2Úmd5r+   zT
            hash_algorithm must be one of "md2", "md5", "sha1", not %s
            é   rK   rL   zM
            key_length can not be longer than 16 for %s - is %s
            é   r+   zO
            key_length can not be longer than 20 for sha1 - is %s
            é   N)rB   r   rC   r   r
   r   r@   rA   r?   ÚgetattrÚhashlibÚdigestÚrange)r5   r8   r:   r6   r7   ÚalgoÚoutputÚ_r   r   r   r       sd   
ü
ü
üü
üüü
üü
r   )r*   F)$Ú
__future__r   r   r   r   ÚsysrQ   r   Ú r   Úutilr	   Ú_typesr
   r   r   Ú_errorsr   Ú_ffir   r   Ú_backendÚ	_mac.utilr   r   Ú	_win.utilÚ_win._kernel32r   r   Ú_openssl.utilÚ__all__Úplatformr   r#   r   r   r   r   r   r   Ú<module>   s0   


g