1109998Smarkm/* crypto/ec/ec_cvt.c */ 2160814Ssimon/* 3160814Ssimon * Originally written by Bodo Moeller for the OpenSSL project. 4160814Ssimon */ 5109998Smarkm/* ==================================================================== 6160814Ssimon * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 7109998Smarkm * 8109998Smarkm * Redistribution and use in source and binary forms, with or without 9109998Smarkm * modification, are permitted provided that the following conditions 10109998Smarkm * are met: 11109998Smarkm * 12109998Smarkm * 1. Redistributions of source code must retain the above copyright 13109998Smarkm * notice, this list of conditions and the following disclaimer. 14109998Smarkm * 15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 16109998Smarkm * notice, this list of conditions and the following disclaimer in 17109998Smarkm * the documentation and/or other materials provided with the 18109998Smarkm * distribution. 19109998Smarkm * 20109998Smarkm * 3. All advertising materials mentioning features or use of this 21109998Smarkm * software must display the following acknowledgment: 22109998Smarkm * "This product includes software developed by the OpenSSL Project 23109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24109998Smarkm * 25109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26109998Smarkm * endorse or promote products derived from this software without 27109998Smarkm * prior written permission. For written permission, please contact 28109998Smarkm * openssl-core@openssl.org. 29109998Smarkm * 30109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 31109998Smarkm * nor may "OpenSSL" appear in their names without prior written 32109998Smarkm * permission of the OpenSSL Project. 33109998Smarkm * 34109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 35109998Smarkm * acknowledgment: 36109998Smarkm * "This product includes software developed by the OpenSSL Project 37109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38109998Smarkm * 39109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 51109998Smarkm * ==================================================================== 52109998Smarkm * 53109998Smarkm * This product includes cryptographic software written by Eric Young 54109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 55109998Smarkm * Hudson (tjh@cryptsoft.com). 56109998Smarkm * 57109998Smarkm */ 58160814Ssimon/* ==================================================================== 59160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60160814Ssimon * 61160814Ssimon * Portions of the attached software ("Contribution") are developed by 62160814Ssimon * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 63160814Ssimon * 64160814Ssimon * The Contribution is licensed pursuant to the OpenSSL open source 65160814Ssimon * license provided above. 66160814Ssimon * 67160814Ssimon * The elliptic curve binary polynomial software is originally written by 68160814Ssimon * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. 69160814Ssimon * 70160814Ssimon */ 71109998Smarkm 72160814Ssimon#include <openssl/err.h> 73109998Smarkm#include "ec_lcl.h" 74109998Smarkm 75109998Smarkm 76109998SmarkmEC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 77109998Smarkm { 78109998Smarkm const EC_METHOD *meth; 79109998Smarkm EC_GROUP *ret; 80160814Ssimon 81238405Sjkim#if defined(OPENSSL_BN_ASM_MONT) 82238405Sjkim /* 83238405Sjkim * This might appear controversial, but the fact is that generic 84238405Sjkim * prime method was observed to deliver better performance even 85238405Sjkim * for NIST primes on a range of platforms, e.g.: 60%-15% 86238405Sjkim * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25% 87238405Sjkim * in 32-bit build and 35%--12% in 64-bit build on Core2... 88238405Sjkim * Coefficients are relative to optimized bn_nist.c for most 89238405Sjkim * intensive ECDSA verify and ECDH operations for 192- and 521- 90238405Sjkim * bit keys respectively. Choice of these boundary values is 91238405Sjkim * arguable, because the dependency of improvement coefficient 92238405Sjkim * from key length is not a "monotone" curve. For example while 93238405Sjkim * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's 94238405Sjkim * generally faster, sometimes "respectfully" faster, sometimes 95238405Sjkim * "tolerably" slower... What effectively happens is that loop 96238405Sjkim * with bn_mul_add_words is put against bn_mul_mont, and the 97238405Sjkim * latter "wins" on short vectors. Correct solution should be 98238405Sjkim * implementing dedicated NxN multiplication subroutines for 99238405Sjkim * small N. But till it materializes, let's stick to generic 100238405Sjkim * prime method... 101238405Sjkim * <appro> 102238405Sjkim */ 103238405Sjkim meth = EC_GFp_mont_method(); 104238405Sjkim#else 105160814Ssimon meth = EC_GFp_nist_method(); 106238405Sjkim#endif 107109998Smarkm 108109998Smarkm ret = EC_GROUP_new(meth); 109109998Smarkm if (ret == NULL) 110109998Smarkm return NULL; 111109998Smarkm 112109998Smarkm if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) 113109998Smarkm { 114160814Ssimon unsigned long err; 115160814Ssimon 116160814Ssimon err = ERR_peek_last_error(); 117160814Ssimon 118160814Ssimon if (!(ERR_GET_LIB(err) == ERR_LIB_EC && 119160814Ssimon ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) || 120160814Ssimon (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) 121160814Ssimon { 122160814Ssimon /* real error */ 123160814Ssimon 124160814Ssimon EC_GROUP_clear_free(ret); 125160814Ssimon return NULL; 126160814Ssimon } 127160814Ssimon 128160814Ssimon 129160814Ssimon /* not an actual error, we just cannot use EC_GFp_nist_method */ 130160814Ssimon 131160814Ssimon ERR_clear_error(); 132160814Ssimon 133109998Smarkm EC_GROUP_clear_free(ret); 134160814Ssimon meth = EC_GFp_mont_method(); 135160814Ssimon 136160814Ssimon ret = EC_GROUP_new(meth); 137160814Ssimon if (ret == NULL) 138160814Ssimon return NULL; 139160814Ssimon 140160814Ssimon if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) 141160814Ssimon { 142160814Ssimon EC_GROUP_clear_free(ret); 143160814Ssimon return NULL; 144160814Ssimon } 145160814Ssimon } 146160814Ssimon 147160814Ssimon return ret; 148160814Ssimon } 149160814Ssimon 150238405Sjkim#ifndef OPENSSL_NO_EC2M 151160814SsimonEC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 152160814Ssimon { 153160814Ssimon const EC_METHOD *meth; 154160814Ssimon EC_GROUP *ret; 155160814Ssimon 156160814Ssimon meth = EC_GF2m_simple_method(); 157160814Ssimon 158160814Ssimon ret = EC_GROUP_new(meth); 159160814Ssimon if (ret == NULL) 160109998Smarkm return NULL; 161160814Ssimon 162160814Ssimon if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) 163160814Ssimon { 164160814Ssimon EC_GROUP_clear_free(ret); 165160814Ssimon return NULL; 166109998Smarkm } 167109998Smarkm 168109998Smarkm return ret; 169109998Smarkm } 170238405Sjkim#endif 171