for (i = 0; i < 2*mlen; i++) a[i] = 0; free(a); for (i = 0; i < 2*mlen; i++) b[i] = 0; free(b); for (i = 0; i < mlen; i++) m[i] = 0; free(m); for (i = 0; i < mlen; i++) n[i] = 0; free(n);
for (i = 0; i < 2*mlen; i++) a[i] = 0; sfree(a); for (i = 0; i < 2*mlen; i++) b[i] = 0; sfree(b); for (i = 0; i < mlen; i++) m[i] = 0; sfree(m); for (i = 0; i < mlen; i++) n[i] = 0; sfree(n);
Bignum modpow(Bignum base, Bignum exp, Bignum mod){    unsigned short *a, *b, *n, *m;    int mshift;    int mlen, i, j;    Bignum result;    /* Allocate m of size mlen, copy mod to m */    /* We use big endian internally */    mlen = mod[0];    m = malloc(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;    }    /* Allocate n of size mlen, copy base to n */    n = malloc(mlen * sizeof(unsigned short));    i = mlen - base[0];    for (j = 0; j < i; j++) n[j] = 0;    for (j = 0; j < base[0]; j++) n[i+j] = base[base[0] - j];    /* Allocate a and b of size 2*mlen. Set a = 1 */    a = malloc(2 * mlen * sizeof(unsigned short));    b = malloc(2 * mlen * sizeof(unsigned short));    for (i = 0; i < 2*mlen; i++) a[i] = 0;    a[2*mlen-1] = 1;    /* Skip leading zero bits of exp. */    i = 0; j = 15;    while (i < exp[0] && (exp[exp[0] - i] & (1 << j)) == 0) {	j--;	if (j < 0) { i++; j = 15; }    }    /* Main computation */    while (i < exp[0]) {	while (j >= 0) {	    internal_mul(a + mlen, a + mlen, b, mlen);	    internal_mod(b, mlen*2, m, mlen, NULL, 0);	    if ((exp[exp[0] - i] & (1 << j)) != 0) {		internal_mul(b + mlen, n, a, mlen);		internal_mod(a, mlen*2, m, mlen, NULL, 0);	    } else {		unsigned short *t;		t = a;  a = b;  b = t;	    }	    j--;	}	i++; j = 15;    }    /* Fixup result in case the modulus was shifted */    if (mshift) {	for (i = mlen - 1; i < 2*mlen - 1; i++)	    a[i] = (a[i] << mshift) | (a[i+1] >> (16-mshift));	a[2*mlen-1] = a[2*mlen-1] << mshift;	internal_mod(a, mlen*2, m, mlen, NULL, 0);	for (i = 2*mlen - 1; i >= 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+mlen];    while (result[0] > 1 && result[result[0]] == 0) result[0]--;    /* Free temporary arrays */    for (i = 0; i < 2*mlen; i++) a[i] = 0; free(a);    for (i = 0; i < 2*mlen; i++) b[i] = 0; free(b);    for (i = 0; i < mlen; i++) m[i] = 0; free(m);    for (i = 0; i < mlen; i++) n[i] = 0; free(n);    return result;}