KGC_TEST/KGC/miracl/source/curve/pairing/irred.cpp

459 lines
9.5 KiB
C++

/* program to find smallest irreducible polynomial */
/* cl /O2 /GX irred.cpp polymod.cpp poly.cpp big.cpp zzn.cpp miracl.lib
*/
#include <iostream>
#include <fstream>
#include <cstring>
#include "polymod.h"
using namespace std;
Miracl precision=200;
// Code to parse formula in command line
// This code isn't mine, but its public domain
// Shamefully I forget the source
//
// NOTE: It may be necessary on some platforms to change the operators * and #
//
#if defined(unix)
#define TIMES '.'
#define RAISE '^'
#else
#define TIMES '*'
#define RAISE '#'
#endif
Big tt;
static char *ss;
void eval_power (Big& oldn,Big& n,char op)
{
if (op) n=pow(oldn,toint(n)); // power(oldn,size(n),n,n);
}
void eval_product (Big& oldn,Big& n,char op)
{
switch (op)
{
case TIMES:
n*=oldn;
break;
case '/':
n=oldn/n;
break;
case '%':
n=oldn%n;
}
}
void eval_sum (Big& oldn,Big& n,char op)
{
switch (op)
{
case '+':
n+=oldn;
break;
case '-':
n=oldn-n;
}
}
void eval (void)
{
Big oldn[3];
Big n;
int i;
char oldop[3];
char op;
char minus;
for (i=0;i<3;i++)
{
oldop[i]=0;
}
LOOP:
while (*ss==' ')
ss++;
if (*ss=='-') /* Unary minus */
{
ss++;
minus=1;
}
else
minus=0;
while (*ss==' ')
ss++;
if (*ss=='(' || *ss=='[' || *ss=='{') /* Number is subexpression */
{
ss++;
eval ();
n=tt;
}
else /* Number is decimal value */
{
for (i=0;ss[i]>='0' && ss[i]<='9';i++)
;
if (!i) /* No digits found */
{
cout << "Error - invalid number" << endl;
exit (20);
}
op=ss[i];
ss[i]=0;
n=atoi(ss);
ss+=i;
*ss=op;
}
if (minus) n=-n;
do
op=*ss++;
while (op==' ');
if (op==0 || op==')' || op==']' || op=='}')
{
eval_power (oldn[2],n,oldop[2]);
eval_product (oldn[1],n,oldop[1]);
eval_sum (oldn[0],n,oldop[0]);
tt=n;
return;
}
else
{
if (op==RAISE)
{
eval_power (oldn[2],n,oldop[2]);
oldn[2]=n;
oldop[2]=RAISE;
}
else
{
if (op==TIMES || op=='/' || op=='%')
{
eval_power (oldn[2],n,oldop[2]);
oldop[2]=0;
eval_product (oldn[1],n,oldop[1]);
oldn[1]=n;
oldop[1]=op;
}
else
{
if (op=='+' || op=='-')
{
eval_power (oldn[2],n,oldop[2]);
oldop[2]=0;
eval_product (oldn[1],n,oldop[1]);
oldop[1]=0;
eval_sum (oldn[0],n,oldop[0]);
oldn[0]=n;
oldop[0]=op;
}
else /* Error - invalid operator */
{
cout << "Error - invalid operator" << endl;
exit (20);
}
}
}
}
goto LOOP;
}
int main(int argc,char ** argv)
{
ofstream ofile;
int ip,i,j,k,m,s,M,Base;
BOOL gotP,ir,fout,first,binomial;
Big w,p,t,xx[16];
miracl *mip=&precision;
argc--; argv++;
if (argc<1)
{
cout << "incorrect usage" << endl;
cout << "Program finds simplest irreducible polynomial with respect" << endl;
cout << "to a given prime modulus, of the form x^k+x^2+n" << endl;
cout << "irred <prime modulus P> <M>" << endl;
cout << "OR" << endl;
cout << "irred <formula for P> <M>" << endl;
cout << "To insist on a binomial, use -b" << endl;
cout << "To input P in Hex, precede with -h" << endl;
cout << "To output to a file, use flag -o <filename>" << endl;
#if defined(unix)
cout << "e.g. irred -f 2^192-2^64-1 6 -o zzn6.dat" << endl;
#else
cout << "e.g. irred -f 2#192-2#64-1 6 -o zzn6.dat" << endl;
#endif
return 0;
}
fout=FALSE;
Base=10;
ip=0;
M=0;
gotP=FALSE;
binomial=FALSE;
while (ip<argc)
{
if (!gotP && strcmp(argv[ip],"-f")==0)
{
ip++;
if (!gotP && ip<argc)
{
ss=argv[ip++];
tt=0;
eval();
p=tt;
gotP=TRUE;
continue;
}
else
{
cout << "Error in command line" << endl;
return 0;
}
}
if (strcmp(argv[ip],"-o")==0)
{
ip++;
if (ip<argc)
{
fout=TRUE;
ofile.open(argv[ip++]);
continue;
}
else
{
cout << "Error in command line" << endl;
return 0;
}
}
if (strcmp(argv[ip],"-h")==0)
{
ip++;
Base=16;
continue;
}
if (strcmp(argv[ip],"-b")==0)
{
ip++;
binomial=TRUE;
continue;
}
if (!gotP)
{
mip->IOBASE=Base;
p=argv[ip++];
mip->IOBASE=10;
gotP=TRUE;
continue;
}
if (gotP)
{
M=atoi(argv[ip++]);
continue;
}
cout << "Error in command line" << endl;
return 0;
}
if (!gotP || M<2)
{
cout << "Error in command line" << endl;
return 0;
}
if (!prime(p))
{
cout << "This number is not prime!" << endl;
exit(0);
}
if (M>36)
{
cout << "M is too big!" << endl;
exit(0);
}
//forever
//{
modulo(p);
cout << "p%24= " << p%24 << endl;
if (M==2) binomial=TRUE;
PolyMod h,g,x;
Poly f;
int ns=0;
x.addterm(1,1);
i=1;
j=2; m=1; first=FALSE;
if (M==12) j=4;
//j=2; m=-1;
forever
{
g=x;
f.clear();
f.addterm(i,0);
if (!binomial) f.addterm(m,j);
f.addterm(1,M);
// cout << f << endl;
setmod(f);
/*
ir=TRUE;
for (k=1;k<=M;k++)
{
g=pow(g,p);
if (k==M) break;
if (k>1 && prime((Big)k) && M%k==0)
{
h=gcd(g-x);
if (!isone(h))
{
cout << "k= " << k << endl;
cout << "h= " << h << endl;
ir=FALSE;
break;
}
}
}
if (ir)
{
if (!iszero(g-x)) ir=FALSE;
break;
}
if (ir) break;
*/
ir=TRUE;
// Ben-Or irreducibility test
for (k=1;k<=M/2;k++)
{
g=pow(g,p);
h=gcd(g-x);
if (!isone(h))
{
ir=FALSE;
break;
}
}
if (ir)
{
cout << "\nirreducible polynomial P(x) = " << f ;
ns++;
if (ns==10) break;
// break;
}
if (first)
{
if (!binomial)
{
if (m==1)
{
m=-1;
continue;
}
m=1;
}
j=j+1;
if (j==M)
{
j=1;
if (i<0) first=FALSE;
else i=-1;
}
continue;
}
//cout << "\ni= " << i << endl;
if (i>0) i=(-i);
else { i=(-i); i++; }
}
//cout << "p= " << p;
//cout << " irreducible polynomial P(x) = " << f << endl;
// cout << "\nirreducible polynomial P(x) = " << f << endl << endl;
if (fout)
{
ofile << i << endl;
if (binomial) ofile << 0 << endl;
else ofile << j << endl;
}
g=x;
g=pow(g,p);
if (fout)
for (i=0;i<M;i++) ofile << g.coeff(i) << endl;
for (j=2;j<M;j++)
for (i=0;i<M;i++) ofile << pow(g,j).coeff(i) << endl;
s=0; // HAC 3.34 Step 3
t=pow(p,M)-1;
while (t%2==0) { t/=2; s++; }
if (fout) ofile << s << endl;
w=t;
for (i=0;i<M;i++)
{
if (fout) ofile << w%p << endl;
w/=p;
}
w=(t+1)/2;
for (i=0;i<M;i++)
{
if (fout) ofile << w%p << endl;
w/=p;
}
//p+=8;
//while (!prime(p)) p+=8;
//}
/*
for (i=1;i<6;i++)
{
cout << i << "*p^2 should be x^" << i << " is " << pow(x,i*p*p) << endl;
}
for (i=1;i<6;i++)
{
cout << i << "*p^3 should be x^" << i << " is " << pow(x,i*p*p*p) << endl;
}
for (i=1;i<8;i++)
{
cout << i << "*p^4 should be x^" << i << " is " << pow(x,i*p*p*p*p) << endl;
}
for (i=1;i<10;i++)
{
cout << i << "*p^5 should be x^" << i << " is " << pow(x,i*p*p*p*p*p) << endl;
}
for (i=1;i<12;i++)
{
cout << i << "*p^6 should be x^" << i << " is " << pow(x,i*p*p*p*p*p*p) << endl;
}
*/
return 0;
}