5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2005 - 2008 Pekka Riikonen
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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "silccrypto.h"
23 static void silc_mp_set_errno(int err)
25 if (err == TFM_FP_VAL)
26 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
27 else if (err == TFM_FP_MEM)
28 silc_set_errno(SILC_ERR_OUT_OF_MEMORY);
31 SilcBool silc_mp_init(SilcMPInt *mp)
37 SilcBool silc_mp_sinit(SilcStack stack, SilcMPInt *mp)
40 stack = silc_stack_alloc(0, stack);
41 tfm_fp_sinit(stack, mp);
45 void silc_mp_uninit(SilcMPInt *mp)
50 size_t silc_mp_size(SilcMPInt *mp)
52 return tfm_fp_unsigned_bin_size(mp);
55 size_t silc_mp_sizeinbase(SilcMPInt *mp, int base)
58 tfm_fp_radix_size(mp, base, &size);
64 SilcBool silc_mp_set(SilcMPInt *dst, SilcMPInt *src)
67 if ((ret = tfm_fp_copy(src, dst))) {
68 silc_mp_set_errno(ret);
74 SilcBool silc_mp_set_ui(SilcMPInt *dst, SilcUInt32 ui)
77 if ((ret = tfm_fp_set(dst, ui))) {
78 silc_mp_set_errno(ret);
84 SilcBool silc_mp_set_si(SilcMPInt *dst, SilcInt32 si)
87 if ((ret = tfm_fp_set(dst, si))) {
88 silc_mp_set_errno(ret);
94 SilcBool silc_mp_set_str(SilcMPInt *dst, const char *str, int base)
97 if ((ret = tfm_fp_read_radix(dst, (char *)str, base))) {
98 silc_mp_set_errno(ret);
104 SilcUInt32 silc_mp_get_ui(SilcMPInt *mp)
106 tfm_fp_int *tmp = mp;
107 return tmp->used > 0 ? tmp->dp[0] : 0;
110 char *silc_mp_get_str(char *str, SilcMPInt *mp, int base)
112 if (tfm_fp_toradix(mp, str, base) != TFM_FP_OKAY)
117 SilcBool silc_mp_add(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *mp2)
120 if ((ret = tfm_fp_add(mp1, mp2, dst))) {
121 silc_mp_set_errno(ret);
127 SilcBool silc_mp_add_ui(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 ui)
130 if ((ret = tfm_fp_add_d(mp1, (tfm_fp_digit)ui, dst))) {
131 silc_mp_set_errno(ret);
137 SilcBool silc_mp_sub(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *mp2)
140 if ((ret = tfm_fp_sub(mp1, mp2, dst))) {
141 silc_mp_set_errno(ret);
147 SilcBool silc_mp_sub_ui(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 ui)
150 if ((ret = tfm_fp_sub_d(mp1, (tfm_fp_digit)ui, dst))) {
151 silc_mp_set_errno(ret);
157 SilcBool silc_mp_mul(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *mp2)
160 if ((ret = tfm_fp_mul(mp1, mp2, dst))) {
161 silc_mp_set_errno(ret);
167 SilcBool silc_mp_mul_ui(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 ui)
170 if ((ret = tfm_fp_mul_d(mp1, (tfm_fp_digit)ui, dst))) {
171 silc_mp_set_errno(ret);
177 SilcBool silc_mp_mul_2exp(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 exp)
180 if ((ret = tfm_fp_mul_2d(mp1, exp, dst))) {
181 silc_mp_set_errno(ret);
187 SilcBool silc_mp_sqrt(SilcMPInt *dst, SilcMPInt *src)
190 if ((ret = tfm_fp_sqrt(src, dst))) {
191 silc_mp_set_errno(ret);
197 SilcBool silc_mp_div(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *mp2)
200 if ((ret = tfm_fp_div(mp1, mp2, dst, NULL))) {
201 silc_mp_set_errno(ret);
207 SilcBool silc_mp_div_ui(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 ui)
210 if ((ret = tfm_fp_div_d(mp1, (tfm_fp_digit)ui, dst, NULL))) {
211 silc_mp_set_errno(ret);
217 SilcBool silc_mp_div_qr(SilcMPInt *q, SilcMPInt *r, SilcMPInt *mp1,
221 if ((ret = tfm_fp_div(mp1, mp2, q, r))) {
222 silc_mp_set_errno(ret);
228 SilcBool silc_mp_div_2exp(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 exp)
231 if ((ret = tfm_fp_div_2d(mp1, exp, dst, NULL))) {
232 silc_mp_set_errno(ret);
238 SilcBool silc_mp_div_2exp_qr(SilcMPInt *q, SilcMPInt *r, SilcMPInt *mp1,
242 if ((ret = tfm_fp_div_2d(mp1, exp, q, r))) {
243 silc_mp_set_errno(ret);
249 SilcBool silc_mp_mod(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *mp2)
252 if ((ret = tfm_fp_mod(mp1, mp2, dst))) {
253 silc_mp_set_errno(ret);
259 SilcBool silc_mp_mod_ui(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 ui)
264 if ((ret = tfm_fp_mod_d(mp1, ui, &d))) {
265 silc_mp_set_errno(ret);
268 if ((ret = silc_mp_set_ui(dst, d))) {
269 silc_mp_set_errno(ret);
275 SilcBool silc_mp_mod_2exp(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 ui)
278 if ((ret = tfm_fp_mod_2d(mp1, ui, dst))) {
279 silc_mp_set_errno(ret);
285 SilcBool silc_mp_pow_ui(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 exp)
288 if ((ret = tfm_fp_expt_d(mp1, (tfm_fp_digit)exp, dst))) {
289 silc_mp_set_errno(ret);
295 SilcBool silc_mp_pow_mod(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *exp,
299 if ((ret = tfm_fp_exptmod(mp1, exp, mod, dst))) {
300 silc_mp_set_errno(ret);
306 SilcBool silc_mp_pow_mod_ui(SilcMPInt *dst, SilcMPInt *mp1, SilcUInt32 exp,
312 if ((ret = silc_mp_init(&tmp))) {
313 silc_mp_set_errno(ret);
316 if ((ret = silc_mp_set_ui(&tmp, exp))) {
317 silc_mp_set_errno(ret);
320 if ((ret = silc_mp_pow_mod(dst, mp1, &tmp, mod))) {
321 silc_mp_set_errno(ret);
324 silc_mp_uninit(&tmp);
328 SilcBool silc_mp_gcd(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *mp2)
331 if ((ret = tfm_fp_gcd(mp1, mp2, dst))) {
332 silc_mp_set_errno(ret);
338 int silc_mp_cmp(SilcMPInt *mp1, SilcMPInt *mp2)
340 return tfm_fp_cmp(mp1, mp2);
343 int silc_mp_cmp_si(SilcMPInt *mp1, SilcInt32 si)
345 return tfm_fp_cmp_d(mp1, si);
348 int silc_mp_cmp_ui(SilcMPInt *mp1, SilcUInt32 ui)
350 return tfm_fp_cmp_d(mp1, ui);
353 SilcBool silc_mp_abs(SilcMPInt *dst, SilcMPInt *src)
355 tfm_fp_abs(src, dst);
359 SilcBool silc_mp_neg(SilcMPInt *dst, SilcMPInt *src)
361 tfm_fp_neg(src, dst);
365 SilcBool silc_mp_and(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *mp2)
368 if ((ret = tfm_fp_and(mp1, mp2, dst))) {
369 silc_mp_set_errno(ret);
375 SilcBool silc_mp_or(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *mp2)
378 if ((ret = tfm_fp_or(mp1, mp2, dst))) {
379 silc_mp_set_errno(ret);
385 SilcBool silc_mp_xor(SilcMPInt *dst, SilcMPInt *mp1, SilcMPInt *mp2)
388 if ((ret = tfm_fp_xor(mp1, mp2, dst))) {
389 silc_mp_set_errno(ret);
395 SilcBool silc_mp_modinv(SilcMPInt *inv, SilcMPInt *a, SilcMPInt *n)
398 if ((ret = tfm_fp_invmod(a, n, inv))) {
399 silc_mp_set_errno(ret);