1/* mpi.h  -  Multi Precision Integers
2 * Copyright (C) 1994, 1996, 1998,
3 *               2001, 2002, 2003, 2005 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser general Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 *	 Actually it's the same code with only minor changes in the
23 *	 way the data is stored; this is to support the abstraction
24 *	 of an optional secure memory allocation which may be used
25 *	 to avoid revealing of sensitive data due to paging etc.
26 */
27
28#ifndef G10_MPI_H
29#define G10_MPI_H
30
31#include <config.h>
32#include <stdio.h>
33#include <string.h>
34
35#include "types.h"
36#include "../mpi/mpi-asm-defs.h"
37
38#include "g10lib.h"
39
40#ifndef _GCRYPT_IN_LIBGCRYPT
41#error this file should only be used inside libgcrypt
42#endif
43
44#ifndef BITS_PER_MPI_LIMB
45#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
46  typedef unsigned int mpi_limb_t;
47  typedef   signed int mpi_limb_signed_t;
48#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
49  typedef unsigned long int mpi_limb_t;
50  typedef   signed long int mpi_limb_signed_t;
51#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
52  typedef unsigned long long int mpi_limb_t;
53  typedef   signed long long int mpi_limb_signed_t;
54#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
55  typedef unsigned short int mpi_limb_t;
56  typedef   signed short int mpi_limb_signed_t;
57#else
58#error BYTES_PER_MPI_LIMB does not match any C type
59#endif
60#define BITS_PER_MPI_LIMB    (8*BYTES_PER_MPI_LIMB)
61#endif /*BITS_PER_MPI_LIMB*/
62
63#define DBG_MPI     _gcry_get_debug_flag( 2 );
64
65struct gcry_mpi
66{
67  int alloced;         /* Array size (# of allocated limbs). */
68  int nlimbs;          /* Number of valid limbs. */
69  int sign;	       /* Indicates a negative number and is also used
70		          for opaque MPIs to store the length.  */
71  unsigned int flags; /* Bit 0: Array to be allocated in secure memory space.*/
72                      /* Bit 2: the limb is a pointer to some m_alloced data.*/
73  mpi_limb_t *d;      /* Array with the limbs */
74};
75
76#define MPI_NULL NULL
77
78#define mpi_get_nlimbs(a)     ((a)->nlimbs)
79#define mpi_is_neg(a)	      ((a)->sign)
80
81/*-- mpiutil.c --*/
82
83#ifdef M_DEBUG
84# define mpi_alloc(n)	_gcry_mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) )
85# define mpi_alloc_secure(n)  _gcry_mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) )
86# define mpi_free(a)	_gcry_mpi_debug_free((a), M_DBGINFO(__LINE__) )
87# define mpi_resize(a,b) _gcry_mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) )
88# define mpi_copy(a)	  _gcry_mpi_debug_copy((a), M_DBGINFO(__LINE__) )
89  gcry_mpi_t _gcry_mpi_debug_alloc( unsigned nlimbs, const char *info );
90  gcry_mpi_t _gcry_mpi_debug_alloc_secure( unsigned nlimbs, const char *info );
91  void _gcry_mpi_debug_free( gcry_mpi_t a, const char *info );
92  void _gcry_mpi_debug_resize( gcry_mpi_t a, unsigned nlimbs, const char *info );
93  gcry_mpi_t  _gcry_mpi_debug_copy( gcry_mpi_t a, const char *info	);
94#else
95# define mpi_alloc(n)	       _gcry_mpi_alloc((n) )
96# define mpi_alloc_secure(n)  _gcry_mpi_alloc_secure((n) )
97# define mpi_free(a)	       _gcry_mpi_free((a) )
98# define mpi_resize(a,b)      _gcry_mpi_resize((a),(b))
99# define mpi_copy(a)	       _gcry_mpi_copy((a))
100  gcry_mpi_t  _gcry_mpi_alloc( unsigned nlimbs );
101  gcry_mpi_t  _gcry_mpi_alloc_secure( unsigned nlimbs );
102  void _gcry_mpi_free( gcry_mpi_t a );
103  void _gcry_mpi_resize( gcry_mpi_t a, unsigned nlimbs );
104  gcry_mpi_t  _gcry_mpi_copy( gcry_mpi_t a );
105#endif
106
107#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
108#define mpi_is_secure(a) ((a) && ((a)->flags&1))
109#define mpi_clear(a)          _gcry_mpi_clear ((a))
110#define mpi_alloc_like(a)     _gcry_mpi_alloc_like((a))
111#define mpi_set(a,b)          _gcry_mpi_set ((a),(b))
112#define mpi_set_ui(a,b)       _gcry_mpi_set_ui ((a),(b))
113#define mpi_get_ui(a,b)       _gcry_mpi_get_ui ((a),(b))
114#define mpi_alloc_set_ui(a)   _gcry_mpi_alloc_set_ui ((a))
115#define mpi_m_check(a)        _gcry_mpi_m_check ((a))
116#define mpi_swap(a,b)         _gcry_mpi_swap ((a),(b))
117#define mpi_new(n)            _gcry_mpi_new ((n))
118#define mpi_snew(n)           _gcry_mpi_snew ((n))
119
120void _gcry_mpi_clear( gcry_mpi_t a );
121gcry_mpi_t  _gcry_mpi_alloc_like( gcry_mpi_t a );
122gcry_mpi_t  _gcry_mpi_alloc_set_ui( unsigned long u);
123gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
124void _gcry_mpi_m_check( gcry_mpi_t a );
125void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
126gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
127gcry_mpi_t _gcry_mpi_snew (unsigned int nbits);
128
129/*-- mpicoder.c --*/
130void  _gcry_log_mpidump( const char *text, gcry_mpi_t a );
131u32   _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid );
132byte *_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
133byte *_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
134void  _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer,
135                             unsigned int nbytes, int sign );
136
137#define log_mpidump _gcry_log_mpidump
138
139/*-- mpi-add.c --*/
140#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v))
141#define mpi_add(w,u,v)    gcry_mpi_add ((w),(u),(v))
142#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m))
143#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v))
144#define mpi_sub(w,u,v)    gcry_mpi_sub ((w),(u),(v))
145#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m))
146
147
148/*-- mpi-mul.c --*/
149#define mpi_mul_ui(w,u,v)   gcry_mpi_mul_ui ((w),(u),(v))
150#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v))
151#define mpi_mul(w,u,v)      gcry_mpi_mul ((w),(u),(v))
152#define mpi_mulm(w,u,v,m)   gcry_mpi_mulm ((w),(u),(v),(m))
153
154
155/*-- mpi-div.c --*/
156#define mpi_fdiv_r_ui(a,b,c)   _gcry_mpi_fdiv_r_ui((a),(b),(c))
157#define mpi_fdiv_r(a,b,c)      _gcry_mpi_fdiv_r((a),(b),(c))
158#define mpi_fdiv_q(a,b,c)      _gcry_mpi_fdiv_q((a),(b),(c))
159#define mpi_fdiv_qr(a,b,c,d)   _gcry_mpi_fdiv_qr((a),(b),(c),(d))
160#define mpi_tdiv_r(a,b,c)      _gcry_mpi_tdiv_r((a),(b),(c))
161#define mpi_tdiv_qr(a,b,c,d)   _gcry_mpi_tdiv_qr((a),(b),(c),(d))
162#define mpi_tdiv_q_2exp(a,b,c) _gcry_mpi_tdiv_q_2exp((a),(b),(c))
163#define mpi_divisible_ui(a,b)  _gcry_mpi_divisible_ui((a),(b))
164
165ulong _gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor );
166void  _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
167void  _gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor );
168void  _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
169void  _gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
170void  _gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
171void  _gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned count );
172int   _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor );
173
174
175/*-- mpi-mod.c --*/
176#define mpi_mod(r,a,m)            _gcry_mpi_mod ((r), (a), (m))
177#define mpi_barrett_init(m,f)     _gcry_mpi_barrett_init ((m),(f))
178#define mpi_barrett_free(c)       _gcry_mpi_barrett_free ((c))
179#define mpi_mod_barrett(r,a,c)    _gcry_mpi_mod_barrett ((r), (a), (c))
180#define mpi_mul_barrett(r,u,v,c)  _gcry_mpi_mul_barrett ((r), (u), (v), (c))
181
182void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
183
184/* Context used with Barrett reduction.  */
185struct barrett_ctx_s;
186typedef struct barrett_ctx_s *mpi_barrett_t;
187
188mpi_barrett_t _gcry_mpi_barrett_init (gcry_mpi_t m, int copy);
189void _gcry_mpi_barrett_free (mpi_barrett_t ctx);
190void _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx);
191void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
192                            mpi_barrett_t ctx);
193
194
195
196/*-- mpi-gcd.c --*/
197
198/*-- mpi-mpow.c --*/
199#define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d))
200void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod);
201
202/*-- mpi-cmp.c --*/
203#define mpi_cmp_ui(a,b) gcry_mpi_cmp_ui ((a),(b))
204#define mpi_cmp(a,b)    gcry_mpi_cmp ((a),(b))
205int gcry_mpi_cmp_ui( gcry_mpi_t u, ulong v );
206int gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v );
207
208/*-- mpi-scan.c --*/
209#define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a))
210int      _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx );
211void     _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int value );
212unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a );
213
214/*-- mpi-bit.c --*/
215#define mpi_normalize(a)       _gcry_mpi_normalize ((a))
216#define mpi_get_nbits(a)       gcry_mpi_get_nbits ((a))
217#define mpi_test_bit(a,b)      gcry_mpi_test_bit ((a),(b))
218#define mpi_set_bit(a,b)       gcry_mpi_set_bit ((a),(b))
219#define mpi_set_highbit(a,b)   gcry_mpi_set_highbit ((a),(b))
220#define mpi_clear_bit(a,b)     gcry_mpi_clear_bit ((a),(b))
221#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
222#define mpi_rshift(a,b,c)      gcry_mpi_rshift ((a),(b),(c))
223#define mpi_lshift(a,b,c)      gcry_mpi_lshift ((a),(b),(c))
224
225void _gcry_mpi_normalize( gcry_mpi_t a );
226
227/*-- mpi-inv.c --*/
228#define mpi_invm(a,b,c) _gcry_mpi_invm ((a),(b),(c))
229
230/*-- ec.c --*/
231
232/* Object to represent a point in projective coordinates. */
233struct mpi_point_s;
234typedef struct mpi_point_s mpi_point_t;
235struct mpi_point_s
236{
237  gcry_mpi_t x;
238  gcry_mpi_t y;
239  gcry_mpi_t z;
240};
241
242/* Context used with elliptic curve functions.  */
243struct mpi_ec_ctx_s;
244typedef struct mpi_ec_ctx_s *mpi_ec_t;
245
246void _gcry_mpi_ec_point_init (mpi_point_t *p);
247void _gcry_mpi_ec_point_free (mpi_point_t *p);
248mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a);
249void _gcry_mpi_ec_free (mpi_ec_t ctx);
250int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
251                             mpi_ec_t ctx);
252void _gcry_mpi_ec_dup_point (mpi_point_t *result,
253                             mpi_point_t *point, mpi_ec_t ctx);
254void _gcry_mpi_ec_add_points (mpi_point_t *result,
255                              mpi_point_t *p1, mpi_point_t *p2,
256                              mpi_ec_t ctx);
257void _gcry_mpi_ec_mul_point (mpi_point_t *result,
258                             gcry_mpi_t scalar, mpi_point_t *point,
259                             mpi_ec_t ctx);
260
261
262
263#endif /*G10_MPI_H*/
264