a
    ù!fJ"  ã                   @   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   s@   || kr||  } }d}|r<|d@ r*|| N }| dK } |dL }q|S )z!Multiply two polynomials in GF(2)r   é   © )Úf1Úf2Úzr   r   ú^/var/www/html/python-backend/venv/lib/python3.9/site-packages/Crypto/Protocol/SecretSharing.pyÚ	_mult_gf2(   s    

r   c                 C   sb   | |k rd| fS t j}d}| }||ƒ}||ƒ|krZd||ƒ| > }||N }|t||ƒN }q&||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|| _n t|ƒdkr(t|ƒ| _ntdƒ‚dS )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)ÚselfZencoded_valuer   r   r   Ú__init__S   s
    z_Element.__init__c                 C   s   | j |j kS ©N©r   )r   Úotherr   r   r   Ú__eq__b   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__e   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   Úencodei   s    z_Element.encodec           	      C   sâ   | j }|j }||kr|| }}| j||fv r4tdƒS dd }|d }}|rÚt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 }qFt|ƒS )Nr   r   r   r   )Úbase)r   Úirr_polyr   ÚintÚbin)	r   Úfactorr	   r
   Zmask1Úvr   Zmask2Zmask3r   r   r   Ú__mul__m   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   sp   | j dkrtdƒ‚| j | j }}d\}}|dkrht||ƒd }||t||ƒA  }}||t||ƒA  }}q(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   Z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'   r.   r0   r4   r9   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 sufficient number of shares to reconstruct the secret (``k < n``).
          n (integer):
            The number of shares that this method will create.
          secret (byte string):
            A byte string of 16 bytes (e.g. the AES 128 key).
          ssss (bool):
            If ``True``, the shares can be used with the ``ssss`` utility.
            Default: ``False``.

        Return (tuples):
            ``n`` tuples. A tuple is meant for each participant and it contains two items:

            1. the unique index (an integer)
            2. the share (a byte string, 16 bytes)
        c                 S   s   g | ]}t td ƒƒ‘qS )r   )r   Úrng©Ú.0Úir   r   r   Ú
<listcomp>Í   ó    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ÚshareZcoeffr   r   r   Ú
make_shareÓ   s    z Shamir.split.<locals>.make_sharec                    s   g | ]}|ˆ|ˆ ˆƒf‘qS r   r   r@   ©rF   rJ   rG   r   r   rC   Ü   rD   )r5   Úappendr   )ÚkÚnÚsecretrG   r   rK   r   Úsplit¨   s    %	zShamir.splitc                    sî   t | ƒ}g }| D ]X}t|d ƒ‰ t|d ƒ}t‡ fdd„|D ƒƒrJtdƒ‚|rZ|ˆ | 7 }| ˆ |f¡ qtdƒ}t|ƒD ]j}|| \}}	tdƒ}
tdƒ}t|ƒD ],}|| d }||kr¢|
|9 }
||| 9 }q¢||	|
 | ¡  7 }qz| ¡ S )aè  Recombine a secret, if enough shares are presented.

        Args:
          shares (tuples):
            The *k* tuples, each containin the index (an integer) and
            the share (a byte string, 16 bytes long) that were assigned to
            a participant.
          ssss (bool):
            If ``True``, the shares were produced by the ``ssss`` utility.
            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   )rA   Úy©rH   r   r   Ú	<genexpr>  rD   z!Shamir.combine.<locals>.<genexpr>zDuplicate share)r   r   Úanyr   rL   r5   r4   r'   )ZsharesrG   rM   Z	gf_sharesÚxÚvaluer7   ÚjZx_jZy_jÚ	numeratorÚdenominatorÚmZx_mr   rR   r   ÚcombineÞ   s,    zShamir.combineN)F)F)r:   r;   r<   r=   ÚstaticmethodrP   r[   r   r   r   r   r>   ¡   s
   5r>   N)ZCrypto.Util.py3compatr   ZCrypto.Utilr   ZCrypto.Util.numberr   r   ZCrypto.Randomr   r?   r   r   Úobjectr   r>   r   r   r   r   Ú<module>"   s   T