xref: /freebsd/crypto/libecc/src/curves/ec_shortw.c (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
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  */
ec_shortw_crv_check_initialized(ec_shortw_crv_src_t crv)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  */
ec_shortw_crv_init(ec_shortw_crv_t crv,fp_src_t a,fp_src_t b,nn_src_t order)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 */
ec_shortw_crv_uninit(ec_shortw_crv_t crv)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