summaryrefslogtreecommitdiff
path: root/protocols/Sametime/src/meanwhile/src/mpi/mpi.h
blob: 0e7cc527a13ce77a818afb667076540524e887d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/*
  mpi.h
  
  by Michael J. Fromberger <http://www.dartmouth.edu/~sting/>
  Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
  
  Arbitrary precision integer arithmetic library
  
  modified for use in Meanwhile as a convenience library
*/

#ifndef _H_MPI_
#define _H_MPI_

#include "mpi-config.h"

#if MP_DEBUG
#undef MP_IOFUNC
#define MP_IOFUNC 1
#endif

#if MP_IOFUNC
#include <stdio.h>
#include <ctype.h>
#endif

#include <limits.h>

#define  MP_NEG  1
#define  MP_ZPOS 0

/* Included for compatibility... */
#define  NEG     MP_NEG
#define  ZPOS    MP_ZPOS

#define  MP_OKAY          0 /* no error, all is well */
#define  MP_YES           0 /* yes (boolean result)  */
#define  MP_NO           -1 /* no (boolean result)   */
#define  MP_MEM          -2 /* out of memory         */
#define  MP_RANGE        -3 /* argument out of range */
#define  MP_BADARG       -4 /* invalid parameter     */
#define  MP_UNDEF        -5 /* answer is undefined   */
#define  MP_LAST_CODE    MP_UNDEF

#include "mpi-types.h"

/* Included for compatibility... */
#define DIGIT_BIT         MP_DIGIT_BIT
#define DIGIT_MAX         MP_DIGIT_MAX

/* Macros for accessing the mw_mp_int internals           */
#define  SIGN(MP)     ((MP)->sign)
#define  USED(MP)     ((MP)->used)
#define  ALLOC(MP)    ((MP)->alloc)
#define  DIGITS(MP)   ((MP)->dp)
#define  DIGIT(MP,N)  (MP)->dp[(N)]

#if MP_ARGCHK == 1
#define  ARGCHK(X,Y)  {if(!(X)){return (Y);}}
#elif MP_ARGCHK == 2
#include <assert.h>
#define  ARGCHK(X,Y)  assert(X)
#else
#define  ARGCHK(X,Y)  /*  */
#endif

/* This defines the maximum I/O base (minimum is 2)   */
#define MAX_RADIX         64

typedef struct {
  mw_mp_sign       sign;    /* sign of this quantity      */
  mw_mp_size       alloc;   /* how many digits allocated  */
  mw_mp_size       used;    /* how many digits used       */
  mw_mp_digit     *dp;      /* the digits themselves      */
} mw_mp_int;

/*------------------------------------------------------------------------*/
/* Default precision                                                      */

unsigned int mw_mp_get_prec(void);
void         mw_mp_set_prec(unsigned int prec);

/*------------------------------------------------------------------------*/
/* Memory management                                                      */

mw_mp_err mw_mp_init(mw_mp_int *mp);
mw_mp_err mw_mp_init_array(mw_mp_int mp[], int count);
mw_mp_err mw_mp_init_size(mw_mp_int *mp, mw_mp_size prec);
mw_mp_err mw_mp_init_copy(mw_mp_int *mp, mw_mp_int *from);
mw_mp_err mw_mp_copy(mw_mp_int *from, mw_mp_int *to);
void   mw_mp_exch(mw_mp_int *mp1, mw_mp_int *mp2);
void   mw_mp_clear(mw_mp_int *mp);
void   mw_mp_clear_array(mw_mp_int mp[], int count);
void   mw_mp_zero(mw_mp_int *mp);
void   mw_mp_set(mw_mp_int *mp, mw_mp_digit d);
mw_mp_err mw_mp_set_int(mw_mp_int *mp, long z);

/*------------------------------------------------------------------------*/
/* Single digit arithmetic                                                */

mw_mp_err mw_mp_add_d(mw_mp_int *a, mw_mp_digit d, mw_mp_int *b);
mw_mp_err mw_mp_sub_d(mw_mp_int *a, mw_mp_digit d, mw_mp_int *b);
mw_mp_err mw_mp_mul_d(mw_mp_int *a, mw_mp_digit d, mw_mp_int *b);
mw_mp_err mw_mp_mul_2(mw_mp_int *a, mw_mp_int *c);
mw_mp_err mw_mp_div_d(mw_mp_int *a, mw_mp_digit d, mw_mp_int *q, mw_mp_digit *r);
mw_mp_err mw_mp_div_2(mw_mp_int *a, mw_mp_int *c);
mw_mp_err mw_mp_expt_d(mw_mp_int *a, mw_mp_digit d, mw_mp_int *c);

/*------------------------------------------------------------------------*/
/* Sign manipulations                                                     */

mw_mp_err mw_mp_abs(mw_mp_int *a, mw_mp_int *b);
mw_mp_err mw_mp_neg(mw_mp_int *a, mw_mp_int *b);

/*------------------------------------------------------------------------*/
/* Full arithmetic                                                        */

mw_mp_err mw_mp_add(mw_mp_int *a, mw_mp_int *b, mw_mp_int *c);
mw_mp_err mw_mp_sub(mw_mp_int *a, mw_mp_int *b, mw_mp_int *c);
mw_mp_err mw_mp_mul(mw_mp_int *a, mw_mp_int *b, mw_mp_int *c);
mw_mp_err mw_mp_mul_2d(mw_mp_int *a, mw_mp_digit d, mw_mp_int *c);
#if MP_SQUARE
mw_mp_err mw_mp_sqr(mw_mp_int *a, mw_mp_int *b);
#else
#define mw_mp_sqr(a, b) mw_mp_mul(a, a, b)
#endif
mw_mp_err mw_mp_div(mw_mp_int *a, mw_mp_int *b, mw_mp_int *q, mw_mp_int *r);
mw_mp_err mw_mp_div_2d(mw_mp_int *a, mw_mp_digit d, mw_mp_int *q, mw_mp_int *r);
mw_mp_err mw_mp_expt(mw_mp_int *a, mw_mp_int *b, mw_mp_int *c);
mw_mp_err mw_mp_2expt(mw_mp_int *a, mw_mp_digit k);
mw_mp_err mw_mp_sqrt(mw_mp_int *a, mw_mp_int *b);

/*------------------------------------------------------------------------*/
/* Modular arithmetic                                                     */

#if MP_MODARITH
mw_mp_err mw_mp_mod(mw_mp_int *a, mw_mp_int *m, mw_mp_int *c);
mw_mp_err mw_mp_mod_d(mw_mp_int *a, mw_mp_digit d, mw_mp_digit *c);
mw_mp_err mw_mp_addmod(mw_mp_int *a, mw_mp_int *b, mw_mp_int *m, mw_mp_int *c);
mw_mp_err mw_mp_submod(mw_mp_int *a, mw_mp_int *b, mw_mp_int *m, mw_mp_int *c);
mw_mp_err mw_mp_mulmod(mw_mp_int *a, mw_mp_int *b, mw_mp_int *m, mw_mp_int *c);
#if MP_SQUARE
mw_mp_err mw_mp_sqrmod(mw_mp_int *a, mw_mp_int *m, mw_mp_int *c);
#else
#define mw_mp_sqrmod(a, m, c) mw_mp_mulmod(a, a, m, c)
#endif
mw_mp_err mw_mp_exptmod(mw_mp_int *a, mw_mp_int *b, mw_mp_int *m, mw_mp_int *c);
mw_mp_err mw_mp_exptmod_d(mw_mp_int *a, mw_mp_digit d, mw_mp_int *m, mw_mp_int *c);
#endif /* MP_MODARITH */

/*------------------------------------------------------------------------*/
/* Comparisons                                                            */

int    mw_mp_cmw_mp_z(mw_mp_int *a);
int    mw_mp_cmw_mp_d(mw_mp_int *a, mw_mp_digit d);
int    mw_mp_cmp(mw_mp_int *a, mw_mp_int *b);
int    mw_mp_cmw_mp_mag(mw_mp_int *a, mw_mp_int *b);
int    mw_mp_cmw_mp_int(mw_mp_int *a, long z);
int    mw_mp_isodd(mw_mp_int *a);
int    mw_mp_iseven(mw_mp_int *a);

/*------------------------------------------------------------------------*/
/* Number theoretic                                                       */

#if MP_NUMTH
mw_mp_err mw_mp_gcd(mw_mp_int *a, mw_mp_int *b, mw_mp_int *c);
mw_mp_err mw_mp_lcm(mw_mp_int *a, mw_mp_int *b, mw_mp_int *c);
mw_mp_err mw_mp_xgcd(mw_mp_int *a, mw_mp_int *b, mw_mp_int *g, mw_mp_int *x, mw_mp_int *y);
mw_mp_err mw_mp_invmod(mw_mp_int *a, mw_mp_int *m, mw_mp_int *c);
#endif /* end MP_NUMTH */

/*------------------------------------------------------------------------*/
/* Input and output                                                       */

#if MP_IOFUNC
void   mw_mp_print(mw_mp_int *mp, FILE *ofp);
#endif /* end MP_IOFUNC */

/*------------------------------------------------------------------------*/
/* Base conversion                                                        */

#define BITS     1
#define BYTES    CHAR_BIT

mw_mp_err mw_mp_read_signed_bin(mw_mp_int *mp, unsigned char *str, int len);
int    mw_mp_signed_bin_size(mw_mp_int *mp);
mw_mp_err mw_mp_to_signed_bin(mw_mp_int *mp, unsigned char *str);

mw_mp_err mw_mp_read_unsigned_bin(mw_mp_int *mp, unsigned char *str, int len);
int    mw_mp_unsigned_bin_size(mw_mp_int *mp);
mw_mp_err mw_mp_to_unsigned_bin(mw_mp_int *mp, unsigned char *str);

int    mw_mp_count_bits(mw_mp_int *mp);

#if MP_COMPAT_MACROS
#define mw_mp_read_raw(mp, str, len) mw_mp_read_signed_bin((mp), (str), (len))
#define mw_mp_raw_size(mp)           mw_mp_signed_bin_size(mp)
#define mw_mp_toraw(mp, str)         mw_mp_to_signed_bin((mp), (str))
#define mw_mp_read_mag(mp, str, len) mw_mp_read_unsigned_bin((mp), (str), (len))
#define mw_mp_mag_size(mp)           mw_mp_unsigned_bin_size(mp)
#define mw_mp_tomag(mp, str)         mw_mp_to_unsigned_bin((mp), (str))
#endif

mw_mp_err mw_mp_read_radix(mw_mp_int *mp, unsigned char *str, int radix);
int    mw_mp_radix_size(mw_mp_int *mp, int radix);
int    mw_mp_value_radix_size(int num, int qty, int radix);
mw_mp_err mw_mp_toradix(mw_mp_int *mp, unsigned char *str, int radix);

int    mw_mp_char2value(char ch, int r);

#define mw_mp_tobinary(M, S)  mw_mp_toradix((M), (S), 2)
#define mw_mp_tooctal(M, S)   mw_mp_toradix((M), (S), 8)
#define mw_mp_todecimal(M, S) mw_mp_toradix((M), (S), 10)
#define mw_mp_tohex(M, S)     mw_mp_toradix((M), (S), 16)

/*------------------------------------------------------------------------*/
/* Error strings                                                          */

const  char  *mw_mp_strerror(mw_mp_err ec);

#endif /* end _H_MPI_ */