KGC_TEST/miracl/source/kangaroo.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;
}