1160814Ssimon/* crypto/ec/ec2_mult.c */ 2160814Ssimon/* ==================================================================== 3160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 4160814Ssimon * 5160814Ssimon * The Elliptic Curve Public-Key Crypto Library (ECC Code) included 6160814Ssimon * herein is developed by SUN MICROSYSTEMS, INC., and is contributed 7160814Ssimon * to the OpenSSL project. 8160814Ssimon * 9160814Ssimon * The ECC Code is licensed pursuant to the OpenSSL open source 10160814Ssimon * license provided below. 11160814Ssimon * 12160814Ssimon * The software is originally written by Sheueling Chang Shantz and 13160814Ssimon * Douglas Stebila of Sun Microsystems Laboratories. 14160814Ssimon * 15160814Ssimon */ 16160814Ssimon/* ==================================================================== 17160814Ssimon * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 18160814Ssimon * 19160814Ssimon * Redistribution and use in source and binary forms, with or without 20160814Ssimon * modification, are permitted provided that the following conditions 21160814Ssimon * are met: 22160814Ssimon * 23160814Ssimon * 1. Redistributions of source code must retain the above copyright 24296465Sdelphij * notice, this list of conditions and the following disclaimer. 25160814Ssimon * 26160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 27160814Ssimon * notice, this list of conditions and the following disclaimer in 28160814Ssimon * the documentation and/or other materials provided with the 29160814Ssimon * distribution. 30160814Ssimon * 31160814Ssimon * 3. All advertising materials mentioning features or use of this 32160814Ssimon * software must display the following acknowledgment: 33160814Ssimon * "This product includes software developed by the OpenSSL Project 34160814Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 35160814Ssimon * 36160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 37160814Ssimon * endorse or promote products derived from this software without 38160814Ssimon * prior written permission. For written permission, please contact 39160814Ssimon * openssl-core@openssl.org. 40160814Ssimon * 41160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 42160814Ssimon * nor may "OpenSSL" appear in their names without prior written 43160814Ssimon * permission of the OpenSSL Project. 44160814Ssimon * 45160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 46160814Ssimon * acknowledgment: 47160814Ssimon * "This product includes software developed by the OpenSSL Project 48160814Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 49160814Ssimon * 50160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 51160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 53160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 54160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 55160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 56160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 57160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 59160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 61160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 62160814Ssimon * ==================================================================== 63160814Ssimon * 64160814Ssimon * This product includes cryptographic software written by Eric Young 65160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 66160814Ssimon * Hudson (tjh@cryptsoft.com). 67160814Ssimon * 68160814Ssimon */ 69160814Ssimon 70160814Ssimon#include <openssl/err.h> 71160814Ssimon 72160814Ssimon#include "ec_lcl.h" 73160814Ssimon 74296465Sdelphij/*- 75296465Sdelphij * Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective 76160814Ssimon * coordinates. 77296465Sdelphij * Uses algorithm Mdouble in appendix of 78296465Sdelphij * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over 79160814Ssimon * GF(2^m) without precomputation". 80160814Ssimon * modified to not require precomputation of c=b^{2^{m-1}}. 81160814Ssimon */ 82296465Sdelphijstatic int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, 83296465Sdelphij BN_CTX *ctx) 84296465Sdelphij{ 85296465Sdelphij BIGNUM *t1; 86296465Sdelphij int ret = 0; 87160814Ssimon 88296465Sdelphij /* Since Mdouble is static we can guarantee that ctx != NULL. */ 89296465Sdelphij BN_CTX_start(ctx); 90296465Sdelphij t1 = BN_CTX_get(ctx); 91296465Sdelphij if (t1 == NULL) 92296465Sdelphij goto err; 93160814Ssimon 94296465Sdelphij if (!group->meth->field_sqr(group, x, x, ctx)) 95296465Sdelphij goto err; 96296465Sdelphij if (!group->meth->field_sqr(group, t1, z, ctx)) 97296465Sdelphij goto err; 98296465Sdelphij if (!group->meth->field_mul(group, z, x, t1, ctx)) 99296465Sdelphij goto err; 100296465Sdelphij if (!group->meth->field_sqr(group, x, x, ctx)) 101296465Sdelphij goto err; 102296465Sdelphij if (!group->meth->field_sqr(group, t1, t1, ctx)) 103296465Sdelphij goto err; 104296465Sdelphij if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) 105296465Sdelphij goto err; 106296465Sdelphij if (!BN_GF2m_add(x, x, t1)) 107296465Sdelphij goto err; 108160814Ssimon 109296465Sdelphij ret = 1; 110296465Sdelphij 111160814Ssimon err: 112296465Sdelphij BN_CTX_end(ctx); 113296465Sdelphij return ret; 114296465Sdelphij} 115160814Ssimon 116296465Sdelphij/*- 117296465Sdelphij * Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery 118160814Ssimon * projective coordinates. 119296465Sdelphij * Uses algorithm Madd in appendix of 120296465Sdelphij * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over 121160814Ssimon * GF(2^m) without precomputation". 122160814Ssimon */ 123296465Sdelphijstatic int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, 124296465Sdelphij BIGNUM *z1, const BIGNUM *x2, const BIGNUM *z2, 125296465Sdelphij BN_CTX *ctx) 126296465Sdelphij{ 127296465Sdelphij BIGNUM *t1, *t2; 128296465Sdelphij int ret = 0; 129160814Ssimon 130296465Sdelphij /* Since Madd is static we can guarantee that ctx != NULL. */ 131296465Sdelphij BN_CTX_start(ctx); 132296465Sdelphij t1 = BN_CTX_get(ctx); 133296465Sdelphij t2 = BN_CTX_get(ctx); 134296465Sdelphij if (t2 == NULL) 135296465Sdelphij goto err; 136160814Ssimon 137296465Sdelphij if (!BN_copy(t1, x)) 138296465Sdelphij goto err; 139296465Sdelphij if (!group->meth->field_mul(group, x1, x1, z2, ctx)) 140296465Sdelphij goto err; 141296465Sdelphij if (!group->meth->field_mul(group, z1, z1, x2, ctx)) 142296465Sdelphij goto err; 143296465Sdelphij if (!group->meth->field_mul(group, t2, x1, z1, ctx)) 144296465Sdelphij goto err; 145296465Sdelphij if (!BN_GF2m_add(z1, z1, x1)) 146296465Sdelphij goto err; 147296465Sdelphij if (!group->meth->field_sqr(group, z1, z1, ctx)) 148296465Sdelphij goto err; 149296465Sdelphij if (!group->meth->field_mul(group, x1, z1, t1, ctx)) 150296465Sdelphij goto err; 151296465Sdelphij if (!BN_GF2m_add(x1, x1, t2)) 152296465Sdelphij goto err; 153160814Ssimon 154296465Sdelphij ret = 1; 155296465Sdelphij 156160814Ssimon err: 157296465Sdelphij BN_CTX_end(ctx); 158296465Sdelphij return ret; 159296465Sdelphij} 160160814Ssimon 161296465Sdelphij/*- 162296465Sdelphij * Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) 163296465Sdelphij * using Montgomery point multiplication algorithm Mxy() in appendix of 164296465Sdelphij * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over 165160814Ssimon * GF(2^m) without precomputation". 166160814Ssimon * Returns: 167160814Ssimon * 0 on error 168160814Ssimon * 1 if return value should be the point at infinity 169160814Ssimon * 2 otherwise 170160814Ssimon */ 171296465Sdelphijstatic int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, 172296465Sdelphij BIGNUM *x1, BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, 173296465Sdelphij BN_CTX *ctx) 174296465Sdelphij{ 175296465Sdelphij BIGNUM *t3, *t4, *t5; 176296465Sdelphij int ret = 0; 177160814Ssimon 178296465Sdelphij if (BN_is_zero(z1)) { 179296465Sdelphij BN_zero(x2); 180296465Sdelphij BN_zero(z2); 181296465Sdelphij return 1; 182296465Sdelphij } 183160814Ssimon 184296465Sdelphij if (BN_is_zero(z2)) { 185296465Sdelphij if (!BN_copy(x2, x)) 186296465Sdelphij return 0; 187296465Sdelphij if (!BN_GF2m_add(z2, x, y)) 188296465Sdelphij return 0; 189296465Sdelphij return 2; 190296465Sdelphij } 191160814Ssimon 192296465Sdelphij /* Since Mxy is static we can guarantee that ctx != NULL. */ 193296465Sdelphij BN_CTX_start(ctx); 194296465Sdelphij t3 = BN_CTX_get(ctx); 195296465Sdelphij t4 = BN_CTX_get(ctx); 196296465Sdelphij t5 = BN_CTX_get(ctx); 197296465Sdelphij if (t5 == NULL) 198296465Sdelphij goto err; 199160814Ssimon 200296465Sdelphij if (!BN_one(t5)) 201296465Sdelphij goto err; 202160814Ssimon 203296465Sdelphij if (!group->meth->field_mul(group, t3, z1, z2, ctx)) 204296465Sdelphij goto err; 205160814Ssimon 206296465Sdelphij if (!group->meth->field_mul(group, z1, z1, x, ctx)) 207296465Sdelphij goto err; 208296465Sdelphij if (!BN_GF2m_add(z1, z1, x1)) 209296465Sdelphij goto err; 210296465Sdelphij if (!group->meth->field_mul(group, z2, z2, x, ctx)) 211296465Sdelphij goto err; 212296465Sdelphij if (!group->meth->field_mul(group, x1, z2, x1, ctx)) 213296465Sdelphij goto err; 214296465Sdelphij if (!BN_GF2m_add(z2, z2, x2)) 215296465Sdelphij goto err; 216160814Ssimon 217296465Sdelphij if (!group->meth->field_mul(group, z2, z2, z1, ctx)) 218296465Sdelphij goto err; 219296465Sdelphij if (!group->meth->field_sqr(group, t4, x, ctx)) 220296465Sdelphij goto err; 221296465Sdelphij if (!BN_GF2m_add(t4, t4, y)) 222296465Sdelphij goto err; 223296465Sdelphij if (!group->meth->field_mul(group, t4, t4, t3, ctx)) 224296465Sdelphij goto err; 225296465Sdelphij if (!BN_GF2m_add(t4, t4, z2)) 226296465Sdelphij goto err; 227160814Ssimon 228296465Sdelphij if (!group->meth->field_mul(group, t3, t3, x, ctx)) 229296465Sdelphij goto err; 230296465Sdelphij if (!group->meth->field_div(group, t3, t5, t3, ctx)) 231296465Sdelphij goto err; 232296465Sdelphij if (!group->meth->field_mul(group, t4, t3, t4, ctx)) 233296465Sdelphij goto err; 234296465Sdelphij if (!group->meth->field_mul(group, x2, x1, t3, ctx)) 235296465Sdelphij goto err; 236296465Sdelphij if (!BN_GF2m_add(z2, x2, x)) 237296465Sdelphij goto err; 238296465Sdelphij 239296465Sdelphij if (!group->meth->field_mul(group, z2, z2, t4, ctx)) 240296465Sdelphij goto err; 241296465Sdelphij if (!BN_GF2m_add(z2, z2, y)) 242296465Sdelphij goto err; 243296465Sdelphij 244296465Sdelphij ret = 2; 245296465Sdelphij 246160814Ssimon err: 247296465Sdelphij BN_CTX_end(ctx); 248296465Sdelphij return ret; 249296465Sdelphij} 250160814Ssimon 251296465Sdelphij/*- 252296465Sdelphij * Computes scalar*point and stores the result in r. 253160814Ssimon * point can not equal r. 254264285Sdelphij * Uses a modified algorithm 2P of 255296465Sdelphij * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over 256160814Ssimon * GF(2^m) without precomputation". 257264285Sdelphij * 258264285Sdelphij * To protect against side-channel attack the function uses constant time 259264285Sdelphij * swap avoiding conditional branches. 260160814Ssimon */ 261296465Sdelphijstatic int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, 262296465Sdelphij EC_POINT *r, 263296465Sdelphij const BIGNUM *scalar, 264296465Sdelphij const EC_POINT *point, 265296465Sdelphij BN_CTX *ctx) 266296465Sdelphij{ 267296465Sdelphij BIGNUM *x1, *x2, *z1, *z2; 268296465Sdelphij int ret = 0, i, j; 269296465Sdelphij BN_ULONG mask; 270160814Ssimon 271296465Sdelphij if (r == point) { 272296465Sdelphij ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT); 273296465Sdelphij return 0; 274296465Sdelphij } 275160814Ssimon 276296465Sdelphij /* if result should be point at infinity */ 277296465Sdelphij if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) || 278296465Sdelphij EC_POINT_is_at_infinity(group, point)) { 279296465Sdelphij return EC_POINT_set_to_infinity(group, r); 280296465Sdelphij } 281160814Ssimon 282296465Sdelphij /* only support affine coordinates */ 283296465Sdelphij if (!point->Z_is_one) 284296465Sdelphij return 0; 285160814Ssimon 286296465Sdelphij /* 287296465Sdelphij * Since point_multiply is static we can guarantee that ctx != NULL. 288296465Sdelphij */ 289296465Sdelphij BN_CTX_start(ctx); 290296465Sdelphij x1 = BN_CTX_get(ctx); 291296465Sdelphij z1 = BN_CTX_get(ctx); 292296465Sdelphij if (z1 == NULL) 293296465Sdelphij goto err; 294160814Ssimon 295296465Sdelphij x2 = &r->X; 296296465Sdelphij z2 = &r->Y; 297264285Sdelphij 298296465Sdelphij bn_wexpand(x1, group->field.top); 299296465Sdelphij bn_wexpand(z1, group->field.top); 300296465Sdelphij bn_wexpand(x2, group->field.top); 301296465Sdelphij bn_wexpand(z2, group->field.top); 302160814Ssimon 303296465Sdelphij if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) 304296465Sdelphij goto err; /* x1 = x */ 305296465Sdelphij if (!BN_one(z1)) 306296465Sdelphij goto err; /* z1 = 1 */ 307296465Sdelphij if (!group->meth->field_sqr(group, z2, x1, ctx)) 308296465Sdelphij goto err; /* z2 = x1^2 = x^2 */ 309296465Sdelphij if (!group->meth->field_sqr(group, x2, z2, ctx)) 310296465Sdelphij goto err; 311296465Sdelphij if (!BN_GF2m_add(x2, x2, &group->b)) 312296465Sdelphij goto err; /* x2 = x^4 + b */ 313160814Ssimon 314296465Sdelphij /* find top most bit and go one past it */ 315296465Sdelphij i = scalar->top - 1; 316296465Sdelphij j = BN_BITS2 - 1; 317296465Sdelphij mask = BN_TBIT; 318296465Sdelphij while (!(scalar->d[i] & mask)) { 319296465Sdelphij mask >>= 1; 320296465Sdelphij j--; 321296465Sdelphij } 322296465Sdelphij mask >>= 1; 323296465Sdelphij j--; 324296465Sdelphij /* if top most bit was at word break, go to next word */ 325296465Sdelphij if (!mask) { 326296465Sdelphij i--; 327296465Sdelphij j = BN_BITS2 - 1; 328296465Sdelphij mask = BN_TBIT; 329296465Sdelphij } 330160814Ssimon 331296465Sdelphij for (; i >= 0; i--) { 332296465Sdelphij for (; j >= 0; j--) { 333296465Sdelphij BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); 334296465Sdelphij BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); 335296465Sdelphij if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) 336296465Sdelphij goto err; 337296465Sdelphij if (!gf2m_Mdouble(group, x1, z1, ctx)) 338296465Sdelphij goto err; 339296465Sdelphij BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); 340296465Sdelphij BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); 341296465Sdelphij mask >>= 1; 342296465Sdelphij } 343296465Sdelphij j = BN_BITS2 - 1; 344296465Sdelphij mask = BN_TBIT; 345296465Sdelphij } 346160814Ssimon 347296465Sdelphij /* convert out of "projective" coordinates */ 348296465Sdelphij i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx); 349296465Sdelphij if (i == 0) 350296465Sdelphij goto err; 351296465Sdelphij else if (i == 1) { 352296465Sdelphij if (!EC_POINT_set_to_infinity(group, r)) 353296465Sdelphij goto err; 354296465Sdelphij } else { 355296465Sdelphij if (!BN_one(&r->Z)) 356296465Sdelphij goto err; 357296465Sdelphij r->Z_is_one = 1; 358296465Sdelphij } 359160814Ssimon 360296465Sdelphij /* GF(2^m) field elements should always have BIGNUM::neg = 0 */ 361296465Sdelphij BN_set_negative(&r->X, 0); 362296465Sdelphij BN_set_negative(&r->Y, 0); 363160814Ssimon 364296465Sdelphij ret = 1; 365296465Sdelphij 366160814Ssimon err: 367296465Sdelphij BN_CTX_end(ctx); 368296465Sdelphij return ret; 369296465Sdelphij} 370160814Ssimon 371296465Sdelphij/*- 372296465Sdelphij * Computes the sum 373160814Ssimon * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1] 374160814Ssimon * gracefully ignoring NULL scalar values. 375160814Ssimon */ 376296465Sdelphijint ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, 377296465Sdelphij const BIGNUM *scalar, size_t num, 378296465Sdelphij const EC_POINT *points[], const BIGNUM *scalars[], 379296465Sdelphij BN_CTX *ctx) 380296465Sdelphij{ 381296465Sdelphij BN_CTX *new_ctx = NULL; 382296465Sdelphij int ret = 0; 383296465Sdelphij size_t i; 384296465Sdelphij EC_POINT *p = NULL; 385296465Sdelphij EC_POINT *acc = NULL; 386160814Ssimon 387296465Sdelphij if (ctx == NULL) { 388296465Sdelphij ctx = new_ctx = BN_CTX_new(); 389296465Sdelphij if (ctx == NULL) 390296465Sdelphij return 0; 391296465Sdelphij } 392160814Ssimon 393296465Sdelphij /* 394296465Sdelphij * This implementation is more efficient than the wNAF implementation for 395296465Sdelphij * 2 or fewer points. Use the ec_wNAF_mul implementation for 3 or more 396296465Sdelphij * points, or if we can perform a fast multiplication based on 397296465Sdelphij * precomputation. 398296465Sdelphij */ 399296465Sdelphij if ((scalar && (num > 1)) || (num > 2) 400296465Sdelphij || (num == 0 && EC_GROUP_have_precompute_mult(group))) { 401296465Sdelphij ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); 402296465Sdelphij goto err; 403296465Sdelphij } 404160814Ssimon 405296465Sdelphij if ((p = EC_POINT_new(group)) == NULL) 406296465Sdelphij goto err; 407296465Sdelphij if ((acc = EC_POINT_new(group)) == NULL) 408296465Sdelphij goto err; 409160814Ssimon 410296465Sdelphij if (!EC_POINT_set_to_infinity(group, acc)) 411296465Sdelphij goto err; 412160814Ssimon 413296465Sdelphij if (scalar) { 414296465Sdelphij if (!ec_GF2m_montgomery_point_multiply 415296465Sdelphij (group, p, scalar, group->generator, ctx)) 416296465Sdelphij goto err; 417296465Sdelphij if (BN_is_negative(scalar)) 418296465Sdelphij if (!group->meth->invert(group, p, ctx)) 419296465Sdelphij goto err; 420296465Sdelphij if (!group->meth->add(group, acc, acc, p, ctx)) 421296465Sdelphij goto err; 422296465Sdelphij } 423160814Ssimon 424296465Sdelphij for (i = 0; i < num; i++) { 425296465Sdelphij if (!ec_GF2m_montgomery_point_multiply 426296465Sdelphij (group, p, scalars[i], points[i], ctx)) 427296465Sdelphij goto err; 428296465Sdelphij if (BN_is_negative(scalars[i])) 429296465Sdelphij if (!group->meth->invert(group, p, ctx)) 430296465Sdelphij goto err; 431296465Sdelphij if (!group->meth->add(group, acc, acc, p, ctx)) 432296465Sdelphij goto err; 433296465Sdelphij } 434160814Ssimon 435296465Sdelphij if (!EC_POINT_copy(r, acc)) 436296465Sdelphij goto err; 437215697Ssimon 438296465Sdelphij ret = 1; 439160814Ssimon 440296465Sdelphij err: 441296465Sdelphij if (p) 442296465Sdelphij EC_POINT_free(p); 443296465Sdelphij if (acc) 444296465Sdelphij EC_POINT_free(acc); 445296465Sdelphij if (new_ctx != NULL) 446296465Sdelphij BN_CTX_free(new_ctx); 447296465Sdelphij return ret; 448296465Sdelphij} 449160814Ssimon 450296465Sdelphij/* 451296465Sdelphij * Precomputation for point multiplication: fall back to wNAF methods because 452296465Sdelphij * ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate 453296465Sdelphij */ 454160814Ssimon 455160814Ssimonint ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx) 456296465Sdelphij{ 457296465Sdelphij return ec_wNAF_precompute_mult(group, ctx); 458296465Sdelphij} 459160814Ssimon 460160814Ssimonint ec_GF2m_have_precompute_mult(const EC_GROUP *group) 461296465Sdelphij{ 462296465Sdelphij return ec_wNAF_have_precompute_mult(group); 463296465Sdelphij} 464