o
    e                    @   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/g da0dd Z1e1  [1g da2dd Z3e3  [3g da4dd Z5e5  [5g d a6d!d" Z7e7  [7g d#a8d$d% Z9e9  [9d&d'ga:d(d) Z;e;  [;d*d+ga<d,d- Z=e=  [=G d.d/ d/e>Z?G d0d1 d1e@ZAeAe/d2 jBe/d2 jCd2ZDe/d2 jEeDd3ZFe/GeHIt0eF [D[Fb0eAe/d4 jBe/d4 jCd4ZJe/d4 jEeJd3ZKe/GeHIt2eK [J[Kb2eAe/d5 jBe/d5 jCd5ZLe/d5 jEeLd3ZMe/GeHIt4eM [L[Mb4eAe/d6 jBe/d6 jCd6ZNe/d6 jEeNd3ZOe/GeHIt6eO [N[Ob6eAe/d7 jBe/d7 jCd7ZPe/d7 jEePd3ZQe/GeHIt8eQ [P[Qb8eAe/d' jBe/d' jCd'ZRe/d' jEeRd3ZSe/GeHIt:eS [R[Sb:eAe/d+ jBe/d+ jCd+ZTe/d+ jEeTd3ZUe/GeHIt<eU [T[Ub<G d8d9 d9e@ZVd:d; ZWd<d= ZXd[d>d?ZYd@dA ZZd\dBdCZ[dDdE Z\dFdG Z]dHdI Z^dJdK Z_dLdM Z`dNdO ZadPdQ Zbd[dRdSZceddTkr_d dleZedUZfe/d5 jgh ZidVZjeee ZkelejD ]Zmeief Znq)eodWeee ek ej dX dY eee ZkelejD ]Zmenef ZnqGeodZeee ek ej dX dY dS dS )]    )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Crypto.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Crypto.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Crypto.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   sN   | j jdkrttd| }|S | j jdkrttd| }|S 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(   DD:\Projects\ConvertPro\env\Lib\site-packages\Crypto/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      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   B   





rC   )p224
NIST P-224zP-224Z
prime224v1Z	secp224r1Znistp224c                  C   r.   )Nl              ?l   FeY8w-X"PVd/%PP!-l   =*8%(?l   !"X!#BXtJ9!'|%VA-l   4~ 
f&Dv@h!fE0m9_qlM/   r0   z#Error %d initializing P-224 context   z1.3.132.0.33rF   zecdsa-sha2-nistp224rE   )r
   r   r%   r2   r3   r   r   r4   r   r   r5   r   r6   r7   r+   r   r8   r9   r:   r;   
p224_names)r=   r>   r?   r@   rA   Zp224_modulusZp224_bZ
p224_orderZec_p224_contextr'   rB   rE   r(   r(   r)   	init_p224   rD   rJ   )p256
NIST P-256zP-256Z
prime256v1Z	secp256r1Znistp256c                  C   r.   )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    r0   z#Error %d initializing P-256 context   z1.2.840.10045.3.1.7rL   zecdsa-sha2-nistp256rK   )r
   r   r%   r2   r3   r   r   r4   r   r   r5   r   r6   r7   r+   r   r8   r9   r:   r;   
p256_names)r=   r>   r?   r@   rA   Zp256_modulusZp256_bZ
p256_orderZec_p256_contextr'   rB   rK   r(   r(   r)   	init_p256  rD   rP   )p384
NIST P-384zP-384Z
prime384v1Z	secp384r1Znistp384c                  C   r.   )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   r0   z#Error %d initializing P-384 contexti  z1.3.132.0.34rR   zecdsa-sha2-nistp384rQ   )r
   r   r%   r2   r3   r   r   r4   r   r   r5   r   r6   r7   r+   r   r8   r9   r:   r;   
p384_names)r=   r>   r?   r@   rA   Zp384_modulusZp384_bZ
p384_orderZec_p384_contextr'   rB   rQ   r(   r(   r)   	init_p3840  rD   rU   )p521
NIST P-521zP-521Z
prime521v1Z	secp521r1Znistp521c                  C   r.   )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   r0   z#Error %d initializing P-521 contexti	  z1.3.132.0.35rW   zecdsa-sha2-nistp521rV   )r
   r   r%   r2   r3   r   r   r4   r   r   r5   r   r6   r7   r+   r   r8   r9   r:   r;   
p521_names)r=   r>   r?   r@   rA   Zp521_modulusZp521_bZ
p521_orderZec_p521_contextr'   rB   rV   r(   r(   r)   	init_p521_  rD   rZ   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-ed25519r[   )r+   r   r8   r9   r:   r;   ed25519_names)r=   r?   r@   rA   r[   r(   r(   r)   init_ed25519  s$   ra   ed448r   c                  C   s   d} d}d}d}t  }t| }|rt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   rb   )r   r$   Zed448_new_contextr3   r5   r   r6   Zed448_free_contextr+   r   r8   r9   r:   r;   ed448_names)r=   r?   r@   rA   Zed448_contextr'   rB   rb   r(   r(   r)   
init_ed448  s.   rf   c                   @   s   e Zd ZdS )UnsupportedEccFeatureN)__name__
__module____qualname__r(   r(   r(   r)   rg     s    rg   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
    rK   c                 C   s  zt | | _W n ty   tdt| w || _|  }t||}t||}t||ks4t||kr8tdt	| d}t	| d}t
 | _z| jj }	W n tyY   t}	Y nw || j t|t|t||	}
|
r{|
dkrut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)r8   r    KeyError
ValueErrorstr_curve_namesize_in_bytesr
   r4   r*   r   _pointrB   r6   AttributeErrorr   r3   r   r   r   )selfxycurvemodulus_bytesxbybrl   	free_funcrB   r'   r(   r(   r)   __init__  s<   




zEccPoint.__init__c                 C   sX   t | d}t | d}t | _|| j |j }|r!td| t| j || _| S )Nclonerm   z"Error %d while cloning an EC point)r*   r   rt   r3   r6   rp   r   )rv   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   )
isinstancerk   r*   rt   r6   )rv   r   Zcmp_funcr(   r(   r)   __eq__  s   

zEccPoint.__eq__c                 C   s
   | |k S Nr(   )rv   r   r(   r(   r)   __ne__      
zEccPoint.__ne__c                 C   s4   t | d}|  }||j }|rtd| |S )Nnegz$Error %d while inverting an EC point)r*   copyrt   r6   rp   )rv   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.)xyrk   rr   )rv   rw   rx   r   r(   r(   r)   r   +  s   
zEccPoint.copyc                 C      | j jdv S )Nr[   rb   )r    namerv   r(   r(   r)   	_is_eddsa1     zEccPoint._is_eddsac                 C   s   |   r	| jdkS | jdkS )z,``True`` if this is the *point-at-infinity*.r   )r   r   )r   rw   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 )z-Return the *point-at-infinity* for the curve.r      )r   rk   rr   r   r(   r(   r)   point_at_infinity<  s   zEccPoint.point_at_infinityc                 C   
   | j d S )Nr   r   r   r(   r(   r)   rw   D     
z
EccPoint.xc                 C   r   )Nr   r   r   r(   r(   r)   rx   H  r   z
EccPoint.yc                 C   sj   |   }t|}t|}t| d}|t|t|t|| j }|r)td| tt	|tt	|fS )Nget_xyz#Error %d while encoding an EC point)
rs   	bytearrayr*   r   r   rt   r6   rp   r   r	   )rv   rz   r{   r|   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)   rs   [  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*   rt   r6   rp   )rv   Zdouble_funcr'   r(   r(   r)   r   c  s
   
zEccPoint.doublec                 C   sD   t | d}|| j |j }|r |dkrt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   )rv   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   )rv   r   r   r(   r(   r)   __add__{     zEccPoint.__add__c                 C   s^   t | d}|dk rtdt|}|| j t|tt|tt	d}|r-td| | S )zMultiply this point by a scalarscalarr   z?Scalar multiplication is only defined for non-negative integersr0   z%Error %d during scalar multiplication)
r*   rp   r
   rt   r6   r   r   r4   r   r   )rv   r   Zscalar_funcsbr'   r(   r(   r)   __imul__  s   



zEccPoint.__imul__c                 C   s   |   }||9 }|S )z2Return a new point, the scalar product of this oner   )rv   r   r   r(   r(   r)   __mul__  r   zEccPoint.__mul__c                 C   s
   |  |S r   )r   )rv   Z	left_handr(   r(   r)   __rmul__  r   zEccPoint.__rmul__N)rK   )rh   ri   rj   __doc__r~   r   r   r   r   r   r   r   r   propertyrw   rx   r   rs   r   r   r   r   r   r   r   r(   r(   r(   r)   rk     s2    
&


rk   r,   )GrE   rK   rQ   rV   c                   @   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   sF  t |}|dd}|dd| _|dd| _|dd| _|du r*| jr*| jj}|r4tdt| |tvr>t	d| t| | _
| j
j| _t| jdut| jdu }|dkre| jdu rct	d	dS |d
krmt	d|  s| jdurzt	dt| j| _d| j  kr| j
jk st	d t	ddS | jdurt	d| j
jdkrt| jdkrt	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.
        ry   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 curvesr[   rM   z0Parameter seed must be 32 bytes long for Ed25519         r0   rb   9   z.Parameter seed must be 57 bytes long for Ed448r      7      8   little	byteorder)r:   pop_d_seedrt   rr   	TypeErrorrq   r8   rp   r    r!   ry   intr   r   r?   r   r4   r   newdigest_prefixr   r   read
from_bytes)rv   kwargskwargs_
curve_namecountZ	seed_hashtmpr(   r(   r)   r~     sb   




zEccKey.__init__c                 C   r   )N)r   r   )r    r!   r   r(   r(   r)   r   #  r   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)rv   otherr(   r(   r)   r   &  s
   
zEccKey.__eq__c                 C   sZ   |   r|  rdtt| j }n
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!   )rv   extrarw   rx   r(   r(   r)   __repr__/  s   zEccKey.__repr__c                 C   s
   | j du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J  J | j j}tjd|d}| j| }|| |}| j j| j| }||| ||   | }||fS )Nr   r   )min_inclusivemax_exclusive)r    r?   r   random_ranger   inverser   rw   )	rv   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   rw   )rv   r   rsr?   ZsinvZpoint1Zpoint2r(   r(   r)   _verifyO  s
   zEccKey._verifyc                 C      |   std| jS NzThis is not a private ECC key)r   rp   r   r   r(   r(   r)   r   V     zEccKey.dc                 C   r   r   )r   rp   r   r   r(   r(   r)   r   \  r   zEccKey.seedc                 C   s    | j d u r| jj| j | _ | j S r   )rt   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
        )ry   r   )r   r    r!   r   r   r(   r(   r)   
public_keyh  s   zEccKey.public_keyc                 C   sn   |   rtd| j }|r%| jj rd}nd}|| jj| }|S d| jj| | jj| }|S )Nz+SEC1 format is unsupported for EdDSA curves         )r   rp   r   rs   rx   is_oddrw   to_bytes)rv   compressrz   
first_byter   r(   r(   r)   _export_SEC1q  s"   
zEccKey._export_SEC1c                 C   s   | j j\}}| jjdkr%t|jddd}|d@ d> |d B |d< t|S | jjdkr@t|jd	dd}|d@ d> |d
< t|S td)Nr[   rM   r   r   r   r   r   rb   r   r   zNot an EdDSA key to export)r   r   r    r   r   r   rp   bytes)rv   rw   rx   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   )rv   r   r   r   paramsr(   r(   r)   _export_subjectPublicKeyInfo  s   
z#EccKey._export_subjectPublicKeyInfoTc                 C   sx   |   sJ | j }d| jj| | jj| }dt| j|t| j	j
ddt|ddg}|s6|d= t| S )Nr   r   r   Zexplicitr   )r   r   rs   rw   r   rx   r   r   r   r    r   r   r   encode)rv   include_ec_paramsrz   r   seqr(   r(   r)   _export_rfc5915_private_der  s   


z"EccKey._export_rfc5915_private_derc                 K   s   ddl m} |dd d urd|vrtd|  r(| jj}t| j	 }d }nd}| j
dd}t| jj}|j||fd	|i|}|S )
Nr   PKCS8
passphrase
protection5At least the 'protection' parameter should be presentr   F)r   Z
key_params)	Crypto.IOr   r6   rp   r   r    r   r   r   r   r   r   wrap)rv   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   )rv   r   r  encoded_derr(   r(   r)   _export_public_pem  s   
zEccKey._export_public_pemc                 K   s*   ddl m} |  }|j|d|fi |S )Nr   r  zEC PRIVATE KEY)r   r  r   r   rv   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   )rv   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
J d|vrtd| jdd|i|}||dS )Nr   r  r   r   r   zENCRYPTED PRIVATE KEYr(   )r   r  rp   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 u rtd| jj |dkr)|  }t|t|f}n;| j }|rDd| 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packr4   ).0rw   r(   r(   r)   
<listcomp>  s     z*EccKey._export_openssh.<locals>.<listcomp> )r   rp   r    opensshr   r   r   r   rs   rx   r   r   rw   r   splitjoinr   r   
b2a_base64)	rv   r   r!   r   compsrz   r   middleZblobr(   r(   r)   _export_openssh  s.   
zEccKey._export_opensshc                 K   sx  |  }|d}|dvrtd| |dd}|  r|dd}t|r1t|}|s1td|d	d
}|sA|  rAtd|dkr_|rV|rR| j|fi |S |  S | j	|fi |S |dkr{|rk|sktd|rw| j
dd|i|S |  S td| |rtd| |dkr| |S |dkr| |S |dkr| |S |dkr| jjdv r|  S | |S | |S )a  Export this ECC key.

        Args:
          format (string):
            The format to use for encoding the key:

            - ``'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 (byte string or string):
            The passphrase to use for protecting the private key.

          use_pkcs8 (boolean):
            Only relevant for private keys.

            If ``True`` (default and recommended), the `PKCS#8`_ representation
            will be used. It must be ``True`` for EdDSA curves.

          protection (string):
            When a private key is exported with password-protection
            and PKCS#8 (both ``DER`` and ``PEM`` formats), this parameter MUST be
            present and be a valid algorithm supported by :mod:`Crypto.IO.PKCS8`.
            It is recommended to use ``PBKDF2WithHMAC-SHA1AndAES128-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.

        .. 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:`Crypto.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  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   r   rp   r   r   r   r   r	  r  r  r  r   r  r   r   r    r   r   r  )rv   r   argsZ
ext_formatr   r   r  r(   r(   r)   
export_key  sT   F





zEccKey.export_keyN)T)rh   ri   rj   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     s6    L	


	
	r   c                  K   s   |  d}t| }|  dt}| rtdt|  t| jdkr,|d}t||d}|S t| jdkr?|d}t||d}|S tjd	|j	|d
}t||d}|S )a1  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:`Crypto.Random.get_random_bytes` is used.
    ry   randfuncr   r[   rM   ry   r   rb   r   r   )r   r   r   )ry   r   )
r   r8   r   r   rq   r   r   r   r   r?   )r   r   ry   r   r   new_keyr   r(   r(   r)   generate  s&   

r#  c                  K   s   | d }t | }| dd}| dd}d| v rtdd||fvr*t|||| d< tdi | }| rJd| v rJ|j|j }|j||fkrJt	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
    ry   point_xNpoint_yr   zUnknown keyword: pointz(Private and public ECC keys do not matchr(   )
r8   r   r   rk   r   r   r   r   r   rp   )r   r   ry   r$  r%  r"  Zpub_keyr(   r(   r)   	construct  s   r&  c           	      C   sP  t  D ]\}}|r|j|kr n||kr nq|r td| td| |j }t| d }|dkrZt| dd|  krCtdt	
| d|d  }t	
| |d d }nG|d	v rt| d| krjtdt	
| dd }|d
 |d
  |j |j}|dkr| r|j| }|d
kr| r|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ry   r$  r%  )r8   itemsr   rg   r=   rs   r   r4   rp   r   r   r>   sqrtr   Zis_evenr&  )	ec_point	curve_oidr   rr   ry   rz   Z
point_typerw   rx   r(   r(   r)   _import_public_der  s8   



r0  c                 G   s   t | \}}}d}dtfdtfd}||v r9|std| z	t |j}W n ty2   tdw t||dS ||v rX|| \}}	|rKtd| |	|\}
}t|
||d	S t	d
| )z4Convert a subjectPublicKeyInfo into an EccKey objectr   z1.3.132.1.12z1.3.132.1.13r   r   r^   rd   z%Missing ECC parameters for ECC OID %szError decoding namedCurver/  z(Unexpected ECC parameters for ECC OID %s)r$  r%  ry   zUnsupported ECC OID: %s)
r   _import_ed25519_public_key_import_ed448_public_keyrp   r   decodevaluer0  r&  rg   )encodedr   r   r.  r   nist_p_oids
eddsa_oidsr/  r   import_eddsa_public_keyrw   rx   r(   r(   r)   _import_subjectPublicKeyInfo  s*   
r<  c                 C   s<  t  j| dd}|d dkrtdztdd|d j}|d ur*||kr*td|}W n	 ty6   Y nw |d u r?td	t D ]\}}|j|krN nqCtd
| t	 |d j
}|j }t||krmtdt|}	t|dkrt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 smallr3  )ry   r   r$  r%  )r   r6  rp   r   r7  r8   r,  r   rg   r   payloadr=   rs   r4   r   r   r   r0  r   rw   rx   r&  )r8  r   r/  r   
parametersr   ry   Zscalar_bytesrz   r   Zpublic_key_encr   r$  r%  r(   r(   r)   _import_rfc5915_derP  s<   



r@  c           
      C   s   ddl m} || |\}}}d}ddd}||v r't |j}t|||S ||v rD|d ur3tdd }t |j	}	t
|| |	dS td	| )
Nr   r   r1  r   r   r2  z.EdDSA ECC private key must not have parametersr!  z!Unsupported ECC purpose (OID: %s))r   r   unwrapr   r6  r7  r@  rp   r   r>  r&  rg   )
r8  r   r   Zalgo_oidr   r   r9  r:  r/  r   r(   r(   r)   _import_pkcs8  s    rB  c                 G   s   t | }t|S r   )r   r<  )r8  r   Zsp_infor(   r(   r)   _import_x509_cert  s   rC  c              
   C   s  zt | |W S  ty } z|d }~w tttfy   Y nw zt| |W S  ty4 } z|d }~w tttfy?   Y nw zt| |W S  tyT } z|d }~w tttfy_   Y nw zt| |W S  tyt } z|d }~w tttfy   Y tdw )NzNot an ECC DER key)r<  rg   rp   r   
IndexErrorrC  r@  rB  )r8  r   errr(   r(   r)   _import_der  sB   rF  c              
   C   s  |  d}t|dvrtdzt|d }g }t|dkrDtd|d d d }||dd|   |d| d  }t|dks|d |d krPtd|d d	rt	
 D ]#\}}|jd u req[|jd
slq[t|j dd }|d |kr~ nq[td| t|d |jd}W |S |d dkrt|d \}	}
td|	|
d}W |S td|d   tttjfy   td|d  w )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: r3     ssh-ed25519r   r+  zUnsupported SSH key type: zError parsing SSH key type: )r  r4   rp   r   
a2b_base64r  unpackappend
startswithr8   r,  r  r   r0  r   r4  r&  rD  r   Error)r8  partsZ	keystringZkeypartsZlkr   ry   r  Zecc_keyrw   rx   r(   r(   r)   _import_openssh_public  sD   

rQ  c                 C   s  ddl m}m}m}m} || |\}}ddtdfi}|dr||\}	}|	tvr/td|	 t|	 }
|
j	d d	 }||\}}t
|d
 dkrLtdt|d| d krZtdt|dd|  }t|d| d  }||\}}t|}||	d}n/||v r|| \}}}||\}}||\}}||\}}|d | }||d}ntd| ||\}}|| td||d|S )Nr   )import_openssh_private_generic
read_bytesread_stringcheck_paddingr_   r   rM   rI  zUnsupported ECC curve %sr   r   r   r(  z/Only uncompressed OpenSSH EC keys are supportedr   zIncorrect public key length)r   ry   )r   ry   zUnsupport SSH agent key type:)r$  r%  r(   )Z_opensshrR  rS  rT  rU  r4  rN  r8   rg   r   r   rp   r4   r   r   r&  )datapasswordrR  rS  rT  rU  Zkey_typeZ	decryptedZ
eddsa_keysZecdsa_curve_namery   rz   r   r$  r%  r   r   r   r   r;  Zseed_lenZprivate_public_keyr   _paddedr(   r(   r)   _import_openssh_private_ecc  s>   


rZ  c                 C   s   t | dkr
tdtd}d}t| }|d d? }|d  dM  < tj|dd	}||kr1td
|dkr7dS |d d | }|d | | d | }z%||}|| | }	t|	|}
|
d@ |krl||
 }
W |
|fS W |
|fS  ty{   tdw )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
    rM   z9Incorrect length. Only Ed25519 public keys are supported.r\   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)r4   rp   r   r   r   r   _tonelli_shanksr8  r=   r   rx   Zx_lsbr%  uvZv_invZx2r$  r(   r(   r)   r4  *  s4   

r4  c                 C   s   t | dkr
tdtd}d}| dd }t| d d? }tj|dd	}||kr-td
|dkr3dS |d d | }|d | | d | }z%||}|| | }	t|	|}
|
d@ |krh||
 }
W |
|fS W |
|fS  tyw   tdw )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.rc   l   Vg?Nr   r   r   r   zInvalid Ed448 key (y)r   r[  r   zInvalid Ed448 public key)r4   rp   r   r   r   r   r\  r]  r(   r(   r)   r5  W  s2   

r5  c              
   C   s`  ddl m} t| } |durt|}| dr+t| }|||\}}}t||}|S | drtt| }d}	d}
tj|	d |
 d	|tj	d
}|||\}}}|rSd}zt
||}W |S  tyi } z|d}~w tys   tdw | dr}t| S t| dkrt| d dkrt
| |S t| dkrt| d dv r|du rtdt| |dS td)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:`Crypto.Signature.eddsa.import_public_key`, or
        * :func:`Crypto.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)rH  rJ  rS   s   zNo curve name was provided)r   zECC key format is not supported)r   r  r   rN  r   r6  rZ  resubDOTALLrF  rg   rp   rQ  r4   r   r0  )r8  r   r   r  Ztext_encodedZopenssh_encodedmarkerZenc_flagr'   Zecparams_startZecparams_endZder_encodedZuefr(   r(   r)   
import_key  sL   ?




re  __main__l   _,)N$chKf-5lk<Xk#E i  z	(P-256 G)i  msz(P-256 arbitrary point))NNr   )p
__future__r   ra  r  r   collectionsr   ZCrypto.Util.py3compatr   r   r   r   r   ZCrypto.Util.numberr	   r
   ZCrypto.Math.Numbersr   ZCrypto.Util.asn1r   r   r   r   ZCrypto.Util._raw_apir   r   r   r   r   r   r   ZCrypto.PublicKeyr   r   r   ZCrypto.Hashr   r   ZCrypto.Randomr   ZCrypto.Random.randomr   r%   r#   r$   r*   r+   r8   r<   rC   rI   rJ   rO   rP   rT   rU   rY   rZ   r`   ra   re   rf   rp   rg   objectrk   r@   rA   Zp192_G_replacer,   r9   r:   r;   Zp224_GrE   Zp256_GrK   Zp384_GrQ   Zp521_GrV   Z	ed25519_Gr[   Zed448_Grb   r   r#  r&  r0  r<  r@  rB  rC  rF  rQ  rZ  r4  r5  re  rh   timer   r   r   r   r   startrangerw   ZpointXprintr(   r(   r(   r)   <module>   s   $



''''' O   N"
68
42!.7-
,
t 