1*f0865ec9SKyle Evans /* 2*f0865ec9SKyle Evans * Copyright (C) 2017 - This file is part of libecc project 3*f0865ec9SKyle Evans * 4*f0865ec9SKyle Evans * Authors: 5*f0865ec9SKyle Evans * Ryad BENADJILA <ryadbenadjila@gmail.com> 6*f0865ec9SKyle Evans * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7*f0865ec9SKyle Evans * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr> 8*f0865ec9SKyle Evans * 9*f0865ec9SKyle Evans * Contributors: 10*f0865ec9SKyle Evans * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr> 11*f0865ec9SKyle Evans * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr> 12*f0865ec9SKyle Evans * 13*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license. 14*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project. 15*f0865ec9SKyle Evans */ 16*f0865ec9SKyle Evans #include <libecc/curves/ec_shortw.h> 17*f0865ec9SKyle Evans 18*f0865ec9SKyle Evans #define EC_SHORTW_CRV_MAGIC ((word_t)(0x9c7c46a1a04c6720ULL)) 19*f0865ec9SKyle Evans 20*f0865ec9SKyle Evans /* 21*f0865ec9SKyle Evans * Check pointed short Weierstrass curve structure has already been 22*f0865ec9SKyle Evans * initialized. Returns -1 on error, 0 on success. 23*f0865ec9SKyle Evans */ 24*f0865ec9SKyle Evans int ec_shortw_crv_check_initialized(ec_shortw_crv_src_t crv) 25*f0865ec9SKyle Evans { 26*f0865ec9SKyle Evans int ret; 27*f0865ec9SKyle Evans 28*f0865ec9SKyle Evans MUST_HAVE((crv != NULL) && (crv->magic == EC_SHORTW_CRV_MAGIC), ret, err); 29*f0865ec9SKyle Evans ret = 0; 30*f0865ec9SKyle Evans 31*f0865ec9SKyle Evans err: 32*f0865ec9SKyle Evans return ret; 33*f0865ec9SKyle Evans } 34*f0865ec9SKyle Evans 35*f0865ec9SKyle Evans /* 36*f0865ec9SKyle Evans * Initialize pointed short Weierstrass curve structure using given a and b 37*f0865ec9SKyle Evans * Fp elements representing curve equation (y^2 = x^3 + ax + b) parameters. 38*f0865ec9SKyle Evans * 'order' parameter is the generator point order. The function returns 0 39*f0865ec9SKyle Evans * on success, -1 on error. 40*f0865ec9SKyle Evans */ 41*f0865ec9SKyle Evans int ec_shortw_crv_init(ec_shortw_crv_t crv, fp_src_t a, fp_src_t b, nn_src_t order) 42*f0865ec9SKyle Evans { 43*f0865ec9SKyle Evans fp tmp, tmp2; 44*f0865ec9SKyle Evans int ret, iszero; 45*f0865ec9SKyle Evans tmp.magic = tmp2.magic = WORD(0); 46*f0865ec9SKyle Evans 47*f0865ec9SKyle Evans ret = nn_check_initialized(order); EG(ret, err); 48*f0865ec9SKyle Evans ret = fp_check_initialized(a); EG(ret, err); 49*f0865ec9SKyle Evans ret = fp_check_initialized(b); EG(ret, err); 50*f0865ec9SKyle Evans MUST_HAVE((a->ctx == b->ctx), ret, err); 51*f0865ec9SKyle Evans MUST_HAVE((crv != NULL), ret, err); 52*f0865ec9SKyle Evans 53*f0865ec9SKyle Evans /* The discriminant (4 a^3 + 27 b^2) must be non zero */ 54*f0865ec9SKyle Evans ret = fp_init(&tmp, a->ctx); EG(ret, err); 55*f0865ec9SKyle Evans ret = fp_init(&tmp2, a->ctx); EG(ret, err); 56*f0865ec9SKyle Evans ret = fp_sqr(&tmp, a); EG(ret, err); 57*f0865ec9SKyle Evans ret = fp_mul(&tmp, &tmp, a); EG(ret, err); 58*f0865ec9SKyle Evans ret = fp_set_word_value(&tmp2, WORD(4)); EG(ret, err); 59*f0865ec9SKyle Evans ret = fp_mul(&tmp, &tmp, &tmp2); EG(ret, err); 60*f0865ec9SKyle Evans 61*f0865ec9SKyle Evans ret = fp_set_word_value(&tmp2, WORD(27)); EG(ret, err); 62*f0865ec9SKyle Evans ret = fp_mul(&tmp2, &tmp2, b); EG(ret, err); 63*f0865ec9SKyle Evans ret = fp_mul(&tmp2, &tmp2, b); EG(ret, err); 64*f0865ec9SKyle Evans 65*f0865ec9SKyle Evans ret = fp_add(&tmp, &tmp, &tmp2); EG(ret, err); 66*f0865ec9SKyle Evans ret = fp_iszero(&tmp, &iszero); EG(ret, err); 67*f0865ec9SKyle Evans MUST_HAVE((!iszero), ret, err); 68*f0865ec9SKyle Evans 69*f0865ec9SKyle Evans ret = fp_init(&(crv->a), a->ctx); EG(ret, err); 70*f0865ec9SKyle Evans ret = fp_init(&(crv->b), b->ctx); EG(ret, err); 71*f0865ec9SKyle Evans ret = fp_init(&(crv->a_monty), a->ctx); EG(ret, err); 72*f0865ec9SKyle Evans 73*f0865ec9SKyle Evans ret = fp_copy(&(crv->a), a); EG(ret, err); 74*f0865ec9SKyle Evans ret = fp_copy(&(crv->b), b); EG(ret, err); 75*f0865ec9SKyle Evans ret = fp_redcify(&(crv->a_monty), a); EG(ret, err); 76*f0865ec9SKyle Evans 77*f0865ec9SKyle Evans ret = nn_copy(&(crv->order), order); EG(ret, err); 78*f0865ec9SKyle Evans 79*f0865ec9SKyle Evans #ifndef NO_USE_COMPLETE_FORMULAS 80*f0865ec9SKyle Evans ret = fp_init(&(crv->b3), b->ctx); EG(ret, err); 81*f0865ec9SKyle Evans ret = fp_init(&(crv->b_monty), b->ctx); EG(ret, err); 82*f0865ec9SKyle Evans ret = fp_init(&(crv->b3_monty), b->ctx); EG(ret, err); 83*f0865ec9SKyle Evans 84*f0865ec9SKyle Evans ret = fp_add(&(crv->b3), b, b); EG(ret, err); 85*f0865ec9SKyle Evans ret = fp_add(&(crv->b3), &(crv->b3), b); EG(ret, err); 86*f0865ec9SKyle Evans ret = fp_redcify(&(crv->b_monty), b); EG(ret, err); 87*f0865ec9SKyle Evans ret = fp_redcify(&(crv->b3_monty), &(crv->b3)); EG(ret, err); 88*f0865ec9SKyle Evans #endif 89*f0865ec9SKyle Evans 90*f0865ec9SKyle Evans crv->magic = EC_SHORTW_CRV_MAGIC; 91*f0865ec9SKyle Evans 92*f0865ec9SKyle Evans err: 93*f0865ec9SKyle Evans fp_uninit(&tmp); 94*f0865ec9SKyle Evans fp_uninit(&tmp2); 95*f0865ec9SKyle Evans 96*f0865ec9SKyle Evans return ret; 97*f0865ec9SKyle Evans } 98*f0865ec9SKyle Evans 99*f0865ec9SKyle Evans /* Uninitialize curve */ 100*f0865ec9SKyle Evans void ec_shortw_crv_uninit(ec_shortw_crv_t crv) 101*f0865ec9SKyle Evans { 102*f0865ec9SKyle Evans if((crv != NULL) && (crv->magic == EC_SHORTW_CRV_MAGIC)){ 103*f0865ec9SKyle Evans crv->magic = WORD(0); 104*f0865ec9SKyle Evans } 105*f0865ec9SKyle Evans 106*f0865ec9SKyle Evans return; 107*f0865ec9SKyle Evans } 108