From 5d5ea22fa7c35b6bff069067ccf2452a5a77edbc Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Wed, 15 Feb 2017 16:08:27 +0800 Subject: [PATCH] add extra ec --- Configure | 2 +- crypto/bn/bn_err.c | 22 +- crypto/ec/ec_err.c | 21 + crypto/ec2/bn_gfp2.c | 497 ++++++++++++++++++++++ crypto/ec2/bn_hash.c | 167 ++++++++ crypto/ec2/bn_solinas.c | 193 +++++++++ crypto/ec2/build.info | 3 + crypto/ec2/ec_expoint.c | 90 ++++ crypto/ec2/ec_hash.c | 181 ++++++++ crypto/ec2/ec_type1.c | 783 +++++++++++++++++++++++++++++++++++ crypto/ec2/fppoint.c | 114 +++++ include/openssl/bn.h | 19 + include/openssl/bn_gfp2.h | 98 +++++ include/openssl/bn_hash.h | 68 +++ include/openssl/bn_solinas.h | 94 +++++ include/openssl/ec.h | 15 + include/openssl/ec_hash.h | 67 +++ include/openssl/ec_type1.h | 100 +++++ include/openssl/fppoint.h | 77 ++++ test/build.info | 6 +- test/ec2test.c | 69 +++ test/recipes/15-test_ec2.t | 12 + 22 files changed, 2695 insertions(+), 3 deletions(-) create mode 100644 crypto/ec2/bn_gfp2.c create mode 100644 crypto/ec2/bn_hash.c create mode 100644 crypto/ec2/bn_solinas.c create mode 100644 crypto/ec2/build.info create mode 100644 crypto/ec2/ec_expoint.c create mode 100644 crypto/ec2/ec_hash.c create mode 100644 crypto/ec2/ec_type1.c create mode 100644 crypto/ec2/fppoint.c create mode 100644 include/openssl/bn_gfp2.h create mode 100644 include/openssl/bn_hash.h create mode 100644 include/openssl/bn_solinas.h create mode 100644 include/openssl/ec_hash.h create mode 100644 include/openssl/ec_type1.h create mode 100644 include/openssl/fppoint.h create mode 100644 test/ec2test.c create mode 100644 test/recipes/15-test_ec2.t diff --git a/Configure b/Configure index f5285065..a84b5704 100755 --- a/Configure +++ b/Configure @@ -311,7 +311,7 @@ $config{sdirs} = [ "buffer", "bio", "stack", "lhash", "rand", "err", "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui", "cms", "ts", "srp", "cmac", "ct", "async", "kdf", - "sm3", "sms4", "kdf2", "ecies", "ffx", "sm2", "paillier", "cpk", "otp", "gmapi" + "sm3", "sms4", "kdf2", "ecies", "ffx", "sm2", "paillier", "cpk", "otp", "gmapi", "ec2" ]; # Known TLS and DTLS protocols diff --git a/crypto/bn/bn_err.c b/crypto/bn/bn_err.c index 5fe9db9e..2796f446 100644 --- a/crypto/bn/bn_err.c +++ b/crypto/bn/bn_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -27,6 +27,7 @@ static ERR_STRING_DATA BN_str_functs[] = { {ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"}, {ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"}, {ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"}, + {ERR_FUNC(BN_F_BN_BN2SOLINAS), "BN_bn2solinas"}, {ERR_FUNC(BN_F_BN_COMPUTE_WNAF), "bn_compute_wNAF"}, {ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"}, {ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"}, @@ -45,6 +46,20 @@ static ERR_STRING_DATA BN_str_functs[] = { {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"}, {ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"}, {ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"}, + {ERR_FUNC(BN_F_BN_GFP2_ADD), "BN_GFP2_add"}, + {ERR_FUNC(BN_F_BN_GFP2_CANONICAL), "BN_GFP2_canonical"}, + {ERR_FUNC(BN_F_BN_GFP2_CMP), "BN_GFP2_cmp"}, + {ERR_FUNC(BN_F_BN_GFP2_COPY), "BN_GFP2_copy"}, + {ERR_FUNC(BN_F_BN_GFP2_DIV_BN), "BN_GFP2_div_bn"}, + {ERR_FUNC(BN_F_BN_GFP2_INV), "BN_GFP2_inv"}, + {ERR_FUNC(BN_F_BN_GFP2_IS_ZERO), "BN_GFP2_is_zero"}, + {ERR_FUNC(BN_F_BN_GFP2_MUL), "BN_GFP2_mul"}, + {ERR_FUNC(BN_F_BN_GFP2_NEW), "BN_GFP2_new"}, + {ERR_FUNC(BN_F_BN_GFP2_ONE), "BN_GFP2_one"}, + {ERR_FUNC(BN_F_BN_GFP2_SET_BN), "BN_GFP2_set_bn"}, + {ERR_FUNC(BN_F_BN_GFP2_SUB), "BN_GFP2_sub"}, + {ERR_FUNC(BN_F_BN_GFP2_ZERO), "BN_GFP2_zero"}, + {ERR_FUNC(BN_F_BN_HASH_TO_RANGE), "BN_hash_to_range"}, {ERR_FUNC(BN_F_BN_LSHIFT), "BN_lshift"}, {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"}, {ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"}, @@ -62,6 +77,7 @@ static ERR_STRING_DATA BN_str_functs[] = { {ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"}, {ERR_FUNC(BN_F_BN_RSHIFT), "BN_rshift"}, {ERR_FUNC(BN_F_BN_SET_WORDS), "bn_set_words"}, + {ERR_FUNC(BN_F_BN_SOLINAS2BN), "BN_solinas2bn"}, {ERR_FUNC(BN_F_BN_USUB), "BN_usub"}, {0, NULL} }; @@ -71,6 +87,7 @@ static ERR_STRING_DATA BN_str_reasons[] = { {ERR_REASON(BN_R_BAD_RECIPROCAL), "bad reciprocal"}, {ERR_REASON(BN_R_BIGNUM_TOO_LONG), "bignum too long"}, {ERR_REASON(BN_R_BITS_TOO_SMALL), "bits too small"}, + {ERR_REASON(BN_R_BUFFER_TOO_SMALL), "buffer too small"}, {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"}, {ERR_REASON(BN_R_DIV_BY_ZERO), "div by zero"}, {ERR_REASON(BN_R_ENCODING_ERROR), "encoding error"}, @@ -80,6 +97,9 @@ static ERR_STRING_DATA BN_str_reasons[] = { {ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"}, {ERR_REASON(BN_R_INVALID_RANGE), "invalid range"}, {ERR_REASON(BN_R_INVALID_SHIFT), "invalid shift"}, + {ERR_REASON(BN_R_INVALID_SOLINAS), "invalid solinas"}, + {ERR_REASON(BN_R_INVALID_SOLINAS_PARAMETERS), + "invalid solinas parameters"}, {ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"}, {ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"}, {ERR_REASON(BN_R_NO_INVERSE), "no inverse"}, diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c index e7d933bc..e776d091 100644 --- a/crypto/ec/ec_err.c +++ b/crypto/ec/ec_err.c @@ -127,6 +127,8 @@ static ERR_STRING_DATA EC_str_functs[] = { {ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), "EC_GROUP_check_discriminant"}, {ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"}, + {ERR_FUNC(EC_F_EC_GROUP_GENERATE_TYPE1CURVE), + "EC_GROUP_generate_type1curve"}, {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"}, {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"}, {ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"}, @@ -137,6 +139,11 @@ static ERR_STRING_DATA EC_str_functs[] = { "EC_GROUP_get_pentanomial_basis"}, {ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), "EC_GROUP_get_trinomial_basis"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA), + "EC_GROUP_get_type1curve_eta"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA), + "EC_GROUP_get_type1curve_zeta"}, + {ERR_FUNC(EC_F_EC_GROUP_IS_TYPE1CURVE), "EC_GROUP_is_type1curve"}, {ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"}, {ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"}, {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "ec_group_new_from_data"}, @@ -144,6 +151,7 @@ static ERR_STRING_DATA EC_str_functs[] = { "EC_GROUP_new_from_ecparameters"}, {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS), "EC_GROUP_new_from_ecpkparameters"}, + {ERR_FUNC(EC_F_EC_GROUP_NEW_TYPE1CURVE), "EC_GROUP_new_type1curve"}, {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"}, {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"}, {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"}, @@ -164,6 +172,7 @@ static ERR_STRING_DATA EC_str_functs[] = { {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"}, {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"}, {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"}, + {ERR_FUNC(EC_F_EC_POINT_CMP_FPPOINT), "EC_POINT_cmp_fppoint"}, {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"}, {ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"}, {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), @@ -172,6 +181,7 @@ static ERR_STRING_DATA EC_str_functs[] = { "EC_POINT_get_affine_coordinates_GFp"}, {ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_get_Jprojective_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_HASH2POINT), "EC_POINT_hash2point"}, {ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"}, {ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"}, {ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"}, @@ -191,6 +201,7 @@ static ERR_STRING_DATA EC_str_functs[] = { "EC_POINT_set_Jprojective_coordinates_GFp"}, {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"}, {ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "ec_pre_comp_new"}, + {ERR_FUNC(EC_F_EC_TYPE1CURVE_TATE), "EC_type1curve_tate"}, {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"}, {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"}, {ERR_FUNC(EC_F_I2D_ECIESPARAMETERS), "i2d_ECIESParameters"}, @@ -245,6 +256,11 @@ static ERR_STRING_DATA EC_str_functs[] = { {ERR_FUNC(EC_F_SM2_KAP_FINAL_CHECK), "SM2_KAP_final_check"}, {ERR_FUNC(EC_F_SM2_KAP_PREPARE), "SM2_KAP_prepare"}, {ERR_FUNC(EC_F_SM2_SIGN_SETUP), "sm2_sign_setup"}, + {ERR_FUNC(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK), + "type1curve_eval_line_textbook"}, + {ERR_FUNC(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK), + "type1curve_eval_miller_textbook"}, + {ERR_FUNC(EC_F_TYPE1CURVE_PHI), "type1curve_phi"}, {0, NULL} }; @@ -283,6 +299,8 @@ static ERR_STRING_DATA EC_str_reasons[] = { {ERR_REASON(EC_R_GET_KDF_FAILED), "get kdf failed"}, {ERR_REASON(EC_R_GET_PUBLIC_KEY_DATA_FAILURE), "get public key data failure"}, + {ERR_REASON(EC_R_GET_TYPE1CURVE_ZETA_FAILURE), + "get type1curve zeta failure"}, {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"}, {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE), "group2pkparameters failure"}, @@ -318,6 +336,9 @@ static ERR_STRING_DATA EC_str_reasons[] = { {ERR_REASON(EC_R_INVALID_SM2_KAP_CHECKSUM_VALUE), "invalid sm2 kap checksum value"}, {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"}, + {ERR_REASON(EC_R_INVALID_TYPE1CURVE), "invalid type1curve"}, + {ERR_REASON(EC_R_INVALID_TYPE1_CURVE), "invalid type1 curve"}, + {ERR_REASON(EC_R_INVLID_TYPE1CURVE), "invlid type1curve"}, {ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"}, {ERR_REASON(EC_R_MALLOC_FAILED), "malloc failed"}, diff --git a/crypto/ec2/bn_gfp2.c b/crypto/ec2/bn_gfp2.c new file mode 100644 index 00000000..1e32e687 --- /dev/null +++ b/crypto/ec2/bn_gfp2.c @@ -0,0 +1,497 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* + * this file implement complex number over prime field + * a = a0 + a1 * i, i^2 == -1 + * most of the routines should be replaced by macros + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * to make it simple, currently both a0 and a1 will be inited + */ + +BN_GFP2 *BN_GFP2_new(void) +{ + int e = 1; + BN_GFP2 *ret = NULL; + + if (!(ret = OPENSSL_malloc(sizeof(BN_GFP2)))) { + BNerr(BN_F_BN_GFP2_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->a0 = BN_new(); + ret->a1 = BN_new(); + if (!ret->a0 || !ret->a1) { + BNerr(BN_F_BN_GFP2_NEW, ERR_R_MALLOC_FAILURE); + goto end; + } + + BN_zero(ret->a0); + BN_zero(ret->a1); + + e = 0; +end: + if (e && ret) { + BN_GFP2_free(ret); + ret = NULL; + } + return ret; +} + +void BN_GFP2_free(BN_GFP2 *a) +{ + if (a) { + BN_free(a->a0); + BN_free(a->a1); + OPENSSL_free(a); + } +} + +int BN_GFP2_copy(BN_GFP2 *r, const BN_GFP2 *a) +{ + if (!r || !r->a0 || !r->a1 || !a || !a->a0 || !a->a1) { + BNerr(BN_F_BN_GFP2_COPY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!BN_copy(r->a0, a->a0)) { + BNerr(BN_F_BN_GFP2_COPY, ERR_R_BN_LIB); + return 0; + } + if (!BN_copy(r->a1, a->a1)) { + BNerr(BN_F_BN_GFP2_COPY, ERR_R_BN_LIB); + return 0; + } + + return 1; +} + +int BN_GFP2_zero(BN_GFP2 *a) +{ + if (!a || !a->a0 || !a->a1) { + BNerr(BN_F_BN_GFP2_ZERO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + BN_zero(a->a0); + BN_zero(a->a1); + return 1; +} + +int BN_GFP2_one(BN_GFP2 *a) +{ + if (!a || !a->a0 || !a->a1) { + BNerr(BN_F_BN_GFP2_ONE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + BN_one(a->a0); + BN_zero(a->a1); + return 1; +} + +/* return 1 on success, so dont use !BN_GFP2_is_zero() to check return value */ +int BN_GFP2_is_zero(const BN_GFP2 *a) +{ + if (!a || !a->a0 || !a->a1) { + BNerr(BN_F_BN_GFP2_IS_ZERO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + return (BN_is_zero(a->a0) && BN_is_zero(a->a1)); +} + +/* + * can we compare values on F_p^2 ? + */ +int BN_GFP2_cmp(const BN_GFP2 *a, const BN_GFP2 *b) +{ + if (!a || !b || !a->a0 || !a->a1 || !b->a0 || !b->a1) { + BNerr(BN_F_BN_GFP2_CMP, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + return ((BN_cmp(a->a0, b->a0) == 0) && (BN_cmp(a->a1, b->a1) == 0)); +} + +int BN_GFP2_add(BN_GFP2 *r, const BN_GFP2 *a, const BN_GFP2 *b, + const BIGNUM *p, BN_CTX *ctx) +{ + if (!a || !b || !a->a0 || !a->a1 || !b->a0 || !b->a1 || !p || !ctx) { + BNerr(BN_F_BN_GFP2_ADD, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!BN_mod_add(r->a0, a->a0, b->a0, p, ctx)) { + BNerr(BN_F_BN_GFP2_ADD, ERR_R_BN_LIB); + return 0; + } + if (!BN_mod_add(r->a1, a->a1, b->a1, p, ctx)) { + BNerr(BN_F_BN_GFP2_ADD, ERR_R_BN_LIB); + return 0; + } + + return 1; +} + +int BN_GFP2_sub(BN_GFP2 *r, const BN_GFP2 *a, const BN_GFP2 *b, + const BIGNUM *p, BN_CTX *ctx) +{ + if (!a || !b || !a->a0 || !a->a1 || !b->a0 || !b->a1 || !p || !ctx) { + BNerr(BN_F_BN_GFP2_SUB, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!BN_mod_sub(r->a0, a->a0, b->a0, p, ctx)) { + BNerr(BN_F_BN_GFP2_SUB, ERR_R_BN_LIB); + return 0; + } + if (!BN_mod_sub(r->a1, a->a1, b->a1, p, ctx)) { + BNerr(BN_F_BN_GFP2_SUB, ERR_R_BN_LIB); + return 0; + } + + return 1; +} + +/* + * (a0 + a1 * i) * (b0 + b1 * i) + * = a0 * b0 + a1 * b1 * i^2 + (a0 * b1 + a1 * b0) * i + * = (a0 * b0 - a1 * b1) + (a0 * b1 + a1 * b0) * i + */ +int BN_GFP2_mul(BN_GFP2 *r, const BN_GFP2 *a, const BN_GFP2 *b, + const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *t = NULL; + + BN_CTX_start(ctx); + + if (!(t = BN_CTX_get(ctx))) { + BNerr(BN_F_BN_GFP2_MUL, ERR_R_BN_LIB); + goto end; + } + + /* r->a0 = a->a0 * b->a0 - a->a1 * b->a1 (mod p) */ + if (!BN_mod_mul(r->a0, a->a0, b->a0, p, ctx)) { + BNerr(BN_F_BN_GFP2_MUL, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_mul(t, a->a1, b->a1, p, ctx)) { + BNerr(BN_F_BN_GFP2_MUL, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_sub(r->a0, r->a0, t, p, ctx)) { + BNerr(BN_F_BN_GFP2_MUL, ERR_R_BN_LIB); + goto end; + } + + /* r->a1 = a->a0 * b->a1 + a->a1 * b->a0 (mod p) */ + if (!BN_mod_mul(r->a1, a->a0, b->a1, p, ctx)) { + BNerr(BN_F_BN_GFP2_MUL, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_mul(t, a->a1, b->a0, p, ctx)) { + BNerr(BN_F_BN_GFP2_MUL, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_add(r->a1, r->a1, t, p, ctx)) { + BNerr(BN_F_BN_GFP2_MUL, ERR_R_BN_LIB); + goto end; + } + + ret = 1; +end: + BN_CTX_end(ctx); + return ret; +} + +int BN_GFP2_sqr(BN_GFP2 *r, const BN_GFP2 *a, + const BIGNUM *p, BN_CTX *ctx) +{ + return BN_GFP2_mul(r, a, a, p, ctx); +} + +/* + * (a0 + a1 * i) * (a0 - a1 * i) + * = a0^2 - a1^2 * i^2 + * = a0^2 + a1^2 + * ==> (a0 + a1 * i) * (a0 - a1 * i) * (a0^2 + a1^2)^-1 == 1 + * ==> (a0 + a1 * i)^-1 == (a0 - a1 * i) * (a0^2 + a1^2)^-1 + */ +int BN_GFP2_inv(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *t = NULL; + + BN_CTX_start(ctx); + + if (!(t = BN_CTX_get(ctx))) { + BNerr(BN_F_BN_GFP2_INV, ERR_R_BN_LIB); + goto end; + } + + /* t = (a0^2 + a1^2)^-1 */ + if (!BN_mod_sqr(r->a0, a->a0, p, ctx)) { + BNerr(BN_F_BN_GFP2_INV, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_sqr(r->a1, a->a1, p, ctx)) { + BNerr(BN_F_BN_GFP2_INV, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_mul(t, r->a0, r->a1, p, ctx)) { + BNerr(BN_F_BN_GFP2_INV, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_inverse(t, t, p, ctx)) { + BNerr(BN_F_BN_GFP2_INV, ERR_R_BN_LIB); + goto end; + } + + /* r0 = a0^ t (mod p) */ + if (!BN_mod_mul(r->a0, a->a0, t, p, ctx)) { + BNerr(BN_F_BN_GFP2_INV, ERR_R_BN_LIB); + goto end; + } + + /* r1 = p - a1^t (mod p) */ + if (!BN_mod_mul(r->a1, a->a1, t, p, ctx)) { + BNerr(BN_F_BN_GFP2_INV, ERR_R_BN_LIB); + goto end; + } + if (!BN_sub(r->a1, p, r->a1)) { + BNerr(BN_F_BN_GFP2_INV, ERR_R_BN_LIB); + goto end; + } + + ret = 1; +end: + BN_CTX_end(ctx); + return ret; +} + +int BN_GFP2_div(BN_GFP2 *r, const BN_GFP2 *a, const BN_GFP2 *b, const BIGNUM *p, BN_CTX *ctx) +{ + if (!BN_GFP2_inv(r, b, p, ctx)) { + return 0; + } + if (!BN_GFP2_mul(r, a, r, p, ctx)) { + return 0; + } + return 1; +} + +/* need a fast implementation. check if k is solinas */ +int BN_GFP2_exp(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *k, const BIGNUM *p, + BN_CTX *ctx) +{ + + return 0; +} + +int BN_GFP2_set_bn(BN_GFP2 *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + if (!r || !a || !p) { + BNerr(BN_F_BN_GFP2_SET_BN, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!BN_copy(r->a0, a)) { + BNerr(BN_F_BN_GFP2_SET_BN, ERR_R_BN_LIB); + return 0; + } + if (!BN_zero(r->a1)) { + BNerr(BN_F_BN_GFP2_SET_BN, ERR_R_BN_LIB); + return 0; + } + return 1; +} + +int BN_GFP2_add_bn(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx) +{ + return BN_mod_add(r->a0, a->a0, b, p, ctx); +} + +int BN_GFP2_sub_bn(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx) +{ + return BN_mod_sub(r->a0, a->a0, b, p, ctx); +} + +int BN_GFP2_mul_bn(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx) +{ + return BN_mod_mul(r->a0, a->a0, b, p, ctx); +} + +int BN_GFP2_div_bn(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *binv; + + if (!(binv = BN_CTX_get(ctx))) { + BNerr(BN_F_BN_GFP2_DIV_BN, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!BN_mod_inverse(binv, b, p, ctx)) { + BNerr(BN_F_BN_GFP2_DIV_BN, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_mul(r->a0, a->a0, binv, p, ctx)) { + BNerr(BN_F_BN_GFP2_DIV_BN, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_mul(r->a1, a->a1, binv, p, ctx)) { + BNerr(BN_F_BN_GFP2_DIV_BN, ERR_R_BN_LIB); + goto end; + } + + ret = 1; +end: + BN_CTX_end(ctx); + return ret; +} + +int BN_GFP2_canonical(const BN_GFP2 *a, unsigned char *out, size_t *outlen, + int order, const BIGNUM *p, BN_CTX *ctx) +{ + size_t len; + + if (!a || !a->a0 || !a->a1 || !outlen || !p) { + BNerr(BN_F_BN_GFP2_CANONICAL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + len = BN_num_bytes(p) * 2; + if (!out) { + *outlen = len; + return 1; + } + if (*outlen < len) { + BNerr(BN_F_BN_GFP2_CANONICAL, BN_R_BUFFER_TOO_SMALL); + return 0; + } + + memset(out, 0, len); + if (order == 0) { + /* low order first output (a0, a1) */ + if (!BN_bn2bin(a->a0, out + len/2 - BN_num_bytes(a->a0))) { + BNerr(BN_F_BN_GFP2_CANONICAL, ERR_R_BN_LIB); + return 0; + } + if (!BN_bn2bin(a->a1, out + len - BN_num_bytes(a->a1))) { + BNerr(BN_F_BN_GFP2_CANONICAL, ERR_R_BN_LIB); + return 0; + } + } else { + /* high order first output (a1, a0) */ + if (!BN_bn2bin(a->a1, out + len/2 - BN_num_bytes(a->a1))) { + BNerr(BN_F_BN_GFP2_CANONICAL, ERR_R_BN_LIB); + return 0; + } + if (!BN_bn2bin(a->a0, out + len - BN_num_bytes(a->a0))) { + BNerr(BN_F_BN_GFP2_CANONICAL, ERR_R_BN_LIB); + return 0; + } + } + + *outlen = len; + return 1; +} + +int BN_bn2gfp2(const BIGNUM *bn, BN_GFP2 *gfp2, const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *a; + + if (!(a = BN_CTX_get(ctx))) { + goto end; + } + + BN_one(a); + if (!BN_lshift(a, a, BN_num_bytes(p)*8)) { + goto end; + } + + if (!BN_rshift(gfp2->a1, bn, BN_num_bytes(p)*8)) { + goto end; + } + if (!BN_mod(gfp2->a0, bn, a, ctx)) { + goto end; + } + + ret = 1; +end: + BN_CTX_end(ctx); + return ret; +} + +/* return (a0 + a1 << 2^n), n = log_2(p), n % 8 == 0 */ +int BN_gfp22bn(const BN_GFP2 *gfp2, BIGNUM *bn, const BIGNUM *p, BN_CTX *ctx) +{ + if (!BN_lshift(bn, gfp2->a1, BN_num_bytes(p) * 8)) { + return 0; + } + if (!BN_add(bn, bn, gfp2->a0)) { + return 0; + } + return 1; +} + diff --git a/crypto/ec2/bn_hash.c b/crypto/ec2/bn_hash.c new file mode 100644 index 00000000..88cf53e2 --- /dev/null +++ b/crypto/ec2/bn_hash.c @@ -0,0 +1,167 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include "../bn/bn_lcl.h" + +int BN_hash_to_range(const EVP_MD *md, BIGNUM **bn, + const void *s, size_t slen, const BIGNUM *range, BN_CTX *bn_ctx) +{ + int ret = 0; + BIGNUM *r = NULL; + BIGNUM *a = NULL; + unsigned char *buf = NULL; + size_t buflen, mdlen; + int nbytes, rounds, i; + + if (!s || slen <= 0 || !md || !range) { + BNerr(BN_F_BN_HASH_TO_RANGE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!(*bn)) { + if (!(r = BN_new())) { + BNerr(BN_F_BN_HASH_TO_RANGE, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + r = *bn; + BN_zero(r); + } + + mdlen = EVP_MD_size(md); + buflen = mdlen + slen; + if (!(buf = OPENSSL_malloc(buflen))) { + BNerr(BN_F_BN_HASH_TO_RANGE, ERR_R_MALLOC_FAILURE); + goto end; + } + memset(buf, 0, mdlen); + memcpy(buf + mdlen, s, slen); + + a = BN_new(); + if (!a) { + BNerr(BN_F_BN_HASH_TO_RANGE, ERR_R_MALLOC_FAILURE); + goto end; + } + + nbytes = BN_num_bytes(range); + rounds = (nbytes + mdlen - 1)/mdlen; + + if (!bn_expand(r, rounds * mdlen * 8)) { + BNerr(BN_F_BN_HASH_TO_RANGE, ERR_R_BN_LIB); + goto end; + } + + for (i = 0; i < rounds; i++) { + if (!EVP_Digest(buf, buflen, buf, (unsigned int *)&mdlen, md, NULL)) { + BNerr(BN_F_BN_HASH_TO_RANGE, ERR_R_EVP_LIB); + goto end; + } + if (!BN_bin2bn(buf, mdlen, a)) { + BNerr(BN_F_BN_HASH_TO_RANGE, ERR_R_BN_LIB); + goto end; + } + if (!BN_lshift(r, r, mdlen * 8)) { + BNerr(BN_F_BN_HASH_TO_RANGE, ERR_R_BN_LIB); + goto end; + } + if (!BN_uadd(r, r, a)) { + goto end; + } + } + + if (!BN_mod(r, r, range, bn_ctx)) { + BNerr(BN_F_BN_HASH_TO_RANGE, ERR_R_BN_LIB); + goto end; + } + + *bn = r; + ret = 1; +end: + if (!ret && !(*bn)) { + BN_free(r); + } + BN_free(a); + OPENSSL_free(buf); + return ret; +} + +#if 0 +int main(void) +{ + char *s = "This ASCII string without null-terminator"; + BIGNUM *bn = NULL; + BIGNUM *ret = NULL; + BIGNUM *range = NULL; + + BN_hex2bn(&range, "ffffffffffffffffffffefffffffffffffffffff"); + BN_hex2bn(&bn, "79317c1610c1fc018e9c53d89d59c108cd518608"); + + if (!BN_hash2bn(&ret, s, strlen(s), EVP_sha1(), range)) { + printf("BN_hash2bn() function failed\n"); + return 0; + } + if (!ret) { + printf("shit\n"); + } + printf("%s\n", BN_bn2hex(ret)); + if (BN_cmp(ret, bn) != 0) { + printf("BN_hash2bn() test failed\n"); + return 0; + } + + printf("BN_hash2bn() test passed\n"); + return 1; +} +#endif + diff --git a/crypto/ec2/bn_solinas.c b/crypto/ec2/bn_solinas.c new file mode 100644 index 00000000..8322e07b --- /dev/null +++ b/crypto/ec2/bn_solinas.c @@ -0,0 +1,193 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include "../bn/bn_lcl.h" + +/* + * generate the solinas prime tables, + * use it for fast check of solinas + */ + +static BN_SOLINAS BN_solinas_table[] = { + { 192, 16, -1, -1 }, + { 192, 64, -1, -1 }, + { 224, 96, -1, 1 }, + { 256, 168, -1, 1 }, + { 384, 80, -1, 1 }, + { 512, 32, -1, 1 }, + { 512, 32, -1, -1 }, + { 1024, 424, -1, -1 }, + { 1024, 856, -1, 1 }, +}; + +/* + * solinas = 2^a + s * 2^b + c, where s, c in {1, -1} + * solinas looks like: + * 2^a + 2^b + 1 = 10000100001 + * 2^a - 2^b + 1 = 1111100001 + * 2^a + 2^b - 1 = 10000011111 + * 2^a - 2^b - 1 = 1111011111 + * so: + * n = len(bits(solinas)) + * c = bits(solinas)[1] == 0 ? 1 : -1 + * s = bits(solinas)[n-2] == 0 ? 1 : -1 + * a = bits(solinas)[n-2] == 0 ? n-1 : n-2 + * b = len(bits(solinas - 2^a - s*2^b - c)) - 1 + * + * examples: + * 0xfffffffffffffffffffffffffffbffff + * 0xffffffffffffffffffffffeffffffffffff + * 0xfffffffffbfffffffffffffffffffffffff + */ + + +int BN_bn2solinas(const BIGNUM *bn, BN_SOLINAS *solinas) +{ + int ret = 0; + BIGNUM *tmp = NULL; + int nbits; + int i; + + if (!solinas || !bn) { + BNerr(BN_F_BN_BN2SOLINAS, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!BN_copy(tmp, bn)) { + goto end; + } + + if ((nbits = BN_num_bits(bn) - 1) < 1) { + BNerr(BN_F_BN_BN2SOLINAS, BN_R_INVALID_SOLINAS); + goto end; + } + + solinas->c = BN_is_bit_set(bn, 1) ? 1 : -1; + if (BN_is_bit_set(bn, nbits - 1)) { + solinas->s = -1; + solinas->a = nbits; + } else { + solinas->s = 1; + solinas->a = nbits - 1; + } + + for (i = 1; i < nbits; i++) { + } + +end: + return 0; +} + +int BN_solinas2bn(const BN_SOLINAS *solinas, BIGNUM *bn) +{ + int ret = 0; + BIGNUM *tmp = NULL; +#if 0 + if (b <= 0 || a <= b || (s != 1 && s != -1) || + (c != 1 && c != -1)) { + BNerr(BN_F_BN_SOLINAS2BN, BN_R_INVALID_SOLINAS_PARAMETERS); + return 0; + } + + if (!(tmp = BN_new())) { + BNerr(BN_F_BN_SOLINAS2BN, ERR_R_MALLOC_FAILURE); + goto end; + } + + BN_one(tmp); + + if (!BN_lshift(solinas, tmp, a)) { + BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); + goto end; + } + if (!BN_lshift(tmp, tmp, b)) { + BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); + goto end; + } + if (!BN_add_word(tmp, c)) { + BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); + goto end; + } + if (s > 0) { + if (!BN_add(solinas, solinas, tmp)) { + BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); + goto end; + } + } else { + if (!BN_sub(solinas, solinas, tmp)) { + BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); + goto end; + } + } + + /* check if solinas is a prime */ + + ret = 1; +end: + BN_free(tmp); +#endif + return ret; +} + +int BN_generate_solinas(BIGNUM *ret, BN_SOLINAS *solinas, BN_GENCB *cb) +{ + return 0; +} + +int BN_is_solinas(const BIGNUM *a) +{ + return 0; +} + diff --git a/crypto/ec2/build.info b/crypto/ec2/build.info new file mode 100644 index 00000000..e6b4dcd2 --- /dev/null +++ b/crypto/ec2/build.info @@ -0,0 +1,3 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=bn_gfp2.c bn_solinas.c bn_hash.c \ + fppoint.c ec_expoint.c ec_hash.c ec_type1.c diff --git a/crypto/ec2/ec_expoint.c b/crypto/ec2/ec_expoint.c new file mode 100644 index 00000000..9cf6e17a --- /dev/null +++ b/crypto/ec2/ec_expoint.c @@ -0,0 +1,90 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* + * this file is to implement elliptic curve operations over extension + * fields + */ + +#include +#include +#include +#include +#include +#include +#include + + +typedef struct { + int security_bits; + int n_bits; + int p_bits; + int q_bits; +} PAIRING_SEC; + +static PAIRING_SEC sec_tbl[] = { + /* k |n| |p| |q| */ + { 80, 1024, 512, 160}, + {112, 2048, 1024, 224}, + {128, 3072, 1536, 256}, + {192, 7680, 3840, 384}, + {256, 15360, 7680, 512} +}; + +const EVP_MD *PAIRING_nbits_to_md(int nbits) +{ + switch (nbits) { + case 1024: return EVP_sha1(); + case 2048: return EVP_sha224(); + case 3072: return EVP_sha256(); + case 7680: return EVP_sha384(); + case 15360: return EVP_sha512(); + } + return NULL; +} + diff --git a/crypto/ec2/ec_hash.c b/crypto/ec2/ec_hash.c new file mode 100644 index 00000000..3d8af96b --- /dev/null +++ b/crypto/ec2/ec_hash.c @@ -0,0 +1,181 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include + +/* currently the EC_POINT_hash2point only support type1curve! */ +int EC_POINT_hash2point(const EC_GROUP *group, const EVP_MD *md, + const char *s, size_t slen, EC_POINT *point, BN_CTX *bn_ctx) +{ + int ret = 0; + BIGNUM *p = NULL; + BIGNUM *x = NULL; + BIGNUM *y = NULL; + BIGNUM *k = NULL; + BIGNUM *q = NULL; + + if (!group || !md || !point || !s || slen <= 0 || !bn_ctx) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != NID_X9_62_prime_field) { + ECerr(EC_F_EC_POINT_HASH2POINT, EC_R_INVALID_CURVE); + return 0; + } + + p = BN_new(); + x = BN_new(); + y = BN_new(); + k = BN_new(); + q = BN_new(); + + if (!p || !x || !y || !k || !q) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_MALLOC_FAILURE); + goto end; + } + + if (!EC_GROUP_get_curve_GFp(group, p, x, y, bn_ctx)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_EC_LIB); + goto end; + } + + /* check group is type-1 curve */ + if (!BN_is_zero(x) || !BN_is_one(y) || BN_mod_word(p, 12) != 11) { + ECerr(EC_F_EC_POINT_HASH2POINT, EC_R_INVALID_CURVE); + goto end; + } + + /* get order */ + if (!EC_GROUP_get_order(group, q, bn_ctx)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_EC_LIB); + goto end; + } + + /* y = HashToRange(s) in [0, p - 1] */ + if (!BN_hash_to_range(md, &y, s, slen, p, bn_ctx)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + + /* x = (y + 1) * (y - 1) mod p */ + if (!BN_copy(x, y)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + if (!BN_copy(k, y)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + if (!BN_add_word(x, 1)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + if (!BN_sub_word(k, 1)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_mul(x, x, k, p, bn_ctx)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + + /* k = (p^2 - 1)/3 */ + if (!BN_lshift1(k, p)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + if (!BN_sub_word(k, 1)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + if (!BN_div_word(k, 3)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + + /* compute x and point = (x, y) */ + if (!BN_mod_exp(x, x, k, p, bn_ctx)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, bn_ctx)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_EC_LIB); + goto end; + } + + /* compute [(p + 1)/q] * point */ + if (!BN_add_word(p, 1)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + if (!BN_div(k, NULL, p, q, bn_ctx)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_BN_LIB); + goto end; + } + if (!EC_POINT_mul(group, point, NULL, point, k, bn_ctx)) { + ECerr(EC_F_EC_POINT_HASH2POINT, ERR_R_EC_LIB); + goto end; + } + + ret = 1; +end: + BN_free(p); + BN_free(x); + BN_free(y); + BN_free(k); + BN_free(q); + return ret; +} + diff --git a/crypto/ec2/ec_type1.c b/crypto/ec2/ec_type1.c new file mode 100644 index 00000000..4c694dfc --- /dev/null +++ b/crypto/ec2/ec_type1.c @@ -0,0 +1,783 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include +#include + +EC_GROUP *EC_GROUP_generate_type1curve(const BIGNUM *order, BN_CTX *bn_ctx) +{ + ECerr(EC_F_EC_GROUP_GENERATE_TYPE1CURVE, 0); + return 0; +} + +EC_GROUP *EC_GROUP_new_type1curve_ex(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, const unsigned char *point, size_t pointlen, + const BIGNUM *order, const BIGNUM *cofactor, BN_CTX *bn_ctx) +{ + return NULL; +} + +EC_GROUP *EC_GROUP_new_type1curve(const BIGNUM *p, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *order, BN_CTX *bn_ctx) +{ + int e = 1; + EC_GROUP *ret = NULL; + BIGNUM *a = NULL; + BIGNUM *b = NULL; + EC_POINT *point = NULL; + + if (!p || !x || !y || !order) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + /* check p = 11 (mod 12) */ + if (BN_mod_word(p, 12) != 11) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, EC_R_INVALID_TYPE1CURVE); + return NULL; + } + + BN_CTX_start(bn_ctx); + a = BN_CTX_get(bn_ctx); + b = BN_CTX_get(bn_ctx); + + if (!a || !b) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, ERR_R_MALLOC_FAILURE); + goto end; + } + + BN_zero(a); + BN_one(b); + + if (!(ret = EC_GROUP_new_curve_GFp(p, a, b, bn_ctx))) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, EC_R_INVALID_TYPE1CURVE); + goto end; + } + + /* prepare generator point from (x, y) */ + if (!(point = EC_POINT_new(ret))) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!EC_POINT_set_affine_coordinates_GFp(ret, point, x, y, bn_ctx)) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, EC_R_INVALID_TYPE1CURVE); + goto end; + } + + /* + * calculate cofactor h = (p + 1)/n + * check n|(p + 1) where n is the order + */ + if (!BN_copy(a, p)) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, ERR_R_BN_LIB); + goto end; + } + if (!BN_add_word(a, 1)) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, ERR_R_BN_LIB); + goto end; + } + /* check (p + 1)%n == 0 */ + if (!BN_div(a, b, a, order, bn_ctx)) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, ERR_R_BN_LIB); + goto end; + } + if (!BN_is_zero(b)) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, EC_R_INVLID_TYPE1CURVE); + goto end; + } + + /* set order and cofactor */ + if (!EC_GROUP_set_generator(ret, point, order, a)) { + ECerr(EC_F_EC_GROUP_NEW_TYPE1CURVE, EC_R_INVALID_TYPE1CURVE); + goto end; + } + + e = 0; + +end: + if (e && ret) { + EC_GROUP_free(ret); + ret = NULL; + } + BN_CTX_end(bn_ctx); + EC_POINT_free(point); + return ret; +} + +int EC_GROUP_is_type1curve(const EC_GROUP *group, BN_CTX *bn_ctx) +{ + ECerr(EC_F_EC_GROUP_IS_TYPE1CURVE, 0); + return 0; +} + +/* + * zeta = F_p((p-1)/2) + ((F_p(3)^((p + 1)/4))/2) * i, in F_p^2 + * which is used in phi() mapping in tate pairing over type1 curve + */ +BN_GFP2 *EC_GROUP_get_type1curve_zeta(const EC_GROUP *group, BN_CTX *bn_ctx) +{ + int e = 1; + BN_GFP2 *ret = NULL; + BIGNUM *a = NULL; + BIGNUM *b = NULL; + BIGNUM *p = NULL; + + if (!group || !bn_ctx) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + BN_CTX_start(bn_ctx); + + ret = BN_GFP2_new(); + a = BN_CTX_get(bn_ctx); + b = BN_CTX_get(bn_ctx); + p = BN_CTX_get(bn_ctx); + + if (!ret || !a || !b || !p) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_MALLOC_FAILURE); + goto end; + } + + /* get curve p, a, b and check it is type1 curve + * p is prime at least 512 bits, a == 0 and b == 1 + */ + if (!EC_GROUP_get_curve_GFp(group, a, b, p, bn_ctx)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_EC_LIB); + goto end; + } + if (!BN_is_zero(a) || !BN_is_one(b)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, EC_R_INVALID_TYPE1_CURVE); + goto end; + } + if (BN_num_bits(p) < 512) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, EC_R_INVALID_TYPE1_CURVE); + goto end; + } + + /* + * set ret->a0 = (p - 1)/2 + */ + if (!BN_copy(ret->a0, p)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!BN_sub_word(ret->a0, 1)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_EC_LIB); + goto end; + } + /* BN_div_word() return remainder, while (p - 1)%2 == 0 */ + if (BN_div_word(ret->a0, 2)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, EC_R_INVALID_TYPE1_CURVE); + goto end; + } + + /* + * ret->a1 = (p + 1)/4, (ret->a1 + 1)%4 == 0 + */ + if (!BN_copy(ret->a1, p)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_BN_LIB); + goto end; + } + if (!BN_add_word(ret->a1, 1)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_BN_LIB); + goto end; + } + if (BN_div_word(ret->a1, 4)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, EC_R_INVALID_TYPE1_CURVE); + goto end; + } + + /* + * re-use a as 3 + * ret->a1 = 3^(ret->a1) mod p = 3^((p + 1)/4) mod p + */ + if (!BN_set_word(a, 3)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_exp(ret->a1, a, ret->a1, p, bn_ctx)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_BN_LIB); + goto end; + } + + /* + * re-use b as 1/2 mod p + * ret->a1 = ret->a1 / 2 mod p = (3^((p + 1)/4)) mod p + */ + if (!BN_set_word(b, 2)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_inverse(b, b, p, bn_ctx)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_mul(ret->a1, ret->a1, b, p, bn_ctx)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA, ERR_R_BN_LIB); + goto end; + } + + e = 0; +end: + if (e && ret) { + BN_GFP2_free(ret); + ret = NULL; + } + BN_CTX_end(bn_ctx); + return ret; +} + +/* + * eta = (p^2 - 1)/n + * which is used in the final modular exponentiation of tate pairing over + * type1 curve + */ +BIGNUM *EC_GROUP_get_type1curve_eta(const EC_GROUP *group, BN_CTX *bn_ctx) +{ + int e = 1; + BIGNUM *ret = NULL; + BIGNUM *a = NULL; + BIGNUM *b = NULL; + BIGNUM *p = NULL; + + if (!group || !bn_ctx) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + BN_CTX_start(bn_ctx); + + ret = BN_new(); + a = BN_CTX_get(bn_ctx); + b = BN_CTX_get(bn_ctx); + p = BN_CTX_get(bn_ctx); + + if (!ret || !a || !b || !p) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA, ERR_R_MALLOC_FAILURE); + goto end; + } + + /* get curve p, a, b and check it is type1 curve + * p is prime at least 512 bits, a == 0 and b == 1 + */ + if (!EC_GROUP_get_curve_GFp(group, a, b, p, bn_ctx)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA, ERR_R_EC_LIB); + goto end; + } + if (!BN_is_zero(a) || !BN_is_one(b)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA, EC_R_INVALID_TYPE1_CURVE); + goto end; + } + if (BN_num_bits(p) < 512) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA, EC_R_INVALID_TYPE1_CURVE); + goto end; + } + + /* get curve order n, re-use a for order n */ + if (!EC_GROUP_get_order(group, a, bn_ctx)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA, ERR_R_EC_LIB); + goto end; + } + + /* + * eta = (p^2 - 1)/n, + */ + if (!BN_sqr(ret, p, bn_ctx)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA, ERR_R_BN_LIB); + goto end; + } + if (!BN_sub_word(ret, 1)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA, ERR_R_BN_LIB); + goto end; + } + if (!BN_div(ret, NULL, ret, a, bn_ctx)) { + ECerr(EC_F_EC_GROUP_GET_TYPE1CURVE_ETA, ERR_R_BN_LIB); + goto end; + } + + e = 1; +end: + if (e && ret) { + BN_free(ret); + ret = NULL; + } + BN_CTX_end(bn_ctx); + return ret; +} + +/* phi: (x, y) => (zeta * x, y) */ +static int type1curve_phi(const EC_GROUP *group, const EC_POINT *point, + BN_GFP2 *x, BN_GFP2 *y, const BIGNUM *p, BN_CTX *bn_ctx) +{ + int ret = 0; + BN_GFP2 *zeta = NULL; + BIGNUM *xP; + BIGNUM *yP; + + if (!group || !point || !x || !y || !p || !bn_ctx) { + ECerr(EC_F_TYPE1CURVE_PHI, +ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + BN_CTX_start(bn_ctx); + xP = BN_CTX_get(bn_ctx); + yP = BN_CTX_get(bn_ctx); + + if (!xP || !yP) { + ECerr(EC_F_TYPE1CURVE_PHI, ERR_R_MALLOC_FAILURE); + goto end; + } + + if (!(zeta = EC_GROUP_get_type1curve_zeta(group, bn_ctx))) { + ECerr(EC_F_TYPE1CURVE_PHI, +EC_R_GET_TYPE1CURVE_ZETA_FAILURE); + goto end; + } + + if (!EC_POINT_get_affine_coordinates_GFp(group, point, xP, yP, bn_ctx)) +{ + ECerr(EC_F_TYPE1CURVE_PHI, ERR_R_EC_LIB); + goto end; + } + + /* return x = zeta * point->x */ + if (!BN_GFP2_mul_bn(x, zeta, xP, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_PHI, ERR_R_BN_LIB); + goto end; + } + + /* return y = point->y */ + if (!BN_GFP2_set_bn(y, yP, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_PHI, ERR_R_BN_LIB); + goto end; + } + + ret = 1; + +end: + BN_CTX_end(bn_ctx); + BN_GFP2_free(zeta); + return ret; +} + +/* + * eval the function defined by the line through point T and P, + * with value Q = (xQ, yQ) + */ +static int type1curve_eval_line_textbook(const EC_GROUP *group, BN_GFP2 *r, + const EC_POINT *T, const EC_POINT *P, const BN_GFP2 *xQ, const BN_GFP2 +*yQ, + BN_CTX *bn_ctx) +{ + int ret = 0; + BN_GFP2 *num = NULL; + BN_GFP2 *den = NULL; + BIGNUM *p; + BIGNUM *xT; + BIGNUM *yT; + BIGNUM *xP; + BIGNUM *yP; + BIGNUM *bn; + BIGNUM *slope; + + if (!group || !r || !T || !P || !xQ || !yQ || !bn_ctx) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + BN_CTX_start(bn_ctx); + p = BN_CTX_get(bn_ctx); + xT = BN_CTX_get(bn_ctx); + yT = BN_CTX_get(bn_ctx); + xP = BN_CTX_get(bn_ctx); + yP = BN_CTX_get(bn_ctx); + bn = BN_CTX_get(bn_ctx); + slope = BN_CTX_get(bn_ctx); + + num = BN_GFP2_new(); + den = BN_GFP2_new(); + + if (!p || !xT || !yT || !xP || !yP || !bn || !slope || !num || !den) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, + ERR_R_MALLOC_FAILURE); + goto end; + } + + /* get prime field p */ + if (!EC_GROUP_get_curve_GFp(group, p, xT, yT, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_EC_LIB); + goto end; + } + + /* get T and P */ + if (!EC_POINT_get_affine_coordinates_GFp(group, T, xT, yT, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_EC_LIB); + goto end; + } + if (!EC_POINT_get_affine_coordinates_GFp(group, P, xP, yP, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_EC_LIB); + goto end; + } + +#if 0 + /* if T == P, slope = (3 * x_T^2 + a)/(2 * y_T) */ + if (T == P || (BN_cmp(xT, xP) == 0 && BN_cmp(yT, yP) == 0)) { + + if (!BN_mod_sqr(bn, xT, p, bn_ctx)) { + goto end; + } + if (!BN_mod_add(slope, bn, bn, p, bn_ctx)) { + goto end; + } + if (!BN_mod_add(slope, slope, bn, p, bn_ctx)) { + goto end; + } + if (!BN_mod_add(den, yT, yT, p, bn_ctx)) { + goto end; + } + if (!BN_mod_inverse(den, den, p, bn_ctx)) { + goto end; + } + if (!BN_mod_mul(slope, slope, den, p, bn_ctx)) { + goto end; + } + } + + /* + * if xT == xP and yT + yP == 0, return xQ - xT + */ + + if (BN_cmp(xT, xP) == 0) { + BIGNUM *t; + if (!(t = BN_CTX_get(bn_ctx))) { + goto end; + } + if (!BN_mod_add(t, yT, yP, p, ctx)) { + goto end; + } + if (BN_is_zero(t)) { + if (!BN_GFP2_sub_bn(r, xQ, xT, p, bn_ctx)) { + goto end; + } + } + } + + /* + * if T == P, slope = (3 * x_T^2 + a)/(2 * y_T) + * else slope = (y_T - y_P)/(x_T - x_P) + */ + if (!BN_mod_sub(num, yT, yP, p, bn_ctx)) { + goto end; + } + if (!BN_mod_sub(den, xT, xP, p, bn_ctx)) { + goto end; + } + if (!BN_mod_inverse(den, den, p, bn_ctx)) { + goto end; + } + if (!BN_mod_mul(slope, num, den, p, bn_ctx)) { + goto end; + } +#endif + + /* + * num = (yQ - ((xQ - xT) * slope)) - yT + * den = xQ + (xT + (xP - slope^2)) + * return num/den + */ + + if (!BN_GFP2_sub_bn(num, xQ, xT, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_BN_LIB); + goto end; + } + if (!BN_GFP2_mul_bn(num, num, slope, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_BN_LIB); + goto end; + } + if (!BN_GFP2_sub(num, yQ, num, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_BN_LIB); + goto end; + } + if (!BN_GFP2_sub_bn(num, num, yT, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_BN_LIB); + goto end; + } + + if (!BN_mod_sqr(bn, slope, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_sub(bn, xP, bn, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_BN_LIB); + goto end; + } + if (!BN_mod_add(bn, xT, bn, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_BN_LIB); + goto end; + } + if (!BN_GFP2_add_bn(den, xQ, bn, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_BN_LIB); + goto end; + } + + + if (!BN_GFP2_div(ret, num, den, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK, +ERR_R_BN_LIB); + goto end; + } + + ret = 1; + +end: + BN_CTX_end(bn_ctx); + BN_GFP2_free(num); + BN_GFP2_free(den); + return ret; +} + +static int type1curve_eval_miller_textbook(const EC_GROUP *group, BN_GFP2 *r, + const EC_POINT *P, const BN_GFP2 *xQ, const BN_GFP2 *yQ, + const BIGNUM *p, BN_CTX *bn_ctx) +{ + int ret = 0; + BN_GFP2 *f = NULL; + BN_GFP2 *g = NULL; + EC_POINT *T = NULL; + BIGNUM *n; + int nbits; + int i; + + if (!group || !r || !P || !xQ || !yQ || !p || !bn_ctx) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + BN_CTX_start(bn_ctx); + n = BN_CTX_get(bn_ctx); + + f = BN_GFP2_new(); + g = BN_GFP2_new(); + T = EC_POINT_new(group); + + if (!n || !f || !g || !T) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_MALLOC_FAILURE); + goto end; + } + + if (!EC_GROUP_get_order(group, n, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_EC_LIB); + goto end; + } + + nbits = BN_num_bits(n); + + /* miller loop */ + for (i = nbits - 2; i >= 0; i--) { + + /* f = f^2 */ + if (!BN_GFP2_sqr(f, f, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_BN_LIB); + goto end; + } + + /* compute g_{T,T}(Q) */ + if (!type1curve_eval_line_textbook(group, g, T, T, xQ, yQ, + bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_EC_LIB); + goto end; + } + + /* f = f * g */ + if (!BN_GFP2_mul(f, f, g, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_BN_LIB); + goto end; + } + + /* T = 2T */ + if (!EC_POINT_dbl(group, T, T, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_EC_LIB); + goto end; + } + + if (BN_is_bit_set(n, i)) { + + /* g = g_{T,P}(Q) */ + if (!type1curve_eval_line_textbook(group, g, T, P, xQ, + yQ, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_EC_LIB); + goto end; + } + + /* f = f * g */ + if (!BN_GFP2_mul(f, f, g, p, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_BN_LIB); + goto end; + } + + /* T = T + P */ + if (!EC_POINT_add(group, T, T, P, bn_ctx)) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, + ERR_R_EC_LIB); + goto end; + } + } + } + + /* set return value */ + if (!BN_GFP2_copy(r, f)) { + ECerr(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK, ERR_R_BN_LIB); + goto end; + } + ret = 1; + +end: + BN_CTX_end(bn_ctx); + BN_GFP2_free(f); + BN_GFP2_free(g); + EC_POINT_free(T); + return ret; +} + +int EC_type1curve_tate(const EC_GROUP *group, BN_GFP2 *r, + const EC_POINT *P, const EC_POINT *Q, BN_CTX *bn_ctx) +{ + int ret = 0; + BN_GFP2 *xQ = NULL; + BN_GFP2 *yQ = NULL; + BIGNUM *eta = NULL; + BIGNUM *p; + BIGNUM *a; + BIGNUM *b; + + if (!group || !ret || !P || !Q || !bn_ctx) { + ECerr(EC_F_EC_TYPE1CURVE_TATE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + BN_CTX_start(bn_ctx); + + xQ = BN_GFP2_new(); + yQ = BN_GFP2_new(); + p = BN_CTX_get(bn_ctx); + a = BN_CTX_get(bn_ctx); + b = BN_CTX_get(bn_ctx); + + if (!xQ || !yQ || !p || !a || !b) { + ECerr(EC_F_EC_TYPE1CURVE_TATE, ERR_R_MALLOC_FAILURE); + goto end; + } + + if (!EC_GROUP_get_curve_GFp(group, p, a, b, bn_ctx)) { + ECerr(EC_F_EC_TYPE1CURVE_TATE, EC_R_INVALID_TYPE1CURVE); + goto end; + } + + /* (xQ, yQ) = phi(Q) */ + if (!type1curve_phi(group, Q, xQ, yQ, p, bn_ctx)) { + ECerr(EC_F_EC_TYPE1CURVE_TATE, ERR_R_EC_LIB); + goto end; + } + + /* compute e(P, phi(Q)) */ + if (!type1curve_eval_miller_textbook(group, r, P, xQ, yQ, p, bn_ctx)) { + ECerr(EC_F_EC_TYPE1CURVE_TATE, ERR_R_EC_LIB); + goto end; + } + + /* compute e(P, phi(Q))^eta, eta = (p^2 - 1)/q */ + if (!(eta = EC_GROUP_get_type1curve_eta(group, bn_ctx))) { + ECerr(EC_F_EC_TYPE1CURVE_TATE, EC_R_INVALID_TYPE1CURVE); + goto end; + } + + ret = 1; + +end: + BN_GFP2_free(xQ); + BN_GFP2_free(yQ); + BN_CTX_end(bn_ctx); + BN_free(eta); + return ret; +} + +int EC_type1curve_tate_ratio(const EC_GROUP *group, BN_GFP2 *r, + const EC_POINT *P1, const EC_POINT *Q1, + const EC_POINT *P2, const EC_POINT *Q2, + BN_CTX *bn_ctx) +{ + return 0; +} + diff --git a/crypto/ec2/fppoint.c b/crypto/ec2/fppoint.c new file mode 100644 index 00000000..86ef5898 --- /dev/null +++ b/crypto/ec2/fppoint.c @@ -0,0 +1,114 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* + * this file is to implement elliptic curve operations over extension + * fields + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ASN1_SEQUENCE(FpPoint) = { + ASN1_SIMPLE(FpPoint, x, BIGNUM), + ASN1_SIMPLE(FpPoint, y, BIGNUM) +} ASN1_SEQUENCE_END(FpPoint) +IMPLEMENT_ASN1_FUNCTIONS(FpPoint) +IMPLEMENT_ASN1_DUP_FUNCTION(FpPoint) + +int EC_POINT_cmp_fppoint(const EC_GROUP *group, const EC_POINT *a, const FpPoint *b, + BN_CTX *bn_ctx) +{ + int ret = -1; + BIGNUM *x = NULL; + BIGNUM *y = NULL; + + if (!group || !a || !b || !bn_ctx) { + ECerr(EC_F_EC_POINT_CMP_FPPOINT, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + BN_CTX_start(bn_ctx); + x = BN_CTX_get(bn_ctx); + y = BN_CTX_get(bn_ctx); + + if (!x || !y) { + ECerr(EC_F_EC_POINT_CMP_FPPOINT, ERR_R_BN_LIB); + goto end; + } + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp(group, a, x, y, bn_ctx)) { + ECerr(EC_F_EC_POINT_CMP_FPPOINT, ERR_R_EC_LIB); + goto end; + } + } else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x, y, bn_ctx)) { + ECerr(EC_F_EC_POINT_CMP_FPPOINT, ERR_R_EC_LIB); + goto end; + } + } + + if (BN_cmp(x, b->x) == 0 && BN_cmp(y, b->y) == 0) { + ret = 0; + } else { + ret = 1; + } + +end: + BN_CTX_end(bn_ctx); + return ret; +} + diff --git a/include/openssl/bn.h b/include/openssl/bn.h index 17bd5213..949f78cc 100644 --- a/include/openssl/bn.h +++ b/include/openssl/bn.h @@ -510,6 +510,7 @@ int ERR_load_BN_strings(void); # define BN_F_BN_BLINDING_UPDATE 103 # define BN_F_BN_BN2DEC 104 # define BN_F_BN_BN2HEX 105 +# define BN_F_BN_BN2SOLINAS 138 # define BN_F_BN_COMPUTE_WNAF 142 # define BN_F_BN_CTX_GET 116 # define BN_F_BN_CTX_NEW 106 @@ -528,6 +529,20 @@ int ERR_load_BN_strings(void); # define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 # define BN_F_BN_GF2M_MOD_SQR 136 # define BN_F_BN_GF2M_MOD_SQRT 137 +# define BN_F_BN_GFP2_ADD 147 +# define BN_F_BN_GFP2_CANONICAL 148 +# define BN_F_BN_GFP2_CMP 149 +# define BN_F_BN_GFP2_COPY 150 +# define BN_F_BN_GFP2_DIV_BN 151 +# define BN_F_BN_GFP2_INV 152 +# define BN_F_BN_GFP2_IS_ZERO 153 +# define BN_F_BN_GFP2_MUL 154 +# define BN_F_BN_GFP2_NEW 155 +# define BN_F_BN_GFP2_ONE 156 +# define BN_F_BN_GFP2_SET_BN 157 +# define BN_F_BN_GFP2_SUB 158 +# define BN_F_BN_GFP2_ZERO 159 +# define BN_F_BN_HASH_TO_RANGE 160 # define BN_F_BN_LSHIFT 145 # define BN_F_BN_MOD_EXP2_MONT 118 # define BN_F_BN_MOD_EXP_MONT 109 @@ -545,6 +560,7 @@ int ERR_load_BN_strings(void); # define BN_F_BN_RAND_RANGE 122 # define BN_F_BN_RSHIFT 146 # define BN_F_BN_SET_WORDS 144 +# define BN_F_BN_SOLINAS2BN 161 # define BN_F_BN_USUB 115 /* Reason codes. */ @@ -552,6 +568,7 @@ int ERR_load_BN_strings(void); # define BN_R_BAD_RECIPROCAL 101 # define BN_R_BIGNUM_TOO_LONG 114 # define BN_R_BITS_TOO_SMALL 118 +# define BN_R_BUFFER_TOO_SMALL 120 # define BN_R_CALLED_WITH_EVEN_MODULUS 102 # define BN_R_DIV_BY_ZERO 103 # define BN_R_ENCODING_ERROR 104 @@ -560,6 +577,8 @@ int ERR_load_BN_strings(void); # define BN_R_INVALID_LENGTH 106 # define BN_R_INVALID_RANGE 115 # define BN_R_INVALID_SHIFT 119 +# define BN_R_INVALID_SOLINAS 121 +# define BN_R_INVALID_SOLINAS_PARAMETERS 122 # define BN_R_NOT_A_SQUARE 111 # define BN_R_NOT_INITIALIZED 107 # define BN_R_NO_INVERSE 108 diff --git a/include/openssl/bn_gfp2.h b/include/openssl/bn_gfp2.h new file mode 100644 index 00000000..facd4388 --- /dev/null +++ b/include/openssl/bn_gfp2.h @@ -0,0 +1,98 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_BN_GFP2_H +#define HEADER_BN_GFP2_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* element a in GF(p^2), where a = a0 + a1 * i, i^2 == -1 */ +typedef struct { + BIGNUM *a0; + BIGNUM *a1; +} BN_GFP2; + +BN_GFP2 *BN_GFP2_new(void); +int BN_GFP2_copy(BN_GFP2 *r, const BN_GFP2 *a); +int BN_GFP2_zero(BN_GFP2 *a); +int BN_GFP2_is_zero(const BN_GFP2 *a); +int BN_GFP2_equ(const BN_GFP2 *a, const BN_GFP2 *b); +int BN_GF2P_add(BN_GFP2 *r, const BN_GFP2 *a, const BN_GFP2 *b, const BIGNUM *p, BN_CTX *ctx); +int BN_GFP2_sub(BN_GFP2 *r, const BN_GFP2 *a, const BN_GFP2 *b, const BIGNUM *p, BN_CTX *ctx); +int BN_GFP2_mul(BN_GFP2 *r, const BN_GFP2 *a, const BN_GFP2 *b, const BIGNUM *p, BN_CTX *ctx); +int BN_GFP2_sqr(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *p, BN_CTX *ctx); +int BN_GFP2_inv(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *p, BN_CTX *ctx); +int BN_GFP2_div(BN_GFP2 *r, const BN_GFP2 *a, const BN_GFP2 *b, const BIGNUM *p, BN_CTX *ctx); +int BN_GFP2_exp(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *k, const BIGNUM *p, BN_CTX *ctx); +int BN_GFP2_set_bn(BN_GFP2 *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_GF2P_add_bn(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *b, const BIGNUM *p,BN_CTX *ctx); +int BN_GFP2_sub_bn(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); +int BN_GFP2_mul_bn(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); +int BN_GFP2_div_bn(BN_GFP2 *r, const BN_GFP2 *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); +void BN_GFP2_free(BN_GFP2 *a); + +int BN_bn2gfp2(const BIGNUM *bn, BN_GFP2 *gfp2, const BIGNUM *p, BN_CTX *ctx); +int BN_gfp22bn(const BN_GFP2 *gfp2, BIGNUM *bn, const BIGNUM *p, BN_CTX *ctx); + +/* + * Canonical a = a0 + a1 * i + * If order is 0 then output a0, a1, else output a1, a0, |a0| = |a1| = |p|. + */ +int BN_GFP2_canonical(const BN_GFP2 *a, unsigned char *out, size_t *outlen, + int order, const BIGNUM *p, BN_CTX *ctx); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/openssl/bn_hash.h b/include/openssl/bn_hash.h new file mode 100644 index 00000000..dd8aed0d --- /dev/null +++ b/include/openssl/bn_hash.h @@ -0,0 +1,68 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_BN_HASH_H +#define HEADER_BN_HASH_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* hash input bytes to bignum in range [0, p - 1] */ +int BN_hash_to_range(const EVP_MD *md, + BIGNUM **bn, const void *in, size_t inlen, + const BIGNUM *p, BN_CTX *ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/openssl/bn_solinas.h b/include/openssl/bn_solinas.h new file mode 100644 index 00000000..67fe53d9 --- /dev/null +++ b/include/openssl/bn_solinas.h @@ -0,0 +1,94 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* + * Solinas Prime (prime number with low weight) + */ + +#ifndef HEADER_BN_SOLINAS_H +#define HEADER_BN_SOLINAS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* solinas prime = 2^a + s * 2^b + c */ +typedef struct { + int a; + int b; + int s; + int c; +} BN_SOLINAS; + +int BN_bn2solinas(const BIGNUM *bn, BN_SOLINAS *solinas); +int BN_solinas2bn(const BN_SOLINAS *solinas, BIGNUM *bn); +int BN_is_solinas(const BIGNUM *bn); + +/* + * the following Solinas primes are from + * "Solinas primes of small weight for fixed sizes" + * https://eprint.iacr.org/2010/058.pdf + * + * 2^192 - 2^16 - 1 + * 2^192 - 2^64 - 1 + * 2^224 - 2^96 + 1 + * 2^256 - 2^168 + 1 + * 2^384 - 2^80 + 1 + * 2^512 - 2^32 + 1 + * 2^512 - 2^32 - 1 + * 2^1024 - 2^424 - 1 + * 2^1024 - 2^856 + 1 + */ + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 3d124dd0..a1789f89 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -1451,6 +1451,7 @@ int ERR_load_EC_strings(void); # define EC_F_EC_GROUP_CHECK 170 # define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 # define EC_F_EC_GROUP_COPY 106 +# define EC_F_EC_GROUP_GENERATE_TYPE1CURVE 307 # define EC_F_EC_GROUP_GET_CURVE_GF2M 172 # define EC_F_EC_GROUP_GET_CURVE_GFP 130 # define EC_F_EC_GROUP_GET_DEGREE 173 @@ -1458,11 +1459,15 @@ int ERR_load_EC_strings(void); # define EC_F_EC_GROUP_GET_ECPKPARAMETERS 262 # define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 # define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +# define EC_F_EC_GROUP_GET_TYPE1CURVE_ETA 308 +# define EC_F_EC_GROUP_GET_TYPE1CURVE_ZETA 309 +# define EC_F_EC_GROUP_IS_TYPE1CURVE 310 # define EC_F_EC_GROUP_NEW 108 # define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 # define EC_F_EC_GROUP_NEW_FROM_DATA 175 # define EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS 263 # define EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS 264 +# define EC_F_EC_GROUP_NEW_TYPE1CURVE 311 # define EC_F_EC_GROUP_SET_CURVE_GF2M 176 # define EC_F_EC_GROUP_SET_CURVE_GFP 109 # define EC_F_EC_GROUP_SET_GENERATOR 111 @@ -1482,11 +1487,13 @@ int ERR_load_EC_strings(void); # define EC_F_EC_POINTS_MAKE_AFFINE 136 # define EC_F_EC_POINT_ADD 112 # define EC_F_EC_POINT_CMP 113 +# define EC_F_EC_POINT_CMP_FPPOINT 312 # define EC_F_EC_POINT_COPY 114 # define EC_F_EC_POINT_DBL 115 # define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 # define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 # define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +# define EC_F_EC_POINT_HASH2POINT 313 # define EC_F_EC_POINT_INVERT 210 # define EC_F_EC_POINT_IS_AT_INFINITY 118 # define EC_F_EC_POINT_IS_ON_CURVE 119 @@ -1501,6 +1508,7 @@ int ERR_load_EC_strings(void); # define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 # define EC_F_EC_POINT_SET_TO_INFINITY 127 # define EC_F_EC_PRE_COMP_NEW 196 +# define EC_F_EC_TYPE1CURVE_TATE 314 # define EC_F_EC_WNAF_MUL 187 # define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 # define EC_F_I2D_ECIESPARAMETERS 279 @@ -1549,6 +1557,9 @@ int ERR_load_EC_strings(void); # define EC_F_SM2_KAP_FINAL_CHECK 304 # define EC_F_SM2_KAP_PREPARE 305 # define EC_F_SM2_SIGN_SETUP 306 +# define EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK 315 +# define EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK 316 +# define EC_F_TYPE1CURVE_PHI 317 /* Reason codes. */ # define EC_R_ASN1_ERROR 115 @@ -1578,6 +1589,7 @@ int ERR_load_EC_strings(void); # define EC_R_GET_CIPHERTEXT_SIZE_FAILED 175 # define EC_R_GET_KDF_FAILED 176 # define EC_R_GET_PUBLIC_KEY_DATA_FAILURE 177 +# define EC_R_GET_TYPE1CURVE_ZETA_FAILURE 192 # define EC_R_GF2M_NOT_SUPPORTED 147 # define EC_R_GROUP2PKPARAMETERS_FAILURE 120 # define EC_R_HMAC_FAILURE 170 @@ -1609,6 +1621,9 @@ int ERR_load_EC_strings(void); # define EC_R_INVALID_SM2_KAP_CHECKSUM_LENGTH 184 # define EC_R_INVALID_SM2_KAP_CHECKSUM_VALUE 185 # define EC_R_INVALID_TRINOMIAL_BASIS 137 +# define EC_R_INVALID_TYPE1CURVE 193 +# define EC_R_INVALID_TYPE1_CURVE 194 +# define EC_R_INVLID_TYPE1CURVE 195 # define EC_R_KDF_PARAMETER_ERROR 148 # define EC_R_KEYS_NOT_SET 140 # define EC_R_MALLOC_FAILED 186 diff --git a/include/openssl/ec_hash.h b/include/openssl/ec_hash.h new file mode 100644 index 00000000..9c84f15c --- /dev/null +++ b/include/openssl/ec_hash.h @@ -0,0 +1,67 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_EC_HASH_H +#define HEADER_EC_HASH_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* hash string s to elliptic curve point */ +int EC_POINT_hash2point(const EC_GROUP *group, const EVP_MD *md, + const char *s, size_t slen, EC_POINT *point, BN_CTX *ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/openssl/ec_type1.h b/include/openssl/ec_type1.h new file mode 100644 index 00000000..effc7f68 --- /dev/null +++ b/include/openssl/ec_type1.h @@ -0,0 +1,100 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* + * type1curve is supersingular curve E: y^2 = x^3 + 1 (mod p) over prime field. + * p = 11 (mod 12) + * a = 0 + * b = 1 + * G = (x, y) + * n is the order of (x, y) + * h = (p + 1)/n + */ + +#ifndef HEADER_EC_TYPE1_H +#define HEADER_EC_TYPE1_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +EC_GROUP *EC_GROUP_generate_typ1curve(const BIGNUM *order, BN_CTX *ctx); + +EC_GROUP *EC_GROUP_new_type1curve(const BIGNUM *p, const BIGNUM *x, + const BIGNUM *y, const BIGNUM *order, BN_CTX *ctx); + +EC_GROUP *EC_GROUP_new_type1curve_ex(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, const unsigned char *point, size_t pointlen, + const BIGNUM *order, const BIGNUM *cofactor, BN_CTX *bn_ctx); + +int EC_GROUP_is_type1curve(const EC_GROUP *group, BN_CTX *ctx); + +BN_GFP2 *EC_GROUP_get_type1curve_zeta(const EC_GROUP *group, BN_CTX *ctx); + +BIGNUM *EC_GROUP_get_type1curve_eta(const EC_GROUP *group, BN_CTX *ctx); + +/* compute tate pairing e(P, Q) over type1curve */ +int EC_type1curve_tate(const EC_GROUP *group, BN_GFP2 *r, + const EC_POINT *P, const EC_POINT *Q, BN_CTX *ctx); + +/* compute tate pairing ratio e(P1, Q1)/e(P2, Q2) over type1curve*/ +int EC_type1curve_tate_ratio(const EC_GROUP *group, BN_GFP2 *r, + const EC_POINT *P1, const EC_POINT *Q1, const EC_POINT *P2, + const EC_POINT *Q2, BN_CTX *bn_ctx); + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/openssl/fppoint.h b/include/openssl/fppoint.h new file mode 100644 index 00000000..a98dd374 --- /dev/null +++ b/include/openssl/fppoint.h @@ -0,0 +1,77 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* + * FpPoint is the affine coordinates presentation of point over E/F_p + * this data struct is used by pairing schemes over type1 curve + */ + +#ifndef HEADER_FPPOINT_H +#define HEADER_FPPOINT_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct fppoint_st { + BIGNUM *x; + BIGNUM *y; +} FpPoint; +DECLARE_ASN1_FUNCTIONS(FpPoint) + +int EC_POINT_cmp_fppoint(const EC_GROUP *group, + const EC_POINT *point, const FpPoint *fppoint, BN_CTX *ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/test/build.info b/test/build.info index 05480751..64e95cbe 100644 --- a/test/build.info +++ b/test/build.info @@ -18,7 +18,7 @@ IF[{- !$disabled{tests} -}] ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \ bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \ sm3test sms4test kdf2test eciestest ffxtest sm2test \ - pailliertest cpktest otptest gmapitest + pailliertest cpktest otptest gmapitest ec2test SOURCE[aborttest]=aborttest.c INCLUDE[aborttest]=../include @@ -325,6 +325,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[gmapitest]=../include DEPEND[gmapitest]=../libcrypto + SOURCE[ec2test]=ec2test.c + INCLUDE[ec2test]=../include + DEPEND[ec2test]=../libcrypto + IF[{- !$disabled{shared} -}] PROGRAMS_NO_INST=shlibloadtest SOURCE[shlibloadtest]=shlibloadtest.c diff --git a/test/ec2test.c b/test/ec2test.c new file mode 100644 index 00000000..8be2662b --- /dev/null +++ b/test/ec2test.c @@ -0,0 +1,69 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include "../e_os.h" + +#ifdef OPENSSL_NO_EC2 +int main(int argc, char **argv) +{ + printf("NO EC2 (EC Extensions) support\n"); + return 0; +} +#else +# include + +int main(int argc, char **argv) +{ + int err = 0; + return err; +} +#endif diff --git a/test/recipes/15-test_ec2.t b/test/recipes/15-test_ec2.t new file mode 100644 index 00000000..9bb923a7 --- /dev/null +++ b/test/recipes/15-test_ec2.t @@ -0,0 +1,12 @@ +#! /usr/bin/env perl +# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use OpenSSL::Test::Simple; + +simple_test("test_ec2", "ec2test", "ec2");