ecp_smpl.c 39 KB

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