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; }
/* * 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")); } }
/* * 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); }