pcpngrsamontstuff.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /*
  2. * Copyright (C) 2016 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include "owndefs.h"
  32. #include "owncp.h"
  33. #include "pcpscramble.h"
  34. #include "pcpngrsa.h"
  35. #include "pcpngrsamontstuff.h"
  36. /*
  37. // Montgomery engine preparation (GetSize/init/Set)
  38. */
  39. void gsMontGetSize(IppsExpMethod method, int maxLen32, int* pSize)
  40. {
  41. cpSize modSize = INTERNAL_BNU_LENGTH(maxLen32);
  42. UNREFERENCED_PARAMETER(method);
  43. *pSize = sizeof(IppsMontState)
  44. + modSize*sizeof(BNU_CHUNK_T) /* modulus */
  45. + modSize*sizeof(BNU_CHUNK_T) /* identity */
  46. + modSize*sizeof(BNU_CHUNK_T) /* square R */
  47. + modSize*sizeof(BNU_CHUNK_T) /* just to compute R^2 */
  48. + MONT_ALIGNMENT-1;
  49. }
  50. void gsMontInit(IppsExpMethod method, int maxLen32, IppsMontState* pMont)
  51. {
  52. UNREFERENCED_PARAMETER(method);
  53. MNT_ID(pMont) = idCtxMontgomery;
  54. MNT_ROOM(pMont) = INTERNAL_BNU_LENGTH(maxLen32);
  55. MNT_SIZE(pMont) = 0;
  56. MNT_HELPER(pMont) = 0;
  57. MNT_CUBE_R(pMont) = NULL;
  58. MNT_TBUFFER(pMont) = NULL;
  59. MNT_SBUFFER(pMont) = NULL;
  60. MNT_PRODUCT(pMont) = NULL;
  61. MNT_KBUFFER(pMont) = NULL;
  62. {
  63. Ipp8u* ptr = (Ipp8u*)pMont;
  64. /* modulus length in BNU_CHUNK_T */
  65. cpSize modSize = MNT_ROOM(pMont);
  66. /* assign internal buffers */
  67. MNT_MODULUS(pMont) = (BNU_CHUNK_T*)( ptr += sizeof(IppsMontState) );
  68. MNT_1(pMont) = (BNU_CHUNK_T*)( ptr += modSize*sizeof(BNU_CHUNK_T) );
  69. MNT_SQUARE_R(pMont)= (BNU_CHUNK_T*)( ptr += modSize*sizeof(BNU_CHUNK_T) );
  70. /* init internal buffers */
  71. ZEXPAND_BNU(MNT_MODULUS(pMont), 0, modSize);
  72. ZEXPAND_BNU(MNT_1(pMont), 0, modSize);
  73. ZEXPAND_BNU(MNT_SQUARE_R(pMont), 0, modSize);
  74. }
  75. }
  76. static BNU_CHUNK_T cpMontHelper(BNU_CHUNK_T m0)
  77. {
  78. BNU_CHUNK_T y = 1;
  79. BNU_CHUNK_T x = 2;
  80. BNU_CHUNK_T mask = 2*x-1;
  81. int i;
  82. for(i=2; i<=BNU_CHUNK_BITS; i++, x<<=1) {
  83. BNU_CHUNK_T rH, rL;
  84. MUL_AB(rH, rL, m0, y);
  85. if( x < (rL & mask) ) /* x < ((m0*y) mod (2*x)) */
  86. y+=x;
  87. mask += mask + 1;
  88. }
  89. return 0-y;
  90. }
  91. void gsMontSet(const Ipp32u* pModulus, int len32, IppsMontState* pMont)
  92. {
  93. BNU_CHUNK_T m0;
  94. cpSize len;
  95. /* store modulus */
  96. ZEXPAND_COPY_BNU((Ipp32u*)(MNT_MODULUS(pMont)), MNT_ROOM(pMont)*(int)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)), pModulus, len32);
  97. /* store modulus length */
  98. len = INTERNAL_BNU_LENGTH(len32);
  99. MNT_SIZE(pMont) = len;
  100. /* pre-compute helper m0, m0*m = -1 mod R */
  101. m0 = cpMontHelper(MNT_MODULUS(pMont)[0]);
  102. MNT_HELPER(pMont) = m0;
  103. /* setup identity */
  104. ZEXPAND_BNU(MNT_1(pMont), 0, len);
  105. MNT_1(pMont)[len] = 1;
  106. cpMod_BNU(MNT_1(pMont), len+1, MNT_MODULUS(pMont), len);
  107. /* setup square */
  108. ZEXPAND_BNU(MNT_SQUARE_R(pMont), 0, len);
  109. COPY_BNU(MNT_SQUARE_R(pMont)+len, MNT_1(pMont), len);
  110. cpMod_BNU(MNT_SQUARE_R(pMont), 2*len, MNT_MODULUS(pMont), len);
  111. }
  112. /*
  113. // "fast" binary montgomery exponentiation
  114. //
  115. // scratch buffer structure:
  116. // precomutation resource[0]
  117. // copy of base (in case of inplace operation)
  118. // product[nsM*2]
  119. // karatsubaBuffer[gsKaratsubaBufferSize()]
  120. */
  121. cpSize gsMontExpBin_BNU(BNU_CHUNK_T* dataY,
  122. const BNU_CHUNK_T* dataX, cpSize nsX,
  123. const BNU_CHUNK_T* dataE, cpSize nsE,
  124. const IppsMontState* pMont,
  125. BNU_CHUNK_T* pBuffer)
  126. {
  127. cpSize nsM = MNT_SIZE(pMont);
  128. /*
  129. // test for special cases:
  130. // x^0 = 1
  131. // 0^e = 0
  132. */
  133. if( cpEqu_BNU_CHUNK(dataE, nsE, 0) ) {
  134. COPY_BNU(dataY, MNT_1(pMont), nsM);
  135. }
  136. else if( cpEqu_BNU_CHUNK(dataX, nsX, 0) ) {
  137. ZEXPAND_BNU(dataY, 0, nsM);
  138. }
  139. /* general case */
  140. else {
  141. BNU_CHUNK_T* dataM = MNT_MODULUS(pMont);
  142. BNU_CHUNK_T m0 = MNT_HELPER(pMont);
  143. /* allocate buffers */
  144. BNU_CHUNK_T* dataT = pBuffer;
  145. BNU_CHUNK_T* pProduct = dataT+nsM;
  146. BNU_CHUNK_T* pBufferMulK = NULL;
  147. BNU_CHUNK_T* pBufferSqrK = NULL;
  148. /* expand base and init result */
  149. ZEXPAND_COPY_BNU(dataT, nsM, dataX, nsX);
  150. COPY_BNU(dataY, dataT, nsM);
  151. FIX_BNU(dataE, nsE);
  152. /* execute most significant part pE */
  153. {
  154. BNU_CHUNK_T eValue = dataE[nsE-1];
  155. int n = cpNLZ_BNU(eValue)+1;
  156. eValue <<= n;
  157. for(; n<BNU_CHUNK_BITS; n++, eValue<<=1) {
  158. /* squaring R = R*R mod Modulus */
  159. cpMontSqr_BNU(dataY,
  160. dataY, nsM,
  161. dataM, nsM, m0,
  162. pProduct, pBufferSqrK);
  163. /* and multiply R = R*X mod Modulus */
  164. if(eValue & ((BNU_CHUNK_T)1<<(BNU_CHUNK_BITS-1)))
  165. cpMontMul_BNU(dataY,
  166. dataY, nsM,
  167. dataT, nsM,
  168. dataM, nsM, m0,
  169. pProduct, pBufferMulK);
  170. }
  171. /* execute rest bits of E */
  172. for(--nsE; nsE>0; nsE--) {
  173. eValue = dataE[nsE-1];
  174. for(n=0; n<BNU_CHUNK_BITS; n++, eValue<<=1) {
  175. /* squaring: R = R*R mod Modulus */
  176. cpMontSqr_BNU(dataY,
  177. dataY, nsM,
  178. dataM, nsM, m0,
  179. pProduct, pBufferSqrK);
  180. if(eValue & ((BNU_CHUNK_T)1<<(BNU_CHUNK_BITS-1)))
  181. cpMontMul_BNU(dataY,
  182. dataY, nsM,
  183. dataT, nsM,
  184. dataM, nsM, m0,
  185. pProduct, pBufferMulK);
  186. }
  187. }
  188. }
  189. }
  190. return nsM;
  191. }
  192. /*
  193. // "safe" binary montgomery exponentiation
  194. //
  195. // scratch buffer structure:
  196. // sscm[nsM]
  197. // dataT[nsM]
  198. // product[nsM*2]
  199. // karatsubaBuffer[gsKaratsubaBufferSize()]
  200. */
  201. cpSize gsMontExpBin_BNU_sscm(BNU_CHUNK_T* dataY,
  202. const BNU_CHUNK_T* dataX, cpSize nsX,
  203. const BNU_CHUNK_T* dataE, cpSize nsE,
  204. const IppsMontState* pMont,
  205. BNU_CHUNK_T* pBuffer)
  206. {
  207. cpSize nsM = MNT_SIZE(pMont);
  208. /*
  209. // test for special cases:
  210. // x^0 = 1
  211. // 0^e = 0
  212. */
  213. if( cpEqu_BNU_CHUNK(dataE, nsE, 0) ) {
  214. COPY_BNU(dataY, MNT_1(pMont), nsM);
  215. }
  216. else if( cpEqu_BNU_CHUNK(dataX, nsX, 0) ) {
  217. ZEXPAND_BNU(dataY, 0, nsM);
  218. }
  219. /* general case */
  220. else {
  221. BNU_CHUNK_T* dataM = MNT_MODULUS(pMont);
  222. BNU_CHUNK_T m0 = MNT_HELPER(pMont);
  223. /* allocate buffers */
  224. BNU_CHUNK_T* sscmBuffer = pBuffer;
  225. BNU_CHUNK_T* dataT = sscmBuffer+nsM;
  226. BNU_CHUNK_T* pProduct = dataT+nsM;
  227. BNU_CHUNK_T* pBufferMulK = NULL;
  228. cpSize i;
  229. BNU_CHUNK_T mask_pattern;
  230. /* execute most significant part pE */
  231. BNU_CHUNK_T eValue = dataE[nsE-1];
  232. int j = BNU_CHUNK_BITS - cpNLZ_BNU(eValue)-1;
  233. int back_step = 0;
  234. /* expand base and init result */
  235. ZEXPAND_COPY_BNU(dataT, nsM, dataX, nsX);
  236. COPY_BNU(dataY, dataT, nsM);
  237. for(j-=1; j>=0; j--) {
  238. mask_pattern = (BNU_CHUNK_T)(back_step-1);
  239. /* safeBuffer = (Y[] and mask_pattern) or (X[] and ~mask_pattern) */
  240. for(i=0; i<nsM; i++)
  241. sscmBuffer[i] = (dataY[i] & mask_pattern) | (dataT[i] & ~mask_pattern);
  242. /* squaring/multiplication: R = R*T mod Modulus */
  243. cpMontMul_BNU(dataY,
  244. dataY, nsM,
  245. sscmBuffer, nsM,
  246. dataM, nsM, m0,
  247. pProduct, pBufferMulK);
  248. /* update back_step and j */
  249. back_step = ((eValue>>j) & 0x1) & (back_step^1);
  250. j += back_step;
  251. }
  252. /* execute rest bits of E */
  253. for(--nsE; nsE>0; nsE--) {
  254. eValue = dataE[nsE-1];
  255. for(j=BNU_CHUNK_BITS-1; j>=0; j--) {
  256. mask_pattern = (BNU_CHUNK_T)(back_step-1);
  257. /* safeBuffer = (Y[] and mask_pattern) or (X[] and ~mask_pattern) */
  258. for(i=0; i<nsM; i++)
  259. sscmBuffer[i] = (dataY[i] & mask_pattern) | (dataT[i] & ~mask_pattern);
  260. /* squaring/multiplication: R = R*T mod Modulus */
  261. cpMontMul_BNU(dataY,
  262. dataY, nsM,
  263. sscmBuffer, nsM,
  264. dataM, nsM, m0,
  265. pProduct, pBufferMulK);
  266. /* update back_step and j */
  267. back_step = ((eValue>>j) & 0x1) & (back_step^1);
  268. j += back_step;
  269. }
  270. }
  271. }
  272. return nsM;
  273. }
  274. /*
  275. // "fast" fixed-size window montgomery exponentiation
  276. //
  277. // scratch buffer structure:
  278. // precomutation resource[(1<<w)nsM*sizeof(BNU_CHUNK_T)]
  279. // dataE[nsM]
  280. // product[nsM*2]
  281. // karatsubaBuffer[gsKaratsubaBufferSize()]
  282. */
  283. cpSize gsMontExpWin_BNU(BNU_CHUNK_T* dataY,
  284. const BNU_CHUNK_T* dataX, cpSize nsX,
  285. const BNU_CHUNK_T* dataExp, cpSize nsE, cpSize wBitSize,
  286. const IppsMontState* pMont,
  287. BNU_CHUNK_T* pBuffer)
  288. {
  289. cpSize nsM = MNT_SIZE(pMont);
  290. /*
  291. // test for special cases:
  292. // x^0 = 1
  293. // 0^e = 0
  294. */
  295. if( cpEqu_BNU_CHUNK(dataExp, nsE, 0) ) {
  296. COPY_BNU(dataY, MNT_1(pMont), nsM);
  297. }
  298. else if( cpEqu_BNU_CHUNK(dataX, nsX, 0) ) {
  299. ZEXPAND_BNU(dataY, 0, nsM);
  300. }
  301. /* general case */
  302. else {
  303. BNU_CHUNK_T* dataM = MNT_MODULUS(pMont);
  304. BNU_CHUNK_T m0 = MNT_HELPER(pMont);
  305. cpSize nPrecomute= 1<<wBitSize;
  306. /* allocate buffers */
  307. BNU_CHUNK_T* pResource = pBuffer;
  308. BNU_CHUNK_T* dataE = pResource + nPrecomute*nsM;
  309. BNU_CHUNK_T* pProduct = dataE+nsM;
  310. BNU_CHUNK_T* pBufferMulK = NULL;
  311. BNU_CHUNK_T* pBufferSqrK = NULL;
  312. /* fixed window param */
  313. cpSize bitsizeE = BITSIZE_BNU(dataExp, nsE);
  314. BNU_CHUNK_T mask = nPrecomute -1;
  315. int n;
  316. /* expand base */
  317. ZEXPAND_COPY_BNU(dataY, nsM, dataX, nsX);
  318. /* initialize recource */
  319. COPY_BNU(pResource+0, MNT_1(pMont), nsM);
  320. COPY_BNU(pResource+nsM, dataY, nsM);
  321. for(n=2; n<nPrecomute; n++) {
  322. cpMul_BNU(pProduct, pResource+(n-1)*nsM, nsM, dataY, nsM, pBufferMulK);
  323. cpMontRed_BNU(pResource+n*nsM, pProduct, dataM, nsM, m0);
  324. }
  325. /* expand exponent*/
  326. ZEXPAND_COPY_BNU(dataE, nsE+1, dataExp, nsE);
  327. bitsizeE = ((bitsizeE+wBitSize-1)/wBitSize) *wBitSize;
  328. /* exponentiation */
  329. {
  330. /* position of the 1-st (left) window */
  331. int eBit = bitsizeE-wBitSize;
  332. /* extract 1-st window value */
  333. Ipp32u eChunk = *((Ipp32u*)((Ipp16u*)dataE + eBit/BITSIZE(Ipp16u)));
  334. int shift = eBit & 0xF;
  335. Ipp32u windowVal = (eChunk>>shift) &mask;
  336. /* initialize result */
  337. COPY_BNU(dataY, pResource+windowVal*nsM, nsM);
  338. for(eBit-=wBitSize; eBit>=0; eBit-=wBitSize) {
  339. /* do square window times */
  340. for(n=0,windowVal=0; n<wBitSize; n++) {
  341. cpSqr_BNU(pProduct, dataY, nsM, pBufferSqrK);
  342. cpMontRed_BNU(dataY, pProduct, dataM, nsM, m0);
  343. }
  344. /* extract next window value */
  345. eChunk = *((Ipp32u*)((Ipp16u*)dataE + eBit/BITSIZE(Ipp16u)));
  346. shift = eBit & 0xF;
  347. windowVal = (eChunk>>shift) &mask;
  348. if(windowVal) {
  349. /* extract precomputed value and muptiply */
  350. cpMul_BNU(pProduct, dataY, nsM, pResource+windowVal*nsM, nsM, pBufferMulK);
  351. cpMontRed_BNU(dataY, pProduct, dataM, nsM, m0);
  352. }
  353. }
  354. }
  355. }
  356. return nsM;
  357. }
  358. /*
  359. // "safe" fixed-size window montgomery exponentiation
  360. //
  361. // scratch buffer structure:
  362. // precomutation resource[(1<<w)nsM*sizeof(BNU_CHUNK_T)]
  363. // dataT[nsM]
  364. // dataE[nsM]
  365. // product[nsM*2]
  366. // karatsubaBuffer[gsKaratsubaBufferSize()]
  367. */
  368. cpSize gsMontExpWin_BNU_sscm(BNU_CHUNK_T* dataY,
  369. const BNU_CHUNK_T* dataX, cpSize nsX,
  370. const BNU_CHUNK_T* dataExp, cpSize nsE, cpSize bitsizeEwin,
  371. const IppsMontState* pMont,
  372. BNU_CHUNK_T* pBuffer)
  373. {
  374. cpSize nsM = MNT_SIZE(pMont);
  375. /*
  376. // test for special cases:
  377. // x^0 = 1
  378. // 0^e = 0
  379. */
  380. if( cpEqu_BNU_CHUNK(dataExp, nsE, 0) ) {
  381. COPY_BNU(dataY, MNT_1(pMont), nsM);
  382. }
  383. else if( cpEqu_BNU_CHUNK(dataX, nsX, 0) ) {
  384. ZEXPAND_BNU(dataY, 0, nsM);
  385. }
  386. /* general case */
  387. else {
  388. BNU_CHUNK_T* dataM = MNT_MODULUS(pMont);
  389. BNU_CHUNK_T m0 = MNT_HELPER(pMont);
  390. cpSize nPrecomute= 1<<bitsizeEwin;
  391. cpSize chunkSize = CACHE_LINE_SIZE/nPrecomute;
  392. /* allocate buffers */
  393. BNU_CHUNK_T* pResource = pBuffer;
  394. BNU_CHUNK_T* dataE = pResource + gsPrecompResourcelen(nPrecomute, nsM);//+nPrecomute*nsM;
  395. BNU_CHUNK_T* dataT = dataE+nsM;
  396. BNU_CHUNK_T* pProduct = dataT+nsM;
  397. BNU_CHUNK_T* pBufferMulK = NULL;
  398. BNU_CHUNK_T* pBufferSqrK = NULL;
  399. /* fixed window param */
  400. cpSize bitsizeE = BITSIZE_BNU(dataExp, nsE);
  401. BNU_CHUNK_T mask = nPrecomute -1;
  402. int n;
  403. /* expand base */
  404. ZEXPAND_COPY_BNU(dataY, nsM, dataX, nsX);
  405. /* initialize recource */
  406. cpScramblePut(((Ipp8u*)pResource)+0, chunkSize, (Ipp32u*)MNT_1(pMont), nsM*sizeof(BNU_CHUNK_T)/sizeof(Ipp32u));
  407. ZEXPAND_COPY_BNU(dataT, nsM, dataX, nsX);
  408. cpScramblePut(((Ipp8u*)pResource)+chunkSize, chunkSize, (Ipp32u*)dataT, nsM*sizeof(BNU_CHUNK_T)/sizeof(Ipp32u));
  409. for(n=2; n<nPrecomute; n++) {
  410. cpMul_BNU(pProduct, dataT, nsM, dataY, nsM, pBufferMulK);
  411. cpMontRed_BNU(dataT, pProduct, dataM, nsM, m0);
  412. cpScramblePut(((Ipp8u*)pResource)+n*chunkSize, chunkSize, (Ipp32u*)dataT, nsM*sizeof(BNU_CHUNK_T)/sizeof(Ipp32u));
  413. }
  414. /* expand exponent*/
  415. ZEXPAND_COPY_BNU(dataE, nsE+1, dataExp, nsE);
  416. bitsizeE = ((bitsizeE+bitsizeEwin-1)/bitsizeEwin) *bitsizeEwin;
  417. /* exponentiation */
  418. {
  419. /* position of the 1-st (left) window */
  420. int eBit = bitsizeE-bitsizeEwin;
  421. /* extract 1-st window value */
  422. Ipp32u eChunk = *((Ipp32u*)((Ipp16u*)dataE + eBit/BITSIZE(Ipp16u)));
  423. int shift = eBit & 0xF;
  424. Ipp32u windowVal = (eChunk>>shift) &mask;
  425. /* initialize result */
  426. cpScrambleGet((Ipp32u*)dataY, nsM*sizeof(BNU_CHUNK_T)/sizeof(Ipp32u), ((Ipp8u*)pResource)+windowVal*chunkSize, chunkSize);
  427. for(eBit-=bitsizeEwin; eBit>=0; eBit-=bitsizeEwin) {
  428. /* do square window times */
  429. for(n=0,windowVal=0; n<bitsizeEwin; n++) {
  430. cpSqr_BNU(pProduct, dataY, nsM, pBufferSqrK);
  431. cpMontRed_BNU(dataY, pProduct, dataM, nsM, m0);
  432. }
  433. /* extract next window value */
  434. eChunk = *((Ipp32u*)((Ipp16u*)dataE + eBit/BITSIZE(Ipp16u)));
  435. shift = eBit & 0xF;
  436. windowVal = (eChunk>>shift) &mask;
  437. /* exptact precomputed value and muptiply */
  438. cpScrambleGet((Ipp32u*)dataT, nsM*sizeof(BNU_CHUNK_T)/sizeof(Ipp32u), ((Ipp8u*)pResource)+windowVal*chunkSize, chunkSize);
  439. cpMul_BNU(pProduct, dataY, nsM, dataT, nsM, pBufferMulK);
  440. cpMontRed_BNU(dataY, pProduct, dataM, nsM, m0);
  441. }
  442. }
  443. }
  444. return nsM;
  445. }