📄 dilog.java
字号:
nbrD = BigInteger.valueOf(d);
for (j=0; j<d; j++) {
if (powerPH.equals(bigNbrB2)) {break;}
bigNbrB2 = bigNbrB2.multiply(bigNbrA2).mod(modulus);
}
if (j==d) {
textExp.setText("Cannot compute discrete logarithm subgroup="+Primes[indexBase]+" exponent="+indexExp);
return;
}
Exponent = BigIntToBigNbr(nbrK).add(subGroupOrder.divide(nbrD).
multiply(BigInteger.valueOf(j)).mod(subGroupOrder));
}
runningExp = runningExp.add(Exponent.multiply(powSubGroupOrder));
powSubGroupOrder = powSubGroupOrder.multiply(subGroupOrder);
}
nbrV[indexBase] = runningExp;
for (indexExp=0; indexExp < indexBase; indexExp++) {
nbrV[indexBase] = nbrV[indexBase].subtract(nbrV[indexExp]).
multiply(Primes[indexExp].pow(Exponents[indexExp]).modInverse(powSubGroupOrder));
}
nbrV[indexBase] = nbrV[indexBase].mod(powSubGroupOrder);
logar = logar.add(nbrV[indexBase].multiply(logarMult));
logarMult = logarMult.multiply(powSubGroupOrder);
}
textExp.setText(logar.toString());
long t=OldTimeElapsed/1000;
labelStatus.setText("Time elapsed: "+
t/86400+"d "+(t%86400)/3600+"h "+((t%3600)/60)+"m "+(t%60)+
"s mod mult: "+lModularMult);
}
private void BigNbrToMont(BigInteger bigNbr, long [] nbr) {
byte [] Result;
int I,J;
long K,P;
Result = bigNbr.toByteArray();
J = 0;
K = 1;
P = 0;
for (I=Result.length-1; I>=0; I--) {
P += K*(long)(Result[I]>=0?Result[I]:Result[I]+256);
K *= 0x100;
if (K == DosALa32) {
CalcAuxModInvU[J] = P;
J++;
K = 1;
P = 0;
}
}
CalcAuxModInvU[J] = P;
for (J++; J<NumberLength; J++) {
CalcAuxModInvU[J] = 0;
}
MultBigNbrModN(CalcAuxModInvU, MontgomeryMultR1, nbr);
}
// nbr = (nbr * mult + add) % TestNbr
private void AdjustExponent(long [] nbr, long mult, long add) {
long Pr;
int j;
Pr = add * DosALa32;
for (j=0; j<NumberLength; j++) {
Pr = (Pr >>> 32) + mult*nbr[j];
nbr[j] = Pr & DosALa32_1;
}
nbr[j] = (Pr >>> 32);
AdjustModN(nbr);
}
private void ExchangeMods() {
long [] Tmp;
int Temp;
double dTemp;
Tmp = TestNbr;
TestNbr = TestNbrOther;
TestNbrOther = Tmp;
Temp = NumberLength;
NumberLength = NumberLengthOther;
NumberLengthOther = Temp;
dTemp = dN;
dN = dNOther;
dNOther = dTemp;
}
private long GetSmallFactors(BigInteger NumberToFactor, BigInteger PD[],
int Exp[], int Type) {
long Div,TestComp;
int i;
boolean checkExpParity = false;
BigNbrToBigInt(NumberToFactor);
NbrFactors = 0;
for (i=0; i<400; i++) {
Exp[i] = 0;
}
while ((TestNbr[0] & 1) == 0) { /* N even */
if (Exp[NbrFactors] == 0) {
PD[NbrFactors] = BigInt2;
}
Exp[NbrFactors]++;
DivBigNbrByLong(TestNbr,2,TestNbr);
}
if (Exp[NbrFactors] != 0) {NbrFactors++;}
while (RemDivBigNbrByLong(TestNbr,3)==0) {
if (Type == 1) {
checkExpParity = !checkExpParity;
}
if (Exp[NbrFactors] == 0) {
PD[NbrFactors] = BigInt3;
}
Exp[NbrFactors]++;
DivBigNbrByLong(TestNbr,3,TestNbr);
}
if (checkExpParity) {
return -1; /* Discard it */
}
if (Exp[NbrFactors] != 0) {NbrFactors++;}
Div = 5;
TestComp = TestNbr[0] + (TestNbr[1] << 32);
if (TestComp < 0) {
TestComp = 10000*DosALa32;
}
else {
for (i=2; i<NumberLength; i++) {
if (TestNbr[i] != 0) {
TestComp = 10000*DosALa32;
break;
}
}
}
while (Div < 131072) {
if (Div%3 != 0) {
while (RemDivBigNbrByLong(TestNbr,Div)==0) {
if (Type == 1 && Div%4 == 3) {
checkExpParity = !checkExpParity;
}
if (Exp[NbrFactors] == 0) {
PD[NbrFactors] = BigInteger.valueOf(Div);
}
Exp[NbrFactors]++;
DivBigNbrByLong(TestNbr,Div,TestNbr);
TestComp = TestNbr[0] + (TestNbr[1] << 32);
if (TestComp < 0) {
TestComp = 10000*DosALa32;
}
else {
for (i=2; i<NumberLength; i++) {
if (TestNbr[i] != 0) {
TestComp = 10000*DosALa32;
break;
}
}
} /* end while */
}
if (checkExpParity) {
return -1; /* Discard it */
}
if (Exp[NbrFactors] != 0) {NbrFactors++;}
}
Div += 2;
if (TestComp < Div*Div && TestComp != 1) {
if (Type == 1 && TestComp%4 == 3) {
return -1; /* Discard it */
}
if (Exp[NbrFactors] != 0) {NbrFactors++;}
PD[NbrFactors] = BigInteger.valueOf(TestComp);
Exp[NbrFactors] = 1;
TestComp = 1;
NbrFactors++;
break;
}
} /* end while */
return TestComp;
}
private void BigNbrToBigInt(BigInteger N) {
byte [] Result;
int I,J;
long K,P;
Result = N.toByteArray();
NumberLength = (Result.length+3)/4;
J = 0;
K = 1;
P = 0;
for (I=Result.length-1; I>=0; I--) {
P += K*(long)(Result[I]>=0?Result[I]:Result[I]+256);
K *= 0x100;
if (K == DosALa32) {
TestNbr[J] = P;
J++;
K = 1;
P = 0;
}
}
TestNbr[J] = P;
if (TestNbr[NumberLength-1] > Mi) {
TestNbr[NumberLength] = 0;
NumberLength++;
}
TestNbr[NumberLength] = 0;
}
private BigInteger BigIntToBigNbr(long [] GD) {
byte [] Result;
int I;
int NL;
NL = NumberLength*4;
Result = new byte[NL];
for (I=0;I<NumberLength;I++) {
Result[NL-1-4*I] = (byte)(GD[I] & 0xFF);
Result[NL-2-4*I] = (byte)(GD[I]/0x100 & 0xFF);
Result[NL-3-4*I] = (byte)(GD[I]/0x10000 & 0xFF);
Result[NL-4-4*I] = (byte)(GD[I]/0x1000000 & 0xFF);
}
return (new BigInteger(Result));
}
private void DivBigNbrByLong(long Dividend[], long Divisor, long Quotient[]) {
int i;
boolean ChSignDivisor=false;
long Divid, Rem = 0;
if (Divisor < 0) {
ChSignDivisor = true;
Divisor = -Divisor;
}
if (Dividend[NumberLength-1] >= DosALa31) {
Rem = Divisor - 1;
}
for (i=NumberLength-1; i>=0; i--) {
Divid = Dividend[i] + (Rem << 32);
Rem = Divid % Divisor;
Quotient[i] = Divid / Divisor;
}
if (ChSignDivisor) {
ChSignBigNbr(Quotient);
}
}
private long RemDivBigNbrByLong(long Dividend[], long Divisor) {
int i;
long Divid, Rem = 0;
if (Divisor < 0) {
Divisor = -Divisor;
}
if (Dividend[NumberLength-1] >= DosALa31) {
Rem = Divisor - 1;
}
for (i=NumberLength-1; i>=0; i--) {
Divid = Dividend[i] + (Rem << 32);
Rem = Divid % Divisor;
}
return Rem;
}
private void ChSignBigNbr(long Nbr[]) {
long Cy=0;
for(int i=0; i<NumberLength; i++) {
Cy -= Nbr[i];
Nbr[i]=(Cy>=0?Cy:Cy+DosALa32);
Cy=(Cy>=0?0:-1);
}
}
private void AddBigNbrModN(long Nbr1[], long Nbr2[], long Sum[]) {
long Cy=0;
int i;
for(i=0; i<NumberLength; i++) {
Cy += Nbr1[i]+Nbr2[i]-TestNbr[i];
Sum[i] = Cy & DosALa32_1;
Cy >>= 32;
}
if (Cy < 0) {
Cy = 0;
for(i=0; i<NumberLength; i++) {
Cy += Sum[i]+TestNbr[i];
Sum[i] = Cy & DosALa32_1;
Cy >>= 32;
}
}
}
private void SubtractBigNbrModN(long Nbr1[], long Nbr2[], long Diff[]) {
long Cy=0;
int i;
for(i=0; i<NumberLength; i++) {
Cy += Nbr1[i]-Nbr2[i];
Diff[i] = Cy & DosALa32_1;
Cy = (Cy>=0?0:-1);
}
if (Cy < 0) {
Cy = 0;
for(i=0; i<NumberLength; i++) {
Cy += Diff[i]+TestNbr[i];
Diff[i] = Cy & DosALa32_1;
Cy >>= 32;
}
}
}
private void MontgomeryMult(long Nbr1[], long Nbr2[], long Prod[]) {
int i,j;
long DosALa32_1 = this.DosALa32_1;
long Pr, Nbr, ProdB0;
long Prod0, Prod1, Prod2, Prod3, Prod4, Prod5, Prod6, Prod7;
long Prod8, Prod9, Prod10, Prod11, Prod12, Prod13, Prod14, Prod15;
long TestNbr0, TestNbr1, TestNbr2, TestNbr3, TestNbr4, TestNbr5, TestNbr6, TestNbr7;
long TestNbr8, TestNbr9, TestNbr10, TestNbr11, TestNbr12, TestNbr13, TestNbr14, TestNbr15;
long Nbr2_0, Nbr2_1, Nbr2_2, Nbr2_3, Nbr2_4, Nbr2_5, Nbr2_6, Nbr2_7;
long Nbr2_8, Nbr2_9, Nbr2_10, Nbr2_11, Nbr2_12, Nbr2_13, Nbr2_14, Nbr2_15;
long New;
String EcmInfo;
if (TerminateThread) {
throw new ArithmeticException();
}
if (lModularMult >= 0) {
lModularMult++;
if ((lModularMult % yieldFreq) == 0) {
calcThread.yield();
New=System.currentTimeMillis();
if (OldTimeElapsed >= 0 &&
OldTimeElapsed/1000 != (OldTimeElapsed + New - Old)/1000) {
OldTimeElapsed += New-Old;
Old = New;
long t=OldTimeElapsed/1000;
labelStatus.setText("Time elapsed: "+
t/86400+"d "+(t%86400)/3600+"h "+((t%3600)/60)+"m "+(t%60)+
"s mod mult: "+lModularMult);
}
}
}
TestNbr0 = TestNbr[0];
TestNbr1 = TestNbr[1];
switch (NumberLength) {
case 2:
Prod0 = Prod1 = 0;
Nbr2_0 = Nbr2[0];
Nbr2_1 = Nbr2[1];
i = 0;
do {
Nbr = Nbr1[i];
Pr = Nbr*Nbr2_0 + Prod0;
ProdB0 = Pr & DosALa32_1;
Pr = (Pr >>> 32) + Nbr*Nbr2_1 + Prod1;
Prod0 = Pr & DosALa32_1;
Prod1 = (Pr >>> 32);
Nbr = (ProdB0 * MontgomeryMultN) & DosALa32_1;
Pr = ((Nbr*TestNbr0 + ProdB0) >>> 32) + Nbr*TestNbr1 + Prod0;
Prod0 = Pr & DosALa32_1;
Prod1 += (Pr >>> 32);
i++;
} while (i<2);
if (Prod1 > TestNbr1 || Prod1 == TestNbr1 &&
(Prod0 >= TestNbr0)) {
Pr = Prod0 - TestNbr0;
Prod0 = Pr & DosALa32_1;
Pr = (Pr>=0?0:-1) + Prod1 - TestNbr1;
Prod1 = Pr & DosALa32_1;
}
Prod[0] = Prod0;
Prod[1] = Prod1;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -