void cpMontRedAdc_BNU(BNU_CHUNK_T* pR, BNU_CHUNK_T* pProduct, const BNU_CHUNK_T* pModulus, cpSize nsM, BNU_CHUNK_T m0) { BNU_CHUNK_T carry; BNU_CHUNK_T extension; cpSize n; for(n=0, carry = 0; n<(nsM-1); n++) { BNU_CHUNK_T u = pProduct[n]*m0; BNU_CHUNK_T t = pProduct[nsM +n +1] + carry; extension = cpAddMulDgt_BNU(pProduct+n, pModulus, nsM, u); ADD_AB(carry, pProduct[nsM+n], pProduct[nsM+n], extension); t += carry; carry = t<pProduct[nsM+n+1]; pProduct[nsM+n+1] = t; } m0 *= pProduct[nsM-1]; extension = cpAddMulDgt_BNU(pProduct+nsM-1, pModulus, nsM, m0); ADD_AB(extension, pProduct[2*nsM-1], pProduct[2*nsM-1], extension); carry |= extension; carry -= cpSub_BNU(pR, pProduct+nsM, pModulus, nsM); /* condition copy: R = carry? Product+mSize : R */ MASKED_COPY_BNU(pR, carry, pProduct+nsM, pR, nsM); }
/* Function cpInc_BNU - increment BigNumber */ BNU_CHUNK_T cpInc_BNU(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize ns, BNU_CHUNK_T val) { cpSize i; for(i=0; i<ns && val; i++) { BNU_CHUNK_T carry; ADD_AB(carry, pR[i], pA[i], val); val = carry; } if(pR!=pA) for(; i<ns; i++) pR[i] = pA[i]; return val; }
BNU_CHUNK_T cpSqrAdc_BNU_school(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize nsA) { cpSize i; BNU_CHUNK_T extension; BNU_CHUNK_T rH, rL; /* init result */ pR[0] = 0; for(i=1, extension=0; i<nsA; i++) { MUL_AB(rH, rL, pA[i], pA[0]); ADD_AB(extension, pR[i], rL, extension); extension += rH; } pR[i] = extension; /* add other a[i]*a[j] */ for(i=1; i<nsA-1; i++) { BNU_CHUNK_T a = pA[i]; cpSize j; for(j=i+1, extension=0; j<nsA; j++) { MUL_AB(rH, rL, pA[j], a); ADD_ABC(extension, pR[i+j], rL, pR[i+j], extension); extension += rH; } pR[i+j] = extension; } /* double a[i]*a[j] */ for(i=1, extension=0; i<(2*nsA-1); i++) { ADD_ABC(extension, pR[i], pR[i], pR[i], extension); } pR[i] = extension; /* add a[i]^2 */ for(i=0, extension=0; i<nsA; i++) { MUL_AB(rH, rL, pA[i], pA[i]); ADD_ABC(extension, pR[2*i], pR[2*i], rL, extension); ADD_ABC(extension, pR[2*i+1], pR[2*i+1], rH, extension); } return pR[2*nsA-1]; }