ec2_smpl.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. /*
  2. * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  4. *
  5. * Licensed under the Apache License 2.0 (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. /*
  11. * ECDSA low level APIs are deprecated for public use, but still ok for
  12. * internal use.
  13. */
  14. #include "internal/deprecated.h"
  15. #include <openssl/err.h>
  16. #include "crypto/bn.h"
  17. #include "ec_local.h"
  18. #ifndef OPENSSL_NO_EC2M
  19. /*
  20. * Initialize a GF(2^m)-based EC_GROUP structure. Note that all other members
  21. * are handled by EC_GROUP_new.
  22. */
  23. int ec_GF2m_simple_group_init(EC_GROUP *group)
  24. {
  25. group->field = BN_new();
  26. group->a = BN_new();
  27. group->b = BN_new();
  28. if (group->field == NULL || group->a == NULL || group->b == NULL) {
  29. BN_free(group->field);
  30. BN_free(group->a);
  31. BN_free(group->b);
  32. return 0;
  33. }
  34. return 1;
  35. }
  36. /*
  37. * Free a GF(2^m)-based EC_GROUP structure. Note that all other members are
  38. * handled by EC_GROUP_free.
  39. */
  40. void ec_GF2m_simple_group_finish(EC_GROUP *group)
  41. {
  42. BN_free(group->field);
  43. BN_free(group->a);
  44. BN_free(group->b);
  45. }
  46. /*
  47. * Clear and free a GF(2^m)-based EC_GROUP structure. Note that all other
  48. * members are handled by EC_GROUP_clear_free.
  49. */
  50. void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
  51. {
  52. BN_clear_free(group->field);
  53. BN_clear_free(group->a);
  54. BN_clear_free(group->b);
  55. group->poly[0] = 0;
  56. group->poly[1] = 0;
  57. group->poly[2] = 0;
  58. group->poly[3] = 0;
  59. group->poly[4] = 0;
  60. group->poly[5] = -1;
  61. }
  62. /*
  63. * Copy a GF(2^m)-based EC_GROUP structure. Note that all other members are
  64. * handled by EC_GROUP_copy.
  65. */
  66. int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
  67. {
  68. if (!BN_copy(dest->field, src->field))
  69. return 0;
  70. if (!BN_copy(dest->a, src->a))
  71. return 0;
  72. if (!BN_copy(dest->b, src->b))
  73. return 0;
  74. dest->poly[0] = src->poly[0];
  75. dest->poly[1] = src->poly[1];
  76. dest->poly[2] = src->poly[2];
  77. dest->poly[3] = src->poly[3];
  78. dest->poly[4] = src->poly[4];
  79. dest->poly[5] = src->poly[5];
  80. if (bn_wexpand(dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) ==
  81. NULL)
  82. return 0;
  83. if (bn_wexpand(dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) ==
  84. NULL)
  85. return 0;
  86. bn_set_all_zero(dest->a);
  87. bn_set_all_zero(dest->b);
  88. return 1;
  89. }
  90. /* Set the curve parameters of an EC_GROUP structure. */
  91. int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
  92. const BIGNUM *p, const BIGNUM *a,
  93. const BIGNUM *b, BN_CTX *ctx)
  94. {
  95. int ret = 0, i;
  96. /* group->field */
  97. if (!BN_copy(group->field, p))
  98. goto err;
  99. i = BN_GF2m_poly2arr(group->field, group->poly, 6) - 1;
  100. if ((i != 5) && (i != 3)) {
  101. ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
  102. goto err;
  103. }
  104. /* group->a */
  105. if (!BN_GF2m_mod_arr(group->a, a, group->poly))
  106. goto err;
  107. if (bn_wexpand(group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
  108. == NULL)
  109. goto err;
  110. bn_set_all_zero(group->a);
  111. /* group->b */
  112. if (!BN_GF2m_mod_arr(group->b, b, group->poly))
  113. goto err;
  114. if (bn_wexpand(group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
  115. == NULL)
  116. goto err;
  117. bn_set_all_zero(group->b);
  118. ret = 1;
  119. err:
  120. return ret;
  121. }
  122. /*
  123. * Get the curve parameters of an EC_GROUP structure. If p, a, or b are NULL
  124. * then there values will not be set but the method will return with success.
  125. */
  126. int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
  127. BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
  128. {
  129. int ret = 0;
  130. if (p != NULL) {
  131. if (!BN_copy(p, group->field))
  132. return 0;
  133. }
  134. if (a != NULL) {
  135. if (!BN_copy(a, group->a))
  136. goto err;
  137. }
  138. if (b != NULL) {
  139. if (!BN_copy(b, group->b))
  140. goto err;
  141. }
  142. ret = 1;
  143. err:
  144. return ret;
  145. }
  146. /*
  147. * Gets the degree of the field. For a curve over GF(2^m) this is the value
  148. * m.
  149. */
  150. int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
  151. {
  152. return BN_num_bits(group->field) - 1;
  153. }
  154. /*
  155. * Checks the discriminant of the curve. y^2 + x*y = x^3 + a*x^2 + b is an
  156. * elliptic curve <=> b != 0 (mod p)
  157. */
  158. int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
  159. BN_CTX *ctx)
  160. {
  161. int ret = 0;
  162. BIGNUM *b;
  163. #ifndef FIPS_MODE
  164. BN_CTX *new_ctx = NULL;
  165. if (ctx == NULL) {
  166. ctx = new_ctx = BN_CTX_new();
  167. if (ctx == NULL) {
  168. ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT,
  169. ERR_R_MALLOC_FAILURE);
  170. goto err;
  171. }
  172. }
  173. #endif
  174. BN_CTX_start(ctx);
  175. b = BN_CTX_get(ctx);
  176. if (b == NULL)
  177. goto err;
  178. if (!BN_GF2m_mod_arr(b, group->b, group->poly))
  179. goto err;
  180. /*
  181. * check the discriminant: y^2 + x*y = x^3 + a*x^2 + b is an elliptic
  182. * curve <=> b != 0 (mod p)
  183. */
  184. if (BN_is_zero(b))
  185. goto err;
  186. ret = 1;
  187. err:
  188. BN_CTX_end(ctx);
  189. #ifndef FIPS_MODE
  190. BN_CTX_free(new_ctx);
  191. #endif
  192. return ret;
  193. }
  194. /* Initializes an EC_POINT. */
  195. int ec_GF2m_simple_point_init(EC_POINT *point)
  196. {
  197. point->X = BN_new();
  198. point->Y = BN_new();
  199. point->Z = BN_new();
  200. if (point->X == NULL || point->Y == NULL || point->Z == NULL) {
  201. BN_free(point->X);
  202. BN_free(point->Y);
  203. BN_free(point->Z);
  204. return 0;
  205. }
  206. return 1;
  207. }
  208. /* Frees an EC_POINT. */
  209. void ec_GF2m_simple_point_finish(EC_POINT *point)
  210. {
  211. BN_free(point->X);
  212. BN_free(point->Y);
  213. BN_free(point->Z);
  214. }
  215. /* Clears and frees an EC_POINT. */
  216. void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
  217. {
  218. BN_clear_free(point->X);
  219. BN_clear_free(point->Y);
  220. BN_clear_free(point->Z);
  221. point->Z_is_one = 0;
  222. }
  223. /*
  224. * Copy the contents of one EC_POINT into another. Assumes dest is
  225. * initialized.
  226. */
  227. int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
  228. {
  229. if (!BN_copy(dest->X, src->X))
  230. return 0;
  231. if (!BN_copy(dest->Y, src->Y))
  232. return 0;
  233. if (!BN_copy(dest->Z, src->Z))
  234. return 0;
  235. dest->Z_is_one = src->Z_is_one;
  236. dest->curve_name = src->curve_name;
  237. return 1;
  238. }
  239. /*
  240. * Set an EC_POINT to the point at infinity. A point at infinity is
  241. * represented by having Z=0.
  242. */
  243. int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group,
  244. EC_POINT *point)
  245. {
  246. point->Z_is_one = 0;
  247. BN_zero(point->Z);
  248. return 1;
  249. }
  250. /*
  251. * Set the coordinates of an EC_POINT using affine coordinates. Note that
  252. * the simple implementation only uses affine coordinates.
  253. */
  254. int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group,
  255. EC_POINT *point,
  256. const BIGNUM *x,
  257. const BIGNUM *y, BN_CTX *ctx)
  258. {
  259. int ret = 0;
  260. if (x == NULL || y == NULL) {
  261. ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES,
  262. ERR_R_PASSED_NULL_PARAMETER);
  263. return 0;
  264. }
  265. if (!BN_copy(point->X, x))
  266. goto err;
  267. BN_set_negative(point->X, 0);
  268. if (!BN_copy(point->Y, y))
  269. goto err;
  270. BN_set_negative(point->Y, 0);
  271. if (!BN_copy(point->Z, BN_value_one()))
  272. goto err;
  273. BN_set_negative(point->Z, 0);
  274. point->Z_is_one = 1;
  275. ret = 1;
  276. err:
  277. return ret;
  278. }
  279. /*
  280. * Gets the affine coordinates of an EC_POINT. Note that the simple
  281. * implementation only uses affine coordinates.
  282. */
  283. int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group,
  284. const EC_POINT *point,
  285. BIGNUM *x, BIGNUM *y,
  286. BN_CTX *ctx)
  287. {
  288. int ret = 0;
  289. if (EC_POINT_is_at_infinity(group, point)) {
  290. ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES,
  291. EC_R_POINT_AT_INFINITY);
  292. return 0;
  293. }
  294. if (BN_cmp(point->Z, BN_value_one())) {
  295. ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES,
  296. ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  297. return 0;
  298. }
  299. if (x != NULL) {
  300. if (!BN_copy(x, point->X))
  301. goto err;
  302. BN_set_negative(x, 0);
  303. }
  304. if (y != NULL) {
  305. if (!BN_copy(y, point->Y))
  306. goto err;
  307. BN_set_negative(y, 0);
  308. }
  309. ret = 1;
  310. err:
  311. return ret;
  312. }
  313. /*
  314. * Computes a + b and stores the result in r. r could be a or b, a could be
  315. * b. Uses algorithm A.10.2 of IEEE P1363.
  316. */
  317. int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  318. const EC_POINT *b, BN_CTX *ctx)
  319. {
  320. BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
  321. int ret = 0;
  322. #ifndef FIPS_MODE
  323. BN_CTX *new_ctx = NULL;
  324. #endif
  325. if (EC_POINT_is_at_infinity(group, a)) {
  326. if (!EC_POINT_copy(r, b))
  327. return 0;
  328. return 1;
  329. }
  330. if (EC_POINT_is_at_infinity(group, b)) {
  331. if (!EC_POINT_copy(r, a))
  332. return 0;
  333. return 1;
  334. }
  335. #ifndef FIPS_MODE
  336. if (ctx == NULL) {
  337. ctx = new_ctx = BN_CTX_new();
  338. if (ctx == NULL)
  339. return 0;
  340. }
  341. #endif
  342. BN_CTX_start(ctx);
  343. x0 = BN_CTX_get(ctx);
  344. y0 = BN_CTX_get(ctx);
  345. x1 = BN_CTX_get(ctx);
  346. y1 = BN_CTX_get(ctx);
  347. x2 = BN_CTX_get(ctx);
  348. y2 = BN_CTX_get(ctx);
  349. s = BN_CTX_get(ctx);
  350. t = BN_CTX_get(ctx);
  351. if (t == NULL)
  352. goto err;
  353. if (a->Z_is_one) {
  354. if (!BN_copy(x0, a->X))
  355. goto err;
  356. if (!BN_copy(y0, a->Y))
  357. goto err;
  358. } else {
  359. if (!EC_POINT_get_affine_coordinates(group, a, x0, y0, ctx))
  360. goto err;
  361. }
  362. if (b->Z_is_one) {
  363. if (!BN_copy(x1, b->X))
  364. goto err;
  365. if (!BN_copy(y1, b->Y))
  366. goto err;
  367. } else {
  368. if (!EC_POINT_get_affine_coordinates(group, b, x1, y1, ctx))
  369. goto err;
  370. }
  371. if (BN_GF2m_cmp(x0, x1)) {
  372. if (!BN_GF2m_add(t, x0, x1))
  373. goto err;
  374. if (!BN_GF2m_add(s, y0, y1))
  375. goto err;
  376. if (!group->meth->field_div(group, s, s, t, ctx))
  377. goto err;
  378. if (!group->meth->field_sqr(group, x2, s, ctx))
  379. goto err;
  380. if (!BN_GF2m_add(x2, x2, group->a))
  381. goto err;
  382. if (!BN_GF2m_add(x2, x2, s))
  383. goto err;
  384. if (!BN_GF2m_add(x2, x2, t))
  385. goto err;
  386. } else {
  387. if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) {
  388. if (!EC_POINT_set_to_infinity(group, r))
  389. goto err;
  390. ret = 1;
  391. goto err;
  392. }
  393. if (!group->meth->field_div(group, s, y1, x1, ctx))
  394. goto err;
  395. if (!BN_GF2m_add(s, s, x1))
  396. goto err;
  397. if (!group->meth->field_sqr(group, x2, s, ctx))
  398. goto err;
  399. if (!BN_GF2m_add(x2, x2, s))
  400. goto err;
  401. if (!BN_GF2m_add(x2, x2, group->a))
  402. goto err;
  403. }
  404. if (!BN_GF2m_add(y2, x1, x2))
  405. goto err;
  406. if (!group->meth->field_mul(group, y2, y2, s, ctx))
  407. goto err;
  408. if (!BN_GF2m_add(y2, y2, x2))
  409. goto err;
  410. if (!BN_GF2m_add(y2, y2, y1))
  411. goto err;
  412. if (!EC_POINT_set_affine_coordinates(group, r, x2, y2, ctx))
  413. goto err;
  414. ret = 1;
  415. err:
  416. BN_CTX_end(ctx);
  417. #ifndef FIPS_MODE
  418. BN_CTX_free(new_ctx);
  419. #endif
  420. return ret;
  421. }
  422. /*
  423. * Computes 2 * a and stores the result in r. r could be a. Uses algorithm
  424. * A.10.2 of IEEE P1363.
  425. */
  426. int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  427. BN_CTX *ctx)
  428. {
  429. return ec_GF2m_simple_add(group, r, a, a, ctx);
  430. }
  431. int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
  432. {
  433. if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
  434. /* point is its own inverse */
  435. return 1;
  436. if (!EC_POINT_make_affine(group, point, ctx))
  437. return 0;
  438. return BN_GF2m_add(point->Y, point->X, point->Y);
  439. }
  440. /* Indicates whether the given point is the point at infinity. */
  441. int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group,
  442. const EC_POINT *point)
  443. {
  444. return BN_is_zero(point->Z);
  445. }
  446. /*-
  447. * Determines whether the given EC_POINT is an actual point on the curve defined
  448. * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
  449. * y^2 + x*y = x^3 + a*x^2 + b.
  450. */
  451. int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
  452. BN_CTX *ctx)
  453. {
  454. int ret = -1;
  455. BIGNUM *lh, *y2;
  456. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  457. const BIGNUM *, BN_CTX *);
  458. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  459. #ifndef FIPS_MODE
  460. BN_CTX *new_ctx = NULL;
  461. #endif
  462. if (EC_POINT_is_at_infinity(group, point))
  463. return 1;
  464. field_mul = group->meth->field_mul;
  465. field_sqr = group->meth->field_sqr;
  466. /* only support affine coordinates */
  467. if (!point->Z_is_one)
  468. return -1;
  469. #ifndef FIPS_MODE
  470. if (ctx == NULL) {
  471. ctx = new_ctx = BN_CTX_new();
  472. if (ctx == NULL)
  473. return -1;
  474. }
  475. #endif
  476. BN_CTX_start(ctx);
  477. y2 = BN_CTX_get(ctx);
  478. lh = BN_CTX_get(ctx);
  479. if (lh == NULL)
  480. goto err;
  481. /*-
  482. * We have a curve defined by a Weierstrass equation
  483. * y^2 + x*y = x^3 + a*x^2 + b.
  484. * <=> x^3 + a*x^2 + x*y + b + y^2 = 0
  485. * <=> ((x + a) * x + y ) * x + b + y^2 = 0
  486. */
  487. if (!BN_GF2m_add(lh, point->X, group->a))
  488. goto err;
  489. if (!field_mul(group, lh, lh, point->X, ctx))
  490. goto err;
  491. if (!BN_GF2m_add(lh, lh, point->Y))
  492. goto err;
  493. if (!field_mul(group, lh, lh, point->X, ctx))
  494. goto err;
  495. if (!BN_GF2m_add(lh, lh, group->b))
  496. goto err;
  497. if (!field_sqr(group, y2, point->Y, ctx))
  498. goto err;
  499. if (!BN_GF2m_add(lh, lh, y2))
  500. goto err;
  501. ret = BN_is_zero(lh);
  502. err:
  503. BN_CTX_end(ctx);
  504. #ifndef FIPS_MODE
  505. BN_CTX_free(new_ctx);
  506. #endif
  507. return ret;
  508. }
  509. /*-
  510. * Indicates whether two points are equal.
  511. * Return values:
  512. * -1 error
  513. * 0 equal (in affine coordinates)
  514. * 1 not equal
  515. */
  516. int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
  517. const EC_POINT *b, BN_CTX *ctx)
  518. {
  519. BIGNUM *aX, *aY, *bX, *bY;
  520. int ret = -1;
  521. #ifndef FIPS_MODE
  522. BN_CTX *new_ctx = NULL;
  523. #endif
  524. if (EC_POINT_is_at_infinity(group, a)) {
  525. return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
  526. }
  527. if (EC_POINT_is_at_infinity(group, b))
  528. return 1;
  529. if (a->Z_is_one && b->Z_is_one) {
  530. return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
  531. }
  532. #ifndef FIPS_MODE
  533. if (ctx == NULL) {
  534. ctx = new_ctx = BN_CTX_new();
  535. if (ctx == NULL)
  536. return -1;
  537. }
  538. #endif
  539. BN_CTX_start(ctx);
  540. aX = BN_CTX_get(ctx);
  541. aY = BN_CTX_get(ctx);
  542. bX = BN_CTX_get(ctx);
  543. bY = BN_CTX_get(ctx);
  544. if (bY == NULL)
  545. goto err;
  546. if (!EC_POINT_get_affine_coordinates(group, a, aX, aY, ctx))
  547. goto err;
  548. if (!EC_POINT_get_affine_coordinates(group, b, bX, bY, ctx))
  549. goto err;
  550. ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
  551. err:
  552. BN_CTX_end(ctx);
  553. #ifndef FIPS_MODE
  554. BN_CTX_free(new_ctx);
  555. #endif
  556. return ret;
  557. }
  558. /* Forces the given EC_POINT to internally use affine coordinates. */
  559. int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
  560. BN_CTX *ctx)
  561. {
  562. BIGNUM *x, *y;
  563. int ret = 0;
  564. #ifndef FIPS_MODE
  565. BN_CTX *new_ctx = NULL;
  566. #endif
  567. if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
  568. return 1;
  569. #ifndef FIPS_MODE
  570. if (ctx == NULL) {
  571. ctx = new_ctx = BN_CTX_new();
  572. if (ctx == NULL)
  573. return 0;
  574. }
  575. #endif
  576. BN_CTX_start(ctx);
  577. x = BN_CTX_get(ctx);
  578. y = BN_CTX_get(ctx);
  579. if (y == NULL)
  580. goto err;
  581. if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
  582. goto err;
  583. if (!BN_copy(point->X, x))
  584. goto err;
  585. if (!BN_copy(point->Y, y))
  586. goto err;
  587. if (!BN_one(point->Z))
  588. goto err;
  589. point->Z_is_one = 1;
  590. ret = 1;
  591. err:
  592. BN_CTX_end(ctx);
  593. #ifndef FIPS_MODE
  594. BN_CTX_free(new_ctx);
  595. #endif
  596. return ret;
  597. }
  598. /*
  599. * Forces each of the EC_POINTs in the given array to use affine coordinates.
  600. */
  601. int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num,
  602. EC_POINT *points[], BN_CTX *ctx)
  603. {
  604. size_t i;
  605. for (i = 0; i < num; i++) {
  606. if (!group->meth->make_affine(group, points[i], ctx))
  607. return 0;
  608. }
  609. return 1;
  610. }
  611. /* Wrapper to simple binary polynomial field multiplication implementation. */
  612. int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r,
  613. const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
  614. {
  615. return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
  616. }
  617. /* Wrapper to simple binary polynomial field squaring implementation. */
  618. int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r,
  619. const BIGNUM *a, BN_CTX *ctx)
  620. {
  621. return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
  622. }
  623. /* Wrapper to simple binary polynomial field division implementation. */
  624. int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r,
  625. const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
  626. {
  627. return BN_GF2m_mod_div(r, a, b, group->field, ctx);
  628. }
  629. /*-
  630. * Lopez-Dahab ladder, pre step.
  631. * See e.g. "Guide to ECC" Alg 3.40.
  632. * Modified to blind s and r independently.
  633. * s:= p, r := 2p
  634. */
  635. static
  636. int ec_GF2m_simple_ladder_pre(const EC_GROUP *group,
  637. EC_POINT *r, EC_POINT *s,
  638. EC_POINT *p, BN_CTX *ctx)
  639. {
  640. /* if p is not affine, something is wrong */
  641. if (p->Z_is_one == 0)
  642. return 0;
  643. /* s blinding: make sure lambda (s->Z here) is not zero */
  644. do {
  645. if (!BN_priv_rand_ex(s->Z, BN_num_bits(group->field) - 1,
  646. BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx)) {
  647. ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB);
  648. return 0;
  649. }
  650. } while (BN_is_zero(s->Z));
  651. /* if field_encode defined convert between representations */
  652. if ((group->meth->field_encode != NULL
  653. && !group->meth->field_encode(group, s->Z, s->Z, ctx))
  654. || !group->meth->field_mul(group, s->X, p->X, s->Z, ctx))
  655. return 0;
  656. /* r blinding: make sure lambda (r->Y here for storage) is not zero */
  657. do {
  658. if (!BN_priv_rand_ex(r->Y, BN_num_bits(group->field) - 1,
  659. BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx)) {
  660. ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB);
  661. return 0;
  662. }
  663. } while (BN_is_zero(r->Y));
  664. if ((group->meth->field_encode != NULL
  665. && !group->meth->field_encode(group, r->Y, r->Y, ctx))
  666. || !group->meth->field_sqr(group, r->Z, p->X, ctx)
  667. || !group->meth->field_sqr(group, r->X, r->Z, ctx)
  668. || !BN_GF2m_add(r->X, r->X, group->b)
  669. || !group->meth->field_mul(group, r->Z, r->Z, r->Y, ctx)
  670. || !group->meth->field_mul(group, r->X, r->X, r->Y, ctx))
  671. return 0;
  672. s->Z_is_one = 0;
  673. r->Z_is_one = 0;
  674. return 1;
  675. }
  676. /*-
  677. * Ladder step: differential addition-and-doubling, mixed Lopez-Dahab coords.
  678. * http://www.hyperelliptic.org/EFD/g12o/auto-code/shortw/xz/ladder/mladd-2003-s.op3
  679. * s := r + s, r := 2r
  680. */
  681. static
  682. int ec_GF2m_simple_ladder_step(const EC_GROUP *group,
  683. EC_POINT *r, EC_POINT *s,
  684. EC_POINT *p, BN_CTX *ctx)
  685. {
  686. if (!group->meth->field_mul(group, r->Y, r->Z, s->X, ctx)
  687. || !group->meth->field_mul(group, s->X, r->X, s->Z, ctx)
  688. || !group->meth->field_sqr(group, s->Y, r->Z, ctx)
  689. || !group->meth->field_sqr(group, r->Z, r->X, ctx)
  690. || !BN_GF2m_add(s->Z, r->Y, s->X)
  691. || !group->meth->field_sqr(group, s->Z, s->Z, ctx)
  692. || !group->meth->field_mul(group, s->X, r->Y, s->X, ctx)
  693. || !group->meth->field_mul(group, r->Y, s->Z, p->X, ctx)
  694. || !BN_GF2m_add(s->X, s->X, r->Y)
  695. || !group->meth->field_sqr(group, r->Y, r->Z, ctx)
  696. || !group->meth->field_mul(group, r->Z, r->Z, s->Y, ctx)
  697. || !group->meth->field_sqr(group, s->Y, s->Y, ctx)
  698. || !group->meth->field_mul(group, s->Y, s->Y, group->b, ctx)
  699. || !BN_GF2m_add(r->X, r->Y, s->Y))
  700. return 0;
  701. return 1;
  702. }
  703. /*-
  704. * Recover affine (x,y) result from Lopez-Dahab r and s, affine p.
  705. * See e.g. "Fast Multiplication on Elliptic Curves over GF(2**m)
  706. * without Precomputation" (Lopez and Dahab, CHES 1999),
  707. * Appendix Alg Mxy.
  708. */
  709. static
  710. int ec_GF2m_simple_ladder_post(const EC_GROUP *group,
  711. EC_POINT *r, EC_POINT *s,
  712. EC_POINT *p, BN_CTX *ctx)
  713. {
  714. int ret = 0;
  715. BIGNUM *t0, *t1, *t2 = NULL;
  716. if (BN_is_zero(r->Z))
  717. return EC_POINT_set_to_infinity(group, r);
  718. if (BN_is_zero(s->Z)) {
  719. if (!EC_POINT_copy(r, p)
  720. || !EC_POINT_invert(group, r, ctx)) {
  721. ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_EC_LIB);
  722. return 0;
  723. }
  724. return 1;
  725. }
  726. BN_CTX_start(ctx);
  727. t0 = BN_CTX_get(ctx);
  728. t1 = BN_CTX_get(ctx);
  729. t2 = BN_CTX_get(ctx);
  730. if (t2 == NULL) {
  731. ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_MALLOC_FAILURE);
  732. goto err;
  733. }
  734. if (!group->meth->field_mul(group, t0, r->Z, s->Z, ctx)
  735. || !group->meth->field_mul(group, t1, p->X, r->Z, ctx)
  736. || !BN_GF2m_add(t1, r->X, t1)
  737. || !group->meth->field_mul(group, t2, p->X, s->Z, ctx)
  738. || !group->meth->field_mul(group, r->Z, r->X, t2, ctx)
  739. || !BN_GF2m_add(t2, t2, s->X)
  740. || !group->meth->field_mul(group, t1, t1, t2, ctx)
  741. || !group->meth->field_sqr(group, t2, p->X, ctx)
  742. || !BN_GF2m_add(t2, p->Y, t2)
  743. || !group->meth->field_mul(group, t2, t2, t0, ctx)
  744. || !BN_GF2m_add(t1, t2, t1)
  745. || !group->meth->field_mul(group, t2, p->X, t0, ctx)
  746. || !group->meth->field_inv(group, t2, t2, ctx)
  747. || !group->meth->field_mul(group, t1, t1, t2, ctx)
  748. || !group->meth->field_mul(group, r->X, r->Z, t2, ctx)
  749. || !BN_GF2m_add(t2, p->X, r->X)
  750. || !group->meth->field_mul(group, t2, t2, t1, ctx)
  751. || !BN_GF2m_add(r->Y, p->Y, t2)
  752. || !BN_one(r->Z))
  753. goto err;
  754. r->Z_is_one = 1;
  755. /* GF(2^m) field elements should always have BIGNUM::neg = 0 */
  756. BN_set_negative(r->X, 0);
  757. BN_set_negative(r->Y, 0);
  758. ret = 1;
  759. err:
  760. BN_CTX_end(ctx);
  761. return ret;
  762. }
  763. static
  764. int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r,
  765. const BIGNUM *scalar, size_t num,
  766. const EC_POINT *points[],
  767. const BIGNUM *scalars[],
  768. BN_CTX *ctx)
  769. {
  770. int ret = 0;
  771. EC_POINT *t = NULL;
  772. /*-
  773. * We limit use of the ladder only to the following cases:
  774. * - r := scalar * G
  775. * Fixed point mul: scalar != NULL && num == 0;
  776. * - r := scalars[0] * points[0]
  777. * Variable point mul: scalar == NULL && num == 1;
  778. * - r := scalar * G + scalars[0] * points[0]
  779. * used, e.g., in ECDSA verification: scalar != NULL && num == 1
  780. *
  781. * In any other case (num > 1) we use the default wNAF implementation.
  782. *
  783. * We also let the default implementation handle degenerate cases like group
  784. * order or cofactor set to 0.
  785. */
  786. if (num > 1 || BN_is_zero(group->order) || BN_is_zero(group->cofactor))
  787. return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
  788. if (scalar != NULL && num == 0)
  789. /* Fixed point multiplication */
  790. return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
  791. if (scalar == NULL && num == 1)
  792. /* Variable point multiplication */
  793. return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);
  794. /*-
  795. * Double point multiplication:
  796. * r := scalar * G + scalars[0] * points[0]
  797. */
  798. if ((t = EC_POINT_new(group)) == NULL) {
  799. ECerr(EC_F_EC_GF2M_SIMPLE_POINTS_MUL, ERR_R_MALLOC_FAILURE);
  800. return 0;
  801. }
  802. if (!ec_scalar_mul_ladder(group, t, scalar, NULL, ctx)
  803. || !ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx)
  804. || !EC_POINT_add(group, r, t, r, ctx))
  805. goto err;
  806. ret = 1;
  807. err:
  808. EC_POINT_free(t);
  809. return ret;
  810. }
  811. /*-
  812. * Computes the multiplicative inverse of a in GF(2^m), storing the result in r.
  813. * If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
  814. * SCA hardening is with blinding: BN_GF2m_mod_inv does that.
  815. */
  816. static int ec_GF2m_simple_field_inv(const EC_GROUP *group, BIGNUM *r,
  817. const BIGNUM *a, BN_CTX *ctx)
  818. {
  819. int ret;
  820. if (!(ret = BN_GF2m_mod_inv(r, a, group->field, ctx)))
  821. ECerr(EC_F_EC_GF2M_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT);
  822. return ret;
  823. }
  824. const EC_METHOD *EC_GF2m_simple_method(void)
  825. {
  826. static const EC_METHOD ret = {
  827. EC_FLAGS_DEFAULT_OCT,
  828. NID_X9_62_characteristic_two_field,
  829. ec_GF2m_simple_group_init,
  830. ec_GF2m_simple_group_finish,
  831. ec_GF2m_simple_group_clear_finish,
  832. ec_GF2m_simple_group_copy,
  833. ec_GF2m_simple_group_set_curve,
  834. ec_GF2m_simple_group_get_curve,
  835. ec_GF2m_simple_group_get_degree,
  836. ec_group_simple_order_bits,
  837. ec_GF2m_simple_group_check_discriminant,
  838. ec_GF2m_simple_point_init,
  839. ec_GF2m_simple_point_finish,
  840. ec_GF2m_simple_point_clear_finish,
  841. ec_GF2m_simple_point_copy,
  842. ec_GF2m_simple_point_set_to_infinity,
  843. 0, /* set_Jprojective_coordinates_GFp */
  844. 0, /* get_Jprojective_coordinates_GFp */
  845. ec_GF2m_simple_point_set_affine_coordinates,
  846. ec_GF2m_simple_point_get_affine_coordinates,
  847. 0, /* point_set_compressed_coordinates */
  848. 0, /* point2oct */
  849. 0, /* oct2point */
  850. ec_GF2m_simple_add,
  851. ec_GF2m_simple_dbl,
  852. ec_GF2m_simple_invert,
  853. ec_GF2m_simple_is_at_infinity,
  854. ec_GF2m_simple_is_on_curve,
  855. ec_GF2m_simple_cmp,
  856. ec_GF2m_simple_make_affine,
  857. ec_GF2m_simple_points_make_affine,
  858. ec_GF2m_simple_points_mul,
  859. 0, /* precompute_mult */
  860. 0, /* have_precompute_mult */
  861. ec_GF2m_simple_field_mul,
  862. ec_GF2m_simple_field_sqr,
  863. ec_GF2m_simple_field_div,
  864. ec_GF2m_simple_field_inv,
  865. 0, /* field_encode */
  866. 0, /* field_decode */
  867. 0, /* field_set_to_one */
  868. ec_key_simple_priv2oct,
  869. ec_key_simple_oct2priv,
  870. 0, /* set private */
  871. ec_key_simple_generate_key,
  872. ec_key_simple_check_key,
  873. ec_key_simple_generate_public_key,
  874. 0, /* keycopy */
  875. 0, /* keyfinish */
  876. ecdh_simple_compute_key,
  877. ecdsa_simple_sign_setup,
  878. ecdsa_simple_sign_sig,
  879. ecdsa_simple_verify_sig,
  880. 0, /* field_inverse_mod_ord */
  881. 0, /* blind_coordinates */
  882. ec_GF2m_simple_ladder_pre,
  883. ec_GF2m_simple_ladder_step,
  884. ec_GF2m_simple_ladder_post
  885. };
  886. return &ret;
  887. }
  888. #endif