simple.c 31 KB

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