gd32w5xx_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file gd32w5xx_crypto_pkc.c
3  * @brief GD32W5 public-key hardware accelerator (PKCAU)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 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 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "gd32w51x.h"
36 #include "core/crypto.h"
39 #include "pkc/rsa.h"
40 #include "ecc/ec.h"
41 #include "ecc/ecdsa.h"
42 #include "ecc/curve25519.h"
43 #include "ecc/curve448.h"
44 #include "debug.h"
45 
46 //Check crypto library configuration
47 #if (GD32W5XX_CRYPTO_PKC_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief PKCAU module initialization
52  * @return Error code
53  **/
54 
56 {
57  //Enable PKCAU peripheral clock
58  rcu_periph_clock_enable(RCU_PKCAU);
59 
60  //Reset the PKCAU peripheral
61  PKCAU_CTL = 0;
62 
63  //Enable the PKCAU peripheral
64  while((PKCAU_CTL & PKCAU_CTL_PKCAUEN) == 0)
65  {
66  PKCAU_CTL = PKCAU_CTL_PKCAUEN;
67  }
68 
69  //Clear flags
70  PKCAU_STATC = PKCAU_STATC_ADDRERRC | PKCAU_STATC_RAMERRC | PKCAU_STATC_ENDC;
71 
72  //Successful processing
73  return NO_ERROR;
74 }
75 
76 
77 /**
78  * @brief Import byte array
79  * @param[in] src Pointer to the byte array
80  * @param[in] srcLen Length of the array to be copied, in bytes
81  * @param[in] destLen Length of the operand, in bits
82  * @param[in] offset PKCAU ram offset
83  **/
84 
85 void pkcauImportArray(const uint8_t *src, size_t srcLen, uint_t destLen,
86  uint_t offset)
87 {
88  uint_t i;
89  uint_t j;
90  uint32_t temp;
91 
92  //Retrieve the length of the operand, in words
93  destLen = (destLen + 31) / 32;
94 
95  //Copy the array to the PKCAU RAM
96  for(i = 0, j = 0; i < srcLen; i++)
97  {
98  switch(i % 4)
99  {
100  case 0:
101  temp = src[srcLen - i - 1];
102  break;
103  case 1:
104  temp |= src[srcLen - i - 1] << 8;
105  break;
106  case 2:
107  temp |= src[srcLen - i - 1] << 16;
108  break;
109  default:
110  temp |= src[srcLen - i - 1] << 24;
111  PKCAU_RAM[offset + j] = temp;
112  j++;
113  break;
114  }
115  }
116 
117  //Pad the operand with zeroes
118  for(; i < (destLen * 4); i++)
119  {
120  switch(i % 4)
121  {
122  case 0:
123  temp = 0;
124  break;
125  case 3:
126  PKCAU_RAM[offset + j] = temp;
127  j++;
128  break;
129  default:
130  break;
131  }
132  }
133 
134  //An additional word with all bits equal to zero must be added
135  PKCAU_RAM[offset + j] = 0;
136 }
137 
138 
139 /**
140  * @brief Import multiple-precision integer
141  * @param[in] a Pointer to the multiple-precision integer
142  * @param[in] length Length of the operand, in bits
143  * @param[in] offset PKCAU ram offset
144  **/
145 
146 void pkcauImportMpi(const Mpi *a, uint_t length, uint_t offset)
147 {
148  uint_t i;
149  uint_t n;
150 
151  //Retrieve the length of the operand, in words
152  length = (length + 31) / 32;
153 
154  //Get the actual length of the multiple-precision integer, in words
155  n = mpiGetLength(a);
156 
157  //Copy the multiple-precision integer to the PKCAU RAM
158  for(i = 0; i < n && i < length; i++)
159  {
160  PKCAU_RAM[offset + i] = a->data[i];
161  }
162 
163  //Pad the operand with zeroes
164  for(; i < length; i++)
165  {
166  PKCAU_RAM[offset + i] = 0;
167  }
168 
169  //An additional word with all bits equal to zero must be added
170  PKCAU_RAM[offset + i] = 0;
171 }
172 
173 
174 /**
175  * @brief Export multiple-precision integer
176  * @param[out] r Pointer to the multiple-precision integer
177  * @param[in] length Length of the operand, in bits
178  * @param[in] offset PKCAU ram offset
179  * @return Error code
180  **/
181 
183 {
184  error_t error;
185  uint_t i;
186 
187  //Retrieve the length of the operand, in words
188  length = (length + 31) / 32;
189 
190  //Skip trailing zeroes
191  while(length > 0 && PKCAU_RAM[offset + length - 1] == 0)
192  {
193  length--;
194  }
195 
196  //Ajust the size of the multiple precision integer
197  error = mpiGrow(r, length);
198 
199  //Check status code
200  if(!error)
201  {
202  //Copy the multiple-precision integer from the PKCAU RAM
203  for(i = 0; i < length; i++)
204  {
205  r->data[i] = PKCAU_RAM[offset + i];
206  }
207 
208  //Pad the resulting value with zeroes
209  for(; i < r->size; i++)
210  {
211  r->data[i] = 0;
212  }
213 
214  //Set the sign
215  r->sign = 1;
216  }
217 
218  //Return status code
219  return error;
220 }
221 
222 
223 /**
224  * @brief Modular exponentiation
225  * @param[out] r Resulting integer R = A ^ E mod P
226  * @param[in] a Pointer to a multiple precision integer
227  * @param[in] e Exponent
228  * @param[in] p Modulus
229  * @return Error code
230  **/
231 
232 error_t pkcauModExp(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
233 {
234  error_t error;
235  uint_t modLen;
236  uint_t expLen;
237  uint32_t temp;
238 
239  //Retrieve the length of the modulus, in bits
240  modLen = mpiGetBitLength(p);
241  //Retrieve the length of the exponent, in bits
242  expLen = mpiGetBitLength(e);
243 
244  //Check the length of the operands
245  if(modLen <= PKCAU_MAX_ROS && expLen <= PKCAU_MAX_ROS)
246  {
247  //Reduce the operand first
248  error = mpiMod(r, a, p);
249 
250  //Check status code
251  if(!error)
252  {
253  //Acquire exclusive access to the PKCAU module
255 
256  //Specify the length of the operand, in bits
258  //Specify the length of the exponent, in bits
260 
261  //Load input arguments into the PKCAU internal RAM
265 
266  //Disable interrupts
267  PKCAU_CTL &= ~(PKCAU_CTL_ADDRERRIE | PKCAU_CTL_RAMERRIE | PKCAU_CTL_ENDIE);
268 
269  //Write in the MODESEL field of PKCAU_CTL register, specifying the operation
270  //which is to be executed
271  temp = PKCAU_CTL & ~PKCAU_CTL_MODESEL;
272  PKCAU_CTL = temp | PKCAU_MODE_MOD_EXP;
273 
274  //Then assert the START bit in PKCAU_CTL register
275  PKCAU_CTL |= PKCAU_CTL_START;
276 
277  //Wait until the ENDF bit in the PKCAU_STAT register is set to 1,
278  //indicating that the computation is complete
279  while((PKCAU_STAT & PKCAU_STAT_ENDF) == 0)
280  {
281  }
282 
283  //Read the result data from the PKCAU internal RAM
284  error = pkcauExportMpi(r, modLen, PKCAU_MOD_EXP_OUT_R);
285 
286  //Then clear ENDC bit by setting ENDC bit in PKCAU_STATC
287  PKCAU_STATC = PKCAU_STATC_ENDC;
288 
289  //Release exclusive access to the PKCAU module
291  }
292  }
293  else
294  {
295  //Perform modular exponentiation
296  error = mpiExpMod(r, a, e, p);
297  }
298 
299  //Return status code
300  return error;
301 }
302 
303 
304 /**
305  * @brief Modular exponentiation with CRT
306  * @param[in] key RSA public key
307  * @param[in] m Message representative
308  * @param[out] c Ciphertext representative
309  * @return Error code
310  **/
311 
313 {
314  error_t error;
315  uint_t nLen;
316  uint_t pLen;
317  uint_t qLen;
318  uint_t dpLen;
319  uint_t dqLen;
320  uint_t qinvLen;
321  uint32_t temp;
322 
323  //Retrieve the length of the private key
324  nLen = mpiGetBitLength(&key->n);
325  pLen = mpiGetBitLength(&key->p);
326  qLen = mpiGetBitLength(&key->q);
327  dpLen = mpiGetBitLength(&key->dp);
328  dqLen = mpiGetBitLength(&key->dq);
329  qinvLen = mpiGetBitLength(&key->qinv);
330 
331  //Check the length of the operands
332  if(nLen <= PKCAU_MAX_ROS && pLen <= (nLen / 2) && qLen <= (nLen / 2) &&
333  dpLen <= (nLen / 2) && dqLen <= (nLen / 2) && qinvLen <= (nLen / 2))
334  {
335  //Acquire exclusive access to the PKCAU module
337 
338  //Specify the length of the operand, in bits
340 
341  //Load input arguments into the PKCAU internal RAM
342  pkcauImportMpi(&key->p, nLen / 2, PKCAU_RSA_CRT_EXP_IN_P);
343  pkcauImportMpi(&key->q, nLen / 2, PKCAU_RSA_CRT_EXP_IN_Q);
344  pkcauImportMpi(&key->dp, nLen / 2, PKCAU_RSA_CRT_EXP_IN_DP);
345  pkcauImportMpi(&key->dq, nLen / 2, PKCAU_RSA_CRT_EXP_IN_DQ);
348 
349  //Disable interrupts
350  PKCAU_CTL &= ~(PKCAU_CTL_ADDRERRIE | PKCAU_CTL_RAMERRIE | PKCAU_CTL_ENDIE);
351 
352  //Write in the MODESEL field of PKCAU_CTL register, specifying the operation
353  //which is to be executed
354  temp = PKCAU_CTL & ~PKCAU_CTL_MODESEL;
355  PKCAU_CTL = temp | PKCAU_MODE_CRT_EXP;
356 
357  //Then assert the START bit in PKCAU_CTL register
358  PKCAU_CTL |= PKCAU_CTL_START;
359 
360  //Wait until the ENDF bit in the PKCAU_STAT register is set to 1,
361  //indicating that the computation is complete
362  while((PKCAU_STAT & PKCAU_STAT_ENDF) == 0)
363  {
364  }
365 
366  //Read the result data from the PKCAU internal RAM
367  error = pkcauExportMpi(m, nLen, PKCAU_RSA_CRT_EXP_OUT_R);
368 
369  //Then clear ENDC bit by setting ENDC bit in PKCAU_STATC
370  PKCAU_STATC = PKCAU_STATC_ENDC;
371 
372  //Release exclusive access to the PKCAU module
374  }
375  else
376  {
377  Mpi m1;
378  Mpi m2;
379  Mpi h;
380 
381  //Initialize multiple-precision integers
382  mpiInit(&m1);
383  mpiInit(&m2);
384  mpiInit(&h);
385 
386  //Compute m1 = c ^ dP mod p
387  error = pkcauModExp(&m1, c, &key->dp, &key->p);
388 
389  //Check status code
390  if(!error)
391  {
392  //Compute m2 = c ^ dQ mod q
393  error = pkcauModExp(&m2, c, &key->dq, &key->q);
394  }
395 
396  //Check status code
397  if(!error)
398  {
399  //Let h = (m1 - m2) * qInv mod p
400  error = mpiSub(&h, &m1, &m2);
401  }
402 
403  //Check status code
404  if(!error)
405  {
406  error = mpiMulMod(&h, &h, &key->qinv, &key->p);
407  }
408 
409  //Check status code
410  if(!error)
411  {
412  //Let m = m2 + q * h
413  error = mpiMul(m, &key->q, &h);
414  }
415 
416  //Check status code
417  if(!error)
418  {
419  error = mpiAdd(m, m, &m2);
420  }
421 
422  //Free previously allocated memory
423  mpiFree(&m1);
424  mpiFree(&m2);
425  mpiFree(&h);
426  }
427 
428  //Return status code
429  return error;
430 }
431 
432 
433 /**
434  * @brief RSA encryption primitive
435  * @param[in] key RSA public key
436  * @param[in] m Message representative
437  * @param[out] c Ciphertext representative
438  * @return Error code
439  **/
440 
441 error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
442 {
443  size_t nLen;
444  size_t eLen;
445 
446  //Retrieve the length of the public key
447  nLen = mpiGetLength(&key->n);
448  eLen = mpiGetLength(&key->e);
449 
450  //Sanity check
451  if(nLen == 0 || eLen == 0)
453 
454  //The message representative m shall be between 0 and n - 1
455  if(mpiCompInt(m, 0) < 0 || mpiComp(m, &key->n) >= 0)
456  return ERROR_OUT_OF_RANGE;
457 
458  //Perform modular exponentiation (c = m ^ e mod n)
459  return pkcauModExp(c, m, &key->e, &key->n);
460 }
461 
462 
463 /**
464  * @brief RSA decryption primitive
465  * @param[in] key RSA private key
466  * @param[in] c Ciphertext representative
467  * @param[out] m Message representative
468  * @return Error code
469  **/
470 
471 error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
472 {
473  error_t error;
474 
475  //The ciphertext representative c shall be between 0 and n - 1
476  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
477  return ERROR_OUT_OF_RANGE;
478 
479  //Use the Chinese remainder algorithm?
480  if(mpiGetLength(&key->n) > 0 && mpiGetLength(&key->p) > 0 &&
481  mpiGetLength(&key->q) > 0 && mpiGetLength(&key->dp) > 0 &&
482  mpiGetLength(&key->dq) > 0 && mpiGetLength(&key->qinv) > 0)
483  {
484  //Perform modular exponentiation (with CRT)
485  error = pkcauRsaCrtExp(key, c, m);
486  }
487  else if(mpiGetLength(&key->n) > 0 && mpiGetLength(&key->d) > 0)
488  {
489  //Perform modular exponentiation (without CRT)
490  error = pkcauModExp(m, c, &key->d, &key->n);
491  }
492  else
493  {
494  //Invalid parameters
495  error = ERROR_INVALID_PARAMETER;
496  }
497 
498  //Return status code
499  return error;
500 }
501 
502 
503 /**
504  * @brief Scalar multiplication
505  * @param[in] params EC domain parameters
506  * @param[out] r Resulting point R = d.S
507  * @param[in] d An integer d such as 0 <= d < p
508  * @param[in] s EC point
509  * @return Error code
510  **/
511 
512 error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d,
513  const EcPoint *s)
514 {
515  error_t error;
516  uint_t modLen;
517  uint_t scalarLen;
518  uint32_t temp;
519 
520  //Retrieve the length of the modulus, in bits
521  modLen = mpiGetBitLength(&params->p);
522  //Retrieve the length of the scalar, in bits
523  scalarLen = mpiGetBitLength(d);
524 
525  //Check the length of the operands
526  if(modLen <= PKCAU_MAX_EOS && scalarLen <= PKCAU_MAX_EOS)
527  {
528  //Acquire exclusive access to the PKCAU module
530 
531  //Specify the length of the modulus, in bits
533  //Specify the length of the scalar, in bits
535  //Set the sign of the coefficient A
537 
538  //Load input arguments into the PKCAU internal RAM
539  pkcauImportMpi(&params->p, modLen, PKCAU_ECC_MUL_IN_P);
540  pkcauImportMpi(&params->a, modLen, PKCAU_ECC_MUL_IN_A);
541  pkcauImportMpi(d, scalarLen, PKCAU_ECC_MUL_IN_K);
542  pkcauImportMpi(&s->x, modLen, PKCAU_ECC_MUL_IN_X);
543  pkcauImportMpi(&s->y, modLen, PKCAU_ECC_MUL_IN_Y);
544 
545  //Disable interrupts
546  PKCAU_CTL &= ~(PKCAU_CTL_ADDRERRIE | PKCAU_CTL_RAMERRIE | PKCAU_CTL_ENDIE);
547 
548  //Write in the MODESEL field of PKCAU_CTL register, specifying the operation
549  //which is to be executed
550  temp = PKCAU_CTL & ~PKCAU_CTL_MODESEL;
551  PKCAU_CTL = temp | PKCAU_MODE_ECC_MUL;
552 
553  //Then assert the START bit in PKCAU_CTL register
554  PKCAU_CTL |= PKCAU_CTL_START;
555 
556  //Wait until the ENDF bit in the PKCAU_STAT register is set to 1,
557  //indicating that the computation is complete
558  while((PKCAU_STAT & PKCAU_STAT_ENDF) == 0)
559  {
560  }
561 
562  //Copy the x-coordinate of the result
563  error = pkcauExportMpi(&r->x, modLen, PKCAU_ECC_MUL_OUT_X);
564 
565  //Check status code
566  if(!error)
567  {
568  //Copy the y-coordinate of the result
569  error = pkcauExportMpi(&r->y, modLen, PKCAU_ECC_MUL_OUT_Y);
570  }
571 
572  //Check status code
573  if(!error)
574  {
575  //Set the z-coordinate of the result
576  error = mpiSetValue(&r->z, 1);
577  }
578 
579  //Then clear ENDC bit by setting ENDC bit in PKCAU_STATC
580  PKCAU_STATC = PKCAU_STATC_ENDC;
581 
582  //Release exclusive access to the PKCAU module
584  }
585  else
586  {
587  //Report an error
588  error = ERROR_FAILURE;
589  }
590 
591  //Return status code
592  return error;
593 }
594 
595 
596 /**
597  * @brief ECDSA signature generation
598  * @param[in] prngAlgo PRNG algorithm
599  * @param[in] prngContext Pointer to the PRNG context
600  * @param[in] params EC domain parameters
601  * @param[in] privateKey Signer's EC private key
602  * @param[in] digest Digest of the message to be signed
603  * @param[in] digestLen Length in octets of the digest
604  * @param[out] signature (R, S) integer pair
605  * @return Error code
606  **/
607 
608 error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
609  const EcDomainParameters *params, const EcPrivateKey *privateKey,
610  const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
611 {
612  error_t error;
613  size_t modLen;
614  size_t orderLen;
615  uint32_t temp;
616  Mpi k;
617 
618  //Check parameters
619  if(params == NULL || privateKey == NULL || digest == NULL || signature == NULL)
621 
622  //Retrieve the length of the modulus, in bits
623  modLen = mpiGetBitLength(&params->p);
624  //Retrieve the length of the base point order, in bits
625  orderLen = mpiGetBitLength(&params->q);
626 
627  //Check the length of the operands
628  if(modLen > PKCAU_MAX_EOS || orderLen > PKCAU_MAX_EOS)
629  return ERROR_FAILURE;
630 
631  //Initialize multiple precision integers
632  mpiInit(&k);
633 
634  //Generate a random number k such as 0 < k < q - 1
635  error = mpiRandRange(&k, &params->q, prngAlgo, prngContext);
636 
637  //Check status code
638  if(!error)
639  {
640  //Acquire exclusive access to the PKCAU module
642 
643  //Specify the length of the modulus, in bits
645  //Specify the length of the base point order, in bits
647  //Set the sign of the coefficient A
649 
650  //Load input arguments into the PKCAU internal RAM
651  pkcauImportMpi(&params->p, modLen, PKCAU_ECDSA_SIGN_IN_P);
652  pkcauImportMpi(&params->a, modLen, PKCAU_ECDSA_SIGN_IN_A);
653  pkcauImportMpi(&params->g.x, modLen, PKCAU_ECDSA_SIGN_IN_GX);
654  pkcauImportMpi(&params->g.y, modLen, PKCAU_ECDSA_SIGN_IN_GY);
655  pkcauImportMpi(&params->q, orderLen, PKCAU_ECDSA_SIGN_IN_N);
656  pkcauImportMpi(&privateKey->d, orderLen, PKCAU_ECDSA_SIGN_IN_D);
657  pkcauImportMpi(&k, orderLen, PKCAU_ECDSA_SIGN_IN_K);
658 
659  //Keep the leftmost bits of the hash value
660  digestLen = MIN(digestLen, (orderLen + 7) / 8);
661  //Load the hash value into the PKCAU internal RAM
662  pkcauImportArray(digest, digestLen, orderLen, PKCAU_ECDSA_SIGN_IN_Z);
663 
664  //Clear error code
666 
667  //Disable interrupts
668  PKCAU_CTL &= ~(PKCAU_CTL_ADDRERRIE | PKCAU_CTL_RAMERRIE | PKCAU_CTL_ENDIE);
669 
670  //Write in the MODESEL field of PKCAU_CTL register, specifying the operation
671  //which is to be executed
672  temp = PKCAU_CTL & ~PKCAU_CTL_MODESEL;
673  PKCAU_CTL = temp | PKCAU_MODE_ECDSA_SIGN;
674 
675  //Then assert the START bit in PKCAU_CTL register
676  PKCAU_CTL |= PKCAU_CTL_START;
677 
678  //Wait until the ENDF bit in the PKCAU_STAT register is set to 1,
679  //indicating that the computation is complete
680  while((PKCAU_STAT & PKCAU_STAT_ENDF) == 0)
681  {
682  }
683 
684  //Successful computation?
686  {
687  error = NO_ERROR;
688  }
689  else
690  {
691  error = ERROR_FAILURE;
692  }
693 
694  //Check status code
695  if(!error)
696  {
697  //Copy integer R
698  error = pkcauExportMpi(&signature->r, orderLen, PKCAU_ECDSA_SIGN_OUT_R);
699  }
700 
701  //Check status code
702  if(!error)
703  {
704  //Copy integer S
705  error = pkcauExportMpi(&signature->s, orderLen, PKCAU_ECDSA_SIGN_OUT_S);
706  }
707 
708  //Then clear ENDC bit by setting ENDC bit in PKCAU_STATC
709  PKCAU_STATC = PKCAU_STATC_ENDC;
710 
711  //Release exclusive access to the PKCAU module
713  }
714 
715  //Release multiple precision integer
716  mpiFree(&k);
717 
718  //Return status code
719  return error;
720 }
721 
722 
723 /**
724  * @brief ECDSA signature verification
725  * @param[in] params EC domain parameters
726  * @param[in] publicKey Signer's EC public key
727  * @param[in] digest Digest of the message whose signature is to be verified
728  * @param[in] digestLen Length in octets of the digest
729  * @param[in] signature (R, S) integer pair
730  * @return Error code
731  **/
732 
734  const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen,
735  const EcdsaSignature *signature)
736 {
737  error_t error;
738  size_t modLen;
739  size_t orderLen;
740  uint32_t temp;
741 
742  //Check parameters
743  if(params == NULL || publicKey == NULL || digest == NULL || signature == NULL)
745 
746  //The verifier shall check that 0 < r < q
747  if(mpiCompInt(&signature->r, 0) <= 0 ||
748  mpiComp(&signature->r, &params->q) >= 0)
749  {
750  //If the condition is violated, the signature shall be rejected as invalid
752  }
753 
754  //The verifier shall check that 0 < s < q
755  if(mpiCompInt(&signature->s, 0) <= 0 ||
756  mpiComp(&signature->s, &params->q) >= 0)
757  {
758  //If the condition is violated, the signature shall be rejected as invalid
760  }
761 
762  //Retrieve the length of the modulus, in bits
763  modLen = mpiGetBitLength(&params->p);
764  //Retrieve the length of the base point order, in bits
765  orderLen = mpiGetBitLength(&params->q);
766 
767  //Check the length of the operands
768  if(modLen > PKCAU_MAX_EOS || orderLen > PKCAU_MAX_EOS)
769  return ERROR_FAILURE;
770 
771  //Acquire exclusive access to the PKCAU module
773 
774  //Specify the length of the modulus, in bits
776  //Specify the length of the base point order, in bits
778  //Set the sign of the coefficient A
780 
781  //Load input arguments into the PKCAU internal RAM
782  pkcauImportMpi(&params->p, modLen, PKCAU_ECDSA_VERIF_IN_P);
783  pkcauImportMpi(&params->a, modLen, PKCAU_ECDSA_VERIF_IN_A);
784  pkcauImportMpi(&params->g.x, modLen, PKCAU_ECDSA_VERIF_IN_GX);
785  pkcauImportMpi(&params->g.y, modLen, PKCAU_ECDSA_VERIF_IN_GY);
786  pkcauImportMpi(&params->q, orderLen, PKCAU_ECDSA_VERIF_IN_N);
787  pkcauImportMpi(&publicKey->q.x, modLen, PKCAU_ECDSA_VERIF_IN_QX);
788  pkcauImportMpi(&publicKey->q.y, modLen, PKCAU_ECDSA_VERIF_IN_QY);
789  pkcauImportMpi(&signature->r, orderLen, PKCAU_ECDSA_VERIF_IN_R);
790  pkcauImportMpi(&signature->s, orderLen, PKCAU_ECDSA_VERIF_IN_S);
791 
792  //Keep the leftmost bits of the hash value
793  digestLen = MIN(digestLen, (orderLen + 7) / 8);
794  //Load the hash value into the PKCAU internal RAM
795  pkcauImportArray(digest, digestLen, orderLen, PKCAU_ECDSA_VERIF_IN_Z);
796 
797  //Clear result
799 
800  //Disable interrupts
801  PKCAU_CTL &= ~(PKCAU_CTL_ADDRERRIE | PKCAU_CTL_RAMERRIE | PKCAU_CTL_ENDIE);
802 
803  //Write in the MODESEL field of PKCAU_CTL register, specifying the operation
804  //which is to be executed
805  temp = PKCAU_CTL & ~PKCAU_CTL_MODESEL;
806  PKCAU_CTL = temp | PKCAU_MODE_ECDSA_VERIFICATION;
807 
808  //Then assert the START bit in PKCAU_CTL register
809  PKCAU_CTL |= PKCAU_CTL_START;
810 
811  //Wait until the ENDF bit in the PKCAU_STAT register is set to 1,
812  //indicating that the computation is complete
813  while((PKCAU_STAT & PKCAU_STAT_ENDF) == 0)
814  {
815  }
816 
817  //Test if the ECDSA signature is valid
819  {
820  error = NO_ERROR;
821  }
822  else
823  {
824  error = ERROR_INVALID_SIGNATURE;
825  }
826 
827  //Then clear ENDC bit by setting ENDC bit in PKCAU_STATC
828  PKCAU_STATC = PKCAU_STATC_ENDC;
829 
830  //Release exclusive access to the PKCAU module
832 
833  //Return status code
834  return error;
835 }
836 
837 
838 #if (X25519_SUPPORT == ENABLED || ED25519_SUPPORT == ENABLED)
839 
840 /**
841  * @brief Modular multiplication
842  * @param[out] r Resulting integer R = (A * B) mod p
843  * @param[in] a An integer such as 0 <= A < p
844  * @param[in] b An integer such as 0 <= B < p
845  **/
846 
847 void curve25519Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
848 {
849  uint_t i;
850  uint64_t temp;
851  uint32_t u[16];
852 
853  //Acquire exclusive access to the PKCAU module
855 
856  //Specify the length of the operands, in bits
858 
859  //Load the first operand into the PKCAU internal RAM
861  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 1] = a[1];
862  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 2] = a[2];
863  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 3] = a[3];
864  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 4] = a[4];
865  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 5] = a[5];
866  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 6] = a[6];
867  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 7] = a[7];
868 
869  //An additional word with all bits equal to zero must be added
871 
872  //Load the second operand into the PKCAU internal RAM
874  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 1] = b[1];
875  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 2] = b[2];
876  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 3] = b[3];
877  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 4] = b[4];
878  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 5] = b[5];
879  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 6] = b[6];
880  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 7] = b[7];
881 
882  //An additional word with all bits equal to zero must be added
884 
885  //Disable interrupts
886  PKCAU_CTL &= ~(PKCAU_CTL_ADDRERRIE | PKCAU_CTL_RAMERRIE | PKCAU_CTL_ENDIE);
887 
888  //Write in the MODESEL field of PKCAU_CTL register, specifying the operation
889  //which is to be executed
890  temp = PKCAU_CTL & ~PKCAU_CTL_MODESEL;
891  PKCAU_CTL = temp | PKCAU_MODE_ARITHMETIC_MUL;
892 
893  //Then assert the START bit in PKCAU_CTL register
894  PKCAU_CTL |= PKCAU_CTL_START;
895 
896  //Wait until the ENDF bit in the PKCAU_STAT register is set to 1,
897  //indicating that the computation is complete
898  while((PKCAU_STAT & PKCAU_STAT_ENDF) == 0)
899  {
900  }
901 
902  //Read the result data from the PKCAU internal RAM
913  u[10] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 10];
914  u[11] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 11];
915  u[12] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 12];
916  u[13] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 13];
917  u[14] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 14];
918  u[15] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 15];
919 
920  //Then clear ENDC bit by setting ENDC bit in PKCAU_STATC
921  PKCAU_STATC = PKCAU_STATC_ENDC;
922 
923  //Release exclusive access to the PKCAU module
925 
926  //Reduce bit 255 (2^255 = 19 mod p)
927  temp = (u[7] >> 31) * 19;
928  //Mask the most significant bit
929  u[7] &= 0x7FFFFFFF;
930 
931  //Perform fast modular reduction (first pass)
932  for(i = 0; i < 8; i++)
933  {
934  temp += u[i];
935  temp += (uint64_t) u[i + 8] * 38;
936  u[i] = temp & 0xFFFFFFFF;
937  temp >>= 32;
938  }
939 
940  //Reduce bit 256 (2^256 = 38 mod p)
941  temp *= 38;
942  //Reduce bit 255 (2^255 = 19 mod p)
943  temp += (u[7] >> 31) * 19;
944  //Mask the most significant bit
945  u[7] &= 0x7FFFFFFF;
946 
947  //Perform fast modular reduction (second pass)
948  for(i = 0; i < 8; i++)
949  {
950  temp += u[i];
951  u[i] = temp & 0xFFFFFFFF;
952  temp >>= 32;
953  }
954 
955  //Reduce non-canonical values
956  curve25519Red(r, u);
957 }
958 
959 #endif
960 #if (X448_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
961 
962 /**
963  * @brief Modular multiplication
964  * @param[out] r Resulting integer R = (A * B) mod p
965  * @param[in] a An integer such as 0 <= A < p
966  * @param[in] b An integer such as 0 <= B < p
967  **/
968 
969 void curve448Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
970 {
971  uint_t i;
972  uint64_t c;
973  uint64_t temp;
974  uint32_t u[28];
975 
976  //Acquire exclusive access to the PKCAU module
978 
979  //Specify the length of the operands, in bits
981 
982  //Load the first operand into the PKCAU internal RAM
984  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 1] = a[1];
985  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 2] = a[2];
986  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 3] = a[3];
987  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 4] = a[4];
988  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 5] = a[5];
989  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 6] = a[6];
990  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 7] = a[7];
991  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 8] = a[8];
992  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 9] = a[9];
993  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 10] = a[10];
994  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 11] = a[11];
995  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 12] = a[12];
996  PKCAU_RAM[PKCAU_ARITH_MUL_IN_A + 13] = a[13];
997 
998  //An additional word with all bits equal to zero must be added
1000 
1001  //Load the second operand into the PKCAU internal RAM
1003  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 1] = b[1];
1004  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 2] = b[2];
1005  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 3] = b[3];
1006  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 4] = b[4];
1007  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 5] = b[5];
1008  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 6] = b[6];
1009  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 7] = b[7];
1010  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 8] = b[8];
1011  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 9] = b[9];
1012  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 10] = b[10];
1013  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 11] = b[11];
1014  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 12] = b[12];
1015  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 13] = b[13];
1016 
1017  //An additional word with all bits equal to zero must be added
1018  PKCAU_RAM[PKCAU_ARITH_MUL_IN_B + 14] = 0;
1019 
1020  //Disable interrupts
1021  PKCAU_CTL &= ~(PKCAU_CTL_ADDRERRIE | PKCAU_CTL_RAMERRIE | PKCAU_CTL_ENDIE);
1022 
1023  //Write in the MODESEL field of PKCAU_CTL register, specifying the operation
1024  //which is to be executed
1025  temp = PKCAU_CTL & ~PKCAU_CTL_MODESEL;
1026  PKCAU_CTL = temp | PKCAU_MODE_ARITHMETIC_MUL;
1027 
1028  //Then assert the START bit in PKCAU_CTL register
1029  PKCAU_CTL |= PKCAU_CTL_START;
1030 
1031  //Wait until the ENDF bit in the PKCAU_STAT register is set to 1,
1032  //indicating that the computation is complete
1033  while((PKCAU_STAT & PKCAU_STAT_ENDF) == 0)
1034  {
1035  }
1036 
1037  //Read the result data from the PKCAU internal RAM
1039  u[1] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 1];
1040  u[2] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 2];
1041  u[3] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 3];
1042  u[4] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 4];
1043  u[5] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 5];
1044  u[6] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 6];
1045  u[7] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 7];
1046  u[8] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 8];
1047  u[9] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 9];
1048  u[10] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 10];
1049  u[11] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 11];
1050  u[12] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 12];
1051  u[13] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 13];
1052  u[14] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 14];
1053  u[15] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 15];
1054  u[16] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 16];
1055  u[17] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 17];
1056  u[18] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 18];
1057  u[19] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 19];
1058  u[20] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 20];
1059  u[21] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 21];
1060  u[22] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 22];
1061  u[23] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 23];
1062  u[24] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 24];
1063  u[25] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 25];
1064  u[26] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 26];
1065  u[27] = PKCAU_RAM[PKCAU_ARITH_MUL_OUT_R + 27];
1066 
1067  //Then clear ENDC bit by setting ENDC bit in PKCAU_STATC
1068  PKCAU_STATC = PKCAU_STATC_ENDC;
1069 
1070  //Release exclusive access to the PKCAU module
1072 
1073  //Perform fast modular reduction (first pass)
1074  for(temp = 0, i = 0; i < 7; i++)
1075  {
1076  temp += u[i];
1077  temp += u[i + 14];
1078  temp += u[i + 21];
1079  u[i] = temp & 0xFFFFFFFF;
1080  temp >>= 32;
1081  }
1082 
1083  for(i = 7; i < 14; i++)
1084  {
1085  temp += u[i];
1086  temp += u[i + 7];
1087  temp += u[i + 14];
1088  temp += u[i + 14];
1089  u[i] = temp & 0xFFFFFFFF;
1090  temp >>= 32;
1091  }
1092 
1093  //Perform fast modular reduction (second pass)
1094  for(c = temp, i = 0; i < 7; i++)
1095  {
1096  temp += u[i];
1097  u[i] = temp & 0xFFFFFFFF;
1098  temp >>= 32;
1099  }
1100 
1101  for(temp += c, i = 7; i < 14; i++)
1102  {
1103  temp += u[i];
1104  u[i] = temp & 0xFFFFFFFF;
1105  temp >>= 32;
1106  }
1107 
1108  //Reduce non-canonical values
1109  curve448Red(r, u, (uint32_t) temp);
1110 }
1111 
1112 #endif
1113 #endif
unsigned int uint_t
Definition: compiler_port.h:50
General definitions for cryptographic algorithms.
#define PrngAlgo
Definition: crypto.h:917
void curve25519Red(uint32_t *r, const uint32_t *a)
Modular reduction.
Definition: curve25519.c:352
Curve25519 elliptic curve (constant-time implementation)
void curve448Red(uint32_t *r, const uint32_t *a, uint32_t h)
Modular reduction.
Definition: curve448.c:368
Curve448 elliptic curve (constant-time implementation)
Debugging facilities.
uint8_t n
ECC (Elliptic Curve Cryptography)
ECDSA (Elliptic Curve Digital Signature Algorithm)
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_SIGNATURE
Definition: error.h:226
@ ERROR_OUT_OF_RANGE
Definition: error.h:137
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
OsMutex gd32w5xxCryptoMutex
GD32W5 hardware cryptographic accelerator.
error_t pkcauInit(void)
PKCAU module initialization.
void pkcauImportArray(const uint8_t *src, size_t srcLen, uint_t destLen, uint_t offset)
Import byte array.
error_t pkcauRsaCrtExp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
Modular exponentiation with CRT.
error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d, const EcPoint *s)
Scalar multiplication.
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
RSA decryption primitive.
error_t pkcauExportMpi(Mpi *r, uint_t length, uint_t offset)
Export multiple-precision integer.
void curve448Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
RSA encryption primitive.
void curve25519Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
error_t pkcauModExp(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
error_t ecdsaVerifySignature(const EcDomainParameters *params, const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
void pkcauImportMpi(const Mpi *a, uint_t length, uint_t offset)
Import multiple-precision integer.
GD32W5 public-key hardware accelerator (PKCAU)
#define PKCAU_ECDSA_SIGN_OUT_R
#define PKCAU_ECDSA_SIGN_IN_K
#define PKCAU_ECC_MUL_OUT_Y
#define PKCAU_MOD_EXP_IN_OP_LEN
#define PKCAU_RSA_CRT_EXP_IN_Q
#define PKCAU_MOD_EXP_IN_A
#define PKCAU_ECDSA_VERIF_IN_QX
#define PKCAU_ECC_MUL_IN_K
#define PKCAU_ECDSA_SIGN_IN_MOD_LEN
#define PKCAU_ECC_MUL_IN_A
#define PKCAU_RSA_CRT_EXP_IN_MOD_LEN
#define PKCAU_ECDSA_VERIF_OUT_RES
#define PKCAU_ECDSA_SIGN_IN_Z
#define PKCAU_RSA_CRT_EXP_OUT_R
#define PKCAU_ECDSA_SIGN_IN_ORDER_LEN
#define PKCAU_ECDSA_SIGN_IN_A
#define PKCAU_MOD_EXP_IN_EXP_LEN
#define PKCAU_ECDSA_VERIF_IN_MOD_LEN
#define PKCAU_ARITH_MUL_IN_A
#define PKCAU_ECDSA_VERIF_IN_Z
#define PKCAU_ARITH_MUL_IN_OP_LEN
#define PKCAU_ECC_MUL_IN_A_SIGN
#define PKCAU_ECDSA_VERIF_IN_GX
#define PKCAU_ECC_MUL_IN_P
#define PKCAU_MAX_EOS
#define PKCAU_MOD_EXP_OUT_R
#define PKCAU_ECDSA_VERIF_IN_GY
#define PKCAU_ECC_MUL_IN_SCALAR_LEN
#define PKCAU_ECDSA_SIGN_IN_GX
#define PKCAU_ECDSA_SIGN_OUT_ERROR
#define PKCAU_ECDSA_SIGN_IN_A_SIGN
#define PKCAU_ECDSA_VERIF_IN_S
#define PKCAU_ECDSA_VERIF_IN_N
#define PKCAU_ECC_MUL_IN_Y
#define PKCAU_ARITH_MUL_OUT_R
#define PKCAU_ECDSA_VERIF_IN_R
#define PKCAU_ECDSA_SIGN_OUT_S
#define PKCAU_RSA_CRT_EXP_IN_DQ
#define PKCAU_ECC_MUL_IN_X
#define PKCAU_ECDSA_SIGN_IN_N
#define PKCAU_MAX_ROS
#define PKCAU_ECDSA_VERIF_IN_ORDER_LEN
#define PKCAU_STATUS_SUCCESS
#define PKCAU_ARITH_MUL_IN_B
#define PKCAU_ECDSA_SIGN_IN_D
#define PKCAU_RSA_CRT_EXP_IN_QINV
#define PKCAU_ECDSA_VERIF_IN_P
#define PKCAU_ECDSA_VERIF_IN_A_SIGN
#define PKCAU_ECDSA_SIGN_IN_P
#define PKCAU_STATUS_INVALID
#define PKCAU_ECC_MUL_OUT_X
#define PKCAU_RSA_CRT_EXP_IN_A
#define PKCAU_MOD_EXP_IN_E
#define PKCAU_ECDSA_VERIF_IN_QY
#define PKCAU_ECC_MUL_IN_MOD_LEN
#define PKCAU_RSA_CRT_EXP_IN_P
#define PKCAU_ECDSA_VERIF_IN_A
#define PKCAU_MOD_EXP_IN_N
#define PKCAU_RSA_CRT_EXP_IN_DP
#define PKCAU_RAM
#define PKCAU_ECDSA_SIGN_IN_GY
uint8_t u
Definition: lldp_ext_med.h:213
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
error_t mpiRandRange(Mpi *r, const Mpi *p, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value in the range 1 to p-1.
Definition: mpi.c:564
error_t mpiSetValue(Mpi *r, int_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:484
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:168
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:234
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:864
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:382
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:338
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:787
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1444
error_t mpiGrow(Mpi *r, uint_t size)
Adjust the size of multiple precision integer.
Definition: mpi.c:94
uint8_t b
Definition: nbns_common.h:104
uint8_t h
Definition: ndp.h:302
uint8_t c
Definition: ndp.h:514
uint8_t r
Definition: ndp.h:346
uint8_t s
Definition: ndp.h:345
uint8_t p
Definition: ndp.h:300
uint8_t m
Definition: ndp.h:304
uint8_t a
Definition: ndp.h:411
#define MIN(a, b)
Definition: os_port.h:63
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
RSA public-key cryptography standard.
EC domain parameters.
Definition: ec.h:76
Mpi p
Prime.
Definition: ec.h:79
EcPoint g
Base point G.
Definition: ec.h:82
Mpi q
Order of the point G.
Definition: ec.h:83
Mpi a
Curve parameter a.
Definition: ec.h:80
EC point.
Definition: ec.h:64
Mpi y
y-coordinate
Definition: ec.h:66
Mpi x
x-coordinate
Definition: ec.h:65
EC private key.
Definition: ec.h:104
Mpi d
Private key.
Definition: ec.h:105
EC public key.
Definition: ec.h:94
EcPoint q
Public key.
Definition: ec.h:95
ECDSA signature.
Definition: ecdsa.h:49
Arbitrary precision integer.
Definition: mpi.h:80
RSA private key.
Definition: rsa.h:68
Mpi p
First factor.
Definition: rsa.h:72
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
Mpi q
Second factor.
Definition: rsa.h:73
Mpi d
Private exponent.
Definition: rsa.h:71
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
Mpi n
Modulus.
Definition: rsa.h:69
RSA public key.
Definition: rsa.h:57
Mpi e
Public exponent.
Definition: rsa.h:59
Mpi n
Modulus.
Definition: rsa.h:58
uint8_t length
Definition: tcp.h:368