91 lines
2.6 KiB
C
91 lines
2.6 KiB
C
/*
|
|
* Test program to find discrete logarithms using Pollard's lambda method
|
|
* for catching kangaroos. This algorithm appears to be the best
|
|
* available for breaking the Diffie-Hellman key exchange algorithm and
|
|
* its variants
|
|
*
|
|
* See "Monte Carlo Methods for Index Computation"
|
|
* by J.M. Pollard in Math. Comp. Vol. 32 1978 pp 918-924
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "miracl.h"
|
|
|
|
#define LIMIT 100000000L
|
|
#define LEAPS 10000 /* = square root of LIMIT */
|
|
#define ALPHA 16 /* primitive root */
|
|
|
|
static char *modulus=
|
|
"295NZNjq8kIndq5Df0NDrA3qk4wxKpbXX4G5bC11A2lRKxcbnap2XDgE4X286glvmxDN66uSaeTjRMrelTY5WfLn";
|
|
|
|
int main()
|
|
{ /* Pollard's lambda algorithm for finding discrete logs *
|
|
* which are known to be less than a certain limit LIMIT */
|
|
big x,n,t,trap,table[32];
|
|
int i,j,m;
|
|
long dm,dn,s,distance[32];
|
|
miracl *mip=mirsys(50,0);
|
|
x=mirvar(0);
|
|
n=mirvar(0);
|
|
t=mirvar(0);
|
|
trap=mirvar(0);
|
|
for (s=1L,m=1;;m++)
|
|
{ /* find table size */
|
|
distance[m-1]=s;
|
|
s*=2;
|
|
if ((2*s/m)>(LEAPS/4)) break;
|
|
}
|
|
mip->IOBASE=60; /* get large modulus */
|
|
cinstr(n,modulus);
|
|
mip->IOBASE=10;
|
|
printf("solve discrete logarithm problem - using Pollard's kangaroos\n");
|
|
printf("finds x in y=%d^x mod n, given y, for fixed n and small x\n",ALPHA);
|
|
printf("known to be less than %ld\n",LIMIT);
|
|
printf("n= ");
|
|
cotnum(n,stdout);
|
|
for (i=0;i<m;i++)
|
|
{ /* create table */
|
|
lgconv(distance[i],t);
|
|
table[i]=mirvar(0);
|
|
powltr(ALPHA,t,n,table[i]);
|
|
}
|
|
lgconv(LIMIT,t);
|
|
powltr(ALPHA,t,n,x);
|
|
printf("setting trap .... \n");
|
|
for (dn=0L,j=0;j<LEAPS;j++)
|
|
{ /* set traps beyond LIMIT using tame kangaroo */
|
|
i=subdiv(x,m,t); /* random function */
|
|
mad(x,table[i],x,n,n,x);
|
|
dn+=distance[i];
|
|
}
|
|
printf("trap set!\n");
|
|
copy(x,trap);
|
|
forever
|
|
{ /* ready to solve */
|
|
printf("Enter x= ");
|
|
cinnum(x,stdin);
|
|
if (size(x)<=0) break;
|
|
powltr(ALPHA,x,n,t);
|
|
printf("y= ");
|
|
cotnum(t,stdout);
|
|
copy(t,x);
|
|
for (dm=0L;;)
|
|
{ /* unlease wild kangaroo - boing - boing ... */
|
|
i=subdiv(x,m,t);
|
|
mad(x,table[i],x,n,n,x);
|
|
dm+=distance[i];
|
|
if (mr_compare(x,trap)==0 || dm>LIMIT+dn) break;
|
|
}
|
|
if (dm>LIMIT+dn)
|
|
{ /* trap stepped over */
|
|
printf("trap failed\n");
|
|
continue;
|
|
}
|
|
printf("Gotcha!\n");
|
|
printf("Discrete log of y= %ld\n",LIMIT+dn-dm);
|
|
}
|
|
return 0;
|
|
}
|
|
|