pcpgfpecpoint.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. /*############################################################################
  2. # Copyright 2016 Intel Corporation
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. ############################################################################*/
  16. /*
  17. //
  18. // Purpose:
  19. // Intel(R) Performance Primitives. Cryptography Primitives.
  20. // EC over GF(p) Operations
  21. //
  22. // Context:
  23. // ippsGFpECPointGetSize()
  24. // ippsGFpECPointInit()
  25. //
  26. // ippsGFpECSetPointAtInfinity()
  27. // ippsGFpECSetPoint()
  28. // ippsGFpECMakePoint()
  29. // ippsGFpECSetPointRandom()
  30. // ippsGFpECSetPointHash()
  31. // ippsGFpECGetPoint()
  32. // ippsGFpECCpyPoint()
  33. //
  34. // ippsGFpECCmpPoint()
  35. // ippsGFpECTstPoint()
  36. // ippsGFpECNegPoint()
  37. // ippsGFpECAddPoint()
  38. // ippsGFpECMulPoint()
  39. //
  40. //
  41. */
  42. #include "owncpepid.h"
  43. #include "pcpgfpecstuff.h"
  44. #include "pcpgfphashstuff.h"
  45. IPPFUN(IppStatus, ippsGFpECPointGetSize,(const IppsGFpECState* pEC, int* pSizeInBytes))
  46. {
  47. IPP_BAD_PTR2_RET(pEC, pSizeInBytes);
  48. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  49. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  50. {
  51. int elemLen = GFP_FELEN(ECP_GFP(pEC));
  52. *pSizeInBytes = sizeof(IppsGFpECPoint)
  53. +elemLen*sizeof(BNU_CHUNK_T) /* X */
  54. +elemLen*sizeof(BNU_CHUNK_T) /* Y */
  55. +elemLen*sizeof(BNU_CHUNK_T);/* Z */
  56. return ippStsNoErr;
  57. }
  58. }
  59. IPPFUN(IppStatus, ippsGFpECPointInit,(const IppsGFpElement* pX, const IppsGFpElement* pY,
  60. IppsGFpECPoint* pPoint, IppsGFpECState* pEC))
  61. {
  62. IPP_BAD_PTR2_RET(pPoint, pEC);
  63. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  64. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  65. {
  66. Ipp8u* ptr = (Ipp8u*)pPoint;
  67. int elemLen = GFP_FELEN(ECP_GFP(pEC));
  68. ECP_POINT_ID(pPoint) = idCtxGFPPoint;
  69. ECP_POINT_FLAGS(pPoint) = 0;
  70. ECP_POINT_FELEN(pPoint) = elemLen;
  71. ptr += sizeof(IppsGFpECPoint);
  72. ECP_POINT_DATA(pPoint) = (BNU_CHUNK_T*)(ptr);
  73. if(pX && pY)
  74. return ippsGFpECSetPoint(pX, pY, pPoint, pEC);
  75. else {
  76. cpEcGFpSetProjectivePointAtInfinity(pPoint, elemLen);
  77. return ippStsNoErr;
  78. }
  79. }
  80. }
  81. IPPFUN(IppStatus, ippsGFpECSetPointAtInfinity,(IppsGFpECPoint* pPoint, IppsGFpECState* pEC))
  82. {
  83. IPP_BAD_PTR2_RET(pPoint, pEC);
  84. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  85. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  86. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
  87. cpEcGFpSetProjectivePointAtInfinity(pPoint, GFP_FELEN(ECP_GFP(pEC)));
  88. return ippStsNoErr;
  89. }
  90. IPPFUN(IppStatus, ippsGFpECSetPoint,(const IppsGFpElement* pX, const IppsGFpElement* pY,
  91. IppsGFpECPoint* pPoint,
  92. IppsGFpECState* pEC))
  93. {
  94. IPP_BAD_PTR2_RET(pPoint, pEC);
  95. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  96. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  97. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
  98. IPP_BAD_PTR2_RET(pX, pY);
  99. IPP_BADARG_RET( !GFPE_TEST_ID(pX), ippStsContextMatchErr );
  100. IPP_BADARG_RET( !GFPE_TEST_ID(pY), ippStsContextMatchErr );
  101. cpEcGFpSetAffinePoint(pPoint, GFPE_DATA(pX), GFPE_DATA(pY), pEC);
  102. return ippStsNoErr;
  103. }
  104. IPPFUN(IppStatus, ippsGFpECMakePoint,(const IppsGFpElement* pX, IppsGFpECPoint* pPoint, IppsGFpECState* pEC))
  105. {
  106. IPP_BAD_PTR3_RET(pX, pPoint, pEC);
  107. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  108. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  109. IPP_BADARG_RET( !GFP_IS_BASIC(ECP_GFP(pEC)), ippStsBadArgErr );
  110. IPP_BADARG_RET( !GFPE_TEST_ID(pX), ippStsContextMatchErr );
  111. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
  112. return cpEcGFpMakePoint(pPoint, GFPE_DATA(pX), pEC)? ippStsNoErr : ippStsQuadraticNonResidueErr;
  113. }
  114. IPPFUN(IppStatus, ippsGFpECSetPointRandom,(IppBitSupplier rndFunc, void* pRndParam,
  115. IppsGFpECPoint* pPoint, IppsGFpECState* pEC,
  116. Ipp8u* pScratchBuffer))
  117. {
  118. IPP_BAD_PTR2_RET(pPoint, pEC);
  119. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  120. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  121. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
  122. IPP_BAD_PTR1_RET(rndFunc);
  123. {
  124. IppsGFpState* pGF = ECP_GFP(pEC);
  125. if( GFP_IS_BASIC(pGF) ) {
  126. BNU_CHUNK_T* pElm = cpGFpGetPool(1, pGF);
  127. do {
  128. /* get random X */
  129. cpGFpRand(pElm, pGF, rndFunc, pRndParam, USE_MONT_SPACE_REPRESENTATION);
  130. } while( !cpEcGFpMakePoint(pPoint, pElm, pEC) );
  131. cpGFpReleasePool(1, pGF);
  132. /* R = cofactor*R */
  133. cpEcGFpMulPoint(pPoint, pPoint, ECP_COFACTOR(pEC), GFP_FELEN(pGF), pEC, pScratchBuffer);
  134. return ippStsNoErr;
  135. }
  136. else {
  137. /* number of bits and dwords being begerated */
  138. int generatedBits = ECP_ORDBITSIZE(pEC) + GF_RAND_ADD_BITS;
  139. int generatedLen = BITS_BNU_CHUNK(generatedBits);
  140. /* allocate random exponent */
  141. int poolElements = (generatedLen + GFP_PELEN(pGF) -1) / GFP_PELEN(pGF);
  142. BNU_CHUNK_T* pExp = cpGFpGetPool(poolElements, pGF);
  143. int nsE;
  144. /* setup copy of the base point */
  145. IppsGFpECPoint G;
  146. cpEcGFpInitPoint(&G, ECP_G(pEC),ECP_AFFINE_POINT|ECP_FINITE_POINT, pEC);
  147. /* get random bits */
  148. rndFunc((Ipp32u*)pExp, generatedBits, pRndParam);
  149. /* reduce with respect to order value */
  150. nsE = cpMod_BNU(pExp, generatedLen, ECP_R(pEC), BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)));
  151. /* compute random point */
  152. cpEcGFpMulPoint(pPoint, &G, pExp, nsE, pEC, pScratchBuffer);
  153. cpGFpReleasePool(poolElements, pGF);
  154. return ippStsNoErr;
  155. }
  156. }
  157. }
  158. IPPFUN(IppStatus, ippsGFpECGetPoint,(const IppsGFpECPoint* pPoint,
  159. IppsGFpElement* pX, IppsGFpElement* pY,
  160. IppsGFpECState* pEC))
  161. {
  162. IPP_BAD_PTR2_RET(pPoint, pEC);
  163. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  164. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  165. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
  166. IPP_BADARG_RET( !IS_ECP_FINITE_POINT(pPoint), ippStsPointAtInfinity);
  167. IPP_BADARG_RET( pX && !GFPE_TEST_ID(pX), ippStsContextMatchErr );
  168. IPP_BADARG_RET( pY && !GFPE_TEST_ID(pY), ippStsContextMatchErr );
  169. cpEcGFpGetAffinePoint((pX)? GFPE_DATA(pX):0, (pY)?GFPE_DATA(pY):0, pPoint, pEC);
  170. return ippStsNoErr;
  171. }
  172. IPPFUN(IppStatus, ippsGFpECCpyPoint,(const IppsGFpECPoint* pA,
  173. IppsGFpECPoint* pR,
  174. IppsGFpECState* pEC))
  175. {
  176. IPP_BAD_PTR3_RET(pA, pR, pEC);
  177. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  178. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  179. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pA), ippStsContextMatchErr );
  180. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pR), ippStsContextMatchErr );
  181. cpEcGFpCopyPoint(pR, pA, GFP_FELEN(ECP_GFP(pEC)));
  182. return ippStsNoErr;
  183. }
  184. IPPFUN(IppStatus, ippsGFpECCmpPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ,
  185. IppECResult* pResult,
  186. IppsGFpECState* pEC))
  187. {
  188. IPP_BAD_PTR4_RET(pP, pQ, pResult, pEC);
  189. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  190. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  191. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
  192. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pQ), ippStsContextMatchErr );
  193. *pResult = cpEcGFpIsPointEquial(pP, pQ, pEC)? ippECPointIsEqual : ippECPointIsNotEqual;
  194. return ippStsNoErr;
  195. }
  196. #if 0
  197. IPPFUN(IppStatus, ippsGFpECTstPoint,(const IppsGFpECPoint* pP,
  198. IppECResult* pResult,
  199. IppsGFpECState* pEC,
  200. Ipp8u* pScratchBuffer))
  201. {
  202. IPP_BAD_PTR3_RET(pP, pResult, pEC);
  203. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  204. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  205. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
  206. {
  207. Ipp32u elemLen = GFP_FELEN(ECP_GFP(pEC));
  208. if( cpEcGFpIsProjectivePointAtInfinity(pP, elemLen) )
  209. *pResult = ippECPointIsAtInfinite;
  210. else if( !cpEcGFpIsPointOnCurve(pP, pEC) )
  211. *pResult = ippECPointIsNotValid;
  212. else {
  213. IppsGFpECPoint T;
  214. cpEcGFpInitPoint(&T, cpEcGFpGetPool(1, pEC),0, pEC);
  215. cpEcGFpMulPoint(&T, pP, ECP_R(pEC), BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)), pEC, pScratchBuffer);
  216. *pResult = cpEcGFpIsProjectivePointAtInfinity(&T, elemLen)? ippECValid : ippECPointOutOfGroup;
  217. cpEcGFpReleasePool(1, pEC);
  218. }
  219. return ippStsNoErr;
  220. }
  221. }
  222. #endif
  223. /*
  224. // Version below is based on observation has been done by Zhao Hui Du.
  225. // See "Opportunity to improve Intel(R) EPID 2.0 performance" Gentry Mark e-mail 1/23/20015.
  226. //
  227. // Shortly: In case of Intel(R) EPID 2.0 EC parameters all EC points belongs to G1.
  228. */
  229. IPPFUN(IppStatus, ippsGFpECTstPoint,(const IppsGFpECPoint* pP,
  230. IppECResult* pResult,
  231. IppsGFpECState* pEC,
  232. Ipp8u* pScratchBuffer))
  233. {
  234. IPP_BAD_PTR3_RET(pP, pResult, pEC);
  235. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  236. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  237. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
  238. {
  239. Ipp32u elemLen = GFP_FELEN(ECP_GFP(pEC));
  240. if( cpEcGFpIsProjectivePointAtInfinity(pP, elemLen) )
  241. *pResult = ippECPointIsAtInfinite;
  242. else if( !cpEcGFpIsPointOnCurve(pP, pEC) )
  243. *pResult = ippECPointIsNotValid;
  244. else {
  245. if(EPID_PARAMS(pEC)&&GFP_IS_BASIC(ECP_GFP(pEC)))
  246. *pResult = ippECValid;
  247. else {
  248. IppsGFpECPoint T;
  249. cpEcGFpInitPoint(&T, cpEcGFpGetPool(1, pEC),0, pEC);
  250. cpEcGFpMulPoint(&T, pP, ECP_R(pEC), BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)), pEC, pScratchBuffer);
  251. *pResult = cpEcGFpIsProjectivePointAtInfinity(&T, elemLen)? ippECValid : ippECPointOutOfGroup;
  252. cpEcGFpReleasePool(1, pEC);
  253. }
  254. }
  255. return ippStsNoErr;
  256. }
  257. }
  258. IPPFUN(IppStatus, ippsGFpECNegPoint,(const IppsGFpECPoint* pP,
  259. IppsGFpECPoint* pR,
  260. IppsGFpECState* pEC))
  261. {
  262. IPP_BAD_PTR3_RET(pP, pR, pEC);
  263. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  264. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  265. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
  266. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pR), ippStsContextMatchErr );
  267. cpEcGFpNegPoint(pR, pP, pEC);
  268. return ippStsNoErr;
  269. }
  270. IPPFUN(IppStatus, ippsGFpECAddPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECPoint* pR,
  271. IppsGFpECState* pEC))
  272. {
  273. IPP_BAD_PTR4_RET(pP, pQ, pR, pEC);
  274. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  275. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  276. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
  277. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pQ), ippStsContextMatchErr );
  278. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pR), ippStsContextMatchErr );
  279. cpEcGFpAddPoint(pR, pP, pQ, pEC);
  280. return ippStsNoErr;
  281. }
  282. IPPFUN(IppStatus, ippsGFpECMulPoint,(const IppsGFpECPoint* pP,
  283. const IppsBigNumState* pN,
  284. IppsGFpECPoint* pR,
  285. IppsGFpECState* pEC,
  286. Ipp8u* pScratchBuffer))
  287. {
  288. IPP_BAD_PTR3_RET(pP, pR, pEC);
  289. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  290. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  291. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
  292. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pR), ippStsContextMatchErr );
  293. IPP_BAD_PTR1_RET(pN);
  294. pN = (IppsBigNumState*)( IPP_ALIGNED_PTR(pN, BN_ALIGNMENT) );
  295. /* test if N >= order */
  296. IPP_BADARG_RET(0<=cpCmp_BNU(BN_NUMBER(pN), BN_SIZE(pN), ECP_R(pEC), BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC))), ippStsOutOfRangeErr);
  297. cpEcGFpMulPoint(pR, pP, BN_NUMBER(pN), BN_SIZE(pN), pEC, pScratchBuffer);
  298. return ippStsNoErr;
  299. }
  300. IPPFUN(IppStatus, ippsGFpECSetPointHash,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppHashID hashID, IppsGFpECPoint* pPoint,
  301. IppsGFpECState* pEC,
  302. Ipp8u* pScratchBuffer))
  303. {
  304. IPP_BAD_PTR2_RET(pPoint, pEC);
  305. pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
  306. IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
  307. IPP_BADARG_RET( !GFP_IS_BASIC(ECP_GFP(pEC)), ippStsBadArgErr );
  308. IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
  309. IPP_BADARG_RET( !cpTestHashID(hashID), ippStsBadArgErr);
  310. {
  311. IppsGFpState* pGF = ECP_GFP(pEC);
  312. int elemLen = GFP_FELEN(pGF);
  313. BNU_CHUNK_T* pModulus = GFP_MODULUS(pGF);
  314. Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE];
  315. int hashLen = cpHashLength(hashID);
  316. BNU_CHUNK_T hashVal[BITS_BNU_CHUNK(IPP_SHA512_DIGEST_BITSIZE)+1];
  317. int hashValLen;
  318. Ipp8u hashCtx[sizeof(IppsSHA512State)+SHA512_ALIGNMENT-1];
  319. cpHashInit(hashCtx, hashID);
  320. {
  321. BNU_CHUNK_T* pPoolElm = cpGFpGetPool(1, pGF);
  322. /* convert hdr => hdrStr */
  323. BNU_CHUNK_T locHdr = (BNU_CHUNK_T)hdr;
  324. Ipp8u hdrOctStr[sizeof(hdr/*locHdr*/)];
  325. cpToOctStr_BNU(hdrOctStr, sizeof(hdrOctStr), &locHdr, 1);
  326. /* compute md = hash(hrd||msg) */
  327. cpHashUpdate(hdrOctStr, sizeof(hdrOctStr), hashCtx, hashID);
  328. cpHashUpdate(pMsg, msgLen, hashCtx, hashID);
  329. cpHashFinal(md, hashCtx, hashID);
  330. /* convert hash into the integer */
  331. hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen);
  332. hashValLen = cpMod_BNU(hashVal, hashValLen, pModulus, elemLen);
  333. cpGFpSet(pPoolElm, hashVal, hashValLen, pGF, USE_MONT_SPACE_REPRESENTATION);
  334. if( cpEcGFpMakePoint(pPoint, pPoolElm, pEC)) {
  335. /* set y-coordinate of the point (positive or negative) */
  336. BNU_CHUNK_T* pY = ECP_POINT_Y(pPoint);
  337. if(pY[0] & 1)
  338. cpGFpNeg(pY, pY, pGF);
  339. /* update point if cofactor>1 */
  340. cpEcGFpMulPoint(pPoint, pPoint, ECP_COFACTOR(pEC), GFP_FELEN(pGF), pEC, pScratchBuffer);
  341. cpGFpReleasePool(1, pGF);
  342. return ippStsNoErr;
  343. }
  344. }
  345. cpGFpReleasePool(1, pGF);
  346. return ippStsQuadraticNonResidueErr;
  347. }
  348. }