static void reverse_subg(giant a, giant b) /* b := a - b; requires b, a non-negative and a >= b. */ { int j; int size = a->sign; giantDigit tmp; giantDigit borrow1 = 0; giantDigit borrow2 = 0; giantDigit *an = a->n; giantDigit *bn = b->n; if(b->sign == 0) { gtog(a, b); return; } for (j=0; j<b->sign; ++j) { if(borrow1 || borrow2) { tmp = giantSubDigits(an[j], (giantDigit)1, &borrow1); } else { tmp = an[j]; borrow1 = 0; } bn[j] = giantSubDigits(tmp, bn[j], &borrow2); } if(borrow1 || borrow2) { /* propagate borrow thru remainder of bn[] */ borrow1 = 1; } for (j=b->sign; j<size; ++j) { if(borrow1) { bn[j] = giantSubDigits(an[j], (giantDigit)1, &borrow1); } else { bn[j] = an[j]; borrow1 = 0; } } b->sign = size; /* REC, 21 Apr 1996. */ while(!b->n[--size]); b->sign = size+1; }
static void normal_subg(giant a, giant b) /* b := b - a; requires b, a non-negative and b >= a. */ { int j; int size = b->sign; giantDigit tmp; giantDigit borrow1 = 0; giantDigit borrow2 = 0; giantDigit *an = a->n; giantDigit *bn = b->n; if(a->sign == 0) { return; } for (j=0; j<a->sign; ++j) { if(borrow1 || borrow2) { tmp = giantSubDigits(bn[j], (giantDigit)1, &borrow1); } else { tmp = bn[j]; borrow1 = 0; } bn[j] = giantSubDigits(tmp, an[j], &borrow2); } if(borrow1 || borrow2) { /* propagate borrow thru remainder of bn[] */ borrow1 = 1; for (j=a->sign; j<size; ++j) { if(borrow1) { bn[j] = giantSubDigits(bn[j], (giantDigit)1, &borrow1); } else { break; } } } /* adjust sign for leading zero digits */ while((size-- > 0) && (b->n[size] == 0)) ; b->sign = (b->n[size] == 0)? 0 : size+1; }
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; }