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 29void 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 */ 50short * 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 65void 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 74void 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 86void 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 114MINT * 115mp_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 134int 135mp_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 */ 155static short 156xtoi(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 */ 173MINT * 174mp_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 196static char 197itox(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 */ 210char * 211mp_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 */ 254void 255mp_mfree(MINT *a) 256{ 257 _mp_xfree(a); 258 free(a); 259} 260