o
    5h                     @   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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 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   h/var/www/html/construction_image-detection-poc/venv/lib/python3.10/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   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rt	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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| _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rt	dt| j| _d| j  kr| j
jk st	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	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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)	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   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| |rt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:`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   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 )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   )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 | }| rd| v r|j|j }|j||fkrtd|S )	a  Build a new ECC key (private or public) starting
    from some base components.

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

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

      d (integer):
        Mandatory for a private key and a NIST P-curve (e.g., P-256).
        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 rt| d| krjtdt	
| dd }|d
 |d
  |j |j}|dkr| r|j| }|d
kr| r|j| }ntdt|||dS )a  Convert an encoded EC point into an EccKey object

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

    Either curve_id or curve_name must be specified

    Unsupported ECC curve (OID: %s)zUnsupported ECC curve (%s)r      r   r$   zIncorrect EC point lengthNr$      r   zIncorrect EC point encoding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 rz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zt|d }g }t|dkrDtd|d d d }||dd|   |d| d  }t|dks|d |d krPtd|d d	rt	
 D ]#\}}|jd u req[|jd
slq[t|j dd }|d |kr~ nq[td| t|d |jd}W |S |d dkrt|d \}	}
td|	|
d}W |S td|d   tttjfy   td|d  w )N    r   zNot an openssh public keyr   r   r   r   zMismatch in openssh public key   ecdsa-sha2-
ecdsa-sha2r   r$   zUnsupported ECC curve: 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 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   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rt| d dkrt
| |S t| dkrt| d dv r|du rtdt| |dS td)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.*?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<Xk#E p256i  z	(P-256 G)i  msz(P-256 arbitrary point))NNry   )@
__future__r   r0  r   r[   Crypto.Util.py3compatr   r   r   r   r   Crypto.Math.Numbersr   Crypto.Util.asn1r	   r
   r   r   Crypto.PublicKeyr   r   r   Crypto.Hashr   r   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    rh   r   r"   rP   startranger]   pointXprintr   r   r   r   <module>   s^       *
G8
C;(!.7-
,~

 