1*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 2*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 3*7c478bd9Sstevel@tonic-gate 4*7c478bd9Sstevel@tonic-gate 5*7c478bd9Sstevel@tonic-gate /* 6*7c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 7*7c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 8*7c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 9*7c478bd9Sstevel@tonic-gate */ 10*7c478bd9Sstevel@tonic-gate /* Portions Copyright(c) 1988, Sun Microsystems Inc. */ 11*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 12*7c478bd9Sstevel@tonic-gate 13*7c478bd9Sstevel@tonic-gate /* 14*7c478bd9Sstevel@tonic-gate * Copyright (c) 1997, by Sun Microsystems, Inc. 15*7c478bd9Sstevel@tonic-gate * All rights reserved. 16*7c478bd9Sstevel@tonic-gate */ 17*7c478bd9Sstevel@tonic-gate 18*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */ 19*7c478bd9Sstevel@tonic-gate 20*7c478bd9Sstevel@tonic-gate /* LINTLIBRARY */ 21*7c478bd9Sstevel@tonic-gate 22*7c478bd9Sstevel@tonic-gate #include <mp.h> 23*7c478bd9Sstevel@tonic-gate #include "libmp.h" 24*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 25*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate static void 28*7c478bd9Sstevel@tonic-gate m_add(MINT *a, MINT *b, MINT *c) 29*7c478bd9Sstevel@tonic-gate { 30*7c478bd9Sstevel@tonic-gate int carry, i; 31*7c478bd9Sstevel@tonic-gate int x; 32*7c478bd9Sstevel@tonic-gate short *cval; 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate cval = _mp_xalloc(a->len + 1, "m_add"); 35*7c478bd9Sstevel@tonic-gate carry = 0; 36*7c478bd9Sstevel@tonic-gate for (i = 0; i < b->len; i++) { 37*7c478bd9Sstevel@tonic-gate x = carry + a->val[i] + b->val[i]; 38*7c478bd9Sstevel@tonic-gate if (x & 0100000) { 39*7c478bd9Sstevel@tonic-gate carry = 1; 40*7c478bd9Sstevel@tonic-gate cval[i] = (short)(x & 077777); 41*7c478bd9Sstevel@tonic-gate } else { 42*7c478bd9Sstevel@tonic-gate carry = 0; 43*7c478bd9Sstevel@tonic-gate cval[i] = (short)x; 44*7c478bd9Sstevel@tonic-gate } 45*7c478bd9Sstevel@tonic-gate } 46*7c478bd9Sstevel@tonic-gate for (; i < a->len; i++) { 47*7c478bd9Sstevel@tonic-gate x = carry + a->val[i]; 48*7c478bd9Sstevel@tonic-gate if (x & 0100000) { 49*7c478bd9Sstevel@tonic-gate cval[i] = (short)(x & 077777); 50*7c478bd9Sstevel@tonic-gate } else { 51*7c478bd9Sstevel@tonic-gate carry = 0; 52*7c478bd9Sstevel@tonic-gate cval[i] = (short)x; 53*7c478bd9Sstevel@tonic-gate } 54*7c478bd9Sstevel@tonic-gate } 55*7c478bd9Sstevel@tonic-gate if (carry == 1) { 56*7c478bd9Sstevel@tonic-gate cval[i] = 1; 57*7c478bd9Sstevel@tonic-gate c->len = i + 1; 58*7c478bd9Sstevel@tonic-gate } else { 59*7c478bd9Sstevel@tonic-gate c->len = a->len; 60*7c478bd9Sstevel@tonic-gate } 61*7c478bd9Sstevel@tonic-gate c->val = cval; 62*7c478bd9Sstevel@tonic-gate if (c->len == 0) { 63*7c478bd9Sstevel@tonic-gate free(cval); 64*7c478bd9Sstevel@tonic-gate } 65*7c478bd9Sstevel@tonic-gate } 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate void 68*7c478bd9Sstevel@tonic-gate mp_madd(MINT *a, MINT *b, MINT *c) 69*7c478bd9Sstevel@tonic-gate { 70*7c478bd9Sstevel@tonic-gate MINT x, y; 71*7c478bd9Sstevel@tonic-gate int sign; 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate x.len = y.len = 0; 74*7c478bd9Sstevel@tonic-gate _mp_move(a, &x); 75*7c478bd9Sstevel@tonic-gate _mp_move(b, &y); 76*7c478bd9Sstevel@tonic-gate _mp_xfree(c); 77*7c478bd9Sstevel@tonic-gate sign = 1; 78*7c478bd9Sstevel@tonic-gate if (x.len >= 0) { 79*7c478bd9Sstevel@tonic-gate if (y.len >= 0) { 80*7c478bd9Sstevel@tonic-gate if (x.len >= y.len) { 81*7c478bd9Sstevel@tonic-gate m_add(&x, &y, c); 82*7c478bd9Sstevel@tonic-gate } else { 83*7c478bd9Sstevel@tonic-gate m_add(&y, &x, c); 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate } else { 86*7c478bd9Sstevel@tonic-gate y.len = -y.len; 87*7c478bd9Sstevel@tonic-gate mp_msub(&x, &y, c); 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate } else { 90*7c478bd9Sstevel@tonic-gate if (y.len <= 0) { 91*7c478bd9Sstevel@tonic-gate x.len = -x.len; 92*7c478bd9Sstevel@tonic-gate y.len = -y.len; 93*7c478bd9Sstevel@tonic-gate sign = -1; 94*7c478bd9Sstevel@tonic-gate mp_madd(&x, &y, c); 95*7c478bd9Sstevel@tonic-gate } else { 96*7c478bd9Sstevel@tonic-gate x.len = -x.len; 97*7c478bd9Sstevel@tonic-gate mp_msub(&y, &x, c); 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate c->len = sign * c->len; 101*7c478bd9Sstevel@tonic-gate _mp_xfree(&x); 102*7c478bd9Sstevel@tonic-gate _mp_xfree(&y); 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate static void 106*7c478bd9Sstevel@tonic-gate m_sub(MINT *a, MINT *b, MINT *c) 107*7c478bd9Sstevel@tonic-gate { 108*7c478bd9Sstevel@tonic-gate int x, i; 109*7c478bd9Sstevel@tonic-gate int borrow; 110*7c478bd9Sstevel@tonic-gate short one; 111*7c478bd9Sstevel@tonic-gate MINT mone; 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate one = 1; 114*7c478bd9Sstevel@tonic-gate mone.len = 1; 115*7c478bd9Sstevel@tonic-gate mone.val = &one; 116*7c478bd9Sstevel@tonic-gate c->val = _mp_xalloc(a->len, "m_sub"); 117*7c478bd9Sstevel@tonic-gate borrow = 0; 118*7c478bd9Sstevel@tonic-gate for (i = 0; i < b->len; i++) { 119*7c478bd9Sstevel@tonic-gate x = borrow + a->val[i] - b->val[i]; 120*7c478bd9Sstevel@tonic-gate if (x & 0100000) { 121*7c478bd9Sstevel@tonic-gate borrow = -1; 122*7c478bd9Sstevel@tonic-gate c->val[i] = (short)(x & 077777); 123*7c478bd9Sstevel@tonic-gate } else { 124*7c478bd9Sstevel@tonic-gate borrow = 0; 125*7c478bd9Sstevel@tonic-gate c->val[i] = (short)x; 126*7c478bd9Sstevel@tonic-gate } 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate for (; i < a->len; i++) { 129*7c478bd9Sstevel@tonic-gate x = borrow + a->val[i]; 130*7c478bd9Sstevel@tonic-gate if (x & 0100000) { 131*7c478bd9Sstevel@tonic-gate c->val[i] = (short)(x & 077777); 132*7c478bd9Sstevel@tonic-gate } else { 133*7c478bd9Sstevel@tonic-gate borrow = 0; 134*7c478bd9Sstevel@tonic-gate c->val[i] = (short)x; 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate if (borrow < 0) { 138*7c478bd9Sstevel@tonic-gate for (i = 0; i < a->len; i++) { 139*7c478bd9Sstevel@tonic-gate c->val[i] ^= 077777; 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate c->len = a->len; 142*7c478bd9Sstevel@tonic-gate mp_madd(c, &mone, c); 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate for (i = a->len-1; i >= 0; --i) { 145*7c478bd9Sstevel@tonic-gate if (c->val[i] > 0) { 146*7c478bd9Sstevel@tonic-gate if (borrow == 0) { 147*7c478bd9Sstevel@tonic-gate c->len = i + 1; 148*7c478bd9Sstevel@tonic-gate } else { 149*7c478bd9Sstevel@tonic-gate c->len = -i - 1; 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate return; 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate free(c->val); 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate void 158*7c478bd9Sstevel@tonic-gate mp_msub(MINT *a, MINT *b, MINT *c) 159*7c478bd9Sstevel@tonic-gate { 160*7c478bd9Sstevel@tonic-gate MINT x, y; 161*7c478bd9Sstevel@tonic-gate int sign; 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate x.len = y.len = 0; 164*7c478bd9Sstevel@tonic-gate _mp_move(a, &x); 165*7c478bd9Sstevel@tonic-gate _mp_move(b, &y); 166*7c478bd9Sstevel@tonic-gate _mp_xfree(c); 167*7c478bd9Sstevel@tonic-gate sign = 1; 168*7c478bd9Sstevel@tonic-gate if (x.len >= 0) { 169*7c478bd9Sstevel@tonic-gate if (y.len >= 0) { 170*7c478bd9Sstevel@tonic-gate if (x.len >= y.len) { 171*7c478bd9Sstevel@tonic-gate m_sub(&x, &y, c); 172*7c478bd9Sstevel@tonic-gate } else { 173*7c478bd9Sstevel@tonic-gate sign = -1; 174*7c478bd9Sstevel@tonic-gate mp_msub(&y, &x, c); 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate } else { 177*7c478bd9Sstevel@tonic-gate y.len = -y.len; 178*7c478bd9Sstevel@tonic-gate mp_madd(&x, &y, c); 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate } else { 181*7c478bd9Sstevel@tonic-gate if (y.len <= 0) { 182*7c478bd9Sstevel@tonic-gate x.len = -x.len; 183*7c478bd9Sstevel@tonic-gate y.len = -y.len; 184*7c478bd9Sstevel@tonic-gate mp_msub(&y, &x, c); 185*7c478bd9Sstevel@tonic-gate } else { 186*7c478bd9Sstevel@tonic-gate x.len = -x.len; 187*7c478bd9Sstevel@tonic-gate mp_madd(&x, &y, c); 188*7c478bd9Sstevel@tonic-gate sign = -1; 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate c->len = sign * c->len; 192*7c478bd9Sstevel@tonic-gate _mp_xfree(&x); 193*7c478bd9Sstevel@tonic-gate _mp_xfree(&y); 194*7c478bd9Sstevel@tonic-gate } 195