Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

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