U
    ÈZj»  ã                   @   sö  d dl mZ d dlZd dlZd dlZd dlmZmZmZ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 d dlmZmZ d dlmZ d	d
lmZmZmZ d	dlmZ  G dd„ de!ƒZ"G dd„ de#ƒZ$dd„ Z%dd„ Z&d6dd„Z'dd„ Z(d7dd„Z)dd„ Z*dd„ Z+dd„ Z,d d!„ Z-d"d#„ Z.d$d%„ Z/d&d'„ Z0d(d)„ Z1d*d+„ Z2d8d,d-„Z3e4d.k�ròd dl5Z5d/Z6ed0 j7 8¡ Z9d1Z:e5 5¡ Z;e<e:ƒD ]Z=e9e6 Z>�qŠe?d2e5 5¡ e; e: d3 d4ƒ e5 5¡ Z;e<e:ƒD ]Z=e>e6 Z>�qÆe?d5e5 5¡ e; e: d3 d4ƒ dS )9é    )Úprint_functionN)ÚbordÚtobytesÚtostrÚbchrÚ	is_string)ÚInteger)ÚDerObjectIdÚDerOctetStringÚDerSequenceÚDerBitString)Ú_expand_subject_public_key_infoÚ_create_subject_public_key_infoÚ _extract_subject_public_key_info)ÚSHA512ÚSHAKE256)Úget_random_bytesé   )ÚEccPointÚ	EccXPointÚ_curves)ÚCurveIDc                   @   s   e Zd ZdS )ÚUnsupportedEccFeatureN)Ú__name__Ú
__module__Ú__qualname__© r   r   úW/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/Crypto/PublicKey/ECC.pyr   7   s   r   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	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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 **canonical** 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` or :class:`EccXPoint`

    :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 Ed22519 (32 bytes), Curve25519 (32 bytes),
                Curve448 (56 bytes), Ed448 (57 bytes).
    :vartype seed: bytes
    c                 K   sb  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rÆt	d	ƒ‚dS |d
krÚt	dƒ‚| j
jtjk�rz| jdk	rüt	dƒ‚t| jƒdk�rt	dƒ‚t | j¡ ¡ }|dd… | _t|dd… ƒ}|d  dM  < |d d@ dB |d< tj|dd�| _�nä| j
jtjk�r"| jdk	�ržt	dƒ‚t| jƒdk�r¶t	dƒ‚t | j¡ d¡}|dd… | _t|dd… ƒ}|d  dM  < |d  dO  < d|d< tj|dd�| _�n<| j
jtjk�rž| jdk	�rFt	dƒ‚t| jƒdk�r^t	dƒ‚t| jƒ}|d  dM  < |d d@ dB |d< tj|dd�| _nÀ| j
jtjk�r| jdk	�rÂt	dƒ‚t| jƒdk�rÚt	dƒ‚t| jƒ}|d  dM  < |d  dO  < tj|dd�| _nH| jdk	�r*t	dƒ‚t| jƒ| _d| j  k�rT| j
jk �s^n t	d ƒ‚dS )!a˜  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 Ed25519 (32 bytes),
            Curve25519 (32 bytes), Curve448 (56 bytes) or Ed448 (57 bytes).
          point : EccPoint or EccXPoint
            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.
        ÚcurveNÚdÚseedÚpointú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 exclusivez/Parameter d can only be used with NIST P curvesé    z0Parameter seed must be 32 bytes long for Ed25519éø   é   é   é@   Úlittle©Ú	byteorderé9   z.Parameter seed must be 57 bytes long for Ed448ér   éü   é7   é€   é8   z3Parameter seed must be 32 bytes long for Curve25519z1Parameter seed must be 56 bytes long for Curve448z2Parameter 'seed' cannot be used with NIST P-curvesr   z;Parameter d must be an integer smaller than the curve order)ÚdictÚpopÚ_dÚ_seedÚ_pointr   Ú	TypeErrorÚstrr   Ú
ValueErrorÚ_curveÚ	canonicalÚintÚidÚ_CurveIDÚED25519Úlenr   ÚnewÚdigestÚ_prefixÚ	bytearrayr   Ú
from_bytesÚED448r   ÚreadÚ
CURVE25519ÚCURVE448Úorder)ÚselfÚkwargsZkwargs_Ú
curve_nameÚcountZ	seed_hashÚtmpr   r   r   Ú__init__Q   s„    





 zEccKey.__init__c                 C   s.   t |tƒsdS | ¡ |  ¡ kr"dS |j| jkS )NF)Ú
isinstancer   Úhas_privateÚpointQ)rL   Úotherr   r   r   Ú__eq__³   s
    
zEccKey.__eq__c                 C   sŽ   |   ¡ r6| jjr&dtt | j¡ƒ }q:dt| jƒ }nd}| jj	t
jt
jfkrj| jj}d| jj||f }n | jj\}}d| jj|||f }|S )Nz	, seed=%sz, d=%dÚ z EccKey(curve='%s', point_x=%d%s)z,EccKey(curve='%s', point_x=%d, point_y=%d%s))rS   r;   Ú
is_edwardsr   ÚbinasciiÚhexlifyr6   r=   r5   r>   r?   rI   rJ   rT   Úxr<   Úxy)rL   Úextrar[   ÚresultÚyr   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)r5   ©rL   r   r   r   rS   Í   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;   rK   ÚAssertionErrorr   Úrandom_ranger5   ÚinverseÚGr[   )	rL   ÚzÚkrK   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;   rK   rf   rg   rT   r[   )rL   rh   ÚrsrK   ZsinvZpoint1Zpoint2r   r   r   Ú_verifyâ   s
    zEccKey._verifyc                 C   s   |   ¡ stdƒ‚| jS ©NzThis is not a private ECC key)rS   r:   r5   ra   r   r   r   r    é   s    zEccKey.dc                 C   s   |   ¡ stdƒ‚| jS ro   )rS   r:   r6   ra   r   r   r   r!   ï   s    zEccKey.seedc                 C   s    | j d kr| jj| j | _ | j S ©N)r7   r;   rg   r5   ra   r   r   r   rT   õ   s    
zEccKey.pointQc                 C   s   t | jj| jd�S )z^A matching ECC public key.

        Returns:
            a new :class:`EccKey` object
        )r   r"   )r   r;   r<   rT   ra   r   r   r   Ú
public_keyû   s    zEccKey.public_keyc                 C   sl   | j jstdƒ‚| j ¡ }|rH| jj ¡ r0d}nd}|| jj |¡ }n d| jj |¡ | jj |¡ }|S )Nz/SEC1 format is only supported for NIST P curvesó   ó   ó   )	r;   Zis_weierstrassr:   rT   Úsize_in_bytesr_   Úis_oddr[   Úto_bytes)rL   ÚcompressÚmodulus_bytesÚ
first_byterq   r   r   r   Ú_export_SEC1  s     
ÿÿþzEccKey._export_SEC1c                 C   sˆ   | j j\}}| jjtjkrFt|jddd�ƒ}|d@ d> |d B |d< n:| jjtjkrxt|jddd�ƒ}|d@ d> |d< nt	d	ƒ‚t
|ƒS )
Nr%   r*   r+   r   é   r'   r-   r2   zNot an EdDSA key to export)rT   r\   r;   r>   r?   r@   rE   rw   rG   r:   Úbytes)rL   r[   r_   r^   r   r   r   Ú_export_eddsa_public   s    zEccKey._export_eddsa_publicc                 C   s<   | j jstdƒ‚| jj}| j ¡ }t|j|dd�ƒ}t|ƒS )NzNot a Montgomery key to exportr*   r+   )	r;   Úis_montgomeryr:   rT   r[   ru   rE   rw   r}   )rL   r[   Z
field_sizer^   r   r   r   Ú_export_montgomery_public,  s    
z EccKey._export_montgomery_publicc                 C   sb   | j jr| j j}|  ¡ }d }n8| j jr<| j j}|  ¡ }d }nd}|  |¡}t| j jƒ}t|||ƒS )Nú1.2.840.10045.2.1)	r;   rX   Úoidr~   r   r€   r{   r	   r   )rL   rx   r‚   rq   Úparamsr   r   r   Ú_export_subjectPublicKeyInfo4  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 )Nrt   r   r   ©Úexplicitr$   )rS   rd   rT   ru   r[   rw   r_   r
   r    r	   r;   r‚   r   r   Úencode)rL   Úinclude_ec_paramsry   rq   Úseqr   r   r   Ú_export_rfc5915_private_derF  s    

ÿþ
ýz"EccKey._export_rfc5915_private_derc                 K   sŠ   ddl m} | dd ¡d k	r,d|kr,tdƒ‚| jd k	rR| 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)Ú	Crypto.IOrŒ   Úgetr:   r6   r;   r‚   r
   r‡   rŠ   r	   Úwrap)rL   rM   rŒ   r‚   Úprivate_keyrƒ   r^   r   r   r   Ú_export_pkcs8a  s$    
ÿþýzEccKey._export_pkcs8c                 C   s"   ddl m} |  |¡}| |d¡S )Nr   ©ÚPEMz
PUBLIC KEY)r�   r•   r„   r‡   )rL   rx   r•   Úencoded_derr   r   r   Ú_export_public_pemv  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‡   ©rL   r�   rM   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‡   )rL   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•   rd   r:   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r0td| j ƒ‚n˜|dkrR|  ¡ }t|ƒt|ƒf}nv| j ¡ }|rˆd| 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 OpenSSHússh-ed25519r$   rt   ú-ó    c                 S   s    g | ]}t  d t|ƒ¡| ‘qS )ú>I)ÚstructÚpackrA   )Ú.0r[   r   r   r   Ú
<listcomp>«  s     z*EccKey._export_openssh.<locals>.<listcomp>ú )rS   r:   r;   Úopensshr   r~   r   rT   ru   r_   rv   r   r[   rw   ÚsplitÚjoinr   rY   Ú
b2a_base64)	rL   rx   Údescrq   Úcompsry   rz   Ú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
¡}|dkr¨| jjrˆtdƒ‚| jjr˜tdƒ‚d|kr¨tdƒ‚|dkrà|rÐ|rÆ| j	|f|ŽS |  
¡ S n| j|f|ŽS nJ|dk�r|rú|sútdƒ‚|�r| jf d|i|—ŽS |  ¡ S ntd| ƒ‚n’|�r>td| ƒ‚|dk�rR|  |¡S |dk�rf|  |¡S |dk�rz|  |¡S |dk�r´| jj�r–|  ¡ S | jj�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 Ed25519 and Ed448: ``bytes`` in the format
                defined in `RFC8032`_.
              * For Curve25519 and Curve448: ``bytes`` in the format
                defined in `RFC7748`_.

          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 Ed25519, Ed448, Curve25519, and Curve448.

            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-SHA512AndAES128-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 Ed25519/Ed448/Curve25519/Curve448,
            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:`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
        .. _RFC7748:    https://tools.ietf.org/html/rfc7748

        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'rx   Fr�   NzEmpty passphraseÚ	use_pkcs8Tz%'pkcs8' must be True for EdDSA curvesz#'pkcs8' must be True for Curve25519rŽ   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°   )Úcopyr4   r:   rS   r   r   r;   rX   r   r›   rš   r™   r“   rŠ   r—   r„   r{   r~   r€   r¬   )rL   rM   ÚargsZ
ext_formatrx   r�   r±   r   r   r   Ú
export_key®  sb    Z




ÿ








zEccKey.export_keyN)T)r   r   r   Ú__doc__rQ   rV   r`   rS   rl   rn   Úpropertyr    r!   rT   rq   r{   r~   r€   r„   rŠ   r“   r—   r™   rš   r›   r¬   r´   r   r   r   r   r   ;   s4   b	


	
	r   c                  K   s  |   d¡}t| }|   dt¡}| r2tdt| ƒ ƒ‚t| jtjkrX|dƒ}t||d�}n°t| jtj	kr~|dƒ}t||d�}nŠt| jtj
kr´|dƒ}t||d�}t|  |j¡ nTt| jtjkrê|dƒ}t||d�}t|  |j¡ n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.
    r   Úrandfuncr#   r%   ©r   r!   r-   r2   r   )rb   rc   r·   )r   r    )r4   r   r   r8   r9   r>   r?   r@   r   rG   rI   ÚvalidaterT   rJ   r   re   rK   )rM   rN   r   r·   r!   Únew_keyr    r   r   r   ÚgenerateF  s2    
þr»   c                  K   s  | d }t | }|  dd¡}|  dd¡}d| kr8tdƒ‚|jtjkrr|dk	rZt||ƒ| d< tf | Ž}| |j	¡ n˜|jtj
kr¬|dk	r”t||ƒ| d< tf | Ž}| |j	¡ n^d||fkrÈt|||ƒ| d< tf | Ž}| ¡ �r
d| k�r
|j|j }|j||fk�r
t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).
        It must be an integer in the range ``[1..order-1]``.

      seed (bytes):
        Mandatory for a private key and curves Ed25519 (32 bytes),
        Curve25519 (32 bytes), Curve448 (56 bytes) and Ed448 (57 bytes).

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

      point_y (integer):
        The Y coordinate (affine) of the ECC point.
        Mandatory for a public key,
        except for Curve25519 and Curve448.

    Returns:
      :class:`EccKey` : a new ECC key object
    r   Úpoint_xNÚpoint_yr"   zUnknown keyword: pointz(Private and public ECC keys do not match)r   r4   r8   r>   r?   rI   r   r   r¹   rT   rJ   r   rS   rg   r    r\   r:   )rM   rN   r   r¼   r½   rº   Zpub_keyr   r   r   Ú	constructp  s0    !


r¾   c           	      C   s\  t  ¡ D ]&\}}|r"|j|kr" qN||kr qNq|rBtd| ƒ‚ntd| ƒ‚|j ¡ }t| d ƒ}|dkr¶t| ƒdd|  krˆtdƒ‚t	 
| d|d … ¡}t	 
| |d d… ¡}n˜|d	k�rFt| ƒd| krØt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©r   r¼   r½   )r   Úitemsr‚   r   Úpru   r   rA   r:   r   rF   ÚbÚsqrtrv   Zis_evenr¾   )	Úec_pointÚ	curve_oidrN   Z_curve_namer   ry   Z
point_typer[   r_   r   r   r   Ú_import_public_der·  s4    



rÊ   c                 G   s  t | ƒ\}}}d}dtfdtfdœ}dtfdtfdœ}||krŠ|sNtd| ƒ‚ztƒ  |¡j}W n tk
r|   td	ƒ‚Y nX t	||d
�S ||krÈ|| \}	}
|r®td| ƒ‚|
|ƒ\}}t
|||	d�S ||k�r|| \}	}|rît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.13ÚEd25519ÚEd448©z1.3.101.112z1.3.101.113Ú
Curve25519ÚCurve448©z1.3.101.110z1.3.101.111z%Missing ECC parameters for ECC OID %szError decoding namedCurve©rÉ   z(Unexpected ECC parameters for ECC OID %s)r¼   r½   r   )r¼   r   zUnsupported ECC OID: %sN)r   Ú_import_ed25519_public_keyÚ_import_ed448_public_keyÚ_import_curve25519_public_keyÚ_import_curve448_public_keyr:   r	   ÚdecodeÚvaluerÊ   r¾   r   )ÚencodedrM   r‚   rÈ   rƒ   Únist_p_oidsÚ
eddsa_oidsÚxdh_oidsrÉ   rN   Úimport_eddsa_public_keyr[   r_   Zimport_xdh_public_keyr   r   r   Ú_import_subjectPublicKeyInfoï  s:    þþ

rÞ   c                 C   sz  t ƒ j| dd�}|d dkr$tdƒ‚tƒ  |d ¡j}d}|t|ƒk ršz>tdd� || ¡j}|d k	rv||krvtdƒ‚|}|d7 }W n tk
r˜   Y nX |d krªtd	ƒ‚t 	¡ D ]\}}|j
|kr² qÖq²td
| ƒ‚|j ¡ }	t|ƒ|	krôtdƒ‚d  }
}|t|ƒk �r`z>tdd� || ¡j}t||d�}|jj}
|jj}|d7 }W n tk
�r^   Y nX t |¡}t|||
|d�S )N©r$   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Ò   )r   r    r¼   r½   )r   r×   r:   r
   ÚpayloadrA   r	   rØ   r   rÄ   r‚   r   rÅ   ru   r   rÊ   rT   r[   r_   r   rF   r¾   )rÙ   r�   rÉ   Zec_private_keyZscalar_bytesZnext_elementÚ
parametersrN   r   ry   r¼   r½   Zpublic_key_encrq   r    r   r   r   Ú_import_rfc5915_der2  sF    


râ   c                 C   sè   ddl m} | | |¡\}}}d}dddœ}ddd	œ}||krXtƒ  |¡j}	t|||	ƒS ||kr’|d k	rptd
ƒ‚d }	tƒ  |¡j	}
t
|| |
d�S ||krØ|| }|d k	r¶td| ƒ‚d }	tƒ  |¡j	}
t
|| |
d�S td| ƒ‚d S )Nr   r‹   rË   rÌ   rÍ   rÎ   rÏ   rÐ   rÑ   z.EdDSA ECC private key must not have parametersr¸   z+%s ECC private key must not have parametersz!Unsupported ECC purpose (OID: %s))r�   rŒ   Úunwrapr	   r×   rØ   râ   r:   r
   rà   r¾   r   )rÙ   r�   rŒ   Zalgo_oidr’   rƒ   rÚ   rÛ   rÜ   rÉ   r!   rN   r   r   r   Ú_import_pkcs8m  s8    þþÿrä   c                 G   s   t | ƒ}t|ƒS rp   )r   rÞ   )rÙ   rM   Zsp_infor   r   r   Ú_import_x509_cert•  s    rå   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)rÞ   r   r:   r8   Ú
IndexErrorrå   râ   rä   )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r€t d|d d… ¡d }| |dd| … ¡ |d| d … }q4|d |d kr˜tdƒ‚|d  d	¡�rt	 
¡ D ]H\}}|jd krÄq°|j d
¡sÒq°t|j  d¡d ƒ}|d |kr° �qq°t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¦   rA   r:   rY   Ú
a2b_base64r    ÚunpackÚappendÚ
startswithr   rÄ   r¥   r   rÊ   r‚   rÓ   r¾   ræ   r8   ÚError)rÙ   ÚpartsZ	keystringZkeypartsZlkrN   r   r«   Zecc_keyr[   r_   r   r   r   Ú_import_openssh_public¼  s<    

ró   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rštdƒ‚t|ƒd| d kr¶t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Ì   r%   rë   zUnsupported ECC curve %sr|   é   r   rÀ   z/Only uncompressed OpenSSH EC keys are supportedr$   zIncorrect public key length)r    r   )r!   r   zUnsupport SSH agent key type:)r¼   r½   )Z_opensshrô   rõ   rö   r÷   rÓ   rð   r   r   Zmodulus_bitsr   r:   rA   r   rF   r¾   )ÚdataÚpasswordrô   rõ   rö   r÷   Zkey_typeZ	decryptedZ
eddsa_keysZecdsa_curve_namer   ry   rq   r¼   r½   r’   r    rƒ   rN   rÝ   Zseed_lenZprivate_public_keyr!   Ú_Úpaddedr   r   r   Ú_import_openssh_private_eccê  s@     ÿ

rý   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 )ai  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:
      x and y (integer)

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

    .. _RFC8032: https://datatracker.ietf.org/doc/html/rfc8032
    r%   z9Incorrect length. Only Ed25519 public keys are supported.l   íÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿl   £x²&(7Z/·
;(P8 ÑsÝe:Ì8ÎÛ
w6Rr'   r|   r(   r*   r+   zInvalid Ed25519 key (y)r   ©r   r   r$   zInvalid Ed25519 public key)rA   r:   r   rE   rF   rf   Ú_tonelli_shanks©rÙ   rÅ   r    r_   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M  < tj|dd�}|S )ah  Import a Curve25519 ECC public key,
    encoded as raw bytes as described in RFC7748_.

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

    Returns:
      x (integer)

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

    .. _RFC7748: https://datatracker.ietf.org/doc/html/rfc7748
    r%   zIncorrect Curve25519 key lengthr'   r(   r*   r+   )rA   r:   rE   r   rF   )rÙ   r[   r¼   r   r   r   rÕ   N  s    rÕ   c                 C   s&   t | ƒdkrtdƒ‚tj| dd�}|S )ad  Import a Curve448 ECC public key,
    encoded as raw bytes as described in RFC7748_.

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

    Returns:
      x (integer)

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

    .. _RFC7748: https://datatracker.ietf.org/doc/html/rfc7748
    r2   zIncorrect Curve448 key lengthr*   r+   )rA   r:   r   rF   )rÙ   r¼   r   r   r   rÖ   j  s    rÖ   c                 C   sô   t | ƒdkrtdƒ‚td j}|d }| dd… }t| d ƒd? }tj|dd	�}||kr`td
ƒ‚|dkrldS |d d | }|d | | d | }z:| |¡}|| | }	t |	|¡}
|
d@ |krÌ||
 }
W n tk
rê   tdƒ‚Y nX |
|fS )ag  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:
        x and y (integer)

    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.Zcurve448i©˜  Nr2   r|   r*   r+   zInvalid Ed448 key (y)r   rþ   r$   zInvalid Ed448 public key)	rA   r:   r   rÅ   r   r   rF   rf   rÿ   r   r   r   r   rÔ   ƒ  s,    

rÔ   c              
   C   s‚  ddl m} t| ƒ} |dk	r$t|ƒ}|  d¡rVt| ƒ}| ||¡\}}}t||ƒ}|S |  d¡rút| ƒ}d}	d}
tj|	d |
 d	|tj	d
�}| ||¡\}}}|r¦d}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 )ap  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`.

    .. note::

        To import X25519/X448 private and public keys, when encoded as raw ``bytes``, use:

        * :func:`Crypto.Protocol.DH.import_x25519_public_key`
        * :func:`Crypto.Protocol.DH.import_x25519_private_key`
        * :func:`Crypto.Protocol.DH.import_x448_public_key`
        * :func:`Crypto.Protocol.DH.import_x448_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.*?rW   )Úflagsz(Invalid DER encoding inside the PEM file)rê   rì   é0   rß   zNo curve name was provided)rN   zECC key format is not supported)r�   r•   r   rð   r   r×   rý   ÚreÚsubÚDOTALLrè   r   r:   ró   rA   r   rÊ   )rÙ   r�   rN   r•   Ztext_encodedZopenssh_encodedÚmarkerZenc_flagr^   Zecparams_startZecparams_endZder_encodedZuefr   r   r   Ú
import_key¯  sH    I


þ 
 
r	  Ú__main__l   ýö_,)¶NÌ$ÔcÐhKf-5lk<X÷k©#E Zp256i¸  z	(P-256 G)iè  Úmsz(P-256 arbitrary point))NN)N)NN)@Ú
__future__r   r  r    rY   ZCrypto.Util.py3compatr   r   r   r   r   ZCrypto.Math.Numbersr   ZCrypto.Util.asn1r	   r
   r   r   ZCrypto.PublicKeyr   r   r   ZCrypto.Hashr   r   ZCrypto.Randomr   r7   r   r   r   r   r?   r:   r   Úobjectr   r»   r¾   rÊ   rÞ   râ   rä   rå   rè   ró   rý   rÓ   rÕ   rÖ   rÔ   r	  r   Útimer    rg   r²   r"   rO   ÚstartÚranger[   ZpointXÚprintr   r   r   r   Ú<module>   sZ       *G
8C
;(!.7-,
~
