blob: a6d7d4a5a213fc35c4f0d40979430803750f4da9 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/**
2 * \file bignum.h
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00003 *
Paul Bakker37ca75d2011-01-06 12:28:03 +00004 * \brief Multi-precision integer library
5 *
Paul Bakker84f12b72010-07-18 10:13:04 +00006 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00007 *
8 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00009 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +000010 *
Paul Bakker77b385e2009-07-28 17:23:11 +000011 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000012 *
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000013 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (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 along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Paul Bakker5121ce52009-01-03 21:22:43 +000026 */
Paul Bakker40e46942009-01-03 21:51:57 +000027#ifndef POLARSSL_BIGNUM_H
28#define POLARSSL_BIGNUM_H
Paul Bakker5121ce52009-01-03 21:22:43 +000029
30#include <stdio.h>
Paul Bakker23986e52011-04-24 08:57:21 +000031#include <string.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Paul Bakkerb5bf1762009-07-19 20:28:35 +000033#define POLARSSL_ERR_MPI_FILE_IO_ERROR 0x0002
34#define POLARSSL_ERR_MPI_BAD_INPUT_DATA 0x0004
35#define POLARSSL_ERR_MPI_INVALID_CHARACTER 0x0006
36#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL 0x0008
37#define POLARSSL_ERR_MPI_NEGATIVE_VALUE 0x000A
38#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO 0x000C
39#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE 0x000E
Paul Bakker5121ce52009-01-03 21:22:43 +000040
41#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
42
43/*
Paul Bakkerf9688572011-05-05 10:00:45 +000044 * Maximum size MPIs are allowed to grow to in number of limbs.
45 */
46#define POLARSSL_MPI_MAX_LIMBS 10000
47
48/*
Paul Bakker5121ce52009-01-03 21:22:43 +000049 * Define the base integer type, architecture-wise
50 */
Paul Bakker40e46942009-01-03 21:51:57 +000051#if defined(POLARSSL_HAVE_INT8)
Paul Bakkera755ca12011-04-24 09:11:17 +000052typedef signed char t_sint;
53typedef unsigned char t_uint;
54typedef unsigned short t_udbl;
Paul Bakker5121ce52009-01-03 21:22:43 +000055#else
Paul Bakker40e46942009-01-03 21:51:57 +000056#if defined(POLARSSL_HAVE_INT16)
Paul Bakkera755ca12011-04-24 09:11:17 +000057typedef signed short t_sint;
58typedef unsigned short t_uint;
59typedef unsigned long t_udbl;
Paul Bakker5121ce52009-01-03 21:22:43 +000060#else
Paul Bakkera755ca12011-04-24 09:11:17 +000061 typedef signed long t_sint;
62 typedef unsigned long t_uint;
Paul Bakker5121ce52009-01-03 21:22:43 +000063 #if defined(_MSC_VER) && defined(_M_IX86)
Paul Bakkera755ca12011-04-24 09:11:17 +000064 typedef unsigned __int64 t_udbl;
Paul Bakker5121ce52009-01-03 21:22:43 +000065 #else
66 #if defined(__amd64__) || defined(__x86_64__) || \
67 defined(__ppc64__) || defined(__powerpc64__) || \
68 defined(__ia64__) || defined(__alpha__)
Paul Bakkera755ca12011-04-24 09:11:17 +000069 typedef unsigned int t_udbl __attribute__((mode(TI)));
Paul Bakker5121ce52009-01-03 21:22:43 +000070 #else
Paul Bakker1a9382e2009-07-11 16:35:32 +000071 #if defined(POLARSSL_HAVE_LONGLONG)
Paul Bakkera755ca12011-04-24 09:11:17 +000072 typedef unsigned long long t_udbl;
Paul Bakker1a9382e2009-07-11 16:35:32 +000073 #endif
Paul Bakker5121ce52009-01-03 21:22:43 +000074 #endif
75 #endif
76#endif
77#endif
78
79/**
80 * \brief MPI structure
81 */
82typedef struct
83{
84 int s; /*!< integer sign */
Paul Bakker23986e52011-04-24 08:57:21 +000085 size_t n; /*!< total # of limbs */
Paul Bakkera755ca12011-04-24 09:11:17 +000086 t_uint *p; /*!< pointer to limbs */
Paul Bakker5121ce52009-01-03 21:22:43 +000087}
88mpi;
89
90#ifdef __cplusplus
91extern "C" {
92#endif
93
94/**
95 * \brief Initialize one or more mpi
96 */
97void mpi_init( mpi *X, ... );
98
99/**
100 * \brief Unallocate one or more mpi
101 */
102void mpi_free( mpi *X, ... );
103
104/**
105 * \brief Enlarge to the specified number of limbs
106 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000107 * \param X MPI to grow
108 * \param nblimbs The target number of limbs
109 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000110 * \return 0 if successful,
111 * 1 if memory allocation failed
112 */
Paul Bakker23986e52011-04-24 08:57:21 +0000113int mpi_grow( mpi *X, size_t nblimbs );
Paul Bakker5121ce52009-01-03 21:22:43 +0000114
115/**
116 * \brief Copy the contents of Y into X
117 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000118 * \param X Destination MPI
119 * \param Y Source MPI
120 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000121 * \return 0 if successful,
122 * 1 if memory allocation failed
123 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000124int mpi_copy( mpi *X, const mpi *Y );
Paul Bakker5121ce52009-01-03 21:22:43 +0000125
126/**
127 * \brief Swap the contents of X and Y
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000128 *
129 * \param X First MPI value
130 * \param Y Second MPI value
Paul Bakker5121ce52009-01-03 21:22:43 +0000131 */
132void mpi_swap( mpi *X, mpi *Y );
133
134/**
135 * \brief Set value from integer
136 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000137 * \param X MPI to set
138 * \param z Value to use
139 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000140 * \return 0 if successful,
141 * 1 if memory allocation failed
142 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000143int mpi_lset( mpi *X, t_sint z );
Paul Bakker5121ce52009-01-03 21:22:43 +0000144
145/**
146 * \brief Return the number of least significant bits
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000147 *
148 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000149 */
Paul Bakker23986e52011-04-24 08:57:21 +0000150size_t mpi_lsb( const mpi *X );
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
152/**
153 * \brief Return the number of most significant bits
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000154 *
155 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000156 */
Paul Bakker23986e52011-04-24 08:57:21 +0000157size_t mpi_msb( const mpi *X );
Paul Bakker5121ce52009-01-03 21:22:43 +0000158
159/**
160 * \brief Return the total size in bytes
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000161 *
162 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000163 */
Paul Bakker23986e52011-04-24 08:57:21 +0000164size_t mpi_size( const mpi *X );
Paul Bakker5121ce52009-01-03 21:22:43 +0000165
166/**
167 * \brief Import from an ASCII string
168 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000169 * \param X Destination MPI
170 * \param radix Input numeric base
171 * \param s Null-terminated string buffer
Paul Bakker5121ce52009-01-03 21:22:43 +0000172 *
Paul Bakker40e46942009-01-03 21:51:57 +0000173 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000174 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000175int mpi_read_string( mpi *X, int radix, const char *s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000176
177/**
178 * \brief Export into an ASCII string
179 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000180 * \param X Source MPI
181 * \param radix Output numeric base
182 * \param s String buffer
183 * \param slen String buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000184 *
Paul Bakkerff60ee62010-03-16 21:09:09 +0000185 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code.
186 * *slen is always updated to reflect the amount
187 * of data that has (or would have) been written.
Paul Bakker5121ce52009-01-03 21:22:43 +0000188 *
189 * \note Call this function with *slen = 0 to obtain the
190 * minimum required buffer size in *slen.
191 */
Paul Bakker23986e52011-04-24 08:57:21 +0000192int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000193
194/**
195 * \brief Read X from an opened file
196 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000197 * \param X Destination MPI
198 * \param radix Input numeric base
199 * \param fin Input file handle
Paul Bakker5121ce52009-01-03 21:22:43 +0000200 *
Paul Bakker40e46942009-01-03 21:51:57 +0000201 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000202 */
203int mpi_read_file( mpi *X, int radix, FILE *fin );
204
205/**
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000206 * \brief Write X into an opened file, or stdout if fout is NULL
Paul Bakker5121ce52009-01-03 21:22:43 +0000207 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000208 * \param p Prefix, can be NULL
209 * \param X Source MPI
210 * \param radix Output numeric base
211 * \param fout Output file handle (can be NULL)
Paul Bakker5121ce52009-01-03 21:22:43 +0000212 *
Paul Bakker40e46942009-01-03 21:51:57 +0000213 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000214 *
215 * \note Set fout == NULL to print X on the console.
216 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000217int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
Paul Bakker5121ce52009-01-03 21:22:43 +0000218
219/**
220 * \brief Import X from unsigned binary data, big endian
221 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000222 * \param X Destination MPI
223 * \param buf Input buffer
224 * \param buflen Input buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000225 *
226 * \return 0 if successful,
227 * 1 if memory allocation failed
228 */
Paul Bakker23986e52011-04-24 08:57:21 +0000229int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000230
231/**
232 * \brief Export X into unsigned binary data, big endian
233 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000234 * \param X Source MPI
235 * \param buf Output buffer
236 * \param buflen Output buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000237 *
238 * \return 0 if successful,
Paul Bakker40e46942009-01-03 21:51:57 +0000239 * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 */
Paul Bakker23986e52011-04-24 08:57:21 +0000241int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
243/**
244 * \brief Left-shift: X <<= count
245 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000246 * \param X MPI to shift
247 * \param count Amount to shift
248 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000249 * \return 0 if successful,
250 * 1 if memory allocation failed
251 */
Paul Bakker23986e52011-04-24 08:57:21 +0000252int mpi_shift_l( mpi *X, size_t count );
Paul Bakker5121ce52009-01-03 21:22:43 +0000253
254/**
255 * \brief Right-shift: X >>= count
256 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000257 * \param X MPI to shift
258 * \param count Amount to shift
259 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000260 * \return 0 if successful,
261 * 1 if memory allocation failed
262 */
Paul Bakker23986e52011-04-24 08:57:21 +0000263int mpi_shift_r( mpi *X, size_t count );
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
265/**
266 * \brief Compare unsigned values
267 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000268 * \param X Left-hand MPI
269 * \param Y Right-hand MPI
270 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 * \return 1 if |X| is greater than |Y|,
272 * -1 if |X| is lesser than |Y| or
273 * 0 if |X| is equal to |Y|
274 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000275int mpi_cmp_abs( const mpi *X, const mpi *Y );
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
277/**
278 * \brief Compare signed values
279 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000280 * \param X Left-hand MPI
281 * \param Y Right-hand MPI
282 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 * \return 1 if X is greater than Y,
284 * -1 if X is lesser than Y or
285 * 0 if X is equal to Y
286 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000287int mpi_cmp_mpi( const mpi *X, const mpi *Y );
Paul Bakker5121ce52009-01-03 21:22:43 +0000288
289/**
290 * \brief Compare signed values
291 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000292 * \param X Left-hand MPI
293 * \param z The integer value to compare to
294 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 * \return 1 if X is greater than z,
296 * -1 if X is lesser than z or
297 * 0 if X is equal to z
298 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000299int mpi_cmp_int( const mpi *X, t_sint z );
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
301/**
302 * \brief Unsigned addition: X = |A| + |B|
303 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000304 * \param X Destination MPI
305 * \param A Left-hand MPI
306 * \param B Right-hand MPI
307 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000308 * \return 0 if successful,
309 * 1 if memory allocation failed
310 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000311int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000312
313/**
314 * \brief Unsigned substraction: X = |A| - |B|
315 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000316 * \param X Destination MPI
317 * \param A Left-hand MPI
318 * \param B Right-hand MPI
319 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000320 * \return 0 if successful,
Paul Bakker40e46942009-01-03 21:51:57 +0000321 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
Paul Bakker5121ce52009-01-03 21:22:43 +0000322 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000323int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000324
325/**
326 * \brief Signed addition: X = A + B
327 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000328 * \param X Destination MPI
329 * \param A Left-hand MPI
330 * \param B Right-hand MPI
331 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000332 * \return 0 if successful,
333 * 1 if memory allocation failed
334 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000335int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000336
337/**
338 * \brief Signed substraction: X = A - B
339 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000340 * \param X Destination MPI
341 * \param A Left-hand MPI
342 * \param B Right-hand MPI
343 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000344 * \return 0 if successful,
345 * 1 if memory allocation failed
346 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000347int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
349/**
350 * \brief Signed addition: X = A + b
351 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000352 * \param X Destination MPI
353 * \param A Left-hand MPI
354 * \param b The integer value to add
355 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 * \return 0 if successful,
357 * 1 if memory allocation failed
358 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000359int mpi_add_int( mpi *X, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
361/**
362 * \brief Signed substraction: X = A - b
363 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000364 * \param X Destination MPI
365 * \param A Left-hand MPI
366 * \param b The integer value to subtract
367 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000368 * \return 0 if successful,
369 * 1 if memory allocation failed
370 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000371int mpi_sub_int( mpi *X, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000372
373/**
374 * \brief Baseline multiplication: X = A * B
375 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000376 * \param X Destination MPI
377 * \param A Left-hand MPI
378 * \param B Right-hand MPI
379 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000380 * \return 0 if successful,
381 * 1 if memory allocation failed
382 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000383int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
385/**
386 * \brief Baseline multiplication: X = A * b
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000387 * Note: b is an unsigned integer type, thus
388 * Negative values of b are ignored.
Paul Bakker5121ce52009-01-03 21:22:43 +0000389 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000390 * \param X Destination MPI
391 * \param A Left-hand MPI
392 * \param b The integer value to multiply with
393 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000394 * \return 0 if successful,
395 * 1 if memory allocation failed
396 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000397int mpi_mul_int( mpi *X, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
399/**
400 * \brief Division by mpi: A = Q * B + R
401 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000402 * \param Q Destination MPI for the quotient
403 * \param R Destination MPI for the rest value
404 * \param A Left-hand MPI
405 * \param B Right-hand MPI
406 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000407 * \return 0 if successful,
408 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000409 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000410 *
411 * \note Either Q or R can be NULL.
412 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000413int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
415/**
416 * \brief Division by int: A = Q * b + R
417 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000418 * \param Q Destination MPI for the quotient
419 * \param R Destination MPI for the rest value
420 * \param A Left-hand MPI
421 * \param b Integer to divide by
422 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 * \return 0 if successful,
424 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000425 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 *
427 * \note Either Q or R can be NULL.
428 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000429int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
431/**
432 * \brief Modulo: R = A mod B
433 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000434 * \param R Destination MPI for the rest value
435 * \param A Left-hand MPI
436 * \param B Right-hand MPI
437 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 * \return 0 if successful,
439 * 1 if memory allocation failed,
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000440 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
441 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000443int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
445/**
446 * \brief Modulo: r = A mod b
447 *
Paul Bakkera755ca12011-04-24 09:11:17 +0000448 * \param r Destination t_uint
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000449 * \param A Left-hand MPI
450 * \param b Integer to divide by
451 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 * \return 0 if successful,
453 * 1 if memory allocation failed,
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000454 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
455 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000457int mpi_mod_int( t_uint *r, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
459/**
460 * \brief Sliding-window exponentiation: X = A^E mod N
461 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000462 * \param X Destination MPI
463 * \param A Left-hand MPI
464 * \param E Exponent MPI
465 * \param N Modular MPI
466 * \param _RR Speed-up MPI used for recalculations
467 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000468 * \return 0 if successful,
469 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000470 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
Paul Bakker5121ce52009-01-03 21:22:43 +0000471 *
472 * \note _RR is used to avoid re-computing R*R mod N across
473 * multiple calls, which speeds up things a bit. It can
474 * be set to NULL if the extra performance is unneeded.
475 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000476int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
478/**
Paul Bakker287781a2011-03-26 13:18:49 +0000479 * \brief Fill an MPI X with size bytes of random
480 *
481 * \param X Destination MPI
482 * \param size Size in bytes
483 * \param f_rng RNG function
484 * \param p_rng RNG parameter
485 *
486 * \return 0 if successful,
487 * 1 if memory allocation failed
488 */
Paul Bakker23986e52011-04-24 08:57:21 +0000489int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng );
Paul Bakker287781a2011-03-26 13:18:49 +0000490
491/**
Paul Bakker5121ce52009-01-03 21:22:43 +0000492 * \brief Greatest common divisor: G = gcd(A, B)
493 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000494 * \param G Destination MPI
495 * \param A Left-hand MPI
496 * \param B Right-hand MPI
497 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 * \return 0 if successful,
499 * 1 if memory allocation failed
500 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000501int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000502
503/**
504 * \brief Modular inverse: X = A^-1 mod N
505 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000506 * \param X Destination MPI
507 * \param A Left-hand MPI
508 * \param N Right-hand MPI
509 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000510 * \return 0 if successful,
511 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000512 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000513 POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
Paul Bakker5121ce52009-01-03 21:22:43 +0000514 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000515int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
Paul Bakker5121ce52009-01-03 21:22:43 +0000516
517/**
518 * \brief Miller-Rabin primality test
519 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000520 * \param X MPI to check
521 * \param f_rng RNG function
522 * \param p_rng RNG parameter
523 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000524 * \return 0 if successful (probably prime),
525 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000526 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
Paul Bakker5121ce52009-01-03 21:22:43 +0000527 */
528int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
529
530/**
531 * \brief Prime number generation
532 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000533 * \param X Destination MPI
Paul Bakkerf9688572011-05-05 10:00:45 +0000534 * \param nbits Required size of X in bits ( 3 <= nbits <= 4096 )
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000535 * \param dh_flag If 1, then (X-1)/2 will be prime too
Paul Bakker5121ce52009-01-03 21:22:43 +0000536 * \param f_rng RNG function
537 * \param p_rng RNG parameter
538 *
539 * \return 0 if successful (probably prime),
540 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000541 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
Paul Bakker5121ce52009-01-03 21:22:43 +0000542 */
Paul Bakker23986e52011-04-24 08:57:21 +0000543int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakker5121ce52009-01-03 21:22:43 +0000544 int (*f_rng)(void *), void *p_rng );
545
546/**
547 * \brief Checkup routine
548 *
549 * \return 0 if successful, or 1 if the test failed
550 */
551int mpi_self_test( int verbose );
552
553#ifdef __cplusplus
554}
555#endif
556
557#endif /* bignum.h */