void printCurveParams(const curveParams *p)
{
	const char *pt;
	const char *ct;
	
	switch(p->primeType) {
	    case FPT_Mersenne:
	    	pt = "FPT_Mersenne";
		break;
	    case FPT_FEE:
	    	pt = "FPT_FEE";
		break;
	    case FPT_General:
	    	pt = "FPT_General";
		break;
	    default:
	    	pt = "UNKNOWN!";
		break;
	}
	switch(p->curveType) {
		case FCT_Montgomery:
			ct = "FCT_Montgomery";
			break;
		case FCT_Weierstrass:
			ct = "FCT_Weierstrass";
			break;
		case FCT_General:
			ct = "FCT_General";
			break;
	    default:
	    	ct = "UNKNOWN!";
			break;
	}
	printf("  q %d   k %d   primeType %s  curveType %s\n",
		p->q, p->k, pt, ct);
	printf("  minBytes %d  maxDigits %d\n", p->minBytes, p->maxDigits);
	printf("  a           : ");
	printGiant(p->a);
	printf("  b           : ");
	printGiant(p->b);
	printf("  c           : ");
	printGiant(p->c);
	printf("  basePrime   : ");
	printGiant(p->basePrime);
	printf("  x1Plus      : ");
	printGiant(p->x1Plus);
	printf("  x1Minus     : ");
	printGiant(p->x1Minus);
	printf("  cOrderPlus  : ");
	printGiant(p->cOrderPlus);
	printf("  cOrderMinus : ");
	printGiant(p->cOrderMinus);
	printf("  x1OrderPlus : ");
	printGiant(p->x1OrderPlus);
	printf("  x1OrderMinus: ");
	printGiant(p->x1OrderMinus);
}
/*
 * Obtain Pm after feeSigNewWithKey() or feeSigParse()
 */
unsigned char *feeSigPm(feeSig sig,
	unsigned *PmLen)
{
	sigInst *sinst = (sigInst*) sig;
	unsigned char *Pm;

	if(sinst->PmX == NULL) {
		dbgLog(("feeSigPm: no PmX!\n"));
		return NULL;
	}
	else {
		Pm = mem_from_giant(sinst->PmX, PmLen);
		#if	SIG_DEBUG
		if(sigDebug)
		{
		    int i;

		    printf("Pm : "); printGiant(sinst->PmX);
		    printf("PmData: ");
		    for(i=0; i<*PmLen; i++) {
		        printf("%x:", Pm[i]);
		    }
		    printf("\n");
		}
		#endif	// SIG_DEBUG
	}
	return Pm;
}
void printPubKey(feePubKey pubKey)
{
	pubKeyInst *pkinst = pubKey;

	printf("\ncurveParams:\n");
	printCurveParams(pkinst->cp);
	printf("plus:\n");
	printKey(pkinst->plus);
	printf("minus:\n");
	printKey(pkinst->minus);
	if(pkinst->privGiant != NULL) {
	    printf("privGiant : ");
	    printGiant(pkinst->privGiant);
	}
}
/*
 * 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;
}
feeReturn feeSigVerify(feeSig sig,
	const unsigned char *data,
	unsigned dataLen,
	feePubKey pubKey)
{
	pointProjStruct Q;
	giant 		messageGiant = NULL;
	pointProjStruct	scratch;
	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"));
		return FR_IllegalArg;
	}

	cp = feePubKeyCurveParams(pubKey);
	if(cp->curveType != FCT_Weierstrass) {
		return feeSigVerifyNoProj(sig, data, dataLen, pubKey);
	}

	borrowPointProj(&Q, cp->maxDigits);
	borrowPointProj(&scratch, cp->maxDigits);

	/*
	 * Q := P1
	 */
	gtog(cp->x1Plus, Q.x);
	gtog(cp->y1Plus, Q.y);
	int_to_giant(1, Q.z);

	messageGiant = 	giant_with_data(data, dataLen);	// M(ciphertext)

	/* Q := u 'o' P1 */
	ellMulProjSimple(&Q, sinst->u, cp);

	/* scratch := theirPub */
	origKey = feePubKeyPlusCurve(pubKey);
	gtog(origKey->x, scratch.x);
	gtog(origKey->y, scratch.y);
	int_to_giant(1, scratch.z);

	#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 */
	ellMulProjSimple(&scratch, messageGiant, cp);

	#if	SIG_DEBUG
	if(sigDebug) {
		printf("signature_compare, with\n");
		printf("p0 = Q:\n");
		printGiant(Q.x);
		printf("p1 = Pm:\n");
		printGiant(sinst->PmX);
		printf("p2 = scratch = R:\n");
		printGiant(scratch.x);
	}
	#endif	// SIG_DEBUG

	if(signature_compare(Q.x, sinst->PmX, scratch.x, cp)) {

		frtn = FR_InvalidSignature;
		#if	LOG_BAD_SIG
		printf("***yup, bad sig***\n");
		#endif	// LOG_BAD_SIG
	}
	else {
		frtn = FR_Success;
	}
	freeGiant(messageGiant);

    	returnPointProj(&Q);
    	returnPointProj(&scratch);
	return frtn;
}
/*
 * Obtain a feeSig object by parsing an existing signature block.
 * Note that if Pm is used to salt a hash of the signed data, this must
 * function must be called prior to hashing.
 */
feeReturn feeSigParse(const unsigned char *sigData,
	size_t sigDataLen,
	feeSig *sig)				// RETURNED
{
	sigInst		*sinst = NULL;
	feeReturn	frtn;
	#if	!CRYPTKIT_DER_ENABLE
	int			version;
	int			magic;
	int			minVersion;
	int			rtn;
	#endif
	
	sinst = sinstAlloc();
	#if		CRYPTKIT_DER_ENABLE
	frtn = feeDERDecodeElGamalSignature(sigData, sigDataLen, &sinst->u, &sinst->PmX);
	if(frtn) {
		goto abort;
	}
	#else
	rtn = byteRepToSig(sigData,
		sigDataLen,
		FEE_SIG_VERSION,
		&magic,
		&version,
		&minVersion,
		&sinst->u,
		&sinst->PmX);
	if(rtn == 0) {
		frtn = FR_BadSignatureFormat;
		goto abort;
	}
	switch(magic) {
	    case FEE_ECDSA_MAGIC:
	    	frtn = FR_WrongSignatureType;		// ECDSA!
		goto abort;
	    case FEE_SIG_MAGIC:
	    	break;					// proceed
	    default:
	    	frtn = FR_BadSignatureFormat;
		goto abort;
	}
	#endif		/* CRYPTKIT_DER_ENABLE */
	
	#if	SIG_DEBUG
	if(sigDebug) {
		printf("sigParse: \n");
		printf("u: ");
		printGiant(sinst->u);
	}
	#endif	// SIG_DEBUG

	*sig = sinst;
	return FR_Success;

abort:
	if(sinst) {
		feeSigFree(sinst);
	}
	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;
}
Example #8
0
/*
 * Decrypt (exactly) a block of data. Caller malloc's plainText. Always
 * generates feeFEEDPlainBlockSize of plaintext, unless finalBlock is
 * non-zero (in which case feeFEEDPlainBlockSize or less bytes of plainText are
 * generated).
 */
feeReturn feeFEEDDecryptBlock(feeFEED feed,
	const unsigned char *cipherText,
	unsigned cipherTextLen,
	unsigned char *plainText,
	unsigned *plainTextLen,			// RETURNED
	int finalBlock)
{
	feedInst 	*finst = (feedInst *) feed;
	feeReturn	frtn = FR_Success;
	unsigned char	clueByte;
	giant		thisClue;		// not alloc'd
	giant		thisS;			// ditto
	int 		parity;

	if(finst->rsCtext == NULL) {
		/*
		 * Init'd for encrypt?
		 */
		return FR_IllegalArg;
	}
	if(cipherTextLen != finst->cipherBlockSize) {
	 	dbgLog(("feeFEEDDecryptBlock: bad cipherTextLen\n"));
		return FR_IllegalArg;
	}
	if(finst->rsBlockCount < finst->rsSizeCipherBlocks) {
		/*
		 * Processing initialRS, FEEDExp-encrypted
		 */
		unsigned char *rsPtr = finst->rsCtext +
			(finst->rsBlockCount * finst->cipherBlockSize);
		unsigned feedExpCipherSize;

		if(finalBlock) {
		    dbgLog(("feeFEEDDecryptBlock: incomplete initialRS\n"));
		    return FR_BadCipherText;
		}
		bcopy(cipherText, rsPtr, finst->cipherBlockSize);
		finst->rsBlockCount++;
		if(finst->rsBlockCount < finst->rsSizeCipherBlocks) {
		    /*
		     * Not done with this yet...
		     */
			bprintf(("=== FEED Decrypt: gobbled 0x%x bytes ctext, no ptext (1)\n", 
				cipherTextLen));
		    *plainTextLen = 0;
		    return FR_Success;
		}

		#if	FEED_DEBUG
		if((finst->rsBlockCount * finst->cipherBlockSize) <
				finst->rsCtextSize) {
		    dbgLog(("feeFEEDDecryptBlock: rsCtextSize underflow!\n"));
		    return FR_Internal;
		}
		#endif	// FEED_DEBUG

		/*
		 * OK, we should have the FEEDExp ciphertext for initialRS
		 * in rsCtext. Note the last few bytes are extra; we don't
		 * pass them to FEEDExp.
		 */
		feedExpCipherSize = feeFEEDCipherBlockSize(finst->feedExp);
		frtn = feeFEEDExpDecrypt(finst->feedExp,
			finst->rsCtext,
			finst->rsCtextSize,
			&finst->initialRS,
			&finst->initialRSSize);
		if(frtn) {
   		    dbgLog(("feeFEEDDecryptBlock: error decrypting "
		    	"initialRS (%s)\n", feeReturnString(frtn)));
		    return FR_BadCipherText;
		}

		/*
		 * we already know how long this should be...
		 */
		if(finst->initialRSSize != finst->initialRSSize) {
   		    dbgLog(("feeFEEDDecryptBlock: initialRS sync error\n"));
		    return FR_BadCipherText;
		}

		/*
		 * Set up clues
		 */
		if(initFromRS(finst)) {
   		    dbgLog(("feeFEEDDecryptBlock: bad initialRS\n"));
		    return FR_BadCipherText;
		}
		else {
		    /*
		     * Normal completion of last cipherblock containing
		     * initialRS.
		     */
			bprintf(("=== FEED Decrypt: gobbled 0x%x bytes ctext, no ptext (2)\n", 
				cipherTextLen));
		    *plainTextLen = 0;
		    return FR_Success;
		}
	}

	/*
	 * grab xm and clueByte from cipherText
	 */
	deserializeGiant(cipherText, finst->xm, finst->cp->minBytes);
	cipherText += finst->cp->minBytes;
	clueByte = *cipherText;

	if((clueByte & CLUE_BIT) == CLUE_PLUS) {
		thisClue = finst->cluePlus;
		thisS = finst->sPlus;
	}
	else {
		thisClue = finst->clueMinus;
		thisS = finst->sMinus;
	}
	if((clueByte & PARITY_BIT) == PARITY_PLUS) {
		parity = SIGN_PLUS;
	}
	else {
		parity = SIGN_MINUS;
	}

	/*
	 * recover xp
	 *     xp = xm + clue(+/-) w/parity
	 * adjust clue
	 *     clue[n+1] = r * clue[n] + (s * P1)
	 */
	elliptic_add(thisClue, finst->xm, finst->xp, finst->cp, parity);

	elliptic_simple(thisClue, finst->r, finst->cp);
	gtog(thisClue, finst->tmp1);
	elliptic_add(finst->tmp1, thisS, thisClue, finst->cp, SIGN_PLUS);

	/*
	 * plaintext in xp
	 */
	#if	FEED_DEBUG
	printf("decrypt  clue %d\n", clueByte);
	printf("  xp : "); printGiant(finst->xp);
	printf("  xm : "); printGiant(finst->xm);
	printf("  cluePlus  :"); printGiant(finst->cluePlus);
	printf("  clueMinus :"); printGiant(finst->clueMinus);
	#endif	// FEED_DEBUG

	if(finalBlock) {
		/*
		 * Snag data from xp in order to find out how much to move to
		 * *plainText
		 */
		unsigned char *ptext = (unsigned char*) fmalloc(finst->plainBlockSize);

		serializeGiant(finst->xp, ptext, finst->plainBlockSize);
		*plainTextLen = ptext[finst->plainBlockSize - 1];
		if(*plainTextLen == RESID_ZERO) {
			bprintf(("=== FEED Decrypt: RESID_ZERO\n"));
			*plainTextLen = 0;
		}
		else if(*plainTextLen > (finst->plainBlockSize - 1)) {
			dbgLog(("feeFEEDDecryptBlock: ptext overflow!\n"));
			bprintf(("feeFEEDDecryptBlock: ptext overflow!\n"));
			frtn = FR_BadCipherText;
		}
		else {
			bprintf(("=== FEED Decrypt: resid len 0x%x\n", *plainTextLen));
			bcopy(ptext, plainText, *plainTextLen);
		}
		ffree(ptext);
	}
	else {
		*plainTextLen = finst->plainBlockSize;
		serializeGiant(finst->xp, plainText, *plainTextLen);
	}
	bprintf(("=== FEED decryptBlock ptextLen 0x%x  ctextLen 0x%x\n",
		*plainTextLen, cipherTextLen));

	return frtn;
}
Example #9
0
/*
 * Encrypt a block or less of data. Caller malloc's cipherText.
 * Generates up to feeFEEDCipherBufSize() bytes of ciphertext.
 */
feeReturn feeFEEDEncryptBlock(feeFEED feed,
	const unsigned char *plainText,
	unsigned plainTextLen,
	unsigned char *cipherText,
	unsigned *cipherTextLen,		// RETURNED
	int finalBlock)
{
	feedInst 		*finst = (feedInst *) feed;
	unsigned		ctextLen = 0;
	feeReturn		frtn = FR_Success;
	int				whichCurve;
	giant			thisClue;		// not alloc'd or freed
	giant			thisS;			// ditto
	unsigned char	clueByte;

	if(plainTextLen > finst->plainBlockSize) {
		return FR_IllegalArg;
	}
	if((plainTextLen < finst->plainBlockSize) && !finalBlock) {
		return FR_IllegalArg;
	}
	if(finst->initialRS == NULL) {
		/*
		 * Init'd for decrypt?
		 */
		return FR_IllegalArg;
	}

	/*
	 * First block - encrypt initialRS via FEEDExp
	 */
	if(finst->rsBlockCount == 0) {
	    unsigned char *thisCtext;	// malloc's by FEEDExp
	    unsigned padLen;

	    if(finst->initialRS == NULL) {
		/*
		 * init'd for decrypt or reused
		 */
		dbgLog(("feeFEEDEncryptBlock: NULL initialRS!\n"));
		return FR_IllegalArg;
	    }

	    frtn = feeFEEDExpEncrypt(finst->feedExp,
		    finst->initialRS,
		    finst->initialRSSize,
		    &thisCtext,
		    &ctextLen);
	    if(frtn) {
		    /*
		     * Should never happen...
		     */
		    dbgLog(("feeFEEDEncryptBlock: error writing encrypted"
			    " initialRS (%s)\n", feeReturnString(frtn)));
		    return FR_Internal;
	    }
	    bcopy(thisCtext, cipherText, ctextLen);
	    cipherText += ctextLen;
	    ffree(thisCtext);

	    finst->rsBlockCount = finst->rsSizeCipherBlocks;
	    padLen = finst->cipherBlockSize -
	    	(ctextLen % finst->cipherBlockSize);	// zeros to write

	    #if		0	/* FEED_DEBUG */

	    /*
	     * Hard-coded assumptions and tests about initRSSize...
	     * Currently we assume that initRSSize % expBlockSize = 0
	     */
	    if((ctextLen / finst->cipherBlockSize) != 5) {
		dbgLog(("feeFEEDEncryptBlock: cipherblock size screwup (1)\n"));
		return FR_Internal;
	    }
	    if(padLen != 3) {
		dbgLog(("feeFEEDEncryptBlock: cipherblock size screwup (2)\n"));
		return FR_Internal;
	    }
	    #endif	// FEED_DEBUG

	    /*
	     * pad to multiple of (our) cipherblock size.
	     */
	    while(padLen) {
		*cipherText++ = 0;
		ctextLen++;
		padLen--;
	    }
	}

	/*
	 * plaintext to giant xp
	 */
	if(finalBlock) {
		unsigned char *ptext = (unsigned char*) fmalloc(finst->plainBlockSize);
		bzero(ptext, finst->plainBlockSize);
		if(plainTextLen) {
			/*
			 * skip for empty block with resid length 0
			 */
			bcopy(plainText, ptext, plainTextLen);
		}
		if(plainTextLen < finst->plainBlockSize) {
		    if(plainTextLen == 0) {
		    	/*
			 * Special case - resid block with no actual plaintext.
			 * Can't actually write zero here; it screws up
			 * deserializing the giant during decrypt
			 */
		        ptext[finst->plainBlockSize - 1] = RESID_ZERO;
				bprintf(("=== FEED encrypt: RESID_ZERO\n"));
		    }
		    else {
				ptext[finst->plainBlockSize - 1] = plainTextLen;
				bprintf(("=== FEED encrypt: resid len 0x%x\n", plainTextLen));
		    }
		}
		/*
		 * else handle evenly aligned case (i.e., finalBlock true
		 * and (plainTextLen ==  plainBlockSize)) below...
		 */
		deserializeGiant(ptext, finst->xp, finst->plainBlockSize);
		ffree(ptext);
	}
	else {
		deserializeGiant(plainText, finst->xp, plainTextLen);
	}

	/*
	 * encrypt xp
	 *     xm = xp + clue(+/-)
	 * determine parity needed to restore xp
	 *     parity = ((xm + clue(+/-) == xp) ? 1 : -1
	 * and adjust clue
	 *     clue[n+1] = r * clue[n] + (s * P1)
	 */
	whichCurve = which_curve(finst->xp, finst->cp);
	if(whichCurve == CURVE_PLUS) {
		thisClue = finst->cluePlus;
		thisS    = finst->sPlus;
		clueByte = CLUE_PLUS;
	}
	else {
		thisClue = finst->clueMinus;
		thisS    = finst->sMinus;
		clueByte = CLUE_MINUS;
	}
	// calculate xm
	elliptic_add(thisClue, finst->xp, finst->xm, finst->cp, SIGN_PLUS);
	// save xm + clue in tmp1
	elliptic_add(finst->xm, thisClue, finst->tmp1, finst->cp, SIGN_PLUS);
	// Adjust clue
	elliptic_simple(thisClue, finst->r, finst->cp);
	gtog(thisClue, finst->tmp2);
	elliptic_add(finst->tmp2, thisS, thisClue, finst->cp, SIGN_PLUS);

	/*
	 * Calculate parity
	 */
	if(gcompg(finst->tmp1, finst->xp) == 0) {
		clueByte |= PARITY_PLUS;
	}

	/*
	 * Ciphertext = (xm, clueByte)
	 */
	serializeGiant(finst->xm, cipherText, finst->cp->minBytes);
	cipherText += finst->cp->minBytes;
	ctextLen += finst->cp->minBytes;
	*cipherText++ = clueByte;
	ctextLen++;

	#if	FEED_DEBUG
	printf("encrypt  clue %d\n", clueByte);
	printf("  xp : "); printGiant(finst->xp);
	printf("  xm : "); printGiant(finst->xm);
	printf("  cluePlus  :"); printGiant(finst->cluePlus);
	printf("  clueMinus :"); printGiant(finst->clueMinus);
	#endif	// FEED_DEBUG

	if(finalBlock && (plainTextLen == finst->plainBlockSize)) {
	       /*
		* Special case: finalBlock true, plainTextLen == blockSize.
		* In this case we generate one more block of ciphertext,
		* with a resid length of zero.
		*/
		unsigned moreCipher;			// additional cipherLen

		frtn = feeFEEDEncryptBlock(feed,
			NULL,				// plainText not used
			0,				// resid
			cipherText,			// append...
			&moreCipher,
			1);
		if(frtn == FR_Success) {
			ctextLen += moreCipher;
		}
	}
	bprintf(("=== FEED encryptBlock ptextLen 0x%x  ctextLen 0x%x\n",
		plainTextLen, ctextLen));
		
	*cipherTextLen = ctextLen;
	return frtn;
}
Example #10
0
/*
 * 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;
}
void printKey(const key k)
{
	printf("  twist %d\n", k->twist);
	printf("  x: ");
	printGiant(k->x);
}