⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fipsalgt.cpp

📁 加密算法RSA
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// fipsalgt.cpp - written and placed in the public domain by Wei Dai

// This file implements the various algorithm tests needed to pass FIPS 140 validation.
// They're preserved here (commented out) in case Crypto++ needs to be revalidated.

#if 0
#ifndef CRYPTOPP_IMPORTS
#define CRYPTOPP_DEFAULT_NO_DLL
#endif
#include "dll.h"
#include "oids.h"

USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)

class LineBreakParser : public AutoSignaling<Bufferless<Filter> >
{
public:
	LineBreakParser(BufferedTransformation *attachment=NULL, byte lineEnd='\n')
		: m_lineEnd(lineEnd) {Detach(attachment);}

	size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
	{
		if (!blocking)
			throw BlockingInputOnly("LineBreakParser");
		
		unsigned int i, last = 0;
		for (i=0; i<length; i++)
		{
			if (begin[i] == m_lineEnd)
			{
				AttachedTransformation()->Put2(begin+last, i-last, GetAutoSignalPropagation(), blocking);
				last = i+1;
			}
		}
		if (last != i)
			AttachedTransformation()->Put2(begin+last, i-last, 0, blocking);

		if (messageEnd && GetAutoSignalPropagation())
		{
			AttachedTransformation()->MessageEnd(GetAutoSignalPropagation()-1, blocking);
			AttachedTransformation()->MessageSeriesEnd(GetAutoSignalPropagation()-1, blocking);
		}

		return 0;
	}

private:
	byte m_lineEnd;
};

class TestDataParser : public Unflushable<FilterWithInputQueue>
{
public:
	enum DataType {OTHER, COUNT, KEY_T, IV, INPUT, OUTPUT};

	TestDataParser(std::string algorithm, std::string test, std::string mode, unsigned int feedbackSize, bool encrypt, BufferedTransformation *attachment)
		: m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize)
		, m_firstLine(true), m_blankLineTransition(0)
	{
		Detach(attachment);

		m_typeToName[COUNT] = "COUNT";

		m_nameToType["COUNT"] = COUNT;
		m_nameToType["KEY"] = KEY_T;
		m_nameToType["KEYs"] = KEY_T;
		m_nameToType["key"] = KEY_T;
		m_nameToType["Key"] = KEY_T;
		m_nameToType["IV"] = IV;
		m_nameToType["IV1"] = IV;
		m_nameToType["CV"] = IV;
		m_nameToType["CV1"] = IV;
		m_nameToType["IB"] = IV;
		m_nameToType["TEXT"] = INPUT;
		m_nameToType["RESULT"] = OUTPUT;
		m_nameToType["Msg"] = INPUT;
		m_nameToType["Seed"] = INPUT;
		m_nameToType["V"] = INPUT;
		m_nameToType["DT"] = IV;
		SetEncrypt(encrypt);

		if (m_algorithm == "DSA" || m_algorithm == "ECDSA")
		{
			if (m_test == "PKV")
				m_trigger = "Qy";
			else if (m_test == "KeyPair")
				m_trigger = "N";
			else if (m_test == "SigGen")
				m_trigger = "Msg";
			else if (m_test == "SigVer")
				m_trigger = "S";
			else if (m_test == "PQGGen")
				m_trigger = "N";
			else if (m_test == "PQGVer")
				m_trigger = "H";
		}
		else if (m_algorithm == "HMAC")
			m_trigger = "Msg";
		else if (m_algorithm == "SHA")
			m_trigger = (m_test == "MONTE") ? "Seed" : "Msg";
		else if (m_algorithm == "RNG")
			m_trigger = "V";
		else if (m_algorithm == "RSA")
			m_trigger = (m_test == "Ver") ? "S" : "Msg";
	}

	void SetEncrypt(bool encrypt)
	{
		m_encrypt = encrypt;
		if (encrypt)
		{
			m_nameToType["PLAINTEXT"] = INPUT;
			m_nameToType["CIPHERTEXT"] = OUTPUT;
			m_nameToType["PT"] = INPUT;
			m_nameToType["CT"] = OUTPUT;
		}
		else
		{
			m_nameToType["PLAINTEXT"] = OUTPUT;
			m_nameToType["CIPHERTEXT"] = INPUT;
			m_nameToType["PT"] = OUTPUT;
			m_nameToType["CT"] = INPUT;
		}

		if (m_algorithm == "AES" || m_algorithm == "TDES")
		{
			if (encrypt)
			{
				m_trigger = "PLAINTEXT";
				m_typeToName[OUTPUT] = "CIPHERTEXT";
			}
			else
			{
				m_trigger = "CIPHERTEXT";
				m_typeToName[OUTPUT] = "PLAINTEXT";
			}
			m_count = 0;
		}
	}

protected:
	void OutputData(std::string &output, const std::string &key, const std::string &data)
	{
		output += key;
		output += "= ";
		output += data;
		output += "\n";
	}

	void OutputData(std::string &output, const std::string &key, int data)
	{
		OutputData(output, key, IntToString(data));
	}

	void OutputData(std::string &output, const std::string &key, const SecByteBlock &data)
	{
		output += key;
		output += "= ";
		HexEncoder(new StringSink(output), false).Put(data, data.size());
		output += "\n";
	}

	void OutputData(std::string &output, const std::string &key, const Integer &data, int size=-1)
	{
		SecByteBlock s(size < 0 ? data.MinEncodedSize() : size);
		data.Encode(s, s.size());
		OutputData(output, key, s);
	}

	void OutputData(std::string &output, const std::string &key, const PolynomialMod2 &data, int size=-1)
	{
		SecByteBlock s(size < 0 ? data.MinEncodedSize() : size);
		data.Encode(s, s.size());
		OutputData(output, key, s);
	}

	void OutputData(std::string &output, DataType t, const std::string &data)
	{
		if (m_algorithm == "SKIPJACK")
		{
			if (m_test == "KAT")
			{
				if (t == OUTPUT)
					output = m_line + data + "\n";
			}
			else
			{
				if (t != COUNT)
				{
					output += m_typeToName[t];
					output += "=";
				}
				output += data;
				output += t == OUTPUT ? "\n" : "  ";
			}
		}
		else if (m_algorithm == "TDES" && t == KEY_T && m_typeToName[KEY_T].empty())
		{
			output += "KEY1 = ";
			output += data.substr(0, 16);
			output += "\nKEY2 = ";
			output += data.size() > 16 ? data.substr(16, 16) : data.substr(0, 16);
			output += "\nKEY3 = ";
			output += data.size() > 32 ? data.substr(32, 16) : data.substr(0, 16);
			output += "\n";
		}
		else
		{
			output += m_typeToName[t];
			output += " = ";
			output += data;
			output += "\n";
		}
	}

	void OutputData(std::string &output, DataType t, int i)
	{
		OutputData(output, t, IntToString(i));
	}

	void OutputData(std::string &output, DataType t, const SecByteBlock &data)
	{
		std::string hexData;
		StringSource(data.begin(), data.size(), true, new HexEncoder(new StringSink(hexData), false));
		OutputData(output, t, hexData);
	}

	void OutputGivenData(std::string &output, DataType t, bool optional = false)
	{
		if (m_data.find(m_typeToName[t]) == m_data.end())
		{
			if (optional)
				return;
			throw Exception(Exception::OTHER_ERROR, "TestDataParser: key not found: " + m_typeToName[t]);
		}

		OutputData(output, t, m_data[m_typeToName[t]]);
	}

	template <class T>
		BlockCipher * NewBT(T *)
	{
		if (!m_encrypt && (m_mode == "ECB" || m_mode == "CBC"))
			return new typename T::Decryption;
		else
			return new typename T::Encryption;
	}

	template <class T>
		SymmetricCipher * NewMode(T *, BlockCipher &bt, const byte *iv)
	{
		if (!m_encrypt)
			return new typename T::Decryption(bt, iv, m_feedbackSize/8);
		else
			return new typename T::Encryption(bt, iv, m_feedbackSize/8);
	}

	static inline void Xor(SecByteBlock &z, const SecByteBlock &x, const SecByteBlock &y)
	{
		assert(x.size() == y.size());
		z.resize(x.size());
		xorbuf(z, x, y, x.size());
	}

	SecByteBlock UpdateKey(SecByteBlock key, const SecByteBlock *text)
	{
		unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000;
		int keySize = key.size(), blockSize = text[0].size();
		SecByteBlock x(keySize);
		for (int k=0; k<keySize;)
		{
			int pos = innerCount * blockSize - keySize + k;
			memcpy(x + k, text[pos / blockSize] + pos % blockSize, blockSize - pos % blockSize);
			k += blockSize - pos % blockSize;
		}

		if (m_algorithm == "TDES" || m_algorithm == "DES")
		{
			for (int i=0; i<keySize; i+=8)
			{
				xorbuf(key+i, x+keySize-8-i, 8);
				DES::CorrectKeyParityBits(key+i);
			}
		}
		else
			xorbuf(key, x, keySize);

		return key;
	}

	static inline void AssignLeftMostBits(SecByteBlock &z, const SecByteBlock &x, unsigned int K)
	{
		z.Assign(x, K/8);
	}

	template <class EC>
	void EC_KeyPair(string &output, int n, const OID &oid)
	{
		DL_GroupParameters_EC<EC> params(oid);
		for (int i=0; i<n; i++)
		{
			DL_PrivateKey_EC<EC> priv;
			DL_PublicKey_EC<EC> pub;
			priv.Initialize(m_rng, params);
			priv.MakePublicKey(pub);

			OutputData(output, "d ", priv.GetPrivateExponent());
			OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength());
			OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength());
		}
	}

	template <class EC>
	void EC_SigGen(string &output, const OID &oid)
	{
		DL_GroupParameters_EC<EC> params(oid);
		typename ECDSA<EC, SHA1>::PrivateKey priv;
		typename ECDSA<EC, SHA1>::PublicKey pub;
		priv.Initialize(m_rng, params);
		priv.MakePublicKey(pub);

		typename ECDSA<EC, SHA1>::Signer signer(priv);
		SecByteBlock sig(signer.SignatureLength());
		StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size()))));
		SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2);

		OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength());
		OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength());
		OutputData(output, "R ", R);
		OutputData(output, "S ", S);
	}

	template <class EC>
	void EC_SigVer(string &output, const OID &oid)
	{
		SecByteBlock x(DecodeHex(m_data["Qx"]));
		SecByteBlock y(DecodeHex(m_data["Qy"]));
		Integer r((m_data["R"]+"h").c_str());
		Integer s((m_data["S"]+"h").c_str());

		typename EC::FieldElement Qx(x, x.size());
		typename EC::FieldElement Qy(y, y.size());
		typename EC::Element Q(Qx, Qy);

		DL_GroupParameters_EC<EC> params(oid);
		typename ECDSA<EC, SHA1>::PublicKey pub;
		pub.Initialize(params, Q);
		typename ECDSA<EC, SHA1>::Verifier verifier(pub);

		SecByteBlock sig(verifier.SignatureLength());
		r.Encode(sig, sig.size()/2);
		s.Encode(sig+sig.size()/2, sig.size()/2);

		SignatureVerificationFilter filter(verifier);
		filter.Put(sig, sig.size());
		StringSource(m_data["Msg"], true, new HexDecoder(new Redirector(filter, Redirector::DATA_ONLY)));
		filter.MessageEnd();
		byte b;
		filter.Get(b);
		OutputData(output, "Result ", b ? "P" : "F");
	}

	template <class EC>
	static bool EC_PKV(RandomNumberGenerator &rng, const SecByteBlock &x, const SecByteBlock &y, const OID &oid)
	{
		typename EC::FieldElement Qx(x, x.size());
		typename EC::FieldElement Qy(y, y.size());
		typename EC::Element Q(Qx, Qy);

		DL_GroupParameters_EC<EC> params(oid);
		typename ECDSA<EC, SHA1>::PublicKey pub;
		pub.Initialize(params, Q);
		return pub.Validate(rng, 3);
	}

	template <class H, class Result>
	Result * CreateRSA2(const std::string &standard)
	{
		if (typeid(Result) == typeid(PK_Verifier))
		{
			if (standard == "R")
				return (Result *) new typename RSASS_ISO<H>::Verifier;
			else if (standard == "P")
				return (Result *) new typename RSASS<PSS, H>::Verifier;
			else if (standard == "1")
				return (Result *) new typename RSASS<PKCS1v15, H>::Verifier;
		}
		else if (typeid(Result) == typeid(PK_Signer))
		{
			if (standard == "R")
				return (Result *) new typename RSASS_ISO<H>::Signer;
			else if (standard == "P")
				return (Result *) new typename RSASS<PSS, H>::Signer;
			else if (standard == "1")
				return (Result *) new typename RSASS<PKCS1v15, H>::Signer;
		}

		return NULL;
	}

	template <class Result>
	Result * CreateRSA(const std::string &standard, const std::string &hash)
	{
		if (hash == "1")
			return CreateRSA2<SHA1, Result>(standard);
		else if (hash == "224")
			return CreateRSA2<SHA224, Result>(standard);
		else if (hash == "256")
			return CreateRSA2<SHA256, Result>(standard);
		else if (hash == "384")
			return CreateRSA2<SHA384, Result>(standard);
		else if (hash == "512")
			return CreateRSA2<SHA512, Result>(standard);
		else
			return NULL;
	}

	virtual void DoTest()
	{
		std::string output;

		if (m_algorithm == "DSA")
		{
			if (m_test == "KeyPair")
			{
				DL_GroupParameters_DSA pqg;
				int modLen = atol(m_bracketString.substr(6).c_str());
				pqg.GenerateRandomWithKeySize(m_rng, modLen);

				OutputData(output, "P ", pqg.GetModulus());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -