選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

1119 行
28 KiB

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