www.pudn.com > miracl.zip > CONFIG.C
/* * MIRACL utility program to automatically generate a mirdef.h file * * config.c * * Compile WITHOUT any optimization * * Run this with your computer/compiler configuration. It will * attempt to create best-fit mirdef.h file for compiling the MIRACL * library. * * Generated are mirdef.tst - the suggested mirdef.h file, and * mirdef.lst which tells which modules should be included in the library * build. * * Copyright (c) 1994-2002 Shamus Software Ltd. */ #include#include #include static int answer(void) { char ch; scanf("%c",&ch); getchar(); if (ch=='Y' || ch=='y') return 1; return 0; } int main() { int chosen,utlen,dllen,flsh,stripped,standard,nofull,port,mant,r; int nbits,words,i,b,dlong,ibits,threaded,choice,selected,special; int chosen64,no64,step_size,double_type,rounding,lmant,dmant; int maxbase,end; char *ptr; char longlong[20],mfn[50]; double s,magic; double x,y,eps; long double lx,ly,leps; FILE *fp,*fpl; printf("This program attempts to generate a mirdef.h file from your\n"); printf("responses to some simple questions, and by some internal tests\n"); printf("of its own.\n\n"); printf("The most fundamental decision is that of the 'underlying type'\n"); printf("that is the C data type to be used to store each digit of a\n"); printf("big number. You input the number of bits in this type, and \n"); printf("this program finds a suitable candidate (usually short, int or \n"); printf("long). Typical values would be 16, 32 or perhaps 64. \n"); printf("The bigger the better, but a good starting point would be to\n"); printf("enter the native wordlength of your computer\n\n"); printf("For your information:-\n"); printf("The size of a short is %d bits\n",8*sizeof(short)); printf("The size of an int is %d bits\n",8*sizeof(int)); printf("The size of a long is %d bits\n",8*sizeof(long)); eps=1.0; for (dmant=0;;dmant++) { /* IMPORTANT TO FOOL OPTIMIZER!!!!!! */ x=1.0+eps; y=1.0; if (x==y) break; eps/=2.0; } printf("The size of a double is %d bits, its mantissa is %d bits\n",8*sizeof(double),dmant); leps=1.0; for (lmant=0;;lmant++) { /* IMPORTANT TO FOOL OPTIMIZER!!!!!! */ lx=1.0+leps; ly=1.0; if (lx==ly) break; leps/=2.0; } printf("The size of a long double is %d bits, its mantissa is %d bits\n",8*sizeof(long double),lmant); fp=fopen("mirdef.tst","w"); fprintf(fp,"/*\n * MIRACL compiler/hardware definitions - mirdef.h\n"); fprintf(fp," * Copyright (c) 1988-2002 Shamus Software Ltd.\n */\n\n"); end=1; ptr=(char *)(&end); if ((int)(*ptr) == 1) { printf("\n Little-endian processor detected\n\n"); fprintf(fp,"#define MR_LITTLE_ENDIAN\n"); } else { printf(" Big-endian processor detected\n\n"); fprintf(fp,"#define MR_BIG_ENDIAN\n"); } printf("A double can be used as the underlying type. In rare circumstances\n"); printf(" this may be optimal. Not recommended for beginners!\n\n"); printf("Do you wish to use a double as the underlying type? (Y/N)?"); double_type=answer(); nofull=0; chosen=0; chosen64=0; no64=0; if (double_type) { fprintf(fp,"#define MIRACL %d\n",8*sizeof(double)); fprintf(fp,"#define mr_utype double\n"); fprintf(fp,"#define mr_dltype long double\n"); fprintf(fp,"#define MR_NOFULLWIDTH\n"); fprintf(fp,"#define MR_FP\n"); nofull=1; } else { printf("\nNow enter number of bits in underlying type= "); scanf("%d",&utlen); getchar(); printf("\n"); if (utlen!=8 && utlen!=16 && utlen!=32 && utlen!=64) { printf("Non-standard system - this program cannot help!\n"); fclose(fp); exit(0); } fprintf(fp,"#define MIRACL %d\n",utlen); if (utlen==8) { printf(" underlying type is a char\n"); fprintf(fp,"#define mr_utype char\n"); chosen=1; } if (!chosen && utlen==8*sizeof(short)) { printf(" underlying type is a short\n"); fprintf(fp,"#define mr_utype short\n"); chosen=1; } if (!chosen && utlen==8*sizeof(int)) { printf(" underlying type is an int\n"); fprintf(fp,"#define mr_utype int\n"); chosen=1; } if (!chosen && utlen==8*sizeof(long)) { printf(" underlying type is a long\n"); fprintf(fp,"#define mr_utype long\n"); chosen=1; } dlong=0; if (!chosen && utlen==16*sizeof(long)) { printf("\nDoes compiler support a %d bit unsigned type? (Y/N)?", utlen); dlong=answer(); if (dlong) { printf("Is it called long long? (Y/N)?"); if (!answer()) { printf("Enter its name : "); scanf("%s",longlong); getchar(); } else strcpy(longlong,"long long"); printf(" underlying type is a %s\n",longlong); fprintf(fp,"#define mr_utype %s\n",longlong); chosen=1; if (64==utlen && !chosen64) { printf(" 64 bit unsigned type is an unsigned %s\n",longlong); fprintf(fp,"#define mr_unsign64 unsigned %s\n",longlong); chosen64=1; } } else { if (utlen==64) no64=1; /* there is no 64-bit type */ } } if (!chosen) { printf("No suitable underlying type could be found\n"); fclose(fp); exit(0); } } /* Now try to find a 32-bit unsigned type */ fprintf(fp,"#define MR_IBITS %d\n",8*sizeof(int)); fprintf(fp,"#define MR_LBITS %d\n",8*sizeof(long)); chosen=0; if (32==8*sizeof(unsigned short)) { printf(" 32 bit unsigned type is a unsigned short\n"); fprintf(fp,"#define mr_unsign32 unsigned short\n"); chosen=1; } if (!chosen && 32==8*sizeof(unsigned int)) { printf(" 32 bit unsigned type is an unsigned int\n"); fprintf(fp,"#define mr_unsign32 unsigned int\n"); chosen=1; } if (!chosen && 32==8*sizeof(long)) { printf(" 32 bit unsigned type is an unsigned long\n"); fprintf(fp,"#define mr_unsign32 unsigned long\n"); chosen=1; } if (!chosen) { printf("No suitable 32 bit unsigned type could be found\n"); fclose(fp); exit(0); } fpl=fopen("miracl.lst","w"); fprintf(fpl,"mrcore.c\n"); fprintf(fpl,"mrarth0.c\n"); fprintf(fpl,"mrarth1.c\n"); fprintf(fpl,"mrarth2.c\n"); fprintf(fpl,"mralloc.c\n"); fprintf(fpl,"mrsmall.c\n"); fprintf(fpl,"mrio1.c\n"); fprintf(fpl,"mrio2.c\n"); fprintf(fpl,"mrgcd.c\n"); fprintf(fpl,"mrjack.c\n"); fprintf(fpl,"mrxgcd.c\n"); fprintf(fpl,"mrarth3.c\n"); fprintf(fpl,"mrrand.c\n"); fprintf(fpl,"mrprime.c\n"); fprintf(fpl,"mrcrt.c\n"); fprintf(fpl,"mrscrt.c\n"); fprintf(fpl,"mrmonty.c\n"); fprintf(fpl,"mrpower.c\n"); fprintf(fpl,"mrcurve.c\n"); fprintf(fpl,"mrfast.c\n"); fprintf(fpl,"mrlucas.c\n"); fprintf(fpl,"mrshs.c\n"); fprintf(fpl,"mrshs256.c\n"); fprintf(fpl,"mraes.c\n"); fprintf(fpl,"mrstrong.c\n"); fprintf(fpl,"mrbrick.c\n"); fprintf(fpl,"mrebrick.c\n"); /* are some of the built-in types 64-bit? */ if (64==8*sizeof(int)) { printf(" 64 bit unsigned type is an unsigned int\n"); fprintf(fp,"#define mr_unsign64 unsigned int\n"); chosen64=1; } if (!chosen64 && 64==8*sizeof(long)) { printf(" 64 bit unsigned type is an unsigned long\n"); fprintf(fp,"#define mr_unsign64 unsigned long\n"); chosen64=1; } /* Now try to find a double length type */ dlong=0; if (!double_type) { dllen=2*utlen; chosen=0; if (!chosen && dllen==8*sizeof(short)) { printf(" double length type is a short\n"); fprintf(fp,"#define mr_dltype short\n"); chosen=1; } if (!chosen && dllen==8*sizeof(int)) { printf(" double length type is an int\n"); fprintf(fp,"#define mr_dltype int\n"); chosen=1; } if (!chosen && dllen==8*sizeof(long)) { printf(" double length type is a long\n"); fprintf(fp,"#define mr_dltype long\n"); chosen=1; } if (!chosen && dllen==16*sizeof(long)) { printf("\nDoes compiler support a %d bit integer type? (Y/N)?", dllen); dlong=answer(); if (dlong) { printf("Is it called long long? (Y/N)?"); if (!answer()) { printf("Enter its name : "); scanf("%s",longlong); getchar(); } else strcpy(longlong,"long long"); printf(" double length type is a %s\n",longlong); fprintf(fp,"#define mr_dltype %s\n",longlong); chosen=1; if (64==dllen && !chosen64) { printf(" 64 bit unsigned type is an unsigned %s\n",longlong); fprintf(fp,"#define mr_unsign64 unsigned %s\n",longlong); chosen64=1; } } else { if (dllen==64) no64=1; /* there is no 64-bit type */ } } } else dlong=1; if (!no64 && !chosen64) { /* Still no 64-bit type, but not ruled out either */ printf("\nDoes compiler support a 64-bit integer type? (Y/N)?"); dlong=answer(); if (dlong) { printf("Is it called long long? (Y/N)?"); if (!answer()) { printf("Enter its name : "); scanf("%s",longlong); getchar(); } else strcpy(longlong,"long long"); printf(" 64-bit type is a %s\n",longlong); fprintf(fp,"#define mr_unsign64 unsigned %s\n",longlong); chosen64=1; } } if (chosen64) fprintf(fpl,"mrshs512.c\n"); port=0; if (chosen) { printf("\nDo you want a C-only version of MIRACL (Y/N)?"); port=answer(); if (port) fprintf(fp,"#define MR_NOASM\n"); } rounding=0; if (double_type) { #ifdef __TURBOC__ rounding=1; #endif #ifdef _MSC_VER rounding=1; #endif #ifdef __GNUC__ rounding=1; #endif if (!rounding) { printf("It will help if rounding control can be exercised on doubles\n"); printf("Can you implement this in mrarth1.c?? (Y/N)?"); if (answer()) rounding=1; } if (rounding) { fprintf(fp,"#define MR_FP_ROUNDING\n"); magic=1.0; for (i=0;i 16) { printf("Enter step size = "); scanf("%d",&step_size); getchar(); } printf("\nTo create the file MRKCM.C you must next execute\n"); if (port) printf("MEX %d C MRKCM\n",step_size); else { printf("MEX %d MRKCM\n",step_size); printf("where is the name of the macro .mcs file (e.g. ms86)\n"); } printf("\nSpecial routines for modular multiplication will now be\n"); printf("automatically be invoked when, for example, powmod() is called\n"); printf("\nRemember to use a full-width base in your programs\n"); printf("by calling mirsys(..,0) or mirsys(..,256) at the start of the program\n"); fprintf(fp,"#define MR_KCM %d\n",step_size); fprintf(fpl,"mrkcm.c\n"); selected=1; } else { printf("\nDo you want to create a Comba fixed size modular\n"); printf("multiplier, for faster modular multiplication with\n"); printf("smaller moduli. Can generates a *lot* of code \n"); printf("Useful particularly for Elliptic Curve cryptosystems.\n"); printf("\nAnswer (Y/N)?"); r=answer(); if (r) { step_size=0; while (step_size<2 || step_size>32) { printf("Enter modulus size in bits = "); scanf("%d",&nbits); getchar(); step_size=nbits/utlen; if ((nbits%utlen)!=0) step_size++; } printf("Are you willing to implement a \"special\" fast method\n"); printf("for modular reduction, for a particular modulus\n"); printf("See mrcomba.tpl. If in any doubt answer No (Y/N)?"); r=answer(); if (r) { special=1; printf("\nYou must first edit the routine comba_redc() in MRCOMBA.TPL"); } printf("\nTo create the file MRCOMBA.C you must next execute\n"); if (port) printf("MEX %d C MRCOMBA\n",step_size); else { printf("MEX %d MRCOMBA\n",step_size); printf("where is the name of the macro .mcs file (e.g. ms86)\n"); } fprintf(fp,"#define MR_COMBA %d\n",step_size); if (special) fprintf(fp,"#define MR_SPECIAL\n"); fprintf(fpl,"mrcomba.c\n"); printf("\nSpecial routines for modular multiplication will now \n"); printf("automatically be invoked when, for example, powmod() is called\n"); printf("\nRemember to use a full-width base in your programs\n"); printf("by calling mirsys(..,0) or mirsys(,..,256) at the start of the program\n"); selected=1; } } } else { if (!double_type) fprintf(fp,"#define MAXBASE ((mr_small)1<<(MIRACL-2))\n"); } if (double_type) { maxbase=0; #ifdef __TURBOC__ if (!port && !selected) { printf("\nDoes your computer have a Pentium processor\n"); printf("and do you wish to exploit its built-in FP coprocessor\n"); printf("NOTE: this may not be optimal for Pentium Pro or Pentium II\n"); printf("Supported only for 80x86 processors, and Borland C Compilers\n"); printf("This is a little experimental - so use with care\n"); printf("Answer (Y/N)?"); r=answer(); if (r) { printf("Enter (maximum) modulus size in bits = "); scanf("%d",&nbits); getchar(); b=31; do { b--; r=64-b-b; s=1.0; for (i=0;i =lmant) break; s*=2.0; } fprintf(fp,"#define MAXBASE %lf\n",s); } } if (!port) { if (!dlong) printf("\nYou must now provide an assembly language file mrmuldv.c,\n"); else printf("\nYou must now provide an assembly or C file mrmuldv.c,\n"); if (!nofull) printf("containing implementations of muldiv(), muldvd(), muldvd2() and muldvm()\n"); else { printf("containing an implementation of muldiv()\n"); if (rounding) printf("..and imuldiv()\n"); } if (!dlong) printf("Check mrmuldv.any - an assembly language version may be\n"); else printf("Check mrmuldv.any - a C or assembly language version is\n"); printf("there already\n"); fprintf(fpl,"mrmuldv.c\n"); } printf("\nA file mirdef.tst has been generated. If you are happy with it,\n"); printf("rename it to mirdef.h and use for compiling the MIRACL library.\n"); printf("A file miracl.lst has been generated that includes all the \n"); printf("files to be included in this build of the MIRACL library.\n"); fprintf(fpl,"\nCompile the above with -O2 optimization\n"); if (threaded) fprintf(fpl,"Also use appropriate flag for multi-threaded compilation\n"); if (!port) { fprintf(fpl,"Note that mrmuldv.c file may be pure assembly, so may \n"); fprintf(fpl,"be renamed to mrmuldv.asm or mrmuldv.s, and assembled \n"); fprintf(fpl,"rather than compiled\n"); } fclose(fp); fclose(fpl); return 0; }