Пример #1
0
uberzahl modexp_mm_crt(mm_t & mm1, mm_t & mm2, crt_t & crt, uberzahl base, uberzahl exp, uberzahl p, uberzahl q){
	if(!crt.initialized){
		crt.p_inverse = p.inverse(q);
    	crt.q_inverse = q.inverse(p);
    	crt.initialized = true;
	}
	return ( crt_helper(MONTGOMERY,mm1,base,exp,p,q, crt.q_inverse) + crt_helper(MONTGOMERY, mm2, base, exp, q, p, crt.p_inverse) ) % (p * q);
}
Пример #2
0
uberzahl modexp_crt(crt_t & crt, uberzahl base,  uberzahl exp, uberzahl p, uberzahl q){
    mm_t mm;
    if(!crt.initialized){
    	crt.p_inverse = p.inverse(q);
    	crt.q_inverse = q.inverse(p);
    	crt.initialized = true;
    }
	return ( crt_helper(CLASSIC,mm, base,exp,p,q,crt.q_inverse) + crt_helper(CLASSIC, mm, base, exp, q, p, crt.p_inverse) ) % (p * q);
}
Пример #3
0
//we don't have to bother with making sure that gcd(R,M) == 1 since M is odd.
uberzahl modexp_mm(mm_t & mm, uberzahl base, uberzahl exp, uberzahl M){
	if(!mm.initialized){
		mm.R = next_power(M);
		mm.Rbits = mm.R.bitLength();
		mm.Mprime = (mm.R-M.inverse(mm.R));
		uberzahl z("1");
		uberzahl t("2");
		mm.Rsq = modexp(mm.R,t,M);
		//mm.z_init = mm.R % M;
		mm.z_init = montgomery_reduction(mm.Rsq, M, mm.Mprime, mm.Rbits, mm.R);
		mm.initialized = true;
	}

	//convert into Montgomery space
	uberzahl z = mm.z_init;

	//According to Piazza post we don't even need to calculate the residues with mod
	if(base * mm.Rsq < mm.R*M)
		base = montgomery_reduction(base * mm.Rsq, M, mm.Mprime, mm.Rbits, mm.R);
	else
		base = base * mm.R % M;

	mediumType i = exp.bitLength() - 1;

	while(i >= 0) {
		z = montgomery_reduction(z * z, M, mm.Mprime, mm.Rbits, mm.R);
		if(exp.bit(i) == 1){
			z = montgomery_reduction(z * base , M, mm.Mprime, mm.Rbits, mm.R);
		}
		if(i == 0)
			break;
		i -= 1;
	}
	return montgomery_reduction(z, M, mm.Mprime, mm.Rbits, mm.R);
}
Пример #4
0
uberzahl chineseModExp2(uberzahl c, uberzahl a, uberzahl p, uberzahl q){ 
	//a^c mod pq
	auto start = chrono::steady_clock::now();
	
	uberzahl dp = c % (p-1);
	uberzahl dq = c % (q-1);

	uberzahl T = q.inverse(p);
	uberzahl S = p.inverse(q);

	uberzahl m1 = originalModExp(dp,a,p,1);
	uberzahl m2 = originalModExp(dq,a,q,1);
    
	uberzahl m = (m1*q*T + m2*p*S) % (p*q);

	auto current = chrono::steady_clock::now();
	auto elapsed = chrono::duration_cast<chrono::duration<double>>(current-start);
	double chrono_time = elapsed.count();
	cerr << "\tSqMult_CRT time: " << chrono_time << "\n"; 
    
	return m;
}