void BigIntAdd(BIGINT *a, BIGINT *b) { _iA = a->ptrLSB; _xA = a->ptrMSBMax; _iB = b->ptrLSB; _xB = BigIntMSB(b); addBI(); // Invalidate MSB pointer a->bMSBValid = 0; }
void BigIntMod(BIGINT *n, BIGINT* m) { BIGINT_DATA_TYPE *ptrMSBn, MSBm; BIGINT_DATA_TYPE_2 qHatInt; union { BIGINT_DATA_TYPE v[2]; BIGINT_DATA_TYPE_2 Val; } topTwoWords; // Find the starting MSBs ptrMSBn = BigIntMSB(n); MSBm = *BigIntMSB(m); // Set up assembly pointers for m // _iB and _xB are limiters in the _mas function _iB = m->ptrLSB; _xB = BigIntMSB(m); // Find out how many bytes we need to shift and move the LSB up _iR = n->ptrLSB + (BigIntMagnitudeDifference(n, m) - 1); // This loops while the order of magnitude (in words) of n > m // Each iteration modulos off one word of magnitude from n while(_iR >= n->ptrLSB) { // Find qHat = MSBn:MSBn-1/MSBm topTwoWords.Val = *((BIGINT_DATA_TYPE_2*)(ptrMSBn - 1)); qHatInt = topTwoWords.Val / MSBm; if(qHatInt > BIGINT_DATA_MAX) qHatInt = BIGINT_DATA_MAX; #if BIGINT_DEBUG putrsUART("\r\n\r\n n = "); BigIntPrint(n); putrsUART("\r\n m = "); BigIntPrint(m); putrsUART("\r\n qHat ("); putulhexUART(qHatInt); putrsUART(") = topTwo("); putulhexUART(topTwoWords.Val); putrsUART(") / ("); putulhexUART(MSBm); putrsUART(") "); #endif // Once qHat is determined, we multiply M by qHat, shift it up // as many bytes as possible, and subtract the result. // In essence, qHat is a rough estimation of the quotient, divided // by a power of 2^8 (PIC18) or 2^16 (PIC24/dsPIC) or 2^32 (PIC32) // This implementation multiplies and subtracts in the same step // using a _mas function which saves about 30% of clock cycles. // Save the old MSB and set up the ASM pointers _wC = (BIGINT_DATA_TYPE)qHatInt; // Do the multiply and subtract // Occassionally this results in underflow...this is solved below. masBI(); // qHat may have been 1 or 2 greater than possible. If so, // the new MSB will be greater than the old one, so we *add* // M back to N in the shifted position until overflow occurs // and this case corrects itself. while(topTwoWords.v[1] < *BigIntMSB(n)) // while(((BIGINT_DATA_TYPE*)&topTwoWords)[1] < *BigIntMSB(n)) { _iA = _iR; _xA = BigIntMSB(n); addBI(); } // We should have modulated off a word (or two if we were lucky), // so move our MSB and LSB pointers as applicable while(*ptrMSBn == 0x0u) { _iR--; n->ptrMSB--; ptrMSBn--; } } // Iteration of the _mas function can only handle full-byte orders // of magnitude. The result may still be a little larger, so this // cleans up the last few multiples with simple subtraction. while(BigIntCompare(n, m) >= 0) { _iA = n->ptrLSB; _xA = n->ptrMSB; subBI(); // Invalidate MSB pointer n->bMSBValid = 0; } }
SigNat sign(PublicKey group, RogueKey rogue, Secret secret, Cert cert, Message msg) { char bsn[MAX_CHAR_ARRAY_LENGTH], m[MAX_CHAR_ARRAY_LENGTH]; char error[MAX_CHAR_ARRAY_LENGTH],c_h[MAX_CHAR_ARRAY_LENGTH]; char hash[MAX_CHAR_ARRAY_LENGTH], inner[MAX_CHAR_ARRAY_LENGTH]; BigInt n_v, c, sv, sf0, sf1, se, see, sew, sr, ser, sw; Origin b; BigInt n,gPrime,g,h,r0,r1,s; BigInt biga,e, p2; BigInt f0,f1,v; Tuple wr,rf0rf1,rwrr,rewrer; BigInt bigt1, bigt2, temp1, temp2, temp3, temp4, temp5, temp6, temp7, w, r; BigInt zeta,bign_V,rf0,rf1, rv, bigt2inv, tilde_TPrime2,n_t; BigInt tilde_T1t, tilde_rf, tilde_N_V,rw,rr,re,ree,rew, rer,hinv, tilde_T1, tilde_T2; Hash hashPub, hashHost ,hashTpm1, hashTpm2; Responses ss; SigNat signat; strcpy(bsn,msg.bsn); strcpy(m,msg.m); b = msg.b; n_v = msg.n_v; if(noOfBits(n_v) > hash_bits){ strcpy(error,"n_v out of bounds"); Abort(error); } n=group.n; gPrime=group.gPrime; g=group.g; h=group.h; r0=group.r0; r1=group.r1; s=group.s; biga = cert.biga; e = cert.e; f0 = secret.f; f1=secret.s; v=secret.t; wr = pick2(rsa_modulus_bits+distribution_bits); w = wr.r; r = wr.m; bigt1 = BImodMult(biga,BImodPower(h,wr.r,n),n); temp1 = BIpower(g,w); temp2 = BIpower(h,e); temp3 = BIpower(gPrime,r); temp4 = BImul(temp1, temp2); temp5 = BImul(temp4, temp3); bigt2 = BImod(temp5,n); zeta = base(bsn,rogue); bign_V = tag(rogue,zeta,f0,f1); rv = pick(random_bits+distribution_bits+hash_bits); rf0rf1 = pick2(halfkeyBits+distribution_bits+hash_bits); rf0 = rf0rf1.r; rf1 = rf0rf1.m; temp1 = BIpower(r0,rf0); temp2 = BIpower(r1,rf1); temp3 = BIpower(s,rv); temp4 = BImul(temp1, temp2); temp5 = BImul(temp4, temp3); tilde_T1t = BImod(temp5,n); temp1 = BIshiftLeft(rf1,halfkeyBits); temp2 = BIadd(rf0, temp1); tilde_rf = BImod(temp2,rogue.rho); tilde_N_V = BImodPower(zeta,tilde_rf,rogue.bigGamma); re = pick(prime_random_bits+distribution_bits+hash_bits); ree = pick(2*prime_total_bits+distribution_bits+hash_bits+1); rwrr = pick2(rsa_modulus_bits+2*distribution_bits+hash_bits); rw = rwrr.r; rr = rwrr.m; rewrer = pick2(prime_total_bits+rsa_modulus_bits+2*distribution_bits+hash_bits+1); rew = rewrer.r; rer = rewrer.m; hinv = BImodInv(h,n); temp1 = tilde_T1t; temp2 = BIpower(bigt1,re); temp3 = BIpower(hinv,rew); temp4 = BImul(temp1, temp2); temp5 = BImul(temp4, temp3); tilde_T1 = BImod(temp5,n); temp1 = BIpower(g,rw); temp2 = BIpower(h,re); temp3 = BIpower(gPrime,rr); temp4 = BImul(temp1, temp2); temp5 = BImul(temp4, temp3); tilde_T2 = BImod(temp5,n); bigt2inv = BImodInv(bigt2,n); temp1 = BIpower(bigt2inv,re); temp2 = BIpower(g,rew); temp3 = BIpower(h,ree); temp4 = BIpower(gPrime,rer); temp5 = BImul(temp1, temp2); temp6 = BImul(temp5, temp3); temp7 = BImul(temp6, temp4); tilde_TPrime2 = BImod(temp7,n); //hash public inputs hashPub = getSha1Hash(); addBI(&hashPub,group.n); addBI(&hashPub,group.g); addBI(&hashPub,group.gPrime); addBI(&hashPub,group.h); addBI(&hashPub,group.r0); addBI(&hashPub,group.r1); addBI(&hashPub,group.s); addBI(&hashPub,group.z); addBI(&hashPub,rogue.gamma); addBI(&hashPub,rogue.bigGamma); addBI(&hashPub,rogue.rho); addBI(&hashPub,zeta); addBI(&hashPub,bigt1); addBI(&hashPub,bigt2); addBI(&hashPub,bign_V); strcpy(hash,hashResult(hashPub)); //hash host inputs hashHost = getSha1Hash(); addBI(&hashHost,tilde_T1); addBI(&hashHost,tilde_T2); addBI(&hashHost,tilde_TPrime2); addBI(&hashHost,tilde_N_V); addBI(&hashHost,n_v); strcpy(c_h,hashResult(hashHost)); n_t = pick(distribution_bits); hashTpm1 = getSha1Hash(); addBytes(&hashTpm1,c_h); addBI(&hashTpm1,n_t); strcpy(inner,hashResult(hashTpm1)); hashTpm2 = getSha1Hash(); addBytes(&hashTpm2,inner); if(b == Card) addByte(&hashTpm2,0); else if (b == Verifier) addByte(&hashTpm2,1); else ; addBytes(&hashTpm2, m); c = BItoNumber(hashResult(hashTpm2)); sv = rval(rv,v,c); sf0 = rval(rf0,f0,c); sf1 = rval(rf1,f1,c); p2 = BIshiftLeft(BItoNumber("1"),prime_total_bits-1); se = rval(re,BIsub(e, p2),c); see = rval(ree,BImul(e,e),c); sw = rval(rw,w,c); sew = rval(rew,BImul(e,w),c); sr = rval(rr,r,c); ser = rval(rer,BImul(e,r),c); ss.sv = sv; ss.sf0 = sf0; ss.sf1 = sf1; ss.se = se; ss.see = see; ss.sw = sw; ss.sew = sew; ss.sr = sr; ss.ser = ser; signat.zeta = zeta; signat.bigt1 = bigt1; signat.bigt2 = bigt2; signat.bign_V = bign_V; signat.c = c; signat.n_t = n_t; signat.ss = ss; return signat; }