U
    g;                     @   s   d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ ddgZG d	d deZG d
d deZG dd deZG dd deZdddZdS )    )DerSequence)long_to_bytes)Integer)HMAC)EccKey)DsaKeyDssSigSchemenewc                   @   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	dS )r   zoA (EC)DSA signature object.
    Do not instantiate directly.
    Use :func:`Cryptodome.Signature.DSS.new`.
    c                 C   s6   || _ || _|| _| j | _| jd d d | _dS )zCreate a new Digital Signature Standard (DSS) object.

        Do not instantiate this object directly,
        use `Cryptodome.Signature.DSS.new` instead.
              N)_key	_encoding_ordersize_in_bits_order_bits_order_bytes)selfkeyencodingorder r   </tmp/pip-unpacked-wheel-_q8s9isk/Cryptodome/Signature/DSS.py__init__3   s
    zDssSigScheme.__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_signA   s    zDssSigScheme.can_signc                 C   s   t dd S NzTo be provided by subclassesNotImplementedErrorr   msg_hashr   r   r   _compute_nonceG   s    zDssSigScheme._compute_noncec                 C   s   t dd S r   r   r   r   r   r   _valid_hashJ   s    zDssSigScheme._valid_hashc                    s    j  std |s$td |}t| d j	 } j 
||} jdkrxd fdd|D }nt| }|S )a  Compute the DSA/ECDSA signature of a message.

        Args:
          msg_hash (hash object):
            The hash that was carried out over the message.
            The object belongs to the :mod:`Cryptodome.Hash` package.
            Under mode ``'fips-186-3'``, the hash must be a FIPS
            approved secure hash (SHA-2 or SHA-3).

        :return: The signature as ``bytes``
        :raise ValueError: if the hash algorithm is incompatible to the (EC)DSA key
        :raise TypeError: if the (EC)DSA key has no private half
        zPrivate key is needed to signHash is not sufficiently strongNbinary    c                    s   g | ]}t | jqS r   )r   r   .0xr   r   r   
<listcomp>k   s   z%DssSigScheme.sign.<locals>.<listcomp>)r   r   	TypeErrorr"   
ValueErrorr!   r   
from_bytesdigestr   _signr   joinr   encode)r   r    noncezZsig_pairoutputr   r   r   signM   s    




zDssSigScheme.signc              	   C   sJ  |  |std| jdkrbt|d| j kr6tddd |d| j || jd fD \}}nlzt j|dd	}W n  ttfk
r   td
Y nX t|dks| stdt	|d t	|d  }}d|  k r| j
k rn nd|  k r| j
k sn tdt	| d| j }| j|||f}|sFtddS )a   Check if a certain (EC)DSA signature is authentic.

        Args:
          msg_hash (hash object):
            The hash that was carried out over the message.
            This is an object belonging to the :mod:`Cryptodome.Hash` module.
            Under mode ``'fips-186-3'``, the hash must be a FIPS
            approved secure hash (SHA-2 or SHA-3).

          signature (``bytes``):
            The signature that needs to be validated.

        :raise ValueError: if the signature is not authentic
        r#   r$      z'The signature is not authentic (length)c                 S   s   g | ]}t |qS r   )r   r,   r&   r   r   r   r)      s   z'DssSigScheme.verify.<locals>.<listcomp>NT)strictz$The signature is not authentic (DER)z,The signature is not authentic (DER content)r   r
   z"The signature is not authentic (d)zThe signature is not authenticF)r"   r+   r   lenr   r   decode
IndexErrorZhasOnlyIntsr   r   r,   r-   r   Z_verify)r   r    	signatureZr_primeZs_primeZder_seqr2   resultr   r   r   verifyz   s0    

8zDssSigScheme.verifyN)
__name__
__module____qualname____doc__r   r   r!   r"   r4   r<   r   r   r   r   r   -   s   -c                       sD   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Z  Z	S )DeterministicDsaSigSchemec                    s   t t| ||| || _d S N)superrA   r   _private_key)r   r   r   r   private_key	__class__r   r   r      s    z"DeterministicDsaSigScheme.__init__c                 C   s8   t |}| j }t|d }||kr4||| L }|S )zSee 2.3.2 in RFC6979r   )r   r,   r   r   r7   )r   bstrr;   Zq_lenZb_lenr   r   r   	_bits2int   s    

z#DeterministicDsaSigScheme._bits2intc                 C   s(   d|  k r| j k sn tt|| jS )zSee 2.3.3 in RFC6979r   )r   AssertionErrorr   r   )r   Z	int_mod_qr   r   r   _int2octets   s    z%DeterministicDsaSigScheme._int2octetsc                 C   s.   |  |}|| jk r|}n
|| j }| |S )zSee 2.3.4 in RFC6979)rI   r   rK   )r   rH   Zz1Zz2r   r   r   _bits2octets   s
    


z&DeterministicDsaSigScheme._bits2octetsc                 C   s   |  }d|j }d|j }dD ]B}t||| | | j | | |  }t|||  }q d}d|  k r~| jk sn |dkrt||d |  }t|||  }d}t|| j	k rt|||  }||7 }q| 
|}qh|S )z!Generate k in a deterministic way       )rN   rM   r   r%   )r-   digest_sizer   r	   rK   rD   rL   r   r7   r   rI   )r   Zmhashh1Zmask_vZnonce_kZint_octr1   Zmask_tr   r   r   r!      s4    



z(DeterministicDsaSigScheme._compute_noncec                 C   s   dS )NTr   r   r   r   r   r"      s    z%DeterministicDsaSigScheme._valid_hash)
r=   r>   r?   r   rI   rK   rL   r!   r"   __classcell__r   r   rF   r   rA      s   
(rA   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )FipsDsaSigScheme))i      )      )rU      )i   rW   c                    sR   t t| ||| || _t|j }|| jf| jkrNd|| jf }t	|d S )Nz+L/N (%d, %d) is not compliant to FIPS 186-3)
rC   rS   r   	_randfuncr   pr   r   _fips_186_3_L_Nr+   )r   r   r   r   randfuncLerrorrF   r   r   r     s    zFipsDsaSigScheme.__init__c                 C   s   t jd| j| jdS Nr
   )Zmin_inclusiveZmax_exclusiver[   )r   random_ranger   rX   r   r   r   r   r!     s    zFipsDsaSigScheme._compute_noncec                 C   s   |j dkp|j dS )z*Verify that SHA-1, SHA-2 or SHA-3 are usedz1.3.14.3.2.26z2.16.840.1.101.3.4.2.)oid
startswithr   r   r   r   r"     s    

zFipsDsaSigScheme._valid_hash)r=   r>   r?   rZ   r   r!   r"   rR   r   r   rF   r   rS      s   
rS   c                       s,   e Zd Z fddZdd Zdd Z  ZS )FipsEcDsaSigSchemec                    s   t t| ||| || _d S rB   )rC   rb   r   rX   )r   r   r   r   r[   rF   r   r   r     s    zFipsEcDsaSigScheme.__init__c                 C   s   t jd| jjj| jdS r^   )r   r_   r   _curver   rX   r   r   r   r   r!     s    z!FipsEcDsaSigScheme._compute_noncec           	      C   sX   | j j }d}d}d}d}|| | | }z|j|k}W n tk
rR   d}Y nX |S )zxVerify that the strength of the hash matches or exceeds
        the strength of the EC. We fail if the hash is too weak.)z2.16.840.1.101.3.4.2.4z2.16.840.1.101.3.4.2.7z2.16.840.1.101.3.4.2.5)z2.16.840.1.101.3.4.2.1z2.16.840.1.101.3.4.2.8z2.16.840.1.101.3.4.2.6)z2.16.840.1.101.3.4.2.2z2.16.840.1.101.3.4.2.9)z2.16.840.1.101.3.4.2.3z2.16.840.1.101.3.4.2.10F)r   ZpointQr   r`   AttributeError)	r   r    Zmodulus_bitssha224sha256sha384sha512Zshsr;   r   r   r   r"   "  s    
zFipsEcDsaSigScheme._valid_hash)r=   r>   r?   r   r!   r"   rR   r   r   rF   r   rb     s   rb   r$   Nc                 C   s   |dkrt d| t| tr@| jj}d}| jdsnt dn.t| trZt| j	}d}nt dt
t|  |  rt| |}nd}|d	krt| |||S |d
krt| trt| |||S t| |||S nt d| dS )a
  Create a signature object :class:`DssSigScheme` that
    can perform (EC)DSA signature or verification.

    .. note::
        Refer to `NIST SP 800 Part 1 Rev 4`_ (or newer release) for an
        overview of the recommended key lengths.

    Args:
        key (:class:`Cryptodome.PublicKey.DSA` or :class:`Cryptodome.PublicKey.ECC`):
            The key to use for computing the signature (*private* keys only)
            or for verifying one.
            For DSA keys, let ``L`` and ``N`` be the bit lengths of the modulus ``p``
            and of ``q``: the pair ``(L,N)`` must appear in the following list,
            in compliance to section 4.2 of `FIPS 186-4`_:

            - (1024, 160) *legacy only; do not create new signatures with this*
            - (2048, 224) *deprecated; do not create new signatures with this*
            - (2048, 256)
            - (3072, 256)

            For ECC, only keys over P-224, P-256, P-384, and P-521 are accepted.

        mode (string):
            The parameter can take these values:

            - ``'fips-186-3'``. The signature generation is randomized and carried out
              according to `FIPS 186-3`_: the nonce ``k`` is taken from the RNG.
            - ``'deterministic-rfc6979'``. The signature generation is not
              randomized. See RFC6979_.

        encoding (string):
            How the signature is encoded. This value determines the output of
            :meth:`sign` and the input to :meth:`verify`.

            The following values are accepted:

            - ``'binary'`` (default), the signature is the raw concatenation
              of ``r`` and ``s``. It is defined in the IEEE P.1363 standard.
              For DSA, the size in bytes of the signature is ``N/4`` bytes
              (e.g. 64 for ``N=256``).
              For ECDSA, the signature is always twice the length of a point
              coordinate (e.g. 64 bytes for P-256).

            - ``'der'``, the signature is a ASN.1 DER SEQUENCE
              with two INTEGERs (``r`` and ``s``). It is defined in RFC3279_.
              The size of the signature is variable.

        randfunc (callable):
            A function that returns random ``bytes``, of a given length.
            If omitted, the internal RNG is used.
            Only applicable for the *'fips-186-3'* mode.

    .. _FIPS 186-3: http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
    .. _FIPS 186-4: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
    .. _NIST SP 800 Part 1 Rev 4: http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r4.pdf
    .. _RFC6979: http://tools.ietf.org/html/rfc6979
    .. _RFC3279: https://tools.ietf.org/html/rfc3279#section-2.2.2
    )r$   ZderzUnknown encoding '%s'dZNISTz ECC key is not on a NIST P curver(   zUnsupported key type Nzdeterministic-rfc6979z
fips-186-3zUnknown DSS mode '%s')r+   
isinstancer   rc   r   Zcurvera   r   r   qstrtyper   getattrrA   rb   rS   )r   moder   r[   r   Zprivate_key_attrrE   r   r   r   r	   6  s*    B




)r$   N)ZCryptodome.Util.asn1r   ZCryptodome.Util.numberr   ZCryptodome.Math.Numbersr   ZCryptodome.Hashr   ZCryptodome.PublicKey.ECCr   ZCryptodome.PublicKey.DSAr   __all__objectr   rA   rS   rb   r	   r   r   r   r   <module>"   s   zN"