o
    Þý°j_»  ã                   @   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+„ Z2d6d,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 dS )8é    )Ú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   ú‹/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/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 representing 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 represents the private component
                in Ed22519 (32 bytes), Curve25519 (32 bytes),
                Curve448 (56 bytes), Ed448 (57 bytes).
    :vartype seed: bytes
    c                 K   sd  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ƒ‚| j
jtjkr»| jdu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�| _dS | j
jtjk�r| jdu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�| _dS | j
jtjk�rL| jdu�rt	dƒ‚t| jƒdk�r+t	dƒ‚t| jƒ}|d  dM  < |d d@ dB |d< tj|dd�| _dS | j
jtjk�r‰| jdu�r^t	dƒ‚t| jƒdk�rjt	dƒ‚t| jƒ}|d  dM  < |d  dO  < tj|dd�| _dS | jdu�r“t	dƒ‚t| jƒ| _d| j  k�r«| j
jk �s°t	d ƒ‚ 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ÚkwargsÚkwargs_Ú
curve_nameÚcountÚ	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�   |   ¡ r| jjrdtt | j¡ƒ }n
dt| jƒ }nd}| jj	t
jt
jfv r6| jj}d| jj||f }|S | 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))rU   r;   Ú
is_edwardsr   ÚbinasciiÚhexlifyr6   r=   r5   r>   r?   rI   rJ   rV   Úxr<   Úxy)rL   Úextrar]   ÚresultÚyr   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)r5   ©rL   r   r   r   rU   Í   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;   rK   r   Úrandom_ranger5   ÚinverseÚGr]   )	rL   ÚzÚkrK   ÚblindÚblind_dÚ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   rg   rh   rV   r]   )rL   ri   ÚrsrK   ÚsinvÚpoint1Úpoint2r   r   r   Ú_verifyâ   s
   zEccKey._verifyc                 C   ó   |   ¡ stdƒ‚| jS ©NzThis is not a private ECC key)rU   r:   r5   rc   r   r   r   r    é   ó   zEccKey.dc                 C   rv   rw   )rU   r:   r6   rc   r   r   r   r!   ï   rx   zEccKey.seedc                 C   s    | j d u r| jj| j | _ | j S ©N)r7   r;   rh   r5   rc   r   r   r   rV   õ   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<   rV   rc   r   r   r   Ú
public_keyû   s   zEccKey.public_keyc                 C   sn   | j jstdƒ‚| j ¡ }|r%| jj ¡ rd}nd}|| jj |¡ }|S d| jj |¡ | jj |¡ }|S )Nz/SEC1 format is only supported for NIST P curvesó   ó   ó   )	r;   Úis_weierstrassr:   rV   Úsize_in_bytesra   Úis_oddr]   Úto_bytes)rL   ÚcompressÚmodulus_bytesÚ
first_byterz   r   r   r   Ú_export_SEC1  s"   
ÿýÿþzEccKey._export_SEC1c                 C   sŒ   | j j\}}| jjtjkr&t|jddd�ƒ}|d@ d> |d B |d< t
|ƒS | jjtjkrBt|jddd�ƒ}|d@ d> |d< t
|ƒS t	d	ƒ‚)
Nr%   r*   r+   r   é   r'   r-   r2   zNot an EdDSA key to export)rV   r^   r;   r>   r?   r@   rE   r�   rG   r:   Úbytes)rL   r]   ra   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:   rV   r]   r   rE   r�   r‡   )rL   r]   Ú
field_sizer`   r   r   r   Ú_export_montgomery_public,  s   
z EccKey._export_montgomery_publicc                 C   sb   | j jr| j j}|  ¡ }d }n| j jr| j j}|  ¡ }d }nd}|  |¡}t| j jƒ}t|||ƒS )Nú1.2.840.10045.2.1)	r;   rZ   Úoidrˆ   r‰   r‹   r…   r	   r   )rL   r‚   r�   rz   Úparamsr   r   r   Ú_export_subjectPublicKeyInfo4  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   ©Úexplicitr$   )rU   rV   r   r]   r�   ra   r
   r    r	   r;   r�   r   r   Úencode)rL   Úinclude_ec_paramsrƒ   rz   Úseqr   r   r   Ú_export_rfc5915_private_derF  s   

ÿþ
ýz"EccKey._export_rfc5915_private_derc                 K   sŠ   ddl m} | dd ¡d urd|vrtdƒ‚| jd ur)| 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“   Ú
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   r‚   r¡   Úencoded_derr   r   r   Ú_export_public_pemv  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’   ©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
J ‚d|vrtdƒ‚| jdd|i|¤Ž}| |d¡S )Nr   r    r™   z5At least the 'protection' parameter should be presentr˜   zENCRYPTED PRIVATE KEYr   )r›   r¡   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 u rtd| j ƒ‚|dkr(|  ¡ }t|ƒt|ƒf}n;| j ¡ }|rCd| 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$   r}   ú-ó    c                 S   s    g | ]}t  d t|ƒ¡| ‘qS )ú>I)ÚstructÚpackrA   )Ú.0r]   r   r   r   Ú
<listcomp>«  s     z*EccKey._export_openssh.<locals>.<listcomp>ú )rU   r:   r;   Úopensshr   rˆ   r   rV   r   ra   r€   r   r]   r�   ÚsplitÚjoinr   r[   Ú
b2a_base64)	rL   r‚   Údescrz   Úcompsrƒ   r„   ÚmiddleÚblobr   r   r   Ú_export_openssh‘  s.   
ÿÿþzEccKey._export_opensshc                 K   s¨  |  ¡ }| d¡}|dvrtd| ƒ‚| dd¡}|  ¡ r“| dd¡}t|ƒr1t|ƒ}|s1tdƒ‚| d	d
¡}|du rS| jjrCtdƒ‚| jjrKtdƒ‚d|v rStdƒ‚|dkrq|rh|rd| j	|fi |¤ŽS |  
¡ S | j|fi |¤ŽS |dkr�|r}|s}tdƒ‚|r‰| jdd|i|¤ŽS |  ¡ S td| ƒ‚|r›td| ƒ‚|dkr¤|  |¡S |dkr­|  |¡S |dkr¶|  |¡S |dkrÏ| jjrÂ|  ¡ S | jjrÊ|  ¡ S |  |¡S |  |¡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¡   ÚDERÚOpenSSHÚSEC1ÚrawzUnknown format '%s'r‚   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¾   r   )Úcopyr4   r:   rU   r   r   r;   rZ   r‰   r§   r¦   r¥   rŸ   r•   r£   r�   r…   rˆ   r‹   r¹   )rL   rM   ÚargsÚ
ext_formatr‚   r˜   r¿   r   r   r   Ú
export_key®  sb   Z
ÿ




zEccKey.export_keyN)T)r   r   r   Ú__doc__rS   rX   rb   rU   rp   ru   Úpropertyr    r!   rV   rz   r…   rˆ   r‹   r�   r•   rŸ   r£   r¥   r¦   r§   r¹   rÃ   r   r   r   r   r   ;   s6    b	


	
	r   c                  K   s  |   d¡}t| }|   dt¡}| rtdt| ƒ ƒ‚t| jtjkr-|dƒ}t||d�}|S t| jtj	krA|dƒ}t||d�}|S t| jtj
kr]|dƒ}t||d�}t|  |j¡ |S t| jtjkry|dƒ}t||d�}t|  |j¡ |S 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   )rd   re   rÆ   )r   r    )r4   r   r   r8   r9   r>   r?   r@   r   rG   rI   ÚvalidaterV   rJ   r   rf   rK   )rM   rO   r   rÆ   r!   Únew_keyr    r   r   r   ÚgenerateF  s:   
ïòöûþrÊ   c                  K   s  | d }t | }|  dd¡}|  dd¡}d| v rtdƒ‚|jtjkr<|dur-t||ƒ| d< tdi | ¤Ž}| |j	¡ |S |jtj
kr\|durMt||ƒ| d< tdi | ¤Ž}| |j	¡ |S d||fvrjt|||ƒ| d< tdi | ¤Ž}| ¡ rŠd| v 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 matchr   )r   r4   r8   r>   r?   rI   r   r   rÈ   rV   rJ   r   rU   rh   r    r^   r:   )rM   rO   r   rË   rÌ   rÉ   Úpub_keyr   r   r   Ú	constructp  s4   !ìõ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 r�t| ƒ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©r   rË   rÌ   )r   Úitemsr�   r   Úpr   r   rA   r:   r   rF   ÚbÚsqrtr€   Úis_evenrÎ   )	Úec_pointÚ	curve_oidrO   Ú_curve_namer   rƒ   Ú
point_typer]   ra   r   r   r   Ú_import_public_der·  s8   ÿ



€rÝ   c                 G   s  t | ƒ\}}}d}dtfdtfdœ}dtfdtfdœ}||v rB|s'td| ƒ‚z	tƒ  |¡j}W n ty;   td	ƒ‚w t	||d
�S ||v ra|| \}	}
|rTtd| ƒ‚|
|ƒ\}}t
|||	d�S ||v r}|| \}	}|rstd| ƒ‚||ƒ}t
||	d�S td| ƒ‚)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: %s)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Ú   rO   Úimport_eddsa_public_keyr]   ra   Úimport_xdh_public_keyr   r   r   Ú_import_subjectPublicKeyInfoï  s<   þþ
ÿrò   c                 C   sr  t ƒ j| dd�}|d dkrtdƒ‚tƒ  |d ¡j}d}|t|ƒk rLztdd� || ¡j}|d ur;||kr;tdƒ‚|}|d7 }W n	 tyK   Y nw |d u rTtd	ƒ‚t 	¡ D ]\}}|j
|krc nqXtd
| ƒ‚|j ¡ }	t|ƒ|	krytdƒ‚d  }
}|t|ƒk r¬ztdd� || ¡j}t||d�}|jj}
|jj}|d7 }W n	 ty«   Y nw t |¡}t|||
|d�S )N©r$   rÒ   rÐ   )Ú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Õ   r   r   rÝ   rV   r]   ra   r   rF   rÎ   )rì   r˜   rÚ   Úec_private_keyÚscalar_bytesÚnext_elementÚ
parametersrO   r   rƒ   rË   rÌ   Úpublic_key_encrz   r    r   r   r   Ú_import_rfc5915_der2  sL   ÿ
ÿ
ÿ
rû   c                 C   sä   ddl m} | | |¡\}}}d}dddœ}ddd	œ}||v r,tƒ  |¡j}	t|||	ƒS ||v rI|d ur8td
ƒ‚d }	tƒ  |¡j	}
t
|| |
d�S ||v rl|| }|d ur[td| ƒ‚d }	tƒ  |¡j	}
t
|| |
d�S td| ƒ‚)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—   Úalgo_oidrž   rŽ   rí   rî   rï   rÚ   r!   rO   r   r   r   Ú_import_pkcs8m  s8   þþÿrþ   c                 G   s   t | ƒ}t|ƒS ry   )r   rò   )rì   rM   Úsp_infor   r   r   Ú_import_x509_cert•  s   r   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ò   r   r:   r8   Ú
IndexErrorr   rû   rþ   )rì   r˜   Úerrr   r   r   Ú_import_der›  sB   €ÿ€ÿ€ÿ€ýr  c              
   C   sˆ  |   d¡}t|ƒdvrtdƒ‚z¡t |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	¡r‘t	 
¡ 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r©t|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: rå   ó   ssh-ed25519rß   rÓ   zUnsupported SSH key type: zError parsing SSH key type: )r²   rA   r:   r[   Ú
a2b_base64r¬   ÚunpackÚappendÚ
startswithr   rÔ   r±   r   rÝ   r�   ræ   rÎ   r  r8   ÚError)rì   ÚpartsÚ	keystringÚkeypartsÚlkrO   r   r·   Úecc_keyr]   ra   r   r   r   Ú_import_openssh_public¼  sD   
ý
ÿ÷ûÿr  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ß   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Ì   r   )Ú_opensshr  r  r  r  ræ   r  r   r   Úmodulus_bitsr   r:   rA   r   rF   rÎ   )ÚdataÚpasswordr  r  r  r  Úkey_typeÚ	decryptedÚ
eddsa_keysÚecdsa_curve_namer   rƒ   rz   rË   rÌ   rž   r    rŽ   rO   rð   Úseed_lenÚ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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 )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   rg   Ú_tonelli_shanks©rì   rÕ   r    ra   Úx_lsbrÌ   ÚuÚvÚv_invÚx2rË   r   r   r   ræ   !  s4   

üþÿ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r0td
ƒ‚|dkr6dS |d d | }|d | | d | }z%| |¡}|| | }	t |	|¡}
|
d@ |krk||
 }
W |
|fS W |
|fS  tyz   tdƒ‚w )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.Ú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   rg   r&  r'  r   r   r   rç   ƒ  s2   


üþÿrç   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r�t| d ƒdkr�t
| |ƒS t| ƒdkr¬t| d ƒdv r¬|du r¦t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:`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.*?rY   )Úflagsz(Invalid DER encoding inside the PEM file)r  r  é0   ró   zNo curve name was provided)rO   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˜   rO   r¡   Útext_encodedÚopenssh_encodedÚmarkerÚenc_flagr`   Úecparams_startÚecparams_endÚder_encodedÚuefr   r   r   Ú
import_key¯  sL   I


þü€ÿ

r;  Ú__main__l   ýö_,)¶NÌ$ÔcÐhKf-5lk<X÷k©#E Úp256i¸  z	(P-256 G)iè  Úmsz(P-256 arbitrary point))NNry   )@Ú
__future__r   r0  r¬   r[   ÚCryptodome.Util.py3compatr   r   r   r   r   ÚCryptodome.Math.Numbersr   ÚCryptodome.Util.asn1r	   r
   r   r   ÚCryptodome.PublicKeyr   r   r   ÚCryptodome.Hashr   r   Ú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    rh   rÀ   r"   rP   ÚstartÚranger]   ÚpointXÚprintr   r   r   r   Ú<module>   s^       *
G8
C;(!.7-
,~

 ï