o
    n~bZ"                     @   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   L/usr/local/lib/python3.10/dist-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)zInitialize 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 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
   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   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   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 )	ShamirzShamir'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>   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shareZcoeffr   r   r   
make_share   s   z Shamir.split.<locals>.make_sharec                    s   g | ]
}|| fqS r   r   r@   rE   rI   rF   r   r   rC      s    )r5   appendr   )knsecretrF   r   rJ   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 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rG   r   r   	<genexpr>  s    z!Shamir.combine.<locals>.<genexpr>zDuplicate share)r   r   anyr   rK   r5   r4   r'   )ZsharesrF   rL   Z	gf_sharesxvaluer7   jZx_jZy_j	numeratordenominatormZx_mr   rQ   r   combine   s.   zShamir.combineN)F)r:   r;   r<   r=   staticmethodrO   rZ   r   r   r   r   r>      s    5r>   N)ZCryptodome.Util.py3compatr   ZCryptodome.Utilr   ZCryptodome.Util.numberr   r   ZCryptodome.Randomr   r?   r   r   objectr   r>   r   r   r   r   <module>   s   !T