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