o
    n~b;                     @   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   C/usr/local/lib/python3.10/dist-packages/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      t dNzTo be provided by subclassesNotImplementedErrorr   msg_hashr   r   r   _compute_nonceG      zDssSigScheme._compute_noncec                 C   r   r   r   r    r   r   r   _valid_hashJ   r#   zDssSigScheme._valid_hashc                    s    j  s	td |std |}t| d j	 } j 
||} jdkr=d fdd|D }|S 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   Z_signr   joinr   encode)r   r!   noncezZsig_pairoutputr   r   r   signM   s   



zDssSigScheme.signc              	   C   sH  |  |s	td| jdkr1t|d| j krtddd |d| j || jd fD \}}n3z
t j|dd	}W n ttfyH   td
w t|dksS| sWtdt	|d t	|d }}d|  k ro| j
k rn tdd|  k r| j
k std tdt	| d| j }| j|||f}|st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_seqr3   resultr   r   r   verifyz   s:   

zDssSigScheme.verifyN)
__name__
__module____qualname____doc__r   r   r"   r$   r5   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                       t t| ||| || _d S N)superrB   r   _private_key)r   r   r   r   private_key	__class__r   r   r         
z"DeterministicDsaSigScheme.__init__c                 C   s8   t |}| j }t|d }||kr||| L }|S )zSee 2.3.2 in RFC6979r   )r   r.   r   r   r8   )r   bstrr<   Zq_lenZb_lenr   r   r   	_bits2int   s   

z#DeterministicDsaSigScheme._bits2intc                 C   s*   d|  k r| j k sJ  J t|| jS )zSee 2.3.3 in RFC6979r   )r   r   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)rL   r   rM   )r   rK   Zz1Zz2r   r   r   _bits2octets   s
   



z&DeterministicDsaSigScheme._bits2octetsc                 C   s  |  }d|j }d|j }dD ]!}t||| | | j | | |  }t|||  }qd}d|  k r?| jk sn |dkrXt||d |  }t|||  }d}t|| j	k rut|||  }||7 }t|| j	k sa| 
|}d|  k r| jk r@|S  q@|S )z!Generate k in a deterministic way       )rP   rO   r   r'   )r/   digest_sizer   r	   rM   rF   rN   r   r8   r   rL   )r   Zmhashh1Zmask_vZnonce_kZint_octr2   Zmask_tr   r   r   r"      sD   



z(DeterministicDsaSigScheme._compute_noncec                 C   s   dS )NTr   r    r   r   r   r$      s   z%DeterministicDsaSigScheme._valid_hash)
r>   r?   r@   r   rL   rM   rN   r"   r$   __classcell__r   r   rH   r   rB      s    
(rB   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )FipsDsaSigScheme))i      )      )rW      )i   rY   c                    sR   t t| ||| || _t|j }|| jf| jvr'd|| jf }t	|d S )Nz+L/N (%d, %d) is not compliant to FIPS 186-3)
rE   rU   r   	_randfuncr   pr   r   _fips_186_3_L_Nr-   )r   r   r   r   randfuncLerrorrH   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   rZ   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@   r\   r   r"   r$   rT   r   r   rH   r   rU      s
    
rU   c                       s,   e Zd Z fddZdd Zdd Z  ZS )FipsEcDsaSigSchemec                    rC   rD   )rE   rd   r   rZ   )r   r   r   r   r]   rH   r   r   r     rJ   zFipsEcDsaSigScheme.__init__c                 C   s   t jd| jjj| jdS r`   )r   ra   r   _curver   rZ   r    r   r   r   r"     s   z!FipsEcDsaSigScheme._compute_noncec           	      C   sV   | j j }d}d}d}d}|| | | }z|j|v }W |S  ty*   d}Y |S w )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   rb   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$   rT   r   r   rH   r   rd     s    rd   r&   Nc                 C   s   |dvr
t d| t| tr| jj}d}nt| tr#t| j}d}n
t dtt	|  | 
 r7t| |}nd}|dkrDt| |||S |dkr[t| trTt| |||S t| |||S t d	| )
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'dr*   zUnsupported key type Nzdeterministic-rfc6979z
fips-186-3zUnknown DSS mode '%s')r-   
isinstancer   re   r   r   r   qstrtyper   getattrrB   rd   rU   )r   moder   r]   r   Zprivate_key_attrrG   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   rB   rU   rd   r	   r   r   r   r   <module>   s   !zN"