#############################################################################
##
#W cfrac.gi GAP4 Package `FactInt' Stefan Kohl
##
## This file contains functions for factorization using the
## Continued Fraction Algorithm (Brillhard-Morrison Algorithm).
##
## Argument of FactorsCFRAC:
##
## <n> the integer to be factored
##
## The result is returned as a list of the prime factors of <n>.
##
#############################################################################
Info(IntegerFactorizationInfo,2,"CFRAC for n = ",n);
Info(IntegerFactorizationInfo,2,"Digits : ",Digits);
zero := Zero(GF(2)); one := One(GF(2));
CollectingIntervals := [1000,2000,5000,10000,20000,50000,100000,200000, 500000,1000000];
CollectingInterval := CollectingIntervals[Minimum(Int(Digits/5),
Length(CollectingIntervals))];
NextCollectionAt := CollectingInterval;
# Generate the factor base
Multiplier := n mod 8; n := n * Multiplier;
FactorBaseSize := QuoInt(Digits^3,200);
FactorBase := [-1]; pi := 1;
for i in [2..FactorBaseSize] do
repeat
pi := NextPrimeInt(pi);
until Legendre(n,pi) = 1;
FactorBase[i] := pi;
od;
MaxFactorBaseEl := FactorBase[FactorBaseSize];
LargePrimeLimit := MaxFactorBaseEl^2;
Required := FactorBaseSize + 20;
Info(IntegerFactorizationInfo,2,"Size of factor base : ",
FactorBaseSize);
Info(IntegerFactorizationInfo,3,"\nFactor base : \n",FactorBase,"\n");
Aj := sqrt;
Bk := 0; Bj := sqrt;
Ck := 1; Cj := n - sqrt^2;
Pk := 1; Pj := sqrt;
Step := 1;
# Abort Trial Division after dividing Ci by the first <AbortingTime>
# primes in the factor base if the the unfactored part after that
# is larger than <abort>
# Calculate the continued fraction expansion of the square root of n
# until there are enough factored Ci's
repeat
# Generate the next set of values of the considered five sequences,
# especially the next Ci
Step := Step + 1;
Ai := QuoInt(sqrt + Bj,Cj);
Bi := Ai * Cj - Bj;
Ci := Ck + Ai * (Bj - Bi);
Pi := (Pk + Ai * Pj) mod n;
# Trial divide Ci
if Step > 100 then
CiBuf := Ci;
if Step mod 2 = 0 then CiFact := [];
else CiFact := [-1];
fi;
for i in [2..AbortingTime1] do
while CiBuf mod FactorBase[i] = 0 do
CiBuf := CiBuf/FactorBase[i];
Add(CiFact,FactorBase[i]);
od;
od;
if CiBuf <= abort1 then
for i in [AbortingTime1 + 1..AbortingTime2] do
while CiBuf mod FactorBase[i] = 0 do
CiBuf := CiBuf/FactorBase[i];
Add(CiFact,FactorBase[i]);
od;
od;
if CiBuf <= abort2 then
for i in [AbortingTime2 + 1..FactorBaseSize] do
while CiBuf mod FactorBase[i] = 0 do
CiBuf := CiBuf/FactorBase[i];
Add(CiFact,FactorBase[i]);
od;
od;
if CiBuf < LargePrimeLimit then
if CiBuf = 1 then
Add(Factored,[Pi,CiFact]);
else
Add(LargeFactors,CiBuf);
Add(CiFact,CiBuf);
Add(FactoredLarge,[Pi,CiFact]);
fi;
fi;
fi;
fi;
fi;
# Look for usable factorizations with a large factor
if Step >= NextCollectionAt
then
Info(IntegerFactorizationInfo,3,"");
Info(IntegerFactorizationInfo,3,
"Collecting relations with a large factor");
if InfoLevel(IntegerFactorizationInfo) < 3 then
Info(IntegerFactorizationInfo,2,
"Step ",String(Step,9)," : Factored/FB.: ",String(RelsFB,4),
", w. Large Fact.: ",String(RelsLarge,4),
", Progress :",String(Progress,3),"%");
fi;
Info(IntegerFactorizationInfo,3,
"Steps : ",
String(Step,10));
Info(IntegerFactorizationInfo,3,
"Complete factorizations over the factor base : ",
String(RelsFB,10));
Info(IntegerFactorizationInfo,3,
"Total factorizations with a large prime factor : ",
String(Length(FactoredLarge),10));
Info(IntegerFactorizationInfo,3,
"Relations with a large prime factor : ",
String(RelsLarge,10));
Info(IntegerFactorizationInfo,3,
"Relations remaining to be found : ",
String(Remaining,10));
Info(IntegerFactorizationInfo,3,
"Elapsed runtime : ",
String(UsedTime,10)," sec.");
Info(IntegerFactorizationInfo,3,
"Progress (relations) : ",
String(Progress,10)," %");
Info(IntegerFactorizationInfo,3,"");
Ak := Aj; Bk := Bj; Ck := Cj; Pk := Pj;
Aj := Ai; Bj := Bi; Cj := Ci; Pj := Pi;
until Length(Factored) + Length(RelationsLarge) >= Required;
# Create exponent matrix
Info(IntegerFactorizationInfo,2,"Creating the exponent matrix");
LeftMatrix := []; Cols := FactorBaseSize;
Factorizations := Concatenation(Factored,RelationsLarge);
Lines := Length(Factorizations);
for Line in [1..Lines] do
LeftMatrix [Line] := ListWithIdenticalEntries(Cols,zero);
CanonFact := Collected(Factorizations[Line][2]);
for i in [1..Length(CanonFact)] do
if CanonFact[i][2] mod 2 = 1
then LeftMatrix[Line]
[Position(FactorBase,CanonFact[i][1])] := one;
fi;
od;
od;
# Calculate X and Y such that X^2 = Y^2 mod n
# and check if 1 < gcd(X - Y,n) < n
Info(IntegerFactorizationInfo,2,"Processing the zero rows");
p := 1; FactorsFound := []; DependencyNr := 1; Line := 1; Ready := false;
while Line <= Length(RightMatrix) and not Ready do
X := 1; Y := 1;
for Col in [1..Lines] do
if RightMatrix[Line][Col] = one
then X := X * Factorizations[Col][1] mod n; fi;
od;
YQuadFactors :=
Collected(Concatenation(List(Filtered([1..Lines],
i->RightMatrix[Line][i] = one),
j->Factorizations[j][2])));
for i in [1..Length(YQuadFactors)] do
Y := Y * YQuadFactors[i][1]^(YQuadFactors[i][2]/2) mod n;
od;
if (X^2 - Y^2) mod n <> 0
then Error("Internal Error : X^2 - Y^2 mod n <> 0"); fi;
p := Gcd(X - Y,n/Multiplier);
if not p in [1,n/Multiplier]
then
Info(IntegerFactorizationInfo,2,
"Dependency no. ",DependencyNr," yielded factor ",p);
Add(FactorsFound,p); FactorsFound := Set(FactorsFound);
if FactorsTD(n/Multiplier,FactorsFound)[2] = []
then Ready := true; fi;
else
Info(IntegerFactorizationInfo,2,
"Dependency no. ",DependencyNr," yielded no factor");
fi;
Line := Line + 1;
DependencyNr := DependencyNr + 1;
od;
if FactorsFound = []
then Error("\nSorry, CFRAC has failed ...\n",
"Perhaps the continued fraction expansion of the square\n",
"root of the number you attempted to factor has properties\n",
"disadvantageous for obtaining a factorization\n",
"with this algorithm, try using the MPQS\n\n"); return [n]; fi;
Result := Flat(FactorsTD(n/Multiplier,FactorsFound));
local FactorsList, StandardFactorsList, m,
Ready, Pos, Passno;
if not (IsInt(n) and n > 1)
then Error("Usage : FactorsCFRAC( <n> ), ",
"where <n> has to be an integer > 1"); fi;
if ValueOption("NoPreprocessing") = true
then FactorsList := Flat(FactorsTD(n));
else Info(IntegerFactorizationInfo,2,
"Doing some preprocessing using Pollard's Rho");
FactorsList := Flat(FactorsRho(n,1,16,8192));
fi;
StandardFactorsList := [[],[]];
for m in FactorsList do
if IsProbablyPrimeInt(m) then Add(StandardFactorsList[1],m);
else Add(StandardFactorsList[2],m); fi;
od;
ApplyFactoringMethod(FactorsPowerCheck,[FactorsCFRAC,"FactorsCFRAC"],
StandardFactorsList,infinity);
FactorsList := Flat(StandardFactorsList);
for Pos in [1..Length(FactorsList)] do
if not IsProbablyPrimeInt(FactorsList[Pos])
then FactorsList[Pos] := CFRACSplit(FactorsList[Pos]); fi;
od;
FactorsList := Flat(FactorsList);
Ready := ForAll(FactorsList,IsProbablyPrimeInt);
until Ready;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.