pointProj newPointProj(unsigned numDigits) { pointProj pt; pt = (pointProj) fmalloc(sizeof(pointProjStruct)); pt->x = newGiant(numDigits); pt->y = newGiant(numDigits); pt->z = newGiant(numDigits); return(pt); }
/* * Create a giant, initialized with specified char[] data. */ giant giant_with_data(const unsigned char *d, int len) { int numDigits = BYTES_TO_GIANT_DIGITS(len); giant result; result = newGiant(numDigits); deserializeGiant(d, result, len); return result; }
/* * Key exchange atom. */ giant make_pad(giant privGiant, key publicKey) { curveParams *par = publicKey->cp; giant result = newGiant(par->maxDigits); gtog(publicKey->x, result); elliptic_simple(result, privGiant, par); return result; }
key new_public(curveParams *cp, int twist) { key k; k = (key) fmalloc(sizeof(keystruct)); k->cp = cp; k->twist = twist; k->x = newGiant(cp->maxDigits); if((twist == CURVE_PLUS) && (cp->curveType == FCT_Weierstrass)) { k->y = newGiant(cp->maxDigits); } else { /* * no projective algebra. We could optimize and save a few bytes * here by setting y to NULL, but that really complicates things * in may other places. Best to have a real giant. */ k->y = newGiant(1); } return(k); }
giant copyGiant(giant x) { int bytes; giant result = newGiant(x->capacity); /* * 13 Jun 1997 * NO! this assumes packed alignment */ bytes = sizeof(giantstruct) + ((x->capacity - 1) * GIANT_BYTES_PER_DIGIT); bcopy(x, result, bytes); return result; }
/* * Init an empty feePubKey from a DER-encoded blob, public and private key versions. */ feeReturn feePubKeyInitFromDERPubBlob(feePubKey pubKey, unsigned char *keyBlob, size_t keyBlobLen) { pubKeyInst *pkinst = (pubKeyInst *) pubKey; feeReturn frtn; int version; if(pkinst == NULL) { return FR_BadPubKey; } /* kind of messy, maybe we should clean this up. But new_public() does too * much - e.g., it allocates the x and y which we really don't want */ memset(pkinst, 0, sizeof(pubKeyInst)); pkinst->plus = (key) fmalloc(sizeof(keystruct)); pkinst->minus = (key) fmalloc(sizeof(keystruct)); if((pkinst->plus == NULL) || (pkinst->minus == NULL)) { return FR_Memory; } memset(pkinst->plus, 0, sizeof(keystruct)); memset(pkinst->minus, 0, sizeof(keystruct)); pkinst->cp = NULL; pkinst->privGiant = NULL; pkinst->plus->twist = CURVE_PLUS; pkinst->minus->twist = CURVE_MINUS; frtn = feeDERDecodePublicKey(keyBlob, (unsigned)keyBlobLen, &version, // currently unused &pkinst->cp, &pkinst->plus->x, &pkinst->minus->x, &pkinst->plus->y); if(frtn) { return frtn; } /* minus curve, y is not used */ pkinst->minus->y = newGiant(1); int_to_giant(0, pkinst->minus->y); pkinst->plus->cp = pkinst->minus->cp = pkinst->cp; return FR_Success; }
feeReturn feePubKeyInitFromECDSAPrivBlob(feePubKey pubKey, const unsigned char *keyBlob, unsigned keyBlobLen, feeDepth depth) { pubKeyInst *pkinst = (pubKeyInst *)pubKey; if(pkinst == NULL) { return FR_BadPubKey; } curveParams *cp = curveParamsForDepth(depth); if(cp == NULL) { return FR_IllegalDepth; } unsigned giantDigits = cp->basePrime->sign; unsigned giantBytes = (cp->q + 7) / 8; /* * The specified private key can be one byte smaller than the modulus */ if((keyBlobLen > giantBytes) || (keyBlobLen < (giantBytes - 1))) { dbgLog(("feePubKeyInitFromECDSAPrivBlob: bad blobLen\n")); return FR_BadKeyBlob; } pkinst->cp = cp; /* cook up a new private giant */ pkinst->privGiant = newGiant(giantDigits); if(pkinst->privGiant == NULL) { return FR_Memory; } deserializeGiant(keyBlob, pkinst->privGiant, keyBlobLen); /* since this blob only had the private data, infer the remaining fields */ pkinst->plus = new_public(pkinst->cp, CURVE_PLUS); set_priv_key_giant(pkinst->plus, pkinst->privGiant); return FR_Success; }
/* * 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; }
/* * Create new feeSig object, including a random large integer 'randGiant' for * possible use in salting a feeHash object, and 'PmX', equal to * randGiant 'o' P1. Note that this is not called when *verifying* a * signature, only when signing. */ feeSig feeSigNewWithKey( feePubKey pubKey, feeRandFcn randFcn, /* optional */ void *randRef) { sigInst *sinst = sinstAlloc(); feeRand frand; unsigned char *randBytes; unsigned randBytesLen; curveParams *cp; if(pubKey == NULL) { return NULL; } cp = feePubKeyCurveParams(pubKey); if(cp == NULL) { return NULL; } /* * Generate random m, a little larger than key size, save as randGiant */ randBytesLen = (feePubKeyBitsize(pubKey) / 8) + 1; randBytes = (unsigned char*) fmalloc(randBytesLen); if(randFcn) { randFcn(randRef, randBytes, randBytesLen); } else { frand = feeRandAlloc(); feeRandBytes(frand, randBytes, randBytesLen); feeRandFree(frand); } sinst->randGiant = giant_with_data(randBytes, randBytesLen); memset(randBytes, 0, randBytesLen); ffree(randBytes); #if FEE_DEBUG if(isZero(sinst->randGiant)) { printf("feeSigNewWithKey: randGiant = 0!\n"); } #endif // FEE_DEBUG /* * Justify randGiant to be in [2, x1OrderPlus] */ x1OrderPlusJustify(sinst->randGiant, cp); /* PmX := randGiant 'o' P1 */ sinst->PmX = newGiant(cp->maxDigits); #if CRYPTKIT_ELL_PROJ_ENABLE if(cp->curveType == FCT_Weierstrass) { pointProjStruct pt0; sinst->PmY = newGiant(cp->maxDigits); /* cook up pt0 as P1 */ pt0.x = sinst->PmX; pt0.y = sinst->PmY; pt0.z = borrowGiant(cp->maxDigits); gtog(cp->x1Plus, pt0.x); gtog(cp->y1Plus, pt0.y); int_to_giant(1, pt0.z); /* pt0 := P1 'o' randGiant */ ellMulProjSimple(&pt0, sinst->randGiant, cp); returnGiant(pt0.z); } else { if(SIG_CURVE == CURVE_PLUS) { gtog(cp->x1Plus, sinst->PmX); } else { gtog(cp->x1Minus, sinst->PmX); } elliptic_simple(sinst->PmX, sinst->randGiant, cp); } #else /* CRYPTKIT_ELL_PROJ_ENABLE */ if(SIG_CURVE == CURVE_PLUS) { gtog(cp->x1Plus, sinst->PmX); } else { gtog(cp->x1Minus, sinst->PmX); } elliptic_simple(sinst->PmX, sinst->randGiant, cp); #endif /* CRYPTKIT_ELL_PROJ_ENABLE */ return sinst; }
/* * FEE_SIG_USING_PROJ true : this is the "no Weierstrass" case * feeSigVerifyNoProj false : this is redefined to feeSigVerify */ feeReturn feeSigVerifyNoProj(feeSig sig, const unsigned char *data, unsigned dataLen, feePubKey pubKey) { giant Q = NULL; giant messageGiant = NULL; giant scratch = NULL; sigInst *sinst = (sigInst*) sig; feeReturn frtn; curveParams *cp; key origKey; // may be plus or minus key if(sinst->PmX == NULL) { dbgLog(("sigVerify without parse!\n")); frtn = FR_IllegalArg; goto out; } cp = feePubKeyCurveParams(pubKey); Q = newGiant(cp->maxDigits); /* * pick a key (+/-) * Q := P1 */ if(SIG_CURVE == CURVE_PLUS) { origKey = feePubKeyPlusCurve(pubKey); gtog(cp->x1Plus, Q); } else { origKey = feePubKeyMinusCurve(pubKey); gtog(cp->x1Minus, Q); } messageGiant = giant_with_data(data, dataLen); // M(ciphertext) /* Q := u 'o' P1 */ elliptic_simple(Q, sinst->u, cp); /* scratch := theirPub */ scratch = newGiant(cp->maxDigits); gtog(origKey->x, scratch); #if SIG_DEBUG if(sigDebug) { printf("verify origKey:\n"); printKey(origKey); printf("messageGiant: "); printGiant(messageGiant); printf("curveParams:\n"); printCurveParams(cp); } #endif // SIG_DEBUG /* scratch := M 'o' theirPub */ elliptic_simple(scratch, messageGiant, cp); #if SIG_DEBUG if(sigDebug) { printf("signature_compare, with\n"); printf("p0 = Q:\n"); printGiant(Q); printf("p1 = Pm:\n"); printGiant(sinst->PmX); printf("p2 = scratch = R:\n"); printGiant(scratch); } #endif // SIG_DEBUG if(signature_compare(Q, sinst->PmX, scratch, cp)) { frtn = FR_InvalidSignature; #if LOG_BAD_SIG printf("***yup, bad sig***\n"); #endif // LOG_BAD_SIG } else { frtn = FR_Success; } out: if(messageGiant != NULL) { freeGiant(messageGiant); } if(Q != NULL) { freeGiant(Q); } if(scratch != NULL) { freeGiant(scratch); } return frtn; }
/* * Sign specified block of data (most likely a hash result) using * specified feePubKey. */ feeReturn feeSigSign(feeSig sig, const unsigned char *data, // data to be signed unsigned dataLen, // in bytes feePubKey pubKey) { sigInst *sinst = (sigInst*) sig; giant messageGiant = NULL; unsigned maxlen; giant privGiant; unsigned privGiantBytes; feeReturn frtn = FR_Success; unsigned randBytesLen; unsigned uDigits; // alloc'd digits in sinst->u curveParams *cp; if(pubKey == NULL) { return FR_BadPubKey; } cp = feePubKeyCurveParams(pubKey); if(cp == NULL) { return FR_BadPubKey; } privGiant = feePubKeyPrivData(pubKey); if(privGiant == NULL) { dbgLog(("Attempt to Sign without private data\n")); frtn = FR_IllegalArg; goto abort; } privGiantBytes = abs(privGiant->sign) * GIANT_BYTES_PER_DIGIT; /* * Note PmX = m 'o' P1. * Get message/digest as giant. May be significantly different * in size from pubKey's basePrime. */ messageGiant = giant_with_data(data, dataLen); // M(text) randBytesLen = feePubKeyBitsize(pubKey) / 8; maxlen = max(randBytesLen, dataLen); /* leave plenty of room.... */ uDigits = (3 * (privGiantBytes + maxlen)) / GIANT_BYTES_PER_DIGIT; sinst->u = newGiant(uDigits); gtog(privGiant, sinst->u); // u := ourPri mulg(messageGiant, sinst->u); // u *= M(text) addg(sinst->randGiant, sinst->u); // u += m /* * Paranoia: we're using the curveParams from the caller's pubKey; * this cp will have a valid x1OrderPlusRecip if pubKey is the same * as the one passed to feeSigNewWithKey() (since feeSigNewWithKey * called x1OrderPlusJustify()). But the caller could conceivably be * using a different instance of their pubKey, in which case * the key's cp->x1OrderPlusRecip may not be valid. */ calcX1OrderPlusRecip(cp); /* u := u mod x1OrderPlus */ #if SIG_DEBUG if(sigDebug) { printf("sigSign:\n"); printf("u pre-modg : "); printGiant(sinst->u); } #endif modg_via_recip(cp->x1OrderPlus, cp->x1OrderPlusRecip, sinst->u); #if SIG_DEBUG if(sigDebug) { printf("privGiant : "); printGiant(privGiant); printf("u : "); printGiant(sinst->u); printf("messageGiant: "); printGiant(messageGiant); printf("curveParams :\n"); printCurveParams(cp); } #endif // SIG_DEBUG abort: if(messageGiant) { freeGiant(messageGiant); } return frtn; }
giant borrowGiant(unsigned numDigits) { giant result; #if GIANTS_VIA_STACK unsigned stackNum; gstack *gs = gstacks; #if WARN_ZERO_GIANT_SIZE if(numDigits == 0) { printf("borrowGiant(0)\n"); numDigits = gstacks[numGstacks-1].numDigits; } #endif // WARN_ZERO_GIANT_SIZE /* * Find appropriate stack */ if(numDigits <= MIN_GIANT_SIZE) stackNum = 0; else if (numDigits <= (MIN_GIANT_SIZE << GIANT_SIZE_INCR)) stackNum = 1; else if (numDigits <= (MIN_GIANT_SIZE << (2 * GIANT_SIZE_INCR))) stackNum = 2; else if (numDigits <= (MIN_GIANT_SIZE << (3 * GIANT_SIZE_INCR))) stackNum = 3; else if (numDigits <= (MIN_GIANT_SIZE << (4 * GIANT_SIZE_INCR))) stackNum = 4; else stackNum = numGstacks; if(stackNum >= numGstacks) { /* * out of bounds; just malloc */ #if LOG_GIANT_STACK_OVERFLOW gstackDbg(("giantFromStack overflow; numDigits %d\n", numDigits)); #endif // LOG_GIANT_STACK_OVERFLOW return newGiant(numDigits); } gs = &gstacks[stackNum]; #if GIANT_MAC_DEBUG if((gs->numFree != 0) && (gs->stack == NULL)) { dblog0("borrowGiant: null stack!\n"); } #endif if(gs->numFree != 0) { result = gs->stack[--gs->numFree]; } else { /* * Stack empty; malloc */ result = newGiant(gs->numDigits); } #else /* GIANTS_VIA_STACK */ result = newGiant(numDigits); #endif /* GIANTS_VIA_STACK */ PROF_INCR(numBorrows); return result; }
int main(int argc, char **argv) { int arg; char *argp; giant *g1; giant *g2; // ditto unsigned char *buf; // random data unsigned numDigits; unsigned i; unsigned numBytes; unsigned mulgElapsed; unsigned sqrElapsed; int loops = LOOPS_DEF; int seedSpec = 0; unsigned seed = 0; unsigned maxSize = MAX_SIZE_DEF; unsigned minSize = MIN_SIZE_DEF; int useOld = 0; 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 'o': useOld = 1; break; case 's': seed = atoi(&argp[2]); seedSpec = 1; break; case 'h': default: usage(argv); } } buf = malloc(maxSize); if(!seedSpec) { unsigned long tim; time(&tim); seed = (unsigned)tim; } SRAND(seed); /* * Scratch giants, big enough for anything. Malloc here, init with * random data before each test * note these mallocs will be too big in the useOld case... */ g1 = malloc(sizeof(giant) * loops); g2 = malloc(sizeof(giant) * loops); if((g1 == NULL) || (g2 == NULL)) { printf("malloc error\n"); exit(1); } if(useOld) { numDigits = ((2 * maxSize) + 1) / 2; } else { numDigits = BYTES_TO_GIANT_DIGITS(2 * maxSize); } for(i=0; i<loops; i++) { g1[i] = newGiant(numDigits); g2[i] = newGiant(numDigits); if((g1[i] == NULL) || (g2[i] == NULL)) { printf("malloc error\n"); exit(1); } } printf("Starting giants test: seed %d\n", seed); for(numBytes=minSize; numBytes<=maxSize; numBytes*=2) { initRandGiants(numBytes, buf, loops, g1, g2); mulgElapsed = mulgTest(loops, g1, g2); initRandGiants(numBytes, buf, loops, g1, g2); sqrElapsed = squareTest(loops, g1, g2); printf(" bits : %4d mulg : %3d ns gsquare : %3d ns\n", numBytes * 8, mulgElapsed / loops, sqrElapsed / loops); } /* for numBytes */ return 0; }
/* * 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; }
/* * cons up: * cluePlus(0) * clueMinus(0) * sPlus * sMinus * r * Assumes: * cluePlus = clueMinus = ourPriv * theirPub * initialRS * initialRSSize * cp * * Called at feeFEEDNewWithPubKey while encrypting, or upon decrypting * first block of data. */ static feeReturn initFromRS(feedInst *finst) { giant s; unsigned rSize = finst->initialRSSize / 2; #if FEED_DEBUG if((finst->initialRS == NULL) || (finst->cp == NULL) || (finst->cluePlus == NULL) || (finst->clueMinus == NULL) || (finst->initialRSSize == 0)) { dbgLog(("initFromRS: resource shortage\n")); return FR_Internal; } #endif // FEED_DEBUG finst->r = giant_with_data(finst->initialRS, rSize); s = giant_with_data(finst->initialRS+rSize, rSize); #if FEED_DEBUG if(isZero(finst->r)) { printf("initFromRS: r = 0! initialRSSize = %d; encr = %s\n", finst->initialRSSize, (finst->rsCtext == NULL) ? "TRUE" : "FALSE"); } if(isZero(s)) { printf("initFromRS: s = 0! initialRSSize = %d; encr = %s\n", finst->initialRSSize, (finst->rsCtext == NULL) ? "TRUE" : "FALSE"); } #endif // FEE_DEBUG /* * Justify r and s to be in [2, minimumX1Order]. */ lesserX1OrderJustify(finst->r, finst->cp); lesserX1OrderJustify(s, finst->cp); /* * sPlus = s * x1Plus * sMinus = s * x1Minus */ finst->sPlus = newGiant(finst->cp->maxDigits); finst->sMinus = newGiant(finst->cp->maxDigits); gtog(finst->cp->x1Plus, finst->sPlus); elliptic_simple(finst->sPlus, s, finst->cp); gtog(finst->cp->x1Minus, finst->sMinus); elliptic_simple(finst->sMinus, s, finst->cp); /* * And finally, the initial clues. They are currently set to * ourPriv * theirPub. */ #if FEED_DEBUG printf("cluePlus : "); printGiant(finst->cluePlus); printf("clueMinus: "); printGiant(finst->clueMinus); #endif // FEED_EEBUG elliptic_simple(finst->cluePlus, finst->r, finst->cp); elliptic_simple(finst->clueMinus, finst->r, finst->cp); #if FEED_DEBUG printf("r : "); printGiant(finst->r); printf("s : "); printGiant(s); printf("sPlus : "); printGiant(finst->sPlus); printf("sMinus : "); printGiant(finst->sMinus); printf("cluePlus : "); printGiant(finst->cluePlus); printf("clueMinus: "); printGiant(finst->clueMinus); #endif // FEED_DEBUG freeGiant(s); return FR_Success; }