""" Class defintion for quadratic sieve factorization """

sage_present = True
try:
    from sage.all_cmdline import *
except ImportError:
    sage_present = False
from RSAExploits.util import compute_priv_rsa_exp
from RSAExploits.exploits.exploit import Exploit

class Qsieve(Exploit):

    def run(self, rsadata_list, info_dict = None):
        """ Factors moduli using quadratic sieve factorization 

            This is currently the 2nd fastest known general purpose
            factoring algorithm
    
            Args:
                rsadata_list: A list of RSA_Data objects with moduli to factor
                info_dict: Not currently used in this exploit

            Side Effects: 
                If a modulus is factored, the corresponding RSA_Data object's
                private key will be computed and initialized

            Return: 
                True if at least one modulus was factored
        """

        global sage_present
        success = False
        
        if not sage_present:
            print "Qsieve Factoring: Sage required, skipping exploit"
            return success 

        print ("Qsieve Factoring: Running Attack...")

        for rsadata in rsadata_list:
            roots = qsieve(rsadata.get_n())
            if roots != None:
                rsadata.set_d(compute_priv_rsa_exp(rsadata.get_e(), roots[0]))
                success = True
    
        if success:     
            print("Qsieve Factoring: Success, roots found, assigned in rsadata.")                       
        else:           
            print("Qsieve Factoring: Failure, roots not found.")

        return success
