U
    Mf                     @   s  d dl 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 d dlmZmZ d dlmZ d dlmZmZmZmZ d dlmZmZmZmZmZmZmZ d d	lm Z m!Z!m"Z" d d
l#m$Z$m%Z% d dl&m'Z' d dl(m)Z) eddZ*eddZ+eddZ,dd Z-eddZ.i Z/ddddddga0dd Z1e1  [1dd d!d"d#d$ga2d%d& Z3e3  [3d'd(d)d*d+d,ga4d-d. Z5e5  [5d/d0d1d2d3d4ga6d5d6 Z7e7  [7d7d8d9d:d;d<ga8d=d> Z9e9  [9d?d@ga:dAdB Z;e;  [;dCdDga<dEdF Z=e=  [=G dGdH dHe>Z?G dIdJ dJe@ZAeAe/d jBe/d jCdZDe/d jEeDdKZFe/GeHIt0eF [D[Fb0eAe/d jBe/d jCdZJe/d jEeJdKZKe/GeHIt2eK [J[Kb2eAe/d' jBe/d' jCd'ZLe/d' jEeLdKZMe/GeHIt4eM [L[Mb4eAe/d/ jBe/d/ jCd/ZNe/d/ jEeNdKZOe/GeHIt6eO [N[Ob6eAe/d7 jBe/d7 jCd7ZPe/d7 jEePdKZQe/GeHIt8eQ [P[Qb8eAe/d@ jBe/d@ jCd@ZRe/d@ jEeRdKZSe/GeHIt:eS [R[Sb:eAe/dD jBe/dD jCdDZTe/dD jEeTdKZUe/GeHIt<eU [T[Ub<G dLdM dMe@ZVdNdO ZWdPdQ ZXdodRdSZYdTdU ZZdpdVdWZ[dXdY Z\dZd[ Z]d\d] Z^d^d_ Z_d`da Z`dbdc Zaddde ZbdqdfdgZceddhkrd dleZediZfe/d' jgh ZidjZjeee ZkelejD ]Zmeief Znqzeodkeee ek ej dl dm eee ZkelejD ]Zmenef Znqeodneee ek ej dl dm dS )r    )print_functionN)
namedtuple)bordtobytestostrbchr	is_string)bytes_to_longlong_to_bytes)Integer)DerObjectIdDerOctetStringDerSequenceDerBitString)load_pycryptodome_raw_libVoidPointerSmartPointerc_size_tc_uint8_ptrc_ulonglongnull_pointer)_expand_subject_public_key_info_create_subject_public_key_info _extract_subject_public_key_info)SHA512SHAKE256)get_random_bytes)getrandbitszCryptodome.PublicKey._ec_wsa  
typedef void EcContext;
typedef void EcPoint;
int ec_ws_new_context(EcContext **pec_ctx,
                      const uint8_t *modulus,
                      const uint8_t *b,
                      const uint8_t *order,
                      size_t len,
                      uint64_t seed);
void ec_free_context(EcContext *ec_ctx);
int ec_ws_new_point(EcPoint **pecp,
                    const uint8_t *x,
                    const uint8_t *y,
                    size_t len,
                    const EcContext *ec_ctx);
void ec_ws_free_point(EcPoint *ecp);
int ec_ws_get_xy(uint8_t *x,
                 uint8_t *y,
                 size_t len,
                 const EcPoint *ecp);
int ec_ws_double(EcPoint *p);
int ec_ws_add(EcPoint *ecpa, EcPoint *ecpb);
int ec_ws_scalar(EcPoint *ecp,
                 const uint8_t *k,
                 size_t len,
                 uint64_t seed);
int ec_ws_clone(EcPoint **pecp2, const EcPoint *ecp);
int ec_ws_cmp(const EcPoint *ecp1, const EcPoint *ecp2);
int ec_ws_neg(EcPoint *p);
zCryptodome.PublicKey._ed25519ai  
typedef void Point;
int ed25519_new_point(Point **out,
                      const uint8_t x[32],
                      const uint8_t y[32],
                      size_t modsize,
                      const void *context);
int ed25519_clone(Point **P, const Point *Q);
void ed25519_free_point(Point *p);
int ed25519_cmp(const Point *p1, const Point *p2);
int ed25519_neg(Point *p);
int ed25519_get_xy(uint8_t *xb, uint8_t *yb, size_t modsize, Point *p);
int ed25519_double(Point *p);
int ed25519_add(Point *P1, const Point *P2);
int ed25519_scalar(Point *P, const uint8_t *scalar, size_t scalar_len, uint64_t seed);
zCryptodome.PublicKey._ed448a*  
typedef void EcContext;
typedef void PointEd448;
int ed448_new_context(EcContext **pec_ctx);
void ed448_context(EcContext *ec_ctx);
void ed448_free_context(EcContext *ec_ctx);
int ed448_new_point(PointEd448 **out,
                    const uint8_t x[56],
                    const uint8_t y[56],
                    size_t len,
                    const EcContext *context);
int ed448_clone(PointEd448 **P, const PointEd448 *Q);
void ed448_free_point(PointEd448 *p);
int ed448_cmp(const PointEd448 *p1, const PointEd448 *p2);
int ed448_neg(PointEd448 *p);
int ed448_get_xy(uint8_t *xb, uint8_t *yb, size_t len, const PointEd448 *p);
int ed448_double(PointEd448 *p);
int ed448_add(PointEd448 *P1, const PointEd448 *P2);
int ed448_scalar(PointEd448 *P, const uint8_t *scalar, size_t scalar_len, uint64_t seed);
c                 C   sJ   | j jdkrttd| }n*| j jdkr8ttd| }nttd| }|S )NEd25519Zed25519_Ed448Zed448_Zec_ws_)_curvedescgetattr_ed25519_lib
_ed448_lib_ec_lib)Zecc_obj	func_nameresult r(   </tmp/pip-unpacked-wheel-l_0d1exj/Cryptodome/PublicKey/ECC.pylib_func   s    r*   _Curvez<p b order Gx Gy G modulus_bits oid context desc openssh namep192
NIST P-192zP-192Z
prime192v1Z	secp192r1Znistp192c                  C   s   d} d}d}d}d}t | d}t |d}t |d}t }t| t|t|t|tt|tt	d}	|	r|t
d|	 t| tj}
tt| t|t|t|t|d d	d
|
ddd}ttt| d S )Nl   l   9{uDjSg9g(Bl   1(i&^#a;l   +' 1t:_|v!a:@ml   H<^W]dZ{cxW\Iq    @   z#Error %d initializing P-192 context   z1.2.840.10045.3.1.1r-   zecdsa-sha2-nistp192r,   )r
   r   r%   ec_ws_new_context
address_ofr   r   lenr   r   ImportErrorr   getec_free_contextr+   r   _curvesupdatedictfromkeys
p192_names)pborderGxGyZp192_modulusZp192_bZ
p192_orderZec_p192_contextr'   contextr,   r(   r(   r)   	init_p192   sB    





rB   p224
NIST P-224zP-224Z
prime224v1Z	secp224r1Znistp224c                  C   s   d} d}d}d}d}t | d}t |d}t |d}t }t| t|t|t|tt|tt	d}	|	r|t
d|	 t| tj}
tt| t|t|t|t|d d	d
|
ddd}ttt| d S )Nl              ?l   FeY8w-X"PVd/%PP!-l   =*8%(?l   !"X!#BXtJ9!'|%VA-l   4~ 
f&Dv@h!fE0m9_qlM/   r/   z#Error %d initializing P-224 context   z1.3.132.0.33rD   zecdsa-sha2-nistp224rC   )r
   r   r%   r1   r2   r   r   r3   r   r   r4   r   r5   r6   r+   r   r7   r8   r9   r:   
p224_names)r<   r=   r>   r?   r@   Zp224_modulusZp224_bZ
p224_orderZec_p224_contextr'   rA   rC   r(   r(   r)   	init_p224   sB    





rH   p256
NIST P-256zP-256Z
prime256v1Z	secp256r1Znistp256c                  C   s   d} d}d}d}d}t | d}t |d}t |d}t }t| t|t|t|tt|tt	d}	|	r|t
d|	 t| tj}
tt| t|t|t|t|d d	d
|
ddd}ttt| d S )Nl   ?               @ l   K`Opq^cv
3,e<1U]>{|R*Zl   Q%x+Ohbi+}s   @ l   B11e	%:f=K`wrH7gHK8hkl   Q~o]l+fUg+<)Z?8O?q!O    r/   z#Error %d initializing P-256 context   z1.2.840.10045.3.1.7rJ   zecdsa-sha2-nistp256rI   )r
   r   r%   r1   r2   r   r   r3   r   r   r4   r   r5   r6   r+   r   r7   r8   r9   r:   
p256_names)r<   r=   r>   r?   r@   Zp256_modulusZp256_bZ
p256_orderZec_p256_contextr'   rA   rI   r(   r(   r)   	init_p256  sB    





rN   p384
NIST P-384zP-384Z
prime384v1Z	secp384r1Znistp384c                  C   s   d} d}d}d}d}t | d}t |d}t |d}t }t| t|t|t|tt|tt	d}	|	r|t
d|	 t| tj}
tt| t|t|t|t|d d	d
|
ddd}ttt| d S )Nl          ~l   *'#.TEbc+Z'@=D 1 "(?7N2Z_+|S/1fl   s)e`gwlX_[nlv|l   
dxRjoyU8T(	:ss"nZL8k&"_Ul   _!uR/sX0
@qaNQNB&JxS8KJEY	K%l 0   r/   z#Error %d initializing P-384 contexti  z1.3.132.0.34rP   zecdsa-sha2-nistp384rO   )r
   r   r%   r1   r2   r   r   r3   r   r   r4   r   r5   r6   r+   r   r7   r8   r9   r:   
p384_names)r<   r=   r>   r?   r@   Zp384_modulusZp384_bZ
p384_orderZec_p384_contextr'   rA   rO   r(   r(   r)   	init_p3840  sB    





rS   p521
NIST P-521zP-521Z
prime521v1Z	secp521r1Znistp521c                  C   s   d} d}d}d}d}t | d}t |d}t |d}t }t| t|t|t|tt|tt	d}	|	r|t
d|	 t| tj}
tt| t|t|t|t|d d	d
|
ddd}ttt| d S )Nl#   l#    ?VQ(zO%b95~cte1oR{V;LHw>l-rZE]"Sr&Ga9}*Fl#   	dp"z\}[z3"nZ;PK#
`7roCQ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`B   r/   z#Error %d initializing P-521 contexti	  z1.3.132.0.35rU   zecdsa-sha2-nistp521rT   )r
   r   r%   r1   r2   r   r   r3   r   r   r4   r   r5   r6   r+   r   r7   r8   r9   r:   
p521_names)r<   r=   r>   r?   r@   Zp521_modulusZp521_bZ
p521_orderZec_p521_contextr'   rA   rT   r(   r(   r)   	init_p521_  sB    





rX   ed25519r   c                  C   sT   d} d}d}d}t t| d t|t|t|d ddd ddd	}ttt| d S )
N   l   S9i@eM^w|o                l   UK5J,{$%Xci\-G'
lJ[sii!l   XfL33ffL33ffL33ffL33ff   1.3.101.112r   ssh-ed25519rY   )r+   r   r7   r8   r9   r:   ed25519_names)r<   r>   r?   r@   rY   r(   r(   r)   init_ed25519  s$    r_   ed448r   c                  C   s   d} d}d}d}t  }t| }|r4td| t| tj}tt	| d t	|t	|t	|d dd|dd d	}t
tt| d S )
N   ?l   DVJ
Ru8a6!m,&vD}D2_l   ^@ 518`b8Cl\p*At(qmj.<+FaS[/SDZ74_3	l   zadoeC@
ZK^DsxssZhNx02>Ilq2 vIZugt'z#Error %d initializing Ed448 contexti  1.3.101.113r   r`   )r   r$   Zed448_new_contextr2   r4   r   r5   Zed448_free_contextr+   r   r7   r8   r9   r:   ed448_names)r<   r>   r?   r@   Zed448_contextr'   rA   r`   r(   r(   r)   
init_ed448  s.    rd   c                   @   s   e Zd ZdS )UnsupportedEccFeatureN)__name__
__module____qualname__r(   r(   r(   r)   re     s   re   c                   @   s   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d Z
dd Zdd Zedd Zedd Zedd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+S )-EccPointaP  A class to model a point on an Elliptic Curve.

    The class supports operators for:

    * Adding two points: ``R = S + T``
    * In-place addition: ``S += T``
    * Negating a point: ``R = -T``
    * Comparing two points: ``if S == T: ...`` or ``if S != T: ...``
    * Multiplying a point by a scalar: ``R = S*k``
    * In-place multiplication by a scalar: ``T *= k``

    :ivar x: The affine X-coordinate of the ECC point
    :vartype x: integer

    :ivar y: The affine Y-coordinate of the ECC point
    :vartype y: integer

    :ivar xy: The tuple with affine X- and Y- coordinates
    rI   c                 C   s  zt | | _W n$ tk
r2   tdt| Y nX || _|  }t||}t||}t||ksnt||krvtdt	| d}t	| d}t
 | _z| jj }	W n tk
r   t}	Y nX || j t|t|t||	}
|
r|
dkrtdtd|
 t| j || _d S )NzUnknown curve name %szIncorrect coordinate length	new_point
free_point   z)The EC point does not belong to the curvez(Error %d while instantiating an EC point)r7   r    KeyError
ValueErrorstr_curve_namesize_in_bytesr
   r3   r*   r   _pointrA   r5   AttributeErrorr   r2   r   r   r   )selfxycurvemodulus_bytesxbybrj   	free_funcrA   r'   r(   r(   r)   __init__  s8    





zEccPoint.__init__c                 C   sX   t | d}t | d}t | _|| j |j }|rBtd| t| j || _| S )Nclonerk   z"Error %d while cloning an EC point)r*   r   rr   r2   r5   rn   r   )rt   pointr}   r{   r'   r(   r(   r)   set
  s    


zEccPoint.setc                 C   s2   t |tsdS t| d}d|| j |j kS )NFcmpr   )
isinstanceri   r*   rr   r5   )rt   r~   Zcmp_funcr(   r(   r)   __eq__  s    

zEccPoint.__eq__c                 C   s
   | |k S Nr(   )rt   r~   r(   r(   r)   __ne__   s    zEccPoint.__ne__c                 C   s4   t | d}|  }||j }|r0td| |S )Nnegz$Error %d while inverting an EC point)r*   copyrr   r5   rn   )rt   Zneg_funcnpr'   r(   r(   r)   __neg__#  s    
zEccPoint.__neg__c                 C   s   | j \}}t||| j}|S )zReturn a copy of this point.)xyri   rp   )rt   ru   rv   r   r(   r(   r)   r   +  s    
zEccPoint.copyc                 C   s   | j jdkS )NrY   r`   )r    namert   r(   r(   r)   	_is_eddsa1  s    zEccPoint._is_eddsac                 C   s    |   r| jdkS | jdkS dS )z,``True`` if this is the *point-at-infinity*.r   )r   r   N)r   ru   r   r   r(   r(   r)   is_point_at_infinity4  s    
zEccPoint.is_point_at_infinityc                 C   s(   |   rtdd| jS tdd| jS dS )z-Return the *point-at-infinity* for the curve.r      N)r   ri   rp   r   r(   r(   r)   point_at_infinity<  s    zEccPoint.point_at_infinityc                 C   s
   | j d S )Nr   r   r   r(   r(   r)   ru   D  s    z
EccPoint.xc                 C   s
   | j d S )Nr   r   r   r(   r(   r)   rv   H  s    z
EccPoint.yc                 C   sj   |   }t|}t|}t| d}|t|t|t|| j }|rRtd| tt	|tt	|fS )Nget_xyz#Error %d while encoding an EC point)
rq   	bytearrayr*   r   r   rr   r5   rn   r   r	   )rt   rx   ry   rz   r   r'   r(   r(   r)   r   L  s    
zEccPoint.xyc                 C   s   |   d d S )z"Size of each coordinate, in bytes.      )size_in_bitsr   r(   r(   r)   rq   [  s    zEccPoint.size_in_bytesc                 C   s   | j jS )z!Size of each coordinate, in bits.)r    modulus_bitsr   r(   r(   r)   r   _  s    zEccPoint.size_in_bitsc                 C   s,   t | d}|| j }|r(td| | S )zuDouble this point (in-place operation).

        Returns:
            This same object (to enable chaining).
        doublez#Error %d while doubling an EC pointr*   rr   r5   rn   )rt   Zdouble_funcr'   r(   r(   r)   r   c  s
    
zEccPoint.doublec                 C   sD   t | d}|| j |j }|r@|dkr4tdtd| | S )zAdd a second point to this oneadd   z#EC points are not on the same curvez#Error %d while adding two EC pointsr   )rt   r~   Zadd_funcr'   r(   r(   r)   __iadd__p  s    
zEccPoint.__iadd__c                 C   s   |   }||7 }|S )z8Return a new point, the addition of this one and anotherr   )rt   r~   r   r(   r(   r)   __add__{  s    zEccPoint.__add__c                 C   s^   t | d}|dk rtdt|}|| j t|tt|tt	d}|rZtd| | S )zMultiply this point by a scalarscalarr   z?Scalar multiplication is only defined for non-negative integersr/   z%Error %d during scalar multiplication)
r*   rn   r
   rr   r5   r   r   r3   r   r   )rt   r   Zscalar_funcZsbr'   r(   r(   r)   __imul__  s    



zEccPoint.__imul__c                 C   s   |   }||9 }|S )z2Return a new point, the scalar product of this oner   )rt   r   r   r(   r(   r)   __mul__  s    zEccPoint.__mul__c                 C   s
   |  |S r   )r   )rt   Z	left_handr(   r(   r)   __rmul__  s    zEccPoint.__rmul__N)rI   )rf   rg   rh   __doc__r|   r   r   r   r   r   r   r   r   propertyru   rv   r   rq   r   r   r   r   r   r   r   r(   r(   r(   r)   ri     s0   
&


ri   )Gc                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
edd Zedd Zedd Zdd Zdd Zdd Zdd Zd0dd Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/S )1EccKeya  Class defining an ECC key.
    Do not instantiate directly.
    Use :func:`generate`, :func:`construct` or :func:`import_key` instead.

    :ivar curve: The name of the curve as defined in the `ECC table`_.
    :vartype curve: string

    :ivar pointQ: an ECC point representating the public component.
    :vartype pointQ: :class:`EccPoint`

    :ivar d: A scalar that represents the private component
             in NIST P curves. It is smaller than the
             order of the generator point.
    :vartype d: integer

    :ivar seed: A seed that representats the private component
                in EdDSA curves
                (Ed25519, 32 bytes; Ed448, 57 bytes).
    :vartype seed: bytes
    c                 K   sN  t |}|dd}|dd| _|dd| _|dd| _|dkrT| jrT| jj}|rhtdt| |tkr|t	d| t| | _
| j
j| _t| jdk	t| jdk	 }|dkr| jdkrt	d	dS |d
krt	d|  s.| jdk	rt	dt| j| _d| j  kr | j
jk sJn t	dn| jdk	rBt	d| j
jdkrt| jdkrht	dt| j }|dd | _t|dd }|d  dM  < |d d@ dB |d< n~| j
jdkr:t| jdkrt	dt| jd}|dd | _t|dd }|d  dM  < |d  dO  < d|d< tj|dd | _dS )!ai  Create a new ECC key

        Keywords:
          curve : string
            The name of the curve.
          d : integer
            Mandatory for a private key one NIST P curves.
            It must be in the range ``[1..order-1]``.
          seed : bytes
            Mandatory for a private key on the Ed25519 (32 bytes)
            or Ed448 (57 bytes) curve.
          point : EccPoint
            Mandatory for a public key. If provided for a private key,
            the implementation will NOT check whether it matches ``d``.

        Only one parameter among ``d``, ``seed`` or ``point`` may be used.
        rw   Ndseedr~   Unknown parameters: zUnsupported curve (%s)r   zGAt lest one between parameters 'point', 'd' or 'seed' must be specified   z,Parameters d and seed are mutually exclusivez7Parameter 'seed' can only be used with Ed25519 or Ed448r   z;Parameter d must be an integer smaller than the curve orderz/Parameter d can only be used with NIST P curvesrY   rK   z0Parameter seed must be 32 bytes long for Ed25519         r/   r`   9   z.Parameter seed must be 57 bytes long for Ed448r      7      8   little	byteorder)r9   pop_d_seedrr   rp   	TypeErrorro   r7   rn   r    r!   rw   intr   r   r>   r   r3   r   newdigest_prefixr   r   read
from_bytes)rt   kwargsZkwargs_
curve_namecountZ	seed_hashtmpr(   r(   r)   r|     s\    




 zEccKey.__init__c                 C   s   | j jdkS )N)r   r   )r    r!   r   r(   r(   r)   r   #  s    zEccKey._is_eddsac                 C   s.   t |tsdS | |  kr"dS |j| jkS )NF)r   r   has_privatepointQ)rt   otherr(   r(   r)   r   &  s
    
zEccKey.__eq__c                 C   sZ   |   r6|  r&dtt| j }q:dt| j }nd}| jj	\}}d| j
j|||f S )Nz	, seed=%sz, d=%d z,EccKey(curve='%s', point_x=%d, point_y=%d%s))r   r   r   binasciihexlifyr   r   r   r   r   r    r!   )rt   extraru   rv   r(   r(   r)   __repr__/  s    zEccKey.__repr__c                 C   s
   | j dk	S )zJ``True`` if this key can be used for making signatures or decrypting data.N)r   r   r(   r(   r)   r   :  s    zEccKey.has_privatec           	      C   s~   d|  k r| j jk sn t| j j}tjd|d}| j| }|| |}| j j| j| }||| ||   | }||fS )Nr   r   )min_inclusivemax_exclusive)	r    r>   AssertionErrorr   random_ranger   inverser   ru   )	rt   zkr>   ZblindZblind_dZinv_blind_krsr(   r(   r)   _sign@  s    
zEccKey._signc                 C   sR   | j j}|d |}| j j|| |  }| j||d  |  }|| j|d kS )Nr   r   )r    r>   r   r   r   ru   )rt   r   rsr>   ZsinvZpoint1Zpoint2r(   r(   r)   _verifyO  s
    zEccKey._verifyc                 C   s   |   std| jS NzThis is not a private ECC key)r   rn   r   r   r(   r(   r)   r   V  s    zEccKey.dc                 C   s   |   std| jS r   )r   rn   r   r   r(   r(   r)   r   \  s    zEccKey.seedc                 C   s    | j d kr| jj| j | _ | j S r   )rr   r    r   r   r   r(   r(   r)   r   b  s    
zEccKey.pointQc                 C   s   t | jj| jdS )z^A matching ECC public key.

        Returns:
            a new :class:`EccKey` object
        )rw   r~   )r   r    r!   r   r   r(   r(   r)   
public_keyh  s    zEccKey.public_keyc                 C   sl   |   rtd| j }|rH| jj r0d}nd}|| jj| }n d| jj| | jj| }|S )Nz+SEC1 format is unsupported for EdDSA curves         )r   rn   r   rq   rv   is_oddru   to_bytes)rt   compressrx   
first_byter   r(   r(   r)   _export_SEC1q  s     
zEccKey._export_SEC1c                 C   s   | j j\}}| jjdkrDt|jddd}|d@ d> |d B |d< n8| jjdkrtt|jd	dd}|d@ d> |d
< ntdt|S )NrY   rK   r   r   r   r   r   r`   r   r   zNot an EdDSA key to export)r   r   r    r   r   r   rn   bytes)rt   ru   rv   r'   r(   r(   r)   _export_eddsa  s    zEccKey._export_eddsac                 C   sD   |   r| jj}|  }d }nd}| |}t| jj}t|||S )N1.2.840.10045.2.1)r   r    oidr   r   r   r   )rt   r   r   r   paramsr(   r(   r)   _export_subjectPublicKeyInfo  s    
z#EccKey._export_subjectPublicKeyInfoTc                 C   sx   |   st| j }d| jj| | jj| }dt| j|t	| j
jddt|ddg}|sl|d= t| S )Nr   r   r   explicitr   )r   r   r   rq   ru   r   rv   r   r   r   r    r   r   r   encode)rt   include_ec_paramsrx   r   seqr(   r(   r)   _export_rfc5915_private_der  s    


z"EccKey._export_rfc5915_private_derc                 K   s   ddl m} |dd d k	r,d|kr,td|  rP| jj}t| j	 }d }nd}| j
dd}t| jj}|j||fd	|i|}|S )
Nr   PKCS8
passphrase
protectionz3At least the 'protection' parameter must be presentr   F)r   Z
key_params)Cryptodome.IOr   r5   rn   r   r    r   r   r   r   r   r   wrap)rt   r   r   r   private_keyr   r'   r(   r(   r)   _export_pkcs8  s$    zEccKey._export_pkcs8c                 C   s"   ddl m} | |}||dS )Nr   PEMz
PUBLIC KEY)r   r   r   r   )rt   r   r   encoded_derr(   r(   r)   _export_public_pem  s    
zEccKey._export_public_pemc                 K   s&   ddl m} |  }|j|d|f|S )Nr   r   zEC PRIVATE KEY)r   r   r   r   rt   r   r   r   r   r(   r(   r)   _export_private_pem  s    zEccKey._export_private_pemc                 C   s    ddl m} |  }||dS )Nr   r   zPRIVATE KEY)r   r   r   r   )rt   r   r   r(   r(   r)   (_export_private_clear_pkcs8_in_clear_pem  s    z/EccKey._export_private_clear_pkcs8_in_clear_pemc                 K   sD   ddl m} |std|kr$td| jf d|i|}||dS )Nr   r   r   z5At least the 'protection' parameter should be presentr   zENCRYPTED PRIVATE KEY)r   r   r   rn   r   r   r   r(   r(   r)   ,_export_private_encrypted_pkcs8_in_clear_pem  s    z3EccKey._export_private_encrypted_pkcs8_in_clear_pemc           	      C   s   |   rtd| jj}|d kr2td| jj n|dkrT|  }t|t|f}nv| j }|rd| jj	
  }t|| jj| }n d| jj| | jj	| }|dd }t|t||f}ddd	 |D }|d
 tt| S )Nz"Cannot export OpenSSH private keysz Cannot export %s keys as OpenSSHr]   r   r   -    c                 S   s    g | ]}t d t|| qS )>I)structpackr3   ).0ru   r(   r(   r)   
<listcomp>  s     z*EccKey._export_openssh.<locals>.<listcomp> )r   rn   r    opensshr   r   r   r   rq   rv   r   r   ru   r   splitjoinr   r   
b2a_base64)	rt   r   r!   r   compsrx   r   middleZblobr(   r(   r)   _export_openssh  s.    
zEccKey._export_opensshc                 K   s  |  }|d}|dkr&td| |dd}|  r|dd}t|rdt|}|sdtd|d	d
}|s|  rtdd|krtd|dkr|r|r| j|f|S |  S n| j	|f|S nJ|dkr
|r|std|r | j
f d|i|S |  S ntd| n|r*td| |dkr>| |S |dkrR| |S |dkrf| |S |dkr| jjdkr|  S | |S n
| |S dS )a  Export this ECC key.

        Args:
          format (string):
            The output format:

            - ``'DER'``. The key will be encoded in ASN.1 DER format (binary).
              For a public key, the ASN.1 ``subjectPublicKeyInfo`` structure
              defined in `RFC5480`_ will be used.
              For a private key, the ASN.1 ``ECPrivateKey`` structure defined
              in `RFC5915`_ is used instead (possibly within a PKCS#8 envelope,
              see the ``use_pkcs8`` flag below).
            - ``'PEM'``. The key will be encoded in a PEM_ envelope (ASCII).
            - ``'OpenSSH'``. The key will be encoded in the OpenSSH_ format
              (ASCII, public keys only).
            - ``'SEC1'``. The public key (i.e., the EC point) will be encoded
              into ``bytes`` according to Section 2.3.3 of `SEC1`_
              (which is a subset of the older X9.62 ITU standard).
              Only for NIST P-curves.
            - ``'raw'``. The public key will be encoded as ``bytes``,
              without any metadata.

              * For NIST P-curves: equivalent to ``'SEC1'``.
              * For EdDSA curves: ``bytes`` in the format defined in `RFC8032`_.

          passphrase (bytes or string):
            (*Private keys only*) The passphrase to protect the
            private key.

          use_pkcs8 (boolean):
            (*Private keys only*)
            If ``True`` (default and recommended), the `PKCS#8`_ representation
            will be used. It must be ``True`` for EdDSA curves.

            If ``False`` and a passphrase is present, the obsolete PEM
            encryption will be used.

          protection (string):
            When a private key is exported with password-protection
            and PKCS#8 (both ``DER`` and ``PEM`` formats), this parameter MUST be
            present,
            For all possible protection schemes,
            refer to :ref:`the encryption parameters of PKCS#8<enc_params>`.
            It is recommended to use ``'PBKDF2WithHMAC-SHA5126AndAES128-CBC'``.

          compress (boolean):
            If ``True``, the method returns a more compact representation
            of the public key, with the X-coordinate only.

            If ``False`` (default), the method returns the full public key.

            This parameter is ignored for EdDSA curves, as compression is
            mandatory.

          prot_params (dict):
            When a private key is exported with password-protection
            and PKCS#8 (both ``DER`` and ``PEM`` formats), this dictionary
            contains the  parameters to use to derive the encryption key
            from the passphrase.
            For all possible values,
            refer to :ref:`the encryption parameters of PKCS#8<enc_params>`.
            The recommendation is to use ``{'iteration_count':21000}`` for PBKDF2,
            and ``{'iteration_count':131072}`` for scrypt.

        .. warning::
            If you don't provide a passphrase, the private key will be
            exported in the clear!

        .. note::
            When exporting a private key with password-protection and `PKCS#8`_
            (both ``DER`` and ``PEM`` formats), any extra parameters
            to ``export_key()`` will be passed to :mod:`Cryptodome.IO.PKCS8`.

        .. _PEM:        http://www.ietf.org/rfc/rfc1421.txt
        .. _`PEM encryption`: http://www.ietf.org/rfc/rfc1423.txt
        .. _OpenSSH:    http://www.openssh.com/txt/rfc5656.txt
        .. _RFC5480:    https://tools.ietf.org/html/rfc5480
        .. _SEC1:       https://www.secg.org/sec1-v2.pdf

        Returns:
            A multi-line string (for ``'PEM'`` and ``'OpenSSH'``) or
            ``bytes`` (for ``'DER'``, ``'SEC1'``, and ``'raw'``) with the encoded key.
        format)r   DERZOpenSSHSEC1rawzUnknown format '%s'r   Fr   NzEmpty passphrase	use_pkcs8Tz%'pkcs8' must be True for EdDSA curvesr   z)'protection' is only supported for PKCS#8r   r  z8Private keys can only be encrpyted with DER using PKCS#8z2Private keys cannot be exported in the '%s' formatzUnexpected parameters: '%s'r  r  r   )r   r   rn   r   r   r   r   r   r   r   r   r   r   r   r   r    r   r   r  )rt   r   argsZ
ext_formatr   r   r  r(   r(   r)   
export_key  sZ    U











zEccKey.export_keyN)T)rf   rg   rh   r   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r(   r(   r(   r)   r     s4   L	


	
	r   c                  K   s   |  d}t| }|  dt}| r2tdt|  t| jdkrV|d}t||d}nBt| jdkrz|d}t||d}ntjd	|j	|d
}t||d}|S )a5  Generate a new private key on the given curve.

    Args:

      curve (string):
        Mandatory. It must be a curve name defined in the `ECC table`_.

      randfunc (callable):
        Optional. The RNG to read randomness from.
        If ``None``, :func:`Cryptodome.Random.get_random_bytes` is used.
    rw   randfuncr   rY   rK   rw   r   r`   r   r   )r   r   r  )rw   r   )
r   r7   r   r   ro   r   r   r   r   r>   )r   r   rw   r  r   new_keyr   r(   r(   r)   generate  s"    
r  c                  K   s   | d }t | }| dd}| dd}d| kr8tdd||fkrTt|||| d< tf | }| rd| kr|j|j }|j||fkrt	d|S )a  Build a new ECC key (private or public) starting
    from some base components.

    In most cases, you will already have an existing key
    which you can read in with :func:`import_key` instead
    of this function.

    Args:
      curve (string):
        Mandatory. The name of the elliptic curve, as defined in the `ECC table`_.

      d (integer):
        Mandatory for a private key and a NIST P-curve (e.g., P-256):
        the integer in the range ``[1..order-1]`` that represents the key.

      seed (bytes):
        Mandatory for a private key and an EdDSA curve.
        It must be 32 bytes for Ed25519, and 57 bytes for Ed448.

      point_x (integer):
        Mandatory for a public key: the X coordinate (affine) of the ECC point.

      point_y (integer):
        Mandatory for a public key: the Y coordinate (affine) of the ECC point.

    Returns:
      :class:`EccKey` : a new ECC key object
    rw   point_xNpoint_yr~   zUnknown keyword: pointz(Private and public ECC keys do not match)
r7   r   r   ri   r   r   r   r   r   rn   )r   r   rw   r  r  r  Zpub_keyr(   r(   r)   	construct  s    
r  c           	      C   s\  t  D ]&\}}|r"|j|kr" qN||kr qNq|rBtd| ntd| |j }t| d }|dkrt| dd|  krtdt	
| d|d  }t	
| |d d }n|d	krFt| d| krtdt	
| dd }|d
 |d
  |j |j}|dkr&| r&|j| }|d
krN| rN|j| }ntdt|||dS )a  Convert an encoded EC point into an EccKey object

    ec_point: byte string with the EC point (SEC1-encoded)
    curve_oid: string with the name the curve
    curve_name: string with the OID of the curve

    Either curve_id or curve_name must be specified

    Unsupported ECC curve (OID: %s)zUnsupported ECC curve (%s)r      r   r   zIncorrect EC point lengthNr      r  zIncorrect EC point encodingrw   r  r  )r7   itemsr   re   r<   rq   r   r3   rn   r   r   r=   sqrtr   Zis_evenr  )	ec_point	curve_oidr   rp   rw   rx   Z
point_typeru   rv   r(   r(   r)   _import_public_der  s4    



r%  c                 G   s   t | \}}}d}dtfdtfd}||krx|s<td| zt |j}W n tk
rj   tdY nX t||dS ||kr|| \}}	|rtd| |	|\}
}t|
||d	S t	d
| dS )z4Convert a subjectPublicKeyInfo into an EccKey objectr   z1.3.132.1.12z1.3.132.1.13r   r   r\   rb   z%Missing ECC parameters for ECC OID %szError decoding namedCurver$  z(Unexpected ECC parameters for ECC OID %s)r  r  rw   zUnsupported ECC OID: %sN)
r   _import_ed25519_public_key_import_ed448_public_keyrn   r   decodevaluer%  r  re   )encodedr   r   r#  r   nist_p_oids
eddsa_oidsr$  r   import_eddsa_public_keyru   rv   r(   r(   r)   _import_subjectPublicKeyInfo.  s(    
r1  c                 C   s@  t  j| dd}|d dkr$tdz6tdd|d j}|d k	rT||krTtd|}W n tk
rn   Y nX |d krtd	t D ]\}}|j|kr qqtd
| t	 |d j
}|j }t||krtdt|}	t|dkr(tdd|d j}
t|
|d}|jj}|jj}nd  }}t||	||dS )N)r  r  )Znr_elementsr   r   z!Incorrect ECC private key versionr   r   zCurve mismatchzNo curve foundr  zPrivate key is too smallr(  )rw   r   r  r  )r   r+  rn   r   r,  r7   r!  r   re   r   payloadr<   rq   r3   r   r   r   r%  r   ru   rv   r  )r-  r   r$  r   
parametersr   rw   Zscalar_bytesrx   r   Zpublic_key_encr   r  r  r(   r(   r)   _import_rfc5915_derb  s8    



r5  c           
      C   s   ddl m} || |\}}}d}ddd}||krNt |j}t|||S ||kr|d k	rftdd }t |j	}	t
|| |	dS td	| d S )
Nr   r   r&  r   r   r'  z.EdDSA ECC private key must not have parametersr  z!Unsupported ECC purpose (OID: %s))r   r   unwrapr   r+  r,  r5  rn   r   r3  r  re   )
r-  r   r   Zalgo_oidr   r   r.  r/  r$  r   r(   r(   r)   _import_pkcs8  s     r7  c                 G   s   t | }t|S r   )r   r1  )r-  r   Zsp_infor(   r(   r)   _import_x509_cert  s    r8  c              
   C   s@  zt | |W S  tk
r2 } z|W 5 d }~X Y n tttfk
rJ   Y nX zt| |W S  tk
r~ } z|W 5 d }~X Y n tttfk
r   Y nX zt| |W S  tk
r } z|W 5 d }~X Y n tttfk
r   Y nX zt| |W S  tk
r } z|W 5 d }~X Y n tttfk
r2   Y nX tdd S )NzNot an ECC DER key)r1  re   rn   r   
IndexErrorr8  r5  r7  )r-  r   errr(   r(   r)   _import_der  s2    r;  c              
   C   s  |  d}t|dkrtdz:t|d }g }t|dkrtd|d d d }||dd|   |d| d  }q4|d |d krtd|d d	rt	
 D ]H\}}|jd krq|jd
sqt|j dd }|d |kr qqtd| t|d |jd}n>|d dkrHt|d \}	}
td|	|
d}ntd|d  W n. tttjfk
r   td|d  Y nX |S )N    r  zNot an openssh public keyr   r  r  r   zMismatch in openssh public key   ecdsa-sha2-
ecdsa-sha2r   r   zUnsupported ECC curve: r(     ssh-ed25519r   r   zUnsupported SSH key type: zError parsing SSH key type: )r  r3   rn   r   
a2b_base64r  unpackappend
startswithr7   r!  r  r   r%  r   r)  r  r9  r   Error)r-  partsZ	keystringZkeypartsZlkr   rw   r  Zecc_keyru   rv   r(   r(   r)   _import_openssh_public  s<    

rF  c                 C   s  ddl m}m}m}m} || |\}}ddtdfi}|dr||\}	}|	tkr`td|	 t|	 }
|
j	d d	 }||\}}t
|d
 dkrtdt|d| d krtdt|dd|  }t|d| d  }||\}}t|}||	d}n`||krX|| \}}}||\}}||\}}||\}}|d | }||d}ntd| ||\}}|| tf ||d|S )Nr   )import_openssh_private_generic
read_bytesread_stringcheck_paddingr]   r   rK   r>  zUnsupported ECC curve %sr   r   r   r  z/Only uncompressed OpenSSH EC keys are supportedr   zIncorrect public key length)r   rw   )r   rw   zUnsupport SSH agent key type:)r  r  )Z_opensshrG  rH  rI  rJ  r)  rC  r7   re   r   r   rn   r3   r   r   r  )datapasswordrG  rH  rI  rJ  Zkey_typeZ	decryptedZ
eddsa_keysZecdsa_curve_namerw   rx   r   r  r  r   r   r   r   r0  Zseed_lenZprivate_public_keyr   _Zpaddedr(   r(   r)   _import_openssh_private_ecc  s@     

rN  c                 C   s   t | dkrtdtd}d}t| }|d d? }|d  dM  < tj|dd	}||krbtd
|dkrndS |d d | }|d | | d | }z:||}|| | }	t|	|}
|
d@ |kr||
 }
W n tk
r   tdY nX |
|fS )a~  Import an Ed25519 ECC public key, encoded as raw bytes as described
    in RFC8032_.

    Args:
      encoded (bytes):
        The Ed25519 public key to import. It must be 32 bytes long.

    Returns:
      :class:`EccKey` : a new ECC key object

    Raises:
      ValueError: when the given key cannot be parsed.

    .. _RFC8032: https://datatracker.ietf.org/doc/html/rfc8032
    rK   z9Incorrect length. Only Ed25519 public keys are supported.rZ   l   x&(7Z/
;(P8 se:8
w6Rr   r   r   r   r   zInvalid Ed25519 key (y)r   r   r   r   zInvalid Ed25519 public key)r3   rn   r   r   r   r   _tonelli_shanksr-  r<   r   rv   Zx_lsbr  uvZv_invZx2r  r(   r(   r)   r)  <  s.    
r)  c                 C   s   t | dkrtdtd}d}| dd }t| d d? }tj|dd	}||krZtd
|dkrfdS |d d | }|d | | d | }z:||}|| | }	t|	|}
|
d@ |kr||
 }
W n tk
r   tdY nX |
|fS )az  Import an Ed448 ECC public key, encoded as raw bytes as described
    in RFC8032_.

    Args:
      encoded (bytes):
        The Ed448 public key to import. It must be 57 bytes long.

    Returns:
      :class:`EccKey` : a new ECC key object

    Raises:
      ValueError: when the given key cannot be parsed.

    .. _RFC8032: https://datatracker.ietf.org/doc/html/rfc8032
    r   z7Incorrect length. Only Ed448 public keys are supported.ra   l   Vg?Nr   r   r   r   zInvalid Ed448 key (y)r   rO  r   zInvalid Ed448 public key)r3   rn   r   r   r   r   rP  rQ  r(   r(   r)   r*  i  s,    
r*  c              
   C   s  ddl m} t| } |dk	r$t|}| drVt| }|||\}}}t||}|S | drt| }d}	d}
tj|	d |
 d	|tj	d
}|||\}}}|rd}zt
||}W n@ tk
r } z|W 5 d}~X Y n tk
r   tdY nX |S | drt| S t| dkr8t| d dkr8t
| |S t| dkrvt| d dkrv|dkrjtdt| |dS tddS )a
  Import an ECC key (public or private).

    Args:
      encoded (bytes or multi-line string):
        The ECC key to import.
        The function will try to automatically detect the right format.

        Supported formats for an ECC **public** key:

        * X.509 certificate: binary (DER) or ASCII (PEM).
        * X.509 ``subjectPublicKeyInfo``: binary (DER) or ASCII (PEM).
        * SEC1_ (or X9.62), as ``bytes``. NIST P curves only.
          You must also provide the ``curve_name`` (with a value from the `ECC table`_)
        * OpenSSH line, defined in RFC5656_ and RFC8709_ (ASCII).
          This is normally the content of files like ``~/.ssh/id_ecdsa.pub``.

        Supported formats for an ECC **private** key:

        * A binary ``ECPrivateKey`` structure, as defined in `RFC5915`_ (DER).
          NIST P curves only.
        * A `PKCS#8`_ structure (or the more recent Asymmetric Key Package, RFC5958_): binary (DER) or ASCII (PEM).
        * `OpenSSH 6.5`_ and newer versions (ASCII).

        Private keys can be in the clear or password-protected.

        For details about the PEM encoding, see `RFC1421`_/`RFC1423`_.

      passphrase (byte string):
        The passphrase to use for decrypting a private key.
        Encryption may be applied protected at the PEM level (not recommended)
        or at the PKCS#8 level (recommended).
        This parameter is ignored if the key in input is not encrypted.

      curve_name (string):
        For a SEC1 encoding only. This is the name of the curve,
        as defined in the `ECC table`_.

    .. note::

        To import EdDSA private and public keys, when encoded as raw ``bytes``, use:

        * :func:`Cryptodome.Signature.eddsa.import_public_key`, or
        * :func:`Cryptodome.Signature.eddsa.import_private_key`.

    Returns:
      :class:`EccKey` : a new ECC key object

    Raises:
      ValueError: when the given key cannot be parsed (possibly because
        the pass phrase is wrong).

    .. _RFC1421: https://datatracker.ietf.org/doc/html/rfc1421
    .. _RFC1423: https://datatracker.ietf.org/doc/html/rfc1423
    .. _RFC5915: https://datatracker.ietf.org/doc/html/rfc5915
    .. _RFC5656: https://datatracker.ietf.org/doc/html/rfc5656
    .. _RFC8709: https://datatracker.ietf.org/doc/html/rfc8709
    .. _RFC5958: https://datatracker.ietf.org/doc/html/rfc5958
    .. _`PKCS#8`: https://datatracker.ietf.org/doc/html/rfc5208
    .. _`OpenSSH 6.5`: https://flak.tedunangst.com/post/new-openssh-key-format-and-bcrypt-pbkdf
    .. _SEC1: https://www.secg.org/sec1-v2.pdf
    r   r   Ns   -----BEGIN OPENSSH PRIVATE KEYs   -----z-----BEGIN EC PARAMETERS-----z-----END EC PARAMETERS-----z.*?r   )flagsz(Invalid DER encoding inside the PEM file)r=  r?  rQ   )r   r  r  zNo curve name was provided)r   zECC key format is not supported)r   r   r   rC  r   r+  rN  resubDOTALLr;  re   rn   rF  r3   r   r%  )r-  r   r   r   Ztext_encodedZopenssh_encodedmarkerZenc_flagr'   Zecparams_startZecparams_endZder_encodedZuefr(   r(   r)   
import_key  sH    ?


 
 
rY  __main__l   _,)N$chKf-5lk<Xk#E i  z	(P-256 G)i  msz(P-256 arbitrary point))NN)N)NN)p
__future__r   rU  r  r   collectionsr   ZCryptodome.Util.py3compatr   r   r   r   r   ZCryptodome.Util.numberr	   r
   ZCryptodome.Math.Numbersr   ZCryptodome.Util.asn1r   r   r   r   ZCryptodome.Util._raw_apir   r   r   r   r   r   r   ZCryptodome.PublicKeyr   r   r   ZCryptodome.Hashr   r   ZCryptodome.Randomr   ZCryptodome.Random.randomr   r%   r#   r$   r*   r+   r7   r;   rB   rG   rH   rM   rN   rR   rS   rW   rX   r^   r_   rc   rd   rn   re   objectri   r?   r@   Zp192_G_replacer,   r8   r9   r:   Zp224_GrC   Zp256_GrI   Zp384_GrO   Zp521_GrT   Z	ed25519_GrY   Zed448_Gr`   r   r  r  r%  r1  r5  r7  r8  r;  rF  rN  r)  r*  rY  rf   timer   r   r   r~   r   startrangeru   ZpointXprintr(   r(   r(   r)   <module>   s   $




'
'
'
'
' O   `"6
84
2!.7-,
t
