ecp_smpl.c 39 KB

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