int main(int argc, char **argv) { int arg; char *argp; giantDigit *digit1; // mallocd arrays giantDigit *digit2; giantDigit *vect1; giantDigit *vect2; giantDigit *dig1p; // ptr into mallocd arrays giantDigit *dig2p; giantDigit *vect1p; giantDigit *vect2p; unsigned numDigits; unsigned i; PLAT_TIME startTime; PLAT_TIME endTime; unsigned elapsed; giantDigit scr1; // op result giantDigit scr2; // op result int loops = LOOPS_DEF; int seedSpec = 0; unsigned seed = 0; unsigned maxSize = MAX_SIZE_DEF; unsigned minSize = MIN_SIZE_DEF; initCryptKit(); #if macintosh argc = ccommand(&argv); #endif for(arg=1; arg<argc; arg++) { argp = argv[arg]; switch(argp[0]) { case 'x': maxSize = atoi(&argp[2]); break; case 'n': minSize = atoi(&argp[2]); break; case 'l': loops = atoi(&argp[2]); break; case 's': seed = atoi(&argp[2]); seedSpec = 1; break; case 'h': default: usage(argv); } } if(!seedSpec) { unsigned long tim; time(&tim); seed = (unsigned)tim; } SRAND(seed); /* * Scratch digits, big enough for anything. Malloc here, init with * random data before each test. */ digit1 = malloc(sizeof(giantDigit) * loops * 2); digit2 = malloc(sizeof(giantDigit) * loops * 2); /* vect1 and vect2 are arrays of giantDigit arrays */ vect1 = malloc(sizeof(giantDigit) * loops * maxSize); vect2 = malloc(sizeof(giantDigit) * loops * maxSize); if((digit1 == NULL) || (digit1 == NULL) || (vect1 == NULL) || (vect2 == NULL)) { printf("malloc error\n"); exit(1); } printf("Starting giantAsm test: seed %d\n", seed); /* giantAddDigits test */ randDigits(loops, digit1); randDigits(loops, digit2); dig1p = digit1; dig2p = digit2; PLAT_GET_TIME(startTime); for(i=0; i<loops; i++) { scr1 = giantAddDigits(*dig1p++, *dig2p++, &scr2); } PLAT_GET_TIME(endTime); elapsed = PLAT_GET_NS(startTime, endTime); printf("giantAddDigits: %f ns\n", (double)elapsed / (double)loops); /* giantAddDouble test */ randDigits(loops, digit1); randDigits(loops * 2, digit2); dig1p = digit1; dig2p = digit2; PLAT_GET_TIME(startTime); for(i=0; i<loops; i++) { giantAddDouble(dig2p, dig2p+1, *dig1p++); dig2p += 2; } PLAT_GET_TIME(endTime); elapsed = PLAT_GET_NS(startTime, endTime); printf("giantAddDouble: %f ns\n", (double)elapsed / (double)loops); /* giantSubDigits test */ randDigits(loops, digit1); randDigits(loops, digit2); dig1p = digit1; dig2p = digit2; PLAT_GET_TIME(startTime); for(i=0; i<loops; i++) { scr1 = giantSubDigits(*dig1p++, *dig2p++, &scr2); } PLAT_GET_TIME(endTime); elapsed = PLAT_GET_NS(startTime, endTime); printf("giantSubDigits: %f ns\n", (double)elapsed / (double)loops); /* giantMulDigits test */ randDigits(loops, digit1); randDigits(loops, digit2); dig1p = digit1; dig2p = digit2; PLAT_GET_TIME(startTime); for(i=0; i<loops; i++) { giantMulDigits(*dig1p++, *dig2p++, &scr1, &scr2); } PLAT_GET_TIME(endTime); elapsed = PLAT_GET_NS(startTime, endTime); printf("giantMulDigits: %f ns\n", (double)elapsed / (double)loops); printf("\nvectorMultiply:\n"); for(numDigits=minSize; numDigits<=maxSize; numDigits*=2) { randDigits(loops, digit1); // plierDigit randDigits(loops * numDigits, vect1); // candVector randDigits(loops * numDigits, vect2); // prodVector dig1p = digit1; vect1p = vect1; vect2p = vect2; PLAT_GET_TIME(startTime); for(i=0; i<loops; i++) { scr1 = VectorMultiply(*dig1p++, // plierDigit vect1p, // candVector numDigits, vect2p); // prodVector vect1p += numDigits; vect2p += numDigits; } PLAT_GET_TIME(endTime); elapsed = PLAT_GET_NS(startTime, endTime); printf(" bits = %4d : %f ns\n", numDigits * GIANT_BITS_PER_DIGIT, (double)elapsed / (double)loops); } /* for numDigits */ return 0; }
void feemod(curveParams *par, giant x) { int sign, sign2; giant t1; giant t3; giant t4; giant t5; #if FEEMOD_LOOP_TEST unsigned feemodLoops = 0; #endif // FEEMOD_LOOP_TEST FEEMOD_CALL_INCR; // for FEEMOD_LOOP_TEST INCR_FEEMODS; // for ellipticMeasure PROF_INCR(numFeemod); // for general profiling switch(par->primeType) { case FPT_Mersenne: /* * Super-optimized Mersenne prime modulus case */ gmersennemod(par->q, x); break; case FPT_FEE: /* * General 2**q-k case */ sign = (x->sign < 0) ? -1 : 1; sign2 = 1; x->sign = abs(x->sign); if(gcompg(par->basePrime, x) >= 0) { goto outFee; } t1 = borrowGiant(par->maxDigits); t3 = borrowGiant(par->maxDigits); t4 = borrowGiant(par->maxDigits); t5 = borrowGiant(par->maxDigits); /* Begin OPT: 11 Jan 98 REC. */ if( ((par->q & (GIANT_BITS_PER_DIGIT - 1)) == 0) && (par->k >= 0) && (par->k < GIANT_DIGIT_MASK)) { /* * Microscopic mod for certain regions of {q,k} * parameter space. */ int j, digits, excess, max; giantDigit carry; giantDigit termHi; // double precision giantDigit termLo; giantDigit *p1, *p2; digits = par->q >> GIANT_LOG2_BITS_PER_DIGIT; while(bitlen(x) > par->q) { excess = (x->sign) - digits; max = (excess > digits) ? excess : digits; carry = 0; p1 = &x->n[0]; p2 = &x->n[digits]; if(excess <= digits) { carry = VectorMultiply(par->k, p2, excess, p1); /* propagate final carry */ p1 += excess; for(j = excess; j < digits; j++) { /* * term = *p1 + carry; * *p1++ = term & 65535; * carry = term >> 16; */ termLo = giantAddDigits(*p1, carry, &carry); *p1++ = termLo; } } else { carry = VectorMultiply(par->k, p2, digits, p1); p1 += digits; p2 += digits; for(j = digits; j < excess; j++) { /* * term = (par->k)*(*p2++) + carry; */ giantMulDigits(par->k, *p2++, &termLo, &termHi); giantAddDouble(&termLo, &termHi, carry); /* * *p1++ = term & 65535; * carry = term >> 16; */ *p1++ = termLo; carry = termHi; } } if(carry > 0) { x->n[max] = carry; } else { while(--max){ if(x->n[max] != 0) break; } } x->sign = max + 1; FEEMOD_LOOP_INCR; } } else { /* Macroscopic mod for general PT_FEE case. */