blob: 38009679ff46e0cf7a1730e90c51c5a01ad5d3f8 [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/**
Paul Bakker6c591fa2011-05-05 11:49:20 +000095 * \brief Initialize one MPI
96 *
97 * \param X One MPI to initialize.
Paul Bakker5121ce52009-01-03 21:22:43 +000098 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000099void mpi_init( mpi *X );
Paul Bakker5121ce52009-01-03 21:22:43 +0000100
101/**
Paul Bakker6c591fa2011-05-05 11:49:20 +0000102 * \brief Unallocate one MPI
103 *
104 * \param X One MPI to unallocate.
Paul Bakker5121ce52009-01-03 21:22:43 +0000105 */
Paul Bakker6c591fa2011-05-05 11:49:20 +0000106void mpi_free( mpi *X );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108/**
109 * \brief Enlarge to the specified number of limbs
110 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000111 * \param X MPI to grow
112 * \param nblimbs The target number of limbs
113 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000114 * \return 0 if successful,
115 * 1 if memory allocation failed
116 */
Paul Bakker23986e52011-04-24 08:57:21 +0000117int mpi_grow( mpi *X, size_t nblimbs );
Paul Bakker5121ce52009-01-03 21:22:43 +0000118
119/**
120 * \brief Copy the contents of Y into X
121 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000122 * \param X Destination MPI
123 * \param Y Source MPI
124 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000125 * \return 0 if successful,
126 * 1 if memory allocation failed
127 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000128int mpi_copy( mpi *X, const mpi *Y );
Paul Bakker5121ce52009-01-03 21:22:43 +0000129
130/**
131 * \brief Swap the contents of X and Y
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000132 *
133 * \param X First MPI value
134 * \param Y Second MPI value
Paul Bakker5121ce52009-01-03 21:22:43 +0000135 */
136void mpi_swap( mpi *X, mpi *Y );
137
138/**
139 * \brief Set value from integer
140 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000141 * \param X MPI to set
142 * \param z Value to use
143 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000144 * \return 0 if successful,
145 * 1 if memory allocation failed
146 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000147int mpi_lset( mpi *X, t_sint z );
Paul Bakker5121ce52009-01-03 21:22:43 +0000148
149/**
150 * \brief Return the number of least significant bits
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000151 *
152 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000153 */
Paul Bakker23986e52011-04-24 08:57:21 +0000154size_t mpi_lsb( const mpi *X );
Paul Bakker5121ce52009-01-03 21:22:43 +0000155
156/**
157 * \brief Return the number of most significant bits
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000158 *
159 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000160 */
Paul Bakker23986e52011-04-24 08:57:21 +0000161size_t mpi_msb( const mpi *X );
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
163/**
164 * \brief Return the total size in bytes
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000165 *
166 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000167 */
Paul Bakker23986e52011-04-24 08:57:21 +0000168size_t mpi_size( const mpi *X );
Paul Bakker5121ce52009-01-03 21:22:43 +0000169
170/**
171 * \brief Import from an ASCII string
172 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000173 * \param X Destination MPI
174 * \param radix Input numeric base
175 * \param s Null-terminated string buffer
Paul Bakker5121ce52009-01-03 21:22:43 +0000176 *
Paul Bakker40e46942009-01-03 21:51:57 +0000177 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000178 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000179int mpi_read_string( mpi *X, int radix, const char *s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000180
181/**
182 * \brief Export into an ASCII string
183 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000184 * \param X Source MPI
185 * \param radix Output numeric base
186 * \param s String buffer
187 * \param slen String buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000188 *
Paul Bakkerff60ee62010-03-16 21:09:09 +0000189 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code.
190 * *slen is always updated to reflect the amount
191 * of data that has (or would have) been written.
Paul Bakker5121ce52009-01-03 21:22:43 +0000192 *
193 * \note Call this function with *slen = 0 to obtain the
194 * minimum required buffer size in *slen.
195 */
Paul Bakker23986e52011-04-24 08:57:21 +0000196int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000197
198/**
199 * \brief Read X from an opened file
200 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000201 * \param X Destination MPI
202 * \param radix Input numeric base
203 * \param fin Input file handle
Paul Bakker5121ce52009-01-03 21:22:43 +0000204 *
Paul Bakker40e46942009-01-03 21:51:57 +0000205 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000206 */
207int mpi_read_file( mpi *X, int radix, FILE *fin );
208
209/**
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000210 * \brief Write X into an opened file, or stdout if fout is NULL
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000212 * \param p Prefix, can be NULL
213 * \param X Source MPI
214 * \param radix Output numeric base
215 * \param fout Output file handle (can be NULL)
Paul Bakker5121ce52009-01-03 21:22:43 +0000216 *
Paul Bakker40e46942009-01-03 21:51:57 +0000217 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000218 *
219 * \note Set fout == NULL to print X on the console.
220 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000221int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
223/**
224 * \brief Import X from unsigned binary data, big endian
225 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000226 * \param X Destination MPI
227 * \param buf Input buffer
228 * \param buflen Input buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000229 *
230 * \return 0 if successful,
231 * 1 if memory allocation failed
232 */
Paul Bakker23986e52011-04-24 08:57:21 +0000233int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000234
235/**
236 * \brief Export X into unsigned binary data, big endian
237 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000238 * \param X Source MPI
239 * \param buf Output buffer
240 * \param buflen Output buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000241 *
242 * \return 0 if successful,
Paul Bakker40e46942009-01-03 21:51:57 +0000243 * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
Paul Bakker5121ce52009-01-03 21:22:43 +0000244 */
Paul Bakker23986e52011-04-24 08:57:21 +0000245int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000246
247/**
248 * \brief Left-shift: X <<= count
249 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000250 * \param X MPI to shift
251 * \param count Amount to shift
252 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 * \return 0 if successful,
254 * 1 if memory allocation failed
255 */
Paul Bakker23986e52011-04-24 08:57:21 +0000256int mpi_shift_l( mpi *X, size_t count );
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
258/**
259 * \brief Right-shift: X >>= count
260 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000261 * \param X MPI to shift
262 * \param count Amount to shift
263 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000264 * \return 0 if successful,
265 * 1 if memory allocation failed
266 */
Paul Bakker23986e52011-04-24 08:57:21 +0000267int mpi_shift_r( mpi *X, size_t count );
Paul Bakker5121ce52009-01-03 21:22:43 +0000268
269/**
270 * \brief Compare unsigned values
271 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000272 * \param X Left-hand MPI
273 * \param Y Right-hand MPI
274 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000275 * \return 1 if |X| is greater than |Y|,
276 * -1 if |X| is lesser than |Y| or
277 * 0 if |X| is equal to |Y|
278 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000279int mpi_cmp_abs( const mpi *X, const mpi *Y );
Paul Bakker5121ce52009-01-03 21:22:43 +0000280
281/**
282 * \brief Compare signed values
283 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000284 * \param X Left-hand MPI
285 * \param Y Right-hand MPI
286 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 * \return 1 if X is greater than Y,
288 * -1 if X is lesser than Y or
289 * 0 if X is equal to Y
290 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000291int mpi_cmp_mpi( const mpi *X, const mpi *Y );
Paul Bakker5121ce52009-01-03 21:22:43 +0000292
293/**
294 * \brief Compare signed values
295 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000296 * \param X Left-hand MPI
297 * \param z The integer value to compare to
298 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000299 * \return 1 if X is greater than z,
300 * -1 if X is lesser than z or
301 * 0 if X is equal to z
302 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000303int mpi_cmp_int( const mpi *X, t_sint z );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305/**
306 * \brief Unsigned addition: X = |A| + |B|
307 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000308 * \param X Destination MPI
309 * \param A Left-hand MPI
310 * \param B Right-hand MPI
311 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000312 * \return 0 if successful,
313 * 1 if memory allocation failed
314 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000315int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000316
317/**
318 * \brief Unsigned substraction: X = |A| - |B|
319 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000320 * \param X Destination MPI
321 * \param A Left-hand MPI
322 * \param B Right-hand MPI
323 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000324 * \return 0 if successful,
Paul Bakker40e46942009-01-03 21:51:57 +0000325 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000327int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000328
329/**
330 * \brief Signed addition: X = A + B
331 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000332 * \param X Destination MPI
333 * \param A Left-hand MPI
334 * \param B Right-hand MPI
335 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000336 * \return 0 if successful,
337 * 1 if memory allocation failed
338 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000339int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
341/**
342 * \brief Signed substraction: X = A - B
343 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000344 * \param X Destination MPI
345 * \param A Left-hand MPI
346 * \param B Right-hand MPI
347 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000348 * \return 0 if successful,
349 * 1 if memory allocation failed
350 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000351int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000352
353/**
354 * \brief Signed addition: X = A + b
355 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000356 * \param X Destination MPI
357 * \param A Left-hand MPI
358 * \param b The integer value to add
359 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000360 * \return 0 if successful,
361 * 1 if memory allocation failed
362 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000363int mpi_add_int( mpi *X, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
365/**
366 * \brief Signed substraction: X = A - b
367 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000368 * \param X Destination MPI
369 * \param A Left-hand MPI
370 * \param b The integer value to subtract
371 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000372 * \return 0 if successful,
373 * 1 if memory allocation failed
374 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000375int mpi_sub_int( mpi *X, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
377/**
378 * \brief Baseline multiplication: X = A * B
379 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000380 * \param X Destination MPI
381 * \param A Left-hand MPI
382 * \param B Right-hand MPI
383 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000384 * \return 0 if successful,
385 * 1 if memory allocation failed
386 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000387int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
389/**
390 * \brief Baseline multiplication: X = A * b
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000391 * Note: b is an unsigned integer type, thus
392 * Negative values of b are ignored.
Paul Bakker5121ce52009-01-03 21:22:43 +0000393 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000394 * \param X Destination MPI
395 * \param A Left-hand MPI
396 * \param b The integer value to multiply with
397 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000398 * \return 0 if successful,
399 * 1 if memory allocation failed
400 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000401int mpi_mul_int( mpi *X, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
403/**
404 * \brief Division by mpi: A = Q * B + R
405 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000406 * \param Q Destination MPI for the quotient
407 * \param R Destination MPI for the rest value
408 * \param A Left-hand MPI
409 * \param B Right-hand MPI
410 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 * \return 0 if successful,
412 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000413 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 *
415 * \note Either Q or R can be NULL.
416 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000417int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
419/**
420 * \brief Division by int: A = Q * b + R
421 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000422 * \param Q Destination MPI for the quotient
423 * \param R Destination MPI for the rest value
424 * \param A Left-hand MPI
425 * \param b Integer to divide by
426 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 * \return 0 if successful,
428 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000429 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 *
431 * \note Either Q or R can be NULL.
432 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000433int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
435/**
436 * \brief Modulo: R = A mod B
437 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000438 * \param R Destination MPI for the rest value
439 * \param A Left-hand MPI
440 * \param B Right-hand MPI
441 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 * \return 0 if successful,
443 * 1 if memory allocation failed,
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000444 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
445 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000447int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
449/**
450 * \brief Modulo: r = A mod b
451 *
Paul Bakkera755ca12011-04-24 09:11:17 +0000452 * \param r Destination t_uint
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000453 * \param A Left-hand MPI
454 * \param b Integer to divide by
455 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 * \return 0 if successful,
457 * 1 if memory allocation failed,
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000458 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
459 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000460 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000461int mpi_mod_int( t_uint *r, const mpi *A, t_sint b );
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463/**
464 * \brief Sliding-window exponentiation: X = A^E mod N
465 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000466 * \param X Destination MPI
467 * \param A Left-hand MPI
468 * \param E Exponent MPI
469 * \param N Modular MPI
470 * \param _RR Speed-up MPI used for recalculations
471 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000472 * \return 0 if successful,
473 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000474 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
Paul Bakker5121ce52009-01-03 21:22:43 +0000475 *
476 * \note _RR is used to avoid re-computing R*R mod N across
477 * multiple calls, which speeds up things a bit. It can
478 * be set to NULL if the extra performance is unneeded.
479 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000480int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000481
482/**
Paul Bakker287781a2011-03-26 13:18:49 +0000483 * \brief Fill an MPI X with size bytes of random
484 *
485 * \param X Destination MPI
486 * \param size Size in bytes
487 * \param f_rng RNG function
488 * \param p_rng RNG parameter
489 *
490 * \return 0 if successful,
491 * 1 if memory allocation failed
492 */
Paul Bakker23986e52011-04-24 08:57:21 +0000493int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng );
Paul Bakker287781a2011-03-26 13:18:49 +0000494
495/**
Paul Bakker5121ce52009-01-03 21:22:43 +0000496 * \brief Greatest common divisor: G = gcd(A, B)
497 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000498 * \param G Destination MPI
499 * \param A Left-hand MPI
500 * \param B Right-hand MPI
501 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000502 * \return 0 if successful,
503 * 1 if memory allocation failed
504 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000505int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
507/**
508 * \brief Modular inverse: X = A^-1 mod N
509 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000510 * \param X Destination MPI
511 * \param A Left-hand MPI
512 * \param N Right-hand MPI
513 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000514 * \return 0 if successful,
515 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000516 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000517 POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
Paul Bakker5121ce52009-01-03 21:22:43 +0000518 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000519int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
Paul Bakker5121ce52009-01-03 21:22:43 +0000520
521/**
522 * \brief Miller-Rabin primality test
523 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000524 * \param X MPI to check
525 * \param f_rng RNG function
526 * \param p_rng RNG parameter
527 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 * \return 0 if successful (probably prime),
529 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000530 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
Paul Bakker5121ce52009-01-03 21:22:43 +0000531 */
532int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
533
534/**
535 * \brief Prime number generation
536 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000537 * \param X Destination MPI
Paul Bakkerf9688572011-05-05 10:00:45 +0000538 * \param nbits Required size of X in bits ( 3 <= nbits <= 4096 )
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000539 * \param dh_flag If 1, then (X-1)/2 will be prime too
Paul Bakker5121ce52009-01-03 21:22:43 +0000540 * \param f_rng RNG function
541 * \param p_rng RNG parameter
542 *
543 * \return 0 if successful (probably prime),
544 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000545 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
Paul Bakker5121ce52009-01-03 21:22:43 +0000546 */
Paul Bakker23986e52011-04-24 08:57:21 +0000547int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakker5121ce52009-01-03 21:22:43 +0000548 int (*f_rng)(void *), void *p_rng );
549
550/**
551 * \brief Checkup routine
552 *
553 * \return 0 if successful, or 1 if the test failed
554 */
555int mpi_self_test( int verbose );
556
557#ifdef __cplusplus
558}
559#endif
560
561#endif /* bignum.h */