int pqlen, mlen, i, j;
int pqlen, mlen, rlen, i, j;
Bignum modmul(Bignum p, Bignum q, Bignum mod){    unsigned short *a, *n, *m, *o;    int mshift;    int pqlen, mlen, i, j;    Bignum result;    /* Allocate m of size mlen, copy mod to m */    /* We use big endian internally */    mlen = mod[0];    m = smalloc(mlen * sizeof(unsigned short));    for (j = 0; j < mlen; j++) m[j] = mod[mod[0] - j];    /* Shift m left to make msb bit set */    for (mshift = 0; mshift < 15; mshift++)	if ((m[0] << mshift) & 0x8000) break;    if (mshift) {	for (i = 0; i < mlen - 1; i++)	    m[i] = (m[i] << mshift) | (m[i+1] >> (16-mshift));	m[mlen-1] = m[mlen-1] << mshift;    }    pqlen = (p[0] > q[0] ? p[0] : q[0]);    /* Allocate n of size pqlen, copy p to n */    n = smalloc(pqlen * sizeof(unsigned short));    i = pqlen - p[0];    for (j = 0; j < i; j++) n[j] = 0;    for (j = 0; j < p[0]; j++) n[i+j] = p[p[0] - j];    /* Allocate o of size pqlen, copy q to o */    o = smalloc(pqlen * sizeof(unsigned short));    i = pqlen - q[0];    for (j = 0; j < i; j++) o[j] = 0;    for (j = 0; j < q[0]; j++) o[i+j] = q[q[0] - j];    /* Allocate a of size 2*pqlen for result */    a = smalloc(2 * pqlen * sizeof(unsigned short));    /* Main computation */    internal_mul(n, o, a, pqlen);    internal_mod(a, pqlen*2, m, mlen, NULL, 0);    /* Fixup result in case the modulus was shifted */    if (mshift) {	for (i = 2*pqlen - mlen - 1; i < 2*pqlen - 1; i++)	    a[i] = (a[i] << mshift) | (a[i+1] >> (16-mshift));	a[2*pqlen-1] = a[2*pqlen-1] << mshift;	internal_mod(a, pqlen*2, m, mlen, NULL, 0);	for (i = 2*pqlen - 1; i >= 2*pqlen - mlen; i--)	    a[i] = (a[i] >> mshift) | (a[i-1] << (16-mshift));    }    /* Copy result to buffer */    result = newbn(mod[0]);    for (i = 0; i < mlen; i++)	result[result[0] - i] = a[i+2*pqlen-mlen];    while (result[0] > 1 && result[result[0]] == 0) result[0]--;    /* Free temporary arrays */    for (i = 0; i < 2*pqlen; i++) a[i] = 0; sfree(a);    for (i = 0; i < mlen; i++) m[i] = 0; sfree(m);    for (i = 0; i < pqlen; i++) n[i] = 0; sfree(n);    for (i = 0; i < pqlen; i++) o[i] = 0; sfree(o);    return result;}