ecp_smpl.c 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769
  1. /* crypto/ec/ecp_smpl.c */
  2. /*
  3. * Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
  4. * for the OpenSSL project. Includes code written by Bodo Moeller for the
  5. * OpenSSL project.
  6. */
  7. /* ====================================================================
  8. * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. *
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. *
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in
  19. * the documentation and/or other materials provided with the
  20. * distribution.
  21. *
  22. * 3. All advertising materials mentioning features or use of this
  23. * software must display the following acknowledgment:
  24. * "This product includes software developed by the OpenSSL Project
  25. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  26. *
  27. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  28. * endorse or promote products derived from this software without
  29. * prior written permission. For written permission, please contact
  30. * openssl-core@openssl.org.
  31. *
  32. * 5. Products derived from this software may not be called "OpenSSL"
  33. * nor may "OpenSSL" appear in their names without prior written
  34. * permission of the OpenSSL Project.
  35. *
  36. * 6. Redistributions of any form whatsoever must retain the following
  37. * acknowledgment:
  38. * "This product includes software developed by the OpenSSL Project
  39. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  42. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  44. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  45. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  46. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  47. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  49. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  50. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  51. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  52. * OF THE POSSIBILITY OF SUCH DAMAGE.
  53. * ====================================================================
  54. *
  55. * This product includes cryptographic software written by Eric Young
  56. * (eay@cryptsoft.com). This product includes software written by Tim
  57. * Hudson (tjh@cryptsoft.com).
  58. *
  59. */
  60. /* ====================================================================
  61. * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  62. * Portions of this software developed by SUN MICROSYSTEMS, INC.,
  63. * and contributed to the OpenSSL project.
  64. */
  65. #include <openssl/err.h>
  66. #include <openssl/symhacks.h>
  67. #include "ec_lcl.h"
  68. const EC_METHOD *EC_GFp_simple_method(void)
  69. {
  70. static const EC_METHOD ret = {
  71. NID_X9_62_prime_field,
  72. ec_GFp_simple_group_init,
  73. ec_GFp_simple_group_finish,
  74. ec_GFp_simple_group_clear_finish,
  75. ec_GFp_simple_group_copy,
  76. ec_GFp_simple_group_set_curve,
  77. ec_GFp_simple_group_get_curve,
  78. ec_GFp_simple_group_get_degree,
  79. ec_GFp_simple_group_check_discriminant,
  80. ec_GFp_simple_point_init,
  81. ec_GFp_simple_point_finish,
  82. ec_GFp_simple_point_clear_finish,
  83. ec_GFp_simple_point_copy,
  84. ec_GFp_simple_point_set_to_infinity,
  85. ec_GFp_simple_set_Jprojective_coordinates_GFp,
  86. ec_GFp_simple_get_Jprojective_coordinates_GFp,
  87. ec_GFp_simple_point_set_affine_coordinates,
  88. ec_GFp_simple_point_get_affine_coordinates,
  89. ec_GFp_simple_set_compressed_coordinates,
  90. ec_GFp_simple_point2oct,
  91. ec_GFp_simple_oct2point,
  92. ec_GFp_simple_add,
  93. ec_GFp_simple_dbl,
  94. ec_GFp_simple_invert,
  95. ec_GFp_simple_is_at_infinity,
  96. ec_GFp_simple_is_on_curve,
  97. ec_GFp_simple_cmp,
  98. ec_GFp_simple_make_affine,
  99. ec_GFp_simple_points_make_affine,
  100. 0 /* mul */ ,
  101. 0 /* precompute_mult */ ,
  102. 0 /* have_precompute_mult */ ,
  103. ec_GFp_simple_field_mul,
  104. ec_GFp_simple_field_sqr,
  105. 0 /* field_div */ ,
  106. 0 /* field_encode */ ,
  107. 0 /* field_decode */ ,
  108. 0 /* field_set_to_one */
  109. };
  110. return &ret;
  111. }
  112. /*
  113. * Most method functions in this file are designed to work with
  114. * non-trivial representations of field elements if necessary
  115. * (see ecp_mont.c): while standard modular addition and subtraction
  116. * are used, the field_mul and field_sqr methods will be used for
  117. * multiplication, and field_encode and field_decode (if defined)
  118. * will be used for converting between representations.
  119. *
  120. * Functions ec_GFp_simple_points_make_affine() and
  121. * ec_GFp_simple_point_get_affine_coordinates() specifically assume
  122. * that if a non-trivial representation is used, it is a Montgomery
  123. * representation (i.e. 'encoding' means multiplying by some factor R).
  124. */
  125. int ec_GFp_simple_group_init(EC_GROUP *group)
  126. {
  127. BN_init(&group->field);
  128. BN_init(&group->a);
  129. BN_init(&group->b);
  130. group->a_is_minus3 = 0;
  131. return 1;
  132. }
  133. void ec_GFp_simple_group_finish(EC_GROUP *group)
  134. {
  135. BN_free(&group->field);
  136. BN_free(&group->a);
  137. BN_free(&group->b);
  138. }
  139. void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
  140. {
  141. BN_clear_free(&group->field);
  142. BN_clear_free(&group->a);
  143. BN_clear_free(&group->b);
  144. }
  145. int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
  146. {
  147. if (!BN_copy(&dest->field, &src->field))
  148. return 0;
  149. if (!BN_copy(&dest->a, &src->a))
  150. return 0;
  151. if (!BN_copy(&dest->b, &src->b))
  152. return 0;
  153. dest->a_is_minus3 = src->a_is_minus3;
  154. return 1;
  155. }
  156. int ec_GFp_simple_group_set_curve(EC_GROUP *group,
  157. const BIGNUM *p, const BIGNUM *a,
  158. const BIGNUM *b, BN_CTX *ctx)
  159. {
  160. int ret = 0;
  161. BN_CTX *new_ctx = NULL;
  162. BIGNUM *tmp_a;
  163. /* p must be a prime > 3 */
  164. if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
  165. ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
  166. return 0;
  167. }
  168. if (ctx == NULL) {
  169. ctx = new_ctx = BN_CTX_new();
  170. if (ctx == NULL)
  171. return 0;
  172. }
  173. BN_CTX_start(ctx);
  174. tmp_a = BN_CTX_get(ctx);
  175. if (tmp_a == NULL)
  176. goto err;
  177. /* group->field */
  178. if (!BN_copy(&group->field, p))
  179. goto err;
  180. BN_set_negative(&group->field, 0);
  181. /* group->a */
  182. if (!BN_nnmod(tmp_a, a, p, ctx))
  183. goto err;
  184. if (group->meth->field_encode) {
  185. if (!group->meth->field_encode(group, &group->a, tmp_a, ctx))
  186. goto err;
  187. } else if (!BN_copy(&group->a, tmp_a))
  188. goto err;
  189. /* group->b */
  190. if (!BN_nnmod(&group->b, b, p, ctx))
  191. goto err;
  192. if (group->meth->field_encode)
  193. if (!group->meth->field_encode(group, &group->b, &group->b, ctx))
  194. goto err;
  195. /* group->a_is_minus3 */
  196. if (!BN_add_word(tmp_a, 3))
  197. goto err;
  198. group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
  199. ret = 1;
  200. err:
  201. BN_CTX_end(ctx);
  202. if (new_ctx != NULL)
  203. BN_CTX_free(new_ctx);
  204. return ret;
  205. }
  206. int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  207. BIGNUM *b, BN_CTX *ctx)
  208. {
  209. int ret = 0;
  210. BN_CTX *new_ctx = NULL;
  211. if (p != NULL) {
  212. if (!BN_copy(p, &group->field))
  213. return 0;
  214. }
  215. if (a != NULL || b != NULL) {
  216. if (group->meth->field_decode) {
  217. if (ctx == NULL) {
  218. ctx = new_ctx = BN_CTX_new();
  219. if (ctx == NULL)
  220. return 0;
  221. }
  222. if (a != NULL) {
  223. if (!group->meth->field_decode(group, a, &group->a, ctx))
  224. goto err;
  225. }
  226. if (b != NULL) {
  227. if (!group->meth->field_decode(group, b, &group->b, ctx))
  228. goto err;
  229. }
  230. } else {
  231. if (a != NULL) {
  232. if (!BN_copy(a, &group->a))
  233. goto err;
  234. }
  235. if (b != NULL) {
  236. if (!BN_copy(b, &group->b))
  237. goto err;
  238. }
  239. }
  240. }
  241. ret = 1;
  242. err:
  243. if (new_ctx)
  244. BN_CTX_free(new_ctx);
  245. return ret;
  246. }
  247. int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
  248. {
  249. return BN_num_bits(&group->field);
  250. }
  251. int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
  252. {
  253. int ret = 0;
  254. BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
  255. const BIGNUM *p = &group->field;
  256. BN_CTX *new_ctx = NULL;
  257. if (ctx == NULL) {
  258. ctx = new_ctx = BN_CTX_new();
  259. if (ctx == NULL) {
  260. ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,
  261. ERR_R_MALLOC_FAILURE);
  262. goto err;
  263. }
  264. }
  265. BN_CTX_start(ctx);
  266. a = BN_CTX_get(ctx);
  267. b = BN_CTX_get(ctx);
  268. tmp_1 = BN_CTX_get(ctx);
  269. tmp_2 = BN_CTX_get(ctx);
  270. order = BN_CTX_get(ctx);
  271. if (order == NULL)
  272. goto err;
  273. if (group->meth->field_decode) {
  274. if (!group->meth->field_decode(group, a, &group->a, ctx))
  275. goto err;
  276. if (!group->meth->field_decode(group, b, &group->b, ctx))
  277. goto err;
  278. } else {
  279. if (!BN_copy(a, &group->a))
  280. goto err;
  281. if (!BN_copy(b, &group->b))
  282. goto err;
  283. }
  284. /*-
  285. * check the discriminant:
  286. * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
  287. * 0 =< a, b < p
  288. */
  289. if (BN_is_zero(a)) {
  290. if (BN_is_zero(b))
  291. goto err;
  292. } else if (!BN_is_zero(b)) {
  293. if (!BN_mod_sqr(tmp_1, a, p, ctx))
  294. goto err;
  295. if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
  296. goto err;
  297. if (!BN_lshift(tmp_1, tmp_2, 2))
  298. goto err;
  299. /* tmp_1 = 4*a^3 */
  300. if (!BN_mod_sqr(tmp_2, b, p, ctx))
  301. goto err;
  302. if (!BN_mul_word(tmp_2, 27))
  303. goto err;
  304. /* tmp_2 = 27*b^2 */
  305. if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
  306. goto err;
  307. if (BN_is_zero(a))
  308. goto err;
  309. }
  310. ret = 1;
  311. err:
  312. if (ctx != NULL)
  313. BN_CTX_end(ctx);
  314. if (new_ctx != NULL)
  315. BN_CTX_free(new_ctx);
  316. return ret;
  317. }
  318. int ec_GFp_simple_point_init(EC_POINT *point)
  319. {
  320. BN_init(&point->X);
  321. BN_init(&point->Y);
  322. BN_init(&point->Z);
  323. point->Z_is_one = 0;
  324. return 1;
  325. }
  326. void ec_GFp_simple_point_finish(EC_POINT *point)
  327. {
  328. BN_free(&point->X);
  329. BN_free(&point->Y);
  330. BN_free(&point->Z);
  331. }
  332. void ec_GFp_simple_point_clear_finish(EC_POINT *point)
  333. {
  334. BN_clear_free(&point->X);
  335. BN_clear_free(&point->Y);
  336. BN_clear_free(&point->Z);
  337. point->Z_is_one = 0;
  338. }
  339. int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
  340. {
  341. if (!BN_copy(&dest->X, &src->X))
  342. return 0;
  343. if (!BN_copy(&dest->Y, &src->Y))
  344. return 0;
  345. if (!BN_copy(&dest->Z, &src->Z))
  346. return 0;
  347. dest->Z_is_one = src->Z_is_one;
  348. return 1;
  349. }
  350. int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
  351. EC_POINT *point)
  352. {
  353. point->Z_is_one = 0;
  354. BN_zero(&point->Z);
  355. return 1;
  356. }
  357. int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
  358. EC_POINT *point,
  359. const BIGNUM *x,
  360. const BIGNUM *y,
  361. const BIGNUM *z,
  362. BN_CTX *ctx)
  363. {
  364. BN_CTX *new_ctx = NULL;
  365. int ret = 0;
  366. if (ctx == NULL) {
  367. ctx = new_ctx = BN_CTX_new();
  368. if (ctx == NULL)
  369. return 0;
  370. }
  371. if (x != NULL) {
  372. if (!BN_nnmod(&point->X, x, &group->field, ctx))
  373. goto err;
  374. if (group->meth->field_encode) {
  375. if (!group->meth->field_encode(group, &point->X, &point->X, ctx))
  376. goto err;
  377. }
  378. }
  379. if (y != NULL) {
  380. if (!BN_nnmod(&point->Y, y, &group->field, ctx))
  381. goto err;
  382. if (group->meth->field_encode) {
  383. if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx))
  384. goto err;
  385. }
  386. }
  387. if (z != NULL) {
  388. int Z_is_one;
  389. if (!BN_nnmod(&point->Z, z, &group->field, ctx))
  390. goto err;
  391. Z_is_one = BN_is_one(&point->Z);
  392. if (group->meth->field_encode) {
  393. if (Z_is_one && (group->meth->field_set_to_one != 0)) {
  394. if (!group->meth->field_set_to_one(group, &point->Z, ctx))
  395. goto err;
  396. } else {
  397. if (!group->
  398. meth->field_encode(group, &point->Z, &point->Z, ctx))
  399. goto err;
  400. }
  401. }
  402. point->Z_is_one = Z_is_one;
  403. }
  404. ret = 1;
  405. err:
  406. if (new_ctx != NULL)
  407. BN_CTX_free(new_ctx);
  408. return ret;
  409. }
  410. int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
  411. const EC_POINT *point,
  412. BIGNUM *x, BIGNUM *y,
  413. BIGNUM *z, BN_CTX *ctx)
  414. {
  415. BN_CTX *new_ctx = NULL;
  416. int ret = 0;
  417. if (group->meth->field_decode != 0) {
  418. if (ctx == NULL) {
  419. ctx = new_ctx = BN_CTX_new();
  420. if (ctx == NULL)
  421. return 0;
  422. }
  423. if (x != NULL) {
  424. if (!group->meth->field_decode(group, x, &point->X, ctx))
  425. goto err;
  426. }
  427. if (y != NULL) {
  428. if (!group->meth->field_decode(group, y, &point->Y, ctx))
  429. goto err;
  430. }
  431. if (z != NULL) {
  432. if (!group->meth->field_decode(group, z, &point->Z, ctx))
  433. goto err;
  434. }
  435. } else {
  436. if (x != NULL) {
  437. if (!BN_copy(x, &point->X))
  438. goto err;
  439. }
  440. if (y != NULL) {
  441. if (!BN_copy(y, &point->Y))
  442. goto err;
  443. }
  444. if (z != NULL) {
  445. if (!BN_copy(z, &point->Z))
  446. goto err;
  447. }
  448. }
  449. ret = 1;
  450. err:
  451. if (new_ctx != NULL)
  452. BN_CTX_free(new_ctx);
  453. return ret;
  454. }
  455. int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
  456. EC_POINT *point,
  457. const BIGNUM *x,
  458. const BIGNUM *y, BN_CTX *ctx)
  459. {
  460. if (x == NULL || y == NULL) {
  461. /*
  462. * unlike for projective coordinates, we do not tolerate this
  463. */
  464. ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES,
  465. ERR_R_PASSED_NULL_PARAMETER);
  466. return 0;
  467. }
  468. return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y,
  469. BN_value_one(), ctx);
  470. }
  471. int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
  472. const EC_POINT *point,
  473. BIGNUM *x, BIGNUM *y,
  474. BN_CTX *ctx)
  475. {
  476. BN_CTX *new_ctx = NULL;
  477. BIGNUM *Z, *Z_1, *Z_2, *Z_3;
  478. const BIGNUM *Z_;
  479. int ret = 0;
  480. if (EC_POINT_is_at_infinity(group, point)) {
  481. ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
  482. EC_R_POINT_AT_INFINITY);
  483. return 0;
  484. }
  485. if (ctx == NULL) {
  486. ctx = new_ctx = BN_CTX_new();
  487. if (ctx == NULL)
  488. return 0;
  489. }
  490. BN_CTX_start(ctx);
  491. Z = BN_CTX_get(ctx);
  492. Z_1 = BN_CTX_get(ctx);
  493. Z_2 = BN_CTX_get(ctx);
  494. Z_3 = BN_CTX_get(ctx);
  495. if (Z_3 == NULL)
  496. goto err;
  497. /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
  498. if (group->meth->field_decode) {
  499. if (!group->meth->field_decode(group, Z, &point->Z, ctx))
  500. goto err;
  501. Z_ = Z;
  502. } else {
  503. Z_ = &point->Z;
  504. }
  505. if (BN_is_one(Z_)) {
  506. if (group->meth->field_decode) {
  507. if (x != NULL) {
  508. if (!group->meth->field_decode(group, x, &point->X, ctx))
  509. goto err;
  510. }
  511. if (y != NULL) {
  512. if (!group->meth->field_decode(group, y, &point->Y, ctx))
  513. goto err;
  514. }
  515. } else {
  516. if (x != NULL) {
  517. if (!BN_copy(x, &point->X))
  518. goto err;
  519. }
  520. if (y != NULL) {
  521. if (!BN_copy(y, &point->Y))
  522. goto err;
  523. }
  524. }
  525. } else {
  526. if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) {
  527. ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
  528. ERR_R_BN_LIB);
  529. goto err;
  530. }
  531. if (group->meth->field_encode == 0) {
  532. /* field_sqr works on standard representation */
  533. if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
  534. goto err;
  535. } else {
  536. if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx))
  537. goto err;
  538. }
  539. if (x != NULL) {
  540. /*
  541. * in the Montgomery case, field_mul will cancel out Montgomery
  542. * factor in X:
  543. */
  544. if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx))
  545. goto err;
  546. }
  547. if (y != NULL) {
  548. if (group->meth->field_encode == 0) {
  549. /*
  550. * field_mul works on standard representation
  551. */
  552. if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
  553. goto err;
  554. } else {
  555. if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx))
  556. goto err;
  557. }
  558. /*
  559. * in the Montgomery case, field_mul will cancel out Montgomery
  560. * factor in Y:
  561. */
  562. if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx))
  563. goto err;
  564. }
  565. }
  566. ret = 1;
  567. err:
  568. BN_CTX_end(ctx);
  569. if (new_ctx != NULL)
  570. BN_CTX_free(new_ctx);
  571. return ret;
  572. }
  573. int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
  574. EC_POINT *point,
  575. const BIGNUM *x_, int y_bit,
  576. BN_CTX *ctx)
  577. {
  578. BN_CTX *new_ctx = NULL;
  579. BIGNUM *tmp1, *tmp2, *x, *y;
  580. int ret = 0;
  581. /* clear error queue */
  582. ERR_clear_error();
  583. if (ctx == NULL) {
  584. ctx = new_ctx = BN_CTX_new();
  585. if (ctx == NULL)
  586. return 0;
  587. }
  588. y_bit = (y_bit != 0);
  589. BN_CTX_start(ctx);
  590. tmp1 = BN_CTX_get(ctx);
  591. tmp2 = BN_CTX_get(ctx);
  592. x = BN_CTX_get(ctx);
  593. y = BN_CTX_get(ctx);
  594. if (y == NULL)
  595. goto err;
  596. /*-
  597. * Recover y. We have a Weierstrass equation
  598. * y^2 = x^3 + a*x + b,
  599. * so y is one of the square roots of x^3 + a*x + b.
  600. */
  601. /* tmp1 := x^3 */
  602. if (!BN_nnmod(x, x_, &group->field, ctx))
  603. goto err;
  604. if (group->meth->field_decode == 0) {
  605. /* field_{sqr,mul} work on standard representation */
  606. if (!group->meth->field_sqr(group, tmp2, x_, ctx))
  607. goto err;
  608. if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
  609. goto err;
  610. } else {
  611. if (!BN_mod_sqr(tmp2, x_, &group->field, ctx))
  612. goto err;
  613. if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx))
  614. goto err;
  615. }
  616. /* tmp1 := tmp1 + a*x */
  617. if (group->a_is_minus3) {
  618. if (!BN_mod_lshift1_quick(tmp2, x, &group->field))
  619. goto err;
  620. if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field))
  621. goto err;
  622. if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field))
  623. goto err;
  624. } else {
  625. if (group->meth->field_decode) {
  626. if (!group->meth->field_decode(group, tmp2, &group->a, ctx))
  627. goto err;
  628. if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx))
  629. goto err;
  630. } else {
  631. /* field_mul works on standard representation */
  632. if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx))
  633. goto err;
  634. }
  635. if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
  636. goto err;
  637. }
  638. /* tmp1 := tmp1 + b */
  639. if (group->meth->field_decode) {
  640. if (!group->meth->field_decode(group, tmp2, &group->b, ctx))
  641. goto err;
  642. if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
  643. goto err;
  644. } else {
  645. if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field))
  646. goto err;
  647. }
  648. if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
  649. unsigned long err = ERR_peek_last_error();
  650. if (ERR_GET_LIB(err) == ERR_LIB_BN
  651. && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
  652. ERR_clear_error();
  653. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  654. EC_R_INVALID_COMPRESSED_POINT);
  655. } else
  656. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  657. ERR_R_BN_LIB);
  658. goto err;
  659. }
  660. if (y_bit != BN_is_odd(y)) {
  661. if (BN_is_zero(y)) {
  662. int kron;
  663. kron = BN_kronecker(x, &group->field, ctx);
  664. if (kron == -2)
  665. goto err;
  666. if (kron == 1)
  667. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  668. EC_R_INVALID_COMPRESSION_BIT);
  669. else
  670. /*
  671. * BN_mod_sqrt() should have cought this error (not a square)
  672. */
  673. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  674. EC_R_INVALID_COMPRESSED_POINT);
  675. goto err;
  676. }
  677. if (!BN_usub(y, &group->field, y))
  678. goto err;
  679. }
  680. if (y_bit != BN_is_odd(y)) {
  681. ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
  682. ERR_R_INTERNAL_ERROR);
  683. goto err;
  684. }
  685. if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
  686. goto err;
  687. ret = 1;
  688. err:
  689. BN_CTX_end(ctx);
  690. if (new_ctx != NULL)
  691. BN_CTX_free(new_ctx);
  692. return ret;
  693. }
  694. size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
  695. point_conversion_form_t form,
  696. unsigned char *buf, size_t len, BN_CTX *ctx)
  697. {
  698. size_t ret;
  699. BN_CTX *new_ctx = NULL;
  700. int used_ctx = 0;
  701. BIGNUM *x, *y;
  702. size_t field_len, i, skip;
  703. if ((form != POINT_CONVERSION_COMPRESSED)
  704. && (form != POINT_CONVERSION_UNCOMPRESSED)
  705. && (form != POINT_CONVERSION_HYBRID)) {
  706. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
  707. goto err;
  708. }
  709. if (EC_POINT_is_at_infinity(group, point)) {
  710. /* encodes to a single 0 octet */
  711. if (buf != NULL) {
  712. if (len < 1) {
  713. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
  714. return 0;
  715. }
  716. buf[0] = 0;
  717. }
  718. return 1;
  719. }
  720. /* ret := required output buffer length */
  721. field_len = BN_num_bytes(&group->field);
  722. ret =
  723. (form ==
  724. POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
  725. /* if 'buf' is NULL, just return required length */
  726. if (buf != NULL) {
  727. if (len < ret) {
  728. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
  729. goto err;
  730. }
  731. if (ctx == NULL) {
  732. ctx = new_ctx = BN_CTX_new();
  733. if (ctx == NULL)
  734. return 0;
  735. }
  736. BN_CTX_start(ctx);
  737. used_ctx = 1;
  738. x = BN_CTX_get(ctx);
  739. y = BN_CTX_get(ctx);
  740. if (y == NULL)
  741. goto err;
  742. if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
  743. goto err;
  744. if ((form == POINT_CONVERSION_COMPRESSED
  745. || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
  746. buf[0] = form + 1;
  747. else
  748. buf[0] = form;
  749. i = 1;
  750. skip = field_len - BN_num_bytes(x);
  751. if (skip > field_len) {
  752. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
  753. goto err;
  754. }
  755. while (skip > 0) {
  756. buf[i++] = 0;
  757. skip--;
  758. }
  759. skip = BN_bn2bin(x, buf + i);
  760. i += skip;
  761. if (i != 1 + field_len) {
  762. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
  763. goto err;
  764. }
  765. if (form == POINT_CONVERSION_UNCOMPRESSED
  766. || form == POINT_CONVERSION_HYBRID) {
  767. skip = field_len - BN_num_bytes(y);
  768. if (skip > field_len) {
  769. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
  770. goto err;
  771. }
  772. while (skip > 0) {
  773. buf[i++] = 0;
  774. skip--;
  775. }
  776. skip = BN_bn2bin(y, buf + i);
  777. i += skip;
  778. }
  779. if (i != ret) {
  780. ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
  781. goto err;
  782. }
  783. }
  784. if (used_ctx)
  785. BN_CTX_end(ctx);
  786. if (new_ctx != NULL)
  787. BN_CTX_free(new_ctx);
  788. return ret;
  789. err:
  790. if (used_ctx)
  791. BN_CTX_end(ctx);
  792. if (new_ctx != NULL)
  793. BN_CTX_free(new_ctx);
  794. return 0;
  795. }
  796. int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
  797. const unsigned char *buf, size_t len, BN_CTX *ctx)
  798. {
  799. point_conversion_form_t form;
  800. int y_bit;
  801. BN_CTX *new_ctx = NULL;
  802. BIGNUM *x, *y;
  803. size_t field_len, enc_len;
  804. int ret = 0;
  805. if (len == 0) {
  806. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
  807. return 0;
  808. }
  809. form = buf[0];
  810. y_bit = form & 1;
  811. form = form & ~1U;
  812. if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
  813. && (form != POINT_CONVERSION_UNCOMPRESSED)
  814. && (form != POINT_CONVERSION_HYBRID)) {
  815. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  816. return 0;
  817. }
  818. if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
  819. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  820. return 0;
  821. }
  822. if (form == 0) {
  823. if (len != 1) {
  824. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  825. return 0;
  826. }
  827. return EC_POINT_set_to_infinity(group, point);
  828. }
  829. field_len = BN_num_bytes(&group->field);
  830. enc_len =
  831. (form ==
  832. POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
  833. if (len != enc_len) {
  834. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  835. return 0;
  836. }
  837. if (ctx == NULL) {
  838. ctx = new_ctx = BN_CTX_new();
  839. if (ctx == NULL)
  840. return 0;
  841. }
  842. BN_CTX_start(ctx);
  843. x = BN_CTX_get(ctx);
  844. y = BN_CTX_get(ctx);
  845. if (y == NULL)
  846. goto err;
  847. if (!BN_bin2bn(buf + 1, field_len, x))
  848. goto err;
  849. if (BN_ucmp(x, &group->field) >= 0) {
  850. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  851. goto err;
  852. }
  853. if (form == POINT_CONVERSION_COMPRESSED) {
  854. if (!EC_POINT_set_compressed_coordinates_GFp
  855. (group, point, x, y_bit, ctx))
  856. goto err;
  857. } else {
  858. if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
  859. goto err;
  860. if (BN_ucmp(y, &group->field) >= 0) {
  861. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  862. goto err;
  863. }
  864. if (form == POINT_CONVERSION_HYBRID) {
  865. if (y_bit != BN_is_odd(y)) {
  866. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
  867. goto err;
  868. }
  869. }
  870. if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
  871. goto err;
  872. }
  873. /* test required by X9.62 */
  874. if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
  875. ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
  876. goto err;
  877. }
  878. ret = 1;
  879. err:
  880. BN_CTX_end(ctx);
  881. if (new_ctx != NULL)
  882. BN_CTX_free(new_ctx);
  883. return ret;
  884. }
  885. int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  886. const EC_POINT *b, BN_CTX *ctx)
  887. {
  888. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  889. const BIGNUM *, BN_CTX *);
  890. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  891. const BIGNUM *p;
  892. BN_CTX *new_ctx = NULL;
  893. BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
  894. int ret = 0;
  895. if (a == b)
  896. return EC_POINT_dbl(group, r, a, ctx);
  897. if (EC_POINT_is_at_infinity(group, a))
  898. return EC_POINT_copy(r, b);
  899. if (EC_POINT_is_at_infinity(group, b))
  900. return EC_POINT_copy(r, a);
  901. field_mul = group->meth->field_mul;
  902. field_sqr = group->meth->field_sqr;
  903. p = &group->field;
  904. if (ctx == NULL) {
  905. ctx = new_ctx = BN_CTX_new();
  906. if (ctx == NULL)
  907. return 0;
  908. }
  909. BN_CTX_start(ctx);
  910. n0 = BN_CTX_get(ctx);
  911. n1 = BN_CTX_get(ctx);
  912. n2 = BN_CTX_get(ctx);
  913. n3 = BN_CTX_get(ctx);
  914. n4 = BN_CTX_get(ctx);
  915. n5 = BN_CTX_get(ctx);
  916. n6 = BN_CTX_get(ctx);
  917. if (n6 == NULL)
  918. goto end;
  919. /*
  920. * Note that in this function we must not read components of 'a' or 'b'
  921. * once we have written the corresponding components of 'r'. ('r' might
  922. * be one of 'a' or 'b'.)
  923. */
  924. /* n1, n2 */
  925. if (b->Z_is_one) {
  926. if (!BN_copy(n1, &a->X))
  927. goto end;
  928. if (!BN_copy(n2, &a->Y))
  929. goto end;
  930. /* n1 = X_a */
  931. /* n2 = Y_a */
  932. } else {
  933. if (!field_sqr(group, n0, &b->Z, ctx))
  934. goto end;
  935. if (!field_mul(group, n1, &a->X, n0, ctx))
  936. goto end;
  937. /* n1 = X_a * Z_b^2 */
  938. if (!field_mul(group, n0, n0, &b->Z, ctx))
  939. goto end;
  940. if (!field_mul(group, n2, &a->Y, n0, ctx))
  941. goto end;
  942. /* n2 = Y_a * Z_b^3 */
  943. }
  944. /* n3, n4 */
  945. if (a->Z_is_one) {
  946. if (!BN_copy(n3, &b->X))
  947. goto end;
  948. if (!BN_copy(n4, &b->Y))
  949. goto end;
  950. /* n3 = X_b */
  951. /* n4 = Y_b */
  952. } else {
  953. if (!field_sqr(group, n0, &a->Z, ctx))
  954. goto end;
  955. if (!field_mul(group, n3, &b->X, n0, ctx))
  956. goto end;
  957. /* n3 = X_b * Z_a^2 */
  958. if (!field_mul(group, n0, n0, &a->Z, ctx))
  959. goto end;
  960. if (!field_mul(group, n4, &b->Y, n0, ctx))
  961. goto end;
  962. /* n4 = Y_b * Z_a^3 */
  963. }
  964. /* n5, n6 */
  965. if (!BN_mod_sub_quick(n5, n1, n3, p))
  966. goto end;
  967. if (!BN_mod_sub_quick(n6, n2, n4, p))
  968. goto end;
  969. /* n5 = n1 - n3 */
  970. /* n6 = n2 - n4 */
  971. if (BN_is_zero(n5)) {
  972. if (BN_is_zero(n6)) {
  973. /* a is the same point as b */
  974. BN_CTX_end(ctx);
  975. ret = EC_POINT_dbl(group, r, a, ctx);
  976. ctx = NULL;
  977. goto end;
  978. } else {
  979. /* a is the inverse of b */
  980. BN_zero(&r->Z);
  981. r->Z_is_one = 0;
  982. ret = 1;
  983. goto end;
  984. }
  985. }
  986. /* 'n7', 'n8' */
  987. if (!BN_mod_add_quick(n1, n1, n3, p))
  988. goto end;
  989. if (!BN_mod_add_quick(n2, n2, n4, p))
  990. goto end;
  991. /* 'n7' = n1 + n3 */
  992. /* 'n8' = n2 + n4 */
  993. /* Z_r */
  994. if (a->Z_is_one && b->Z_is_one) {
  995. if (!BN_copy(&r->Z, n5))
  996. goto end;
  997. } else {
  998. if (a->Z_is_one) {
  999. if (!BN_copy(n0, &b->Z))
  1000. goto end;
  1001. } else if (b->Z_is_one) {
  1002. if (!BN_copy(n0, &a->Z))
  1003. goto end;
  1004. } else {
  1005. if (!field_mul(group, n0, &a->Z, &b->Z, ctx))
  1006. goto end;
  1007. }
  1008. if (!field_mul(group, &r->Z, n0, n5, ctx))
  1009. goto end;
  1010. }
  1011. r->Z_is_one = 0;
  1012. /* Z_r = Z_a * Z_b * n5 */
  1013. /* X_r */
  1014. if (!field_sqr(group, n0, n6, ctx))
  1015. goto end;
  1016. if (!field_sqr(group, n4, n5, ctx))
  1017. goto end;
  1018. if (!field_mul(group, n3, n1, n4, ctx))
  1019. goto end;
  1020. if (!BN_mod_sub_quick(&r->X, n0, n3, p))
  1021. goto end;
  1022. /* X_r = n6^2 - n5^2 * 'n7' */
  1023. /* 'n9' */
  1024. if (!BN_mod_lshift1_quick(n0, &r->X, p))
  1025. goto end;
  1026. if (!BN_mod_sub_quick(n0, n3, n0, p))
  1027. goto end;
  1028. /* n9 = n5^2 * 'n7' - 2 * X_r */
  1029. /* Y_r */
  1030. if (!field_mul(group, n0, n0, n6, ctx))
  1031. goto end;
  1032. if (!field_mul(group, n5, n4, n5, ctx))
  1033. goto end; /* now n5 is n5^3 */
  1034. if (!field_mul(group, n1, n2, n5, ctx))
  1035. goto end;
  1036. if (!BN_mod_sub_quick(n0, n0, n1, p))
  1037. goto end;
  1038. if (BN_is_odd(n0))
  1039. if (!BN_add(n0, n0, p))
  1040. goto end;
  1041. /* now 0 <= n0 < 2*p, and n0 is even */
  1042. if (!BN_rshift1(&r->Y, n0))
  1043. goto end;
  1044. /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
  1045. ret = 1;
  1046. end:
  1047. if (ctx) /* otherwise we already called BN_CTX_end */
  1048. BN_CTX_end(ctx);
  1049. if (new_ctx != NULL)
  1050. BN_CTX_free(new_ctx);
  1051. return ret;
  1052. }
  1053. int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  1054. BN_CTX *ctx)
  1055. {
  1056. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  1057. const BIGNUM *, BN_CTX *);
  1058. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  1059. const BIGNUM *p;
  1060. BN_CTX *new_ctx = NULL;
  1061. BIGNUM *n0, *n1, *n2, *n3;
  1062. int ret = 0;
  1063. if (EC_POINT_is_at_infinity(group, a)) {
  1064. BN_zero(&r->Z);
  1065. r->Z_is_one = 0;
  1066. return 1;
  1067. }
  1068. field_mul = group->meth->field_mul;
  1069. field_sqr = group->meth->field_sqr;
  1070. p = &group->field;
  1071. if (ctx == NULL) {
  1072. ctx = new_ctx = BN_CTX_new();
  1073. if (ctx == NULL)
  1074. return 0;
  1075. }
  1076. BN_CTX_start(ctx);
  1077. n0 = BN_CTX_get(ctx);
  1078. n1 = BN_CTX_get(ctx);
  1079. n2 = BN_CTX_get(ctx);
  1080. n3 = BN_CTX_get(ctx);
  1081. if (n3 == NULL)
  1082. goto err;
  1083. /*
  1084. * Note that in this function we must not read components of 'a' once we
  1085. * have written the corresponding components of 'r'. ('r' might the same
  1086. * as 'a'.)
  1087. */
  1088. /* n1 */
  1089. if (a->Z_is_one) {
  1090. if (!field_sqr(group, n0, &a->X, ctx))
  1091. goto err;
  1092. if (!BN_mod_lshift1_quick(n1, n0, p))
  1093. goto err;
  1094. if (!BN_mod_add_quick(n0, n0, n1, p))
  1095. goto err;
  1096. if (!BN_mod_add_quick(n1, n0, &group->a, p))
  1097. goto err;
  1098. /* n1 = 3 * X_a^2 + a_curve */
  1099. } else if (group->a_is_minus3) {
  1100. if (!field_sqr(group, n1, &a->Z, ctx))
  1101. goto err;
  1102. if (!BN_mod_add_quick(n0, &a->X, n1, p))
  1103. goto err;
  1104. if (!BN_mod_sub_quick(n2, &a->X, n1, p))
  1105. goto err;
  1106. if (!field_mul(group, n1, n0, n2, ctx))
  1107. goto err;
  1108. if (!BN_mod_lshift1_quick(n0, n1, p))
  1109. goto err;
  1110. if (!BN_mod_add_quick(n1, n0, n1, p))
  1111. goto err;
  1112. /*-
  1113. * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
  1114. * = 3 * X_a^2 - 3 * Z_a^4
  1115. */
  1116. } else {
  1117. if (!field_sqr(group, n0, &a->X, ctx))
  1118. goto err;
  1119. if (!BN_mod_lshift1_quick(n1, n0, p))
  1120. goto err;
  1121. if (!BN_mod_add_quick(n0, n0, n1, p))
  1122. goto err;
  1123. if (!field_sqr(group, n1, &a->Z, ctx))
  1124. goto err;
  1125. if (!field_sqr(group, n1, n1, ctx))
  1126. goto err;
  1127. if (!field_mul(group, n1, n1, &group->a, ctx))
  1128. goto err;
  1129. if (!BN_mod_add_quick(n1, n1, n0, p))
  1130. goto err;
  1131. /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
  1132. }
  1133. /* Z_r */
  1134. if (a->Z_is_one) {
  1135. if (!BN_copy(n0, &a->Y))
  1136. goto err;
  1137. } else {
  1138. if (!field_mul(group, n0, &a->Y, &a->Z, ctx))
  1139. goto err;
  1140. }
  1141. if (!BN_mod_lshift1_quick(&r->Z, n0, p))
  1142. goto err;
  1143. r->Z_is_one = 0;
  1144. /* Z_r = 2 * Y_a * Z_a */
  1145. /* n2 */
  1146. if (!field_sqr(group, n3, &a->Y, ctx))
  1147. goto err;
  1148. if (!field_mul(group, n2, &a->X, n3, ctx))
  1149. goto err;
  1150. if (!BN_mod_lshift_quick(n2, n2, 2, p))
  1151. goto err;
  1152. /* n2 = 4 * X_a * Y_a^2 */
  1153. /* X_r */
  1154. if (!BN_mod_lshift1_quick(n0, n2, p))
  1155. goto err;
  1156. if (!field_sqr(group, &r->X, n1, ctx))
  1157. goto err;
  1158. if (!BN_mod_sub_quick(&r->X, &r->X, n0, p))
  1159. goto err;
  1160. /* X_r = n1^2 - 2 * n2 */
  1161. /* n3 */
  1162. if (!field_sqr(group, n0, n3, ctx))
  1163. goto err;
  1164. if (!BN_mod_lshift_quick(n3, n0, 3, p))
  1165. goto err;
  1166. /* n3 = 8 * Y_a^4 */
  1167. /* Y_r */
  1168. if (!BN_mod_sub_quick(n0, n2, &r->X, p))
  1169. goto err;
  1170. if (!field_mul(group, n0, n1, n0, ctx))
  1171. goto err;
  1172. if (!BN_mod_sub_quick(&r->Y, n0, n3, p))
  1173. goto err;
  1174. /* Y_r = n1 * (n2 - X_r) - n3 */
  1175. ret = 1;
  1176. err:
  1177. BN_CTX_end(ctx);
  1178. if (new_ctx != NULL)
  1179. BN_CTX_free(new_ctx);
  1180. return ret;
  1181. }
  1182. int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
  1183. {
  1184. if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
  1185. /* point is its own inverse */
  1186. return 1;
  1187. return BN_usub(&point->Y, &group->field, &point->Y);
  1188. }
  1189. int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
  1190. {
  1191. return BN_is_zero(&point->Z);
  1192. }
  1193. int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
  1194. BN_CTX *ctx)
  1195. {
  1196. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  1197. const BIGNUM *, BN_CTX *);
  1198. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  1199. const BIGNUM *p;
  1200. BN_CTX *new_ctx = NULL;
  1201. BIGNUM *rh, *tmp, *Z4, *Z6;
  1202. int ret = -1;
  1203. if (EC_POINT_is_at_infinity(group, point))
  1204. return 1;
  1205. field_mul = group->meth->field_mul;
  1206. field_sqr = group->meth->field_sqr;
  1207. p = &group->field;
  1208. if (ctx == NULL) {
  1209. ctx = new_ctx = BN_CTX_new();
  1210. if (ctx == NULL)
  1211. return -1;
  1212. }
  1213. BN_CTX_start(ctx);
  1214. rh = BN_CTX_get(ctx);
  1215. tmp = BN_CTX_get(ctx);
  1216. Z4 = BN_CTX_get(ctx);
  1217. Z6 = BN_CTX_get(ctx);
  1218. if (Z6 == NULL)
  1219. goto err;
  1220. /*-
  1221. * We have a curve defined by a Weierstrass equation
  1222. * y^2 = x^3 + a*x + b.
  1223. * The point to consider is given in Jacobian projective coordinates
  1224. * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
  1225. * Substituting this and multiplying by Z^6 transforms the above equation into
  1226. * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
  1227. * To test this, we add up the right-hand side in 'rh'.
  1228. */
  1229. /* rh := X^2 */
  1230. if (!field_sqr(group, rh, &point->X, ctx))
  1231. goto err;
  1232. if (!point->Z_is_one) {
  1233. if (!field_sqr(group, tmp, &point->Z, ctx))
  1234. goto err;
  1235. if (!field_sqr(group, Z4, tmp, ctx))
  1236. goto err;
  1237. if (!field_mul(group, Z6, Z4, tmp, ctx))
  1238. goto err;
  1239. /* rh := (rh + a*Z^4)*X */
  1240. if (group->a_is_minus3) {
  1241. if (!BN_mod_lshift1_quick(tmp, Z4, p))
  1242. goto err;
  1243. if (!BN_mod_add_quick(tmp, tmp, Z4, p))
  1244. goto err;
  1245. if (!BN_mod_sub_quick(rh, rh, tmp, p))
  1246. goto err;
  1247. if (!field_mul(group, rh, rh, &point->X, ctx))
  1248. goto err;
  1249. } else {
  1250. if (!field_mul(group, tmp, Z4, &group->a, ctx))
  1251. goto err;
  1252. if (!BN_mod_add_quick(rh, rh, tmp, p))
  1253. goto err;
  1254. if (!field_mul(group, rh, rh, &point->X, ctx))
  1255. goto err;
  1256. }
  1257. /* rh := rh + b*Z^6 */
  1258. if (!field_mul(group, tmp, &group->b, Z6, ctx))
  1259. goto err;
  1260. if (!BN_mod_add_quick(rh, rh, tmp, p))
  1261. goto err;
  1262. } else {
  1263. /* point->Z_is_one */
  1264. /* rh := (rh + a)*X */
  1265. if (!BN_mod_add_quick(rh, rh, &group->a, p))
  1266. goto err;
  1267. if (!field_mul(group, rh, rh, &point->X, ctx))
  1268. goto err;
  1269. /* rh := rh + b */
  1270. if (!BN_mod_add_quick(rh, rh, &group->b, p))
  1271. goto err;
  1272. }
  1273. /* 'lh' := Y^2 */
  1274. if (!field_sqr(group, tmp, &point->Y, ctx))
  1275. goto err;
  1276. ret = (0 == BN_ucmp(tmp, rh));
  1277. err:
  1278. BN_CTX_end(ctx);
  1279. if (new_ctx != NULL)
  1280. BN_CTX_free(new_ctx);
  1281. return ret;
  1282. }
  1283. int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
  1284. const EC_POINT *b, BN_CTX *ctx)
  1285. {
  1286. /*-
  1287. * return values:
  1288. * -1 error
  1289. * 0 equal (in affine coordinates)
  1290. * 1 not equal
  1291. */
  1292. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  1293. const BIGNUM *, BN_CTX *);
  1294. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  1295. BN_CTX *new_ctx = NULL;
  1296. BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
  1297. const BIGNUM *tmp1_, *tmp2_;
  1298. int ret = -1;
  1299. if (EC_POINT_is_at_infinity(group, a)) {
  1300. return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
  1301. }
  1302. if (EC_POINT_is_at_infinity(group, b))
  1303. return 1;
  1304. if (a->Z_is_one && b->Z_is_one) {
  1305. return ((BN_cmp(&a->X, &b->X) == 0)
  1306. && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
  1307. }
  1308. field_mul = group->meth->field_mul;
  1309. field_sqr = group->meth->field_sqr;
  1310. if (ctx == NULL) {
  1311. ctx = new_ctx = BN_CTX_new();
  1312. if (ctx == NULL)
  1313. return -1;
  1314. }
  1315. BN_CTX_start(ctx);
  1316. tmp1 = BN_CTX_get(ctx);
  1317. tmp2 = BN_CTX_get(ctx);
  1318. Za23 = BN_CTX_get(ctx);
  1319. Zb23 = BN_CTX_get(ctx);
  1320. if (Zb23 == NULL)
  1321. goto end;
  1322. /*-
  1323. * We have to decide whether
  1324. * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
  1325. * or equivalently, whether
  1326. * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
  1327. */
  1328. if (!b->Z_is_one) {
  1329. if (!field_sqr(group, Zb23, &b->Z, ctx))
  1330. goto end;
  1331. if (!field_mul(group, tmp1, &a->X, Zb23, ctx))
  1332. goto end;
  1333. tmp1_ = tmp1;
  1334. } else
  1335. tmp1_ = &a->X;
  1336. if (!a->Z_is_one) {
  1337. if (!field_sqr(group, Za23, &a->Z, ctx))
  1338. goto end;
  1339. if (!field_mul(group, tmp2, &b->X, Za23, ctx))
  1340. goto end;
  1341. tmp2_ = tmp2;
  1342. } else
  1343. tmp2_ = &b->X;
  1344. /* compare X_a*Z_b^2 with X_b*Z_a^2 */
  1345. if (BN_cmp(tmp1_, tmp2_) != 0) {
  1346. ret = 1; /* points differ */
  1347. goto end;
  1348. }
  1349. if (!b->Z_is_one) {
  1350. if (!field_mul(group, Zb23, Zb23, &b->Z, ctx))
  1351. goto end;
  1352. if (!field_mul(group, tmp1, &a->Y, Zb23, ctx))
  1353. goto end;
  1354. /* tmp1_ = tmp1 */
  1355. } else
  1356. tmp1_ = &a->Y;
  1357. if (!a->Z_is_one) {
  1358. if (!field_mul(group, Za23, Za23, &a->Z, ctx))
  1359. goto end;
  1360. if (!field_mul(group, tmp2, &b->Y, Za23, ctx))
  1361. goto end;
  1362. /* tmp2_ = tmp2 */
  1363. } else
  1364. tmp2_ = &b->Y;
  1365. /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
  1366. if (BN_cmp(tmp1_, tmp2_) != 0) {
  1367. ret = 1; /* points differ */
  1368. goto end;
  1369. }
  1370. /* points are equal */
  1371. ret = 0;
  1372. end:
  1373. BN_CTX_end(ctx);
  1374. if (new_ctx != NULL)
  1375. BN_CTX_free(new_ctx);
  1376. return ret;
  1377. }
  1378. int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
  1379. BN_CTX *ctx)
  1380. {
  1381. BN_CTX *new_ctx = NULL;
  1382. BIGNUM *x, *y;
  1383. int ret = 0;
  1384. if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
  1385. return 1;
  1386. if (ctx == NULL) {
  1387. ctx = new_ctx = BN_CTX_new();
  1388. if (ctx == NULL)
  1389. return 0;
  1390. }
  1391. BN_CTX_start(ctx);
  1392. x = BN_CTX_get(ctx);
  1393. y = BN_CTX_get(ctx);
  1394. if (y == NULL)
  1395. goto err;
  1396. if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
  1397. goto err;
  1398. if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
  1399. goto err;
  1400. if (!point->Z_is_one) {
  1401. ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
  1402. goto err;
  1403. }
  1404. ret = 1;
  1405. err:
  1406. BN_CTX_end(ctx);
  1407. if (new_ctx != NULL)
  1408. BN_CTX_free(new_ctx);
  1409. return ret;
  1410. }
  1411. int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
  1412. EC_POINT *points[], BN_CTX *ctx)
  1413. {
  1414. BN_CTX *new_ctx = NULL;
  1415. BIGNUM *tmp, *tmp_Z;
  1416. BIGNUM **prod_Z = NULL;
  1417. size_t i;
  1418. int ret = 0;
  1419. if (num == 0)
  1420. return 1;
  1421. if (ctx == NULL) {
  1422. ctx = new_ctx = BN_CTX_new();
  1423. if (ctx == NULL)
  1424. return 0;
  1425. }
  1426. BN_CTX_start(ctx);
  1427. tmp = BN_CTX_get(ctx);
  1428. tmp_Z = BN_CTX_get(ctx);
  1429. if (tmp == NULL || tmp_Z == NULL)
  1430. goto err;
  1431. prod_Z = OPENSSL_malloc(num * sizeof prod_Z[0]);
  1432. if (prod_Z == NULL)
  1433. goto err;
  1434. for (i = 0; i < num; i++) {
  1435. prod_Z[i] = BN_new();
  1436. if (prod_Z[i] == NULL)
  1437. goto err;
  1438. }
  1439. /*
  1440. * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
  1441. * skipping any zero-valued inputs (pretend that they're 1).
  1442. */
  1443. if (!BN_is_zero(&points[0]->Z)) {
  1444. if (!BN_copy(prod_Z[0], &points[0]->Z))
  1445. goto err;
  1446. } else {
  1447. if (group->meth->field_set_to_one != 0) {
  1448. if (!group->meth->field_set_to_one(group, prod_Z[0], ctx))
  1449. goto err;
  1450. } else {
  1451. if (!BN_one(prod_Z[0]))
  1452. goto err;
  1453. }
  1454. }
  1455. for (i = 1; i < num; i++) {
  1456. if (!BN_is_zero(&points[i]->Z)) {
  1457. if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1],
  1458. &points[i]->Z, ctx))
  1459. goto err;
  1460. } else {
  1461. if (!BN_copy(prod_Z[i], prod_Z[i - 1]))
  1462. goto err;
  1463. }
  1464. }
  1465. /*
  1466. * Now use a single explicit inversion to replace every non-zero
  1467. * points[i]->Z by its inverse.
  1468. */
  1469. if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) {
  1470. ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
  1471. goto err;
  1472. }
  1473. if (group->meth->field_encode != 0) {
  1474. /*
  1475. * In the Montgomery case, we just turned R*H (representing H) into
  1476. * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to
  1477. * multiply by the Montgomery factor twice.
  1478. */
  1479. if (!group->meth->field_encode(group, tmp, tmp, ctx))
  1480. goto err;
  1481. if (!group->meth->field_encode(group, tmp, tmp, ctx))
  1482. goto err;
  1483. }
  1484. for (i = num - 1; i > 0; --i) {
  1485. /*
  1486. * Loop invariant: tmp is the product of the inverses of points[0]->Z
  1487. * .. points[i]->Z (zero-valued inputs skipped).
  1488. */
  1489. if (!BN_is_zero(&points[i]->Z)) {
  1490. /*
  1491. * Set tmp_Z to the inverse of points[i]->Z (as product of Z
  1492. * inverses 0 .. i, Z values 0 .. i - 1).
  1493. */
  1494. if (!group->
  1495. meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
  1496. goto err;
  1497. /*
  1498. * Update tmp to satisfy the loop invariant for i - 1.
  1499. */
  1500. if (!group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx))
  1501. goto err;
  1502. /* Replace points[i]->Z by its inverse. */
  1503. if (!BN_copy(&points[i]->Z, tmp_Z))
  1504. goto err;
  1505. }
  1506. }
  1507. if (!BN_is_zero(&points[0]->Z)) {
  1508. /* Replace points[0]->Z by its inverse. */
  1509. if (!BN_copy(&points[0]->Z, tmp))
  1510. goto err;
  1511. }
  1512. /* Finally, fix up the X and Y coordinates for all points. */
  1513. for (i = 0; i < num; i++) {
  1514. EC_POINT *p = points[i];
  1515. if (!BN_is_zero(&p->Z)) {
  1516. /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
  1517. if (!group->meth->field_sqr(group, tmp, &p->Z, ctx))
  1518. goto err;
  1519. if (!group->meth->field_mul(group, &p->X, &p->X, tmp, ctx))
  1520. goto err;
  1521. if (!group->meth->field_mul(group, tmp, tmp, &p->Z, ctx))
  1522. goto err;
  1523. if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx))
  1524. goto err;
  1525. if (group->meth->field_set_to_one != 0) {
  1526. if (!group->meth->field_set_to_one(group, &p->Z, ctx))
  1527. goto err;
  1528. } else {
  1529. if (!BN_one(&p->Z))
  1530. goto err;
  1531. }
  1532. p->Z_is_one = 1;
  1533. }
  1534. }
  1535. ret = 1;
  1536. err:
  1537. BN_CTX_end(ctx);
  1538. if (new_ctx != NULL)
  1539. BN_CTX_free(new_ctx);
  1540. if (prod_Z != NULL) {
  1541. for (i = 0; i < num; i++) {
  1542. if (prod_Z[i] == NULL)
  1543. break;
  1544. BN_clear_free(prod_Z[i]);
  1545. }
  1546. OPENSSL_free(prod_Z);
  1547. }
  1548. return ret;
  1549. }
  1550. int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
  1551. const BIGNUM *b, BN_CTX *ctx)
  1552. {
  1553. return BN_mod_mul(r, a, b, &group->field, ctx);
  1554. }
  1555. int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
  1556. BN_CTX *ctx)
  1557. {
  1558. return BN_mod_sqr(r, a, &group->field, ctx);
  1559. }