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
/*
 * Common code used by x1OrderPlusJustify() and x1OrderPlusMod() to generate
 * reciprocal of x1OrderPlus.
 * 8 Sep 1998 - also used by feeSigSign().
 */
void calcX1OrderPlusRecip(curveParams *cp)
{
	if(isZero(cp->x1OrderPlusRecip)) {
		if((cp->x1OrderPlus == lesserX1Order(cp)) &&
		   (!isZero(cp->lesserX1OrderRecip))) {
		   	/*
			 * lesserX1Order happens to be x1OrderPlus, and we
			 * have a reciprocal for lesserX1Order. Copy it over.
			 */
			recipLog((
				"lesserX1OrderRecip --> x1OrderPlusRecip\n"));
		 	gtog(cp->lesserX1OrderRecip, cp->x1OrderPlusRecip);
		}
		else {
			/* Calculate the reciprocal. */
			recipLog(("calc x1OrderPlusRecip\n"));
			make_recip(cp->x1OrderPlus, cp->x1OrderPlusRecip);
		}
	}
	else {
		recipLog(("using existing x1OrderPlusRecip\n"));
	}
}
Пример #3
0
/*
 * curveOrderJustify routines with specific orders, using (and possibly
 * generating) associated reciprocals.
 */
void lesserX1OrderJustify(giant g, curveParams *cp)
{
	/*
	 * Note this is a pointer to a giant in *cp, not a newly
	 * malloc'd giant!
	 */
	giant lesserX1Ord = lesserX1Order(cp);

	if(isZero(lesserX1Ord)) {
		return;
	}

	/*
	 * Calculate reciprocal if we don't have it
	 */
	if(isZero(cp->lesserX1OrderRecip)) {
		if((lesserX1Ord == cp->x1OrderPlus) &&
		   (!isZero(cp->x1OrderPlusRecip))) {
		   	/*
			 * lesserX1Ord happens to be x1OrderPlus, and we
			 * have a reciprocal for x1OrderPlus. Copy it over.
			 */
			recipLog((
				"x1OrderPlusRecip --> lesserX1OrderRecip\n"));
		 	gtog(cp->x1OrderPlusRecip, cp->lesserX1OrderRecip);
		}
		else {
			/* Calculate the reciprocal. */
			recipLog(("calc lesserX1OrderRecip\n"));
			make_recip(lesserX1Ord, cp->lesserX1OrderRecip);
		}
	}
	else {
		recipLog(("using existing lesserX1OrderRecip\n"));
	}
	curveOrderJustifyWithRecip(g, lesserX1Ord, cp->lesserX1OrderRecip);
}