U
    MfSk                     @   s  d dl Z d dlmZmZ d dlmZmZmZmZm	Z	m
Z
mZmZmZ ddlmZ dZe jdkrfeded	eZd	ed
Zeedreded dkrd dlmZmZmZmZ G dd deZdd Znd dlmZ dd ZG dd deZe Z G dd deZ!dS )    N)tobytesis_native_int)	backendload_libget_raw_bufferget_c_stringnull_pointercreate_string_bufferc_ulongc_size_tc_uint8_ptr   )IntegerBaseaY  typedef unsigned long UNIX_ULONG;
        typedef struct { int a; int b; void *c; } MPZ;
        typedef MPZ mpz_t[1];
        typedef UNIX_ULONG mp_bitcnt_t;

        void __gmpz_init (mpz_t x);
        void __gmpz_init_set (mpz_t rop, const mpz_t op);
        void __gmpz_init_set_ui (mpz_t rop, UNIX_ULONG op);

        UNIX_ULONG __gmpz_get_ui (const mpz_t op);
        void __gmpz_set (mpz_t rop, const mpz_t op);
        void __gmpz_set_ui (mpz_t rop, UNIX_ULONG op);
        void __gmpz_add (mpz_t rop, const mpz_t op1, const mpz_t op2);
        void __gmpz_add_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2);
        void __gmpz_sub_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2);
        void __gmpz_addmul (mpz_t rop, const mpz_t op1, const mpz_t op2);
        void __gmpz_addmul_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2);
        void __gmpz_submul_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2);
        void __gmpz_import (mpz_t rop, size_t count, int order, size_t size,
                            int endian, size_t nails, const void *op);
        void * __gmpz_export (void *rop, size_t *countp, int order,
                              size_t size,
                              int endian, size_t nails, const mpz_t op);
        size_t __gmpz_sizeinbase (const mpz_t op, int base);
        void __gmpz_sub (mpz_t rop, const mpz_t op1, const mpz_t op2);
        void __gmpz_mul (mpz_t rop, const mpz_t op1, const mpz_t op2);
        void __gmpz_mul_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2);
        int __gmpz_cmp (const mpz_t op1, const mpz_t op2);
        void __gmpz_powm (mpz_t rop, const mpz_t base, const mpz_t exp, const
                          mpz_t mod);
        void __gmpz_powm_ui (mpz_t rop, const mpz_t base, UNIX_ULONG exp,
                             const mpz_t mod);
        void __gmpz_pow_ui (mpz_t rop, const mpz_t base, UNIX_ULONG exp);
        void __gmpz_sqrt(mpz_t rop, const mpz_t op);
        void __gmpz_mod (mpz_t r, const mpz_t n, const mpz_t d);
        void __gmpz_neg (mpz_t rop, const mpz_t op);
        void __gmpz_abs (mpz_t rop, const mpz_t op);
        void __gmpz_and (mpz_t rop, const mpz_t op1, const mpz_t op2);
        void __gmpz_ior (mpz_t rop, const mpz_t op1, const mpz_t op2);
        void __gmpz_clear (mpz_t x);
        void __gmpz_tdiv_q_2exp (mpz_t q, const mpz_t n, mp_bitcnt_t b);
        void __gmpz_fdiv_q (mpz_t q, const mpz_t n, const mpz_t d);
        void __gmpz_mul_2exp (mpz_t rop, const mpz_t op1, mp_bitcnt_t op2);
        int __gmpz_tstbit (const mpz_t op, mp_bitcnt_t bit_index);
        int __gmpz_perfect_square_p (const mpz_t op);
        int __gmpz_jacobi (const mpz_t a, const mpz_t b);
        void __gmpz_gcd (mpz_t rop, const mpz_t op1, const mpz_t op2);
        UNIX_ULONG __gmpz_gcd_ui (mpz_t rop, const mpz_t op1,
                                     UNIX_ULONG op2);
        void __gmpz_lcm (mpz_t rop, const mpz_t op1, const mpz_t op2);
        int __gmpz_invert (mpz_t rop, const mpz_t op1, const mpz_t op2);
        int __gmpz_divisible_p (const mpz_t n, const mpz_t d);
        int __gmpz_divisible_ui_p (const mpz_t n, UNIX_ULONG d);
        win32zNot using GMP on WindowsZgmp)libraryapiZ__mpir_versionzMPIR library detectedr   ctypes)	Structurec_intc_void_pbyrefc                   @   s"   e Zd ZdefdefdefgZdS )_MPZZ	_mp_allocZ_mp_sizeZ_mp_dN)__name__
__module____qualname__r   r   _fields_ r   r   ?/tmp/pip-unpacked-wheel-l_0d1exj/Cryptodome/Math/_IntegerGMP.pyr   p   s   r   c                   C   s
   t t S N)r   r   r   r   r   r   new_mpzu   s    r   )ffic                   C   s
   t dS )NzMPZ*)r    newr   r   r   r   r   |   s    c                   @   s   e Zd Zdd ZdS )_GMPc                 C   s^   | drd|dd   }n(| dr8d|dd   }ntd| tt|}t| || |S )NZmpz_Z__gmpz_   Zgmp_Z__gmp_zAttribute %s is invalid)
startswithAttributeErrorgetattrlibsetattr)selfname	func_namefuncr   r   r   __getattr__   s    


z_GMP.__getattr__N)r   r   r   r-   r   r   r   r   r"      s   r"   c                   @   s  e Zd ZdZe Zeeed dd Z	dd Z
dd Zd	d
 Zdd Zdd ZdmddZednd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eZd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Z dod1d2Z!dpd3d4Z"d5d6 Z#dqd7d8Z$d9d: Z%d;d< Z&d=d> Z'd?d@ Z(dAdB Z)dCdD Z*dEdF Z+dGdH Z,dIdJ Z-dKdL Z.dMdN Z/dOdP Z0dQdR Z1dSdT Z2dUdV Z3dWdX Z4dYdZ Z5d[d\ Z6d]d^ Z7d_d` Z8dadb Z9dcdd Z:dedf Z;edgdh Z<edidj Z=dkdl Z>d0S )r
IntegerGMPz#A fast, arbitrary precision integerr   c              	   C   s$  t  | _d| _t|tr tdt|rt| j d| _|dkrFdS t  }t| z~|dk}t
|}| d d d }|dkr|d }t|td||d ? @  t||t|d  t| j| j| q|W 5 t	| X |st| j| j n(t|trt| j|j d| _ntdS )	z*Initialize the integer to the given value.Fz-A floating point type is not a natural numberTr   Nr           )r   _mpz_p_initialized
isinstancefloat
ValueErrorr   _gmpZmpz_init	mpz_clearabs
bit_lengthZ
mpz_set_uir
   mpz_mul_2expmpz_addmpz_negr.   mpz_init_setNotImplementedError)r)   valuetmpZpositivereduceslotsr   r   r   __init__   s:    

zIntegerGMP.__init__c              	   C   s   t  }t|| j zXd}d}t|| jdkrjt|d@ }|||d > O }t||t	d |d }qW 5 t| X | dk r| }t
|S )Nr   r0   r/   r   )r   r6   r=   r1   r7   mpz_cmp_zero_mpz_pZ
mpz_get_uimpz_tdiv_q_2expr
   int)r)   r@   r?   ZslotZlsbr   r   r   __int__   s    zIntegerGMP.__int__c                 C   s   t t| S r   )strrG   r)   r   r   r   __str__   s    zIntegerGMP.__str__c                 C   s   dt |  S )NzInteger(%s))rI   rJ   r   r   r   __repr__   s    zIntegerGMP.__repr__c                 C   s   t t| S r   )hexrG   rJ   r   r   r   __hex__   s    zIntegerGMP.__hex__c                 C   s   t | S r   )rG   rJ   r   r   r   	__index__   s    zIntegerGMP.__index__bigc              	   C   s   | dk rt dt| jdd d }||  kr:dkrFn nt dt|}t|tdtddtd| j dtd||  t	| }|d	krn*|d
krt
|}|  t|}nt d|S )a  Convert the number into a byte string.

        This method encodes the number in network order and prepends
        as many zero bytes as required. It only works for non-negative
        values.

        :Parameters:
          block_size : integer
            The exact size the output byte string must have.
            If zero, the string has the minimal length.
          byteorder : string
            'big' for big-endian integers (default), 'little' for litte-endian.
        :Returns:
          A byte string.
        :Raise ValueError:
          If the value is negative or if ``block_size`` is
          provided and the length of the byte string would exceed it.
        r   .Conversion only valid for non-negative numbers         z@Number is too big to convert to byte string of prescribed lengthr       rP   littleIncorrect byteorder)r5   r6   mpz_sizeinbaser1   r	   Z
mpz_exportr   r   maxr   	bytearrayreversebytes)r)   
block_size	byteorderZbuf_lenbufresultr   r   r   to_bytes   s0    	
zIntegerGMP.to_bytesc              
   C   sd   t d}|dkrn"|dkr,t| } |   ntdt|jtt| dtddtdt	|  |S )a  Convert a byte string into a number.

        :Parameters:
          byte_string : byte string
            The input number, encoded in network order.
            It can only be non-negative.
          byteorder : string
            'big' for big-endian integers (default), 'little' for litte-endian.

        :Return:
          The ``Integer`` object carrying the same value as the input.
        r   rP   rV   rW   r   )
r.   rZ   r[   r5   r6   Z
mpz_importr1   r   lenr   )Zbyte_stringr^   r`   r   r   r   
from_bytes  s"    

zIntegerGMP.from_bytesc                 C   s    t |tst|}|| j|jS r   )r3   r.   r1   )r)   r,   termr   r   r   _apply_and_return7  s    
zIntegerGMP._apply_and_returnc                 C   s(   t |tst|sdS | tj|dkS )NFr   r3   r.   r   re   r6   rD   r)   rd   r   r   r   __eq__<  s    zIntegerGMP.__eq__c                 C   s(   t |tst|sdS | tj|dkS )NTr   rf   rg   r   r   r   __ne__A  s    zIntegerGMP.__ne__c                 C   s   |  tj|dk S Nr   re   r6   rD   rg   r   r   r   __lt__F  s    zIntegerGMP.__lt__c                 C   s   |  tj|dkS rj   rk   rg   r   r   r   __le__I  s    zIntegerGMP.__le__c                 C   s   |  tj|dkS rj   rk   rg   r   r   r   __gt__L  s    zIntegerGMP.__gt__c                 C   s   |  tj|dkS rj   rk   rg   r   r   r   __ge__O  s    zIntegerGMP.__ge__c                 C   s   t | j| jdkS rj   r6   rD   r1   rE   rJ   r   r   r   __nonzero__R  s    zIntegerGMP.__nonzero__c                 C   s   t | j| jdk S rj   rp   rJ   r   r   r   is_negativeV  s    zIntegerGMP.is_negativec                 C   sP   t d}t|t s8zt |}W n tk
r6   t Y S X t|j| j|j |S rj   )r.   r3   r>   NotImplementedr6   r;   r1   r)   rd   r`   r   r   r   __add__Z  s    

zIntegerGMP.__add__c                 C   sP   t d}t|t s8zt |}W n tk
r6   t Y S X t|j| j|j |S rj   )r.   r3   r>   rs   r6   mpz_subr1   rt   r   r   r   __sub__f  s    

zIntegerGMP.__sub__c                 C   sP   t d}t|t s8zt |}W n tk
r6   t Y S X t|j| j|j |S rj   )r.   r3   r>   rs   r6   mpz_mulr1   rt   r   r   r   __mul__r  s    

zIntegerGMP.__mul__c                 C   sN   t |tst|}t|j| jdkr.tdtd}t|j| j|j |S )Nr   Division by zero)r3   r.   r6   rD   r1   rE   ZeroDivisionErrorZ
mpz_fdiv_q)r)   divisorr`   r   r   r   __floordiv__~  s    
zIntegerGMP.__floordiv__c                 C   sb   t |tst|}t|j| j}|dkr2td|dk rBtdtd}t|j| j|j |S Nr   rz   Modulus must be positive	r3   r.   r6   rD   r1   rE   r{   r5   Zmpz_mod)r)   r|   compr`   r   r   r   __mod__  s    
zIntegerGMP.__mod__Nc                 C   s   |d krD|dk rt d|dkr(t dt| j| jtt| nt|tsVt|}|sbtd|	 rrt dt
|r|dk rt d|dk rt| j| jt||j | S t|}n|	 rt dt| j| j|j|j | S )Nr   zExponent must not be negative   zExponent is too bigrz   r      )r5   r6   Z
mpz_pow_uir1   r
   rG   r3   r.   r{   rr   r   Zmpz_powm_uiZmpz_powm)r)   exponentmodulusr   r   r   inplace_pow  sD    


zIntegerGMP.inplace_powc                 C   s   t | }|||S r   )r.   r   )r)   r   r   r`   r   r   r   __pow__  s    zIntegerGMP.__pow__c                 C   s   t d}t|j| j |S rj   )r.   r6   Zmpz_absr1   )r)   r`   r   r   r   __abs__  s    zIntegerGMP.__abs__c                 C   sf   |dkr2| dk rt dtd}t|j| j n0|dkrBt dt|}t| t| | |}|S )zGReturn the largest Integer that does not
        exceed the square rootNr   zSquare root of negative valuer   )r5   r.   r6   Zmpz_sqrtr1   rG   Z_tonelli_shanksr)   r   r`   r   r   r   sqrt  s    zIntegerGMP.sqrtc                 C   s   t |rvd|  krdk r:n nt| j| jt| | S d|  k rNdk rnn nt| j| jt|  | S t|}t| j| j|j | S Nr   r    )r   r6   
mpz_add_uir1   r
   
mpz_sub_uir.   r;   rg   r   r   r   __iadd__  s&    zIntegerGMP.__iadd__c                 C   s   t |rvd|  krdk r:n nt| j| jt| | S d|  k rNdk rnn nt| j| jt|  | S t|}t| j| j|j | S r   )r   r6   r   r1   r
   r   r.   rv   rg   r   r   r   __isub__  s&    zIntegerGMP.__isub__c                 C   s   t |rd|  krdk r:n nt| j| jt| | S d|  k rNdk r~n n,t| j| jt|  t| j| j | S t|}t| j| j|j | S r   )r   r6   Z
mpz_mul_uir1   r
   r<   r.   rx   rg   r   r   r   __imul__  s(    zIntegerGMP.__imul__c                 C   sZ   t |tst|}t|j|j}|dkr2td|dk rBtdt| j| j|j | S r~   r   )r)   r|   r   r   r   r   __imod__  s    
zIntegerGMP.__imod__c                 C   s2   t d}t|t st |}t|j| j|j |S rj   )r.   r3   r6   Zmpz_andr1   rt   r   r   r   __and__!  s    
zIntegerGMP.__and__c                 C   s2   t d}t|t st |}t|j| j|j |S rj   )r.   r3   r6   Zmpz_iorr1   rt   r   r   r   __or__*  s    
zIntegerGMP.__or__c                 C   sN   t d}|dk rtd|dkr0| dk r,dS dS t|j| jtt| |S Nr   znegative shift countr   )r.   r5   r6   rF   r1   r
   rG   r)   posr`   r   r   r   
__rshift__3  s    
zIntegerGMP.__rshift__c                 C   sF   |dk rt d|dkr(| dk r$dS dS t| j| jtt| | S r   )r5   r6   rF   r1   r
   rG   r)   r   r   r   r   __irshift__A  s    
zIntegerGMP.__irshift__c                 C   sD   t d}d|  krdk s&n tdt|j| jtt| |S Nr   r   zIncorrect shift count)r.   r5   r6   r:   r1   r
   rG   r   r   r   r   
__lshift__N  s    
zIntegerGMP.__lshift__c                 C   s<   d|  krdk sn t dt| j| jtt| | S r   )r5   r6   r:   r1   r
   rG   r   r   r   r   __ilshift__W  s    
zIntegerGMP.__ilshift__c                 C   sF   | dk rt d|dk r t d|dkr,dS tt| jtt|S )zPReturn True if the n-th bit is set to 1.
        Bit 0 is the least significant.r   z)no bit representation for negative valuesznegative bit countr   )r5   boolr6   
mpz_tstbitr1   r
   rG   )r)   nr   r   r   get_bit_  s    

zIntegerGMP.get_bitc                 C   s   t | jddkS )Nr   r   r6   r   r1   rJ   r   r   r   is_oddm  s    zIntegerGMP.is_oddc                 C   s   t | jddkS rj   r   rJ   r   r   r   is_evenp  s    zIntegerGMP.is_evenc                 C   s   | dk rt dt| jdS )z=Return the minimum number of bits that can encode the number.r   rQ   rR   )r5   r6   rX   r1   rJ   r   r   r   size_in_bitss  s    zIntegerGMP.size_in_bitsc                 C   s   |   d d d S )z>Return the minimum number of bytes that can encode the number.r   rT   )r   rJ   r   r   r   size_in_bytesz  s    zIntegerGMP.size_in_bytesc                 C   s   t | jdkS rj   )r6   Zmpz_perfect_square_pr1   rJ   r   r   r   is_perfect_square~  s    zIntegerGMP.is_perfect_squarec                 C   sb   t |rFd|  k rdk r>n nt| jt|r:tddS t|}t| j|jr^tddS )z3Raise an exception if the small prime is a divisor.r   r   zThe value is compositeN)r   r6   Zmpz_divisible_ui_pr1   r
   r5   r.   Zmpz_divisible_p)r)   Zsmall_primer   r   r   fail_if_divisible_by  s    zIntegerGMP.fail_if_divisible_byc                 C   s   t |tst|}t|rd|  k r.dk rLn nt| j|jt| | S d|  k r`dk rn nt| j|jt|  | S t|}t| j|j|j | S )z/Increment the number by the product of a and b.r   r   r   )	r3   r.   r   r6   Zmpz_addmul_uir1   r
   Zmpz_submul_uiZ
mpz_addmul)r)   abr   r   r   multiply_accumulate  s*    
zIntegerGMP.multiply_accumulatec                 C   s&   t |tst|}t| j|j | S )z'Set the Integer to have the given value)r3   r.   r6   Zmpz_setr1   )r)   sourcer   r   r   set  s    
zIntegerGMP.setc                 C   sf   t |tst|}t|j| j}|dkr2td|dk rBtdt| j| j|j}|sbtd| S )zCompute the inverse of this number in the ring of
        modulo integers.

        Raise an exception if no inverse exists.
        r   Modulus cannot be zeror   z No inverse value can be computed)	r3   r.   r6   rD   r1   rE   r{   r5   Z
mpz_invert)r)   r   r   r`   r   r   r   inplace_inverse  s     
zIntegerGMP.inplace_inversec                 C   s   t | }|| |S r   )r.   r   r   r   r   r   inverse  s    
zIntegerGMP.inversec                 C   sb   t d}t|rJd|  k r$dk rBn nt|j| jt| |S t |}t|j| j|j |S )zUCompute the greatest common denominator between this
        number and another term.r   i  )r.   r   r6   Z
mpz_gcd_uir1   r
   Zmpz_gcdrt   r   r   r   gcd  s    zIntegerGMP.gcdc                 C   s2   t d}t|t st |}t|j| j|j |S )zQCompute the least common multiplier between this
        number and another term.r   )r.   r3   r6   Zmpz_lcmr1   rt   r   r   r   lcm  s
    
zIntegerGMP.lcmc                 C   sL   t | tst| } t |ts$t|}|dks4| r<tdt| j|jS )zCompute the Jacobi symbolr   z,n must be positive odd for the Jacobi symbol)r3   r.   r   r5   r6   Z
mpz_jacobir1   )r   r   r   r   r   jacobi_symbol  s    

zIntegerGMP.jacobi_symbolc                 C   s   t | tst| } t |ts$t|}t |ts6t|}|dk rFtd|dkrVtd|d@ dkrjtdt| }| | | |}|S )Nr   r   r   r   zOdd modulus is required)r3   r.   r5   r{   rb   ra   )Zterm1Zterm2r   Znumbers_lenr`   r   r   r   _mult_modulo_bytes  s    


zIntegerGMP._mult_modulo_bytesc                 C   s@   z&| j d k	r| jrt| j  d | _ W n tk
r:   Y nX d S r   )r1   r2   r6   r7   r%   rJ   r   r   r   __del__  s    

zIntegerGMP.__del__)r   rP   )rP   )N)N)N)?r   r   r   __doc__r   rE   r6   Zmpz_init_set_uir
   rC   rH   rK   rL   rN   rO   ra   staticmethodrc   re   rh   ri   rl   rm   rn   ro   rq   __bool__rr   ru   rw   ry   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r.      sv   +
2 
'

				


r.   )"sysZCryptodome.Util.py3compatr   r   ZCryptodome.Util._raw_apir   r   r   r   r   r	   r
   r   r   Z_IntegerBaser   Zgmp_defsplatformImportErrorr'   implementationhasattrr   r   r   r   r   r   r   r    objectr"   r6   r.   r   r   r   r   <module>   s&   ,7




