Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  pplus1.gi   Sprache: unbekannt

 
#############################################################################
##
#W  pplus1.gi               GAP4 Package `FactInt'                Stefan Kohl
##
##  This file contains functions for factorization using a variant of
##  Williams' p+1.
##
##  Arguments of FactorsPplus1:
##
##  <n>         the integer to be factored
##  <Residues>  the number of residues that should be examined
##              (the probability of hitting a usable one is
##              approx. 1 - 1/2^<Residues>)
##  <Limit1>    the limit for the first stage
##  <Limit2>    the limit for the second stage
##
##  The result is returned as a list of two lists. The first list
##  contains the prime factors found, and the second list contains
##  remaining unfactored parts of <n>, if there are any.
##
#############################################################################

BindGlobal("Pplus1Product", function (a,b,n)

  local  c,c12,a12b12;

  a12b12 := a[1][2] * b[1][2];
  c12    := (a[1][1] * b[1][2] + a[1][2] * b[2][2]) mod n;
  c      := [[(a[1][1] * b[1][1] + a12b12) mod n, c12],
             [c12, (a12b12 + a[2][2] * b[2][2]) mod n]];
  return c;
end);

BindGlobal("Pplus1Square", function (a,n)

  local  c,c12,a12a12;

  a12a12 := a[1][2] * a[1][2];
  c12    := a[1][2] * (a[1][1] + a[2][2]) mod n;
  c      := [[(a[1][1]^2 + a12a12) mod n, c12],
             [c12, (a12a12 + a[2][2]^2) mod n]];
  return c;
end);

BindGlobal("Pplus1Power", function (Base,exp,n)

  local  Power,BinExp,i;

  BinExp := CoefficientsQadic(exp,2);
  Power  := Base;

  for i in [Length(BinExp),Length(BinExp)-1..2] do
    Power := Pplus1Square(Power,n);
    if BinExp[i-1] = 1 then
      Power := Pplus1Product(Power,Base,n);
    fi;
  od;

  return Power;
end);

BindGlobal("Pplus1Split", function (n,Residues,Limit1,Limit2)

  local  Residue,ResNo,a,
         PowerOfa,PowerAfterFirstStage,p,pExponent,
         DiffPowers,DiffPos,DiffSum,NextDiff,DiffsLng,BufProd,
         FactorFoundAndReady,FactorsFound;

  FactorFoundAndReady := function (PowerProd)
    
    local  Result,i,j,k;

    Result := Gcd(PowerProd,n);
    if not Result in [1,n] then
      Info(IntegerFactorizationInfo,1,LogInt(Result,10) + 1,
           "-digit factor ",Result," was found");
      Add(FactorsFound,Result); n := n/Result;
      if IsProbablyPrimeInt(n) then Add(FactorsFound,n); return true; fi;
      if IsBound(DiffPowers) then 
        for i in [1..Length(DiffPowers)] do 
          if IsBound(DiffPowers[i]) then 
            for j in [1,2] do for k in [1,2] do
              DiffPowers[i][j][k] := DiffPowers[i][j][k] mod n;
            od; od; 
          fi;
        od;
      fi;
    fi;
    return false;
  end;

  if IsProbablyPrimeInt(n) then return [n]; fi;
  FactorsFound := [];

  Info(IntegerFactorizationInfo,2,
       "p+1 for n = ",n,"\nResidues : ",Residues,
       ", Limit1 : ",Limit1,", Limit2 : ",Limit2);

  Residue := 1;
  for ResNo in [1..Residues] do
    Info(IntegerFactorizationInfo,2,"Residue no. ",ResNo);
    a := [[Residue,1],[1,0]];

    Info(IntegerFactorizationInfo,3,"First stage");
    p := 2; PowerOfa := a;
    while p <= Limit1 do
      pExponent := LogInt(Limit1,p);
      PowerOfa  := Pplus1Power(PowerOfa,p^pExponent,n);
      if   FactorFoundAndReady(PowerOfa[1][2]) 
      then return FactorsFound; fi;
      p := NextPrimeInt(p);
    od;

    Info(IntegerFactorizationInfo,3,"Second stage");
    PowerAfterFirstStage := PowerOfa; PowerOfa := [[1,0],[0,1]];
    DiffPowers := []; DiffPos := 1; DiffSum := 0;
    DiffsLng := Length(PrimeDiffs); BufProd := 1;
    while (DiffSum <= Limit2) and (DiffPos <= DiffsLng) do
      NextDiff := PrimeDiffs[DiffPos];
      DiffSum := DiffSum + NextDiff;
      if not IsBound(DiffPowers[NextDiff]) 
      then DiffPowers[NextDiff] := 
           Pplus1Power(PowerAfterFirstStage,NextDiff,n); fi;
      PowerOfa := Pplus1Product(PowerOfa,DiffPowers[NextDiff],n);
      BufProd  := BufProd * PowerOfa[1][2] mod n;
      if DiffPos mod 50 = 0 then
        if   FactorFoundAndReady(BufProd)
        then return FactorsFound; fi;
      fi; 
      DiffPos := DiffPos + 1;
    od;
    Residue := NextPrimeInt(Residue);
  od;

  Add(FactorsFound,n); return FactorsFound;
end);

#############################################################################
##
#F  FactorsPplus1( <n>, [ [ <Residues> ], <Limit1>, [ <Limit2> ] ] )
##
InstallGlobalFunction( FactorsPplus1,

function ( arg )

  local  n, Residues, Limit1, Limit2, GetArg, ArgCorrect,
         FactorsList, m, Split, q;

  GetArg := function (ArgPos,ArgName,ArgDefault)
    if IsBound(arg[ArgPos]) then 
      if arg[ArgPos] <> fail then return arg[ArgPos];
                             else return ArgDefault; fi; 
    fi;
    if ValueOption(ArgName) <> fail then return ValueOption(ArgName); fi;
    return ArgDefault;
  end;

  ArgCorrect := Length(arg) in [1..4];
  if ArgCorrect then
    n := arg[1];
    if Length(arg) = 4 
    then
      Residues := arg[2];
      Limit1   := GetArg(3,"Pplus1Limit1",Int(PrimeDiffLimit/40));
      Limit2   := GetArg(4,"Pplus1Limit2",40 * Limit1);
    else
      Residues := GetArg(5,"Pplus1Residues",2);
      Limit1   := GetArg(2,"Pplus1Limit1",Int(PrimeDiffLimit/40));
      Limit2   := GetArg(3,"Pplus1Limit2",40 * Limit1);
    fi; 
    if not (IsInt(n) and n >= 1 and IsInt(Residues) and Residues >= 1
            and IsPosInt(Limit1) and IsPosInt(Limit2)) 
    then ArgCorrect := false; fi; 
  fi;
  if not ArgCorrect
  then Error("Usage : FactorsPplus1( <n>, [ [ <Residues> ], <Limit1>, ",
             "[ <Limit2> ] ] ), where <n>, <Residues>, ",
             "<Limit1> and <Limit2> have to be positive integers");
  fi;

  if IsProbablyPrimeInt(n) then return [[n],[]]; fi;

  InitPrimeDiffs(Limit2); 

  FactorsList := FactorsTD(n);
  if FactorsList[2] <> [] then
    m := FactorsList[2][1];
    if   SmallestRootInt(m) < m
    then ApplyFactoringMethod(FactorsPowerCheck,
                              [FactorsPplus1,"FactorsPplus1"],
                              FactorsList,infinity);
    else
      Split := Pplus1Split(m,Residues,Limit1,Limit2);
      FactorsList[2] := [];
      for q in Split do if   IsProbablyPrimeInt(q) 
                        then Add(FactorsList[1],q);
                        else Add(FactorsList[2],q); fi; od;
    fi;
  fi;

  Sort(FactorsList[1]); Sort(FactorsList[2]);
  FactorizationCheck(n,FactorsList);
  return FactorsList;
end);

#############################################################################
##
#E  pplus1.gi  . . . . . . . . . . . . . . . . . . . . . . . . . .  ends here

[ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge