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;
}
Example #2
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. */