1
/* mpi.h - Multi Precision Integers
2
* Copyright (C) 1994, 1996, 1998,
3
* 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
5
* This file is part of Libgcrypt.
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.
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.
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
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.
36
#include "../mpi/mpi-asm-defs.h"
40
#ifndef _GCRYPT_IN_LIBGCRYPT
41
#error this file should only be used inside libgcrypt
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;
58
#error BYTES_PER_MPI_LIMB does not match any C type
60
#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
61
#endif /*BITS_PER_MPI_LIMB*/
63
#define DBG_MPI _gcry_get_debug_flag( 2 );
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 */
78
#define mpi_get_nlimbs(a) ((a)->nlimbs)
79
#define mpi_is_neg(a) ((a)->sign)
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 );
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 );
107
#define gcry_mpi_copy _gcry_mpi_copy
109
#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
110
#define mpi_is_secure(a) ((a) && ((a)->flags&1))
111
#define mpi_clear(a) _gcry_mpi_clear ((a))
112
#define mpi_alloc_like(a) _gcry_mpi_alloc_like((a))
113
#define mpi_set(a,b) gcry_mpi_set ((a),(b))
114
#define mpi_set_ui(a,b) gcry_mpi_set_ui ((a),(b))
115
#define mpi_get_ui(a,b) _gcry_mpi_get_ui ((a),(b))
116
#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a))
117
#define mpi_m_check(a) _gcry_mpi_m_check ((a))
118
#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b))
119
#define mpi_new(n) _gcry_mpi_new ((n))
120
#define mpi_snew(n) _gcry_mpi_snew ((n))
122
void _gcry_mpi_clear( gcry_mpi_t a );
123
gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a );
124
gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u);
125
gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
126
gcry_err_code_t gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
127
void _gcry_mpi_m_check( gcry_mpi_t a );
128
void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
129
gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
130
gcry_mpi_t _gcry_mpi_snew (unsigned int nbits);
133
void _gcry_log_mpidump( const char *text, gcry_mpi_t a );
134
u32 _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid );
135
byte *_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
136
byte *_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
137
void _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer,
138
unsigned int nbytes, int sign );
140
#define log_mpidump _gcry_log_mpidump
143
#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v))
144
#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v))
145
#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m))
146
#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v))
147
#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v))
148
#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m))
152
#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v))
153
#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v))
154
#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v))
155
#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m))
159
#define mpi_fdiv_r_ui(a,b,c) _gcry_mpi_fdiv_r_ui((a),(b),(c))
160
#define mpi_fdiv_r(a,b,c) _gcry_mpi_fdiv_r((a),(b),(c))
161
#define mpi_fdiv_q(a,b,c) _gcry_mpi_fdiv_q((a),(b),(c))
162
#define mpi_fdiv_qr(a,b,c,d) _gcry_mpi_fdiv_qr((a),(b),(c),(d))
163
#define mpi_tdiv_r(a,b,c) _gcry_mpi_tdiv_r((a),(b),(c))
164
#define mpi_tdiv_qr(a,b,c,d) _gcry_mpi_tdiv_qr((a),(b),(c),(d))
165
#define mpi_tdiv_q_2exp(a,b,c) _gcry_mpi_tdiv_q_2exp((a),(b),(c))
166
#define mpi_divisible_ui(a,b) _gcry_mpi_divisible_ui((a),(b))
168
ulong _gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor );
169
void _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
170
void _gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor );
171
void _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
172
void _gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
173
void _gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
174
void _gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned count );
175
int _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor );
179
#define mpi_mod(r,a,m) _gcry_mpi_mod ((r), (a), (m))
180
#define mpi_barrett_init(m,f) _gcry_mpi_barrett_init ((m),(f))
181
#define mpi_barrett_free(c) _gcry_mpi_barrett_free ((c))
182
#define mpi_mod_barrett(r,a,c) _gcry_mpi_mod_barrett ((r), (a), (c))
183
#define mpi_mul_barrett(r,u,v,c) _gcry_mpi_mul_barrett ((r), (u), (v), (c))
185
void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
187
/* Context used with Barrett reduction. */
188
struct barrett_ctx_s;
189
typedef struct barrett_ctx_s *mpi_barrett_t;
191
mpi_barrett_t _gcry_mpi_barrett_init (gcry_mpi_t m, int copy);
192
void _gcry_mpi_barrett_free (mpi_barrett_t ctx);
193
void _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx);
194
void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
202
#define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d))
203
void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod);
206
#define mpi_cmp_ui(a,b) gcry_mpi_cmp_ui ((a),(b))
207
#define mpi_cmp(a,b) gcry_mpi_cmp ((a),(b))
208
int gcry_mpi_cmp_ui( gcry_mpi_t u, ulong v );
209
int gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v );
212
#define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a))
213
int _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx );
214
void _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int value );
215
unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a );
218
#define mpi_normalize(a) _gcry_mpi_normalize ((a))
219
#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a))
220
#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b))
221
#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b))
222
#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b))
223
#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b))
224
#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
225
#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c))
226
#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c))
228
void _gcry_mpi_normalize( gcry_mpi_t a );
231
#define mpi_invm(a,b,c) gcry_mpi_invm ((a),(b),(c))
235
/* Object to represent a point in projective coordinates. */
237
typedef struct mpi_point_s mpi_point_t;
245
/* Context used with elliptic curve functions. */
247
typedef struct mpi_ec_ctx_s *mpi_ec_t;
249
void _gcry_mpi_ec_point_init (mpi_point_t *p);
250
void _gcry_mpi_ec_point_free (mpi_point_t *p);
251
mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a);
252
void _gcry_mpi_ec_free (mpi_ec_t ctx);
253
int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
255
void _gcry_mpi_ec_dup_point (mpi_point_t *result,
256
mpi_point_t *point, mpi_ec_t ctx);
257
void _gcry_mpi_ec_add_points (mpi_point_t *result,
258
mpi_point_t *p1, mpi_point_t *p2,
260
void _gcry_mpi_ec_mul_point (mpi_point_t *result,
261
gcry_mpi_t scalar, mpi_point_t *point,