コード例 #1
1
static feeReturn feeGenPrivate(pubKeyInst *pkinst,
	const unsigned char *passwd,
	unsigned passwdLen,
	char hashPasswd)
{
	unsigned 		privLen;			// desired size of pkinst->privData
	feeHash 		*hash = NULL;		// a malloc'd array
	unsigned		digestLen;			// size of MD5 digest
	unsigned 		dataSize;			// min(privLen, passwdLen)
	unsigned		numDigests = 0;
	unsigned		i;
	unsigned char	*cp;
	unsigned		toMove;				// for this digest
	unsigned		moved;				// total digested
	unsigned char	*digest = NULL;
	unsigned char	*privData = NULL;	// temp, before modg(curveOrder)
	giant			corder;				// lesser of two curve orders
	
	/*
	 * generate privData which is just larger than the smaller
	 * curve order.
	 * We'll take the result mod the curve order when we're done.
	 * Note we do *not* have to free corder - it's a pointer to a giant
	 * in pkinst->cp.
	 */
	corder = lesserX1Order(pkinst->cp);
	CKASSERT(!isZero(corder));
	privLen = (bitlen(corder) / 8) + 1;

	if(!hashPasswd) {
		/* 
		 * Caller trusts the incoming entropy. Verify it's big enough and proceed. 
		 */
		if(passwdLen < privLen) {
			return FR_ShortPrivData;
		}
		privLen = passwdLen;
		privData = (unsigned char *)passwd;
		goto finishUp;
	}
	if(passwdLen < 2) {
		return FR_IllegalArg;
	}


	/*
	 * Calculate how many MD5 digests we'll generate.
	 */
	if(privLen > passwdLen) {
		dataSize = passwdLen;
	}
	else {
		dataSize = privLen;
	}
	digestLen = feeHashDigestLen();
	numDigests = (dataSize + digestLen - 1) / digestLen;

	hash = (void**) fmalloc(numDigests * sizeof(feeHash));
	for(i=0; i<numDigests; i++) {
		hash[i] = feeHashAlloc();
	}

	/*
	 * fill digests with passwd data, digestLen (or resid length)
	 * at a time. If (passwdLen > privLen), last digest will hash all
	 * remaining passwd data.
	 */
	cp = (unsigned char *)passwd;
	moved = 0;
	for(i=0; i<numDigests; i++) {
		if(i == (numDigests - 1)) {		    // last digest
		    toMove = passwdLen - moved;
		}
		else {
		    toMove = digestLen;
		}
		feeHashAddData(hash[i], cp, toMove);
		cp += toMove;
		moved += toMove;
	}

	/*
	 * copy digests to privData, up to privLen bytes. Pad with
	 * additional copies of digests if necessary.
	 */
	privData = (unsigned char*) fmalloc(privLen);
	cp = privData;
	moved = 0;
	i = 0;			// digest number
	for(moved=0; moved<privLen; ) {
		if((moved + digestLen) > privLen) {
		   toMove = privLen - moved;
		}
		else {
		   toMove = digestLen;
		}
		digest = feeHashDigest(hash[i++]);
		bcopy(digest, cp, toMove);
		cp += toMove;
		moved += toMove;
		if(i == numDigests) {
		    i = 0;		// wrap to 0, start padding
		}
	}
	
finishUp:
	/*
	 * Convert to giant, justify result to within [2, lesserX1Order]
	 */
	pkinst->privGiant = giant_with_data(privData, privLen);

	#if	FEE_DEBUG
	if(isZero(pkinst->privGiant)) {
		printf("feeGenPrivate: privData = 0!\n");
	}
	#endif	// FEE_DEBUG

	lesserX1OrderJustify(pkinst->privGiant, pkinst->cp);
	if(hashPasswd) {
		memset(privData, 0, privLen);
		ffree(privData);
		for(i=0; i<numDigests; i++) {
			feeHashFree(hash[i]);
		}
		ffree(hash);
	}
	return FR_Success;
}
コード例 #2
0
/*
 * Obtain size of the modulus of privKey in bytes.
 */
size_t sslPrivKeyLengthInBytes(SSLPrivKey *privKey)
{
#if 0
	/* Get the length of p + q (which is the size of the modulus) in bits. */
	gi_uint16 bitLen = bitlen(&privKey->rsaKey.p.g) +
		bitlen(&privKey->rsaKey.q.g);
	/* Convert it to bytes. */
	return (bitLen + 7) / 8;
#else
    return SecKeyGetBlockSize(SECKEYREF(privKey));
#endif
}
コード例 #3
0
static void
powermodg(
	giant		x,
	giant		n,
	curveParams	*cp
)
/* x becomes x^n (mod basePrime). */
{
	int 		len, pos;
	giant		scratch2 = borrowGiant(cp->maxDigits);

	gtog(x, scratch2);
	int_to_giant(1, x);
	len = bitlen(n);
	pos = 0;
	while (1)
	{
		if (bitval(n, pos++))
		{
			mulg(scratch2, x);
			feemod(cp, x);
		}
		if (pos>=len)
			break;
		gsquare(scratch2);
		feemod(cp, scratch2);
	}
	returnGiant(scratch2);
}
コード例 #4
0
void
gmersennemod(
	int 	n,
	giant 	g
)
/* g := g (mod 2^n - 1) */
{
    int the_sign;
    giant scratch3 = borrowGiant(g->capacity);
    giant scratch4 = borrowGiant(1);

    if ((the_sign = gsign(g)) < 0) absg(g);
    while (bitlen(g) > n) {
	gtog(g,scratch3);
	gshiftright(n,scratch3);
	addg(scratch3,g);
	gshiftleft(n,scratch3);
	subg(scratch3,g);
    }
    if(isZero(g)) goto out;
    int_to_giant(1,scratch3);
    gshiftleft(n,scratch3);
    int_to_giant(1,scratch4);
    subg(scratch4,scratch3);
    if(gcompg(g,scratch3) >= 0) subg(scratch3,g);
    if (the_sign < 0) {
	g->sign = -g->sign;
	addg(scratch3,g);
    }
out:
    returnGiant(scratch3);
    returnGiant(scratch4);
}
コード例 #5
0
ファイル: elliptic.c プロジェクト: Apple-FOSS-Mirror/Security
/*
 * New, 13 Jan 1997.
 */
static void feepowermodg(curveParams *par, giant x, giant n)
/* Power ladder.
   x := x^n  (mod 2^q-k)
 */
{
    int len, pos;
    giant t1;

    PROF_START;
    t1 = borrowGiant(par->maxDigits);
    gtog(x, t1);
    int_to_giant(1, x);
    len = bitlen(n);
    pos = 0;
    while(1) {
	if(bitval(n, pos++)) {
	    mulg(t1, x);
	    feemod(par, x);
	}
	if(pos>=len) break;
	gsquare(t1);
	feemod(par, t1);
    }
    returnGiant(t1);
    PROF_END(powerModTime);
}
コード例 #6
0
void ellMulProj(pointProj pt0, pointProj pt1, giant k, curveParams *cp)
/* General elliptic multiplication;
   pt1 := k*pt0 on the curve,
   with k an arbitrary integer.
 */
{
	giant x = pt0->x, y = pt0->y, z = pt0->z,
		  xx = pt1->x, yy = pt1->y, zz = pt1->z;
	int ksign, hlen, klen, b, hb, kb;
    	giant t0;

	CKASSERT(cp->curveType == FCT_Weierstrass);
	if(isZero(k)) {
		int_to_giant(1, xx);
		int_to_giant(1, yy);
		int_to_giant(0, zz);
		return;
	}
	t0 = borrowGiant(cp->maxDigits);
    	ksign = k->sign;
	if(ksign < 0) negg(k);
	gtog(x,xx); gtog(y,yy); gtog(z,zz);
	gtog(k, t0); addg(t0, t0); addg(k, t0); /* t0 := 3k. */
	hlen = bitlen(t0);
	klen = bitlen(k);
	for(b = hlen-2; b > 0; b--) {
		ellDoubleProj(pt1,cp);
		hb = bitval(t0, b);
		if(b < klen) kb = bitval(k, b); else kb = 0;
		if((hb != 0) && (kb == 0))
			ellAddProj(pt1, pt0, cp);
		else if((hb == 0) && (kb !=0))
			ellSubProj(pt1, pt0, cp);
	}
	if(ksign < 0) {
		ellNegProj(pt1, cp);
		k->sign = -k->sign;
	}
	returnGiant(t0);
}
コード例 #7
0
unsigned feePubKeyBitsize(feePubKey pubKey)
{
	pubKeyInst *pkinst = (pubKeyInst *) pubKey;
	switch(pkinst->cp->primeType) {
		case FPT_General:	/* cp->q is here for just this purpose */
		case FPT_Mersenne:
			return pkinst->cp->q;
		case FPT_FEE:		/* could be larger or smaller than 2^q-1 */
		default:
			return bitlen(pkinst->cp->basePrime);	
	}
	/* NOT REACHED */
	return 0;
}
コード例 #8
0
static void bdivg(giant v, giant u)
/* u becomes greatest power of two not exceeding u/v. */
{
    int diff = bitlen(u) - bitlen(v);
    giant scratch7;

    if (diff<0) {
        int_to_giant(0,u);
        return;
    }
    scratch7 = borrowGiant(u->capacity);
    gtog(v, scratch7);
    gshiftleft(diff,scratch7);
    if(gcompg(u,scratch7) < 0) diff--;
    if(diff<0) {
        int_to_giant(0,u);
    	returnGiant(scratch7);
        return;
    }
    int_to_giant(1,u);
    gshiftleft(diff,u);
    returnGiant(scratch7);
}
コード例 #9
0
void gmersennemod(int n, giant g) {
/*   g becomes g mod ((2^n)-1)
     31 Jul 96 modified REC.
     17 Jan 97 modified REC.
*/
    unsigned bits = n & (GIANT_BITS_PER_DIGIT - 1);
    unsigned digits =  1 + ((n-1) >> GIANT_LOG2_BITS_PER_DIGIT);
    int isPositive = (g->sign > 0);
    int j;
    int b;
    int size;
    int foundzero;
    giantDigit mask = (bits == 0) ? GIANT_DIGIT_MASK : (giantDigit)((1<<bits)-1);
    giant scratch1;

    b = bitlen(g);
    if(b < n) {
        unsigned numDigits = (n + GIANT_BITS_PER_DIGIT - 1) >>
		GIANT_LOG2_BITS_PER_DIGIT;
	giantDigit lastWord = 0;
	giantDigit bits = 1;

        if(g->sign >= 0) return;

	/*
	 * Cons up ((2**n)-1), add to g.
	 */
	scratch1 = borrowGiant(numDigits + 1);
	scratch1->sign = numDigits;
	for(j=0; j<(int)(numDigits-1); j++) {
		scratch1->n[j] = GIANT_DIGIT_MASK;
	}

	/*
	 * Last word has lower (n & (GIANT_BITS_PER_DIGIT-1)) bits set.
	 */
	for(j=0; j < (int)(n & (GIANT_BITS_PER_DIGIT-1)); j++) {
		lastWord |= bits;
		bits <<= 1;
	}
	scratch1->n[numDigits-1] = lastWord;
	addg(g, scratch1);   /* One version. */
	gtog(scratch1, g);
	returnGiant(scratch1);
	return;
    }
コード例 #10
0
ファイル: EmuRsa.cpp プロジェクト: ILOVEPIE/Cxbx-Reloaded
void make_recip(giant d, giant r)
/* r becomes the steady-state reciprocal
* 2^(2b)/d, where b = bit-length of d-1. */
{
	int		b;
	giant 	tmp, tmp2;

	if (isZero(d) || (d->sign < 0))
	{
		exit(SIGN);
	}
	tmp = popg();
	tmp2 = popg();
	itog(1, r);
	subg(r, d);
	b = bitlen(d);
	addg(r, d);
	gshiftleft(b, r);
	gtog(r, tmp2);
	while (1)
	{
		gtog(r, tmp);
		squareg(tmp);
		gshiftright(b, tmp);
		mulg(d, tmp);
		gshiftright(b, tmp);
		addg(r, r);
		subg(tmp, r);
		if (gcompg(r, tmp2) <= 0)
			break;
		gtog(r, tmp2);
	}
	itog(1, tmp);
	gshiftleft(2 * b, tmp);
	gtog(r, tmp2);
	mulg(d, tmp2);
	subg(tmp2, tmp);
	itog(1, tmp2);
	while (tmp->sign < 0)
	{
		subg(tmp2, r);
		addg(d, tmp);
	}
	pushg(2);
}
コード例 #11
0
static void
powFp2(giant a, giant b, giant w2, giant n, curveParams *cp)
/* Perform powering in the field F_p^2:
   a + b w := (a + b w)^n (mod p), where parameter w2 is a quadratic
   nonresidue (formally equal to w^2).
 */
{
	int j;
	giant t6;
	giant t7;
	giant t8;
	giant t9;

	if(isZero(n)) {
		int_to_giant(1,a);
		int_to_giant(0,b);
		return;
	}
    	t6 = borrowGiant(cp->maxDigits);
    	t7 = borrowGiant(cp->maxDigits);
    	t8 = borrowGiant(cp->maxDigits);
    	t9 = borrowGiant(cp->maxDigits);
	gtog(a, t8); gtog(b, t9);
	for(j = bitlen(n)-2; j >= 0; j--) {
		gtog(b, t6);
		mulg(a, b); addg(b,b); feemod(cp, b);  /* b := 2 a b. */
		gsquare(t6); feemod(cp, t6);
		mulg(w2, t6); feemod(cp, t6);
		gsquare(a); addg(t6, a); feemod(cp, a);
						/* a := a^2 + b^2 w2. */
		if(bitval(n, j)) {
			gtog(b, t6); mulg(t8, b); feemod(cp, b);
			gtog(a, t7); mulg(t9, a); addg(a, b); feemod(cp, b);
			mulg(t9, t6); feemod(cp, t6);
			mulg(w2, t6); feemod(cp, t6);
			mulg(t8, a); addg(t6, a); feemod(cp, a);
		}
	}
	returnGiant(t6);
	returnGiant(t7);
	returnGiant(t8);
	returnGiant(t9);
	return;
}
コード例 #12
0
ファイル: EmuRsa.cpp プロジェクト: ILOVEPIE/Cxbx-Reloaded
void modg_via_recip(giant d, giant r, giant n)
/* This is the fastest mod of the present collection.
* n := n % d, where r is the precalculated
* steady-state reciprocal of d. */
{
	int		s = (bitlen(r) - 1), sign = n->sign;
	giant 	tmp, tmp2;

	if (isZero(d) || (d->sign < 0))
	{
		exit(SIGN);
	}

	tmp = popg();
	tmp2 = popg();

	n->sign = abs(n->sign);
	while (1)
	{
		gtog(n, tmp); gshiftright(s - 1, tmp);
		mulg(r, tmp);
		gshiftright(s + 1, tmp);
		mulg(d, tmp);
		subg(tmp, n);
		if (gcompg(n, d) >= 0)
			subg(d, n);
		if (gcompg(n, d) < 0)
			break;
	}
	if (sign >= 0)
		goto done;
	if (isZero(n))
		goto done;
	negg(n);
	addg(d, n);
done:
	pushg(2);
	return;
}
コード例 #13
0
ファイル: EmuRsa.cpp プロジェクト: ILOVEPIE/Cxbx-Reloaded
void powermodg(giant x, giant n, giant g)
/* x becomes x^n (mod g). */
{
	int 		len, pos;
	giant		scratch2 = popg();

	gtog(x, scratch2);
	itog(1, x);
	len = bitlen(n);
	pos = 0;
	while (1)
	{
		if (bitval(n, pos++))
		{
			mulg(scratch2, x);
			modg(g, x);
		}
		if (pos >= len)
			break;
		squareg(scratch2);
		modg(g, scratch2);
	}
	pushg(1);
}
コード例 #14
0
ファイル: elliptic.c プロジェクト: Apple-FOSS-Mirror/Security
/*
 * General elliptic multiply.
 *
 * {xx, zz} := k * {xx, zz}
 */
void elliptic(giant xx, giant zz, giant k, curveParams *par) {
	int len = bitlen(k);
        int pos = len - 2;
        giant xs;
        giant zs;
        giant xorg;
        giant zorg;

	PROF_START;
	if(sequalg(1,k)) return;
	if(sequalg(2,k)) {
		ell_even(xx, zz, xx, zz, par);
		goto out;
	}
        zs = borrowGiant(par->maxDigits);
        xs = borrowGiant(par->maxDigits);
        zorg = borrowGiant(par->maxDigits);
        xorg = borrowGiant(par->maxDigits);
	gtog(xx, xorg); gtog(zz, zorg);
	ell_even(xx, zz, xs, zs, par);
	do {
	   if(bitval(k, pos--)) {
	   	ell_odd(xs, zs, xx, zz, xorg, zorg, par);
		ell_even(xs, zs, xs, zs, par);
	   } else {
	   	ell_odd(xx, zz, xs, zs, xorg, zorg, par);
		ell_even(xx, zz, xx, zz, par);
	   }
        } while (pos >= 0);	// REC fix 9/23/94
        returnGiant(xs);
        returnGiant(zs);
        returnGiant(xorg);
        returnGiant(zorg);
out:
	PROF_END(ellipticTime);
}
コード例 #15
0
ファイル: elliptic.c プロジェクト: Apple-FOSS-Mirror/Security
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. */
コード例 #16
0
ファイル: feeFEED.c プロジェクト: darlinghq/darling-security
/*
 * Alloc and init a feeFEED object associated with specified public and
 * private keys.
 */
feeFEED feeFEEDNewWithPubKey(feePubKey myPrivKey,
	feePubKey theirPubKey,
	int forEncrypt,			// 0 ==> decrypt   1 ==> encrypt
	feeRandFcn randFcn,		// optional 
	void *randRef)
{
	feedInst 		*finst;
	giant			privGiant;
	key				k;
	unsigned 		expPlainSize;
	unsigned 		expCipherSize;
	unsigned 		expBlocks;

	if(!curveParamsEquivalent(feePubKeyCurveParams(theirPubKey),
		    feePubKeyCurveParams(myPrivKey))) {
		dbgLog(("feeFEEDNewWithPubKey: Incompatible Keys\n"));
		return NULL;
	}
	finst = (feedInst*) fmalloc(sizeof(feedInst));
	bzero(finst, sizeof(feedInst));
	finst->forEncrypt = forEncrypt;
	finst->cp = curveParamsCopy(feePubKeyCurveParams(theirPubKey));
	finst->rsBlockCount = 0;
	finst->xp = newGiant(finst->cp->maxDigits);
	finst->xm = newGiant(finst->cp->maxDigits);
	finst->tmp1 = newGiant(finst->cp->maxDigits);
	if(forEncrypt) {
	    finst->tmp2 = newGiant(finst->cp->maxDigits);
	}

	/*
	 * cluePlus  = ourPriv * theirPub+
	 * clueMinus = ourPriv * theirPub-
	 */
	finst->cluePlus  = newGiant(finst->cp->maxDigits);
	finst->clueMinus = newGiant(finst->cp->maxDigits);
	privGiant = feePubKeyPrivData(myPrivKey);
	if(privGiant == NULL) {
		dbgLog(("feeFEEDNewWithPubKey: no private key\n"));
		goto abort;
	}
	k = feePubKeyPlusCurve(theirPubKey);
	gtog(k->x, finst->cluePlus);			// cluePlus = theirPub+
	elliptic_simple(finst->cluePlus, privGiant, finst->cp);
	k = feePubKeyMinusCurve(theirPubKey);
	gtog(k->x, finst->clueMinus);			// theirPub-
	elliptic_simple(finst->clueMinus, privGiant, finst->cp);

	/*
	 * Set up block sizes.
	 */
	if(finst->cp->primeType == FPT_General) {
	    unsigned blen = bitlen(finst->cp->basePrime);

	    finst->plainBlockSize = blen / 8;
	    if((blen & 0x7) == 0) {
	    	/*
		 * round down some more...
		 */
		finst->plainBlockSize--;
	    }
	}
	else {
	    finst->plainBlockSize = finst->cp->q / 8;
	    if(((finst->cp->q & 0x7) == 0) && (finst->cp->k > 0)) {
		/*
		 * Special case, with q mod 8 == 0. Here we have to
		 * trim back the plainBlockSize by one byte.
		 */
		finst->plainBlockSize--;
	    }
	}
	finst->cipherBlockSize = finst->cp->minBytes + 1;

	/*
	 * the size of initialRS is subject to tweaking - if we make it
	 * not a multiple of plainBlockSize, we save one FEEDExp cipherBlock
	 * in our ciphertext.
	 */
	finst->initialRSSize = finst->plainBlockSize * 2;
	if(finst->initialRSSize > RS_MIN_SIZE) {
	    unsigned minPlainBlocks;
	    unsigned maxSize;

	    /*
	     * How many plainblocks to hold RS_MIN_SIZE?
	     */
	    minPlainBlocks = (RS_MIN_SIZE + finst->plainBlockSize - 1) /
	    	finst->plainBlockSize;

	    /*
	     * Max size = that many plainblocks, less 2 bytes (to avoid
	     * extra residue block).
	     */
	    maxSize = minPlainBlocks * finst->plainBlockSize - 2;

	    /*
	     * But don't bother with more than 2 plainblocks worth
	     */
	    if(finst->initialRSSize > maxSize) {
	        finst->initialRSSize = maxSize;
	    }
	}
	/* else leave it alone, that's small enough */

	if(forEncrypt) {
		feeRand frand = NULL;

		/*
		 * Encrypt-capable FEEDExp object
		 */
		finst->feedExp = feeFEEDExpNewWithPubKey(theirPubKey,
			randFcn,
			randRef);
		if(finst->feedExp == NULL) {
			goto abort;
		}

		/*
		 * Generate initial r and s data.
		 */
		finst->initialRS = (unsigned char*) fmalloc(finst->initialRSSize);
		if(randFcn != NULL) {
			randFcn(randRef, finst->initialRS, finst->initialRSSize);
		}
		else {
			frand = feeRandAlloc();
			feeRandBytes(frand, finst->initialRS, finst->initialRSSize);
			feeRandFree(frand);
		}
		if(initFromRS(finst)) {
			goto abort;
		}
	}
	else {
		/*
		 * Decrypt-capable FEEDExp object
		 */
		finst->feedExp = feeFEEDExpNewWithPubKey(myPrivKey,
			randFcn,
			randRef);
		if(finst->feedExp == NULL) {
			goto abort;
		}

	}

	/*
	 * Figure out how many of our cipherblocks it takes to hold
	 * a FEEDExp-encrypted initialRS. If initialRSSize is an exact
	 * multiple of expPlainSize, we get an additional feedExp
	 * residue block.
	 */
	expPlainSize = feeFEEDExpPlainBlockSize(finst->feedExp);
	expCipherSize = feeFEEDExpCipherBlockSize(finst->feedExp);
	expBlocks = (finst->initialRSSize + expPlainSize - 1) /
		expPlainSize;
	if((finst->initialRSSize % expPlainSize) == 0) {
		expBlocks++;
	}

	/*
	 * Total meaningful bytes of encrypted initialRS
	 */
	finst->rsCtextSize = expBlocks * expCipherSize;

	/*
	 * Number of our cipherblocks it takes to hold rsCtextSize
	 */
	finst->rsSizeCipherBlocks = (finst->rsCtextSize +
		finst->cipherBlockSize - 1) / finst->cipherBlockSize;
	if(!forEncrypt) {
	    finst->rsCtext = (unsigned char*) fmalloc(finst->rsSizeCipherBlocks *
		finst->cipherBlockSize);
	}

	/*
	 * Sanity check...
	 */
	#if	FEED_DEBUG
	{
	    unsigned fexpBlockSize = feeFEEDExpCipherBlockSize(finst->feedExp);

	    /*
	     * FEEDExp has one more giant in ciphertext, plaintext is
	     * same size
	     */
	    if((finst->cipherBlockSize + finst->cp->minBytes) !=
			fexpBlockSize) {
		dbgLog(("feeFEEDNewWithPubKey: FEEDExp CBlock Size "
			"screwup\n"));
		goto abort;
	    }
	    fexpBlockSize = feeFEEDExpPlainBlockSize(finst->feedExp);
	    if(fexpBlockSize != finst->plainBlockSize) {
		dbgLog(("feeFEEDNewWithPubKey: FEEDExp PBlock Size "
			"screwup\n"));
		goto abort;
	    }
	}
	#endif	// FEED_DEBUG

	return finst;

abort:
	feeFEEDFree(finst);
	return NULL;
}
コード例 #17
0
/*
 * Alloc and init a feeFEEDExp object associated with specified feePubKey.
 */
feeFEEDExp feeFEEDExpNewWithPubKey(
	feePubKey pubKey,
	feeRandFcn randFcn,		// optional 
	void *randRef)
{
	feedInst 		*finst = (feedInst *) fmalloc(sizeof(feedInst));
	giant 			privGiant;

	finst->cp = curveParamsCopy(feePubKeyCurveParams(pubKey));
	finst->plus = new_public_with_key(feePubKeyPlusCurve(pubKey),
		finst->cp);
	finst->minus = new_public_with_key(feePubKeyMinusCurve(pubKey),
		finst->cp);

	/*
	 * These might yield NULL data; we can only encrypt in that case.
	 */
	privGiant = feePubKeyPrivData(pubKey);
	if(privGiant) {
		finst->gPriv = newGiant(finst->cp->maxDigits);
		gtog(privGiant, finst->gPriv);
	}
	else {
		finst->gPriv = NULL;
	}

	/*
	 * Conservative, rounding down, on plaintext blocks since we don't
	 * want to split bytes.
	 */
	if(finst->cp->primeType == FPT_General) {
	    unsigned blen = bitlen(finst->cp->basePrime);

	    finst->plainBlockSize = blen / 8;
	    if((blen % 8) == 0) {
	    	/*
		 * round down some more...
		 */
		finst->plainBlockSize--;
	    }
	}
	else {
	    finst->plainBlockSize = finst->cp->q / 8;
	    if(((finst->cp->q & 0x7) == 0) && (finst->cp->k > 0)) {
		/*
		 * Special case, with q mod 8 == 0. Here we have to trim back
		 * the plainBlockSize by one byte.
		 */
		finst->plainBlockSize--;
	    }
	}

	/*
	 * One block of ciphertext - two giants (with implied sign) and a
	 * parity byte
	 */
	finst->cipherBlockSize = (2 * finst->cp->minBytes) + 1;

	finst->xp = newGiant(finst->cp->maxDigits);
	finst->xc = newGiant(finst->cp->maxDigits);
	finst->xq = newGiant(finst->cp->maxDigits);
	finst->xm = newGiant(finst->cp->maxDigits);
	finst->xaux = newGiant(finst->cp->maxDigits);
	finst->rand = NULL;
	finst->randData = NULL;
	finst->randFcn = randFcn;
	finst->randRef = randRef;
	return finst;
}
コード例 #18
0
int main(int argc, char **argv)
{
	int 		arg;
	char 		*argp;
	unsigned 	sigLoops = SIGN_LOOPS_DEF;
	unsigned	vfyLoops = VFY_LOOPS_DEF;
	unsigned	numKeys = NUM_KEYS; // might be less for very small loops
	unsigned	depth;
	feeRand 	rand;
	
	feePubKey	keys[NUM_KEYS];
	/* sigLoops copies of each of {digestData, sigData} */
	FeeData		*digestData;
	FeeData		*sigData;
	
	unsigned 	seed;
	unsigned	i;
	PLAT_TIME	startTime;
	PLAT_TIME	endTime;
	double		elapsed;
	curveParams	*cp;
	unsigned	minDepth = 0;
	unsigned	maxDepth = FEE_DEPTH_MAX;
	unsigned	basePrimeLen;
	char		*curveType;
	feeReturn	frtn;
	
	for(arg=1; arg<argc; arg++) {
		argp = argv[arg];
		switch(argp[0]) {
		    case 's':
		    	sigLoops = atoi(&argp[2]);
			break;
		    case 'v':
		    	vfyLoops = atoi(&argp[2]);
			break;
		    case 'D':
		    	minDepth = maxDepth = atoi(&argp[2]);
			break;
		    default:
		    	usage(argv);
			break;
		}
	}
	
	/*
	 * Common random generator
	 */
	time((time_t *)&seed);
	rand = feeRandAllocWithSeed(seed);

	if(numKeys > sigLoops) {
	    numKeys = sigLoops;
	}
	digestData = (FeeData *)fmalloc(sizeof(FeeData) * sigLoops);
	sigData    = (FeeData *)fmalloc(sizeof(FeeData) * sigLoops);
		
	/* alloc the data, once, for largest private key or "digest" we'll use */
	for(i=0; i<sigLoops; i++) {
	    mallocData(&digestData[i], PRIV_KEY_SIZE_BYTES);
	}   
	for(depth=minDepth; depth<=maxDepth; depth++) {
	
		/*
		 * Get curve params for this depth
	 	 */
		cp = curveParamsForDepth(depth);
		if(cp == NULL) {
			printf("malloc failure\n");
			exit(1);
		}
		switch(cp->curveType) {
		    case FCT_Montgomery:
		    	curveType = "FCT_Montgomery";
			break;
		    case FCT_Weierstrass:
			curveType = "FCT_Weierstrass";
			break;
		    case FCT_General:
		    	curveType = "FCT_General";
			break;
		    default:
		    	printf("***Unknown curveType!\n");
			exit(1);
		}
		
		switch(cp->primeType) {
		    case FPT_General:
		    	printf("depth=%d; FPT_General, %s; keysize=%d;\n", 
				depth, curveType, bitlen(cp->basePrime));
			break;
		    case FPT_Mersenne:
			printf("depth=%d; FPT_Mersenne, %s; q=%d\n",
				depth, curveType, cp->q);
			break;
		    default:
			printf("depth=%d; FPT_FEE, %s; q=%d k=%d\n",
				depth, curveType, cp->q, cp->k);
			break;
		}
		basePrimeLen = bitlen(cp->basePrime);
		
		/* one set of random data as private keys */
		unsigned privSize = (basePrimeLen + 8) / 8;
		genRandData(digestData, numKeys, privSize, rand);
	
		/* generate the keys (no hash - we've got that covered) */
		for(i=0; i<numKeys; i++) {
		    keys[i] = feePubKeyAlloc();
		    feePubKeyInitFromPrivDataDepth(keys[i], digestData[i].data, privSize, 
			depth, 0);
		}

		/* now different data to actually sign */
		genRandData(digestData, sigLoops, DIGEST_SIZE_BYTES, rand);
		
		/*
		 * sign 
		 */
		PLAT_GET_TIME(startTime);
		for(i=0; i<sigLoops; i++) {
		    FeeData *digst = &digestData[i];
		    FeeData *sig   = &sigData[i];
		    feePubKey fkey = keys[i % numKeys];
		    
		    feeSig fs = feeSigNewWithKey(fkey, randCallback, rand);
		    frtn = feeSigSign(fs, digst->data, digst->length, fkey);
		    if(frtn) {
			printf("***Error %d on feeSigSign\n", (int)frtn);
			break;
		    }
		    frtn = feeSigData(fs, &sig->data, &sig->length);
		    if(frtn) {
			printf("***Error %d on feeSigData\n", (int)frtn);
			break;
		    }
		    feeSigFree(fs);
		}
		PLAT_GET_TIME(endTime);
		elapsed = PLAT_GET_US(startTime, endTime);
		printf("   sign:   %12.2f us per op\n", 
			elapsed / sigLoops);
	
		/*
		 * verify - might be doing more of these than we have
		 * valid signatures.....
		 */
		unsigned dex=0;
		PLAT_GET_TIME(startTime);
		for(i=0; i<vfyLoops; i++) {
		    FeeData *digst = &digestData[dex];
		    FeeData *sig   = &sigData[dex];
		    feePubKey fkey = keys[dex % numKeys];
		    
		    feeSig fs;
		    frtn = feeSigParse(sig->data, sig->length, &fs);
		    if(frtn) {
			printf("***Error %d on feeSigParse\n", (int)frtn);
			break;
		    }
		    frtn = feeSigVerify(fs, digst->data, digst->length, fkey);
		    if(frtn) {
			printf("***Error %d on feeSigVerify\n", (int)frtn);
			break;
		    }
		    feeSigFree(fs);
		    dex++;
		    if(dex == sigLoops) {
			/* that's all the data we have, recycle */
			dex = 0;
		    }
		}
		PLAT_GET_TIME(endTime);
		elapsed = PLAT_GET_US(startTime, endTime);
		printf("   verify: %12.2f us per op\n", 
			elapsed / vfyLoops);

		freeCurveParams(cp);
		/* possibly limited number of signatures.... */
		for(i=0; i<sigLoops; i++) {
		    ffree(sigData[i].data);	// mallocd by feeSigData()
		}
		for(i=0; i<numKeys; i++) {
		    feePubKeyFree(keys[i]); 
		}
	}
	
	feeRandFree(rand);
	for(i=0; i<sigLoops; i++) {
	    ffree(digestData[i].data);
	}
	ffree(digestData);
	ffree(sigData);
	
	return 0;
}