int main() { int i, j; int size = sizeof(a_l)/sizeof(int); for (j = 0; j < size; j++) { a_l[j] = rand() % MAXRANDINT; } precomputation(); computation(3, size); postcomputation(); return 0; }
void mexp(int k, mpz_t b[k], mpz_t e[k], mpz_t *m, mpz_t *r) { // Main multiexp alg from paper int i, j, jnew, J, l, precompindex, offset,km; unsigned det; int msb_set; unsigned bitlen, maxbitlen = 0; // Setup and precomputation bases = b; modulus = m; numberOfFactors = k; // Compute window size for (i = 0; i < k; i++) { bitlen = mpz_sizeinbase(e[i], 2); if (bitlen > maxbitlen) maxbitlen = bitlen; } // TODO: Make this more elegant double lmb = log(maxbitlen)/log(2); winSize = (int) ceil((lmb - 2*(log(lmb)/log(2))) / k); if(winSize <= 0) winSize =1; // Build up precomputation table precomputation(); km = k -1; mpz_set_ui(*r, 1); // Find maximal bit length of all exponents // Type conversion from unsigned to int. Only a problem for exponents // that have more binary digits than max(int). This is unlikely to occur in practice. // Maybe add check on arg to m_exp() to test for this possible problem? j = maxbitlen - 1; // A-while while (j >= 0) { // check if bit #maxbitlen is zero for all exponents // TODO: in the first iteraration this is the case by def of maxbitlen // -> can we skip first iteration to improve efficiency? msb_set = 0; for(i=0; i< k && msb_set == 0; i++) msb_set = mpz_tstbit(e[i], j); // B-if if (msb_set == 0) { mpz_powm_ui(*r, *r, 2, *m); j--; } // C-else else { if ( (j-winSize) > -1) jnew = j-winSize; else jnew = -1; J = jnew + 1; // D-while (is implemented as do-while) for(;;) { i = km; msb_set = 0; for(i=0; i< k && msb_set == 0; i++) msb_set = mpz_tstbit(e[i], j); if (msb_set == 0) J++; else break; } // E-for precompindex = 0; offset = winSize - (j - J) -1; for (i = km; i >= 0; i--) { // Compute access index into pre-computation table precompindex <<= offset; for (l = j; l >= J; l--) { precompindex <<= 1; precompindex = precompindex | mpz_tstbit(e[i], l); } } // F-while det = 1; det <<= ((j-J)+1); mpz_powm_ui(*r, *r,det, *m); j = J-1; mpz_mul(*r, *r, preCompTable[precompindex]); mpz_mod(*r, *r, *m); // G-while if (j > jnew) { det =1; det <<= (j-jnew); mpz_powm_ui(*r, *r,det, *m); j = jnew + 1; } } } freeMemory(); }