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 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 * 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 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 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 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 * 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 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 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 * 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 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 * 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 249 mp_mfree(MINT *a) 250 { 251 _mp_xfree(a); 252 free(a); 253 } 254