o
    Þý°j²#  ã                   @   sh   d dl mZ d dlmZ d dlmZmZ d dlmZ	 dd„ Z
dd„ ZG d	d
„ d
eƒZG dd„ deƒZdS )é    )Úis_native_int)Únumber)Úlong_to_bytesÚbytes_to_long)Úget_random_bytesc                 C   sB   || kr	|| } }d}|r|d@ r|| N }| dK } |dL }|s|S )z!Multiply two polynomials in GF(2)r   é   © )Úf1Úf2Úzr   r   ú”/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/Cryptodome/Protocol/SecretSharing.pyÚ	_mult_gf2(   s   
ür   c                 C   sl   | |k rd| fS t j}d}| }||ƒ}||ƒ|kr2d||ƒ| > }||N }|t||ƒN }||ƒ|ks||fS )z˜
    Compute division of polynomials over GF(2).
    Given a and b, it finds two polynomials q and r such that:

    a = b*q + r with deg(r)<deg(b)
    r   r   )r   Úsizer   )ÚaÚbÚdegÚqÚrÚdÚsr   r   r   Ú_div_gf27   s   ýr   c                   @   s\   e Zd ZdZd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d„ ZdS )Ú_ElementzElement of GF(2^128) fieldé‡   é   é€   c                 C   s4   t |ƒr	|| _dS t|ƒdkrt|ƒ| _dS tdƒ‚)zïInitialize the element to a certain value.

        The value passed as parameter is internally encoded as
        a 128-bit integer, where each bit represents a polynomial
        coefficient. The LSB is the constant coefficient.
        é   z8The encoded value must be an integer or a 16 byte stringN)r   Ú_valueÚlenr   Ú
ValueError)ÚselfÚencoded_valuer   r   r   Ú__init__T   s
   
z_Element.__init__c                 C   s   | j |j kS ©N©r   )r   Úotherr   r   r   Ú__eq__c   s   z_Element.__eq__c                 C   s   | j S )z7Return the field element, encoded as a 128-bit integer.r#   ©r   r   r   r   Ú__int__f   s   z_Element.__int__c                 C   s   t | jdƒS )z6Return the field element, encoded as a 16 byte string.r   )r   r   r&   r   r   r   Úencodej   s   z_Element.encodec           	      C   sä   | j }|j }||kr||}}| j||fv rtdƒS dd }|d}}|rntt|d@ ƒdd … d dd�}|||A @ || d |@ B }|dK }tt|d? d@ ƒdd … d dd�}||| jA @ || d |@ B }|dL }|s%t|ƒS )Nr   r   r   r   )Úbase)r   Úirr_polyr   ÚintÚbin)	r   Úfactorr	   r
   Úmask1Úvr   Úmask2Úmask3r   r   r   Ú__mul__n   s"   

 $ø	z_Element.__mul__c                 C   s   t | j|jA ƒS r"   )r   r   )r   Útermr   r   r   Ú__add__‡   s   z_Element.__add__c                 C   sv   | j dkr	tdƒ‚| j | j}}d\}}|dkr7t||ƒd }||t||ƒA }}||t||ƒA }}|dkst|ƒS )z0Return the inverse of this element in GF(2^128).r   zInversion of zero)r   r   )r   r   r*   r   r   r   )r   Úr0Úr1Ús0Ús1r   r   r   r   ÚinverseŠ   s   
ýz_Element.inversec                 C   s(   t | jƒ}t|d ƒD ]}||  }q|S )Nr   )r   r   Úrange)r   ÚexponentÚresultÚ_r   r   r   Ú__pow__›   s   

z_Element.__pow__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r*   r!   r%   r'   r(   r2   r4   r9   r>   r   r   r   r   r   M   s    r   c                   @   s,   e Zd ZdZeddd„ƒZeddd„ƒZdS )	ÚShamirz›Shamir's secret sharing scheme.

    A secret is split into ``n`` shares, and it is sufficient to collect
    ``k`` of them to reconstruct the secret.
    Fc                    sL   dd„ t | d ƒD ƒ‰ ˆ  t|ƒ¡ dd„ ‰‡ ‡‡fdd„t d|d ƒD ƒS )a½  Split a secret into ``n`` shares.

        The secret can be reconstructed later using just ``k`` shares
        out of the original ``n``.
        Each share must be kept confidential to the person it was
        assigned to.

        Each share is associated to an index (starting from 1).

        Args:
          k (integer):
            The number of shares needed to reconstruct the secret.
          n (integer):
            The number of shares to create (at least ``k``).
          secret (byte string):
            A byte string of 16 bytes (e.g. an AES 128 key).
          ssss (bool):
            If ``True``, the shares can be used with the ``ssss`` utility
            (without using the "diffusion layer").
            Default: ``False``.

        Return (tuples):
            ``n`` tuples, one per participant.
            A tuple contains two items:

            1. the unique index (an integer)
            2. the share (16 bytes)
        c                 S   s   g | ]}t td ƒƒ‘qS )r   )r   Úrng©Ú.0Úir   r   r   Ú
<listcomp>Ð   s    z Shamir.split.<locals>.<listcomp>r   c                 S   sF   t | ƒ}t dƒ}|D ]}|| | }q
|r|t | ƒt|ƒ 7 }| ¡ S )Nr   )r   r   r(   )ÚuserÚcoeffsÚssssÚidxÚshareÚcoeffr   r   r   Ú
make_shareÖ   s   z Shamir.split.<locals>.make_sharec                    s   g | ]
}|ˆ|ˆ ˆƒf‘qS r   r   rE   ©rJ   rO   rK   r   r   rH   ç   s    )r:   Úappendr   )ÚkÚnÚsecretrK   r   rP   r   Úsplit©   s   ' zShamir.splitc                    sî   t | ƒ}g }| D ],}t|d ƒ‰ t|d ƒ}t‡ fdd„|D ƒƒr%tdƒ‚|r-|ˆ | 7 }| ˆ |f¡ qtdƒ}t|ƒD ]5}|| \}}	tdƒ}
tdƒ}t|ƒD ]}|| d }||krg|
|9 }
||| 9 }qQ||	|
 | ¡  7 }q=| ¡ S )a’  Recombine a secret, if enough shares are presented.

        Args:
          shares (tuples):
            The *k* tuples, each containing the index (an integer) and
            the share (a byte string, 16 bytes long) that were assigned to
            a participant.

            .. note::

                Pass exactly as many share as they are required,
                and no more.

          ssss (bool):
            If ``True``, the shares were produced by the ``ssss`` utility
            (without using the "diffusion layer").
            Default: ``False``.

        Return:
            The original secret, as a byte string (16 bytes long).
        r   r   c                 3   s   � | ]	}|d  ˆ kV  qdS )r   Nr   )rF   Úy©rL   r   r   Ú	<genexpr>  s   € z!Shamir.combine.<locals>.<genexpr>zDuplicate share)r   r   Úanyr   rQ   r:   r9   r(   )ÚsharesrK   rR   Ú	gf_sharesÚxÚvaluer<   ÚjÚx_jÚy_jÚ	numeratorÚdenominatorÚmÚx_mr   rW   r   Úcombineé   s.   &€zShamir.combineN)F)r?   r@   rA   rB   ÚstaticmethodrU   re   r   r   r   r   rC   ¢   s    ?rC   N)ÚCryptodome.Util.py3compatr   ÚCryptodome.Utilr   ÚCryptodome.Util.numberr   r   ÚCryptodome.Randomr   rD   r   r   Úobjectr   rC   r   r   r   r   Ú<module>   s   !U