1
2 /*
3 * Licensed Materials - Property of IBM
4 *
5 * trousers - An open source TCG Software Stack
6 *
7 * (C) Copyright International Business Machines Corp. 2006
8 *
9 */
10
11 #ifndef BI_GMP_
12 #define BI_GMP_
13
14 #include <gmp.h>
15 // needed for OPENSSL_free
16 #include <openssl/crypto.h>
17
18 typedef mpz_t bi_t;
19 typedef mpz_ptr bi_ptr;
20
21 extern gmp_randstate_t state;
22
23 /* initialized the given big integer */
bi_new(bi_t i)24 INLINE_DECL bi_ptr bi_new(bi_t i) {
25 mpz_init( i);
26 return i;
27 }
28
29 /* create a big integer pointer */
bi_new_ptr(void)30 INLINE_DECL bi_ptr bi_new_ptr(void) {
31 mpz_ptr res;
32
33 res = (mpz_ptr)malloc( sizeof( mpz_t));
34 if( res == NULL) return NULL;
35 mpz_init( res);
36 return res;
37 }
38
39 /* free resources allocated to the big integer <i> */
bi_free(const bi_ptr i)40 INLINE_DECL void bi_free(const bi_ptr i) {
41 mpz_clear( i);
42 }
43
44 /* free resources allocated to the big integer pointer <i> */
bi_free_ptr(const bi_ptr i)45 INLINE_DECL void bi_free_ptr(const bi_ptr i) {
46 mpz_clear( i);
47 free( i);
48 }
49
50 /* return the current number of bits of the number */
bi_length(const bi_ptr res)51 INLINE_DECL long bi_length( const bi_ptr res) {
52 return mpz_sizeinbase( res, 2);
53 }
54
55 /***********************************************************************************
56 CONVERSIONS
57 *************************************************************************************/
58
59
60 /* return an hex dump of the given big integer */
bi_2_hex_char(const bi_ptr i)61 INLINE_DECL char *bi_2_hex_char(const bi_ptr i) {
62 char *ret;
63
64 gmp_asprintf( &ret, "%ZX", i);
65 list_add( allocs, ret);
66 return ret;
67 }
68
69 /* return an hex dump of the given big integer */
bi_2_dec_char(const bi_ptr i)70 INLINE_DECL char *bi_2_dec_char(const bi_ptr i) {
71 char *ret;
72
73 gmp_asprintf( &ret, "%Zd", i);
74 list_add( allocs, ret);
75 return ret;
76 }
77
78 /* set <i> to the same value as the big integer <value> */
bi_set(bi_ptr result,const bi_ptr value)79 INLINE_DECL bi_ptr bi_set( bi_ptr result, const bi_ptr value) {
80 mpz_set( result, value);
81 return result;
82 }
83
84 /* set the initialized variable to the value represented by the given hex format stirng */
bi_set_as_hex(bi_ptr result,const char * value)85 INLINE_DECL bi_ptr bi_set_as_hex( bi_ptr result, const char *value) {
86 mpz_set_str( result, value, 16);
87 return result;
88 }
89
90 /* set the initialized variable to the value represented by the given hex format stirng */
bi_set_as_dec(bi_ptr result,const char * value)91 INLINE_DECL bi_ptr bi_set_as_dec( bi_ptr result, const char *value) {
92 mpz_set_str( result, value, 10);
93 return result;
94 }
95
96 /* set <i> with the value represented by unsigned int <value> */
97 /* <i> := <value> */
bi_set_as_si(bi_ptr result,const int value)98 INLINE_DECL bi_ptr bi_set_as_si( bi_ptr result, const int value) {
99 mpz_set_si( result, value);
100 return result;
101 }
102
103 /* return (long)bi_t */
bi_get_si(const bi_ptr i)104 INLINE_DECL long bi_get_si(const bi_ptr i) {
105 return mpz_get_si( i);
106 }
107
108 /* convert a bi type to a openssl BIGNUM struct */
bi_2_BIGNUM(const bi_ptr i)109 INLINE_DECL BIGNUM *bi_2_BIGNUM( const bi_ptr i) {
110 BIGNUM *result;
111 char *value = bi_2_hex_char( i);
112
113 BN_hex2bn( &result, value);
114 return result;
115 }
116
117 /* set <i> with the value represented by the given openssl BIGNUM struct */
bi_set_as_BIGNUM(bi_ptr i,BIGNUM * bn)118 INLINE_DECL bi_ptr bi_set_as_BIGNUM( bi_ptr i, BIGNUM *bn) {
119 char *value = BN_bn2hex( bn);
120
121 if( value == NULL) return NULL;
122 bi_set_as_hex( i, value);
123 OPENSSL_free( value);
124 return i;
125 }
126
127 /***********************************************************************************
128 BASIC MATH OPERATION
129 *************************************************************************************/
130
131 /* <result> := result + 1 */
bi_inc(bi_ptr result)132 INLINE_DECL bi_ptr bi_inc(bi_ptr result) {
133 mpz_add_ui( result, result, 1);
134 return result;
135 }
136
137 /* <result> := result - 1 */
bi_dec(bi_ptr result)138 INLINE_DECL bi_ptr bi_dec(bi_ptr result) {
139 mpz_sub_ui( result, result, 1);
140 return result;
141 }
142
143 /* set <result> by the division of <i> by the long <n> */
144 /* <result> := <i> / <n> */
bi_div_si(bi_ptr result,const bi_ptr i,const long n)145 INLINE_DECL bi_ptr bi_div_si( bi_ptr result, const bi_ptr i, const long n) {
146 mpz_div_ui( result, i, n);
147 return result;
148 }
149
150 /* <result> := <i> / <n> */
bi_div(bi_ptr result,const bi_ptr i,const bi_ptr n)151 INLINE_DECL bi_ptr bi_div( bi_ptr result, const bi_ptr i, const bi_ptr n) {
152 mpz_div( result, i, n);
153 return result;
154 }
155
156 /* <result> := - <result> */
bi_negate(bi_ptr result)157 INLINE_DECL bi_ptr bi_negate( bi_ptr result) {
158 mpz_neg( result, result);
159 return result;
160 }
161
162 /* multiply the given big integer <i> by the give long <n> and return the result in <result> */
bi_mul_si(bi_ptr result,const bi_ptr i,const long n)163 INLINE_DECL bi_ptr bi_mul_si( bi_ptr result, const bi_ptr i, const long n) {
164 mpz_mul_si( result, i, n);
165 return result;
166 }
167
168 /* <result> := <i> * <n> */
bi_mul(bi_ptr result,const bi_ptr i,const bi_ptr n)169 INLINE_DECL bi_ptr bi_mul( bi_ptr result, const bi_ptr i, const bi_ptr n) {
170 mpz_mul( result, i, n);
171 return result;
172 }
173
174 /* <result> := <i> + <n> */
bi_add_si(bi_ptr result,const bi_ptr i,const long n)175 INLINE_DECL bi_ptr bi_add_si( bi_ptr result, const bi_ptr i, const long n) {
176 mpz_add_ui( result, i, n);
177 return result;
178 }
179
180 /* <result> := <i> + <n> */
bi_add(bi_ptr result,const bi_ptr i,const bi_ptr n)181 INLINE_DECL bi_ptr bi_add( bi_ptr result, const bi_ptr i, const bi_ptr n) {
182 mpz_add( result, i, n);
183 return result;
184 }
185
186 /* <result> := <i> - <n> */
bi_sub_si(bi_ptr result,const bi_ptr i,const long n)187 INLINE_DECL bi_ptr bi_sub_si( bi_ptr result, const bi_ptr i, const long n) {
188 // n should be unsigned
189 mpz_sub_ui( result, i, n);
190 return result;
191 }
192
193 /* <result> := <i> - <n> */
bi_sub(bi_ptr result,const bi_ptr i,const bi_ptr n)194 INLINE_DECL bi_ptr bi_sub( bi_ptr result, const bi_ptr i, const bi_ptr n) {
195 mpz_sub( result, result, n);
196 return result;
197 }
198
199 /* <result> := ( <g> ^ <e> ) mod <m> */
bi_mod_exp(bi_ptr result,const bi_ptr g,const bi_ptr e,const bi_ptr m)200 INLINE_DECL bi_ptr bi_mod_exp( bi_ptr result, const bi_ptr g, const bi_ptr e, const bi_ptr m) {
201 mpz_powm( result, g, e, m);
202 return result;
203 }
204
205 /* <result> := ( <g> ^ <e> ) mod <m> */
bi_mod_exp_si(bi_ptr result,const bi_ptr g,const bi_ptr e,const long m)206 INLINE_DECL bi_ptr bi_mod_exp_si( bi_ptr result, const bi_ptr g, const bi_ptr e, const long m) {
207 mpz_t bi_m;
208
209 mpz_init( bi_m);
210 mpz_set_si( bi_m, m);
211 mpz_powm( result, g, e, bi_m);
212 mpz_clear( bi_m);
213 return result;
214 }
215
216 /***********************************************************************************
217 BITS OPERATION
218 *************************************************************************************/
219 /* set the bit to 1 */
bi_setbit(bi_ptr result,const int bit)220 INLINE_DECL bi_ptr bi_setbit(bi_ptr result, const int bit) {
221 mpz_setbit( result, bit);
222 return result;
223 }
224
225 /* <result> := <i> << <n> */
bi_shift_left(bi_ptr result,const bi_ptr i,const int n)226 INLINE_DECL bi_ptr bi_shift_left( bi_ptr result, const bi_ptr i, const int n) {
227 mpz_mul_2exp( result, i, n);
228 return result;
229 }
230
231 /* <result> := <i> >> <n> */
bi_shift_right(bi_ptr result,const bi_ptr i,const int n)232 INLINE_DECL bi_ptr bi_shift_right( bi_ptr result, const bi_ptr i, const int n) {
233 mpz_div_2exp( result, i, n);
234 return result;
235 }
236
237 /***********************************************************************************
238 COMPARAISON
239 *************************************************************************************/
240 /* n1<n2 return negative value
241 * n1 = n2 return 0
242 * n1>n2 return positive value
243 */
bi_cmp(const bi_ptr n1,const bi_ptr n2)244 INLINE_DECL int bi_cmp( const bi_ptr n1, const bi_ptr n2) {
245 return mpz_cmp( n1, n2);
246 }
247
248 /* n1<n2 return negative value
249 * n1 = n2 return 0
250 * n1>n2 return positive value
251 */
bi_cmp_si(const bi_ptr n1,const int n2)252 INLINE_DECL int bi_cmp_si( const bi_ptr n1, const int n2) {
253 return mpz_cmp_ui( n1, n2);
254 }
255
256 /* n1 == n2 return 1 (true)
257 * else return 0
258 */
bi_equals(const bi_ptr n1,const bi_ptr n2)259 INLINE_DECL int bi_equals( const bi_ptr n1, const bi_ptr n2) {
260 return mpz_cmp( n1, n2) == 0 ? 1 : 0;
261 }
262
263 /* n1 == n2 return 1 (true)
264 * else return 0
265 */
bi_equals_si(const bi_ptr n1,const int n2)266 INLINE_DECL int bi_equals_si( const bi_ptr n1, const int n2) {
267 return mpz_cmp_ui( n1, n2) == 0 ? 1 : 0;
268 }
269
270 /* create a random of length <length> bits */
271 /* res := random( length) */
bi_urandom(bi_ptr result,const long length)272 INLINE_DECL bi_ptr bi_urandom( bi_ptr result, const long length) {
273 mpz_urandomb( result, state, length);
274 return result;
275 }
276
277 /* res := <n> mod <m> */
bi_mod_si(bi_ptr result,const bi_ptr n,const long m)278 INLINE_DECL bi_ptr bi_mod_si( bi_ptr result, const bi_ptr n, const long m) {
279 mpz_mod_ui( result, n, m);
280 return result;
281 }
282
283 /* res := <n> mod <m> */
bi_mod(bi_ptr result,const bi_ptr n,const bi_ptr m)284 INLINE_DECL bi_ptr bi_mod( bi_ptr result, const bi_ptr n, const bi_ptr m) {
285 mpz_mod( result, n, m);
286 return result;
287 }
288
289 /* result := (inverse of <i>) mod <m> */
290 /* if the inverse exist, return >0, otherwise 0 */
bi_invert_mod(bi_ptr result,const bi_ptr i,const bi_ptr m)291 INLINE_DECL int bi_invert_mod( bi_ptr result, const bi_ptr i, const bi_ptr m) {
292 return mpz_invert( result, i, m);
293 }
294
295 #endif /*BI_GMP_*/
296