U
    ;g"Y                     @   s  d dl mZmZmZmZ d dlZd dlZd dlZddlm	Z	 ddl
mZmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZmZ ddlmZ dd	lmZ ejd
k reZ e!Z"ndd Z e	 Z#e#dkre$ddddddgZ%ddddZ&d d ddZ'dd Z(dd Z)dd Z*dd Z+dd Z,dd Z-G d d! d!Z.G d"d# d#Z/e/dddZ0e.d$d%d&Z1e/e1d'd(d)Z2e.d*d%d+Z3e/e3d,d-d.Z4e.d/d%d0Z5e/e5d1d2d3Z6e.d4d%d5Z7e/e7d6d7d8Z8e.d9d%d:Z9e/e9d;d<d=Z:dS )>    )unicode_literalsdivisionabsolute_importprint_functionN   )backend)
CertificateDSASignatureECDomainParametersECPointBitStringECPrivateKeyint_from_bytesPrivateKeyAlgorithmPrivateKeyInfoPublicKeyAlgorithmPublicKeyInfo)pretty_message)	type_namebyte_cls)
rand_bytes)SignatureError)   c                 C   s
   t | gS )N)bytes)num r   3/tmp/pip-unpacked-wheel-x1gypflw/oscrypto/_ecdsa.pychr_cls   s    r   Z	winlegacyz2Pure-python ECDSA code is only for Windows XP/2003ec_generate_pairec_compute_public_key_pointec_public_key_info
ecdsa_signecdsa_verify    0   B   	secp256r1	secp384r1	secp521r1   c                 C   s   | t dddgkr$ttdt| t|  }tttd|  }t|}t	|dd}|dkr<||j
k r<qfq<tdtd	td
| ddtd|dd}t|}| |d jd< t|| |fS )a  
    Generates a EC public/private key pair

    :param curve:
        A unicode string. Valid values include "secp256r1", "secp384r1" and
        "secp521r1".

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type

    :return:
        A 2-element tuple of (asn1crypto.keys.PublicKeyInfo,
        asn1crypto.keys.PrivateKeyInfo)
    r&   r'   r(   \
            curve must be one of "secp256r1", "secp384r1", "secp521r1", not %s
            r%   Fsignedr   ecnamednamevalue	algorithm
parametersZecPrivkeyVer1)versionprivate_key)r5   Zprivate_key_algorithmr6   r6   
public_key)set
ValueErrorr   reprCURVE_BYTESSECP256R1_BASE_POINTSECP384R1_BASE_POINTSECP521R1_BASE_POINTr   r   orderr   r   r
   r   r   copyparsedr   )curvecurve_num_bytescurve_base_pointprivate_key_bytesprivate_key_intZprivate_key_infoZec_pointr   r   r   r   C   sB    c                 C   s   t | tsttdt| | j\}}|dkr:ttd|dkrPttdn<|dkr|tddd	gkr|ttd
t|t	t
td| }|| d jd j }t|j|jS )a  
    Constructs the PublicKeyInfo for a PrivateKeyInfo

    :param private_key:
        An asn1crypto.keys.PrivateKeyInfo object

    :raises:
        ValueError - when any of the parameters contain an invalid value

    :return:
        An asn1crypto.keys.ECPointBitString object
    zy
            private_key must be an instance of the
            asn1crypto.keys.PrivateKeyInfo class, not %s
            Zimplicit_cazj
            Unable to compute public key for EC key using Implicit CA
            parameters
            Z	specifiedzX
            Unable to compute public key for EC key over a specified field
            r.   r&   r'   r(   zj
                Named curve must be one of "secp256r1", "secp384r1", "secp521r1", not %s
                r%   r6   )
isinstancer   	TypeErrorr   r   rB   r9   r8   r:   r<   r=   r>   rA   nativer   Zfrom_coordsxy)r6   Z
curve_typedetailsZ
base_pointZpublic_pointr   r   r   r      s8    

c                 C   sD   |t dddgkr$ttdt|ttdtd|dd| d	S )
a  
    Constructs the PublicKeyInfo for an ECPointBitString

    :param private_key:
        An asn1crypto.keys.ECPointBitString object

    :param curve:
        A unicode string of the curve name - one of secp256r1, secp384r1 or secp521r1

    :raises:
        ValueError - when any of the parameters contain an invalid value

    :return:
        An asn1crypto.keys.PublicKeyInfo object
    r&   r'   r(   r*   r-   r.   r/   r2   )r3   r7   )r8   r9   r   r:   r   r   r
   )public_key_pointrB   r   r   r   r      s    c                 C   s2  t | drt| jts(ttdt| | j}|tdddgkrLt	tdt|t
shttdt||tdd	d
ddgkrt	tdt|tt|}| jd j}|d j}|d j}t| }tttd| }	|	j}
|| }t|}t|dd|
 }d| }d| }t||d | | | }t||| }t||d | | | }t||| }d}d}d}t||k rt||| }||7 }qxt|d| dd}|dkst||
krАqt|	| j|
 }|dkrqtt||
||| |
   |
 }|dkr qtq qtt||d S )aN  
    Generates an ECDSA signature in pure Python (thus slow)

    :param private_key:
        The PrivateKey to generate the signature with

    :param data:
        A byte string of the data the signature is for

    :param hash_algorithm:
        A unicode string of "sha1", "sha256", "sha384" or "sha512"

    :raises:
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by the OS crypto library

    :return:
        A byte string of the signature
    asn1zy
            private_key must be an instance of the
            oscrypto.asymmetric.PrivateKey class, not %s
            r&   r'   r(   zx
            private_key does not use one of the named curves secp256r1,
            secp384r1 or secp521r1
            <
            data must be a byte string, not %s
            sha1sha224sha256sha384sha512z
            hash_algorithm must be one of "sha1", "sha224", "sha256", "sha384",
            "sha512", not %s
            r6   r%   Fr+          r       )rs)hasattrrG   rN   r   rH   r   r   rB   r8   r9   r   r:   getattrhashlibrA   contentsrI   r;   r<   r=   r>   r?   digestlenr   hmacnewrJ   inverse_modr	   dump)r6   datahash_algorithm
curve_name	hash_funcZec_private_keyrE   rF   rC   rD   nr_   Zhash_lengthhVKrY   rZ   Tkr   r   r   r       st    





c                 C   s  t | d}|rt| jttfs0ttdt| | j}|t	dddgkrTt
tdt|tspttdt|t|tsttdt||t	d	d
dddgkrt
tdt|| j}t|tr|j}tttd| }|d  \}}	|j}
t|j||	|
}z"t|}|d j}|d j}W n t
k
r@   tdY nX d}||dk O }|||
kO }||dk O }|||
kO }|rtdtt|}|| }t|dd|
 }t||
}|| |
 }|| |
 }|| ||  }||j|
 krtddS )a  
    Verifies an ECDSA signature in pure Python (thus slow)

    :param certificate_or_public_key:
        A Certificate or PublicKey instance to verify the signature with

    :param signature:
        A byte string of the signature to verify

    :param data:
        A byte string of the data the signature is for

    :param hash_algorithm:
        A unicode string of "md5", "sha1", "sha256", "sha384" or "sha512"

    :raises:
        oscrypto.errors.SignatureError - when the signature is determined to be invalid
        ValueError - when any of the parameters contain an invalid value
        TypeError - when any of the parameters are of the wrong type
        OSError - when an error is returned by the OS crypto library
    rN   z
            certificate_or_public_key must be an instance of the
            oscrypto.asymmetric.PublicKey or oscrypto.asymmetric.Certificate
            classes, not %s
            r&   r'   r(   z
            certificate_or_public_key does not use one of the named curves
            secp256r1, secp384r1 or secp521r1
            zA
            signature must be a byte string, not %s
            rO   rP   rQ   rR   rS   rT   rU   r%   r7   rY   rZ   zSignature is invalidr   r   Fr+   N)r[   rG   rN   r   r   rH   r   r   rB   r8   r9   r   r:   r7   r<   r=   r>   Z	to_coordsr?   
PrimePointr	   loadrI   r   r\   r]   r_   r   rc   rJ   )Zcertificate_or_public_key	signaturere   rf   Zhas_asn1rg   rN   rD   rJ   rK   ri   rM   rY   rZ   invalidrh   r_   zwu1u2Z
hash_pointr   r   r   r!   `  sx    
	






c           	      C   s   | dk s|| kr| | } | | }}d\}}}}|dkrrt |||f \}}}|||  |||  ||f\}}}}q.|dks~t|dkr|S || S dS )z
    Compute the modular inverse of a (mod p)

    :param a:
        An integer

    :param p:
        An integer

    :return:
        An integer
    r   )r   r   r   r   r   N)divmodAssertionError)	apcdZucZvcZudZvdqr   r   r   rc     s    
&rc   c                   @   s    e Zd ZdZdd Zdd ZdS )
PrimeCurvezc
    Elliptic curve over a prime field. Characteristic two field curves are not
    supported.
    c                 C   s   || _ || _|| _dS )a  
        The curve of points satisfying y^2 = x^3 + a*x + b (mod p)

        :param p:
            The prime number as an integer

        :param a:
            The component a as an integer

        :param b:
            The component b as an integer
        N)rz   ry   b)selfrz   ry   r   r   r   r   __init__-  s    zPrimeCurve.__init__c                 C   sB   |j |j  }|j|j |j }||| j|j  | j  | j dkS )z~
        :param point:
            A Point object

        :return:
            Boolean if the point is on this curve
        r   )rK   rJ   ry   r   rz   )r   pointy2x3r   r   r   contains?  s    	zPrimeCurve.containsN)__name__
__module____qualname____doc__r   r   r   r   r   r   r~   '  s   r~   c                   @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )ro   z1
    A point on a prime-field elliptic curve
    Nc                 C   sR   || _ || _|| _|| _| j r2| j | s2td| jrN| | j tkrNtddS )a)  
        :param curve:
            A PrimeCurve object

        :param x:
            The x coordinate of the point as an integer

        :param y:
            The y coordinate of the point as an integer

        :param order:
            The order of the point, as an integer - optional
        zInvalid EC pointN)rB   rJ   rK   r?   r   r9   INFINITY)r   rB   rJ   rK   r?   r   r   r   r   R  s    zPrimePoint.__init__c                 C   s0   | j |j kr(| j|jkr(| j|jkr(dS dS dS )zy
        :param other:
            A PrimePoint object

        :return:
            0 if identical, 1 otherwise
        r   r   N)rB   rJ   rK   r   otherr   r   r   __cmp__o  s    $zPrimePoint.__cmp__c                 C   s   |t kr| S | t kr|S | j|jks(t| j|jkrX| j|j | jj dkrPt S |  S | jj}|j| j t|j| j | | }|| | j |j | }|| j|  | j | }t| j||S )zq
        :param other:
            A PrimePoint object

        :return:
            A PrimePoint object
        r   )	r   rB   rx   rJ   rK   rz   doublerc   ro   )r   r   rz   l_r   y3r   r   r   __add__|  s    "zPrimePoint.__add__c                 C   s   dd }|}| j r|| j  }|dkr(tS | tkr4tS |dks@td| }t| j| j| j | j }||d }| }|dkr| }||@ dkr||@ dkr||  }||@ dkr||@ dkr|| }|d }qp|S )
        :param other:
            An integer to multiple the Point by

        :return:
            A PrimePoint object
        c                 S   s*   | dkst d}|| kr"d| }q|d S )Nr   r      )rx   )rJ   resultr   r   r   leftmost_bit  s
    
z(PrimePoint.__mul__.<locals>.leftmost_bitr   r   r   r   )r?   r   rx   ro   rB   rJ   rK   r   )r   r   r   eZe3Znegative_selfir   r   r   r   __mul__  s*    	

zPrimePoint.__mul__c                 C   s   | | S )r   r   r   r   r   r   __rmul__  s    	zPrimePoint.__rmul__c                 C   st   | j j}| j j}d| j | j | td| j | | }|| d| j  | }|| j|  | j | }t| j ||S )zS
        :return:
            A PrimePoint object that is twice this point
        r   r   )rB   rz   ry   rJ   rc   rK   ro   )r   rz   ry   r   r   r   r   r   r   r     s    (zPrimePoint.double)N)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   ro   M  s   
+ro   l   l   9{uDjSg9g(Bl   +' 1t:_|v!a:@ml   H<^W]dZ{cxW\Iq l   1(i&^#a;l              ?l   FeY8w-X"PVd/%PP!-l   !"X!#BXtJ9!'|%VA-l   4~ 
f&Dv@h!fE0m9_qlM/l   =*8%(?l   ?               @ l   K`Opq^cv
3,e<1U]>{|R*Zl   B11e	%:f=K`wrH7gHK8hkl   Q~o]l+fUg+<)Z?8O?q!Ol   Q%x+Ohbi+}s   @ l          ~l   *'#.TEbc+Z'@=D 1 "(?7N2Z_+|S/1fl   
dxRjoyU8T(	:ss"nZL8k&"_Ul   _!uR/sX0
@qaNQNB&JxS8KJEY	K%l l   s)e`gwlX_[nlv|l#   l#    ?VQ(zO%b95~cte1oR{V;LHw>l-rZE]"Sr&Ga9}*Fl#   f=xK)H-apY$3^Q	n%k{;/K!u{4-{?$Od8V1l3s:l#   Pf?QE$XN!85aZUWL9YLhzf$Du13otc!%pMxjRr`l#   	dp"z\}[z3"nZ;PK#
`7roCQ);
__future__r   r   r   r   r]   ra   sys r   Z_asn1r   r	   r
   r   r   r   r   r   r   r   _errorsr   _typesr   r   utilr   errorsr   version_infochrr   xrangerangeZ_backendSystemError__all__r;   ZCURVE_EXTRA_BITSr   r   r   r    r!   rc   r~   ro   r   ZSECP192R1_CURVEZSECP192R1_BASE_POINTZSECP224R1_CURVEZSECP224R1_BASE_POINTZSECP256R1_CURVEr<   ZSECP384R1_CURVEr=   ZSECP521R1_CURVEr>   r   r   r   r   <module>   s   0

<;%  %#& 				