The termination of the loop is a consequence of $\lfloor n/2^k\rfloor \rightarrow 0$ after
finitely many steps, i.e. there exists $k\in\mathbb{N}$ such that $\lfloor n/2^k\rfloor = 0$.
\newpage
-\subsection{The RISCAL Formalization}
+\subsection*{The RISCAL Formalization}
{\scriptsize \verbatimboxed{../lefttoright.txt}}
\subsection{Computing Integer Roots}
$$
hence we have shown $x^2\leq a < (x+1)^2$, and taking square roots shows the claim.
\newpage
-\subsection{The RISCAL Formalization}
+\subsection*{The RISCAL Formalization}
%{\scriptsize \verbatiminput{../integerroot.txt}}
{\scriptsize \verbatimboxed{../integerroot.txt}}
\appendix
}
t = locpm1;
- cout << "Express p-1 = " << p-1 << " as 2^" << s << "*" << t << endl;
+// cout << "Express p-1 = " << p-1 << " as 2^" << s << "*" << t << endl;
unsigned long* e = new unsigned long[s];
e[0] = 0;
xGCD(g,p,u,v);
gi = fmod(u,p)+p;
- cout << "So far we got: t=" << t << " and s=" << 2 << " and gi=" << gi << endl;
+// cout << "So far we got: t=" << t << " and s=" << 2 << " and gi=" << gi << endl;
for(long i=1;i<s;i++)
{
tmp = a*pow(gi,e[i-1]);
- cout << "tmp: " << tmp << endl;
+// cout << "tmp: " << tmp << endl;
tmp = pow(tmp,(p-1)/pow(2,i+1));
- cout << "tmp: " << tmp << endl;
+// cout << "tmp: " << tmp << endl;
if(fmod(tmp,p) != 1)
e[i] = pow(2,i)+e[i-1];
else
e[i] = e[i-1];
}
- cout << "we got e:" << e[0] << " and " << e[1] << endl;
+// cout << "we got e:" << e[0] << " and " << e[1] << endl;
tmp = fmod(a*pow(gi,e[s-1]), p);
- cout << "tmp: " << tmp << endl;
+// cout << "tmp: " << tmp << endl;
tmp = fmod(g*pow(tmp,(t+1)/2),p);
- cout << "tmp: " << tmp << endl;
+ cout << "Computed Solution: " << tmp << endl;
}
+void discrete_log(long p, long g, long a)
+{
+ long m = -floor(-sqrt(p-1));
+ cout << "So far we got: m=" << m << endl;
+ long *A = new long[m];
+ long *b = new long[m];
+
+ A[0] = 1;
+ b[0] = a;
+
+ for(int i=1;i<m;i++)
+ {
+ A[i] = fmod(g*A[i-1],p);
+ }
+
+ cout << "So far we got: " << endl;
+ for(int i=0;i<m;i++)
+ {
+ cout << "A[" << i << "] = " << A[i] << "; ";
+ }
+ cout << endl;
+
+ long gi, s;
+ xGCD(g,p,gi,s);
+ gi = gi%p;
+ cout << "We got: gi=" << gi << endl;
+
+ long gim = 1;
+
+ for(int i=0;i<m;i++)
+ gim = ((gim * gi) %p);
+ cout << "We got: gim=" << gim << endl;
+
+ for(int i=0;i<m;i++)
+ {
+ for(int j=0;j<m;j++)
+ {
+ if(A[j] == b[i])
+ {
+ cout << "We got: i=" << i << " and j=" << j << endl;
+ cout << "This gives the discrete logarithm: " << i*m + j << endl;
+ }
+ }
+ b[i+1] = b[i]*gim % p;
+ }
+
+
+}
+
+
int main(int argc, char** argv)
{
if(argc == 1)
cout << "Algorithm A: Trial division" << endl;
cout << "Algorithm C: Fermat like factorization" << endl;
cout << "Algorithm D: Tonelli's Algorithm" << endl;
+ cout << "Algorithm E: Discrete Logarithm" << endl;
cin >> input;
cout << endl;
- }while((input != 'A') && (input != 'C') && (input != 'D') );
+ }while((input != 'A') && (input != 'C') && (input != 'D') && (input != 'E') );
switch(input)
{
}
case 'D':
{
- cout << "Algorithm of Tonelli" << endl;
+// cout << "Algorithm of Tonelli" << endl;
tonelli(10,2,13);
break;
}
+ case 'E':
+ {
+ // cout << "Algorithm of Tonelli" << endl;
+ discrete_log(113, 3, 57);
+ break;
+ }
default:
break;
}