o
    Þý°jRB  ã                   @   s¼  d dl Z d dlmZ d dlmZ d dlmZ ddlmZm	Z	 ddl
mZmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZmZmZ d dlmZm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efddefddefddefddefdœZ de!de!de!d e!d!ef
d"d#„Z"d$e!de!d%e!d&e#d e!d!efd'd(„Z$d)e!d*e!d e!d!efd+d,„Z%G d-d.„ d.ƒZ&ddddd/œd0ed1ed2ee! d3ee d4ee'e!e!f  d%ee! d5e&fd6d7„Z(dS )8é    N)ÚIntEnum)Ú
ModuleType)ÚOptionalé   )Ú_HKDF_extractÚ_HKDF_expand)Úkey_agreementÚimport_x25519_public_keyÚimport_x448_public_key)Ústrxor)ÚECC)ÚEccKey)ÚSHA256ÚSHA384ÚSHA512)ÚAESÚChaCha20_Poly1305c                   @   s    e Zd ZdZdZdZdZdZdS )ÚMODEz
HPKE modesr   r   é   é   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚBASEÚPSKÚAUTHÚAUTH_PSK© r   r   ú‹/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/Cryptodome/Protocol/HPKE.pyr      s    r   c                   @   s   e Zd ZdZdZdZdZdS )ÚAEADz>Authenticated Encryption with Associated Data (AEAD) Functionsr   r   r   N)r   r   r   r   Ú
AES128_GCMÚ
AES256_GCMÚCHACHA20_POLY1305r   r   r   r   r       s
    r    c                   @   ó   e Zd ZdS )ÚDeserializeErrorN©r   r   r   r   r   r   r   r%      ó    r%   c                   @   r$   )ÚMessageLimitReachedErrorNr&   r   r   r   r   r(   "   r'   r(   é   é   r   é   r   é    é!   ©z
NIST P-256z
NIST P-384z
NIST P-521Ú
Curve25519ÚCurve448ÚsaltÚlabelÚikmÚsuite_idÚhashmodc                 C   s   d| | | }t | ||ƒS )Nó   HPKE-v1)r   )r1   r2   r3   r4   r5   Úlabeled_ikmr   r   r   Ú_labeled_extract/   s   r8   ÚprkÚinfoÚLc                 C   s*   t  d|¡d | | | }t| |||ƒS )Nú>Hr6   )ÚstructÚpackr   )r9   r2   r:   r;   r4   r5   Úlabeled_infor   r   r   Ú_labeled_expand8   s   ÿÿr@   ÚdhÚkem_contextc                 C   s,   |j }tdd| ||ƒ}t|d||||ƒ}|S )Nó    s   eae_prks   shared_secret)Údigest_sizer8   r@   )rA   rB   r4   r5   ÚNsecretÚeae_prkÚshared_secretr   r   r   Ú_extract_and_expandC   s   üûrH   c                   @   s  e Zd Zdedee dee deeef dededefdd	„Z	e
	
	
d"dedededee dee f
dd„ƒZe
	
d#dededededee f
dd„ƒZe
dedeeef fdd„ƒZdedededefdd„Zdd„ Zd#dedee fdd„Zd#dedee fd d!„Zd
S )$ÚHPKE_CipherÚreceiver_keyÚencÚ
sender_keyÚpsk_pairr:   Úaead_idÚmodec           
   
   C   sH  |d u rdn|| _ 	 |  ||¡ |j| _|| _|| _zt| j \| _| _| _	W n t
y< } z	td | j¡ƒ|‚d }~ww | jtjkrEdnd| _d| _d| _| j	j| _| ¡  | _| jrr|d urdtdƒ‚|  || j| j	|¡\}	| _ n|d u rztdƒ‚|  ||| j| j	|¡}	d| _d	d
| j > d	 | _| j|	|g|¢R Ž \| _| _| _d S )NrC   z!Curve {} is not supported by HPKEr)   r,   é   z0Parameter 'enc' cannot be an input  when sealingz'Parameter 'enc' required when unsealingr   r   é   )rK   Ú_verify_psk_inputsÚcurveÚ_curveÚ_aead_idÚ_modeÚ_Curve_ConfigÚ_kem_idÚ_kdf_idÚ_hashmodÚKeyErrorÚ
ValueErrorÚformatr    r!   Ú_NkÚ_NnÚ_NtrD   Ú_NhÚhas_privateÚ_encryptÚ_encapÚ_decapÚ	_sequenceÚ_max_sequenceÚ_key_scheduleÚ_keyÚ_base_nonceÚ_export_secret)
ÚselfrJ   rK   rL   rM   r:   rN   rO   ÚkerG   r   r   r   Ú__init__Z   s\   	þ€ÿ
ýüÿþþzHPKE_Cipher.__init__NÚkem_idr5   Úeph_keyc                 C   sÈ   |d u s
|  ¡ s
J ‚|d u s|  ¡ sJ ‚|d u rtj| jd�}| ¡ jdd�}|  ¡ jdd�}|| }i }|rE|| ¡ jdd�7 }d|i}dt d|¡ }	||	|fdd„}
td
|| |
d	œ|¤Ž}||fS )N)rS   Úraw©r]   Ústatic_privó   KEMr<   c                 S   ó   t | |||ƒS ©N©rH   ©rA   rB   r4   r5   r   r   r   Úkdf¬   ó   zHPKE_Cipher._encap.<locals>.kdf)Úeph_privÚ
static_pubry   r   )	rb   r   ÚgeneraterS   Ú
public_keyÚ
export_keyr=   r>   r   )rJ   ro   r5   rL   rp   rK   ÚpkRmrB   Úextra_paramr4   ry   rG   r   r   r   rd   •   s.   
ýþýzHPKE_Cipher._encapc              
   C   sâ   |  ¡ sJ ‚z|jdkrt| ƒ}n|jdkrt| ƒ}ntj| |jd�}W n ty5 } ztdƒ|‚d }~ww | ¡ j	dd�}| | }i }	|rT|| ¡ j	dd�7 }d|i}	dt
 d	|¡ }
||
|fd
d„}td|||dœ|	¤Ž}|S )Nr/   r0   )Ú
curve_namez*'enc' is not a valid encapsulated HPKE keyrq   rr   r|   rt   r<   c                 S   ru   rv   rw   rx   r   r   r   ry   Ô   rz   zHPKE_Cipher._decap.<locals>.kdf)Úeph_pubrs   ry   r   )rb   rS   r	   r
   r   Ú
import_keyr\   r%   r~   r   r=   r>   r   )rK   rJ   ro   r5   rL   ÚpkEÚver€   rB   r�   r4   ry   rG   r   r   r   re   ¸   s<   



€
€ÿ
ýþýzHPKE_Cipher._decapc                 C   s|   |\}}|dk|dkA rt dƒ‚|dkr&| tjtjfv r$t d| j› �ƒ‚d S t|ƒdk r0t dƒ‚| tjtjfv r<t dƒ‚d S )NrC   zInconsistent PSK inputszPSK is required with mode r,   z!PSK must be at least 32 byte longz$PSK is not compatible with this mode)r\   r   r   r   ÚnameÚlenr   r   )rO   rM   Úpsk_idÚpskr   r   r   rR   à   s   ÿÿzHPKE_Cipher._verify_psk_inputsrG   r‰   rŠ   c                 C   s²   dt  d| j| j| j¡ }tdd||| jƒ}tdd||| jƒ}| j dd¡| | }t|d||| jƒ}	t	|	d	|| j
|| jƒ}
t	|	d
|| j|| jƒ}t	|	d|| j|| jƒ}|
||fS )Ns   HPKEz>HHHrC   s   psk_id_hashs	   info_hashr   Úbigs   secrets   keys
   base_nonces   exp)r=   r>   rX   rY   rU   r8   rZ   rV   Úto_bytesr@   r^   r_   ra   )rl   rG   r:   r‰   rŠ   r4   Úpsk_id_hashÚ	info_hashÚkey_schedule_contextÚsecretÚkeyÚ
base_nonceÚexporter_secretr   r   r   rh   ð   s\   ýüüüûûû
zHPKE_Cipher._key_schedulec                 C   s˜   t | j| j | jd¡ƒ}| jtjtjfv r"t	j
| jt	j|| jd�}n| jtjkr1tj
| j|d�}n	td| jd›�ƒ‚| j| jkrCtƒ ‚|  jd7  _|S )Nr‹   )ÚnonceÚmac_len)r‘   r”   úUnknown AEAD cipher ID ú#xr   )r   rj   rf   rŒ   r_   rU   r    r!   r"   r   Únewri   ÚMODE_GCMr`   r#   r   r\   rg   r(   )rl   r”   Úcipherr   r   r   Ú_new_cipher&  s   zHPKE_Cipher._new_cipherÚ	plaintextÚ	auth_datac                 C   s:   | j stdƒ‚|  ¡ }|r| |¡ | |¡\}}|| S )aæ  Encrypt and authenticate a message.

        This method can be invoked multiple times
        to seal an ordered sequence of messages.

        Arguments:
          plaintext: bytes
            The message to seal.
          auth_data: bytes
            Optional. Additional Authenticated data (AAD) that is not encrypted
            but that will be also covered by the authentication tag.

        Returns:
           The ciphertext concatenated with the authentication tag.
        z$This cipher can only be used to seal)rc   r\   r›   ÚupdateÚencrypt_and_digest)rl   rœ   r�   rš   ÚctÚtagr   r   r   Úseal3  s   
zHPKE_Cipher.sealÚ
ciphertextc                 C   sŽ   | j rtdƒ‚t|ƒ| jk rtdƒ‚|  ¡ }|r| |¡ z| |d| j … || j d… ¡}W |S  tyF   | jdkrBtdƒ‚tdƒ‚w )að  Decrypt a message and validate its authenticity.

        This method can be invoked multiple times
        to unseal an ordered sequence of messages.

        Arguments:
          cipertext: bytes
            The message to unseal.
          auth_data: bytes
            Optional. Additional Authenticated data (AAD) that
            was also covered by the authentication tag.

        Returns:
           The original plaintext.

        Raises: ValueError
           If the ciphertext (in combination with the AAD) is not valid.

           But if it is the first time you call ``unseal()`` this
           exception may also mean that any of the parameters or keys
           used to establish the session is wrong or that one is missing.
        z&This cipher can only be used to unsealzCiphertext is too smallNr   zAIncorrect HPKE keys/parameters or invalid message (wrong MAC tag)zInvalid message (wrong MAC tag))rc   r\   rˆ   r`   r›   rž   Údecrypt_and_verifyrf   )rl   r£   r�   rš   Úptr   r   r   ÚunsealL  s"   
ÿü
ýzHPKE_Cipher.unseal)NNrv   )r   r   r   r   r   ÚbytesÚtupler    r   rn   ÚstaticmethodÚintr   rd   re   rR   rh   r›   r¢   r¦   r   r   r   r   rI   X   sj    ÿþý
üûú
ù;üÿþýü"üÿþýü'ÿþý
ü6rI   )rK   rL   rŠ   r:   rJ   rN   rK   rL   rŠ   Úreturnc           	      C   sÒ   |t vrtd|d›�ƒ‚| j}|dvrtd|› �ƒ‚|rIt|  ¡ ƒt| ¡ ƒ }|dkr0tdƒ‚|j|kr>td |j|¡ƒ‚|du rEtjntj}n
|du rPtj	ntj
}|du rYd	}|du r_d
}t| ||||||ƒS )aŽ	  Create an HPKE context which can be used:

    - by the sender to seal (encrypt) a message or
    - by the receiver to unseal (decrypt) it.

    As a minimum, the two parties agree on the receiver's asymmetric key
    (of which the sender will only know the public half).

    Additionally, for authentication purposes, they may also agree on:

    * the sender's asymmetric key (of which the receiver will only know the public half)

    * a shared secret (e.g., a symmetric key derived from a password)

    Args:
      receiver_key:
        The ECC key of the receiver.
        It must be on one of the following curves: ``NIST P-256``,
        ``NIST P-384``, ``NIST P-521``, ``X25519`` or ``X448``.

        If this is a **public** key, the HPKE context can only be used to
        **seal** (**encrypt**).

        If this is a **private** key, the HPKE context can only be used to
        **unseal** (**decrypt**).

      aead_id:
        The HPKE identifier of the symmetric cipher.
        The possible values are:

        * ``HPKE.AEAD.AES128_GCM``
        * ``HPKE.AEAD.AES256_GCM``
        * ``HPKE.AEAD.CHACHA20_POLY1305``

      enc:
        The encapsulated session key (i.e., the KEM shared secret).

        The receiver must always specify this parameter.

        The sender must always omit this parameter.

      sender_key:
        The ECC key of the sender.
        It must be on the same curve as the ``receiver_key``.
        If the ``receiver_key`` is a public key, ``sender_key`` must be a
        private key, and vice versa.

      psk:
        A Pre-Shared Key (PSK) as a 2-tuple of non-empty
        byte strings: the identifier and the actual secret value.
        Sender and receiver must use the same PSK (or none).

        The secret value must be at least 32 bytes long,
        but it  must not be a low-entropy password
        (use a KDF like PBKDF2 or scrypt to derive a secret
        from a password).

      info:
        A non-secret parameter that contributes
        to the generation of all session keys.
        Sender and receive must use the same **info** parameter (or none).

    Returns:
        An object that can be used for
        sealing (if ``receiver_key`` is a public key) or
        unsealing (if ``receiver_key`` is a private key).
        In the latter case,
        correctness of all the keys and parameters will only
        be assessed with the first call to ``unseal()``.
    r–   r—   r.   zUnsupported curve r   zExactly 1 private key requiredz'Sender key uses {} but recipient key {}N)rC   rC   rC   )r    r\   rS   rª   rb   r]   r   r   r   r   r   rI   )	rJ   rN   rK   rL   rŠ   r:   rS   Úcount_private_keysrO   r   r   r   r˜   v  s:   M

ÿ

ÿúr˜   ))r=   Úenumr   Útypesr   Útypingr   ÚKDFr   r   ÚDHr   r	   r
   ÚCryptodome.Util.strxorr   ÚCryptodome.PublicKeyr   ÚCryptodome.PublicKey.ECCr   ÚCryptodome.Hashr   r   r   ÚCryptodome.Cipherr   r   r   r    r\   r%   r(   rW   r§   r8   rª   r@   rH   rI   r¨   r˜   r   r   r   r   Ú<module>   sˆ    û	ÿþý
ü	ÿþýü
ûÿþ
ý  "
ûÿþýüûû