/*************************************************************************** * Copyright 2013 CertiVox UK Ltd. * * This file is part of CertiVox MIRACL Crypto SDK. * * The CertiVox MIRACL Crypto SDK provides developers with an * extensive and efficient set of cryptographic functions. * For further information about its features and functionalities please * refer to http://www.certivox.com * * * The CertiVox MIRACL Crypto SDK is free software: you can * redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the * Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * * The CertiVox MIRACL Crypto SDK is distributed in the hope * that it will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * * * You should have received a copy of the GNU Affero General Public * License along with CertiVox MIRACL Crypto SDK. * If not, see . * * You can be released from the requirements of the license by purchasing * a commercial license. Buying such a license is mandatory as soon as you * develop commercial activities involving the CertiVox MIRACL Crypto SDK * without disclosing the source code of your own applications, or shipping * the CertiVox MIRACL Crypto SDK with a closed source product. * * ***************************************************************************/ /* * 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 * miracl.lst which tells which modules should be included in the library * build. */ #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,chosen2,utlen,dllen,flsh,stripped,standard,nofull,port,mant,r,userlen; int nbits,i,b,dlong,threaded,choice,selected,special,sb,ab; int chosen64,no64,step_size,double_type,rounding,lmant,dmant,static_build,maxsize; int maxbase,bitsinchar,llsize,nio,edwards,double_length_type; int qlong,qllen; long end; unsigned char byte; char *ptr; char longlong[20]; double s,magic; double x,y,eps; long double lx,ly,leps; FILE *fp,*fpl; bitsinchar=0; byte=1; while (byte!=0) {byte<<=1; bitsinchar++;} 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 char is %d bits\n",bitsinchar); printf("The size of a short is %d bits\n",bitsinchar*sizeof(short)); printf("The size of an int is %d bits\n",bitsinchar*sizeof(int)); printf("The size of a long is %d bits\n",bitsinchar*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",bitsinchar*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",bitsinchar*sizeof(long double),lmant); fp=fopen("mirdef.tst","wt"); fprintf(fp,"/*\n * MIRACL compiler/hardware definitions - mirdef.h\n */\n"); end=1; ptr=(char *)(&end); if ((*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!\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; llsize=-1; /* no check for long long yet */ no64=0; if (double_type) { fprintf(fp,"#define MIRACL %d\n",bitsinchar*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==bitsinchar) { printf(" underlying type is a char\n"); fprintf(fp,"#define mr_utype char\n"); chosen=1; } if (!chosen && utlen==bitsinchar*sizeof(short)) { printf(" underlying type is a short\n"); fprintf(fp,"#define mr_utype short\n"); chosen=1; } if (!chosen && utlen==bitsinchar*sizeof(int)) { printf(" underlying type is an int\n"); fprintf(fp,"#define mr_utype int\n"); chosen=1; } if (!chosen && utlen==bitsinchar*sizeof(long)) { printf(" underlying type is a long\n"); fprintf(fp,"#define mr_utype long\n"); chosen=1; } dlong=0; if (!chosen && utlen==2*bitsinchar*sizeof(long)) { printf("\nDoes compiler support a %d bit unsigned type? (Y/N)?", utlen); dlong=answer(); if (dlong) { llsize=utlen; /* there is a long long */ 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 { llsize=0; /* there is no long long */ 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); } } fprintf(fp,"#define MR_IBITS %d\n",bitsinchar*sizeof(int)); fprintf(fp,"#define MR_LBITS %d\n",bitsinchar*sizeof(long)); /* Now try to find 32-bit unsigned types */ chosen=0; if (32==bitsinchar*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==bitsinchar*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==bitsinchar*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); } /* are some of the built-in types 64-bit? */ if (64==bitsinchar*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==bitsinchar*sizeof(long)) { printf(" 64 bit unsigned type is an unsigned long\n"); fprintf(fp,"#define mr_unsign64 unsigned long\n"); chosen64=1; } if (!chosen64 && llsize>0 && 64==llsize) { printf(" 64 bit unsigned type is a %s\n",longlong); fprintf(fp,"#define mr_unsign64 %s\n",longlong); chosen64=1; } /* Now try to find a double length type */ dlong=0; dllen=0; double_length_type=0; if (!double_type) { dllen=2*utlen; chosen=0; if (!chosen && dllen==bitsinchar*sizeof(short)) { printf(" double length type is a short\n"); fprintf(fp,"#define mr_dltype short\n"); double_length_type=1; if (sizeof(short)==sizeof(int)) fprintf(fp,"#define MR_DLTYPE_IS_INT\n"); chosen=1; } if (!chosen && dllen==bitsinchar*sizeof(int)) { printf(" double length type is an int\n"); fprintf(fp,"#define mr_dltype int\n"); double_length_type=1; fprintf(fp,"#define MR_DLTYPE_IS_INT\n"); chosen=1; } if (!chosen && dllen==bitsinchar*sizeof(long)) { printf(" double length type is a long\n"); fprintf(fp,"#define mr_dltype long\n"); double_length_type=1; fprintf(fp,"#define MR_DLTYPE_IS_LONG\n"); chosen=1; } if (!chosen && llsize>0 && dllen==llsize) { printf(" double length type is a %s\n",longlong); fprintf(fp,"#define mr_dltype %s\n",longlong); double_length_type=1; chosen=1; } if (!chosen && dllen==2*bitsinchar*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); double_length_type=1; 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; /* Now try to find a double length type */ qlong=0; if (!double_type) { qllen=4*utlen; chosen2=0; if (!chosen2 && qllen==bitsinchar*sizeof(long)) { printf(" quad length type is a long\n"); fprintf(fp,"#define mr_qltype long\n"); chosen2=1; } if (!chosen2 && llsize>0 && dllen==llsize) { printf(" quad length type is a %s\n",longlong); fprintf(fp,"#define mr_qltype %s\n",longlong); chosen2=1; } if (!chosen2 && qllen==2*bitsinchar*sizeof(long)) { printf("\nDoes compiler support a %d bit integer type? (Y/N)?", qllen); qlong=answer(); if (qlong) { printf("Is it called long long? (Y/N)?"); if (!answer()) { printf("Enter its name : "); scanf("%s",longlong); getchar(); } else strcpy(longlong,"long long"); printf(" quad length type is a %s\n",longlong); fprintf(fp,"#define mr_qltype %s\n",longlong); chosen2=1; if (64==qllen && !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 (qllen==64) no64=1; /* there is no 64-bit type */ } } } else qlong=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; } } fpl=fopen("miracl.lst","wt"); ab=0; static_build=0; if (!double_type) { printf("\nFor very constrained environments it is possible to build a version of MIRACL\n"); printf("which does not require a heap. Not recommended for beginners.\n"); printf("Some routines are not available in this mode and the max length of Big\n"); printf("variables is fixed at compile time\n"); printf("Do you want a no-heap version of the MIRACL C library? (Y/N)? "); static_build=answer(); if (static_build) { printf("Please enter the max size of your Big numbers in bits= "); scanf("%d",&nbits); getchar(); maxsize=nbits/utlen; if ((nbits%utlen)!=0) maxsize++; fprintf(fp,"#define MR_STATIC %d\n",maxsize); fprintf(fp,"#define MR_ALWAYS_BINARY\n"); ab=1; } } fprintf(fpl,"mrcore.c\n"); fprintf(fpl,"mrarth0.c\n"); fprintf(fpl,"mrarth1.c\n"); fprintf(fpl,"mrarth2.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,"mrbits.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,"mrsroot.c\n"); fprintf(fpl,"mrlucas.c\n"); fprintf(fpl,"mrshs.c\n"); fprintf(fpl,"mrshs256.c\n"); fprintf(fpl,"mraes.c\n"); fprintf(fpl,"mrgcm.c\n"); fprintf(fpl,"mrfpe.c\n"); fprintf(fpl,"mrstrong.c\n"); fprintf(fpl,"mrcurve.c\n"); fprintf(fpl,"mrbrick.c\n"); fprintf(fpl,"mrebrick.c\n"); fprintf(fpl,"mrzzn2.c\n"); fprintf(fpl,"mrzzn2b.c\n"); fprintf(fpl,"mrzzn3.c\n"); fprintf(fpl,"mrecn2.c\n"); if (!static_build) { fprintf(fpl,"mrfast.c\n"); fprintf(fpl,"mralloc.c\n"); } if (chosen64) { fprintf(fpl,"mrshs512.c\n"); fprintf(fpl,"mrsha3.c\n"); } port=0; if (chosen && double_length_type) { 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;i32) { printf("Enter field size in bits = "); scanf("%d",&nbits); getchar(); step_size=nbits/utlen; if ((nbits%utlen)!=0) step_size++; } printf("\nTo create the file MRCOMBA2.C you must next execute\n"); if (port) printf("MEX %d C MRCOMBA2\n",step_size); else { printf("MEX %d MRCOMBA2\n",step_size); printf("where is the name of the macro .mcs file (e.g. smartmips)\n"); } fprintf(fp,"#define MR_COMBA2 %d\n",step_size); fprintf(fpl,"mrcomba2.c\n"); printf("\nSpecial routines for polynomial multiplication will now \n"); printf("automatically be invoked \n"); } fprintf(fp,"#define MAXBASE ((mr_small)1<<(MIRACL-1))\n"); } else { if (!double_type) fprintf(fp,"#define MAXBASE ((mr_small)1<<(MIRACL-2))\n"); } printf("\nDo you wish to use the Karatsuba/Comba/Montgomery method\n"); printf("for modular arithmetic - as used by exponentiation\n"); printf("cryptosystems like RSA.\n"); if (port) { printf("This method may be faster than the standard method when\n"); printf("using larger moduli, or if your processor has no \n"); printf("unsigned integer multiply/divide instruction in its\n"); printf("instruction set. This is true of some popular RISC computers\n"); } else { printf("This method is probably fastest om most processors which\n"); printf("which support unsigned mul and a carry flag\n"); printf("NOTE: your compiler must support in-line assembly,\n"); printf("and you must be able to supply a suitable .mcs file\n"); printf("like, for example, ms86.mcs for pentium processors\n"); } printf("\nAnswer (Y/N)?"); r=answer(); if (r) { printf("\nThis method can only be used with moduli whose length in\n"); printf("bits can be represented as %d*(step size)*2^n, for any value\n",utlen); printf("of n. For example if you input a step size of 8, then \n"); printf("moduli of 256, 512, 1024 bits etc will use this fast code\n"); if (nofull) printf("(assuming a full-length base)\n"); if (port) printf("In this case case a step size of about 4 is probably optimal\n"); else { printf("The best step size can be determined by experiment, but\n"); printf("larger step sizes generate more code. For the Pentium 8 is \n"); printf("about optimal. For the Pentium Pro/Pentium II 16 is better.\n"); if (!nofull) printf("If in doubt, set to 8\n"); } step_size=0; while (step_size<2 || step_size>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 generate a lot of code \n"); printf("Useful particularly for Elliptic Curve cryptosystems over GF(p).\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(); if (nofull) { printf("Enter base size in bits = "); scanf("%d",&userlen); getchar(); } else userlen=utlen; step_size=nbits/userlen; if ((nbits%userlen)!=0) step_size++; } if (!nofull && (nbits%utlen)==0) { printf("\nDo you wish to use a \"special\" fast method\n"); printf("for modular reduction, for a particular modulus\n"); printf("Two types are supported - Generalised Mersenne Primes\n"); printf("also known as Solinas primes\n"); printf("(many already supported - easy to add more - see mrcomba.tpl)\n"); printf("and Pseudo Mersenne Primes (automatically supported)\n"); printf("If in any doubt answer No (Y/N)?"); r=answer(); if (r) { special=1; printf("\nIs your modulus a Generalized Mersenne Prime (Y/N)?"); r=answer(); if (r) special=1; else { printf("\nIs your modulus a \"Pseudo Mersenne\" Prime of the form\n"); printf("2^%d-c where c fits in a single word (Y/N)?",nbits); r=answer(); if (r) special=2; } } } 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"); if (special==1) fprintf(fp,"#define MR_GENERALIZED_MERSENNE\n"); if (special==2) fprintf(fp,"#define MR_PSEUDO_MERSENNE\n"); if (special) fprintf(fp,"#define MR_NO_LAZY_REDUCTION\n"); fprintf(fpl,"mrcomba.c\n"); printf("\nSpecial routines for modular multiplication will now \n"); printf("automatically be invoked for this modulus\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; } } 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); } } fprintf(fp,"#define MR_BITSINCHAR %d\n",bitsinchar); printf("\nDo you want to save space by using a smaller but slightly slower \n"); printf("AES implementation. Default to No. (Y/N)?"); r=answer(); if (r) { fprintf(fp,"#define MR_SMALL_AES\n"); } edwards=0; printf("\nDo you want to use Edwards paramaterization of elliptic curves over Fp\n"); printf("This is faster for basic Elliptic Curve cryptography (but does not support\n"); printf("Pairing-based Cryptography and some applications). Default to No. (Y/N)?"); r=answer(); if (r) { edwards=1; fprintf(fp,"#define MR_EDWARDS\n"); } if (!edwards) { printf("\nDo you want to save space by using only affine coordinates \n"); printf("for elliptic curve cryptography. Default to No. (Y/N)?"); r=answer(); if (r) { fprintf(fp,"#define MR_AFFINE_ONLY\n"); } } printf("\nDo you want to save space by not using point compression \n"); printf("for EC(p) elliptic curve cryptography. Default to No. (Y/N)?"); r=answer(); if (r) fprintf(fp,"#define MR_NOSUPPORT_COMPRESSION\n"); printf("\nDo you want to save space by not supporting special code \n"); printf("for EC double-addition, as required for ECDSA signature \n"); printf("verification, or any multi-addition of points. Default to No. (Y/N)?"); r=answer(); if (r) fprintf(fp,"#define MR_NO_ECC_MULTIADD\n"); printf("\nDo you want to save RAM by using a smaller sliding window \n"); printf("for all elliptic curve cryptography. Default to No. (Y/N)?"); r=answer(); if (r) fprintf(fp,"#define MR_SMALL_EWINDOW\n"); if (!special) { printf("\nDo you want to save some space by supressing Lazy Reduction? \n"); printf("(as used for ZZn2 arithmetic). Default to No. (Y/N)?"); r=answer(); if (r) fprintf(fp,"#define MR_NO_LAZY_REDUCTION\n"); } printf("\nDo you NOT want to use the built in random number generator?\n"); printf("Removing it saves space, and maybe you have your own source\n"); printf("of randomness? Default to No. (Y/N)?"); r=answer(); if (r) fprintf(fp,"#define MR_NO_RAND\n"); sb=0; if (!nofull && ab) { printf("\nDo you want to save space by only using a simple number base?\n"); printf("(the number base in mirsys(.) must be 0 or must divide 2^U\n"); printf("exactly, where U is number of bits in the underlying type)\n"); printf("NOTE: no number base changes possible\n"); printf("Default to No. (Y/N)?"); r=answer(); if (r) { sb=1; fprintf(fp,"#define MR_SIMPLE_BASE\n"); } } if (sb) { printf("\nDo you want to save space by only using simple I/O? \n"); printf("(Input from ROM, and Input/Output as binary bytes only) \n"); printf("(However crude HEX-only output is supported) \n"); printf("Default to No. (Y/N)?"); r=answer(); if (r) fprintf(fp,"#define MR_SIMPLE_IO\n"); } if (!double_type) { printf("\nDo you want to save space by NOT supporting KOBLITZ curves \n"); printf("for EC(2^m) elliptic curve cryptography. Default to No. (Y/N)?"); r=answer(); if (r) fprintf(fp,"#define MR_NOKOBLITZ\n"); printf("\nDo you want to save space by NOT supporting SUPERSINGULAR curves \n"); printf("for EC(2^m) elliptic curve cryptography. Default to No. (Y/N)?"); r=answer(); if (r) { fprintf(fp,"#define MR_NO_SS\n"); } } printf("\nDo you want to enable a Double Precision big type. See doubig.txt\n"); printf("for more information. Default to No. (Y/N)?"); r=answer(); if (r) { fprintf(fp,"#define MR_DOUBLE_BIG\n"); } printf("\nDo you want to compile MIRACL as a C++ library, rather than a C library?\n"); printf("Default to No. (Y/N)?"); r=answer(); if (r) { fprintf(fp,"#define MR_CPP\n"); } printf("\nDo you want to avoid the use of compiler intrinsics?\n"); printf("Default to No. (Y/N)?"); r=answer(); if (r) { fprintf(fp,"#define MR_NO_INTRINSICS\n"); } 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; }