xref: /freebsd-src/crypto/libecc/src/curves/ec_shortw.c (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
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