Exemplo n.º 1
0
Integer InvertibleRabinFunction::CalculateInverse(const Integer &in) const
{
	DoQuickSanityCheck();

	Integer cp=in%m_p, cq=in%m_q;

	int jp = Jacobi(cp, m_p);
	int jq = Jacobi(cq, m_q);

	if (jq==-1)
	{
		cp = cp*EuclideanMultiplicativeInverse(m_r, m_p)%m_p;
		cq = cq*EuclideanMultiplicativeInverse(m_r, m_q)%m_q;
	}

	if (jp==-1)
	{
		cp = cp*EuclideanMultiplicativeInverse(m_s, m_p)%m_p;
		cq = cq*EuclideanMultiplicativeInverse(m_s, m_q)%m_q;
	}

	cp = ModularSquareRoot(cp, m_p);
	cq = ModularSquareRoot(cq, m_q);

	if (jp==-1)
		cp = m_p-cp;

	Integer out = CRT(cq, m_q, cp, m_p, m_u);

	if ((jq==-1 && out.IsEven()) || (jq==1 && out.IsOdd()))
		out = m_n-out;

	return out;
}
Exemplo n.º 2
0
Integer InvertibleRabinFunction::CalculateInverse(const Integer &in) const
{
	Integer cp=in%p, cq=in%q;

	int jp = Jacobi(cp, p);
	int jq = Jacobi(cq, q);

	if (jq==-1)
	{
		cp = cp*EuclideanMultiplicativeInverse(r, p)%p;
		cq = cq*EuclideanMultiplicativeInverse(r, q)%q;
	}

	if (jp==-1)
	{
		cp = cp*EuclideanMultiplicativeInverse(s, p)%p;
		cq = cq*EuclideanMultiplicativeInverse(s, q)%q;
	}

	cp = ModularSquareRoot(cp, p);
	cq = ModularSquareRoot(cq, q);

	if (jp==-1)
		cp = p-cp;

	Integer out = CRT(cq, q, cp, p, u);

	if ((jq==-1 && out.IsEven()) || (jq==1 && out.IsOdd()))
		out = n-out;

	return out;
}
Exemplo n.º 3
0
// generate a random private key
InvertableRSAFunction::InvertableRSAFunction(RandomNumberGenerator &rng, unsigned int keybits, const Integer &eStart)
{
	assert(keybits >= 16);
	// generate 2 random primes of suitable size
	if (keybits%2==0)
	{
		const Integer minP = Integer(182) << (keybits/2-8);
		const Integer maxP = Integer::Power2(keybits/2)-1;
		p.Randomize(rng, minP, maxP, Integer::PRIME);
		q.Randomize(rng, minP, maxP, Integer::PRIME);
	}
	else
	{
		const Integer minP = Integer::Power2((keybits-1)/2);
		const Integer maxP = Integer(181) << ((keybits+1)/2-8);
		p.Randomize(rng, minP, maxP, Integer::PRIME);
		q.Randomize(rng, minP, maxP, Integer::PRIME);
	}

	// pre-calculate some other data for faster speed
	const Integer lcm = LCM(p-1, q-1);
	// make sure e starts odd
	for (e = eStart+(1-eStart%2); GCD(e, lcm)!=1; ++e, ++e);
	d = EuclideanMultiplicativeInverse(e, lcm);
	dp = d % (p-1);
	dq = d % (q-1);
	u = EuclideanMultiplicativeInverse(q, p);
	n = p * q;
	assert(n.BitCount() == keybits);
}
Exemplo n.º 4
0
Integer ModularRoot(const Integer &a, const Integer &e,
					const Integer &p, const Integer &q)
{
	Integer dp = EuclideanMultiplicativeInverse(e, p-1);
	Integer dq = EuclideanMultiplicativeInverse(e, q-1);
	Integer u = EuclideanMultiplicativeInverse(p, q);
	assert(!!dp && !!dq && !!u);
	return ModularRoot(a, dp, dq, p, q, u);
}
Exemplo n.º 5
0
void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
{
	int modulusSize = 2048;
	alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);

	ASSERT( modulusSize >= 16 );

	m_e = alg.GetValueWithDefault("PublicExponent", Integer(17));

	ASSERT( m_e >= 3 );
	ASSERT( !m_e.IsEven() );

	RSAPrimeSelector selector(m_e);
	const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize)
		("PointerToPrimeSelector", selector.GetSelectorPointer());
	m_p.GenerateRandom(rng, primeParam);
	m_q.GenerateRandom(rng, primeParam);

	m_d = EuclideanMultiplicativeInverse(m_e, LCM(m_p-1, m_q-1));
	assert(m_d.IsPositive());

	m_dp = m_d % (m_p-1);
	m_dq = m_d % (m_q-1);
	m_n = m_p * m_q;
	m_u = m_q.InverseMod(m_p);
}
Exemplo n.º 6
0
void ElGamalDecryptor::RawDecrypt(const Integer &a, const Integer &b, Integer &m) const
{
	if (x.BitCount()+20 < p.BitCount())	// if x is short
		m = b * EuclideanMultiplicativeInverse(a_exp_b_mod_c(a, x, p), p) % p;
	else	// save a multiplicative inverse calculation
		m = b * a_exp_b_mod_c(a, p-1-x, p) % p;
}
Exemplo n.º 7
0
BlumGoldwasserPrivateKey::BlumGoldwasserPrivateKey(const Integer &n, const Integer &p, const Integer &q, const Integer &u)
	: BlumGoldwasserPublicKey(n),
	  p(p), q(q), u(u)
{
	assert(n == p*q);
	assert(u == EuclideanMultiplicativeInverse(p, q));
}
Exemplo n.º 8
0
Integer InvertibleRabinFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &in) const
{
	DoQuickSanityCheck();

	ModularArithmetic modn(m_n);
	Integer r(rng, Integer::One(), m_n - Integer::One());
	r = modn.Square(r);
	Integer r2 = modn.Square(r);
	Integer c = modn.Multiply(in, r2);		// blind

	Integer cp=c%m_p, cq=c%m_q;

	int jp = Jacobi(cp, m_p);
	int jq = Jacobi(cq, m_q);

	if (jq==-1)
	{
		cp = cp*EuclideanMultiplicativeInverse(m_r, m_p)%m_p;
		cq = cq*EuclideanMultiplicativeInverse(m_r, m_q)%m_q;
	}

	if (jp==-1)
	{
		cp = cp*EuclideanMultiplicativeInverse(m_s, m_p)%m_p;
		cq = cq*EuclideanMultiplicativeInverse(m_s, m_q)%m_q;
	}

	cp = ModularSquareRoot(cp, m_p);
	cq = ModularSquareRoot(cq, m_q);

	if (jp==-1)
		cp = m_p-cp;

	Integer out = CRT(cq, m_q, cp, m_p, m_u);

	out = modn.Divide(out, r);	// unblind

	if ((jq==-1 && out.IsEven()) || (jq==1 && out.IsOdd()))
		out = m_n-out;

	return out;
}
Exemplo n.º 9
0
Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u)
{
	Integer d = (m*m-4);
	Integer p2, q2;
	#pragma omp parallel
		#pragma omp sections
		{
			#pragma omp section
			{
				p2 = p-Jacobi(d,p);
				p2 = Lucas(EuclideanMultiplicativeInverse(e,p2), m, p);
			}
			#pragma omp section
			{
				q2 = q-Jacobi(d,q);
				q2 = Lucas(EuclideanMultiplicativeInverse(e,q2), m, q);
			}
		}
	return CRT(p2, p, q2, q, u);
}
Exemplo n.º 10
0
BlumGoldwasserPrivateKey::BlumGoldwasserPrivateKey(BufferedTransformation &bt)
{
	BERSequenceDecoder seq(bt);
	n.BERDecode(seq);
	modulusLen = n.ByteCount();

	p.BERDecode(seq);
	q.BERDecode(seq);
	u.BERDecode(seq);

	assert(n == p*q);
	assert(u == EuclideanMultiplicativeInverse(p, q));
}
Exemplo n.º 11
0
void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits)
{
	CRYPTOPP_ASSERT(qbits > 9);	// no primes exist for pbits = 10, qbits = 9
	CRYPTOPP_ASSERT(pbits > qbits);

	const Integer minQ = Integer::Power2(qbits - 1);
	const Integer maxQ = Integer::Power2(qbits) - 1;
	const Integer minP = Integer::Power2(pbits - 1);
	const Integer maxP = Integer::Power2(pbits) - 1;

top:

	Integer r1, r2;
	do
	{
		(void)q.Randomize(rng, minQ, maxQ, Integer::PRIME, 7, 12);
		// Solution always exists because q === 7 mod 12.
		(void)SolveModularQuadraticEquation(r1, r2, 1, -1, 1, q);
		// I believe k_i, r1 and r2 are being used slightly different than the
		// paper's algorithm. I believe it is leading to the failed asserts.
		// Just make the assert part of the condition.
		if(!p.Randomize(rng, minP, maxP, Integer::PRIME, CRT(rng.GenerateBit() ?
			r1 : r2, q, 2, 3, EuclideanMultiplicativeInverse(p, 3)), 3 * q)) { continue; }
	} while (((p % 3U) != 2) || (((p.Squared() - p + 1) % q).NotZero()));

	// CRYPTOPP_ASSERT((p % 3U) == 2);
	// CRYPTOPP_ASSERT(((p.Squared() - p + 1) % q).IsZero());

	GFP2_ONB<ModularArithmetic> gfp2(p);
	GFP2Element three = gfp2.ConvertIn(3), t;

	while (true)
	{
		g.c1.Randomize(rng, Integer::Zero(), p-1);
		g.c2.Randomize(rng, Integer::Zero(), p-1);
		t = XTR_Exponentiate(g, p+1, p);
		if (t.c1 == t.c2)
			continue;
		g = XTR_Exponentiate(g, (p.Squared()-p+1)/q, p);
		if (g != three)
			break;
	}

	if (XTR_Exponentiate(g, q, p) != three)
		goto top;

	// CRYPTOPP_ASSERT(XTR_Exponentiate(g, q, p) == three);
}
Exemplo n.º 12
0
// generate a random private key
InvertibleRabinFunction::InvertibleRabinFunction(RandomNumberGenerator &rng, unsigned int keybits)
{
	assert(keybits >= 16);
	// generate 2 random primes of suitable size
	if (keybits%2==0)
	{
		const Integer minP = Integer(182) << (keybits/2-8);
		const Integer maxP = Integer::Power2(keybits/2)-1;
		p.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
		q.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
	}
	else
	{
		const Integer minP = Integer::Power2((keybits-1)/2);
		const Integer maxP = Integer(181) << ((keybits+1)/2-8);
		p.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
		q.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
	}

	bool rFound=false, sFound=false;
	Integer t=2;
	while (!(rFound && sFound))
	{
		int jp = Jacobi(t, p);
		int jq = Jacobi(t, q);

		if (!rFound && jp==1 && jq==-1)
		{
			r = t;
			rFound = true;
		}

		if (!sFound && jp==-1 && jq==1)
		{
			s = t;
			sFound = true;
		}

		++t;
	}

	n = p * q;
	assert(n.BitCount() == keybits);
	u = EuclideanMultiplicativeInverse(q, p);
	assert(u*q%p==1);
}
Exemplo n.º 13
0
Arquivo: rsa.cpp Projeto: acat/emule
void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
{
	int modulusSize = 2048;
	alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);

	if (modulusSize < 16)
		throw InvalidArgument("InvertibleRSAFunction: specified modulus size is too small");

	m_e = alg.GetValueWithDefault("PublicExponent", Integer(17));

	if (m_e < 3 || m_e.IsEven())
		throw InvalidArgument("InvertibleRSAFunction: invalid public exponent");

	RSAPrimeSelector selector(m_e);
	const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize)
		("PointerToPrimeSelector", selector.GetSelectorPointer());
	m_p.GenerateRandom(rng, primeParam);
	m_q.GenerateRandom(rng, primeParam);

	m_d = EuclideanMultiplicativeInverse(m_e, LCM(m_p-1, m_q-1));
	assert(m_d.IsPositive());

	m_dp = m_d % (m_p-1);
	m_dq = m_d % (m_q-1);
	m_n = m_p * m_q;
	m_u = m_q.InverseMod(m_p);

	if (FIPS_140_2_ComplianceEnabled())
	{
		RSASS<PKCS1v15, SHA>::Signer signer(*this);
		RSASS<PKCS1v15, SHA>::Verifier verifier(signer);
		SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);

		RSAES<OAEP<SHA> >::Decryptor decryptor(*this);
		RSAES<OAEP<SHA> >::Encryptor encryptor(decryptor);
		EncryptionPairwiseConsistencyTest_FIPS_140_Only(encryptor, decryptor);
	}
}
Exemplo n.º 14
0
// generate a random private key
BlumGoldwasserPrivateKey::BlumGoldwasserPrivateKey(RandomNumberGenerator &rng, unsigned int keybits)
{
	assert(keybits >= 16);
	// generate 2 random primes of suitable size
	if (keybits%2==0)
	{
		const Integer minP = Integer(182) << (keybits/2-8);
		const Integer maxP = Integer::Power2(keybits/2)-1;
		p.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
		q.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
	}
	else
	{
		const Integer minP = Integer::Power2((keybits-1)/2);
		const Integer maxP = Integer(181) << ((keybits+1)/2-8);
		p.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
		q.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
	}

	n = p*q;
	u = EuclideanMultiplicativeInverse(p, q);
	modulusLen = n.ByteCount();
}
Exemplo n.º 15
0
void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits)
{
	assert(qbits > 9);	// no primes exist for pbits = 10, qbits = 9
	assert(pbits > qbits);

	const Integer minQ = Integer::Power2(qbits - 1);
	const Integer maxQ = Integer::Power2(qbits) - 1;
	const Integer minP = Integer::Power2(pbits - 1);
	const Integer maxP = Integer::Power2(pbits) - 1;

	Integer r1, r2;
	do
	{
		bool qFound = q.Randomize(rng, minQ, maxQ, Integer::PRIME, 7, 12);
		CRYPTOPP_UNUSED(qFound); assert(qFound);
		bool solutionsExist = SolveModularQuadraticEquation(r1, r2, 1, -1, 1, q);
		CRYPTOPP_UNUSED(solutionsExist); assert(solutionsExist);
	} while (!p.Randomize(rng, minP, maxP, Integer::PRIME, CRT(rng.GenerateBit()?r1:r2, q, 2, 3, EuclideanMultiplicativeInverse(p, 3)), 3*q));
	assert(((p.Squared() - p + 1) % q).IsZero());

	GFP2_ONB<ModularArithmetic> gfp2(p);
	GFP2Element three = gfp2.ConvertIn(3), t;

	while (true)
	{
		g.c1.Randomize(rng, Integer::Zero(), p-1);
		g.c2.Randomize(rng, Integer::Zero(), p-1);
		t = XTR_Exponentiate(g, p+1, p);
		if (t.c1 == t.c2)
			continue;
		g = XTR_Exponentiate(g, (p.Squared()-p+1)/q, p);
		if (g != three)
			break;
	}
	assert(XTR_Exponentiate(g, q, p) == three);
}
Exemplo n.º 16
0
Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q)
{
	return InverseLucas(e, m, p, q, EuclideanMultiplicativeInverse(p, q));
}
Exemplo n.º 17
0
Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q)
{
	return CRT(xp, p, xq, q, EuclideanMultiplicativeInverse(p, q));
}