U
    gc                     @   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rd dl5Z5d/Z6ed0 j78 Z9d1Z:e55 Z;e<e:D ]Z=e9e6 Z>qe?d2e55 e; e: d3 d4 e55 Z;e<e:D ]Z=e>e6 Z>qe?d5e55 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   </tmp/pip-unpacked-wheel-_q8s9isk/Cryptodome/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rt	d	dS |d
krt	d| j
jtjkrz| jdk	rt	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	rt	d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| _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	rt	dt| jdkrt	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	byteorder9   z.Parameter seed must be 57 bytes long for Ed448r      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)Cryptodome.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 }|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 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rtd| jj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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:`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
        .. _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}nt| jtj	kr~|d}t||d}nt| 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 )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.
    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	rt||| d< tf | }||j	 n^d||fkrt|||| 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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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|| \}	}
|rtd| |
|\}}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.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 rz>tdd|| j}|d k	rv||krvtd|}|d7 }W n tk
r   Y nX |d krtd	t	 D ]\}}|j
|kr qqtd
| |j }	t||	krt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	rt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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   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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   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!   _Z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 se: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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`.

    .. note::

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

        * :func:`Cryptodome.Protocol.DH.import_x25519_public_key`
        * :func:`Cryptodome.Protocol.DH.import_x25519_private_key`
        * :func:`Cryptodome.Protocol.DH.import_x448_public_key`
        * :func:`Cryptodome.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<Xk#E Zp256i  z	(P-256 G)i  msz(P-256 arbitrary point))NN)N)NN)@
__future__r   r  r   rY   ZCryptodome.Util.py3compatr   r   r   r   r   ZCryptodome.Math.Numbersr   ZCryptodome.Util.asn1r	   r
   r   r   ZCryptodome.PublicKeyr   r   r   ZCryptodome.Hashr   r   ZCryptodome.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-,
~
