MPHELL  4.0.0
mphell-curve.c
Go to the documentation of this file.
1 /*
2  MPHELL-4.0
3  Author(s): The MPHELL team
4 
5  (C) Copyright 2015-2018 - Institut Fourier / Univ. Grenoble Alpes (France)
6 
7  This file is part of the MPHELL Library.
8  MPHELL is free software: you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as published by
10  the Free Software Foundation, version 3 of the License.
11 
12  MPHELL is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with MPHELL. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
26 #include "mphell-curve.h"
27 
28 /**************************************TMP**********************************/
29 
30 /* void ec_point_get_pool_elt (ec_point_ptr P, field_ptr k, uint8_t stack){} is inline */
31 
32 /* void ec_point_relax_pool_elt (ec_point_ptr P, field_ptr k, uint8_t stack){} is inline */
33 
34 /************************************SETTERS**********************************/
35 
36 void
38 {
39  E->k = (field_t*)k;
40  number_init(&(E->q), k->size);
41  field_elt_alloc(&E->a, k);
42  field_elt_alloc(&E->b, k);
43  ec_point_alloc(E->G, k);
44  number_init(&(E->n), k->size);
45  number_init(&(E->h), k->size);
46  field_elt_alloc(&E->D, k);
47  field_elt_alloc(&E->disc, k);
48  E->id_curve=malloc(100*sizeof(char));
49 }
50 
51 void
53 {
54  field_elt_init(E->a, k);
55  field_elt_init(E->b, k);
56  ec_point_init(E->G, k);
57  field_elt_init(E->D, k);
58  field_elt_init(E->disc, k);
59 }
60 
61 void
62 ec_create (ec_curve_ptr E, const char *id_curve, field_srcptr k, fe_srcptr a,
63  fe_srcptr b, ec_point_srcptr G, number_srcptr h, number_srcptr n,
64  const ec_type type, const ec_formula f, uint8_t stack)
65 {
66  E->k = (field_t*)k;
67  field_get_size(E->q, k);
68  field_elt_copy(E->a, a, k);
69  field_elt_copy(E->b, b, k);
70 
71  if(G != NULL)
72  {
73  ec_point_copy(E->G, G, k);
74  }
75  else
76  {
77  field_elt_set_ui(E->G->x, 0, true, k, stack);
78  field_elt_set_ui(E->G->y, 0, true, k, stack);
79  field_elt_set_ui(E->G->z, 0, true, k, stack);
80  field_elt_set_ui(E->G->t, 0, true, k, stack);
81  }
82  if(h != NULL)
83  {
84  number_copy(E->h, h);
85  }
86  else
87  {
88  number_set_ui(E->h, 1);
89  }
90 
91  if(n != NULL)
92  {
93  number_copy(E->n, n);
94  }
95  else
96  {
97  number_set_ui(E->n, 0);
98  }
99  E->type = type;
100  E->f = f;
101  if((id_curve != NULL) && (id_curve[0] !='\0'))
102  {
103  strcpy(E->id_curve, id_curve);
104  }
105  else
106  {
107  strcpy(E->id_curve, "no_name");
108  }
109  ec_compute_disc(E, stack);
110  ec_test_spec(E, stack);
111 }
112 
113 void
114 ec_use_curve (ec_curve_ptr E, field_ptr k, const ec_known_curve id_curve, const ec_formula f, uint8_t stack)
115 {
116  number tmp;
117  switch(id_curve)
118  {
119  case NIST_192:
120  /* Create k */
121  number_tmp_alloc(&tmp, bits_to_nblock(192), stack);
122  number_set_str(tmp, "fffffffffffffffffffffffffffffffeffffffffffffffff", 16);
123  field_create(k, "p192r1", stack, 1, tmp);
124  number_copy(E->q, tmp);
125  number_tmp_free(&tmp, bits_to_nblock(192), stack);
126  E->k = (field_t*)k;
127 
128  /* Initialise the curve, now that k is set up */
129  ec_init(E, k);
130 
131  /* Set curve parameters*/
132  field_elt_set_str(E->a, "fffffffffffffffffffffffffffffffefffffffffffffffc", 16, false, (field_t*)k, stack);
133  field_elt_set_str(E->b, "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16, false, (field_t*)k, stack);
134  ec_point_set_aff_str(E->G, "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", "07192b95ffc8da78631011ed6b24cdd573f977a11e794811", false, 16, WEIERSTRASS, k, stack);
135  number_set_str(E->n, "ffffffffffffffffffffffff99def836146bc9b1b4d22831", 16);
136  number_set_str(E->h, "000000000000000000000000000000000000000000000001", 16);
137  E->type = WEIERSTRASS;
138  E->f = f;
139  strcpy(E->id_curve, "nist_p192");
140  ec_compute_disc(E, stack);
141  ec_test_spec(E, stack);
142  break;
143 
144  case NIST_224:
145  /* Create k */
146  number_tmp_alloc(&tmp, bits_to_nblock(224), stack);
147  number_set_str(tmp, "ffffffffffffffffffffffffffffffff000000000000000000000001", 16);
148  field_create(k, "p224r1", stack, 1, tmp);
149  number_copy(E->q,tmp);
150  number_tmp_free(&tmp, bits_to_nblock(224), stack);
151  E->k = (field_t*)k;
152 
153  /* Initialise the curve, now that k is set up */
154  ec_init(E, k);
155 
156  /* Set curve parameters*/
157  field_elt_set_str(E->a, "fffffffffffffffffffffffffffffffefffffffffffffffffffffffe", 16, false, (field_t*)k, stack);
158  field_elt_set_str(E->b, "b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", 16, false, (field_t*)k, stack);
159  ec_point_set_aff_str(E->G, "b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", false, 16, WEIERSTRASS, k, stack);
160  number_set_str(E->n, "ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d", 16);
161  number_set_str(E->h, "00000000000000000000000000000000000000000000000000000001", 16);
162  E->type = WEIERSTRASS;
163  E->f = f;
164  strcpy(E->id_curve, "nist_p224");
165  ec_compute_disc(E, stack);
166  ec_test_spec(E, stack);
167  break;
168 
169  case NIST_256:
170  /* Create k */
171  number_tmp_alloc(&tmp, bits_to_nblock(256), stack);
172  number_set_str(tmp, "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16);
173  field_create(k, "p256r1", stack, 1, tmp);
174  number_copy(E->q,tmp);
175  number_tmp_free(&tmp, bits_to_nblock(256), stack);
176  E->k = (field_t*)k;
177 
178  /* Initialise the curve, now that k is set up */
179  ec_init(E, k);
180 
181  /* Set curve parameters*/
182  field_elt_set_str(E->a, "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16, false, (field_t*)k, stack);
183  field_elt_set_str(E->b, "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16, false, (field_t*)k, stack);
184  ec_point_set_aff_str(E->G, "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", false, 16, WEIERSTRASS, k, stack);
185  number_set_str(E->n, "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16);
186  number_set_str(E->h, "0000000000000000000000000000000000000000000000000000000000000001", 16);
187  E->type = WEIERSTRASS;
188  E->f = f;
189  strcpy(E->id_curve, "nist_p256");
190  ec_compute_disc(E, stack);
191  ec_test_spec(E, stack);
192  break;
193 
194  case NIST_384:
195  /* Create k */
196  number_tmp_alloc(&tmp, bits_to_nblock(384), stack);
197  number_set_str(tmp, "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff", 16);
198  number_copy(E->q,tmp);
199  field_create(k, "p384r1", stack, 1, tmp);
200  number_tmp_free(&tmp, bits_to_nblock(384), stack);
201  E->k = (field_t*)k;
202 
203  /* Initialise the curve, now that k is set up */
204  ec_init(E, k);
205 
206  /* Set curve parameters*/
207  field_elt_set_str(E->a, "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc", 16, false, (field_t*)k, stack);
208  field_elt_set_str(E->b, "b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef", 16, false, (field_t*)k, stack);
209  ec_point_set_aff_str(E->G, "aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760aB7", "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5F", false, 16, WEIERSTRASS, k, stack);
210  number_set_str(E->n, "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973", 16);
211  number_set_str(E->h, "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 16);
212  E->type = WEIERSTRASS;
213  E->f = f;
214  strcpy(E->id_curve, "nist_p384");
215  ec_compute_disc(E, stack);
216  ec_test_spec(E, stack);
217  break;
218 
219  case NIST_521:
220  /* Create k */
221  number_tmp_alloc(&tmp, bits_to_nblock(521), stack);
222  number_set_str(tmp, "000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16);
223  number_copy(E->q,tmp);
224  field_create(k, "p521r1", stack, 1, tmp);
225  number_tmp_free(&tmp, bits_to_nblock(521), stack);
226  E->k = (field_t*)k;
227 
228  /* Initialise the curve, now that k is set up */
229  ec_init(E, k);
230 
231  /* Set curve parameters*/
232  field_elt_set_str(E->a, "000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", 16, false, (field_t*)k, stack);
233  field_elt_set_str(E->b, "00000051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16, false, (field_t*)k, stack);
234  ec_point_set_aff_str(E->G, "000000c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0000011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", false, 16, WEIERSTRASS, k, stack);
235  number_set_str(E->n, "000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", 16);
236  number_set_str(E->h, "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 16);
237  E->type = WEIERSTRASS;
238  E->f = f;
239  strcpy(E->id_curve, "nist_p521");
240  ec_compute_disc(E, stack);
241  ec_test_spec(E, stack);
242  break;
243 
244  case BRAINPOOL_160:
245  /* Create k */
246  number_tmp_alloc(&tmp, bits_to_nblock(160), stack);
247  number_set_str(tmp, "E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16);
248  number_copy(E->q,tmp);
249  field_create(k, "ZZ_160", stack, 1, tmp);
250  number_tmp_free(&tmp, bits_to_nblock(160), stack);
251  E->k = (field_t*)k;
252 
253  /* Initialise the curve, now that k is set up */
254  ec_init(E, k);
255 
256  /* Set curve parameters*/
257  field_elt_set_str(E->a, "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", 16, false, (field_t*)k, stack);
258  field_elt_set_str(E->b, "1E589A8595423412134FAA2DBDEC95C8D8675E58", 16, false, (field_t*)k, stack);
259  ec_point_set_aff_str(E->G, "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", "1667CB477A1A8EC338F94741669C976316DA6321", false, 16, WEIERSTRASS, k, stack);
260  number_set_str(E->n, "E95E4A5F737059DC60DF5991D45029409E60FC09", 16);
261  number_set_str(E->h, "0000000000000000000000000000000000000001", 16);
262  E->type = WEIERSTRASS;
263  E->f = f;
264  strcpy(E->id_curve, "brainpool_p160r1");
265  ec_compute_disc(E, stack);
266  ec_test_spec(E, stack);
267  break;
268 
269  case BRAINPOOL_192:
270  /* Create k */
271  number_tmp_alloc(&tmp, bits_to_nblock(192), stack);
272  number_set_str(tmp, "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16);
273  number_copy(E->q,tmp);
274  field_create(k, "ZZ_192", stack, 1, tmp);
275  number_tmp_free(&tmp, bits_to_nblock(192), stack);
276  E->k = (field_t*)k;
277 
278  /* Initialise the curve, now that k is set up */
279  ec_init(E, k);
280 
281  /* Set curve parameters*/
282  field_elt_set_str(E->a, "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", 16, false, (field_t*)k, stack);
283  field_elt_set_str(E->b, "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", 16, false, (field_t*)k, stack);
284  ec_point_set_aff_str(E->G, "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", false, 16, WEIERSTRASS, k, stack);
285  number_set_str(E->n, "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16);
286  number_set_str(E->h, "000000000000000000000000000000000000000000000001", 16);
287  E->type = WEIERSTRASS;
288  E->f = f;
289  strcpy(E->id_curve, "brainpool_p192r1");
290  ec_compute_disc(E, stack);
291  ec_test_spec(E, stack);
292  break;
293 
294  case BRAINPOOL_224:
295  /* Create k */
296  number_tmp_alloc(&tmp, bits_to_nblock(224), stack);
297  number_set_str(tmp, "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16);
298  number_copy(E->q,tmp);
299  field_create(k, "ZZ_224", stack, 1, tmp);
300  number_tmp_free(&tmp, bits_to_nblock(224), stack);
301  E->k = (field_t*)k;
302 
303  /* Initialise the curve, now that k is set up */
304  ec_init(E, k);
305 
306  /* Set curve parameters*/
307  field_elt_set_str(E->a, "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", 16, false, (field_t*)k, stack);
308  field_elt_set_str(E->b, "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", 16, false, (field_t*)k, stack);
309  ec_point_set_aff_str(E->G, "D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", false, 16, WEIERSTRASS, k, stack);
310  number_set_str(E->n, "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16);
311  number_set_str(E->h, "00000000000000000000000000000000000000000000000000000001", 16);
312  E->type = WEIERSTRASS;
313  E->f = f;
314  strcpy(E->id_curve, "brainpool_p224r1");
315  ec_compute_disc(E, stack);
316  ec_test_spec(E, stack);
317  break;
318 
319  case BRAINPOOL_256:
320  /* Create k */
321  number_tmp_alloc(&tmp, bits_to_nblock(256), stack);
322  number_set_str(tmp, "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16);
323  number_copy(E->q,tmp);
324  field_create(k, "ZZ_256", stack, 1, tmp);
325  number_tmp_free(&tmp, bits_to_nblock(256), stack);
326  E->k = (field_t*)k;
327 
328  /* Initialise the curve, now that k is set up */
329  ec_init(E, k);
330 
331  /* Set curve parameters*/
332  field_elt_set_str(E->a, "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", 16, false, (field_t*)k, stack);
333  field_elt_set_str(E->b, "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16, false, (field_t*)k, stack);
334  ec_point_set_aff_str(E->G, "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", false, 16, WEIERSTRASS, k, stack);
335  number_set_str(E->n, "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16);
336  number_set_str(E->h, "0000000000000000000000000000000000000000000000000000000000000001", 16);
337  E->type = WEIERSTRASS;
338  E->f = f;
339  strcpy(E->id_curve, "brainpool_p256r1");
340  ec_compute_disc(E, stack);
341  ec_test_spec(E, stack);
342  break;
343 
344  case BRAINPOOL_320:
345  /* Create k */
346  number_tmp_alloc(&tmp, bits_to_nblock(320), stack);
347  number_set_str(tmp, "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16);
348  number_copy(E->q,tmp);
349  field_create(k, "ZZ_320", stack, 1, tmp);
350  number_tmp_free(&tmp, bits_to_nblock(320), stack);
351  E->k = (field_t*)k;
352 
353  /* Initialise the curve, now that k is set up */
354  ec_init(E, k);
355 
356  /* Set curve parameters*/
357  field_elt_set_str(E->a, "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", 16, false, (field_t*)k, stack);
358  field_elt_set_str(E->b, "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", 16, false, (field_t*)k, stack);
359  ec_point_set_aff_str(E->G, "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", false, 16, WEIERSTRASS, k, stack);
360  number_set_str(E->n, "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16);
361  number_set_str(E->h, "00000000000000000000000000000000000000000000000000000000000000000000000000000001", 16);
362  E->type = WEIERSTRASS;
363  E->f = f;
364  strcpy(E->id_curve, "brainpool_p320r1");
365  ec_compute_disc(E, stack);
366  ec_test_spec(E, stack);
367  break;
368 
369  case BRAINPOOL_384:
370  /* Create k */
371  number_tmp_alloc(&tmp, bits_to_nblock(384), stack);
372  number_set_str(tmp, "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16);
373  number_copy(E->q,tmp);
374  field_create(k, "ZZ_384", stack, 1, tmp);
375  number_tmp_free(&tmp, bits_to_nblock(384), stack);
376  E->k = (field_t*)k;
377 
378  /* Initialise the curve, now that k is set up */
379  ec_init(E, k);
380 
381  /* Set curve parameters*/
382  field_elt_set_str(E->a, "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", 16, false, (field_t*)k, stack);
383  field_elt_set_str(E->b, "4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", 16, false, (field_t*)k, stack);
384  ec_point_set_aff_str(E->G, "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", false, 16, WEIERSTRASS, k, stack);
385  number_set_str(E->n, "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16);
386  number_set_str(E->h, "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 16);
387  E->type = WEIERSTRASS;
388  E->f = f;
389  strcpy(E->id_curve, "brainpool_p384r1");
390  ec_compute_disc(E, stack);
391  ec_test_spec(E, stack);
392  break;
393 
394  case BRAINPOOL_512:
395  /* Create k */
396  number_tmp_alloc(&tmp, bits_to_nblock(512), stack);
397  number_set_str(tmp, "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16);
398  number_copy(E->q,tmp);
399  field_create(k, "ZZ_512", stack, 1, tmp);
400  number_tmp_free(&tmp, bits_to_nblock(512), stack);
401  E->k = (field_t*)k;
402 
403  /* Initialise the curve, now that k is set up */
404  ec_init(E, k);
405 
406  /* Set curve parameters*/
407  field_elt_set_str(E->a, "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", 16, false, (field_t*)k, stack);
408  field_elt_set_str(E->b, "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", 16, false, (field_t*)k, stack);
409  ec_point_set_aff_str(E->G, "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", false, 16, WEIERSTRASS, k, stack);
410  number_set_str(E->n, "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16);
411  number_set_str(E->h, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 16);
412  E->type = WEIERSTRASS;
413  E->f = f;
414  strcpy(E->id_curve, "brainpool_p512r1");
415  ec_compute_disc(E, stack);
416  ec_test_spec(E, stack);
417  break;
418 
419  case FR_256:
420  /* Create k */
421  number_tmp_alloc(&tmp, bits_to_nblock(256), stack);
422  number_set_str(tmp, "F1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C03", 16);
423  number_copy(E->q,tmp);
424  field_create(k, "ZZ_256", stack, 1, tmp);
425  number_tmp_free(&tmp, bits_to_nblock(256), stack);
426  E->k = (field_t*)k;
427 
428  /* Initialise the curve, now that k is set up */
429  ec_init(E, k);
430 
431  /* Set curve parameters*/
432  field_elt_set_str(E->a, "F1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C00", 16, false, (field_t*)k, stack);
433  field_elt_set_str(E->b, "EE353FCA5428A9300D4ABA754A44C00FDFEC0C9AE4B1A1803075ED967B7BB73F", 16, false, (field_t*)k, stack);
434  ec_point_set_aff_str(E->G, "B6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF", "6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB", false, 16, WEIERSTRASS, k, stack);
435  number_set_str(E->n, "F1FD178C0B3AD58F10126DE8CE42435B53DC67E140D2BF941FFDD459C6D655E1", 16);
436  number_set_str(E->h, "0000000000000000000000000000000000000000000000000000000000000001", 16);
437  E->type = WEIERSTRASS;
438  E->f = f;
439  strcpy(E->id_curve, "frp256v1");
440  ec_compute_disc(E, stack);
441  ec_test_spec(E, stack);
442  break;
443 
444  case JQ_256_3:
445  /* Create k */
446  number_tmp_alloc(&tmp, bits_to_nblock(256), stack);
447  number_set_str(tmp, "b09f075797da89f57ec8c0265b014c5ba37bcb84208a4c4d83199a31d17cb1af", 16);
448  number_copy(E->q,tmp);
449  field_create(k, "ZZ_256", stack, 1, tmp);
450  number_tmp_free(&tmp, bits_to_nblock(256), stack);
451  E->k = (field_t*)k;
452 
453  /* Initialise the curve, now that k is set up */
454  ec_init(E, k);
455 
456  /* Set curve parameters*/
457  field_elt_set_str(E->a, "1468727718e87fae1d94287a36205fa0e3b70bbaad31a097c1ffa5a5db263683", 16, false, (field_t*)k, stack);
458  ec_point_set_str(E->G, "7e99fa90a889802939e8704d3cc8abc5c0c879540dea85075eabfb6c73d515c5", "5d5db0901ca66a952304e220fcf6581c55fb7fb7986522096911c09d1e76de9b", "86eccefd9aa9174b1e61505ba174452525f7fd2989304574b298978e79690c20", "77d5d37af2ee21e362a68ec5e277b40538434a020c6d1a3c885b6eb8fec53dd3", false, 16, k, stack);
459  number_set_str(E->n, "2c27c1d5e5f6a27d5fb2300996c0531746f66dec9a2e0bd13eabeafa863611f7", 16);
460  number_set_str(E->h, "0000000000000000000000000000000000000000000000000000000000000004", 16);
461  E->type = JACOBI_QUARTIC;
462  E->f = f;
463  strcpy(E->id_curve, "jq256_3");
464  ec_compute_disc(E, stack);
465  ec_test_spec(E, stack);
466  break;
467 
468  case ED_25519:
469  /* Create k */
470  number_tmp_alloc(&tmp, bits_to_nblock(256), stack);
471  number_set_str(tmp, "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed", 16);
472  number_copy(E->q,tmp);
473  field_create(k, "ZZ_256", stack, 1, tmp);
474  number_tmp_free(&tmp, bits_to_nblock(256), stack);
475  E->k = (field_t*)k;
476 
477  /* Initialise the curve, now that k is set up */
478  ec_init(E, k);
479 
480  /* Set curve parameters*/
481  field_elt_set_str(E->a, "0000000000000000000000000000000000000000000000000000000000000001", 16, false, (field_t*)k, stack);
482  field_elt_set_str(E->b, "2dfc9311d490018c7338bf8688861767ff8ff5b2bebe27548a14b235eca6874a", 16, false, (field_t*)k, stack);
483  ec_point_set_aff_str(E->G, "159a6849e44c3c7f061b3d570fc4ed5b5d14c8ba4253df49cc7edf80f533ad9b", "6666666666666666666666666666666666666666666666666666666666666658", false, 16, EDWARDS, k, stack);
484  number_set_str(E->n, "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed", 16);
485  number_set_str(E->h, "0000000000000000000000000000000000000000000000000000000000000008", 16);
486  E->type = EDWARDS;
487  E->f = f;
488  strcpy(E->id_curve, "ed_25519");
489  ec_compute_disc(E, stack);
490  ec_test_spec(E, stack);
491  break;
492  }
493 }
494 
495 void ec_random(ec_curve_ptr E, const char *id_curve, char * seed_res, field_srcptr k, const ec_type type, const ec_formula f, uint8_t stack)
496 {
497  field_elt a, b;
498  field_elt_get_pool_elt(&a, (field_t*)k, stack);
499  field_elt_get_pool_elt(&b, (field_t*)k, stack);
500  switch(type)
501  {
502  case JACOBI_QUARTIC :
503  jacobi_quartic_curve_random_generation(a, seed_res, k, stack);
504  field_elt_set_ui(b, 0, false, k, stack);
505  ec_create(E, id_curve, k, a, b, NULL, NULL, NULL, type, f, stack);
506  break;
507 
508  case EDWARDS :
509  edwards_curve_random_generation(b, seed_res, k, stack);
510  field_elt_set_one(a, k);
511  ec_create(E, id_curve, k, a, b, NULL, NULL, NULL, type, f, stack);
512  break;
513 
514  case WEIERSTRASS :
515  weierstrass_curve_random_generation(a, b, seed_res, k, stack);
516  ec_create(E, id_curve, k, a, b, NULL, NULL, NULL, type, f, stack);
517  break;
518  }
519  field_elt_relax_pool_elt(&a, (field_t*)k, stack);
520  field_elt_relax_pool_elt(&b, (field_t*)k, stack);
521 }
522 
523 bool ec_verify_random_generation(ec_curve_ptr E, const char * seed, uint8_t stack)
524 {
525  bool res = false;
526  switch(E->type)
527  {
528  case JACOBI_QUARTIC :
529  res = jacobi_quartic_verify_random_generation(E, seed, stack);
530  break;
531 
532  case EDWARDS :
533  res = edwards_verify_random_generation(E, seed, stack);
534  break;
535 
536  case WEIERSTRASS :
537  res = weierstrass_verify_random_generation(E, seed, stack);
538  break;
539  }
540  return res;
541 }
542 
543 void
545 {
546  switch(E->type)
547  {
548  case JACOBI_QUARTIC :
549  break;
550 
551  case EDWARDS :
552  E->f = EXTENDED_EDWARDS;
553  break;
554 
555  case WEIERSTRASS :
556  E->f = JACOBIAN;
557  break;
558  }
559 }
560 
561 void
563 {
564  switch(E->type)
565  {
566  case JACOBI_QUARTIC :
567  break;
568 
569  case EDWARDS :
570  /* Hard to tell which one is the better so no choice made here */
571  break;
572 
573  case WEIERSTRASS :
574  E->f = JACOBIAN;
575  break;
576  }
577 }
578 
579 void
580 ec_compute_disc (ec_curve_ptr E, uint8_t stack)
581 {
582  switch(E->type)
583  {
584  case JACOBI_QUARTIC :
585  jacobi_quartic_compute_disc(E, stack);
586  break;
587 
588  case EDWARDS :
589  edwards_compute_disc(E, stack);
590  break;
591 
592  case WEIERSTRASS :
593  weierstrass_compute_disc(E, stack);
594  break;
595  }
596 }
597 
598 void
599 ec_test_spec (ec_curve_ptr E, uint8_t stack)
600 {
601  field_elt tmp1;
602  field_elt_get_pool_elt(&tmp1, E->k, stack);
603  field_elt_set_ui(tmp1, 3, false, E->k, stack);
604  field_elt_neg(tmp1, tmp1, E->k);
605 
606  if(field_elt_cmp(tmp1, E->a, E->k) == 0)
607  {
608  E->ec_spec1 = true;
609  }
610  else
611  {
612  E->ec_spec1 = false;
613  }
614  field_elt_relax_pool_elt(&tmp1, E->k, stack);
615 }
616 
617 void
619 {
620  field_t *k = E->k;
621  number_copy(E_res->q, E->q);
622  E_res->k = k;
623  field_elt_copy(E_res->a, E->a, k);
624  field_elt_copy(E_res->b, E->b, k);
625  ec_point_copy(E_res->G, E->G, k);
626  number_copy(E_res->h, E->h);
627  number_copy(E_res->n, E->n);
628  field_elt_copy(E_res->D, E->D, k);
629  field_elt_copy(E_res->disc, E->disc, k);
630  E_res->type=E->type;
631  if(E->id_curve != NULL)
632  {
633  strcpy(E_res->id_curve, E->id_curve);
634  }
635  else
636  {
637  strcpy(E_res->id_curve, "no_name");
638  }
639  E_res->f=E->f;
640 }
641 
642 void
644 {
645  field_t *k = E->k;
646  field_elt_clear(&E->a, k);
647  field_elt_clear(&E->b, k);
648  ec_point_clear(E->G, k);
649  field_elt_clear(&E->D, k);
650  field_elt_clear(&E->disc, k);
651 
652 }
653 
654 void
656 {
657  field_t *k = E->k;
658  number_free(&E->q);
659  field_elt_free(&E->a, k);
660  field_elt_free(&E->b, k);
661  ec_point_free(E->G, k);
662  number_free(&E->h);
663  number_free(&E->n);
664  field_elt_free(&E->D, k);
665  field_elt_free(&E->disc, k);
666  if(E->id_curve != NULL)
667  {
668  free(E->id_curve);
669  }
670 }
671 
672 void
674 {
675  field_elt_alloc(&(P->x), k);
676  field_elt_alloc(&(P->y), k);
677  field_elt_alloc(&(P->z), k);
678  field_elt_alloc(&(P->t), k);
679 }
680 
681 void
683 {
684  field_elt_init(P->x, k);
685  field_elt_init(P->y, k);
686  field_elt_init(P->z, k);
687  field_elt_init(P->t, k);
688 }
689 
690 void
692 {
693  field_elt_clear(&(P->x), k);
694  field_elt_clear(&(P->y), k);
695  field_elt_clear(&(P->z), k);
696  field_elt_clear(&(P->t), k);
697 }
698 
699 void
701 {
702  field_elt_free(&(P->x), k);
703  field_elt_free(&(P->y), k);
704  field_elt_free(&(P->z), k);
705  field_elt_free(&(P->t), k);
706 }
707 
708 void
710 {
711  field_elt_copy(P3->x, P->x, k);
712  field_elt_copy(P3->y, P->y, k);
713  field_elt_copy(P3->z, P->z, k);
714  field_elt_copy(P3->t, P->t, k);
715 }
716 
717 void
720 {
721  field_elt_copy(P->x, x, k);
722  field_elt_copy(P->y, y, k);
723  field_elt_copy(P->z, z, k);
724  field_elt_copy(P->t, t, k);
725 }
726 
727 void
728 ec_point_set_str (ec_point_ptr P, const char *str_x, const char *str_y,
729  const char *str_z, const char *str_t, const bool is_reduced,
730  const uint8_t base, field_srcptr k, uint8_t stack)
731 {
732  field_elt_set_str(P->x, str_x, base, is_reduced, k, stack);
733  field_elt_set_str(P->y, str_y, base, is_reduced, k, stack);
734  field_elt_set_str(P->z, str_z, base, is_reduced, k, stack);
735  field_elt_set_str(P->t, str_t, base, is_reduced, k, stack);
736 }
737 
738 void
740  const ec_type type, field_srcptr k, uint8_t stack)
741 {
742  switch(type)
743  {
744  case JACOBI_QUARTIC :
745  jacobi_quartic_point_set_aff(P, x, y, k, stack);
746  break;
747 
748  case EDWARDS :
749  edwards_point_set_aff(P, x, y, k, stack);
750  break;
751 
752  case WEIERSTRASS :
753  weierstrass_point_set_aff(P, x, y, k);
754  break;
755  }
756 }
757 
758 void
759 ec_point_set_aff_str (ec_point_ptr P, const char *str_x, const char *str_y,
760  const bool is_reduced, const uint8_t base, const ec_type type,
761  field_srcptr k, uint8_t stack)
762 {
763  switch(type)
764  {
765  case JACOBI_QUARTIC :
766  jacobi_quartic_point_set_aff_str(P, str_x, str_y, is_reduced, base, k, stack);
767  break;
768 
769  case EDWARDS :
770  edwards_point_set_aff_str(P, str_x, str_y, is_reduced, base, k, stack);
771  break;
772 
773  case WEIERSTRASS :
774  weierstrass_point_set_aff_str(P, str_x, str_y, is_reduced, base, k, stack);
775  break;
776  }
777 }
778 
779 void
781 {
782  switch(E->type)
783  {
784  case JACOBI_QUARTIC :
785  jacobi_quartic_point_set_neutral(dst, E, stack);
786  break;
787 
788  case EDWARDS :
789  edwards_point_set_neutral(dst, E, stack);
790  break;
791 
792  case WEIERSTRASS :
793  weierstrass_point_set_neutral(dst, E, stack);
794  break;
795  }
796 }
797 
798 void
800 {
801  switch(E->type)
802  {
803  case JACOBI_QUARTIC :
804  jacobi_quartic_point_norm(P, E, stack);
805  break;
806 
807  case EDWARDS :
808  edwards_point_norm(P, E, stack);
809  break;
810 
811  case WEIERSTRASS :
812  weierstrass_point_norm(P, E, stack);
813  break;
814  }
815 }
816 
817 void
819 {
820  switch(E->type)
821  {
822  case JACOBI_QUARTIC :
823  jacobi_quartic_point_get_x_affine(x, P, E, stack);
824  break;
825 
826  case EDWARDS :
827  edwards_point_get_x_affine(x, P, E, stack);
828  break;
829 
830  case WEIERSTRASS :
831  weierstrass_point_get_x_affine(x, P, E, stack);
832  break;
833  }
834 }
835 
836 void
838 {
839  switch(E->type)
840  {
841  case JACOBI_QUARTIC :
842  jacobi_quartic_point_get_y_affine(y, P, E, stack);
843  break;
844 
845  case EDWARDS :
846  edwards_point_get_y_affine(y, P, E, stack);
847  break;
848 
849  case WEIERSTRASS :
850  weierstrass_point_get_y_affine(y, P, E, stack);
851  break;
852  }
853 }
854 
855 void
857 {
858  field_elt_lift(P->x, P->x, k, stack);
859  field_elt_lift(P->y, P->y, k, stack);
860  field_elt_lift(P->z, P->z, k, stack);
861  field_elt_lift(P->t, P->t, k, stack);
862 }
863 
864 bool
866 {
867  switch(E->type)
868  {
869  case JACOBI_QUARTIC :
870  return jacobi_quartic_belongs(P, E, stack);
871  break;
872 
873  case EDWARDS :
874  return edwards_belongs(P, E, stack);
875  break;
876 
877  case WEIERSTRASS :
878  return weierstrass_belongs(P, E, stack);
879  break;
880  }
881  return false;
882 }
883 
884 void
886 {
887  switch(E->type)
888  {
889  case JACOBI_QUARTIC :
890  jacobi_quartic_point_random(P, E, stack);
891  break;
892 
893  case EDWARDS :
894  edwards_point_random(P, E, stack);
895  break;
896 
897  case WEIERSTRASS :
898  weierstrass_point_random(P, E, stack);
899  break;
900  }
901 }
902 
909 void
910 ec_type_str(char** str, const ec_type type)
911 {
912  switch(type)
913  {
914  case JACOBI_QUARTIC :
915  *str = (char*)malloc(strlen("JACOBI QUARTIC") + 1);
916  strcpy(*str, "JACOBI QUARTIC");
917  break;
918 
919  case EDWARDS :
920  *str = (char*)malloc(strlen("EDWARDS") + 1);
921  strcpy(*str, "EDWARDS");
922  break;
923 
924  case WEIERSTRASS :
925  *str = (char*)malloc(strlen("WEIERSTRASS") + 1);
926  strcpy(*str, "WEIERSTRASS");
927  break;
928  }
929 }
930 
931 void
932 ec_curve_str (char **str, ec_curve_srcptr E, const uint8_t base, uint8_t stack)
933 {
934  field_t *k = E->k;
935 
936  char *a_str, *b_str, *G_str, *h_str, *n_str, *k_str, *type_str, *disc_str, *D_str;
937 
938  ec_point P;
939  ec_point_get_pool_elt(P, E->k, stack);
940  ec_point_copy(P, E->G, k);
941  if(!field_elt_iszero(E->G->z, k))
942  {
943  ec_point_norm(P, E, stack);
944  }
945 
946  switch(E->type)
947  {
948  case JACOBI_QUARTIC :
949  ec_type_str(&type_str, E->type);
950  field_str(&k_str, E->k, base, stack);
951  field_elt_str(&a_str, E->a, base, true, k, stack);
952  number_str(&h_str, E->h, base);
953  number_str(&n_str, E->n, base);
954  field_elt_str(&disc_str, E->disc, base, true, k, stack);
955  ec_point_str(&G_str, P, base, true, k, stack);
956 
957  *str = (char*)malloc(strlen(a_str) + strlen(k_str) +
958  strlen(h_str) + strlen(n_str) + strlen(G_str) +
959  strlen(type_str) + strlen(disc_str) + 100);
960 
961  sprintf(*str,"id:%s\ntype:%s\nK:%s\nA:%s\nG:%s\nh:%s\nn:%s\ndisc:%s\n",
962  E->id_curve, type_str, k_str, a_str, G_str, h_str, n_str, disc_str);
963 
964  free(type_str);
965  free(k_str);
966  free(a_str);
967  free(G_str);
968  free(h_str);
969  free(n_str);
970  free(disc_str);
971  ec_point_relax_pool_elt(P, E->k, stack);
972  break;
973 
974  case EDWARDS :
975  ec_type_str(&type_str, E->type);
976  field_str(&k_str, E->k, base, stack);
977  field_elt_str(&a_str, E->a, base, true, k, stack);
978  field_elt_str(&b_str, E->b, base, true, k, stack);
979  number_str(&h_str, E->h, base);
980  number_str(&n_str, E->n, base);
981  field_elt_str(&disc_str, E->disc, base, true, k, stack);
982  ec_point_str(&G_str, P, base, true, k, stack);
983 
984  *str = (char*)malloc(strlen(a_str) + strlen(b_str) + strlen(k_str) +
985  strlen(h_str) + strlen(n_str) + strlen(G_str) +
986  strlen(type_str) + strlen(disc_str) + 100);
987 
988  sprintf(*str,"id:%s\ntype:%s\nK:%s\nA:%s\nD:%s\nG:%s\nh:%s\nn:%s\ndisc:%s\n",
989  E->id_curve, type_str, k_str, a_str, b_str, G_str, h_str, n_str, disc_str);
990 
991  free(type_str);
992  free(k_str);
993  free(a_str);
994  free(b_str);
995  free(G_str);
996  free(h_str);
997  free(n_str);
998  free(disc_str);
999  ec_point_relax_pool_elt(P, E->k, stack);
1000  break;
1001 
1002  case WEIERSTRASS :
1003  ec_type_str(&type_str, E->type);
1004  field_str(&k_str, E->k, base, stack);
1005  field_elt_str(&a_str, E->a, base, true, k, stack);
1006  field_elt_str(&b_str, E->b, base, true, k, stack);
1007  number_str(&h_str, E->h, base);
1008  number_str(&n_str, E->n, base);
1009  field_elt_str(&D_str, E->D, base, true, k, stack);
1010  field_elt_str(&disc_str, E->disc, base, true, k, stack);
1011  ec_point_str(&G_str, P, base, true, k, stack);
1012 
1013  *str = (char*)malloc(strlen(a_str) + strlen(b_str) + strlen(k_str) +
1014  strlen(n_str) + strlen(n_str) + strlen(G_str) + strlen(type_str) +
1015  strlen(D_str) + strlen(disc_str) + 100);
1016 
1017  sprintf(*str,"id:%s\ntype:%s\nK:%s\nA:%s\nB:%s\nG:%s\nh:%s\nn:%s\ndisc:%s\nD:%s",
1018  E->id_curve, type_str, k_str, a_str, b_str, G_str, h_str, n_str, disc_str,
1019  D_str);
1020 
1021  free(type_str);
1022  free(k_str);
1023  free(a_str);
1024  free(b_str);
1025  free(G_str);
1026  free(h_str);
1027  free(n_str);
1028  free(disc_str);
1029  free(D_str);
1030  ec_point_relax_pool_elt(P, E->k, stack);
1031  break;
1032  }
1033 }
1034 
1035 void
1036 ec_curve_print (ec_curve_srcptr E, const uint8_t base, uint8_t stack)
1037 {
1038  char *str;
1039  ec_curve_str(&str, E, base, stack);
1040  printf("%s\n", str);
1041  free(str);
1042 }
1043 
1044 void
1045 ec_point_str (char **str, ec_point_srcptr P, const uint8_t base,
1046  const bool lift, field_srcptr k, uint8_t stack)
1047 {
1048  char *x_str, *y_str, *z_str, *t_str;
1049  field_elt_str(&x_str, P->x, base, lift, k, stack);
1050  field_elt_str(&y_str, P->y, base, lift, k, stack);
1051  field_elt_str(&z_str, P->z, base, lift, k, stack);
1052  field_elt_str(&t_str, P->t, base, lift, k, stack);
1053 
1054  *str = (char*)malloc(strlen(x_str) + strlen(y_str) + strlen(z_str) +
1055  strlen(t_str) + 20);
1056  sprintf(*str, "[%s,\n%s,\n%s,\n%s]", x_str, y_str, z_str, t_str);
1057  free(x_str);
1058  free(y_str);
1059  free(z_str);
1060  free(t_str);
1061 }
1062 
1063 void
1064 ec_point_print (ec_point_srcptr P, const uint8_t base, const bool lift, field_srcptr k, uint8_t stack)
1065 {
1066  char *str;
1067  ec_point_str(&str, P, base, lift, k, stack);
1068  printf("%s\n", str);
1069  free(str);
1070 }
1071 
1072 /*******************************COMPARISON************************************/
1073 
1074 bool
1076 {
1077  switch(E->type)
1078  {
1079  case JACOBI_QUARTIC :
1080  return jacobi_quartic_point_is_neutral(P, E);
1081  break;
1082 
1083  case EDWARDS :
1084  return edwards_point_is_neutral(P, E);
1085  break;
1086 
1087  case WEIERSTRASS :
1088  return weierstrass_point_is_neutral(P, E, stack);
1089  break;
1090  }
1091  return false;
1092 }
1093 
1094 bool
1096 {
1097  switch(E->type)
1098  {
1099  case JACOBI_QUARTIC :
1100  return jacobi_quartic_point_are_equal(P1, P2, E, stack);
1101  break;
1102 
1103  case EDWARDS :
1104  return edwards_point_are_equal(P1, P2, E, stack);
1105  break;
1106 
1107  case WEIERSTRASS :
1108  return weierstrass_point_are_equal(P1, P2, E, stack);
1109  break;
1110  }
1111  return false;
1112 }
1113 
1114 /*******************************OPERATIONS************************************/
1115 
1116 void
1118 {
1119  switch(E->type)
1120  {
1121  case JACOBI_QUARTIC :
1122  jacobi_quartic_point_neg(P3, P1, E);
1123  break;
1124 
1125  case EDWARDS :
1126  edwards_point_neg(P3, P1, E);
1127  break;
1128 
1129  case WEIERSTRASS :
1130  weierstrass_point_neg(P3, P1, E);
1131  break;
1132  }
1133 }
1134 
1135 /* UNIFIED => Resistant to SPA */
1136 
1137 void
1139  ec_curve_srcptr E, uint8_t stack)
1140 {
1141  switch(E->type)
1142  {
1143  case JACOBI_QUARTIC :
1144  jacobi_quartic_point_add_unified(P3, P1, P2, E, stack);
1145  break;
1146 
1147  case EDWARDS :
1148  /* Only EXTENDED_EDWARDS coordinate provide unified addition */
1149  MPHELL_ASSERT(E->f==EXTENDED_EDWARDS, "\nOnly Extended Edwards coordinates are supported \n");
1150  edwards_point_add_unified(P3, P1, P2, E, stack);
1151  break;
1152 
1153  case WEIERSTRASS :
1154  /* Only PROJECTIVE coordinates provide unified addition, JACOBIAN coordinates provide unified multiplication through COZ */
1155  MPHELL_ASSERT(E->f==PROJECTIVE, "\nOnly Projective coordinates are supported \n");
1156  weierstrass_point_add_unified(P3, P1, P2, E, stack);
1157  break;
1158  }
1159 }
1160 
1161 void
1163 {
1164  switch(E->type)
1165  {
1166  case JACOBI_QUARTIC :
1167  jacobi_quartic_point_add_unified(P3, P1, P1, E, stack);
1168  break;
1169 
1170  case EDWARDS :
1171  /* Only EXTENDED_EDWARDS coordinates provide unified addition */
1172  MPHELL_ASSERT(E->f==EXTENDED_EDWARDS, "\nOnly Extended Edwards coordinates are supported \n");
1173  edwards_point_add_unified(P3, P1, P1, E, stack);
1174  break;
1175 
1176  case WEIERSTRASS :
1177  /* Only PROJECTIVE coordinates provide unified addition, JACOBIAN coordinates provide unified multiplication through COZ */
1178  MPHELL_ASSERT(E->f==PROJECTIVE, "\nOnly Projective coordinates are supported \n");
1179  weierstrass_point_add_unified(P3, P1, P1, E, stack);
1180  break;
1181  }
1182 }
1183 
1184 void
1186  ec_curve_srcptr E, uint8_t stack)
1187 {
1188  field_t *k = (field_t*)E->k;
1189  ec_point tmp;
1190  ec_point_get_pool_elt(tmp, k, stack);
1191 
1192  ec_point_neg(tmp, P2, E);
1193  ec_point_add_unified(P3, P1, tmp, E, stack);
1194 
1195  ec_point_relax_pool_elt(tmp, k, stack);
1196 }
1197 
1207 void
1209  ec_curve_srcptr E, uint8_t stack)
1210 {
1211  ec_point_set_neutral(P3, E, stack);
1212  if(!number_iszero(n))
1213  {
1214  field_t *k = (field_t*)E->k;
1215  ec_point tmp;
1216  ec_point_get_pool_elt(tmp, k, stack);
1217  int16_t l = number_log2(n);
1218  int16_t i;
1219 
1220  /* Set n in base 2: n_str=[n_l-1, ..., n_0] */
1221  char n_str[k->bit_size+4];
1222  number_to_bit_string(n_str, n);
1223 
1224  ec_point_copy(tmp, P1, k);
1225 
1226  i = l-1;
1227 
1228  while (i>=0)
1229  {
1230  if (n_str[i]=='1')
1231  {
1232  ec_point_add_unified(P3, P3, tmp, E, stack);
1233  }
1234  ec_point_add_unified(tmp, tmp, tmp, E, stack);
1235  i--;
1236  }
1237  ec_point_relax_pool_elt(tmp, k, stack);
1238  }
1239 }
1240 
1241 void
1243  ec_curve_srcptr E, uint8_t stack)
1244 {
1245  switch(E->type)
1246  {
1247  case JACOBI_QUARTIC :
1248  ec_point_mul_naive_unified(P3, n, P1, E, stack);
1249  break;
1250 
1251  case EDWARDS :
1252  switch(E->f)
1253  {
1254  case EXTENDED_EDWARDS:
1255  /* Only EXTENDED_EDWARDS coordinates provide unified addition */
1256  ec_point_mul_naive_unified(P3, n, P1, E, stack);
1257  break;
1258  default:
1259  mphell_error("ec_point_mul_unified, the only available coordinate system is EXTENDED_EDWARDS for unified multiplication over Edwards curves \n");
1260  break;
1261  }
1262  break;
1263 
1264  case WEIERSTRASS :
1265  switch(E->f)
1266  {
1267  case PROJECTIVE:
1268  /* Only PROJECTIVE coordinates provide unified addition */
1269  ec_point_mul_naive_unified(P3, n, P1, E, stack);
1270  break;
1271  case JACOBIAN:
1272  /* But Jacobian coordinates provide unified multiplication through COZ */
1273  weierstrass_Zmontgomery_Kim(P3, n, P1, E, stack);
1274  /* weierstrass_Zmontgomery_ladder(P3, n, P1, E, stack); */
1275  break;
1276  default :
1277  mphell_error("ec_point_mul_unified, the only available coordinates are PROJECTIVE and JACOBIAN\n");
1278  break;
1279  }
1280  break;
1281 
1282  default :
1283  mphell_error("ec_point_mul_unified, the only available curves are WEIERSTRASS, JACOBI_QUARTIC and EDWARDS\n");
1284  break;
1285  }
1286 }
1287 
1288 /* DEDICATED => Not resistant to SPA, but faster */
1289 
1290 void
1292  ec_curve_srcptr E, uint8_t stack)
1293 {
1294  switch(E->type)
1295  {
1296  case JACOBI_QUARTIC :
1297  /* Only the unified addition is implemented because it is faster than the dedicated addition */
1298  jacobi_quartic_point_add_unified(P3, P1, P2, E, stack);
1299  break;
1300 
1301  case EDWARDS :
1302  edwards_point_add_dedicated(P3, P1, P2, E, stack);
1303  break;
1304 
1305  case WEIERSTRASS :
1306  weierstrass_point_add_dedicated(P3, P1, P2, E, stack);
1307  break;
1308  }
1309 }
1310 
1311 void
1313 {
1314  switch(E->type)
1315  {
1316  case JACOBI_QUARTIC :
1317  /* The dedicated doubling save time compared to the unified doubling */
1318  jacobi_quartic_point_dbl_dedicated(P3, P1, E, stack);
1319  break;
1320 
1321  case EDWARDS :
1322  edwards_point_dbl_dedicated(P3, P1, E, stack);
1323  break;
1324 
1325  case WEIERSTRASS :
1326  weierstrass_point_dbl_dedicated(P3, P1, E, stack);
1327  break;
1328  }
1329 }
1330 
1331 void
1333  ec_curve_srcptr E, uint8_t stack)
1334 {
1335  field_t *k = (field_t*)E->k;
1336  ec_point tmp;
1337  ec_point_get_pool_elt(tmp, k, stack);
1338 
1339  ec_point_neg(tmp, P2, E);
1340  ec_point_add(P3, P1, tmp, E, stack);
1341 
1342  ec_point_relax_pool_elt(tmp, k, stack);
1343 }
1344 
1354 void
1356  ec_curve_srcptr E, uint8_t stack)
1357 {
1358  ec_point_set_neutral(P3, E, stack);
1359  if(!number_iszero(n))
1360  {
1361  field_t *k = (field_t*)E->k;
1362  ec_point tmp;
1363  ec_point_get_pool_elt(tmp, k, stack);
1364  int16_t l = number_log2(n);
1365  int16_t i;
1366 
1367  /* Set n in base 2: n_str=[n_l-1, ..., n_0] */
1368  char n_str[k->bit_size+4];
1369  number_to_bit_string(n_str, n);
1370 
1371  ec_point_copy(tmp, P1, k);
1372 
1373  i = l-1;
1374 
1375  while (i>=0)
1376  {
1377  if (n_str[i]=='1')
1378  {
1379  ec_point_add(P3, P3, tmp, E, stack);
1380  }
1381  ec_point_dbl(tmp, tmp, E, stack);
1382  i--;
1383  }
1384  ec_point_relax_pool_elt(tmp, k, stack);
1385  }
1386 }
1387 
1396 int16_t binary_to_indice(char *str, int16_t beg, int16_t end)
1397 {
1398  /* str = [n_(l-1), ..., n_beg, ..., n_end, ..., n_0] */
1399  /* 0 3 6 l-1 */
1400  MPHELL_ASSERT(str[beg]=='1', "Sliding window error, str[beg]!=1\n");
1401  MPHELL_ASSERT(str[end]=='1', "Sliding window error, str[end]!=1\n");
1402  int16_t i;
1403  uint16_t j = 1;
1404  uint16_t res = 1;
1405  for (i = end-1; i >= beg; i--)
1406  {
1407  if (str[i]=='1')
1408  {
1409  res+=((uint16_t)1<<j);
1410  }
1411  j++;
1412  }
1413  return ((res-1)/2);
1414 }
1415 
1424 int16_t binary_to_indice_new(char *str, int16_t beg, int16_t end)
1425 {
1426  /* str = [n_(l-1), ..., n_beg, ..., n_end, ..., n_0] */
1427  /* 0 3 6 l-1 */
1428  int16_t i;
1429  uint16_t j = 0;
1430  uint16_t res = 0;
1431  for (i = end; i >= beg; i--)
1432  {
1433  if (str[i]=='1')
1434  {
1435  res+=((uint16_t)1<<j);
1436  }
1437  j++;
1438  }
1439  return res;
1440 }
1441 
1451 void
1453  ec_curve_srcptr E, uint8_t stack)
1454 {
1455  ec_point_set_neutral(P3, E, stack);
1456 
1457  field_t *k = (field_t*)E->k;
1458  ec_point tmp;
1459  ec_point_get_pool_elt(tmp, k, stack);
1460 
1461  int16_t e;
1462  int16_t pr;
1463  int16_t l = number_log2(n);
1464  int16_t i, s, h;
1465 
1466  /* Set n in base 2: n_str=[n_l-1, ..., n_0] */
1467  char n_str[k->bit_size+4];
1468  number_to_bit_string(n_str, n);
1469 
1470  /* Constant e */
1471  if(l<70)
1472  {
1473  /* Precompute 3P1, 5P1, 7P1 */
1474  e = 3;
1475  pr = 3;
1476  }
1477  else if(l<197)
1478  {
1479  /* Precompute 3P1, 5P1, 7P1, 9P1, 11P1, 13P1, 15P1 */
1480  e = 4;
1481  pr = 7;
1482  }
1483  else if(l<539)
1484  {
1485  /* Precompute 3P1, 5P1, 7P1, 9P1, 11P1, 13P1, 15P1, 17P1, 19P1, 21P1, 23P1, 25P1, 27P1, 29P1, 31P1 */
1486  e = 5;
1487  pr = 15;
1488  }
1489  else
1490  {
1491  /* Precompute 3P1, ... , 63P1 (31 values) */
1492  e = 6;
1493  pr = 31;
1494  }
1495 
1496  /* Precomputes value 3P1, 5P1, ..., (2^e - 1)P1 */
1497 
1498  ec_point tab[pr+1];
1499 
1500  for(i = 0; i <= pr; i++)
1501  {
1502  ec_point_get_pool_elt(tab[i], k, stack);
1503  }
1504 
1505  ec_point_dbl(tmp, P1, E, stack); /* tmp = 2P1 */
1506 
1507  ec_point_copy(tab[0], P1, k); /* tab[0] = P1 */
1508  for(i = 1; i <= pr; i++)
1509  {
1510  /* tab[i]=(2*i + 1) P1 */
1511  ec_point_add(tab[i], tmp, tab[i-1], E, stack);
1512  }
1513 
1514  /* Sliding method */
1515  i = 0; /* l-1 */
1516 
1517  while(i < l)
1518  {
1519  if (n_str[i]=='0')
1520  {
1521  ec_point_dbl(P3, P3, E, stack);
1522  i++;
1523  }
1524  else
1525  {
1526  s = i+e-1; /* l-1 -> l-4 for e = 4 */
1527  if (s > l-1)
1528  {
1529  s = l-1;
1530  }
1531  while(n_str[s]=='0')
1532  {
1533  s--;
1534  }
1535  if(i!=0)
1536  {
1537  for(h=1; h<=s-i+1; h++)
1538  {
1539  ec_point_dbl(P3, P3, E, stack);
1540  }
1541  ec_point_add(P3, P3, tab[binary_to_indice(n_str, i, s)], E, stack);
1542  }
1543  else
1544  {
1545  ec_point_copy(P3, tab[binary_to_indice(n_str, i, s)], k);
1546  }
1547  i=s+1;
1548  }
1549  }
1550 
1551  for(i = 0; i <= pr; i++)
1552  {
1553  ec_point_relax_pool_elt(tab[i], k, stack);
1554  }
1555  ec_point_relax_pool_elt(tmp, k, stack);
1556 }
1557 
1558 void
1559 ec_point_mul_with_precomp (ec_point_ptr P3, number_srcptr n, ec_point * tab_P1,
1560  int16_t win_size, ec_curve_srcptr E, uint8_t stack)
1561 {
1562  ec_point_set_neutral(P3, E, stack);
1563 
1564  int16_t e = win_size;
1565  int16_t l = number_log2(n);
1566  int16_t i, s, h;
1567 
1568  /* Set n in base 2: n_str=[n_l-1, ..., n_0] */
1569  char n_str[E->k->bit_size+4];
1570  number_to_bit_string(n_str, n);
1571 
1572  /* Sliding method */
1573  i = 0; /* l-1 */
1574 
1575  while(i < l)
1576  {
1577  if (n_str[i]=='0')
1578  {
1579  ec_point_dbl(P3, P3, E, stack);
1580  i++;
1581  }
1582  else
1583  {
1584  s = i+e-1; /* l-1 -> l-4 for e = 4 */
1585  if (s > l-1)
1586  {
1587  s = l-1;
1588  }
1589  while(n_str[s]=='0')
1590  {
1591  s--;
1592  }
1593  if(i!=0)
1594  {
1595  for(h=1; h<=s-i+1; h++)
1596  {
1597  ec_point_dbl(P3, P3, E, stack);
1598  }
1599  ec_point_add(P3, P3, tab_P1[binary_to_indice(n_str, i, s)], E, stack);
1600  }
1601  else
1602  {
1603  ec_point_copy(P3, tab_P1[binary_to_indice(n_str, i, s)], E->k);
1604  }
1605  i=s+1;
1606  }
1607  }
1608 }
1609 
1610 void
1611 ec_point_2mul_with_precomp (ec_point_ptr P3, number_srcptr n1, ec_point * tab_P1,
1612  number_srcptr n2, ec_point * tab_P2,
1613  int16_t win_size, ec_curve_srcptr E, uint8_t stack)
1614 {
1615  ec_point_set_neutral(P3, E, stack);
1616 
1617  int16_t i, s, h, l, i1, i2, a, b;
1618  int16_t e = win_size;
1619  int16_t l1 = number_log2(n1);
1620  int16_t l2 = number_log2(n2);
1621 
1622  /* Set n1, n2 in base 2: n1_str=[n_l-1, ..., n_0] */
1623  char n1_str[E->k->bit_size+4];
1624  char n2_str[E->k->bit_size+4];
1625  number_to_bit_string(n1_str, n1);
1626  number_to_bit_string(n2_str, n2);
1627 
1628  /* Sliding method */
1629  i = 0; /* l-1 */
1630  i1 = 0;
1631  i2 = 0;
1632  bool init = false;
1633 
1634  if(l1>l2)
1635  {
1636  l=l2;
1637  while(i1<l1-l2)
1638  {
1639  if (n1_str[i1]=='0')
1640  {
1641  ec_point_dbl(P3, P3, E, stack);
1642  i1++;
1643  }
1644  else
1645  {
1646  s = i1+e-1;
1647  if(s>l1-l2-1)
1648  {
1649  s = l1-l2-1;
1650  }
1651  while(n1_str[s]=='0')
1652  {
1653  s--;
1654  }
1655  if(init)
1656  {
1657  for(h=1; h<=s-i1+1; h++)
1658  {
1659  ec_point_dbl(P3, P3, E, stack);
1660  }
1661  ec_point_add(P3, P3, tab_P1[binary_to_indice_new(n1_str, i1, s)], E, stack);
1662  }
1663  else
1664  {
1665  ec_point_copy(P3, tab_P1[binary_to_indice_new(n1_str, i1, s)], E->k);
1666  init = true;
1667  }
1668  i1=s+1;
1669  }
1670  }
1671  }
1672  else if(l2>l1)
1673  {
1674  l=l1;
1675  while(i2<l2-l1)
1676  {
1677  if (n2_str[i2]=='0')
1678  {
1679  ec_point_dbl(P3, P3, E, stack);
1680  i2++;
1681  }
1682  else
1683  {
1684  s = i2+e-1;
1685  if(s>l2-l1-1)
1686  {
1687  s = l2-l1-1;
1688  }
1689  while(n2_str[s]=='0')
1690  {
1691  s--;
1692  }
1693  if(init)
1694  {
1695  for(h=1; h<=s-i2+1; h++)
1696  {
1697  ec_point_dbl(P3, P3, E, stack);
1698  }
1699  ec_point_add(P3, P3, tab_P2[binary_to_indice_new(n2_str, i2, s)], E, stack);
1700  }
1701  else
1702  {
1703  ec_point_copy(P3, tab_P2[binary_to_indice_new(n2_str, i2, s)], E->k);
1704  init = true;
1705  }
1706  i2=s+1;
1707  }
1708  }
1709  }
1710  else
1711  {
1712  l=l1;
1713  }
1714  while(i < l)
1715  {
1716  if ((n1_str[i+i1]=='0') && (n2_str[i+i2]=='0'))
1717  {
1718  ec_point_dbl(P3, P3, E, stack);
1719  i++;
1720  }
1721  else
1722  {
1723  s = i+e-1; /* l-1 -> l-4 for e = 4 */
1724  if (s > l-1)
1725  {
1726  s = l-1;
1727  }
1728  while((n1_str[s+i1]=='0') && (n2_str[s+i2]=='0'))
1729  {
1730  s--;
1731  }
1732  if(init)
1733  {
1734  for(h=1; h<=s-i+1; h++)
1735  {
1736  ec_point_dbl(P3, P3, E, stack);
1737  }
1738  a = binary_to_indice_new(n1_str, i+i1, s+i1);
1739  b = binary_to_indice_new(n2_str, i+i2, s+i2);
1740  if(a == 0)
1741  {
1742  ec_point_add(P3, P3, tab_P2[b], E, stack);
1743  }
1744  else if (b == 0)
1745  {
1746  ec_point_add(P3, P3, tab_P1[a], E, stack);
1747  }
1748  else
1749  {
1750  ec_point_add(P3, P3, tab_P1[a], E, stack);
1751  ec_point_add(P3, P3, tab_P2[b], E, stack);
1752  }
1753  }
1754  else
1755  {
1756  a = binary_to_indice_new(n1_str, i+i1, s+i1);
1757  b = binary_to_indice_new(n2_str, i+i2, s+i2);
1758  if(a == 0)
1759  {
1760  ec_point_copy(P3, tab_P2[b], E->k);
1761  }
1762  else if (b == 0)
1763  {
1764  ec_point_copy(P3, tab_P1[a], E->k);
1765  }
1766  else
1767  {
1768  ec_point_copy(P3, tab_P1[a], E->k);
1769  ec_point_add(P3, P3, tab_P2[b], E, stack);
1770  }
1771  init = true;
1772  }
1773  i=s+1;
1774  }
1775  }
1776 }
1777 
1778 void
1779 ec_point_mul(ec_point_ptr P3, number_srcptr n, ec_point_srcptr P1,
1780  ec_curve_srcptr E, uint8_t stack)
1781 {
1782  switch(E->type)
1783  {
1784  case JACOBI_QUARTIC :
1785  ec_point_mul_sliding_window(P3, n, P1, E, stack);
1786  break;
1787 
1788  case EDWARDS :
1789  ec_point_mul_sliding_window(P3, n, P1, E, stack);
1790  break;
1791 
1792  case WEIERSTRASS :
1793  switch(E->f)
1794  {
1795  case PROJECTIVE:
1796  ec_point_mul_sliding_window(P3, n, P1, E, stack);
1797  break;
1798  case JACOBIAN:
1799  ec_point_mul_sliding_window(P3, n, P1, E, stack);
1800  break;
1801  default :
1802  mphell_error("ec_point_mul, the only available coordinates are PROJECTIVE and JACOBIAN\n");
1803  break;
1804  }
1805  break;
1806 
1807  default :
1808  mphell_error("ec_point_mul, the only available curves are WEIERSTRASS, JACOBI_QUARTIC and EDWARDS\n");
1809  break;
1810  }
1811 }
1812 
1813 /***********************************CONVERSION JACOBI WEIERSTRASS********************************/
1814 
1815 void
1817  ec_curve_srcptr E, uint8_t stack)
1818 {
1819  /* E: y^2 = z^2 + 2ax^2 + t^2; x^2 = zt; a != 1 */
1820  /* dst = (X3,X3,Z3,T3) */
1821  /* P = (X1,Y1,Z1,T1) */
1822 
1823  field_t *k = E->k;
1824 
1825  ec_point P;
1826  ec_point_get_pool_elt(P, E->k, stack);
1827  ec_point_copy(P, P1, k);
1828  ec_point_norm(P, E, stack);
1829 
1831  {
1832  weierstrass_point_set_neutral(dst, E, stack);
1833  }
1834  else
1835  {
1836  field_elt t2, t1;
1837  field_elt_get_pool_elt(&t2, k, stack);
1838  field_elt_get_pool_elt(&t1, k, stack);
1839 
1840  field_elt_set_one(t1, k); /* t1 = 1 */
1841  field_elt_neg(t1, t1, k); /* t1 = -1 */
1842 
1843  if (field_elt_iszero(P->x, k) && field_elt_cmp(P->y, t1, k)==0 && field_elt_isone(P->z, k))
1844  {
1845  /* Point of order 2 */
1846  field_elt_set_ui(t1, 4, false, k, stack); /* t1 = 4 */
1847  field_elt_set_ui(t2, 3, false, k, stack); /* t2 = 3 */
1848  field_elt_div(t1, t1, t2, k, stack); /* t1 = 4 / 3 */
1849  field_elt_neg(t1, t1, k); /* t1 = -(4 / 3) */
1850  field_elt_mul(dst->x, t1, E->a, k, stack); /* X3 = -(4 / 3).a */
1851  field_elt_set_ui(dst->y, 0, false, k, stack); /* Y3 = 0 */
1852  }
1853  else
1854  {
1855  field_elt_sqr(t1, P->z, k, stack); /* t1 = Z1^2 */
1856  field_elt_add(dst->x, P->y, t1, k); /* X3 = Y1 + Z1^2 */
1857  field_elt_copy(dst->y, dst->x, k); /* Y3 = Y1 + Z1^2 */
1858  field_elt_add(dst->x, dst->x, dst->x, k); /* X3 = 2.(Y1 + Z1^2) */
1859  field_elt_sqr(t1, P->x, k, stack); /* t1 = X1^2 */
1860  field_elt_div(dst->x, dst->x, t1, k, stack); /* X3 = 2.(Y1 + Z1^2)/(X1^2) */
1861  field_elt_add(t1, E->a, E->a, k); /* t1 = 2.a */
1862  field_elt_set_ui(t2, 3, false, k, stack); /* t2 = 3 */
1863  field_elt_div(t1, t1, t2, k, stack); /* t1 = 2.a/3 */
1864  field_elt_add(dst->x, dst->x, t1, k); /* X3 = 2.(Y1+Z1^2)/(X1^2) + 2.a/3 */
1865 
1866  field_elt_add(dst->y, dst->y, dst->y, k); /* Y3 = 2.(Y1 + Z1^2) */
1867  field_elt_add(dst->y, dst->y, dst->y, k); /* Y3 = 4.(Y1 + Z1^2) */
1868  field_elt_add(t1, E->a, E->a, k); /* t1 = 2.a */
1869  field_elt_add(t1, t1, t1, k); /* t1 = 4.a */
1870  field_elt_sqr(t2, P->x, k, stack); /* t2 = X1^2 */
1871  field_elt_mul(t1, t1, t2, k, stack); /* t1 = 4.a.X1^2 */
1872  field_elt_mul(t2, t2, P->x, k, stack); /* t2 = X1^3 */
1873  field_elt_add(dst->y, dst->y, t1, k); /* Y3 = 4.(Y1 + Z1^2) + 4.a.X1^2 */
1874  field_elt_div(dst->y, dst->y, t2, k, stack); /* Y3 = (4.(Y1 + Z1^2) + 4.a.X1^2)/X1^3 */
1875  field_elt_mul(dst->y, dst->y, P->z, k, stack); /* Y3 = Z1.(4.(Y1 + Z1^2) + 4.a.X1^2)/X1^3 */
1876  }
1877 
1878  field_elt_set_one(dst->z, k); /* Z3 = 1 */
1879  field_elt_set_one(dst->t, k); /* T3 = 1 */
1880 
1881  ec_point_relax_pool_elt(P, k, stack);
1882  field_elt_relax_pool_elt(&t2, k, stack);
1883  field_elt_relax_pool_elt(&t1, k, stack);
1884  }
1885 }
1886 
1887 void
1889 {
1890  field_t *k = E->k;
1891  field_elt t, t1, t2;
1892  field_elt_get_pool_elt(&t, k, stack);
1893  field_elt_get_pool_elt(&t1, k, stack);
1894  field_elt_get_pool_elt(&t2, k, stack);
1895 
1896  field_elt_sqr(t2, E->a, k, stack); /* t2 = a^2 */
1897  field_elt_set_ui(t1, 3, false, k, stack); /* t1 = 3 */
1898  field_elt_div(t, t2, t1, k, stack); /* t = a^2 / 3 */
1899  field_elt_set_one(t1, k); /* t1 = 1 */
1900  field_elt_add(t, t, t1, k); /* t = (a^2)/3 + 1 */
1901  field_elt_set_ui(t1, 4, false, k, stack); /* t1 = 4 */
1902  field_elt_neg(t1, t1, k); /* t1 = -4 */
1903  field_elt_mul(E_res->a, t, t1, k, stack); /* Aw = -4((a^2)/3 + 1) */
1904 
1905  field_elt_set_ui(t, 64, false, k, stack); /* t = 64 */
1906  field_elt_set_ui(t1, 27, false, k, stack); /* t1 = 27 */
1907  field_elt_div(t, t, t1, k, stack); /* t = 64 / 27 */
1908  field_elt_mul(t2, t2, E->a, k, stack); /* t2 = a^3 */
1909  field_elt_mul(E_res->b, t2, t, k, stack); /* Bw = (64/27).a^3 */
1910  field_elt_set_ui(t, 4, false, k, stack); /* t = 4 */
1911  field_elt_set_ui(t1, 3, false, k, stack); /* t1 = 3 */
1912  field_elt_div(t, t, t1, k, stack); /* t = 4 / 3 */
1913  field_elt_mul(t, t, E->a, k, stack); /* t = (4/3)a */
1914  field_elt_mul(t, t, E_res->a, k, stack); /* t = (4/3)a.Aw */
1915  field_elt_add(E_res->b, E_res->b, t, k); /* Bw = (64/27).a^3 + (4/3)a.Aw */
1916 
1917  number_copy(E_res->h, E->h);
1918  number_copy(E_res->n, E->n);
1919  E_res->k = (field_t*)(E->k); /* The same field is used, do not free 2 times */
1920 
1921  jacobi_quartic_point_to_weierstrass_point(E_res->G, E->G, E, stack);
1922 
1923  E_res->type = WEIERSTRASS;
1924  E_res->f = PROJECTIVE;
1925  ec_compute_disc(E_res, stack);
1926  ec_test_spec(E_res, stack);
1927 
1928  if(!weierstrass_belongs(E_res->G, E_res, stack))
1929  {
1930  mphell_error("ERROR: jacobi_quartic_to_weierstrass\n");
1931  mphell_error("G do not belong to E_res\n");
1932  }
1933 
1934  if(E->id_curve != NULL)
1935  {
1936  strcpy(E_res->id_curve, E->id_curve);
1937  }
1938  else
1939  {
1940  strcpy(E_res->id_curve, "no_name");
1941  }
1942 
1943  field_elt_relax_pool_elt(&t, k, stack);
1944  field_elt_relax_pool_elt(&t1, k, stack);
1945  field_elt_relax_pool_elt(&t2, k, stack);
1946 }
1947 
1948 void
1950 {
1951  /* E: y^2 = z^2 + 2ax^2 + t^2; x^2 = zt; a != 1 */
1952  /* dst = (X3,X3,T3,Z3) */
1953  /* P = (X1,Y1,Z1,T1) */
1954 
1955  field_t *k = E->k;
1956 
1957  ec_point P;
1958  ec_point_get_pool_elt(P, k, stack);
1959  ec_point_copy(P, P1, k);
1960  ec_point_norm(P, E, stack);
1961 
1962  if(weierstrass_point_is_neutral(P, E, stack))
1963  {
1964  jacobi_quartic_point_set_neutral(dst, E, stack);
1965  }
1966  else
1967  {
1968  field_elt t1, t2;
1969  field_elt_get_pool_elt(&t1, k, stack);
1970  field_elt_get_pool_elt(&t2, k, stack);
1971 
1972  field_elt_set_ui(t1, 3, false, k, stack); /* t1 = 3 */
1973  field_elt_div(t1, E->a, t1, k, stack); /* t1 = a / 3 */
1974  field_elt_set_ui(t2, 4, false, k, stack); /* t2 = 4 */
1975  field_elt_mul(t1, t1, t2, k, stack); /* t1 = (4/3).a */
1976 
1977  field_elt_neg(t2, t1, k); /* t2 = -(4/3).a */
1978 
1979  if(field_elt_cmp(t2, P->x, k)==0 && field_elt_iszero(P->y, k))
1980  {
1981  /* dst = (0, -1, 1, 0) */
1982  field_elt_set_ui(dst->x, 0, false, k, stack);
1983  field_elt_set_one(dst->y, k);
1984  field_elt_neg(dst->y, dst->y, k);
1985  field_elt_set_one(dst->z, k);
1986  field_elt_set_ui(dst->t, 0, false, k, stack);
1987 
1988  }
1989  else
1990  {
1991  /* Same formula but we multiply each X3,Y3,Z3 coordinates by Y1 */
1992  field_elt_add(t2, t1, t1, k); /* t2 = (8/3).a */
1993  field_elt_add(dst->x, P->x, P->x, k); /* X3 = 2.X1 */
1994  field_elt_copy(dst->y, dst->x, k); /* Y3 = 2.X1 */
1995  field_elt_add(dst->x, dst->x, t2, k); /* X3 = 2.X1 + (8/3).a */
1996  field_elt_mul(dst->x, dst->x, P->y, k, stack); /* X3 = (2.X1 + (8/3).a).Y1 */
1997 
1998  field_elt_sub(dst->y, dst->y, t1, k); /* Y3 = 2.X1 - (4/3).a */
1999  field_elt_add(t2, P->x, t1, k); /* t2 = X1 + (4/3).a */
2000  field_elt_sqr(t2, t2, k, stack); /* t2 = (X1 + (4/3).a)^2 */
2001  field_elt_mul(dst->y, dst->y, t2, k, stack); /* Y3 = (2.X1 - (4/3).a).(X1 + (4/3).a)^2 */
2002  field_elt_sqr(t2, P->y, k, stack); /* t2 = Y1^2 */
2003  field_elt_sub(dst->y, dst->y, t2, k); /* Y3 = (2.X1 - (4/3).a).(X1 + (4/3).a)^2 - Y1^2 */
2004 
2005  field_elt_copy(dst->z, t2, k); /* Z3 = Y1^2 */
2006  field_elt_sqr(dst->t, dst->x, k, stack); /* T3 = X3^2 */
2007  field_elt_div(dst->t, dst->t, dst->z, k, stack); /* T3 = (X3^2)/Z3 */
2008 
2009  ec_point P_test;
2010  ec_point_get_pool_elt(P_test, E->k, stack);
2011  jacobi_quartic_point_to_weierstrass_point(P_test, dst, E, stack);
2012  ec_point_norm(P_test, E, stack);
2013 
2014  if(!ec_point_are_equal(P_test, P, E, stack))
2015  {
2016  field_elt_neg(dst->y, dst->y, k); /* Y3 = -(X3^4 + 2.a.X3^2 + 1)^(1/2) */
2017  }
2018  ec_point_relax_pool_elt(P_test, k, stack);
2019  }
2020 
2021  field_elt_relax_pool_elt(&t1, k, stack);
2022  field_elt_relax_pool_elt(&t2, k, stack);
2023  ec_point_relax_pool_elt(P, k, stack);
2024  }
2025 }
2026 
2027 void
2028 weierstrass_to_jacobi_quartic (ec_curve_ptr E_res, ec_curve_srcptr E, const bool determined, fe_ptr teta, uint8_t stack)
2029 {
2030  /* E: y^2 = y^2 = x^3 + a.x + b */
2031  /* E_res: y^2 = bj.x^4 + 2aj.x^2 + 1 */
2032 
2033  field_t *k = E->k;
2034  field_elt t1, t2;
2035  field_elt_get_pool_elt(&t1, k, stack);
2036  field_elt_get_pool_elt(&t2, k, stack);
2037 
2038  if(!determined)
2039  {
2040  /* We compute the (3 possible candidates for) teta */
2041  ec_point P1,P2,P3;
2042  ec_point_get_pool_elt(P1, E->k, stack);
2043  ec_point_get_pool_elt(P2, E->k, stack);
2044  ec_point_get_pool_elt(P3, E->k, stack);
2045  weierstrass_points_of_order_2(P1, P2, P3, E, stack);
2046 
2047  /* And we test if we took the good one */
2048  if(!weierstrass_point_are_equal(P1, P2, E, stack))
2049  {
2050  do
2051  {
2052  field_elt_copy(teta,P1->x, k);
2053  field_elt_sqr(t1, teta, k, stack); /* t1 = teta^2 */
2054  field_elt_set_ui(t2, 3, false, k, stack); /* t2 = 3 */
2055  field_elt_mul(t1, t1, t2, k, stack); /* t1 = 3.teta^2 */
2056  field_elt_set_ui(t2, 4, false, k, stack); /* t2 = 4 */
2057  field_elt_mul(t2, t2, E->a, k, stack); /* t2 = 4.a */
2058  field_elt_add(t1, t1, t2, k); /* t1 = 3.teta^2 + 4.a */
2059  field_elt_set_ui(t2, 16, false, k, stack); /* t2 = 16 */
2060  field_elt_neg(t2, t2, k); /* t2 = -16 */
2061  field_elt_div(E_res->b, t1, t2, k, stack); /* bj = -(3.teta^2 + 4.a)/16 */
2062  ec_point_copy(P1,P2, k);
2063  ec_point_copy(P2,P3, k);
2064  }while(!field_elt_isone(E_res->b, k));
2065  /* At this point theta has been computed and checked. */
2066  }
2067  else
2068  {
2069  field_elt_copy(teta,P1->x, k);
2070  field_elt_sqr(t1, teta, k, stack); /* t1 = teta^2 */
2071  field_elt_set_ui(t2, 3, false, k, stack); /* t2 = 3 */
2072  field_elt_mul(t1, t1, t2, k, stack); /* t1 = 3.teta^2 */
2073  field_elt_set_ui(t2, 4, false, k, stack); /* t2 = 4 */
2074  field_elt_mul(t2, t2, E->a, k, stack); /* t2 = 4.a */
2075  field_elt_add(t1, t1, t2, k); /* t1 = 3.teta^2 + 4.a */
2076  field_elt_set_ui(t2, 16, false, k, stack); /* t2 = 16 */
2077  field_elt_neg(t2, t2, k); /* t2 = -16 */
2078  field_elt_div(E_res->b, t1, t2, k, stack); /* bj = -(3.teta^2 + 4.a)/16 */
2079  }
2080 
2081  ec_point_relax_pool_elt(P1, k, stack);
2082  ec_point_relax_pool_elt(P2, k, stack);
2083  ec_point_relax_pool_elt(P3, k, stack);
2084  }
2085  else
2086  {
2087  field_elt_sqr(t1, teta, k, stack); /* t1 = teta^2 */
2088  field_elt_set_ui(t2, 3, false, k, stack); /* t2 = 3 */
2089  field_elt_mul(t1, t1, t2, k, stack); /* t1 = 3.teta^2 */
2090  field_elt_set_ui(t2, 4, false, k, stack); /* t2 = 4 */
2091  field_elt_mul(t2, t2, E->a, k, stack); /* t2 = 4.a */
2092  field_elt_add(t1, t1, t2, k); /* t1 = 3.teta^2 + 4.a */
2093  field_elt_set_ui(t2, 16, false, k, stack); /* t2 = 16 */
2094  field_elt_neg(t2, t2, k); /* t2 = -16 */
2095  field_elt_div(E_res->b, t1, t2, k, stack); /* bj = -(3.teta^2 + 4.a)/16 */
2096  /* We could eventually add an MPHELL ASSERT to check that b_j is indeed equals to one */
2097  }
2098  field_elt_set_ui(t1, 3, false, k, stack); /* t1 = 3 */
2099  field_elt_neg(t1, t1, k); /* t1 = -3 */
2100  field_elt_mul(t1,t1,teta, k, stack); /* t1 = -3.teta */
2101  field_elt_set_ui(t2, 4, false, k, stack); /* t2 = 4 */
2102  field_elt_div(E_res->a, t1, t2, k, stack); /* aj = -(3.teta)/4 */
2103 
2104  E_res->k = (field_t*)(E->k); /* The same field is used, do not free 2 times */
2105  E_res->type = JACOBI_QUARTIC;
2106  E_res->f = PROJECTIVE;
2107  ec_compute_disc(E_res, stack);
2108  ec_test_spec(E_res, stack);
2109 
2110  number_copy(E_res->h, E->h);
2111  number_copy(E_res->n, E->n);
2112 
2113  weierstrass_point_to_jacobi_quartic_point(E_res->G, E->G, E_res, stack);
2114 
2115  if(!jacobi_quartic_belongs(E_res->G, E_res, stack))
2116  {
2117  mphell_error("ERROR: weierstrass_to_jacobi_quartic\n");
2118  mphell_error("G do not belong to E_res\n");
2119  }
2120 
2121  if(E->id_curve != NULL)
2122  {
2123  strcpy(E_res->id_curve, E->id_curve);
2124  }
2125  else
2126  {
2127  strcpy(E_res->id_curve, "no_name");
2128  }
2129 
2130  field_elt_relax_pool_elt(&t1, k, stack);
2131  field_elt_relax_pool_elt(&t2, k, stack);
2132 }
2133 
2134 /***********************************CONVERSION EDWARDS WEIERSTRASS********************************/
2135 
2136 /* The main reference for this part are [BBJ+08,Theorem3.2] for the conversion
2137  * between Montgomery and Twisted Edwards Curves and then the [CS17,§2.4]
2138  * for the conversion between short Weierstrass and Montgomery. There is also
2139  * in [CS17,§2.5] formulas for conversion between Montgomery and Twisted
2140  * Edwards curves
2141  *
2142  */
2143 void
2145 {
2146  ec_point P;
2147  field_elt c,d,e,f;
2148  field_t *k = E->k;
2149 
2150  E_res->k = (field_t*)(E->k);
2151  E_res->type = WEIERSTRASS;
2152  number_copy(E_res->h, E->h);
2153  number_copy(E_res->n, E->n);
2154  E_res->f=PROJECTIVE;
2155 
2156  field_elt_get_pool_elt(&c, k, stack);
2157  field_elt_get_pool_elt(&d, k, stack);
2158  field_elt_get_pool_elt(&e, k, stack);
2159  field_elt_get_pool_elt(&f, k, stack);
2160  ec_point_get_pool_elt(P, k, stack);
2161  ec_point_copy(P,E->G, k);
2162 
2163  /* First we normalise the point P */
2164  if(!field_elt_isone(P->z, k))
2165  {
2166  edwards_point_norm(P,E, stack);
2167  }
2168 
2169  /* First step Edwards to Montgomery
2170  * (here a d should be understood as coefficients of the
2171  * twisted Edwards curve )
2172  */
2173  field_elt_sub(c,E->a,E->b, k); /* c = a -d */
2174  field_elt_inv(c,c, k, stack); /* c = 1 / (a - d) */
2175  field_elt_add(c,c,c, k); /* c = 2 / (a - d) */
2176  field_elt_add(d,c,c, k); /* B = 4 / (a - d) (stored in d) */
2177  field_elt_add(e,E->a,E->b, k); /* e = a + d */
2178  field_elt_mul(e,e,c, k, stack); /* A = 2 ( a + d ) / ( a - d ) (stored in e) */
2179  /* We have computed the coefficients of the birationnally equivalent
2180  * Montgomery curve we have also to compute the image of E->G
2181  */
2182  field_elt_set_one(c,k);
2183  field_elt_sub(c,c,P->y, k);
2184  field_elt_inv(c,c, k, stack); /* c = 1 /(1-v) */
2185  field_elt_inc(f,P->y, k);
2186  field_elt_mul(f,c,f, k, stack); /* f = (1 + v)/(1 -v) */
2187  field_elt_div(P->y,f,P->x, k, stack); /* y = (1 + v)/((1 -v) * u) */
2188  field_elt_copy(P->x,f, k); /* x = (1 + v)/(1 -v) */
2189 
2190 
2191  /* Second step Montgomery to short Weierstras
2192  * At this step we have a Montgomery curve with coefficients (e,d)
2193  * instead of the usual notation A,B
2194  */
2195  field_elt_set_ui(f, 3, false, k, stack);
2196  field_elt_div(c,e,f, k, stack); /* c = A / 3 */
2197  field_elt_add(P->x, P->x, c, k);
2198  field_elt_div(P->x, P->x, d, k, stack); /* u = ( x + A / 3) / B */
2199  field_elt_copy(E_res->b,d, k);
2200  field_elt_div(P->y, P->y,d, k, stack); /* v = y / B */
2201  field_elt_copy(E_res->a,e, k);
2202  field_elt_set_one(P->z,k);
2203  field_elt_set_one(P->t,k);
2204  ec_point_copy(E_res->G,P, k);
2205 
2206  /* After the computation of the image of E->G we compute the short
2207  * Weierstrass coefficients we have a=1/B**2(1-A^2/3) b = (A/(3*B**3))*(2 * A**2/9 -1)
2208  */
2209  field_elt_sqr(e,E_res->a, k, stack); /* e = A^2 */
2210  field_elt_div(c,e,f, k, stack); /* c = A^2 /3 */
2211  field_elt_set_one(e,k);
2212  field_elt_sub(e,e,c, k); /* e = 1 - A^2 /3 */
2213  field_elt_inv(d,E_res->b, k, stack); /* d = 1 / B */
2214  field_elt_sqr(c,d, k, stack); /* c = 1 / B^2 */
2215  field_elt_mul(e,c,e, k, stack); /* e = ( 1 - A^2 /3 ) / B^2 */
2216  field_elt_div(f,E_res->a,f, k, stack); /* f = A / 3 */
2217  field_elt_sqr(c,f, k, stack); /* c = A^2 /9 */
2218  field_elt_add(c,c,c, k); /* c = 2 A^2 /9 */
2219  field_elt_dec(c,c, k); /* c = 2 A^2 /9 -1 */
2220  field_elt_mul(c,c,f, k, stack); /* c = ( A / 3 ) (2 A^2 /9 - 1) */
2221  field_elt_sqr(f,d, k, stack); /* f = 1 / B^2 */
2222  field_elt_mul(c,c,f, k, stack); /* c = ( A / 3 ) (2 A^2 /9 - 1) / B^2 */
2223  field_elt_mul(E_res->b,d,c, k, stack); /* c = ( A / 3 ) (2 A^2 /9 - 1) / B^3 */
2224  field_elt_copy(E_res->a,e, k);
2225 
2226  if(E->id_curve != NULL)
2227  {
2228  strcpy(E_res->id_curve, E->id_curve);
2229  }
2230  else
2231  {
2232  strcpy(E_res->id_curve, "no_name");
2233  }
2234 
2235  ec_compute_disc(E_res, stack);
2236  ec_test_spec(E_res, stack);
2237 
2238  /* We now free the memory */
2239  field_elt_relax_pool_elt(&c, k, stack);
2240  field_elt_relax_pool_elt(&d, k, stack);
2241  field_elt_relax_pool_elt(&e, k, stack);
2242  field_elt_relax_pool_elt(&f, k, stack);
2243  ec_point_relax_pool_elt(P, k, stack);
2244 }
2245 
2246 void
2248  ec_curve_srcptr E, uint8_t stack)
2249 {
2250  field_elt c,d,e,f;
2251  field_t *k = E->k;
2252 
2253  field_elt_get_pool_elt(&c, k, stack);
2254  field_elt_get_pool_elt(&d, k, stack);
2255  field_elt_get_pool_elt(&e, k, stack);
2256  field_elt_get_pool_elt(&f, k, stack);
2257  ec_point_copy(dst,P, k);
2258 
2259  /* First we normalise the point dst */
2260  if(!field_elt_isone(dst->z, k))
2261  {
2262  edwards_point_norm(dst,E, stack);
2263  }
2264 
2265  /* First step Edwards to Montgomery
2266  * (here a d should be understood as coefficients of the
2267  * twisted Edwards curve )
2268  */
2269  field_elt_sub(c,E->a,E->b, k); /* c = a -d */
2270  field_elt_inv(c, c, k, stack); /* c = 1 / (a - d) */
2271  field_elt_add(c,c,c, k); /* c = 2 / (a - d) */
2272  field_elt_add(d,c,c, k); /* B = 4 / (a - d) (stored in d) */
2273  field_elt_add(e,E->a,E->b, k); /* e = a + d */
2274  field_elt_mul(e,e,c, k, stack); /* A = 2 ( a + d ) / ( a - d ) (stored in e) */
2275 
2276  /* We have computed the coefficients of the birationnally equivalent
2277  * Montgomery curve we have also to compute the image of dst
2278  * Those Montgomery coefficients were necessary for the next step.
2279  */
2280 
2281  field_elt_set_one(c,k);
2282  field_elt_sub(c,c,dst->y, k);
2283  field_elt_inv(c,c, k, stack); /* c = 1 /(1-v) */
2284  field_elt_inc(f,dst->y, k);
2285  field_elt_mul(f,c,f, k, stack); /* f = (1 + v)/(1 -v) */
2286  field_elt_div(dst->y,f,dst->x, k, stack); /* y = (1 + v)/((1 -v) u ) */
2287  field_elt_copy(dst->x,f, k); /* x = (1 + v)/(1 -v) */
2288 
2289  /* Second step Montgomery to short Weierstras */
2290  /* At this step we have a Montgomery curve with coefficients (e,d)
2291  * instead of the usual notation A,B
2292  */
2293  field_elt_set_ui(f, 3, false, k, stack);
2294  field_elt_div(f,e,f, k, stack); /* f = A / 3 */
2295  field_elt_add(dst->x, dst->x, f, k);
2296  field_elt_div(dst->x, dst->x, d, k, stack); /* u = ( x + A / 3) /B */
2297  field_elt_div(dst->y,dst->y,d, k, stack); /* v = y /B */
2298  field_elt_set_one(dst->t,k);
2299 
2300  /* We now free the memory */
2301  field_elt_relax_pool_elt(&c, k, stack);
2302  field_elt_relax_pool_elt(&d, k, stack);
2303  field_elt_relax_pool_elt(&e, k, stack);
2304  field_elt_relax_pool_elt(&f, k, stack);
2305 }
2306 
2307 void
2308 weierstrass_to_edwards (ec_curve_ptr E_res, ec_curve_srcptr E, const uint8_t n, fe_ptr alpha, fe_ptr beta, uint8_t stack)
2309 {
2310  ec_point S,P,Q,R;
2311  field_elt c,d,e,f,a;
2312  field_t *k = E->k;
2313 
2314  E_res->k = (field_t*)(E->k);
2315  E_res->type = EDWARDS;
2316  number_copy(E_res->h, E->h);
2317  number_copy(E_res->n, E->n);
2318  E_res->f=EXTENDED_EDWARDS;
2319  field_elt_get_pool_elt(&a, k, stack);
2320  field_elt_get_pool_elt(&c, k, stack);
2321  field_elt_get_pool_elt(&d, k, stack);
2322  field_elt_get_pool_elt(&e, k, stack);
2323  field_elt_get_pool_elt(&f, k, stack);
2324  ec_point_get_pool_elt(S, k, stack);
2325  ec_point_get_pool_elt(P, k, stack);
2326  ec_point_get_pool_elt(Q, k, stack);
2327  ec_point_get_pool_elt(R, k, stack);
2328  ec_point_copy(P,E->G, k);
2329 
2330  field_elt_set_one(a,k);
2331  field_elt_dec(a,a, k);
2332  field_elt_copy(E_res->D,a, k);
2333 
2334  /* First we normalise the point P */
2335  if(!field_elt_isone(P->z, k))
2336  {
2337  edwards_point_norm(P, E, stack);
2338  }
2339 
2340  /* First step short Weierstrass to Montgomery */
2341  field_elt_set_ui(f, 3, false, k, stack);
2342  /* First we compute the abscissa of a point of order 2 of the Curve */
2343  switch(n)
2344  {
2345  case 1:
2346  /* We suppose here that the user gives us as input alpha aka the abscissa of a point of order 2 which is good for a mapping */
2347  field_elt_copy(c, alpha, k);
2348  field_elt_sqr(a, c, k, stack);
2349  field_elt_mul(d, a, f, k, stack); /* d = 3 alpha^2 */
2350  field_elt_add(e, d, E->a, k); /* d = 3 alpha^2 + a */
2351  MPHELL_ASSERT( field_elt_issquare(e, k, stack), "This curve do not seem to be isomorphic to an edwards curve \n We do not have 3*alpha^2 + a = beta^2 \n");
2352  field_elt_sqrt(e, e, k, stack); /* beta = (3 alpha^2 + a)^(1/2) (stored in e) */
2353  field_elt_copy(beta, e, k);
2354  break;
2355 
2356  case 2:
2357  /* We suppose here that the user gives us as input alpha (aka the abscissa of a point of order 2) and beta ((3*alpha^2+a)^(1/2)) which are good for a mapping */
2358  field_elt_copy(c, alpha, k);
2359  field_elt_copy(e, beta, k);
2360  break;
2361 
2362  default:
2363  /* No data specified for the correspondance we want to use */
2364  /* First we compute the abscissa of a point of order 2 of the Curve */
2365  weierstrass_points_of_order_2(Q, R, S, E, stack);
2366  /* If we are here this means that Q is a point of order 2 */
2367  do
2368  {
2369  field_elt_copy(c, Q->x, k); /* alpha = Qx (stored in c) */
2370  field_elt_copy(alpha, c, k);
2371  field_elt_sqr(a, c, k, stack);
2372  field_elt_mul(d, a, f, k, stack); /* d = 3 alpha^2 */
2373  field_elt_add(e, d, E->a, k); /* d = 3 alpha^2 + a */
2374  ec_point_copy(Q, R, k);
2375  ec_point_copy(R, S, k);
2376  }while(!field_elt_issquare(e, k, stack));
2377  MPHELL_ASSERT( field_elt_issquare(e, k, stack), "This curve do not seem to be isomorphic to an edwards curve \n We do not have 3*alpha^2 + a = beta^2 \n");
2378  field_elt_sqrt(e, e, k, stack); /* beta = (3 alpha^2 + a)^(1/2) (stored in e) */
2379  field_elt_copy(beta, e, k);
2380  break;
2381  }
2382 
2383  field_elt_mul(d, f, c, k, stack); /* d = 3 alpha */
2384  field_elt_inv(E_res->b, e, k, stack); /* B = 1 / beta */
2385  field_elt_mul(E_res->a, d, E_res->b, k, stack); /* A = 3 alpha / beta */
2386  field_elt_sub(d, P->x, c, k);
2387  field_elt_mul(P->x, d, E_res->b, k, stack); /* x = (u - alpha) / beta */
2388  field_elt_mul(P->y, P->y, E_res->b, k, stack); /* y = v / beta */
2389 
2390  /* Second step Montgomery to Edwards */
2391  /* We compute the coefficients of the twisted edwards curve */
2392  field_elt_dec(a, f, k);
2393  field_elt_sub(c, E_res->a, a, k); /* c = A - 2 */
2394  field_elt_add(e, E_res->a, a, k); /* e = A + 2 */
2395  field_elt_inv(d, E_res->b, k, stack); /* d = 1 / B */
2396  field_elt_mul(E_res->a, e, d, k, stack); /* a = (A + 2) / B */
2397  field_elt_mul(E_res->b, c, d, k, stack); /* d = (A - 2) / B */
2398 
2399  /* We compute the mapping of the point P */
2400  field_elt_dec(d, P->x, k);
2401  field_elt_inc(e, P->x, k);
2402  field_elt_div(P->x, P->x, P->y, k, stack); /* u = x / y */
2403  field_elt_div(P->y, d, e, k, stack); /* v = (x - 1)/(x + 1) */
2404  edwards_point_set_aff(E_res->G, P->x, P->y, k, stack);
2405  if(E->id_curve != NULL)
2406  {
2407  strcpy(E_res->id_curve, E->id_curve);
2408  }
2409  else
2410  {
2411  strcpy(E_res->id_curve, "no_name");
2412  }
2413 
2414  ec_compute_disc(E_res, stack);
2415  ec_test_spec(E_res, stack);
2416 
2417  /*We now free the memory */
2418  field_elt_relax_pool_elt(&a, k, stack);
2419  field_elt_relax_pool_elt(&c, k, stack);
2420  field_elt_relax_pool_elt(&d, k, stack);
2421  field_elt_relax_pool_elt(&e, k, stack);
2422  field_elt_relax_pool_elt(&f, k, stack);
2423  ec_point_relax_pool_elt(S, k, stack);
2424  ec_point_relax_pool_elt(P, k, stack);
2425  ec_point_relax_pool_elt(Q, k, stack);
2426  ec_point_relax_pool_elt(R, k, stack);
2427 }
2428 
2429 void
2431  ec_curve_srcptr E, const uint8_t n, fe_ptr alpha, fe_ptr beta, uint8_t stack)
2432 {
2433  ec_point Q;
2434  field_elt c,d,e,f,a;
2435  field_t *k = E->k;
2436 
2437  /* Allocation */
2438  field_elt_get_pool_elt(&a, k, stack);
2439  field_elt_get_pool_elt(&c, k, stack);
2440  field_elt_get_pool_elt(&d, k, stack);
2441  field_elt_get_pool_elt(&e, k, stack);
2442  field_elt_get_pool_elt(&f, k, stack);
2443  ec_point_get_pool_elt(Q, k, stack);
2444 
2445  ec_point_copy(dst,P, k);
2446 
2447  /* First we normalise the point dst */
2448  if(!field_elt_isone(dst->z, k))
2449  {
2450  edwards_point_norm(dst,E, stack);
2451  }
2452  field_elt_set_ui(f, 3, false, k, stack);
2453  /* First step short Weierstrass to Montgomery */
2454  switch(n)
2455  {
2456  case 1:
2457  /* We suppose here that the user gives us as input alpha aka the abscissa of a point of order 2 */
2458  field_elt_copy(c,alpha, k);
2459 
2460  field_elt_sqr(a, c, k, stack);
2461  field_elt_mul(d, a, f, k, stack); /* d = 3 alpha^2 */
2462  field_elt_add(e, d, E->a, k); /* d = 3 alpha^2 + a */
2463  MPHELL_ASSERT( field_elt_issquare(e, k, stack), "This curve do not seem to be isomorphic to an edwards curve \n We do not have 3*alpha^2 + a = beta^2 \n");
2464  field_elt_sqrt(e, e, k, stack); /* beta = (3 alpha^2 + a)^(1/2) (stored in e) */
2465  field_elt_copy(beta, e, k);
2466  break;
2467 
2468  case 2:
2469  /* We suppose here that the user gives us as input alpha (aka the abscissa of a point of order 2) and beta ((3*alpha^2+a)^(1/2)) */
2470  field_elt_copy(c, alpha, k);
2471  field_elt_copy(e, beta, k);
2472  break;
2473 
2474  default:
2475  /* No data specified for the correspondance we want to use */
2476  /* First we compute the abscissa of a point of order 2 of the Curve */
2477  weierstrass_point_of_order_2(Q, E, stack);
2478  /* If we are here this means that Q is a point of order 2 */
2479  field_elt_copy(c, Q->x, k); /* alpha = Qx (stored in c) */
2480  field_elt_copy(alpha, c, k);
2481  field_elt_sqr(a, c, k, stack);
2482  field_elt_mul(d, a, f, k, stack); /* d = 3 alpha^2 */
2483  field_elt_add(e, d, E->a, k); /* d = 3 alpha^2 + a */
2484  MPHELL_ASSERT( field_elt_issquare(e, k, stack), "This curve do not seem to be isomorphic to an edwards curve \n We do not have 3*alpha^2 + a = beta^2 \n");
2485  field_elt_sqrt(e, e, k, stack); /* beta = (3 alpha^2 + a)^(1/2) (stored in e) */
2486  field_elt_copy(beta, e, k);
2487  break;
2488  }
2489  field_elt_inv(a, e, k, stack); /* a = 1 / beta */
2490  field_elt_sub(d, dst->x, c, k);
2491  field_elt_mul(dst->x, d, a, k, stack); /* x = (u - alpha) / beta */
2492  field_elt_mul(dst->y, dst->y, a, k, stack); /* y = v / beta */
2493 
2494  /* Second step Montgomery to Edwards */
2495  /* We compute the mapping of the point P */
2496  field_elt_dec(d,dst->x, k);
2497  field_elt_inc(e,dst->x, k);
2498  field_elt_div(dst->x,dst->x,dst->y, k, stack); /* u = x / y */
2499  field_elt_div(dst->y,d,e, k, stack); /* v = (x - 1)/(x + 1) */
2500  field_elt_mul(dst->t,dst->x,dst->y, k, stack);
2501 
2502 
2503  /* We now free the memory */
2504  field_elt_relax_pool_elt(&a, k, stack);
2505  field_elt_relax_pool_elt(&c, k, stack);
2506  field_elt_relax_pool_elt(&d, k, stack);
2507  field_elt_relax_pool_elt(&e, k, stack);
2508  field_elt_relax_pool_elt(&f, k, stack);
2509  ec_point_relax_pool_elt(Q, k, stack);
2510 }
2511 
bool ec_belongs(ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Test if P belongs to E.
Definition: mphell-curve.c:865
bool edwards_verify_random_generation(ec_curve E, const char *seed, uint8_t stack)
Test if E if generated from the seed "seed".
void weierstrass_point_neg(ec_point_ptr P3, ec_point_srcptr P1, ec_curve_srcptr E)
Set P3 to -P1.
bool number_iszero(number_srcptr src)
Test if src is zero.
void ec_point_set(ec_point_ptr P, fe_srcptr x, fe_srcptr y, fe_srcptr z, fe_srcptr t, field_srcptr k)
Set a point from its coordinates.
Definition: mphell-curve.c:718
bool weierstrass_verify_random_generation(ec_curve E, const char *seed, uint8_t stack)
Test if E if generated from the seed "seed".
fp_elt * field_elt
Generic field element.
Definition: mphell-field.h:39
void ec_random(ec_curve_ptr E, const char *id_curve, char *seed_res, field_srcptr k, const ec_type type, const ec_formula f, uint8_t stack)
Create a random elliptic curve E, not cryptographically secure (not tested to be)....
Definition: mphell-curve.c:495
field_elt y
Definition: mphell-curve.h:106
void ec_point_set_neutral(ec_point_ptr dst, ec_curve_srcptr E, uint8_t stack)
Set dst to the neutral element.
Definition: mphell-curve.c:780
bool edwards_point_is_neutral(ec_point_srcptr P, ec_curve_srcptr E)
Test if P is the neutral element.
static bool field_elt_iszero(fe_srcptr src, field_srcptr k)
Test if src is zero.
Definition: mphell-field.h:504
void ec_create(ec_curve_ptr E, const char *id_curve, field_srcptr k, fe_srcptr a, fe_srcptr b, ec_point_srcptr G, number_srcptr h, number_srcptr n, const ec_type type, const ec_formula f, uint8_t stack)
Create an elliptic curve E, the curve must be allocated and initialised (ec_alloc & ec_init)
Definition: mphell-curve.c:62
void field_elt_free(fe_ptr *src, field_srcptr k)
Free space used by src.
Definition: mphell-field.c:356
static void field_elt_mul(fe_ptr dst, fe_srcptr src1, fe_srcptr src2, field_srcptr k, uint8_t stack)
Set dst <- src1 * src2, if Montgomery arithmetic is used, the Montgomery multiplication will be used ...
Definition: mphell-field.h:753
void ec_point_dbl_unified(ec_point_ptr P3, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to 2*P1, using unified formulae (protection against SPA)
ec_type type
Definition: mphell-curve.h:145
uint16_t bit_size
Definition: mphell-field.h:95
number q
Definition: mphell-curve.h:143
void weierstrass_point_set_aff_str(ec_point_ptr P, const char *str_x, const char *str_y, const bool is_reduced, const uint8_t base, field_srcptr k, uint8_t stack)
Set dest to the affine point (str_x,str_y)
void ec_type_str(char **str, const ec_type type)
Allocate *str and write in it the type of E.
Definition: mphell-curve.c:910
void edwards_point_neg(ec_point_ptr P3, ec_point_srcptr P1, ec_curve_srcptr E)
Compute the opposite of a point of the the Edwards elliptic curve E.
uint16_t number_log2(number_srcptr src)
Calculate log2(src), which is the binary size of src.
void mphell_error(char *expr)
Write in stderr, filename, line and expr, free mphell.
Definition: mphell-errors.c:45
void ec_point_set_str(ec_point_ptr P, const char *str_x, const char *str_y, const char *str_z, const char *str_t, const bool is_reduced, const uint8_t base, field_srcptr k, uint8_t stack)
Set a point from its coordinates under string format.
Definition: mphell-curve.c:728
void edwards_point_random(ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Set P to a random point on E.
void weierstrass_Zmontgomery_Kim(ec_point_ptr P3, number_srcptr n, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Perform the Montgomery ladder, taken from Kim et al's 2017 work, compute P3=[n]P1 it has the drawback...
void edwards_point_add_unified(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Compute the unified addition of 2 points P1 and P2 of the Edwards elliptic curve E,...
void number_to_bit_string(char *str, number_srcptr src)
Converts src (must be positive) to a bit string.
Define a field.
Definition: mphell-field.h:90
Define an elliptic curve point.
Definition: mphell-curve.h:103
void weierstrass_to_edwards(ec_curve_ptr E_res, ec_curve_srcptr E, const uint8_t n, fe_ptr alpha, fe_ptr beta, uint8_t stack)
Convert the Weierstrass elliptic curve E to the one of the corresponding Edwards elliptic curve accor...
void ec_point_alloc(ec_point_ptr P, field_srcptr k)
Allocate an elliptic curve point.
Definition: mphell-curve.c:673
bool ec_spec1
Definition: mphell-curve.h:152
number h
Definition: mphell-curve.h:149
field_elt t
Definition: mphell-curve.h:108
static void field_elt_inc(fe_ptr dst, fe_srcptr src, field_srcptr k)
Set dst <- src + 1.
Definition: mphell-field.h:535
void edwards_to_weierstrass(ec_curve_ptr E_res, ec_curve_srcptr E, uint8_t stack)
Convert the Edwards elliptic curve E to the corresponding Weierstrass elliptic curve E_res.
void ec_point_neg(ec_point_ptr P3, ec_point_srcptr P1, ec_curve_srcptr E)
Set P3 to -P1.
void number_set_ui(number_ptr dst, const block src)
Set dst to src.
void ec_init(ec_curve_ptr E, field_srcptr k)
Initialise a curve.
Definition: mphell-curve.c:52
void edwards_point_get_y_affine(field_elt y, ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert P->y to its affine representation.
void ec_point_print(ec_point_srcptr P, const uint8_t base, const bool lift, field_srcptr k, uint8_t stack)
Print a description of P.
void weierstrass_point_random(ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Set P to a random point on E.
void jacobi_quartic_point_set_neutral(ec_point_ptr dst, ec_curve_srcptr E, uint8_t stack)
Set dst to the neutral element: (0,1,0,1).
uint8_t bits_to_nblock(const uint16_t nbits)
Return the number of blocks required to store a nbits number.
Definition: mphell-util.c:29
void field_elt_sqrt(fe_ptr dst, fe_srcptr src, field_srcptr k, uint8_t stack)
Set dst <- src^(1/2)
void field_elt_alloc(fe_ptr *dst, field_srcptr k)
Allocate space for a field element.
Definition: mphell-field.c:277
int16_t binary_to_indice(char *str, int16_t beg, int16_t end)
Compute the indice for the sliding window multiplication.
ec_formula f
Definition: mphell-curve.h:146
void jacobi_quartic_to_weierstrass(ec_curve_ptr E_res, ec_curve_srcptr E, uint8_t stack)
Convert a jacobi quartic elliptic curve into a Weierstrass elliptic curve.
void edwards_point_set_aff_str(ec_point_ptr P, const char *str_x, const char *str_y, const bool is_reduced, const uint8_t base, field_srcptr k, uint8_t stack)
Set dest to the affine point twisted Edwards coordinates point (str_x,str_y,1,str_x str_y)
void ec_point_get_y_affine(field_elt y, ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert P->y to its affine representation.
Definition: mphell-curve.c:837
void weierstrass_compute_disc(ec_curve E, uint8_t stack)
Set the discriminant of E: disc = -16(4a^3 + 27b^2)
void ec_point_init(ec_point_ptr P, field_srcptr k)
Initialise an elliptic curve point.
Definition: mphell-curve.c:682
field_elt b
Definition: mphell-curve.h:144
void field_elt_div(fe_ptr dst, fe_srcptr src1, fe_srcptr src2, field_srcptr k, uint8_t stack)
Set dst <- src1 / src2.
uint8_t size
Definition: mphell-field.h:94
void ec_point_add(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Set P3 to P1 + P2, using dedicated formulae (not protected against SPA, but faster)
void ec_compute_disc(ec_curve_ptr E, uint8_t stack)
Set the discriminant of E.
Definition: mphell-curve.c:580
void jacobi_quartic_point_get_y_affine(field_elt y, ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert P->y to its affine representation.
bool jacobi_quartic_point_are_equal(ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Test if P1 and P2 are equal on E.
bool field_elt_isone(fe_srcptr src, field_srcptr k)
Test if src is one.
Definition: mphell-field.c:774
void number_free(number *dst)
Free a number_ptr allocated on the RAM memory (malloc)
Definition: mphell-number.c:75
bool jacobi_quartic_point_is_neutral(ec_point_srcptr P, ec_curve_srcptr E)
Test if P is the neutral element.
void ec_use_curve(ec_curve_ptr E, field_ptr k, const ec_known_curve id_curve, const ec_formula f, uint8_t stack)
Create the elliptic curve (and the associated base field) id_curve, the curve and the field must me a...
Definition: mphell-curve.c:114
field_elt disc
Definition: mphell-curve.h:150
void weierstrass_point_add_unified(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Set P3 to P1 + P2, using unified formulae (protection against SPA)
void ec_point_free(ec_point_ptr P, field_srcptr k)
Free the point P.
Definition: mphell-curve.c:700
void ec_point_str(char **str, ec_point_srcptr P, const uint8_t base, const bool lift, field_srcptr k, uint8_t stack)
Allocate *str and write in it the description of P.
void ec_free(ec_curve_ptr E)
Free the elliptic curve E.
Definition: mphell-curve.c:655
void weierstrass_point_set_neutral(ec_point_ptr dst, ec_curve_srcptr E, uint8_t stack)
Set dst to the neutral element: (0,1,0) for projective coordinates and (1,1,0) for jacobian coordinat...
static void ec_point_relax_pool_elt(ec_point_ptr P, field_ptr k, uint8_t stack)
Relax an initialised point from the pool.
Definition: mphell-curve.h:218
bool weierstrass_belongs(ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Test if P belongs to E.
void weierstrass_point_get_x_affine(field_elt x, ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert P->x to its affine representation.
void weierstrass_point_get_y_affine(field_elt y, ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert P->y to its affine representation.
void field_elt_set_one(fe_ptr dst, field_srcptr k)
Set dst to one (or its Montgomery form if Montgomery arithmetic is used)
Definition: mphell-field.c:376
bool ec_point_is_neutral(ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Test if P is the neutral element.
Declaration of ECC functions.
void field_elt_copy(fe_ptr dst, fe_srcptr src, field_srcptr k)
Copy src into dst, src and dst must belong to the same field.
Definition: mphell-field.c:318
void weierstrass_point_set_aff(ec_point_ptr P, fe_srcptr x, fe_srcptr y, field_srcptr k)
Set dest to the affine point (x, y)
void field_create(field_ptr k, const char *id, uint8_t stack, const uint32_t n,...)
Initialize the different fields of the structure pointed by k.
Definition: mphell-field.c:76
void weierstrass_point_to_edwards_point(ec_point_ptr dst, ec_point_srcptr P, ec_curve_srcptr E, const uint8_t n, fe_ptr alpha, fe_ptr beta, uint8_t stack)
Convert the point of the Weierstrass elliptic curve E to the elliptic curve of one of the correspondi...
bool weierstrass_point_is_neutral(ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Test if P is the neutral element.
void weierstrass_point_to_jacobi_quartic_point(ec_point_ptr dst, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Convert a point on a weierstrass elliptic curve to a point on a jacobi quartic elliptic curve.
void ec_point_set_aff_str(ec_point_ptr P, const char *str_x, const char *str_y, const bool is_reduced, const uint8_t base, const ec_type type, field_srcptr k, uint8_t stack)
Set a point from its affine coordinates under string format.
Definition: mphell-curve.c:759
void field_get_size(number_ptr c, field_srcptr k)
Get the size of the field "k".
Definition: mphell-field.c:220
static void ec_point_get_pool_elt(ec_point_ptr P, field_ptr k, uint8_t stack)
Get an initialised point from the pool.
Definition: mphell-curve.h:202
void weierstrass_point_of_order_2(ec_point_ptr dst, ec_curve_srcptr E, uint8_t stack)
Set dst to one of the point of order 2 of the curve E assuming that at least one exist.
void ec_point_add_unified(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Set P3 to P1 + P2, using unified formulae (protection against SPA)
void field_elt_str(char **str, fe_srcptr src, const uint8_t base, const bool lift, field_srcptr k, uint8_t stack)
Converts src to string format in base specified by base.
Definition: mphell-field.c:691
void edwards_point_get_x_affine(field_elt x, ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert P->x to its affine representation.
void jacobi_quartic_point_dbl_dedicated(ec_point_ptr P3, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to 2*P1, using dedicated formulae (not protected against SPA, but faster)
void edwards_point_add_dedicated(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Compute the addition of 2 points P1 and P2 of the Edwards elliptic curve E (not protected against SPA...
bool field_elt_issquare(fe_srcptr src, field_srcptr k, uint8_t stack)
Test if src is a square using the Lengendre symbol.
Definition: mphell-field.c:921
void ec_point_dbl(ec_point_ptr P3, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to 2*P1, using dedicated formulae (not protected against SPA, but faster)
void jacobi_quartic_point_set_aff_str(ec_point_ptr P, const char *str_x, const char *str_y, const bool is_reduced, const uint8_t base, field_srcptr k, uint8_t stack)
Set dest to the affine point (str_x,str_y)
char * id_curve
Definition: mphell-curve.h:141
bool weierstrass_point_are_equal(ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Test if P1 and P2 are equal on E (BUT do not test if they belong to the curve)
void field_elt_lift(fe_ptr dst, fe_srcptr src, field_srcptr k, uint8_t stack)
If Montgomery arithmetic is used, lift src (which is into Montgomery form) to classical fp (or its co...
Definition: mphell-field.c:544
void number_copy(number_ptr dst, number_srcptr src)
Copy src into dst.
Definition: mphell-number.c:87
void ec_point_mul_naive(ec_point_ptr P3, number_srcptr n, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to n * P1 using naive double and add method, Montgomery and Joye multiplication are also avail...
void ec_alloc(ec_curve_ptr E, field_srcptr k)
Allocate a curve.
Definition: mphell-curve.c:37
void edwards_point_set_aff(ec_point_ptr P, fe_srcptr x, fe_srcptr y, field_srcptr k, uint8_t stack)
Set dest to the extended twisted Edwards coordinates point (x,y,1,xy)
void field_elt_clear(fe_ptr *src, field_srcptr k)
Clear space used by src (remove the action of field_elt_init but let the one of field_elt_alloc)
Definition: mphell-field.c:337
void ec_copy(ec_curve_ptr E_res, ec_curve_srcptr E)
Copy E into E_res which has been previously allocated, beware: the same field is used,...
Definition: mphell-curve.c:618
const fp_elt * fe_srcptr
Pointer on a field element, the field element cannot be modified through this pointer.
Definition: mphell-field.h:51
void ec_set_fast_unified_coordinates(ec_curve_ptr E)
Set the fastest unified coordinates system.
Definition: mphell-curve.c:544
void jacobi_quartic_compute_disc(ec_curve E, uint8_t stack)
Set the discriminant of E: disc = (2^8).(a^2 - 1)^2.
Definition: mphell-jacobi.c:32
void jacobi_quartic_point_to_weierstrass_point(ec_point_ptr dst, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Convert a point on a jacobi quartic elliptic curve to a point on a weierstrass elliptic curve.
bool ec_point_are_equal(ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Test if P1 and P2 are equal on E.
void ec_point_sub_unified(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Set P3 to P1 - P2, using unified formulae (protection against SPA)
field_elt z
Definition: mphell-curve.h:107
void edwards_point_to_weierstrass_point(ec_point_ptr dst, ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Convert the Edwards point P of the elliptic curve E to the corresponding Weierstrass elliptic curve p...
int8_t field_elt_cmp(fe_srcptr src1, fe_srcptr src2, field_srcptr k)
Compare src1 and src2.
Definition: mphell-field.c:732
void edwards_curve_random_generation(fe_ptr d, char *seed_res, field_srcptr k, uint8_t stack)
Generate a 160 bits seed and coefficients a and b defining a Weiestrass elliptic curve....
number n
Definition: mphell-curve.h:148
void edwards_compute_disc(ec_curve E, uint8_t stack)
Set the discriminant of E: disc = a.d.(a-d)^4.
void number_tmp_free(number *t, const uint8_t size, uint8_t stack)
Free a temporary number.
Definition: mphell-number.c:45
void jacobi_quartic_point_norm(ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert a point in extented projective coordinate (X,Y,T,Z) to an affine point (x,...
void jacobi_quartic_point_set_aff(ec_point_ptr P, fe_srcptr x, fe_srcptr y, field_srcptr k, uint8_t stack)
Set dest to the affine point (x,y)
void jacobi_quartic_point_random(ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Create a random point P on the elliptic curve E.
enum ec_algo_enum ec_formula
Define the type of coordinate.
Definition: mphell-curve.h:68
fp_elt * fe_ptr
Pointer on a field element.
Definition: mphell-field.h:45
void field_elt_inv(fe_ptr dst, fe_srcptr src, field_srcptr k, uint8_t stack)
Set dst <- src^(-1)
field_elt x
Definition: mphell-curve.h:105
void ec_point_mul(ec_point_ptr P3, number_srcptr n, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to n * P1 using Montgomery for Weierstrass elliptic curve, and naive method for other elliptic...
bool jacobi_quartic_belongs(ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Test if P belongs to E.
int16_t binary_to_indice_new(char *str, int16_t beg, int16_t end)
Compute the indice for the sliding window multiplication.
bool edwards_belongs(ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Test if P belongs to E.
void weierstrass_points_of_order_2(ec_point_ptr dst1, ec_point_ptr dst2, ec_point_ptr dst3, ec_curve_srcptr E, uint8_t stack)
Set dst1, dst2, dst3 to the points of order 2 of the curve E assuming they are different otherwise th...
ec_point G
Definition: mphell-curve.h:147
void field_elt_init(fe_ptr dst, field_srcptr k)
Initialise the field element.
Definition: mphell-field.c:299
void field_str(char **str, field_srcptr k, const uint8_t base, uint8_t stack)
Converts k to string format in base specified by base.
Definition: mphell-field.c:651
void ec_point_copy(ec_point_ptr P3, ec_point_srcptr P, field_srcptr k)
Copy P into P3.
Definition: mphell-curve.c:709
void ec_point_2mul_with_precomp(ec_point_ptr P3, number_srcptr n1, ec_point *tab_P1, number_srcptr n2, ec_point *tab_P2, int16_t win_size, ec_curve_srcptr E, uint8_t stack)
Set P3 to n1 * P1 + n2 * P2 using 2 precomputated array.
void jacobi_quartic_curve_random_generation(fe_ptr a, char *seed_res, field_srcptr k, uint8_t stack)
Generate a 160 bits seed and coefficients a and b defining a Weiestrass elliptic curve....
void ec_curve_print(ec_curve_srcptr E, const uint8_t base, uint8_t stack)
Print a description of E.
enum ec_type_enum ec_type
Define the type of curve.
Definition: mphell-curve.h:50
field_ptr k
Definition: mphell-curve.h:142
void number_set_str(number_ptr dst, const char *str, const uint8_t base)
Set dst to str.
void number_tmp_alloc(number *t, const uint8_t size, uint8_t stack)
Allocate a temporary number.
Definition: mphell-number.c:31
static void field_elt_neg(fe_ptr dst, fe_srcptr src, field_srcptr k)
Set dst <- (-src)
Definition: mphell-field.h:695
void weierstrass_to_jacobi_quartic(ec_curve_ptr E_res, ec_curve_srcptr E, const bool determined, fe_ptr teta, uint8_t stack)
Convert a Weierstrass elliptic curve into a jacobi quartic elliptic curve.
void number_init(number *dst, const uint8_t n)
Allocate a number_ptr on the RAM memory (malloc)
Definition: mphell-number.c:59
void weierstrass_point_norm(ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Set P in affine coordinates.
void weierstrass_point_dbl_dedicated(ec_point_ptr P3, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to 2 * P1, using dedicated formulae (not protected against SPA, but faster)
void ec_point_clear(ec_point_ptr P, field_srcptr k)
Clear the point P (remove the action of ec_point_init, but let the one of ec_point_alloc)
Definition: mphell-curve.c:691
void ec_point_random(ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Create a random point P on the elliptic curve E.
Definition: mphell-curve.c:885
void ec_point_mul_with_precomp(ec_point_ptr P3, number_srcptr n, ec_point *tab_P1, int16_t win_size, ec_curve_srcptr E, uint8_t stack)
Set P3 to n * P1 using naive double and add method, Montgomery and Joye multiplication are also avail...
Define an elliptic curve.
Definition: mphell-curve.h:139
void field_elt_set_str(fe_ptr dst, const char *str, const uint8_t base, const bool isreduced, field_srcptr k, uint8_t stack)
Set dst to str, if Montgomery arithmetic is used, is_reduced == false -> transform dst into its Montg...
Definition: mphell-field.c:505
static void field_elt_sqr(fe_ptr dst, fe_srcptr src, field_srcptr k, uint8_t stack)
Set dst <- src^2.
Definition: mphell-field.h:913
bool jacobi_quartic_verify_random_generation(ec_curve E, const char *seed, uint8_t stack)
Test if E if generated from the seed "seed".
Definition: mphell-jacobi.c:54
void ec_point_set_aff(ec_point_ptr P, fe_srcptr x, fe_srcptr y, const ec_type type, field_srcptr k, uint8_t stack)
Set a point from its affine coordinates.
Definition: mphell-curve.c:739
enum ec_known_curve_enum ec_known_curve
Define the hardcoded curves.
Definition: mphell-curve.h:97
void ec_curve_str(char **str, ec_curve_srcptr E, const uint8_t base, uint8_t stack)
Allocate *str and write in it the description of E.
Definition: mphell-curve.c:932
void field_elt_set_ui(fe_ptr dst, const block src, const bool isreduced, field_srcptr k, uint8_t stack)
Set dst to src, if Montgomery arithmetic is used, is_reduced == false -> transform dst into its Montg...
Definition: mphell-field.c:395
void jacobi_quartic_point_add_unified(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Set P3 to P1 + P2 using extended projective coordinate (T=(X^2)/Z), and unified formulae (protection ...
void ec_point_mul_sliding_window(ec_point_ptr P3, number_srcptr n, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to n * P1 using naive double and add method, Montgomery and Joye multiplication are also avail...
void edwards_point_norm(ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Set P in affine coordinates.
void jacobi_quartic_point_neg(ec_point_ptr P3, ec_point_srcptr P1, ec_curve_srcptr E)
Set P3 to -P1.
void edwards_point_dbl_dedicated(ec_point_ptr P3, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Compute the double of a point of the Edwards elliptic curve E (not protected against SPA,...
static void field_elt_sub(fe_ptr dst, fe_srcptr src1, fe_srcptr src2, field_srcptr k)
Set dst <- src1 - src2.
Definition: mphell-field.h:642
static void field_elt_dec(fe_ptr dst, fe_srcptr src, field_srcptr k)
Set dst <- src - 1.
Definition: mphell-field.h:615
void ec_clear(ec_curve_ptr E)
Clear the elliptic curve E (remove the action of ec_init, but let the one of ec_alloc)
Definition: mphell-curve.c:643
void ec_point_mul_naive_unified(ec_point_ptr P3, number_srcptr n, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to n * P1 using naive double and add method, Montgomery and Joye multiplication are also avail...
static void field_elt_relax_pool_elt(field_elt *dst, field_ptr k, uint8_t stack)
Relax an initialised field element from the pool.
Definition: mphell-field.h:167
void ec_point_lift(ec_point_ptr P, field_srcptr k, uint8_t stack)
Lift the coordinates from Montgomery basis to classical arithmetic.
Definition: mphell-curve.c:856
bool ec_verify_random_generation(ec_curve_ptr E, const char *seed, uint8_t stack)
Test if E if generated from the seed "seed", using algorithm A.3.4.2 from ANS X9.62-1998....
Definition: mphell-curve.c:523
static void field_elt_add(fe_ptr dst, fe_srcptr src1, fe_srcptr src2, field_srcptr k)
Set dst <- src1 + src2.
Definition: mphell-field.h:562
void ec_point_sub(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Set P3 to P1 - P2, using dedicated formulae (not protected against SPA, but faster)
void ec_set_fast_dedicated_coordinates(ec_curve_ptr E)
Set the fastest dedicated coordinates system.
Definition: mphell-curve.c:562
static void field_elt_get_pool_elt(field_elt *dst, field_ptr k, uint8_t stack)
Get an initialised field element from the pool.
Definition: mphell-field.h:134
void number_str(char **str, number_srcptr src, const uint8_t base)
Converts src to string format in base specified by base.
void weierstrass_point_add_dedicated(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Set P3 to P1 + P2, using dedicated formulae (not protected against SPA, but faster)
void weierstrass_curve_random_generation(fe_ptr a, fe_ptr b, char *seed_res, field_srcptr k, uint8_t stack)
Generate a 160 bits seed and coefficients a and b defining a Weiestrass elliptic curve....
void edwards_point_set_neutral(ec_point_ptr dst, ec_curve_srcptr E, uint8_t stack)
Set dst to the neutral element: (0,1,0,1) for extended twisted Edwards coordinates.
bool edwards_point_are_equal(ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Test if P1 and P2 are equal on E (BUT do not test if the points belongs to the curve )
void ec_point_norm(ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert a point in projective or jacobian coordinate to an affine point (x,y)
Definition: mphell-curve.c:799
void jacobi_quartic_point_get_x_affine(field_elt x, ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert P->x to its affine representation.
void ec_point_get_x_affine(field_elt x, ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert P->x to its affine representation.
Definition: mphell-curve.c:818
field_elt D
Definition: mphell-curve.h:151
void ec_test_spec(ec_curve_ptr E, uint8_t stack)
Set the E->ec_spec1 to true if E->a = -3 mod p, false otherwise.
Definition: mphell-curve.c:599
void ec_point_mul_unified(ec_point_ptr P3, number_srcptr n, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to n * P1 using Montgomery for Weierstrass elliptic curve, and naive method for other elliptic...