ec.c
Go to the documentation of this file.
1 /**
2  * @file ec.c
3  * @brief ECC (Elliptic Curve Cryptography)
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneCrypto Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/crypto.h"
34 #include "ecc/ec.h"
35 #include "ecc/curve25519.h"
36 #include "ecc/curve448.h"
37 #include "ecc/ed25519.h"
38 #include "ecc/ed448.h"
39 #include "debug.h"
40 
41 //Check crypto library configuration
42 #if (EC_SUPPORT == ENABLED)
43 
44 //EC Public Key OID (1.2.840.10045.2.1)
45 const uint8_t EC_PUBLIC_KEY_OID[7] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01};
46 
47 
48 /**
49  * @brief Initialize EC domain parameters
50  * @param[in] params Pointer to the EC domain parameters to be initialized
51  **/
52 
54 {
55  //Initialize structure
56  params->type = EC_CURVE_TYPE_NONE;
57  params->mod = NULL;
58 
59  //Initialize EC domain parameters
60  mpiInit(&params->p);
61  mpiInit(&params->a);
62  mpiInit(&params->b);
63  ecInit(&params->g);
64  mpiInit(&params->q);
65 }
66 
67 
68 /**
69  * @brief Release EC domain parameters
70  * @param[in] params Pointer to the EC domain parameters to free
71  **/
72 
74 {
75  //Release previously allocated resources
76  mpiFree(&params->p);
77  mpiFree(&params->a);
78  mpiFree(&params->b);
79  ecFree(&params->g);
80  mpiFree(&params->q);
81 }
82 
83 
84 /**
85  * @brief Load EC domain parameters
86  * @param[out] params Pointer to the structure to be initialized
87  * @param[in] curveInfo Elliptic curve parameters
88  * @return Error code
89  **/
90 
92  const EcCurveInfo *curveInfo)
93 {
94  error_t error;
95 
96  //Debug message
97  TRACE_DEBUG("Loading %s EC domain parameters...\r\n", curveInfo->name);
98 
99  //Curve name
100  params->name = curveInfo->name;
101  //Curve type
102  params->type = curveInfo->type;
103 
104  //Import prime modulus
105  MPI_CHECK(mpiReadRaw(&params->p, curveInfo->p, curveInfo->pLen));
106  //Import parameter a
107  MPI_CHECK(mpiReadRaw(&params->a, curveInfo->a, curveInfo->aLen));
108  //Import parameter b
109  MPI_CHECK(mpiReadRaw(&params->b, curveInfo->b, curveInfo->bLen));
110  //Import the x-coordinate of the base point G
111  MPI_CHECK(mpiReadRaw(&params->g.x, curveInfo->gx, curveInfo->gxLen));
112  //Import the y-coordinate of the base point G
113  MPI_CHECK(mpiReadRaw(&params->g.y, curveInfo->gy, curveInfo->gyLen));
114  //Import base point order q
115  MPI_CHECK(mpiReadRaw(&params->q, curveInfo->q, curveInfo->qLen));
116 
117  //Normalize base point G
118  MPI_CHECK(mpiSetValue(&params->g.z, 1));
119 
120  //Cofactor h
121  params->h = curveInfo->h;
122  //Fast modular reduction
123  params->mod = curveInfo->mod;
124 
125  //Debug message
126  TRACE_DEBUG(" p:\r\n");
127  TRACE_DEBUG_MPI(" ", &params->p);
128  TRACE_DEBUG(" a:\r\n");
129  TRACE_DEBUG_MPI(" ", &params->a);
130  TRACE_DEBUG(" b:\r\n");
131  TRACE_DEBUG_MPI(" ", &params->b);
132  TRACE_DEBUG(" Gx:\r\n");
133  TRACE_DEBUG_MPI(" ", &params->g.x);
134  TRACE_DEBUG(" Gy:\r\n");
135  TRACE_DEBUG_MPI(" ", &params->g.y);
136  TRACE_DEBUG(" q:\r\n");
137  TRACE_DEBUG_MPI(" ", &params->q);
138 
139 end:
140  //Return status code
141  return error;
142 }
143 
144 
145 /**
146  * @brief Initialize elliptic curve point
147  * @param[in,out] r Pointer to the EC point to be initialized
148  **/
149 
151 {
152  //Initialize structure
153  mpiInit(&r->x);
154  mpiInit(&r->y);
155  mpiInit(&r->z);
156 }
157 
158 
159 /**
160  * @brief Release an elliptic curve point
161  * @param[in,out] r Pointer to the EC point to initialize to free
162  **/
163 
165 {
166  //Release previously allocated resources
167  mpiFree(&r->x);
168  mpiFree(&r->y);
169  mpiFree(&r->z);
170 }
171 
172 
173 /**
174  * @brief Copy EC point
175  * @param[out] r Destination EC point
176  * @param[in] s Source EC point
177  * @return Error code
178  **/
179 
181 {
182  error_t error;
183 
184  //R and S are the same instance?
185  if(r == s)
186  return NO_ERROR;
187 
188  //Copy coordinates
189  MPI_CHECK(mpiCopy(&r->x, &s->x));
190  MPI_CHECK(mpiCopy(&r->y, &s->y));
191  MPI_CHECK(mpiCopy(&r->z, &s->z));
192 
193 end:
194  //Return status code
195  return error;
196 }
197 
198 
199 /**
200  * @brief Convert an octet string to an EC point
201  * @param[in] params EC domain parameters
202  * @param[out] r EC point resulting from the conversion
203  * @param[in] data Pointer to the octet string
204  * @param[in] length Length of the octet string
205  * @return Error code
206  **/
207 
209  const uint8_t *data, size_t length)
210 {
211  error_t error;
212 
213  //Montgomery or Edwards curve?
214  if(params->type == EC_CURVE_TYPE_X25519 ||
215  params->type == EC_CURVE_TYPE_X448 ||
216  params->type == EC_CURVE_TYPE_ED25519 ||
217  params->type == EC_CURVE_TYPE_ED448)
218  {
219  //Empty octet string?
220  if(length == 0)
222 
223  //Check the length of the octet string
224  if((params->type == EC_CURVE_TYPE_X25519 && length != CURVE25519_BYTE_LEN) ||
225  (params->type == EC_CURVE_TYPE_X448 && length != CURVE448_BYTE_LEN) ||
228  {
230  }
231 
232  //Convert the octet string to a multiple precision integer
234  //Any error to report?
235  if(error)
236  return error;
237  }
238  //Weierstrass curve?
239  else
240  {
241  size_t k;
242 
243  //Get the length in octets of the prime
244  k = mpiGetByteLength(&params->p);
245 
246  //Check the length of the octet string
247  if(length != (k * 2 + 1))
248  return ERROR_DECODING_FAILED;
249 
250  //Compressed point representation is not supported
251  if(data[0] != 0x04)
253 
254  //Convert the x-coordinate to a multiple precision integer
255  error = mpiImport(&r->x, data + 1, k, MPI_FORMAT_BIG_ENDIAN);
256  //Any error to report?
257  if(error)
258  return error;
259 
260  //Convert the y-coordinate to a multiple precision integer
261  error = mpiImport(&r->y, data + k + 1, k, MPI_FORMAT_BIG_ENDIAN);
262  //Any error to report?
263  if(error)
264  return error;
265  }
266 
267  //Successful processing
268  return NO_ERROR;
269 }
270 
271 
272 /**
273  * @brief Convert an EC point to an octet string
274  * @param[in] params EC domain parameters
275  * @param[in] a EC point to be converted
276  * @param[out] data Pointer to the octet string
277  * @param[out] length Length of the resulting octet string
278  * @return Error code
279  **/
280 
282  uint8_t *data, size_t *length)
283 {
284  error_t error;
285  size_t k;
286 
287  //Get the length in octets of the prime
288  k = mpiGetByteLength(&params->p);
289 
290  //Montgomery curve?
291  if(params->type == EC_CURVE_TYPE_X25519 ||
292  params->type == EC_CURVE_TYPE_X448)
293  {
294  //Convert the u-coordinate to an octet string
295  error = mpiExport(&a->x, data, k, MPI_FORMAT_LITTLE_ENDIAN);
296  //Conversion failed?
297  if(error)
298  return error;
299 
300  //Return the total number of bytes that have been written
301  *length = k;
302  }
303  //Weierstrass curve?
304  else
305  {
306  //Point compression is not used
307  data[0] = 0x04;
308 
309  //Convert the x-coordinate to an octet string
310  error = mpiExport(&a->x, data + 1, k, MPI_FORMAT_BIG_ENDIAN);
311  //Conversion failed?
312  if(error)
313  return error;
314 
315  //Convert the y-coordinate to an octet string
316  error = mpiExport(&a->y, data + k + 1, k, MPI_FORMAT_BIG_ENDIAN);
317  //Conversion failed?
318  if(error)
319  return error;
320 
321  //Return the total number of bytes that have been written
322  *length = k * 2 + 1;
323  }
324 
325  //Successful processing
326  return NO_ERROR;
327 }
328 
329 
330 /**
331  * @brief Compute projective representation
332  * @param[in] params EC domain parameters
333  * @param[out] r Projective representation of the point
334  * @param[in] s Affine representation of the point
335  * @return Error code
336  **/
337 
339  const EcPoint *s)
340 {
341  error_t error;
342 
343  //Copy point
344  EC_CHECK(ecCopy(r, s));
345  //Map the point to projective space
346  MPI_CHECK(mpiSetValue(&r->z, 1));
347 
348 end:
349  //Return status code
350  return error;
351 }
352 
353 
354 /**
355  * @brief Recover affine representation
356  * @param[in] params EC domain parameters
357  * @param[out] r Affine representation of the point
358  * @param[in] s Projective representation of the point
359  * @return Error code
360  **/
361 
363  const EcPoint *s)
364 {
365  error_t error;
366  Mpi a;
367  Mpi b;
368 
369  //Point at the infinity?
370  if(mpiCompInt(&s->z, 0) == 0)
372 
373  //Initialize multiple precision integers
374  mpiInit(&a);
375  mpiInit(&b);
376 
377  //Compute a = 1/Sz mod p
378  MPI_CHECK(mpiInvMod(&a, &s->z, &params->p));
379 
380  //Set Rx = a^2 * Sx mod p
381  EC_CHECK(ecSqrMod(params, &b, &a));
382  EC_CHECK(ecMulMod(params, &r->x, &b, &s->x));
383 
384  //Set Ry = a^3 * Sy mod p
385  EC_CHECK(ecMulMod(params, &b, &b, &a));
386  EC_CHECK(ecMulMod(params, &r->y, &b, &s->y));
387 
388  //Set Rz = 1
389  MPI_CHECK(mpiSetValue(&r->z, 1));
390 
391 end:
392  //Release multiple precision integers
393  mpiFree(&a);
394  mpiFree(&b);
395 
396  //Return status code
397  return error;
398 }
399 
400 
401 /**
402  * @brief Check whether the affine point S is on the curve
403  * @param[in] params EC domain parameters
404  * @param[in] s Affine representation of the point
405  * @return TRUE if the affine point S is on the curve, else FALSE
406  **/
407 
409 {
410  error_t error;
411  Mpi t1;
412  Mpi t2;
413 
414  //Initialize multiple precision integers
415  mpiInit(&t1);
416  mpiInit(&t2);
417 
418  //Compute t1 = (Sx^3 + a * Sx + b) mod p
419  EC_CHECK(ecSqrMod(params, &t1, &s->x));
420  EC_CHECK(ecMulMod(params, &t1, &t1, &s->x));
421  EC_CHECK(ecMulMod(params, &t2, &params->a, &s->x));
422  EC_CHECK(ecAddMod(params, &t1, &t1, &t2));
423  EC_CHECK(ecAddMod(params, &t1, &t1, &params->b));
424 
425  //Compute t2 = Sy^2
426  EC_CHECK(ecSqrMod(params, &t2, &s->y));
427 
428  //Check whether the point is on the elliptic curve
429  if(mpiComp(&t1, &t2) != 0)
430  error = ERROR_FAILURE;
431 
432 end:
433  //Release multiple precision integers
434  mpiFree(&t1);
435  mpiFree(&t2);
436 
437  //Return TRUE if the affine point S is on the curve, else FALSE
438  return error ? FALSE : TRUE;
439 }
440 
441 
442 /**
443  * @brief Point doubling
444  * @param[in] params EC domain parameters
445  * @param[out] r Resulting point R = 2S
446  * @param[in] s Point S
447  * @return Error code
448  **/
449 
451  const EcPoint *s)
452 {
453  error_t error;
454  Mpi t1;
455  Mpi t2;
456  Mpi t3;
457  Mpi t4;
458  Mpi t5;
459 
460  //Initialize multiple precision integers
461  mpiInit(&t1);
462  mpiInit(&t2);
463  mpiInit(&t3);
464  mpiInit(&t4);
465  mpiInit(&t5);
466 
467  //Set t1 = Sx
468  MPI_CHECK(mpiCopy(&t1, &s->x));
469  //Set t2 = Sy
470  MPI_CHECK(mpiCopy(&t2, &s->y));
471  //Set t3 = Sz
472  MPI_CHECK(mpiCopy(&t3, &s->z));
473 
474  //Point at the infinity?
475  if(mpiCompInt(&t3, 0) == 0)
476  {
477  //Set R = (1, 1, 0)
478  MPI_CHECK(mpiSetValue(&r->x, 1));
479  MPI_CHECK(mpiSetValue(&r->y, 1));
480  MPI_CHECK(mpiSetValue(&r->z, 0));
481  }
482  else
483  {
484  //SECP K1 elliptic curve?
485  if(params->type == EC_CURVE_TYPE_SECP_K1)
486  {
487  //Compute t5 = t1^2
488  EC_CHECK(ecSqrMod(params, &t5, &t1));
489  //Compute t4 = 3 * t5
490  EC_CHECK(ecAddMod(params, &t4, &t5, &t5));
491  EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
492  }
493  //SECP R1 elliptic curve?
494  else if(params->type == EC_CURVE_TYPE_SECP_R1)
495  {
496  //Compute t4 = t3^2
497  EC_CHECK(ecSqrMod(params, &t4, &t3));
498  //Compute t5 = t1 - t4
499  EC_CHECK(ecSubMod(params, &t5, &t1, &t4));
500  //Compute t4 = t1 + t4
501  EC_CHECK(ecAddMod(params, &t4, &t1, &t4));
502  //Compute t5 = t4 * t5
503  EC_CHECK(ecMulMod(params, &t5, &t4, &t5));
504  //Compute t4 = 3 * t5
505  EC_CHECK(ecAddMod(params, &t4, &t5, &t5));
506  EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
507  }
508  else
509  {
510  //Compute t4 = t3^4
511  EC_CHECK(ecSqrMod(params, &t4, &t3));
512  EC_CHECK(ecSqrMod(params, &t4, &t4));
513  //Compute t4 = a * t4
514  EC_CHECK(ecMulMod(params, &t4, &t4, &params->a));
515  //Compute t5 = t1^2
516  EC_CHECK(ecSqrMod(params, &t5, &t1));
517  //Compute t4 = t4 + 3 * t5
518  EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
519  EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
520  EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
521  }
522 
523  //Compute t3 = t3 * t2
524  EC_CHECK(ecMulMod(params, &t3, &t3, &t2));
525  //Compute t3 = 2 * t3
526  EC_CHECK(ecAddMod(params, &t3, &t3, &t3));
527  //Compute t2 = t2^2
528  EC_CHECK(ecSqrMod(params, &t2, &t2));
529  //Compute t5 = t1 * t2
530  EC_CHECK(ecMulMod(params, &t5, &t1, &t2));
531  //Compute t5 = 4 * t5
532  EC_CHECK(ecAddMod(params, &t5, &t5, &t5));
533  EC_CHECK(ecAddMod(params, &t5, &t5, &t5));
534  //Compute t1 = t4^2
535  EC_CHECK(ecSqrMod(params, &t1, &t4));
536  //Compute t1 = t1 - 2 * t5
537  EC_CHECK(ecSubMod(params, &t1, &t1, &t5));
538  EC_CHECK(ecSubMod(params, &t1, &t1, &t5));
539  //Compute t2 = t2^2
540  EC_CHECK(ecSqrMod(params, &t2, &t2));
541  //Compute t2 = 8 * t2
542  EC_CHECK(ecAddMod(params, &t2, &t2, &t2));
543  EC_CHECK(ecAddMod(params, &t2, &t2, &t2));
544  EC_CHECK(ecAddMod(params, &t2, &t2, &t2));
545  //Compute t5 = t5 - t1
546  EC_CHECK(ecSubMod(params, &t5, &t5, &t1));
547  //Compute t5 = t4 * t5
548  EC_CHECK(ecMulMod(params, &t5, &t4, &t5));
549  //Compute t2 = t5 - t2
550  EC_CHECK(ecSubMod(params, &t2, &t5, &t2));
551 
552  //Set Rx = t1
553  MPI_CHECK(mpiCopy(&r->x, &t1));
554  //Set Ry = t2
555  MPI_CHECK(mpiCopy(&r->y, &t2));
556  //Set Rz = t3
557  MPI_CHECK(mpiCopy(&r->z, &t3));
558  }
559 
560 end:
561  //Release multiple precision integers
562  mpiFree(&t1);
563  mpiFree(&t2);
564  mpiFree(&t3);
565  mpiFree(&t4);
566  mpiFree(&t5);
567 
568  //Return status code
569  return error;
570 }
571 
572 
573 /**
574  * @brief Point addition (helper routine)
575  * @param[in] params EC domain parameters
576  * @param[out] r Resulting point R = S + T
577  * @param[in] s First operand
578  * @param[in] t Second operand
579  * @return Error code
580  **/
581 
583  const EcPoint *s, const EcPoint *t)
584 {
585  error_t error;
586  Mpi t1;
587  Mpi t2;
588  Mpi t3;
589  Mpi t4;
590  Mpi t5;
591  Mpi t6;
592  Mpi t7;
593 
594  //Initialize multiple precision integers
595  mpiInit(&t1);
596  mpiInit(&t2);
597  mpiInit(&t3);
598  mpiInit(&t4);
599  mpiInit(&t5);
600  mpiInit(&t6);
601  mpiInit(&t7);
602 
603  //Set t1 = Sx
604  MPI_CHECK(mpiCopy(&t1, &s->x));
605  //Set t2 = Sy
606  MPI_CHECK(mpiCopy(&t2, &s->y));
607  //Set t3 = Sz
608  MPI_CHECK(mpiCopy(&t3, &s->z));
609  //Set t4 = Tx
610  MPI_CHECK(mpiCopy(&t4, &t->x));
611  //Set t5 = Ty
612  MPI_CHECK(mpiCopy(&t5, &t->y));
613 
614  //Check whether Tz != 1
615  if(mpiCompInt(&t->z, 1) != 0)
616  {
617  //Compute t6 = Tz
618  MPI_CHECK(mpiCopy(&t6, &t->z));
619  //Compute t7 = t6^2
620  EC_CHECK(ecSqrMod(params, &t7, &t6));
621  //Compute t1 = t1 * t7
622  EC_CHECK(ecMulMod(params, &t1, &t1, &t7));
623  //Compute t7 = t6 * t7
624  EC_CHECK(ecMulMod(params, &t7, &t6, &t7));
625  //Compute t2 = t2 * t7
626  EC_CHECK(ecMulMod(params, &t2, &t2, &t7));
627  }
628 
629  //Compute t7 = t3^2
630  EC_CHECK(ecSqrMod(params, &t7, &t3));
631  //Compute t4 = t4 * t7
632  EC_CHECK(ecMulMod(params, &t4, &t4, &t7));
633  //Compute t7 = t3 * t7
634  EC_CHECK(ecMulMod(params, &t7, &t3, &t7));
635  //Compute t5 = t5 * t7
636  EC_CHECK(ecMulMod(params, &t5, &t5, &t7));
637  //Compute t4 = t1 - t4
638  EC_CHECK(ecSubMod(params, &t4, &t1, &t4));
639  //Compute t5 = t2 - t5
640  EC_CHECK(ecSubMod(params, &t5, &t2, &t5));
641 
642  //Check whether t4 == 0
643  if(mpiCompInt(&t4, 0) == 0)
644  {
645  //Check whether t5 == 0
646  if(mpiCompInt(&t5, 0) == 0)
647  {
648  //Set R = (0, 0, 0)
649  MPI_CHECK(mpiSetValue(&r->x, 0));
650  MPI_CHECK(mpiSetValue(&r->y, 0));
651  MPI_CHECK(mpiSetValue(&r->z, 0));
652  }
653  else
654  {
655  //Set R = (1, 1, 0)
656  MPI_CHECK(mpiSetValue(&r->x, 1));
657  MPI_CHECK(mpiSetValue(&r->y, 1));
658  MPI_CHECK(mpiSetValue(&r->z, 0));
659  }
660  }
661  else
662  {
663  //Compute t1 = 2 * t1 - t4
664  EC_CHECK(ecAddMod(params, &t1, &t1, &t1));
665  EC_CHECK(ecSubMod(params, &t1, &t1, &t4));
666  //Compute t2 = 2 * t2 - t5
667  EC_CHECK(ecAddMod(params, &t2, &t2, &t2));
668  EC_CHECK(ecSubMod(params, &t2, &t2, &t5));
669 
670  //Check whether Tz != 1
671  if(mpiCompInt(&t->z, 1) != 0)
672  {
673  //Compute t3 = t3 * t6
674  EC_CHECK(ecMulMod(params, &t3, &t3, &t6));
675  }
676 
677  //Compute t3 = t3 * t4
678  EC_CHECK(ecMulMod(params, &t3, &t3, &t4));
679  //Compute t7 = t4^2
680  EC_CHECK(ecSqrMod(params, &t7, &t4));
681  //Compute t4 = t4 * t7
682  EC_CHECK(ecMulMod(params, &t4, &t4, &t7));
683  //Compute t7 = t1 * t7
684  EC_CHECK(ecMulMod(params, &t7, &t1, &t7));
685  //Compute t1 = t5^2
686  EC_CHECK(ecSqrMod(params, &t1, &t5));
687  //Compute t1 = t1 - t7
688  EC_CHECK(ecSubMod(params, &t1, &t1, &t7));
689  //Compute t7 = t7 - 2 * t1
690  EC_CHECK(ecAddMod(params, &t6, &t1, &t1));
691  EC_CHECK(ecSubMod(params, &t7, &t7, &t6));
692  //Compute t5 = t5 * t7
693  EC_CHECK(ecMulMod(params, &t5, &t5, &t7));
694  //Compute t4 = t2 * t4
695  EC_CHECK(ecMulMod(params, &t4, &t2, &t4));
696  //Compute t2 = t5 - t4
697  EC_CHECK(ecSubMod(params, &t2, &t5, &t4));
698 
699  //Compute t2 = t2 / 2
700  if(mpiIsEven(&t2))
701  {
702  MPI_CHECK(mpiShiftRight(&t2, 1));
703  }
704  else
705  {
706  MPI_CHECK(mpiAdd(&t2, &t2, &params->p));
707  MPI_CHECK(mpiShiftRight(&t2, 1));
708  }
709 
710  //Set Rx = t1
711  MPI_CHECK(mpiCopy(&r->x, &t1));
712  //Set Ry = t2
713  MPI_CHECK(mpiCopy(&r->y, &t2));
714  //Set Rz = t3
715  MPI_CHECK(mpiCopy(&r->z, &t3));
716  }
717 
718 end:
719  //Release multiple precision integers
720  mpiFree(&t1);
721  mpiFree(&t2);
722  mpiFree(&t3);
723  mpiFree(&t4);
724  mpiFree(&t5);
725  mpiFree(&t6);
726  mpiFree(&t7);
727 
728  //Return status code
729  return error;
730 }
731 
732 
733 /**
734  * @brief Point addition
735  * @param[in] params EC domain parameters
736  * @param[out] r Resulting point R = S + T
737  * @param[in] s First operand
738  * @param[in] t Second operand
739  * @return Error code
740  **/
741 
743  const EcPoint *s, const EcPoint *t)
744 {
745  error_t error;
746 
747  //Check whether Sz == 0
748  if(mpiCompInt(&s->z, 0) == 0)
749  {
750  //Set R = T
751  MPI_CHECK(mpiCopy(&r->x, &t->x));
752  MPI_CHECK(mpiCopy(&r->y, &t->y));
753  MPI_CHECK(mpiCopy(&r->z, &t->z));
754  }
755  //Check whether Tz == 0
756  else if(mpiCompInt(&t->z, 0) == 0)
757  {
758  //Set R = S
759  MPI_CHECK(mpiCopy(&r->x, &s->x));
760  MPI_CHECK(mpiCopy(&r->y, &s->y));
761  MPI_CHECK(mpiCopy(&r->z, &s->z));
762  }
763  else
764  {
765  //Compute R = S + T
766  EC_CHECK(ecAdd(params, r, s, t));
767 
768  //Check whether R == (0, 0, 0)
769  if(mpiCompInt(&r->x, 0) == 0 &&
770  mpiCompInt(&r->y, 0) == 0 &&
771  mpiCompInt(&r->z, 0) == 0)
772  {
773  //Compute R = 2 * S
774  EC_CHECK(ecDouble(params, r, s));
775  }
776  }
777 
778 end:
779  //Return status code
780  return error;
781 }
782 
783 
784 /**
785  * @brief Point subtraction
786  * @param[in] params EC domain parameters
787  * @param[out] r Resulting point R = S - T
788  * @param[in] s First operand
789  * @param[in] t Second operand
790  * @return Error code
791  **/
792 
794  const EcPoint *s, const EcPoint *t)
795 {
796  error_t error;
797  EcPoint u;
798 
799  //Initialize EC point
800  ecInit(&u);
801 
802  //Set Ux = Tx and Uz = Tz
803  MPI_CHECK(mpiCopy(&u.x, &t->x));
804  MPI_CHECK(mpiCopy(&u.z, &t->z));
805  //Set Uy = p - Ty
806  MPI_CHECK(mpiSub(&u.y, &params->p, &t->y));
807 
808  //Compute R = S + U
809  EC_CHECK(ecFullAdd(params, r, s, &u));
810 
811 end:
812  //Release EC point
813  ecFree(&u);
814 
815  //Return status code
816  return error;
817 }
818 
819 
820 /**
821  * @brief Scalar multiplication
822  * @param[in] params EC domain parameters
823  * @param[out] r Resulting point R = d.S
824  * @param[in] d An integer d such as 0 <= d < p
825  * @param[in] s EC point
826  * @return Error code
827  **/
828 
829 error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d,
830  const EcPoint *s)
831 {
832  error_t error;
833  uint_t i;
834  Mpi h;
835 
836  //Initialize multiple precision integer
837  mpiInit(&h);
838 
839  //Check whether d == 0
840  if(mpiCompInt(d, 0) == 0)
841  {
842  //Set R = (1, 1, 0)
843  MPI_CHECK(mpiSetValue(&r->x, 1));
844  MPI_CHECK(mpiSetValue(&r->y, 1));
845  MPI_CHECK(mpiSetValue(&r->z, 0));
846  }
847  //Check whether d == 1
848  else if(mpiCompInt(d, 1) == 0)
849  {
850  //Set R = S
851  MPI_CHECK(mpiCopy(&r->x, &s->x));
852  MPI_CHECK(mpiCopy(&r->y, &s->y));
853  MPI_CHECK(mpiCopy(&r->z, &s->z));
854  }
855  //Check whether Sz == 0
856  else if(mpiCompInt(&s->z, 0) == 0)
857  {
858  //Set R = (1, 1, 0)
859  MPI_CHECK(mpiSetValue(&r->x, 1));
860  MPI_CHECK(mpiSetValue(&r->y, 1));
861  MPI_CHECK(mpiSetValue(&r->z, 0));
862  }
863  else
864  {
865  //Check whether Sz != 1
866  if(mpiCompInt(&s->z, 1) != 0)
867  {
868  //Normalize S
869  EC_CHECK(ecAffinify(params, r, s));
870  EC_CHECK(ecProjectify(params, r, r));
871  }
872  else
873  {
874  //Set R = S
875  MPI_CHECK(mpiCopy(&r->x, &s->x));
876  MPI_CHECK(mpiCopy(&r->y, &s->y));
877  MPI_CHECK(mpiCopy(&r->z, &s->z));
878  }
879 
880 //Left-to-right binary method
881 #if 0
882  for(i = mpiGetBitLength(d) - 1; i >= 1; i--)
883  {
884  //Point doubling
885  EC_CHECK(ecDouble(params, r, r));
886 
887  if(mpiGetBitValue(d, i - 1))
888  {
889  //Compute R = R + S
890  EC_CHECK(ecFullAdd(params, r, r, s));
891  }
892  }
893 //Fast left-to-right binary method
894 #else
895  //Precompute h = 3 * d
896  MPI_CHECK(mpiAdd(&h, d, d));
897  MPI_CHECK(mpiAdd(&h, &h, d));
898 
899  //Scalar multiplication
900  for(i = mpiGetBitLength(&h) - 2; i >= 1; i--)
901  {
902  //Point doubling
903  EC_CHECK(ecDouble(params, r, r));
904 
905  //Check whether h(i) == 1 and k(i) == 0
906  if(mpiGetBitValue(&h, i) && !mpiGetBitValue(d, i))
907  {
908  //Compute R = R + S
909  EC_CHECK(ecFullAdd(params, r, r, s));
910  }
911  //Check whether h(i) == 0 and k(i) == 1
912  else if(!mpiGetBitValue(&h, i) && mpiGetBitValue(d, i))
913  {
914  //Compute R = R - S
915  EC_CHECK(ecFullSub(params, r, r, s));
916  }
917  }
918 #endif
919  }
920 
921 end:
922  //Release multiple precision integer
923  mpiFree(&h);
924 
925  //Return status code
926  return error;
927 }
928 
929 
930 /**
931  * @brief An auxiliary function for the twin multiplication
932  * @param[in] t An integer T such as 0 <= T <= 31
933  * @return Output value
934  **/
935 
937 {
938  uint_t h;
939 
940  //Check the value of T
941  if(18 <= t && t < 22)
942  {
943  h = 9;
944  }
945  else if(14 <= t && t < 18)
946  {
947  h = 10;
948  }
949  else if(22 <= t && t < 24)
950  {
951  h = 11;
952  }
953  else if(4 <= t && t < 12)
954  {
955  h = 14;
956  }
957  else
958  {
959  h = 12;
960  }
961 
962  //Return value
963  return h;
964 }
965 
966 
967 /**
968  * @brief Twin multiplication
969  * @param[in] params EC domain parameters
970  * @param[out] r Resulting point R = d0.S + d1.T
971  * @param[in] d0 An integer d such as 0 <= d0 < p
972  * @param[in] s EC point
973  * @param[in] d1 An integer d such as 0 <= d1 < p
974  * @param[in] t EC point
975  * @return Error code
976  **/
977 
979  const Mpi *d0, const EcPoint *s, const Mpi *d1, const EcPoint *t)
980 {
981  error_t error;
982  int_t k;
983  uint_t m;
984  uint_t m0;
985  uint_t m1;
986  uint_t c0;
987  uint_t c1;
988  uint_t h0;
989  uint_t h1;
990  int_t u0;
991  int_t u1;
992  EcPoint spt;
993  EcPoint smt;
994 
995  //Initialize EC points
996  ecInit(&spt);
997  ecInit(&smt);
998 
999  //Precompute SpT = S + T
1000  EC_CHECK(ecFullAdd(params, &spt, s, t));
1001  //Precompute SmT = S - T
1002  EC_CHECK(ecFullSub(params, &smt, s, t));
1003 
1004  //Let m0 be the bit length of d0
1005  m0 = mpiGetBitLength(d0);
1006  //Let m1 be the bit length of d1
1007  m1 = mpiGetBitLength(d1);
1008  //Let m = MAX(m0, m1)
1009  m = MAX(m0, m1);
1010 
1011  //Let c be a 2 x 6 binary matrix
1012  c0 = mpiGetBitValue(d0, m - 4);
1013  c0 |= mpiGetBitValue(d0, m - 3) << 1;
1014  c0 |= mpiGetBitValue(d0, m - 2) << 2;
1015  c0 |= mpiGetBitValue(d0, m - 1) << 3;
1016  c1 = mpiGetBitValue(d1, m - 4);
1017  c1 |= mpiGetBitValue(d1, m - 3) << 1;
1018  c1 |= mpiGetBitValue(d1, m - 2) << 2;
1019  c1 |= mpiGetBitValue(d1, m - 1) << 3;
1020 
1021  //Set R = (1, 1, 0)
1022  MPI_CHECK(mpiSetValue(&r->x, 1));
1023  MPI_CHECK(mpiSetValue(&r->y, 1));
1024  MPI_CHECK(mpiSetValue(&r->z, 0));
1025 
1026  //Calculate both multiplications at the same time
1027  for(k = m; k >= 0; k--)
1028  {
1029  //Compute h(0) = 16 * c(0,1) + 8 * c(0,2) + 4 * c(0,3) + 2 * c(0,4) + c(0,5)
1030  h0 = c0 & 0x1F;
1031 
1032  //Check whether c(0,0) == 1
1033  if(c0 & 0x20)
1034  {
1035  h0 = 31 - h0;
1036  }
1037 
1038  //Compute h(1) = 16 * c(1,1) + 8 * c(1,2) + 4 * c(1,3) + 2 * c(1,4) + c(1,5)
1039  h1 = c1 & 0x1F;
1040 
1041  //Check whether c(1,0) == 1
1042  if(c1 & 0x20)
1043  {
1044  h1 = 31 - h1;
1045  }
1046 
1047  //Compute u(0)
1048  if(h0 < ecTwinMultF(h1))
1049  {
1050  u0 = 0;
1051  }
1052  else if(c0 & 0x20)
1053  {
1054  u0 = -1;
1055  }
1056  else
1057  {
1058  u0 = 1;
1059  }
1060 
1061  //Compute u(1)
1062  if(h1 < ecTwinMultF(h0))
1063  {
1064  u1 = 0;
1065  }
1066  else if(c1 & 0x20)
1067  {
1068  u1 = -1;
1069  }
1070  else
1071  {
1072  u1 = 1;
1073  }
1074 
1075  //Update c matrix
1076  c0 <<= 1;
1077  c0 |= mpiGetBitValue(d0, k - 5);
1078  c0 ^= u0 ? 0x20 : 0x00;
1079  c1 <<= 1;
1080  c1 |= mpiGetBitValue(d1, k - 5);
1081  c1 ^= u1 ? 0x20 : 0x00;
1082 
1083  //Point doubling
1084  EC_CHECK(ecDouble(params, r, r));
1085 
1086  //Check u(0) and u(1)
1087  if(u0 == -1 && u1 == -1)
1088  {
1089  //Compute R = R - SpT
1090  EC_CHECK(ecFullSub(params, r, r, &spt));
1091  }
1092  else if(u0 == -1 && u1 == 0)
1093  {
1094  //Compute R = R - S
1095  EC_CHECK(ecFullSub(params, r, r, s));
1096  }
1097  else if(u0 == -1 && u1 == 1)
1098  {
1099  //Compute R = R - SmT
1100  EC_CHECK(ecFullSub(params, r, r, &smt));
1101  }
1102  else if(u0 == 0 && u1 == -1)
1103  {
1104  //Compute R = R - T
1105  EC_CHECK(ecFullSub(params, r, r, t));
1106  }
1107  else if(u0 == 0 && u1 == 1)
1108  {
1109  //Compute R = R + T
1110  EC_CHECK(ecFullAdd(params, r, r, t));
1111  }
1112  else if(u0 == 1 && u1 == -1)
1113  {
1114  //Compute R = R + SmT
1115  EC_CHECK(ecFullAdd(params, r, r, &smt));
1116  }
1117  else if(u0 == 1 && u1 == 0)
1118  {
1119  //Compute R = R + S
1120  EC_CHECK(ecFullAdd(params, r, r, s));
1121  }
1122  else if(u0 == 1 && u1 == 1)
1123  {
1124  //Compute R = R + SpT
1125  EC_CHECK(ecFullAdd(params, r, r, &spt));
1126  }
1127  }
1128 
1129 end:
1130  //Release EC points
1131  ecFree(&spt);
1132  ecFree(&smt);
1133 
1134  //Return status code
1135  return error;
1136 }
1137 
1138 
1139 /**
1140  * @brief Fast modular addition
1141  * @param[in] params EC domain parameters
1142  * @param[out] r Resulting integer R = (A + B) mod p
1143  * @param[in] a An integer such as 0 <= A < p
1144  * @param[in] b An integer such as 0 <= B < p
1145  * @return Error code
1146  **/
1147 
1148 error_t ecAddMod(const EcDomainParameters *params, Mpi *r, const Mpi *a,
1149  const Mpi *b)
1150 {
1151  error_t error;
1152 
1153  //Compute R = A + B
1154  MPI_CHECK(mpiAdd(r, a, b));
1155 
1156  //Compute R = (A + B) mod p
1157  if(mpiComp(r, &params->p) >= 0)
1158  {
1159  MPI_CHECK(mpiSub(r, r, &params->p));
1160  }
1161 
1162 end:
1163  //Return status code
1164  return error;
1165 }
1166 
1167 
1168 /**
1169  * @brief Fast modular subtraction
1170  * @param[in] params EC domain parameters
1171  * @param[out] r Resulting integer R = (A - B) mod p
1172  * @param[in] a An integer such as 0 <= A < p
1173  * @param[in] b An integer such as 0 <= B < p
1174  * @return Error code
1175  **/
1176 
1177 error_t ecSubMod(const EcDomainParameters *params, Mpi *r, const Mpi *a,
1178  const Mpi *b)
1179 {
1180  error_t error;
1181 
1182  //Compute R = A - B
1183  MPI_CHECK(mpiSub(r, a, b));
1184 
1185  //Compute R = (A - B) mod p
1186  if(mpiCompInt(r, 0) < 0)
1187  {
1188  MPI_CHECK(mpiAdd(r, r, &params->p));
1189  }
1190 
1191 end:
1192  //Return status code
1193  return error;
1194 }
1195 
1196 
1197 /**
1198  * @brief Fast modular multiplication
1199  * @param[in] params EC domain parameters
1200  * @param[out] r Resulting integer R = (A * B) mod p
1201  * @param[in] a An integer such as 0 <= A < p
1202  * @param[in] b An integer such as 0 <= B < p
1203  * @return Error code
1204  **/
1205 
1206 error_t ecMulMod(const EcDomainParameters *params, Mpi *r, const Mpi *a,
1207  const Mpi *b)
1208 {
1209  error_t error;
1210 
1211  //Compute R = A * B
1212  MPI_CHECK(mpiMul(r, a, b));
1213 
1214  //Compute R = (A * B) mod p
1215  if(params->mod != NULL)
1216  {
1217  MPI_CHECK(params->mod(r, &params->p));
1218  }
1219  else
1220  {
1221  MPI_CHECK(mpiMod(r, r, &params->p));
1222  }
1223 
1224 end:
1225  //Return status code
1226  return error;
1227 }
1228 
1229 
1230 /**
1231  * @brief Fast modular squaring
1232  * @param[in] params EC domain parameters
1233  * @param[out] r Resulting integer R = (A ^ 2) mod p
1234  * @param[in] a An integer such as 0 <= A < p
1235  * @return Error code
1236  **/
1237 
1238 error_t ecSqrMod(const EcDomainParameters *params, Mpi *r, const Mpi *a)
1239 {
1240  error_t error;
1241 
1242  //Compute R = A ^ 2
1243  MPI_CHECK(mpiMul(r, a, a));
1244 
1245  //Compute R = (A ^ 2) mod p
1246  if(params->mod != NULL)
1247  {
1248  MPI_CHECK(params->mod(r, &params->p));
1249  }
1250  else
1251  {
1252  MPI_CHECK(mpiMod(r, r, &params->p));
1253  }
1254 
1255 end:
1256  //Return status code
1257  return error;
1258 }
1259 
1260 #endif
#define ED448_PUBLIC_KEY_LEN
Definition: ed448.h:39
size_t bLen
Length of b.
Definition: ec_curves.h:301
#define CURVE448_BYTE_LEN
Definition: curve448.h:37
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:747
size_t qLen
Length of q.
Definition: ec_curves.h:307
ECC (Elliptic Curve Cryptography)
EC domain parameters.
Definition: ec.h:61
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:60
Arbitrary precision integer.
Definition: mpi.h:67
Curve448 elliptic curve (constant-time implementation)
error_t ecAdd(const EcDomainParameters *params, EcPoint *r, const EcPoint *s, const EcPoint *t)
Point addition (helper routine)
Definition: ec.c:582
#define CURVE25519_BYTE_LEN
Definition: curve25519.h:37
EcCurveType type
Curve type.
Definition: ec_curves.h:295
Debugging facilities.
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:91
Generic error code.
Definition: error.h:43
#define mpiIsEven(a)
Definition: mpi.h:43
error_t ecAffinify(const EcDomainParameters *params, EcPoint *r, const EcPoint *s)
Recover affine representation.
Definition: ec.c:362
error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d, const EcPoint *s)
Scalar multiplication.
Definition: ec.c:829
General definitions for cryptographic algorithms.
Invalid parameter.
Definition: error.h:45
Elliptic curve parameters.
Definition: ec_curves.h:290
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:287
EcFastModAlgo mod
Fast modular reduction.
Definition: ec.h:71
#define EC_CHECK(f)
Definition: ec.h:37
Mpi x
x-coordinate
Definition: ec.h:51
#define MPI_CHECK(f)
Definition: mpi.h:40
error_t ecImport(const EcDomainParameters *params, EcPoint *r, const uint8_t *data, size_t length)
Convert an octet string to an EC point.
Definition: ec.c:208
void ecInit(EcPoint *r)
Initialize elliptic curve point.
Definition: ec.c:150
uint8_t m
Definition: ndp.h:299
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:511
Curve25519 elliptic curve (constant-time implementation)
uint8_t a
Definition: ndp.h:407
uint_t ecTwinMultF(uint_t t)
An auxiliary function for the twin multiplication.
Definition: ec.c:936
#define MAX(a, b)
Definition: os_port.h:64
Mpi b
Curve parameter b.
Definition: ec.h:67
bool_t ecIsPointAffine(const EcDomainParameters *params, const EcPoint *s)
Check whether the affine point S is on the curve.
Definition: ec.c:408
#define TRUE
Definition: os_port.h:48
EcFastModAlgo mod
Fast modular reduction.
Definition: ec_curves.h:309
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:101
EcCurveType type
Curve type.
Definition: ec.h:64
const uint8_t gx[66]
x-coordinate of the base point G
Definition: ec_curves.h:302
Elliptic curve point.
Definition: ec.h:49
error_t ecProjectify(const EcDomainParameters *params, EcPoint *r, const EcPoint *s)
Compute projective representation.
Definition: ec.c:338
size_t gxLen
Length of Gx.
Definition: ec_curves.h:303
error_t mpiSetValue(Mpi *r, int_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:429
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:33
const uint8_t p[66]
Prime modulus p.
Definition: ec_curves.h:296
size_t gyLen
Length of Gy.
Definition: ec_curves.h:305
signed int int_t
Definition: compiler_port.h:42
Mpi y
y-coordinate
Definition: ec.h:52
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:190
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:73
Mpi q
Order of the point G.
Definition: ec.h:69
Mpi p
Prime.
Definition: ec.h:65
size_t pLen
Length of p.
Definition: ec_curves.h:297
Ed25519 elliptic curve (constant-time implementation)
error_t mpiCopy(Mpi *r, const Mpi *a)
Copy a multiple precision integer.
Definition: mpi.c:392
uint_t mpiGetBitValue(const Mpi *a, uint_t index)
Get the bit value at the specified index.
Definition: mpi.c:262
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:674
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:53
uint8_t s
EcPoint g
Base point G.
Definition: ec.h:68
error_t ecExport(const EcDomainParameters *params, const EcPoint *a, uint8_t *data, size_t *length)
Convert an EC point to an octet string.
Definition: ec.c:281
uint32_t h
Cofactor h.
Definition: ec.h:70
Success.
Definition: error.h:42
error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
Definition: mpi.c:1416
const uint8_t gy[66]
y-coordinate of the base point G
Definition: ec_curves.h:304
error_t
Error codes.
Definition: error.h:40
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:331
void ecFree(EcPoint *r)
Release an elliptic curve point.
Definition: ec.c:164
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:596
const uint8_t q[66]
Order of the base point G.
Definition: ec_curves.h:306
error_t ecDouble(const EcDomainParameters *params, EcPoint *r, const EcPoint *s)
Point doubling.
Definition: ec.c:450
unsigned int uint_t
Definition: compiler_port.h:43
error_t ecSqrMod(const EcDomainParameters *params, Mpi *r, const Mpi *a)
Fast modular squaring.
Definition: ec.c:1238
uint8_t data[]
Definition: dtls_misc.h:167
error_t ecTwinMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d0, const EcPoint *s, const Mpi *d1, const EcPoint *t)
Twin multiplication.
Definition: ec.c:978
const uint8_t b[66]
Curve parameter b.
Definition: ec_curves.h:300
uint32_t t2
error_t ecSubMod(const EcDomainParameters *params, Mpi *r, const Mpi *a, const Mpi *b)
Fast modular subtraction.
Definition: ec.c:1177
uint32_t r
Definition: ndp.h:342
error_t ecMulMod(const EcDomainParameters *params, Mpi *r, const Mpi *a, const Mpi *b)
Fast modular multiplication.
Definition: ec.c:1206
const uint8_t a[66]
Curve parameter a.
Definition: ec_curves.h:298
Mpi a
Curve parameter a.
Definition: ec.h:66
const char_t * name
Curve name.
Definition: ec_curves.h:292
uint32_t t1
Mpi z
z-coordinate
Definition: ec.h:53
Ed448 elliptic curve (constant-time implementation)
uint8_t length
Definition: dtls_misc.h:140
uint8_t h
Definition: ndp.h:297
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:46
error_t ecCopy(EcPoint *r, const EcPoint *s)
Copy EC point.
Definition: ec.c:180
error_t ecFullSub(const EcDomainParameters *params, EcPoint *r, const EcPoint *s, const EcPoint *t)
Point subtraction.
Definition: ec.c:793
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
Definition: mpi.c:1094
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:154
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
#define ED25519_PUBLIC_KEY_LEN
Definition: ed25519.h:39
const char_t * name
Curve name.
Definition: ec.h:63
uint8_t b[6]
Definition: dtls_misc.h:130
size_t aLen
Length of a.
Definition: ec_curves.h:299
error_t ecAddMod(const EcDomainParameters *params, Mpi *r, const Mpi *a, const Mpi *b)
Fast modular addition.
Definition: ec.c:1148
uint32_t h
Cofactor h.
Definition: ec_curves.h:308
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1283
#define TRACE_DEBUG(...)
Definition: debug.h:98
error_t mpiShiftRight(Mpi *r, uint_t n)
Right shift operation.
Definition: mpi.c:1041
error_t ecFullAdd(const EcDomainParameters *params, EcPoint *r, const EcPoint *s, const EcPoint *t)
Point addition.
Definition: ec.c:742
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:45