2
0

ecp_smpl.c 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409
  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. EC_FLAGS_DEFAULT_OCT,
  72. NID_X9_62_prime_field,
  73. ec_GFp_simple_group_init,
  74. ec_GFp_simple_group_finish,
  75. ec_GFp_simple_group_clear_finish,
  76. ec_GFp_simple_group_copy,
  77. ec_GFp_simple_group_set_curve,
  78. ec_GFp_simple_group_get_curve,
  79. ec_GFp_simple_group_get_degree,
  80. ec_GFp_simple_group_check_discriminant,
  81. ec_GFp_simple_point_init,
  82. ec_GFp_simple_point_finish,
  83. ec_GFp_simple_point_clear_finish,
  84. ec_GFp_simple_point_copy,
  85. ec_GFp_simple_point_set_to_infinity,
  86. ec_GFp_simple_set_Jprojective_coordinates_GFp,
  87. ec_GFp_simple_get_Jprojective_coordinates_GFp,
  88. ec_GFp_simple_point_set_affine_coordinates,
  89. ec_GFp_simple_point_get_affine_coordinates,
  90. 0, 0, 0,
  91. ec_GFp_simple_add,
  92. ec_GFp_simple_dbl,
  93. ec_GFp_simple_invert,
  94. ec_GFp_simple_is_at_infinity,
  95. ec_GFp_simple_is_on_curve,
  96. ec_GFp_simple_cmp,
  97. ec_GFp_simple_make_affine,
  98. ec_GFp_simple_points_make_affine,
  99. 0 /* mul */ ,
  100. 0 /* precompute_mult */ ,
  101. 0 /* have_precompute_mult */ ,
  102. ec_GFp_simple_field_mul,
  103. ec_GFp_simple_field_sqr,
  104. 0 /* field_div */ ,
  105. 0 /* field_encode */ ,
  106. 0 /* field_decode */ ,
  107. 0 /* field_set_to_one */
  108. };
  109. return &ret;
  110. }
  111. /*
  112. * Most method functions in this file are designed to work with
  113. * non-trivial representations of field elements if necessary
  114. * (see ecp_mont.c): while standard modular addition and subtraction
  115. * are used, the field_mul and field_sqr methods will be used for
  116. * multiplication, and field_encode and field_decode (if defined)
  117. * will be used for converting between representations.
  118. *
  119. * Functions ec_GFp_simple_points_make_affine() and
  120. * ec_GFp_simple_point_get_affine_coordinates() specifically assume
  121. * that if a non-trivial representation is used, it is a Montgomery
  122. * representation (i.e. 'encoding' means multiplying by some factor R).
  123. */
  124. int ec_GFp_simple_group_init(EC_GROUP *group)
  125. {
  126. group->field = BN_new();
  127. group->a = BN_new();
  128. group->b = BN_new();
  129. if (!group->field || !group->a || !group->b) {
  130. BN_free(group->field);
  131. BN_free(group->a);
  132. BN_free(group->b);
  133. return 0;
  134. }
  135. group->a_is_minus3 = 0;
  136. return 1;
  137. }
  138. void ec_GFp_simple_group_finish(EC_GROUP *group)
  139. {
  140. BN_free(group->field);
  141. BN_free(group->a);
  142. BN_free(group->b);
  143. }
  144. void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
  145. {
  146. BN_clear_free(group->field);
  147. BN_clear_free(group->a);
  148. BN_clear_free(group->b);
  149. }
  150. int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
  151. {
  152. if (!BN_copy(dest->field, src->field))
  153. return 0;
  154. if (!BN_copy(dest->a, src->a))
  155. return 0;
  156. if (!BN_copy(dest->b, src->b))
  157. return 0;
  158. dest->a_is_minus3 = src->a_is_minus3;
  159. return 1;
  160. }
  161. int ec_GFp_simple_group_set_curve(EC_GROUP *group,
  162. const BIGNUM *p, const BIGNUM *a,
  163. const BIGNUM *b, BN_CTX *ctx)
  164. {
  165. int ret = 0;
  166. BN_CTX *new_ctx = NULL;
  167. BIGNUM *tmp_a;
  168. /* p must be a prime > 3 */
  169. if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
  170. ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
  171. return 0;
  172. }
  173. if (ctx == NULL) {
  174. ctx = new_ctx = BN_CTX_new();
  175. if (ctx == NULL)
  176. return 0;
  177. }
  178. BN_CTX_start(ctx);
  179. tmp_a = BN_CTX_get(ctx);
  180. if (tmp_a == NULL)
  181. goto err;
  182. /* group->field */
  183. if (!BN_copy(group->field, p))
  184. goto err;
  185. BN_set_negative(group->field, 0);
  186. /* group->a */
  187. if (!BN_nnmod(tmp_a, a, p, ctx))
  188. goto err;
  189. if (group->meth->field_encode) {
  190. if (!group->meth->field_encode(group, group->a, tmp_a, ctx))
  191. goto err;
  192. } else if (!BN_copy(group->a, tmp_a))
  193. goto err;
  194. /* group->b */
  195. if (!BN_nnmod(group->b, b, p, ctx))
  196. goto err;
  197. if (group->meth->field_encode)
  198. if (!group->meth->field_encode(group, group->b, group->b, ctx))
  199. goto err;
  200. /* group->a_is_minus3 */
  201. if (!BN_add_word(tmp_a, 3))
  202. goto err;
  203. group->a_is_minus3 = (0 == BN_cmp(tmp_a, group->field));
  204. ret = 1;
  205. err:
  206. BN_CTX_end(ctx);
  207. BN_CTX_free(new_ctx);
  208. return ret;
  209. }
  210. int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  211. BIGNUM *b, BN_CTX *ctx)
  212. {
  213. int ret = 0;
  214. BN_CTX *new_ctx = NULL;
  215. if (p != NULL) {
  216. if (!BN_copy(p, group->field))
  217. return 0;
  218. }
  219. if (a != NULL || b != NULL) {
  220. if (group->meth->field_decode) {
  221. if (ctx == NULL) {
  222. ctx = new_ctx = BN_CTX_new();
  223. if (ctx == NULL)
  224. return 0;
  225. }
  226. if (a != NULL) {
  227. if (!group->meth->field_decode(group, a, group->a, ctx))
  228. goto err;
  229. }
  230. if (b != NULL) {
  231. if (!group->meth->field_decode(group, b, group->b, ctx))
  232. goto err;
  233. }
  234. } else {
  235. if (a != NULL) {
  236. if (!BN_copy(a, group->a))
  237. goto err;
  238. }
  239. if (b != NULL) {
  240. if (!BN_copy(b, group->b))
  241. goto err;
  242. }
  243. }
  244. }
  245. ret = 1;
  246. err:
  247. BN_CTX_free(new_ctx);
  248. return ret;
  249. }
  250. int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
  251. {
  252. return BN_num_bits(group->field);
  253. }
  254. int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
  255. {
  256. int ret = 0;
  257. BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
  258. const BIGNUM *p = group->field;
  259. BN_CTX *new_ctx = NULL;
  260. if (ctx == NULL) {
  261. ctx = new_ctx = BN_CTX_new();
  262. if (ctx == NULL) {
  263. ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,
  264. ERR_R_MALLOC_FAILURE);
  265. goto err;
  266. }
  267. }
  268. BN_CTX_start(ctx);
  269. a = BN_CTX_get(ctx);
  270. b = BN_CTX_get(ctx);
  271. tmp_1 = BN_CTX_get(ctx);
  272. tmp_2 = BN_CTX_get(ctx);
  273. order = BN_CTX_get(ctx);
  274. if (order == NULL)
  275. goto err;
  276. if (group->meth->field_decode) {
  277. if (!group->meth->field_decode(group, a, group->a, ctx))
  278. goto err;
  279. if (!group->meth->field_decode(group, b, group->b, ctx))
  280. goto err;
  281. } else {
  282. if (!BN_copy(a, group->a))
  283. goto err;
  284. if (!BN_copy(b, group->b))
  285. goto err;
  286. }
  287. /*-
  288. * check the discriminant:
  289. * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
  290. * 0 =< a, b < p
  291. */
  292. if (BN_is_zero(a)) {
  293. if (BN_is_zero(b))
  294. goto err;
  295. } else if (!BN_is_zero(b)) {
  296. if (!BN_mod_sqr(tmp_1, a, p, ctx))
  297. goto err;
  298. if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
  299. goto err;
  300. if (!BN_lshift(tmp_1, tmp_2, 2))
  301. goto err;
  302. /* tmp_1 = 4*a^3 */
  303. if (!BN_mod_sqr(tmp_2, b, p, ctx))
  304. goto err;
  305. if (!BN_mul_word(tmp_2, 27))
  306. goto err;
  307. /* tmp_2 = 27*b^2 */
  308. if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
  309. goto err;
  310. if (BN_is_zero(a))
  311. goto err;
  312. }
  313. ret = 1;
  314. err:
  315. if (ctx != NULL)
  316. BN_CTX_end(ctx);
  317. BN_CTX_free(new_ctx);
  318. return ret;
  319. }
  320. int ec_GFp_simple_point_init(EC_POINT *point)
  321. {
  322. point->X = BN_new();
  323. point->Y = BN_new();
  324. point->Z = BN_new();
  325. point->Z_is_one = 0;
  326. if (!point->X || !point->Y || !point->Z) {
  327. BN_free(point->X);
  328. BN_free(point->Y);
  329. BN_free(point->Z);
  330. return 0;
  331. }
  332. return 1;
  333. }
  334. void ec_GFp_simple_point_finish(EC_POINT *point)
  335. {
  336. BN_free(point->X);
  337. BN_free(point->Y);
  338. BN_free(point->Z);
  339. }
  340. void ec_GFp_simple_point_clear_finish(EC_POINT *point)
  341. {
  342. BN_clear_free(point->X);
  343. BN_clear_free(point->Y);
  344. BN_clear_free(point->Z);
  345. point->Z_is_one = 0;
  346. }
  347. int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
  348. {
  349. if (!BN_copy(dest->X, src->X))
  350. return 0;
  351. if (!BN_copy(dest->Y, src->Y))
  352. return 0;
  353. if (!BN_copy(dest->Z, src->Z))
  354. return 0;
  355. dest->Z_is_one = src->Z_is_one;
  356. return 1;
  357. }
  358. int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
  359. EC_POINT *point)
  360. {
  361. point->Z_is_one = 0;
  362. BN_zero(point->Z);
  363. return 1;
  364. }
  365. int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
  366. EC_POINT *point,
  367. const BIGNUM *x,
  368. const BIGNUM *y,
  369. const BIGNUM *z,
  370. BN_CTX *ctx)
  371. {
  372. BN_CTX *new_ctx = NULL;
  373. int ret = 0;
  374. if (ctx == NULL) {
  375. ctx = new_ctx = BN_CTX_new();
  376. if (ctx == NULL)
  377. return 0;
  378. }
  379. if (x != NULL) {
  380. if (!BN_nnmod(point->X, x, group->field, ctx))
  381. goto err;
  382. if (group->meth->field_encode) {
  383. if (!group->meth->field_encode(group, point->X, point->X, ctx))
  384. goto err;
  385. }
  386. }
  387. if (y != NULL) {
  388. if (!BN_nnmod(point->Y, y, group->field, ctx))
  389. goto err;
  390. if (group->meth->field_encode) {
  391. if (!group->meth->field_encode(group, point->Y, point->Y, ctx))
  392. goto err;
  393. }
  394. }
  395. if (z != NULL) {
  396. int Z_is_one;
  397. if (!BN_nnmod(point->Z, z, group->field, ctx))
  398. goto err;
  399. Z_is_one = BN_is_one(point->Z);
  400. if (group->meth->field_encode) {
  401. if (Z_is_one && (group->meth->field_set_to_one != 0)) {
  402. if (!group->meth->field_set_to_one(group, point->Z, ctx))
  403. goto err;
  404. } else {
  405. if (!group->
  406. meth->field_encode(group, point->Z, point->Z, ctx))
  407. goto err;
  408. }
  409. }
  410. point->Z_is_one = Z_is_one;
  411. }
  412. ret = 1;
  413. err:
  414. BN_CTX_free(new_ctx);
  415. return ret;
  416. }
  417. int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
  418. const EC_POINT *point,
  419. BIGNUM *x, BIGNUM *y,
  420. BIGNUM *z, BN_CTX *ctx)
  421. {
  422. BN_CTX *new_ctx = NULL;
  423. int ret = 0;
  424. if (group->meth->field_decode != 0) {
  425. if (ctx == NULL) {
  426. ctx = new_ctx = BN_CTX_new();
  427. if (ctx == NULL)
  428. return 0;
  429. }
  430. if (x != NULL) {
  431. if (!group->meth->field_decode(group, x, point->X, ctx))
  432. goto err;
  433. }
  434. if (y != NULL) {
  435. if (!group->meth->field_decode(group, y, point->Y, ctx))
  436. goto err;
  437. }
  438. if (z != NULL) {
  439. if (!group->meth->field_decode(group, z, point->Z, ctx))
  440. goto err;
  441. }
  442. } else {
  443. if (x != NULL) {
  444. if (!BN_copy(x, point->X))
  445. goto err;
  446. }
  447. if (y != NULL) {
  448. if (!BN_copy(y, point->Y))
  449. goto err;
  450. }
  451. if (z != NULL) {
  452. if (!BN_copy(z, point->Z))
  453. goto err;
  454. }
  455. }
  456. ret = 1;
  457. err:
  458. BN_CTX_free(new_ctx);
  459. return ret;
  460. }
  461. int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
  462. EC_POINT *point,
  463. const BIGNUM *x,
  464. const BIGNUM *y, BN_CTX *ctx)
  465. {
  466. if (x == NULL || y == NULL) {
  467. /*
  468. * unlike for projective coordinates, we do not tolerate this
  469. */
  470. ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES,
  471. ERR_R_PASSED_NULL_PARAMETER);
  472. return 0;
  473. }
  474. return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y,
  475. BN_value_one(), ctx);
  476. }
  477. int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
  478. const EC_POINT *point,
  479. BIGNUM *x, BIGNUM *y,
  480. BN_CTX *ctx)
  481. {
  482. BN_CTX *new_ctx = NULL;
  483. BIGNUM *Z, *Z_1, *Z_2, *Z_3;
  484. const BIGNUM *Z_;
  485. int ret = 0;
  486. if (EC_POINT_is_at_infinity(group, point)) {
  487. ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
  488. EC_R_POINT_AT_INFINITY);
  489. return 0;
  490. }
  491. if (ctx == NULL) {
  492. ctx = new_ctx = BN_CTX_new();
  493. if (ctx == NULL)
  494. return 0;
  495. }
  496. BN_CTX_start(ctx);
  497. Z = BN_CTX_get(ctx);
  498. Z_1 = BN_CTX_get(ctx);
  499. Z_2 = BN_CTX_get(ctx);
  500. Z_3 = BN_CTX_get(ctx);
  501. if (Z_3 == NULL)
  502. goto err;
  503. /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
  504. if (group->meth->field_decode) {
  505. if (!group->meth->field_decode(group, Z, point->Z, ctx))
  506. goto err;
  507. Z_ = Z;
  508. } else {
  509. Z_ = point->Z;
  510. }
  511. if (BN_is_one(Z_)) {
  512. if (group->meth->field_decode) {
  513. if (x != NULL) {
  514. if (!group->meth->field_decode(group, x, point->X, ctx))
  515. goto err;
  516. }
  517. if (y != NULL) {
  518. if (!group->meth->field_decode(group, y, point->Y, ctx))
  519. goto err;
  520. }
  521. } else {
  522. if (x != NULL) {
  523. if (!BN_copy(x, point->X))
  524. goto err;
  525. }
  526. if (y != NULL) {
  527. if (!BN_copy(y, point->Y))
  528. goto err;
  529. }
  530. }
  531. } else {
  532. if (!BN_mod_inverse(Z_1, Z_, group->field, ctx)) {
  533. ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
  534. ERR_R_BN_LIB);
  535. goto err;
  536. }
  537. if (group->meth->field_encode == 0) {
  538. /* field_sqr works on standard representation */
  539. if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
  540. goto err;
  541. } else {
  542. if (!BN_mod_sqr(Z_2, Z_1, group->field, ctx))
  543. goto err;
  544. }
  545. if (x != NULL) {
  546. /*
  547. * in the Montgomery case, field_mul will cancel out Montgomery
  548. * factor in X:
  549. */
  550. if (!group->meth->field_mul(group, x, point->X, Z_2, ctx))
  551. goto err;
  552. }
  553. if (y != NULL) {
  554. if (group->meth->field_encode == 0) {
  555. /*
  556. * field_mul works on standard representation
  557. */
  558. if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
  559. goto err;
  560. } else {
  561. if (!BN_mod_mul(Z_3, Z_2, Z_1, group->field, ctx))
  562. goto err;
  563. }
  564. /*
  565. * in the Montgomery case, field_mul will cancel out Montgomery
  566. * factor in Y:
  567. */
  568. if (!group->meth->field_mul(group, y, point->Y, Z_3, ctx))
  569. goto err;
  570. }
  571. }
  572. ret = 1;
  573. err:
  574. BN_CTX_end(ctx);
  575. BN_CTX_free(new_ctx);
  576. return ret;
  577. }
  578. int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  579. const EC_POINT *b, BN_CTX *ctx)
  580. {
  581. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  582. const BIGNUM *, BN_CTX *);
  583. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  584. const BIGNUM *p;
  585. BN_CTX *new_ctx = NULL;
  586. BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
  587. int ret = 0;
  588. if (a == b)
  589. return EC_POINT_dbl(group, r, a, ctx);
  590. if (EC_POINT_is_at_infinity(group, a))
  591. return EC_POINT_copy(r, b);
  592. if (EC_POINT_is_at_infinity(group, b))
  593. return EC_POINT_copy(r, a);
  594. field_mul = group->meth->field_mul;
  595. field_sqr = group->meth->field_sqr;
  596. p = group->field;
  597. if (ctx == NULL) {
  598. ctx = new_ctx = BN_CTX_new();
  599. if (ctx == NULL)
  600. return 0;
  601. }
  602. BN_CTX_start(ctx);
  603. n0 = BN_CTX_get(ctx);
  604. n1 = BN_CTX_get(ctx);
  605. n2 = BN_CTX_get(ctx);
  606. n3 = BN_CTX_get(ctx);
  607. n4 = BN_CTX_get(ctx);
  608. n5 = BN_CTX_get(ctx);
  609. n6 = BN_CTX_get(ctx);
  610. if (n6 == NULL)
  611. goto end;
  612. /*
  613. * Note that in this function we must not read components of 'a' or 'b'
  614. * once we have written the corresponding components of 'r'. ('r' might
  615. * be one of 'a' or 'b'.)
  616. */
  617. /* n1, n2 */
  618. if (b->Z_is_one) {
  619. if (!BN_copy(n1, a->X))
  620. goto end;
  621. if (!BN_copy(n2, a->Y))
  622. goto end;
  623. /* n1 = X_a */
  624. /* n2 = Y_a */
  625. } else {
  626. if (!field_sqr(group, n0, b->Z, ctx))
  627. goto end;
  628. if (!field_mul(group, n1, a->X, n0, ctx))
  629. goto end;
  630. /* n1 = X_a * Z_b^2 */
  631. if (!field_mul(group, n0, n0, b->Z, ctx))
  632. goto end;
  633. if (!field_mul(group, n2, a->Y, n0, ctx))
  634. goto end;
  635. /* n2 = Y_a * Z_b^3 */
  636. }
  637. /* n3, n4 */
  638. if (a->Z_is_one) {
  639. if (!BN_copy(n3, b->X))
  640. goto end;
  641. if (!BN_copy(n4, b->Y))
  642. goto end;
  643. /* n3 = X_b */
  644. /* n4 = Y_b */
  645. } else {
  646. if (!field_sqr(group, n0, a->Z, ctx))
  647. goto end;
  648. if (!field_mul(group, n3, b->X, n0, ctx))
  649. goto end;
  650. /* n3 = X_b * Z_a^2 */
  651. if (!field_mul(group, n0, n0, a->Z, ctx))
  652. goto end;
  653. if (!field_mul(group, n4, b->Y, n0, ctx))
  654. goto end;
  655. /* n4 = Y_b * Z_a^3 */
  656. }
  657. /* n5, n6 */
  658. if (!BN_mod_sub_quick(n5, n1, n3, p))
  659. goto end;
  660. if (!BN_mod_sub_quick(n6, n2, n4, p))
  661. goto end;
  662. /* n5 = n1 - n3 */
  663. /* n6 = n2 - n4 */
  664. if (BN_is_zero(n5)) {
  665. if (BN_is_zero(n6)) {
  666. /* a is the same point as b */
  667. BN_CTX_end(ctx);
  668. ret = EC_POINT_dbl(group, r, a, ctx);
  669. ctx = NULL;
  670. goto end;
  671. } else {
  672. /* a is the inverse of b */
  673. BN_zero(r->Z);
  674. r->Z_is_one = 0;
  675. ret = 1;
  676. goto end;
  677. }
  678. }
  679. /* 'n7', 'n8' */
  680. if (!BN_mod_add_quick(n1, n1, n3, p))
  681. goto end;
  682. if (!BN_mod_add_quick(n2, n2, n4, p))
  683. goto end;
  684. /* 'n7' = n1 + n3 */
  685. /* 'n8' = n2 + n4 */
  686. /* Z_r */
  687. if (a->Z_is_one && b->Z_is_one) {
  688. if (!BN_copy(r->Z, n5))
  689. goto end;
  690. } else {
  691. if (a->Z_is_one) {
  692. if (!BN_copy(n0, b->Z))
  693. goto end;
  694. } else if (b->Z_is_one) {
  695. if (!BN_copy(n0, a->Z))
  696. goto end;
  697. } else {
  698. if (!field_mul(group, n0, a->Z, b->Z, ctx))
  699. goto end;
  700. }
  701. if (!field_mul(group, r->Z, n0, n5, ctx))
  702. goto end;
  703. }
  704. r->Z_is_one = 0;
  705. /* Z_r = Z_a * Z_b * n5 */
  706. /* X_r */
  707. if (!field_sqr(group, n0, n6, ctx))
  708. goto end;
  709. if (!field_sqr(group, n4, n5, ctx))
  710. goto end;
  711. if (!field_mul(group, n3, n1, n4, ctx))
  712. goto end;
  713. if (!BN_mod_sub_quick(r->X, n0, n3, p))
  714. goto end;
  715. /* X_r = n6^2 - n5^2 * 'n7' */
  716. /* 'n9' */
  717. if (!BN_mod_lshift1_quick(n0, r->X, p))
  718. goto end;
  719. if (!BN_mod_sub_quick(n0, n3, n0, p))
  720. goto end;
  721. /* n9 = n5^2 * 'n7' - 2 * X_r */
  722. /* Y_r */
  723. if (!field_mul(group, n0, n0, n6, ctx))
  724. goto end;
  725. if (!field_mul(group, n5, n4, n5, ctx))
  726. goto end; /* now n5 is n5^3 */
  727. if (!field_mul(group, n1, n2, n5, ctx))
  728. goto end;
  729. if (!BN_mod_sub_quick(n0, n0, n1, p))
  730. goto end;
  731. if (BN_is_odd(n0))
  732. if (!BN_add(n0, n0, p))
  733. goto end;
  734. /* now 0 <= n0 < 2*p, and n0 is even */
  735. if (!BN_rshift1(r->Y, n0))
  736. goto end;
  737. /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
  738. ret = 1;
  739. end:
  740. if (ctx) /* otherwise we already called BN_CTX_end */
  741. BN_CTX_end(ctx);
  742. BN_CTX_free(new_ctx);
  743. return ret;
  744. }
  745. int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  746. BN_CTX *ctx)
  747. {
  748. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  749. const BIGNUM *, BN_CTX *);
  750. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  751. const BIGNUM *p;
  752. BN_CTX *new_ctx = NULL;
  753. BIGNUM *n0, *n1, *n2, *n3;
  754. int ret = 0;
  755. if (EC_POINT_is_at_infinity(group, a)) {
  756. BN_zero(r->Z);
  757. r->Z_is_one = 0;
  758. return 1;
  759. }
  760. field_mul = group->meth->field_mul;
  761. field_sqr = group->meth->field_sqr;
  762. p = group->field;
  763. if (ctx == NULL) {
  764. ctx = new_ctx = BN_CTX_new();
  765. if (ctx == NULL)
  766. return 0;
  767. }
  768. BN_CTX_start(ctx);
  769. n0 = BN_CTX_get(ctx);
  770. n1 = BN_CTX_get(ctx);
  771. n2 = BN_CTX_get(ctx);
  772. n3 = BN_CTX_get(ctx);
  773. if (n3 == NULL)
  774. goto err;
  775. /*
  776. * Note that in this function we must not read components of 'a' once we
  777. * have written the corresponding components of 'r'. ('r' might the same
  778. * as 'a'.)
  779. */
  780. /* n1 */
  781. if (a->Z_is_one) {
  782. if (!field_sqr(group, n0, a->X, ctx))
  783. goto err;
  784. if (!BN_mod_lshift1_quick(n1, n0, p))
  785. goto err;
  786. if (!BN_mod_add_quick(n0, n0, n1, p))
  787. goto err;
  788. if (!BN_mod_add_quick(n1, n0, group->a, p))
  789. goto err;
  790. /* n1 = 3 * X_a^2 + a_curve */
  791. } else if (group->a_is_minus3) {
  792. if (!field_sqr(group, n1, a->Z, ctx))
  793. goto err;
  794. if (!BN_mod_add_quick(n0, a->X, n1, p))
  795. goto err;
  796. if (!BN_mod_sub_quick(n2, a->X, n1, p))
  797. goto err;
  798. if (!field_mul(group, n1, n0, n2, ctx))
  799. goto err;
  800. if (!BN_mod_lshift1_quick(n0, n1, p))
  801. goto err;
  802. if (!BN_mod_add_quick(n1, n0, n1, p))
  803. goto err;
  804. /*-
  805. * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
  806. * = 3 * X_a^2 - 3 * Z_a^4
  807. */
  808. } else {
  809. if (!field_sqr(group, n0, a->X, ctx))
  810. goto err;
  811. if (!BN_mod_lshift1_quick(n1, n0, p))
  812. goto err;
  813. if (!BN_mod_add_quick(n0, n0, n1, p))
  814. goto err;
  815. if (!field_sqr(group, n1, a->Z, ctx))
  816. goto err;
  817. if (!field_sqr(group, n1, n1, ctx))
  818. goto err;
  819. if (!field_mul(group, n1, n1, group->a, ctx))
  820. goto err;
  821. if (!BN_mod_add_quick(n1, n1, n0, p))
  822. goto err;
  823. /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
  824. }
  825. /* Z_r */
  826. if (a->Z_is_one) {
  827. if (!BN_copy(n0, a->Y))
  828. goto err;
  829. } else {
  830. if (!field_mul(group, n0, a->Y, a->Z, ctx))
  831. goto err;
  832. }
  833. if (!BN_mod_lshift1_quick(r->Z, n0, p))
  834. goto err;
  835. r->Z_is_one = 0;
  836. /* Z_r = 2 * Y_a * Z_a */
  837. /* n2 */
  838. if (!field_sqr(group, n3, a->Y, ctx))
  839. goto err;
  840. if (!field_mul(group, n2, a->X, n3, ctx))
  841. goto err;
  842. if (!BN_mod_lshift_quick(n2, n2, 2, p))
  843. goto err;
  844. /* n2 = 4 * X_a * Y_a^2 */
  845. /* X_r */
  846. if (!BN_mod_lshift1_quick(n0, n2, p))
  847. goto err;
  848. if (!field_sqr(group, r->X, n1, ctx))
  849. goto err;
  850. if (!BN_mod_sub_quick(r->X, r->X, n0, p))
  851. goto err;
  852. /* X_r = n1^2 - 2 * n2 */
  853. /* n3 */
  854. if (!field_sqr(group, n0, n3, ctx))
  855. goto err;
  856. if (!BN_mod_lshift_quick(n3, n0, 3, p))
  857. goto err;
  858. /* n3 = 8 * Y_a^4 */
  859. /* Y_r */
  860. if (!BN_mod_sub_quick(n0, n2, r->X, p))
  861. goto err;
  862. if (!field_mul(group, n0, n1, n0, ctx))
  863. goto err;
  864. if (!BN_mod_sub_quick(r->Y, n0, n3, p))
  865. goto err;
  866. /* Y_r = n1 * (n2 - X_r) - n3 */
  867. ret = 1;
  868. err:
  869. BN_CTX_end(ctx);
  870. BN_CTX_free(new_ctx);
  871. return ret;
  872. }
  873. int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
  874. {
  875. if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
  876. /* point is its own inverse */
  877. return 1;
  878. return BN_usub(point->Y, group->field, point->Y);
  879. }
  880. int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
  881. {
  882. return BN_is_zero(point->Z);
  883. }
  884. int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
  885. BN_CTX *ctx)
  886. {
  887. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  888. const BIGNUM *, BN_CTX *);
  889. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  890. const BIGNUM *p;
  891. BN_CTX *new_ctx = NULL;
  892. BIGNUM *rh, *tmp, *Z4, *Z6;
  893. int ret = -1;
  894. if (EC_POINT_is_at_infinity(group, point))
  895. return 1;
  896. field_mul = group->meth->field_mul;
  897. field_sqr = group->meth->field_sqr;
  898. p = group->field;
  899. if (ctx == NULL) {
  900. ctx = new_ctx = BN_CTX_new();
  901. if (ctx == NULL)
  902. return -1;
  903. }
  904. BN_CTX_start(ctx);
  905. rh = BN_CTX_get(ctx);
  906. tmp = BN_CTX_get(ctx);
  907. Z4 = BN_CTX_get(ctx);
  908. Z6 = BN_CTX_get(ctx);
  909. if (Z6 == NULL)
  910. goto err;
  911. /*-
  912. * We have a curve defined by a Weierstrass equation
  913. * y^2 = x^3 + a*x + b.
  914. * The point to consider is given in Jacobian projective coordinates
  915. * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
  916. * Substituting this and multiplying by Z^6 transforms the above equation into
  917. * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
  918. * To test this, we add up the right-hand side in 'rh'.
  919. */
  920. /* rh := X^2 */
  921. if (!field_sqr(group, rh, point->X, ctx))
  922. goto err;
  923. if (!point->Z_is_one) {
  924. if (!field_sqr(group, tmp, point->Z, ctx))
  925. goto err;
  926. if (!field_sqr(group, Z4, tmp, ctx))
  927. goto err;
  928. if (!field_mul(group, Z6, Z4, tmp, ctx))
  929. goto err;
  930. /* rh := (rh + a*Z^4)*X */
  931. if (group->a_is_minus3) {
  932. if (!BN_mod_lshift1_quick(tmp, Z4, p))
  933. goto err;
  934. if (!BN_mod_add_quick(tmp, tmp, Z4, p))
  935. goto err;
  936. if (!BN_mod_sub_quick(rh, rh, tmp, p))
  937. goto err;
  938. if (!field_mul(group, rh, rh, point->X, ctx))
  939. goto err;
  940. } else {
  941. if (!field_mul(group, tmp, Z4, group->a, ctx))
  942. goto err;
  943. if (!BN_mod_add_quick(rh, rh, tmp, p))
  944. goto err;
  945. if (!field_mul(group, rh, rh, point->X, ctx))
  946. goto err;
  947. }
  948. /* rh := rh + b*Z^6 */
  949. if (!field_mul(group, tmp, group->b, Z6, ctx))
  950. goto err;
  951. if (!BN_mod_add_quick(rh, rh, tmp, p))
  952. goto err;
  953. } else {
  954. /* point->Z_is_one */
  955. /* rh := (rh + a)*X */
  956. if (!BN_mod_add_quick(rh, rh, group->a, p))
  957. goto err;
  958. if (!field_mul(group, rh, rh, point->X, ctx))
  959. goto err;
  960. /* rh := rh + b */
  961. if (!BN_mod_add_quick(rh, rh, group->b, p))
  962. goto err;
  963. }
  964. /* 'lh' := Y^2 */
  965. if (!field_sqr(group, tmp, point->Y, ctx))
  966. goto err;
  967. ret = (0 == BN_ucmp(tmp, rh));
  968. err:
  969. BN_CTX_end(ctx);
  970. BN_CTX_free(new_ctx);
  971. return ret;
  972. }
  973. int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
  974. const EC_POINT *b, BN_CTX *ctx)
  975. {
  976. /*-
  977. * return values:
  978. * -1 error
  979. * 0 equal (in affine coordinates)
  980. * 1 not equal
  981. */
  982. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  983. const BIGNUM *, BN_CTX *);
  984. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  985. BN_CTX *new_ctx = NULL;
  986. BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
  987. const BIGNUM *tmp1_, *tmp2_;
  988. int ret = -1;
  989. if (EC_POINT_is_at_infinity(group, a)) {
  990. return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
  991. }
  992. if (EC_POINT_is_at_infinity(group, b))
  993. return 1;
  994. if (a->Z_is_one && b->Z_is_one) {
  995. return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
  996. }
  997. field_mul = group->meth->field_mul;
  998. field_sqr = group->meth->field_sqr;
  999. if (ctx == NULL) {
  1000. ctx = new_ctx = BN_CTX_new();
  1001. if (ctx == NULL)
  1002. return -1;
  1003. }
  1004. BN_CTX_start(ctx);
  1005. tmp1 = BN_CTX_get(ctx);
  1006. tmp2 = BN_CTX_get(ctx);
  1007. Za23 = BN_CTX_get(ctx);
  1008. Zb23 = BN_CTX_get(ctx);
  1009. if (Zb23 == NULL)
  1010. goto end;
  1011. /*-
  1012. * We have to decide whether
  1013. * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
  1014. * or equivalently, whether
  1015. * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
  1016. */
  1017. if (!b->Z_is_one) {
  1018. if (!field_sqr(group, Zb23, b->Z, ctx))
  1019. goto end;
  1020. if (!field_mul(group, tmp1, a->X, Zb23, ctx))
  1021. goto end;
  1022. tmp1_ = tmp1;
  1023. } else
  1024. tmp1_ = a->X;
  1025. if (!a->Z_is_one) {
  1026. if (!field_sqr(group, Za23, a->Z, ctx))
  1027. goto end;
  1028. if (!field_mul(group, tmp2, b->X, Za23, ctx))
  1029. goto end;
  1030. tmp2_ = tmp2;
  1031. } else
  1032. tmp2_ = b->X;
  1033. /* compare X_a*Z_b^2 with X_b*Z_a^2 */
  1034. if (BN_cmp(tmp1_, tmp2_) != 0) {
  1035. ret = 1; /* points differ */
  1036. goto end;
  1037. }
  1038. if (!b->Z_is_one) {
  1039. if (!field_mul(group, Zb23, Zb23, b->Z, ctx))
  1040. goto end;
  1041. if (!field_mul(group, tmp1, a->Y, Zb23, ctx))
  1042. goto end;
  1043. /* tmp1_ = tmp1 */
  1044. } else
  1045. tmp1_ = a->Y;
  1046. if (!a->Z_is_one) {
  1047. if (!field_mul(group, Za23, Za23, a->Z, ctx))
  1048. goto end;
  1049. if (!field_mul(group, tmp2, b->Y, Za23, ctx))
  1050. goto end;
  1051. /* tmp2_ = tmp2 */
  1052. } else
  1053. tmp2_ = b->Y;
  1054. /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
  1055. if (BN_cmp(tmp1_, tmp2_) != 0) {
  1056. ret = 1; /* points differ */
  1057. goto end;
  1058. }
  1059. /* points are equal */
  1060. ret = 0;
  1061. end:
  1062. BN_CTX_end(ctx);
  1063. BN_CTX_free(new_ctx);
  1064. return ret;
  1065. }
  1066. int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
  1067. BN_CTX *ctx)
  1068. {
  1069. BN_CTX *new_ctx = NULL;
  1070. BIGNUM *x, *y;
  1071. int ret = 0;
  1072. if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
  1073. return 1;
  1074. if (ctx == NULL) {
  1075. ctx = new_ctx = BN_CTX_new();
  1076. if (ctx == NULL)
  1077. return 0;
  1078. }
  1079. BN_CTX_start(ctx);
  1080. x = BN_CTX_get(ctx);
  1081. y = BN_CTX_get(ctx);
  1082. if (y == NULL)
  1083. goto err;
  1084. if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
  1085. goto err;
  1086. if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
  1087. goto err;
  1088. if (!point->Z_is_one) {
  1089. ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
  1090. goto err;
  1091. }
  1092. ret = 1;
  1093. err:
  1094. BN_CTX_end(ctx);
  1095. BN_CTX_free(new_ctx);
  1096. return ret;
  1097. }
  1098. int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
  1099. EC_POINT *points[], BN_CTX *ctx)
  1100. {
  1101. BN_CTX *new_ctx = NULL;
  1102. BIGNUM *tmp, *tmp_Z;
  1103. BIGNUM **prod_Z = NULL;
  1104. size_t i;
  1105. int ret = 0;
  1106. if (num == 0)
  1107. return 1;
  1108. if (ctx == NULL) {
  1109. ctx = new_ctx = BN_CTX_new();
  1110. if (ctx == NULL)
  1111. return 0;
  1112. }
  1113. BN_CTX_start(ctx);
  1114. tmp = BN_CTX_get(ctx);
  1115. tmp_Z = BN_CTX_get(ctx);
  1116. if (tmp == NULL || tmp_Z == NULL)
  1117. goto err;
  1118. prod_Z = OPENSSL_malloc(num * sizeof prod_Z[0]);
  1119. if (prod_Z == NULL)
  1120. goto err;
  1121. for (i = 0; i < num; i++) {
  1122. prod_Z[i] = BN_new();
  1123. if (prod_Z[i] == NULL)
  1124. goto err;
  1125. }
  1126. /*
  1127. * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
  1128. * skipping any zero-valued inputs (pretend that they're 1).
  1129. */
  1130. if (!BN_is_zero(points[0]->Z)) {
  1131. if (!BN_copy(prod_Z[0], points[0]->Z))
  1132. goto err;
  1133. } else {
  1134. if (group->meth->field_set_to_one != 0) {
  1135. if (!group->meth->field_set_to_one(group, prod_Z[0], ctx))
  1136. goto err;
  1137. } else {
  1138. if (!BN_one(prod_Z[0]))
  1139. goto err;
  1140. }
  1141. }
  1142. for (i = 1; i < num; i++) {
  1143. if (!BN_is_zero(points[i]->Z)) {
  1144. if (!group->
  1145. meth->field_mul(group, prod_Z[i], prod_Z[i - 1], points[i]->Z,
  1146. ctx))
  1147. goto err;
  1148. } else {
  1149. if (!BN_copy(prod_Z[i], prod_Z[i - 1]))
  1150. goto err;
  1151. }
  1152. }
  1153. /*
  1154. * Now use a single explicit inversion to replace every non-zero
  1155. * points[i]->Z by its inverse.
  1156. */
  1157. if (!BN_mod_inverse(tmp, prod_Z[num - 1], group->field, ctx)) {
  1158. ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
  1159. goto err;
  1160. }
  1161. if (group->meth->field_encode != 0) {
  1162. /*
  1163. * In the Montgomery case, we just turned R*H (representing H) into
  1164. * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to
  1165. * multiply by the Montgomery factor twice.
  1166. */
  1167. if (!group->meth->field_encode(group, tmp, tmp, ctx))
  1168. goto err;
  1169. if (!group->meth->field_encode(group, tmp, tmp, ctx))
  1170. goto err;
  1171. }
  1172. for (i = num - 1; i > 0; --i) {
  1173. /*
  1174. * Loop invariant: tmp is the product of the inverses of points[0]->Z
  1175. * .. points[i]->Z (zero-valued inputs skipped).
  1176. */
  1177. if (!BN_is_zero(points[i]->Z)) {
  1178. /*
  1179. * Set tmp_Z to the inverse of points[i]->Z (as product of Z
  1180. * inverses 0 .. i, Z values 0 .. i - 1).
  1181. */
  1182. if (!group->
  1183. meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
  1184. goto err;
  1185. /*
  1186. * Update tmp to satisfy the loop invariant for i - 1.
  1187. */
  1188. if (!group->meth->field_mul(group, tmp, tmp, points[i]->Z, ctx))
  1189. goto err;
  1190. /* Replace points[i]->Z by its inverse. */
  1191. if (!BN_copy(points[i]->Z, tmp_Z))
  1192. goto err;
  1193. }
  1194. }
  1195. if (!BN_is_zero(points[0]->Z)) {
  1196. /* Replace points[0]->Z by its inverse. */
  1197. if (!BN_copy(points[0]->Z, tmp))
  1198. goto err;
  1199. }
  1200. /* Finally, fix up the X and Y coordinates for all points. */
  1201. for (i = 0; i < num; i++) {
  1202. EC_POINT *p = points[i];
  1203. if (!BN_is_zero(p->Z)) {
  1204. /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
  1205. if (!group->meth->field_sqr(group, tmp, p->Z, ctx))
  1206. goto err;
  1207. if (!group->meth->field_mul(group, p->X, p->X, tmp, ctx))
  1208. goto err;
  1209. if (!group->meth->field_mul(group, tmp, tmp, p->Z, ctx))
  1210. goto err;
  1211. if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx))
  1212. goto err;
  1213. if (group->meth->field_set_to_one != 0) {
  1214. if (!group->meth->field_set_to_one(group, p->Z, ctx))
  1215. goto err;
  1216. } else {
  1217. if (!BN_one(p->Z))
  1218. goto err;
  1219. }
  1220. p->Z_is_one = 1;
  1221. }
  1222. }
  1223. ret = 1;
  1224. err:
  1225. BN_CTX_end(ctx);
  1226. BN_CTX_free(new_ctx);
  1227. if (prod_Z != NULL) {
  1228. for (i = 0; i < num; i++) {
  1229. if (prod_Z[i] == NULL)
  1230. break;
  1231. BN_clear_free(prod_Z[i]);
  1232. }
  1233. OPENSSL_free(prod_Z);
  1234. }
  1235. return ret;
  1236. }
  1237. int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
  1238. const BIGNUM *b, BN_CTX *ctx)
  1239. {
  1240. return BN_mod_mul(r, a, b, group->field, ctx);
  1241. }
  1242. int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
  1243. BN_CTX *ctx)
  1244. {
  1245. return BN_mod_sqr(r, a, group->field, ctx);
  1246. }