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