T MP_mul(T z, T x, T y) { int sx, sy; assert(x); assert(y); assert(z); sx = sign(x); sy = sign(y); if (sx) { XP_neg(nbytes, tmp[0], x, 1); x = tmp[0]; x[nbytes-1] &= msb; } if (sy) { XP_neg(nbytes, tmp[1], y, 1); y = tmp[1]; y[nbytes-1] &= msb; } memset(tmp[3], '\0', 2*nbytes); XP_mul(tmp[3], nbytes, x, nbytes, y); if (sx != sy) XP_neg(nbytes, z, tmp[3], 1); else memcpy(z, tmp[3], nbytes); z[nbytes-1] &= msb; { int i; if (tmp[3][nbytes-1]&~msb) RAISE(MP_Overflow); for (i = 0; i < nbytes; i++) if (tmp[3][i+nbytes] != 0) RAISE(MP_Overflow); } if (sx == sy && sign(z)) RAISE(MP_Overflow); return z; }
T MP_mul2u(T z, T x, T y) { assert(x); assert(y); assert(z); memset(tmp[3], '\0', 2*nbytes); XP_mul(tmp[3], nbytes, x, nbytes, y); memcpy(z, tmp[3], (2*nbits - 1)/8 + 1); return z; }
T AP_mul(T x, T y) { T z; assert(x); assert(y); z = mk(x->ndigits + y->ndigits); XP_mul(z->digits, x->ndigits, x->digits, y->ndigits, y->digits); normalize(z, z->size); z->sign = iszero(z) || ((x->sign^y->sign) == 0) ? 1 : -1; return z; }
T MP_mulu(T z, T x, T y) { assert(x); assert(y); assert(z); memset(tmp[3], '\0', 2*nbytes); XP_mul(tmp[3], nbytes, x, nbytes, y); memcpy(z, tmp[3], nbytes); z[nbytes-1] &= msb; { int i; if (tmp[3][nbytes-1]&~msb) RAISE(MP_Overflow); for (i = 0; i < nbytes; i++) if (tmp[3][i+nbytes] != 0) RAISE(MP_Overflow); } return z; }
T MP_mul2(T z, T x, T y) { int sx, sy; assert(x); assert(y); assert(z); sx = sign(x); sy = sign(y); if (sx) { XP_neg(nbytes, tmp[0], x, 1); x = tmp[0]; x[nbytes-1] &= msb; } if (sy) { XP_neg(nbytes, tmp[1], y, 1); y = tmp[1]; y[nbytes-1] &= msb; } memset(tmp[3], '\0', 2*nbytes); XP_mul(tmp[3], nbytes, x, nbytes, y); if (sx != sy) XP_neg((2*nbits - 1)/8 + 1, z, tmp[3], 1); else memcpy(z, tmp[3], (2*nbits - 1)/8 + 1); return z; }