U
    Mf0                     @   sr   d dl mZ d dlmZmZ d dlmZmZ d dlm	Z	m
Z
mZmZ dd Zdd ZG d	d
 d
eZdddZdS )    )Integer)SHA512SHAKE256)bchris_bytes)EccKey	construct_import_ed25519_public_key_import_ed448_public_keyc                 C   sZ   t | dkrt| \}}d}n.t | dkr<t| \}}d}ntdt |  t|||dS )a  Create a new Ed25519 or Ed448 public key object,
    starting from the key encoded as raw ``bytes``,
    in the format described in RFC8032.

    Args:
      encoded (bytes):
        The EdDSA public key to import.
        It must be 32 bytes for Ed25519, and 57 bytes for Ed448.

    Returns:
      :class:`Cryptodome.PublicKey.EccKey` : a new ECC key object.

    Raises:
      ValueError: when the given key cannot be parsed.
        ZEd255199   ZEd448zNot an EdDSA key (%d bytes))curveZpoint_xZpoint_y)lenr	   r
   
ValueErrorr   )encodedxy
curve_name r   >/tmp/pip-unpacked-wheel-l_0d1exj/Cryptodome/Signature/eddsa.pyimport_public_key)   s    r   c                 C   s8   t | dkrd}nt | dkr$d}ntdt| |dS )a  Create a new Ed25519 or Ed448 private key object,
    starting from the key encoded as raw ``bytes``,
    in the format described in RFC8032.

    Args:
      encoded (bytes):
        The EdDSA private key to import.
        It must be 32 bytes for Ed25519, and 57 bytes for Ed448.

    Returns:
      :class:`Cryptodome.PublicKey.EccKey` : a new ECC key object.

    Raises:
      ValueError: when the given key cannot be parsed.
    r   ed25519r   ed448z8Incorrect length. Only EdDSA private keys are supported.)seedr   )r   r   r   )r   r   r   r   r   import_private_keyE   s    r   c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )EdDSASigSchemezpAn EdDSA signature object.
    Do not instantiate directly.
    Use :func:`Cryptodome.Signature.eddsa.new`.
    c                 C   s$   || _ || _| | _|jj| _dS )zCreate a new EdDSA object.

        Do not instantiate this object directly,
        use `Cryptodome.Signature.DSS.new` instead.
        N)_key_context_export_eddsa_A_curveorder_order)selfkeycontextr   r   r   __init__i   s    
zEdDSASigScheme.__init__c                 C   s
   | j  S )zRReturn ``True`` if this signature object can be used
        for signing messages.)r   has_private)r#   r   r   r   can_signu   s    zEdDSASigScheme.can_signc                 C   s   | j  std| j jjdkrHt|tj}|s@t|s@td| j	}n>| j jjdkr~t|t
j}|svt|svtd| j}ntd|||S )aR  Compute the EdDSA signature of a message.

        Args:
          msg_or_hash (bytes or a hash object):
            The message to sign (``bytes``, in case of *PureEdDSA*) or
            the hash that was carried out over the message (hash object, for *HashEdDSA*).

            The hash object must be :class:`Cryptodome.Hash.SHA512` for Ed25519,
            and :class:`Cryptodome.Hash.SHAKE256` object for Ed448.

        :return: The signature as ``bytes``. It is always 64 bytes for Ed25519, and 114 bytes for Ed448.
        :raise TypeError: if the EdDSA key has no private half
        zPrivate key is needed to signr   -'msg_or_hash' must be bytes of a SHA-512 hashr   .'msg_or_hash' must be bytes of a SHAKE256 hashIncorrect curve for EdDSA)r   r'   	TypeErrorr    name
isinstancer   
SHA512Hashr   _sign_ed25519r   SHAKE256_XOF_sign_ed448r   )r#   msg_or_hashphZeddsa_sign_methodr   r   r   sign{   s    
zEdDSASigScheme.signc                 C   s   | j s
|r4t|}dt| tt| j  | j  }nd}|rD| n|}t|| jj |  }t	
|d| j }t|| jjj d }t|| | j |  }	t	
|	d| j }
||
| jj  | j }||dd S )N    SigEd25519 no Ed25519 collisions    littleZpointr   )r   intr   r   digestr   newr   _prefixr   
from_bytesr"   r   r    Gr   r   dto_bytes)r#   r3   r4   flagdom2PHMr_hashrR_pkk_hashksr   r   r   r0      s     

zEdDSASigScheme._sign_ed25519c                 C   s   t |}dt| tt| j | j }|r6|dn|}t|| jj | d}t	
|d| j }t|| jjj d }t|| | j | d}	t	
|	d| j }
||
| jj  | j }||dd S )N   SigEd448@   r   r8   r9   r   )r:   r   r   r   readr   r<   r   r=   r   r>   r"   r   r    r?   r   r   r@   rA   )r#   r3   r4   rB   dom4rD   rE   rF   rG   rH   rI   rJ   r   r   r   r2      s    
zEdDSASigScheme._sign_ed448c                 C   s   | j jjdkr6t|tj}|s.t|s.td| j}n>| j jjdkrlt|t	j
}|sdt|sdtd| j}ntd||||S )a  Check if an EdDSA signature is authentic.

        Args:
          msg_or_hash (bytes or a hash object):
            The message to verify (``bytes``, in case of *PureEdDSA*) or
            the hash that was carried out over the message (hash object, for *HashEdDSA*).

            The hash object must be :class:`Cryptodome.Hash.SHA512` object for Ed25519,
            and :class:`Cryptodome.Hash.SHAKE256` for Ed448.

          signature (``bytes``):
            The signature that needs to be validated.
            It must be 64 bytes for Ed25519, and 114 bytes for Ed448.

        :raise ValueError: if the signature is not authentic
        r   r)   r   r*   r+   )r   r    r-   r.   r   r/   r   r,   _verify_ed25519r   r1   _verify_ed448r   )r#   r3   	signaturer4   Zeddsa_verify_methodr   r   r   verify   s    zEdDSASigScheme.verifyc                 C   s,  t |dkrtd| js|rHt|}dt| tt | j | j }nd}|rX| n|}zt|d d j}W n tk
r   tdY nX t	|dd  d}|| j
krtdt||d d  | j |  }	t	|	d| j
 }
|d	 | jjj }d	| |
d	 | jj  }||kr(td
d S )NrL   'The signature is not authentic (length)r6   r7   r   "The signature is not authentic (R)r8   "The signature is not authentic (S)   The signature is not authentic)r   r   r   r:   r   r;   r   pointQr   r>   r"   r   r<   r   r   r    r?   )r#   r3   rR   r4   rB   rC   rD   RrJ   rH   rI   point1point2r   r   r   rP      s0    


$
zEdDSASigScheme._verify_ed25519c                 C   s   t |dkrtdt|}dt| tt | j | j }|rJ|dn|}zt|d d j}W n tk
r   tdY nX t	|dd  d}|| j
krtdt||d d  | j | d}	t	|	d| j
 }
|d	 | jjj }d	| |
d	 | jj  }||krtd
d S )NrM   rT   rK   rL   r   rU   r8   rV   rW   rX   )r   r   r:   r   r   rN   r   rY   r   r>   r"   r   r<   r   r   r    r?   )r#   r3   rR   r4   rB   rO   rD   rZ   rJ   rH   rI   r[   r\   r   r   r   rQ     s,    

&
zEdDSASigScheme._verify_ed448N)__name__
__module____qualname____doc__r&   r(   r5   r0   r2   rS   rP   rQ   r   r   r   r   r   c   s   ###r   Nc                 C   sV   t | tr|  std|dkr*td|dkr8d}nt|dkrLtdt| |S )a  Create a signature object :class:`EdDSASigScheme` that
    can perform or verify an EdDSA signature.

    Args:
        key (:class:`Cryptodome.PublicKey.ECC` object):
            The key to use for computing the signature (*private* keys only)
            or for verifying one.
            The key must be on the curve ``Ed25519`` or ``Ed448``.

        mode (string):
            This parameter must be ``'rfc8032'``.

        context (bytes):
            Up to 255 bytes of `context <https://datatracker.ietf.org/doc/html/rfc8032#page-41>`_,
            which is a constant byte string to segregate different protocols or
            different applications of the same key.
    z&EdDSA can only be used with EdDSA keysZrfc8032zMode must be 'rfc8032'Nr7      z3Context for EdDSA must not be longer than 255 bytes)r.   r   Z	_is_eddsar   r   r   )r$   moder%   r   r   r   r<   9  s    r<   )N)ZCryptodome.Math.Numbersr   ZCryptodome.Hashr   r   ZCryptodome.Util.py3compatr   r   ZCryptodome.PublicKey.ECCr   r   r	   r
   r   r   objectr   r<   r   r   r   r   <module>   s    W