sfree(workspace);
Bignum bigmuladd(Bignum a, Bignum b, Bignum addend){    int alen = a[0], blen = b[0];    int mlen = (alen > blen ? alen : blen);    int rlen, i, maxspot;    BignumInt *workspace;    Bignum ret;    /* mlen space for a, mlen space for b, 2*mlen for result */    workspace = snewn(mlen * 4, BignumInt);    for (i = 0; i < mlen; i++) {	workspace[0 * mlen + i] = (mlen - i <= a[0] ? a[mlen - i] : 0);	workspace[1 * mlen + i] = (mlen - i <= b[0] ? b[mlen - i] : 0);    }    internal_mul(workspace + 0 * mlen, workspace + 1 * mlen,		 workspace + 2 * mlen, mlen);    /* now just copy the result back */    rlen = alen + blen + 1;    if (addend && rlen <= addend[0])	rlen = addend[0] + 1;    ret = newbn(rlen);    maxspot = 0;    for (i = 1; i <= ret[0]; i++) {	ret[i] = (i <= 2 * mlen ? workspace[4 * mlen - i] : 0);	if (ret[i] != 0)	    maxspot = i;    }    ret[0] = maxspot;    /* now add in the addend, if any */    if (addend) {	BignumDblInt carry = 0;	for (i = 1; i <= rlen; i++) {	    carry += (i <= ret[0] ? ret[i] : 0);	    carry += (i <= addend[0] ? addend[i] : 0);	    ret[i] = (BignumInt) carry & BIGNUM_INT_MASK;	    carry >>= BIGNUM_INT_BITS;	    if (ret[i] != 0 && i > maxspot)		maxspot = i;	}    }    ret[0] = maxspot;    return ret;}