src/protocols/sametime/meanwhile/mpi/mpi.c

Fri, 20 Jan 2006 00:19:53 +0000

author
Ethan Blanton <elb@pidgin.im>
date
Fri, 20 Jan 2006 00:19:53 +0000
changeset 12956
39a4efae983c
parent 12261
672e2d392a73
permissions
-rw-r--r--

[gaim-migrate @ 15309]
Add .cvsignore actions to meanwhile so cvs shuts up about it.

12261
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2 mpi.c
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
4 by Michael J. Fromberger <http://www.dartmouth.edu/~sting/>
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
5 Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
6
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
7 Arbitrary precision integer arithmetic library
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
8
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
9 $Id: mpi.c 14563 2005-11-29 23:31:40Z taliesein $
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
10 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
11
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
12 #include "mpi.h"
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
13 #include <stdlib.h>
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
14 #include <string.h>
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
15 #include <ctype.h>
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
16
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
17 #if MP_DEBUG
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
18 #include <stdio.h>
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
19
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
20 #define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
21 #else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
22 #define DIAG(T,V)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
23 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
24
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
25 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
26 If MP_LOGTAB is not defined, use the math library to compute the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
27 logarithms on the fly. Otherwise, use the static table below.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
28 Pick which works best for your system.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
29 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
30 #if MP_LOGTAB
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
31
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
32 /* {{{ s_logv_2[] - log table for 2 in various bases */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
33
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
34 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
35 A table of the logs of 2 for various bases (the 0 and 1 entries of
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
36 this table are meaningless and should not be referenced).
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
37
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
38 This table is used to compute output lengths for the mp_toradix()
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
39 function. Since a number n in radix r takes up about log_r(n)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
40 digits, we estimate the output size by taking the least integer
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
41 greater than log_r(n), where:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
42
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
43 log_r(n) = log_2(n) * log_r(2)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
44
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
45 This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
46 which are the output bases supported.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
47 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
48
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
49 #include "logtab.h"
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
50
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
51 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
52 #define LOG_V_2(R) s_logv_2[(R)]
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
53
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
54 #else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
55
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
56 #include <math.h>
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
57 #define LOG_V_2(R) (log(2.0)/log(R))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
58
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
59 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
60
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
61 /* Default precision for newly created mp_int's */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
62 static unsigned int s_mp_defprec = MP_DEFPREC;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
63
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
64 /* {{{ Digit arithmetic macros */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
65
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
66 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
67 When adding and multiplying digits, the results can be larger than
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
68 can be contained in an mp_digit. Thus, an mp_word is used. These
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
69 macros mask off the upper and lower digits of the mp_word (the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
70 mp_word may be more than 2 mp_digits wide, but we only concern
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
71 ourselves with the low-order 2 mp_digits)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
72
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
73 If your mp_word DOES have more than 2 mp_digits, you need to
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
74 uncomment the first line, and comment out the second.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
75 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
76
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
77 /* #define CARRYOUT(W) (((W)>>DIGIT_BIT)&MP_DIGIT_MAX) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
78 #define CARRYOUT(W) ((W)>>DIGIT_BIT)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
79 #define ACCUM(W) ((W)&MP_DIGIT_MAX)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
80
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
81 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
82
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
83 /* {{{ Comparison constants */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
84
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
85 #define MP_LT -1
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
86 #define MP_EQ 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
87 #define MP_GT 1
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
88
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
89 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
90
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
91 /* {{{ Constant strings */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
92
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
93 /* Constant strings returned by mp_strerror() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
94 static const char *mp_err_string[] = {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
95 "unknown result code", /* say what? */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
96 "boolean true", /* MP_OKAY, MP_YES */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
97 "boolean false", /* MP_NO */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
98 "out of memory", /* MP_MEM */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
99 "argument out of range", /* MP_RANGE */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
100 "invalid input parameter", /* MP_BADARG */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
101 "result is undefined" /* MP_UNDEF */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
102 };
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
103
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
104 /* Value to digit maps for radix conversion */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
105
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
106 /* s_dmap_1 - standard digits and letters */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
107 static const char *s_dmap_1 =
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
108 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
109
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
110 #if 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
111 /* s_dmap_2 - base64 ordering for digits */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
112 static const char *s_dmap_2 =
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
113 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
114 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
115
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
116 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
117
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
118 /* {{{ Static function declarations */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
119
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
120 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
121 If MP_MACRO is false, these will be defined as actual functions;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
122 otherwise, suitable macro definitions will be used. This works
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
123 around the fact that ANSI C89 doesn't support an 'inline' keyword
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
124 (although I hear C9x will ... about bloody time). At present, the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
125 macro definitions are identical to the function bodies, but they'll
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
126 expand in place, instead of generating a function call.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
127
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
128 I chose these particular functions to be made into macros because
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
129 some profiling showed they are called a lot on a typical workload,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
130 and yet they are primarily housekeeping.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
131 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
132 #if MP_MACRO == 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
133 void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
134 void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count); /* copy */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
135 void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
136 void s_mp_free(void *ptr); /* general free function */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
137 #else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
138
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
139 /* Even if these are defined as macros, we need to respect the settings
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
140 of the MP_MEMSET and MP_MEMCPY configuration options...
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
141 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
142 #if MP_MEMSET == 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
143 #define s_mp_setz(dp, count) \
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
144 {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;}
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
145 #else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
146 #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
147 #endif /* MP_MEMSET */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
148
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
149 #if MP_MEMCPY == 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
150 #define s_mp_copy(sp, dp, count) \
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
151 {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];}
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
152 #else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
153 #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
154 #endif /* MP_MEMCPY */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
155
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
156 #define s_mp_alloc(nb, ni) calloc(nb, ni)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
157 #define s_mp_free(ptr) {if(ptr) free(ptr);}
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
158 #endif /* MP_MACRO */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
159
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
160 mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
161 mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
162
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
163 void s_mp_clamp(mp_int *mp); /* clip leading zeroes */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
164
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
165 void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
166
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
167 mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
168 void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
169 void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
170 void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
171 mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
172 void s_mp_div_2(mp_int *mp); /* divide by 2 in place */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
173 mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
174 mp_digit s_mp_norm(mp_int *a, mp_int *b); /* normalize for division */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
175 mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
176 mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
177 mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
178 mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
179 /* unsigned digit divide */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
180 mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
181 /* Barrett reduction */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
182 mp_err s_mp_add(mp_int *a, mp_int *b); /* magnitude addition */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
183 mp_err s_mp_sub(mp_int *a, mp_int *b); /* magnitude subtract */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
184 mp_err s_mp_mul(mp_int *a, mp_int *b); /* magnitude multiply */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
185 #if 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
186 void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
187 /* multiply buffers in place */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
188 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
189 #if MP_SQUARE
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
190 mp_err s_mp_sqr(mp_int *a); /* magnitude square */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
191 #else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
192 #define s_mp_sqr(a) s_mp_mul(a, a)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
193 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
194 mp_err s_mp_div(mp_int *a, mp_int *b); /* magnitude divide */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
195 mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
196 int s_mp_cmp(mp_int *a, mp_int *b); /* magnitude comparison */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
197 int s_mp_cmp_d(mp_int *a, mp_digit d); /* magnitude digit compare */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
198 int s_mp_ispow2(mp_int *v); /* is v a power of 2? */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
199 int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
200
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
201 int s_mp_tovalue(char ch, int r); /* convert ch to value */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
202 char s_mp_todigit(int val, int r, int low); /* convert val to digit */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
203 int s_mp_outlen(int bits, int r); /* output length in bytes */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
204
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
205 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
206
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
207 /* {{{ Default precision manipulation */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
208
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
209 unsigned int mp_get_prec(void)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
210 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
211 return s_mp_defprec;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
212
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
213 } /* end mp_get_prec() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
214
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
215 void mp_set_prec(unsigned int prec)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
216 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
217 if(prec == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
218 s_mp_defprec = MP_DEFPREC;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
219 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
220 s_mp_defprec = prec;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
221
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
222 } /* end mp_set_prec() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
223
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
224 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
225
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
226 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
227 /* {{{ mp_init(mp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
228
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
229 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
230 mp_init(mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
231
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
232 Initialize a new zero-valued mp_int. Returns MP_OKAY if successful,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
233 MP_MEM if memory could not be allocated for the structure.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
234 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
235
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
236 mp_err mp_init(mp_int *mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
237 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
238 return mp_init_size(mp, s_mp_defprec);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
239
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
240 } /* end mp_init() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
241
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
242 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
243
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
244 /* {{{ mp_init_array(mp[], count) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
245
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
246 mp_err mp_init_array(mp_int mp[], int count)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
247 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
248 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
249 int pos;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
250
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
251 ARGCHK(mp !=NULL && count > 0, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
252
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
253 for(pos = 0; pos < count; ++pos) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
254 if((res = mp_init(&mp[pos])) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
255 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
256 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
257
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
258 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
259
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
260 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
261 while(--pos >= 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
262 mp_clear(&mp[pos]);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
263
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
264 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
265
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
266 } /* end mp_init_array() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
267
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
268 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
269
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
270 /* {{{ mp_init_size(mp, prec) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
271
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
272 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
273 mp_init_size(mp, prec)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
274
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
275 Initialize a new zero-valued mp_int with at least the given
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
276 precision; returns MP_OKAY if successful, or MP_MEM if memory could
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
277 not be allocated for the structure.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
278 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
279
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
280 mp_err mp_init_size(mp_int *mp, mp_size prec)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
281 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
282 ARGCHK(mp != NULL && prec > 0, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
283
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
284 if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
285 return MP_MEM;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
286
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
287 SIGN(mp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
288 USED(mp) = 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
289 ALLOC(mp) = prec;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
290
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
291 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
292
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
293 } /* end mp_init_size() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
294
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
295 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
296
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
297 /* {{{ mp_init_copy(mp, from) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
298
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
299 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
300 mp_init_copy(mp, from)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
301
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
302 Initialize mp as an exact copy of from. Returns MP_OKAY if
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
303 successful, MP_MEM if memory could not be allocated for the new
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
304 structure.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
305 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
306
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
307 mp_err mp_init_copy(mp_int *mp, mp_int *from)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
308 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
309 ARGCHK(mp != NULL && from != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
310
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
311 if(mp == from)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
312 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
313
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
314 if((DIGITS(mp) = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
315 return MP_MEM;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
316
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
317 s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
318 USED(mp) = USED(from);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
319 ALLOC(mp) = USED(from);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
320 SIGN(mp) = SIGN(from);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
321
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
322 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
323
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
324 } /* end mp_init_copy() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
325
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
326 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
327
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
328 /* {{{ mp_copy(from, to) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
329
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
330 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
331 mp_copy(from, to)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
332
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
333 Copies the mp_int 'from' to the mp_int 'to'. It is presumed that
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
334 'to' has already been initialized (if not, use mp_init_copy()
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
335 instead). If 'from' and 'to' are identical, nothing happens.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
336 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
337
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
338 mp_err mp_copy(mp_int *from, mp_int *to)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
339 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
340 ARGCHK(from != NULL && to != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
341
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
342 if(from == to)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
343 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
344
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
345 { /* copy */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
346 mp_digit *tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
347
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
348 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
349 If the allocated buffer in 'to' already has enough space to hold
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
350 all the used digits of 'from', we'll re-use it to avoid hitting
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
351 the memory allocater more than necessary; otherwise, we'd have
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
352 to grow anyway, so we just allocate a hunk and make the copy as
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
353 usual
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
354 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
355 if(ALLOC(to) >= USED(from)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
356 s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
357 s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
358
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
359 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
360 if((tmp = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
361 return MP_MEM;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
362
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
363 s_mp_copy(DIGITS(from), tmp, USED(from));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
364
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
365 if(DIGITS(to) != NULL) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
366 #if MP_CRYPTO
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
367 s_mp_setz(DIGITS(to), ALLOC(to));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
368 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
369 s_mp_free(DIGITS(to));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
370 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
371
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
372 DIGITS(to) = tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
373 ALLOC(to) = USED(from);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
374 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
375
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
376 /* Copy the precision and sign from the original */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
377 USED(to) = USED(from);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
378 SIGN(to) = SIGN(from);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
379 } /* end copy */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
380
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
381 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
382
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
383 } /* end mp_copy() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
384
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
385 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
386
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
387 /* {{{ mp_exch(mp1, mp2) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
388
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
389 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
390 mp_exch(mp1, mp2)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
391
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
392 Exchange mp1 and mp2 without allocating any intermediate memory
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
393 (well, unless you count the stack space needed for this call and the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
394 locals it creates...). This cannot fail.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
395 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
396
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
397 void mp_exch(mp_int *mp1, mp_int *mp2)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
398 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
399 #if MP_ARGCHK == 2
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
400 assert(mp1 != NULL && mp2 != NULL);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
401 #else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
402 if(mp1 == NULL || mp2 == NULL)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
403 return;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
404 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
405
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
406 s_mp_exch(mp1, mp2);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
407
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
408 } /* end mp_exch() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
409
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
410 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
411
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
412 /* {{{ mp_clear(mp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
413
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
414 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
415 mp_clear(mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
416
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
417 Release the storage used by an mp_int, and void its fields so that
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
418 if someone calls mp_clear() again for the same int later, we won't
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
419 get tollchocked.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
420 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
421
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
422 void mp_clear(mp_int *mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
423 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
424 if(mp == NULL)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
425 return;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
426
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
427 if(DIGITS(mp) != NULL) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
428 #if MP_CRYPTO
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
429 s_mp_setz(DIGITS(mp), ALLOC(mp));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
430 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
431 s_mp_free(DIGITS(mp));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
432 DIGITS(mp) = NULL;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
433 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
434
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
435 USED(mp) = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
436 ALLOC(mp) = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
437
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
438 } /* end mp_clear() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
439
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
440 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
441
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
442 /* {{{ mp_clear_array(mp[], count) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
443
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
444 void mp_clear_array(mp_int mp[], int count)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
445 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
446 ARGCHK(mp != NULL && count > 0, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
447
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
448 while(--count >= 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
449 mp_clear(&mp[count]);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
450
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
451 } /* end mp_clear_array() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
452
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
453 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
454
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
455 /* {{{ mp_zero(mp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
456
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
457 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
458 mp_zero(mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
459
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
460 Set mp to zero. Does not change the allocated size of the structure,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
461 and therefore cannot fail (except on a bad argument, which we ignore)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
462 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
463 void mp_zero(mp_int *mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
464 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
465 if(mp == NULL)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
466 return;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
467
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
468 s_mp_setz(DIGITS(mp), ALLOC(mp));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
469 USED(mp) = 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
470 SIGN(mp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
471
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
472 } /* end mp_zero() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
473
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
474 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
475
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
476 /* {{{ mp_set(mp, d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
477
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
478 void mp_set(mp_int *mp, mp_digit d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
479 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
480 if(mp == NULL)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
481 return;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
482
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
483 mp_zero(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
484 DIGIT(mp, 0) = d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
485
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
486 } /* end mp_set() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
487
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
488 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
489
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
490 /* {{{ mp_set_int(mp, z) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
491
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
492 mp_err mp_set_int(mp_int *mp, long z)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
493 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
494 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
495 unsigned long v = abs(z);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
496 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
497
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
498 ARGCHK(mp != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
499
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
500 mp_zero(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
501 if(z == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
502 return MP_OKAY; /* shortcut for zero */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
503
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
504 for(ix = sizeof(long) - 1; ix >= 0; ix--) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
505
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
506 if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
507 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
508
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
509 res = s_mp_add_d(mp,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
510 (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
511 if(res != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
512 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
513
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
514 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
515
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
516 if(z < 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
517 SIGN(mp) = MP_NEG;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
518
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
519 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
520
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
521 } /* end mp_set_int() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
522
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
523 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
524
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
525 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
526 /* {{{ Digit arithmetic */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
527
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
528 /* {{{ mp_add_d(a, d, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
529
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
530 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
531 mp_add_d(a, d, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
532
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
533 Compute the sum b = a + d, for a single digit d. Respects the sign of
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
534 its primary addend (single digits are unsigned anyway).
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
535 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
536
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
537 mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
538 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
539 mp_err res = MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
540
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
541 ARGCHK(a != NULL && b != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
542
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
543 if((res = mp_copy(a, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
544 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
545
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
546 if(SIGN(b) == MP_ZPOS) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
547 res = s_mp_add_d(b, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
548 } else if(s_mp_cmp_d(b, d) >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
549 res = s_mp_sub_d(b, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
550 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
551 SIGN(b) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
552
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
553 DIGIT(b, 0) = d - DIGIT(b, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
554 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
555
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
556 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
557
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
558 } /* end mp_add_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
559
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
560 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
561
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
562 /* {{{ mp_sub_d(a, d, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
563
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
564 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
565 mp_sub_d(a, d, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
566
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
567 Compute the difference b = a - d, for a single digit d. Respects the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
568 sign of its subtrahend (single digits are unsigned anyway).
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
569 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
570
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
571 mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
572 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
573 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
574
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
575 ARGCHK(a != NULL && b != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
576
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
577 if((res = mp_copy(a, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
578 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
579
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
580 if(SIGN(b) == MP_NEG) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
581 if((res = s_mp_add_d(b, d)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
582 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
583
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
584 } else if(s_mp_cmp_d(b, d) >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
585 if((res = s_mp_sub_d(b, d)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
586 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
587
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
588 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
589 mp_neg(b, b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
590
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
591 DIGIT(b, 0) = d - DIGIT(b, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
592 SIGN(b) = MP_NEG;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
593 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
594
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
595 if(s_mp_cmp_d(b, 0) == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
596 SIGN(b) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
597
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
598 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
599
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
600 } /* end mp_sub_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
601
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
602 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
603
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
604 /* {{{ mp_mul_d(a, d, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
605
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
606 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
607 mp_mul_d(a, d, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
608
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
609 Compute the product b = a * d, for a single digit d. Respects the sign
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
610 of its multiplicand (single digits are unsigned anyway)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
611 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
612
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
613 mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
614 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
615 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
616
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
617 ARGCHK(a != NULL && b != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
618
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
619 if(d == 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
620 mp_zero(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
621 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
622 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
623
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
624 if((res = mp_copy(a, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
625 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
626
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
627 res = s_mp_mul_d(b, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
628
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
629 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
630
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
631 } /* end mp_mul_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
632
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
633 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
634
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
635 /* {{{ mp_mul_2(a, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
636
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
637 mp_err mp_mul_2(mp_int *a, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
638 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
639 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
640
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
641 ARGCHK(a != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
642
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
643 if((res = mp_copy(a, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
644 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
645
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
646 return s_mp_mul_2(c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
647
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
648 } /* end mp_mul_2() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
649
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
650 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
651
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
652 /* {{{ mp_div_d(a, d, q, r) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
653
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
654 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
655 mp_div_d(a, d, q, r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
656
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
657 Compute the quotient q = a / d and remainder r = a mod d, for a
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
658 single digit d. Respects the sign of its divisor (single digits are
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
659 unsigned anyway).
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
660 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
661
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
662 mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
663 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
664 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
665 mp_digit rem;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
666 int pow;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
667
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
668 ARGCHK(a != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
669
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
670 if(d == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
671 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
672
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
673 /* Shortcut for powers of two ... */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
674 if((pow = s_mp_ispow2d(d)) >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
675 mp_digit mask;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
676
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
677 mask = (1 << pow) - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
678 rem = DIGIT(a, 0) & mask;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
679
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
680 if(q) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
681 mp_copy(a, q);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
682 s_mp_div_2d(q, pow);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
683 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
684
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
685 if(r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
686 *r = rem;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
687
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
688 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
689 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
690
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
691 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
692 If the quotient is actually going to be returned, we'll try to
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
693 avoid hitting the memory allocator by copying the dividend into it
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
694 and doing the division there. This can't be any _worse_ than
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
695 always copying, and will sometimes be better (since it won't make
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
696 another copy)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
697
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
698 If it's not going to be returned, we need to allocate a temporary
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
699 to hold the quotient, which will just be discarded.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
700 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
701 if(q) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
702 if((res = mp_copy(a, q)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
703 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
704
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
705 res = s_mp_div_d(q, d, &rem);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
706 if(s_mp_cmp_d(q, 0) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
707 SIGN(q) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
708
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
709 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
710 mp_int qp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
711
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
712 if((res = mp_init_copy(&qp, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
713 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
714
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
715 res = s_mp_div_d(&qp, d, &rem);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
716 if(s_mp_cmp_d(&qp, 0) == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
717 SIGN(&qp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
718
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
719 mp_clear(&qp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
720 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
721
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
722 if(r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
723 *r = rem;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
724
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
725 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
726
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
727 } /* end mp_div_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
728
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
729 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
730
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
731 /* {{{ mp_div_2(a, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
732
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
733 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
734 mp_div_2(a, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
735
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
736 Compute c = a / 2, disregarding the remainder.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
737 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
738
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
739 mp_err mp_div_2(mp_int *a, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
740 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
741 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
742
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
743 ARGCHK(a != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
744
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
745 if((res = mp_copy(a, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
746 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
747
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
748 s_mp_div_2(c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
749
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
750 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
751
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
752 } /* end mp_div_2() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
753
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
754 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
755
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
756 /* {{{ mp_expt_d(a, d, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
757
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
758 mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
759 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
760 mp_int s, x;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
761 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
762 mp_sign cs = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
763
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
764 ARGCHK(a != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
765
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
766 if((res = mp_init(&s)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
767 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
768 if((res = mp_init_copy(&x, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
769 goto X;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
770
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
771 DIGIT(&s, 0) = 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
772
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
773 if((d % 2) == 1)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
774 cs = SIGN(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
775
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
776 while(d != 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
777 if(d & 1) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
778 if((res = s_mp_mul(&s, &x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
779 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
780 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
781
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
782 d >>= 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
783
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
784 if((res = s_mp_sqr(&x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
785 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
786 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
787
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
788 SIGN(&s) = cs;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
789
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
790 s_mp_exch(&s, c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
791
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
792 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
793 mp_clear(&x);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
794 X:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
795 mp_clear(&s);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
796
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
797 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
798
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
799 } /* end mp_expt_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
800
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
801 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
802
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
803 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
804
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
805 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
806 /* {{{ Full arithmetic */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
807
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
808 /* {{{ mp_abs(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
809
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
810 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
811 mp_abs(a, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
812
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
813 Compute b = |a|. 'a' and 'b' may be identical.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
814 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
815
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
816 mp_err mp_abs(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
817 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
818 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
819
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
820 ARGCHK(a != NULL && b != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
821
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
822 if((res = mp_copy(a, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
823 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
824
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
825 SIGN(b) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
826
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
827 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
828
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
829 } /* end mp_abs() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
830
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
831 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
832
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
833 /* {{{ mp_neg(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
834
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
835 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
836 mp_neg(a, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
837
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
838 Compute b = -a. 'a' and 'b' may be identical.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
839 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
840
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
841 mp_err mp_neg(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
842 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
843 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
844
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
845 ARGCHK(a != NULL && b != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
846
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
847 if((res = mp_copy(a, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
848 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
849
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
850 if(s_mp_cmp_d(b, 0) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
851 SIGN(b) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
852 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
853 SIGN(b) = (SIGN(b) == MP_NEG) ? MP_ZPOS : MP_NEG;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
854
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
855 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
856
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
857 } /* end mp_neg() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
858
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
859 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
860
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
861 /* {{{ mp_add(a, b, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
862
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
863 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
864 mp_add(a, b, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
865
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
866 Compute c = a + b. All parameters may be identical.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
867 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
868
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
869 mp_err mp_add(mp_int *a, mp_int *b, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
870 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
871 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
872 int cmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
873
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
874 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
875
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
876 if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
877
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
878 /* Commutativity of addition lets us do this in either order,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
879 so we avoid having to use a temporary even if the result
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
880 is supposed to replace the output
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
881 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
882 if(c == b) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
883 if((res = s_mp_add(c, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
884 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
885 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
886 if(c != a && (res = mp_copy(a, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
887 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
888
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
889 if((res = s_mp_add(c, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
890 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
891 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
892
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
893 } else if((cmp = s_mp_cmp(a, b)) > 0) { /* different sign: a > b */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
894
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
895 /* If the output is going to be clobbered, we will use a temporary
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
896 variable; otherwise, we'll do it without touching the memory
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
897 allocator at all, if possible
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
898 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
899 if(c == b) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
900 mp_int tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
901
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
902 if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
903 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
904 if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
905 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
906 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
907 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
908
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
909 s_mp_exch(&tmp, c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
910 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
911
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
912 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
913
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
914 if(c != a && (res = mp_copy(a, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
915 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
916 if((res = s_mp_sub(c, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
917 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
918
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
919 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
920
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
921 } else if(cmp == 0) { /* different sign, a == b */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
922
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
923 mp_zero(c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
924 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
925
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
926 } else { /* different sign: a < b */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
927
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
928 /* See above... */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
929 if(c == a) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
930 mp_int tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
931
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
932 if((res = mp_init_copy(&tmp, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
933 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
934 if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
935 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
936 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
937 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
938
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
939 s_mp_exch(&tmp, c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
940 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
941
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
942 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
943
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
944 if(c != b && (res = mp_copy(b, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
945 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
946 if((res = s_mp_sub(c, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
947 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
948
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
949 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
950 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
951
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
952 if(USED(c) == 1 && DIGIT(c, 0) == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
953 SIGN(c) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
954
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
955 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
956
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
957 } /* end mp_add() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
958
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
959 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
960
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
961 /* {{{ mp_sub(a, b, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
962
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
963 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
964 mp_sub(a, b, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
965
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
966 Compute c = a - b. All parameters may be identical.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
967 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
968
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
969 mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
970 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
971 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
972 int cmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
973
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
974 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
975
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
976 if(SIGN(a) != SIGN(b)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
977 if(c == a) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
978 if((res = s_mp_add(c, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
979 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
980 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
981 if(c != b && ((res = mp_copy(b, c)) != MP_OKAY))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
982 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
983 if((res = s_mp_add(c, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
984 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
985 SIGN(c) = SIGN(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
986 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
987
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
988 } else if((cmp = s_mp_cmp(a, b)) > 0) { /* Same sign, a > b */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
989 if(c == b) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
990 mp_int tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
991
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
992 if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
993 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
994 if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
995 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
996 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
997 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
998 s_mp_exch(&tmp, c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
999 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1000
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1001 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1002 if(c != a && ((res = mp_copy(a, c)) != MP_OKAY))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1003 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1004
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1005 if((res = s_mp_sub(c, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1006 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1007 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1008
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1009 } else if(cmp == 0) { /* Same sign, equal magnitude */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1010 mp_zero(c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1011 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1012
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1013 } else { /* Same sign, b > a */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1014 if(c == a) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1015 mp_int tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1016
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1017 if((res = mp_init_copy(&tmp, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1018 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1019
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1020 if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1021 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1022 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1023 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1024 s_mp_exch(&tmp, c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1025 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1026
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1027 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1028 if(c != b && ((res = mp_copy(b, c)) != MP_OKAY))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1029 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1030
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1031 if((res = s_mp_sub(c, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1032 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1033 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1034
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1035 SIGN(c) = !SIGN(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1036 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1037
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1038 if(USED(c) == 1 && DIGIT(c, 0) == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1039 SIGN(c) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1040
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1041 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1042
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1043 } /* end mp_sub() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1044
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1045 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1046
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1047 /* {{{ mp_mul(a, b, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1048
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1049 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1050 mp_mul(a, b, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1051
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1052 Compute c = a * b. All parameters may be identical.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1053 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1054
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1055 mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1056 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1057 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1058 mp_sign sgn;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1059
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1060 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1061
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1062 sgn = (SIGN(a) == SIGN(b)) ? MP_ZPOS : MP_NEG;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1063
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1064 if(c == b) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1065 if((res = s_mp_mul(c, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1066 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1067
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1068 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1069 if((res = mp_copy(a, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1070 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1071
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1072 if((res = s_mp_mul(c, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1073 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1074 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1075
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1076 if(sgn == MP_ZPOS || s_mp_cmp_d(c, 0) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1077 SIGN(c) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1078 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1079 SIGN(c) = sgn;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1080
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1081 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1082
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1083 } /* end mp_mul() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1084
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1085 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1086
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1087 /* {{{ mp_mul_2d(a, d, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1088
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1089 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1090 mp_mul_2d(a, d, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1091
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1092 Compute c = a * 2^d. a may be the same as c.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1093 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1094
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1095 mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1096 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1097 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1098
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1099 ARGCHK(a != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1100
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1101 if((res = mp_copy(a, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1102 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1103
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1104 if(d == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1105 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1106
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1107 return s_mp_mul_2d(c, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1108
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1109 } /* end mp_mul() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1110
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1111 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1112
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1113 /* {{{ mp_sqr(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1114
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1115 #if MP_SQUARE
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1116 mp_err mp_sqr(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1117 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1118 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1119
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1120 ARGCHK(a != NULL && b != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1121
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1122 if((res = mp_copy(a, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1123 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1124
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1125 if((res = s_mp_sqr(b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1126 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1127
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1128 SIGN(b) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1129
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1130 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1131
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1132 } /* end mp_sqr() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1133 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1134
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1135 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1136
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1137 /* {{{ mp_div(a, b, q, r) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1138
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1139 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1140 mp_div(a, b, q, r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1141
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1142 Compute q = a / b and r = a mod b. Input parameters may be re-used
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1143 as output parameters. If q or r is NULL, that portion of the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1144 computation will be discarded (although it will still be computed)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1145
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1146 Pay no attention to the hacker behind the curtain.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1147 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1148
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1149 mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1150 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1151 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1152 mp_int qtmp, rtmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1153 int cmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1154
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1155 ARGCHK(a != NULL && b != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1156
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1157 if(mp_cmp_z(b) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1158 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1159
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1160 /* If a <= b, we can compute the solution without division, and
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1161 avoid any memory allocation
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1162 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1163 if((cmp = s_mp_cmp(a, b)) < 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1164 if(r) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1165 if((res = mp_copy(a, r)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1166 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1167 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1168
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1169 if(q)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1170 mp_zero(q);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1171
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1172 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1173
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1174 } else if(cmp == 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1175
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1176 /* Set quotient to 1, with appropriate sign */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1177 if(q) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1178 int qneg = (SIGN(a) != SIGN(b));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1179
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1180 mp_set(q, 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1181 if(qneg)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1182 SIGN(q) = MP_NEG;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1183 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1184
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1185 if(r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1186 mp_zero(r);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1187
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1188 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1189 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1190
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1191 /* If we get here, it means we actually have to do some division */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1192
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1193 /* Set up some temporaries... */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1194 if((res = mp_init_copy(&qtmp, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1195 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1196 if((res = mp_init_copy(&rtmp, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1197 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1198
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1199 if((res = s_mp_div(&qtmp, &rtmp)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1200 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1201
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1202 /* Compute the signs for the output */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1203 SIGN(&rtmp) = SIGN(a); /* Sr = Sa */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1204 if(SIGN(a) == SIGN(b))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1205 SIGN(&qtmp) = MP_ZPOS; /* Sq = MP_ZPOS if Sa = Sb */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1206 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1207 SIGN(&qtmp) = MP_NEG; /* Sq = MP_NEG if Sa != Sb */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1208
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1209 if(s_mp_cmp_d(&qtmp, 0) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1210 SIGN(&qtmp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1211 if(s_mp_cmp_d(&rtmp, 0) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1212 SIGN(&rtmp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1213
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1214 /* Copy output, if it is needed */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1215 if(q)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1216 s_mp_exch(&qtmp, q);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1217
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1218 if(r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1219 s_mp_exch(&rtmp, r);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1220
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1221 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1222 mp_clear(&rtmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1223 mp_clear(&qtmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1224
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1225 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1226
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1227 } /* end mp_div() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1228
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1229 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1230
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1231 /* {{{ mp_div_2d(a, d, q, r) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1232
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1233 mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1234 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1235 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1236
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1237 ARGCHK(a != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1238
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1239 if(q) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1240 if((res = mp_copy(a, q)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1241 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1242
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1243 s_mp_div_2d(q, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1244 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1245
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1246 if(r) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1247 if((res = mp_copy(a, r)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1248 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1249
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1250 s_mp_mod_2d(r, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1251 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1252
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1253 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1254
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1255 } /* end mp_div_2d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1256
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1257 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1258
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1259 /* {{{ mp_expt(a, b, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1260
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1261 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1262 mp_expt(a, b, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1263
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1264 Compute c = a ** b, that is, raise a to the b power. Uses a
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1265 standard iterative square-and-multiply technique.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1266 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1267
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1268 mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1269 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1270 mp_int s, x;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1271 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1272 mp_digit d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1273 int dig, bit;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1274
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1275 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1276
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1277 if(mp_cmp_z(b) < 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1278 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1279
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1280 if((res = mp_init(&s)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1281 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1282
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1283 mp_set(&s, 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1284
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1285 if((res = mp_init_copy(&x, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1286 goto X;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1287
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1288 /* Loop over low-order digits in ascending order */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1289 for(dig = 0; dig < (USED(b) - 1); dig++) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1290 d = DIGIT(b, dig);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1291
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1292 /* Loop over bits of each non-maximal digit */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1293 for(bit = 0; bit < DIGIT_BIT; bit++) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1294 if(d & 1) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1295 if((res = s_mp_mul(&s, &x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1296 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1297 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1298
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1299 d >>= 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1300
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1301 if((res = s_mp_sqr(&x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1302 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1303 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1304 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1305
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1306 /* Consider now the last digit... */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1307 d = DIGIT(b, dig);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1308
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1309 while(d) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1310 if(d & 1) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1311 if((res = s_mp_mul(&s, &x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1312 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1313 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1314
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1315 d >>= 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1316
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1317 if((res = s_mp_sqr(&x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1318 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1319 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1320
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1321 if(mp_iseven(b))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1322 SIGN(&s) = SIGN(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1323
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1324 res = mp_copy(&s, c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1325
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1326 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1327 mp_clear(&x);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1328 X:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1329 mp_clear(&s);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1330
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1331 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1332
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1333 } /* end mp_expt() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1334
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1335 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1336
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1337 /* {{{ mp_2expt(a, k) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1338
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1339 /* Compute a = 2^k */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1340
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1341 mp_err mp_2expt(mp_int *a, mp_digit k)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1342 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1343 ARGCHK(a != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1344
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1345 return s_mp_2expt(a, k);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1346
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1347 } /* end mp_2expt() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1348
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1349 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1350
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1351 /* {{{ mp_mod(a, m, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1352
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1353 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1354 mp_mod(a, m, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1355
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1356 Compute c = a (mod m). Result will always be 0 <= c < m.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1357 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1358
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1359 mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1360 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1361 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1362 int mag;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1363
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1364 ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1365
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1366 if(SIGN(m) == MP_NEG)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1367 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1368
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1369 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1370 If |a| > m, we need to divide to get the remainder and take the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1371 absolute value.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1372
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1373 If |a| < m, we don't need to do any division, just copy and adjust
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1374 the sign (if a is negative).
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1375
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1376 If |a| == m, we can simply set the result to zero.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1377
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1378 This order is intended to minimize the average path length of the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1379 comparison chain on common workloads -- the most frequent cases are
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1380 that |a| != m, so we do those first.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1381 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1382 if((mag = s_mp_cmp(a, m)) > 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1383 if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1384 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1385
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1386 if(SIGN(c) == MP_NEG) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1387 if((res = mp_add(c, m, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1388 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1389 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1390
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1391 } else if(mag < 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1392 if((res = mp_copy(a, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1393 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1394
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1395 if(mp_cmp_z(a) < 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1396 if((res = mp_add(c, m, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1397 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1398
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1399 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1400
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1401 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1402 mp_zero(c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1403
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1404 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1405
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1406 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1407
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1408 } /* end mp_mod() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1409
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1410 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1411
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1412 /* {{{ mp_mod_d(a, d, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1413
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1414 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1415 mp_mod_d(a, d, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1416
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1417 Compute c = a (mod d). Result will always be 0 <= c < d
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1418 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1419 mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1420 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1421 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1422 mp_digit rem;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1423
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1424 ARGCHK(a != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1425
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1426 if(s_mp_cmp_d(a, d) > 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1427 if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1428 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1429
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1430 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1431 if(SIGN(a) == MP_NEG)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1432 rem = d - DIGIT(a, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1433 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1434 rem = DIGIT(a, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1435 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1436
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1437 if(c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1438 *c = rem;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1439
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1440 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1441
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1442 } /* end mp_mod_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1443
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1444 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1445
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1446 /* {{{ mp_sqrt(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1447
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1448 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1449 mp_sqrt(a, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1450
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1451 Compute the integer square root of a, and store the result in b.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1452 Uses an integer-arithmetic version of Newton's iterative linear
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1453 approximation technique to determine this value; the result has the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1454 following two properties:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1455
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1456 b^2 <= a
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1457 (b+1)^2 >= a
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1458
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1459 It is a range error to pass a negative value.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1460 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1461 mp_err mp_sqrt(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1462 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1463 mp_int x, t;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1464 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1465
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1466 ARGCHK(a != NULL && b != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1467
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1468 /* Cannot take square root of a negative value */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1469 if(SIGN(a) == MP_NEG)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1470 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1471
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1472 /* Special cases for zero and one, trivial */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1473 if(mp_cmp_d(a, 0) == MP_EQ || mp_cmp_d(a, 1) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1474 return mp_copy(a, b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1475
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1476 /* Initialize the temporaries we'll use below */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1477 if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1478 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1479
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1480 /* Compute an initial guess for the iteration as a itself */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1481 if((res = mp_init_copy(&x, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1482 goto X;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1483
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1484 for(;;) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1485 /* t = (x * x) - a */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1486 mp_copy(&x, &t); /* can't fail, t is big enough for original x */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1487 if((res = mp_sqr(&t, &t)) != MP_OKAY ||
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1488 (res = mp_sub(&t, a, &t)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1489 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1490
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1491 /* t = t / 2x */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1492 s_mp_mul_2(&x);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1493 if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1494 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1495 s_mp_div_2(&x);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1496
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1497 /* Terminate the loop, if the quotient is zero */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1498 if(mp_cmp_z(&t) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1499 break;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1500
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1501 /* x = x - t */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1502 if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1503 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1504
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1505 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1506
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1507 /* Copy result to output parameter */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1508 mp_sub_d(&x, 1, &x);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1509 s_mp_exch(&x, b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1510
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1511 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1512 mp_clear(&x);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1513 X:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1514 mp_clear(&t);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1515
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1516 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1517
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1518 } /* end mp_sqrt() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1519
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1520 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1521
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1522 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1523
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1524 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1525 /* {{{ Modular arithmetic */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1526
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1527 #if MP_MODARITH
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1528 /* {{{ mp_addmod(a, b, m, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1529
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1530 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1531 mp_addmod(a, b, m, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1532
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1533 Compute c = (a + b) mod m
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1534 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1535
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1536 mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1537 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1538 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1539
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1540 ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1541
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1542 if((res = mp_add(a, b, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1543 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1544 if((res = mp_mod(c, m, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1545 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1546
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1547 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1548
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1549 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1550
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1551 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1552
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1553 /* {{{ mp_submod(a, b, m, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1554
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1555 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1556 mp_submod(a, b, m, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1557
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1558 Compute c = (a - b) mod m
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1559 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1560
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1561 mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1562 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1563 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1564
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1565 ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1566
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1567 if((res = mp_sub(a, b, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1568 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1569 if((res = mp_mod(c, m, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1570 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1571
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1572 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1573
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1574 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1575
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1576 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1577
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1578 /* {{{ mp_mulmod(a, b, m, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1579
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1580 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1581 mp_mulmod(a, b, m, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1582
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1583 Compute c = (a * b) mod m
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1584 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1585
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1586 mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1587 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1588 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1589
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1590 ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1591
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1592 if((res = mp_mul(a, b, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1593 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1594 if((res = mp_mod(c, m, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1595 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1596
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1597 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1598
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1599 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1600
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1601 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1602
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1603 /* {{{ mp_sqrmod(a, m, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1604
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1605 #if MP_SQUARE
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1606 mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1607 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1608 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1609
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1610 ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1611
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1612 if((res = mp_sqr(a, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1613 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1614 if((res = mp_mod(c, m, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1615 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1616
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1617 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1618
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1619 } /* end mp_sqrmod() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1620 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1621
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1622 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1623
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1624 /* {{{ mp_exptmod(a, b, m, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1625
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1626 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1627 mp_exptmod(a, b, m, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1628
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1629 Compute c = (a ** b) mod m. Uses a standard square-and-multiply
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1630 method with modular reductions at each step. (This is basically the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1631 same code as mp_expt(), except for the addition of the reductions)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1632
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1633 The modular reductions are done using Barrett's algorithm (see
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1634 s_mp_reduce() below for details)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1635 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1636
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1637 mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1638 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1639 mp_int s, x, mu;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1640 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1641 mp_digit d, *db = DIGITS(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1642 mp_size ub = USED(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1643 int dig, bit;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1644
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1645 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1646
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1647 if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1648 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1649
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1650 if((res = mp_init(&s)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1651 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1652 if((res = mp_init_copy(&x, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1653 goto X;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1654 if((res = mp_mod(&x, m, &x)) != MP_OKAY ||
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1655 (res = mp_init(&mu)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1656 goto MU;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1657
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1658 mp_set(&s, 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1659
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1660 /* mu = b^2k / m */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1661 s_mp_add_d(&mu, 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1662 s_mp_lshd(&mu, 2 * USED(m));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1663 if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1664 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1665
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1666 /* Loop over digits of b in ascending order, except highest order */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1667 for(dig = 0; dig < (ub - 1); dig++) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1668 d = *db++;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1669
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1670 /* Loop over the bits of the lower-order digits */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1671 for(bit = 0; bit < DIGIT_BIT; bit++) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1672 if(d & 1) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1673 if((res = s_mp_mul(&s, &x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1674 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1675 if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1676 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1677 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1678
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1679 d >>= 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1680
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1681 if((res = s_mp_sqr(&x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1682 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1683 if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1684 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1685 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1686 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1687
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1688 /* Now do the last digit... */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1689 d = *db;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1690
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1691 while(d) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1692 if(d & 1) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1693 if((res = s_mp_mul(&s, &x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1694 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1695 if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1696 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1697 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1698
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1699 d >>= 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1700
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1701 if((res = s_mp_sqr(&x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1702 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1703 if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1704 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1705 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1706
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1707 s_mp_exch(&s, c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1708
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1709 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1710 mp_clear(&mu);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1711 MU:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1712 mp_clear(&x);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1713 X:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1714 mp_clear(&s);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1715
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1716 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1717
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1718 } /* end mp_exptmod() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1719
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1720 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1721
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1722 /* {{{ mp_exptmod_d(a, d, m, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1723
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1724 mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1725 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1726 mp_int s, x;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1727 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1728
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1729 ARGCHK(a != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1730
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1731 if((res = mp_init(&s)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1732 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1733 if((res = mp_init_copy(&x, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1734 goto X;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1735
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1736 mp_set(&s, 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1737
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1738 while(d != 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1739 if(d & 1) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1740 if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1741 (res = mp_mod(&s, m, &s)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1742 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1743 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1744
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1745 d /= 2;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1746
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1747 if((res = s_mp_sqr(&x)) != MP_OKAY ||
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1748 (res = mp_mod(&x, m, &x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1749 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1750 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1751
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1752 s_mp_exch(&s, c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1753
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1754 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1755 mp_clear(&x);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1756 X:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1757 mp_clear(&s);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1758
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1759 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1760
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1761 } /* end mp_exptmod_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1762
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1763 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1764 #endif /* if MP_MODARITH */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1765
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1766 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1767
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1768 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1769 /* {{{ Comparison functions */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1770
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1771 /* {{{ mp_cmp_z(a) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1772
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1773 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1774 mp_cmp_z(a)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1775
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1776 Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1777 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1778
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1779 int mp_cmp_z(mp_int *a)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1780 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1781 if(SIGN(a) == MP_NEG)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1782 return MP_LT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1783 else if(USED(a) == 1 && DIGIT(a, 0) == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1784 return MP_EQ;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1785 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1786 return MP_GT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1787
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1788 } /* end mp_cmp_z() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1789
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1790 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1791
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1792 /* {{{ mp_cmp_d(a, d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1793
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1794 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1795 mp_cmp_d(a, d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1796
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1797 Compare a <=> d. Returns <0 if a<d, 0 if a=d, >0 if a>d
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1798 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1799
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1800 int mp_cmp_d(mp_int *a, mp_digit d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1801 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1802 ARGCHK(a != NULL, MP_EQ);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1803
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1804 if(SIGN(a) == MP_NEG)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1805 return MP_LT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1806
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1807 return s_mp_cmp_d(a, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1808
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1809 } /* end mp_cmp_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1810
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1811 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1812
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1813 /* {{{ mp_cmp(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1814
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1815 int mp_cmp(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1816 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1817 ARGCHK(a != NULL && b != NULL, MP_EQ);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1818
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1819 if(SIGN(a) == SIGN(b)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1820 int mag;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1821
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1822 if((mag = s_mp_cmp(a, b)) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1823 return MP_EQ;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1824
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1825 if(SIGN(a) == MP_ZPOS)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1826 return mag;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1827 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1828 return -mag;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1829
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1830 } else if(SIGN(a) == MP_ZPOS) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1831 return MP_GT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1832 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1833 return MP_LT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1834 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1835
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1836 } /* end mp_cmp() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1837
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1838 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1839
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1840 /* {{{ mp_cmp_mag(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1841
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1842 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1843 mp_cmp_mag(a, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1844
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1845 Compares |a| <=> |b|, and returns an appropriate comparison result
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1846 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1847
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1848 int mp_cmp_mag(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1849 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1850 ARGCHK(a != NULL && b != NULL, MP_EQ);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1851
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1852 return s_mp_cmp(a, b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1853
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1854 } /* end mp_cmp_mag() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1855
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1856 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1857
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1858 /* {{{ mp_cmp_int(a, z) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1859
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1860 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1861 This just converts z to an mp_int, and uses the existing comparison
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1862 routines. This is sort of inefficient, but it's not clear to me how
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1863 frequently this wil get used anyway. For small positive constants,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1864 you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1865 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1866 int mp_cmp_int(mp_int *a, long z)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1867 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1868 mp_int tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1869 int out;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1870
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1871 ARGCHK(a != NULL, MP_EQ);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1872
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1873 mp_init(&tmp); mp_set_int(&tmp, z);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1874 out = mp_cmp(a, &tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1875 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1876
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1877 return out;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1878
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1879 } /* end mp_cmp_int() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1880
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1881 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1882
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1883 /* {{{ mp_isodd(a) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1884
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1885 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1886 mp_isodd(a)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1887
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1888 Returns a true (non-zero) value if a is odd, false (zero) otherwise.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1889 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1890 int mp_isodd(mp_int *a)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1891 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1892 ARGCHK(a != NULL, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1893
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1894 return (DIGIT(a, 0) & 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1895
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1896 } /* end mp_isodd() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1897
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1898 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1899
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1900 /* {{{ mp_iseven(a) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1901
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1902 int mp_iseven(mp_int *a)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1903 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1904 return !mp_isodd(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1905
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1906 } /* end mp_iseven() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1907
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1908 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1909
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1910 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1911
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1912 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1913 /* {{{ Number theoretic functions */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1914
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1915 #if MP_NUMTH
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1916 /* {{{ mp_gcd(a, b, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1917
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1918 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1919 Like the old mp_gcd() function, except computes the GCD using the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1920 binary algorithm due to Josef Stein in 1961 (via Knuth).
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1921 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1922 mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1923 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1924 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1925 mp_int u, v, t;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1926 mp_size k = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1927
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1928 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1929
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1930 if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1931 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1932 if(mp_cmp_z(a) == MP_EQ) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1933 if((res = mp_copy(b, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1934 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1935 SIGN(c) = MP_ZPOS; return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1936 } else if(mp_cmp_z(b) == MP_EQ) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1937 if((res = mp_copy(a, c)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1938 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1939 SIGN(c) = MP_ZPOS; return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1940 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1941
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1942 if((res = mp_init(&t)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1943 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1944 if((res = mp_init_copy(&u, a)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1945 goto U;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1946 if((res = mp_init_copy(&v, b)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1947 goto V;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1948
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1949 SIGN(&u) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1950 SIGN(&v) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1951
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1952 /* Divide out common factors of 2 until at least 1 of a, b is even */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1953 while(mp_iseven(&u) && mp_iseven(&v)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1954 s_mp_div_2(&u);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1955 s_mp_div_2(&v);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1956 ++k;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1957 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1958
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1959 /* Initialize t */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1960 if(mp_isodd(&u)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1961 if((res = mp_copy(&v, &t)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1962 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1963
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1964 /* t = -v */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1965 if(SIGN(&v) == MP_ZPOS)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1966 SIGN(&t) = MP_NEG;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1967 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1968 SIGN(&t) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1969
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1970 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1971 if((res = mp_copy(&u, &t)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1972 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1973
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1974 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1975
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1976 for(;;) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1977 while(mp_iseven(&t)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1978 s_mp_div_2(&t);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1979 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1980
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1981 if(mp_cmp_z(&t) == MP_GT) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1982 if((res = mp_copy(&t, &u)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1983 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1984
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1985 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1986 if((res = mp_copy(&t, &v)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1987 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1988
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1989 /* v = -t */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1990 if(SIGN(&t) == MP_ZPOS)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1991 SIGN(&v) = MP_NEG;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1992 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1993 SIGN(&v) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1994 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1995
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1996 if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1997 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1998
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
1999 if(s_mp_cmp_d(&t, 0) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2000 break;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2001 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2002
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2003 s_mp_2expt(&v, k); /* v = 2^k */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2004 res = mp_mul(&u, &v, c); /* c = u * v */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2005
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2006 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2007 mp_clear(&v);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2008 V:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2009 mp_clear(&u);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2010 U:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2011 mp_clear(&t);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2012
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2013 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2014
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2015 } /* end mp_bgcd() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2016
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2017 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2018
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2019 /* {{{ mp_lcm(a, b, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2020
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2021 /* We compute the least common multiple using the rule:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2022
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2023 ab = [a, b](a, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2024
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2025 ... by computing the product, and dividing out the gcd.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2026 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2027
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2028 mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2029 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2030 mp_int gcd, prod;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2031 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2032
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2033 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2034
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2035 /* Set up temporaries */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2036 if((res = mp_init(&gcd)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2037 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2038 if((res = mp_init(&prod)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2039 goto GCD;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2040
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2041 if((res = mp_mul(a, b, &prod)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2042 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2043 if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2044 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2045
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2046 res = mp_div(&prod, &gcd, c, NULL);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2047
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2048 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2049 mp_clear(&prod);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2050 GCD:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2051 mp_clear(&gcd);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2052
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2053 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2054
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2055 } /* end mp_lcm() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2056
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2057 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2058
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2059 /* {{{ mp_xgcd(a, b, g, x, y) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2060
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2061 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2062 mp_xgcd(a, b, g, x, y)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2063
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2064 Compute g = (a, b) and values x and y satisfying Bezout's identity
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2065 (that is, ax + by = g). This uses the extended binary GCD algorithm
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2066 based on the Stein algorithm used for mp_gcd()
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2067 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2068
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2069 mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2070 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2071 mp_int gx, xc, yc, u, v, A, B, C, D;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2072 mp_int *clean[9];
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2073 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2074 int last = -1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2075
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2076 if(mp_cmp_z(b) == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2077 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2078
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2079 /* Initialize all these variables we need */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2080 if((res = mp_init(&u)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2081 clean[++last] = &u;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2082 if((res = mp_init(&v)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2083 clean[++last] = &v;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2084 if((res = mp_init(&gx)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2085 clean[++last] = &gx;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2086 if((res = mp_init(&A)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2087 clean[++last] = &A;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2088 if((res = mp_init(&B)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2089 clean[++last] = &B;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2090 if((res = mp_init(&C)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2091 clean[++last] = &C;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2092 if((res = mp_init(&D)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2093 clean[++last] = &D;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2094 if((res = mp_init_copy(&xc, a)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2095 clean[++last] = &xc;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2096 mp_abs(&xc, &xc);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2097 if((res = mp_init_copy(&yc, b)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2098 clean[++last] = &yc;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2099 mp_abs(&yc, &yc);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2100
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2101 mp_set(&gx, 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2102
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2103 /* Divide by two until at least one of them is even */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2104 while(mp_iseven(&xc) && mp_iseven(&yc)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2105 s_mp_div_2(&xc);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2106 s_mp_div_2(&yc);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2107 if((res = s_mp_mul_2(&gx)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2108 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2109 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2110
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2111 mp_copy(&xc, &u);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2112 mp_copy(&yc, &v);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2113 mp_set(&A, 1); mp_set(&D, 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2114
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2115 /* Loop through binary GCD algorithm */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2116 for(;;) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2117 while(mp_iseven(&u)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2118 s_mp_div_2(&u);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2119
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2120 if(mp_iseven(&A) && mp_iseven(&B)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2121 s_mp_div_2(&A); s_mp_div_2(&B);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2122 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2123 if((res = mp_add(&A, &yc, &A)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2124 s_mp_div_2(&A);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2125 if((res = mp_sub(&B, &xc, &B)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2126 s_mp_div_2(&B);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2127 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2128 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2129
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2130 while(mp_iseven(&v)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2131 s_mp_div_2(&v);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2132
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2133 if(mp_iseven(&C) && mp_iseven(&D)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2134 s_mp_div_2(&C); s_mp_div_2(&D);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2135 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2136 if((res = mp_add(&C, &yc, &C)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2137 s_mp_div_2(&C);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2138 if((res = mp_sub(&D, &xc, &D)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2139 s_mp_div_2(&D);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2140 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2141 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2142
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2143 if(mp_cmp(&u, &v) >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2144 if((res = mp_sub(&u, &v, &u)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2145 if((res = mp_sub(&A, &C, &A)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2146 if((res = mp_sub(&B, &D, &B)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2147
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2148 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2149 if((res = mp_sub(&v, &u, &v)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2150 if((res = mp_sub(&C, &A, &C)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2151 if((res = mp_sub(&D, &B, &D)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2152
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2153 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2154
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2155 /* If we're done, copy results to output */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2156 if(mp_cmp_z(&u) == 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2157 if(x)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2158 if((res = mp_copy(&C, x)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2159
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2160 if(y)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2161 if((res = mp_copy(&D, y)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2162
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2163 if(g)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2164 if((res = mp_mul(&gx, &v, g)) != MP_OKAY) goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2165
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2166 break;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2167 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2168 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2169
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2170 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2171 while(last >= 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2172 mp_clear(clean[last--]);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2173
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2174 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2175
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2176 } /* end mp_xgcd() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2177
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2178 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2179
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2180 /* {{{ mp_invmod(a, m, c) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2181
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2182 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2183 mp_invmod(a, m, c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2184
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2185 Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2186 This is equivalent to the question of whether (a, m) = 1. If not,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2187 MP_UNDEF is returned, and there is no inverse.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2188 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2189
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2190 mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2191 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2192 mp_int g, x;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2193 mp_sign sa;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2194 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2195
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2196 ARGCHK(a && m && c, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2197
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2198 if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2199 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2200
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2201 sa = SIGN(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2202
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2203 if((res = mp_init(&g)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2204 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2205 if((res = mp_init(&x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2206 goto X;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2207
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2208 if((res = mp_xgcd(a, m, &g, &x, NULL)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2209 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2210
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2211 if(mp_cmp_d(&g, 1) != MP_EQ) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2212 res = MP_UNDEF;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2213 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2214 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2215
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2216 res = mp_mod(&x, m, c);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2217 SIGN(c) = sa;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2218
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2219 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2220 mp_clear(&x);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2221 X:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2222 mp_clear(&g);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2223
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2224 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2225
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2226 } /* end mp_invmod() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2227
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2228 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2229 #endif /* if MP_NUMTH */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2230
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2231 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2232
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2233 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2234 /* {{{ mp_print(mp, ofp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2235
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2236 #if MP_IOFUNC
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2237 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2238 mp_print(mp, ofp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2239
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2240 Print a textual representation of the given mp_int on the output
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2241 stream 'ofp'. Output is generated using the internal radix.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2242 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2243
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2244 void mp_print(mp_int *mp, FILE *ofp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2245 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2246 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2247
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2248 if(mp == NULL || ofp == NULL)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2249 return;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2250
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2251 fputc((SIGN(mp) == MP_NEG) ? '-' : '+', ofp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2252
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2253 for(ix = USED(mp) - 1; ix >= 0; ix--) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2254 fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2255 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2256
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2257 } /* end mp_print() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2258
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2259 #endif /* if MP_IOFUNC */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2260
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2261 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2262
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2263 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2264 /* {{{ More I/O Functions */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2265
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2266 /* {{{ mp_read_signed_bin(mp, str, len) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2267
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2268 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2269 mp_read_signed_bin(mp, str, len)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2270
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2271 Read in a raw value (base 256) into the given mp_int
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2272 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2273
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2274 mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2275 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2276 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2277
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2278 ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2279
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2280 if((res = mp_read_unsigned_bin(mp, str + 1, len - 1)) == MP_OKAY) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2281 /* Get sign from first byte */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2282 if(str[0])
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2283 SIGN(mp) = MP_NEG;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2284 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2285 SIGN(mp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2286 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2287
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2288 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2289
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2290 } /* end mp_read_signed_bin() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2291
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2292 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2293
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2294 /* {{{ mp_signed_bin_size(mp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2295
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2296 int mp_signed_bin_size(mp_int *mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2297 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2298 ARGCHK(mp != NULL, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2299
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2300 return mp_unsigned_bin_size(mp) + 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2301
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2302 } /* end mp_signed_bin_size() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2303
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2304 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2305
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2306 /* {{{ mp_to_signed_bin(mp, str) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2307
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2308 mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2309 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2310 ARGCHK(mp != NULL && str != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2311
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2312 /* Caller responsible for allocating enough memory (use mp_raw_size(mp)) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2313 str[0] = (char)SIGN(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2314
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2315 return mp_to_unsigned_bin(mp, str + 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2316
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2317 } /* end mp_to_signed_bin() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2318
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2319 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2320
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2321 /* {{{ mp_read_unsigned_bin(mp, str, len) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2322
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2323 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2324 mp_read_unsigned_bin(mp, str, len)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2325
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2326 Read in an unsigned value (base 256) into the given mp_int
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2327 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2328
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2329 mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2330 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2331 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2332 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2333
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2334 ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2335
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2336 mp_zero(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2337
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2338 for(ix = 0; ix < len; ix++) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2339 if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2340 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2341
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2342 if((res = mp_add_d(mp, str[ix], mp)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2343 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2344 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2345
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2346 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2347
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2348 } /* end mp_read_unsigned_bin() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2349
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2350 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2351
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2352 /* {{{ mp_unsigned_bin_size(mp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2353
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2354 int mp_unsigned_bin_size(mp_int *mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2355 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2356 mp_digit topdig;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2357 int count;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2358
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2359 ARGCHK(mp != NULL, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2360
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2361 /* Special case for the value zero */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2362 if(USED(mp) == 1 && DIGIT(mp, 0) == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2363 return 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2364
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2365 count = (USED(mp) - 1) * sizeof(mp_digit);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2366 topdig = DIGIT(mp, USED(mp) - 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2367
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2368 while(topdig != 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2369 ++count;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2370 topdig >>= CHAR_BIT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2371 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2372
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2373 return count;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2374
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2375 } /* end mp_unsigned_bin_size() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2376
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2377 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2378
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2379 /* {{{ mp_to_unsigned_bin(mp, str) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2380
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2381 mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2382 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2383 mp_digit *dp, *end, d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2384 unsigned char *spos;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2385
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2386 ARGCHK(mp != NULL && str != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2387
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2388 dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2389 end = dp + USED(mp) - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2390 spos = str;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2391
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2392 /* Special case for zero, quick test */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2393 if(dp == end && *dp == 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2394 *str = '\0';
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2395 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2396 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2397
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2398 /* Generate digits in reverse order */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2399 while(dp < end) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2400 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2401
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2402 d = *dp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2403 for(ix = 0; ix < sizeof(mp_digit); ++ix) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2404 *spos = d & UCHAR_MAX;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2405 d >>= CHAR_BIT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2406 ++spos;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2407 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2408
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2409 ++dp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2410 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2411
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2412 /* Now handle last digit specially, high order zeroes are not written */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2413 d = *end;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2414 while(d != 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2415 *spos = d & UCHAR_MAX;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2416 d >>= CHAR_BIT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2417 ++spos;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2418 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2419
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2420 /* Reverse everything to get digits in the correct order */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2421 while(--spos > str) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2422 unsigned char t = *str;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2423 *str = *spos;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2424 *spos = t;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2425
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2426 ++str;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2427 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2428
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2429 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2430
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2431 } /* end mp_to_unsigned_bin() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2432
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2433 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2434
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2435 /* {{{ mp_count_bits(mp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2436
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2437 int mp_count_bits(mp_int *mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2438 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2439 int len;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2440 mp_digit d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2441
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2442 ARGCHK(mp != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2443
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2444 len = DIGIT_BIT * (USED(mp) - 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2445 d = DIGIT(mp, USED(mp) - 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2446
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2447 while(d != 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2448 ++len;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2449 d >>= 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2450 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2451
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2452 return len;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2453
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2454 } /* end mp_count_bits() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2455
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2456 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2457
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2458 /* {{{ mp_read_radix(mp, str, radix) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2459
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2460 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2461 mp_read_radix(mp, str, radix)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2462
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2463 Read an integer from the given string, and set mp to the resulting
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2464 value. The input is presumed to be in base 10. Leading non-digit
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2465 characters are ignored, and the function reads until a non-digit
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2466 character or the end of the string.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2467 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2468
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2469 mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2470 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2471 int ix = 0, val = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2472 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2473 mp_sign sig = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2474
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2475 ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2476 MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2477
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2478 mp_zero(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2479
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2480 /* Skip leading non-digit characters until a digit or '-' or '+' */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2481 while(str[ix] &&
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2482 (s_mp_tovalue(str[ix], radix) < 0) &&
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2483 str[ix] != '-' &&
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2484 str[ix] != '+') {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2485 ++ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2486 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2487
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2488 if(str[ix] == '-') {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2489 sig = MP_NEG;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2490 ++ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2491 } else if(str[ix] == '+') {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2492 sig = MP_ZPOS; /* this is the default anyway... */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2493 ++ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2494 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2495
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2496 while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2497 if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2498 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2499 if((res = s_mp_add_d(mp, val)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2500 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2501 ++ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2502 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2503
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2504 if(s_mp_cmp_d(mp, 0) == MP_EQ)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2505 SIGN(mp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2506 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2507 SIGN(mp) = sig;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2508
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2509 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2510
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2511 } /* end mp_read_radix() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2512
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2513 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2514
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2515 /* {{{ mp_radix_size(mp, radix) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2516
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2517 int mp_radix_size(mp_int *mp, int radix)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2518 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2519 int len;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2520 ARGCHK(mp != NULL, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2521
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2522 len = s_mp_outlen(mp_count_bits(mp), radix) + 1; /* for NUL terminator */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2523
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2524 if(mp_cmp_z(mp) < 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2525 ++len; /* for sign */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2526
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2527 return len;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2528
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2529 } /* end mp_radix_size() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2530
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2531 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2532
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2533 /* {{{ mp_value_radix_size(num, qty, radix) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2534
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2535 /* num = number of digits
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2536 qty = number of bits per digit
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2537 radix = target base
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2538
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2539 Return the number of digits in the specified radix that would be
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2540 needed to express 'num' digits of 'qty' bits each.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2541 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2542 int mp_value_radix_size(int num, int qty, int radix)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2543 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2544 ARGCHK(num >= 0 && qty > 0 && radix >= 2 && radix <= MAX_RADIX, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2545
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2546 return s_mp_outlen(num * qty, radix);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2547
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2548 } /* end mp_value_radix_size() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2549
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2550 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2551
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2552 /* {{{ mp_toradix(mp, str, radix) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2553
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2554 mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2555 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2556 int ix, pos = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2557
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2558 ARGCHK(mp != NULL && str != NULL, MP_BADARG);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2559 ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2560
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2561 if(mp_cmp_z(mp) == MP_EQ) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2562 str[0] = '0';
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2563 str[1] = '\0';
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2564 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2565 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2566 mp_int tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2567 mp_sign sgn;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2568 mp_digit rem, rdx = (mp_digit)radix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2569 char ch;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2570
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2571 if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2572 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2573
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2574 /* Save sign for later, and take absolute value */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2575 sgn = SIGN(&tmp); SIGN(&tmp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2576
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2577 /* Generate output digits in reverse order */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2578 while(mp_cmp_z(&tmp) != 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2579 if((res = s_mp_div_d(&tmp, rdx, &rem)) != MP_OKAY) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2580 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2581 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2582 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2583
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2584 /* Generate digits, use capital letters */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2585 ch = s_mp_todigit(rem, radix, 0);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2586
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2587 str[pos++] = ch;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2588 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2589
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2590 /* Add - sign if original value was negative */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2591 if(sgn == MP_NEG)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2592 str[pos++] = '-';
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2593
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2594 /* Add trailing NUL to end the string */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2595 str[pos--] = '\0';
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2596
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2597 /* Reverse the digits and sign indicator */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2598 ix = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2599 while(ix < pos) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2600 char tmp = str[ix];
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2601
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2602 str[ix] = str[pos];
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2603 str[pos] = tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2604 ++ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2605 --pos;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2606 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2607
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2608 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2609 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2610
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2611 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2612
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2613 } /* end mp_toradix() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2614
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2615 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2616
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2617 /* {{{ mp_char2value(ch, r) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2618
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2619 int mp_char2value(char ch, int r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2620 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2621 return s_mp_tovalue(ch, r);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2622
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2623 } /* end mp_tovalue() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2624
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2625 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2626
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2627 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2628
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2629 /* {{{ mp_strerror(ec) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2630
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2631 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2632 mp_strerror(ec)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2633
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2634 Return a string describing the meaning of error code 'ec'. The
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2635 string returned is allocated in static memory, so the caller should
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2636 not attempt to modify or free the memory associated with this
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2637 string.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2638 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2639 const char *mp_strerror(mp_err ec)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2640 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2641 int aec = (ec < 0) ? -ec : ec;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2642
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2643 /* Code values are negative, so the senses of these comparisons
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2644 are accurate */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2645 if(ec < MP_LAST_CODE || ec > MP_OKAY) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2646 return mp_err_string[0]; /* unknown error code */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2647 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2648 return mp_err_string[aec + 1];
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2649 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2650
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2651 } /* end mp_strerror() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2652
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2653 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2654
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2655 /*========================================================================*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2656 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2657 /* Static function definitions (internal use only) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2658
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2659 /* {{{ Memory management */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2660
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2661 /* {{{ s_mp_grow(mp, min) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2662
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2663 /* Make sure there are at least 'min' digits allocated to mp */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2664 mp_err s_mp_grow(mp_int *mp, mp_size min)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2665 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2666 if(min > ALLOC(mp)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2667 mp_digit *tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2668
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2669 /* Set min to next nearest default precision block size */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2670 min = ((min + (s_mp_defprec - 1)) / s_mp_defprec) * s_mp_defprec;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2671
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2672 if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2673 return MP_MEM;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2674
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2675 s_mp_copy(DIGITS(mp), tmp, USED(mp));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2676
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2677 #if MP_CRYPTO
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2678 s_mp_setz(DIGITS(mp), ALLOC(mp));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2679 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2680 s_mp_free(DIGITS(mp));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2681 DIGITS(mp) = tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2682 ALLOC(mp) = min;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2683 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2684
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2685 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2686
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2687 } /* end s_mp_grow() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2688
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2689 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2690
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2691 /* {{{ s_mp_pad(mp, min) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2692
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2693 /* Make sure the used size of mp is at least 'min', growing if needed */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2694 mp_err s_mp_pad(mp_int *mp, mp_size min)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2695 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2696 if(min > USED(mp)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2697 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2698
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2699 /* Make sure there is room to increase precision */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2700 if(min > ALLOC(mp) && (res = s_mp_grow(mp, min)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2701 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2702
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2703 /* Increase precision; should already be 0-filled */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2704 USED(mp) = min;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2705 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2706
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2707 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2708
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2709 } /* end s_mp_pad() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2710
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2711 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2712
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2713 /* {{{ s_mp_setz(dp, count) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2714
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2715 #if MP_MACRO == 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2716 /* Set 'count' digits pointed to by dp to be zeroes */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2717 void s_mp_setz(mp_digit *dp, mp_size count)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2718 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2719 #if MP_MEMSET == 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2720 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2721
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2722 for(ix = 0; ix < count; ix++)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2723 dp[ix] = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2724 #else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2725 memset(dp, 0, count * sizeof(mp_digit));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2726 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2727
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2728 } /* end s_mp_setz() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2729 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2730
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2731 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2732
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2733 /* {{{ s_mp_copy(sp, dp, count) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2734
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2735 #if MP_MACRO == 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2736 /* Copy 'count' digits from sp to dp */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2737 void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2738 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2739 #if MP_MEMCPY == 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2740 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2741
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2742 for(ix = 0; ix < count; ix++)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2743 dp[ix] = sp[ix];
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2744 #else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2745 memcpy(dp, sp, count * sizeof(mp_digit));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2746 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2747
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2748 } /* end s_mp_copy() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2749 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2750
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2751 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2752
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2753 /* {{{ s_mp_alloc(nb, ni) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2754
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2755 #if MP_MACRO == 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2756 /* Allocate ni records of nb bytes each, and return a pointer to that */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2757 void *s_mp_alloc(size_t nb, size_t ni)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2758 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2759 return calloc(nb, ni);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2760
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2761 } /* end s_mp_alloc() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2762 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2763
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2764 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2765
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2766 /* {{{ s_mp_free(ptr) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2767
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2768 #if MP_MACRO == 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2769 /* Free the memory pointed to by ptr */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2770 void s_mp_free(void *ptr)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2771 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2772 if(ptr)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2773 free(ptr);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2774
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2775 } /* end s_mp_free() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2776 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2777
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2778 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2779
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2780 /* {{{ s_mp_clamp(mp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2781
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2782 /* Remove leading zeroes from the given value */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2783 void s_mp_clamp(mp_int *mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2784 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2785 mp_size du = USED(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2786 mp_digit *zp = DIGITS(mp) + du - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2787
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2788 while(du > 1 && !*zp--)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2789 --du;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2790
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2791 if(du == 1 && *zp == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2792 SIGN(mp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2793
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2794 USED(mp) = du;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2795
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2796 } /* end s_mp_clamp() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2797
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2798
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2799 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2800
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2801 /* {{{ s_mp_exch(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2802
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2803 /* Exchange the data for a and b; (b, a) = (a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2804 void s_mp_exch(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2805 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2806 mp_int tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2807
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2808 tmp = *a;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2809 *a = *b;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2810 *b = tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2811
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2812 } /* end s_mp_exch() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2813
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2814 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2815
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2816 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2817
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2818 /* {{{ Arithmetic helpers */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2819
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2820 /* {{{ s_mp_lshd(mp, p) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2821
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2822 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2823 Shift mp leftward by p digits, growing if needed, and zero-filling
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2824 the in-shifted digits at the right end. This is a convenient
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2825 alternative to multiplication by powers of the radix
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2826 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2827
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2828 mp_err s_mp_lshd(mp_int *mp, mp_size p)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2829 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2830 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2831 mp_size pos;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2832 mp_digit *dp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2833 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2834
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2835 if(p == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2836 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2837
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2838 if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2839 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2840
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2841 pos = USED(mp) - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2842 dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2843
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2844 /* Shift all the significant figures over as needed */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2845 for(ix = pos - p; ix >= 0; ix--)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2846 dp[ix + p] = dp[ix];
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2847
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2848 /* Fill the bottom digits with zeroes */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2849 for(ix = 0; ix < p; ix++)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2850 dp[ix] = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2851
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2852 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2853
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2854 } /* end s_mp_lshd() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2855
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2856 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2857
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2858 /* {{{ s_mp_rshd(mp, p) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2859
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2860 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2861 Shift mp rightward by p digits. Maintains the invariant that
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2862 digits above the precision are all zero. Digits shifted off the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2863 end are lost. Cannot fail.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2864 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2865
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2866 void s_mp_rshd(mp_int *mp, mp_size p)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2867 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2868 mp_size ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2869 mp_digit *dp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2870
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2871 if(p == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2872 return;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2873
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2874 /* Shortcut when all digits are to be shifted off */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2875 if(p >= USED(mp)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2876 s_mp_setz(DIGITS(mp), ALLOC(mp));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2877 USED(mp) = 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2878 SIGN(mp) = MP_ZPOS;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2879 return;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2880 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2881
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2882 /* Shift all the significant figures over as needed */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2883 dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2884 for(ix = p; ix < USED(mp); ix++)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2885 dp[ix - p] = dp[ix];
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2886
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2887 /* Fill the top digits with zeroes */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2888 ix -= p;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2889 while(ix < USED(mp))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2890 dp[ix++] = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2891
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2892 /* Strip off any leading zeroes */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2893 s_mp_clamp(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2894
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2895 } /* end s_mp_rshd() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2896
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2897 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2898
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2899 /* {{{ s_mp_div_2(mp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2900
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2901 /* Divide by two -- take advantage of radix properties to do it fast */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2902 void s_mp_div_2(mp_int *mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2903 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2904 s_mp_div_2d(mp, 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2905
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2906 } /* end s_mp_div_2() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2907
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2908 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2909
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2910 /* {{{ s_mp_mul_2(mp) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2911
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2912 mp_err s_mp_mul_2(mp_int *mp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2913 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2914 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2915 mp_digit kin = 0, kout, *dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2916 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2917
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2918 /* Shift digits leftward by 1 bit */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2919 for(ix = 0; ix < USED(mp); ix++) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2920 kout = (dp[ix] >> (DIGIT_BIT - 1)) & 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2921 dp[ix] = (dp[ix] << 1) | kin;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2922
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2923 kin = kout;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2924 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2925
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2926 /* Deal with rollover from last digit */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2927 if(kin) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2928 if(ix >= ALLOC(mp)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2929 if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2930 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2931 dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2932 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2933
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2934 dp[ix] = kin;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2935 USED(mp) += 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2936 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2937
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2938 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2939
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2940 } /* end s_mp_mul_2() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2941
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2942 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2943
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2944 /* {{{ s_mp_mod_2d(mp, d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2945
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2946 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2947 Remainder the integer by 2^d, where d is a number of bits. This
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2948 amounts to a bitwise AND of the value, and does not require the full
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2949 division code
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2950 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2951 void s_mp_mod_2d(mp_int *mp, mp_digit d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2952 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2953 unsigned int ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2954 unsigned int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2955 mp_digit dmask, *dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2956
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2957 if(ndig >= USED(mp))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2958 return;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2959
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2960 /* Flush all the bits above 2^d in its digit */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2961 dmask = (1 << nbit) - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2962 dp[ndig] &= dmask;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2963
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2964 /* Flush all digits above the one with 2^d in it */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2965 for(ix = ndig + 1; ix < USED(mp); ix++)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2966 dp[ix] = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2967
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2968 s_mp_clamp(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2969
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2970 } /* end s_mp_mod_2d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2971
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2972 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2973
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2974 /* {{{ s_mp_mul_2d(mp, d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2975
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2976 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2977 Multiply by the integer 2^d, where d is a number of bits. This
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2978 amounts to a bitwise shift of the value, and does not require the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2979 full multiplication code.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2980 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2981 mp_err s_mp_mul_2d(mp_int *mp, mp_digit d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2982 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2983 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2984 mp_digit save, next, mask, *dp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2985 mp_size used;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2986 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2987
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2988 if((res = s_mp_lshd(mp, d / DIGIT_BIT)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2989 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2990
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2991 dp = DIGITS(mp); used = USED(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2992 d %= DIGIT_BIT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2993
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2994 mask = (1 << d) - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2995
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2996 /* If the shift requires another digit, make sure we've got one to
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2997 work with */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2998 if((dp[used - 1] >> (DIGIT_BIT - d)) & mask) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
2999 if((res = s_mp_grow(mp, used + 1)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3000 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3001 dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3002 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3003
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3004 /* Do the shifting... */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3005 save = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3006 for(ix = 0; ix < used; ix++) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3007 next = (dp[ix] >> (DIGIT_BIT - d)) & mask;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3008 dp[ix] = (dp[ix] << d) | save;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3009 save = next;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3010 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3011
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3012 /* If, at this point, we have a nonzero carryout into the next
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3013 digit, we'll increase the size by one digit, and store it...
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3014 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3015 if(save) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3016 dp[used] = save;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3017 USED(mp) += 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3018 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3019
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3020 s_mp_clamp(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3021 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3022
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3023 } /* end s_mp_mul_2d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3024
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3025 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3026
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3027 /* {{{ s_mp_div_2d(mp, d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3028
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3029 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3030 Divide the integer by 2^d, where d is a number of bits. This
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3031 amounts to a bitwise shift of the value, and does not require the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3032 full division code (used in Barrett reduction, see below)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3033 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3034 void s_mp_div_2d(mp_int *mp, mp_digit d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3035 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3036 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3037 mp_digit save, next, mask, *dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3038
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3039 s_mp_rshd(mp, d / DIGIT_BIT);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3040 d %= DIGIT_BIT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3041
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3042 mask = (1 << d) - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3043
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3044 save = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3045 for(ix = USED(mp) - 1; ix >= 0; ix--) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3046 next = dp[ix] & mask;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3047 dp[ix] = (dp[ix] >> d) | (save << (DIGIT_BIT - d));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3048 save = next;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3049 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3050
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3051 s_mp_clamp(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3052
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3053 } /* end s_mp_div_2d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3054
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3055 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3056
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3057 /* {{{ s_mp_norm(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3058
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3059 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3060 s_mp_norm(a, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3061
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3062 Normalize a and b for division, where b is the divisor. In order
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3063 that we might make good guesses for quotient digits, we want the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3064 leading digit of b to be at least half the radix, which we
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3065 accomplish by multiplying a and b by a constant. This constant is
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3066 returned (so that it can be divided back out of the remainder at the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3067 end of the division process).
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3068
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3069 We multiply by the smallest power of 2 that gives us a leading digit
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3070 at least half the radix. By choosing a power of 2, we simplify the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3071 multiplication and division steps to simple shifts.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3072 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3073 mp_digit s_mp_norm(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3074 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3075 mp_digit t, d = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3076
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3077 t = DIGIT(b, USED(b) - 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3078 while(t < (RADIX / 2)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3079 t <<= 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3080 ++d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3081 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3082
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3083 if(d != 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3084 s_mp_mul_2d(a, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3085 s_mp_mul_2d(b, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3086 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3087
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3088 return d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3089
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3090 } /* end s_mp_norm() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3091
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3092 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3093
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3094 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3095
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3096 /* {{{ Primitive digit arithmetic */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3097
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3098 /* {{{ s_mp_add_d(mp, d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3099
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3100 /* Add d to |mp| in place */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3101 mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3102 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3103 mp_word w, k = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3104 mp_size ix = 1, used = USED(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3105 mp_digit *dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3106
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3107 w = dp[0] + d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3108 dp[0] = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3109 k = CARRYOUT(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3110
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3111 while(ix < used && k) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3112 w = dp[ix] + k;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3113 dp[ix] = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3114 k = CARRYOUT(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3115 ++ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3116 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3117
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3118 if(k != 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3119 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3120
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3121 if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3122 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3123
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3124 DIGIT(mp, ix) = k;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3125 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3126
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3127 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3128
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3129 } /* end s_mp_add_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3130
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3131 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3132
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3133 /* {{{ s_mp_sub_d(mp, d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3134
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3135 /* Subtract d from |mp| in place, assumes |mp| > d */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3136 mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3137 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3138 mp_word w, b = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3139 mp_size ix = 1, used = USED(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3140 mp_digit *dp = DIGITS(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3141
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3142 /* Compute initial subtraction */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3143 w = (RADIX + dp[0]) - d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3144 b = CARRYOUT(w) ? 0 : 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3145 dp[0] = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3146
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3147 /* Propagate borrows leftward */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3148 while(b && ix < used) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3149 w = (RADIX + dp[ix]) - b;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3150 b = CARRYOUT(w) ? 0 : 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3151 dp[ix] = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3152 ++ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3153 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3154
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3155 /* Remove leading zeroes */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3156 s_mp_clamp(mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3157
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3158 /* If we have a borrow out, it's a violation of the input invariant */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3159 if(b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3160 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3161 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3162 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3163
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3164 } /* end s_mp_sub_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3165
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3166 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3167
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3168 /* {{{ s_mp_mul_d(a, d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3169
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3170 /* Compute a = a * d, single digit multiplication */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3171 mp_err s_mp_mul_d(mp_int *a, mp_digit d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3172 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3173 mp_word w, k = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3174 mp_size ix, max;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3175 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3176 mp_digit *dp = DIGITS(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3177
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3178 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3179 Single-digit multiplication will increase the precision of the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3180 output by at most one digit. However, we can detect when this
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3181 will happen -- if the high-order digit of a, times d, gives a
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3182 two-digit result, then the precision of the result will increase;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3183 otherwise it won't. We use this fact to avoid calling s_mp_pad()
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3184 unless absolutely necessary.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3185 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3186 max = USED(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3187 w = dp[max - 1] * d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3188 if(CARRYOUT(w) != 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3189 if((res = s_mp_pad(a, max + 1)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3190 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3191 dp = DIGITS(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3192 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3193
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3194 for(ix = 0; ix < max; ix++) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3195 w = (dp[ix] * d) + k;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3196 dp[ix] = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3197 k = CARRYOUT(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3198 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3199
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3200 /* If there is a precision increase, take care of it here; the above
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3201 test guarantees we have enough storage to do this safely.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3202 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3203 if(k) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3204 dp[max] = k;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3205 USED(a) = max + 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3206 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3207
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3208 s_mp_clamp(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3209
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3210 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3211
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3212 } /* end s_mp_mul_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3213
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3214 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3215
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3216 /* {{{ s_mp_div_d(mp, d, r) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3217
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3218 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3219 s_mp_div_d(mp, d, r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3220
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3221 Compute the quotient mp = mp / d and remainder r = mp mod d, for a
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3222 single digit d. If r is null, the remainder will be discarded.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3223 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3224
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3225 mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3226 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3227 mp_word w = 0, t;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3228 mp_int quot;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3229 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3230 mp_digit *dp = DIGITS(mp), *qp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3231 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3232
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3233 if(d == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3234 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3235
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3236 /* Make room for the quotient */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3237 if((res = mp_init_size(&quot, USED(mp))) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3238 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3239
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3240 USED(&quot) = USED(mp); /* so clamping will work below */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3241 qp = DIGITS(&quot);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3242
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3243 /* Divide without subtraction */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3244 for(ix = USED(mp) - 1; ix >= 0; ix--) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3245 w = (w << DIGIT_BIT) | dp[ix];
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3246
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3247 if(w >= d) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3248 t = w / d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3249 w = w % d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3250 } else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3251 t = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3252 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3253
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3254 qp[ix] = t;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3255 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3256
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3257 /* Deliver the remainder, if desired */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3258 if(r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3259 *r = w;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3260
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3261 s_mp_clamp(&quot);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3262 mp_exch(&quot, mp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3263 mp_clear(&quot);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3264
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3265 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3266
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3267 } /* end s_mp_div_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3268
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3269 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3270
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3271 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3272
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3273 /* {{{ Primitive full arithmetic */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3274
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3275 /* {{{ s_mp_add(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3276
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3277 /* Compute a = |a| + |b| */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3278 mp_err s_mp_add(mp_int *a, mp_int *b) /* magnitude addition */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3279 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3280 mp_word w = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3281 mp_digit *pa, *pb;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3282 mp_size ix, used = USED(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3283 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3284
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3285 /* Make sure a has enough precision for the output value */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3286 if((used > USED(a)) && (res = s_mp_pad(a, used)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3287 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3288
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3289 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3290 Add up all digits up to the precision of b. If b had initially
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3291 the same precision as a, or greater, we took care of it by the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3292 padding step above, so there is no problem. If b had initially
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3293 less precision, we'll have to make sure the carry out is duly
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3294 propagated upward among the higher-order digits of the sum.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3295 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3296 pa = DIGITS(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3297 pb = DIGITS(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3298 for(ix = 0; ix < used; ++ix) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3299 w += *pa + *pb++;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3300 *pa++ = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3301 w = CARRYOUT(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3302 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3303
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3304 /* If we run out of 'b' digits before we're actually done, make
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3305 sure the carries get propagated upward...
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3306 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3307 used = USED(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3308 while(w && ix < used) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3309 w += *pa;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3310 *pa++ = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3311 w = CARRYOUT(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3312 ++ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3313 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3314
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3315 /* If there's an overall carry out, increase precision and include
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3316 it. We could have done this initially, but why touch the memory
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3317 allocator unless we're sure we have to?
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3318 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3319 if(w) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3320 if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3321 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3322
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3323 DIGIT(a, ix) = w; /* pa may not be valid after s_mp_pad() call */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3324 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3325
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3326 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3327
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3328 } /* end s_mp_add() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3329
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3330 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3331
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3332 /* {{{ s_mp_sub(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3333
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3334 /* Compute a = |a| - |b|, assumes |a| >= |b| */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3335 mp_err s_mp_sub(mp_int *a, mp_int *b) /* magnitude subtract */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3336 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3337 mp_word w = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3338 mp_digit *pa, *pb;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3339 mp_size ix, used = USED(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3340
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3341 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3342 Subtract and propagate borrow. Up to the precision of b, this
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3343 accounts for the digits of b; after that, we just make sure the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3344 carries get to the right place. This saves having to pad b out to
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3345 the precision of a just to make the loops work right...
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3346 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3347 pa = DIGITS(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3348 pb = DIGITS(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3349
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3350 for(ix = 0; ix < used; ++ix) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3351 w = (RADIX + *pa) - w - *pb++;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3352 *pa++ = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3353 w = CARRYOUT(w) ? 0 : 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3354 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3355
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3356 used = USED(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3357 while(ix < used) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3358 w = RADIX + *pa - w;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3359 *pa++ = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3360 w = CARRYOUT(w) ? 0 : 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3361 ++ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3362 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3363
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3364 /* Clobber any leading zeroes we created */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3365 s_mp_clamp(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3366
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3367 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3368 If there was a borrow out, then |b| > |a| in violation
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3369 of our input invariant. We've already done the work,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3370 but we'll at least complain about it...
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3371 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3372 if(w)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3373 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3374 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3375 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3376
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3377 } /* end s_mp_sub() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3378
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3379 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3380
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3381 /* {{{ s_mp_mul(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3382
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3383 /* Compute a = |a| * |b| */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3384 mp_err s_mp_mul(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3385 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3386 mp_word w, k = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3387 mp_int tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3388 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3389 mp_size ix, jx, ua = USED(a), ub = USED(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3390 mp_digit *pa, *pb, *pt, *pbt;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3391
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3392 if((res = mp_init_size(&tmp, ua + ub)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3393 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3394
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3395 /* This has the effect of left-padding with zeroes... */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3396 USED(&tmp) = ua + ub;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3397
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3398 /* We're going to need the base value each iteration */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3399 pbt = DIGITS(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3400
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3401 /* Outer loop: Digits of b */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3402
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3403 pb = DIGITS(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3404 for(ix = 0; ix < ub; ++ix, ++pb) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3405 if(*pb == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3406 continue;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3407
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3408 /* Inner product: Digits of a */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3409 pa = DIGITS(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3410 for(jx = 0; jx < ua; ++jx, ++pa) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3411 pt = pbt + ix + jx;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3412 w = *pb * *pa + k + *pt;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3413 *pt = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3414 k = CARRYOUT(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3415 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3416
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3417 pbt[ix + jx] = k;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3418 k = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3419 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3420
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3421 s_mp_clamp(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3422 s_mp_exch(&tmp, a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3423
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3424 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3425
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3426 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3427
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3428 } /* end s_mp_mul() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3429
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3430 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3431
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3432 /* {{{ s_mp_kmul(a, b, out, len) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3433
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3434 #if 0
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3435 void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3436 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3437 mp_word w, k = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3438 mp_size ix, jx;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3439 mp_digit *pa, *pt;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3440
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3441 for(ix = 0; ix < len; ++ix, ++b) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3442 if(*b == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3443 continue;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3444
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3445 pa = a;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3446 for(jx = 0; jx < len; ++jx, ++pa) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3447 pt = out + ix + jx;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3448 w = *b * *pa + k + *pt;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3449 *pt = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3450 k = CARRYOUT(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3451 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3452
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3453 out[ix + jx] = k;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3454 k = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3455 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3456
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3457 } /* end s_mp_kmul() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3458 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3459
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3460 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3461
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3462 /* {{{ s_mp_sqr(a) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3463
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3464 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3465 Computes the square of a, in place. This can be done more
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3466 efficiently than a general multiplication, because many of the
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3467 computation steps are redundant when squaring. The inner product
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3468 step is a bit more complicated, but we save a fair number of
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3469 iterations of the multiplication loop.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3470 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3471 #if MP_SQUARE
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3472 mp_err s_mp_sqr(mp_int *a)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3473 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3474 mp_word w, k = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3475 mp_int tmp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3476 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3477 mp_size ix, jx, kx, used = USED(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3478 mp_digit *pa1, *pa2, *pt, *pbt;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3479
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3480 if((res = mp_init_size(&tmp, 2 * used)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3481 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3482
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3483 /* Left-pad with zeroes */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3484 USED(&tmp) = 2 * used;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3485
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3486 /* We need the base value each time through the loop */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3487 pbt = DIGITS(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3488
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3489 pa1 = DIGITS(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3490 for(ix = 0; ix < used; ++ix, ++pa1) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3491 if(*pa1 == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3492 continue;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3493
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3494 w = DIGIT(&tmp, ix + ix) + (*pa1 * *pa1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3495
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3496 pbt[ix + ix] = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3497 k = CARRYOUT(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3498
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3499 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3500 The inner product is computed as:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3501
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3502 (C, S) = t[i,j] + 2 a[i] a[j] + C
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3503
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3504 This can overflow what can be represented in an mp_word, and
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3505 since C arithmetic does not provide any way to check for
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3506 overflow, we have to check explicitly for overflow conditions
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3507 before they happen.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3508 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3509 for(jx = ix + 1, pa2 = DIGITS(a) + jx; jx < used; ++jx, ++pa2) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3510 mp_word u = 0, v;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3511
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3512 /* Store this in a temporary to avoid indirections later */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3513 pt = pbt + ix + jx;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3514
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3515 /* Compute the multiplicative step */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3516 w = *pa1 * *pa2;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3517
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3518 /* If w is more than half MP_WORD_MAX, the doubling will
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3519 overflow, and we need to record a carry out into the next
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3520 word */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3521 u = (w >> (MP_WORD_BIT - 1)) & 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3522
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3523 /* Double what we've got, overflow will be ignored as defined
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3524 for C arithmetic (we've already noted if it is to occur)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3525 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3526 w *= 2;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3527
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3528 /* Compute the additive step */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3529 v = *pt + k;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3530
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3531 /* If we do not already have an overflow carry, check to see
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3532 if the addition will cause one, and set the carry out if so
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3533 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3534 u |= ((MP_WORD_MAX - v) < w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3535
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3536 /* Add in the rest, again ignoring overflow */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3537 w += v;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3538
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3539 /* Set the i,j digit of the output */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3540 *pt = ACCUM(w);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3541
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3542 /* Save carry information for the next iteration of the loop.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3543 This is why k must be an mp_word, instead of an mp_digit */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3544 k = CARRYOUT(w) | (u << DIGIT_BIT);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3545
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3546 } /* for(jx ...) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3547
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3548 /* Set the last digit in the cycle and reset the carry */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3549 k = DIGIT(&tmp, ix + jx) + k;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3550 pbt[ix + jx] = ACCUM(k);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3551 k = CARRYOUT(k);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3552
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3553 /* If we are carrying out, propagate the carry to the next digit
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3554 in the output. This may cascade, so we have to be somewhat
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3555 circumspect -- but we will have enough precision in the output
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3556 that we won't overflow
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3557 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3558 kx = 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3559 while(k) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3560 k = pbt[ix + jx + kx] + 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3561 pbt[ix + jx + kx] = ACCUM(k);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3562 k = CARRYOUT(k);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3563 ++kx;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3564 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3565 } /* for(ix ...) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3566
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3567 s_mp_clamp(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3568 s_mp_exch(&tmp, a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3569
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3570 mp_clear(&tmp);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3571
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3572 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3573
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3574 } /* end s_mp_sqr() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3575 #endif
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3576
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3577 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3578
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3579 /* {{{ s_mp_div(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3580
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3581 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3582 s_mp_div(a, b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3583
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3584 Compute a = a / b and b = a mod b. Assumes b > a.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3585 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3586
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3587 mp_err s_mp_div(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3588 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3589 mp_int quot, rem, t;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3590 mp_word q;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3591 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3592 mp_digit d;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3593 int ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3594
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3595 if(mp_cmp_z(b) == 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3596 return MP_RANGE;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3597
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3598 /* Shortcut if b is power of two */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3599 if((ix = s_mp_ispow2(b)) >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3600 mp_copy(a, b); /* need this for remainder */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3601 s_mp_div_2d(a, (mp_digit)ix);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3602 s_mp_mod_2d(b, (mp_digit)ix);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3603
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3604 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3605 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3606
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3607 /* Allocate space to store the quotient */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3608 if((res = mp_init_size(&quot, USED(a))) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3609 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3610
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3611 /* A working temporary for division */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3612 if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3613 goto T;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3614
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3615 /* Allocate space for the remainder */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3616 if((res = mp_init_size(&rem, USED(a))) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3617 goto REM;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3618
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3619 /* Normalize to optimize guessing */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3620 d = s_mp_norm(a, b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3621
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3622 /* Perform the division itself...woo! */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3623 ix = USED(a) - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3624
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3625 while(ix >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3626 /* Find a partial substring of a which is at least b */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3627 while(s_mp_cmp(&rem, b) < 0 && ix >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3628 if((res = s_mp_lshd(&rem, 1)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3629 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3630
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3631 if((res = s_mp_lshd(&quot, 1)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3632 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3633
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3634 DIGIT(&rem, 0) = DIGIT(a, ix);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3635 s_mp_clamp(&rem);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3636 --ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3637 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3638
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3639 /* If we didn't find one, we're finished dividing */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3640 if(s_mp_cmp(&rem, b) < 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3641 break;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3642
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3643 /* Compute a guess for the next quotient digit */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3644 q = DIGIT(&rem, USED(&rem) - 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3645 if(q <= DIGIT(b, USED(b) - 1) && USED(&rem) > 1)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3646 q = (q << DIGIT_BIT) | DIGIT(&rem, USED(&rem) - 2);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3647
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3648 q /= DIGIT(b, USED(b) - 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3649
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3650 /* The guess can be as much as RADIX + 1 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3651 if(q >= RADIX)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3652 q = RADIX - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3653
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3654 /* See what that multiplies out to */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3655 mp_copy(b, &t);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3656 if((res = s_mp_mul_d(&t, q)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3657 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3658
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3659 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3660 If it's too big, back it off. We should not have to do this
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3661 more than once, or, in rare cases, twice. Knuth describes a
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3662 method by which this could be reduced to a maximum of once, but
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3663 I didn't implement that here.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3664 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3665 while(s_mp_cmp(&t, &rem) > 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3666 --q;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3667 s_mp_sub(&t, b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3668 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3669
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3670 /* At this point, q should be the right next digit */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3671 if((res = s_mp_sub(&rem, &t)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3672 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3673
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3674 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3675 Include the digit in the quotient. We allocated enough memory
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3676 for any quotient we could ever possibly get, so we should not
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3677 have to check for failures here
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3678 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3679 DIGIT(&quot, 0) = q;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3680 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3681
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3682 /* Denormalize remainder */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3683 if(d != 0)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3684 s_mp_div_2d(&rem, d);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3685
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3686 s_mp_clamp(&quot);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3687 s_mp_clamp(&rem);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3688
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3689 /* Copy quotient back to output */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3690 s_mp_exch(&quot, a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3691
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3692 /* Copy remainder back to output */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3693 s_mp_exch(&rem, b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3694
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3695 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3696 mp_clear(&rem);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3697 REM:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3698 mp_clear(&t);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3699 T:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3700 mp_clear(&quot);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3701
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3702 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3703
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3704 } /* end s_mp_div() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3705
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3706 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3707
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3708 /* {{{ s_mp_2expt(a, k) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3709
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3710 mp_err s_mp_2expt(mp_int *a, mp_digit k)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3711 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3712 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3713 mp_size dig, bit;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3714
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3715 dig = k / DIGIT_BIT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3716 bit = k % DIGIT_BIT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3717
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3718 mp_zero(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3719 if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3720 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3721
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3722 DIGIT(a, dig) |= (1 << bit);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3723
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3724 return MP_OKAY;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3725
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3726 } /* end s_mp_2expt() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3727
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3728 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3729
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3730 /* {{{ s_mp_reduce(x, m, mu) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3731
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3732 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3733 Compute Barrett reduction, x (mod m), given a precomputed value for
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3734 mu = b^2k / m, where b = RADIX and k = #digits(m). This should be
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3735 faster than straight division, when many reductions by the same
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3736 value of m are required (such as in modular exponentiation). This
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3737 can nearly halve the time required to do modular exponentiation,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3738 as compared to using the full integer divide to reduce.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3739
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3740 This algorithm was derived from the _Handbook of Applied
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3741 Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3742 pp. 603-604.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3743 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3744
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3745 mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3746 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3747 mp_int q;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3748 mp_err res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3749 mp_size um = USED(m);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3750
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3751 if((res = mp_init_copy(&q, x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3752 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3753
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3754 s_mp_rshd(&q, um - 1); /* q1 = x / b^(k-1) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3755 s_mp_mul(&q, mu); /* q2 = q1 * mu */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3756 s_mp_rshd(&q, um + 1); /* q3 = q2 / b^(k+1) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3757
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3758 /* x = x mod b^(k+1), quick (no division) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3759 s_mp_mod_2d(x, DIGIT_BIT * (um + 1));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3760
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3761 /* q = q * m mod b^(k+1), quick (no division) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3762 s_mp_mul(&q, m);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3763 s_mp_mod_2d(&q, DIGIT_BIT * (um + 1));
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3764
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3765 /* x = x - q */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3766 if((res = mp_sub(x, &q, x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3767 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3768
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3769 /* If x < 0, add b^(k+1) to it */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3770 if(mp_cmp_z(x) < 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3771 mp_set(&q, 1);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3772 if((res = s_mp_lshd(&q, um + 1)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3773 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3774 if((res = mp_add(x, &q, x)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3775 goto CLEANUP;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3776 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3777
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3778 /* Back off if it's too big */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3779 while(mp_cmp(x, m) >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3780 if((res = s_mp_sub(x, m)) != MP_OKAY)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3781 break;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3782 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3783
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3784 CLEANUP:
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3785 mp_clear(&q);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3786
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3787 return res;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3788
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3789 } /* end s_mp_reduce() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3790
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3791 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3792
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3793 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3794
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3795 /* {{{ Primitive comparisons */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3796
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3797 /* {{{ s_mp_cmp(a, b) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3798
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3799 /* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3800 int s_mp_cmp(mp_int *a, mp_int *b)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3801 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3802 mp_size ua = USED(a), ub = USED(b);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3803
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3804 if(ua > ub)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3805 return MP_GT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3806 else if(ua < ub)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3807 return MP_LT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3808 else {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3809 int ix = ua - 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3810 mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3811
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3812 while(ix >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3813 if(*ap > *bp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3814 return MP_GT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3815 else if(*ap < *bp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3816 return MP_LT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3817
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3818 --ap; --bp; --ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3819 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3820
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3821 return MP_EQ;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3822 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3823
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3824 } /* end s_mp_cmp() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3825
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3826 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3827
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3828 /* {{{ s_mp_cmp_d(a, d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3829
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3830 /* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3831 int s_mp_cmp_d(mp_int *a, mp_digit d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3832 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3833 mp_size ua = USED(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3834 mp_digit *ap = DIGITS(a);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3835
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3836 if(ua > 1)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3837 return MP_GT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3838
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3839 if(*ap < d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3840 return MP_LT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3841 else if(*ap > d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3842 return MP_GT;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3843 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3844 return MP_EQ;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3845
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3846 } /* end s_mp_cmp_d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3847
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3848 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3849
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3850 /* {{{ s_mp_ispow2(v) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3851
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3852 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3853 Returns -1 if the value is not a power of two; otherwise, it returns
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3854 k such that v = 2^k, i.e. lg(v).
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3855 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3856 int s_mp_ispow2(mp_int *v)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3857 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3858 mp_digit d, *dp;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3859 mp_size uv = USED(v);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3860 int extra = 0, ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3861
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3862 d = DIGIT(v, uv - 1); /* most significant digit of v */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3863
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3864 while(d && ((d & 1) == 0)) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3865 d >>= 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3866 ++extra;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3867 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3868
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3869 if(d == 1) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3870 ix = uv - 2;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3871 dp = DIGITS(v) + ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3872
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3873 while(ix >= 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3874 if(*dp)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3875 return -1; /* not a power of two */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3876
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3877 --dp; --ix;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3878 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3879
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3880 return ((uv - 1) * DIGIT_BIT) + extra;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3881 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3882
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3883 return -1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3884
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3885 } /* end s_mp_ispow2() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3886
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3887 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3888
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3889 /* {{{ s_mp_ispow2d(d) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3890
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3891 int s_mp_ispow2d(mp_digit d)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3892 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3893 int pow = 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3894
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3895 while((d & 1) == 0) {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3896 ++pow; d >>= 1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3897 }
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3898
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3899 if(d == 1)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3900 return pow;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3901
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3902 return -1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3903
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3904 } /* end s_mp_ispow2d() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3905
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3906 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3907
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3908 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3909
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3910 /* {{{ Primitive I/O helpers */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3911
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3912 /* {{{ s_mp_tovalue(ch, r) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3913
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3914 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3915 Convert the given character to its digit value, in the given radix.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3916 If the given character is not understood in the given radix, -1 is
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3917 returned. Otherwise the digit's numeric value is returned.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3918
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3919 The results will be odd if you use a radix < 2 or > 62, you are
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3920 expected to know what you're up to.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3921 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3922 int s_mp_tovalue(char ch, int r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3923 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3924 int val, xch;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3925
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3926 if(r > 36)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3927 xch = ch;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3928 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3929 xch = toupper(ch);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3930
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3931 if(isdigit(xch))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3932 val = xch - '0';
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3933 else if(isupper(xch))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3934 val = xch - 'A' + 10;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3935 else if(islower(xch))
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3936 val = xch - 'a' + 36;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3937 else if(xch == '+')
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3938 val = 62;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3939 else if(xch == '/')
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3940 val = 63;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3941 else
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3942 return -1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3943
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3944 if(val < 0 || val >= r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3945 return -1;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3946
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3947 return val;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3948
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3949 } /* end s_mp_tovalue() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3950
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3951 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3952
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3953 /* {{{ s_mp_todigit(val, r, low) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3954
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3955 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3956 Convert val to a radix-r digit, if possible. If val is out of range
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3957 for r, returns zero. Otherwise, returns an ASCII character denoting
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3958 the value in the given radix.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3959
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3960 The results may be odd if you use a radix < 2 or > 64, you are
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3961 expected to know what you're doing.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3962 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3963
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3964 char s_mp_todigit(int val, int r, int low)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3965 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3966 char ch;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3967
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3968 if(val < 0 || val >= r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3969 return 0;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3970
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3971 ch = s_dmap_1[val];
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3972
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3973 if(r <= 36 && low)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3974 ch = tolower(ch);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3975
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3976 return ch;
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3977
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3978 } /* end s_mp_todigit() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3979
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3980 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3981
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3982 /* {{{ s_mp_outlen(bits, radix) */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3983
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3984 /*
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3985 Return an estimate for how long a string is needed to hold a radix
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3986 r representation of a number with 'bits' significant bits.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3987
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3988 Does not include space for a sign or a NUL terminator.
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3989 */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3990 int s_mp_outlen(int bits, int r)
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3991 {
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3992 return (int)((double)bits * LOG_V_2(r) + 0.5);
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3993
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3994 } /* end s_mp_outlen() */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3995
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3996 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3997
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3998 /* }}} */
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
3999
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
4000 /*------------------------------------------------------------------------*/
672e2d392a73 [gaim-migrate @ 14563]
Christopher O'Brien <siege@pidgin.im>
parents:
diff changeset
4001 /* HERE THERE BE DRAGONS */

mercurial