1/* crypto/ec/ec_lib.c */ 2/* ==================================================================== 3 * Copyright (c) 1998-2001 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#include <string.h> 57 58#include <openssl/err.h> 59#include <openssl/opensslv.h> 60 61#include "ec_lcl.h" 62 63static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT; 64 65 66/* functions for EC_GROUP objects */ 67 68EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) 69 { 70 EC_GROUP *ret; 71 72 if (meth == NULL) 73 { 74 ECerr(EC_F_EC_GROUP_NEW, ERR_R_PASSED_NULL_PARAMETER); 75 return NULL; 76 } 77 if (meth->group_init == 0) 78 { 79 ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 80 return NULL; 81 } 82 83 ret = OPENSSL_malloc(sizeof *ret); 84 if (ret == NULL) 85 { 86 ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); 87 return NULL; 88 } 89 90 ret->meth = meth; 91 92 ret->extra_data = NULL; 93 ret->extra_data_dup_func = 0; 94 ret->extra_data_free_func = 0; 95 ret->extra_data_clear_free_func = 0; 96 97 if (!meth->group_init(ret)) 98 { 99 OPENSSL_free(ret); 100 return NULL; 101 } 102 103 return ret; 104 } 105 106 107void EC_GROUP_free(EC_GROUP *group) 108 { 109 if (!group) return; 110 111 if (group->meth->group_finish != 0) 112 group->meth->group_finish(group); 113 114 EC_GROUP_free_extra_data(group); 115 116 OPENSSL_free(group); 117 } 118 119 120void EC_GROUP_clear_free(EC_GROUP *group) 121 { 122 if (!group) return; 123 124 if (group->meth->group_clear_finish != 0) 125 group->meth->group_clear_finish(group); 126 else if (group->meth != NULL && group->meth->group_finish != 0) 127 group->meth->group_finish(group); 128 129 EC_GROUP_clear_free_extra_data(group); 130 131 OPENSSL_cleanse(group, sizeof *group); 132 OPENSSL_free(group); 133 } 134 135 136int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) 137 { 138 if (dest->meth->group_copy == 0) 139 { 140 ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 141 return 0; 142 } 143 if (dest->meth != src->meth) 144 { 145 ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); 146 return 0; 147 } 148 if (dest == src) 149 return 1; 150 151 EC_GROUP_clear_free_extra_data(dest); 152 if (src->extra_data_dup_func) 153 { 154 if (src->extra_data != NULL) 155 { 156 dest->extra_data = src->extra_data_dup_func(src->extra_data); 157 if (dest->extra_data == NULL) 158 return 0; 159 } 160 161 dest->extra_data_dup_func = src->extra_data_dup_func; 162 dest->extra_data_free_func = src->extra_data_free_func; 163 dest->extra_data_clear_free_func = src->extra_data_clear_free_func; 164 } 165 166 return dest->meth->group_copy(dest, src); 167 } 168 169 170const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) 171 { 172 return group->meth; 173 } 174 175 176int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 177 { 178 if (group->meth->group_set_curve_GFp == 0) 179 { 180 ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 181 return 0; 182 } 183 return group->meth->group_set_curve_GFp(group, p, a, b, ctx); 184 } 185 186 187int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) 188 { 189 if (group->meth->group_get_curve_GFp == 0) 190 { 191 ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 192 return 0; 193 } 194 return group->meth->group_get_curve_GFp(group, p, a, b, ctx); 195 } 196 197 198int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor) 199 { 200 if (group->meth->group_set_generator == 0) 201 { 202 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 203 return 0; 204 } 205 return group->meth->group_set_generator(group, generator, order, cofactor); 206 } 207 208 209EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) 210 { 211 if (group->meth->group_get0_generator == 0) 212 { 213 ECerr(EC_F_EC_GROUP_GET0_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 214 return 0; 215 } 216 return group->meth->group_get0_generator(group); 217 } 218 219 220int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) 221 { 222 if (group->meth->group_get_order == 0) 223 { 224 ECerr(EC_F_EC_GROUP_GET_ORDER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 225 return 0; 226 } 227 return group->meth->group_get_order(group, order, ctx); 228 } 229 230 231int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) 232 { 233 if (group->meth->group_get_cofactor == 0) 234 { 235 ECerr(EC_F_EC_GROUP_GET_COFACTOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 236 return 0; 237 } 238 return group->meth->group_get_cofactor(group, cofactor, ctx); 239 } 240 241 242/* this has 'package' visibility */ 243int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *), 244 void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *)) 245 { 246 if ((group->extra_data != NULL) 247 || (group->extra_data_dup_func != 0) 248 || (group->extra_data_free_func != 0) 249 || (group->extra_data_clear_free_func != 0)) 250 { 251 ECerr(EC_F_EC_GROUP_SET_EXTRA_DATA, EC_R_SLOT_FULL); 252 return 0; 253 } 254 255 group->extra_data = extra_data; 256 group->extra_data_dup_func = extra_data_dup_func; 257 group->extra_data_free_func = extra_data_free_func; 258 group->extra_data_clear_free_func = extra_data_clear_free_func; 259 return 1; 260 } 261 262 263/* this has 'package' visibility */ 264void *EC_GROUP_get_extra_data(const EC_GROUP *group, void *(*extra_data_dup_func)(void *), 265 void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *)) 266 { 267 if ((group->extra_data_dup_func != extra_data_dup_func) 268 || (group->extra_data_free_func != extra_data_free_func) 269 || (group->extra_data_clear_free_func != extra_data_clear_free_func)) 270 { 271#if 0 /* this was an error in 0.9.7, but that does not make a lot of sense */ 272 ECerr(..._F_EC_GROUP_GET_EXTRA_DATA, ..._R_NO_SUCH_EXTRA_DATA); 273#endif 274 return NULL; 275 } 276 277 return group->extra_data; 278 } 279 280 281/* this has 'package' visibility */ 282void EC_GROUP_free_extra_data(EC_GROUP *group) 283 { 284 if (group->extra_data_free_func) 285 group->extra_data_free_func(group->extra_data); 286 group->extra_data = NULL; 287 group->extra_data_dup_func = 0; 288 group->extra_data_free_func = 0; 289 group->extra_data_clear_free_func = 0; 290 } 291 292 293/* this has 'package' visibility */ 294void EC_GROUP_clear_free_extra_data(EC_GROUP *group) 295 { 296 if (group->extra_data_clear_free_func) 297 group->extra_data_clear_free_func(group->extra_data); 298 else if (group->extra_data_free_func) 299 group->extra_data_free_func(group->extra_data); 300 group->extra_data = NULL; 301 group->extra_data_dup_func = 0; 302 group->extra_data_free_func = 0; 303 group->extra_data_clear_free_func = 0; 304 } 305 306 307 308/* functions for EC_POINT objects */ 309 310EC_POINT *EC_POINT_new(const EC_GROUP *group) 311 { 312 EC_POINT *ret; 313 314 if (group == NULL) 315 { 316 ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER); 317 return NULL; 318 } 319 if (group->meth->point_init == 0) 320 { 321 ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 322 return NULL; 323 } 324 325 ret = OPENSSL_malloc(sizeof *ret); 326 if (ret == NULL) 327 { 328 ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); 329 return NULL; 330 } 331 332 ret->meth = group->meth; 333 334 if (!ret->meth->point_init(ret)) 335 { 336 OPENSSL_free(ret); 337 return NULL; 338 } 339 340 return ret; 341 } 342 343 344void EC_POINT_free(EC_POINT *point) 345 { 346 if (!point) return; 347 348 if (point->meth->point_finish != 0) 349 point->meth->point_finish(point); 350 OPENSSL_free(point); 351 } 352 353 354void EC_POINT_clear_free(EC_POINT *point) 355 { 356 if (!point) return; 357 358 if (point->meth->point_clear_finish != 0) 359 point->meth->point_clear_finish(point); 360 else if (point->meth != NULL && point->meth->point_finish != 0) 361 point->meth->point_finish(point); 362 OPENSSL_cleanse(point, sizeof *point); 363 OPENSSL_free(point); 364 } 365 366 367int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) 368 { 369 if (dest->meth->point_copy == 0) 370 { 371 ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 372 return 0; 373 } 374 if (dest->meth != src->meth) 375 { 376 ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); 377 return 0; 378 } 379 if (dest == src) 380 return 1; 381 return dest->meth->point_copy(dest, src); 382 } 383 384 385const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) 386 { 387 return point->meth; 388 } 389 390 391int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) 392 { 393 if (group->meth->point_set_to_infinity == 0) 394 { 395 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 396 return 0; 397 } 398 if (group->meth != point->meth) 399 { 400 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); 401 return 0; 402 } 403 return group->meth->point_set_to_infinity(group, point); 404 } 405 406 407int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 408 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) 409 { 410 if (group->meth->point_set_Jprojective_coordinates_GFp == 0) 411 { 412 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 413 return 0; 414 } 415 if (group->meth != point->meth) 416 { 417 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); 418 return 0; 419 } 420 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx); 421 } 422 423 424int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, 425 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) 426 { 427 if (group->meth->point_get_Jprojective_coordinates_GFp == 0) 428 { 429 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 430 return 0; 431 } 432 if (group->meth != point->meth) 433 { 434 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); 435 return 0; 436 } 437 return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx); 438 } 439 440 441int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 442 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 443 { 444 if (group->meth->point_set_affine_coordinates_GFp == 0) 445 { 446 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 447 return 0; 448 } 449 if (group->meth != point->meth) 450 { 451 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); 452 return 0; 453 } 454 return group->meth->point_set_affine_coordinates_GFp(group, point, x, y, ctx); 455 } 456 457 458int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, 459 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 460 { 461 if (group->meth->point_get_affine_coordinates_GFp == 0) 462 { 463 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 464 return 0; 465 } 466 if (group->meth != point->meth) 467 { 468 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); 469 return 0; 470 } 471 return group->meth->point_get_affine_coordinates_GFp(group, point, x, y, ctx); 472 } 473 474 475int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 476 const BIGNUM *x, int y_bit, BN_CTX *ctx) 477 { 478 if (group->meth->point_set_compressed_coordinates_GFp == 0) 479 { 480 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 481 return 0; 482 } 483 if (group->meth != point->meth) 484 { 485 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); 486 return 0; 487 } 488 return group->meth->point_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx); 489 } 490 491 492size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, 493 unsigned char *buf, size_t len, BN_CTX *ctx) 494 { 495 if (group->meth->point2oct == 0) 496 { 497 ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 498 return 0; 499 } 500 if (group->meth != point->meth) 501 { 502 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); 503 return 0; 504 } 505 return group->meth->point2oct(group, point, form, buf, len, ctx); 506 } 507 508 509int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, 510 const unsigned char *buf, size_t len, BN_CTX *ctx) 511 { 512 if (group->meth->oct2point == 0) 513 { 514 ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 515 return 0; 516 } 517 if (group->meth != point->meth) 518 { 519 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); 520 return 0; 521 } 522 return group->meth->oct2point(group, point, buf, len, ctx); 523 } 524 525 526int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) 527 { 528 if (group->meth->add == 0) 529 { 530 ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 531 return 0; 532 } 533 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) 534 { 535 ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); 536 return 0; 537 } 538 return group->meth->add(group, r, a, b, ctx); 539 } 540 541 542int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) 543 { 544 if (group->meth->dbl == 0) 545 { 546 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 547 return 0; 548 } 549 if ((group->meth != r->meth) || (r->meth != a->meth)) 550 { 551 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); 552 return 0; 553 } 554 return group->meth->dbl(group, r, a, ctx); 555 } 556 557 558int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) 559 { 560 if (group->meth->dbl == 0) 561 { 562 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 563 return 0; 564 } 565 if (group->meth != a->meth) 566 { 567 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); 568 return 0; 569 } 570 return group->meth->invert(group, a, ctx); 571 } 572 573 574int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) 575 { 576 if (group->meth->is_at_infinity == 0) 577 { 578 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 579 return 0; 580 } 581 if (group->meth != point->meth) 582 { 583 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); 584 return 0; 585 } 586 return group->meth->is_at_infinity(group, point); 587 } 588 589 590int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) 591 { 592 if (group->meth->is_on_curve == 0) 593 { 594 ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 595 return 0; 596 } 597 if (group->meth != point->meth) 598 { 599 ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); 600 return 0; 601 } 602 return group->meth->is_on_curve(group, point, ctx); 603 } 604 605 606int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) 607 { 608 if (group->meth->point_cmp == 0) 609 { 610 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 611 return 0; 612 } 613 if ((group->meth != a->meth) || (a->meth != b->meth)) 614 { 615 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); 616 return 0; 617 } 618 return group->meth->point_cmp(group, a, b, ctx); 619 } 620 621 622int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 623 { 624 if (group->meth->make_affine == 0) 625 { 626 ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 627 return 0; 628 } 629 if (group->meth != point->meth) 630 { 631 ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); 632 return 0; 633 } 634 return group->meth->make_affine(group, point, ctx); 635 } 636 637 638int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) 639 { 640 size_t i; 641 642 if (group->meth->points_make_affine == 0) 643 { 644 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 645 return 0; 646 } 647 for (i = 0; i < num; i++) 648 { 649 if (group->meth != points[i]->meth) 650 { 651 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); 652 return 0; 653 } 654 } 655 return group->meth->points_make_affine(group, num, points, ctx); 656 } 657