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