1 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
2 /* All Rights Reserved */
3
4
5 /*
6 * Copyright (c) 1980 Regents of the University of California.
7 * All rights reserved. The Berkeley software License Agreement
8 * specifies the terms and conditions for redistribution.
9 */
10 /* Portions Copyright(c) 1988, Sun Microsystems Inc. */
11 /* All Rights Reserved */
12
13 /*
14 * Copyright (c) 1997, by Sun Microsystems, Inc.
15 * All rights reserved.
16 */
17
18 #include <stdio.h>
19 #include <mp.h>
20 #include <sys/types.h>
21 #include "libmp.h"
22 #include <stdlib.h>
23 #include <unistd.h>
24
25 void
_mp_move(MINT * a,MINT * b)26 _mp_move(MINT *a, MINT *b)
27 {
28 int i, j;
29
30 _mp_xfree(b);
31 b->len = a->len;
32 if ((i = a->len) < 0) {
33 i = -i;
34 }
35 if (i == 0) {
36 return;
37 }
38 b->val = _mp_xalloc(i, "_mp_move");
39 for (j = 0; j < i; j++) {
40 b->val[j] = a->val[j];
41 }
42 }
43
44 short *
_mp_xalloc(int nint,char * s __unused)45 _mp_xalloc(int nint, char *s __unused)
46 {
47 short *i;
48
49 i = malloc(sizeof (short) * ((unsigned)nint + 2)); /* ??? 2 ??? */
50 #ifdef DEBUG
51 (void) fprintf(stderr, "%s: %p\n", s, i);
52 #endif
53 if (i == NULL) {
54 _mp_fatal("mp: no free space");
55 }
56 return (i);
57 }
58
59 void
_mp_fatal(char * s)60 _mp_fatal(char *s)
61 {
62 (void) fprintf(stderr, "%s\n", s);
63 (void) fflush(stdout);
64 (void) sleep(2);
65 abort();
66 }
67
68 void
_mp_xfree(MINT * c)69 _mp_xfree(MINT *c)
70 {
71 #ifdef DBG
72 (void) fprintf(stderr, "xfree ");
73 #endif
74 if (c->len != 0) {
75 free(c->val);
76 c->len = 0;
77 }
78 }
79
80 void
_mp_mcan(MINT * a)81 _mp_mcan(MINT *a)
82 {
83 int i, j;
84
85 if ((i = a->len) == 0) {
86 return;
87 }
88 if (i < 0) {
89 i = -i;
90 }
91 for (j = i; j > 0 && a->val[j-1] == 0; j--)
92 ;
93 if (j == i) {
94 return;
95 }
96 if (j == 0) {
97 _mp_xfree(a);
98 return;
99 }
100 if (a->len > 0) {
101 a->len = j;
102 } else {
103 a->len = -j;
104 }
105 }
106
107
108 MINT *
mp_itom(short n)109 mp_itom(short n)
110 {
111 MINT *a;
112
113 a = malloc(sizeof (MINT));
114 if (n > 0) {
115 a->len = 1;
116 a->val = _mp_xalloc(1, "mp_itom1");
117 *a->val = n;
118 } else if (n < 0) {
119 a->len = -1;
120 a->val = _mp_xalloc(1, "mp_itom2");
121 *a->val = -n;
122 } else {
123 a->len = 0;
124 }
125 return (a);
126 }
127
128 int
mp_mcmp(MINT * a,MINT * b)129 mp_mcmp(MINT *a, MINT *b)
130 {
131 MINT c;
132 int res;
133
134 _mp_mcan(a);
135 _mp_mcan(b);
136 if (a->len != b->len) {
137 return (a->len - b->len);
138 }
139 c.len = 0;
140 mp_msub(a, b, &c);
141 res = c.len;
142 _mp_xfree(&c);
143 return (res);
144 }
145
146 /*
147 * Convert hex digit to binary value
148 */
149 static short
xtoi(char c)150 xtoi(char c)
151 {
152 if (c >= '0' && c <= '9') {
153 return (c - '0');
154 } else if (c >= 'a' && c <= 'f') {
155 return (c - 'a' + 10);
156 } else if (c >= 'A' && c <= 'F') {
157 return (c - 'A' + 10);
158 } else {
159 return (-1);
160 }
161 }
162
163
164 /*
165 * Convert hex key to MINT key
166 */
167 MINT *
mp_xtom(char * key)168 mp_xtom(char *key)
169 {
170 short digit;
171 MINT *m = mp_itom(0);
172 MINT *d;
173 MINT *sixteen;
174
175 sixteen = mp_itom(16);
176 for (; *key; key++) {
177 digit = xtoi(*key);
178 if (digit < 0) {
179 return (NULL);
180 }
181 d = mp_itom(digit);
182 mp_mult(m, sixteen, m);
183 mp_madd(m, d, m);
184 mp_mfree(d);
185 }
186 mp_mfree(sixteen);
187 return (m);
188 }
189
190 static char
itox(short d)191 itox(short d)
192 {
193 d &= 15;
194 if (d < 10) {
195 return ('0' + d);
196 } else {
197 return ('a' - 10 + d);
198 }
199 }
200
201 /*
202 * Convert MINT key to hex key
203 */
204 char *
mp_mtox(MINT * key)205 mp_mtox(MINT *key)
206 {
207 MINT *m = mp_itom(0);
208 MINT *zero = mp_itom(0);
209 short r;
210 char *p;
211 char c;
212 char *s;
213 char *hex;
214 int size;
215
216 #define BASEBITS (8 * (unsigned int)sizeof (short) - 1)
217
218 if (key->len >= 0) {
219 size = key->len;
220 } else {
221 size = -key->len;
222 }
223 hex = malloc((size_t)((size * BASEBITS + 3)) / 4 + (size ? 1 : 2));
224 if (hex == NULL) {
225 return (NULL);
226 }
227 _mp_move(key, m);
228 p = hex;
229 do {
230 mp_sdiv(m, 16, m, &r);
231 *p++ = itox(r);
232 } while (mp_mcmp(m, zero) != 0);
233 mp_mfree(m);
234 mp_mfree(zero);
235
236 *p = 0;
237 for (p--, s = hex; s < p; s++, p--) {
238 c = *p;
239 *p = *s;
240 *s = c;
241 }
242 return (hex);
243 }
244
245 /*
246 * Deallocate a multiple precision integer
247 */
248 void
mp_mfree(MINT * a)249 mp_mfree(MINT *a)
250 {
251 _mp_xfree(a);
252 free(a);
253 }
254