// EGPublicKey::CopyFromPrivateKey
// Copies public key from a private key.  Existing key (if any) is replaced.  This
// method takes the binary rep of the private key and drops the private portion
// to generate the public key.
void
EGPublicKey::CopyFromPrivateKey(const EGPrivateKey& theKeyR)
{
	ClearLocal();

	try
	{
		ByteQueue aPrivQueue;
		aPrivQueue.Put(theKeyR.GetKey(), theKeyR.GetKeyLen());
		aPrivQueue.Close();

		ElGamalVerifier aKey(aPrivQueue);
		ByteQueue       aPubQueue;
		aKey.DEREncode(aPubQueue);
		aPubQueue.Close();

		AllocKeyBuf(aPubQueue.MaxRetrieveable());
		aPubQueue.Get(mKey, mKeyLen);
	}
	catch (Exception& anEx)
	{
		WDBG_AH("EGPublicKey::CopyFromPrivateKey Caught CryptoLib exception: " << anEx.what());
#ifndef _WONCRYPT_NOEXCEPTIONS
		throw WONCrypt::CryptException(WONCommon::ExCryptoLib, __LINE__, __FILE__, anEx.what());
#else
		Invalidate();
#endif
	}
}
// EGPublicKey::Dump
// Streaming method.  Outputs key to specfied stream.  Outputs key length followed
// by each factor of the key.
void
EGPublicKey::Dump(std::ostream& os) const
{
	// Output KeyLen followed by P, G, and Y
	try
	{
		ByteQueue aQueue;
		aQueue.Put(mKey, mKeyLen);
		aQueue.Close();

		Integer            p, q, g, y;
		BERSequenceDecoder aDecoder(aQueue);
		p.BERDecode(aDecoder);
		q.BERDecode(aDecoder);
		g.BERDecode(aDecoder);
		y.BERDecode(aDecoder);
		os << "(Len=" << mKeyLen << " P=" << p << " Q=" << q << " G=" << g
		   << " Y=" << y << ')';
	}
	catch (Exception& anEx)
	{
		WDBG_AH("EGPublicKey::Dump Caught CryptoLib exception: " << anEx.what());
		os << "(EGPublicKey Exception: " << anEx.what() << ')';
	}
}
// EGPublicKey::AllocateSig
// Allocates the mSigP member if needed.  Feeds binary rep of key into the
// ElGamalVerifier class from Crypto++.
void
EGPublicKey::AllocateSig() const
{
	WTRACE("EGPublicKey::AllocateSig");
	if (! mSigP)
	{
		WDBG_LL("EGPublicKey::AllocateSig Allocating crypt object.");
		ByteQueue aQueue;
		aQueue.Put(mKey, mKeyLen);
		aQueue.Close();
		mSigP = new ElGamalVerifier(aQueue);
	}
}
// EGPublicKey::AllocateCrypt
// Allocates the mCryptP member if needed.  Manually decodes binary rep into factors
// and feeds appropriate factor to the ElGamalEncryptor class from Crypto++.
void
EGPublicKey::AllocateCrypt() const
{
	WTRACE("EGPublicKey::AllocateCrypt");
	if (! mCryptP)
	{
		WDBG_LL("EGPublicKey::AllocateCrypt Allocating crypt object.");
		ByteQueue aQueue;
		aQueue.Put(mKey, mKeyLen);
		aQueue.Close();

		// *HACK*
		// Manually build the ElGamalEncryptor object.  See notes at
		// top of this file.
		Integer p, q, g, y;
		BERSequenceDecoder seq(aQueue);
		p.BERDecode(seq);
		q.BERDecode(seq);
		g.BERDecode(seq);
		y.BERDecode(seq);
		mCryptP = new ElGamalEncryptor(p, g, y);
	}
}