KGC_TEST/KGC/miracl/source/irp.cpp

231 lines
5.1 KiB
C++

//
// Program to generate code for reduction modulo an irreducible trinomial or pentanomial
// over the field GF(2^m), m a prime
//
// cl /O2 /GX irp.cpp
//
// code is generated and can be cut-and-pasted into the function
// reduce2(.) in the MIRACL module mrgf2m.c
//
// To find a suitable irreducible polynomial, see the program findbase.cpp
//
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i,j,W,M,A,B,C,k1,k2,k3,k4,rs1,rs2,rs3,rs4,ls1,ls2,ls3,ls4;
int ind[64],shift[64][8],xxor,nxor,nsh;
argc--; argv++;
if (argc<3 || argc>5)
{
cout << "incorrect usage" << endl;
cout << "Program generates reduction code for given irreducible polynomial" << endl;
cout << "of the form x^M+x^A+1 or x^M+x^A+x^B+x^C+1 for odd M" << endl;
cout << "for a computer with wordlength W" << endl;
cout << "irp <W> <M> <A>" << endl;
cout << "OR" << endl;
cout << "irp <W> <M> <A> <B> <C>" << endl;
cout << "The code that is generated can be copied into the" << endl;
cout << "function reduce2 in the module mrgf2m.c" << endl;
return 0;
}
A=B=C=0;
W=atoi(argv[0]);
M=atoi(argv[1]);
A=atoi(argv[2]);
if (W<0 || W%8!=0 || A<1 || M-A < W) exit(0);
if (argc==5)
{
B=atoi(argv[3]);
C=atoi(argv[4]);
if (B<1 || C<1 || B>A || C>B) exit(0);
}
k1=1+M/W;
rs1=M%W;
ls1=W-rs1;
k2=1+(M-A)/W;
rs2=(M-A)%W;
ls2=W-rs2;
if (B)
{
k3=1+(M-B)/W;
rs3=(M-B)%W;
ls3=W-rs3;
k4=1+(M-C)/W;
rs4=(M-C)%W;
ls4=W-rs4;
}
for (i=0;i<64;i++) ind[i]=0;
if (rs1==0)
{
shift[k1-1][ind[k1-1]]=0;
ind[k1-1]++;
}
else
{
shift[k1-1][ind[k1-1]]=rs1;
ind[k1-1]++;
shift[k1][ind[k1]]=-ls1;
ind[k1]++;
}
if (rs2==0)
{
shift[k2-1][ind[k2-1]]=0;
ind[k2-1]++;
}
else
{
shift[k2-1][ind[k2-1]]=rs2;
ind[k2-1]++;
shift[k2][ind[k2]]=-ls2;
ind[k2]++;
}
if (B)
{
if (rs3==0)
{
shift[k3-1][ind[k3-1]]=0;
ind[k3-1]++;
}
else
{
shift[k3-1][ind[k3-1]]=rs3;
ind[k3-1]++;
shift[k3][ind[k3]]=-ls3;
ind[k3]++;
}
if (rs4==0)
{
shift[k4-1][ind[k4-1]]=0;
ind[k4-1]++;
}
else
{
shift[k4-1][ind[k4-1]]=rs4;
ind[k4-1]++;
shift[k4][ind[k4]]=-ls4;
ind[k4]++;
}
}
if (B) printf(" if (M==%d && A==%d && B==%d && C==%d)\n",M,A,B,C);
else printf(" if (M==%d && A==%d)\n",M,A);
printf(" {\n for (i=xl-1;i>=%d;i--)\n {\n",k1);
printf(" w=gx[i]; gx[i]=0;\n");
nxor=0; nsh=0;
for (i=0;i<64;i++)
{
if (ind[i]==0) continue;
nxor++;
printf(" gx[i-%d]^=",i);
xxor=0;
for (j=0;j<ind[i];j++)
{
if (xxor) printf("^");
if (shift[i][j]==0) {printf("w"); xxor++;}
if (shift[i][j]>0) {printf("(w>>%d)",shift[i][j]); xxor++; nsh++; }
if (shift[i][j]<0) {printf("(w<<%d)",-shift[i][j]); xxor++; nsh++;}
}
nxor+=(xxor-1);
printf(";\n");
}
printf(" } /* XORs= %d shifts= %d */\n",nxor,nsh);
printf(" top=gx[%d]>>%d; ",k1-1,rs1);
printf("gx[0]^=top; ");
printf("top<<=%d;\n",rs1);
for (i=0;i<64;i++) ind[i]=0;
if (rs2==0)
{
shift[k1-k2][ind[k1-k2]]=0;
ind[k1-k2]++;
}
else
{
shift[k1-k2][ind[k1-k2]]=rs2;
ind[k1-k2]++;
if (k1>k2)
{
shift[k1-k2-1][ind[k1-k2-1]]=-ls2;
ind[k1-k2-1]++;
}
}
if (B)
{
if (rs3==0)
{
shift[k1-k3][ind[k1-k3]]=0;
ind[k1-k3]++;
}
else
{
shift[k1-k3][ind[k1-k3]]=rs3;
ind[k1-k3]++;
if (k1>k3)
{
shift[k1-k3-1][ind[k1-k3-1]]=-ls3;
ind[k1-k3-1]++;
}
}
if (rs4==0)
{
shift[k1-k4][ind[k1-k4]]=0;
ind[k1-k4]++;
}
else
{
shift[k1-k4][ind[k1-k4]]=rs4;
ind[k1-k4]++;
if (k1>k4)
{
shift[k1-k4-1][ind[k1-k4-1]]=-ls4;
ind[k1-k4-1]++;
}
}
}
for (i=0;i<64;i++)
{
if (ind[i]==0) continue;
printf(" gx[%d]^=",i);
xxor=0;
for (j=0;j<ind[i];j++)
{
if (xxor) printf("^");
if (shift[i][j]==0) {printf("top"); xxor++;}
if (shift[i][j]>0) {printf("(top>>%d)",shift[i][j]); xxor++;}
if (shift[i][j]<0) {printf("(top<<%d)",-shift[i][j]); xxor++;}
}
printf(";\n");
}
printf(" gx[%d]^=top;\n",k1-1);
printf(" x->len=%d;\n",k1);
printf(" if (gx[%d]==0) mr_lzero(x);\n",k1-1);
printf(" return;\n }\n");
return 0;
}