blob: cb0ac9b8c5a1acd0774bda6f4d2935d22a857639 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/**
2 * \file bignum.h
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00003 *
Paul Bakker77b385e2009-07-28 17:23:11 +00004 * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
5 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00006 *
Paul Bakker77b385e2009-07-28 17:23:11 +00007 * Joined copyright on original XySSL code with: Christophe Devine
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00008 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Paul Bakker5121ce52009-01-03 21:22:43 +000022 */
Paul Bakker40e46942009-01-03 21:51:57 +000023#ifndef POLARSSL_BIGNUM_H
24#define POLARSSL_BIGNUM_H
Paul Bakker5121ce52009-01-03 21:22:43 +000025
26#include <stdio.h>
27
Paul Bakkerb5bf1762009-07-19 20:28:35 +000028#define POLARSSL_ERR_MPI_FILE_IO_ERROR 0x0002
29#define POLARSSL_ERR_MPI_BAD_INPUT_DATA 0x0004
30#define POLARSSL_ERR_MPI_INVALID_CHARACTER 0x0006
31#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL 0x0008
32#define POLARSSL_ERR_MPI_NEGATIVE_VALUE 0x000A
33#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO 0x000C
34#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE 0x000E
Paul Bakker5121ce52009-01-03 21:22:43 +000035
36#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
37
38/*
39 * Define the base integer type, architecture-wise
40 */
Paul Bakker40e46942009-01-03 21:51:57 +000041#if defined(POLARSSL_HAVE_INT8)
Paul Bakker5121ce52009-01-03 21:22:43 +000042typedef unsigned char t_int;
43typedef unsigned short t_dbl;
44#else
Paul Bakker40e46942009-01-03 21:51:57 +000045#if defined(POLARSSL_HAVE_INT16)
Paul Bakker5121ce52009-01-03 21:22:43 +000046typedef unsigned short t_int;
47typedef unsigned long t_dbl;
48#else
49 typedef unsigned long t_int;
50 #if defined(_MSC_VER) && defined(_M_IX86)
51 typedef unsigned __int64 t_dbl;
52 #else
53 #if defined(__amd64__) || defined(__x86_64__) || \
54 defined(__ppc64__) || defined(__powerpc64__) || \
55 defined(__ia64__) || defined(__alpha__)
56 typedef unsigned int t_dbl __attribute__((mode(TI)));
57 #else
Paul Bakker1a9382e2009-07-11 16:35:32 +000058 #if defined(POLARSSL_HAVE_LONGLONG)
59 typedef unsigned long long t_dbl;
60 #endif
Paul Bakker5121ce52009-01-03 21:22:43 +000061 #endif
62 #endif
63#endif
64#endif
65
66/**
67 * \brief MPI structure
68 */
69typedef struct
70{
71 int s; /*!< integer sign */
72 int n; /*!< total # of limbs */
73 t_int *p; /*!< pointer to limbs */
74}
75mpi;
76
77#ifdef __cplusplus
78extern "C" {
79#endif
80
81/**
82 * \brief Initialize one or more mpi
83 */
84void mpi_init( mpi *X, ... );
85
86/**
87 * \brief Unallocate one or more mpi
88 */
89void mpi_free( mpi *X, ... );
90
91/**
92 * \brief Enlarge to the specified number of limbs
93 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +000094 * \param X MPI to grow
95 * \param nblimbs The target number of limbs
96 *
Paul Bakker5121ce52009-01-03 21:22:43 +000097 * \return 0 if successful,
98 * 1 if memory allocation failed
99 */
100int mpi_grow( mpi *X, int nblimbs );
101
102/**
103 * \brief Copy the contents of Y into X
104 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000105 * \param X Destination MPI
106 * \param Y Source MPI
107 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000108 * \return 0 if successful,
109 * 1 if memory allocation failed
110 */
111int mpi_copy( mpi *X, mpi *Y );
112
113/**
114 * \brief Swap the contents of X and Y
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000115 *
116 * \param X First MPI value
117 * \param Y Second MPI value
Paul Bakker5121ce52009-01-03 21:22:43 +0000118 */
119void mpi_swap( mpi *X, mpi *Y );
120
121/**
122 * \brief Set value from integer
123 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000124 * \param X MPI to set
125 * \param z Value to use
126 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000127 * \return 0 if successful,
128 * 1 if memory allocation failed
129 */
130int mpi_lset( mpi *X, int z );
131
132/**
133 * \brief Return the number of least significant bits
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000134 *
135 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000136 */
137int mpi_lsb( mpi *X );
138
139/**
140 * \brief Return the number of most significant bits
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000141 *
142 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000143 */
144int mpi_msb( mpi *X );
145
146/**
147 * \brief Return the total size in bytes
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000148 *
149 * \param X MPI to use
Paul Bakker5121ce52009-01-03 21:22:43 +0000150 */
151int mpi_size( mpi *X );
152
153/**
154 * \brief Import from an ASCII string
155 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000156 * \param X Destination MPI
157 * \param radix Input numeric base
158 * \param s Null-terminated string buffer
Paul Bakker5121ce52009-01-03 21:22:43 +0000159 *
Paul Bakker40e46942009-01-03 21:51:57 +0000160 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000161 */
162int mpi_read_string( mpi *X, int radix, char *s );
163
164/**
165 * \brief Export into an ASCII string
166 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000167 * \param X Source MPI
168 * \param radix Output numeric base
169 * \param s String buffer
170 * \param slen String buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000171 *
Paul Bakker40e46942009-01-03 21:51:57 +0000172 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000173 *
174 * \note Call this function with *slen = 0 to obtain the
175 * minimum required buffer size in *slen.
176 */
177int mpi_write_string( mpi *X, int radix, char *s, int *slen );
178
179/**
180 * \brief Read X from an opened file
181 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000182 * \param X Destination MPI
183 * \param radix Input numeric base
184 * \param fin Input file handle
Paul Bakker5121ce52009-01-03 21:22:43 +0000185 *
Paul Bakker40e46942009-01-03 21:51:57 +0000186 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000187 */
188int mpi_read_file( mpi *X, int radix, FILE *fin );
189
190/**
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000191 * \brief Write X into an opened file, or stdout if fout is NULL
Paul Bakker5121ce52009-01-03 21:22:43 +0000192 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000193 * \param p Prefix, can be NULL
194 * \param X Source MPI
195 * \param radix Output numeric base
196 * \param fout Output file handle (can be NULL)
Paul Bakker5121ce52009-01-03 21:22:43 +0000197 *
Paul Bakker40e46942009-01-03 21:51:57 +0000198 * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
Paul Bakker5121ce52009-01-03 21:22:43 +0000199 *
200 * \note Set fout == NULL to print X on the console.
201 */
202int mpi_write_file( char *p, mpi *X, int radix, FILE *fout );
203
204/**
205 * \brief Import X from unsigned binary data, big endian
206 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000207 * \param X Destination MPI
208 * \param buf Input buffer
209 * \param buflen Input buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000210 *
211 * \return 0 if successful,
212 * 1 if memory allocation failed
213 */
214int mpi_read_binary( mpi *X, unsigned char *buf, int buflen );
215
216/**
217 * \brief Export X into unsigned binary data, big endian
218 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000219 * \param X Source MPI
220 * \param buf Output buffer
221 * \param buflen Output buffer size
Paul Bakker5121ce52009-01-03 21:22:43 +0000222 *
223 * \return 0 if successful,
Paul Bakker40e46942009-01-03 21:51:57 +0000224 * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
Paul Bakker5121ce52009-01-03 21:22:43 +0000225 */
226int mpi_write_binary( mpi *X, unsigned char *buf, int buflen );
227
228/**
229 * \brief Left-shift: X <<= count
230 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000231 * \param X MPI to shift
232 * \param count Amount to shift
233 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000234 * \return 0 if successful,
235 * 1 if memory allocation failed
236 */
237int mpi_shift_l( mpi *X, int count );
238
239/**
240 * \brief Right-shift: X >>= count
241 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000242 * \param X MPI to shift
243 * \param count Amount to shift
244 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000245 * \return 0 if successful,
246 * 1 if memory allocation failed
247 */
248int mpi_shift_r( mpi *X, int count );
249
250/**
251 * \brief Compare unsigned values
252 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000253 * \param X Left-hand MPI
254 * \param Y Right-hand MPI
255 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000256 * \return 1 if |X| is greater than |Y|,
257 * -1 if |X| is lesser than |Y| or
258 * 0 if |X| is equal to |Y|
259 */
260int mpi_cmp_abs( mpi *X, mpi *Y );
261
262/**
263 * \brief Compare signed values
264 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000265 * \param X Left-hand MPI
266 * \param Y Right-hand MPI
267 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000268 * \return 1 if X is greater than Y,
269 * -1 if X is lesser than Y or
270 * 0 if X is equal to Y
271 */
272int mpi_cmp_mpi( mpi *X, mpi *Y );
273
274/**
275 * \brief Compare signed values
276 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000277 * \param X Left-hand MPI
278 * \param z The integer value to compare to
279 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 * \return 1 if X is greater than z,
281 * -1 if X is lesser than z or
282 * 0 if X is equal to z
283 */
284int mpi_cmp_int( mpi *X, int z );
285
286/**
287 * \brief Unsigned addition: X = |A| + |B|
288 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000289 * \param X Destination MPI
290 * \param A Left-hand MPI
291 * \param B Right-hand MPI
292 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 * \return 0 if successful,
294 * 1 if memory allocation failed
295 */
296int mpi_add_abs( mpi *X, mpi *A, mpi *B );
297
298/**
299 * \brief Unsigned substraction: X = |A| - |B|
300 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000301 * \param X Destination MPI
302 * \param A Left-hand MPI
303 * \param B Right-hand MPI
304 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000305 * \return 0 if successful,
Paul Bakker40e46942009-01-03 21:51:57 +0000306 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
Paul Bakker5121ce52009-01-03 21:22:43 +0000307 */
308int mpi_sub_abs( mpi *X, mpi *A, mpi *B );
309
310/**
311 * \brief Signed addition: X = A + B
312 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000313 * \param X Destination MPI
314 * \param A Left-hand MPI
315 * \param B Right-hand MPI
316 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000317 * \return 0 if successful,
318 * 1 if memory allocation failed
319 */
320int mpi_add_mpi( mpi *X, mpi *A, mpi *B );
321
322/**
323 * \brief Signed substraction: X = A - B
324 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000325 * \param X Destination MPI
326 * \param A Left-hand MPI
327 * \param B Right-hand MPI
328 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 * \return 0 if successful,
330 * 1 if memory allocation failed
331 */
332int mpi_sub_mpi( mpi *X, mpi *A, mpi *B );
333
334/**
335 * \brief Signed addition: X = A + b
336 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000337 * \param X Destination MPI
338 * \param A Left-hand MPI
339 * \param b The integer value to add
340 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000341 * \return 0 if successful,
342 * 1 if memory allocation failed
343 */
344int mpi_add_int( mpi *X, mpi *A, int b );
345
346/**
347 * \brief Signed substraction: X = A - b
348 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000349 * \param X Destination MPI
350 * \param A Left-hand MPI
351 * \param b The integer value to subtract
352 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000353 * \return 0 if successful,
354 * 1 if memory allocation failed
355 */
356int mpi_sub_int( mpi *X, mpi *A, int b );
357
358/**
359 * \brief Baseline multiplication: X = A * B
360 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000361 * \param X Destination MPI
362 * \param A Left-hand MPI
363 * \param B Right-hand MPI
364 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000365 * \return 0 if successful,
366 * 1 if memory allocation failed
367 */
368int mpi_mul_mpi( mpi *X, mpi *A, mpi *B );
369
370/**
371 * \brief Baseline multiplication: X = A * b
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000372 * Note: b is an unsigned integer type, thus
373 * Negative values of b are ignored.
Paul Bakker5121ce52009-01-03 21:22:43 +0000374 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000375 * \param X Destination MPI
376 * \param A Left-hand MPI
377 * \param b The integer value to multiply with
378 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000379 * \return 0 if successful,
380 * 1 if memory allocation failed
381 */
382int mpi_mul_int( mpi *X, mpi *A, t_int b );
383
384/**
385 * \brief Division by mpi: A = Q * B + R
386 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000387 * \param Q Destination MPI for the quotient
388 * \param R Destination MPI for the rest value
389 * \param A Left-hand MPI
390 * \param B Right-hand MPI
391 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000392 * \return 0 if successful,
393 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000394 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 *
396 * \note Either Q or R can be NULL.
397 */
398int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B );
399
400/**
401 * \brief Division by int: A = Q * b + R
402 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000403 * \param Q Destination MPI for the quotient
404 * \param R Destination MPI for the rest value
405 * \param A Left-hand MPI
406 * \param b Integer to divide by
407 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 * \return 0 if successful,
409 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000410 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 *
412 * \note Either Q or R can be NULL.
413 */
414int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b );
415
416/**
417 * \brief Modulo: R = A mod B
418 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000419 * \param R Destination MPI for the rest value
420 * \param A Left-hand MPI
421 * \param B Right-hand MPI
422 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 * \return 0 if successful,
424 * 1 if memory allocation failed,
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000425 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
426 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 */
428int mpi_mod_mpi( mpi *R, mpi *A, mpi *B );
429
430/**
431 * \brief Modulo: r = A mod b
432 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000433 * \param a Destination t_int
434 * \param A Left-hand MPI
435 * \param b Integer to divide by
436 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 * \return 0 if successful,
438 * 1 if memory allocation failed,
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000439 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
440 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 */
442int mpi_mod_int( t_int *r, mpi *A, int b );
443
444/**
445 * \brief Sliding-window exponentiation: X = A^E mod N
446 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000447 * \param X Destination MPI
448 * \param A Left-hand MPI
449 * \param E Exponent MPI
450 * \param N Modular MPI
451 * \param _RR Speed-up MPI used for recalculations
452 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 * \return 0 if successful,
454 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000455 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 *
457 * \note _RR is used to avoid re-computing R*R mod N across
458 * multiple calls, which speeds up things a bit. It can
459 * be set to NULL if the extra performance is unneeded.
460 */
461int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR );
462
463/**
464 * \brief Greatest common divisor: G = gcd(A, B)
465 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000466 * \param G Destination MPI
467 * \param A Left-hand MPI
468 * \param B Right-hand MPI
469 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000470 * \return 0 if successful,
471 * 1 if memory allocation failed
472 */
473int mpi_gcd( mpi *G, mpi *A, mpi *B );
474
475/**
476 * \brief Modular inverse: X = A^-1 mod N
477 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000478 * \param X Destination MPI
479 * \param A Left-hand MPI
480 * \param N Right-hand MPI
481 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000482 * \return 0 if successful,
483 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000484 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000485 POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
Paul Bakker5121ce52009-01-03 21:22:43 +0000486 */
487int mpi_inv_mod( mpi *X, mpi *A, mpi *N );
488
489/**
490 * \brief Miller-Rabin primality test
491 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000492 * \param X MPI to check
493 * \param f_rng RNG function
494 * \param p_rng RNG parameter
495 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000496 * \return 0 if successful (probably prime),
497 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000498 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
Paul Bakker5121ce52009-01-03 21:22:43 +0000499 */
500int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
501
502/**
503 * \brief Prime number generation
504 *
Paul Bakker13e2dfe2009-07-28 07:18:38 +0000505 * \param X Destination MPI
506 * \param nbits Required size of X in bits
507 * \param dh_flag If 1, then (X-1)/2 will be prime too
Paul Bakker5121ce52009-01-03 21:22:43 +0000508 * \param f_rng RNG function
509 * \param p_rng RNG parameter
510 *
511 * \return 0 if successful (probably prime),
512 * 1 if memory allocation failed,
Paul Bakker40e46942009-01-03 21:51:57 +0000513 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
Paul Bakker5121ce52009-01-03 21:22:43 +0000514 */
515int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
516 int (*f_rng)(void *), void *p_rng );
517
518/**
519 * \brief Checkup routine
520 *
521 * \return 0 if successful, or 1 if the test failed
522 */
523int mpi_self_test( int verbose );
524
525#ifdef __cplusplus
526}
527#endif
528
529#endif /* bignum.h */