blob: a635f265b76d543e6ee52ccda39db26910103fb3 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/**
2 * \file bignum.h
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00003 *
4 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
5 *
Paul Bakker785a9ee2009-01-25 14:15:10 +00006 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Paul Bakker5121ce52009-01-03 21:22:43 +000021 */
Paul Bakker40e46942009-01-03 21:51:57 +000022#ifndef POLARSSL_BIGNUM_H
23#define POLARSSL_BIGNUM_H
Paul Bakker5121ce52009-01-03 21:22:43 +000024
25#include <stdio.h>
26
Paul Bakkerb5bf1762009-07-19 20:28:35 +000027#define POLARSSL_ERR_MPI_FILE_IO_ERROR 0x0002
28#define POLARSSL_ERR_MPI_BAD_INPUT_DATA 0x0004
29#define POLARSSL_ERR_MPI_INVALID_CHARACTER 0x0006
30#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL 0x0008
31#define POLARSSL_ERR_MPI_NEGATIVE_VALUE 0x000A
32#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO 0x000C
33#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE 0x000E
Paul Bakker5121ce52009-01-03 21:22:43 +000034
35#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
36
37/*
38 * Define the base integer type, architecture-wise
39 */
Paul Bakker40e46942009-01-03 21:51:57 +000040#if defined(POLARSSL_HAVE_INT8)
Paul Bakker5121ce52009-01-03 21:22:43 +000041typedef unsigned char t_int;
42typedef unsigned short t_dbl;
43#else
Paul Bakker40e46942009-01-03 21:51:57 +000044#if defined(POLARSSL_HAVE_INT16)
Paul Bakker5121ce52009-01-03 21:22:43 +000045typedef unsigned short t_int;
46typedef unsigned long t_dbl;
47#else
48 typedef unsigned long t_int;
49 #if defined(_MSC_VER) && defined(_M_IX86)
50 typedef unsigned __int64 t_dbl;
51 #else
52 #if defined(__amd64__) || defined(__x86_64__) || \
53 defined(__ppc64__) || defined(__powerpc64__) || \
54 defined(__ia64__) || defined(__alpha__)
55 typedef unsigned int t_dbl __attribute__((mode(TI)));
56 #else
Paul Bakker1a9382e2009-07-11 16:35:32 +000057 #if defined(POLARSSL_HAVE_LONGLONG)
58 typedef unsigned long long t_dbl;
59 #endif
Paul Bakker5121ce52009-01-03 21:22:43 +000060 #endif
61 #endif
62#endif
63#endif
64
65/**
66 * \brief MPI structure
67 */
68typedef struct
69{
70 int s; /*!< integer sign */
71 int n; /*!< total # of limbs */
72 t_int *p; /*!< pointer to limbs */
73}
74mpi;
75
76#ifdef __cplusplus
77extern "C" {
78#endif
79
80/**
81 * \brief Initialize one or more mpi
82 */
83void mpi_init( mpi *X, ... );
84
85/**
86 * \brief Unallocate one or more mpi
87 */
88void mpi_free( mpi *X, ... );
89
90/**
91 * \brief Enlarge to the specified number of limbs
92 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +000093 * \param X MPI to grow
94 * \param nblimbs The target number of limbs
95 *
Paul Bakker5121ce52009-01-03 21:22:43 +000096 * \return 0 if successful,
97 * 1 if memory allocation failed
98 */
99int mpi_grow( mpi *X, int nblimbs );
100
101/**
102 * \brief Copy the contents of Y into X
103 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000104 * \param X Destination MPI
105 * \param Y Source MPI
106 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000107 * \return 0 if successful,
108 * 1 if memory allocation failed
109 */
110int mpi_copy( mpi *X, mpi *Y );
111
112/**
113 * \brief Swap the contents of X and Y
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000114 *
115 * \param X First MPI value
116 * \param Y Second MPI value
Paul Bakker5121ce52009-01-03 21:22:43 +0000117 */
118void mpi_swap( mpi *X, mpi *Y );
119
120/**
121 * \brief Set value from integer
122 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000123 * \param X MPI to set
124 * \param z Value to use
125 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000126 * \return 0 if successful,
127 * 1 if memory allocation failed
128 */
129int mpi_lset( mpi *X, int z );
130
131/**
132 * \brief Return the number of least significant bits
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000133 *
134 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000135 */
136int mpi_lsb( mpi *X );
137
138/**
139 * \brief Return the number of most significant bits
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000140 *
141 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000142 */
143int mpi_msb( mpi *X );
144
145/**
146 * \brief Return the total size in bytes
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000147 *
148 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000149 */
150int mpi_size( mpi *X );
151
152/**
153 * \brief Import from an ASCII string
154 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000155 * \param X Destination MPI
156 * \param radix Input numeric base
157 * \param s Null-terminated string buffer
Paul Bakker5121ce52009-01-03 21:22:43 +0000158 *
Paul Bakker40e46942009-01-03 21:51:57 +0000159 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000160 */
161int mpi_read_string( mpi *X, int radix, char *s );
162
163/**
164 * \brief Export into an ASCII string
165 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000166 * \param X Source MPI
167 * \param radix Output numeric base
168 * \param s String buffer
169 * \param slen String buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000170 *
Paul Bakker40e46942009-01-03 21:51:57 +0000171 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000172 *
173 * \note Call this function with *slen = 0 to obtain the
174 * minimum required buffer size in *slen.
175 */
176int mpi_write_string( mpi *X, int radix, char *s, int *slen );
177
178/**
179 * \brief Read X from an opened file
180 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000181 * \param X Destination MPI
182 * \param radix Input numeric base
183 * \param fin Input file handle
Paul Bakker5121ce52009-01-03 21:22:43 +0000184 *
Paul Bakker40e46942009-01-03 21:51:57 +0000185 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000186 */
187int mpi_read_file( mpi *X, int radix, FILE *fin );
188
189/**
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000190 * \brief Write X into an opened file, or stdout if fout is NULL
Paul Bakker5121ce52009-01-03 21:22:43 +0000191 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000192 * \param p Prefix, can be NULL
193 * \param X Source MPI
194 * \param radix Output numeric base
195 * \param fout Output file handle (can be NULL)
Paul Bakker5121ce52009-01-03 21:22:43 +0000196 *
Paul Bakker40e46942009-01-03 21:51:57 +0000197 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000198 *
199 * \note Set fout == NULL to print X on the console.
200 */
201int mpi_write_file( char *p, mpi *X, int radix, FILE *fout );
202
203/**
204 * \brief Import X from unsigned binary data, big endian
205 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000206 * \param X Destination MPI
207 * \param buf Input buffer
208 * \param buflen Input buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000209 *
210 * \return 0 if successful,
211 * 1 if memory allocation failed
212 */
213int mpi_read_binary( mpi *X, unsigned char *buf, int buflen );
214
215/**
216 * \brief Export X into unsigned binary data, big endian
217 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000218 * \param X Source MPI
219 * \param buf Output buffer
220 * \param buflen Output buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000221 *
222 * \return 0 if successful,
Paul Bakker40e46942009-01-03 21:51:57 +0000223 * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
Paul Bakker5121ce52009-01-03 21:22:43 +0000224 */
225int mpi_write_binary( mpi *X, unsigned char *buf, int buflen );
226
227/**
228 * \brief Left-shift: X <<= count
229 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000230 * \param X MPI to shift
231 * \param count Amount to shift
232 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000233 * \return 0 if successful,
234 * 1 if memory allocation failed
235 */
236int mpi_shift_l( mpi *X, int count );
237
238/**
239 * \brief Right-shift: X >>= count
240 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000241 * \param X MPI to shift
242 * \param count Amount to shift
243 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000244 * \return 0 if successful,
245 * 1 if memory allocation failed
246 */
247int mpi_shift_r( mpi *X, int count );
248
249/**
250 * \brief Compare unsigned values
251 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000252 * \param X Left-hand MPI
253 * \param Y Right-hand MPI
254 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000255 * \return 1 if |X| is greater than |Y|,
256 * -1 if |X| is lesser than |Y| or
257 * 0 if |X| is equal to |Y|
258 */
259int mpi_cmp_abs( mpi *X, mpi *Y );
260
261/**
262 * \brief Compare signed values
263 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000264 * \param X Left-hand MPI
265 * \param Y Right-hand MPI
266 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 * \return 1 if X is greater than Y,
268 * -1 if X is lesser than Y or
269 * 0 if X is equal to Y
270 */
271int mpi_cmp_mpi( mpi *X, mpi *Y );
272
273/**
274 * \brief Compare signed values
275 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000276 * \param X Left-hand MPI
277 * \param z The integer value to compare to
278 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 * \return 1 if X is greater than z,
280 * -1 if X is lesser than z or
281 * 0 if X is equal to z
282 */
283int mpi_cmp_int( mpi *X, int z );
284
285/**
286 * \brief Unsigned addition: X = |A| + |B|
287 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000288 * \param X Destination MPI
289 * \param A Left-hand MPI
290 * \param B Right-hand MPI
291 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 * \return 0 if successful,
293 * 1 if memory allocation failed
294 */
295int mpi_add_abs( mpi *X, mpi *A, mpi *B );
296
297/**
298 * \brief Unsigned substraction: X = |A| - |B|
299 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000300 * \param X Destination MPI
301 * \param A Left-hand MPI
302 * \param B Right-hand MPI
303 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000304 * \return 0 if successful,
Paul Bakker40e46942009-01-03 21:51:57 +0000305 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
Paul Bakker5121ce52009-01-03 21:22:43 +0000306 */
307int mpi_sub_abs( mpi *X, mpi *A, mpi *B );
308
309/**
310 * \brief Signed addition: X = A + B
311 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000312 * \param X Destination MPI
313 * \param A Left-hand MPI
314 * \param B Right-hand MPI
315 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000316 * \return 0 if successful,
317 * 1 if memory allocation failed
318 */
319int mpi_add_mpi( mpi *X, mpi *A, mpi *B );
320
321/**
322 * \brief Signed substraction: X = A - B
323 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000324 * \param X Destination MPI
325 * \param A Left-hand MPI
326 * \param B Right-hand MPI
327 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000328 * \return 0 if successful,
329 * 1 if memory allocation failed
330 */
331int mpi_sub_mpi( mpi *X, mpi *A, mpi *B );
332
333/**
334 * \brief Signed addition: X = A + b
335 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000336 * \param X Destination MPI
337 * \param A Left-hand MPI
338 * \param b The integer value to add
339 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000340 * \return 0 if successful,
341 * 1 if memory allocation failed
342 */
343int mpi_add_int( mpi *X, mpi *A, int b );
344
345/**
346 * \brief Signed substraction: X = A - b
347 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000348 * \param X Destination MPI
349 * \param A Left-hand MPI
350 * \param b The integer value to subtract
351 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000352 * \return 0 if successful,
353 * 1 if memory allocation failed
354 */
355int mpi_sub_int( mpi *X, mpi *A, int b );
356
357/**
358 * \brief Baseline multiplication: X = A * B
359 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000360 * \param X Destination MPI
361 * \param A Left-hand MPI
362 * \param B Right-hand MPI
363 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000364 * \return 0 if successful,
365 * 1 if memory allocation failed
366 */
367int mpi_mul_mpi( mpi *X, mpi *A, mpi *B );
368
369/**
370 * \brief Baseline multiplication: X = A * b
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000371 * Note: b is an unsigned integer type, thus
372 * Negative values of b are ignored.
Paul Bakker5121ce52009-01-03 21:22:43 +0000373 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000374 * \param X Destination MPI
375 * \param A Left-hand MPI
376 * \param b The integer value to multiply with
377 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000378 * \return 0 if successful,
379 * 1 if memory allocation failed
380 */
381int mpi_mul_int( mpi *X, mpi *A, t_int b );
382
383/**
384 * \brief Division by mpi: A = Q * B + R
385 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000386 * \param Q Destination MPI for the quotient
387 * \param R Destination MPI for the rest value
388 * \param A Left-hand MPI
389 * \param B Right-hand MPI
390 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000391 * \return 0 if successful,
392 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000393 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000394 *
395 * \note Either Q or R can be NULL.
396 */
397int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B );
398
399/**
400 * \brief Division by int: 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 Integer to divide by
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 */
413int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b );
414
415/**
416 * \brief Modulo: R = A mod B
417 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000418 * \param R Destination MPI for the rest value
419 * \param A Left-hand MPI
420 * \param B Right-hand MPI
421 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000422 * \return 0 if successful,
423 * 1 if memory allocation failed,
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000424 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
425 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 */
427int mpi_mod_mpi( mpi *R, mpi *A, mpi *B );
428
429/**
430 * \brief Modulo: r = A mod b
431 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000432 * \param a Destination t_int
433 * \param A Left-hand MPI
434 * \param b Integer to divide by
435 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 * \return 0 if successful,
437 * 1 if memory allocation failed,
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000438 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
439 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000440 */
441int mpi_mod_int( t_int *r, mpi *A, int b );
442
443/**
444 * \brief Sliding-window exponentiation: X = A^E mod N
445 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000446 * \param X Destination MPI
447 * \param A Left-hand MPI
448 * \param E Exponent MPI
449 * \param N Modular MPI
450 * \param _RR Speed-up MPI used for recalculations
451 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 * \return 0 if successful,
453 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000454 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
Paul Bakker5121ce52009-01-03 21:22:43 +0000455 *
456 * \note _RR is used to avoid re-computing R*R mod N across
457 * multiple calls, which speeds up things a bit. It can
458 * be set to NULL if the extra performance is unneeded.
459 */
460int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR );
461
462/**
463 * \brief Greatest common divisor: G = gcd(A, B)
464 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000465 * \param G Destination MPI
466 * \param A Left-hand MPI
467 * \param B Right-hand MPI
468 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000469 * \return 0 if successful,
470 * 1 if memory allocation failed
471 */
472int mpi_gcd( mpi *G, mpi *A, mpi *B );
473
474/**
475 * \brief Modular inverse: X = A^-1 mod N
476 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000477 * \param X Destination MPI
478 * \param A Left-hand MPI
479 * \param N Right-hand MPI
480 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000481 * \return 0 if successful,
482 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000483 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000484 POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
Paul Bakker5121ce52009-01-03 21:22:43 +0000485 */
486int mpi_inv_mod( mpi *X, mpi *A, mpi *N );
487
488/**
489 * \brief Miller-Rabin primality test
490 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000491 * \param X MPI to check
492 * \param f_rng RNG function
493 * \param p_rng RNG parameter
494 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 * \return 0 if successful (probably prime),
496 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000497 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 */
499int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
500
501/**
502 * \brief Prime number generation
503 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000504 * \param X Destination MPI
505 * \param nbits Required size of X in bits
506 * \param dh_flag If 1, then (X-1)/2 will be prime too
Paul Bakker5121ce52009-01-03 21:22:43 +0000507 * \param f_rng RNG function
508 * \param p_rng RNG parameter
509 *
510 * \return 0 if successful (probably prime),
511 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000512 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
Paul Bakker5121ce52009-01-03 21:22:43 +0000513 */
514int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
515 int (*f_rng)(void *), void *p_rng );
516
517/**
518 * \brief Checkup routine
519 *
520 * \return 0 if successful, or 1 if the test failed
521 */
522int mpi_self_test( int verbose );
523
524#ifdef __cplusplus
525}
526#endif
527
528#endif /* bignum.h */