mpi.h
Go to the documentation of this file.
1 /**
2  * @file mpi.h
3  * @brief MPI (Multiple Precision Integer Arithmetic)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 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.5.0
29  **/
30 
31 #ifndef _MPI_H
32 #define _MPI_H
33 
34 //Dependencies
35 #include <stdio.h>
36 #include "core/crypto.h"
37 
38 //Maximum size of a multiple precision integer, in bits
39 #ifndef MPI_MAX_BITS
40  #define MPI_MAX_BITS 4096
41 #elif (MPI_MAX_BITS < 0)
42  #error MPI_MAX_BITS parameter is not valid
43 #endif
44 
45 //Size of the MPI base type, in bits
46 #ifndef MPI_BITS_PER_WORD
47  #define MPI_BITS_PER_WORD 32
48 #elif (MPI_BITS_PER_WORD != 8 || MPI_BITS_PER_WORD != 16 || MPI_BITS_PER_WORD != 32)
49  #error MPI_BITS_PER_WORD parameter is not valid
50 #endif
51 
52 //Maximum size of a multiple precision integer, in words
53 #define MPI_MAX_WORDS ((MPI_MAX_BITS + MPI_BITS_PER_WORD - 1) / MPI_BITS_PER_WORD)
54 
55 //Size of the MPI base type, in bytes
56 #define MPI_BYTES_PER_WORD (MPI_BITS_PER_WORD / 8)
57 
58 //MPI base types
59 #if (MPI_BITS_PER_WORD == 8)
60  #define mpi_word_t uint8_t
61  #define mpi_sword_t int8_t
62  #define mpi_dword_t uint16_t
63 #elif (MPI_BITS_PER_WORD == 16)
64  #define mpi_word_t uint16_t
65  #define mpi_sword_t int16_t
66  #define mpi_dword_t uint32_t
67 #elif (MPI_BITS_PER_WORD == 32)
68  #define mpi_word_t uint32_t
69  #define mpi_sword_t int32_t
70  #define mpi_dword_t uint64_t
71 #endif
72 
73 //Error code checking
74 #define MPI_CHECK(f) if((error = f) != NO_ERROR) goto end
75 
76 //Miscellaneous macros
77 #define mpiIsEven(a) !mpiGetBitValue(a, 0)
78 #define mpiIsOdd(a) mpiGetBitValue(a, 0)
79 
80 //C++ guard
81 #ifdef __cplusplus
82 extern "C" {
83 #endif
84 
85 
86 /**
87  * @brief MPI import/export format
88  **/
89 
90 typedef enum
91 {
95 
96 
97 /**
98  * @brief Arbitrary precision integer
99  **/
100 
101 typedef struct
102 {
105 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
107 #else
109 #endif
110 } Mpi;
111 
112 
113 //MPI related functions
114 void mpiInit(Mpi *r);
115 void mpiFree(Mpi *r);
116 
117 error_t mpiGrow(Mpi *r, uint_t size);
118 
119 uint_t mpiGetLength(const Mpi *a);
120 uint_t mpiGetByteLength(const Mpi *a);
121 uint_t mpiGetBitLength(const Mpi *a);
122 
124 uint_t mpiGetBitValue(const Mpi *a, uint_t index);
125 
126 int_t mpiComp(const Mpi *a, const Mpi *b);
127 int_t mpiCompInt(const Mpi *a, mpi_sword_t b);
128 int_t mpiCompAbs(const Mpi *a, const Mpi *b);
129 
130 error_t mpiCopy(Mpi *r, const Mpi *a);
132 
133 error_t mpiRand(Mpi *r, uint_t length, const PrngAlgo *prngAlgo,
134  void *prngContext);
135 
136 error_t mpiRandRange(Mpi *r, const Mpi *p, const PrngAlgo *prngAlgo,
137  void *prngContext);
138 
140 
141 error_t mpiImport(Mpi *r, const uint8_t *input, size_t length,
142  MpiFormat format);
143 
144 error_t mpiExport(const Mpi *a, uint8_t *output, size_t length,
145  MpiFormat format);
146 
147 error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b);
148 error_t mpiAddInt(Mpi *r, const Mpi *a, mpi_sword_t b);
149 
150 error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b);
151 error_t mpiSubInt(Mpi *r, const Mpi *a, mpi_sword_t b);
152 
153 error_t mpiAddAbs(Mpi *r, const Mpi *a, const Mpi *b);
154 error_t mpiSubAbs(Mpi *r, const Mpi *a, const Mpi *b);
155 
158 
159 error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b);
160 error_t mpiMulInt(Mpi *r, const Mpi *a, mpi_sword_t b);
161 
162 error_t mpiDiv(Mpi *q, Mpi *r, const Mpi *a, const Mpi *b);
163 error_t mpiDivInt(Mpi *q, Mpi *r, const Mpi *a, mpi_sword_t b);
164 
165 error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p);
166 error_t mpiAddMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p);
167 error_t mpiSubMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p);
168 error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p);
169 error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p);
170 
171 error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p);
172 error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p);
173 error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p);
174 
175 error_t mpiMontgomeryMul(Mpi *r, const Mpi *a, const Mpi *b, uint_t k,
176  const Mpi *p, Mpi *t);
177 
178 error_t mpiMontgomeryRed(Mpi *r, const Mpi *a, uint_t k, const Mpi *p, Mpi *t);
179 
180 void mpiMulAccCore(mpi_word_t *r, const mpi_word_t *a, int_t m,
181  const mpi_word_t b);
182 
183 void mpiDump(FILE *stream, const char_t *prepend, const Mpi *a);
184 
185 //C++ guard
186 #ifdef __cplusplus
187 }
188 #endif
189 
190 #endif
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
error_t mpiSubInt(Mpi *r, const Mpi *a, mpi_sword_t b)
Subtract an integer from a multiple precision integer.
Definition: mpi.c:1018
error_t mpiCopy(Mpi *r, const Mpi *a)
Copy a multiple precision integer.
Definition: mpi.c:516
error_t mpiAddMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular addition.
Definition: mpi.c:1652
uint8_t b
Definition: nbns_common.h:104
uint8_t a
Definition: ndp.h:411
void mpiDump(FILE *stream, const char_t *prepend, const Mpi *a)
Display the contents of a multiple precision integer.
Definition: mpi.c:2184
Arbitrary precision integer.
Definition: mpi.h:102
signed int int_t
Definition: compiler_port.h:56
#define PrngAlgo
Definition: crypto.h:973
uint8_t p
Definition: ndp.h:300
error_t mpiExport(const Mpi *a, uint8_t *output, size_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:809
uint8_t t
Definition: lldp_ext_med.h:212
uint8_t data[]
Definition: ethernet.h:222
error_t mpiSubAbs(Mpi *r, const Mpi *a, const Mpi *b)
Helper routine for multiple precision subtraction.
Definition: mpi.c:1141
int_t mpiCompAbs(const Mpi *a, const Mpi *b)
Compare the absolute value of two multiple precision integers.
Definition: mpi.c:457
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
void mpiMulAccCore(mpi_word_t *r, const mpi_word_t *a, int_t m, const mpi_word_t b)
Multiply-accumulate operation.
Definition: mpi.c:2127
error_t mpiAddAbs(Mpi *r, const Mpi *a, const Mpi *b)
Helper routine for multiple precision addition.
Definition: mpi.c:1047
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:652
error_t mpiSetValue(Mpi *r, mpi_sword_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:562
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:358
int_t mpiCompInt(const Mpi *a, mpi_sword_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:429
uint8_t r
Definition: ndp.h:346
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
error_t mpiMulInt(Mpi *r, const Mpi *a, mpi_sword_t b)
Multiply a multiple precision integer by an integer.
Definition: mpi.c:1455
@ MPI_FORMAT_LITTLE_ENDIAN
Definition: mpi.h:92
error_t
Error codes.
Definition: error.h:43
error_t mpiMontgomeryMul(Mpi *r, const Mpi *a, const Mpi *b, uint_t k, const Mpi *p, Mpi *t)
Montgomery multiplication.
Definition: mpi.c:2023
General definitions for cryptographic algorithms.
error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
error_t mpiMontgomeryRed(Mpi *r, const Mpi *a, uint_t k, const Mpi *p, Mpi *t)
Montgomery reduction.
Definition: mpi.c:2096
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:188
uint8_t length
Definition: tcp.h:375
#define mpi_word_t
Definition: mpi.h:68
error_t mpiSetBitValue(Mpi *r, uint_t index, uint_t value)
Set the bit value at the specified index.
Definition: mpi.c:295
MpiFormat
MPI import/export format.
Definition: mpi.h:91
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:891
char char_t
Definition: compiler_port.h:55
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:254
error_t mpiCheckProbablePrime(const Mpi *a)
Test whether a number is probable prime.
uint8_t m
Definition: ndp.h:304
uint8_t n
error_t mpiGrow(Mpi *r, uint_t size)
Adjust the size of multiple precision integer.
Definition: mpi.c:102
uint_t size
Definition: mpi.h:104
#define MPI_MAX_WORDS
Definition: mpi.h:53
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:215
uint_t mpiGetBitValue(const Mpi *a, uint_t index)
Get the bit value at the specified index.
Definition: mpi.c:333
uint8_t value[]
Definition: tcp.h:376
error_t mpiSubMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular subtraction.
Definition: mpi.c:1675
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
error_t mpiShiftRight(Mpi *r, uint_t n)
Right shift operation.
Definition: mpi.c:1310
error_t mpiRand(Mpi *r, uint_t length, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value.
Definition: mpi.c:598
error_t mpiDiv(Mpi *q, Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision division.
Definition: mpi.c:1485
error_t mpiImport(Mpi *r, const uint8_t *input, size_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:712
error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (fast calculation)
#define mpi_sword_t
Definition: mpi.h:69
unsigned int uint_t
Definition: compiler_port.h:57
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1587
error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)
error_t mpiDivInt(Mpi *q, Mpi *r, const Mpi *a, mpi_sword_t b)
Divide a multiple precision integer by an integer.
Definition: mpi.c:1558
mpi_word_t * data
Definition: mpi.h:106
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:969
error_t mpiShiftLeft(Mpi *r, uint_t n)
Left shift operation.
Definition: mpi.c:1243
int_t sign
Definition: mpi.h:103
error_t mpiAddInt(Mpi *r, const Mpi *a, mpi_sword_t b)
Add an integer to a multiple precision integer.
Definition: mpi.c:940